summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--LGPL_EXCEPTION.txt22
-rw-r--r--config.tests/arch/arch.cpp44
-rw-r--r--config.tests/avx512/avx512.cpp5
-rw-r--r--config_help.txt5
-rw-r--r--configure.json92
-rw-r--r--configure.pri27
-rw-r--r--doc/global/macros.qdocconf5
-rw-r--r--doc/src/examples/bearermonitor.qdoc35
-rw-r--r--doc/src/examples/customtypesending.qdoc121
-rw-r--r--doc/src/examples/dbus-chat.qdoc36
-rw-r--r--doc/src/examples/digiflip.qdoc31
-rw-r--r--doc/src/examples/fingerpaint.qdoc42
-rw-r--r--doc/src/examples/flickable.qdoc33
-rw-r--r--doc/src/examples/flightinfo.qdoc33
-rw-r--r--doc/src/examples/htmlinfo.qdoc68
-rw-r--r--doc/src/examples/lightmaps.qdoc33
-rw-r--r--doc/src/examples/pinchzoom.qdoc38
-rw-r--r--doc/src/examples/raycasting.qdoc33
-rw-r--r--doc/src/examples/rsslisting.qdoc36
-rw-r--r--doc/src/examples/styleexample.qdoc33
-rw-r--r--doc/src/images/gradients-demo.pngbin93147 -> 85199 bytes
-rw-r--r--examples/corelib/serialization/cbordump/cbordump.pro14
-rw-r--r--examples/corelib/serialization/cbordump/main.cpp765
-rw-r--r--examples/corelib/serialization/cbordump/tag-transform.xslt25
-rw-r--r--examples/corelib/serialization/convert/cborconverter.cpp393
-rw-r--r--examples/corelib/serialization/convert/cborconverter.h85
-rw-r--r--examples/corelib/serialization/convert/convert.pro29
-rw-r--r--examples/corelib/serialization/convert/converter.h103
-rw-r--r--examples/corelib/serialization/convert/datastreamconverter.cpp273
-rw-r--r--examples/corelib/serialization/convert/datastreamconverter.h85
-rw-r--r--examples/corelib/serialization/convert/jsonconverter.cpp212
-rw-r--r--examples/corelib/serialization/convert/jsonconverter.h85
-rw-r--r--examples/corelib/serialization/convert/main.cpp234
-rw-r--r--examples/corelib/serialization/convert/nullconverter.cpp99
-rw-r--r--examples/corelib/serialization/convert/nullconverter.h69
-rw-r--r--examples/corelib/serialization/convert/textconverter.cpp160
-rw-r--r--examples/corelib/serialization/convert/textconverter.h70
-rw-r--r--examples/corelib/serialization/convert/xmlconverter.cpp514
-rw-r--r--examples/corelib/serialization/convert/xmlconverter.h69
-rw-r--r--examples/corelib/serialization/serialization.pro5
-rw-r--r--examples/corelib/threads/queuedcustomtype/window.cpp3
-rw-r--r--examples/examples.pro3
-rw-r--r--examples/gui/doc/src/rasterwindow.qdoc5
-rw-r--r--examples/gui/rasterwindow/rasterwindow.cpp4
-rw-r--r--examples/network/doc/images/secureudpclient-example.pngbin0 -> 23211 bytes
-rw-r--r--examples/network/doc/images/secureudpserver-example.pngbin0 -> 38412 bytes
-rw-r--r--examples/network/doc/src/secureudpclient.qdoc124
-rw-r--r--examples/network/doc/src/secureudpserver.qdoc131
-rw-r--r--examples/network/loopback/dialog.cpp55
-rw-r--r--examples/network/loopback/dialog.h27
-rw-r--r--examples/network/loopback/main.cpp4
-rw-r--r--examples/network/network-chat/client.cpp2
-rw-r--r--examples/network/network-chat/connection.cpp264
-rw-r--r--examples/network/network-chat/connection.h17
-rw-r--r--examples/network/network-chat/peermanager.cpp54
-rw-r--r--examples/network/network-chat/peermanager.h4
-rw-r--r--examples/network/network-chat/server.cpp3
-rw-r--r--examples/network/network.pro7
-rw-r--r--examples/network/secureudpclient/addressdialog.cpp118
-rw-r--r--examples/network/secureudpclient/addressdialog.h85
-rw-r--r--examples/network/secureudpclient/addressdialog.ui132
-rw-r--r--examples/network/secureudpclient/association.cpp197
-rw-r--r--examples/network/secureudpclient/association.h97
-rw-r--r--examples/network/secureudpclient/main.cpp64
-rw-r--r--examples/network/secureudpclient/mainwindow.cpp185
-rw-r--r--examples/network/secureudpclient/mainwindow.h111
-rw-r--r--examples/network/secureudpclient/mainwindow.ui198
-rw-r--r--examples/network/secureudpclient/secureudpclient.pro22
-rw-r--r--examples/network/secureudpserver/main.cpp64
-rw-r--r--examples/network/secureudpserver/mainwindow.cpp138
-rw-r--r--examples/network/secureudpserver/mainwindow.h92
-rw-r--r--examples/network/secureudpserver/mainwindow.ui207
-rw-r--r--examples/network/secureudpserver/nicselector.cpp95
-rw-r--r--examples/network/secureudpserver/nicselector.h84
-rw-r--r--examples/network/secureudpserver/nicselector.ui144
-rw-r--r--examples/network/secureudpserver/secureudpserver.pro21
-rw-r--r--examples/network/secureudpserver/server.cpp277
-rw-r--r--examples/network/secureudpserver/server.h107
-rw-r--r--examples/opengl/contextinfo/widget.cpp2
-rw-r--r--examples/opengl/qopenglwindow/main.cpp15
-rw-r--r--examples/touch/dials/dials.pro8
-rw-r--r--examples/touch/dials/doc/src/touch-dials.qdoc38
-rw-r--r--examples/touch/fingerpaint/fingerpaint.pro13
-rw-r--r--examples/touch/knobs/doc/src/touch-knobs.qdoc38
-rw-r--r--examples/touch/knobs/knobs.pro8
-rw-r--r--examples/touch/pinchzoom/pinchzoom.pro16
-rw-r--r--examples/vulkan/hellovulkantexture/hellovulkantexture.cpp16
-rw-r--r--examples/widgets/doc/src/customsortfiltermodel.qdoc16
-rw-r--r--examples/widgets/doc/src/gradients.qdoc7
-rw-r--r--examples/widgets/graphicsview/boxes/glextensions.h15
-rw-r--r--examples/widgets/graphicsview/boxes/scene.cpp16
-rw-r--r--examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp17
-rw-r--r--examples/widgets/mainwindows/mainwindow/mainwindow.cpp1
-rw-r--r--examples/widgets/painting/deform/pathdeform.cpp11
-rw-r--r--examples/widgets/painting/gradients/gradients.cpp58
-rw-r--r--examples/widgets/painting/gradients/gradients.h7
-rw-r--r--examples/widgets/painting/gradients/gradients.html6
-rw-r--r--examples/widgets/richtext/calendar/mainwindow.cpp6
-rw-r--r--examples/widgets/richtext/textedit/example.html14
-rw-r--r--examples/widgets/richtext/textedit/textedit.cpp140
-rw-r--r--examples/widgets/tools/undo/main.cpp2
-rw-r--r--examples/widgets/touch/dials/dials.pro8
-rw-r--r--examples/widgets/touch/dials/dials.ui (renamed from examples/touch/dials/dials.ui)0
-rw-r--r--examples/widgets/touch/dials/doc/images/touch-dials-example.png (renamed from examples/touch/dials/doc/images/touch-dials-example.png)bin17676 -> 17676 bytes
-rw-r--r--examples/widgets/touch/dials/doc/src/touch-dials.qdoc38
-rw-r--r--examples/widgets/touch/dials/main.cpp (renamed from examples/touch/dials/main.cpp)0
-rw-r--r--examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc42
-rw-r--r--examples/widgets/touch/fingerpaint/fingerpaint.pro13
-rw-r--r--examples/widgets/touch/fingerpaint/main.cpp (renamed from examples/touch/fingerpaint/main.cpp)0
-rw-r--r--examples/widgets/touch/fingerpaint/mainwindow.cpp (renamed from examples/touch/fingerpaint/mainwindow.cpp)0
-rw-r--r--examples/widgets/touch/fingerpaint/mainwindow.h (renamed from examples/touch/fingerpaint/mainwindow.h)0
-rw-r--r--examples/widgets/touch/fingerpaint/scribblearea.cpp (renamed from examples/touch/fingerpaint/scribblearea.cpp)0
-rw-r--r--examples/widgets/touch/fingerpaint/scribblearea.h (renamed from examples/touch/fingerpaint/scribblearea.h)0
-rw-r--r--examples/widgets/touch/knobs/doc/images/touch-knobs-example.png (renamed from examples/touch/knobs/doc/images/touch-knobs-example.png)bin1290 -> 1290 bytes
-rw-r--r--examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc38
-rw-r--r--examples/widgets/touch/knobs/knob.cpp (renamed from examples/touch/knobs/knob.cpp)0
-rw-r--r--examples/widgets/touch/knobs/knob.h (renamed from examples/touch/knobs/knob.h)0
-rw-r--r--examples/widgets/touch/knobs/knobs.pro8
-rw-r--r--examples/widgets/touch/knobs/main.cpp (renamed from examples/touch/knobs/main.cpp)0
-rw-r--r--examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.pngbin0 -> 42493 bytes
-rw-r--r--examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc38
-rw-r--r--examples/widgets/touch/pinchzoom/graphicsview.cpp (renamed from examples/touch/pinchzoom/graphicsview.cpp)0
-rw-r--r--examples/widgets/touch/pinchzoom/graphicsview.h (renamed from examples/touch/pinchzoom/graphicsview.h)0
-rw-r--r--examples/widgets/touch/pinchzoom/images/cheese.jpg (renamed from examples/touch/pinchzoom/images/cheese.jpg)bin3029 -> 3029 bytes
-rw-r--r--examples/widgets/touch/pinchzoom/main.cpp (renamed from examples/touch/pinchzoom/main.cpp)0
-rw-r--r--examples/widgets/touch/pinchzoom/mice.qrc (renamed from examples/touch/pinchzoom/mice.qrc)0
-rw-r--r--examples/widgets/touch/pinchzoom/mouse.cpp (renamed from examples/touch/pinchzoom/mouse.cpp)0
-rw-r--r--examples/widgets/touch/pinchzoom/mouse.h (renamed from examples/touch/pinchzoom/mouse.h)0
-rw-r--r--examples/widgets/touch/pinchzoom/pinchzoom.pro16
-rw-r--r--examples/widgets/touch/touch.pro (renamed from examples/touch/touch.pro)0
-rw-r--r--examples/widgets/widgets.pro1
-rw-r--r--examples/widgets/widgets/tablet/mainwindow.cpp16
-rw-r--r--examples/widgets/widgets/tablet/mainwindow.h3
-rw-r--r--examples/widgets/widgets/tablet/tablet.pro5
-rw-r--r--examples/widgets/widgets/tablet/tabletcanvas.cpp12
-rw-r--r--examples/widgets/widgets/tablet/tabletcanvas.h1
-rw-r--r--header.MIT28
-rw-r--r--mkspecs/android-clang/qmake.conf2
-rw-r--r--mkspecs/common/android-base-head.conf7
-rw-r--r--mkspecs/common/android-base-tail.conf2
-rw-r--r--mkspecs/common/clang.conf2
-rw-r--r--mkspecs/common/g++-base.conf2
-rw-r--r--mkspecs/common/gcc-base.conf8
-rw-r--r--mkspecs/common/icc-base-unix.conf106
-rw-r--r--mkspecs/common/macx.conf4
-rw-r--r--mkspecs/common/msvc-desktop.conf4
-rw-r--r--mkspecs/common/msvc-version.conf6
-rw-r--r--mkspecs/common/qcc-base-qnx.conf10
-rw-r--r--mkspecs/common/winrt_winphone/qmake.conf4
-rw-r--r--mkspecs/features/data/macros.cpp3
-rw-r--r--mkspecs/features/default_post.prf15
-rw-r--r--mkspecs/features/exclusive_builds.prf4
-rw-r--r--mkspecs/features/gc_binaries.prf3
-rw-r--r--mkspecs/features/lrelease.prf41
-rw-r--r--mkspecs/features/qml_module.prf14
-rw-r--r--mkspecs/features/qml_plugin.prf2
-rw-r--r--mkspecs/features/qt.prf11
-rw-r--r--mkspecs/features/qt_app.prf3
-rw-r--r--mkspecs/features/qt_build_config.prf1
-rw-r--r--mkspecs/features/qt_common.prf32
-rw-r--r--mkspecs/features/qt_configure.prf167
-rw-r--r--mkspecs/features/qt_module.prf13
-rw-r--r--mkspecs/features/qt_test_helper.prf35
-rw-r--r--mkspecs/features/resources.prf36
-rw-r--r--mkspecs/features/simd.prf27
-rw-r--r--mkspecs/features/testcase.prf41
-rw-r--r--mkspecs/features/toolchain.prf37
-rw-r--r--mkspecs/features/uic.prf4
-rw-r--r--mkspecs/features/uikit/default_pre.prf2
-rw-r--r--mkspecs/features/uikit/gc_binaries.prf2
-rw-r--r--mkspecs/features/unix/separate_debug_info.prf10
-rw-r--r--mkspecs/features/wasm/qt.prf12
-rw-r--r--mkspecs/features/wasm/wasm.prf81
-rw-r--r--mkspecs/linux-icc/qmake.conf116
-rw-r--r--mkspecs/macx-clang/Info.plist.disable_highdpi8
-rw-r--r--mkspecs/macx-clang/qmake.conf4
-rw-r--r--mkspecs/macx-g++/qmake.conf4
-rw-r--r--mkspecs/macx-icc/qmake.conf88
-rw-r--r--mkspecs/macx-ios-clang/qmake.conf2
-rw-r--r--mkspecs/macx-tvos-clang/qmake.conf2
-rw-r--r--mkspecs/macx-watchos-clang/qmake.conf2
-rw-r--r--mkspecs/macx-xcode/default.xcscheme10
-rw-r--r--mkspecs/wasm-emscripten/qmake.conf90
-rw-r--r--mkspecs/wasm-emscripten/qplatformdefs.h181
-rw-r--r--mkspecs/win32-icc/qmake.conf1
-rw-r--r--qmake/Makefile.unix6
-rw-r--r--qmake/Makefile.win321
-rw-r--r--qmake/doc/src/qmake-manual.qdoc85
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp35
-rw-r--r--qmake/generators/mac/pbuilder_pbx.h12
-rw-r--r--qmake/generators/makefile.cpp222
-rw-r--r--qmake/generators/makefile.h17
-rw-r--r--qmake/generators/makefiledeps.cpp28
-rw-r--r--qmake/generators/metamakefile.cpp28
-rw-r--r--qmake/generators/metamakefile.h2
-rw-r--r--qmake/generators/projectgenerator.cpp19
-rw-r--r--qmake/generators/projectgenerator.h10
-rw-r--r--qmake/generators/unix/unixmake.cpp14
-rw-r--r--qmake/generators/unix/unixmake.h24
-rw-r--r--qmake/generators/unix/unixmake2.cpp35
-rw-r--r--qmake/generators/win32/mingw_make.cpp20
-rw-r--r--qmake/generators/win32/mingw_make.h28
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp2
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.h44
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp9
-rw-r--r--qmake/generators/win32/msvc_nmake.h18
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp2
-rw-r--r--qmake/generators/win32/msvc_objectmodel.h34
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp41
-rw-r--r--qmake/generators/win32/msvc_vcproj.h18
-rw-r--r--qmake/generators/win32/msvc_vcxproj.h2
-rw-r--r--qmake/generators/win32/registry.cpp6
-rw-r--r--qmake/generators/win32/winmakefile.cpp34
-rw-r--r--qmake/generators/win32/winmakefile.h14
-rw-r--r--qmake/library/ioutils.cpp6
-rw-r--r--qmake/library/proitems.h59
-rw-r--r--qmake/library/qmakebuiltins.cpp1470
-rw-r--r--qmake/library/qmakeevaluator.cpp35
-rw-r--r--qmake/library/qmakeevaluator.h14
-rw-r--r--qmake/library/qmakeevaluator_p.h22
-rw-r--r--qmake/library/qmakeparser.cpp18
-rw-r--r--qmake/library/qmakeparser.h4
-rw-r--r--qmake/library/qmakevfs.cpp37
-rw-r--r--qmake/library/qmakevfs.h6
-rw-r--r--qmake/main.cpp36
-rw-r--r--qmake/meta.cpp121
-rw-r--r--qmake/meta.h9
-rw-r--r--qmake/option.cpp4
-rw-r--r--qmake/option.h10
-rw-r--r--qmake/project.cpp10
-rw-r--r--qmake/property.cpp4
-rw-r--r--src/3rdparty/double-conversion/bignum-dtoa.cc8
-rw-r--r--src/3rdparty/double-conversion/bignum-dtoa.h2
-rw-r--r--src/3rdparty/double-conversion/bignum.cc15
-rw-r--r--src/3rdparty/double-conversion/bignum.h5
-rw-r--r--src/3rdparty/double-conversion/cached-powers.cc15
-rw-r--r--src/3rdparty/double-conversion/cached-powers.h2
-rw-r--r--src/3rdparty/double-conversion/diy-fp.cc4
-rw-r--r--src/3rdparty/double-conversion/diy-fp.h24
-rw-r--r--src/3rdparty/double-conversion/double-conversion.cc281
-rw-r--r--src/3rdparty/double-conversion/double-conversion.pri2
-rw-r--r--src/3rdparty/double-conversion/fast-dtoa.cc8
-rw-r--r--src/3rdparty/double-conversion/fast-dtoa.h2
-rw-r--r--src/3rdparty/double-conversion/fixed-dtoa.cc11
-rw-r--r--src/3rdparty/double-conversion/fixed-dtoa.h2
-rw-r--r--src/3rdparty/double-conversion/ieee.h8
-rw-r--r--src/3rdparty/double-conversion/include/double-conversion/double-conversion.h53
-rw-r--r--src/3rdparty/double-conversion/include/double-conversion/utils.h90
-rw-r--r--src/3rdparty/double-conversion/qt_attribution.json4
-rw-r--r--src/3rdparty/double-conversion/strtod.cc51
-rw-r--r--src/3rdparty/double-conversion/strtod.h2
-rw-r--r--src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jarbin54213 -> 54329 bytes
-rw-r--r--src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties3
-rwxr-xr-xsrc/3rdparty/gradle/gradlew8
-rw-r--r--src/3rdparty/gradle/gradlew.bat2
-rw-r--r--src/3rdparty/harfbuzz-ng/qt_attribution.json2
-rw-r--r--src/3rdparty/harfbuzz/qt_attribution.json2
-rw-r--r--src/3rdparty/libjpeg.pri6
-rw-r--r--src/3rdparty/tinycbor/.gitignore81
-rw-r--r--src/3rdparty/tinycbor/LICENSE21
-rw-r--r--src/3rdparty/tinycbor/README13
-rw-r--r--src/3rdparty/tinycbor/VERSION1
-rw-r--r--src/3rdparty/tinycbor/qt_attribution.json14
-rw-r--r--src/3rdparty/tinycbor/src/cbor.h722
-rw-r--r--src/3rdparty/tinycbor/src/cborencoder.c677
-rw-r--r--src/3rdparty/tinycbor/src/cborerrorstrings.c188
-rw-r--r--src/3rdparty/tinycbor/src/cborinternal_p.h314
-rw-r--r--src/3rdparty/tinycbor/src/cborjson.h62
-rw-r--r--src/3rdparty/tinycbor/src/cborparser.c1526
-rw-r--r--src/3rdparty/tinycbor/src/compilersupport_p.h205
-rw-r--r--src/3rdparty/tinycbor/src/tinycbor-version.h3
-rw-r--r--src/3rdparty/tinycbor/tests/.gitignore15
-rw-r--r--src/3rdparty/tinycbor/tests/encoder/data.cpp310
-rw-r--r--src/3rdparty/tinycbor/tests/encoder/encoder.pro9
-rw-r--r--src/3rdparty/tinycbor/tests/encoder/tst_encoder.cpp496
-rw-r--r--src/3rdparty/tinycbor/tests/parser/data.cpp573
-rw-r--r--src/3rdparty/tinycbor/tests/parser/parser.pro10
-rw-r--r--src/3rdparty/tinycbor/tests/parser/tst_parser.cpp1667
-rw-r--r--src/3rdparty/wasm/DejaVuSans.ttfbin0 -> 493564 bytes
-rw-r--r--src/3rdparty/wasm/LICENSE15
-rw-r--r--src/3rdparty/wasm/Vera.ttfbin0 -> 65932 bytes
-rw-r--r--src/3rdparty/wasm/qt_attribution.json21
-rw-r--r--src/3rdparty/xcb/README8
-rw-r--r--src/3rdparty/xcb/include/xcb/randr.h175
-rw-r--r--src/3rdparty/xcb/include/xcb/render.h229
-rw-r--r--src/3rdparty/xcb/include/xcb/shape.h43
-rw-r--r--src/3rdparty/xcb/include/xcb/shm.h24
-rw-r--r--src/3rdparty/xcb/include/xcb/sync.h567
-rw-r--r--src/3rdparty/xcb/include/xcb/xfixes.h150
-rw-r--r--src/3rdparty/xcb/include/xcb/xinerama.h157
-rw-r--r--src/3rdparty/xcb/include/xcb/xinput.h9306
-rw-r--r--src/3rdparty/xcb/libxcb/randr.c817
-rw-r--r--src/3rdparty/xcb/libxcb/render.c950
-rw-r--r--src/3rdparty/xcb/libxcb/shape.c85
-rw-r--r--src/3rdparty/xcb/libxcb/shm.c19
-rw-r--r--src/3rdparty/xcb/libxcb/support_libxcb_versions_where_xcb_sumof_not_available.patch273
-rw-r--r--src/3rdparty/xcb/libxcb/sync.c751
-rw-r--r--src/3rdparty/xcb/libxcb/xfixes.c321
-rw-r--r--src/3rdparty/xcb/libxcb/xinerama.c212
-rw-r--r--src/3rdparty/xcb/libxcb/xinput.c14156
-rw-r--r--src/3rdparty/xcb/libxcb/xkb.c39
-rw-r--r--src/3rdparty/xkbcommon.pri4
-rw-r--r--src/android/jar/jar.pro2
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java9
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/EditContextView.java120
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/EditMenu.java142
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java85
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java361
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java56
-rw-r--r--src/android/templates/AndroidManifest.xml2
-rw-r--r--src/android/templates/build.gradle10
-rw-r--r--src/angle/src/common/common.pri5
-rw-r--r--src/corelib/Qt5CoreMacros.cmake43
-rw-r--r--src/corelib/animation/qabstractanimation.cpp12
-rw-r--r--src/corelib/codecs/qeucjpcodec_p.h10
-rw-r--r--src/corelib/codecs/qeuckrcodec_p.h20
-rw-r--r--src/corelib/codecs/qgb18030codec_p.h28
-rw-r--r--src/corelib/codecs/qiconvcodec_p.h8
-rw-r--r--src/corelib/codecs/qjiscodec_p.h10
-rw-r--r--src/corelib/codecs/qjpunicode.cpp54
-rw-r--r--src/corelib/codecs/qsjiscodec_p.h10
-rw-r--r--src/corelib/codecs/qtextcodec.cpp34
-rw-r--r--src/corelib/codecs/qtextcodec.h3
-rw-r--r--src/corelib/codecs/qtextcodec_p.h2
-rw-r--r--src/corelib/codecs/qutfcodec.cpp101
-rw-r--r--src/corelib/codecs/qutfcodec_p.h4
-rw-r--r--src/corelib/codecs/qwindowscodec_p.h8
-rw-r--r--src/corelib/configure.json11
-rw-r--r--src/corelib/corelib.pro1
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp48
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp14
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qeasingcurve.cpp8
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp7
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qscopeguard.cpp67
-rw-r--r--src/corelib/doc/snippets/qstring/main.cpp5
-rw-r--r--src/corelib/doc/src/objectmodel/signalsandslots.qdoc4
-rw-r--r--src/corelib/global/archdetect.cpp2
-rw-r--r--src/corelib/global/global.pri1
-rw-r--r--src/corelib/global/qcompilerdetection.h24
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h3
-rw-r--r--src/corelib/global/qendian.cpp919
-rw-r--r--src/corelib/global/qendian.h65
-rw-r--r--src/corelib/global/qendian.qdoc554
-rw-r--r--src/corelib/global/qglobal.cpp94
-rw-r--r--src/corelib/global/qglobal.h8
-rw-r--r--src/corelib/global/qglobalstatic.h2
-rw-r--r--src/corelib/global/qglobalstatic.qdoc2
-rw-r--r--src/corelib/global/qlogging.cpp78
-rw-r--r--src/corelib/global/qnamespace.h58
-rw-r--r--src/corelib/global/qnamespace.qdoc54
-rw-r--r--src/corelib/global/qnumeric_p.h52
-rw-r--r--src/corelib/global/qoperatingsystemversion_win.cpp2
-rw-r--r--src/corelib/global/qprocessordetection.h8
-rw-r--r--src/corelib/global/qrandom.cpp8
-rw-r--r--src/corelib/global/qsystemdetection.h2
-rw-r--r--src/corelib/global/qtrace_p.h2
-rw-r--r--src/corelib/global/qversiontagging.cpp11
-rw-r--r--src/corelib/io/qdebug.cpp16
-rw-r--r--src/corelib/io/qdebug.h13
-rw-r--r--src/corelib/io/qdebug_p.h2
-rw-r--r--src/corelib/io/qdir.cpp28
-rw-r--r--src/corelib/io/qdir.h2
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp48
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp16
-rw-r--r--src/corelib/io/qfilesystemiterator_win.cpp3
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm2
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp7
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp38
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp29
-rw-r--r--src/corelib/io/qiodevice.cpp5
-rw-r--r--src/corelib/io/qloggingregistry.cpp14
-rw-r--r--src/corelib/io/qprocess_unix.cpp1
-rw-r--r--src/corelib/io/qprocess_win.cpp123
-rw-r--r--src/corelib/io/qresource.cpp10
-rw-r--r--src/corelib/io/qsettings.cpp17
-rw-r--r--src/corelib/io/qsettings_mac.cpp18
-rw-r--r--src/corelib/io/qsettings_win.cpp91
-rw-r--r--src/corelib/io/qsettings_winrt.cpp18
-rw-r--r--src/corelib/io/qurl.cpp66
-rw-r--r--src/corelib/io/qurlrecode.cpp142
-rw-r--r--src/corelib/io/qwindowspipereader.cpp10
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp17
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.h3
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp246
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.h15
-rw-r--r--src/corelib/kernel/kernel.pri4
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp9
-rw-r--r--src/corelib/kernel/qcfsocketnotifier.cpp6
-rw-r--r--src/corelib/kernel/qcore_mac.cpp2
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm57
-rw-r--r--src/corelib/kernel/qcore_mac_p.h154
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp108
-rw-r--r--src/corelib/kernel/qcoreapplication.h8
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp642
-rw-r--r--src/corelib/kernel/qcoreevent.cpp8
-rw-r--r--src/corelib/kernel/qcoreglobaldata.cpp5
-rw-r--r--src/corelib/kernel/qdeadlinetimer.cpp1
-rw-r--r--src/corelib/kernel/qdeadlinetimer.h5
-rw-r--r--src/corelib/kernel/qelapsedtimer_win.cpp15
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm70
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf_p.h36
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp112
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp22
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h1
-rw-r--r--src/corelib/kernel/qeventloop.cpp30
-rw-r--r--src/corelib/kernel/qmetaobject.cpp105
-rw-r--r--src/corelib/kernel/qmetaobject.h1
-rw-r--r--src/corelib/kernel/qmetaobject_p.h7
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp49
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder_p.h10
-rw-r--r--src/corelib/kernel/qmetatype.cpp234
-rw-r--r--src/corelib/kernel/qmetatype.h50
-rw-r--r--src/corelib/kernel/qmetatype_p.h16
-rw-r--r--src/corelib/kernel/qobject.cpp43
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h32
-rw-r--r--src/corelib/kernel/qsharedmemory_win.cpp14
-rw-r--r--src/corelib/kernel/qsystemerror.cpp4
-rw-r--r--src/corelib/kernel/qsystemsemaphore_win.cpp7
-rw-r--r--src/corelib/kernel/qtcore_eval.cpp2
-rw-r--r--src/corelib/kernel/qtestsupport_core.cpp126
-rw-r--r--src/corelib/kernel/qtestsupport_core.h92
-rw-r--r--src/corelib/kernel/qtimer.cpp42
-rw-r--r--src/corelib/kernel/qtimer.h17
-rw-r--r--src/corelib/kernel/qtranslator.cpp15
-rw-r--r--src/corelib/kernel/qvariant.cpp364
-rw-r--r--src/corelib/kernel/qvariant.h2
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp7
-rw-r--r--src/corelib/kernel/qwineventnotifier.h2
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp9
-rw-r--r--src/corelib/plugin/plugin.pri1
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp127
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h3
-rw-r--r--src/corelib/plugin/qlibrary.cpp48
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp27
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp4
-rw-r--r--src/corelib/plugin/qplugin.h28
-rw-r--r--src/corelib/plugin/qplugin_p.h75
-rw-r--r--src/corelib/plugin/qpluginloader.cpp11
-rw-r--r--src/corelib/plugin/qsystemlibrary.cpp2
-rw-r--r--src/corelib/qtcore.tracepoints39
-rw-r--r--src/corelib/serialization/qcborarray.cpp1213
-rw-r--r--src/corelib/serialization/qcborarray.h298
-rw-r--r--src/corelib/serialization/qcborcommon.h147
-rw-r--r--src/corelib/serialization/qcbordiagnostic.cpp347
-rw-r--r--src/corelib/serialization/qcbormap.cpp1766
-rw-r--r--src/corelib/serialization/qcbormap.h349
-rw-r--r--src/corelib/serialization/qcborstream.cpp2954
-rw-r--r--src/corelib/serialization/qcborstream.h267
-rw-r--r--src/corelib/serialization/qcborvalue.cpp2477
-rw-r--r--src/corelib/serialization/qcborvalue.h467
-rw-r--r--src/corelib/serialization/qcborvalue_p.h398
-rw-r--r--src/corelib/serialization/qdatastream.cpp1
-rw-r--r--src/corelib/serialization/qdatastream.h5
-rw-r--r--src/corelib/serialization/qjson_p.h32
-rw-r--r--src/corelib/serialization/qjsonarray.cpp4
-rw-r--r--src/corelib/serialization/qjsonarray.h2
-rw-r--r--src/corelib/serialization/qjsoncbor.cpp954
-rw-r--r--src/corelib/serialization/qjsonobject.cpp11
-rw-r--r--src/corelib/serialization/qjsonobject.h2
-rw-r--r--src/corelib/serialization/qjsonvalue.cpp52
-rw-r--r--src/corelib/serialization/qjsonvalue.h3
-rw-r--r--src/corelib/serialization/qtextstream.cpp15
-rw-r--r--src/corelib/serialization/qtextstream.h1
-rw-r--r--src/corelib/serialization/serialization.pri16
-rw-r--r--src/corelib/statemachine/qhistorystate.cpp21
-rw-r--r--src/corelib/statemachine/qhistorystate_p.h17
-rw-r--r--src/corelib/thread/qfuture.h1
-rw-r--r--src/corelib/thread/qfutureinterface.h2
-rw-r--r--src/corelib/thread/qmutex.cpp4
-rw-r--r--src/corelib/thread/qmutex.h6
-rw-r--r--src/corelib/thread/qmutex_linux.cpp5
-rw-r--r--src/corelib/thread/qmutex_mac.cpp5
-rw-r--r--src/corelib/thread/qmutex_p.h3
-rw-r--r--src/corelib/thread/qmutex_unix.cpp6
-rw-r--r--src/corelib/thread/qmutexpool.cpp4
-rw-r--r--src/corelib/thread/qmutexpool_p.h4
-rw-r--r--src/corelib/thread/qreadwritelock.cpp3
-rw-r--r--src/corelib/thread/qreadwritelock.h6
-rw-r--r--src/corelib/thread/qreadwritelock_p.h6
-rw-r--r--src/corelib/thread/qsemaphore.cpp10
-rw-r--r--src/corelib/thread/qsemaphore.h7
-rw-r--r--src/corelib/thread/qthread.cpp130
-rw-r--r--src/corelib/thread/qthread.h24
-rw-r--r--src/corelib/thread/qthread_p.h26
-rw-r--r--src/corelib/thread/qthread_unix.cpp20
-rw-r--r--src/corelib/thread/qthread_win.cpp74
-rw-r--r--src/corelib/thread/qthreadpool.cpp4
-rw-r--r--src/corelib/thread/qthreadpool.h4
-rw-r--r--src/corelib/thread/qthreadpool_p.h3
-rw-r--r--src/corelib/thread/qthreadstorage.cpp3
-rw-r--r--src/corelib/thread/qthreadstorage.h79
-rw-r--r--src/corelib/thread/qwaitcondition.h9
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp57
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp20
-rw-r--r--src/corelib/thread/thread.pri110
-rw-r--r--src/corelib/tools/qalgorithms.qdoc1
-rw-r--r--src/corelib/tools/qarraydata.h2
-rw-r--r--src/corelib/tools/qbytearray.cpp295
-rw-r--r--src/corelib/tools/qbytearray.h17
-rw-r--r--src/corelib/tools/qcollator.cpp15
-rw-r--r--src/corelib/tools/qcollator_icu.cpp4
-rw-r--r--src/corelib/tools/qcollator_p.h37
-rw-r--r--src/corelib/tools/qcontiguouscache.h2
-rw-r--r--src/corelib/tools/qcryptographichash.cpp40
-rw-r--r--src/corelib/tools/qcryptographichash.h1
-rw-r--r--src/corelib/tools/qdatetime.cpp72
-rw-r--r--src/corelib/tools/qeasingcurve.cpp2
-rw-r--r--src/corelib/tools/qhash.cpp5
-rw-r--r--src/corelib/tools/qhash.h2
-rw-r--r--src/corelib/tools/qhashfunctions.h5
-rw-r--r--src/corelib/tools/qlinkedlist.h2
-rw-r--r--src/corelib/tools/qlist.h2
-rw-r--r--src/corelib/tools/qlocale.cpp121
-rw-r--r--src/corelib/tools/qlocale.h29
-rw-r--r--src/corelib/tools/qlocale.qdoc7
-rw-r--r--src/corelib/tools/qlocale_data_p.h11235
-rw-r--r--src/corelib/tools/qlocale_p.h1
-rw-r--r--src/corelib/tools/qlocale_tools.cpp28
-rw-r--r--src/corelib/tools/qlocale_tools_p.h13
-rw-r--r--src/corelib/tools/qlocale_win.cpp17
-rw-r--r--src/corelib/tools/qmakearray_p.h179
-rw-r--r--src/corelib/tools/qmap.h2
-rw-r--r--src/corelib/tools/qregexp.cpp56
-rw-r--r--src/corelib/tools/qregularexpression.cpp256
-rw-r--r--src/corelib/tools/qregularexpression.h11
-rw-r--r--src/corelib/tools/qringbuffer.cpp8
-rw-r--r--src/corelib/tools/qscopeguard.h96
-rw-r--r--src/corelib/tools/qscopeguard.qdoc55
-rw-r--r--src/corelib/tools/qset.h2
-rw-r--r--src/corelib/tools/qshareddata.h25
-rw-r--r--src/corelib/tools/qsimd.cpp271
-rw-r--r--src/corelib/tools/qsimd_p.h208
-rw-r--r--src/corelib/tools/qsimd_x86.cpp116
-rw-r--r--src/corelib/tools/qsimd_x86_p.h222
-rw-r--r--src/corelib/tools/qstring.cpp605
-rw-r--r--src/corelib/tools/qstring.h13
-rw-r--r--src/corelib/tools/qstringalgorithms.h1
-rw-r--r--src/corelib/tools/qstringlist.cpp25
-rw-r--r--src/corelib/tools/qstringlist.h13
-rw-r--r--src/corelib/tools/qstringliteral.h18
-rw-r--r--src/corelib/tools/qstringview.cpp14
-rw-r--r--src/corelib/tools/qstringview.h3
-rw-r--r--src/corelib/tools/qt_attribution.json5
-rw-r--r--src/corelib/tools/qtimezone.cpp14
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp47
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h3
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp118
-rw-r--r--src/corelib/tools/qtimezoneprivate_win.cpp25
-rw-r--r--src/corelib/tools/qunicodetables_p.h6
-rw-r--r--src/corelib/tools/tools.pri22
-rw-r--r--src/dbus/qdbus_symbols.cpp8
-rw-r--r--src/dbus/qdbus_symbols_p.h57
-rw-r--r--src/dbus/qdbusmessage.cpp44
-rw-r--r--src/dbus/qdbusmessage.h3
-rw-r--r--src/dbus/qdbusmessage_p.h1
-rw-r--r--src/dbus/qdbusmetaobject.cpp2
-rw-r--r--src/gui/accessible/qaccessible.cpp26
-rw-r--r--src/gui/accessible/qaccessiblecache.cpp14
-rw-r--r--src/gui/accessible/qaccessiblecache_p.h1
-rw-r--r--src/gui/configure.json153
-rw-r--r--src/gui/configure.pri3
-rw-r--r--src/gui/doc/qtgui.qdocconf3
-rw-r--r--src/gui/image/image.pri5
-rw-r--r--src/gui/image/qbitmap.cpp52
-rw-r--r--src/gui/image/qbitmap.h1
-rw-r--r--src/gui/image/qicon.cpp33
-rw-r--r--src/gui/image/qicon.h3
-rw-r--r--src/gui/image/qiconloader.cpp20
-rw-r--r--src/gui/image/qiconloader_p.h3
-rw-r--r--src/gui/image/qimage.cpp292
-rw-r--r--src/gui/image/qimage.h7
-rw-r--r--src/gui/image/qimage_avx2.cpp67
-rw-r--r--src/gui/image/qimage_conversions.cpp813
-rw-r--r--src/gui/image/qimage_p.h11
-rw-r--r--src/gui/image/qimage_sse2.cpp125
-rw-r--r--src/gui/image/qimage_sse4.cpp76
-rw-r--r--src/gui/image/qimagereader.cpp117
-rw-r--r--src/gui/image/qimagereader.h1
-rw-r--r--src/gui/image/qimagereaderwriterhelpers.cpp180
-rw-r--r--src/gui/image/qimagereaderwriterhelpers_p.h139
-rw-r--r--src/gui/image/qimagewriter.cpp123
-rw-r--r--src/gui/image/qimagewriter.h1
-rw-r--r--src/gui/image/qpixmap.cpp10
-rw-r--r--src/gui/image/qpixmap_blitter.cpp8
-rw-r--r--src/gui/image/qpixmap_raster.cpp11
-rw-r--r--src/gui/image/qpixmap_win.cpp422
-rw-r--r--src/gui/image/qpixmapcache.cpp25
-rw-r--r--src/gui/image/qpnghandler.cpp154
-rw-r--r--src/gui/image/qxbmhandler.cpp2
-rw-r--r--src/gui/image/qxpmhandler.cpp4
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.cpp45
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.h3
-rw-r--r--src/gui/kernel/kernel.pri7
-rw-r--r--src/gui/kernel/qdnd_p.h4
-rw-r--r--src/gui/kernel/qevent.cpp58
-rw-r--r--src/gui/kernel/qevent.h13
-rw-r--r--src/gui/kernel/qguiapplication.cpp132
-rw-r--r--src/gui/kernel/qguiapplication_p.h11
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp3
-rw-r--r--src/gui/kernel/qkeysequence.cpp5
-rw-r--r--src/gui/kernel/qopenglcontext.cpp100
-rw-r--r--src/gui/kernel/qopenglwindow.cpp6
-rw-r--r--src/gui/kernel/qpalette.cpp43
-rw-r--r--src/gui/kernel/qpalette.h4
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp37
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h23
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.cpp41
-rw-r--r--src/gui/kernel/qplatformintegration.cpp4
-rw-r--r--src/gui/kernel/qplatformmenu.h1
-rw-r--r--src/gui/kernel/qplatformscreen.cpp2
-rw-r--r--src/gui/kernel/qplatformsurface.cpp25
-rw-r--r--src/gui/kernel/qplatformsurface.h9
-rw-r--r--src/gui/kernel/qplatformwindow.cpp84
-rw-r--r--src/gui/kernel/qplatformwindow.h5
-rw-r--r--src/gui/kernel/qplatformwindow_p.h2
-rw-r--r--src/gui/kernel/qshortcutmap.cpp13
-rw-r--r--src/gui/kernel/qsimpledrag.cpp132
-rw-r--r--src/gui/kernel/qsimpledrag_p.h32
-rw-r--r--src/gui/kernel/qsurface.cpp4
-rw-r--r--src/gui/kernel/qsurface.h6
-rw-r--r--src/gui/kernel/qtestsupport_gui.cpp83
-rw-r--r--src/gui/kernel/qtestsupport_gui.h56
-rw-r--r--src/gui/kernel/qwindow.cpp41
-rw-r--r--src/gui/kernel/qwindow_p.h6
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp42
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h18
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h2
-rw-r--r--src/gui/math3d/qvector2d.cpp67
-rw-r--r--src/gui/math3d/qvector2d.h74
-rw-r--r--src/gui/math3d/qvector3d.cpp97
-rw-r--r--src/gui/math3d/qvector3d.h94
-rw-r--r--src/gui/math3d/qvector4d.cpp124
-rw-r--r--src/gui/math3d/qvector4d.h112
-rw-r--r--src/gui/opengl/opengl.pri2
-rw-r--r--src/gui/opengl/qopengl.h2
-rw-r--r--src/gui/opengl/qopenglbuffer.cpp13
-rw-r--r--src/gui/opengl/qopengldebug.cpp4
-rw-r--r--src/gui/opengl/qopenglengineshadermanager.cpp63
-rw-r--r--src/gui/opengl/qopenglengineshadermanager_p.h4
-rw-r--r--src/gui/opengl/qopenglengineshadersource_p.h173
-rw-r--r--src/gui/opengl/qopenglextensions_p.h3
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp86
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp43
-rw-r--r--src/gui/opengl/qopenglfunctions.h3
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp102
-rw-r--r--src/gui/opengl/qopenglprogrambinarycache.cpp18
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp11
-rw-r--r--src/gui/opengl/qopengltexturecache.cpp199
-rw-r--r--src/gui/opengl/qopengltexturecache_p.h24
-rw-r--r--src/gui/opengl/qopengltextureuploader.cpp328
-rw-r--r--src/gui/opengl/qopengltextureuploader_p.h84
-rw-r--r--src/gui/painting/WEBGRADIENTS_LICENSE.txt21
-rw-r--r--src/gui/painting/painting.pri9
-rw-r--r--src/gui/painting/qblendfunctions.cpp16
-rw-r--r--src/gui/painting/qbrush.cpp88
-rw-r--r--src/gui/painting/qbrush.h176
-rw-r--r--src/gui/painting/qcolor.cpp5
-rw-r--r--src/gui/painting/qcompositionfunctions.cpp1094
-rw-r--r--src/gui/painting/qcosmeticstroker_p.h3
-rw-r--r--src/gui/painting/qdrawhelper.cpp3510
-rw-r--r--src/gui/painting/qdrawhelper_avx2.cpp69
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp22
-rw-r--r--src/gui/painting/qdrawhelper_p.h136
-rw-r--r--src/gui/painting/qdrawhelper_sse4.cpp266
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp59
-rw-r--r--src/gui/painting/qdrawingprimitive_sse2_p.h69
-rw-r--r--src/gui/painting/qemulationpaintengine.cpp27
-rw-r--r--src/gui/painting/qimagescale.cpp238
-rw-r--r--src/gui/painting/qmemrotate.cpp33
-rw-r--r--src/gui/painting/qmemrotate_p.h1
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp65
-rw-r--r--src/gui/painting/qpagedpaintdevice.h6
-rw-r--r--src/gui/painting/qpagedpaintdevice_p.h40
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp5
-rw-r--r--src/gui/painting/qpaintengineex.cpp2
-rw-r--r--src/gui/painting/qpainter.cpp71
-rw-r--r--src/gui/painting/qpainter.h18
-rw-r--r--src/gui/painting/qpdf.cpp3
-rw-r--r--src/gui/painting/qpdfwriter.cpp27
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp9
-rw-r--r--src/gui/painting/qplatformbackingstore.h2
-rw-r--r--src/gui/painting/qrgba64.h4
-rw-r--r--src/gui/painting/qrgba64_p.h39
-rw-r--r--src/gui/painting/qt_attribution.json14
-rw-r--r--src/gui/painting/webgradients.binaryjsonbin0 -> 50792 bytes
-rw-r--r--src/gui/painting/webgradients.css909
-rw-r--r--src/gui/qtgui.tracepoints18
-rw-r--r--src/gui/text/qcssparser.cpp7
-rw-r--r--src/gui/text/qfont.cpp13
-rw-r--r--src/gui/text/qfontdatabase.cpp9
-rw-r--r--src/gui/text/qfontengine.cpp2
-rw-r--r--src/gui/text/qstatictext.cpp9
-rw-r--r--src/gui/text/qtextdocument.cpp52
-rw-r--r--src/gui/text/qtextdocument.h4
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp40
-rw-r--r--src/gui/text/qtextdocumentfragment_p.h1
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp42
-rw-r--r--src/gui/text/qtextengine.cpp93
-rw-r--r--src/gui/text/qtextengine_p.h8
-rw-r--r--src/gui/text/qtextformat.cpp57
-rw-r--r--src/gui/text/qtextformat.h14
-rw-r--r--src/gui/text/qtexthtmlparser.cpp7
-rw-r--r--src/gui/text/qtextlayout.cpp28
-rw-r--r--src/gui/text/qtextodfwriter.cpp261
-rw-r--r--src/gui/text/qtextodfwriter_p.h18
-rw-r--r--src/gui/text/qtextoption.cpp3
-rw-r--r--src/gui/text/qzip.cpp23
-rw-r--r--src/gui/util/qdesktopservices.cpp22
-rw-r--r--src/gui/util/qktxhandler.cpp199
-rw-r--r--src/gui/util/qktxhandler_p.h78
-rw-r--r--src/gui/util/qpkmhandler.cpp126
-rw-r--r--src/gui/util/qpkmhandler_p.h70
-rw-r--r--src/gui/util/qshadergraphloader.cpp15
-rw-r--r--src/gui/util/qshadernodesloader.cpp8
-rw-r--r--src/gui/util/qshadernodesloader_p.h1
-rw-r--r--src/gui/util/qtexturefiledata.cpp280
-rw-r--r--src/gui/util/qtexturefiledata_p.h115
-rw-r--r--src/gui/util/qtexturefilehandler_p.h79
-rw-r--r--src/gui/util/qtexturefilereader.cpp102
-rw-r--r--src/gui/util/qtexturefilereader_p.h88
-rw-r--r--src/gui/util/qvalidator.cpp38
-rw-r--r--src/gui/util/util.pri13
-rw-r--r--src/gui/vulkan/qvulkanwindow.cpp11
-rw-r--r--src/network/access/access.pri7
-rw-r--r--src/network/access/http2/http2protocol.cpp3
-rw-r--r--src/network/access/qhsts.cpp5
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp15
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp2
-rw-r--r--src/network/access/qhttpnetworkheader.cpp6
-rw-r--r--src/network/access/qhttpnetworkreply.cpp5
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend.cpp4
-rw-r--r--src/network/access/qnetworkaccessdebugpipebackend_p.h1
-rw-r--r--src/network/access/qnetworkaccessfilebackend.cpp6
-rw-r--r--src/network/access/qnetworkaccessfilebackend_p.h2
-rw-r--r--src/network/access/qnetworkaccessftpbackend.cpp61
-rw-r--r--src/network/access/qnetworkaccessftpbackend_p.h5
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp15
-rw-r--r--src/network/access/qnetworkaccessmanager.h3
-rw-r--r--src/network/access/qnetworkdiskcache.cpp6
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp4
-rw-r--r--src/network/access/qnetworkreplywasmimpl.cpp640
-rw-r--r--src/network/access/qnetworkreplywasmimpl_p.h153
-rw-r--r--src/network/access/qnetworkrequest.cpp134
-rw-r--r--src/network/access/qnetworkrequest.h6
-rw-r--r--src/network/configure.json28
-rw-r--r--src/network/configure.pri2
-rw-r--r--src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp14
-rw-r--r--src/network/doc/snippets/code/src_network_ssl_qdtls.cpp138
-rw-r--r--src/network/doc/snippets/code/src_network_ssl_qdtlscookie.cpp125
-rw-r--r--src/network/doc/src/ssl.qdoc9
-rw-r--r--src/network/kernel/qauthenticator.cpp8
-rw-r--r--src/network/kernel/qhostinfo_win.cpp8
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp21
-rw-r--r--src/network/kernel/qnetworkproxy_win.cpp15
-rw-r--r--src/network/socket/qabstractsocket.cpp5
-rw-r--r--src/network/socket/qhttpsocketengine.cpp5
-rw-r--r--src/network/socket/qlocalserver_win.cpp10
-rw-r--r--src/network/socket/qlocalsocket.cpp2
-rw-r--r--src/network/socket/qlocalsocket_win.cpp6
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp7
-rw-r--r--src/network/ssl/qasn1element_p.h54
-rw-r--r--src/network/ssl/qdtls.cpp1163
-rw-r--r--src/network/ssl/qdtls.h186
-rw-r--r--src/network/ssl/qdtls_openssl.cpp1462
-rw-r--r--src/network/ssl/qdtls_openssl_p.h213
-rw-r--r--src/network/ssl/qdtls_p.h155
-rw-r--r--src/network/ssl/qpassworddigestor.cpp187
-rw-r--r--src/network/ssl/qpassworddigestor.h60
-rw-r--r--src/network/ssl/qssl.cpp4
-rw-r--r--src/network/ssl/qssl.h7
-rw-r--r--src/network/ssl/qsslcertificate.cpp70
-rw-r--r--src/network/ssl/qsslcertificate.h11
-rw-r--r--src/network/ssl/qsslcertificate_openssl.cpp15
-rw-r--r--src/network/ssl/qsslcertificate_p.h4
-rw-r--r--src/network/ssl/qsslcertificate_qt.cpp6
-rw-r--r--src/network/ssl/qsslcertificate_winrt.cpp5
-rw-r--r--src/network/ssl/qsslcertificateextension.h5
-rw-r--r--src/network/ssl/qsslconfiguration.cpp62
-rw-r--r--src/network/ssl/qsslconfiguration.h15
-rw-r--r--src/network/ssl/qsslconfiguration_p.h9
-rw-r--r--src/network/ssl/qsslcontext_openssl.cpp15
-rw-r--r--src/network/ssl/qsslcontext_openssl11.cpp86
-rw-r--r--src/network/ssl/qsslcontext_opensslpre11.cpp56
-rw-r--r--src/network/ssl/qssldiffiehellmanparameters_openssl.cpp4
-rw-r--r--src/network/ssl/qsslkey_openssl.cpp46
-rw-r--r--src/network/ssl/qsslkey_p.cpp97
-rw-r--r--src/network/ssl/qsslkey_p.h11
-rw-r--r--src/network/ssl/qsslkey_qt.cpp410
-rw-r--r--src/network/ssl/qsslpresharedkeyauthenticator.h1
-rw-r--r--src/network/ssl/qsslsocket.cpp95
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp193
-rw-r--r--src/network/ssl/qsslsocket_mac_p.h7
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp267
-rw-r--r--src/network/ssl/qsslsocket_openssl11.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl11_symbols_p.h39
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h19
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp326
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h38
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11_symbols_p.h15
-rw-r--r--src/network/ssl/qwindowscarootfetcher.cpp168
-rw-r--r--src/network/ssl/qwindowscarootfetcher_p.h79
-rw-r--r--src/network/ssl/ssl.pri66
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp3
-rw-r--r--src/opengl/qgl.cpp32
-rw-r--r--src/opengl/qgl_p.h2
-rw-r--r--src/opengl/qglframebufferobject.cpp22
-rw-r--r--src/opengl/qglpaintdevice.cpp1
-rw-r--r--src/platformheaders/cocoafunctions/qcocoawindowfunctions.qdoc2
-rw-r--r--src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h60
-rw-r--r--src/platformheaders/xcbfunctions/qxcbwindowfunctions.h21
-rw-r--r--src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc75
-rw-r--r--src/platformheaders/xcbfunctions/xcbfunctions.pri1
-rw-r--r--src/platformsupport/clipboard/qmacmime.mm12
-rw-r--r--src/platformsupport/edid/qedidparser.cpp21
-rw-r--r--src/platformsupport/edid/qedidvendortable_p.h4296
-rw-r--r--src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp2
-rw-r--r--src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h3
-rw-r--r--src/platformsupport/eventdispatchers/qunixeventdispatcher.cpp5
-rw-r--r--src/platformsupport/eventdispatchers/qunixeventdispatcher_qpa_p.h3
-rw-r--r--src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp28
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp9
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm46
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm35
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp39
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp2
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h8
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp7
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h5
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp5
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h3
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice.cpp159
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice_p.h35
-rw-r--r--src/platformsupport/services/genericunix/qgenericunixservices.cpp59
-rw-r--r--src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp26
-rw-r--r--src/platformsupport/vkconvenience/qbasicvulkanplatforminstance_p.h6
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.mm38
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp6
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp30
-rw-r--r--src/plugins/platforms/android/androidjniinput.h4
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp368
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h41
-rw-r--r--src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp16
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.h2
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro16
-rw-r--r--src/plugins/platforms/cocoa/main.mm2
-rw-r--r--src/plugins/platforms/cocoa/messages.cpp18
-rw-r--r--src/plugins/platforms/cocoa/messages.h10
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm86
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h26
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm95
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm179
-rw-r--r--src/plugins/platforms/cocoa/qcocoaclipboard.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm31
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm20
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm132
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm66
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm62
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h28
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm585
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h57
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm122
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h11
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm59
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintrospection.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoakeymapper.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm80
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h7
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm130
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm202
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h36
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm158
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm48
-rw-r--r--src/plugins/platforms/cocoa/qcocoansmenu.h22
-rw-r--r--src/plugins/platforms/cocoa/qcocoansmenu.mm151
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintdevice.mm22
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.h14
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm272
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm78
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm90
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm89
-rw-r--r--src/plugins/platforms/cocoa/qcocoavulkaninstance.h75
-rw-r--r--src/plugins/platforms/cocoa/qcocoavulkaninstance.mm95
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h26
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm827
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.h4
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm14
-rw-r--r--src/plugins/platforms/cocoa/qmultitouch_mac.mm2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h96
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm1939
-rw-r--r--src/plugins/platforms/cocoa/qnsview_accessibility.mm90
-rw-r--r--src/plugins/platforms/cocoa/qnsview_complextext.mm315
-rw-r--r--src/plugins/platforms/cocoa/qnsview_dragging.mm300
-rw-r--r--src/plugins/platforms/cocoa/qnsview_drawing.mm167
-rw-r--r--src/plugins/platforms/cocoa/qnsview_gestures.mm169
-rw-r--r--src/plugins/platforms/cocoa/qnsview_keys.mm262
-rw-r--r--src/plugins/platforms/cocoa/qnsview_menus.mm133
-rw-r--r--src/plugins/platforms/cocoa/qnsview_mouse.mm624
-rw-r--r--src/plugins/platforms/cocoa/qnsview_tablet.mm223
-rw-r--r--src/plugins/platforms/cocoa/qnsview_touch.mm100
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm93
-rw-r--r--src/plugins/platforms/cocoa/qnswindow.h1
-rw-r--r--src/plugins/platforms/cocoa/qnswindow.mm72
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h14
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm41
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm56
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac_p.h8
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm10
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac_p.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp6
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp4
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h4
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h10
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp4
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h4
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp6
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp8
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp2
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfshooks.cpp2
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsintegration.cpp3
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp115
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp5
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h6
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm14
-rw-r--r--src/plugins/platforms/ios/qiosclipboard.mm24
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm39
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm15
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm8
-rw-r--r--src/plugins/platforms/ios/qiosmenu.mm32
-rw-r--r--src/plugins/platforms/ios/qiosoptionalplugininterface.h4
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm35
-rw-r--r--src/plugins/platforms/ios/qiostextinputoverlay.mm85
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.h10
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm56
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.h2
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm36
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm6
-rw-r--r--src/plugins/platforms/ios/quiaccessibilityelement.h7
-rw-r--r--src/plugins/platforms/ios/quiaccessibilityelement.mm13
-rw-r--r--src/plugins/platforms/ios/quiview.h15
-rw-r--r--src/plugins/platforms/ios/quiview.mm117
-rw-r--r--src/plugins/platforms/ios/quiview_accessibility.mm7
-rw-r--r--src/plugins/platforms/platforms.pro2
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxglobal.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp70
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h22
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp45
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp156
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.h26
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp23
-rw-r--r--src/plugins/platforms/wasm/main.cpp54
-rw-r--r--src/plugins/platforms/wasm/qtloader.js516
-rw-r--r--src/plugins/platforms/wasm/qtlogo.svg67
-rw-r--r--src/plugins/platforms/wasm/qwasmbackingstore.cpp165
-rw-r--r--src/plugins/platforms/wasm/qwasmbackingstore.h70
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.cpp721
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.h169
-rw-r--r--src/plugins/platforms/wasm/qwasmcursor.cpp131
-rw-r--r--src/plugins/platforms/wasm/qwasmcursor.h43
-rw-r--r--src/plugins/platforms/wasm/qwasmeventdispatcher.cpp181
-rw-r--r--src/plugins/platforms/wasm/qwasmeventdispatcher.h64
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.cpp522
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.h210
-rw-r--r--src/plugins/platforms/wasm/qwasmfontdatabase.cpp86
-rw-r--r--src/plugins/platforms/wasm/qwasmfontdatabase.h49
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp219
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.h92
-rw-r--r--src/plugins/platforms/wasm/qwasmopenglcontext.cpp147
-rw-r--r--src/plugins/platforms/wasm/qwasmopenglcontext.h63
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp118
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.h82
-rw-r--r--src/plugins/platforms/wasm/qwasmstylepixmaps_p.h183
-rw-r--r--src/plugins/platforms/wasm/qwasmtheme.cpp50
-rw-r--r--src/plugins/platforms/wasm/qwasmtheme.h56
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.cpp398
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.h124
-rw-r--r--src/plugins/platforms/wasm/wasm.json3
-rw-r--r--src/plugins/platforms/wasm/wasm.pro65
-rw-r--r--src/plugins/platforms/wasm/wasm_shell.html61
-rw-r--r--src/plugins/platforms/windows/main.cpp2
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json12
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h26
-rw-r--r--src/plugins/platforms/windows/qwin10helpers.cpp4
-rw-r--r--src/plugins/platforms/windows/qwin10helpers.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.h3
-rw-r--r--src/plugins/platforms/windows/qwindowscombase.h4
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp176
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h40
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp33
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h14
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp59
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp73
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsdropdataobject.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsdropdataobject.h2
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp16
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsgdiintegration.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsgdiintegration.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp18
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h14
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.h7
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp38
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h11
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.h2
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp145
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.h10
-rw-r--r--src/plugins/platforms/windows/qwindowsmenu.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp90
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp175
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp21
-rw-r--r--src/plugins/platforms/windows/qwindowsole.h10
-rw-r--r--src/plugins/platforms/windows/qwindowsopenglcontext.h14
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp84
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h8
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp641
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.h82
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp34
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsservices.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsservices.h4
-rw-r--r--src/plugins/platforms/windows/qwindowssystemtrayicon.h2
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp35
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h35
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp36
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h7
-rw-r--r--src/plugins/platforms/windows/qwindowsthreadpoolrunner.h14
-rw-r--r--src/plugins/platforms/windows/qwindowsvulkaninstance.cpp33
-rw-r--r--src/plugins/platforms/windows/qwindowsvulkaninstance.h7
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp195
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h21
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp17
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.h8
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.cpp12
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h12
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.cpp15
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h16
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h12
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h8
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp17
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h42
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp26
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.h15
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h20
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h16
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp15
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h12
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h10
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h12
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h24
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp31
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h43
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h10
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp8
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiautils.h16
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.cpp13
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h12
-rw-r--r--src/plugins/platforms/windows/windows.pri4
-rw-r--r--src/plugins/platforms/winrt/main.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp17
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.h5
-rw-r--r--src/plugins/platforms/winrt/qwinrtcanvas.cpp142
-rw-r--r--src/plugins/platforms/winrt/qwinrtcanvas.h75
-rw-r--r--src/plugins/platforms/winrt/qwinrtclipboard.cpp5
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp65
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.h3
-rw-r--r--src/plugins/platforms/winrt/qwinrtdrag.cpp27
-rw-r--r--src/plugins/platforms/winrt/qwinrtdrag.h4
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrteventdispatcher.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp30
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp25
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.h4
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp6
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp17
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h5
-rw-r--r--src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp11
-rw-r--r--src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp136
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h11
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp10
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h2
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.cpp113
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.h64
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.cpp76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.h72
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.cpp182
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.h117
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaemptypropertyvalue.h108
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp160
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.h78
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp135
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.h76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.cpp88
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.h74
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp789
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h125
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.cpp112
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.h76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.cpp149
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.h80
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.cpp99
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.h77
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.cpp167
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.h80
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp214
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.h78
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp158
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.h76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp141
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.h75
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp167
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.h76
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp232
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.h83
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp497
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.h95
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.cpp104
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.h75
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.cpp182
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.h83
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp136
-rw-r--r--src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.h77
-rw-r--r--src/plugins/platforms/winrt/uiautomation/uiautomation.pri45
-rw-r--r--src/plugins/platforms/winrt/winrt.pro4
-rw-r--r--src/plugins/platforms/xcb/README27
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp207
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.h31
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp122
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp599
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h102
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp599
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp334
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h15
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp51
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp868
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbmain.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp62
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h11
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp22
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp41
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbvulkaninstance.cpp29
-rw-r--r--src/plugins/platforms/xcb/qxcbvulkaninstance.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp384
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h23
-rw-r--r--src/plugins/platforms/xcb/xcb-static/xcb-static.pro5
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro8
-rw-r--r--src/plugins/platformthemes/flatpak/flatpak.json3
-rw-r--r--src/plugins/platformthemes/flatpak/flatpak.pro17
-rw-r--r--src/plugins/platformthemes/flatpak/main.cpp65
-rw-r--r--src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp355
-rw-r--r--src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h106
-rw-r--r--src/plugins/platformthemes/flatpak/qflatpaktheme.cpp196
-rw-r--r--src/plugins/platformthemes/flatpak/qflatpaktheme.h90
-rw-r--r--src/plugins/platformthemes/platformthemes.pro2
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/main.cpp67
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp407
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h106
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp200
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h90
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/xdgdesktopportal.json3
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/xdgdesktopportal.pro17
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine.cpp13
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine_p.h1
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport.cpp78
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.cpp80
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.h2
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintdevice.cpp149
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintdevice.h51
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintersupport.h3
-rw-r--r--src/plugins/sqldrivers/configure.json2
-rw-r--r--src/plugins/sqldrivers/configure.pri14
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql.cpp12
-rw-r--r--src/plugins/sqldrivers/odbc/qsql_odbc.cpp11
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp7
-rw-r--r--src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp44
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm136
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle.cpp32
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle_p.h43
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle.cpp16
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle_p.h42
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_mac.mm11
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix.cpp69
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix_p.h11
-rw-r--r--src/printsupport/dialogs/qpagesetupwidget.ui3
-rw-r--r--src/printsupport/dialogs/qprintdialog_mac.mm19
-rw-r--r--src/printsupport/dialogs/qprintdialog_unix.cpp909
-rw-r--r--src/printsupport/dialogs/qprintpreviewdialog.cpp5
-rw-r--r--src/printsupport/dialogs/qprintpropertieswidget.ui106
-rw-r--r--src/printsupport/kernel/qcups.cpp20
-rw-r--r--src/printsupport/kernel/qcups_p.h5
-rw-r--r--src/printsupport/kernel/qplatformprintdevice.cpp21
-rw-r--r--src/printsupport/kernel/qplatformprintdevice.h14
-rw-r--r--src/printsupport/kernel/qprintengine_pdf.cpp10
-rw-r--r--src/printsupport/kernel/qprintengine_pdf_p.h1
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp57
-rw-r--r--src/printsupport/kernel/qprinter.cpp43
-rw-r--r--src/printsupport/kernel/qprinter_p.h4
-rw-r--r--src/sql/configure.json22
-rw-r--r--src/sql/kernel/qsqlquery.cpp4
-rw-r--r--src/sql/kernel/qtsqlglobal.h1
-rw-r--r--src/sql/kernel/qtsqlglobal_p.h1
-rw-r--r--src/sql/models/qsqlquerymodel.h3
-rw-r--r--src/sql/models/qsqlquerymodel_p.h4
-rw-r--r--src/sql/models/qsqlrelationaldelegate.h25
-rw-r--r--src/sql/models/qsqlrelationaltablemodel.h2
-rw-r--r--src/sql/models/qsqltablemodel.cpp4
-rw-r--r--src/sql/models/qsqltablemodel.h2
-rw-r--r--src/sql/models/qsqltablemodel_p.h4
-rw-r--r--src/sql/sql.pro2
-rw-r--r--src/testlib/doc/snippets/code/doc_src_qtestlib.cpp30
-rw-r--r--src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp20
-rw-r--r--src/testlib/doc/src/qttestlib-manual.qdoc12
-rw-r--r--src/testlib/qabstracttestlogger.cpp23
-rw-r--r--src/testlib/qabstracttestlogger_p.h8
-rw-r--r--src/testlib/qappletestlogger.cpp149
-rw-r--r--src/testlib/qappletestlogger_p.h95
-rw-r--r--src/testlib/qplaintestlogger.cpp18
-rw-r--r--src/testlib/qsignalspy.h8
-rw-r--r--src/testlib/qtaptestlogger.cpp254
-rw-r--r--src/testlib/qtaptestlogger_p.h85
-rw-r--r--src/testlib/qtest.h21
-rw-r--r--src/testlib/qtestcase.cpp73
-rw-r--r--src/testlib/qtestcase.h21
-rw-r--r--src/testlib/qtestcase.qdoc99
-rw-r--r--src/testlib/qtesteventloop.h5
-rw-r--r--src/testlib/qtestlog.cpp33
-rw-r--r--src/testlib/qtestlog_p.h6
-rw-r--r--src/testlib/qtestresult.cpp2
-rw-r--r--src/testlib/qtestsystem.h105
-rw-r--r--src/testlib/qxctestlogger.mm10
-rw-r--r--src/testlib/qxctestlogger_p.h2
-rw-r--r--src/testlib/testlib.pro9
-rw-r--r--src/tools/androiddeployqt/main.cpp66
-rw-r--r--src/tools/bootstrap/bootstrap.pro4
-rw-r--r--src/tools/moc/cbordevice.h96
-rw-r--r--src/tools/moc/generator.cpp183
-rw-r--r--src/tools/moc/generator.h6
-rw-r--r--src/tools/moc/moc.h7
-rw-r--r--src/tools/moc/moc.pri6
-rw-r--r--src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp2
-rw-r--r--src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp2
-rw-r--r--src/tools/rcc/main.cpp18
-rw-r--r--src/tools/rcc/rcc.cpp18
-rw-r--r--src/tools/rcc/rcc.h4
-rw-r--r--src/tools/tracegen/etw.cpp3
-rw-r--r--src/tools/tracegen/lttng.cpp4
-rw-r--r--src/tools/tracegen/provider.cpp39
-rw-r--r--src/tools/tracegen/provider.h2
-rw-r--r--src/tools/uic/cpp/cppwritedeclaration.cpp19
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp252
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.h12
-rw-r--r--src/tools/uic/customwidgetsinfo.cpp4
-rw-r--r--src/tools/uic/driver.cpp4
-rw-r--r--src/tools/uic/driver.h1
-rw-r--r--src/tools/uic/main.cpp6
-rw-r--r--src/tools/uic/option.h2
-rw-r--r--src/tools/uic/treewalker.h2
-rw-r--r--src/tools/uic/ui4.cpp755
-rw-r--r--src/tools/uic/uic.cpp4
-rw-r--r--src/tools/uic/uic.h1
-rw-r--r--src/tools/uic/utils.h26
-rw-r--r--src/widgets/accessible/complexwidgets.cpp11
-rw-r--r--src/widgets/accessible/complexwidgets_p.h2
-rw-r--r--src/widgets/accessible/itemviews.cpp10
-rw-r--r--src/widgets/accessible/qaccessiblemenu.cpp7
-rw-r--r--src/widgets/accessible/qaccessiblewidgets.cpp4
-rw-r--r--src/widgets/configure.json2
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp4
-rw-r--r--src/widgets/dialogs/qcolordialog.h5
-rw-r--r--src/widgets/dialogs/qdialog.cpp20
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp25
-rw-r--r--src/widgets/dialogs/qfiledialog.h2
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h14
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp35
-rw-r--r--src/widgets/dialogs/qfilesystemmodel_p.h6
-rw-r--r--src/widgets/dialogs/qinputdialog.cpp6
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp23
-rw-r--r--src/widgets/dialogs/qwizard_win.cpp6
-rw-r--r--src/widgets/dialogs/qwizard_win_p.h15
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout.h1
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp6
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout_p.h7
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsitem_p.h4
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp33
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.cpp98
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.h4
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp16
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.cpp25
-rw-r--r--src/widgets/itemviews/qheaderview.cpp16
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp68
-rw-r--r--src/widgets/itemviews/qlistview.cpp66
-rw-r--r--src/widgets/itemviews/qlistview.h4
-rw-r--r--src/widgets/itemviews/qlistview_p.h2
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp9
-rw-r--r--src/widgets/itemviews/qtableview.cpp55
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp36
-rw-r--r--src/widgets/itemviews/qtablewidget.h1
-rw-r--r--src/widgets/itemviews/qtablewidget_p.h5
-rw-r--r--src/widgets/itemviews/qtreeview.cpp57
-rw-r--r--src/widgets/itemviews/qtreeview_p.h2
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp56
-rw-r--r--src/widgets/itemviews/qtreewidget.h11
-rw-r--r--src/widgets/itemviews/qtreewidget_p.h7
-rw-r--r--src/widgets/kernel/kernel.pri6
-rw-r--r--src/widgets/kernel/qapplication.cpp85
-rw-r--r--src/widgets/kernel/qapplication_p.h2
-rw-r--r--src/widgets/kernel/qgesture.cpp4
-rw-r--r--src/widgets/kernel/qlayout.cpp27
-rw-r--r--src/widgets/kernel/qlayout.h1
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer_p.h18
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp13
-rw-r--r--src/widgets/kernel/qshortcut.cpp12
-rw-r--r--src/widgets/kernel/qtestsupport_widgets.cpp113
-rw-r--r--src/widgets/kernel/qtestsupport_widgets.h61
-rw-r--r--src/widgets/kernel/qtooltip.cpp54
-rw-r--r--src/widgets/kernel/qwhatsthis.cpp10
-rw-r--r--src/widgets/kernel/qwhatsthis.h4
-rw-r--r--src/widgets/kernel/qwidget.cpp128
-rw-r--r--src/widgets/kernel/qwidget.h1
-rw-r--r--src/widgets/kernel/qwidget_p.h4
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp89
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp116
-rw-r--r--src/widgets/kernel/qwidgetwindow_p.h3
-rw-r--r--src/widgets/qtwidgets.tracepoints4
-rw-r--r--src/widgets/styles/images/titlebar-contexthelp-16.pngbin0 -> 396 bytes
-rw-r--r--src/widgets/styles/images/titlebar-contexthelp-32.pngbin0 -> 661 bytes
-rw-r--r--src/widgets/styles/images/titlebar-contexthelp-48.pngbin0 -> 891 bytes
-rw-r--r--src/widgets/styles/images/titlebar-max-16.pngbin0 -> 158 bytes
-rw-r--r--src/widgets/styles/images/titlebar-max-32.pngbin0 -> 163 bytes
-rw-r--r--src/widgets/styles/images/titlebar-max-48.pngbin0 -> 167 bytes
-rw-r--r--src/widgets/styles/images/titlebar-min-16.pngbin0 -> 166 bytes
-rw-r--r--src/widgets/styles/images/titlebar-min-32.pngbin0 -> 171 bytes
-rw-r--r--src/widgets/styles/images/titlebar-min-48.pngbin0 -> 175 bytes
-rw-r--r--src/widgets/styles/images/titlebar-shade-16.pngbin0 -> 253 bytes
-rw-r--r--src/widgets/styles/images/titlebar-shade-32.pngbin0 -> 282 bytes
-rw-r--r--src/widgets/styles/images/titlebar-shade-48.pngbin0 -> 339 bytes
-rw-r--r--src/widgets/styles/images/titlebar-unshade-16.pngbin0 -> 244 bytes
-rw-r--r--src/widgets/styles/images/titlebar-unshade-32.pngbin0 -> 294 bytes
-rw-r--r--src/widgets/styles/images/titlebar-unshade-48.pngbin0 -> 336 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-16.pngbin0 -> 349 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-32.pngbin0 -> 568 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-8.pngbin0 -> 220 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-rtl-16.pngbin0 -> 128 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-rtl-32.pngbin0 -> 148 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-h-rtl-8.pngbin0 -> 114 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-macstyle.png (renamed from src/widgets/styles/images/toolbar-ext.png)bin516 -> 516 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-macstyle@2x.png (renamed from src/widgets/styles/images/toolbar-ext@2x.png)bin505 -> 505 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-v-10.pngbin0 -> 387 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-v-20.pngbin0 -> 625 bytes
-rw-r--r--src/widgets/styles/images/toolbar-ext-v-5.pngbin0 -> 223 bytes
-rw-r--r--src/widgets/styles/qcommonstyle.cpp140
-rw-r--r--src/widgets/styles/qstyle.cpp7
-rw-r--r--src/widgets/styles/qstyle.h1
-rw-r--r--src/widgets/styles/qstyle.qrc28
-rw-r--r--src/widgets/styles/qstylehelper.cpp8
-rw-r--r--src/widgets/styles/qstylehelper_p.h1
-rw-r--r--src/widgets/styles/qstyleoption.cpp8
-rw-r--r--src/widgets/styles/qstyleoption.h2
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp94
-rw-r--r--src/widgets/styles/qstylesheetstyle_p.h7
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp19
-rw-r--r--src/widgets/util/qcompleter.cpp46
-rw-r--r--src/widgets/util/qcompleter.h4
-rw-r--r--src/widgets/util/qscroller.cpp4
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp2
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp70
-rw-r--r--src/widgets/util/qundostack.cpp55
-rw-r--r--src/widgets/util/qundostack.h5
-rw-r--r--src/widgets/widgets.pro3
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp68
-rw-r--r--src/widgets/widgets/qabstractspinbox.h7
-rw-r--r--src/widgets/widgets/qabstractspinbox_p.h4
-rw-r--r--src/widgets/widgets/qcombobox.cpp5
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp12
-rw-r--r--src/widgets/widgets/qlabel.cpp30
-rw-r--r--src/widgets/widgets/qlineedit.cpp22
-rw-r--r--src/widgets/widgets/qlineedit.h1
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp11
-rw-r--r--src/widgets/widgets/qmainwindow.cpp4
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp56
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h12
-rw-r--r--src/widgets/widgets/qmdiarea.cpp4
-rw-r--r--src/widgets/widgets/qmenu.cpp2
-rw-r--r--src/widgets/widgets/qmenu.h8
-rw-r--r--src/widgets/widgets/qmenu_mac.mm3
-rw-r--r--src/widgets/widgets/qmenubar.h6
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp6
-rw-r--r--src/widgets/widgets/qspinbox.cpp128
-rw-r--r--src/widgets/widgets/qspinbox.h8
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp6
-rw-r--r--src/widgets/widgets/qsplitter.cpp17
-rw-r--r--src/widgets/widgets/qtabbar.cpp22
-rw-r--r--src/widgets/widgets/qtabbar_p.h17
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp7
-rw-r--r--src/widgets/widgets/qtextedit.cpp3
-rw-r--r--src/widgets/widgets/qtoolbarlayout_p.h2
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp10
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h1
-rw-r--r--src/widgets/widgets/qwidgetresizehandler.cpp1
-rw-r--r--src/winmain/qtmain_winrt.cpp73
-rw-r--r--src/xml/doc/src/xml-processing.qdoc4
-rw-r--r--tests/auto/auto.pro4
-rw-r--r--tests/auto/cmake/CMakeLists.txt1
-rw-r--r--tests/auto/cmake/test_add_big_resource/CMakeLists.txt13
-rw-r--r--tests/auto/cmake/test_add_big_resource/myobject.cpp44
-rw-r--r--tests/auto/cmake/test_add_big_resource/myobject.h44
-rw-r--r--tests/auto/cmake/test_add_big_resource/resource_file.txt1
-rw-r--r--tests/auto/cmake/test_add_big_resource/resource_file2.txt1
-rw-r--r--tests/auto/cmake/test_add_big_resource/test_add_big_resource.qrc6
-rw-r--r--tests/auto/cmake/test_add_big_resource/test_add_big_resource2.qrc6
-rw-r--r--tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp2
-rw-r--r--tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST1
-rw-r--r--tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST1
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/echo/echo.pro4
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro3
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/test.pro6
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/test/test.pro13
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp9
-rw-r--r--tests/auto/corelib/codecs/utf8/tst_utf8.cpp15
-rw-r--r--tests/auto/corelib/codecs/utf8/utf8data.cpp30
-rw-r--r--tests/auto/corelib/global/qflags/tst_qflags.cpp22
-rw-r--r--tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp6
-rw-r--r--tests/auto/corelib/global/qlogging/app/app.pro11
-rw-r--r--tests/auto/corelib/global/qlogging/test/test.pro16
-rw-r--r--tests/auto/corelib/global/qlogging/tst_qlogging.cpp27
-rw-r--r--tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp2
-rw-r--r--tests/auto/corelib/global/qtendian/tst_qtendian.cpp136
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp16
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp1
-rw-r--r--tests/auto/corelib/io/qfile/.gitignore8
-rw-r--r--tests/auto/corelib/io/qfile/qfile.pro3
-rw-r--r--tests/auto/corelib/io/qfile/stdinprocess/main.cpp2
-rw-r--r--tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro6
-rw-r--r--tests/auto/corelib/io/qfile/test.pro26
-rw-r--r--tests/auto/corelib/io/qfile/test/test.pro25
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp49
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp42
-rw-r--r--tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp7
-rw-r--r--tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp2
-rw-r--r--tests/auto/corelib/io/qresourceengine/qresourceengine.pro27
-rw-r--r--tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro33
-rw-r--r--tests/auto/corelib/io/qresourceengine/staticplugin/.gitignore1
-rw-r--r--tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp9
-rw-r--r--tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.json1
-rw-r--r--tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.pro8
-rw-r--r--tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp14
-rw-r--r--tests/auto/corelib/io/qsettings/qsettings.pro2
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp6
-rw-r--r--tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp2
-rw-r--r--tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp2
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp52
-rw-r--r--tests/auto/corelib/itemmodels/itemmodels.pro3
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/.gitignore1
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/qsortfilterproxymodel.pro9
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp4853
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp4950
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h189
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore1
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro16
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp59
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore1
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro16
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp59
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp4
-rw-r--r--tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h2
-rw-r--r--tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST1
-rw-r--r--tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST1
-rw-r--r--tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp13
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp42
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp2
-rw-r--r--tests/auto/corelib/kernel/qmetatype/qmetatype.pro2
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp247
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h18
-rw-r--r--tests/auto/corelib/kernel/qobject/.gitignore8
-rw-r--r--tests/auto/corelib/kernel/qobject/qobject.pro8
-rw-r--r--tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro7
-rw-r--r--tests/auto/corelib/kernel/qobject/test.pro10
-rw-r--r--tests/auto/corelib/kernel/qobject/test/test.pro10
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp32
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/producerconsumer/main.cpp (renamed from tests/auto/corelib/kernel/qsharedmemory/sharedmemoryhelper/main.cpp)0
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/producerconsumer/producerconsumer.pro5
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro4
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/sharedmemoryhelper/sharedmemoryhelper.pro17
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/test.pro8
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/test/test.pro18
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp839
-rw-r--r--tests/auto/corelib/kernel/qsharedmemory/tst_qsharedmemory.cpp821
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/acquirerelease.pro5
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/main.cpp (renamed from tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/main.cpp)0
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro2
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/systemsemaphorehelper.pro17
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/test.pro7
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/test/test.pro17
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp307
-rw-r--r--tests/auto/corelib/kernel/qsystemsemaphore/tst_qsystemsemaphore.cpp292
-rw-r--r--tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp29
-rw-r--r--tests/auto/corelib/kernel/qtranslator/android_testdata.qrc1
-rw-r--r--tests/auto/corelib/kernel/qtranslator/hellotr_empty.qm1
-rw-r--r--tests/auto/corelib/kernel/qtranslator/hellotr_empty.ts3
-rw-r--r--tests/auto/corelib/kernel/qtranslator/qtranslator.pro2
-rw-r--r--tests/auto/corelib/kernel/qtranslator/qtranslator.qrc1
-rw-r--r--tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp58
-rw-r--r--tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp21
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.foo3
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.xml21
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy2.foo3
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc3
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp7
-rw-r--r--tests/auto/corelib/plugin/plugin.pro3
-rw-r--r--tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp64
-rw-r--r--tests/auto/corelib/plugin/qplugin/tst_qplugin.pro2
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h2
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp39
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/utf8_data.json17
-rw-r--r--tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro11
-rw-r--r--tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp1091
-rw-r--r--tests/auto/corelib/serialization/qcborstreamwriter/qcborstreamwriter.pro8
-rw-r--r--tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp313
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro11
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp1692
-rw-r--r--tests/auto/corelib/serialization/qcborvalue_json/qcborvalue_json.pro7
-rw-r--r--tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp348
-rw-r--r--tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp22
-rw-r--r--tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp12
-rw-r--r--tests/auto/corelib/serialization/serialization.pro4
-rw-r--r--tests/auto/corelib/thread/qfuture/tst_qfuture.cpp4
-rw-r--r--tests/auto/corelib/thread/qsemaphore/BLACKLIST2
-rw-r--r--tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp3
-rw-r--r--tests/auto/corelib/thread/qthreadonce/qthreadonce.h4
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro10
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/test/test.pro17
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp22
-rw-r--r--tests/auto/corelib/thread/thread.pro39
-rw-r--r--tests/auto/corelib/tools/collections/tst_collections.cpp4
-rw-r--r--tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp129
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp24
-rw-r--r--tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp11
-rw-r--r--tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp5
-rw-r--r--tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp5
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp695
-rw-r--r--tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro1
-rw-r--r--tests/auto/corelib/tools/qmakearray/qmakearray.pro4
-rw-r--r--tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp103
-rw-r--r--tests/auto/corelib/tools/qregularexpression/alwaysoptimize/alwaysoptimize.pro7
-rw-r--r--tests/auto/corelib/tools/qregularexpression/alwaysoptimize/tst_qregularexpression_alwaysoptimize.cpp51
-rw-r--r--tests/auto/corelib/tools/qregularexpression/defaultoptimize/defaultoptimize.pro7
-rw-r--r--tests/auto/corelib/tools/qregularexpression/defaultoptimize/tst_qregularexpression_defaultoptimize.cpp39
-rw-r--r--tests/auto/corelib/tools/qregularexpression/forceoptimize/forceoptimize.pro8
-rw-r--r--tests/auto/corelib/tools/qregularexpression/forceoptimize/tst_qregularexpression_forceoptimize.cpp39
-rw-r--r--tests/auto/corelib/tools/qregularexpression/qregularexpression.pro7
-rw-r--r--tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp289
-rw-r--r--tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.h74
-rw-r--r--tests/auto/corelib/tools/qscopeguard/qscopeguard.pro4
-rw-r--r--tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp85
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/externaltests.cpp20
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp99
-rw-r--r--tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp9
-rw-r--r--tests/auto/corelib/tools/qstringview/tst_qstringview.cpp20
-rw-r--r--tests/auto/corelib/tools/qtimeline/BLACKLIST2
-rw-r--r--tests/auto/corelib/tools/qtimezone/qtimezone.pro2
-rw-r--r--tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp25
-rw-r--r--tests/auto/corelib/tools/tools.pro1
-rw-r--r--tests/auto/dbus/qdbusinterface/qdbusinterface/qdbusinterface.pro9
-rw-r--r--tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp10
-rw-r--r--tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp27
-rw-r--r--tests/auto/gui/gui.pro2
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_utf8_comment.jpgbin0 -> 705 bytes
-rw-r--r--tests/auto/gui/image/qimage/qimage.pro3
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp224
-rw-r--r--tests/auto/gui/image/qimagereader/images/basn0g16.pngbin0 -> 167 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/images/basn2c16.pngbin0 -> 302 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/images/basn4a16.pngbin0 -> 2206 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/images/basn6a16.pngbin0 -> 3435 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/images/kollada-16bpc.pngbin0 -> 24360 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/images/tbwn0g16.pngbin0 -> 1313 bytes
-rw-r--r--tests/auto/gui/image/qimagereader/qimagereader.pro3
-rw-r--r--tests/auto/gui/image/qimagereader/qimagereader.qrc69
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp9
-rw-r--r--tests/auto/gui/image/qpicture/qpicture.pro1
-rw-r--r--tests/auto/gui/image/qpicture/tst_qpicture.cpp38
-rw-r--r--tests/auto/gui/image/qpixmap/tst_qpixmap.cpp22
-rw-r--r--tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp3
-rw-r--r--tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp12
-rw-r--r--tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp26
-rw-r--r--tests/auto/gui/kernel/qguiapplication/BLACKLIST4
-rw-r--r--tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp6
-rw-r--r--tests/auto/gui/kernel/qpalette/tst_qpalette.cpp3
-rw-r--r--tests/auto/gui/kernel/qtouchevent/qtouchevent.pro1
-rw-r--r--tests/auto/gui/kernel/qwindow/BLACKLIST2
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp99
-rw-r--r--tests/auto/gui/painting/qbrush/tst_qbrush.cpp21
-rw-r--r--tests/auto/gui/painting/qcolor/tst_qcolor.cpp20
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp63
-rw-r--r--tests/auto/gui/qopengl/tst_qopengl.cpp79
-rw-r--r--tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp24
-rw-r--r--tests/auto/gui/text/qglyphrun/BLACKLIST3
-rw-r--r--tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp3
-rw-r--r--tests/auto/gui/text/qstatictext/tst_qstatictext.cpp62
-rw-r--r--tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp12
-rw-r--r--tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp7
-rw-r--r--tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp4
-rw-r--r--tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp8
-rw-r--r--tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp8
-rw-r--r--tests/auto/gui/util/qtexturefilereader/qtexturefilereader.pro5
-rw-r--r--tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc7
-rw-r--r--tests/auto/gui/util/qtexturefilereader/texturefiles/car.ktxbin0 -> 11908 bytes
-rw-r--r--tests/auto/gui/util/qtexturefilereader/texturefiles/car_mips.ktxbin0 -> 8088 bytes
-rw-r--r--tests/auto/gui/util/qtexturefilereader/texturefiles/pattern.pkmbin0 -> 2064 bytes
-rw-r--r--tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp111
-rw-r--r--tests/auto/gui/util/util.pro2
-rw-r--r--tests/auto/network-settings.h61
-rw-r--r--tests/auto/network/access/hpack/hpack.pro4
-rw-r--r--tests/auto/network/access/hsts/hsts.pro2
-rw-r--r--tests/auto/network/access/http2/http2.pro2
-rw-r--r--tests/auto/network/access/http2/http2srv.cpp32
-rw-r--r--tests/auto/network/access/http2/http2srv.h4
-rw-r--r--tests/auto/network/access/http2/tst_http2.cpp19
-rw-r--r--tests/auto/network/access/qnetworkreply/certs/qt-test-net-cacert.pem16
-rw-r--r--tests/auto/network/access/qnetworkreply/test/test.pro3
-rw-r--r--tests/auto/network/access/qnetworkreply/testserver_index.html3
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp557
-rw-r--r--tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp96
-rw-r--r--tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp4
-rw-r--r--tests/auto/network/ssl/qdtls/certs/bogus-ca.crt20
-rw-r--r--tests/auto/network/ssl/qdtls/certs/bogus-ca.key27
-rw-r--r--tests/auto/network/ssl/qdtls/certs/bogus-client.crt19
-rw-r--r--tests/auto/network/ssl/qdtls/certs/bogus-client.key27
-rw-r--r--tests/auto/network/ssl/qdtls/certs/bogus-server.crt19
-rw-r--r--tests/auto/network/ssl/qdtls/certs/bogus-server.key27
-rw-r--r--tests/auto/network/ssl/qdtls/certs/fake-login.live.com.key15
-rw-r--r--tests/auto/network/ssl/qdtls/certs/fake-login.live.com.pem19
-rw-r--r--tests/auto/network/ssl/qdtls/certs/fluke.cert75
-rw-r--r--tests/auto/network/ssl/qdtls/certs/fluke.key15
-rw-r--r--tests/auto/network/ssl/qdtls/certs/ss-srv-cert.pem18
-rw-r--r--tests/auto/network/ssl/qdtls/certs/ss-srv-key.pem18
-rw-r--r--tests/auto/network/ssl/qdtls/qdtls.pro16
-rw-r--r--tests/auto/network/ssl/qdtls/tst_qdtls.cpp1324
-rw-r--r--tests/auto/network/ssl/qdtlscookie/qdtlscookie.pro15
-rw-r--r--tests/auto/network/ssl/qdtlscookie/tst_qdtlscookie.cpp478
-rw-r--r--tests/auto/network/ssl/qpassworddigestor/qpassworddigestor.pro4
-rw-r--r--tests/auto/network/ssl/qpassworddigestor/tst_qpassworddigestor.cpp171
-rw-r--r--tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro1
-rw-r--r--tests/auto/network/ssl/qsslcipher/qsslcipher.pro1
-rw-r--r--tests/auto/network/ssl/qssldiffiehellmanparameters/qssldiffiehellmanparameters.pro1
-rw-r--r--tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro1
-rw-r--r--tests/auto/network/ssl/qsslerror/qsslerror.pro1
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-DES.derbin0 -> 243 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-DES.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-RC2-64.derbin0 -> 243 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-RC2-64.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-DES.derbin0 -> 243 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-DES.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-RC2-64.derbin0 -> 243 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-RC2-64.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA1.derbin0 -> 290 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA1.pem9
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA256.derbin0 -> 304 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA256.pem9
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA1.derbin0 -> 290 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA1.pem9
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA256.derbin0 -> 304 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA256.pem9
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA1.derbin0 -> 281 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA1.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA256.derbin0 -> 295 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA256.pem9
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.derbin0 -> 244 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.derbin0 -> 244 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.derbin0 -> 244 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.derbin0 -> 244 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem8
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.derbin0 -> 237 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.derbin0 -> 237 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA1.derbin0 -> 289 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA1.pem9
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA256.derbin0 -> 303 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA256.pem9
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8.derbin0 -> 201 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-DES.derbin0 -> 163 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-DES.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-RC2-64.derbin0 -> 163 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-RC2-64.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-DES.derbin0 -> 163 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-DES.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-RC2-64.derbin0 -> 163 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-RC2-64.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA1.derbin0 -> 209 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA1.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA256.derbin0 -> 223 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA256.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA1.derbin0 -> 209 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA1.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA256.derbin0 -> 223 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA256.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA1.derbin0 -> 200 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA1.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA256.derbin0 -> 214 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA256.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-2DES.derbin0 -> 164 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-2DES.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-3DES.derbin0 -> 164 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-3DES.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-128.derbin0 -> 164 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-40.derbin0 -> 164 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-128.derbin0 -> 157 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-40.derbin0 -> 157 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem6
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA1.derbin0 -> 208 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA1.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA256.derbin0 -> 222 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA256.pem7
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8.derbin0 -> 122 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8.pem5
-rwxr-xr-xtests/auto/network/ssl/qsslkey/keys/genkeys.sh55
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-DES.derbin0 -> 389 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-DES.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-RC2-64.derbin0 -> 389 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-RC2-64.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-DES.derbin0 -> 389 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-DES.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-RC2-64.derbin0 -> 389 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-RC2-64.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA1.derbin0 -> 435 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA1.pem12
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA256.derbin0 -> 449 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA256.pem12
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA1.derbin0 -> 435 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA1.pem12
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA256.derbin0 -> 449 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA256.pem12
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA1.derbin0 -> 426 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA1.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA256.derbin0 -> 440 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA256.pem12
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.derbin0 -> 390 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.derbin0 -> 390 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.derbin0 -> 390 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.derbin0 -> 390 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.derbin0 -> 384 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem10
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.derbin0 -> 384 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem10
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA1.derbin0 -> 426 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA1.pem11
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA256.derbin0 -> 440 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA256.pem12
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8.derbin0 -> 345 bytes
-rw-r--r--tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8.pem10
-rw-r--r--tests/auto/network/ssl/qsslkey/qsslkey.pro1
-rw-r--r--tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp52
-rw-r--r--tests/auto/network/ssl/qsslsocket/qsslsocket.pro1
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp97
-rw-r--r--tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro1
-rw-r--r--tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro1
-rw-r--r--tests/auto/network/ssl/ssl.pro11
-rw-r--r--tests/auto/opengl/qgl/BLACKLIST1
-rw-r--r--tests/auto/opengl/qglthreads/tst_qglthreads.cpp7
-rw-r--r--tests/auto/other/gestures/BLACKLIST12
-rw-r--r--tests/auto/other/lancelot/paintcommands.cpp49
-rw-r--r--tests/auto/other/lancelot/paintcommands.h2
-rw-r--r--tests/auto/other/lancelot/scripts/gradientxform_object.qps15
-rw-r--r--tests/auto/other/lancelot/scripts/image_dpr.qps43
-rw-r--r--tests/auto/other/macnativeevents/macnativeevents.pro2
-rw-r--r--tests/auto/other/other.pro6
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp4
-rw-r--r--tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm4
-rw-r--r--tests/auto/other/qfocusevent/BLACKLIST1
-rw-r--r--tests/auto/other/qfocusevent/tst_qfocusevent.cpp5
-rw-r--r--tests/auto/printsupport/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp3
-rw-r--r--tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp4
-rw-r--r--tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp20
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp55
-rw-r--r--tests/auto/sql/kernel/qsqlresult/qsqlresult.pro2
-rw-r--r--tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp2
-rw-r--r--tests/auto/sql/models/qsqlrelationaldelegate/qsqlrelationaldelegate.pro5
-rw-r--r--tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp170
-rw-r--r--tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp47
-rw-r--r--tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp62
-rw-r--r--tests/auto/testlib/selftests/expected_assert.tap16
-rw-r--r--tests/auto/testlib/selftests/expected_badxml.tap61
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibcounting.tap17
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibeventcounter.tap15
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibtickcounter.tap9
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibwalltime.tap11
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.lightxml36
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.tap456
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.teamcity16
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.txt20
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.xml36
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.xunitxml18
-rw-r--r--tests/auto/testlib/selftests/expected_commandlinedata.tap20
-rw-r--r--tests/auto/testlib/selftests/expected_counting.tap118
-rw-r--r--tests/auto/testlib/selftests/expected_crashes_4.txt7
-rw-r--r--tests/auto/testlib/selftests/expected_datatable.tap183
-rw-r--r--tests/auto/testlib/selftests/expected_datetime.tap46
-rw-r--r--tests/auto/testlib/selftests/expected_exceptionthrow.tap14
-rw-r--r--tests/auto/testlib/selftests/expected_expectfail.tap96
-rw-r--r--tests/auto/testlib/selftests/expected_failcleanup.tap20
-rw-r--r--tests/auto/testlib/selftests/expected_failinit.tap19
-rw-r--r--tests/auto/testlib/selftests/expected_failinitdata.tap18
-rw-r--r--tests/auto/testlib/selftests/expected_fetchbogus.tap15
-rw-r--r--tests/auto/testlib/selftests/expected_findtestdata.tap10
-rw-r--r--tests/auto/testlib/selftests/expected_float.tap82
-rw-r--r--tests/auto/testlib/selftests/expected_globaldata.tap52
-rw-r--r--tests/auto/testlib/selftests/expected_keyboard.lightxml18
-rw-r--r--tests/auto/testlib/selftests/expected_keyboard.tap9
-rw-r--r--tests/auto/testlib/selftests/expected_keyboard.teamcity8
-rw-r--r--tests/auto/testlib/selftests/expected_keyboard.txt7
-rw-r--r--tests/auto/testlib/selftests/expected_keyboard.xml21
-rw-r--r--tests/auto/testlib/selftests/expected_keyboard.xunitxml12
-rw-r--r--tests/auto/testlib/selftests/expected_longstring.tap23
-rw-r--r--tests/auto/testlib/selftests/expected_maxwarnings.tap2011
-rw-r--r--tests/auto/testlib/selftests/expected_pairdiagnostics.tap32
-rw-r--r--tests/auto/testlib/selftests/expected_singleskip.tap9
-rw-r--r--tests/auto/testlib/selftests/expected_skip.tap13
-rw-r--r--tests/auto/testlib/selftests/expected_skipcleanup.tap9
-rw-r--r--tests/auto/testlib/selftests/expected_skipinit.tap8
-rw-r--r--tests/auto/testlib/selftests/expected_skipinitdata.tap7
-rw-r--r--tests/auto/testlib/selftests/expected_sleep.tap9
-rw-r--r--tests/auto/testlib/selftests/expected_strcmp.tap87
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.tap68
-rw-r--r--tests/auto/testlib/selftests/expected_tuplediagnostics.lightxml34
-rw-r--r--tests/auto/testlib/selftests/expected_tuplediagnostics.tap33
-rw-r--r--tests/auto/testlib/selftests/expected_tuplediagnostics.teamcity14
-rw-r--r--tests/auto/testlib/selftests/expected_tuplediagnostics.txt15
-rw-r--r--tests/auto/testlib/selftests/expected_tuplediagnostics.xml37
-rw-r--r--tests/auto/testlib/selftests/expected_tuplediagnostics.xunitxml22
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.tap118
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.tap136
-rw-r--r--tests/auto/testlib/selftests/expected_verifyexceptionthrown.tap53
-rw-r--r--tests/auto/testlib/selftests/expected_warnings.tap42
-rw-r--r--tests/auto/testlib/selftests/expected_xunit.tap44
-rwxr-xr-xtests/auto/testlib/selftests/generate_expected_output.py28
-rw-r--r--tests/auto/testlib/selftests/keyboard/keyboard.pro7
-rw-r--r--tests/auto/testlib/selftests/keyboard/tst_keyboard.cpp88
-rw-r--r--tests/auto/testlib/selftests/selftests.pri6
-rw-r--r--tests/auto/testlib/selftests/selftests.qrc219
-rw-r--r--tests/auto/testlib/selftests/test/test.pro4
-rw-r--r--tests/auto/testlib/selftests/tst_selftests.cpp395
-rw-r--r--tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp65
-rw-r--r--tests/auto/testlib/selftests/tuplediagnostics/tuplediagnostics.pro6
-rw-r--r--tests/auto/testserver.pri109
-rw-r--r--tests/auto/tools/moc/cxx11-enums.h7
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp34
-rw-r--r--tests/auto/tools/qmakelib/evaltest.cpp72
-rw-r--r--tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h4
-rw-r--r--tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h4
-rw-r--r--tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h2
-rw-r--r--tests/auto/tools/uic/baseline/Main_Window.ui.h8
-rw-r--r--tests/auto/tools/uic/baseline/Widget.ui.h10
-rw-r--r--tests/auto/tools/uic/baseline/addlinkdialog.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/addtorrentform.ui.h48
-rw-r--r--tests/auto/tools/uic/baseline/authenticationdialog.ui.h20
-rw-r--r--tests/auto/tools/uic/baseline/backside.ui.h30
-rw-r--r--tests/auto/tools/uic/baseline/batchtranslation.ui.h34
-rw-r--r--tests/auto/tools/uic/baseline/bookmarkdialog.ui.h32
-rw-r--r--tests/auto/tools/uic/baseline/bookwindow.ui.h36
-rw-r--r--tests/auto/tools/uic/baseline/browserwidget.ui.h26
-rw-r--r--tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h8
-rw-r--r--tests/auto/tools/uic/baseline/buttongroup.ui.h36
-rw-r--r--tests/auto/tools/uic/baseline/calculator.ui.h58
-rw-r--r--tests/auto/tools/uic/baseline/calculatorform.ui.h38
-rw-r--r--tests/auto/tools/uic/baseline/certificateinfo.ui.h20
-rw-r--r--tests/auto/tools/uic/baseline/chatdialog.ui.h16
-rw-r--r--tests/auto/tools/uic/baseline/chatmainwindow.ui.h32
-rw-r--r--tests/auto/tools/uic/baseline/chatsetnickname.ui.h16
-rw-r--r--tests/auto/tools/uic/baseline/config.ui.h104
-rw-r--r--tests/auto/tools/uic/baseline/connectdialog.ui.h28
-rw-r--r--tests/auto/tools/uic/baseline/controller.ui.h14
-rw-r--r--tests/auto/tools/uic/baseline/cookies.ui.h16
-rw-r--r--tests/auto/tools/uic/baseline/cookiesexceptions.ui.h36
-rw-r--r--tests/auto/tools/uic/baseline/default.ui.h52
-rw-r--r--tests/auto/tools/uic/baseline/dialog.ui.h10
-rw-r--r--tests/auto/tools/uic/baseline/downloaditem.ui.h22
-rw-r--r--tests/auto/tools/uic/baseline/downloads.ui.h12
-rw-r--r--tests/auto/tools/uic/baseline/embeddeddialog.ui.h20
-rw-r--r--tests/auto/tools/uic/baseline/enumnostdset.ui.h4
-rw-r--r--tests/auto/tools/uic/baseline/filespage.ui.h12
-rw-r--r--tests/auto/tools/uic/baseline/filternamedialog.ui.h12
-rw-r--r--tests/auto/tools/uic/baseline/filterpage.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/finddialog.ui.h32
-rw-r--r--tests/auto/tools/uic/baseline/form.ui.h20
-rw-r--r--tests/auto/tools/uic/baseline/formwindowsettings.ui.h56
-rw-r--r--tests/auto/tools/uic/baseline/generalpage.ui.h12
-rw-r--r--tests/auto/tools/uic/baseline/gridalignment.ui.h12
-rw-r--r--tests/auto/tools/uic/baseline/gridpanel.ui.h26
-rw-r--r--tests/auto/tools/uic/baseline/helpdialog.ui.h60
-rw-r--r--tests/auto/tools/uic/baseline/history.ui.h16
-rw-r--r--tests/auto/tools/uic/baseline/icontheme.ui.h20
-rw-r--r--tests/auto/tools/uic/baseline/idbased.ui.h6
-rw-r--r--tests/auto/tools/uic/baseline/identifierpage.ui.h12
-rw-r--r--tests/auto/tools/uic/baseline/imagedialog.ui.h36
-rw-r--r--tests/auto/tools/uic/baseline/inputpage.ui.h12
-rw-r--r--tests/auto/tools/uic/baseline/installdialog.ui.h26
-rw-r--r--tests/auto/tools/uic/baseline/languagesdialog.ui.h26
-rw-r--r--tests/auto/tools/uic/baseline/listwidgeteditor.ui.h28
-rw-r--r--tests/auto/tools/uic/baseline/mainwindow.ui.h88
-rw-r--r--tests/auto/tools/uic/baseline/mydialog.ui.h8
-rw-r--r--tests/auto/tools/uic/baseline/myform.ui.h26
-rw-r--r--tests/auto/tools/uic/baseline/newactiondialog.ui.h24
-rw-r--r--tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/newform.ui.h16
-rw-r--r--tests/auto/tools/uic/baseline/orderdialog.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/outputpage.ui.h12
-rw-r--r--tests/auto/tools/uic/baseline/pagefold.ui.h56
-rw-r--r--tests/auto/tools/uic/baseline/paletteeditor.ui.h32
-rw-r--r--tests/auto/tools/uic/baseline/passworddialog.ui.h20
-rw-r--r--tests/auto/tools/uic/baseline/pathpage.ui.h16
-rw-r--r--tests/auto/tools/uic/baseline/phrasebookbox.ui.h32
-rw-r--r--tests/auto/tools/uic/baseline/pixmapfunction.ui47
-rw-r--r--tests/auto/tools/uic/baseline/pixmapfunction.ui.h74
-rw-r--r--tests/auto/tools/uic/baseline/plugindialog.ui.h14
-rw-r--r--tests/auto/tools/uic/baseline/preferencesdialog.ui.h36
-rw-r--r--tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h26
-rw-r--r--tests/auto/tools/uic/baseline/previewdialogbase.ui.h26
-rw-r--r--tests/auto/tools/uic/baseline/previewwidget.ui.h42
-rw-r--r--tests/auto/tools/uic/baseline/proxy.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/qfiledialog.ui.h54
-rw-r--r--tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h72
-rw-r--r--tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h66
-rw-r--r--tests/auto/tools/uic/baseline/qprintwidget.ui.h32
-rw-r--r--tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h42
-rw-r--r--tests/auto/tools/uic/baseline/qtgradientdialog.ui.h8
-rw-r--r--tests/auto/tools/uic/baseline/qtgradienteditor.ui.h158
-rw-r--r--tests/auto/tools/uic/baseline/qtgradientview.ui.h16
-rw-r--r--tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h8
-rw-r--r--tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h32
-rw-r--r--tests/auto/tools/uic/baseline/qttoolbardialog.ui.h36
-rw-r--r--tests/auto/tools/uic/baseline/qttrid.ui.h56
-rw-r--r--tests/auto/tools/uic/baseline/querywidget.ui.h36
-rw-r--r--tests/auto/tools/uic/baseline/remotecontrol.ui.h56
-rw-r--r--tests/auto/tools/uic/baseline/saveformastemplate.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/settings.ui.h34
-rw-r--r--tests/auto/tools/uic/baseline/signalslotdialog.ui.h30
-rw-r--r--tests/auto/tools/uic/baseline/sslclient.ui.h36
-rw-r--r--tests/auto/tools/uic/baseline/sslerrors.ui.h16
-rw-r--r--tests/auto/tools/uic/baseline/statistics.ui.h42
-rw-r--r--tests/auto/tools/uic/baseline/stringlisteditor.ui.h32
-rw-r--r--tests/auto/tools/uic/baseline/stylesheeteditor.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/tabbedbrowser.ui.h28
-rw-r--r--tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h66
-rw-r--r--tests/auto/tools/uic/baseline/tetrixwindow.ui.h30
-rw-r--r--tests/auto/tools/uic/baseline/textfinder.ui.h14
-rw-r--r--tests/auto/tools/uic/baseline/topicchooser.ui.h20
-rw-r--r--tests/auto/tools/uic/baseline/translatedialog.ui.h34
-rw-r--r--tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h2
-rw-r--r--tests/auto/tools/uic/baseline/translationsettings.ui.h18
-rw-r--r--tests/auto/tools/uic/baseline/treewidgeteditor.ui.h56
-rw-r--r--tests/auto/tools/uic/baseline/trpreviewtool.ui.h38
-rw-r--r--tests/auto/tools/uic/baseline/validators.ui.h72
-rw-r--r--tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h46
-rw-r--r--tests/auto/widgets/dialogs/dialogs.pro1
-rw-r--r--tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro2
-rw-r--r--tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp6
-rw-r--r--tests/auto/widgets/dialogs/qdialog/BLACKLIST2
-rw-r--r--tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp11
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp96
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST2
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp2
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp2
-rw-r--r--tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp9
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp3
-rw-r--r--tests/auto/widgets/effects/qgraphicseffect/BLACKLIST3
-rw-r--r--tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp4
-rw-r--r--tests/auto/widgets/graphicsview/graphicsview.pro2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp56
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp128
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST12
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp6
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp3
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp26
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp9
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp2
-rw-r--r--tests/auto/widgets/itemviews/qdirmodel/tst_qdirmodel.cpp18
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/BLACKLIST3
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp72
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST1
-rw-r--r--tests/auto/widgets/itemviews/qitemview/BLACKLIST2
-rw-r--r--tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp31
-rw-r--r--tests/auto/widgets/itemviews/qlistview/qlistview.pro1
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp86
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp20
-rw-r--r--tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp57
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/BLACKLIST2
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp11
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp66
-rw-r--r--tests/auto/widgets/kernel/qapplication/BLACKLIST1
-rw-r--r--tests/auto/widgets/kernel/qapplication/desktopsettingsaware/desktopsettingsaware.pro12
-rw-r--r--tests/auto/widgets/kernel/qapplication/modal/modal.pro12
-rw-r--r--tests/auto/widgets/kernel/qapplication/test/test.pro26
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp56
-rw-r--r--tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp20
-rw-r--r--tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp3
-rw-r--r--tests/auto/widgets/kernel/qgesturerecognizer/BLACKLIST2
-rw-r--r--tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp2
-rw-r--r--tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp12
-rw-r--r--tests/auto/widgets/kernel/qwidget/BLACKLIST39
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp193
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/BLACKLIST3
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp133
-rw-r--r--tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp12
-rw-r--r--tests/auto/widgets/styles/qstyle/tst_qstyle.cpp10
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp55
-rw-r--r--tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp9
-rw-r--r--tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp4
-rw-r--r--tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp7
-rw-r--r--tests/auto/widgets/widgets/qcombobox/qcombobox.pro3
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp57
-rw-r--r--tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp616
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp23
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp635
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp91
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp10
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp29
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro2
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp40
-rw-r--r--tests/auto/widgets/widgets/qmenu/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qmenu/qmenu.pro2
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp181
-rw-r--r--tests/auto/widgets/widgets/qmenubar/BLACKLIST3
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp7
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp3
-rw-r--r--tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp3
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp2
-rw-r--r--tests/auto/widgets/widgets/qsizegrip/BLACKLIST2
-rw-r--r--tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp11
-rw-r--r--tests/auto/widgets/widgets/qspinbox/BLACKLIST3
-rw-r--r--tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp589
-rw-r--r--tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp6
-rw-r--r--tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp3
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/qtextbrowser.pro2
-rw-r--r--tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp40
-rw-r--r--tests/auto/widgets/widgets/qtextedit/qtextedit.pro2
-rw-r--r--tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp6
-rw-r--r--tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp3
-rw-r--r--tests/auto/widgets/widgets/widgets.pro2
-rw-r--r--tests/baselineserver/shared/qbaselinetest.cpp30
-rw-r--r--tests/benchmarks/corelib/tools/qtimezone/main.cpp52
-rw-r--r--tests/benchmarks/corelib/tools/qtimezone/qtimezone.pro4
-rw-r--r--tests/benchmarks/corelib/tools/tools.pro1
-rw-r--r--tests/benchmarks/gui/graphicsview/graphicsview.pro16
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp234
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro5
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp140
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro5
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp120
-rw-r--r--tests/benchmarks/gui/gui.pro8
-rw-r--r--tests/benchmarks/gui/image/image.pro3
-rw-r--r--tests/benchmarks/gui/image/qimagereader/qimagereader.pro1
-rw-r--r--tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp2
-rw-r--r--tests/benchmarks/gui/kernel/kernel.pro4
-rw-r--r--tests/benchmarks/gui/painting/painting.pro1
-rw-r--r--tests/benchmarks/gui/painting/qpainter/tst_qpainter.cpp4
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/main.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/main.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png)bin6598 -> 6598 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png)bin6687 -> 6687 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png)bin6261 -> 6261 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png)bin6783 -> 6783 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png)bin6317 -> 6317 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png)bin7020 -> 7020 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png)bin3706 -> 3706 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png)bin6749 -> 6749 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png)bin5436 -> 5436 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png)bin1454 -> 1454 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png)bin2983 -> 2983 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png)bin3463 -> 3463 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png)bin763 -> 763 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png)bin2252 -> 2252 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png)bin2451 -> 2451 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png)bin6330 -> 6330 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png)bin6237 -> 6237 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png)bin6192 -> 6192 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png)bin7489 -> 7489 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png)bin6764 -> 6764 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png)bin6218 -> 6218 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png)bin6122 -> 6122 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png)bin6658 -> 6658 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png)bin8293 -> 8293 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png)bin4783 -> 4783 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h (renamed from tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/functional/functional.pro (renamed from tests/benchmarks/gui/graphicsview/functional/functional.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/graphicsview.pro10
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro (renamed from tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro (renamed from tests/benchmarks/gui/graphicsview/qgraphicsitem/qgraphicsitem.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp234
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicslayout/qgraphicslayout.pro5
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp143
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro5
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp120
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro (renamed from tests/benchmarks/gui/graphicsview/qgraphicsscene/qgraphicsscene.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.debug (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.debug)bin863805 -> 863805 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.h (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.pro (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/fileprint.png (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/fileprint.png)bin1456 -> 1456 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/images.qrc (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/images.qrc)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/main.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/main.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.h (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/qt4logo.png (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/qt4logo.png)bin48333 -> 48333 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/rotateleft.png (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateleft.png)bin1754 -> 1754 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/rotateright.png (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateright.png)bin1732 -> 1732 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/view.h (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/zoomin.png (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomin.png)bin1622 -> 1622 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/zoomout.png (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomout.png)bin1601 -> 1601 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/moveItems/moveItems.pro (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/moveItems.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/scrolltest/scrolltest.pro (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/scrolltest.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.h (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.h (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.pri (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.pri)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/images.qrc (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/images.qrc)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/qt4logo.png (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/qt4logo.png)bin48333 -> 48333 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/images/designer.png (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/images/designer.png)bin4205 -> 4205 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/images/wine-big.jpeg (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine-big.jpeg)bin12249 -> 12249 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/images/wine.jpeg (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine.jpeg)bin2265 -> 2265 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/qgraphicsview.pro (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/qgraphicsview.qrc (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.qrc)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/random.data (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/random.data)bin800 -> 800 bytes
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro (renamed from tests/benchmarks/gui/graphicsview/qgraphicswidget/qgraphicswidget.pro)0
-rw-r--r--tests/benchmarks/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp (renamed from tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp)0
-rw-r--r--tests/benchmarks/widgets/itemviews/itemviews.pro (renamed from tests/benchmarks/gui/itemviews/itemviews.pro)0
-rw-r--r--tests/benchmarks/widgets/itemviews/qheaderview/qheaderview.pro (renamed from tests/benchmarks/gui/itemviews/qheaderview/qheaderview.pro)0
-rw-r--r--tests/benchmarks/widgets/itemviews/qheaderview/qheaderviewbench.cpp (renamed from tests/benchmarks/gui/itemviews/qheaderview/qheaderviewbench.cpp)0
-rw-r--r--tests/benchmarks/widgets/itemviews/qtableview/qtableview.pro (renamed from tests/benchmarks/gui/itemviews/qtableview/qtableview.pro)0
-rw-r--r--tests/benchmarks/widgets/itemviews/qtableview/tst_qtableview.cpp (renamed from tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp)0
-rw-r--r--tests/benchmarks/widgets/kernel/kernel.pro4
-rw-r--r--tests/benchmarks/widgets/kernel/qapplication/main.cpp (renamed from tests/benchmarks/gui/kernel/qapplication/main.cpp)0
-rw-r--r--tests/benchmarks/widgets/kernel/qapplication/qapplication.pro (renamed from tests/benchmarks/gui/kernel/qapplication/qapplication.pro)0
-rw-r--r--tests/benchmarks/widgets/kernel/qwidget/qwidget.pro (renamed from tests/benchmarks/gui/kernel/qwidget/qwidget.pro)0
-rw-r--r--tests/benchmarks/widgets/kernel/qwidget/tst_qwidget.cpp (renamed from tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp)0
-rw-r--r--tests/benchmarks/widgets/styles/qstylesheetstyle/main.cpp (renamed from tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp)0
-rw-r--r--tests/benchmarks/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro (renamed from tests/benchmarks/gui/styles/qstylesheetstyle/qstylesheetstyle.pro)0
-rw-r--r--tests/benchmarks/widgets/styles/styles.pro (renamed from tests/benchmarks/gui/styles/styles.pro)0
-rw-r--r--tests/benchmarks/widgets/widgets.pro10
-rw-r--r--tests/manual/cocoa/menurama/main.cpp37
-rw-r--r--tests/manual/cocoa/menurama/mainwindow.ui16
-rw-r--r--tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.h7
-rw-r--r--tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.m25
-rw-r--r--tests/manual/cocoa/qmaccocoaviewcontainer/main.mm2
-rw-r--r--tests/manual/cocoa/qt_on_cocoa/main.mm32
-rw-r--r--tests/manual/highdpi/dragwidget.cpp2
-rw-r--r--tests/manual/highdpi/main.cpp93
-rw-r--r--tests/manual/windowchildgeometry/controllerwidget.cpp6
-rw-r--r--tests/manual/windowgeometry/controllerwidget.cpp18
-rwxr-xr-xtests/testserver/apache2/apache2.sh77
-rw-r--r--tests/testserver/apache2/testdata/dav.conf7
-rw-r--r--tests/testserver/apache2/testdata/deflate.conf5
-rw-r--r--tests/testserver/apache2/testdata/main.conf56
-rw-r--r--tests/testserver/apache2/testdata/security.conf51
-rw-r--r--tests/testserver/apache2/testdata/ssl.conf2
-rwxr-xr-xtests/testserver/apache2/testdata/www/cgi-bin/echo.cgi11
-rwxr-xr-xtests/testserver/apache2/testdata/www/cgi-bin/get-cookie.cgi5
-rwxr-xr-xtests/testserver/apache2/testdata/www/cgi-bin/http-delete.cgi22
-rwxr-xr-xtests/testserver/apache2/testdata/www/cgi-bin/http-unknown-authentication-method.cgi17
-rwxr-xr-xtests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires500.cgi12
-rwxr-xr-xtests/testserver/apache2/testdata/www/cgi-bin/multipart.cgi42
-rwxr-xr-xtests/testserver/apache2/testdata/www/cgi-bin/set-cookie.cgi9
-rw-r--r--tests/testserver/apache2/testdata/www/htdocs/auth-digest/index.html1
-rw-r--r--tests/testserver/apache2/testdata/www/htdocs/digest-authfile1
-rw-r--r--tests/testserver/apache2/testdata/www/htdocs/fluke.gifbin0 -> 27906 bytes
-rw-r--r--tests/testserver/apache2/testdata/www/htdocs/index.html3
-rw-r--r--tests/testserver/apache2/testdata/www/htdocs/protected/.htaccess5
-rwxr-xr-xtests/testserver/apache2/testdata/www/htdocs/protected/cgi-bin/md5sum.cgi6
-rw-r--r--tests/testserver/apache2/testdata/www/htdocs/rfcs-auth/index.html1
-rwxr-xr-xtests/testserver/common/ssl.sh39
-rwxr-xr-xtests/testserver/common/startup.sh57
-rw-r--r--tests/testserver/common/testdata/ssl/private/qt-test-server-key.pem15
-rw-r--r--tests/testserver/common/testdata/ssl/qt-test-server-cert.pem16
-rw-r--r--tests/testserver/common/testdata/system/passwords12
-rwxr-xr-xtests/testserver/danted/danted.sh44
-rw-r--r--tests/testserver/danted/testdata/danted-authenticating.conf19
-rw-r--r--tests/testserver/danted/testdata/danted.conf19
-rw-r--r--tests/testserver/docker-compose.yml83
-rwxr-xr-xtests/testserver/ftp-proxy/ftp-proxy.sh40
-rwxr-xr-xtests/testserver/squid/squid.sh46
-rw-r--r--tests/testserver/squid/testdata/squid-authenticating-ntlm.conf41
-rw-r--r--tests/testserver/squid/testdata/squid.conf46
-rw-r--r--tests/testserver/vsftpd/testdata/ftp/pub/file-not-readable.txt1
-rw-r--r--tests/testserver/vsftpd/testdata/vsftpd.conf112
-rw-r--r--tests/testserver/vsftpd/testdata/vsftpd.user_list20
-rwxr-xr-xtests/testserver/vsftpd/vsftpd.sh66
-rwxr-xr-xutil/edid/qedidvendortable.py9
-rw-r--r--util/gradientgen/.gitignore2
-rwxr-xr-xutil/gradientgen/gradientgen.js133
-rw-r--r--util/gradientgen/package-lock.json183
-rw-r--r--util/gradientgen/package.json13
-rw-r--r--util/gradientgen/tobinaryjson.cpp54
-rw-r--r--util/gradientgen/tobinaryjson.pro4
-rwxr-xr-xutil/local_database/cldr2qlocalexml.py47
-rw-r--r--util/local_database/enumdata.py1576
-rwxr-xr-xutil/local_database/qlocalexml2cpp.py66
-rw-r--r--util/unicode/main.cpp8
-rwxr-xr-xutil/x86simdgen/generate.pl199
-rw-r--r--util/x86simdgen/simd.txt37
2380 files changed, 144762 insertions, 42945 deletions
diff --git a/.qmake.conf b/.qmake.conf
index afdc0cb413..5df08093cd 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -4,4 +4,4 @@ CONFIG += warning_clean
QT_SOURCE_TREE = $$PWD
QT_BUILD_TREE = $$shadowed($$PWD)
-MODULE_VERSION = 5.11.2
+MODULE_VERSION = 5.12.0
diff --git a/LGPL_EXCEPTION.txt b/LGPL_EXCEPTION.txt
deleted file mode 100644
index 5cdacb9a4e..0000000000
--- a/LGPL_EXCEPTION.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-The Qt Company Qt LGPL Exception version 1.1
-
-As an additional permission to the GNU Lesser General Public License version
-2.1, the object code form of a "work that uses the Library" may incorporate
-material from a header file that is part of the Library. You may distribute
-such object code under terms of your choice, provided that:
- (i) the header files of the Library have not been modified; and
- (ii) the incorporated material is limited to numerical parameters, data
- structure layouts, accessors, macros, inline functions and
- templates; and
- (iii) you comply with the terms of Section 6 of the GNU Lesser General
- Public License version 2.1.
-
-Moreover, you may apply this exception to a modified version of the Library,
-provided that such modification does not involve copying material from the
-Library into the modified Library's header files unless such material is
-limited to (i) numerical parameters; (ii) data structure layouts;
-(iii) accessors; and (iv) small macros, templates and inline functions of
-five lines or less in length.
-
-Furthermore, you are not required to apply this additional permission to a
-modified version of the Library.
diff --git a/config.tests/arch/arch.cpp b/config.tests/arch/arch.cpp
index bb3efec177..2ccfe127b5 100644
--- a/config.tests/arch/arch.cpp
+++ b/config.tests/arch/arch.cpp
@@ -80,19 +80,19 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
" avx2"
#endif
#ifdef __AVX512F__
-// AVX512 Foundation, Intel Xeon Phi codename "Knights Landing" and Intel Xeon codename "Skylake"
+// AVX512 Foundation, Intel Xeon Scalable ("Skylake" server), some Intel Core 7th generation ("Skylake")
" avx512f"
#endif
#ifdef __AVX512CD__
-// AVX512 Conflict Detection, Intel Xeon Phi codename "Knights Landing" and Intel Xeon codename "Skylake"
+// AVX512 Conflict Detection, Intel Xeon Scalable ("Skylake" server), some Intel Core 7th generation ("Skylake")
" avx512cd"
#endif
#ifdef __AVX512DQ__
-// AVX512 Double & Quadword, Intel Xeon processor codename "Skylake"
+// AVX512 Double & Quadword, Intel Xeon Scalable ("Skylake" server), some Intel Core 7th generation ("Skylake")
" avx512dq"
#endif
#ifdef __AVX512BW__
-// AVX512 Byte & Word, Intel Xeon processor codename "Skylake"
+// AVX512 Byte & Word, Intel Xeon Scalable ("Skylake" server), some Intel Core 7th generation ("Skylake")
" avx512bw"
#endif
#ifdef __AVX512ER__
@@ -104,7 +104,7 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
" avx512pf"
#endif
#ifdef __AVX512VL__
-// AVX512 Vector Length, Intel Xeon processor codename "Skylake"
+// AVX512 Vector Length, Intel Xeon Scalable ("Skylake" server), some Intel Core 7th generation ("Skylake")
" avx512vl"
#endif
#ifdef __AVX512IFMA__
@@ -115,6 +115,22 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
// AVX512 Vector Byte Manipulation Instructions, Intel processor codename "Cannonlake"
" avx512vbmi"
#endif
+#ifdef __AVX512VBMI2__
+// AVX512 Vector Byte Manipulation Instructions #2, Intel processor codename "Ice Lake"
+" avx512vbmi2"
+#endif
+#ifdef __AVX512VPOPCNTDQ__
+// AVX512 Vector Population Count Double & Quad, Future Intel Xeon Phi processor codename "Knights Mill", Intel processor codename "Ice Lake"
+" avx512vpopcntdq"
+#endif
+#ifdef __AVX5124FMAPS__
+// AVX512 4-iteration Fused Multiply Accumulation Packed Single, Future Intel Xeon Phi processor codename "Knights Mill"
+" avx5124fmaps"
+#endif
+#ifdef __AVX5124VNNIW__
+// AVX512 4-iteration Vector Neural Network Instructions Word, Future Intel Xeon Phi processor codename "Knights Mill"
+" avx5124vnniw"
+#endif
#ifdef __BMI__
// Bit Manipulation Instructions 1, Intel Core 4th Generation ("Haswell"), AMD "Bulldozer 2"
" bmi"
@@ -145,6 +161,14 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
// rdfsgsbase, wrfsgsbase, Intel Core 3rd Generation ("Ivy Bridge")
" fsgsbase"
#endif
+#ifdef __GFNI__
+// Galois Field new instructions, Intel processor codename "Ice Lake"
+" gfni"
+#endif
+#ifdef __IBT__
+// Indirect Branch Tracking, Intel processor TBA
+" ibt"
+#endif
#ifdef __LWP__
// LWP instructions, AMD "Bulldozer"
" lwp"
@@ -186,6 +210,10 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
// Prefetch data for writing, Intel Core 5th Generation ("Broadwell")
" prfchw"
#endif
+#ifdef __RDPID__
+// Read Processor ID, Intel processors codename "Ice Lake" and "Goldmont Plus"
+" rdpid"
+#endif
#ifdef __RDRND__
// Random number generator, Intel Core 3rd Generation ("Ivy Bridge")
" rdrnd"
@@ -199,9 +227,13 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
" rtm"
#endif
#ifdef __SHA__
-// SHA-1 and SHA-256 instructions, Intel processor TBA
+// SHA-1 and SHA-256 instructions, Intel processors codename "Cannon Lake" and "Goldmont"
" sha"
#endif
+#ifdef __SHSTK__
+// Shadow stack, Intel processor TBA
+" shstk"
+#endif
#if defined(__SSE__) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1) || defined(_M_X64)
// Streaming SIMD Extensions, Intel Pentium III, AMD Athlon
" sse"
diff --git a/config.tests/avx512/avx512.cpp b/config.tests/avx512/avx512.cpp
index 29e88ebf15..4d47db8463 100644
--- a/config.tests/avx512/avx512.cpp
+++ b/config.tests/avx512/avx512.cpp
@@ -65,6 +65,10 @@ int main(int, char**argv)
d = _mm512_loadu_pd((double *)argv + 64);
f = _mm512_loadu_ps((float *)argv + 128);
+ // some intrinsic that GCC forgot until GCC 8
+ i = _mm512_maskz_set1_epi32(m, '?');
+ _mm512_mask_cvtepi32_storeu_epi8(argv, m, i);
+
#ifdef WANT_AVX512ER
/* AVX512 Exponential and Reciprocal */
f = _mm512_exp2a23_round_ps(f, 8);
@@ -84,6 +88,7 @@ int main(int, char**argv)
#ifdef WANT_AVX512BW
/* AVX512 Byte and Word support */
i = _mm512_mask_loadu_epi8(i, m, argv - 8);
+ _mm512_mask_cvtepi16_storeu_epi8(argv + 8, m, i);
#endif
#ifdef WANT_AVX512VL
/* AVX512 Vector Length */
diff --git a/config_help.txt b/config_help.txt
index f90d4439cd..5b32eb183f 100644
--- a/config_help.txt
+++ b/config_help.txt
@@ -98,6 +98,9 @@ Build options:
-gdb-index ........... Index the debug info to speed up GDB
[no; auto if -developer-build with debug info]
-strip ............... Strip release binaries of unneeded symbols [yes]
+ -gc-binaries ......... Place each function or data item into its own section
+ and enable linker garbage collection of unused
+ sections. [auto for static builds, otherwise no]
-force-asserts ....... Enable Q_ASSERT even in release builds [no]
-developer-build ..... Compile and link Qt for developing Qt itself
(exports for auto-tests, extra checks, etc.) [no]
@@ -298,7 +301,7 @@ Gui, printing, widget options:
-libinput .......... Enable libinput support [auto]
-mtdev ............. Enable mtdev support [auto]
-tslib ............. Enable tslib support [auto]
- -xinput2 ........... Enable XInput2 support [auto]
+ -xcb-xinput ........ Enable XInput2 support [auto]
-xkbcommon-x11 ..... Select xkbcommon used in combination with xcb
[system/qt/no]
-xkbcommon-evdev ... Enable X-less xkbcommon in combination with libinput
diff --git a/configure.json b/configure.json
index 2dc79137e8..3d78039a9f 100644
--- a/configure.json
+++ b/configure.json
@@ -11,6 +11,7 @@
"src/corelib",
"src/network",
"src/gui",
+ "src/sql",
"src/xml",
"src/widgets",
"src/printsupport",
@@ -79,6 +80,7 @@
"force-debug-info": { "type": "boolean", "name": "force_debug_info" },
"force-pkg-config": { "type": "void", "name": "pkg-config" },
"framework": "boolean",
+ "gc-binaries": { "type": "boolean", "name": "gc_binaries" },
"gdb-index": { "type": "boolean", "name": "gdb_index" },
"gcc-sysroot": "boolean",
"gcov": "boolean",
@@ -159,21 +161,16 @@
},
"sources": [
{ "libs": "-lzdll", "condition": "config.msvc" },
- { "libs": "-lz", "condition": "!config.msvc" }
+ { "libs": "-lzlib", "condition": "config.msvc" },
+ { "libs": "-lz", "condition": "!config.msvc" },
+ { "libs": "-s USE_ZLIB=1", "condition": "config.wasm" }
]
},
"dbus": {
"label": "D-Bus >= 1.2",
"test": {
"include": "dbus/dbus.h",
- "main": "(void) dbus_bus_get_private(DBUS_BUS_SYSTEM, (DBusError *)NULL);",
- "qmake": [
- "CONFIG += build_all",
- "CONFIG(debug, debug|release): \\",
- " LIBS += $$LIBS_DEBUG",
- "else: \\",
- " LIBS += $$LIBS_RELEASE"
- ]
+ "main": "(void) dbus_bus_get_private(DBUS_BUS_SYSTEM, (DBusError *)NULL);"
},
"sources": [
{ "type": "pkgConfig", "args": "dbus-1 >= 1.2" },
@@ -259,6 +256,36 @@
"type": "compile",
"test": "stl"
},
+ "c99": {
+ "label": "C99 support",
+ "type": "compile",
+ "test": {
+ "head": [
+ "#if __STDC_VERSION__ >= 199901L",
+ "// Compiler claims to support C99, trust it",
+ "#else",
+ "# error __STDC_VERSION__ must be >= 199901L",
+ "#endif"
+ ],
+ "lang": "c",
+ "qmake": "CONFIG += c99"
+ }
+ },
+ "c11": {
+ "label": "C11 support",
+ "type": "compile",
+ "test": {
+ "head": [
+ "#if __STDC_VERSION__ >= 201112L",
+ "// Compiler claims to support C11, trust it",
+ "#else",
+ "# error __STDC_VERSION__ must be >= 201112L",
+ "#endif"
+ ],
+ "lang": "c",
+ "qmake": "CONFIG += c11"
+ }
+ },
"c++14": {
"label": "C++14 support",
"type": "compile",
@@ -372,6 +399,17 @@
]
}
},
+ "gc_binaries": {
+ "label": "support for split sections and linker garbage collection",
+ "type": "compile",
+ "test": {
+ "qmake": [
+ "isEmpty(QMAKE_CFLAGS_SPLIT_SECTIONS): error(\"Nope\")",
+ "isEmpty(QMAKE_CXXFLAGS_SPLIT_SECTIONS): error(\"Nope\")",
+ "isEmpty(QMAKE_LFLAGS_GCSECTIONS): error(\"Nope\")"
+ ]
+ }
+ },
"sse2": {
"label": "SSE2 instructions",
"type": "x86Simd"
@@ -568,6 +606,10 @@
"compiler-flags": {
"output": [ "compilerFlags" ]
},
+ "gc_binaries": {
+ "condition": "!features.shared && tests.gc_binaries",
+ "output": [ "privateFeature" ]
+ },
"gcc-sysroot": {
"output": [ "gccSysroot" ],
"condition": "input.sysroot != ''"
@@ -578,7 +620,7 @@
},
"use_gold_linker": {
"label": "Using gold linker",
- "condition": "!config.win32 && !config.integrity && tests.use_gold_linker",
+ "condition": "!config.win32 && !config.integrity && !config.wasm && tests.use_gold_linker",
"output": [ "privateConfig", "useGoldLinker" ]
},
"optimize_debug": {
@@ -793,9 +835,22 @@
"condition": "features.c++14 && tests.c++1z",
"output": [ "publicFeature", "publicQtConfig" ]
},
+ "c89": {
+ "label": "C89"
+ },
+ "c99": {
+ "label": "C99",
+ "condition": "tests.c99",
+ "output": [ "publicFeature" ]
+ },
+ "c11": {
+ "label": "C11",
+ "condition": "features.c99 && tests.c11",
+ "output": [ "publicFeature" ]
+ },
"precompile_header": {
"label": "Using precompiled headers",
- "condition": "config.msvc || tests.precompile_header",
+ "condition": "tests.precompile_header",
"output": [
"privateConfig",
{ "type": "varRemove", "negative": true, "name": "CONFIG", "value": "'precompile_header'" }
@@ -1059,10 +1114,17 @@
"condition": "libs.zlib",
"output": [ "privateFeature" ]
},
+ "thread": {
+ "label": "Thread support",
+ "purpose": "Provides QThread and related classes.",
+ "section": "Kernel",
+ "output": [ "publicFeature" ]
+ },
"future": {
"label": "QFuture",
"purpose": "Provides QFuture and related classes.",
"section": "Kernel",
+ "condition": "features.thread",
"output": [ "publicFeature" ]
},
"concurrent": {
@@ -1075,6 +1137,7 @@
"dbus": {
"label": "Qt D-Bus",
"autoDetect": "!config.uikit && !config.android && !config.winrt",
+ "condition": "features.thread",
"output": [ "privateFeature", "feature" ]
},
"dbus-linked": {
@@ -1106,10 +1169,12 @@
},
"network": {
"label": "Qt Network",
+ "condition": "features.thread",
"output": [ "privateFeature" ]
},
"sql": {
"label": "Qt Sql",
+ "condition": "features.thread",
"output": [ "privateFeature" ]
},
"testlib": {
@@ -1254,6 +1319,11 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5
},
"shared",
{
+ "message": "Using C standard",
+ "type": "firstAvailableFeature",
+ "args": "c11 c99 c89"
+ },
+ {
"message": "Using C++ standard",
"type": "firstAvailableFeature",
"args": "c++1z c++14 c++11"
diff --git a/configure.pri b/configure.pri
index 6e7f6b76a4..3747f96f3d 100644
--- a/configure.pri
+++ b/configure.pri
@@ -68,7 +68,7 @@ defineReplace(qtConfFunc_crossCompile) {
}
defineReplace(qtConfFunc_licenseCheck) {
- exists($$QT_SOURCE_TREE/LICENSE.LGPL3)|exists($$QT_SOURCE_TREE/LICENSE.GPL2): \
+ exists($$QT_SOURCE_TREE/LICENSE.LGPL3)|exists($$QT_SOURCE_TREE/LICENSE.GPL2)|exists($$QT_SOURCE_TREE/LICENSE.GPL3): \
hasOpenSource = true
else: \
hasOpenSource = false
@@ -187,8 +187,13 @@ defineReplace(qtConfFunc_licenseCheck) {
theLicense = "GNU Lesser General Public License (LGPL) version 3"
showWhat = "Type 'L' to view the GNU Lesser General Public License version 3 (LGPLv3)."
gpl2Ok = false
+ gpl3Ok = false
winrt {
notTheLicense = "Note: GPL version 2 is not available on WinRT."
+ } else: wasm {
+ gpl3Ok = true
+ theLicense = "GNU General Public License (GPL) version 3"
+ showWhat = "Type 'G' to view the GNU General Public License version 3 (GPLv3)."
} else: $$qtConfEvaluate("features.android-style-assets") {
notTheLicense = "Note: GPL version 2 is not available due to using Android style assets."
} else {
@@ -230,6 +235,8 @@ defineReplace(qtConfFunc_licenseCheck) {
licenseFile = $$QT_SOURCE_TREE/LICENSE.LGPL3
} else: equals(commercial, no):equals(val, g):$$gpl2Ok {
licenseFile = $$QT_SOURCE_TREE/LICENSE.GPL2
+ } else: equals(commercial, no):equals(val, g):$$gpl3Ok {
+ licenseFile = $$QT_SOURCE_TREE/LICENSE.GPL3
} else {
next()
}
@@ -251,6 +258,11 @@ defineTest(qtConfTest_machineTuple) {
return(true)
}
+defineTest(qtConfTest_verifySpec) {
+ qtConfTest_compile($$1): return(true)
+ qtConfFatalError("Cannot compile a minimal program. The toolchain or QMakeSpec is broken.", log)
+}
+
defineTest(qtConfTest_architecture) {
!qtConfTest_compile($${1}): \
error("Could not determine $$eval($${1}.label). See config.log for details.")
@@ -263,6 +275,8 @@ defineTest(qtConfTest_architecture) {
content = $$cat($$test_out_dir/arch.exe, blob)
else: android:exists($$test_out_dir/libarch.so): \
content = $$cat($$test_out_dir/libarch.so, blob)
+ else: wasm:exists($$test_out_dir/arch.wasm): \
+ content = $$cat($$test_out_dir/arch.wasm, blob)
else: \
error("$$eval($${1}.label) detection binary not found.")
@@ -412,7 +426,7 @@ defineTest(qtConfTest_x86SimdAlways) {
qtConfCheckFeature($$f)
equals($${fpfx}.$${f}.available, true): configs += $$f
}
- $${1}.literal_args = $$system_quote(SIMD=$$join(configs, " "))
+ $${1}.literal_args = SIMD=$$join(configs, " ")
qtConfTest_compile($${1})
}
@@ -590,6 +604,9 @@ defineTest(qtConfOutput_prepareOptions) {
target_arch = armeabi-v7a
platform = $$eval(config.input.android-ndk-platform)
+ isEmpty(platform): equals(target_arch, arm64-v8a): \
+ platform = android-21
+
isEmpty(platform): \
platform = android-16 ### the windows configure disagrees ...
@@ -1141,6 +1158,12 @@ defineReplace(qtConfOutputPostProcess_publicPro) {
"QT_ICC_MINOR_VERSION = $$format_number($$replace(QMAKE_ICC_VER, "(..)(..)", "\\2"))" \
"QT_ICC_PATCH_VERSION = $$QMAKE_ICC_UPDATE_VER"
}
+ !isEmpty(QMAKE_GHS_VERSION) {
+ output += \
+ "QT_GHS_MAJOR_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\1")" \
+ "QT_GHS_MINOR_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\2")" \
+ "QT_GHS_PATCH_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\3")"
+ }
output += "QT_EDITION = $$config.input.qt_edition"
!contains(config.input.qt_edition, "(OpenSource|Preview)") {
diff --git a/doc/global/macros.qdocconf b/doc/global/macros.qdocconf
index dbf8c5cc6a..704b1da277 100644
--- a/doc/global/macros.qdocconf
+++ b/doc/global/macros.qdocconf
@@ -19,6 +19,7 @@ macro.QD = "\\e{Qt Designer}"
macro.QL = "\\e{Qt Linguist}"
macro.QQV = "\\e{Qt QML Viewer}"
macro.QtVersion = "$QT_VERSION"
+macro.QtVer = "$QT_VER"
macro.param = "\\e"
macro.raisedaster.HTML = "<sup>*</sup>"
macro.rarrow.HTML = "&rarr;"
@@ -40,6 +41,10 @@ macro.endfloat.HTML = "</div>"
macro.clearfloat.HTML = "<br style=\"clear: both\" />"
macro.emptyspan.HTML = "<span></span>"
+# Expands to the minor version based on the QT_VER environment variable
+macro.QtMinorVersion = "$QT_VER"
+macro.QtMinorVersion.match = "\\d+\\.(\\d+)"
+
# Embed YouTube content by video ID - Example: \youtube dQw4w9WgXcQ
# Also requires a <ID>.jpg thumbnail for offline docs. In .qdocconf, add:
#
diff --git a/doc/src/examples/bearermonitor.qdoc b/doc/src/examples/bearermonitor.qdoc
deleted file mode 100644
index ab68f99a7b..0000000000
--- a/doc/src/examples/bearermonitor.qdoc
+++ /dev/null
@@ -1,35 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example bearermonitor
- \title Bearer Monitor Example
-
- The Bearer Monitor example shows how to use the Bearer Management API.
-
- \image bearermonitor-example.png Screenshot of the Bearer Monitor example
-*/
diff --git a/doc/src/examples/customtypesending.qdoc b/doc/src/examples/customtypesending.qdoc
deleted file mode 100644
index 9fd64b42fd..0000000000
--- a/doc/src/examples/customtypesending.qdoc
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example tools/customtypesending
- \title Custom Type Sending Example
-
- The Custom Type Sending example shows how to use a custom type with signals
- and slots.
-
- \image customtypesending-example.png
-
- \section1 Overview
-
- In the \l{Custom Type Example}, we showed how to integrate custom types
- with the meta-object system, enabling them to be stored in QVariant
- objects, written out in debugging information and used in signal-slot
- communication.
-
- In this example, we demonstrate that the preparations made to the
- \c Message class and its declaration with Q_DECLARE_METATYPE() enable it
- to be used with direct signal-slot connections. We do this by creating
- a \c Window class containing signals and slots whose signatures include
- \c Message arguments.
-
- \section1 The Window and Message Class Definitions
-
- We define a simple \c Window class with a signal and public slot that
- allow a \c Message object to be sent via a signal-slot connection:
-
- \snippet examples/tools/customtypesending/window.h Window class definition
-
- The window will contain a text editor to show the contents of a message
- and a push button that the user can click to send a message. To facilitate
- this, we also define the \c sendMessage() slot. We also keep a \c Message
- instance in the \c thisMessage private variable which holds the actual
- message to be sent.
-
- The \c Message class is defined in the following way:
-
- \snippet examples/tools/customtypesending/message.h custom type definition
-
- The type is declared to the meta-type system with the Q_DECLARE_METATYPE()
- macro:
-
- \snippet examples/tools/customtypesending/message.h custom type meta-type declaration
-
- This will make the type available for use in direct signal-slot connections.
-
- \section1 The Window Class Implementation
-
- The \c Window constructor sets up a user interface containing a text
- editor and a push button.
-
- \snippet examples/tools/customtypesending/window.cpp Window constructor
-
- The button's \l{QPushButton::}{clicked()} signal is connected to the
- window's \c{sendMessage()} slot, which emits the \c{messageSent(Message)}
- signal with the \c Message held by the \c thisMessage variable:
-
- \snippet examples/tools/customtypesending/window.cpp sending a message
-
- We implement a slot to allow the message to be received, and this also
- lets us set the message in the window programatically:
-
- \snippet examples/tools/customtypesending/window.cpp receiving a message
-
- In this function, we simply assign the new message to \c thisMessage
- and update the text in the editor.
-
- \section1 Making the Connection
-
- In the example's \c{main()} function, we perform the connection between
- two instances of the \c Window class:
-
- \snippet examples/tools/customtypesending/main.cpp main function
-
- We set the message for the first window and connect the
- \c{messageSent(Message)} signal from each window to the other's
- \c{setMessage(Message)} slot. Since the signals and slots mechanism is only
- concerned with the type, we can simplify the signatures of both the
- signal and slot when we make the connection.
-
- When the user clicks on the \uicontrol{Send message} button in either window,
- the message shown will be emitted in a signal that the other window will
- receive and display.
-
- \section1 Further Reading
-
- Although the custom \c Message type can be used with direct signals and
- slots, an additional registration step needs to be performed if you want
- to use it with queued signal-slot connections. See the
- \l{Queued Custom Type Example} for details.
-
- More information on using custom types with Qt can be found in the
- \l{Creating Custom Qt Types} document.
-*/
diff --git a/doc/src/examples/dbus-chat.qdoc b/doc/src/examples/dbus-chat.qdoc
deleted file mode 100644
index 703d4eef50..0000000000
--- a/doc/src/examples/dbus-chat.qdoc
+++ /dev/null
@@ -1,36 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example dbus/dbus-chat
- \title D-Bus Chat Example
-
- The D-Bus Chat example shows how to use D-Bus to communicate between two
- applications.
-
- \image dbus-chat-example.png
-*/
diff --git a/doc/src/examples/digiflip.qdoc b/doc/src/examples/digiflip.qdoc
deleted file mode 100644
index 174b807a05..0000000000
--- a/doc/src/examples/digiflip.qdoc
+++ /dev/null
@@ -1,31 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example embedded/digiflip
- \title Digiflip
-*/
diff --git a/doc/src/examples/fingerpaint.qdoc b/doc/src/examples/fingerpaint.qdoc
deleted file mode 100644
index 79001ddc7d..0000000000
--- a/doc/src/examples/fingerpaint.qdoc
+++ /dev/null
@@ -1,42 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example touch/fingerpaint
- \title Finger Paint Example
- \ingroup touchinputexamples
- \brief Shows the use of a touchscreen to make a simple painting application
-
- The Finger Paint example shows the use of a touchscreen with a custom widget
- to create a simple painting application.
-
- \image touch-fingerpaint-example.png
-
- This example was specifically designed to work with a touchscreen, using
- QTouchEvent instead of QMouseEvent to handle user input over the custom
- widget. As a result, it is not possible to draw with the mouse cursor.
-*/
diff --git a/doc/src/examples/flickable.qdoc b/doc/src/examples/flickable.qdoc
deleted file mode 100644
index f289f421c3..0000000000
--- a/doc/src/examples/flickable.qdoc
+++ /dev/null
@@ -1,33 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example embedded/flickable
- \title Flickable List
-
- \image flickable-demo.png
-*/
diff --git a/doc/src/examples/flightinfo.qdoc b/doc/src/examples/flightinfo.qdoc
deleted file mode 100644
index 7e5162eb0e..0000000000
--- a/doc/src/examples/flightinfo.qdoc
+++ /dev/null
@@ -1,33 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example embedded/flightinfo
- \title Flight Info
-
- \image flightinfo-demo.png
-*/
diff --git a/doc/src/examples/htmlinfo.qdoc b/doc/src/examples/htmlinfo.qdoc
deleted file mode 100644
index 8397a28715..0000000000
--- a/doc/src/examples/htmlinfo.qdoc
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example xml/htmlinfo
- \title XML HTML Info Example
-
- The XML HTML Info example provides a simple command line utility that
- scans the current directory for HTML files and prints statistics about
- them to standard out.
-
- The files are parsed using a QXmlStreamReader object. If the file does
- not contain a well-formed XML document, a description of the error is
- printed to the standard error console.
-
- \section1 Basic Operation
-
- The main function of the example uses QDir to access files in the current
- directory that match either "*.htm" or "*.html". For each file found,
- the \c parseHtmlFile() function is called.
-
- Reading XML is handled by an instance of the QXmlStreamReader class, which
- operates on the input file object:
-
- \snippet examples/xml/htmlinfo/main.cpp 0
-
- The work of parsing and the XML and extracting statistics is done in a
- while loop, and is driven by input from the reader:
-
- \snippet examples/xml/htmlinfo/main.cpp 1
-
- If more input is available, the next token from the input file is read
- and parsed. The program then looks for the specific element types,
- "title", "a", and "p", and stores information about them.
-
- When there is no more input, the loop terminates. If an error occurred,
- information is written to the standard out file via a stream, and the
- example exits:
-
- \snippet examples/xml/htmlinfo/main.cpp 2
-
- If no error occurred, the example prints some statistics from the data
- gathered in the loop, and then exits.
-*/
diff --git a/doc/src/examples/lightmaps.qdoc b/doc/src/examples/lightmaps.qdoc
deleted file mode 100644
index c9f1fd664f..0000000000
--- a/doc/src/examples/lightmaps.qdoc
+++ /dev/null
@@ -1,33 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example embedded/lightmaps
- \title Light Maps
-
- \image lightmaps-demo.png
-*/
diff --git a/doc/src/examples/pinchzoom.qdoc b/doc/src/examples/pinchzoom.qdoc
deleted file mode 100644
index 077e9c5ee3..0000000000
--- a/doc/src/examples/pinchzoom.qdoc
+++ /dev/null
@@ -1,38 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example touch/pinchzoom
- \title Pinch Zoom Example
- \ingroup touchinputexamples
- \brief Shows how to recognize a gesture
-
- The Pinch Zoom example shows how to use low-level touch information
- to recognize a gesture.
-
- \image touch-pinchzoom-example.png
-*/
diff --git a/doc/src/examples/raycasting.qdoc b/doc/src/examples/raycasting.qdoc
deleted file mode 100644
index 16c1b7a754..0000000000
--- a/doc/src/examples/raycasting.qdoc
+++ /dev/null
@@ -1,33 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example embedded/raycasting
- \title Ray Casting
-
- \image raycasting-demo.png
-*/
diff --git a/doc/src/examples/rsslisting.qdoc b/doc/src/examples/rsslisting.qdoc
deleted file mode 100644
index 6ca22ce5b5..0000000000
--- a/doc/src/examples/rsslisting.qdoc
+++ /dev/null
@@ -1,36 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example xml/rsslisting
- \title RSS-Listing Example
-
- The RSS-Listing example shows how to create a widget that displays news items
- from RDF news sources.
-
- \image rsslistingexample.png
-*/
diff --git a/doc/src/examples/styleexample.qdoc b/doc/src/examples/styleexample.qdoc
deleted file mode 100644
index 6294800cef..0000000000
--- a/doc/src/examples/styleexample.qdoc
+++ /dev/null
@@ -1,33 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example embedded/styleexample
- \title Embedded Styles
-
- \image styledemo-demo.png
-*/
diff --git a/doc/src/images/gradients-demo.png b/doc/src/images/gradients-demo.png
index d80708e048..4c0959561d 100644
--- a/doc/src/images/gradients-demo.png
+++ b/doc/src/images/gradients-demo.png
Binary files differ
diff --git a/examples/corelib/serialization/cbordump/cbordump.pro b/examples/corelib/serialization/cbordump/cbordump.pro
new file mode 100644
index 0000000000..7fb2ef69f0
--- /dev/null
+++ b/examples/corelib/serialization/cbordump/cbordump.pro
@@ -0,0 +1,14 @@
+QT += core
+QT -= gui
+
+TARGET = cbordump
+CONFIG += console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/corelib/serialization/cbordump
+INSTALLS += target
+
+SOURCES += main.cpp
diff --git a/examples/corelib/serialization/cbordump/main.cpp b/examples/corelib/serialization/cbordump/main.cpp
new file mode 100644
index 0000000000..222bd43645
--- /dev/null
+++ b/examples/corelib/serialization/cbordump/main.cpp
@@ -0,0 +1,765 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCborStreamReader>
+#include <QCommandLineParser>
+#include <QCommandLineOption>
+#include <QCoreApplication>
+#include <QFile>
+#include <QLocale>
+#include <QStack>
+
+#include <locale.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+/*
+ * To regenerate:
+ * curl -O https://www.iana.org/assignments/cbor-tags/cbor-tags.xml
+ * xsltproc tag-transform.xslt cbor-tags.xml
+ */
+
+// GENERATED CODE
+struct CborTagDescription
+{
+ QCborTag tag;
+ const char *description; // with space and parentheses
+};
+
+// CBOR Tags
+static const CborTagDescription tagDescriptions[] = {
+ // from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
+ { QCborTag(0), " (Standard date/time string; see Section 2.4.1 [RFC7049])" },
+ { QCborTag(1), " (Epoch-based date/time; see Section 2.4.1 [RFC7049])" },
+ { QCborTag(2), " (Positive bignum; see Section 2.4.2 [RFC7049])" },
+ { QCborTag(3), " (Negative bignum; see Section 2.4.2 [RFC7049])" },
+ { QCborTag(4), " (Decimal fraction; see Section 2.4.3 [RFC7049])" },
+ { QCborTag(5), " (Bigfloat; see Section 2.4.3 [RFC7049])" },
+ { QCborTag(16), " (COSE Single Recipient Encrypted Data Object [RFC8152])" },
+ { QCborTag(17), " (COSE Mac w/o Recipients Object [RFC8152])" },
+ { QCborTag(18), " (COSE Single Signer Data Object [RFC8152])" },
+ { QCborTag(21), " (Expected conversion to base64url encoding; see Section 2.4.4.2 [RFC7049])" },
+ { QCborTag(22), " (Expected conversion to base64 encoding; see Section 2.4.4.2 [RFC7049])" },
+ { QCborTag(23), " (Expected conversion to base16 encoding; see Section 2.4.4.2 [RFC7049])" },
+ { QCborTag(24), " (Encoded CBOR data item; see Section 2.4.4.1 [RFC7049])" },
+ { QCborTag(25), " (reference the nth previously seen string)" },
+ { QCborTag(26), " (Serialised Perl object with classname and constructor arguments)" },
+ { QCborTag(27), " (Serialised language-independent object with type name and constructor arguments)" },
+ { QCborTag(28), " (mark value as (potentially) shared)" },
+ { QCborTag(29), " (reference nth marked value)" },
+ { QCborTag(30), " (Rational number)" },
+ { QCborTag(32), " (URI; see Section 2.4.4.3 [RFC7049])" },
+ { QCborTag(33), " (base64url; see Section 2.4.4.3 [RFC7049])" },
+ { QCborTag(34), " (base64; see Section 2.4.4.3 [RFC7049])" },
+ { QCborTag(35), " (Regular expression; see Section 2.4.4.3 [RFC7049])" },
+ { QCborTag(36), " (MIME message; see Section 2.4.4.3 [RFC7049])" },
+ { QCborTag(37), " (Binary UUID ( section 4.1.2))" },
+ { QCborTag(38), " (Language-tagged string)" },
+ { QCborTag(39), " (Identifier)" },
+ { QCborTag(61), " (CBOR Web Token (CWT))" },
+ { QCborTag(96), " (COSE Encrypted Data Object [RFC8152])" },
+ { QCborTag(97), " (COSE MACed Data Object [RFC8152])" },
+ { QCborTag(98), " (COSE Signed Data Object [RFC8152])" },
+ { QCborTag(256), " (mark value as having string references)" },
+ { QCborTag(257), " (Binary MIME message)" },
+ { QCborTag(258), " (Mathematical finite set)" },
+ { QCborTag(260), " (Network Address (IPv4 or IPv6 or MAC Address))" },
+ { QCborTag(264), " (Decimal fraction with arbitrary exponent)" },
+ { QCborTag(265), " (Bigfloat with arbitrary exponent)" },
+ { QCborTag(1001), " (extended time)" },
+ { QCborTag(1002), " (duration)" },
+ { QCborTag(1003), " (period)" },
+ { QCborTag(22098), " (hint that indicates an additional level of indirection)" },
+ { QCborTag(55799), " (Self-describe CBOR; see Section 2.4.5 [RFC7049])" },
+ { QCborTag(15309736), " (RAINS Message)" },
+ { QCborTag(-1), nullptr }
+};
+// END GENERATED CODE
+
+enum {
+ // See RFC 7049 section 2.
+ SmallValueBitLength = 5,
+ SmallValueMask = (1 << SmallValueBitLength) - 1, /* 0x1f */
+ Value8Bit = 24,
+ Value16Bit = 25,
+ Value32Bit = 26,
+ Value64Bit = 27
+};
+
+struct CborDumper
+{
+ enum DumpOption {
+ ShowCompact = 0x01,
+ ShowWidthIndicators = 0x02,
+ ShowAnnotated = 0x04
+ };
+ Q_DECLARE_FLAGS(DumpOptions, DumpOption)
+
+ CborDumper(QFile *f, DumpOptions opts_);
+ QCborError dump();
+
+private:
+ void dumpOne(int nestingLevel);
+ void dumpOneDetailed(int nestingLevel);
+
+ void printByteArray(const QByteArray &ba);
+ void printWidthIndicator(quint64 value, char space = '\0');
+ void printStringWidthIndicator(quint64 value);
+
+ QCborStreamReader reader;
+ QByteArray data;
+ QStack<quint8> byteArrayEncoding;
+ qint64 offset = 0;
+ DumpOptions opts;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(CborDumper::DumpOptions)
+
+static int cborNumberSize(quint64 value)
+{
+ int normalSize = 1;
+ if (value > std::numeric_limits<quint32>::max())
+ normalSize += 8;
+ else if (value > std::numeric_limits<quint16>::max())
+ normalSize += 4;
+ else if (value > std::numeric_limits<quint8>::max())
+ normalSize += 2;
+ else if (value >= Value8Bit)
+ normalSize += 1;
+ return normalSize;
+}
+
+CborDumper::CborDumper(QFile *f, DumpOptions opts_)
+ : opts(opts_)
+{
+ // try to mmap the file, this is faster
+ char *ptr = reinterpret_cast<char *>(f->map(0, f->size(), QFile::MapPrivateOption));
+ if (ptr) {
+ // worked
+ data = QByteArray::fromRawData(ptr, f->size());
+ reader.addData(data);
+ } else if ((opts & ShowAnnotated) || f->isSequential()) {
+ // details requires full contents, so allocate memory
+ data = f->readAll();
+ reader.addData(data);
+ } else {
+ // just use the QIODevice
+ reader.setDevice(f);
+ }
+}
+
+QCborError CborDumper::dump()
+{
+ byteArrayEncoding << quint8(QCborKnownTags::ExpectedBase16);
+ if (!reader.lastError()) {
+ if (opts & ShowAnnotated)
+ dumpOneDetailed(0);
+ else
+ dumpOne(0);
+ }
+
+ QCborError err = reader.lastError();
+ offset = reader.currentOffset();
+ if (err) {
+ fflush(stdout);
+ fprintf(stderr, "cbordump: decoding failed at %lld: %s\n",
+ offset, qPrintable(err.toString()));
+ if (!data.isEmpty())
+ fprintf(stderr, " bytes at %lld: %s\n", offset,
+ data.mid(offset, 9).toHex(' ').constData());
+ } else {
+ if (!opts.testFlag(ShowAnnotated))
+ printf("\n");
+ if (offset < data.size() || (reader.device() && reader.device()->bytesAvailable()))
+ fprintf(stderr, "Warning: bytes remaining at the end of the CBOR stream\n");
+ }
+
+ return err;
+}
+
+template <typename T> static inline bool canConvertTo(double v)
+{
+ // The [conv.fpint] (7.10 Floating-integral conversions) section of the
+ // standard says only exact conversions are guaranteed. Converting
+ // integrals to floating-point with loss of precision has implementation-
+ // defined behavior whether the next higher or next lower is returned;
+ // converting FP to integral is UB if it can't be represented.;
+ Q_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
+
+ double supremum = ldexp(1, std::numeric_limits<T>::digits);
+ if (v >= supremum)
+ return false;
+
+ if (v < std::numeric_limits<T>::min()) // either zero or a power of two, so it's exact
+ return false;
+
+ // we're in range
+ return v == floor(v);
+}
+
+static QString fpToString(double v, const char *suffix)
+{
+ if (qIsInf(v))
+ return v < 0 ? QStringLiteral("-inf") : QStringLiteral("inf");
+ if (qIsNaN(v))
+ return QStringLiteral("nan");
+ if (canConvertTo<qint64>(v))
+ return QString::number(qint64(v)) + ".0" + suffix;
+ if (canConvertTo<quint64>(v))
+ return QString::number(quint64(v)) + ".0" + suffix;
+
+ QString s = QString::number(v, 'g', QLocale::FloatingPointShortest);
+ if (!s.contains('.') && !s.contains('e'))
+ s += '.';
+ s += suffix;
+ return s;
+};
+
+void CborDumper::dumpOne(int nestingLevel)
+{
+ QString indent(1, QLatin1Char(' '));
+ QString indented = indent;
+ if (!opts.testFlag(ShowCompact)) {
+ indent = QLatin1Char('\n') + QString(4 * nestingLevel, QLatin1Char(' '));
+ indented = QLatin1Char('\n') + QString(4 + 4 * nestingLevel, QLatin1Char(' '));
+ }
+
+ switch (reader.type()) {
+ case QCborStreamReader::UnsignedInteger: {
+ quint64 u = reader.toUnsignedInteger();
+ printf("%llu", u);
+ reader.next();
+ printWidthIndicator(u);
+ return;
+ }
+
+ case QCborStreamReader::NegativeInteger: {
+ quint64 n = quint64(reader.toNegativeInteger());
+ if (n == 0) // -2^64 (wrapped around)
+ printf("-18446744073709551616");
+ else
+ printf("-%llu", n);
+ reader.next();
+ printWidthIndicator(n);
+ return;
+ }
+
+ case QCborStreamReader::ByteArray:
+ case QCborStreamReader::String: {
+ bool isLengthKnown = reader.isLengthKnown();
+ if (!isLengthKnown) {
+ printf("(_ ");
+ ++offset;
+ }
+
+ QString comma;
+ if (reader.isByteArray()) {
+ auto r = reader.readByteArray();
+ while (r.status == QCborStreamReader::Ok) {
+ printf("%s", qPrintable(comma));
+ printByteArray(r.data);
+ printStringWidthIndicator(r.data.size());
+
+ r = reader.readByteArray();
+ comma = QLatin1Char(',') + indented;
+ }
+ } else {
+ auto r = reader.readString();
+ while (r.status == QCborStreamReader::Ok) {
+ printf("%s\"%s\"", qPrintable(comma), qPrintable(r.data));
+ printStringWidthIndicator(r.data.toUtf8().size());
+
+ r = reader.readString();
+ comma = QLatin1Char(',') + indented;
+ }
+ }
+
+ if (!isLengthKnown && !reader.lastError())
+ printf(")");
+ break;
+ }
+
+ case QCborStreamReader::Array:
+ case QCborStreamReader::Map: {
+ const char *delimiters = (reader.isArray() ? "[]" : "{}");
+ printf("%c", delimiters[0]);
+
+ if (reader.isLengthKnown()) {
+ quint64 len = reader.length();
+ reader.enterContainer();
+ printWidthIndicator(len, ' ');
+ } else {
+ reader.enterContainer();
+ offset = reader.currentOffset();
+ printf("_ ");
+ }
+
+ const char *comma = "";
+ while (!reader.lastError() && reader.hasNext()) {
+ printf("%s%s", comma, qPrintable(indented));
+ comma = ",";
+ dumpOne(nestingLevel + 1);
+
+ if (reader.parentContainerType() != QCborStreamReader::Map)
+ continue;
+ if (reader.lastError())
+ break;
+ printf(": ");
+ dumpOne(nestingLevel + 1);
+ }
+
+ if (!reader.lastError()) {
+ reader.leaveContainer();
+ printf("%s%c", qPrintable(indent), delimiters[1]);
+ }
+ break;
+ }
+
+ case QCborStreamReader::Tag: {
+ QCborTag tag = reader.toTag();
+ printf("%llu", quint64(tag));
+
+ if (tag == QCborKnownTags::ExpectedBase16 || tag == QCborKnownTags::ExpectedBase64
+ || tag == QCborKnownTags::ExpectedBase64url)
+ byteArrayEncoding.push(quint8(tag));
+
+ if (reader.next()) {
+ printWidthIndicator(quint64(tag));
+ printf("(");
+ dumpOne(nestingLevel); // same level!
+ printf(")");
+ }
+
+ if (tag == QCborKnownTags::ExpectedBase16 || tag == QCborKnownTags::ExpectedBase64
+ || tag == QCborKnownTags::ExpectedBase64url)
+ byteArrayEncoding.pop();
+ break;
+ }
+
+ case QCborStreamReader::SimpleType:
+ switch (reader.toSimpleType()) {
+ case QCborSimpleType::False:
+ printf("false");
+ break;
+ case QCborSimpleType::True:
+ printf("true");
+ break;
+ case QCborSimpleType::Null:
+ printf("null");
+ break;
+ case QCborSimpleType::Undefined:
+ printf("undefined");
+ break;
+ default:
+ printf("simple(%u)", quint8(reader.toSimpleType()));
+ break;
+ }
+ reader.next();
+ break;
+
+ case QCborStreamReader::Float16:
+ printf("%s", qPrintable(fpToString(reader.toFloat16(), "f16")));
+ reader.next();
+ break;
+ case QCborStreamReader::Float:
+ printf("%s", qPrintable(fpToString(reader.toFloat(), "f")));
+ reader.next();
+ break;
+ case QCborStreamReader::Double:
+ printf("%s", qPrintable(fpToString(reader.toDouble(), "")));
+ reader.next();
+ break;
+ case QCborStreamReader::Invalid:
+ return;
+ }
+
+ offset = reader.currentOffset();
+}
+
+void CborDumper::dumpOneDetailed(int nestingLevel)
+{
+ auto tagDescription = [](QCborTag tag) {
+ for (auto entry : tagDescriptions) {
+ if (entry.tag == tag)
+ return entry.description;
+ if (entry.tag > tag)
+ break;
+ }
+ return "";
+ };
+ auto printOverlong = [](int actualSize, quint64 value) {
+ if (cborNumberSize(value) != actualSize)
+ printf(" (overlong)");
+ };
+ auto print = [=](const char *descr, const char *fmt, ...) {
+ qint64 prevOffset = offset;
+ offset = reader.currentOffset();
+ if (prevOffset == offset)
+ return;
+
+ QByteArray bytes = data.mid(prevOffset, offset - prevOffset);
+ QByteArray indent(nestingLevel * 2, ' ');
+ printf("%-50s # %s ", (indent + bytes.toHex(' ')).constData(), descr);
+
+ va_list va;
+ va_start(va, fmt);
+ vprintf(fmt, va);
+ va_end(va);
+
+ if (strstr(fmt, "%ll")) {
+ // Only works because all callers below that use %ll, use it as the
+ // first arg
+ va_start(va, fmt);
+ quint64 value = va_arg(va, quint64);
+ va_end(va);
+ printOverlong(bytes.size(), value);
+ }
+
+ puts("");
+ };
+
+ auto printFp = [=](const char *descr, double d) {
+ QString s = fpToString(d, "");
+ if (s.size() <= 6)
+ return print(descr, "%s", qPrintable(s));
+ return print(descr, "%a", d);
+ };
+
+ auto printString = [=](const char *descr) {
+ QByteArray indent(nestingLevel * 2, ' ');
+ const char *chunkStr = (reader.isLengthKnown() ? "" : "chunk ");
+ int width = 48 - indent.size();
+ int bytesPerLine = qMax(width / 3, 5);
+
+ qsizetype size = reader.currentStringChunkSize();
+ if (size < 0)
+ return; // error
+ if (size >= std::numeric_limits<int>::max()) {
+ fprintf(stderr, "String length too big, %lli\n", qint64(size));
+ exit(EXIT_FAILURE);
+ }
+
+ // if asking for the current string chunk changes the offset, then it
+ // was chunked
+ print(descr, "(indeterminate length)");
+
+ QByteArray bytes(size, Qt::Uninitialized);
+ auto r = reader.readStringChunk(bytes.data(), bytes.size());
+ while (r.status == QCborStreamReader::Ok) {
+ // We'll have to decode the length's width directly from CBOR...
+ const char *lenstart = data.constData() + offset;
+ const char *lenend = lenstart + 1;
+ quint8 additionalInformation = (*lenstart & SmallValueMask);
+
+ // Decode this number directly from CBOR (see RFC 7049 section 2)
+ if (additionalInformation >= Value8Bit) {
+ if (additionalInformation == Value8Bit)
+ lenend += 1;
+ else if (additionalInformation == Value16Bit)
+ lenend += 2;
+ else if (additionalInformation == Value32Bit)
+ lenend += 4;
+ else
+ lenend += 8;
+ }
+
+ {
+ QByteArray lenbytes = QByteArray::fromRawData(lenstart, lenend - lenstart);
+ printf("%-50s # %s %slength %llu",
+ (indent + lenbytes.toHex(' ')).constData(), descr, chunkStr, quint64(size));
+ printOverlong(lenbytes.size(), size);
+ puts("");
+ }
+
+ offset = reader.currentOffset();
+
+ for (int i = 0; i < r.data; i += bytesPerLine) {
+ QByteArray section = bytes.mid(i, bytesPerLine);
+ printf(" %s%s", indent.constData(), section.toHex(' ').constData());
+
+ // print the decode
+ QByteArray spaces(width > 0 ? width - section.size() * 3 + 1: 0, ' ');
+ printf("%s # \"", spaces.constData());
+ auto ptr = reinterpret_cast<const uchar *>(section.constData());
+ for (int j = 0; j < section.size(); ++j)
+ printf("%c", ptr[j] >= 0x80 || ptr[j] < 0x20 ? '.' : ptr[j]);
+
+ puts("\"");
+ }
+
+ // get the next chunk
+ size = reader.currentStringChunkSize();
+ if (size < 0)
+ return; // error
+ if (size >= std::numeric_limits<int>::max()) {
+ fprintf(stderr, "String length too big, %lli\n", qint64(size));
+ exit(EXIT_FAILURE);
+ }
+ bytes.resize(size);
+ r = reader.readStringChunk(bytes.data(), bytes.size());
+ }
+ };
+
+ if (reader.lastError())
+ return;
+
+ switch (reader.type()) {
+ case QCborStreamReader::UnsignedInteger: {
+ quint64 u = reader.toUnsignedInteger();
+ reader.next();
+ if (u < 65536 || (u % 100000) == 0)
+ print("Unsigned integer", "%llu", u);
+ else
+ print("Unsigned integer", "0x%llx", u);
+ return;
+ }
+
+ case QCborStreamReader::NegativeInteger: {
+ quint64 n = quint64(reader.toNegativeInteger());
+ reader.next();
+ print("Negative integer", n == 0 ? "-18446744073709551616" : "-%llu", n);
+ return;
+ }
+
+ case QCborStreamReader::ByteArray:
+ case QCborStreamReader::String: {
+ bool isLengthKnown = reader.isLengthKnown();
+ const char *descr = (reader.isString() ? "Text string" : "Byte string");
+ if (!isLengthKnown)
+ ++nestingLevel;
+
+ printString(descr);
+ if (reader.lastError())
+ return;
+
+ if (!isLengthKnown) {
+ --nestingLevel;
+ print("Break", "");
+ }
+ break;
+ }
+
+ case QCborStreamReader::Array:
+ case QCborStreamReader::Map: {
+ const char *descr = (reader.isArray() ? "Array" : "Map");
+ if (reader.isLengthKnown()) {
+ quint64 len = reader.length();
+ reader.enterContainer();
+ print(descr, "length %llu", len);
+ } else {
+ reader.enterContainer();
+ print(descr, "(indeterminate length)");
+ }
+
+ while (!reader.lastError() && reader.hasNext())
+ dumpOneDetailed(nestingLevel + 1);
+
+ if (!reader.lastError()) {
+ reader.leaveContainer();
+ print("Break", "");
+ }
+ break;
+ }
+
+ case QCborStreamReader::Tag: {
+ QCborTag tag = reader.toTag();
+ reader.next();
+ print("Tag", "%llu%s", quint64(tag), tagDescription(tag));
+ dumpOneDetailed(nestingLevel + 1);
+ break;
+ }
+
+ case QCborStreamReader::SimpleType: {
+ QCborSimpleType st = reader.toSimpleType();
+ reader.next();
+ switch (st) {
+ case QCborSimpleType::False:
+ print("Simple Type", "false");
+ break;
+ case QCborSimpleType::True:
+ print("Simple Type", "true");
+ break;
+ case QCborSimpleType::Null:
+ print("Simple Type", "null");
+ break;
+ case QCborSimpleType::Undefined:
+ print("Simple Type", "undefined");
+ break;
+ default:
+ print("Simple Type", "%u", quint8(st));
+ break;
+ }
+ break;
+ }
+
+ case QCborStreamReader::Float16: {
+ double d = reader.toFloat16();
+ reader.next();
+ printFp("Float16", d);
+ break;
+ }
+ case QCborStreamReader::Float: {
+ double d = reader.toFloat();
+ reader.next();
+ printFp("Float", d);
+ break;
+ }
+ case QCborStreamReader::Double: {
+ double d = reader.toDouble();
+ reader.next();
+ printFp("Double", d);
+ break;
+ }
+ case QCborStreamReader::Invalid:
+ return;
+ }
+
+ offset = reader.currentOffset();
+}
+
+void CborDumper::printByteArray(const QByteArray &ba)
+{
+ switch (byteArrayEncoding.top()) {
+ default:
+ printf("h'%s'", ba.toHex(' ').constData());
+ break;
+
+ case quint8(QCborKnownTags::ExpectedBase64):
+ printf("b64'%s'", ba.toBase64().constData());
+ break;
+
+ case quint8(QCborKnownTags::ExpectedBase64url):
+ printf("b64'%s'", ba.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals).constData());
+ break;
+ }
+}
+
+void printIndicator(quint64 value, qint64 previousOffset, qint64 offset, char space)
+{
+ int normalSize = cborNumberSize(value);
+ int actualSize = offset - previousOffset;
+
+ if (actualSize != normalSize) {
+ Q_ASSERT(actualSize > 1);
+ actualSize -= 2;
+ printf("_%d", qPopulationCount(uint(actualSize)));
+ if (space)
+ printf("%c", space);
+ }
+}
+
+void CborDumper::printWidthIndicator(quint64 value, char space)
+{
+ qint64 previousOffset = offset;
+ offset = reader.currentOffset();
+ if (opts & ShowWidthIndicators)
+ printIndicator(value, previousOffset, offset, space);
+}
+
+void CborDumper::printStringWidthIndicator(quint64 value)
+{
+ qint64 previousOffset = offset;
+ offset = reader.currentOffset();
+ if (opts & ShowWidthIndicators)
+ printIndicator(value, previousOffset, offset - uint(value), '\0');
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+ setlocale(LC_ALL, "C");
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QStringLiteral("CBOR Dumper tool"));
+ parser.addHelpOption();
+
+ QCommandLineOption compact({QStringLiteral("c"), QStringLiteral("compact")},
+ QStringLiteral("Use compact form (no line breaks)"));
+ parser.addOption(compact);
+
+ QCommandLineOption showIndicators({QStringLiteral("i"), QStringLiteral("indicators")},
+ QStringLiteral("Show indicators for width of lengths and integrals"));
+ parser.addOption(showIndicators);
+
+ QCommandLineOption verbose({QStringLiteral("a"), QStringLiteral("annotated")},
+ QStringLiteral("Show bytes and annotated decoding"));
+ parser.addOption(verbose);
+
+ parser.addPositionalArgument(QStringLiteral("[source]"),
+ QStringLiteral("CBOR file to read from"));
+
+ parser.process(app);
+
+ CborDumper::DumpOptions opts;
+ if (parser.isSet(compact))
+ opts |= CborDumper::ShowCompact;
+ if (parser.isSet(showIndicators))
+ opts |= CborDumper::ShowWidthIndicators;
+ if (parser.isSet(verbose))
+ opts |= CborDumper::ShowAnnotated;
+
+ QStringList files = parser.positionalArguments();
+ if (files.isEmpty())
+ files << "-";
+ for (const QString &file : qAsConst(files)) {
+ QFile f(file);
+ if (file == "-" ? f.open(stdin, QIODevice::ReadOnly) : f.open(QIODevice::ReadOnly)) {
+ if (files.size() > 1)
+ printf("/ From \"%s\" /\n", qPrintable(file));
+
+ CborDumper dumper(&f, opts);
+ QCborError err = dumper.dump();
+ if (err)
+ return EXIT_FAILURE;
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/examples/corelib/serialization/cbordump/tag-transform.xslt b/examples/corelib/serialization/cbordump/tag-transform.xslt
new file mode 100644
index 0000000000..3cc1b9b293
--- /dev/null
+++ b/examples/corelib/serialization/cbordump/tag-transform.xslt
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://www.iana.org/assignments" xmlns="http://www.iana.org/assignments" xmlns:_="http://www.iana.org/assignments" xmlns:DEFAULT="http://www.iana.org/assignments" version="1.0">
+<xsl:output omit-xml-declaration="yes" indent="no" method="text"/>
+<xsl:template match="/a:registry[@id='cbor-tags']">struct CborTagDescription
+{
+ QCborTag tag;
+ const char *description; // with space and parentheses
+};
+
+// <xsl:value-of select="a:registry/a:title"/>
+static const CborTagDescription tagDescriptions[] = {
+ // from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
+<xsl:for-each select="a:registry/a:record">
+ <xsl:sort select="a:value" data-type="number"/>
+ <xsl:if test="a:semantics != ''">
+ <xsl:call-template name="row"/>
+ </xsl:if>
+ </xsl:for-each> { QCborTag(-1), nullptr }
+};
+</xsl:template>
+<xsl:template name="row"> { QCborTag(<xsl:value-of select="a:value"/>), " (<xsl:value-of select="a:semantics"/> <xsl:call-template name="xref"/>)" },
+</xsl:template>
+<xsl:template name="xref"><xsl:if test="a:xref/@type = 'rfc'"> [<xsl:value-of select="translate(a:xref/@data,'rfc','RFC')"/>]</xsl:if>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/examples/corelib/serialization/convert/cborconverter.cpp b/examples/corelib/serialization/convert/cborconverter.cpp
new file mode 100644
index 0000000000..41724c935e
--- /dev/null
+++ b/examples/corelib/serialization/convert/cborconverter.cpp
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cborconverter.h"
+
+#include <QCborStreamReader>
+#include <QCborStreamWriter>
+#include <QCborMap>
+#include <QCborArray>
+#include <QCborValue>
+#include <QDataStream>
+#include <QDebug>
+#include <QFloat16>
+#include <QFile>
+#include <QMetaType>
+#include <QTextStream>
+
+#include <stdio.h>
+
+static CborConverter cborConverter;
+static CborDiagnosticDumper cborDiagnosticDumper;
+
+static const char optionHelp[] =
+ "convert-float-to-int=yes|no Write integers instead of floating point, if no\n"
+ " loss of precision occurs on conversion.\n"
+ "float16=yes|always|no Write using half-precision floating point.\n"
+ " If 'always', won't check for loss of precision.\n"
+ "float32=yes|always|no Write using single-precision floating point.\n"
+ " If 'always', won't check for loss of precision.\n"
+ "signature=yes|no Prepend the CBOR signature to the file output.\n"
+ ;
+
+static const char diagnosticHelp[] =
+ "extended=no|yes Use extended CBOR diagnostic format.\n"
+ "line-wrap=yes|no Split output into multiple lines.\n"
+ ;
+
+QT_BEGIN_NAMESPACE
+
+QDataStream &operator<<(QDataStream &ds, QCborSimpleType st)
+{
+ return ds << quint8(st);
+}
+
+QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st)
+{
+ quint8 v;
+ ds >> v;
+ st = QCborSimpleType(v);
+ return ds;
+}
+
+QDataStream &operator<<(QDataStream &ds, QCborTag tag)
+{
+ return ds << quint64(tag);
+}
+
+QDataStream &operator>>(QDataStream &ds, QCborTag &tag)
+{
+ quint64 v;
+ ds >> v;
+ tag = QCborTag(v);
+ return ds;
+}
+
+QT_END_NAMESPACE
+
+// We can't use QCborValue::toVariant directly because that would destroy
+// non-string keys in CBOR maps (QVariantMap can't handle those). Instead, we
+// have our own set of converter functions so we can keep the keys properly.
+
+static QVariant convertCborValue(const QCborValue &value);
+
+static QVariant convertCborMap(const QCborMap &map)
+{
+ VariantOrderedMap result;
+ result.reserve(map.size());
+ for (auto pair : map)
+ result.append({ convertCborValue(pair.first), convertCborValue(pair.second) });
+ return QVariant::fromValue(result);
+}
+
+static QVariant convertCborArray(const QCborArray &array)
+{
+ QVariantList result;
+ result.reserve(array.size());
+ for (auto value : array)
+ result.append(convertCborValue(value));
+ return result;
+}
+
+static QVariant convertCborValue(const QCborValue &value)
+{
+ if (value.isArray())
+ return convertCborArray(value.toArray());
+ if (value.isMap())
+ return convertCborMap(value.toMap());
+ return value.toVariant();
+}
+
+enum TrimFloatingPoint { Double, Float, Float16 };
+static QCborValue convertFromVariant(const QVariant &v, TrimFloatingPoint fpTrimming)
+{
+ if (v.userType() == QVariant::List) {
+ const QVariantList list = v.toList();
+ QCborArray array;
+ for (const QVariant &v : list)
+ array.append(convertFromVariant(v, fpTrimming));
+
+ return array;
+ }
+
+ if (v.userType() == qMetaTypeId<VariantOrderedMap>()) {
+ const auto m = v.value<VariantOrderedMap>();
+ QCborMap map;
+ for (const auto &pair : m)
+ map.insert(convertFromVariant(pair.first, fpTrimming),
+ convertFromVariant(pair.second, fpTrimming));
+ return map;
+ }
+
+ if (v.userType() == QVariant::Double && fpTrimming != Double) {
+ float f = float(v.toDouble());
+ if (fpTrimming == Float16)
+ return float(qfloat16(f));
+ return f;
+ }
+
+ return QCborValue::fromVariant(v);
+}
+
+QString CborDiagnosticDumper::name()
+{
+ return QStringLiteral("cbor-dump");
+}
+
+Converter::Direction CborDiagnosticDumper::directions()
+{
+ return Out;
+}
+
+Converter::Options CborDiagnosticDumper::outputOptions()
+{
+ return SupportsArbitraryMapKeys;
+}
+
+const char *CborDiagnosticDumper::optionsHelp()
+{
+ return diagnosticHelp;
+}
+
+bool CborDiagnosticDumper::probeFile(QIODevice *f)
+{
+ Q_UNUSED(f);
+ return false;
+}
+
+QVariant CborDiagnosticDumper::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ Q_UNREACHABLE();
+ Q_UNUSED(f);
+ Q_UNUSED(outputConverter);
+ return QVariant();
+}
+
+void CborDiagnosticDumper::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ QCborValue::DiagnosticNotationOptions opts = QCborValue::LineWrapped;
+ for (const QString &s : options) {
+ QStringList pair = s.split('=');
+ if (pair.size() == 2) {
+ if (pair.first() == "line-wrap") {
+ opts &= ~QCborValue::LineWrapped;
+ if (pair.last() == "yes") {
+ opts |= QCborValue::LineWrapped;
+ continue;
+ } else if (pair.last() == "no") {
+ continue;
+ }
+ }
+ if (pair.first() == "extended") {
+ opts &= ~QCborValue::ExtendedFormat;
+ if (pair.last() == "yes")
+ opts |= QCborValue::ExtendedFormat;
+ continue;
+ }
+ }
+
+ fprintf(stderr, "Unknown CBOR diagnostic option '%s'. Available options are:\n%s",
+ qPrintable(s), diagnosticHelp);
+ exit(EXIT_FAILURE);
+ }
+
+ QTextStream out(f);
+ out << convertFromVariant(contents, Double).toDiagnosticNotation(opts)
+ << endl;
+}
+
+CborConverter::CborConverter()
+{
+ qRegisterMetaType<QCborTag>();
+ qRegisterMetaTypeStreamOperators<QCborTag>();
+ QMetaType::registerDebugStreamOperator<QCborTag>();
+}
+
+QString CborConverter::name()
+{
+ return "cbor";
+}
+
+Converter::Direction CborConverter::directions()
+{
+ return InOut;
+}
+
+Converter::Options CborConverter::outputOptions()
+{
+ return SupportsArbitraryMapKeys;
+}
+
+const char *CborConverter::optionsHelp()
+{
+ return optionHelp;
+}
+
+bool CborConverter::probeFile(QIODevice *f)
+{
+ if (QFile *file = qobject_cast<QFile *>(f)) {
+ if (file->fileName().endsWith(QLatin1String(".cbor")))
+ return true;
+ }
+ return f->isReadable() && f->peek(3) == QByteArray("\xd9\xd9\xf7", 3);
+}
+
+QVariant CborConverter::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ const char *ptr = nullptr;
+ if (auto file = qobject_cast<QFile *>(f))
+ ptr = reinterpret_cast<char *>(file->map(0, file->size()));
+
+ QByteArray mapped = QByteArray::fromRawData(ptr, ptr ? f->size() : 0);
+ QCborStreamReader reader(mapped);
+ if (!ptr)
+ reader.setDevice(f);
+
+ if (reader.isTag() && reader.toTag() == QCborKnownTags::Signature)
+ reader.next();
+
+ QCborValue contents = QCborValue::fromCbor(reader);
+ qint64 offset = reader.currentOffset();
+ if (reader.lastError()) {
+ fprintf(stderr, "Error loading CBOR contents (byte %lld): %s\n", offset,
+ qPrintable(reader.lastError().toString()));
+ fprintf(stderr, " bytes: %s\n",
+ (ptr ? mapped.mid(offset, 9) : f->read(9)).toHex(' ').constData());
+ exit(EXIT_FAILURE);
+ } else if (offset < mapped.size() || (!ptr && f->bytesAvailable())) {
+ fprintf(stderr, "Warning: bytes remaining at the end of the CBOR stream\n");
+ }
+
+ if (outputConverter == nullptr)
+ outputConverter = &cborDiagnosticDumper;
+ else if (outputConverter == null)
+ return QVariant();
+ else if (!outputConverter->outputOptions().testFlag(SupportsArbitraryMapKeys))
+ return contents.toVariant();
+ return convertCborValue(contents);
+}
+
+void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ bool useSignature = true;
+ bool useIntegers = true;
+ enum { Yes, No, Always } useFloat16 = Yes, useFloat = Yes;
+
+ for (const QString &s : options) {
+ QStringList pair = s.split('=');
+ if (pair.size() == 2) {
+ if (pair.first() == "convert-float-to-int") {
+ if (pair.last() == "yes") {
+ useIntegers = true;
+ continue;
+ } else if (pair.last() == "no") {
+ useIntegers = false;
+ continue;
+ }
+ }
+
+ if (pair.first() == "float16") {
+ if (pair.last() == "no") {
+ useFloat16 = No;
+ continue;
+ } else if (pair.last() == "yes") {
+ useFloat16 = Yes;
+ continue;
+ } else if (pair.last() == "always") {
+ useFloat16 = Always;
+ continue;
+ }
+ }
+
+ if (pair.first() == "float32") {
+ if (pair.last() == "no") {
+ useFloat = No;
+ continue;
+ } else if (pair.last() == "yes") {
+ useFloat = Yes;
+ continue;
+ } else if (pair.last() == "always") {
+ useFloat = Always;
+ continue;
+ }
+ }
+
+ if (pair.first() == "signature") {
+ if (pair.last() == "yes") {
+ useSignature = true;
+ continue;
+ } else if (pair.last() == "no") {
+ useSignature = false;
+ continue;
+ }
+ }
+ }
+
+ fprintf(stderr, "Unknown CBOR format option '%s'. Valid options are:\n%s",
+ qPrintable(s), optionHelp);
+ exit(EXIT_FAILURE);
+ }
+
+ QCborValue v = convertFromVariant(contents,
+ useFloat16 == Always ? Float16 : useFloat == Always ? Float : Double);
+ QCborStreamWriter writer(f);
+ if (useSignature)
+ writer.append(QCborKnownTags::Signature);
+
+ QCborValue::EncodingOptions opts;
+ if (useIntegers)
+ opts |= QCborValue::UseIntegers;
+ if (useFloat != No)
+ opts |= QCborValue::UseFloat;
+ if (useFloat16 != No)
+ opts |= QCborValue::UseFloat16;
+ v.toCbor(writer, opts);
+}
+
diff --git a/examples/corelib/serialization/convert/cborconverter.h b/examples/corelib/serialization/convert/cborconverter.h
new file mode 100644
index 0000000000..f0a89cb141
--- /dev/null
+++ b/examples/corelib/serialization/convert/cborconverter.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CBORCONVERTER_H
+#define CBORCONVERTER_H
+
+#include "converter.h"
+
+class CborDiagnosticDumper : public Converter
+{
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+class CborConverter : public Converter
+{
+public:
+ CborConverter();
+
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+#endif // CBORCONVERTER_H
diff --git a/examples/corelib/serialization/convert/convert.pro b/examples/corelib/serialization/convert/convert.pro
new file mode 100644
index 0000000000..d9b1de41e3
--- /dev/null
+++ b/examples/corelib/serialization/convert/convert.pro
@@ -0,0 +1,29 @@
+QT += core
+QT -= gui
+
+TARGET = convert
+CONFIG += console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/corelib/serialization/convert
+INSTALLS += target
+
+SOURCES += main.cpp \
+ cborconverter.cpp \
+ jsonconverter.cpp \
+ datastreamconverter.cpp \
+ textconverter.cpp \
+ xmlconverter.cpp \
+ nullconverter.cpp
+
+HEADERS += \
+ converter.h \
+ cborconverter.h \
+ jsonconverter.h \
+ datastreamconverter.h \
+ textconverter.h \
+ xmlconverter.h \
+ nullconverter.h
diff --git a/examples/corelib/serialization/convert/converter.h b/examples/corelib/serialization/convert/converter.h
new file mode 100644
index 0000000000..82e1fa1cb3
--- /dev/null
+++ b/examples/corelib/serialization/convert/converter.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONVERTER_H
+#define CONVERTER_H
+
+#include <QIODevice>
+#include <QPair>
+#include <QVariant>
+#include <QVector>
+
+class VariantOrderedMap : public QVector<QPair<QVariant, QVariant>>
+{
+public:
+ VariantOrderedMap() = default;
+ VariantOrderedMap(const QVariantMap &map)
+ {
+ reserve(map.size());
+ for (auto it = map.begin(); it != map.end(); ++it)
+ append({it.key(), it.value()});
+ }
+};
+using Map = VariantOrderedMap;
+Q_DECLARE_METATYPE(Map)
+
+class Converter
+{
+protected:
+ Converter();
+
+public:
+ static Converter *null;
+
+ enum Direction {
+ In = 1, Out = 2, InOut = 3
+ };
+
+ enum Option {
+ SupportsArbitraryMapKeys = 0x01
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
+ virtual ~Converter() = 0;
+
+ virtual QString name() = 0;
+ virtual Direction directions() = 0;
+ virtual Options outputOptions() = 0;
+ virtual const char *optionsHelp() = 0;
+ virtual bool probeFile(QIODevice *f) = 0;
+ virtual QVariant loadFile(QIODevice *f, Converter *&outputConverter) = 0;
+ virtual void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) = 0;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(Converter::Options)
+
+#endif // CONVERTER_H
diff --git a/examples/corelib/serialization/convert/datastreamconverter.cpp b/examples/corelib/serialization/convert/datastreamconverter.cpp
new file mode 100644
index 0000000000..7cdb844141
--- /dev/null
+++ b/examples/corelib/serialization/convert/datastreamconverter.cpp
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "datastreamconverter.h"
+
+#include <QDataStream>
+#include <QDebug>
+#include <QTextStream>
+
+static const char optionHelp[] =
+ "byteorder=host|big|little Byte order to use.\n"
+ "version=<n> QDataStream version (default: Qt 5.0).\n"
+ ;
+
+static const char signature[] = "qds";
+
+static DataStreamDumper dataStreamDumper;
+static DataStreamConverter DataStreamConverter;
+
+QDataStream &operator<<(QDataStream &ds, const VariantOrderedMap &map)
+{
+ ds << qint64(map.size());
+ for (const auto &pair : map)
+ ds << pair.first << pair.second;
+ return ds;
+}
+
+QDataStream &operator>>(QDataStream &ds, VariantOrderedMap &map)
+{
+ map.clear();
+
+ qint64 size;
+ ds >> size;
+ map.reserve(size);
+
+ while (size-- > 0) {
+ VariantOrderedMap::value_type pair;
+ ds >> pair.first >> pair.second;
+ map.append(pair);
+ }
+
+ return ds;
+}
+
+
+static QString dumpVariant(const QVariant &v, const QString &indent = QLatin1String("\n"))
+{
+ QString result;
+ QString indented = indent + QLatin1String(" ");
+
+ int type = v.userType();
+ if (type == qMetaTypeId<VariantOrderedMap>() || type == QVariant::Map) {
+ const auto map = (type == QVariant::Map) ?
+ VariantOrderedMap(v.toMap()) : v.value<VariantOrderedMap>();
+
+ result = QLatin1String("Map {");
+ for (const auto &pair : map) {
+ result += indented + dumpVariant(pair.first, indented);
+ result.chop(1); // remove comma
+ result += QLatin1String(" => ") + dumpVariant(pair.second, indented);
+
+ }
+ result.chop(1); // remove comma
+ result += indent + QLatin1String("},");
+ } else if (type == QVariant::List) {
+ const QVariantList list = v.toList();
+
+ result = QLatin1String("List [");
+ for (const auto &item : list)
+ result += indented + dumpVariant(item, indented);
+ result.chop(1); // remove comma
+ result += indent + QLatin1String("],");
+ } else {
+ QDebug debug(&result);
+ debug.nospace() << v << ',';
+ }
+ return result;
+}
+
+QString DataStreamDumper::name()
+{
+ return QStringLiteral("datastream-dump");
+}
+
+Converter::Direction DataStreamDumper::directions()
+{
+ return Out;
+}
+
+Converter::Options DataStreamDumper::outputOptions()
+{
+ return SupportsArbitraryMapKeys;
+}
+
+const char *DataStreamDumper::optionsHelp()
+{
+ return nullptr;
+}
+
+bool DataStreamDumper::probeFile(QIODevice *f)
+{
+ Q_UNUSED(f);
+ return false;
+}
+
+QVariant DataStreamDumper::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ Q_UNREACHABLE();
+ Q_UNUSED(f);
+ Q_UNUSED(outputConverter);
+ return QVariant();
+}
+
+void DataStreamDumper::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ Q_UNUSED(options);
+ QString s = dumpVariant(contents);
+ s[s.size() - 1] = QLatin1Char('\n'); // replace the comma with newline
+
+ QTextStream out(f);
+ out << s;
+}
+
+DataStreamConverter::DataStreamConverter()
+{
+ qRegisterMetaType<VariantOrderedMap>();
+ qRegisterMetaTypeStreamOperators<VariantOrderedMap>();
+}
+
+QString DataStreamConverter::name()
+{
+ return QStringLiteral("datastream");
+}
+
+Converter::Direction DataStreamConverter::directions()
+{
+ return InOut;
+}
+
+Converter::Options DataStreamConverter::outputOptions()
+{
+ return SupportsArbitraryMapKeys;
+}
+
+const char *DataStreamConverter::optionsHelp()
+{
+ return optionHelp;
+}
+
+bool DataStreamConverter::probeFile(QIODevice *f)
+{
+ return f->isReadable() && f->peek(sizeof(signature) - 1) == signature;
+}
+
+QVariant DataStreamConverter::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ if (!outputConverter)
+ outputConverter = &dataStreamDumper;
+
+ char c;
+ if (f->read(sizeof(signature) -1) != signature ||
+ !f->getChar(&c) || (c != 'l' && c != 'B')) {
+ fprintf(stderr, "Could not load QDataStream file: invalid signature.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ QDataStream ds(f);
+ ds.setByteOrder(c == 'l' ? QDataStream::LittleEndian : QDataStream::BigEndian);
+
+ std::underlying_type<QDataStream::Version>::type version;
+ ds >> version;
+ ds.setVersion(QDataStream::Version(version));
+
+ QVariant result;
+ ds >> result;
+ return result;
+}
+
+void DataStreamConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ QDataStream::Version version = QDataStream::Qt_5_0;
+ auto order = QDataStream::ByteOrder(QSysInfo::ByteOrder);
+ for (const QString &option : options) {
+ const QStringList pair = option.split('=');
+ if (pair.size() == 2) {
+ if (pair.first() == "byteorder") {
+ if (pair.last() == "little") {
+ order = QDataStream::LittleEndian;
+ continue;
+ } else if (pair.last() == "big") {
+ order = QDataStream::BigEndian;
+ continue;
+ } else if (pair.last() == "host") {
+ order = QDataStream::ByteOrder(QSysInfo::ByteOrder);
+ continue;
+ }
+ }
+ if (pair.first() == "version") {
+ bool ok;
+ int n = pair.last().toInt(&ok);
+ if (ok) {
+ version = QDataStream::Version(n);
+ continue;
+ }
+
+ fprintf(stderr, "Invalid version number '%s': must be a number from 1 to %d.\n",
+ qPrintable(pair.last()), QDataStream::Qt_DefaultCompiledVersion);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ fprintf(stderr, "Unknown QDataStream formatting option '%s'. Available options are:\n%s",
+ qPrintable(option), optionHelp);
+ exit(EXIT_FAILURE);
+ }
+
+ char c = order == QDataStream::LittleEndian ? 'l' : 'B';
+ f->write(signature);
+ f->write(&c, 1);
+
+ QDataStream ds(f);
+ ds.setVersion(version);
+ ds.setByteOrder(order);
+ ds << std::underlying_type<decltype(version)>::type(version);
+ ds << contents;
+}
diff --git a/examples/corelib/serialization/convert/datastreamconverter.h b/examples/corelib/serialization/convert/datastreamconverter.h
new file mode 100644
index 0000000000..1b74abc54f
--- /dev/null
+++ b/examples/corelib/serialization/convert/datastreamconverter.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DATASTREAMCONVERTER_H
+#define DATASTREAMCONVERTER_H
+
+#include "converter.h"
+
+class DataStreamDumper : public Converter
+{
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+class DataStreamConverter : public Converter
+{
+public:
+ DataStreamConverter();
+
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+#endif // DATASTREAMCONVERTER_H
diff --git a/examples/corelib/serialization/convert/jsonconverter.cpp b/examples/corelib/serialization/convert/jsonconverter.cpp
new file mode 100644
index 0000000000..80d1cc6827
--- /dev/null
+++ b/examples/corelib/serialization/convert/jsonconverter.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "jsonconverter.h"
+
+#include <QFile>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonValue>
+
+static JsonConverter jsonConverter;
+static BinaryJsonConverter BinaryJsonConverter;
+
+static const char optionHelp[] =
+ "compact=no|yes Use compact JSON form.\n";
+
+static QJsonDocument convertFromVariant(const QVariant &v)
+{
+ QJsonDocument doc = QJsonDocument::fromVariant(v);
+ if (!doc.isObject() && !doc.isArray()) {
+ fprintf(stderr, "Could not convert contents to JSON.\n");
+ exit(EXIT_FAILURE);
+ }
+ return doc;
+}
+
+JsonConverter::JsonConverter()
+{
+}
+
+QString JsonConverter::name()
+{
+ return "json";
+}
+
+Converter::Direction JsonConverter::directions()
+{
+ return InOut;
+}
+
+Converter::Options JsonConverter::outputOptions()
+{
+ return {};
+}
+
+const char *JsonConverter::optionsHelp()
+{
+ return optionHelp;
+}
+
+bool JsonConverter::probeFile(QIODevice *f)
+{
+ if (QFile *file = qobject_cast<QFile *>(f)) {
+ if (file->fileName().endsWith(QLatin1String(".json")))
+ return true;
+ }
+
+ if (f->isReadable()) {
+ QByteArray ba = f->peek(1);
+ return ba == "{" || ba == "[";
+ }
+ return false;
+}
+
+QVariant JsonConverter::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ if (!outputConverter)
+ outputConverter = this;
+
+ QJsonParseError error;
+ QJsonDocument doc;
+ if (auto file = qobject_cast<QFile *>(f)) {
+ const char *ptr = reinterpret_cast<char *>(file->map(0, file->size()));
+ if (ptr)
+ doc = QJsonDocument::fromJson(QByteArray::fromRawData(ptr, file->size()), &error);
+ }
+
+ if (doc.isNull())
+ doc = QJsonDocument::fromJson(f->readAll(), &error);
+ if (error.error) {
+ fprintf(stderr, "Could not parse JSON content: offset %d: %s",
+ error.offset, qPrintable(error.errorString()));
+ exit(EXIT_FAILURE);
+ }
+ if (outputConverter == null)
+ return QVariant();
+ return doc.toVariant();
+}
+
+void JsonConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ QJsonDocument::JsonFormat format = QJsonDocument::Indented;
+ for (const QString &s : options) {
+ if (s == QLatin1String("compact=no")) {
+ format = QJsonDocument::Indented;
+ } else if (s == QLatin1String("compact=yes")) {
+ format = QJsonDocument::Compact;
+ } else {
+ fprintf(stderr, "Unknown option '%s' to JSON output. Valid options are:\n%s", qPrintable(s), optionHelp);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ f->write(convertFromVariant(contents).toJson(format));
+}
+
+QString BinaryJsonConverter::name()
+{
+ return "binary-json";
+}
+
+Converter::Direction BinaryJsonConverter::directions()
+{
+ return InOut;
+}
+
+Converter::Options BinaryJsonConverter::outputOptions()
+{
+ return {};
+}
+
+const char *BinaryJsonConverter::optionsHelp()
+{
+ return nullptr;
+}
+
+bool BinaryJsonConverter::probeFile(QIODevice *f)
+{
+ return f->isReadable() && f->peek(4) == "qbjs";
+}
+
+QVariant BinaryJsonConverter::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ if (!outputConverter)
+ outputConverter = &jsonConverter;
+
+ QJsonDocument doc;
+ if (auto file = qobject_cast<QFile *>(f)) {
+ uchar *ptr = file->map(0, file->size());
+ if (ptr)
+ doc = QJsonDocument::fromRawData(reinterpret_cast<char *>(ptr), file->size());
+ }
+
+ if (doc.isNull())
+ doc = QJsonDocument::fromBinaryData(f->readAll());
+
+ if (!doc.isObject() && !doc.isArray()) {
+ fprintf(stderr, "Failed to load Binary JSON.\n");
+ exit(EXIT_FAILURE);
+ }
+ if (outputConverter == null)
+ return QVariant();
+ return doc.toVariant();
+}
+
+void BinaryJsonConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ if (!options.isEmpty()) {
+ fprintf(stderr, "Unknown option '%s' to JSON output. This format has no options.\n", qPrintable(options.first()));
+ exit(EXIT_FAILURE);
+ }
+
+ f->write(convertFromVariant(contents).toBinaryData());
+}
diff --git a/examples/corelib/serialization/convert/jsonconverter.h b/examples/corelib/serialization/convert/jsonconverter.h
new file mode 100644
index 0000000000..17170603c7
--- /dev/null
+++ b/examples/corelib/serialization/convert/jsonconverter.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef JSONCONVERTER_H
+#define JSONCONVERTER_H
+
+#include "converter.h"
+
+class JsonConverter : public Converter
+{
+public:
+ JsonConverter();
+
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+class BinaryJsonConverter : public Converter
+{
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+#endif // JSONCONVERTER_H
diff --git a/examples/corelib/serialization/convert/main.cpp b/examples/corelib/serialization/convert/main.cpp
new file mode 100644
index 0000000000..e9d14792b0
--- /dev/null
+++ b/examples/corelib/serialization/convert/main.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "converter.h"
+
+#include <QCommandLineParser>
+#include <QCommandLineOption>
+#include <QCoreApplication>
+#include <QFile>
+#include <QFileInfo>
+
+#include <stdio.h>
+
+static QVector<Converter *> *availableConverters;
+
+Converter::Converter()
+{
+ if (!availableConverters)
+ availableConverters = new QVector<Converter *>;
+ availableConverters->append(this);
+}
+
+Converter::~Converter()
+{
+ availableConverters->removeAll(this);
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ QStringList inputFormats;
+ QStringList outputFormats;
+ for (Converter *conv : qAsConst(*availableConverters)) {
+ auto direction = conv->directions();
+ QString name = conv->name();
+ if (direction & Converter::In)
+ inputFormats << name;
+ if (direction & Converter::Out)
+ outputFormats << name;
+ }
+ inputFormats.sort();
+ outputFormats.sort();
+ inputFormats.prepend("auto");
+ outputFormats.prepend("auto");
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QStringLiteral("Qt file format conversion tool"));
+ parser.addHelpOption();
+
+ QCommandLineOption inputFormatOption(QStringList{"I", "input-format"});
+ inputFormatOption.setDescription(QLatin1String("Select the input format for the input file. Available formats: ") +
+ inputFormats.join(", "));
+ inputFormatOption.setValueName("format");
+ inputFormatOption.setDefaultValue(inputFormats.constFirst());
+ parser.addOption(inputFormatOption);
+
+ QCommandLineOption outputFormatOption(QStringList{"O", "output-format"});
+ outputFormatOption.setDescription(QLatin1String("Select the output format for the output file. Available formats: ") +
+ outputFormats.join(", "));
+ outputFormatOption.setValueName("format");
+ outputFormatOption.setDefaultValue(outputFormats.constFirst());
+ parser.addOption(outputFormatOption);
+
+ QCommandLineOption optionOption(QStringList{"o", "option"});
+ optionOption.setDescription(QStringLiteral("Format-specific options. Use --format-options to find out what options are available."));
+ optionOption.setValueName("options...");
+ optionOption.setDefaultValues({});
+ parser.addOption(optionOption);
+
+ QCommandLineOption formatOptionsOption("format-options");
+ formatOptionsOption.setDescription(QStringLiteral("Prints the list of valid options for --option for the converter format <format>."));
+ formatOptionsOption.setValueName("format");
+ parser.addOption(formatOptionsOption);
+
+ parser.addPositionalArgument(QStringLiteral("[source]"),
+ QStringLiteral("File to read from (stdin if none)"));
+ parser.addPositionalArgument(QStringLiteral("[destination]"),
+ QStringLiteral("File to write to (stdout if none)"));
+
+ parser.process(app);
+
+ if (parser.isSet(formatOptionsOption)) {
+ QString format = parser.value(formatOptionsOption);
+ for (Converter *conv : qAsConst(*availableConverters)) {
+ if (conv->name() == format) {
+ const char *help = conv->optionsHelp();
+ if (help)
+ printf("The following options are available for format '%s':\n\n%s", qPrintable(format), help);
+ else
+ printf("Format '%s' supports no options.\n", qPrintable(format));
+ return EXIT_SUCCESS;
+ }
+ }
+
+ fprintf(stderr, "Unknown file format '%s'\n", qPrintable(format));
+ return EXIT_FAILURE;
+ }
+
+ Converter *inconv = nullptr;
+ QString format = parser.value(inputFormatOption);
+ if (format != "auto") {
+ for (Converter *conv : qAsConst(*availableConverters)) {
+ if (conv->name() == format) {
+ inconv = conv;
+ break;
+ }
+ }
+
+ if (!inconv) {
+ fprintf(stderr, "Unknown file format \"%s\"\n", qPrintable(format));
+ return EXIT_FAILURE;
+ }
+ }
+
+ Converter *outconv = nullptr;
+ format = parser.value(outputFormatOption);
+ if (format != "auto") {
+ for (Converter *conv : qAsConst(*availableConverters)) {
+ if (conv->name() == format) {
+ outconv = conv;
+ break;
+ }
+ }
+
+ if (!outconv) {
+ fprintf(stderr, "Unknown file format \"%s\"\n", qPrintable(format));
+ return EXIT_FAILURE;
+ }
+ }
+
+ QStringList files = parser.positionalArguments();
+ QFile input(files.value(0));
+ QFile output(files.value(1));
+
+ if (input.fileName().isEmpty())
+ input.open(stdin, QIODevice::ReadOnly);
+ else
+ input.open(QIODevice::ReadOnly);
+ if (!input.isOpen()) {
+ fprintf(stderr, "Could not open \"%s\" for reading: %s\n",
+ qPrintable(input.fileName()), qPrintable(input.errorString()));
+ return EXIT_FAILURE;
+ }
+
+ if (output.fileName().isEmpty())
+ output.open(stdout, QIODevice::WriteOnly | QIODevice::Truncate);
+ else
+ output.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ if (!output.isOpen()) {
+ fprintf(stderr, "Could not open \"%s\" for writing: %s\n",
+ qPrintable(output.fileName()), qPrintable(output.errorString()));
+ return EXIT_FAILURE;
+ }
+
+ if (!inconv) {
+ // probe the input to find a file format
+ for (Converter *conv : qAsConst(*availableConverters)) {
+ if (conv->directions() & Converter::In && conv->probeFile(&input)) {
+ inconv = conv;
+ break;
+ }
+ }
+
+ if (!inconv) {
+ fprintf(stderr, "Could not determine input format. pass -I option.\n");
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (!outconv) {
+ // probe the output to find a file format
+ for (Converter *conv : qAsConst(*availableConverters)) {
+ if (conv->directions() & Converter::Out && conv->probeFile(&output)) {
+ outconv = conv;
+ break;
+ }
+ }
+ }
+
+ // now finally perform the conversion
+ QVariant data = inconv->loadFile(&input, outconv);
+ Q_ASSERT_X(outconv, "Converter Tool",
+ "Internal error: converter format did not provide default");
+ outconv->saveFile(&output, data, parser.values(optionOption));
+ return EXIT_SUCCESS;
+}
diff --git a/examples/corelib/serialization/convert/nullconverter.cpp b/examples/corelib/serialization/convert/nullconverter.cpp
new file mode 100644
index 0000000000..2de492e64e
--- /dev/null
+++ b/examples/corelib/serialization/convert/nullconverter.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nullconverter.h"
+
+static NullConverter nullConverter;
+Converter* Converter::null = &nullConverter;
+
+QString NullConverter::name()
+{
+ return QLatin1String("null");
+}
+
+Converter::Direction NullConverter::directions()
+{
+ return Out;
+}
+
+Converter::Options NullConverter::outputOptions()
+{
+ return SupportsArbitraryMapKeys;
+}
+
+const char *NullConverter::optionsHelp()
+{
+ return nullptr;
+}
+
+bool NullConverter::probeFile(QIODevice *f)
+{
+ Q_UNUSED(f);
+ return false;
+}
+
+QVariant NullConverter::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ Q_UNUSED(f);
+ Q_UNUSED(outputConverter);
+ outputConverter = this;
+ return QVariant();
+}
+
+void NullConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ if (!options.isEmpty()) {
+ fprintf(stderr, "Unknown option '%s' to null output. This format has no options.\n", qPrintable(options.first()));
+ exit(EXIT_FAILURE);
+ }
+
+ Q_UNUSED(f);
+ Q_UNUSED(contents);
+}
diff --git a/examples/corelib/serialization/convert/nullconverter.h b/examples/corelib/serialization/convert/nullconverter.h
new file mode 100644
index 0000000000..af7339f092
--- /dev/null
+++ b/examples/corelib/serialization/convert/nullconverter.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NULLCONVERTER_H
+#define NULLCONVERTER_H
+
+#include "converter.h"
+
+class NullConverter : public Converter
+{
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+#endif // NULLCONVERTER_H
diff --git a/examples/corelib/serialization/convert/textconverter.cpp b/examples/corelib/serialization/convert/textconverter.cpp
new file mode 100644
index 0000000000..e80e69a0b5
--- /dev/null
+++ b/examples/corelib/serialization/convert/textconverter.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "textconverter.h"
+
+#include <QFile>
+#include <QTextStream>
+
+static void dumpVariant(QTextStream &out, const QVariant &v)
+{
+ switch (v.userType()) {
+ case QVariant::List: {
+ const QVariantList list = v.toList();
+ for (const QVariant &item : list)
+ dumpVariant(out, item);
+ break;
+ }
+
+ case QVariant::String: {
+ const QStringList list = v.toStringList();
+ for (const QString &s : list)
+ out << s << endl;
+ break;
+ }
+
+ case QVariant::Map: {
+ const QVariantMap map = v.toMap();
+ for (auto it = map.begin(); it != map.end(); ++it) {
+ out << it.key() << " => ";
+ dumpVariant(out, it.value());
+ }
+ break;
+ }
+
+ case QMetaType::Nullptr:
+ out << "(null)" << endl;
+ break;
+
+ default:
+ out << v.toString() << endl;
+ break;
+ }
+}
+
+QString TextConverter::name()
+{
+ return QStringLiteral("text");
+}
+
+Converter::Direction TextConverter::directions()
+{
+ return InOut;
+}
+
+Converter::Options TextConverter::outputOptions()
+{
+ return {};
+}
+
+const char *TextConverter::optionsHelp()
+{
+ return nullptr;
+}
+
+bool TextConverter::probeFile(QIODevice *f)
+{
+ if (QFile *file = qobject_cast<QFile *>(f))
+ return file->fileName().endsWith(QLatin1String(".txt"));
+ return false;
+}
+
+QVariant TextConverter::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ if (!outputConverter)
+ outputConverter = this;
+
+ QVariantList list;
+ QTextStream in(f);
+ QString line ;
+ while (!in.atEnd()) {
+ in.readLineInto(&line);
+
+ bool ok;
+ qint64 v = line.toLongLong(&ok);
+ if (ok) {
+ list.append(v);
+ continue;
+ }
+
+ double d = line.toDouble(&ok);
+ if (ok) {
+ list.append(d);
+ continue;
+ }
+
+ list.append(line);
+ }
+
+ return list;
+}
+
+void TextConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ if (!options.isEmpty()) {
+ fprintf(stderr, "Unknown option '%s' to text output. This format has no options.\n", qPrintable(options.first()));
+ exit(EXIT_FAILURE);
+ }
+
+ QTextStream out(f);
+ dumpVariant(out, contents);
+}
+
+static TextConverter textConverter;
diff --git a/examples/corelib/serialization/convert/textconverter.h b/examples/corelib/serialization/convert/textconverter.h
new file mode 100644
index 0000000000..66f5136c02
--- /dev/null
+++ b/examples/corelib/serialization/convert/textconverter.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTCONVERTER_H
+#define TEXTCONVERTER_H
+
+#include "converter.h"
+
+class TextConverter : public Converter
+{
+
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+#endif // TEXTCONVERTER_H
diff --git a/examples/corelib/serialization/convert/xmlconverter.cpp b/examples/corelib/serialization/convert/xmlconverter.cpp
new file mode 100644
index 0000000000..62908273ce
--- /dev/null
+++ b/examples/corelib/serialization/convert/xmlconverter.cpp
@@ -0,0 +1,514 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xmlconverter.h"
+
+#include <QBitArray>
+#include <QtCborCommon>
+#include <QFile>
+#include <QFloat16>
+#include <QMetaType>
+#include <QRegularExpression>
+#include <QUrl>
+#include <QXmlStreamReader>
+#include <QXmlStreamWriter>
+
+static const char optionHelp[] =
+ "compact=no|yes Use compact XML form.\n";
+
+static XmlConverter xmlConverter;
+
+static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options);
+
+static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options options)
+{
+ QVariantList list;
+ while (!xml.atEnd() && !xml.isEndElement()) {
+ xml.readNext();
+ switch (xml.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ list << variantFromXml(xml, options);
+ continue;
+
+ case QXmlStreamReader::EndElement:
+ continue;
+
+ case QXmlStreamReader::Comment:
+ // ignore comments
+ continue;
+
+ case QXmlStreamReader::Characters:
+ // ignore whitespace
+ if (xml.isWhitespace())
+ continue;
+ Q_FALLTHROUGH();
+
+ default:
+ break;
+ }
+
+ fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(),
+ qPrintable(xml.tokenString()), qPrintable(xml.name().toString()));
+ exit(EXIT_FAILURE);
+ }
+
+ xml.readNext();
+ return list;
+}
+
+static VariantOrderedMap::value_type mapEntryFromXml(QXmlStreamReader &xml, Converter::Options options)
+{
+ QVariant key, value;
+ while (!xml.atEnd() && !xml.isEndElement()) {
+ xml.readNext();
+ switch (xml.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ if (value.isValid())
+ break;
+ if (key.isValid())
+ value = variantFromXml(xml, options);
+ else
+ key = variantFromXml(xml, options);
+ continue;
+
+ case QXmlStreamReader::EndElement:
+ continue;
+
+ case QXmlStreamReader::Comment:
+ // ignore comments
+ continue;
+
+ case QXmlStreamReader::Characters:
+ // ignore whitespace
+ if (xml.isWhitespace())
+ continue;
+ Q_FALLTHROUGH();
+
+ default:
+ break;
+ }
+
+ fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(),
+ qPrintable(xml.tokenString()), qPrintable(xml.name().toString()));
+ exit(EXIT_FAILURE);
+ }
+
+ return { key, value };
+}
+
+static QVariant mapFromXml(QXmlStreamReader &xml, Converter::Options options)
+{
+ QVariantMap map1;
+ VariantOrderedMap map2;
+
+ while (!xml.atEnd() && !xml.isEndElement()) {
+ xml.readNext();
+ switch (xml.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ if (xml.name() == QLatin1String("entry")) {
+ auto pair = mapEntryFromXml(xml, options);
+ if (options & Converter::SupportsArbitraryMapKeys)
+ map2.append(pair);
+ else
+ map1.insert(pair.first.toString(), pair.second);
+ continue;
+ }
+ break;
+
+ case QXmlStreamReader::EndElement:
+ continue;
+
+ case QXmlStreamReader::Comment:
+ // ignore comments
+ continue;
+
+ case QXmlStreamReader::Characters:
+ // ignore whitespace
+ if (xml.isWhitespace())
+ continue;
+ Q_FALLTHROUGH();
+
+ default:
+ break;
+ }
+
+ fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(),
+ qPrintable(xml.tokenString()), qPrintable(xml.name().toString()));
+ exit(EXIT_FAILURE);
+ }
+
+ xml.readNext();
+ if (options & Converter::SupportsArbitraryMapKeys)
+ return QVariant::fromValue(map2);
+ return map1;
+}
+
+static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options)
+{
+ QStringRef name = xml.name();
+ if (name == QLatin1String("list"))
+ return listFromXml(xml, options);
+ if (name == QLatin1String("map"))
+ return mapFromXml(xml, options);
+ if (name != QLatin1String("value")) {
+ fprintf(stderr, "%lld:%lld: Invalid XML key '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(), qPrintable(name.toString()));
+ exit(EXIT_FAILURE);
+ }
+
+ QXmlStreamAttributes attrs = xml.attributes();
+ QStringRef type = attrs.value(QLatin1String("type"));
+
+ forever {
+ xml.readNext();
+ if (xml.isComment())
+ continue;
+ if (xml.isCDATA() || xml.isCharacters() || xml.isEndElement())
+ break;
+
+ fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(),
+ qPrintable(xml.tokenString()), qPrintable(name.toString()));
+ exit(EXIT_FAILURE);
+ }
+
+ QStringRef text = xml.text();
+ if (!xml.isCDATA())
+ text = text.trimmed();
+
+ QVariant result;
+ bool ok;
+ if (type.isEmpty()) {
+ // ok
+ } else if (type == QLatin1String("number")) {
+ // try integer first
+ qint64 v = text.toLongLong(&ok);
+ if (ok) {
+ result = v;
+ } else {
+ // let's see floating point
+ double d = text.toDouble(&ok);
+ result = d;
+ if (!ok) {
+ fprintf(stderr, "%lld:%lld: Invalid XML: could not interpret '%s' as a number.\n",
+ xml.lineNumber(), xml.columnNumber(), qPrintable(text.toString()));
+ exit(EXIT_FAILURE);
+ }
+ }
+ } else if (type == QLatin1String("bytes")) {
+ QByteArray data = text.toLatin1();
+ QStringRef encoding = attrs.value("encoding");
+ if (encoding == QLatin1String("base64url")) {
+ result = QByteArray::fromBase64(data, QByteArray::Base64UrlEncoding);
+ } else if (encoding == QLatin1String("hex")) {
+ result = QByteArray::fromHex(data);
+ } else if (encoding.isEmpty() || encoding == QLatin1String("base64")) {
+ result = QByteArray::fromBase64(data);
+ } else {
+ fprintf(stderr, "%lld:%lld: Invalid XML: unknown encoding '%s' for bytes.\n",
+ xml.lineNumber(), xml.columnNumber(), qPrintable(encoding.toString()));
+ exit(EXIT_FAILURE);
+ }
+ } else if (type == QLatin1String("string")) {
+ result = text.toString();
+ } else if (type == QLatin1String("null")) {
+ result = QVariant::fromValue(nullptr);
+ } else if (type == QLatin1String("CBOR simple type")) {
+ result = QVariant::fromValue(QCborSimpleType(text.toShort()));
+ } else if (type == QLatin1String("bits")) {
+ QBitArray ba;
+ ba.resize(text.size());
+ qsizetype n = 0;
+ for (qsizetype i = 0; i < text.size(); ++i) {
+ QChar c = text.at(i);
+ if (c == '1') {
+ ba.setBit(n++);
+ } else if (c == '0') {
+ ++n;
+ } else if (!c.isSpace()) {
+ fprintf(stderr, "%lld:%lld: Invalid XML: invalid bit string '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(), qPrintable(text.toString()));
+ exit(EXIT_FAILURE);
+ }
+ }
+ ba.resize(n);
+ result = ba;
+ } else {
+ int id = QVariant::Invalid;
+ if (type == QLatin1String("datetime"))
+ id = QVariant::DateTime;
+ else if (type == QLatin1String("url"))
+ id = QVariant::Url;
+ else if (type == QLatin1String("uuid"))
+ id = QVariant::Uuid;
+ else if (type == QLatin1String("regex"))
+ id = QVariant::RegularExpression;
+ else
+ id = QMetaType::type(type.toLatin1());
+ if (id == QVariant::Invalid) {
+ fprintf(stderr, "%lld:%lld: Invalid XML: unknown type '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(), qPrintable(type.toString()));
+ exit(EXIT_FAILURE);
+ }
+
+ result = text.toString();
+ if (!result.convert(id)) {
+ fprintf(stderr, "%lld:%lld: Invalid XML: could not parse content as type '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(), qPrintable(type.toString()));
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ do {
+ xml.readNext();
+ } while (xml.isComment() || xml.isWhitespace());
+
+ if (!xml.isEndElement()) {
+ fprintf(stderr, "%lld:%lld: Invalid XML %s '%s'.\n",
+ xml.lineNumber(), xml.columnNumber(),
+ qPrintable(xml.tokenString()), qPrintable(name.toString()));
+ exit(EXIT_FAILURE);
+ }
+
+ xml.readNext();
+ return result;
+}
+
+static void variantToXml(QXmlStreamWriter &xml, const QVariant &v)
+{
+ int type = v.userType();
+ if (type == QVariant::List) {
+ QVariantList list = v.toList();
+ xml.writeStartElement("list");
+ for (const QVariant &v : list)
+ variantToXml(xml, v);
+ xml.writeEndElement();
+ } else if (type == QVariant::Map || type == qMetaTypeId<VariantOrderedMap>()) {
+ const VariantOrderedMap map = (type == QVariant::Map) ?
+ VariantOrderedMap(v.toMap()) :
+ v.value<VariantOrderedMap>();
+
+ xml.writeStartElement("map");
+ for (const auto &pair : map) {
+ xml.writeStartElement("entry");
+ variantToXml(xml, pair.first);
+ variantToXml(xml, pair.second);
+ xml.writeEndElement();
+ }
+ xml.writeEndElement();
+ } else {
+ xml.writeStartElement("value");
+ QString typeString = QStringLiteral("type");
+ switch (type) {
+ case QMetaType::Short:
+ case QMetaType::UShort:
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ case QMetaType::Long:
+ case QMetaType::ULong:
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong:
+ case QMetaType::Float:
+ case QMetaType::Double:
+ xml.writeAttribute(typeString, "number");
+ xml.writeCharacters(v.toString());
+ break;
+
+ case QMetaType::QByteArray:
+ xml.writeAttribute(typeString, "bytes");
+ xml.writeAttribute("encoding", "base64");
+ xml.writeCharacters(QString::fromLatin1(v.toByteArray().toBase64()));
+ break;
+
+ case QMetaType::QString:
+ xml.writeAttribute(typeString, "string");
+ xml.writeCDATA(v.toString());
+ break;
+
+ case QMetaType::Bool:
+ xml.writeAttribute(typeString, "bool");
+ xml.writeCharacters(v.toString());
+ break;
+
+ case QMetaType::Nullptr:
+ xml.writeAttribute(typeString, "null");
+ break;
+
+ case QMetaType::UnknownType:
+ break;
+
+ case QMetaType::QDate:
+ case QMetaType::QTime:
+ case QMetaType::QDateTime:
+ xml.writeAttribute(typeString, "dateime");
+ xml.writeCharacters(v.toString());
+ break;
+
+ case QMetaType::QUrl:
+ xml.writeAttribute(typeString, "url");
+ xml.writeCharacters(v.toUrl().toString(QUrl::FullyEncoded));
+ break;
+
+ case QMetaType::QUuid:
+ xml.writeAttribute(typeString, "uuid");
+ xml.writeCharacters(v.toString());
+ break;
+
+ case QMetaType::QBitArray:
+ xml.writeAttribute(typeString, "bits");
+ xml.writeCharacters([](const QBitArray &ba) {
+ QString result;
+ for (qsizetype i = 0; i < ba.size(); ++i) {
+ if (i && i % 72 == 0)
+ result += '\n';
+ result += QLatin1Char(ba.testBit(i) ? '1' : '0');
+ }
+ return result;
+ }(v.toBitArray()));
+ break;
+
+ case QMetaType::QRegularExpression:
+ xml.writeAttribute(typeString, "regex");
+ xml.writeCharacters(v.toRegularExpression().pattern());
+ break;
+
+ default:
+ if (type == qMetaTypeId<qfloat16>()) {
+ xml.writeAttribute(typeString, "number");
+ xml.writeCharacters(QString::number(float(v.value<qfloat16>())));
+ } else if (type == qMetaTypeId<QCborSimpleType>()) {
+ xml.writeAttribute(typeString, "CBOR simple type");
+ xml.writeCharacters(QString::number(int(v.value<QCborSimpleType>())));
+ } else {
+ // does this convert to string?
+ const char *typeName = v.typeName();
+ QVariant copy = v;
+ if (copy.convert(QVariant::String)) {
+ xml.writeAttribute(typeString, QString::fromLatin1(typeName));
+ xml.writeCharacters(copy.toString());
+ } else {
+ fprintf(stderr, "XML: don't know how to serialize type '%s'.\n", typeName);
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+ xml.writeEndElement();
+ }
+}
+
+QString XmlConverter::name()
+{
+ return QStringLiteral("xml");
+}
+
+Converter::Direction XmlConverter::directions()
+{
+ return InOut;
+}
+
+Converter::Options XmlConverter::outputOptions()
+{
+ return SupportsArbitraryMapKeys;
+}
+
+const char *XmlConverter::optionsHelp()
+{
+ return optionHelp;
+}
+
+bool XmlConverter::probeFile(QIODevice *f)
+{
+ if (QFile *file = qobject_cast<QFile *>(f)) {
+ if (file->fileName().endsWith(QLatin1String(".xml")))
+ return true;
+ }
+
+ return f->isReadable() && f->peek(5) == "<?xml";
+}
+
+QVariant XmlConverter::loadFile(QIODevice *f, Converter *&outputConverter)
+{
+ if (!outputConverter)
+ outputConverter = this;
+
+ QXmlStreamReader xml(f);
+ xml.readNextStartElement();
+ QVariant v = variantFromXml(xml, outputConverter->outputOptions());
+ if (xml.hasError()) {
+ fprintf(stderr, "XML error: %s", qPrintable(xml.errorString()));
+ exit(EXIT_FAILURE);
+ }
+
+ return v;
+}
+
+void XmlConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options)
+{
+ bool compact = false;
+ for (const QString &s : options) {
+ if (s == QLatin1String("compact=no")) {
+ compact = false;
+ } else if (s == QLatin1String("compact=yes")) {
+ compact = true;
+ } else {
+ fprintf(stderr, "Unknown option '%s' to XML output. Valid options are:\n%s", qPrintable(s), optionHelp);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ QXmlStreamWriter xml(f);
+ xml.setAutoFormatting(!compact);
+ xml.writeStartDocument();
+ variantToXml(xml, contents);
+ xml.writeEndDocument();
+}
diff --git a/examples/corelib/serialization/convert/xmlconverter.h b/examples/corelib/serialization/convert/xmlconverter.h
new file mode 100644
index 0000000000..8fc0fea592
--- /dev/null
+++ b/examples/corelib/serialization/convert/xmlconverter.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XMLCONVERTER_H
+#define XMLCONVERTER_H
+
+#include "converter.h"
+
+class XmlConverter : public Converter
+{
+ // Converter interface
+public:
+ QString name() override;
+ Direction directions() override;
+ Options outputOptions() override;
+ const char *optionsHelp() override;
+ bool probeFile(QIODevice *f) override;
+ QVariant loadFile(QIODevice *f, Converter *&outputConverter) override;
+ void saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) override;
+};
+
+#endif // XMLCONVERTER_H
diff --git a/examples/corelib/serialization/serialization.pro b/examples/corelib/serialization/serialization.pro
index af4d3e6f0f..7651444f19 100644
--- a/examples/corelib/serialization/serialization.pro
+++ b/examples/corelib/serialization/serialization.pro
@@ -1,2 +1,5 @@
TEMPLATE = subdirs
-SUBDIRS = savegame
+SUBDIRS = \
+ cbordump \
+ convert \
+ savegame
diff --git a/examples/corelib/threads/queuedcustomtype/window.cpp b/examples/corelib/threads/queuedcustomtype/window.cpp
index 7b9004d868..2cefba1e17 100644
--- a/examples/corelib/threads/queuedcustomtype/window.cpp
+++ b/examples/corelib/threads/queuedcustomtype/window.cpp
@@ -108,9 +108,8 @@ void Window::loadImage()
void Window::loadImage(const QImage &image)
{
- QDesktopWidget desktop;
QImage useImage;
- QRect space = desktop.availableGeometry();
+ QRect space = QGuiApplication::primaryScreen()->availableGeometry();
if (image.width() > 0.75*space.width() || image.height() > 0.75*space.height())
useImage = image.scaled(0.75*space.width(), 0.75*space.height(),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
diff --git a/examples/examples.pro b/examples/examples.pro
index 4ec5ca60e2..077e5828a9 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -4,8 +4,7 @@ CONFIG += no_docs_target
SUBDIRS = \
corelib \
embedded \
- qpa \
- touch
+ qpa
qtHaveModule(dbus): SUBDIRS += dbus
qtHaveModule(network): SUBDIRS += network
diff --git a/examples/gui/doc/src/rasterwindow.qdoc b/examples/gui/doc/src/rasterwindow.qdoc
index 36612e1707..0c52a62b8e 100644
--- a/examples/gui/doc/src/rasterwindow.qdoc
+++ b/examples/gui/doc/src/rasterwindow.qdoc
@@ -99,9 +99,8 @@
The resize event is guaranteed to be called prior to the window
being shown on screen and will also be called whenever the window
- is resized while on screen. We use this to resize the back buffer
- and call renderNow() if we are visible to immediately update the
- visual representation of the window on screen.
+ is resized while on screen. We use this to resize the back buffer,
+ and defer rendering to the corresponding/following expose event.
\snippet rasterwindow/rasterwindow.cpp 3
diff --git a/examples/gui/rasterwindow/rasterwindow.cpp b/examples/gui/rasterwindow/rasterwindow.cpp
index 3eacd20145..4dd2ac25ca 100644
--- a/examples/gui/rasterwindow/rasterwindow.cpp
+++ b/examples/gui/rasterwindow/rasterwindow.cpp
@@ -83,8 +83,6 @@ void RasterWindow::renderLater()
void RasterWindow::resizeEvent(QResizeEvent *resizeEvent)
{
m_backingStore->resize(resizeEvent->size());
- if (isExposed())
- renderNow();
}
//! [5]
@@ -109,7 +107,7 @@ void RasterWindow::renderNow()
QPaintDevice *device = m_backingStore->paintDevice();
QPainter painter(device);
- painter.fillRect(0, 0, width(), height(), Qt::white);
+ painter.fillRect(0, 0, width(), height(), QGradient::NightFade);
render(&painter);
painter.end();
diff --git a/examples/network/doc/images/secureudpclient-example.png b/examples/network/doc/images/secureudpclient-example.png
new file mode 100644
index 0000000000..a566aa4ce5
--- /dev/null
+++ b/examples/network/doc/images/secureudpclient-example.png
Binary files differ
diff --git a/examples/network/doc/images/secureudpserver-example.png b/examples/network/doc/images/secureudpserver-example.png
new file mode 100644
index 0000000000..a117b02834
--- /dev/null
+++ b/examples/network/doc/images/secureudpserver-example.png
Binary files differ
diff --git a/examples/network/doc/src/secureudpclient.qdoc b/examples/network/doc/src/secureudpclient.qdoc
new file mode 100644
index 0000000000..dc8538cf85
--- /dev/null
+++ b/examples/network/doc/src/secureudpclient.qdoc
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example secureudpclient
+ \title DTLS client
+ \ingroup examples-network
+ \brief This example demonstrates how to implement client-side DTLS connections.
+
+ \image secureudpclient-example.png Screenshot of the DTLS client example.
+
+ \note The DTLS client example is intended to be run alongside the \l{secureudpserver}{DTLS server} example.
+
+ The example DTLS client can establish several DTLS connections to one
+ or many DTLS servers. A client-side DTLS connection is implemented by the
+ DtlsAssociation class. This class uses QUdpSocket to read and write datagrams
+ and QDtls for encryption:
+
+ \snippet secureudpclient/association.h 0
+
+ The constructor sets the minimal TLS configuration for the new DTLS connection,
+ and sets the address and the port of the server:
+
+ \dots
+ \snippet secureudpclient/association.cpp 1
+ \dots
+
+ The QDtls::handshakeTimeout() signal is connected to the handleTimeout() slot
+ to deal with packet loss and retransmission during the handshake phase:
+
+ \dots
+ \snippet secureudpclient/association.cpp 2
+ \dots
+
+ To ensure we receive only the datagrams from the server, we connect our UDP socket to the server:
+
+ \dots
+ \snippet secureudpclient/association.cpp 3
+ \dots
+
+ The QUdpSocket::readyRead() signal is connected to the readyRead() slot:
+
+ \dots
+ \snippet secureudpclient/association.cpp 13
+ \dots
+
+ When a secure connection to a server is established, a DtlsAssociation object
+ will be sending short ping messages to the server, using a timer:
+
+ \snippet secureudpclient/association.cpp 4
+
+ startHandshake() starts a handshake with the server:
+
+ \snippet secureudpclient/association.cpp 5
+
+ The readyRead() slot reads a datagram sent by the server:
+
+ \snippet secureudpclient/association.cpp 6
+
+ If the handshake was already completed, this datagram is decrypted:
+
+ \snippet secureudpclient/association.cpp 7
+
+ otherwise, we try to continue the handshake:
+
+ \snippet secureudpclient/association.cpp 8
+
+ When the handshake has completed, we send our first ping message:
+
+ \snippet secureudpclient/association.cpp 9
+
+ The pskRequired() slot provides the Pre-Shared Key (PSK) needed during the handshake
+ phase:
+
+ \snippet secureudpclient/association.cpp 14
+
+ \note For the sake of brevity, the definition of pskRequired() is oversimplified.
+ The documentation for the QSslPreSharedKeyAuthenticator class explains in detail
+ how this slot can be properly implemented.
+
+ pingTimeout() sends an encrypted message to the server:
+
+ \snippet secureudpclient/association.cpp 10
+
+ During the handshake phase the client must handle possible timeouts, which
+ can happen due to packet loss. The handshakeTimeout() slot retransmits
+ the handshake messages:
+
+ \snippet secureudpclient/association.cpp 11
+
+ Before a client connection is destroyed, its DTLS connection must be shut down:
+
+ \snippet secureudpclient/association.cpp 12
+
+ Error messages, informational messages, and decrypted responses from servers
+ are displayed by the UI:
+
+ \snippet secureudpclient/mainwindow.cpp 0
+*/
+
diff --git a/examples/network/doc/src/secureudpserver.qdoc b/examples/network/doc/src/secureudpserver.qdoc
new file mode 100644
index 0000000000..0857f7065f
--- /dev/null
+++ b/examples/network/doc/src/secureudpserver.qdoc
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example secureudpserver
+ \title DTLS server
+ \ingroup examples-network
+ \brief This examples demonstrates how to implement a simple DTLS server.
+
+ \image secureudpserver-example.png Screenshot of the DTLS server example.
+
+ \note The DTLS server example is intended to be run alongside the \l{secureudpclient}{DTLS client} example.
+
+ The server is implemented by the DtlsServer class. It uses QUdpSocket,
+ QDtlsClientVerifier, and QDtls to test each client's reachability, complete a handshake,
+ and read and write encrypted messages.
+
+ \snippet secureudpserver/server.h 0
+
+ The constructor connects the QUdpSocket::readyRead() signal to its
+ readyRead() slot and sets the minimal needed TLS configuration:
+
+ \snippet secureudpserver/server.cpp 1
+
+ \note The server is not using a certificate and is relying on Pre-Shared
+ Key (PSK) handshake.
+
+ listen() binds QUdpSocket:
+
+ \snippet secureudpserver/server.cpp 2
+
+ The readyRead() slot processes incoming datagrams:
+
+ \dots
+ \snippet secureudpserver/server.cpp 3
+ \dots
+
+ After extracting an address and a port number, the server first tests
+ if it's a datagram from an already known peer:
+
+ \dots
+ \snippet secureudpserver/server.cpp 4
+ \dots
+
+ If it is a new, unknown address and port, the datagram is processed as a
+ potential ClientHello message, sent by a DTLS client:
+
+ \dots
+ \snippet secureudpserver/server.cpp 5
+ \dots
+
+ If it's a known DTLS client, the server either decrypts the datagram:
+
+ \dots
+ \snippet secureudpserver/server.cpp 6
+ \dots
+
+ or continues a handshake with this peer:
+
+ \dots
+ \snippet secureudpserver/server.cpp 7
+ \dots
+
+ handleNewConnection() verifies it's a reachable DTLS client, or sends a
+ HelloVerifyRequest:
+
+ \snippet secureudpserver/server.cpp 8
+ \dots
+
+ If the new client was verified to be a reachable DTLS client, the server creates
+ and configures a new QDtls object, and starts a server-side handshake:
+
+ \dots
+ \snippet secureudpserver/server.cpp 9
+ \dots
+
+ doHandshake() progresses through the handshake phase:
+
+ \snippet secureudpserver/server.cpp 11
+
+ During the handshake phase, the QDtls::pskRequired() signal is emitted and
+ the pskRequired() slot provides the preshared key:
+
+ \snippet secureudpserver/server.cpp 13
+
+ \note For the sake of brevity, the definition of pskRequired() is oversimplified.
+ The documentation for the QSslPreSharedKeyAuthenticator class explains in detail
+ how this slot can be properly implemented.
+
+ After the handshake is completed for the network peer, an encrypted DTLS
+ connection is considered to be established and the server decrypts subsequent
+ datagrams, sent by the peer, by calling decryptDatagram(). The server also
+ sends an encrypted response to the peer:
+
+ \snippet secureudpserver/server.cpp 12
+
+ The server closes its DTLS connections by calling QDtls::shutdown():
+
+ \snippet secureudpserver/server.cpp 14
+
+ During its operation, the server reports errors, informational messages, and
+ decrypted datagrams, by emitting signals errorMessage(), warningMessage(),
+ infoMessage(), and datagramReceived(). These messages are logged by the server's
+ UI:
+
+ \snippet secureudpserver/mainwindow.cpp 0
+*/
diff --git a/examples/network/loopback/dialog.cpp b/examples/network/loopback/dialog.cpp
index 99317b9c77..b4e6b0fd5e 100644
--- a/examples/network/loopback/dialog.cpp
+++ b/examples/network/loopback/dialog.cpp
@@ -48,11 +48,11 @@
**
****************************************************************************/
-#include <QtWidgets>
-#include <QtNetwork>
-
#include "dialog.h"
+#include <QtNetwork>
+#include <QtWidgets>
+
static const int TotalBytes = 50 * 1024 * 1024;
static const int PayloadSize = 64 * 1024; // 64 KB
@@ -71,15 +71,15 @@ Dialog::Dialog(QWidget *parent)
buttonBox->addButton(startButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
- connect(startButton, SIGNAL(clicked()), this, SLOT(start()));
- connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
- connect(&tcpServer, SIGNAL(newConnection()),
- this, SLOT(acceptConnection()));
- connect(&tcpClient, SIGNAL(connected()), this, SLOT(startTransfer()));
- connect(&tcpClient, SIGNAL(bytesWritten(qint64)),
- this, SLOT(updateClientProgress(qint64)));
- connect(&tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
- this, SLOT(displayError(QAbstractSocket::SocketError)));
+ connect(startButton, &QAbstractButton::clicked, this, &Dialog::start);
+ connect(quitButton, &QAbstractButton::clicked, this, &QWidget::close);
+ connect(&tcpServer, &QTcpServer::newConnection,
+ this, &Dialog::acceptConnection);
+ connect(&tcpClient, &QAbstractSocket::connected, this, &Dialog::startTransfer);
+ connect(&tcpClient, &QIODevice::bytesWritten,
+ this, &Dialog::updateClientProgress);
+ connect(&tcpClient, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
+ this, &Dialog::displayError);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(clientProgressBar);
@@ -124,10 +124,18 @@ void Dialog::start()
void Dialog::acceptConnection()
{
tcpServerConnection = tcpServer.nextPendingConnection();
- connect(tcpServerConnection, SIGNAL(readyRead()),
- this, SLOT(updateServerProgress()));
- connect(tcpServerConnection, SIGNAL(error(QAbstractSocket::SocketError)),
- this, SLOT(displayError(QAbstractSocket::SocketError)));
+ if (!tcpServerConnection) {
+ serverStatusLabel->setText(tr("Error: got invalid pending connection!"));
+ return;
+ }
+
+ connect(tcpServerConnection, &QIODevice::readyRead,
+ this, &Dialog::updateServerProgress);
+ connect(tcpServerConnection,
+ QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
+ this, &Dialog::displayError);
+ connect(tcpServerConnection, &QTcpSocket::disconnected,
+ tcpServerConnection, &QTcpSocket::deleteLater);
serverStatusLabel->setText(tr("Accepted connection"));
tcpServer.close();
@@ -136,13 +144,13 @@ void Dialog::acceptConnection()
void Dialog::startTransfer()
{
// called when the TCP client connected to the loopback server
- bytesToWrite = TotalBytes - (int)tcpClient.write(QByteArray(PayloadSize, '@'));
+ bytesToWrite = TotalBytes - int(tcpClient.write(QByteArray(PayloadSize, '@')));
clientStatusLabel->setText(tr("Connected"));
}
void Dialog::updateServerProgress()
{
- bytesReceived += (int)tcpServerConnection->bytesAvailable();
+ bytesReceived += int(tcpServerConnection->bytesAvailable());
tcpServerConnection->readAll();
serverProgressBar->setMaximum(TotalBytes);
@@ -161,17 +169,16 @@ void Dialog::updateServerProgress()
void Dialog::updateClientProgress(qint64 numBytes)
{
- // callen when the TCP client has written some bytes
- bytesWritten += (int)numBytes;
+ // called when the TCP client has written some bytes
+ bytesWritten += int(numBytes);
// only write more if not finished and when the Qt write buffer is below a certain size.
- if (bytesToWrite > 0 && tcpClient.bytesToWrite() <= 4*PayloadSize)
- bytesToWrite -= (int)tcpClient.write(QByteArray(qMin(bytesToWrite, PayloadSize), '@'));
+ if (bytesToWrite > 0 && tcpClient.bytesToWrite() <= 4 * PayloadSize)
+ bytesToWrite -= tcpClient.write(QByteArray(qMin(bytesToWrite, PayloadSize), '@'));
clientProgressBar->setMaximum(TotalBytes);
clientProgressBar->setValue(bytesWritten);
- clientStatusLabel->setText(tr("Sent %1MB")
- .arg(bytesWritten / (1024 * 1024)));
+ clientStatusLabel->setText(tr("Sent %1MB").arg(bytesWritten / (1024 * 1024)));
}
void Dialog::displayError(QAbstractSocket::SocketError socketError)
diff --git a/examples/network/loopback/dialog.h b/examples/network/loopback/dialog.h
index b23cfa030b..a70c20550a 100644
--- a/examples/network/loopback/dialog.h
+++ b/examples/network/loopback/dialog.h
@@ -60,9 +60,6 @@ class QDialogButtonBox;
class QLabel;
class QProgressBar;
class QPushButton;
-class QTcpServer;
-class QTcpSocket;
-class QAction;
QT_END_NAMESPACE
class Dialog : public QDialog
@@ -70,7 +67,7 @@ class Dialog : public QDialog
Q_OBJECT
public:
- Dialog(QWidget *parent = 0);
+ Dialog(QWidget *parent = nullptr);
public slots:
void start();
@@ -81,21 +78,21 @@ public slots:
void displayError(QAbstractSocket::SocketError socketError);
private:
- QProgressBar *clientProgressBar;
- QProgressBar *serverProgressBar;
- QLabel *clientStatusLabel;
- QLabel *serverStatusLabel;
+ QProgressBar *clientProgressBar = nullptr;
+ QProgressBar *serverProgressBar = nullptr;
+ QLabel *clientStatusLabel = nullptr;
+ QLabel *serverStatusLabel = nullptr;
- QPushButton *startButton;
- QPushButton *quitButton;
- QDialogButtonBox *buttonBox;
+ QPushButton *startButton = nullptr;
+ QPushButton *quitButton = nullptr;
+ QDialogButtonBox *buttonBox = nullptr;
QTcpServer tcpServer;
QTcpSocket tcpClient;
- QTcpSocket *tcpServerConnection;
- int bytesToWrite;
- int bytesWritten;
- int bytesReceived;
+ QTcpSocket *tcpServerConnection = nullptr;
+ int bytesToWrite = 0;
+ int bytesWritten = 0;
+ int bytesReceived = 0;
};
#endif
diff --git a/examples/network/loopback/main.cpp b/examples/network/loopback/main.cpp
index 9959c472f4..094a11d4fc 100644
--- a/examples/network/loopback/main.cpp
+++ b/examples/network/loopback/main.cpp
@@ -48,10 +48,10 @@
**
****************************************************************************/
-#include <QApplication>
-
#include "dialog.h"
+#include <QApplication>
+
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
diff --git a/examples/network/network-chat/client.cpp b/examples/network/network-chat/client.cpp
index c1eda52a0c..97c2c44b6b 100644
--- a/examples/network/network-chat/client.cpp
+++ b/examples/network/network-chat/client.cpp
@@ -78,7 +78,7 @@ void Client::sendMessage(const QString &message)
QString Client::nickName() const
{
- return QString(peerManager->userName()) + '@' + QHostInfo::localHostName()
+ return peerManager->userName() + '@' + QHostInfo::localHostName()
+ ':' + QString::number(server.serverPort());
}
diff --git a/examples/network/network-chat/connection.cpp b/examples/network/network-chat/connection.cpp
index 332d5dc56b..58cf67eb6d 100644
--- a/examples/network/network-chat/connection.cpp
+++ b/examples/network/network-chat/connection.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@@ -55,17 +56,29 @@
static const int TransferTimeout = 30 * 1000;
static const int PongTimeout = 60 * 1000;
static const int PingInterval = 5 * 1000;
-static const char SeparatorToken = ' ';
+
+/*
+ * Protocol is defined as follows, using the CBOR Data Definition Language:
+ *
+ * protocol = [
+ * greeting, ; must start with a greeting command
+ * * command ; zero or more regular commands after
+ * ]
+ * command = plaintext / ping / pong / greeting
+ * plaintext = { 0 => text }
+ * ping = { 1 => null }
+ * pong = { 2 => null }
+ * greeting = { 3 => text }
+ */
Connection::Connection(QObject *parent)
- : QTcpSocket(parent)
+ : QTcpSocket(parent), writer(this)
{
greetingMessage = tr("undefined");
username = tr("unknown");
state = WaitingForGreeting;
currentDataType = Undefined;
- numBytesForCurrentDataType = -1;
- transferTimerId = 0;
+ transferTimerId = -1;
isGreetingMessageSent = false;
pingTimer.setInterval(PingInterval);
@@ -76,6 +89,22 @@ Connection::Connection(QObject *parent)
this, SLOT(sendGreetingMessage()));
}
+Connection::Connection(qintptr socketDescriptor, QObject *parent)
+ : Connection(parent)
+{
+ setSocketDescriptor(socketDescriptor);
+ reader.setDevice(this);
+}
+
+Connection::~Connection()
+{
+ if (isGreetingMessageSent) {
+ // Indicate clean shutdown.
+ writer.endArray();
+ waitForBytesWritten(2000);
+ }
+}
+
QString Connection::name() const
{
return username;
@@ -91,9 +120,11 @@ bool Connection::sendMessage(const QString &message)
if (message.isEmpty())
return false;
- QByteArray msg = message.toUtf8();
- QByteArray data = "MESSAGE " + QByteArray::number(msg.size()) + ' ' + msg;
- return write(data) == data.size();
+ writer.startMap(1);
+ writer.append(PlainText);
+ writer.append(message);
+ writer.endMap();
+ return true;
}
void Connection::timerEvent(QTimerEvent *timerEvent)
@@ -101,61 +132,75 @@ void Connection::timerEvent(QTimerEvent *timerEvent)
if (timerEvent->timerId() == transferTimerId) {
abort();
killTimer(transferTimerId);
- transferTimerId = 0;
+ transferTimerId = -1;
}
}
void Connection::processReadyRead()
{
- if (state == WaitingForGreeting) {
- if (!readProtocolHeader())
- return;
- if (currentDataType != Greeting) {
- abort();
- return;
+ // we've got more data, let's parse
+ reader.reparse();
+ while (reader.lastError() == QCborError::NoError) {
+ if (state == WaitingForGreeting) {
+ if (!reader.isArray())
+ break; // protocol error
+
+ reader.enterContainer(); // we'll be in this array forever
+ state = ReadingGreeting;
+ } else if (reader.containerDepth() == 1) {
+ // Current state: no command read
+ // Next state: read command ID
+ if (!reader.hasNext()) {
+ reader.leaveContainer();
+ disconnectFromHost();
+ return;
+ }
+
+ if (!reader.isMap() || !reader.isLengthKnown() || reader.length() != 1)
+ break; // protocol error
+ reader.enterContainer();
+ } else if (currentDataType == Undefined) {
+ // Current state: read command ID
+ // Next state: read command payload
+ if (!reader.isInteger())
+ break; // protocol error
+ currentDataType = DataType(reader.toInteger());
+ reader.next();
+ } else {
+ // Current state: read command payload
+ if (reader.isString()) {
+ auto r = reader.readString();
+ buffer += r.data;
+ if (r.status != QCborStreamReader::EndOfString)
+ continue;
+ } else if (reader.isNull()) {
+ reader.next();
+ } else {
+ break; // protocol error
+ }
+
+ // Next state: no command read
+ reader.leaveContainer();
+ if (transferTimerId != -1) {
+ killTimer(transferTimerId);
+ transferTimerId = -1;
+ }
+
+ if (state == ReadingGreeting) {
+ if (currentDataType != Greeting)
+ break; // protocol error
+ processGreeting();
+ } else {
+ processData();
+ }
}
- state = ReadingGreeting;
}
- if (state == ReadingGreeting) {
- if (!hasEnoughData())
- return;
-
- buffer = read(numBytesForCurrentDataType);
- if (buffer.size() != numBytesForCurrentDataType) {
- abort();
- return;
- }
-
- username = QString(buffer) + '@' + peerAddress().toString() + ':'
- + QString::number(peerPort());
- currentDataType = Undefined;
- numBytesForCurrentDataType = 0;
- buffer.clear();
-
- if (!isValid()) {
- abort();
- return;
- }
-
- if (!isGreetingMessageSent)
- sendGreetingMessage();
-
- pingTimer.start();
- pongTime.start();
- state = ReadyForUse;
- emit readyForUse();
- }
+ if (reader.lastError() != QCborError::EndOfFile)
+ abort(); // parse error
- do {
- if (currentDataType == Undefined) {
- if (!readProtocolHeader())
- return;
- }
- if (!hasEnoughData())
- return;
- processData();
- } while (bytesAvailable() > 0);
+ if (transferTimerId != -1 && reader.containerDepth() > 1)
+ transferTimerId = startTimer(TransferTimeout);
}
void Connection::sendPing()
@@ -165,112 +210,58 @@ void Connection::sendPing()
return;
}
- write("PING 1 p");
+ writer.startMap(1);
+ writer.append(Ping);
+ writer.append(nullptr); // no payload
+ writer.endMap();
}
void Connection::sendGreetingMessage()
{
- QByteArray greeting = greetingMessage.toUtf8();
- QByteArray data = "GREETING " + QByteArray::number(greeting.size()) + ' ' + greeting;
- if (write(data) == data.size())
- isGreetingMessageSent = true;
-}
+ writer.startArray(); // this array never ends
-int Connection::readDataIntoBuffer(int maxSize)
-{
- if (maxSize > MaxBufferSize)
- return 0;
+ writer.startMap(1);
+ writer.append(Greeting);
+ writer.append(greetingMessage);
+ writer.endMap();
+ isGreetingMessageSent = true;
- int numBytesBeforeRead = buffer.size();
- if (numBytesBeforeRead == MaxBufferSize) {
- abort();
- return 0;
- }
-
- while (bytesAvailable() > 0 && buffer.size() < maxSize) {
- buffer.append(read(1));
- if (buffer.endsWith(SeparatorToken))
- break;
- }
- return buffer.size() - numBytesBeforeRead;
+ if (!reader.device())
+ reader.setDevice(this);
}
-int Connection::dataLengthForCurrentDataType()
+void Connection::processGreeting()
{
- if (bytesAvailable() <= 0 || readDataIntoBuffer() <= 0
- || !buffer.endsWith(SeparatorToken))
- return 0;
-
- buffer.chop(1);
- int number = buffer.toInt();
+ username = buffer + '@' + peerAddress().toString() + ':'
+ + QString::number(peerPort());
+ currentDataType = Undefined;
buffer.clear();
- return number;
-}
-
-bool Connection::readProtocolHeader()
-{
- if (transferTimerId) {
- killTimer(transferTimerId);
- transferTimerId = 0;
- }
-
- if (readDataIntoBuffer() <= 0) {
- transferTimerId = startTimer(TransferTimeout);
- return false;
- }
- if (buffer == "PING ") {
- currentDataType = Ping;
- } else if (buffer == "PONG ") {
- currentDataType = Pong;
- } else if (buffer == "MESSAGE ") {
- currentDataType = PlainText;
- } else if (buffer == "GREETING ") {
- currentDataType = Greeting;
- } else {
- currentDataType = Undefined;
+ if (!isValid()) {
abort();
- return false;
- }
-
- buffer.clear();
- numBytesForCurrentDataType = dataLengthForCurrentDataType();
- return true;
-}
-
-bool Connection::hasEnoughData()
-{
- if (transferTimerId) {
- QObject::killTimer(transferTimerId);
- transferTimerId = 0;
+ return;
}
- if (numBytesForCurrentDataType <= 0)
- numBytesForCurrentDataType = dataLengthForCurrentDataType();
-
- if (bytesAvailable() < numBytesForCurrentDataType
- || numBytesForCurrentDataType <= 0) {
- transferTimerId = startTimer(TransferTimeout);
- return false;
- }
+ if (!isGreetingMessageSent)
+ sendGreetingMessage();
- return true;
+ pingTimer.start();
+ pongTime.start();
+ state = ReadyForUse;
+ emit readyForUse();
}
void Connection::processData()
{
- buffer = read(numBytesForCurrentDataType);
- if (buffer.size() != numBytesForCurrentDataType) {
- abort();
- return;
- }
-
switch (currentDataType) {
case PlainText:
- emit newMessage(username, QString::fromUtf8(buffer));
+ emit newMessage(username, buffer);
break;
case Ping:
- write("PONG 1 p");
+ writer.startMap(1);
+ writer.append(Pong);
+ writer.append(nullptr); // no payload
+ writer.endMap();
break;
case Pong:
pongTime.restart();
@@ -280,6 +271,5 @@ void Connection::processData()
}
currentDataType = Undefined;
- numBytesForCurrentDataType = 0;
buffer.clear();
}
diff --git a/examples/network/network-chat/connection.h b/examples/network/network-chat/connection.h
index 67d25d4d1e..fa0671a522 100644
--- a/examples/network/network-chat/connection.h
+++ b/examples/network/network-chat/connection.h
@@ -51,10 +51,12 @@
#ifndef CONNECTION_H
#define CONNECTION_H
+#include <QCborStreamReader>
+#include <QCborStreamWriter>
+#include <QElapsedTimer>
#include <QHostAddress>
#include <QString>
#include <QTcpSocket>
-#include <QTime>
#include <QTimer>
static const int MaxBufferSize = 1024000;
@@ -78,6 +80,8 @@ public:
};
Connection(QObject *parent = 0);
+ Connection(qintptr socketDescriptor, QObject *parent = 0);
+ ~Connection();
QString name() const;
void setGreetingMessage(const QString &message);
@@ -96,20 +100,19 @@ private slots:
void sendGreetingMessage();
private:
- int readDataIntoBuffer(int maxSize = MaxBufferSize);
- int dataLengthForCurrentDataType();
- bool readProtocolHeader();
bool hasEnoughData();
+ void processGreeting();
void processData();
+ QCborStreamReader reader;
+ QCborStreamWriter writer;
QString greetingMessage;
QString username;
QTimer pingTimer;
- QTime pongTime;
- QByteArray buffer;
+ QElapsedTimer pongTime;
+ QString buffer;
ConnectionState state;
DataType currentDataType;
- int numBytesForCurrentDataType;
int transferTimerId;
bool isGreetingMessageSent;
};
diff --git a/examples/network/network-chat/peermanager.cpp b/examples/network/network-chat/peermanager.cpp
index c70cc5e56d..38fa2e8e50 100644
--- a/examples/network/network-chat/peermanager.cpp
+++ b/examples/network/network-chat/peermanager.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
@@ -62,16 +63,14 @@ PeerManager::PeerManager(Client *client)
{
this->client = client;
- QStringList envVariables;
- envVariables << "USERNAME" << "USER" << "USERDOMAIN"
- << "HOSTNAME" << "DOMAINNAME";
+ static const char *envVariables[] = {
+ "USERNAME", "USER", "USERDOMAIN", "HOSTNAME", "DOMAINNAME"
+ };
- QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
- foreach (QString string, envVariables) {
- if (environment.contains(string)) {
- username = environment.value(string).toUtf8();
+ for (const char *varname : envVariables) {
+ username = qEnvironmentVariable(varname);
+ if (!username.isNull())
break;
- }
}
if (username.isEmpty())
@@ -95,7 +94,7 @@ void PeerManager::setServerPort(int port)
serverPort = port;
}
-QByteArray PeerManager::userName() const
+QString PeerManager::userName() const
{
return username;
}
@@ -108,7 +107,7 @@ void PeerManager::startBroadcasting()
bool PeerManager::isLocalHostAddress(const QHostAddress &address)
{
foreach (QHostAddress localAddress, ipAddresses) {
- if (address == localAddress)
+ if (address.isEqual(localAddress))
return true;
}
return false;
@@ -116,9 +115,14 @@ bool PeerManager::isLocalHostAddress(const QHostAddress &address)
void PeerManager::sendBroadcastDatagram()
{
- QByteArray datagram(username);
- datagram.append('@');
- datagram.append(QByteArray::number(serverPort));
+ QByteArray datagram;
+ {
+ QCborStreamWriter writer(&datagram);
+ writer.startArray(2);
+ writer.append(username);
+ writer.append(serverPort);
+ writer.endArray();
+ }
bool validBroadcastAddresses = true;
foreach (QHostAddress address, broadcastAddresses) {
@@ -142,11 +146,27 @@ void PeerManager::readBroadcastDatagram()
&senderIp, &senderPort) == -1)
continue;
- QList<QByteArray> list = datagram.split('@');
- if (list.size() != 2)
- continue;
+ int senderServerPort;
+ {
+ // decode the datagram
+ QCborStreamReader reader(datagram);
+ if (reader.lastError() != QCborError::NoError || !reader.isArray())
+ continue;
+ if (!reader.isLengthKnown() || reader.length() != 2)
+ continue;
+
+ reader.enterContainer();
+ if (reader.lastError() != QCborError::NoError || !reader.isString())
+ continue;
+ while (reader.readString().status == QCborStreamReader::Ok) {
+ // we don't actually need the username right now
+ }
+
+ if (reader.lastError() != QCborError::NoError || !reader.isUnsignedInteger())
+ continue;
+ senderServerPort = reader.toInteger();
+ }
- int senderServerPort = list.at(1).toInt();
if (isLocalHostAddress(senderIp) && senderServerPort == serverPort)
continue;
diff --git a/examples/network/network-chat/peermanager.h b/examples/network/network-chat/peermanager.h
index 0bcd67579c..b79028235b 100644
--- a/examples/network/network-chat/peermanager.h
+++ b/examples/network/network-chat/peermanager.h
@@ -68,7 +68,7 @@ public:
PeerManager(Client *client);
void setServerPort(int port);
- QByteArray userName() const;
+ QString userName() const;
void startBroadcasting();
bool isLocalHostAddress(const QHostAddress &address);
@@ -87,7 +87,7 @@ private:
QList<QHostAddress> ipAddresses;
QUdpSocket broadcastSocket;
QTimer broadcastTimer;
- QByteArray username;
+ QString username;
int serverPort;
};
diff --git a/examples/network/network-chat/server.cpp b/examples/network/network-chat/server.cpp
index cc154728d5..b3e4a07f60 100644
--- a/examples/network/network-chat/server.cpp
+++ b/examples/network/network-chat/server.cpp
@@ -61,7 +61,6 @@ Server::Server(QObject *parent)
void Server::incomingConnection(qintptr socketDescriptor)
{
- Connection *connection = new Connection(this);
- connection->setSocketDescriptor(socketDescriptor);
+ Connection *connection = new Connection(socketDescriptor, this);
emit newConnection(connection);
}
diff --git a/examples/network/network.pro b/examples/network/network.pro
index d64b16c760..93049014eb 100644
--- a/examples/network/network.pro
+++ b/examples/network/network.pro
@@ -29,7 +29,12 @@ qtHaveModule(widgets) {
}
- qtConfig(openssl): SUBDIRS += securesocketclient
+ qtConfig(openssl) {
+ SUBDIRS += \
+ securesocketclient \
+ secureudpserver \
+ secureudpclient
+ }
qtConfig(sctp): SUBDIRS += multistreamserver multistreamclient
}
diff --git a/examples/network/secureudpclient/addressdialog.cpp b/examples/network/secureudpclient/addressdialog.cpp
new file mode 100644
index 0000000000..ccb58c853c
--- /dev/null
+++ b/examples/network/secureudpclient/addressdialog.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "addressdialog.h"
+#include "ui_addressdialog.h"
+
+#include <QtCore>
+#include <QtNetwork>
+#include <QtWidgets>
+
+#include <limits>
+
+AddressDialog::AddressDialog(QWidget *parent)
+ : QDialog(parent),
+ ui(new Ui::AddressDialog)
+{
+ ui->setupUi(this);
+ setupHostSelector();
+ setupPortSelector();
+}
+
+AddressDialog::~AddressDialog()
+{
+ delete ui;
+}
+
+QString AddressDialog::remoteName() const
+{
+ if (ui->addressSelector->count())
+ return ui->addressSelector->currentText();
+ return {};
+}
+
+quint16 AddressDialog::remotePort() const
+{
+ return quint16(ui->portSelector->text().toUInt());
+}
+
+void AddressDialog::setupHostSelector()
+{
+ QString name(QHostInfo::localHostName());
+ if (!name.isEmpty()) {
+ ui->addressSelector->addItem(name);
+ const QString domain = QHostInfo::localDomainName();
+ if (!domain.isEmpty())
+ ui->addressSelector->addItem(name + QChar('.') + domain);
+ }
+
+ if (name != QStringLiteral("localhost"))
+ ui->addressSelector->addItem(QStringLiteral("localhost"));
+
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ for (const QHostAddress &ipAddress : ipAddressesList) {
+ if (!ipAddress.isLoopback())
+ ui->addressSelector->addItem(ipAddress.toString());
+ }
+
+ ui->addressSelector->insertSeparator(ui->addressSelector->count());
+
+ for (const QHostAddress &ipAddress : ipAddressesList) {
+ if (ipAddress.isLoopback())
+ ui->addressSelector->addItem(ipAddress.toString());
+ }
+}
+
+void AddressDialog::setupPortSelector()
+{
+ ui->portSelector->setValidator(new QIntValidator(0, std::numeric_limits<quint16>::max(),
+ ui->portSelector));
+ ui->portSelector->setText(QStringLiteral("22334"));
+}
diff --git a/examples/network/secureudpclient/addressdialog.h b/examples/network/secureudpclient/addressdialog.h
new file mode 100644
index 0000000000..43792faa4b
--- /dev/null
+++ b/examples/network/secureudpclient/addressdialog.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef ADDRESSDIALOG_H
+#define ADDRESSDIALOG_H
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+
+class AddressDialog;
+
+}
+
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+class AddressDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit AddressDialog(QWidget *parent = nullptr);
+ ~AddressDialog();
+
+ QString remoteName() const;
+ quint16 remotePort() const;
+
+private:
+ void setupHostSelector();
+ void setupPortSelector();
+
+ Ui::AddressDialog *ui = nullptr;
+};
+
+#endif // ADDRESSDIALOG_H
diff --git a/examples/network/secureudpclient/addressdialog.ui b/examples/network/secureudpclient/addressdialog.ui
new file mode 100644
index 0000000000..a7d9bdc253
--- /dev/null
+++ b/examples/network/secureudpclient/addressdialog.ui
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AddressDialog</class>
+ <widget class="QDialog" name="AddressDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>548</width>
+ <height>143</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Host info</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Host name (server's address):</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="addressSelector">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>320</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>320</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <property name="frame">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Server port:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="portSelector">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>320</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>320</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>AddressDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>AddressDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/network/secureudpclient/association.cpp b/examples/network/secureudpclient/association.cpp
new file mode 100644
index 0000000000..c950260078
--- /dev/null
+++ b/examples/network/secureudpclient/association.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "association.h"
+
+QT_BEGIN_NAMESPACE
+
+DtlsAssociation::DtlsAssociation(const QHostAddress &address, quint16 port,
+ const QString &connectionName)
+ : name(connectionName),
+ crypto(QSslSocket::SslClientMode)
+{
+ //! [1]
+ auto configuration = QSslConfiguration::defaultDtlsConfiguration();
+ configuration.setPeerVerifyMode(QSslSocket::VerifyNone);
+ crypto.setPeer(address, port);
+ crypto.setDtlsConfiguration(configuration);
+ //! [1]
+
+ //! [2]
+ connect(&crypto, &QDtls::handshakeTimeout, this, &DtlsAssociation::handshakeTimeout);
+ //! [2]
+ connect(&crypto, &QDtls::pskRequired, this, &DtlsAssociation::pskRequired);
+ //! [3]
+ socket.connectToHost(address.toString(), port);
+ //! [3]
+ //! [13]
+ connect(&socket, &QUdpSocket::readyRead, this, &DtlsAssociation::readyRead);
+ //! [13]
+ //! [4]
+ pingTimer.setInterval(5000);
+ connect(&pingTimer, &QTimer::timeout, this, &DtlsAssociation::pingTimeout);
+ //! [4]
+}
+
+//! [12]
+DtlsAssociation::~DtlsAssociation()
+{
+ if (crypto.isConnectionEncrypted())
+ crypto.shutdown(&socket);
+}
+//! [12]
+
+//! [5]
+void DtlsAssociation::startHandshake()
+{
+ if (socket.state() != QAbstractSocket::ConnectedState) {
+ emit infoMessage(tr("%1: connecting UDP socket first ...").arg(name));
+ connect(&socket, &QAbstractSocket::connected, this, &DtlsAssociation::udpSocketConnected);
+ return;
+ }
+
+ if (!crypto.doHandshake(&socket))
+ emit errorMessage(tr("%1: failed to start a handshake - %2").arg(name, crypto.dtlsErrorString()));
+ else
+ emit infoMessage(tr("%1: starting a handshake").arg(name));
+}
+//! [5]
+
+void DtlsAssociation::udpSocketConnected()
+{
+ emit infoMessage(tr("%1: UDP socket is now in ConnectedState, continue with handshake ...").arg(name));
+ startHandshake();
+}
+
+void DtlsAssociation::readyRead()
+{
+ //! [6]
+ QByteArray dgram(socket.pendingDatagramSize(), Qt::Uninitialized);
+ const qint64 bytesRead = socket.readDatagram(dgram.data(), dgram.size());
+ if (bytesRead <= 0) {
+ emit warningMessage(tr("%1: spurious read notification?").arg(name));
+ return;
+ }
+
+ dgram.resize(bytesRead);
+ //! [6]
+ //! [7]
+ if (crypto.isConnectionEncrypted()) {
+ const QByteArray plainText = crypto.decryptDatagram(&socket, dgram);
+ if (plainText.size()) {
+ emit serverResponse(name, dgram, plainText);
+ return;
+ }
+
+ if (crypto.dtlsError() == QDtlsError::RemoteClosedConnectionError) {
+ emit errorMessage(tr("%1: shutdown alert received").arg(name));
+ socket.close();
+ pingTimer.stop();
+ return;
+ }
+
+ emit warningMessage(tr("%1: zero-length datagram received?").arg(name));
+ } else {
+ //! [7]
+ //! [8]
+ if (!crypto.doHandshake(&socket, dgram)) {
+ emit errorMessage(tr("%1: handshake error - %2").arg(name, crypto.dtlsErrorString()));
+ return;
+ }
+ //! [8]
+
+ //! [9]
+ if (crypto.isConnectionEncrypted()) {
+ emit infoMessage(tr("%1: encrypted connection established!").arg(name));
+ pingTimer.start();
+ pingTimeout();
+ } else {
+ //! [9]
+ emit infoMessage(tr("%1: continuing with handshake ...").arg(name));
+ }
+ }
+}
+
+//! [11]
+void DtlsAssociation::handshakeTimeout()
+{
+ emit warningMessage(tr("%1: handshake timeout, trying to re-transmit").arg(name));
+ if (!crypto.handleTimeout(&socket))
+ emit errorMessage(tr("%1: failed to re-transmit - %2").arg(name, crypto.dtlsErrorString()));
+}
+//! [11]
+
+//! [14]
+void DtlsAssociation::pskRequired(QSslPreSharedKeyAuthenticator *auth)
+{
+ Q_ASSERT(auth);
+
+ emit infoMessage(tr("%1: providing pre-shared key ...").arg(name));
+ auth->setIdentity(name.toLatin1());
+ auth->setPreSharedKey(QByteArrayLiteral("\x1a\x2b\x3c\x4d\x5e\x6f"));
+}
+//! [14]
+
+//! [10]
+void DtlsAssociation::pingTimeout()
+{
+ static const QString message = QStringLiteral("I am %1, please, accept our ping %2");
+ const qint64 written = crypto.writeDatagramEncrypted(&socket, message.arg(name).arg(ping).toLatin1());
+ if (written <= 0) {
+ emit errorMessage(tr("%1: failed to send a ping - %2").arg(name, crypto.dtlsErrorString()));
+ pingTimer.stop();
+ return;
+ }
+
+ ++ping;
+}
+//! [10]
+
+QT_END_NAMESPACE
diff --git a/examples/network/secureudpclient/association.h b/examples/network/secureudpclient/association.h
new file mode 100644
index 0000000000..be89ce695e
--- /dev/null
+++ b/examples/network/secureudpclient/association.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef ASSOCIATION_H
+#define ASSOCIATION_H
+
+#include <QtNetwork>
+#include <QtCore>
+
+QT_BEGIN_NAMESPACE
+
+//! [0]
+class DtlsAssociation : public QObject
+{
+ Q_OBJECT
+
+public:
+ DtlsAssociation(const QHostAddress &address, quint16 port,
+ const QString &connectionName);
+ ~DtlsAssociation();
+ void startHandshake();
+
+signals:
+ void errorMessage(const QString &message);
+ void warningMessage(const QString &message);
+ void infoMessage(const QString &message);
+ void serverResponse(const QString &clientInfo, const QByteArray &datagraam,
+ const QByteArray &plainText);
+
+private slots:
+ void udpSocketConnected();
+ void readyRead();
+ void handshakeTimeout();
+ void pskRequired(QSslPreSharedKeyAuthenticator *auth);
+ void pingTimeout();
+
+private:
+ QString name;
+ QUdpSocket socket;
+ QDtls crypto;
+
+ QTimer pingTimer;
+ unsigned ping = 0;
+
+ Q_DISABLE_COPY(DtlsAssociation)
+};
+//! [0]
+
+QT_END_NAMESPACE
+
+#endif // ASSOCIATION_H
diff --git a/examples/network/secureudpclient/main.cpp b/examples/network/secureudpclient/main.cpp
new file mode 100644
index 0000000000..2cf35878f2
--- /dev/null
+++ b/examples/network/secureudpclient/main.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QT_USE_NAMESPACE
+
+ QApplication app(argc, argv);
+ MainWindow window;
+ window.show();
+
+ return app.exec();
+}
diff --git a/examples/network/secureudpclient/mainwindow.cpp b/examples/network/secureudpclient/mainwindow.cpp
new file mode 100644
index 0000000000..2fbf757c81
--- /dev/null
+++ b/examples/network/secureudpclient/mainwindow.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtNetwork>
+
+#include "addressdialog.h"
+#include "association.h"
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+#include <utility>
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent),
+ ui(new Ui::MainWindow),
+ nameTemplate(QStringLiteral("Alice (clone number %1)"))
+{
+ ui->setupUi(this);
+ updateUi();
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+//! [0]
+
+const QString colorizer(QStringLiteral("<font color=\"%1\">%2</font><br>"));
+
+void MainWindow::addErrorMessage(const QString &message)
+{
+ ui->clientMessages->insertHtml(colorizer.arg(QStringLiteral("Crimson"), message));
+}
+
+void MainWindow::addWarningMessage(const QString &message)
+{
+ ui->clientMessages->insertHtml(colorizer.arg(QStringLiteral("DarkOrange"), message));
+}
+
+void MainWindow::addInfoMessage(const QString &message)
+{
+ ui->clientMessages->insertHtml(colorizer.arg(QStringLiteral("DarkBlue"), message));
+}
+
+void MainWindow::addServerResponse(const QString &clientInfo, const QByteArray &datagram,
+ const QByteArray &plainText)
+{
+ static const QString messageColor = QStringLiteral("DarkMagenta");
+ static const QString formatter = QStringLiteral("<br>---------------"
+ "<br>%1 received a DTLS datagram:<br> %2"
+ "<br>As plain text:<br> %3");
+
+ const QString html = formatter.arg(clientInfo, QString::fromUtf8(datagram.toHex(' ')),
+ QString::fromUtf8(plainText));
+ ui->serverMessages->insertHtml(colorizer.arg(messageColor, html));
+}
+
+//! [0]
+
+void MainWindow::on_connectButton_clicked()
+{
+ if (lookupId != -1) {
+ QHostInfo::abortHostLookup(lookupId);
+ lookupId = -1;
+ port = 0;
+ updateUi();
+ return;
+ }
+
+ AddressDialog dialog;
+ if (dialog.exec() != QDialog::Accepted)
+ return;
+
+ const QString hostName = dialog.remoteName();
+ if (hostName.isEmpty())
+ return addWarningMessage(tr("Host name or address required to connect"));
+
+ port = dialog.remotePort();
+ QHostAddress remoteAddress;
+ if (remoteAddress.setAddress(hostName))
+ return startNewConnection(remoteAddress);
+
+ addInfoMessage(tr("Looking up the host ..."));
+ lookupId = QHostInfo::lookupHost(hostName, this, SLOT(lookupFinished(QHostInfo)));
+ updateUi();
+}
+
+void MainWindow::updateUi()
+{
+ ui->connectButton->setText(lookupId == -1 ? tr("Connect ...") : tr("Cancel lookup"));
+ ui->shutdownButton->setEnabled(connections.size() != 0);
+}
+
+void MainWindow::lookupFinished(const QHostInfo &hostInfo)
+{
+ if (hostInfo.lookupId() != lookupId)
+ return;
+
+ lookupId = -1;
+ updateUi();
+
+ if (hostInfo.error() != QHostInfo::NoError) {
+ addErrorMessage(hostInfo.errorString());
+ return;
+ }
+
+ const QList<QHostAddress> foundAddresses = hostInfo.addresses();
+ if (foundAddresses.empty()) {
+ addWarningMessage(tr("Host not found"));
+ return;
+ }
+
+ const auto remoteAddress = foundAddresses.at(0);
+ addInfoMessage(tr("Connecting to: %1").arg(remoteAddress.toString()));
+ startNewConnection(remoteAddress);
+}
+
+void MainWindow::startNewConnection(const QHostAddress &address)
+{
+ AssocPtr newConnection(new DtlsAssociation(address, port, nameTemplate.arg(nextId)));
+ connect(newConnection.data(), &DtlsAssociation::errorMessage, this, &MainWindow::addErrorMessage);
+ connect(newConnection.data(), &DtlsAssociation::warningMessage, this, &MainWindow::addWarningMessage);
+ connect(newConnection.data(), &DtlsAssociation::infoMessage, this, &MainWindow::addInfoMessage);
+ connect(newConnection.data(), &DtlsAssociation::serverResponse, this, &MainWindow::addServerResponse);
+ connections.push_back(std::move(newConnection));
+ connections.back()->startHandshake();
+ updateUi();
+
+ ++nextId;
+}
+
+void MainWindow::on_shutdownButton_clicked()
+{
+ connections.clear();
+ updateUi();
+}
diff --git a/examples/network/secureudpclient/mainwindow.h b/examples/network/secureudpclient/mainwindow.h
new file mode 100644
index 0000000000..0d443fd376
--- /dev/null
+++ b/examples/network/secureudpclient/mainwindow.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QSharedPointer>
+#include <QVector>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+
+class MainWindow;
+
+}
+
+class QHostAddress;
+class QHostInfo;
+
+class DtlsAssociation;
+
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = nullptr);
+ ~MainWindow();
+
+private slots:
+
+ void addErrorMessage(const QString &message);
+ void addWarningMessage(const QString &message);
+ void addInfoMessage(const QString &message);
+ void addServerResponse(const QString &clientInfo, const QByteArray &datagram,
+ const QByteArray &plainText);
+
+ void on_connectButton_clicked();
+ void on_shutdownButton_clicked();
+
+ void lookupFinished(const QHostInfo &hostInfo);
+
+private:
+ void updateUi();
+ void startNewConnection(const QHostAddress &address);
+
+ Ui::MainWindow *ui = nullptr;
+
+ using AssocPtr = QSharedPointer<DtlsAssociation>;
+ QVector<AssocPtr> connections;
+
+ QString nameTemplate;
+ unsigned nextId = 0;
+
+ quint16 port = 0;
+ int lookupId = -1;
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/network/secureudpclient/mainwindow.ui b/examples/network/secureudpclient/mainwindow.ui
new file mode 100644
index 0000000000..59a31974ee
--- /dev/null
+++ b/examples/network/secureudpclient/mainwindow.ui
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1200</width>
+ <height>550</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>1200</width>
+ <height>550</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>1200</width>
+ <height>550</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>DTLS client</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>590</width>
+ <height>400</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>DTLS info messages:</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <widget class="QTextEdit" name="clientMessages">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>570</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>570</width>
+ <height>360</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>570</width>
+ <height>360</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="connectButton">
+ <property name="text">
+ <string>Connect ...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="shutdownButton">
+ <property name="text">
+ <string>Shutdown connections</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="minimumSize">
+ <size>
+ <width>580</width>
+ <height>490</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>580</width>
+ <height>490</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Received datagrams:</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <widget class="QTextEdit" name="serverMessages">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>560</width>
+ <height>450</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>560</width>
+ <height>450</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>560</width>
+ <height>450</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1200</width>
+ <height>22</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/network/secureudpclient/secureudpclient.pro b/examples/network/secureudpclient/secureudpclient.pro
new file mode 100644
index 0000000000..44e4200994
--- /dev/null
+++ b/examples/network/secureudpclient/secureudpclient.pro
@@ -0,0 +1,22 @@
+QT += widgets network
+
+TARGET = secureudpclient
+TEMPLATE = app
+
+SOURCES += \
+ main.cpp \
+ association.cpp \
+ mainwindow.cpp \
+ addressdialog.cpp
+
+HEADERS += \
+ association.h \
+ mainwindow.h \
+ addressdialog.h
+
+FORMS += \
+ mainwindow.ui \
+ addressdialog.ui
+
+target.path = $$[QT_INSTALL_EXAMPLES]/network/secureudpclient
+INSTALLS += target
diff --git a/examples/network/secureudpserver/main.cpp b/examples/network/secureudpserver/main.cpp
new file mode 100644
index 0000000000..1a29d9d7ec
--- /dev/null
+++ b/examples/network/secureudpserver/main.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QT_USE_NAMESPACE
+
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/examples/network/secureudpserver/mainwindow.cpp b/examples/network/secureudpserver/mainwindow.cpp
new file mode 100644
index 0000000000..ef1974c311
--- /dev/null
+++ b/examples/network/secureudpserver/mainwindow.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "nicselector.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow()
+ : ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+
+ connect(&server, &DtlsServer::errorMessage, this, &MainWindow::addErrorMessage);
+ connect(&server, &DtlsServer::warningMessage, this, &MainWindow::addWarningMessage);
+ connect(&server, &DtlsServer::infoMessage, this, &MainWindow::addInfoMessage);
+ connect(&server, &DtlsServer::datagramReceived, this, &MainWindow::addClientMessage);
+
+ updateUi();
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::on_startButton_clicked()
+{
+ if (!server.isListening()) {
+ NicSelector ipDialog;
+ if (ipDialog.exec() == QDialog::Accepted) {
+ const QHostAddress address = ipDialog.selectedIp();
+ const quint16 port = ipDialog.selectedPort();
+ if (address.isNull()) {
+ addErrorMessage(tr("Failed to start listening, no valid address/port"));
+ } else if (server.listen(address, port)) {
+ addInfoMessage(tr("Server is listening on address %1 and port %2")
+ .arg(address.toString())
+ .arg(port));
+ }
+ }
+ } else {
+ server.close();
+ addInfoMessage(tr("Server is not accepting new connections"));
+ }
+
+ updateUi();
+}
+
+void MainWindow::on_quitButton_clicked()
+{
+ QCoreApplication::exit(0);
+}
+
+void MainWindow::updateUi()
+{
+ server.isListening() ? ui->startButton->setText(tr("Stop listening"))
+ : ui->startButton->setText(tr("Start listening"));
+}
+
+//! [0]
+const QString colorizer(QStringLiteral("<font color=\"%1\">%2</font><br>"));
+
+void MainWindow::addErrorMessage(const QString &message)
+{
+ ui->serverInfo->insertHtml(colorizer.arg(QStringLiteral("Crimson"), message));
+}
+
+void MainWindow::addWarningMessage(const QString &message)
+{
+ ui->serverInfo->insertHtml(colorizer.arg(QStringLiteral("DarkOrange"), message));
+}
+
+void MainWindow::addInfoMessage(const QString &message)
+{
+ ui->serverInfo->insertHtml(colorizer.arg(QStringLiteral("DarkBlue"), message));
+}
+
+void MainWindow::addClientMessage(const QString &peerInfo, const QByteArray &datagram,
+ const QByteArray &plainText)
+{
+ static const QString messageColor = QStringLiteral("DarkMagenta");
+ static const QString formatter = QStringLiteral("<br>---------------"
+ "<br>A message from %1"
+ "<br>DTLS datagram:<br> %2"
+ "<br>As plain text:<br> %3");
+
+ const QString html = formatter.arg(peerInfo, QString::fromUtf8(datagram.toHex(' ')),
+ QString::fromUtf8(plainText));
+ ui->messages->insertHtml(colorizer.arg(messageColor, html));
+}
+//! [0]
diff --git a/examples/network/secureudpserver/mainwindow.h b/examples/network/secureudpserver/mainwindow.h
new file mode 100644
index 0000000000..b39d984d50
--- /dev/null
+++ b/examples/network/secureudpserver/mainwindow.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "server.h"
+
+#include <QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+class MainWindow;
+}
+
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow();
+ ~MainWindow();
+
+private slots:
+ void addErrorMessage(const QString &message);
+ void addWarningMessage(const QString &message);
+ void addInfoMessage(const QString &message);
+ void addClientMessage(const QString &peerInfo, const QByteArray &datagram,
+ const QByteArray &plainText);
+
+ void on_startButton_clicked();
+ void on_quitButton_clicked();
+
+private:
+ void updateUi();
+
+ Ui::MainWindow *ui = nullptr;
+ DtlsServer server;
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/network/secureudpserver/mainwindow.ui b/examples/network/secureudpserver/mainwindow.ui
new file mode 100644
index 0000000000..e25e19921b
--- /dev/null
+++ b/examples/network/secureudpserver/mainwindow.ui
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1090</width>
+ <height>670</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>1090</width>
+ <height>670</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>1090</width>
+ <height>670</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>DTLS server</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <widget class="QWidget" name="layoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>1050</width>
+ <height>576</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QGroupBox" name="infoBox">
+ <property name="minimumSize">
+ <size>
+ <width>520</width>
+ <height>540</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>520</width>
+ <height>540</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Dtls server info:</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <widget class="QTextEdit" name="serverInfo">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>500</width>
+ <height>500</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>500</width>
+ <height>500</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>500</width>
+ <height>500</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="minimumSize">
+ <size>
+ <width>520</width>
+ <height>540</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>520</width>
+ <height>540</height>
+ </size>
+ </property>
+ <property name="title">
+ <string>Received messages:</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <widget class="QTextEdit" name="messages">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>500</width>
+ <height>500</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>500</width>
+ <height>500</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>500</width>
+ <height>500</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="startButton">
+ <property name="text">
+ <string>Start listening</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="quitButton">
+ <property name="text">
+ <string>Quit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1090</width>
+ <height>22</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QToolBar" name="mainToolBar">
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/network/secureudpserver/nicselector.cpp b/examples/network/secureudpserver/nicselector.cpp
new file mode 100644
index 0000000000..ea26439d74
--- /dev/null
+++ b/examples/network/secureudpserver/nicselector.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <limits>
+
+#include <QtCore>
+#include <QtNetwork>
+
+#include "nicselector.h"
+#include "ui_nicselector.h"
+
+NicSelector::NicSelector(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::NicSelector)
+{
+ ui->setupUi(this);
+ auto portValidator = new QIntValidator(0, int(std::numeric_limits<quint16>::max()),
+ ui->portSelector);
+ ui->portSelector->setValidator(portValidator);
+ ui->portSelector->setText(QStringLiteral("22334"));
+
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ availableAddresses.reserve(ipAddressesList.size());
+ for (const QHostAddress &ip : ipAddressesList) {
+ if (ip != QHostAddress::LocalHost && ip.toIPv4Address()) {
+ availableAddresses.push_back(ip);
+ ui->ipSelector->addItem(ip.toString());
+ }
+ }
+}
+
+NicSelector::~NicSelector()
+{
+ delete ui;
+}
+
+QHostAddress NicSelector::selectedIp() const
+{
+ if (!availableAddresses.size())
+ return {};
+
+ return availableAddresses[ui->ipSelector->currentIndex()];
+}
+
+quint16 NicSelector::selectedPort() const
+{
+ return quint16(ui->portSelector->text().toUInt());
+}
diff --git a/examples/network/secureudpserver/nicselector.h b/examples/network/secureudpserver/nicselector.h
new file mode 100644
index 0000000000..7962a78318
--- /dev/null
+++ b/examples/network/secureudpserver/nicselector.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NICSELECTOR_H
+#define NICSELECTOR_H
+
+#include <QDialog>
+#include <QHostAddress>
+#include <QVector>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+class NicSelector;
+}
+
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+class NicSelector : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit NicSelector(QWidget *parent = nullptr);
+ ~NicSelector();
+
+ QHostAddress selectedIp() const;
+ quint16 selectedPort() const;
+
+private:
+ Ui::NicSelector *ui = nullptr;
+ QVector<QHostAddress> availableAddresses;
+};
+
+#endif // NICSELECTOR_H
diff --git a/examples/network/secureudpserver/nicselector.ui b/examples/network/secureudpserver/nicselector.ui
new file mode 100644
index 0000000000..b0ba376b66
--- /dev/null
+++ b/examples/network/secureudpserver/nicselector.ui
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NicSelector</class>
+ <widget class="QDialog" name="NicSelector">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>373</width>
+ <height>213</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>IP and port</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetFixedSize</enum>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Listen on address:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="ipSelector">
+ <property name="minimumSize">
+ <size>
+ <width>250</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetFixedSize</enum>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="portSelector">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>NicSelector</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>NicSelector</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/network/secureudpserver/secureudpserver.pro b/examples/network/secureudpserver/secureudpserver.pro
new file mode 100644
index 0000000000..910655aae4
--- /dev/null
+++ b/examples/network/secureudpserver/secureudpserver.pro
@@ -0,0 +1,21 @@
+QT += widgets network
+
+TARGET = secureudpserver
+TEMPLATE = app
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp \
+ server.cpp \
+ nicselector.cpp
+
+HEADERS += \
+ mainwindow.h \
+ server.h \
+ nicselector.h
+
+FORMS = mainwindow.ui \
+ nicselector.ui
+
+target.path = $$[QT_INSTALL_EXAMPLES]/network/secureudpserver
+INSTALLS += target
diff --git a/examples/network/secureudpserver/server.cpp b/examples/network/secureudpserver/server.cpp
new file mode 100644
index 0000000000..0d83fa9b51
--- /dev/null
+++ b/examples/network/secureudpserver/server.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "server.h"
+
+#include <algorithm>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+
+QString peer_info(const QHostAddress &address, quint16 port)
+{
+ const static QString info = QStringLiteral("(%1:%2)");
+ return info.arg(address.toString()).arg(port);
+}
+
+QString connection_info(QSharedPointer<QDtls> connection)
+{
+ QString info(DtlsServer::tr("Session cipher: "));
+ info += connection->sessionCipher().name();
+
+ info += DtlsServer::tr("; session protocol: ");
+ switch (connection->sessionProtocol()) {
+ case QSsl::DtlsV1_0:
+ info += DtlsServer::tr("DTLS 1.0.");
+ break;
+ case QSsl::DtlsV1_2:
+ info += DtlsServer::tr("DTLS 1.2.");
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ info += DtlsServer::tr("DTLS 1.2 or later.");
+ break;
+ default:
+ info += DtlsServer::tr("Unknown protocol.");
+ }
+
+ return info;
+}
+
+} // unnamed namespace
+
+//! [1]
+DtlsServer::DtlsServer()
+{
+ connect(&serverSocket, &QAbstractSocket::readyRead, this, &DtlsServer::readyRead);
+
+ serverConfiguration = QSslConfiguration::defaultDtlsConfiguration();
+ serverConfiguration.setPreSharedKeyIdentityHint("Qt DTLS example server");
+ serverConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
+}
+//! [1]
+
+DtlsServer::~DtlsServer()
+{
+ shutdown();
+}
+
+//! [2]
+bool DtlsServer::listen(const QHostAddress &address, quint16 port)
+{
+ if (address != serverSocket.localAddress() || port != serverSocket.localPort()) {
+ shutdown();
+ listening = serverSocket.bind(address, port);
+ if (!listening)
+ emit errorMessage(serverSocket.errorString());
+ } else {
+ listening = true;
+ }
+
+ return listening;
+}
+//! [2]
+
+bool DtlsServer::isListening() const
+{
+ return listening;
+}
+
+void DtlsServer::close()
+{
+ listening = false;
+}
+
+void DtlsServer::readyRead()
+{
+ //! [3]
+ const qint64 bytesToRead = serverSocket.pendingDatagramSize();
+ if (bytesToRead <= 0) {
+ emit warningMessage(tr("A spurious read notification"));
+ return;
+ }
+
+ QByteArray dgram(bytesToRead, Qt::Uninitialized);
+ QHostAddress peerAddress;
+ quint16 peerPort = 0;
+ const qint64 bytesRead = serverSocket.readDatagram(dgram.data(), dgram.size(),
+ &peerAddress, &peerPort);
+ if (bytesRead <= 0) {
+ emit warningMessage(tr("Failed to read a datagram: ") + serverSocket.errorString());
+ return;
+ }
+
+ dgram.resize(bytesRead);
+ //! [3]
+ //! [4]
+ if (peerAddress.isNull() || !peerPort) {
+ emit warningMessage(tr("Failed to extract peer info (address, port)"));
+ return;
+ }
+
+ const auto client = std::find_if(knownClients.begin(), knownClients.end(),
+ [&](const DtlsConnection &connection){
+ return connection->peerAddress() == peerAddress
+ && connection->peerPort() == peerPort;
+ });
+ //! [4]
+
+ //! [5]
+ if (client == knownClients.end())
+ return handleNewConnection(peerAddress, peerPort, dgram);
+ //! [5]
+
+ //! [6]
+ if ((*client)->isConnectionEncrypted()) {
+ decryptDatagram(*client, dgram);
+ if ((*client)->dtlsError() == QDtlsError::RemoteClosedConnectionError)
+ knownClients.erase(client);
+ return;
+ }
+ //! [6]
+
+ //! [7]
+ doHandshake(*client, dgram);
+ //! [7]
+}
+
+//! [13]
+void DtlsServer::pskRequired(QSslPreSharedKeyAuthenticator *auth)
+{
+ Q_ASSERT(auth);
+
+ emit infoMessage(tr("PSK callback, received a client's identity: '%1'")
+ .arg(QString::fromLatin1(auth->identity())));
+ auth->setPreSharedKey(QByteArrayLiteral("\x1a\x2b\x3c\x4d\x5e\x6f"));
+}
+//! [13]
+
+//! [8]
+void DtlsServer::handleNewConnection(const QHostAddress &peerAddress,
+ quint16 peerPort, const QByteArray &clientHello)
+{
+ if (!listening)
+ return;
+
+ const QString peerInfo = peer_info(peerAddress, peerPort);
+ if (cookieSender.verifyClient(&serverSocket, clientHello, peerAddress, peerPort)) {
+ emit infoMessage(peerInfo + tr(": verified, starting a handshake"));
+ //! [8]
+ //! [9]
+ DtlsConnection newConnection(new QDtls(QSslSocket::SslServerMode));
+ newConnection->setDtlsConfiguration(serverConfiguration);
+ newConnection->setPeer(peerAddress, peerPort);
+ newConnection->connect(newConnection.data(), &QDtls::pskRequired,
+ this, &DtlsServer::pskRequired);
+ knownClients.push_back(newConnection);
+ doHandshake(newConnection, clientHello);
+ //! [9]
+ } else if (cookieSender.dtlsError() != QDtlsError::NoError) {
+ emit errorMessage(tr("DTLS error: ") + cookieSender.dtlsErrorString());
+ } else {
+ emit infoMessage(peerInfo + tr(": not verified yet"));
+ }
+}
+
+//! [11]
+void DtlsServer::doHandshake(DtlsConnection newConnection, const QByteArray &clientHello)
+{
+ const bool result = newConnection->doHandshake(&serverSocket, clientHello);
+ if (!result) {
+ emit errorMessage(newConnection->dtlsErrorString());
+ return;
+ }
+
+ const QString peerInfo = peer_info(newConnection->peerAddress(),
+ newConnection->peerPort());
+ switch (newConnection->handshakeState()) {
+ case QDtls::HandshakeInProgress:
+ emit infoMessage(peerInfo + tr(": handshake is in progress ..."));
+ break;
+ case QDtls::HandshakeComplete:
+ emit infoMessage(tr("Connection with %1 encrypted. %2")
+ .arg(peerInfo, connection_info(newConnection)));
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+}
+//! [11]
+
+//! [12]
+void DtlsServer::decryptDatagram(DtlsConnection connection, const QByteArray &clientMessage)
+{
+ Q_ASSERT(connection->isConnectionEncrypted());
+
+ const QString peerInfo = peer_info(connection->peerAddress(), connection->peerPort());
+ const QByteArray dgram = connection->decryptDatagram(&serverSocket, clientMessage);
+ if (dgram.size()) {
+ emit datagramReceived(peerInfo, clientMessage, dgram);
+ connection->writeDatagramEncrypted(&serverSocket, tr("to %1: ACK").arg(peerInfo).toLatin1());
+ } else if (connection->dtlsError() == QDtlsError::NoError) {
+ emit warningMessage(peerInfo + ": " + tr("0 byte dgram, could be a re-connect attempt?"));
+ } else {
+ emit errorMessage(peerInfo + ": " + connection->dtlsErrorString());
+ }
+}
+//! [12]
+
+//! [14]
+void DtlsServer::shutdown()
+{
+ for (DtlsConnection &connection : knownClients)
+ connection->shutdown(&serverSocket);
+
+ knownClients.clear();
+ serverSocket.close();
+}
+//! [14]
+
+QT_END_NAMESPACE
diff --git a/examples/network/secureudpserver/server.h b/examples/network/secureudpserver/server.h
new file mode 100644
index 0000000000..b720368e7b
--- /dev/null
+++ b/examples/network/secureudpserver/server.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef SERVER_H
+#define SERVER_H
+
+#include <QtCore>
+#include <QtNetwork>
+
+#include <vector>
+
+QT_BEGIN_NAMESPACE
+
+//! [0]
+class DtlsServer : public QObject
+{
+ Q_OBJECT
+
+public:
+ DtlsServer();
+ ~DtlsServer();
+
+ bool listen(const QHostAddress &address, quint16 port);
+ bool isListening() const;
+ void close();
+
+signals:
+ void errorMessage(const QString &message);
+ void warningMessage(const QString &message);
+ void infoMessage(const QString &message);
+
+ void datagramReceived(const QString &peerInfo, const QByteArray &cipherText,
+ const QByteArray &plainText);
+
+private slots:
+ void readyRead();
+ void pskRequired(QSslPreSharedKeyAuthenticator *auth);
+
+private:
+ void handleNewConnection(const QHostAddress &peerAddress, quint16 peerPort,
+ const QByteArray &clientHello);
+
+ using DtlsConnection = QSharedPointer<QDtls>;
+ void doHandshake(DtlsConnection newConnection, const QByteArray &clientHello);
+ void decryptDatagram(DtlsConnection connection, const QByteArray &clientMessage);
+ void shutdown();
+
+ bool listening = false;
+ QUdpSocket serverSocket;
+
+ QSslConfiguration serverConfiguration;
+ QDtlsClientVerifier cookieSender;
+ QVector<DtlsConnection> knownClients;
+
+ Q_DISABLE_COPY(DtlsServer)
+};
+//! [0]
+
+QT_END_NAMESPACE
+
+#endif // SERVER_H
diff --git a/examples/opengl/contextinfo/widget.cpp b/examples/opengl/contextinfo/widget.cpp
index fc21983f38..a5d9e98bf8 100644
--- a/examples/opengl/contextinfo/widget.cpp
+++ b/examples/opengl/contextinfo/widget.cpp
@@ -252,7 +252,7 @@ Widget::Widget(QWidget *parent)
if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
str << " Qt::AA_UseSoftwareOpenGL";
if (QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL))
- str << " Qt::AA_UseSoftwareOpenGL";
+ str << " Qt::AA_UseDesktopOpenGL";
layout->addWidget(new QLabel(description));
setLayout(layout);
diff --git a/examples/opengl/qopenglwindow/main.cpp b/examples/opengl/qopenglwindow/main.cpp
index 4f008b45a6..8932269ddf 100644
--- a/examples/opengl/qopenglwindow/main.cpp
+++ b/examples/opengl/qopenglwindow/main.cpp
@@ -92,7 +92,6 @@ private:
QMatrix4x4 m_view;
QMatrix4x4 m_model_triangle;
QMatrix4x4 m_model_text;
- QBrush m_brush;
FragmentToy m_fragment_toy;
QStaticText m_text_layout;
@@ -111,16 +110,12 @@ OpenGLWindow::OpenGLWindow()
, m_text_layout("The triangle and this text is rendered with QPainter")
, m_animate(true)
{
+ setGeometry(300, 300, 500, 500);
+
m_view.lookAt(QVector3D(3,1,1),
QVector3D(0,0,0),
QVector3D(0,1,0));
- QLinearGradient gradient(QPointF(-1,-1), QPointF(1,1));
- gradient.setColorAt(0, Qt::red);
- gradient.setColorAt(1, Qt::green);
-
- m_brush = QBrush(gradient);
-
setAnimating(m_animate);
}
@@ -134,11 +129,11 @@ void OpenGLWindow::paintGL()
QMatrix4x4 mvp = m_projection * m_view * m_model_triangle;
p.setTransform(mvp.toTransform(), true);
- p.fillPath(painterPathForTriangle(), m_brush);
+ p.fillPath(painterPathForTriangle(), QBrush(QGradient(QGradient::NightFade)));
QTransform text_transform = (m_window_painter_matrix * m_view * m_model_text).toTransform();
p.setTransform(text_transform, false);
- p.setPen(QPen(Qt::white));
+ p.setPen(QPen(Qt::black));
m_text_layout.prepare(text_transform);
qreal x = - (m_text_layout.size().width() / 2);
qreal y = 0;
@@ -197,7 +192,7 @@ int main(int argc, char **argv)
fmt.setDepthBufferSize(24);
fmt.setStencilBufferSize(8);
window.setFormat(fmt);
- window.showMaximized();
+ window.show();
return app.exec();
}
diff --git a/examples/touch/dials/dials.pro b/examples/touch/dials/dials.pro
deleted file mode 100644
index 2c522a46f0..0000000000
--- a/examples/touch/dials/dials.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT += widgets
-
-SOURCES += main.cpp
-FORMS += dials.ui
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/touch/dials
-INSTALLS += target
diff --git a/examples/touch/dials/doc/src/touch-dials.qdoc b/examples/touch/dials/doc/src/touch-dials.qdoc
deleted file mode 100644
index 10784c8c0d..0000000000
--- a/examples/touch/dials/doc/src/touch-dials.qdoc
+++ /dev/null
@@ -1,38 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example touch/dials
- \title Touch Dials Example
- \ingroup touchinputexamples
- \brief Shows how to apply touch to a set of standard Qt widgets
-
- The Touch Dials example shows how to apply touch to a set of
- standard Qt widgets.
-
- \image touch-dials-example.png
-*/
diff --git a/examples/touch/fingerpaint/fingerpaint.pro b/examples/touch/fingerpaint/fingerpaint.pro
deleted file mode 100644
index f196f7eed4..0000000000
--- a/examples/touch/fingerpaint/fingerpaint.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-QT += widgets
-requires(qtConfig(filedialog))
-qtHaveModule(printsupport): QT += printsupport
-
-HEADERS = mainwindow.h \
- scribblearea.h
-SOURCES = main.cpp \
- mainwindow.cpp \
- scribblearea.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/touch/fingerpaint
-INSTALLS += target
diff --git a/examples/touch/knobs/doc/src/touch-knobs.qdoc b/examples/touch/knobs/doc/src/touch-knobs.qdoc
deleted file mode 100644
index d39dd564b2..0000000000
--- a/examples/touch/knobs/doc/src/touch-knobs.qdoc
+++ /dev/null
@@ -1,38 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example touch/knobs
- \title Touch Knobs Example
- \ingroup touchinputexamples
- \brief Shows how to create custom controls that accept touch input
-
- The Touch Knobs example shows how to create custom controls that
- accept touch input.
-
- \image touch-knobs-example.png
-*/
diff --git a/examples/touch/knobs/knobs.pro b/examples/touch/knobs/knobs.pro
deleted file mode 100644
index 267ba26167..0000000000
--- a/examples/touch/knobs/knobs.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT += widgets
-
-HEADERS = knob.h
-SOURCES = main.cpp knob.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/touch/knobs
-INSTALLS += target
diff --git a/examples/touch/pinchzoom/pinchzoom.pro b/examples/touch/pinchzoom/pinchzoom.pro
deleted file mode 100644
index 9441cc1d92..0000000000
--- a/examples/touch/pinchzoom/pinchzoom.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-QT += widgets
-
-HEADERS += \
- mouse.h \
- graphicsview.h
-SOURCES += \
- main.cpp \
- mouse.cpp \
- graphicsview.cpp
-
-RESOURCES += \
- mice.qrc
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/touch/pinchzoom
-INSTALLS += target
diff --git a/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp b/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp
index 67ae0ca5dc..257191ef4e 100644
--- a/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp
+++ b/examples/vulkan/hellovulkantexture/hellovulkantexture.cpp
@@ -223,6 +223,16 @@ bool VulkanRenderer::createTextureImage(const QSize &size, VkImage *image, VkDev
VkMemoryRequirements memReq;
m_devFuncs->vkGetImageMemoryRequirements(dev, *image, &memReq);
+ if (!(memReq.memoryTypeBits & (1 << memIndex))) {
+ VkPhysicalDeviceMemoryProperties physDevMemProps;
+ m_window->vulkanInstance()->functions()->vkGetPhysicalDeviceMemoryProperties(m_window->physicalDevice(), &physDevMemProps);
+ for (uint32_t i = 0; i < physDevMemProps.memoryTypeCount; ++i) {
+ if (!(memReq.memoryTypeBits & (1 << i)))
+ continue;
+ memIndex = i;
+ }
+ }
+
VkMemoryAllocateInfo allocInfo = {
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
nullptr,
@@ -294,12 +304,12 @@ void VulkanRenderer::ensureTexture()
barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- barrier.srcAccessMask = 0; // VK_ACCESS_HOST_WRITE_BIT ### no, keep validation layer happy (??)
+ barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
barrier.image = m_texImage;
m_devFuncs->vkCmdPipelineBarrier(cb,
- VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
0, 0, nullptr, 0, nullptr,
1, &barrier);
@@ -312,7 +322,7 @@ void VulkanRenderer::ensureTexture()
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
barrier.image = m_texStaging;
m_devFuncs->vkCmdPipelineBarrier(cb,
- VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, nullptr, 0, nullptr,
1, &barrier);
diff --git a/examples/widgets/doc/src/customsortfiltermodel.qdoc b/examples/widgets/doc/src/customsortfiltermodel.qdoc
index 6eab846e89..9f0d13dd83 100644
--- a/examples/widgets/doc/src/customsortfiltermodel.qdoc
+++ b/examples/widgets/doc/src/customsortfiltermodel.qdoc
@@ -121,14 +121,14 @@
\snippet itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 6
- We use QRegExp to define a pattern for the addresses we are looking
- for. The QRegExp::indexIn() function attempts to find a match in
- the given string and returns the position of the first match, or
- -1 if there was no match. If the given string contains the
- pattern, we use QRegExp's \l {QRegExp::cap()}{cap()} function to
- retrieve the actual address. The \l {QRegExp::cap()}{cap()}
- function returns the text captured by the \e nth
- subexpression. The entire match has index 0 and the parenthesized
+ We use QRegularExpression to define a pattern for the addresses we
+ are looking for. The \l {QRegularExpression::match()}{match()} function
+ returns a QRegularExpressionMatch object which contains the result of
+ the matching. If there is a match,
+ \l {QRegularExpressionMatch::hasMatch()}{hasMatch()} returns true. The
+ result of the match can be retrieved with QRegularExpressionMatch's
+ \l {QRegularExpressionMatch::captured()}{captured()} function.
+ The entire match has index 0 and the parenthesized
subexpressions have indexes starting from 1 (excluding
non-capturing parentheses).
diff --git a/examples/widgets/doc/src/gradients.qdoc b/examples/widgets/doc/src/gradients.qdoc
index 936bd2b014..457e6f837a 100644
--- a/examples/widgets/doc/src/gradients.qdoc
+++ b/examples/widgets/doc/src/gradients.qdoc
@@ -51,7 +51,12 @@
gradient. You can move points, and add new ones, by clicking with the left
mouse button, and remove points by clicking with the right button.
- There are three default configurations available at the bottom of
+ There are three example configurations available at the bottom of
the page that are provided as suggestions on how a color table could be
configured.
+
+ Qt also provides a suite of named gradient presets. They are based on the
+ free WebGradients collection. Click on the name in the Presets box to show
+ the gradient. Use the arrow buttons to browse through the available
+ presets.
*/
diff --git a/examples/widgets/graphicsview/boxes/glextensions.h b/examples/widgets/graphicsview/boxes/glextensions.h
index ac73e61641..685700d866 100644
--- a/examples/widgets/graphicsview/boxes/glextensions.h
+++ b/examples/widgets/graphicsview/boxes/glextensions.h
@@ -78,18 +78,11 @@ glMapBuffer
glUnmapBuffer
*/
-#ifndef Q_OS_MAC
-# ifndef APIENTRYP
-# ifdef APIENTRY
-# define APIENTRYP APIENTRY *
-# else
-# define APIENTRY
-# define APIENTRYP *
-# endif
-# endif
-#else
+#ifndef APIENTRY
# define APIENTRY
-# define APIENTRYP *
+#endif
+#ifndef APIENTRYP
+# define APIENTRYP APIENTRY *
#endif
#ifndef GL_VERSION_1_2
diff --git a/examples/widgets/graphicsview/boxes/scene.cpp b/examples/widgets/graphicsview/boxes/scene.cpp
index f51cad99ac..1637c1f781 100644
--- a/examples/widgets/graphicsview/boxes/scene.cpp
+++ b/examples/widgets/graphicsview/boxes/scene.cpp
@@ -952,17 +952,17 @@ void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
return;
if (event->buttons() & Qt::LeftButton) {
- m_trackBalls[0].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[0].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
} else {
- m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
}
if (event->buttons() & Qt::RightButton) {
- m_trackBalls[1].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[1].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
} else {
- m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
}
if (event->buttons() & Qt::MidButton) {
@@ -980,12 +980,12 @@ void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event)
return;
if (event->buttons() & Qt::LeftButton) {
- m_trackBalls[0].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[0].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
}
if (event->buttons() & Qt::RightButton) {
- m_trackBalls[1].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[1].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
}
@@ -1002,12 +1002,12 @@ void Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
return;
if (event->button() == Qt::LeftButton) {
- m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
}
if (event->button() == Qt::RightButton) {
- m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
}
diff --git a/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp b/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp
index c93368b390..35426657d9 100644
--- a/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp
+++ b/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp
@@ -101,15 +101,20 @@ bool MySortFilterProxyModel::lessThan(const QModelIndex &left,
if (leftData.type() == QVariant::DateTime) {
return leftData.toDateTime() < rightData.toDateTime();
} else {
- static QRegExp emailPattern("[\\w\\.]*@[\\w\\.]*)");
+ static const QRegularExpression emailPattern("[\\w\\.]*@[\\w\\.]*");
QString leftString = leftData.toString();
- if(left.column() == 1 && emailPattern.indexIn(leftString) != -1)
- leftString = emailPattern.cap(1);
-
+ if (left.column() == 1) {
+ const QRegularExpressionMatch match = emailPattern.match(leftString);
+ if (match.hasMatch())
+ leftString = match.captured(0);
+ }
QString rightString = rightData.toString();
- if(right.column() == 1 && emailPattern.indexIn(rightString) != -1)
- rightString = emailPattern.cap(1);
+ if (right.column() == 1) {
+ const QRegularExpressionMatch match = emailPattern.match(rightString);
+ if (match.hasMatch())
+ rightString = match.captured(0);
+ }
return QString::localeAwareCompare(leftString, rightString) < 0;
}
diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp
index fe31207326..4ba180f312 100644
--- a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp
+++ b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp
@@ -97,6 +97,7 @@ MainWindow::MainWindow(const CustomSizeHintMap &customSizeHints,
QWidget *parent, Qt::WindowFlags flags)
: QMainWindow(parent, flags)
{
+ Q_UNUSED(message);
setObjectName("MainWindow");
setWindowTitle("Qt Main Window Example");
diff --git a/examples/widgets/painting/deform/pathdeform.cpp b/examples/widgets/painting/deform/pathdeform.cpp
index 490a8508d6..805804716f 100644
--- a/examples/widgets/painting/deform/pathdeform.cpp
+++ b/examples/widgets/painting/deform/pathdeform.cpp
@@ -50,7 +50,8 @@
#include "pathdeform.h"
-#include <QApplication>
+#include <QGuiApplication>
+#include <QScreen>
#include <QtDebug>
#include <QMouseEvent>
#include <QTimerEvent>
@@ -247,7 +248,7 @@ void PathDeformControls::layoutForSmallScreen()
deformSlider->setValue(80);
fontSizeSlider->setValue(120);
- QRect screen_size = QApplication::desktop()->screenGeometry();
+ QRect screen_size = QGuiApplication::primaryScreen()->geometry();
radiusSlider->setValue(qMin(screen_size.width(), screen_size.height())/5);
m_renderer->setText(tr("Qt"));
@@ -277,7 +278,7 @@ PathDeformWidget::PathDeformWidget(QWidget *parent, bool smallScreen)
connect(m_renderer, SIGNAL(clicked()), this, SLOT(showControls()));
connect(m_controls, SIGNAL(okPressed()), this, SLOT(hideControls()));
- connect(m_controls, SIGNAL(quitPressed()), QApplication::instance(), SLOT(quit()));
+ connect(m_controls, SIGNAL(quitPressed()), QCoreApplication::instance(), SLOT(quit()));
}
@@ -482,6 +483,10 @@ void PathDeformRenderer::timerEvent(QTimerEvent *e)
void PathDeformRenderer::mousePressEvent(QMouseEvent *e)
{
+ if (m_show_doc) {
+ setDescriptionEnabled(false);
+ return;
+ }
setDescriptionEnabled(false);
m_repaintTimer.stop();
diff --git a/examples/widgets/painting/gradients/gradients.cpp b/examples/widgets/painting/gradients/gradients.cpp
index 78c174a8bf..6d9f514a8d 100644
--- a/examples/widgets/painting/gradients/gradients.cpp
+++ b/examples/widgets/painting/gradients/gradients.cpp
@@ -301,8 +301,15 @@ GradientWidget::GradientWidget(QWidget *parent)
m_reflectSpreadButton = new QRadioButton(tr("Reflect Spread"), spreadGroup);
m_repeatSpreadButton = new QRadioButton(tr("Repeat Spread"), spreadGroup);
+ QGroupBox *presetsGroup = new QGroupBox(mainGroup);
+ presetsGroup->setTitle(tr("Presets"));
+ QPushButton *prevPresetButton = new QPushButton(tr("<"), presetsGroup);
+ m_presetButton = new QPushButton(tr("(unset)"), presetsGroup);
+ QPushButton *nextPresetButton = new QPushButton(tr(">"), presetsGroup);
+ updatePresetName();
+
QGroupBox *defaultsGroup = new QGroupBox(mainGroup);
- defaultsGroup->setTitle(tr("Defaults"));
+ defaultsGroup->setTitle(tr("Examples"));
QPushButton *default1Button = new QPushButton(tr("1"), defaultsGroup);
QPushButton *default2Button = new QPushButton(tr("2"), defaultsGroup);
QPushButton *default3Button = new QPushButton(tr("3"), defaultsGroup);
@@ -327,11 +334,12 @@ GradientWidget::GradientWidget(QWidget *parent)
mainLayout->addWidget(m_renderer);
mainLayout->addWidget(mainGroup);
- mainGroup->setFixedWidth(180);
+ mainGroup->setFixedWidth(200);
QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
mainGroupLayout->addWidget(editorGroup);
mainGroupLayout->addWidget(typeGroup);
mainGroupLayout->addWidget(spreadGroup);
+ mainGroupLayout->addWidget(presetsGroup);
mainGroupLayout->addWidget(defaultsGroup);
mainGroupLayout->addStretch(1);
mainGroupLayout->addWidget(showSourceButton);
@@ -353,6 +361,11 @@ GradientWidget::GradientWidget(QWidget *parent)
spreadGroupLayout->addWidget(m_repeatSpreadButton);
spreadGroupLayout->addWidget(m_reflectSpreadButton);
+ QHBoxLayout *presetsGroupLayout = new QHBoxLayout(presetsGroup);
+ presetsGroupLayout->addWidget(prevPresetButton);
+ presetsGroupLayout->addWidget(m_presetButton, 1);
+ presetsGroupLayout->addWidget(nextPresetButton);
+
QHBoxLayout *defaultsGroupLayout = new QHBoxLayout(defaultsGroup);
defaultsGroupLayout->addWidget(default1Button);
defaultsGroupLayout->addWidget(default2Button);
@@ -375,6 +388,13 @@ GradientWidget::GradientWidget(QWidget *parent)
connect(m_repeatSpreadButton, &QRadioButton::clicked,
m_renderer, &GradientRenderer::setRepeatSpread);
+ connect(prevPresetButton, &QPushButton::clicked,
+ this, &GradientWidget::setPrevPreset);
+ connect(m_presetButton, &QPushButton::clicked,
+ this, &GradientWidget::setPreset);
+ connect(nextPresetButton, &QPushButton::clicked,
+ this, &GradientWidget::setNextPreset);
+
connect(default1Button, &QPushButton::clicked,
this, &GradientWidget::setDefault1);
connect(default2Button, &QPushButton::clicked,
@@ -471,6 +491,40 @@ void GradientWidget::setDefault(int config)
m_renderer->setGradientStops(stops);
}
+void GradientWidget::updatePresetName()
+{
+ QMetaEnum presetEnum = QMetaEnum::fromType<QGradient::Preset>();
+ m_presetButton->setText(QLatin1String(presetEnum.key(m_presetIndex)));
+}
+
+void GradientWidget::changePresetBy(int indexOffset)
+{
+ QMetaEnum presetEnum = QMetaEnum::fromType<QGradient::Preset>();
+ m_presetIndex = qBound(0, m_presetIndex + indexOffset, presetEnum.keyCount() - 1);
+
+ QGradient::Preset preset = static_cast<QGradient::Preset>(presetEnum.value(m_presetIndex));
+ QGradient gradient(preset);
+ if (gradient.type() != QGradient::LinearGradient)
+ return;
+
+ QLinearGradient *linearGradientPointer = static_cast<QLinearGradient *>(&gradient);
+ QLineF objectStopsLine(linearGradientPointer->start(), linearGradientPointer->finalStop());
+ qreal scaleX = qFuzzyIsNull(objectStopsLine.dx()) ? 1.0 : (0.8 * m_renderer->width() / qAbs(objectStopsLine.dx()));
+ qreal scaleY = qFuzzyIsNull(objectStopsLine.dy()) ? 1.0 : (0.8 * m_renderer->height() / qAbs(objectStopsLine.dy()));
+ QLineF logicalStopsLine = QTransform::fromScale(scaleX, scaleY).map(objectStopsLine);
+ logicalStopsLine.translate(m_renderer->rect().center() - logicalStopsLine.center());
+ QPolygonF logicalStops;
+ logicalStops << logicalStopsLine.p1() << logicalStopsLine.p2();
+
+ m_linearButton->animateClick();
+ m_padSpreadButton->animateClick();
+ m_editor->setGradientStops(gradient.stops());
+ m_renderer->hoverPoints()->setPoints(logicalStops);
+ m_renderer->setGradientStops(gradient.stops());
+
+ updatePresetName();
+}
+
GradientRenderer::GradientRenderer(QWidget *parent)
: ArthurFrame(parent)
{
diff --git a/examples/widgets/painting/gradients/gradients.h b/examples/widgets/painting/gradients/gradients.h
index b4db298bb4..c6525d18f8 100644
--- a/examples/widgets/painting/gradients/gradients.h
+++ b/examples/widgets/painting/gradients/gradients.h
@@ -164,9 +164,14 @@ public slots:
void setDefault2() { setDefault(2); }
void setDefault3() { setDefault(3); }
void setDefault4() { setDefault(4); }
+ void setPreset() { changePresetBy(0); }
+ void setPrevPreset() { changePresetBy(-1); }
+ void setNextPreset() { changePresetBy(1); }
private:
void setDefault(int i);
+ void updatePresetName();
+ void changePresetBy(int indexOffset);
GradientRenderer *m_renderer;
GradientEditor *m_editor;
@@ -177,7 +182,9 @@ private:
QRadioButton *m_padSpreadButton;
QRadioButton *m_reflectSpreadButton;
QRadioButton *m_repeatSpreadButton;
+ QPushButton *m_presetButton;
+ int m_presetIndex = 0;
};
#endif // GRADIENTS_H
diff --git a/examples/widgets/painting/gradients/gradients.html b/examples/widgets/painting/gradients/gradients.html
index 1ea2c0ed6c..82c449035f 100644
--- a/examples/widgets/painting/gradients/gradients.html
+++ b/examples/widgets/painting/gradients/gradients.html
@@ -24,8 +24,12 @@ green and blue components while the last defines the alpha of the
gradient. You can move points, and add new ones, by clicking with the left
mouse button, and remove points by clicking with the right button.</p>
-<p>There are three default configurations available at the bottom of
+<p>There are three example configurations available at the bottom of
the page that are provided as suggestions on how a color table could be
configured.</p>
+<p>Qt also provides a suite of named gradient presets. They are based on the
+free WebGradients collection. Click on the name in the Presets box to show the
+gradient. Use the arrow buttons to browse through the available presets.</p>
+
</html>
diff --git a/examples/widgets/richtext/calendar/mainwindow.cpp b/examples/widgets/richtext/calendar/mainwindow.cpp
index 12c418e0b1..38dc0e2849 100644
--- a/examples/widgets/richtext/calendar/mainwindow.cpp
+++ b/examples/widgets/richtext/calendar/mainwindow.cpp
@@ -66,7 +66,7 @@ MainWindow::MainWindow()
QComboBox *monthCombo = new QComboBox;
for (int month = 1; month <= 12; ++month)
- monthCombo->addItem(QDate::longMonthName(month));
+ monthCombo->addItem(QLocale::system().monthName(month));
QDateTimeEdit *yearEdit = new QDateTimeEdit;
yearEdit->setDisplayFormat("yyyy");
@@ -168,7 +168,7 @@ void MainWindow::insertCalendar()
QTextTableCell cell = table->cellAt(0, weekDay-1);
//! [11] //! [12]
QTextCursor cellCursor = cell.firstCursorPosition();
- cellCursor.insertText(QString("%1").arg(QDate::longDayName(weekDay)), boldFormat);
+ cellCursor.insertText(QLocale::system().dayName(weekDay), boldFormat);
}
//! [12]
@@ -194,7 +194,7 @@ void MainWindow::insertCalendar()
cursor.endEditBlock();
//! [14]
setWindowTitle(tr("Calendar for %1 %2"
- ).arg(QDate::longMonthName(selectedDate.month())
+ ).arg(QLocale::system().monthName(selectedDate.month())
).arg(selectedDate.year()));
}
//! [14]
diff --git a/examples/widgets/richtext/textedit/example.html b/examples/widgets/richtext/textedit/example.html
index e3a56d1154..99090a697f 100644
--- a/examples/widgets/richtext/textedit/example.html
+++ b/examples/widgets/richtext/textedit/example.html
@@ -1,14 +1,14 @@
<html><head><meta name="qrichtext" content="1" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>QTextEdit Example</title><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;">
-<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:20pt; font-weight:600;">QTextEdit</span></p>
+<h1 align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:20pt; font-weight:600;">QTextEdit</span></h1>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The QTextEdit widget is an advanced editor that supports formatted rich text. It can be used to display HTML and other rich document formats. Internally, QTextEdit uses the QTextDocument class to describe both the high-level structure of each document and the low-level formatting of paragraphs.</span></p>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">If you are viewing this document in the <span style=" font-style:italic;">textedit</span> example, you can edit this document to explore Qt's rich text editing features. We have included some comments in each of the following sections to encourage you to experiment. </p>
-<p style=" margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:18pt; font-weight:600;"><span style=" font-size:16pt;">Font and Paragraph Styles</span></p>
+<h2 style=" margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:18pt; font-weight:600;"><span style=" font-size:16pt;">Font and Paragraph Styles</span></h2>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">QTextEdit supports </span><span style=" font-size:11pt; font-weight:600;">bold</span><span style=" font-size:11pt;">, </span><span style=" font-size:11pt; font-style:italic;">italic</span><span style=" font-size:11pt;">, and </span><span style=" font-size:11pt; text-decoration: underline;">underlined</span><span style=" font-size:11pt;"> font styles, and can display </span><span style=" font-size:11pt; font-weight:600; color:#00007f;">multicolored</span><span style=" font-size:11pt;"> </span><span style=" font-size:11pt; font-weight:600; color:#aa0000;">text</span><span style=" font-size:11pt;">. Font families such as </span><span style=" font-family:'Times New Roman'; font-size:11pt; font-weight:600;">Times New Roman</span><span style=" font-size:11pt;"> and </span><span style=" font-family:'Courier'; font-size:11pt; font-weight:600;">Courier</span><span style=" font-size:11pt;"> can also be used directly. </span><span style=" font-size:11pt; font-style:italic;">If you place the cursor in a region of styled text, the controls in the tool bars will change to reflect the current style.</span></p>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">Paragraphs can be formatted so that the text is left-aligned, right-aligned, centered, or fully justified.</p>
<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-style:italic;">Try changing the alignment of some text and resize the editor to see how the text layout changes.</span> </p>
-<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16pt; font-weight:600;">Lists</span></p>
+<h2 align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16pt; font-weight:600;">Lists</span></h2>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:16pt; font-weight:600;"><span style=" font-size:11pt; font-weight:400;">Different kinds of lists can be included in rich text documents. Standard bullet lists can be nested, using different symbols for each level of the list: </span></p>
<ul style="-qt-list-indent: 1;"><li style=" font-size:11pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Disc symbols are typically used for top-level list items. </li></ul>
<ul type=circle style="-qt-list-indent: 2;"><li style=" font-size:11pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Circle symbols can be used to distinguish between items in lower-level lists.</li></ul>
@@ -24,10 +24,10 @@ p, li { white-space: pre-wrap; }
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">The list will automatically be renumbered if you add or remove items. <span style=" font-style:italic;">Try adding new sections to the above list or removing existing item to see the numbers change.</span> </p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
-<p style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Images</span></p>
+<h2 style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Images</span></h2>
<p style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:16pt; font-weight:600;"><span style=" font-size:11pt; font-weight:400;">Inline images are treated like ordinary ranges of characters in the text editor, so they flow with the surrounding text. Images can also be selected in the same way as text, making it easy to cut, copy, and paste them. </span></p>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><img src=":/images/logo32.png" /><span style=" font-style:italic;"> Try to select this image by clicking and dragging over it with the mouse, or use the text cursor to select it by holding down Shift and using the arrow keys. You can then cut or copy it, and paste it into different parts of this document.</span></p>
-<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Tables</span></p>
+<h2 align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Tables</span></h2>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:16pt; font-weight:600;"><span style=" font-size:11pt; font-weight:400;">QTextEdit can arrange and format tables, supporting features such as row and column spans, text formatting within cells, and size constraints for columns. </span></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
@@ -72,8 +72,8 @@ p, li { white-space: pre-wrap; }
<td></td></tr></table>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; font-style:italic;">Try adding text to the cells in the table and experiment with the alignment of the paragraphs.</p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Hyperlinks</span></p>
+<h2 style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Hyperlinks</span></h2>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">QTextEdit is designed to support hyperlinks between documents, and this feature is used extensively in </span><span style=" font-size:11pt; font-style:italic;">Qt Assistant</span><span style=" font-size:11pt;">. Hyperlinks are automatically created when an HTML file is imported into an editor. Since the rich text framework supports hyperlinks natively, they can also be created programatically.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Undo and Redo</span></p>
+<h2 style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Undo and Redo</span></h2>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">Full support for undo and redo operations is built into QTextEdit and the underlying rich text framework. Operations on a document can be packaged together to make editing a more comfortable experience for the user.</p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-style:italic;">Try making changes to this document and press Ctrl+Z to undo them. You can always recover the original contents of the document.</span> </p></body></html>
diff --git a/examples/widgets/richtext/textedit/textedit.cpp b/examples/widgets/richtext/textedit/textedit.cpp
index fe4ee4f499..0d51ce61ad 100644
--- a/examples/widgets/richtext/textedit/textedit.cpp
+++ b/examples/widgets/richtext/textedit/textedit.cpp
@@ -141,13 +141,23 @@ TextEdit::TextEdit(QWidget *parent)
#ifndef QT_NO_CLIPBOARD
actionCut->setEnabled(false);
+ connect(textEdit, &QTextEdit::copyAvailable, actionCut, &QAction::setEnabled);
actionCopy->setEnabled(false);
+ connect(textEdit, &QTextEdit::copyAvailable, actionCopy, &QAction::setEnabled);
connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &TextEdit::clipboardDataChanged);
#endif
textEdit->setFocus();
setCurrentFileName(QString());
+
+#ifdef Q_OS_MACOS
+ // Use dark text on light background on macOS, also in dark mode.
+ QPalette pal = textEdit->palette();
+ pal.setColor(QPalette::Base, QColor(Qt::white));
+ pal.setColor(QPalette::Text, QColor(Qt::black));
+ textEdit->setPalette(pal);
+#endif
}
void TextEdit::closeEvent(QCloseEvent *e)
@@ -348,6 +358,12 @@ void TextEdit::setupTextActions()
comboStyle->addItem("Ordered List (Alpha upper)");
comboStyle->addItem("Ordered List (Roman lower)");
comboStyle->addItem("Ordered List (Roman upper)");
+ comboStyle->addItem("Heading 1");
+ comboStyle->addItem("Heading 2");
+ comboStyle->addItem("Heading 3");
+ comboStyle->addItem("Heading 4");
+ comboStyle->addItem("Heading 5");
+ comboStyle->addItem("Heading 6");
connect(comboStyle, QOverload<int>::of(&QComboBox::activated), this, &TextEdit::textStyle);
@@ -575,44 +591,56 @@ void TextEdit::textSize(const QString &p)
void TextEdit::textStyle(int styleIndex)
{
QTextCursor cursor = textEdit->textCursor();
+ QTextListFormat::Style style = QTextListFormat::ListStyleUndefined;
+
+ switch (styleIndex) {
+ case 1:
+ style = QTextListFormat::ListDisc;
+ break;
+ case 2:
+ style = QTextListFormat::ListCircle;
+ break;
+ case 3:
+ style = QTextListFormat::ListSquare;
+ break;
+ case 4:
+ style = QTextListFormat::ListDecimal;
+ break;
+ case 5:
+ style = QTextListFormat::ListLowerAlpha;
+ break;
+ case 6:
+ style = QTextListFormat::ListUpperAlpha;
+ break;
+ case 7:
+ style = QTextListFormat::ListLowerRoman;
+ break;
+ case 8:
+ style = QTextListFormat::ListUpperRoman;
+ break;
+ default:
+ break;
+ }
- if (styleIndex != 0) {
- QTextListFormat::Style style = QTextListFormat::ListDisc;
-
- switch (styleIndex) {
- default:
- case 1:
- style = QTextListFormat::ListDisc;
- break;
- case 2:
- style = QTextListFormat::ListCircle;
- break;
- case 3:
- style = QTextListFormat::ListSquare;
- break;
- case 4:
- style = QTextListFormat::ListDecimal;
- break;
- case 5:
- style = QTextListFormat::ListLowerAlpha;
- break;
- case 6:
- style = QTextListFormat::ListUpperAlpha;
- break;
- case 7:
- style = QTextListFormat::ListLowerRoman;
- break;
- case 8:
- style = QTextListFormat::ListUpperRoman;
- break;
- }
+ cursor.beginEditBlock();
- cursor.beginEditBlock();
+ QTextBlockFormat blockFmt = cursor.blockFormat();
- QTextBlockFormat blockFmt = cursor.blockFormat();
+ if (style == QTextListFormat::ListStyleUndefined) {
+ blockFmt.setObjectIndex(-1);
+ int headingLevel = styleIndex >= 9 ? styleIndex - 9 + 1 : 0; // H1 to H6, or Standard
+ blockFmt.setHeadingLevel(headingLevel);
+ cursor.setBlockFormat(blockFmt);
+ int sizeAdjustment = headingLevel ? 4 - headingLevel : 0; // H1 to H6: +3 to -2
+ QTextCharFormat fmt;
+ fmt.setFontWeight(headingLevel ? QFont::Bold : QFont::Normal);
+ fmt.setProperty(QTextFormat::FontSizeAdjustment, sizeAdjustment);
+ cursor.select(QTextCursor::LineUnderCursor);
+ cursor.mergeCharFormat(fmt);
+ textEdit->mergeCurrentCharFormat(fmt);
+ } else {
QTextListFormat listFmt;
-
if (cursor.currentList()) {
listFmt = cursor.currentList()->format();
} else {
@@ -620,18 +648,11 @@ void TextEdit::textStyle(int styleIndex)
blockFmt.setIndent(0);
cursor.setBlockFormat(blockFmt);
}
-
listFmt.setStyle(style);
-
cursor.createList(listFmt);
-
- cursor.endEditBlock();
- } else {
- // ####
- QTextBlockFormat bfmt;
- bfmt.setObjectIndex(-1);
- cursor.mergeBlockFormat(bfmt);
}
+
+ cursor.endEditBlock();
}
void TextEdit::textColor()
@@ -666,6 +687,41 @@ void TextEdit::currentCharFormatChanged(const QTextCharFormat &format)
void TextEdit::cursorPositionChanged()
{
alignmentChanged(textEdit->alignment());
+ QTextList *list = textEdit->textCursor().currentList();
+ if (list) {
+ switch (list->format().style()) {
+ case QTextListFormat::ListDisc:
+ comboStyle->setCurrentIndex(1);
+ break;
+ case QTextListFormat::ListCircle:
+ comboStyle->setCurrentIndex(2);
+ break;
+ case QTextListFormat::ListSquare:
+ comboStyle->setCurrentIndex(3);
+ break;
+ case QTextListFormat::ListDecimal:
+ comboStyle->setCurrentIndex(4);
+ break;
+ case QTextListFormat::ListLowerAlpha:
+ comboStyle->setCurrentIndex(5);
+ break;
+ case QTextListFormat::ListUpperAlpha:
+ comboStyle->setCurrentIndex(6);
+ break;
+ case QTextListFormat::ListLowerRoman:
+ comboStyle->setCurrentIndex(7);
+ break;
+ case QTextListFormat::ListUpperRoman:
+ comboStyle->setCurrentIndex(8);
+ break;
+ default:
+ comboStyle->setCurrentIndex(-1);
+ break;
+ }
+ } else {
+ int headingLevel = textEdit->textCursor().blockFormat().headingLevel();
+ comboStyle->setCurrentIndex(headingLevel ? headingLevel + 8 : 0);
+ }
}
void TextEdit::clipboardDataChanged()
diff --git a/examples/widgets/tools/undo/main.cpp b/examples/widgets/tools/undo/main.cpp
index eff44ca3e8..a5ec1b1b83 100644
--- a/examples/widgets/tools/undo/main.cpp
+++ b/examples/widgets/tools/undo/main.cpp
@@ -62,4 +62,4 @@ int main(int argc, char **argv)
win.show();
return app.exec();
-};
+}
diff --git a/examples/widgets/touch/dials/dials.pro b/examples/widgets/touch/dials/dials.pro
new file mode 100644
index 0000000000..0e823551cc
--- /dev/null
+++ b/examples/widgets/touch/dials/dials.pro
@@ -0,0 +1,8 @@
+QT += widgets
+
+SOURCES += main.cpp
+FORMS += dials.ui
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/dials
+INSTALLS += target
diff --git a/examples/touch/dials/dials.ui b/examples/widgets/touch/dials/dials.ui
index 8ca7ae9475..8ca7ae9475 100644
--- a/examples/touch/dials/dials.ui
+++ b/examples/widgets/touch/dials/dials.ui
diff --git a/examples/touch/dials/doc/images/touch-dials-example.png b/examples/widgets/touch/dials/doc/images/touch-dials-example.png
index 60e1776fc3..60e1776fc3 100644
--- a/examples/touch/dials/doc/images/touch-dials-example.png
+++ b/examples/widgets/touch/dials/doc/images/touch-dials-example.png
Binary files differ
diff --git a/examples/widgets/touch/dials/doc/src/touch-dials.qdoc b/examples/widgets/touch/dials/doc/src/touch-dials.qdoc
new file mode 100644
index 0000000000..dec8248efb
--- /dev/null
+++ b/examples/widgets/touch/dials/doc/src/touch-dials.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example touch/dials
+ \title Touch Dials Example
+ \ingroup touchinputexamples
+ \brief Shows how to apply touch to a set of standard Qt widgets.
+
+ The Touch Dials example shows how to apply touch to a set of
+ standard Qt widgets.
+
+ \image touch-dials-example.png
+*/
diff --git a/examples/touch/dials/main.cpp b/examples/widgets/touch/dials/main.cpp
index 071f485de3..071f485de3 100644
--- a/examples/touch/dials/main.cpp
+++ b/examples/widgets/touch/dials/main.cpp
diff --git a/examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc b/examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc
new file mode 100644
index 0000000000..6f8f636f86
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example touch/fingerpaint
+ \title Finger Paint Example
+ \ingroup touchinputexamples
+ \brief Shows the use of a touchscreen to make a simple painting application.
+
+ The Finger Paint example shows the use of a touchscreen with a custom widget
+ to create a simple painting application.
+
+ \image touch-fingerpaint-example.png
+
+ This example was specifically designed to work with a touchscreen, using
+ QTouchEvent instead of QMouseEvent to handle user input over the custom
+ widget. As a result, it is not possible to draw with the mouse cursor.
+*/
diff --git a/examples/widgets/touch/fingerpaint/fingerpaint.pro b/examples/widgets/touch/fingerpaint/fingerpaint.pro
new file mode 100644
index 0000000000..6370da6607
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/fingerpaint.pro
@@ -0,0 +1,13 @@
+QT += widgets
+requires(qtConfig(filedialog))
+qtHaveModule(printsupport): QT += printsupport
+
+HEADERS = mainwindow.h \
+ scribblearea.h
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ scribblearea.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/fingerpaint
+INSTALLS += target
diff --git a/examples/touch/fingerpaint/main.cpp b/examples/widgets/touch/fingerpaint/main.cpp
index e7ab8856b7..e7ab8856b7 100644
--- a/examples/touch/fingerpaint/main.cpp
+++ b/examples/widgets/touch/fingerpaint/main.cpp
diff --git a/examples/touch/fingerpaint/mainwindow.cpp b/examples/widgets/touch/fingerpaint/mainwindow.cpp
index 0e45eea240..0e45eea240 100644
--- a/examples/touch/fingerpaint/mainwindow.cpp
+++ b/examples/widgets/touch/fingerpaint/mainwindow.cpp
diff --git a/examples/touch/fingerpaint/mainwindow.h b/examples/widgets/touch/fingerpaint/mainwindow.h
index 47c339050e..47c339050e 100644
--- a/examples/touch/fingerpaint/mainwindow.h
+++ b/examples/widgets/touch/fingerpaint/mainwindow.h
diff --git a/examples/touch/fingerpaint/scribblearea.cpp b/examples/widgets/touch/fingerpaint/scribblearea.cpp
index aa4e60c934..aa4e60c934 100644
--- a/examples/touch/fingerpaint/scribblearea.cpp
+++ b/examples/widgets/touch/fingerpaint/scribblearea.cpp
diff --git a/examples/touch/fingerpaint/scribblearea.h b/examples/widgets/touch/fingerpaint/scribblearea.h
index 5138e3a1ab..5138e3a1ab 100644
--- a/examples/touch/fingerpaint/scribblearea.h
+++ b/examples/widgets/touch/fingerpaint/scribblearea.h
diff --git a/examples/touch/knobs/doc/images/touch-knobs-example.png b/examples/widgets/touch/knobs/doc/images/touch-knobs-example.png
index 1cbd90d101..1cbd90d101 100644
--- a/examples/touch/knobs/doc/images/touch-knobs-example.png
+++ b/examples/widgets/touch/knobs/doc/images/touch-knobs-example.png
Binary files differ
diff --git a/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc b/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc
new file mode 100644
index 0000000000..6da5992195
--- /dev/null
+++ b/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example touch/knobs
+ \title Touch Knobs Example
+ \ingroup touchinputexamples
+ \brief Shows how to create custom controls that accept touch input.
+
+ The Touch Knobs example shows how to create custom controls that
+ accept touch input.
+
+ \image touch-knobs-example.png
+*/
diff --git a/examples/touch/knobs/knob.cpp b/examples/widgets/touch/knobs/knob.cpp
index 12aaa1e948..12aaa1e948 100644
--- a/examples/touch/knobs/knob.cpp
+++ b/examples/widgets/touch/knobs/knob.cpp
diff --git a/examples/touch/knobs/knob.h b/examples/widgets/touch/knobs/knob.h
index c16b61d6f1..c16b61d6f1 100644
--- a/examples/touch/knobs/knob.h
+++ b/examples/widgets/touch/knobs/knob.h
diff --git a/examples/widgets/touch/knobs/knobs.pro b/examples/widgets/touch/knobs/knobs.pro
new file mode 100644
index 0000000000..0915b0665a
--- /dev/null
+++ b/examples/widgets/touch/knobs/knobs.pro
@@ -0,0 +1,8 @@
+QT += widgets
+
+HEADERS = knob.h
+SOURCES = main.cpp knob.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/knobs
+INSTALLS += target
diff --git a/examples/touch/knobs/main.cpp b/examples/widgets/touch/knobs/main.cpp
index ea0e857e7b..ea0e857e7b 100644
--- a/examples/touch/knobs/main.cpp
+++ b/examples/widgets/touch/knobs/main.cpp
diff --git a/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png b/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png
new file mode 100644
index 0000000000..7db51fbf55
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png
Binary files differ
diff --git a/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc b/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc
new file mode 100644
index 0000000000..61db2f96c5
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example touch/pinchzoom
+ \title Pinch Zoom Example
+ \ingroup touchinputexamples
+ \brief Shows how to recognize a gesture.
+
+ The Pinch Zoom example shows how to use low-level touch information
+ to recognize a gesture.
+
+ \image touch-pinchzoom-example.png
+*/
diff --git a/examples/touch/pinchzoom/graphicsview.cpp b/examples/widgets/touch/pinchzoom/graphicsview.cpp
index 54e134aea2..54e134aea2 100644
--- a/examples/touch/pinchzoom/graphicsview.cpp
+++ b/examples/widgets/touch/pinchzoom/graphicsview.cpp
diff --git a/examples/touch/pinchzoom/graphicsview.h b/examples/widgets/touch/pinchzoom/graphicsview.h
index d4e2e32d36..d4e2e32d36 100644
--- a/examples/touch/pinchzoom/graphicsview.h
+++ b/examples/widgets/touch/pinchzoom/graphicsview.h
diff --git a/examples/touch/pinchzoom/images/cheese.jpg b/examples/widgets/touch/pinchzoom/images/cheese.jpg
index dea5795fd0..dea5795fd0 100644
--- a/examples/touch/pinchzoom/images/cheese.jpg
+++ b/examples/widgets/touch/pinchzoom/images/cheese.jpg
Binary files differ
diff --git a/examples/touch/pinchzoom/main.cpp b/examples/widgets/touch/pinchzoom/main.cpp
index 938432600f..938432600f 100644
--- a/examples/touch/pinchzoom/main.cpp
+++ b/examples/widgets/touch/pinchzoom/main.cpp
diff --git a/examples/touch/pinchzoom/mice.qrc b/examples/widgets/touch/pinchzoom/mice.qrc
index accdb4d0a6..accdb4d0a6 100644
--- a/examples/touch/pinchzoom/mice.qrc
+++ b/examples/widgets/touch/pinchzoom/mice.qrc
diff --git a/examples/touch/pinchzoom/mouse.cpp b/examples/widgets/touch/pinchzoom/mouse.cpp
index 1e6814be13..1e6814be13 100644
--- a/examples/touch/pinchzoom/mouse.cpp
+++ b/examples/widgets/touch/pinchzoom/mouse.cpp
diff --git a/examples/touch/pinchzoom/mouse.h b/examples/widgets/touch/pinchzoom/mouse.h
index 870bfcd6c0..870bfcd6c0 100644
--- a/examples/touch/pinchzoom/mouse.h
+++ b/examples/widgets/touch/pinchzoom/mouse.h
diff --git a/examples/widgets/touch/pinchzoom/pinchzoom.pro b/examples/widgets/touch/pinchzoom/pinchzoom.pro
new file mode 100644
index 0000000000..ebbc7ddf1f
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/pinchzoom.pro
@@ -0,0 +1,16 @@
+QT += widgets
+
+HEADERS += \
+ mouse.h \
+ graphicsview.h
+SOURCES += \
+ main.cpp \
+ mouse.cpp \
+ graphicsview.cpp
+
+RESOURCES += \
+ mice.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/pinchzoom
+INSTALLS += target
diff --git a/examples/touch/touch.pro b/examples/widgets/touch/touch.pro
index 018ec134eb..018ec134eb 100644
--- a/examples/touch/touch.pro
+++ b/examples/widgets/touch/touch.pro
diff --git a/examples/widgets/widgets.pro b/examples/widgets/widgets.pro
index f9d863b69e..8bd85bfe6b 100644
--- a/examples/widgets/widgets.pro
+++ b/examples/widgets/widgets.pro
@@ -19,6 +19,7 @@ SUBDIRS = \
scroller \
statemachine \
tools \
+ touch \
tutorials \
widgets
diff --git a/examples/widgets/widgets/tablet/mainwindow.cpp b/examples/widgets/widgets/tablet/mainwindow.cpp
index 994666d4de..a048119533 100644
--- a/examples/widgets/widgets/tablet/mainwindow.cpp
+++ b/examples/widgets/widgets/tablet/mainwindow.cpp
@@ -104,15 +104,16 @@ void MainWindow::setEventCompression(bool compress)
}
//! [5]
-void MainWindow::save()
+bool MainWindow::save()
{
QString path = QDir::currentPath() + "/untitled.png";
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"),
path);
-
- if (!m_canvas->saveImage(fileName))
+ bool success = m_canvas->saveImage(fileName);
+ if (!success)
QMessageBox::information(this, "Error Saving Picture",
"Could not save the image");
+ return success;
}
//! [5]
@@ -128,6 +129,14 @@ void MainWindow::load()
}
//! [6]
+void MainWindow::clear()
+{
+ if (QMessageBox::question(this, tr("Save changes"), tr("Do you want to save your changes?"),
+ QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
+ QMessageBox::Save) != QMessageBox::Save || save())
+ m_canvas->clear();
+}
+
//! [7]
void MainWindow::about()
{
@@ -142,6 +151,7 @@ void MainWindow::createMenus()
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(tr("&Open..."), this, &MainWindow::load, QKeySequence::Open);
fileMenu->addAction(tr("&Save As..."), this, &MainWindow::save, QKeySequence::SaveAs);
+ fileMenu->addAction(tr("&New"), this, &MainWindow::clear, QKeySequence::New);
fileMenu->addAction(tr("E&xit"), this, &MainWindow::close, QKeySequence::Quit);
QMenu *brushMenu = menuBar()->addMenu(tr("&Brush"));
diff --git a/examples/widgets/widgets/tablet/mainwindow.h b/examples/widgets/widgets/tablet/mainwindow.h
index 4b99324f04..4be28784b5 100644
--- a/examples/widgets/widgets/tablet/mainwindow.h
+++ b/examples/widgets/widgets/tablet/mainwindow.h
@@ -72,8 +72,9 @@ private slots:
void setLineWidthValuator(QAction *action);
void setSaturationValuator(QAction *action);
void setEventCompression(bool compress);
- void save();
+ bool save();
void load();
+ void clear();
void about();
private:
diff --git a/examples/widgets/widgets/tablet/tablet.pro b/examples/widgets/widgets/tablet/tablet.pro
index 5772cd0385..647dc2c2f7 100644
--- a/examples/widgets/widgets/tablet/tablet.pro
+++ b/examples/widgets/widgets/tablet/tablet.pro
@@ -10,6 +10,11 @@ SOURCES = mainwindow.cpp \
tabletapplication.cpp
RESOURCES += images.qrc
+# Avoid naming the target "tablet", as it would create an executable
+# named "tablet.exe" on Windows and trigger a bug (in the Wacom drivers, apparently)
+# preventing tablet messages from being received.
+TARGET = qttablet
+
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/tablet
INSTALLS += target
diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp
index 73678ab754..bfcc84e182 100644
--- a/examples/widgets/widgets/tablet/tabletcanvas.cpp
+++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp
@@ -90,6 +90,12 @@ bool TabletCanvas::loadImage(const QString &file)
}
//! [2]
+void TabletCanvas::clear()
+{
+ m_pixmap.fill(Qt::white);
+ update();
+}
+
//! [3]
void TabletCanvas::tabletEvent(QTabletEvent *event)
{
@@ -142,12 +148,14 @@ void TabletCanvas::initPixmap()
m_pixmap = newPixmap;
}
-void TabletCanvas::paintEvent(QPaintEvent *)
+void TabletCanvas::paintEvent(QPaintEvent *event)
{
if (m_pixmap.isNull())
initPixmap();
QPainter painter(this);
- painter.drawPixmap(0, 0, m_pixmap);
+ QRect pixmapPortion = QRect(event->rect().topLeft() * devicePixelRatioF(),
+ event->rect().size() * devicePixelRatioF());
+ painter.drawPixmap(event->rect().topLeft(), m_pixmap, pixmapPortion);
}
//! [4]
diff --git a/examples/widgets/widgets/tablet/tabletcanvas.h b/examples/widgets/widgets/tablet/tabletcanvas.h
index 671d5376f8..c63ef76893 100644
--- a/examples/widgets/widgets/tablet/tabletcanvas.h
+++ b/examples/widgets/widgets/tablet/tabletcanvas.h
@@ -79,6 +79,7 @@ public:
bool saveImage(const QString &file);
bool loadImage(const QString &file);
+ void clear();
void setAlphaChannelValuator(Valuator type)
{ m_alphaChannelValuator = type; }
void setColorSaturationValuator(Valuator type)
diff --git a/header.MIT b/header.MIT
new file mode 100644
index 0000000000..df431dda02
--- /dev/null
+++ b/header.MIT
@@ -0,0 +1,28 @@
+/****************************************************************************
+**
+** Copyright (C) YYYY Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:MIT$
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf
index b665000d00..953b13dc37 100644
--- a/mkspecs/android-clang/qmake.conf
+++ b/mkspecs/android-clang/qmake.conf
@@ -40,7 +40,7 @@ QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \
ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH
ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so
-ANDROID_CXX_STL_LIBS = -lc++
+ANDROID_CXX_STL_LIBS = -lc++_shared
QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz
diff --git a/mkspecs/common/android-base-head.conf b/mkspecs/common/android-base-head.conf
index 9be6111915..c7c27298b9 100644
--- a/mkspecs/common/android-base-head.conf
+++ b/mkspecs/common/android-base-head.conf
@@ -75,3 +75,10 @@ equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \
QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64
CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-
+
+QMAKE_PCH_OUTPUT_EXT = .gch
+
+QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
+QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
+QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
+QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
diff --git a/mkspecs/common/android-base-tail.conf b/mkspecs/common/android-base-tail.conf
index 7c3ae9566a..e239fa01c5 100644
--- a/mkspecs/common/android-base-tail.conf
+++ b/mkspecs/common/android-base-tail.conf
@@ -30,6 +30,8 @@ QMAKE_CFLAGS_THREAD = -D_REENTRANT
QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
QMAKE_CFLAGS_NEON = -mfpu=neon
+QMAKE_CFLAGS_GNUC99 = -std=gnu99
+QMAKE_CFLAGS_GNUC11 = -std=gnu11
QMAKE_CXXFLAGS_CXX11 = -std=c++11
QMAKE_CXXFLAGS_CXX14 = -std=c++14
QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf
index 0fb84bc1b3..5800aaa5b4 100644
--- a/mkspecs/common/clang.conf
+++ b/mkspecs/common/clang.conf
@@ -21,6 +21,8 @@ QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_
QMAKE_CFLAGS_USE_PRECOMPILE = -Xclang -include-pch -Xclang ${QMAKE_PCH_OUTPUT}
QMAKE_CFLAGS_LTCG = -flto
QMAKE_CFLAGS_DISABLE_LTCG = -fno-lto
+QMAKE_CFLAGS_GNUC99 = -std=gnu99
+QMAKE_CFLAGS_GNUC11 = -std=gnu11
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
diff --git a/mkspecs/common/g++-base.conf b/mkspecs/common/g++-base.conf
index c42c46b0ec..fa0f0c391d 100644
--- a/mkspecs/common/g++-base.conf
+++ b/mkspecs/common/g++-base.conf
@@ -27,6 +27,8 @@ QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
+QMAKE_CFLAGS_GNUC99 = -std=gnu99
+QMAKE_CFLAGS_GNUC11 = -std=gnu11
QMAKE_CXXFLAGS_CXX11 = -std=c++11
QMAKE_CXXFLAGS_CXX14 = -std=c++1y
QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf
index 234f71d495..c2669e4833 100644
--- a/mkspecs/common/gcc-base.conf
+++ b/mkspecs/common/gcc-base.conf
@@ -50,7 +50,7 @@ QMAKE_CFLAGS_ISYSTEM = -isystem
QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
QMAKE_CFLAGS_EXCEPTIONS_OFF += -fno-exceptions
-QMAKE_CFLAGS_SPLIT_SECTIONS += -ffunction-sections
+QMAKE_CFLAGS_SPLIT_SECTIONS += -ffunction-sections -fdata-sections
QMAKE_CFLAGS_LTCG = -flto -fno-fat-lto-objects
QMAKE_CFLAGS_LTCG_FATOBJECTS = -ffat-lto-objects
QMAKE_CFLAGS_DISABLE_LTCG = -fno-lto
@@ -81,6 +81,9 @@ QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO +=
QMAKE_LFLAGS_EXCEPTIONS_OFF +=
QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG -fuse-linker-plugin
+QMAKE_CFLAGS_C99 = -std=c99
+QMAKE_CFLAGS_C11 = -std=c11
+
QMAKE_CFLAGS_SSE2 += -msse2
QMAKE_CFLAGS_SSE3 += -msse3
QMAKE_CFLAGS_SSSE3 += -mssse3
@@ -105,6 +108,9 @@ QMAKE_CFLAGS_NEON += -mfpu=neon
QMAKE_CFLAGS_MIPS_DSP += -mdsp
QMAKE_CFLAGS_MIPS_DSPR2 += -mdspr2
+# -march=haswell is supported as of GCC 4.9 and Clang 3.6
+QMAKE_CFLAGS_ARCH_HASWELL = -march=core-avx2
+
# Wrapper tools that understand .o/.a files with GIMPLE instead of machine code
QMAKE_AR_LTCG = gcc-ar cqs
QMAKE_NM_LTCG = gcc-nm -P
diff --git a/mkspecs/common/icc-base-unix.conf b/mkspecs/common/icc-base-unix.conf
new file mode 100644
index 0000000000..54eda984b7
--- /dev/null
+++ b/mkspecs/common/icc-base-unix.conf
@@ -0,0 +1,106 @@
+#
+# Base qmake configuration for ICC on *nix-systems
+#
+# Before making changes to this file, please read the comment in
+# icc-base.conf, to make sure the change goes in the right place.
+#
+# To verify that your change has the desired effect on the final configuration
+# you can use the manual test in tests/manual/mkspecs.
+#
+
+MAKEFILE_GENERATOR = UNIX
+QMAKE_COMPILER_DEFINES += __GNUC__
+
+QMAKE_COMPILER = gcc intel_icc # icc pretends to be gcc
+
+QMAKE_CFLAGS_OPTIMIZE = -O2
+QMAKE_CFLAGS_OPTIMIZE_SIZE = -Os
+
+QMAKE_CC = icc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_APP = -fPIC
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280,3373
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_OPTIMIZE
+QMAKE_CFLAGS_DEBUG = -O0 -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CFLAGS_SPLIT_SECTIONS = -ffunction-sections -fdata-sections
+QMAKE_CFLAGS_LTCG = -ipo
+QMAKE_CFLAGS_DISABLE_LTCG = -no-ipo
+
+QMAKE_CFLAGS_SSE2 += -msse2
+QMAKE_CFLAGS_SSE3 += -msse3
+QMAKE_CFLAGS_SSSE3 += -mssse3
+QMAKE_CFLAGS_SSE4_1 += -msse4.1
+QMAKE_CFLAGS_SSE4_2 += -msse4.2
+QMAKE_CFLAGS_AVX += -march=core-avx
+QMAKE_CFLAGS_AVX2 += -march=core-avx2
+QMAKE_CFLAGS_AVX512F += -march=broadwell -xCOMMON-AVX512
+QMAKE_CFLAGS_AVX512CD += -march=broadwell -xCOMMON-AVX512
+QMAKE_CFLAGS_AVX512ER += -march=knl
+QMAKE_CFLAGS_AVX512PF += -march=knl
+QMAKE_CFLAGS_AVX512DQ += -march=skylake-avx512
+QMAKE_CFLAGS_AVX512BW += -march=skylake-avx512
+QMAKE_CFLAGS_AVX512VL += -march=skylake-avx512
+QMAKE_CFLAGS_AESNI += -maes
+QMAKE_CFLAGS_F16C += $$QMAKE_CFLAGS_AVX2
+QMAKE_CFLAGS_RDRND += -mrdrnd
+QMAKE_CFLAGS_SHANI += -msha
+
+QMAKE_CXX = icpc
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_APP = $$QMAKE_CFLAGS_APP
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
+QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
+QMAKE_CXXFLAGS_CXX11 = -std=c++11
+QMAKE_CXXFLAGS_CXX14 = -std=c++1y
+QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
+QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
+QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++1y
+QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z
+QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
+QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG
+
+# pch support
+CONFIG += icc_pch_style
+QMAKE_PCH_OUTPUT_EXT = .pchi
+QMAKE_CXXFLAGS_USE_PRECOMPILE = -pch-use ${QMAKE_PCH_OUTPUT} -include ${QMAKE_PCH_INPUT}
+QMAKE_CXXFLAGS_PRECOMPILE = -c -pch-create ${QMAKE_PCH_OUTPUT} -include ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_TEMP_OBJECT} ${QMAKE_PCH_TEMP_SOURCE}
+
+# Symbol visibility control
+QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
+QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_LINK = icpc
+QMAKE_LINK_SHLIB = icpc
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_THREAD =
+QMAKE_LFLAGS_RPATH = -Wl,-rpath,
+QMAKE_LFLAGS_CXX11 =
+QMAKE_LFLAGS_CXX14 =
+QMAKE_LFLAGS_CXX1Z =
+QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)/ti_files
diff --git a/mkspecs/common/macx.conf b/mkspecs/common/macx.conf
index 8f9eda10d7..6e95112f9b 100644
--- a/mkspecs/common/macx.conf
+++ b/mkspecs/common/macx.conf
@@ -5,6 +5,8 @@
QMAKE_PLATFORM += macos osx macx
QMAKE_MAC_SDK = macosx
+QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12
+QMAKE_APPLE_DEVICE_ARCHS = x86_64
QT_MAC_SDK_VERSION_TESTED_WITH = 10.13
device.sdk = macosx
@@ -13,4 +15,6 @@ device.dir_affix = $${device.sdk}
device.CONFIG = $${device.sdk}
device.deployment_identifier = $${device.sdk}
+QMAKE_LIBS_VULKAN =
+
include(mac.conf)
diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf
index b7d2eecc82..a4fadeb029 100644
--- a/mkspecs/common/msvc-desktop.conf
+++ b/mkspecs/common/msvc-desktop.conf
@@ -16,7 +16,9 @@ MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
QMAKE_COMPILER = msvc
CONFIG += flat debug_and_release debug_and_release_target precompile_header autogen_precompile_source embed_manifest_dll embed_manifest_exe
-DEFINES += UNICODE _UNICODE WIN32
+# MSVC 2017 15.8+ fixed std::aligned_storage but compilation fails without
+# _ENABLE_EXTENDED_ALIGNED_STORAGE flag since the fix breaks binary compatibility.
+DEFINES += UNICODE _UNICODE WIN32 _ENABLE_EXTENDED_ALIGNED_STORAGE
QMAKE_COMPILER_DEFINES += _WIN32
contains(QMAKE_TARGET.arch, x86_64) {
DEFINES += WIN64
diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf
index 5805383a04..3fb55c9d81 100644
--- a/mkspecs/common/msvc-version.conf
+++ b/mkspecs/common/msvc-version.conf
@@ -110,12 +110,6 @@ greaterThan(QMAKE_MSC_VER, 1909) {
QMAKE_CXXFLAGS_CXX14 = -std:c++14
QMAKE_CXXFLAGS_CXX1Z = -std:c++17
}
-
- # MSVC 2017 15.8+ fixed std::aligned_storage but compilation fails without
- # this flag since the fix breaks binary compatibility.
- greaterThan(QMAKE_MSC_VER, 1914) {
- DEFINES += _ENABLE_EXTENDED_ALIGNED_STORAGE
- }
}
greaterThan(QMAKE_MSC_VER, 1910) {
diff --git a/mkspecs/common/qcc-base-qnx.conf b/mkspecs/common/qcc-base-qnx.conf
index 148645b4e9..21ce269006 100644
--- a/mkspecs/common/qcc-base-qnx.conf
+++ b/mkspecs/common/qcc-base-qnx.conf
@@ -42,9 +42,13 @@ QMAKE_INCDIR_POST = $${QNX_DIR}/usr/include $${QNX_DIR}/usr/include/freety
QMAKE_LIBDIR_POST = $${QNX_DIR}/$${QNX_CPUDIR}/lib $${QNX_DIR}/$${QNX_CPUDIR}/usr/lib
QMAKE_RPATHLINKDIR_POST += $${QNX_DIR}/$${QNX_CPUDIR}/lib $${QNX_DIR}/$${QNX_CPUDIR}/usr/lib
-QMAKE_CXXFLAGS_CXX11 = -Wc,-std=gnu++11
-QMAKE_CXXFLAGS_CXX14 = -Wc,-std=gnu++1y
-QMAKE_CXXFLAGS_CXX1Z = -Wc,-std=gnu++1z
+QMAKE_CXXFLAGS_CXX11 =
+QMAKE_CXXFLAGS_CXX14 =
+QMAKE_CXXFLAGS_CXX1Z =
+
+QMAKE_CXXFLAGS_GNUCXX11 = -Wc,-std=gnu++11
+QMAKE_CXXFLAGS_GNUCXX14 = -Wc,-std=gnu++1y
+QMAKE_CXXFLAGS_GNUCXX1Z = -Wc,-std=gnu++1z
QMAKE_LINK_C = $$QMAKE_CC
QMAKE_LINK_C_SHLIB = $$QMAKE_CC
diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf
index 8c1a767dfa..375e084127 100644
--- a/mkspecs/common/winrt_winphone/qmake.conf
+++ b/mkspecs/common/winrt_winphone/qmake.conf
@@ -8,7 +8,9 @@ MAKEFILE_GENERATOR = MSBUILD
QMAKE_COMPILER = msvc
QMAKE_PLATFORM = winrt win32
CONFIG = package_manifest $$CONFIG incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target rtti
-DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN
+# MSVC 2017 15.8+ fixed std::aligned_storage but compilation fails without
+# _ENABLE_EXTENDED_ALIGNED_STORAGE flag since the fix breaks binary compatibility.
+DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN _ENABLE_EXTENDED_ALIGNED_STORAGE
QMAKE_COMPILER_DEFINES += _WIN32
DEPLOYMENT_PLUGIN += qwinrt
diff --git a/mkspecs/features/data/macros.cpp b/mkspecs/features/data/macros.cpp
index 9dcb8f0914..7a06fad1a6 100644
--- a/mkspecs/features/data/macros.cpp
+++ b/mkspecs/features/data/macros.cpp
@@ -27,3 +27,6 @@ QMAKE_GCC_MAJOR_VERSION = __GNUC__
QMAKE_GCC_MINOR_VERSION = __GNUC_MINOR__
QMAKE_GCC_PATCH_VERSION = __GNUC_PATCHLEVEL__
#endif
+#ifdef __ghs__
+QMAKE_GHS_VERSION = __GHS_VERSION_NUMBER
+#endif
diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf
index 9eba5bcf00..ad4a5f6365 100644
--- a/mkspecs/features/default_post.prf
+++ b/mkspecs/features/default_post.prf
@@ -134,7 +134,7 @@ c++11|c++14|c++1z {
isEmpty(QMAKE_CXXFLAGS_GNU$$cxxstd) {
strict_c++: QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_STRICTCXX
} else {
- !strict_c++: cxxstd = GNU$$cxxstd
+ !strict_c++|isEmpty(QMAKE_CXXFLAGS_$$cxxstd): cxxstd = GNU$$cxxstd
}
QMAKE_CXXFLAGS += $$eval(QMAKE_CXXFLAGS_$$cxxstd)
@@ -143,6 +143,19 @@ c++11|c++14|c++1z {
unset(cxxstd)
}
+c99|c11 {
+ c11: cstd = C11
+ else: cstd = C99
+
+ !isEmpty(QMAKE_CFLAGS_GNU$$cstd) {
+ !strict_c|isEmpty(QMAKE_CFLAGS_$$cstd): cstd = GNU$$cstd
+ }
+
+ QMAKE_CFLAGS += $$eval(QMAKE_CFLAGS_$$cstd)
+
+ unset(cstd)
+}
+
utf8_source {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_UTF8_SOURCE
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_UTF8_SOURCE
diff --git a/mkspecs/features/exclusive_builds.prf b/mkspecs/features/exclusive_builds.prf
index 2d7f0e1ab6..1ff9a04d42 100644
--- a/mkspecs/features/exclusive_builds.prf
+++ b/mkspecs/features/exclusive_builds.prf
@@ -38,5 +38,5 @@ defineTest(addExclusiveBuilds) {
}
# Default directories to process
-QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR TRACEGEN_DIR QMLCACHE_DIR
-QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR QMLCACHE_DIR
+QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR TRACEGEN_DIR QMLCACHE_DIR LRELEASE_DIR
+QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR QMLCACHE_DIR LRELEASE_DIR
diff --git a/mkspecs/features/gc_binaries.prf b/mkspecs/features/gc_binaries.prf
new file mode 100644
index 0000000000..111d5d95ef
--- /dev/null
+++ b/mkspecs/features/gc_binaries.prf
@@ -0,0 +1,3 @@
+QMAKE_CFLAGS += $$QMAKE_CFLAGS_SPLIT_SECTIONS
+QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SPLIT_SECTIONS
+QMAKE_LFLAGS += $$QMAKE_LFLAGS_GCSECTIONS
diff --git a/mkspecs/features/lrelease.prf b/mkspecs/features/lrelease.prf
new file mode 100644
index 0000000000..1e828b64df
--- /dev/null
+++ b/mkspecs/features/lrelease.prf
@@ -0,0 +1,41 @@
+# Automatically generate .qm files out of .ts files in TRANSLATIONS and
+# EXTRA_TRANSLATIONS.
+#
+# If embed_translations is enabled, the generated .qm files are made available
+# in the resource system under :/i18n/.
+#
+# Otherwise, the .qm files are available in the build directory in LRELEASE_DIR.
+# They can also be automatically installed by setting QM_FILES_INSTALL_PATH.
+
+qtPrepareTool(QMAKE_LRELEASE, lrelease)
+
+isEmpty(LRELEASE_DIR): LRELEASE_DIR = .qm
+isEmpty(QM_FILES_RESOURCE_PREFIX): QM_FILES_RESOURCE_PREFIX = i18n
+
+lrelease.name = lrelease
+lrelease.input = TRANSLATIONS EXTRA_TRANSLATIONS
+lrelease.output = $$LRELEASE_DIR/${QMAKE_FILE_IN_BASE}.qm
+lrelease.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} $$QMAKE_LRELEASE_FLAGS -qm ${QMAKE_FILE_OUT}
+silent: lrelease.commands = @echo lrelease ${QMAKE_FILE_IN} && $$lrelease.commands
+lrelease.CONFIG = no_link
+QMAKE_EXTRA_COMPILERS += lrelease
+
+all_translations = $$TRANSLATIONS $$EXTRA_TRANSLATIONS
+for (translation, all_translations) {
+ # mirrors $$LRELEASE_DIR/${QMAKE_FILE_IN_BASE}.qm above
+ translation = $$basename(translation)
+ QM_FILES += $$OUT_PWD/$$LRELEASE_DIR/$$replace(translation, \\..*$, .qm)
+}
+embed_translations {
+ qmake_qm_files.files = $$QM_FILES
+ qmake_qm_files.base = $$OUT_PWD/$$LRELEASE_DIR
+ qmake_qm_files.prefix = $$QM_FILES_RESOURCE_PREFIX
+ RESOURCES += qmake_qm_files
+} else {
+ !isEmpty(QM_FILES_INSTALL_PATH) {
+ qm_files.files = $$QM_FILES
+ qm_files.path = $$QM_FILES_INSTALL_PATH
+ INSTALLS += qm_files
+ }
+ lrelease.CONFIG += target_predeps no_clean
+}
diff --git a/mkspecs/features/qml_module.prf b/mkspecs/features/qml_module.prf
index 4db0040dc5..65212b2abf 100644
--- a/mkspecs/features/qml_module.prf
+++ b/mkspecs/features/qml_module.prf
@@ -31,13 +31,17 @@ qml1_target {
instbase = $$[QT_INSTALL_QML]
}
-!qml1_target:static: CONFIG += builtin_resources
+!qml1_target:static: \
+ CONFIG += builtin_resources
+else: \
+ CONFIG += install_qml_files
builtin_resources {
URITARGET = $$replace(URI, "\\.", "_")
- # Ensure the QML files are included in the resources. In static builds,
- # the QML engine reads also the qmldir file from the resources.
- $${URITARGET}.files = $$qmldir_file $$fq_qml_files
+ # In static builds, the QML engine reads also the qmldir file from the resources.
+ static: $${URITARGET}.files = $$qmldir_file
+ # Ensure the QML files are included in the resources.
+ $${URITARGET}.files += $$fq_qml_files
# qt-project.org/imports is the path used for locating imports inside the resources
$${URITARGET}.prefix = /qt-project.org/imports/$$TARGETPATH
RESOURCES += $${URITARGET}
@@ -47,7 +51,7 @@ builtin_resources {
qmldir.base = $$_PRO_FILE_PWD_
# Tools need qmldir and plugins.qmltypes always installed on the file system
qmldir.files = $$qmldir_file $$fq_aux_qml_files
-!builtin_resources: qmldir.files += $$fq_qml_files
+install_qml_files: qmldir.files += $$fq_qml_files
qmldir.path = $$instbase/$$TARGETPATH
INSTALLS += qmldir
diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf
index d49f4c49c1..0786dbfd84 100644
--- a/mkspecs/features/qml_plugin.prf
+++ b/mkspecs/features/qml_plugin.prf
@@ -111,7 +111,7 @@ load(qt_common)
load(resolve_target)
TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, )
qmltypes.target = qmltypes
- qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$replace(TARGETPATHBASE, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE
+ qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$QMAKE_QMLPLUGINDUMP_FLAGS $$replace(TARGETPATHBASE, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE
qmltypes.depends = $$QMAKE_RESOLVED_TARGET
} else {
qmltypes.CONFIG += recursive
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index b57afcf72d..90e318e2a4 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -230,7 +230,16 @@ for(ever) {
QMAKE_FRAMEWORKPATH *= $$MODULE_FRAMEWORKS
!isEmpty(MODULE_MODULE) {
contains(MODULE_CONFIG, lib_bundle) {
- LIBS$$var_sfx += -framework $$MODULE_MODULE
+ framework = $$MODULE_MODULE
+ qtConfig(debug_and_release):!macx-xcode {
+ platform_target_suffix = $$qtPlatformTargetSuffix()
+ !isEmpty(platform_target_suffix): \
+ # The -framework linker argument supports a name[,suffix] version,
+ # where if the suffix is specified the framework is first searched
+ # for the library with the suffix and then without.
+ framework = $$framework,$$platform_target_suffix
+ }
+ LIBS$$var_sfx += -framework $$framework
} else {
!isEmpty(MODULE_LIBS_ADD): \
LIBS$$var_sfx += -L$$MODULE_LIBS_ADD
diff --git a/mkspecs/features/qt_app.prf b/mkspecs/features/qt_app.prf
index 883f8ca215..8354f30eea 100644
--- a/mkspecs/features/qt_app.prf
+++ b/mkspecs/features/qt_app.prf
@@ -20,9 +20,6 @@ isEmpty(QMAKE_TARGET_DESCRIPTION): \
isEmpty(QMAKE_INFO_PLIST): CONFIG -= app_bundle
-# This decreases the binary size for tools if statically linked
-QMAKE_LFLAGS += $$QMAKE_LFLAGS_GCSECTIONS
-
host_build: QT -= gui # no host tool will ever use gui
host_build:force_bootstrap {
!build_pass:qtConfig(release_tools): CONFIG += release
diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf
index 021036e4f9..0c6c10dded 100644
--- a/mkspecs/features/qt_build_config.prf
+++ b/mkspecs/features/qt_build_config.prf
@@ -27,6 +27,7 @@ RCC_DIR = .rcc
UI_DIR = .uic
TRACEGEN_DIR = .tracegen
QMLCACHE_DIR = .qmlcache
+LRELEASE_DIR = .qm
intel_icl {
# ICL 14.0 has a bug that makes it not find #includes in dirs starting with .
MOC_DIR = tmp/moc
diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf
index 415044bb64..4ad9946ae0 100644
--- a/mkspecs/features/qt_common.prf
+++ b/mkspecs/features/qt_common.prf
@@ -17,6 +17,8 @@ DEFINES *= QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
qtConfig(c++11): CONFIG += c++11 strict_c++
qtConfig(c++14): CONFIG += c++14
qtConfig(c++1z): CONFIG += c++1z
+qtConfig(c99): CONFIG += c99
+qtConfig(c11): CONFIG += c11
qtConfig(stack-protector-strong): CONFIG += stack_protector_strong
contains(TEMPLATE, .*lib) {
# module and plugins
@@ -56,19 +58,31 @@ host_build:cross_compile: return()
# -Wvla: use of variable-length arrays (an extension to C++)
clang {
clang_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION}
+ apple_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION}
versionAtLeast(clang_ver, 3.5): \
QMAKE_CXXFLAGS_WARN_ON += -Wdate-time
- # Clang/LLVM 5.0 and Xcode 9.0 introduced unguarded availability warnings.
- # The same construct has been a hard error in Swift from the very beginning.
- apple_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION}
- darwin:if(versionAtLeast(clang_ver, 5.0)|versionAtLeast(apple_ver, 9.0)): \
+ versionAtLeast(clang_ver, 3.6)|versionAtLeast(apple_ver, 6.3): \
+ QMAKE_CXXFLAGS_WARN_ON += -Winconsistent-missing-override
+
+ darwin {
QMAKE_CXXFLAGS_WARN_ON += \
- -Werror=unguarded-availability \
- -Werror=unguarded-availability-new \
- -Werror=unsupported-availability-guard
+ -Wobjc-interface-ivars \
+ -Wobjc-method-access \
+ -Wobjc-multiple-method-names
+
+ # Clang/LLVM 5.0 and Xcode 9.0 introduced unguarded availability warnings.
+ # The same construct has been a hard error in Swift from the very beginning.
+ versionAtLeast(clang_ver, 5.0)|versionAtLeast(apple_ver, 9.0): \
+ QMAKE_CXXFLAGS_WARN_ON += \
+ -Werror=unguarded-availability \
+ -Werror=unguarded-availability-new \
+ -Werror=unsupported-availability-guard
+ }
} else: gcc:!intel_icc {
QMAKE_CXXFLAGS_WARN_ON += -Wvla
+ # GCC 5 fixed -Wmissing-field-initializers for when there are no initializers
+ lessThan(QT_GCC_MAJOR_VERSION, 5): QMAKE_CXXFLAGS_WARN_ON += -Wno-missing-field-initializers
# GCC 5 introduced -Wdate-time
greaterThan(QT_GCC_MAJOR_VERSION, 4): QMAKE_CXXFLAGS_WARN_ON += -Wdate-time
# GCC 6 introduced these
@@ -82,11 +96,11 @@ warnings_are_errors:warning_clean {
# This setting is compiler-dependent anyway because it depends on the version of the
# compiler.
clang {
- # Apple clang 4.0-4.2,5.0-5.1,6.0-6.4,7.0-7.3
+ # Apple clang 4.0-4.2,5.0-5.1,6.0-6.4,7.0-7.3,8.0-8.3,9.0-9.2
# Regular clang 3.x-6.0
apple_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION}
reg_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION}
- contains(apple_ver, "4\\.[012]|5\\.[01]|6\\.[01234]|7\\.[0123]")|contains(reg_ver, "[345]\\.|6\\.0") {
+ contains(apple_ver, "4\\.[012]|5\\.[01]|6\\.[01234]|7\\.[0123]|8\\.[0123]|9\\.[012]")|contains(reg_ver, "[345]\\.|6\\.0") {
QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR
}
} else:intel_icc:linux {
diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf
index 4039bba431..81b820978a 100644
--- a/mkspecs/features/qt_configure.prf
+++ b/mkspecs/features/qt_configure.prf
@@ -495,6 +495,15 @@ defineTest(qtConfLibrary_inline) {
!defined($${1}.libs, var):isEmpty($${1}.builds._KEYS_): \
error("'inline' source in library '$$lib' specifies neither 'libs' nor 'builds'.")
+ # library lists are specified as strings in the json sources for
+ # readability, but it's a pain to work with that, so expand it now.
+ eval($${1}.libs = $$eval($${1}.libs))
+ export($${1}.libs)
+ for (b, $${1}.builds._KEYS_) {
+ eval($${1}.builds.$${b} = $$eval($${1}.builds.$${b}))
+ export($${1}.builds.$${b})
+ }
+
# if multiple libraries provide the same export, it makes sense
# to make them recognize the same input variables.
input = $$eval($${2}.alias)
@@ -507,7 +516,7 @@ defineTest(qtConfLibrary_inline) {
iv = $${input}.libs.$${b}
vars += $$eval(config.commandline.rev_assignments.$${iv})
defined(config.input.$${iv}, var) {
- $${1}.builds.$${b} = $$eval(config.input.$${iv})
+ eval($${1}.builds.$${b} = $$eval(config.input.$${iv}))
export($${1}.builds.$${b})
$${1}.builds._KEYS_ *= $${b}
any = true
@@ -528,28 +537,28 @@ defineTest(qtConfLibrary_inline) {
# direct libs. overwrites inline libs.
defined(config.input.$${input}.libs, var) {
- $${1}.libs = $$eval(config.input.$${input}.libs)
+ eval($${1}.libs = $$eval(config.input.$${input}.libs))
export($${1}.libs)
}
# prefix. prepends to (possibly overwritten) inline libs.
- prefix = $$val_escape(config.input.$${input}.prefix)
+ prefix = $$eval(config.input.$${input}.prefix)
!isEmpty(prefix) {
$${1}.includedir = $$prefix/include
export($${1}.includedir)
- $${1}.libs = "-L$$prefix/lib $$eval($${1}.libs)"
+ $${1}.libs = -L$$prefix/lib $$eval($${1}.libs)
export($${1}.libs)
}
- incdir = $$val_escape(config.input.$${input}.incdir)
+ incdir = $$eval(config.input.$${input}.incdir)
!isEmpty(incdir) {
$${1}.includedir = $$incdir
export($${1}.includedir)
}
- libdir = $$val_escape(config.input.$${input}.libdir)
+ libdir = $$eval(config.input.$${input}.libdir)
!isEmpty(libdir) {
- $${1}.libs = "-L$$libdir $$eval($${1}.libs)"
+ $${1}.libs = -L$$libdir $$eval($${1}.libs)
export($${1}.libs)
}
@@ -563,13 +572,12 @@ defineTest(qtConfLibrary_makeSpec) {
isEmpty(spec): \
error("makeSpec source in library '$$eval($${1}.library)' does not specify 'spec'.")
- $${1}.includedir = "$$val_escape(QMAKE_INCDIR_$$spec)"
+ $${1}.includedir = $$eval(QMAKE_INCDIR_$$spec)
export($${1}.includedir)
- libs =
+ $${1}.libs =
for (l, QMAKE_LIBDIR_$$spec): \
- libs += -L$$l
- libs += $$eval(QMAKE_LIBS_$$spec)
- $${1}.libs = "$$val_escape(libs)"
+ $${1}.libs += -L$$l
+ $${1}.libs += $$eval(QMAKE_LIBS_$$spec)
export($${1}.libs)
# the library definition is always in scope, so no point in exporting it.
@@ -596,13 +604,39 @@ defineTest(qtConfLibrary_pkgConfig) {
qtRunLoggedCommand("$$pkg_config --modversion $$args", version)|return(false)
qtRunLoggedCommand("$$pkg_config --libs-only-L $$args", libpaths)|return(false)
qtRunLoggedCommand("$$pkg_config --libs-only-l $$args", libs)|return(false)
- qtRunLoggedCommand("$$pkg_config --cflags $$args", $${1}.cflags)|return(false)
version ~= s/[^0-9.].*$//
$${1}.version = $$first(version)
export($${1}.version)
- libpaths += $$libs
- $${1}.libs = "$$libpaths"
+ eval($${1}.libs = $$libpaths $$libs)
export($${1}.libs)
+
+ qtRunLoggedCommand("$$pkg_config --cflags $$args", $${1}.cflags)|return(false)
+ # Split CFLAGS into stuff that goes into DEFINES, INCLUDEPATH, and other stuff.
+ # The compound variable is still set in case something wants to use it outside
+ # regular library exports.
+ defines =
+ includes =
+ ignored =
+ eval(cflags = $$eval($${1}.cflags))
+ for (i, cflags) {
+ contains(i, "-I.*") {
+ i ~= s/^-I//
+ includes += $$i
+ } else: contains(i, "-D.*") {
+ i ~= s/^-D//
+ defines += $$i
+ } else {
+ # Sometimes, pkg-config files include other flags
+ # we really don't need and shouldn't add.
+ ignored += $$i
+ }
+ }
+ !isEmpty(ignored): \
+ qtLog("Note: Dropped compiler flags '$$ignored'.")
+ $${1}.defines = $$defines
+ export($${1}.defines)
+ $${1}.includedir = $$includes
+ export($${1}.includedir)
return(true)
}
@@ -624,21 +658,35 @@ defineTest(qtConfTest_getPkgConfigVariable) {
}
defineReplace(qtConfLibraryArgs) {
- qmake_args =
- libs = $$eval($${1}.libs)
- !isEmpty(libs): \
- qmake_args += $$system_quote(LIBS += $$libs)
+ NAME = $$upper($$eval($${1}.library))
+ qmake_args = "QMAKE_LIBS_$${NAME} = $$val_escape($${1}.libs)"
for (b, $${1}.builds._KEYS_): \
- qmake_args += $$system_quote(LIBS_$$upper($$b) += $$eval($${1}.builds.$${b}))
+ qmake_args += "QMAKE_LIBS_$${NAME}_$$upper($$b) = $$val_escape($${1}.builds.$${b})"
includedir = $$eval($${1}.includedir)
!isEmpty(includedir): \
- qmake_args += $$system_quote(INCLUDEPATH *= $$includedir)
- cflags = $$eval($${1}.cflags)
- !isEmpty(cflags): \
- qmake_args += $$system_quote(QMAKE_CFLAGS += $$cflags) $$system_quote(QMAKE_CXXFLAGS += $$cflags)
+ qmake_args += "QMAKE_INCDIR_$${NAME} = $$val_escape(includedir)"
+ defines = $$eval($${1}.defines)
+ !isEmpty(defines): \
+ qmake_args += "QMAKE_DEFINES_$${NAME} = $$val_escape(defines)"
return($$qmake_args)
}
+defineReplace(qtConfAllLibraryArgs) {
+ isEmpty(1): return()
+ dep_uses =
+ dep_args =
+ for (use, 1) {
+ use_cfg = $$section(use, :, 0, 0)
+ use_lib = $$section(use, :, 1, 1)
+ dep_uses += $$use_lib
+ !isEmpty(use_cfg) {
+ lpfx = $${use_cfg}.libraries.$$use_lib
+ dep_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source))
+ }
+ }
+ return("QMAKE_USE += $$dep_uses" $$dep_args)
+}
+
defineTest(qtConfExportLibrary) {
lpfx = $${currentConfig}.libraries.$$1
alias = $$eval($${lpfx}.alias)
@@ -650,38 +698,17 @@ defineTest(qtConfExportLibrary) {
!$$qtConfEvaluate($$eval($${spfx}.export)): return()
output = privatePro
-
- eval(libs = $$eval($${spfx}.libs))
- eval(cflags = $$eval($${spfx}.cflags))
- eval(includes = $$eval($${spfx}.includedir))
-
- # Split $$cflags into stuff that goes into DEFINES, INCLUDEPATH, and other stuff.
- defines =
- ignored =
- for (i, cflags) {
- contains(i, "-I.*") {
- i ~= s/^-I//
- includes += $$i
- } else: contains(i, "-D.*") {
- i ~= s/^-D//
- defines += $$i
- } else {
- # Sometimes, pkg-config files or *-config scripts include other flags
- # we really don't need and shouldn't add (pg_config is really bad).
- ignored += $$i
- }
- }
- !isEmpty(ignored): \
- qtConfAddNote("Dropped compiler flags '$$ignored' when detecting library '$$name'.")
-
NAME = $$upper($$name)
# LIBS is emitted even if empty, as this allows the library to be "seen".
+ libs = $$eval($${spfx}.libs)
qtConfOutputVar(assign, $$output, QMAKE_LIBS_$$NAME, $$libs)
for (b, $${spfx}.builds._KEYS_) {
- eval(blibs = $$eval($${spfx}.builds.$${b}))
+ blibs = $$eval($${spfx}.builds.$${b})
qtConfOutputVar(assign, $$output, QMAKE_LIBS_$${NAME}_$$upper($$b), $$blibs)
}
+ defines = $$eval($${spfx}.defines)
!isEmpty(defines): qtConfOutputVar(assign, $$output, QMAKE_DEFINES_$$NAME, $$defines)
+ includes = $$eval($${spfx}.includedir)
!isEmpty(includes): qtConfOutputVar(assign, $$output, QMAKE_INCDIR_$$NAME, $$includes)
!isEmpty($${currentConfig}.module): \
qtConfExtendVar($$output, "QT.$${currentModule}_private.libraries", $$name)
@@ -708,7 +735,7 @@ defineTest(qtConfHandleLibrary) {
export($${lpfx}.result)
return()
}
- use_args = $$eval($${lpfx}.literal_args)
+ resolved_uses = $$eval($${lpfx}.resolved_uses)
qtConfLoadResult($${lpfx}, $$1, "library") {
$$eval($${lpfx}.result): \
@@ -741,9 +768,12 @@ defineTest(qtConfHandleLibrary) {
next()
}
+ $${lpfx}.source = $$s
+ export($${lpfx}.source)
+
# if the library defines a test, use it to verify the source.
!isEmpty($${lpfx}.test)|!isEmpty($${lpfx}.test._KEYS_) {
- $${lpfx}.literal_args = $$qtConfLibraryArgs($$spfx) $$use_args
+ $${lpfx}.resolved_uses = $$currentConfig:$$1 $$resolved_uses
$${lpfx}.host = $$eval($${spfx}.host)
!qtConfTest_compile($$lpfx) {
qtLog(" => source failed verification.")
@@ -759,9 +789,6 @@ defineTest(qtConfHandleLibrary) {
for (b, $${spfx}.builds._KEYS_): \
$${lpfx}.cache += sources.$${s}.builds.$${b}
- $${lpfx}.source = $$s
- export($${lpfx}.source)
-
# immediately output the library as well.
qtConfExportLibrary($$1)
@@ -855,21 +882,30 @@ defineTest(qtConfTestPrepare_compile) {
!defined(QMAKE_LIBS_$$nu, var): \
error("Test $$1 tries to use undeclared library '$$u'")
# using an external library by exported name.
- $${1}.literal_args += $$system_quote(QMAKE_USE += $$u)
+ $${1}.resolved_uses += :$$u
} else {
lpfx = $${libConfig}.libraries.$${u}
- isEmpty($${lpfx}.source): \
+ !equals($${lpfx}.result, true): \
return(false)
- $${1}.literal_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source))
+ $${1}.resolved_uses += $$libConfig:$$u
}
}
- export($${1}.literal_args)
+ export($${1}.resolved_uses)
return(true)
}
defineTest(qtConfPrepareCompileTestSource) {
test_dir = $$2
+ test_lang = $$eval($${1}.lang)
+ isEmpty(test_lang): test_lang = "c++"
+
+ equals(test_lang, "c++"): suffix = "cpp"
+ else: equals(test_lang, "c"): suffix = "c"
+ else: equals(test_lang, "objc"): suffix = "m"
+ else: equals(test_lang, "objc++"): suffix = "mm"
+ else: error("Unknown language '$$test_lang' in compile test $$1")
+
# Create source code
contents = "/* Generated by configure */"
# Custom code before includes
@@ -893,10 +929,10 @@ defineTest(qtConfPrepareCompileTestSource) {
" /* END TEST */" \
" return 0;" \
"}"
- write_file($$test_dir/main.cpp, contents)|error()
+ write_file($$test_dir/main.$$suffix, contents)|error()
# Create stub .pro file
- contents = "SOURCES = main.cpp"
+ contents = "SOURCES = main.$$suffix"
# Custom project code
for (ent, $$qtConfScalarOrList($${1}.qmake)): \
contents += $$ent
@@ -983,8 +1019,12 @@ defineTest(qtConfTest_compile) {
cont = "CONFIG += QTDIR_build"
write_file($$test_base_out_dir/.qmake.cache, cont)|error()
+ $${1}.literal_args += $$qtConfAllLibraryArgs($$eval($${1}.resolved_uses))
+
# add possible command line args
- qmake_args += $$qtConfPrepareArgs($$eval($${1}.args)) $$eval($${1}.literal_args)
+ qmake_args += \
+ $$qtConfPrepareArgs($$eval($${1}.args)) \
+ $$qtSystemQuote($$eval($${1}.literal_args))
qtRunLoggedCommand("$$test_cmd_base $$qmake_args $$system_quote($$test_dir)") {
qtRunLoggedCommand("$$test_cmd_base $$QMAKE_MAKE"): \
@@ -994,11 +1034,6 @@ defineTest(qtConfTest_compile) {
return(false)
}
-defineTest(qtConfTest_verifySpec) {
- qtConfTest_compile($$1): return(true)
- qtConfFatalError("Cannot compile a minimal program. The toolchain or QMakeSpec is broken.", log)
-}
-
defineTest(qtConfTest_files) {
for(i, $${1}.files._KEYS_) {
f = $$eval($${1}.files.$${i})
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index 8c7adc45eb..51b5bde67a 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -29,8 +29,6 @@ host_build|staticlib: CONFIG += static
host_build {
QT -= gui # no host module will ever use gui
- QMAKE_CFLAGS += $$QMAKE_CFLAGS_SPLIT_SECTIONS
- QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SPLIT_SECTIONS
force_bootstrap {
!build_pass:qtConfig(release_tools): CONFIG += release
contains(QT, core(-private)?|xml) {
@@ -266,15 +264,20 @@ load(qt_installs)
load(qt_targets)
# this builds on top of qt_common
-!internal_module:!lib_bundle:if(unix|mingw) {
+!internal_module:if(unix|mingw) {
CONFIG += create_pc
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
host_build: \
QMAKE_PKGCONFIG_LIBDIR = $$[QT_HOST_LIBS]
else: \
QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS/raw]
- QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw]
- QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME
+ lib_bundle {
+ QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_LIBS/raw]/$${MODULE_INCNAME}.framework/Headers
+ QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE
+ } else {
+ QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw]
+ QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME
+ }
QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ")
QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)
for(i, MODULE_DEPENDS): \
diff --git a/mkspecs/features/qt_test_helper.prf b/mkspecs/features/qt_test_helper.prf
new file mode 100644
index 0000000000..5daa14731d
--- /dev/null
+++ b/mkspecs/features/qt_test_helper.prf
@@ -0,0 +1,35 @@
+#
+# W A R N I N G
+# -------------
+#
+# This file is not part of the Qt API. It exists purely as an
+# implementation detail. It may change from version to version
+# without notice, or even be removed.
+#
+# We mean it.
+#
+
+# If an auto test needs a helper application, this helper should
+# be put into the same directory as the test itself. This common
+# folder should be the test's "main directory" or a "debug" or "release"
+# subfolder inside this main directory if debug_and_release is enabled.
+# Additionally the helper's executable is suffixed with "_helper" to
+# avoid name clashes with its folder.
+
+CONFIG -= app_bundle
+CONFIG += console
+
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/$${TARGET}_helper
+ } else {
+ TARGET = ../../release/$${TARGET}_helper
+ }
+} else {
+ TARGET = ../$${TARGET}_helper
+}
+
+parentFolder = $$dirname(_PRO_FILE_PWD_)
+testFolder = $$basename(parentFolder)
+target.path = $$[QT_INSTALL_TESTS]/$$testFolder
+INSTALLS += target
diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf
index ff45446219..a25846bd77 100644
--- a/mkspecs/features/resources.prf
+++ b/mkspecs/features/resources.prf
@@ -72,10 +72,44 @@ for(resource, RESOURCES) {
RESOURCES += $$resource_file
}
+!isEmpty(RESOURCES):contains(TEMPLATE, .*lib):plugin:static {
+ pluginName = $$lower($$replace(_PRO_FILE_, .*/([^/.]+)\\.[^/.]+, \\1))
+
+ resource_init_function = $${pluginName}_plugin_resource_init
+ DEFINES += "QT_PLUGIN_RESOURCE_INIT_FUNCTION=$$resource_init_function"
+
+ RESOURCE_INIT_CPP = $$OUT_PWD/$${pluginName}_plugin_resources.cpp
+
+ GENERATED_SOURCES += $$RESOURCE_INIT_CPP
+ QMAKE_DISTCLEAN += $$RESOURCE_INIT_CPP
+
+ !build_pass {
+ RESOURCE_INIT_CONT = \
+ "// This file is autogenerated by qmake. It contains a function that" \
+ "// references all resources the plugin includes and the function is" \
+ "// referenced by Qt_(MOC_)EXPORT_PLUGIN to ensure the inclusion in" \
+ "// the statically linked plugin." \
+ "$${LITERAL_HASH}include <QtCore/qglobal.h>" \
+ "void $${resource_init_function}() " \
+ "{" \
+
+ for (resource, RESOURCES) {
+ resource_name = $$section($$list($$basename(resource)), ., 0, 0)
+ resource_name = $$replace(resource_name, [^a-zA-Z0-9_], _)
+ RESOURCE_INIT_CONT += " Q_INIT_RESOURCE($$resource_name);"
+ }
+
+ RESOURCE_INIT_CONT += \
+ "}"
+
+ write_file($$RESOURCE_INIT_CPP, RESOURCE_INIT_CONT)|error()
+ }
+}
+
rcc.input = RESOURCES
rcc.name = RCC ${QMAKE_FILE_IN}
rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN}
-rcc.CONFIG += add_inputs_as_makefile_deps
+rcc.CONFIG += add_inputs_as_makefile_deps dep_lines
!resources_big|ltcg|macx-xcode|contains(TEMPLATE, "vc.*") {
diff --git a/mkspecs/features/simd.prf b/mkspecs/features/simd.prf
index e4bee7107c..a0b40fcf11 100644
--- a/mkspecs/features/simd.prf
+++ b/mkspecs/features/simd.prf
@@ -141,6 +141,28 @@ addSimdCompiler(neon)
addSimdCompiler(mips_dsp)
addSimdCompiler(mips_dspr2)
+# Haswell sub-architecture
+defineTest(addSimdArch) {
+ name = arch_$$1
+ dependencies = $$2
+ upname = $$upper($$name)
+
+ cpu_features_missing =
+ for(part, dependencies) {
+ !contains(QT_CPU_FEATURES, $$part): cpu_features_missing = 1
+ }
+
+ CONFIG += $$name
+ isEmpty(cpu_features_missing): QT_CPU_FEATURES += $$name
+
+ export(QT_CPU_FEATURES)
+ export(CONFIG)
+ addSimdCompiler($$name)
+}
+
+isEmpty(QMAKE_CFLAGS_ARCH_HASWELL): QMAKE_CFLAGS_ARCH_HASWELL = $$QMAKE_CFLAGS_AVX2
+avx2: addSimdArch(haswell, avx2 bmi bmi2 f16c fma lzcnt popcnt)
+
# Follow the Intel compiler's lead and define profiles of AVX512 instructions
defineTest(addAvx512Profile) {
name = $$1
@@ -149,7 +171,7 @@ defineTest(addAvx512Profile) {
varname = QMAKE_CFLAGS_$$upname
cpu_features_missing =
- cflags = $$QMAKE_CFLAGS_AVX512F
+ cflags = $$QMAKE_CFLAGS_ARCH_HASWELL $$QMAKE_CFLAGS_AVX512F
for(part, dependencies) {
!CONFIG($$part): return() # Profile isn't supported by the compiler
@@ -168,7 +190,4 @@ defineTest(addAvx512Profile) {
addSimdCompiler($$name)
}
addAvx512Profile(avx512common, avx512cd)
-addAvx512Profile(avx512mic, avx512cd avx512er avx512pf)
addAvx512Profile(avx512core, avx512cd avx512bw avx512dq avx512vl)
-addAvx512Profile(avx512ifmavl, avx512ifma avx512vl)
-addAvx512Profile(avx512vbmivl, avx512vbmi avx512vl)
diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf
index 8d51c9d028..79883b7f09 100644
--- a/mkspecs/features/testcase.prf
+++ b/mkspecs/features/testcase.prf
@@ -9,6 +9,18 @@ testcase_exceptions: CONFIG += exceptions
# Set in qt_build_config.prf
testcase_no_bundle: CONFIG -= app_bundle
+# Allow testcases to mark themselves as not supporting high-DPI
+testcase_lowdpi {
+ macos {
+ !isEmpty(QMAKE_INFO_PLIST): \
+ error("QMAKE_INFO_PLIST already set, can't apply testcase_lowdpi")
+
+ QMAKE_INFO_PLIST = $$QMAKESPEC/Info.plist.disable_highdpi
+ } else {
+ # TODO: Add support for other platforms if possible
+ }
+}
+
benchmark: type = benchmark
else: type = check
@@ -77,12 +89,11 @@ isEmpty(BUILDS)|build_pass {
# Install tests unless no_testcase_installs is set, or there is already
# a `target' in INSTALLS.
#
- # Tests are installed under a directory named after the target so that each
- # test has its own directory for testdata etc.
+ # Tests are installed under a directory named after their source folder
+ # so that each test has its own directory for testdata etc.
#
- load(resolve_target)
- TARGET_BASENAME = $$basename(QMAKE_RESOLVED_TARGET)
- target.path = $$[QT_INSTALL_TESTS]/$$TARGET_BASENAME
+ TEST_FOLDER = $$basename(_PRO_FILE_PWD_)
+ target.path = $$[QT_INSTALL_TESTS]/$$TEST_FOLDER
INSTALLS += target
}
@@ -183,20 +194,26 @@ isEmpty(BUILDS)|build_pass {
}
builtin_testdata {
- ALL_TESTDATA = $$TESTDATA $$GENERATED_TESTDATA
-
- # BLACKLIST needs to be added to the testdata
- BLACKLISTPATH = $$_PRO_FILE_PWD_/BLACKLIST
- exists($$BLACKLISTPATH): ALL_TESTDATA *= $$BLACKLISTPATH
-
# RESOURCES does not support wildcards (for good reasons)
- for(td, ALL_TESTDATA): \
+ for (td, TESTDATA): \
testdata.files += $$files($$absolute_path($$td, $$_PRO_FILE_PWD_))
+ # BLACKLIST needs to be added to the testdata
+ BLACKLISTPATH = $$_PRO_FILE_PWD_/BLACKLIST
+ exists($$BLACKLISTPATH): \
+ testdata.files *= $$BLACKLISTPATH
!isEmpty(testdata.files) {
testdata.base = $$_PRO_FILE_PWD_
RESOURCES += testdata
}
+ # Extra compilers don't create wildcards to start with.
+ for (td, GENERATED_TESTDATA): \
+ gentestdata.files += $$absolute_path($$td, $$OUT_PWD)
+ !isEmpty(gentestdata.files) {
+ gentestdata.base = $$OUT_PWD
+ RESOURCES += gentestdata
+ }
+
!isEmpty(TEST_HELPER_INSTALLS): \
error("This platform does not support tests which require helpers.")
}
diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf
index fdf3d1cdd3..4ecfb8d889 100644
--- a/mkspecs/features/toolchain.prf
+++ b/mkspecs/features/toolchain.prf
@@ -34,7 +34,9 @@ isEmpty($${target_prefix}.INCDIRS) {
#
# Get default include and library paths from compiler
#
- gcc {
+ wasm {
+ # wasm compiler does not work here, just use defaults
+ } else: gcc {
cmd_suffix = "<$$QMAKE_SYSTEM_NULL_DEVICE >$$QMAKE_SYSTEM_NULL_DEVICE"
equals(QMAKE_HOST.os, Windows): \
cmd_prefix = "set LC_ALL=C&"
@@ -142,6 +144,29 @@ isEmpty($${target_prefix}.INCDIRS) {
!integrity: \
error("failed to parse default search paths from compiler output")
QMAKE_DEFAULT_LIBDIRS = $$unique(QMAKE_DEFAULT_LIBDIRS)
+ } else: ghs {
+ cmd = $$QMAKE_CXX $$QMAKE_CXXFLAGS -$${LITERAL_HASH} -o /tmp/fake_output /tmp/fake_input.cpp
+ output = $$system("$$cmd", blob, ec)
+ !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output)
+ output ~= s/\\\\\\n {8}//g
+ output = $$split(output, $$escape_expand(\\n))
+ for (line, output) {
+ contains(line, "^[^ ]+/ecom[^ ]+ .* /tmp/fake_input\\.cpp") {
+ for (parameter, $$list($$line)) {
+ contains(parameter, "^(-I|--include_no_mmd=|--sys_include=).*") {
+ parameter ~= s/^(-I|--include_no_mmd=|--sys_include=)//
+ QMAKE_DEFAULT_INCDIRS += $$clean_path($$parameter)
+ }
+ }
+ } else: contains(line, "^[^ ]+/elxr .*") {
+ for (parameter, $$list($$line)) {
+ contains(parameter, "^-L.*") {
+ parameter ~= s/^-L//
+ QMAKE_DEFAULT_LIBDIRS += $$clean_path($$parameter)
+ }
+ }
+ }
+ }
} else: msvc {
# This doesn't differentiate between host and target,
# but neither do the compilers.
@@ -168,14 +193,14 @@ isEmpty($${target_prefix}.INCDIRS) {
#
defineReplace(qtVariablesFromMSVC) {
- ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) <NUL 2>NUL", lines, ec)
+ ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec)
!equals(ec, 0): qtCompilerErrror($$1, $$ret)
return($$ret)
}
defineReplace(qtVariablesFromGCC) {
ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \
- <$$QMAKE_SYSTEM_NULL_DEVICE 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec)
+ 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec)
!equals(ec, 0): qtCompilerErrror($$1, $$ret)
return($$ret)
}
@@ -199,11 +224,11 @@ isEmpty($${target_prefix}.COMPILER_MACROS) {
} else {
vars = $$qtVariablesFromMSVC($$QMAKE_CXX)
}
- } else: gcc {
+ } else: gcc|ghs {
vars = $$qtVariablesFromGCC($$QMAKE_CXX)
}
for (v, vars) {
- contains(v, $${LITERAL_HASH}.*)|contains(v, " *"): next()
+ !contains(v, "[A-Z_]+ = .*"): next()
# Set both <varname> for the outer scope ...
eval($$v)
v ~= s/ .*//
@@ -245,6 +270,8 @@ QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX
__GNUC__=$$QMAKE_GCC_MAJOR_VERSION \
__GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \
__GNUC_PATCHLEVEL__=$$QMAKE_GCC_PATCH_VERSION
+!isEmpty(QMAKE_GHS_VERSION): \
+ QMAKE_COMPILER_DEFINES += __ghs__ __GHS_VERSION_NUMBER=$$QMAKE_GHS_VERSION
QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
diff --git a/mkspecs/features/uic.prf b/mkspecs/features/uic.prf
index 134d3b4acb..1cedce5ae7 100644
--- a/mkspecs/features/uic.prf
+++ b/mkspecs/features/uic.prf
@@ -3,15 +3,13 @@ qtPrepareTool(QMAKE_UIC, uic, _DEP)
isEmpty(UI_DIR):UI_DIR = .
isEmpty(QMAKE_MOD_UIC):QMAKE_MOD_UIC = ui_
-contains(TEMPLATE, .*lib):dll: QMAKE_UIC_FLAGS += -no-stringliteral
-
uic.depends += $$QMAKE_UIC_EXE
uic.commands = $$QMAKE_UIC $$QMAKE_UIC_FLAGS ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
uic.depend_command = $$QMAKE_UIC_DEP -d ${QMAKE_FILE_IN}
uic.output = $$UI_DIR/$${QMAKE_MOD_UIC}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)}
uic.input = FORMS
uic.variable_out = GENERATED_FILES
-uic.CONFIG += no_link target_predeps
+uic.CONFIG += no_link target_predeps dep_lines
uic.name = UIC ${QMAKE_FILE_IN}
silent:uic.commands = @echo uic ${QMAKE_FILE_IN} && $$uic.commands
QMAKE_EXTRA_COMPILERS += uic
diff --git a/mkspecs/features/uikit/default_pre.prf b/mkspecs/features/uikit/default_pre.prf
index 6a44a67bca..ea6882fbc8 100644
--- a/mkspecs/features/uikit/default_pre.prf
+++ b/mkspecs/features/uikit/default_pre.prf
@@ -24,5 +24,3 @@ load(default_pre)
!versionAtLeast(QMAKE_XCODE_VERSION, 4.3): \
error("This mkspec requires Xcode 4.3 or later")
-ios:shared:!versionAtLeast(QMAKE_IOS_DEPLOYMENT_TARGET, 8.0): \
- QMAKE_IOS_DEPLOYMENT_TARGET = 8.0
diff --git a/mkspecs/features/uikit/gc_binaries.prf b/mkspecs/features/uikit/gc_binaries.prf
new file mode 100644
index 0000000000..c4f7445951
--- /dev/null
+++ b/mkspecs/features/uikit/gc_binaries.prf
@@ -0,0 +1,2 @@
+# bitcode (release mode) is incompatible with splitting sections.
+!bitcode|!release: load(gc_binaries)
diff --git a/mkspecs/features/unix/separate_debug_info.prf b/mkspecs/features/unix/separate_debug_info.prf
index 0b34b17c27..9070cf33f0 100644
--- a/mkspecs/features/unix/separate_debug_info.prf
+++ b/mkspecs/features/unix/separate_debug_info.prf
@@ -72,10 +72,12 @@ have_target:!static:if(darwin|!isEmpty(QMAKE_OBJCOPY)) {
debug_info_plist_target.path += $${target.path}/$${debug_info_target_rel}.$$debug_info_suffix/Contents
INSTALLS += debug_info_plist_target
- debug_script_target.CONFIG += no_check_exist
- debug_script_target.files = $${debug_info_target}.$$debug_info_suffix/Contents/Resources/Python/$${TARGET}.py
- debug_script_target.path += $${target.path}/$${debug_info_target_rel}.$$debug_info_suffix/Contents/Resources/Python
- INSTALLS += debug_script_target
+ !isEmpty(debug_script.output) {
+ debug_script_target.CONFIG += no_check_exist
+ debug_script_target.files = $${debug_script.output}
+ debug_script_target.path += $${target.path}/$${debug_info_target_rel}.$$debug_info_suffix/Contents/Resources/Python
+ INSTALLS += debug_script_target
+ }
}
debug_info_target.CONFIG += no_check_exist
diff --git a/mkspecs/features/wasm/qt.prf b/mkspecs/features/wasm/qt.prf
new file mode 100644
index 0000000000..9b9b58d3de
--- /dev/null
+++ b/mkspecs/features/wasm/qt.prf
@@ -0,0 +1,12 @@
+
+qt_depends = $$resolve_depends(QT, "QT.")
+equals(TEMPLATE, app):contains(qt_depends, gui(-private)?) {
+ LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms
+
+ lib_name = wasm
+ lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix()
+ LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS)
+}
+
+load(qt)
+
diff --git a/mkspecs/features/wasm/wasm.prf b/mkspecs/features/wasm/wasm.prf
new file mode 100644
index 0000000000..278a6719c7
--- /dev/null
+++ b/mkspecs/features/wasm/wasm.prf
@@ -0,0 +1,81 @@
+
+# DESTDIR will be empty if not set in the app .pro file; make sure it has a value
+isEmpty(DESTDIR): DESTDIR = $$OUT_PWD
+
+# Create js and wasm files for applications
+contains(TEMPLATE, .*app) {
+ TARGET_BASE = $${TARGET}
+ TARGET_HTML = $${TARGET}.html
+ TARGET_JS = $${TARGET}.js
+
+ # Make the emscripten compiler generate a js file
+ TARGET = $$TARGET_JS
+
+ QMAKE_INCDIR += $$(HOME)/.emscripten_ports/openssl/include
+
+ CONFIG += static
+ js_file.files = $$TARGET_JS
+ js_file.path = $$target.path
+ isEmpty(js_file.path): \
+ js_file.path += ./
+ INSTALLS += js_file
+
+ # Copy hosting html and javascript to the application build directory.
+ exists($$[QT_INSTALL_PLUGINS]/platforms/wasm_shell.html) {
+ # don't pass this until it's installed somewhere
+ # otherwise makespec test fails during qt configure
+ WASM_PLUGIN_PATH = $$[QT_INSTALL_PLUGINS]/platforms
+ } else {
+ ## internal build. not installed
+ WASM_PLUGIN_PATH = $$PWD/../../../src/plugins/platforms/wasm
+ }
+
+ # Copy/Generate main .html file (e.g. myapp.html) from the webassembly_shell.html by
+ # replacing the app name placeholder with the actual app name.
+ apphtml.name = application main html file
+ apphtml.output = $$DESTDIR/$$TARGET_HTML
+ apphtml.commands = sed -e s/APPNAME/$$TARGET_BASE/g $$WASM_PLUGIN_PATH/wasm_shell.html > $$DESTDIR/$$TARGET_HTML
+ apphtml.input = $$WASM_PLUGIN_PATH/wasm_shell.html
+ apphtml.depends = $$apphtml.input
+ QMAKE_EXTRA_COMPILERS += apphtml
+
+ appjs.name = application qtloader.js
+ appjs.output = $$DESTDIR/qtloader.js
+ appjs.commands = $$QMAKE_COPY $$WASM_PLUGIN_PATH/qtloader.js $$DESTDIR
+ appjs.input = $$WASM_PLUGIN_PATH/qtloader.js
+ appjs.depends = $$appjs.input
+ QMAKE_EXTRA_COMPILERS += appjs
+
+ appsvg.name = application qtlogo.svg
+ appsvg.output = $$DESTDIR/qtlogo.svg
+ appsvg.commands = $$QMAKE_COPY $$WASM_PLUGIN_PATH/qtlogo.svg $$DESTDIR
+ appsvg.input = $$WASM_PLUGIN_PATH/qtlogo.svg
+ appsvg.depends = $$appsvg.input
+ QMAKE_EXTRA_COMPILERS += appsvg
+
+ QMAKE_EXTRA_TARGETS += apphtml appjs appsvg
+ POST_TARGETDEPS += apphtml appjs appsvg
+
+ # Add manual target to make "make -B shellfiles" work.
+ shellfiles.target = shellfiles
+ shellfiles.depends = apphtml appjs appsvg
+ QMAKE_EXTRA_TARGETS += shellfiles
+
+ # emscripten ports are linked into the main module (this app), not the Qt
+ # libs which reference them
+ qt {
+ qt_depends = $$resolve_depends(QT, "QT.")
+ contains(qt_depends, core(-private)?): QMAKE_LFLAGS += \
+ $$QMAKE_LIBS_THREAD $$QMAKE_LIBS_ZLIB
+ contains(qt_depends, gui(-private)?): QMAKE_LFLAGS += \
+ $$QMAKE_LIBS_FREETYPE $$QMAKE_LIBS_LIBPNG
+ }
+}
+
+# Creates the stand-alone version of the library from bitcode
+!static:contains(TEMPLATE, .*lib): {
+ load(resolve_target)
+ QMAKE_POST_LINK += $$QMAKE_LINK_SHLIB $$QMAKE_RESOLVED_TARGET -o $${QMAKE_RESOLVED_TARGET}.js
+
+ QMAKE_INCDIR += $$(HOME)/.emscripten_ports/openssl/include
+}
diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf
index ec09afe381..75a601b1f1 100644
--- a/mkspecs/linux-icc/qmake.conf
+++ b/mkspecs/linux-icc/qmake.conf
@@ -1,104 +1,39 @@
#
# qmake configuration for linux-icc
#
+# Written for Intel C++ Compiler for Linux version 17.0 or higher
+#
-MAKEFILE_GENERATOR = UNIX
-
-QMAKE_COMPILER = gcc intel_icc # icc pretends to be gcc
+include(../common/icc-base-unix.conf)
-QMAKE_CFLAGS_OPTIMIZE = -O2
-QMAKE_CFLAGS_OPTIMIZE_SIZE = -Os
+# modifications to icc-base-unix.conf
-QMAKE_CC = icc
-QMAKE_LEX = flex
-QMAKE_LEXFLAGS =
-QMAKE_YACC = yacc
-QMAKE_YACCFLAGS = -d
-QMAKE_CFLAGS =
-QMAKE_CFLAGS_APP = -fPIC
-QMAKE_CFLAGS_DEPS = -M
-QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261,3373
-QMAKE_CFLAGS_WARN_OFF = -w
-QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_OPTIMIZE
-QMAKE_CFLAGS_DEBUG = -O0 -g
-QMAKE_CFLAGS_SHLIB = -fPIC
-QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CFLAGS_YACC =
QMAKE_CFLAGS_ISYSTEM = -isystem
QMAKE_CFLAGS_THREAD = -D_REENTRANT
-QMAKE_CFLAGS_SPLIT_SECTIONS = -ffunction-sections
-QMAKE_CFLAGS_LTCG = -ipo -fno-fat-lto-objects
-QMAKE_CFLAGS_LTCG_FATOBJECTS = -ffat-lto-objects
-QMAKE_CFLAGS_DISABLE_LTCG = -no-ipo
-QMAKE_CFLAGS_SSE2 += -xSSE2
-QMAKE_CFLAGS_SSE3 += -xSSE3
-QMAKE_CFLAGS_SSSE3 += -xSSSE3
-QMAKE_CFLAGS_SSE4_1 += -xSSE4.1
-QMAKE_CFLAGS_SSE4_2 += -xSSE4.2
-QMAKE_CFLAGS_AVX += -xAVX
-QMAKE_CFLAGS_AVX2 += -xCORE-AVX2
-QMAKE_CFLAGS_AVX512F += -xCOMMON-AVX512
-QMAKE_CFLAGS_AVX512CD += -xCOMMON-AVX512
-QMAKE_CFLAGS_AVX512ER += -xMIC-AVX512
-QMAKE_CFLAGS_AVX512PF += -xMIC-AVX512
-QMAKE_CFLAGS_AVX512DQ += -xCORE-AVX512
-QMAKE_CFLAGS_AVX512BW += -xCORE-AVX512
-QMAKE_CFLAGS_AVX512VL += -xCORE-AVX512
-QMAKE_CFLAGS_AESNI += -maes
-QMAKE_CFLAGS_F16C += $$QMAKE_CFLAGS_AVX2
-QMAKE_CFLAGS_RDRND += -mrdrnd
-QMAKE_CFLAGS_SHANI += -msha
-
-QMAKE_CXX = icpc
-QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
-QMAKE_CXXFLAGS_APP = $$QMAKE_CFLAGS_APP
-QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
-QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
-QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
-QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
-QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
-QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
-QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
-QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS
-# Disabling exceptions disabled - workaround for QTBUG-36577
-#QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
-QMAKE_CXXFLAGS_CXX11 = -std=c++11
-QMAKE_CXXFLAGS_CXX14 = -std=c++1y
-QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
-QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
-QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++1y
-QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z
-QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
-QMAKE_CXXFLAGS_LTCG_FATOBJECTS = $$QMAKE_CFLAGS_LTCG_FATOBJECTS
-QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG
-
-QMAKE_INCDIR =
-QMAKE_LIBDIR =
-QMAKE_INCDIR_X11 =
-QMAKE_LIBDIR_X11 =
-QMAKE_INCDIR_OPENGL =
-QMAKE_LIBDIR_OPENGL =
-QMAKE_LINK = icpc
-QMAKE_LINK_SHLIB = icpc
-QMAKE_LFLAGS =
-QMAKE_LFLAGS_RELEASE =
QMAKE_LFLAGS_APP = -pie
-QMAKE_LFLAGS_DEBUG =
QMAKE_LFLAGS_SHLIB = -shared -shared-intel
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_SONAME = -Wl,-soname,
-QMAKE_LFLAGS_THREAD =
QMAKE_LFLAGS_NOUNDEF = -Wl,-z,defs
-QMAKE_LFLAGS_RPATH = -Wl,-rpath,
QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link,
-QMAKE_LFLAGS_CXX11 =
-QMAKE_LFLAGS_CXX14 =
-QMAKE_LFLAGS_CXX1Z =
-QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
+
+# -Bsymbolic-functions (ld) support
+QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions
+QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list,
+QMAKE_LFLAGS_VERSION_SCRIPT = -Wl,--version-script,
+
+# fat LTO support for Linux ICC; not available for macOS ICC, see
+# https://software.intel.com/en-us/cpp-compiler-18.0-developer-guide-and-reference-ffat-lto-objects
+QMAKE_CFLAGS_LTCG += -fno-fat-lto-objects
+QMAKE_CXXFLAGS_LTCG += -fno-fat-lto-objects
+QMAKE_LFLAGS_LTCG += -fno-fat-lto-objects
+QMAKE_CFLAGS_LTCG_FATOBJECTS = -ffat-lto-objects
+QMAKE_CXXFLAGS_LTCG_FATOBJECTS = $$QMAKE_CFLAGS_LTCG_FATOBJECTS
QMAKE_LIBS =
QMAKE_LIBS_DYNLOAD = -ldl
@@ -111,22 +46,5 @@ QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P
QMAKE_RANLIB =
-QMAKE_CLEAN = -r $(OBJECTS_DIR)/ti_files
-
-# pch support
-CONFIG += icc_pch_style
-QMAKE_PCH_OUTPUT_EXT = .pchi
-QMAKE_CXXFLAGS_USE_PRECOMPILE = -pch-use ${QMAKE_PCH_OUTPUT} -include ${QMAKE_PCH_INPUT}
-QMAKE_CXXFLAGS_PRECOMPILE = -c -pch-create ${QMAKE_PCH_OUTPUT} -include ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_TEMP_OBJECT} ${QMAKE_PCH_TEMP_SOURCE}
-
-# -Bsymbolic-functions (ld) support
-QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions
-QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list,
-QMAKE_LFLAGS_VERSION_SCRIPT = -Wl,--version-script,
-
-# Symbol visibility control
-QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
-QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
-
include(../common/linux.conf)
load(qt_config)
diff --git a/mkspecs/macx-clang/Info.plist.disable_highdpi b/mkspecs/macx-clang/Info.plist.disable_highdpi
new file mode 100644
index 0000000000..a9b89888ad
--- /dev/null
+++ b/mkspecs/macx-clang/Info.plist.disable_highdpi
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>NSHighResolutionCapable</key>
+ <string>NO</string>
+</dict>
+</plist>
diff --git a/mkspecs/macx-clang/qmake.conf b/mkspecs/macx-clang/qmake.conf
index 14c885fd78..464f327ac4 100644
--- a/mkspecs/macx-clang/qmake.conf
+++ b/mkspecs/macx-clang/qmake.conf
@@ -2,10 +2,6 @@
# qmake configuration for Clang on OS X
#
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
-
-QMAKE_APPLE_DEVICE_ARCHS = x86_64
-
# Opt-in xcb QPA support with XQuartz:
#
# configure \
diff --git a/mkspecs/macx-g++/qmake.conf b/mkspecs/macx-g++/qmake.conf
index 5686610b17..d0e0026f1e 100644
--- a/mkspecs/macx-g++/qmake.conf
+++ b/mkspecs/macx-g++/qmake.conf
@@ -10,10 +10,6 @@ MAKEFILE_GENERATOR = UNIX
CONFIG += app_bundle incremental global_init_link_order lib_version_first
QMAKE_INCREMENTAL_STYLE = sublib
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
-
-QMAKE_APPLE_DEVICE_ARCHS = x86_64
-
include(../common/macx.conf)
include(../common/gcc-base-mac.conf)
include(../common/g++-macx.conf)
diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf
index fa3944f843..4daad497af 100644
--- a/mkspecs/macx-icc/qmake.conf
+++ b/mkspecs/macx-icc/qmake.conf
@@ -1,107 +1,33 @@
#
# qmake configuration for macx-icc
#
-# Written for Intel C++ Compiler version 14.0 for OS X
+# Written for Intel C++ Compiler for macOS version 17.0 or higher
#
-MAKEFILE_GENERATOR = UNIX
+include(../common/icc-base-unix.conf)
+
+# modifications to icc-base-unix.conf
+
CONFIG += app_bundle
QMAKE_INCREMENTAL_STYLE = sublibs
-QMAKE_COMPILER_DEFINES += __APPLE__ __GNUC__
-
-QMAKE_COMPILER = gcc clang intel_icc # icc pretends to be gcc and clang
+QMAKE_COMPILER_DEFINES += __APPLE__
-QMAKE_CFLAGS_OPTIMIZE = -O2
-QMAKE_CFLAGS_OPTIMIZE_SIZE = -Os
+QMAKE_COMPILER += clang # icc pretends to be clang too
-QMAKE_CC = icc
-QMAKE_CFLAGS =
-QMAKE_CFLAGS_DEPS = -M
-QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280,3373
-QMAKE_CFLAGS_WARN_OFF = -w
-QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_OPTIMIZE
-QMAKE_CFLAGS_DEBUG = -g -O0
-QMAKE_CFLAGS_SHLIB = -fPIC
-QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_THREAD =
-QMAKE_CFLAGS_SPLIT_SECTIONS = -ffunction-sections
-QMAKE_CFLAGS_LTCG = -ipo
-QMAKE_CFLAGS_DISABLE_LTCG = -no-ipo
-QMAKE_CFLAGS_SSE2 += -msse2
-QMAKE_CFLAGS_SSE3 += -msse3
-QMAKE_CFLAGS_SSSE3 += -mssse3
-QMAKE_CFLAGS_SSE4_1 += -msse4.1
-QMAKE_CFLAGS_SSE4_2 += -msse4.2
-QMAKE_CFLAGS_AVX += -mavx
-QMAKE_CFLAGS_AVX2 += -march=core-avx2
-QMAKE_CFLAGS_AVX512F += -xCOMMON-AVX512
-QMAKE_CFLAGS_AVX512CD += -xCOMMON-AVX512
-QMAKE_CFLAGS_AVX512ER += -xMIC-AVX512
-QMAKE_CFLAGS_AVX512PF += -xMIC-AVX512
-QMAKE_CFLAGS_AVX512DQ += -xCORE-AVX512
-QMAKE_CFLAGS_AVX512BW += -xCORE-AVX512
-QMAKE_CFLAGS_AVX512VL += -xCORE-AVX512
-QMAKE_CFLAGS_AESNI += -maes
-QMAKE_CFLAGS_F16C += $$QMAKE_CFLAGS_AVX2
-QMAKE_CFLAGS_RDRND += -mrdrnd
-QMAKE_CFLAGS_SHANI += -msha
-
-QMAKE_CXX = icpc
-QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
-QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
-QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
-QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
-QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
-QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
-QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
-QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
-QMAKE_CXXFLAGS_CXX11 = -std=c++11
-QMAKE_CXXFLAGS_CXX14 = -std=c++1y
-QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
-QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
-QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++1y
-QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z
-QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS
-QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
-QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG
-QMAKE_LINK = icpc
-QMAKE_LINK_SHLIB = icpc
-QMAKE_LFLAGS =
-QMAKE_LFLAGS_RELEASE =
-QMAKE_LFLAGS_DEBUG =
QMAKE_LFLAGS_SHLIB = -single_module -dynamiclib
QMAKE_LFLAGS_INCREMENTAL = -undefined suppress -flat_namespace
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}
QMAKE_LFLAGS_HEADERPAD = -headerpad_max_install_names
-QMAKE_LFLAGS_THREAD =
-QMAKE_LFLAGS_RPATH = -Wl,-rpath,
-QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
QMAKE_LFLAGS_VERSION = -current_version$${LITERAL_WHITESPACE}
QMAKE_LFLAGS_COMPAT_VERSION = -compatibility_version$${LITERAL_WHITESPACE}
-QMAKE_CLEAN = -r $(OBJECTS_DIR)/ti_files
-
-# pch support
-CONFIG += icc_pch_style
-QMAKE_PCH_OUTPUT_EXT = .pchi
-QMAKE_CXXFLAGS_USE_PRECOMPILE = -pch-use ${QMAKE_PCH_OUTPUT} -include ${QMAKE_PCH_INPUT}
-QMAKE_CXXFLAGS_PRECOMPILE = -c -pch-create ${QMAKE_PCH_OUTPUT} -include ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_TEMP_OBJECT} ${QMAKE_PCH_TEMP_SOURCE}
-
-# Symbol visibility control
-QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
-QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
-
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
-
-QMAKE_APPLE_DEVICE_ARCHS = x86_64
-
include(../common/macx.conf)
-
load(qt_config)
diff --git a/mkspecs/macx-ios-clang/qmake.conf b/mkspecs/macx-ios-clang/qmake.conf
index d58b9fcbe1..88e96ef32e 100644
--- a/mkspecs/macx-ios-clang/qmake.conf
+++ b/mkspecs/macx-ios-clang/qmake.conf
@@ -2,7 +2,7 @@
# qmake configuration for macx-ios-clang
#
-QMAKE_IOS_DEPLOYMENT_TARGET = 10.0
+QMAKE_IOS_DEPLOYMENT_TARGET = 11.0
# Universal target (iPhone and iPad)
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 1,2
diff --git a/mkspecs/macx-tvos-clang/qmake.conf b/mkspecs/macx-tvos-clang/qmake.conf
index ab1a95fe88..77f6a02f7b 100644
--- a/mkspecs/macx-tvos-clang/qmake.conf
+++ b/mkspecs/macx-tvos-clang/qmake.conf
@@ -2,7 +2,7 @@
# qmake configuration for macx-tvos-clang
#
-QMAKE_TVOS_DEPLOYMENT_TARGET = 10.0
+QMAKE_TVOS_DEPLOYMENT_TARGET = 11.0
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 3
diff --git a/mkspecs/macx-watchos-clang/qmake.conf b/mkspecs/macx-watchos-clang/qmake.conf
index bd28722d44..8194261275 100644
--- a/mkspecs/macx-watchos-clang/qmake.conf
+++ b/mkspecs/macx-watchos-clang/qmake.conf
@@ -2,7 +2,7 @@
# qmake configuration for macx-watchos-clang
#
-QMAKE_WATCHOS_DEPLOYMENT_TARGET = 3.0
+QMAKE_WATCHOS_DEPLOYMENT_TARGET = 4.0
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 4
diff --git a/mkspecs/macx-xcode/default.xcscheme b/mkspecs/macx-xcode/default.xcscheme
index bda2b8c1c0..bd2cb0e565 100644
--- a/mkspecs/macx-xcode/default.xcscheme
+++ b/mkspecs/macx-xcode/default.xcscheme
@@ -17,7 +17,7 @@
BlueprintIdentifier = "@TARGET_PBX_KEY@"
BuildableName = "@QMAKE_ORIG_TARGET@"
BlueprintName = "@QMAKE_ORIG_TARGET@"
- ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj">
+ ReferencedContainer = "container:@QMAKE_RELATIVE_PBX_DIR@">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -35,7 +35,7 @@
BlueprintIdentifier = "@TEST_BUNDLE_PBX_KEY@"
BuildableName = "Qt Test"
BlueprintName = "Qt Test"
- ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj">
+ ReferencedContainer = "container:@QMAKE_RELATIVE_PBX_DIR@">
</BuildableReference>
</TestableReference>
</Testables>
@@ -45,7 +45,7 @@
BlueprintIdentifier = "@TARGET_PBX_KEY@"
BuildableName = "@QMAKE_ORIG_TARGET@"
BlueprintName = "@QMAKE_ORIG_TARGET@"
- ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj">
+ ReferencedContainer = "container:@QMAKE_RELATIVE_PBX_DIR@">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
@@ -71,7 +71,7 @@
BlueprintIdentifier = "@TARGET_PBX_KEY@"
BuildableName = "@QMAKE_ORIG_TARGET@"
BlueprintName = "@QMAKE_ORIG_TARGET@"
- ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj">
+ ReferencedContainer = "container:@QMAKE_RELATIVE_PBX_DIR@">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
@@ -96,7 +96,7 @@
BlueprintIdentifier = "@TARGET_PBX_KEY@"
BuildableName = "@QMAKE_ORIG_TARGET@"
BlueprintName = "@QMAKE_ORIG_TARGET@"
- ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj">
+ ReferencedContainer = "container:@QMAKE_RELATIVE_PBX_DIR@">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf
new file mode 100644
index 0000000000..c3b67310c8
--- /dev/null
+++ b/mkspecs/wasm-emscripten/qmake.conf
@@ -0,0 +1,90 @@
+# qmake configuration for building with emscripten
+MAKEFILE_GENERATOR = UNIX
+QMAKE_PLATFORM = wasm unix
+
+include(../common/gcc-base.conf)
+include(../common/clang.conf)
+
+EMTERP_FLAGS = \
+ -s EMTERPRETIFY=1 \
+ -s EMTERPRETIFY_ASYNC=1 \
+ -s \"EMTERPRETIFY_FILE=\'data.binary\'\" \
+ -s ASSERTIONS=1 \
+ --profiling-funcs
+
+EMCC_COMMON_CFLAGS = \
+ -s USE_LIBPNG=1 \
+ -s USE_FREETYPE=1 \
+ -s USE_ZLIB=1
+
+EMCC_COMMON_LFLAGS = \
+ -s WASM=1 \
+ -s FULL_ES2=1 \
+ -s ALLOW_MEMORY_GROWTH=1 \
+ -s USE_WEBGL2=1 \
+ -s NO_EXIT_RUNTIME=0 \
+ -s ERROR_ON_UNDEFINED_SYMBOLS=1 \
+ --bind \
+ -s \"BINARYEN_METHOD=\'native-wasm\'\" \
+ -s \"BINARYEN_TRAP_MODE=\'clamp\'\"
+
+EMCC_COMMON_LFLAGS_DEBUG = \
+ $$EMCC_COMMON_LFLAGS \
+ -s ASSERTIONS=2 \
+ -s DEMANGLE_SUPPORT=1 \
+ # -s LIBRARY_DEBUG=1 \ #print out library calls, verbose
+ # -s SYSCALL_DEBUG=1 \ #print out sys calls, verbose
+ # -s FS_LOG=1 \ #print out filesystem ops, verbose
+ # -s SOCKET_DEBUG \ #print out socket,network data transfer
+ -s GL_DEBUG=1
+
+# the -s arguments can also be used with release builds
+# but here in debug for clarity
+
+QMAKE_COMPILER += emscripten
+
+QMAKE_CC = emcc
+QMAKE_CXX = em++
+
+QMAKE_CFLAGS += $$EMCC_COMMON_CFLAGS
+QMAKE_CXXFLAGS += $$EMCC_COMMON_CFLAGS
+
+# Practical debugging setup:
+# "-g4" preserves function names for stack traces
+# "-Os" produces reasonably sized binaries
+QMAKE_CFLAGS_DEBUG -= -g
+QMAKE_CXXFLAGS_DEBUG -= -g
+QMAKE_CFLAGS_DEBUG += -Os -g4
+QMAKE_CXXFLAGS_DEBUG += -Os -g4
+QMAKE_LFLAGS_DEBUG += -Os -g4
+
+QMAKE_CXXFLAGS_RELEASE -= -O2
+QMAKE_CXXFLAGS_RELEASE += -O3
+QMAKE_CFLAGS_RELEASE -= -O2
+QMAKE_CFLAGS_RELEASE += -O3
+QMAKE_LFLAGS_RELEASE += -O3
+MAKE_CFLAGS_OPTIMIZE += -O3
+MAKE_CFLAGS_OPTIMIZE_FULL += -Oz
+
+QMAKE_LINK = $$QMAKE_CXX
+QMAKE_LINK_SHLIB = $$QMAKE_CXX
+QMAKE_LINK_C = $$QMAKE_CC
+QMAKE_LINK_C_SHLIB = $$QMAKE_CC
+
+QMAKE_LIBS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_LFLAGS += $$EMCC_COMMON_LFLAGS
+QMAKE_LFLAGS_DEBUG += $$EMCC_COMMON_LFLAGS_DEBUG
+
+QMAKE_PREFIX_SHLIB = lib
+QMAKE_EXTENSION_SHLIB = so # llvm bitcode, linked to js in post_link
+QMAKE_PREFIX_STATICLIB = lib
+QMAKE_EXTENSION_STATICLIB = a # llvm bitcode
+
+QMAKE_AR = emar cqs
+QMAKE_DISTCLEAN += *.html *.js *.wasm
+
+QT_QPA_DEFAULT_PLATFORM = wasm
+
+QTPLUGIN.platforms = wasm
+load(qt_config)
diff --git a/mkspecs/wasm-emscripten/qplatformdefs.h b/mkspecs/wasm-emscripten/qplatformdefs.h
new file mode 100644
index 0000000000..c1a0d7b1a8
--- /dev/null
+++ b/mkspecs/wasm-emscripten/qplatformdefs.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMDEFS_H
+#define QPLATFORMDEFS_H
+
+// Get Qt defines/settings
+
+#include "qglobal.h"
+
+// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
+
+// 1) need to reset default environment if _BSD_SOURCE is defined
+// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0
+// 3) it seems older glibc need this to include the X/Open stuff
+
+#include <unistd.h>
+
+// We are hot - unistd.h should have turned on the specific APIs we requested
+
+#include <features.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <signal.h>
+#include <dlfcn.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/ipc.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#ifndef QT_NO_IPV6IFNAME
+#include <net/if.h>
+#endif
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#ifdef QT_LARGEFILE_SUPPORT
+#define QT_STATBUF struct stat64
+#define QT_STATBUF4TSTAT struct stat64
+#define QT_STAT ::stat64
+#define QT_FSTAT ::fstat64
+#define QT_LSTAT ::lstat64
+#define QT_OPEN ::open64
+#define QT_TRUNCATE ::truncate64
+#define QT_FTRUNCATE ::ftruncate64
+#define QT_LSEEK ::lseek64
+#else
+#define QT_STATBUF struct stat
+#define QT_STATBUF4TSTAT struct stat
+#define QT_STAT ::stat
+#define QT_FSTAT ::fstat
+#define QT_LSTAT ::lstat
+#define QT_OPEN ::open
+#define QT_TRUNCATE ::truncate
+#define QT_FTRUNCATE ::ftruncate
+#define QT_LSEEK ::lseek
+#endif
+
+#ifdef QT_LARGEFILE_SUPPORT
+#define QT_FOPEN ::fopen64
+#define QT_FSEEK ::fseeko64
+#define QT_FTELL ::ftello64
+#define QT_FGETPOS ::fgetpos64
+#define QT_FSETPOS ::fsetpos64
+#define QT_MMAP ::mmap64
+#define QT_FPOS_T fpos64_t
+#define QT_OFF_T off64_t
+#else
+#define QT_FOPEN ::fopen
+#define QT_FSEEK ::fseek
+#define QT_FTELL ::ftell
+#define QT_FGETPOS ::fgetpos
+#define QT_FSETPOS ::fsetpos
+#define QT_MMAP ::mmap
+#define QT_FPOS_T fpos_t
+#define QT_OFF_T long
+#endif
+
+#define QT_STAT_REG S_IFREG
+#define QT_STAT_DIR S_IFDIR
+#define QT_STAT_MASK S_IFMT
+#define QT_STAT_LNK S_IFLNK
+#define QT_SOCKET_CONNECT ::connect
+#define QT_SOCKET_BIND ::bind
+#define QT_FILENO fileno
+#define QT_CLOSE ::close
+#define QT_READ ::read
+#define QT_WRITE ::write
+#define QT_ACCESS ::access
+#define QT_GETCWD ::getcwd
+#define QT_CHDIR ::chdir
+#define QT_MKDIR ::mkdir
+#define QT_RMDIR ::rmdir
+#define QT_OPEN_LARGEFILE O_LARGEFILE
+#define QT_OPEN_RDONLY O_RDONLY
+#define QT_OPEN_WRONLY O_WRONLY
+#define QT_OPEN_RDWR O_RDWR
+#define QT_OPEN_CREAT O_CREAT
+#define QT_OPEN_TRUNC O_TRUNC
+#define QT_OPEN_APPEND O_APPEND
+#define QT_OPEN_EXCL O_EXCL
+
+// Directory iteration
+#define QT_DIR DIR
+
+#define QT_OPENDIR ::opendir
+#define QT_CLOSEDIR ::closedir
+
+#if defined(QT_LARGEFILE_SUPPORT) \
+ && defined(QT_USE_XOPEN_LFS_EXTENSIONS) \
+ && !defined(QT_NO_READDIR64)
+#define QT_DIRENT struct dirent64
+#define QT_READDIR ::readdir64
+#define QT_READDIR_R ::readdir64_r
+#else
+#define QT_DIRENT struct dirent
+#define QT_READDIR ::readdir
+#define QT_READDIR_R ::readdir_r
+#endif
+
+#define QT_SOCKET_CONNECT ::connect
+#define QT_SOCKET_BIND ::bind
+
+
+#define QT_SIGNAL_RETTYPE void
+#define QT_SIGNAL_ARGS int
+#define QT_SIGNAL_IGNORE SIG_IGN
+
+#define QT_SOCKLEN_T socklen_t
+
+#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
+#endif
+
+#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf
index 2447c712b1..3cb0d58824 100644
--- a/mkspecs/win32-icc/qmake.conf
+++ b/mkspecs/win32-icc/qmake.conf
@@ -12,7 +12,6 @@ include(../common/msvc-desktop.conf)
# modifications to msvc-desktop.conf
QMAKE_COMPILER += intel_icl
-DEFINES += _ENABLE_EXTENDED_ALIGNED_STORAGE
QMAKE_CFLAGS_OPTIMIZE_FULL = -O3
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index 426387f0c2..29461be5c5 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -18,7 +18,7 @@ OBJS = \
#qt code (please keep in order matching DEPEND_SRC)
QOBJS = \
qtextcodec.o qutfcodec.o \
- qglobal.o qlogging.o qmalloc.o qnumeric.o qoperatingsystemversion.o qrandom.o \
+ qendian.o qglobal.o qlogging.o qmalloc.o qnumeric.o qoperatingsystemversion.o qrandom.o \
qabstractfileengine.o qbuffer.o qdatastream.o qdebug.o \
qdir.o qdiriterator.o \
qfile.o qfiledevice.o qfileinfo.o qfilesystemengine.o \
@@ -68,6 +68,7 @@ DEPEND_SRC = \
$(QMKGENSRC)/xmloutput.cpp \
$(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp \
$(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \
+ $(SOURCE_PATH)/src/corelib/global/qendian.cpp \
$(SOURCE_PATH)/src/corelib/global/qglobal.cpp \
$(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp \
$(SOURCE_PATH)/src/corelib/global/qlogging.cpp \
@@ -295,6 +296,9 @@ qdebug.o: $(SOURCE_PATH)/src/corelib/io/qdebug.cpp
qmalloc.o: $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
+qendian.o: $(SOURCE_PATH)/src/corelib/global/qendian.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $<
+
qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 5292332187..a1699bd6f8 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -83,6 +83,7 @@ QTOBJS= \
qfsfileengine_win.obj \
qsystemlibrary.obj \
qfileinfo.obj \
+ qendian.obj \
qglobal.obj \
qhash.obj \
qiodevice.obj \
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index b07ded3888..409062cf49 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -956,14 +956,35 @@
default is used.
\row \li thread \li Thread support is enabled. This is enabled when CONFIG
includes \c qt, which is the default.
+ \row \li c99 \li C99 support is enabled. This option has no effect if
+ the compiler does not support C99, or can't select the C standard.
+ By default, the compiler default is used.
+ \row \li c11 \li C11 support is enabled. This option has no effect if
+ the compiler does not support C11, or can't select the C standard.
+ By default, the compiler default is used.
+ \row \li strict_c \li Disables support for C compiler extensions.
+ By default, they are enabled.
\row \li c++11 \li C++11 support is enabled. This option has no effect if
- the compiler does not support C++11.
- By default, support is disabled.
+ the compiler does not support C++11, or can't select the C++ standard.
+ By default, support is enabled.
\row \li c++14 \li C++14 support is enabled. This option has no effect if
- the compiler does not support C++14.
+ the compiler does not support C++14, or can't select the C++ standard.
+ By default, the compiler default is used.
+ \row \li c++1z \li C++17 support is enabled. This option has no effect if
+ the compiler does not support C++17, or can't select the C++ standard.
By default, support is disabled.
+ \row \li strict_c++ \li Disables support for C++ compiler extensions.
+ By default, they are enabled.
\row \li depend_includepath \li Appending the value of INCLUDEPATH to
DEPENDPATH is enabled. Set by default.
+ \row \li lrelease \li Run \c lrelease for all files listed in
+ \l TRANSLATIONS and \l EXTRA_TRANSLATIONS. If \c embed_translations
+ is not set, install the generated .qm files into
+ QM_FILES_INSTALL_PATH. Use QMAKE_LRELEASE_FLAGS to add options to
+ the lrelease call. Not set by default.
+ \row \li embed_translations \li Embed the generated translations from
+ \c lrelease in the executable, under \l{QM_FILES_RESOURCE_PREFIX}.
+ Requires \c lrelease to be set, too. Not set by default.
\endtable
When you use the \c debug_and_release option (which is the default under
@@ -1149,6 +1170,24 @@
Specifies where to copy the \l{#TARGET}{target} dll.
+ \target EXTRA_TRANSLATIONS
+ \section1 EXTRA_TRANSLATIONS
+
+ Specifies a list of translation (.ts) files that contain
+ translations of the user interface text into non-native languages.
+
+ In contrast to \l TRANSLATIONS, translation files in \c EXTRA_TRANSLATIONS
+ will be processed only by \l{Using lrelease}{lrelease}, not
+ \l{Using lupdate}{lupdate}.
+
+ You can use \l{CONFIG}{CONFIG += lrelease} to automatically compile the
+ files during the build, and
+ \l{CONFIG}{CONFIG += lrelease embed_translations} to make them available in
+ \l{The Qt Resource System}.
+
+ See the \l{Qt Linguist Manual} for more information about
+ internationalization (i18n) and localization (l10n) with Qt.
+
\target FORMS
\section1 FORMS
@@ -1419,6 +1458,21 @@
\note Do not attempt to overwrite the value of this variable.
+ \target QM_FILES_RESOURCE_PREFIX
+ \section1 QM_FILES_RESOURCE_PREFIX
+
+ Specifies the directory in the resource system where \c .qm files will
+ be made available by \l{CONFIG}{CONFIG += embed_translations}.
+
+ The default is \c{:/i18n/}.
+
+ \target QM_FILES_INSTALL_PATH
+ \section1 QM_FILES_INSTALL_PATH
+
+ Specifies the target directory \c .qm files generated by
+ \l{CONFIG}{CONFIG += lrelease} will be installed to. Does not have any
+ effect if \l{CONFIG}{CONFIG += embed_translations} is set.
+
\target QMAKE_systemvariable
\section1 QMAKE
@@ -2134,6 +2188,12 @@
value of this variable is typically handled by qmake or
\l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
+ \target QMAKE_LRELEASE_FLAGS
+ \section1 QMAKE_LRELEASE_FLAGS
+
+ List of additional options passed to \l{Using lrelease}{lrelease} when
+ enabled through \l{CONFIG}{CONFIG += lrelease}.
+
\section1 QMAKE_OBJECTIVE_CFLAGS
Specifies the Objective C/C++ compiler flags for building
@@ -2342,9 +2402,7 @@
This variable is used to customize the list of options passed to the
\l{uic}{User Interface Compiler} in each of the build rules where it is
- used. For example, \c{-no-stringliteral} can be passed to use QLatin1String
- instead of QStringLiteral in generated code (which is the default for
- dynamic libraries).
+ used.
\section1 QMAKE_WATCHOS_DEPLOYMENT_TARGET
@@ -2613,11 +2671,21 @@
determine how the project is built, it is necessary to declare TEMPLATE on
the command line rather than use the \c -t option.
+ \target TRANSLATIONS
\section1 TRANSLATIONS
Specifies a list of translation (.ts) files that contain
translations of the user interface text into non-native languages.
+ Translation files in \c TRANSLATIONS will be processed by both
+ \l{Using lrelease}{lrelease} and \l{Using lupdate} tools. Use
+ \l EXTRA_TRANSLATIONS if you want only \c lrelease to process a file.
+
+ You can use \l{CONFIG}{CONFIG += lrelease} to automatically compile the
+ files during the build, and
+ \l{CONFIG}{CONFIG += lrelease embed_translations} to make them available in
+ \l{The Qt Resource System}.
+
See the \l{Qt Linguist Manual} for more information about
internationalization (i18n) and localization (l10n) with Qt.
@@ -4511,6 +4579,11 @@
\li The dependencies for the output only get generated from the depends
member and from nowhere else.
\row
+ \li dep_lines
+ \li The output from the .depend_command is interpreted to be one file
+ per line. The default is to split on whitespace and is maintained
+ only for backwards compatibility reasons.
+ \row
\li no_link
\li Indicates that the output should not be added to the list of objects
to be linked in.
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index a0aea70dc5..72daa97fe4 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -542,6 +542,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QTextStream mkt(&mkf);
writeHeader(mkt);
mkt << "QMAKE = " << var("QMAKE_QMAKE") << endl;
+ project->values("QMAKE_MAKE_QMAKE_EXTRA_COMMANDS")
+ << "@echo 'warning: Xcode project has been regenerated, custom settings have been lost. " \
+ "Use CONFIG+=no_autoqmake to prevent this behavior in the future, " \
+ "at the cost of requiring manual project change tracking.'";
writeMakeQmake(mkt);
mkt.flush();
mkf.close();
@@ -825,7 +829,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES
ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"),
&frameworkdirs = project->values("QMAKE_FRAMEWORKPATH");
- static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
+ static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
for (int i = 0; libs[i]; i++) {
tmp = project->values(libs[i]);
for(int x = 0; x < tmp.count();) {
@@ -848,7 +852,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
encode the version number in the Project file which might be a bad
things in days to come? --Sam
*/
- QString lib_file = QMakeMetaInfo::findLib(Option::normalizePath((*lit) + Option::dir_sep + lib));
+ QString lib_file = QMakeMetaInfo::checkLib(Option::normalizePath(
+ (*lit) + Option::dir_sep + lib + Option::prl_ext));
if (!lib_file.isEmpty()) {
QMakeMetaInfo libinfo(project);
if(libinfo.readLib(lib_file)) {
@@ -1417,7 +1422,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
testHost.append("Contents/MacOS/");
testHost.append(targetName);
- static const char * const configs[] = { "Debug", "Release", 0 };
+ static const char * const configs[] = { "Debug", "Release", nullptr };
for (int i = 0; configs[i]; i++) {
QString testBundleBuildConfig = keyFor(pbx_dir + "QMAKE_PBX_TEST_BUNDLE_BUILDCONFIG_" + configs[i]);
t << "\t\t" << testBundleBuildConfig << " = {\n"
@@ -1782,6 +1787,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
schemeData.replace(QLatin1String("@QMAKE_ORIG_TARGET@"), target);
schemeData.replace(QLatin1String("@TARGET_PBX_KEY@"), keyFor(pbx_dir + "QMAKE_PBX_TARGET"));
schemeData.replace(QLatin1String("@TEST_BUNDLE_PBX_KEY@"), keyFor("QMAKE_TEST_BUNDLE_REFERENCE"));
+ schemeData.replace(QLatin1String("@QMAKE_RELATIVE_PBX_DIR@"), fileFixify(pbx_dir));
QTextStream outputSchemeStream(&outputSchemeFile);
outputSchemeStream << schemeData;
@@ -1876,33 +1882,28 @@ ProjectBuilderMakefileGenerator::keyFor(const QString &block)
bool
ProjectBuilderMakefileGenerator::openOutput(QFile &file, const QString &build) const
{
- if(QDir::isRelativePath(file.fileName()))
- file.setFileName(Option::output_dir + "/" + file.fileName()); //pwd when qmake was run
+ Q_ASSERT_X(QDir::isRelativePath(file.fileName()), "ProjectBuilderMakefileGenerator",
+ "runQMake() should have normalized the filename and made it relative");
+
QFileInfo fi(fileInfo(file.fileName()));
- if(fi.suffix() != "pbxproj" || file.fileName().isEmpty()) {
+ if (fi.suffix() != "pbxproj") {
QString output = file.fileName();
- if(fi.isDir())
- output += QDir::separator();
- if(!output.endsWith(projectSuffix())) {
- if(file.fileName().isEmpty() || fi.isDir()) {
- if(project->first("TEMPLATE") == "subdirs" || project->isEmpty("QMAKE_ORIG_TARGET"))
+ if (!output.endsWith(projectSuffix())) {
+ if (fi.fileName().isEmpty()) {
+ if (project->first("TEMPLATE") == "subdirs" || project->isEmpty("QMAKE_ORIG_TARGET"))
output += fileInfo(project->projectFile()).baseName();
else
output += project->first("QMAKE_ORIG_TARGET").toQString();
}
output += projectSuffix() + QDir::separator();
- } else if(output[(int)output.length() - 1] != QDir::separator()) {
+ } else {
output += QDir::separator();
}
output += QString("project.pbxproj");
file.setFileName(output);
- bool ret = UnixMakefileGenerator::openOutput(file, build);
- ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1);
- Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2);
- return ret;
}
- ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir;
+ pbx_dir = Option::output_dir + Option::dir_sep + file.fileName().section(Option::dir_sep, 0, 0);
return UnixMakefileGenerator::openOutput(file, build);
}
diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h
index 1d5cbc538d..f15c814cb4 100644
--- a/qmake/generators/mac/pbuilder_pbx.h
+++ b/qmake/generators/mac/pbuilder_pbx.h
@@ -36,11 +36,11 @@ QT_BEGIN_NAMESPACE
class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator
{
bool writingUnixMakefileGenerator;
- QString pbx_dir;
+ mutable QString pbx_dir;
int pbuilderVersion() const;
bool writeSubDirs(QTextStream &);
bool writeMakeParts(QTextStream &);
- bool writeMakefile(QTextStream &);
+ bool writeMakefile(QTextStream &) override;
QString pbxbuild();
QHash<QString, QString> keys;
@@ -64,11 +64,11 @@ public:
ProjectBuilderMakefileGenerator();
~ProjectBuilderMakefileGenerator();
- virtual bool supportsMetaBuild() { return false; }
- virtual bool openOutput(QFile &, const QString &) const;
+ bool supportsMetaBuild() override { return false; }
+ bool openOutput(QFile &, const QString &) const override;
protected:
- bool doPrecompiledHeaders() const { return false; }
- virtual bool doDepends() const { return writingUnixMakefileGenerator && UnixMakefileGenerator::doDepends(); }
+ bool doPrecompiledHeaders() const override { return false; }
+ bool doDepends() const override { return writingUnixMakefileGenerator && UnixMakefileGenerator::doDepends(); }
};
inline ProjectBuilderMakefileGenerator::~ProjectBuilderMakefileGenerator()
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 73e09a1025..7c359071bf 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -96,7 +96,7 @@ bool MakefileGenerator::mkdir(const QString &in_path) const
// ** base makefile generator
MakefileGenerator::MakefileGenerator() :
- no_io(false), project(0)
+ no_io(false), project(nullptr)
{
}
@@ -164,7 +164,7 @@ MakefileGenerator::initOutPaths()
v["PRECOMPILED_DIR"] = v["OBJECTS_DIR"];
static const char * const dirs[] = { "OBJECTS_DIR", "DESTDIR",
"SUBLIBS_DIR", "DLLDESTDIR",
- "PRECOMPILED_DIR", 0 };
+ "PRECOMPILED_DIR", nullptr };
for (int x = 0; dirs[x]; x++) {
const ProKey dkey(dirs[x]);
if (v[dkey].isEmpty())
@@ -424,7 +424,7 @@ MakefileGenerator::init()
}
incs.append(project->specDir());
- const char * const cacheKeys[] = { "_QMAKE_STASH_", "_QMAKE_SUPER_CACHE_", 0 };
+ const char * const cacheKeys[] = { "_QMAKE_STASH_", "_QMAKE_SUPER_CACHE_", nullptr };
for (int i = 0; cacheKeys[i]; ++i) {
if (v[cacheKeys[i]].isEmpty())
continue;
@@ -614,7 +614,7 @@ MakefileGenerator::init()
//build up a list of compilers
QVector<Compiler> compilers;
{
- const char *builtins[] = { "OBJECTS", "SOURCES", "PRECOMPILED_HEADER", 0 };
+ const char *builtins[] = { "OBJECTS", "SOURCES", "PRECOMPILED_HEADER", nullptr };
for(x = 0; builtins[x]; ++x) {
Compiler compiler;
compiler.variable_in = builtins[x];
@@ -829,7 +829,7 @@ MakefileGenerator::init()
}
//fix up the target deps
- static const char * const fixpaths[] = { "PRE_TARGETDEPS", "POST_TARGETDEPS", 0 };
+ static const char * const fixpaths[] = { "PRE_TARGETDEPS", "POST_TARGETDEPS", nullptr };
for (int path = 0; fixpaths[path]; path++) {
ProStringList &l = v[fixpaths[path]];
for (ProStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
@@ -876,20 +876,37 @@ MakefileGenerator::init()
}
bool
-MakefileGenerator::processPrlFile(QString &file)
+MakefileGenerator::processPrlFile(QString &file, bool baseOnly)
{
- bool try_replace_file = false;
QString f = fileFixify(file, FileFixifyBackwards);
- QString meta_file = QMakeMetaInfo::findLib(f);
- if (!meta_file.isEmpty()) {
- try_replace_file = true;
- } else {
- QString tmp = f;
- int ext = tmp.lastIndexOf('.');
- if(ext != -1)
- tmp = tmp.left(ext);
- meta_file = QMakeMetaInfo::findLib(tmp);
+ // Explicitly given full .prl name
+ if (!baseOnly && f.endsWith(Option::prl_ext))
+ return processPrlFileCore(file, QStringRef(), f);
+ // Explicitly given or derived (from -l) base name
+ if (processPrlFileCore(file, QStringRef(), f + Option::prl_ext))
+ return true;
+ if (!baseOnly) {
+ // Explicitly given full library name
+ int off = qMax(f.lastIndexOf('/'), f.lastIndexOf('\\')) + 1;
+ int ext = f.midRef(off).lastIndexOf('.');
+ if (ext != -1)
+ return processPrlFileBase(file, f.midRef(off), f.leftRef(off + ext), off);
}
+ return false;
+}
+
+bool
+MakefileGenerator::processPrlFileBase(QString &origFile, const QStringRef &origName,
+ const QStringRef &fixedBase, int slashOff)
+{
+ return processPrlFileCore(origFile, origName, fixedBase + Option::prl_ext);
+}
+
+bool
+MakefileGenerator::processPrlFileCore(QString &origFile, const QStringRef &origName,
+ const QString &fixedFile)
+{
+ const QString meta_file = QMakeMetaInfo::checkLib(fixedFile);
if (meta_file.isEmpty())
return false;
QMakeMetaInfo libinfo(project);
@@ -898,9 +915,33 @@ MakefileGenerator::processPrlFile(QString &file)
fprintf(stderr, "Error processing meta file %s\n", meta_file.toLatin1().constData());
return false;
}
- if (project->isActiveConfig("no_read_prl_" + libinfo.type().toLower())) {
- debug_msg(2, "Ignored meta file %s [%s]",
- meta_file.toLatin1().constData(), libinfo.type().toLatin1().constData());
+ if (project->isActiveConfig("no_read_prl_qmake")) {
+ debug_msg(2, "Ignored meta file %s", meta_file.toLatin1().constData());
+ return false;
+ }
+ ProString tgt = libinfo.first("QMAKE_PRL_TARGET");
+ if (tgt.isEmpty()) {
+ fprintf(stderr, "Error: %s does not define QMAKE_PRL_TARGET\n",
+ meta_file.toLatin1().constData());
+ return false;
+ }
+ if (!tgt.contains('.') && !libinfo.values("QMAKE_PRL_CONFIG").contains("lib_bundle")) {
+ fprintf(stderr, "Error: %s defines QMAKE_PRL_TARGET without extension\n",
+ meta_file.toLatin1().constData());
+ return false;
+ }
+ if (origName.isEmpty()) {
+ // We got a .prl file as input, replace it with an actual library.
+ int off = qMax(origFile.lastIndexOf('/'), origFile.lastIndexOf('\\')) + 1;
+ debug_msg(1, " Replacing library reference %s with %s",
+ origFile.mid(off).toLatin1().constData(),
+ tgt.toQString().toLatin1().constData());
+ origFile.replace(off, 1000, tgt.toQString());
+ } else if (tgt != origName) {
+ // We got an actual library as input, and found the wrong .prl for it.
+ debug_msg(2, "Mismatched meta file %s (want %s, got %s)",
+ meta_file.toLatin1().constData(),
+ origName.toLatin1().constData(), tgt.toLatin1().constData());
return false;
}
project->values("QMAKE_CURRENT_PRL_LIBS") = libinfo.values("QMAKE_PRL_LIBS");
@@ -909,23 +950,6 @@ MakefileGenerator::processPrlFile(QString &file)
for (const ProString &def : libinfo.values("QMAKE_PRL_DEFINES"))
if (!defs.contains(def) && prl_defs.contains(def))
defs.append(def);
- if (try_replace_file) {
- ProString tgt = libinfo.first("QMAKE_PRL_TARGET");
- if (tgt.isEmpty()) {
- fprintf(stderr, "Error: %s does not define QMAKE_PRL_TARGET\n",
- meta_file.toLatin1().constData());
- } else if (!tgt.contains('.')
- && !libinfo.values("QMAKE_PRL_CONFIG").contains("lib_bundle")) {
- fprintf(stderr, "Error: %s defines QMAKE_PRL_TARGET without extension\n",
- meta_file.toLatin1().constData());
- } else {
- int off = qMax(file.lastIndexOf('/'), file.lastIndexOf('\\')) + 1;
- debug_msg(1, " Replacing library reference %s with %s",
- file.mid(off).toLatin1().constData(),
- tgt.toQString().toLatin1().constData());
- file.replace(off, 1000, tgt.toQString());
- }
- }
QString mf = fileFixify(meta_file);
if (!project->values("QMAKE_PRL_INTERNAL_FILES").contains(mf))
project->values("QMAKE_PRL_INTERNAL_FILES").append(mf);
@@ -1078,18 +1102,7 @@ MakefileGenerator::write()
QString
MakefileGenerator::prlFileName(bool fixify)
{
- QString ret = project->first("TARGET_PRL").toQString();
- if(ret.isEmpty())
- ret = project->first("TARGET").toQString();
- int slsh = ret.lastIndexOf(Option::dir_sep);
- if(slsh != -1)
- ret.remove(0, slsh);
- if(!ret.endsWith(Option::prl_ext)) {
- int dot = ret.indexOf('.');
- if(dot != -1)
- ret.truncate(dot);
- ret += Option::prl_ext;
- }
+ QString ret = project->first("PRL_TARGET") + Option::prl_ext;
if(!project->isEmpty("QMAKE_BUNDLE"))
ret.prepend(project->first("QMAKE_BUNDLE") + Option::dir_sep);
if(fixify) {
@@ -1815,12 +1828,27 @@ MakefileGenerator::writeExtraTargets(QTextStream &t)
}
}
+static QStringList splitDeps(const QString &indeps, bool lineMode)
+{
+ if (!lineMode)
+ return indeps.simplified().split(' ');
+ QStringList deps = indeps.split('\n', QString::SkipEmptyParts);
+#ifdef Q_OS_WIN
+ for (auto &dep : deps) {
+ if (dep.endsWith(QLatin1Char('\r')))
+ dep.chop(1);
+ }
+#endif
+ return deps;
+}
+
void
MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
{
QString clean_targets;
const ProStringList &quc = project->values("QMAKE_EXTRA_COMPILERS");
for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) {
+ const ProStringList &config = project->values(ProKey(*it + ".CONFIG"));
QString tmp_out = fileFixify(project->first(ProKey(*it + ".output")).toQString(),
FileFixifyFromOutdir);
const QString tmp_cmd = project->values(ProKey(*it + ".commands")).join(' ');
@@ -1831,6 +1859,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
+ IoUtils::shellQuote(Option::fixPathToLocalOS(Option::output_dir, false))
+ QLatin1String(" && ");
}
+ const bool dep_lines = (config.indexOf("dep_lines") != -1);
const ProStringList &vars = project->values(ProKey(*it + ".variables"));
if(tmp_out.isEmpty() || tmp_cmd.isEmpty())
continue;
@@ -1847,7 +1876,6 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
}
t << "compiler_" << (*it) << "_make_all:";
- const ProStringList &config = project->values(ProKey(*it + ".CONFIG"));
if (config.indexOf("combine") != -1) {
// compilers with a combined input only have one output
QString input = project->first(ProKey(*it + ".output")).toQString();
@@ -1954,12 +1982,13 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
QT_PCLOSE(proc);
if(!indeps.isEmpty()) {
QDir outDir(Option::output_dir);
- // ### This is basically fubar. Add 'lines' flag to CONFIG?
- QStringList dep_cmd_deps = indeps.replace('\n', ' ').simplified().split(' ');
+ QStringList dep_cmd_deps = splitDeps(indeps, dep_lines);
for(int i = 0; i < dep_cmd_deps.count(); ++i) {
QString &file = dep_cmd_deps[i];
QString absFile = outDir.absoluteFilePath(file);
- if (exists(absFile)) {
+ if (absFile == file) {
+ // already absolute; don't do any checks.
+ } else if (exists(absFile)) {
file = absFile;
} else {
QString localFile;
@@ -1978,7 +2007,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
" prints paths relative to source directory",
(*it).toLatin1().constData());
else
- file.clear();
+ file = absFile; // fallback for generated resources
} else {
file = localFile;
}
@@ -2048,12 +2077,13 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
QT_PCLOSE(proc);
if(!indeps.isEmpty()) {
QDir outDir(Option::output_dir);
- // ### This is basically fubar. Add 'lines' flag to CONFIG?
- QStringList dep_cmd_deps = indeps.replace('\n', ' ').simplified().split(' ');
+ QStringList dep_cmd_deps = splitDeps(indeps, dep_lines);
for(int i = 0; i < dep_cmd_deps.count(); ++i) {
QString &file = dep_cmd_deps[i];
QString absFile = outDir.absoluteFilePath(file);
- if (exists(absFile)) {
+ if (absFile == file) {
+ // already absolute; don't do any checks.
+ } else if (exists(absFile)) {
file = absFile;
} else {
QString localFile;
@@ -2072,7 +2102,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t)
" prints paths relative to source directory",
(*it).toLatin1().constData());
else
- file.clear();
+ file = absFile; // fallback for generated resources
} else {
file = localFile;
}
@@ -2730,6 +2760,9 @@ MakefileGenerator::writeMakeQmake(QTextStream &t, bool noDummyQmakeAll)
const ProStringList &included = escapeDependencyPaths(project->values("QMAKE_INTERNAL_INCLUDED_FILES"));
t << included.join(QString(" \\\n\t\t")) << "\n\t"
<< qmake << endl;
+ const ProStringList &extraCommands = project->values("QMAKE_MAKE_QMAKE_EXTRA_COMMANDS");
+ if (!extraCommands.isEmpty())
+ t << "\t" << extraCommands.join(QString("\n\t")) << endl;
for(int include = 0; include < included.size(); ++include) {
const ProString &i = included.at(include);
if(!i.isEmpty())
@@ -2746,7 +2779,7 @@ MakefileGenerator::writeMakeQmake(QTextStream &t, bool noDummyQmakeAll)
QFileInfo
MakefileGenerator::fileInfo(QString file) const
{
- static QHash<FileInfoCacheKey, QFileInfo> *cache = 0;
+ static QHash<FileInfoCacheKey, QFileInfo> *cache = nullptr;
static QFileInfo noInfo = QFileInfo();
if(!cache) {
cache = new QHash<FileInfoCacheKey, QFileInfo>;
@@ -3132,54 +3165,31 @@ MakefileGenerator::specdir()
bool
MakefileGenerator::openOutput(QFile &file, const QString &build) const
{
- {
- QString outdir;
- if(!file.fileName().isEmpty()) {
- if(QDir::isRelativePath(file.fileName()))
- file.setFileName(Option::output_dir + "/" + file.fileName()); //pwd when qmake was run
- QFileInfo fi(fileInfo(file.fileName()));
- if(fi.isDir())
- outdir = file.fileName() + '/';
- }
- if(!outdir.isEmpty() || file.fileName().isEmpty()) {
- QString fname = "Makefile";
- if(!project->isEmpty("MAKEFILE"))
- fname = project->first("MAKEFILE").toQString();
- file.setFileName(outdir + fname);
- }
- }
- if(QDir::isRelativePath(file.fileName())) {
- QString fname = Option::output_dir; //pwd when qmake was run
- if(!fname.endsWith("/"))
- fname += "/";
- fname += file.fileName();
- file.setFileName(fname);
- }
- if(!build.isEmpty())
+ debug_msg(3, "asked to open output file '%s' in %s",
+ qPrintable(file.fileName()), qPrintable(Option::output_dir));
+
+ if (file.fileName().isEmpty()) {
+ file.setFileName(!project->isEmpty("MAKEFILE")
+ ? project->first("MAKEFILE").toQString() : "Makefile");
+ }
+
+ file.setFileName(QDir(Option::output_dir).absoluteFilePath(file.fileName()));
+
+ if (!build.isEmpty())
file.setFileName(file.fileName() + "." + build);
- if(project->isEmpty("QMAKE_MAKEFILE"))
+
+ if (project->isEmpty("QMAKE_MAKEFILE"))
project->values("QMAKE_MAKEFILE").append(file.fileName());
+
+ // Make required directories. Note that we do this based on the
+ // filename, not Option::output_dir, as the filename may include
+ // generator specific directories not included in output_dir.
int slsh = file.fileName().lastIndexOf('/');
- if(slsh != -1)
+ if (slsh != -1)
mkdir(file.fileName().left(slsh));
- if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
- QFileInfo fi(fileInfo(Option::output.fileName()));
- QString od;
- if(fi.isSymLink())
- od = fileInfo(fi.readLink()).absolutePath();
- else
- od = fi.path();
- od = QDir::fromNativeSeparators(od);
- if(QDir::isRelativePath(od)) {
- QString dir = Option::output_dir;
- if (!dir.endsWith('/') && !od.isEmpty())
- dir += '/';
- od.prepend(dir);
- }
- Option::output_dir = od;
- return true;
- }
- return false;
+
+ debug_msg(3, "opening output file %s", qPrintable(file.fileName()));
+ return file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
}
QString
@@ -3315,10 +3325,8 @@ MakefileGenerator::writePkgConfigFile()
t << "Libs: ";
QString pkgConfiglibName;
if (target_mode == TARG_MAC_MODE && project->isActiveConfig("lib_bundle")) {
- if (libDir != QLatin1String("/System/Library/Frameworks")
- && libDir != QLatin1String("/Library/Frameworks")) {
+ if (libDir != QLatin1String("/Library/Frameworks"))
t << "-F${libdir} ";
- }
ProString bundle;
if (!project->isEmpty("QMAKE_FRAMEWORK_BUNDLE_NAME"))
bundle = project->first("QMAKE_FRAMEWORK_BUNDLE_NAME");
@@ -3363,6 +3371,10 @@ MakefileGenerator::writePkgConfigFile()
;
if (!project->values("QMAKE_DEFAULT_INCDIRS").contains(includeDir))
t << "-I${includedir}";
+ if (target_mode == TARG_MAC_MODE && project->isActiveConfig("lib_bundle")
+ && libDir != QLatin1String("/Library/Frameworks")) {
+ t << " -F${libdir}";
+ }
t << endl;
// requires
diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h
index f32bec650e..b5c150e1cb 100644
--- a/qmake/generators/makefile.h
+++ b/qmake/generators/makefile.h
@@ -124,9 +124,9 @@ protected:
{ return replaceExtraCompilerVariables(val, QStringList(in), QStringList(out), forShell); }
//interface to the source file info
- QMakeLocalFileName fixPathForFile(const QMakeLocalFileName &, bool);
- QMakeLocalFileName findFileForDep(const QMakeLocalFileName &, const QMakeLocalFileName &);
- QFileInfo findFileInfo(const QMakeLocalFileName &);
+ QMakeLocalFileName fixPathForFile(const QMakeLocalFileName &, bool) override;
+ QMakeLocalFileName findFileForDep(const QMakeLocalFileName &, const QMakeLocalFileName &) override;
+ QFileInfo findFileInfo(const QMakeLocalFileName &) override;
QMakeProject *project;
//escape
@@ -172,7 +172,7 @@ protected:
{ int ret; canExecute(cmdline, &ret); return ret; }
bool canExecute(const QStringList &cmdline, int *argv0) const;
inline bool canExecute(const QString &cmdline) const
- { return canExecute(cmdline.split(' '), 0); }
+ { return canExecute(cmdline.split(' '), nullptr); }
bool mkdir(const QString &dir) const;
QString mkdir_p_asstring(const QString &dir, bool escape=true) const;
@@ -198,7 +198,7 @@ protected:
//for prl
QString prlFileName(bool fixify=true);
void writePrlFile();
- bool processPrlFile(QString &);
+ bool processPrlFile(QString &, bool baseOnly);
virtual void writePrlFile(QTextStream &);
//make sure libraries are found
@@ -246,9 +246,14 @@ protected:
QString installMetaFile(const ProKey &replace_rule, const QString &src, const QString &dst);
+ virtual bool processPrlFileBase(QString &origFile, const QStringRef &origName,
+ const QStringRef &fixedBase, int slashOff);
+ bool processPrlFileCore(QString &origFile, const QStringRef &origName,
+ const QString &fixedFile);
+
public:
MakefileGenerator();
- virtual ~MakefileGenerator();
+ ~MakefileGenerator();
QMakeProject *projectFile() const;
void setProjectFile(QMakeProject *p);
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index ffccdefbe1..decc1d980c 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -81,7 +81,7 @@ const QString
struct SourceDependChildren;
struct SourceFile {
- SourceFile() : deps(0), type(QMakeSourceFileInfo::TYPE_UNKNOWN),
+ SourceFile() : deps(nullptr), type(QMakeSourceFileInfo::TYPE_UNKNOWN),
mocable(0), traversed(0), exists(1),
moc_checked(0), dep_checked(0), included_count(0) { }
~SourceFile();
@@ -95,8 +95,8 @@ struct SourceFile {
struct SourceDependChildren {
SourceFile **children;
int num_nodes, used_nodes;
- SourceDependChildren() : children(0), num_nodes(0), used_nodes(0) { }
- ~SourceDependChildren() { if(children) free(children); children = 0; }
+ SourceDependChildren() : children(nullptr), num_nodes(0), used_nodes(0) { }
+ ~SourceDependChildren() { if (children) free(children); children = nullptr; }
void addChild(SourceFile *s) {
if(num_nodes <= used_nodes) {
num_nodes += 200;
@@ -115,10 +115,10 @@ public:
SourceFile *lookupFile(const char *);
inline SourceFile *lookupFile(const QString &f) { return lookupFile(f.toLatin1().constData()); }
inline SourceFile *lookupFile(const QMakeLocalFileName &f) { return lookupFile(f.local().toLatin1().constData()); }
- void addFile(SourceFile *, const char *k=0, bool own=true);
+ void addFile(SourceFile *, const char *k = nullptr, bool own = true);
struct SourceFileNode {
- SourceFileNode() : key(0), next(0), file(0), own_file(1) { }
+ SourceFileNode() : key(nullptr), next(nullptr), file(nullptr), own_file(1) { }
~SourceFileNode() {
delete [] key;
if(own_file)
@@ -135,7 +135,7 @@ SourceFiles::SourceFiles()
{
nodes = (SourceFileNode**)malloc(sizeof(SourceFileNode*)*(num_nodes=3037));
for(int n = 0; n < num_nodes; n++)
- nodes[n] = 0;
+ nodes[n] = nullptr;
}
SourceFiles::~SourceFiles()
@@ -170,7 +170,7 @@ SourceFile *SourceFiles::lookupFile(const char *file)
if(!strcmp(p->key, file))
return p->file;
}
- return 0;
+ return nullptr;
}
void SourceFiles::addFile(SourceFile *p, const char *k, bool own_file)
@@ -259,11 +259,11 @@ QMakeSourceFileInfo::QMakeSourceFileInfo(const QString &cf)
dep_mode = Recursive;
//quick project lookups
- includes = files = 0;
+ includes = files = nullptr;
files_changed = false;
//buffer
- spare_buffer = 0;
+ spare_buffer = nullptr;
spare_buffer_size = 0;
//cache
@@ -281,7 +281,7 @@ QMakeSourceFileInfo::~QMakeSourceFileInfo()
//buffer
if(spare_buffer) {
free(spare_buffer);
- spare_buffer = 0;
+ spare_buffer = nullptr;
spare_buffer_size = 0;
}
@@ -538,7 +538,7 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
const QMakeLocalFileName sourceFile = fixPathForFile(file->file, true);
struct stat fst;
- char *buffer = 0;
+ char *buffer = nullptr;
int buffer_len = 0;
{
int fd;
@@ -588,7 +588,7 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
}
for (; x < buffer_len; ++x) {
bool try_local = true;
- char *inc = 0;
+ char *inc = nullptr;
if(file->type == QMakeSourceFileInfo::TYPE_UI) {
// skip whitespaces
while (x < buffer_len && (buffer[x] == ' ' || buffer[x] == '\t'))
@@ -802,7 +802,7 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
if (cpp_state == WantName)
buffer[clean] = '\0';
else // i.e. malformed
- inc = 0;
+ inc = nullptr;
cpp_state = InCode; // hereafter
break;
@@ -915,7 +915,7 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file)
file->moc_checked = true;
int buffer_len = 0;
- char *buffer = 0;
+ char *buffer = nullptr;
{
struct stat fst;
int fd;
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp
index 874b4286bc..8ebd0c61ce 100644
--- a/qmake/generators/metamakefile.cpp
+++ b/qmake/generators/metamakefile.cpp
@@ -62,11 +62,11 @@ private:
public:
BuildsMetaMakefileGenerator(QMakeProject *p, const QString &n, bool op) : MetaMakefileGenerator(p, n, op), init_flag(false) { }
- virtual ~BuildsMetaMakefileGenerator() { clearBuilds(); }
+ ~BuildsMetaMakefileGenerator() { clearBuilds(); }
- virtual bool init();
- virtual int type() const { return BUILDSMETATYPE; }
- virtual bool write();
+ bool init() override;
+ int type() const override { return BUILDSMETATYPE; }
+ bool write() override;
};
void
@@ -138,7 +138,7 @@ BuildsMetaMakefileGenerator::init()
bool
BuildsMetaMakefileGenerator::write()
{
- Build *glue = 0;
+ Build *glue = nullptr;
if(!makefiles.isEmpty() && !makefiles.first()->build.isNull()) {
glue = new Build;
glue->name = name;
@@ -228,7 +228,7 @@ MakefileGenerator
if (build_proj->read(project->projectFile()))
return createMakefileGenerator(build_proj);
}
- return 0;
+ return nullptr;
}
class SubdirsMetaMakefileGenerator : public MetaMakefileGenerator
@@ -236,7 +236,7 @@ class SubdirsMetaMakefileGenerator : public MetaMakefileGenerator
protected:
bool init_flag;
struct Subdir {
- Subdir() : makefile(0), indent(0) { }
+ Subdir() : makefile(nullptr), indent(0) { }
~Subdir() { delete makefile; }
QString input_dir;
QString output_dir, output_file;
@@ -248,11 +248,11 @@ protected:
public:
SubdirsMetaMakefileGenerator(QMakeProject *p, const QString &n, bool op) : MetaMakefileGenerator(p, n, op), init_flag(false) { }
- virtual ~SubdirsMetaMakefileGenerator();
+ ~SubdirsMetaMakefileGenerator();
- virtual bool init();
- virtual int type() const { return SUBDIRSMETATYPE; }
- virtual bool write();
+ bool init() override;
+ int type() const override { return SUBDIRSMETATYPE; }
+ bool write() override;
};
bool
@@ -336,7 +336,7 @@ SubdirsMetaMakefileGenerator::init()
hasError |= !sub->makefile->write();
delete sub;
qmakeClearCaches();
- sub = 0;
+ sub = nullptr;
Option::output.setFileName(output_name);
}
Option::output_dir = old_output_dir;
@@ -412,7 +412,7 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO)
{
Option::postProcessProject(proj);
- MakefileGenerator *mkfile = NULL;
+ MakefileGenerator *mkfile = nullptr;
if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
mkfile = new ProjectGenerator;
mkfile->setProjectFile(proj);
@@ -459,7 +459,7 @@ MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &na
{
Option::postProcessProject(proj);
- MetaMakefileGenerator *ret = 0;
+ MetaMakefileGenerator *ret = nullptr;
if ((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
Option::qmake_mode == Option::QMAKE_GENERATE_PRL)) {
if (proj->first("TEMPLATE").endsWith("subdirs"))
diff --git a/qmake/generators/metamakefile.h b/qmake/generators/metamakefile.h
index 706bca3363..9337130143 100644
--- a/qmake/generators/metamakefile.h
+++ b/qmake/generators/metamakefile.h
@@ -49,7 +49,7 @@ public:
virtual ~MetaMakefileGenerator();
- static MetaMakefileGenerator *createMetaGenerator(QMakeProject *proj, const QString &name, bool op=true, bool *success = 0);
+ static MetaMakefileGenerator *createMetaGenerator(QMakeProject *proj, const QString &name, bool op=true, bool *success = nullptr);
static MakefileGenerator *createMakefileGenerator(QMakeProject *proj, bool noIO = false);
inline QMakeProject *projectFile() const { return project; }
diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp
index 073d315aab..f45a90b851 100644
--- a/qmake/generators/projectgenerator.cpp
+++ b/qmake/generators/projectgenerator.cpp
@@ -229,7 +229,7 @@ ProjectGenerator::init()
ProStringList &h = v["HEADERS"];
bool no_qt_files = true;
- static const char *srcs[] = { "SOURCES", "YACCSOURCES", "LEXSOURCES", "FORMS", 0 };
+ static const char *srcs[] = { "SOURCES", "YACCSOURCES", "LEXSOURCES", "FORMS", nullptr };
for (int i = 0; srcs[i]; i++) {
const ProStringList &l = v[srcs[i]];
QMakeSourceFileInfo::SourceFileType type = QMakeSourceFileInfo::TYPE_C;
@@ -473,18 +473,11 @@ ProjectGenerator::getWritableVar(const char *vk, bool)
bool
ProjectGenerator::openOutput(QFile &file, const QString &build) const
{
- QString outdir;
- if(!file.fileName().isEmpty()) {
- QFileInfo fi(fileInfo(file.fileName()));
- if(fi.isDir())
- outdir = fi.path() + QDir::separator();
- }
- if(!outdir.isEmpty() || file.fileName().isEmpty()) {
- QString dir = qmake_getpwd();
- int s = dir.lastIndexOf('/');
- if(s != -1)
- dir = dir.right(dir.length() - (s + 1));
- file.setFileName(outdir + dir + Option::pro_ext);
+ ProString fileName = file.fileName();
+ if (!fileName.endsWith(Option::pro_ext)) {
+ if (fileName.isEmpty())
+ fileName = fileInfo(Option::output_dir).fileName();
+ file.setFileName(fileName + Option::pro_ext);
}
return MakefileGenerator::openOutput(file, build);
}
diff --git a/qmake/generators/projectgenerator.h b/qmake/generators/projectgenerator.h
index 89c66f1ec8..cbc9f371ab 100644
--- a/qmake/generators/projectgenerator.h
+++ b/qmake/generators/projectgenerator.h
@@ -40,16 +40,16 @@ class ProjectGenerator : public MakefileGenerator
QString getWritableVar(const char *, bool fixPath=true);
QString fixPathToQmake(const QString &file);
protected:
- virtual void init();
- virtual bool writeMakefile(QTextStream &);
+ void init() override;
+ bool writeMakefile(QTextStream &) override;
- virtual QString escapeFilePath(const QString &path) const { Q_ASSERT(false); return QString(); }
+ QString escapeFilePath(const QString &path) const override { Q_ASSERT(false); return QString(); }
public:
ProjectGenerator();
~ProjectGenerator();
- virtual bool supportsMetaBuild() { return false; }
- virtual bool openOutput(QFile &, const QString &) const;
+ bool supportsMetaBuild() override { return false; }
+ bool openOutput(QFile &, const QString &) const override;
};
inline ProjectGenerator::~ProjectGenerator()
diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp
index 894020d2bd..4fe1a54501 100644
--- a/qmake/generators/unix/unixmake.cpp
+++ b/qmake/generators/unix/unixmake.cpp
@@ -420,7 +420,7 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
libdirs.append(QMakeLocalFileName(dlib.toQString()));
frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks"));
frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks"));
- static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
+ static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
for (int i = 0; lflags[i]; i++) {
ProStringList &l = project->values(lflags[i]);
for (ProStringList::Iterator it = l.begin(); it != l.end(); ) {
@@ -443,7 +443,7 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
dep_it != libdirs.end(); ++dep_it) {
QString libBase = (*dep_it).local() + '/'
+ project->first("QMAKE_PREFIX_SHLIB") + lib;
- if (linkPrl && processPrlFile(libBase))
+ if (linkPrl && processPrlFile(libBase, true))
goto found;
for (ProStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) {
if (exists(libBase + '.' + (*extit)))
@@ -471,12 +471,12 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
}
for (const QMakeLocalFileName &dir : qAsConst(frameworkdirs)) {
QString frameworkDirectory = dir.local() + "/" + frameworkName + + ".framework/";
- QString suffixedPrl = frameworkDirectory + opt + Option::prl_ext;
- if (processPrlFile(suffixedPrl))
+ QString suffixedPrl = frameworkDirectory + opt;
+ if (processPrlFile(suffixedPrl, true))
break;
if (hasSuffix) {
- QString unsuffixedPrl = frameworkDirectory + frameworkName + Option::prl_ext;
- if (processPrlFile(unsuffixedPrl))
+ QString unsuffixedPrl = frameworkDirectory + frameworkName;
+ if (processPrlFile(unsuffixedPrl, true))
break;
}
}
@@ -487,7 +487,7 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
}
}
} else if (linkPrl) {
- processPrlFile(opt);
+ processPrlFile(opt, false);
}
ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS");
diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h
index da5cdb320c..c5e42aa1ae 100644
--- a/qmake/generators/unix/unixmake.h
+++ b/qmake/generators/unix/unixmake.h
@@ -38,7 +38,7 @@ class UnixMakefileGenerator : public MakefileGenerator
bool include_deps;
QString libtoolFileName(bool fixify=true);
void writeLibtoolFile(); // for libtool
- void writePrlFile(QTextStream &);
+ void writePrlFile(QTextStream &) override;
public:
UnixMakefileGenerator();
@@ -46,23 +46,23 @@ public:
protected:
virtual bool doPrecompiledHeaders() const { return project->isActiveConfig("precompile_header"); }
- virtual bool doDepends() const { return !Option::mkfile::do_stub_makefile && MakefileGenerator::doDepends(); }
+ bool doDepends() const override { return !Option::mkfile::do_stub_makefile && MakefileGenerator::doDepends(); }
#ifdef Q_OS_WIN // MinGW x-compiling for QNX
- virtual QString installRoot() const;
+ QString installRoot() const override;
#endif
- virtual QString defaultInstall(const QString &);
- virtual ProString fixLibFlag(const ProString &lib);
+ QString defaultInstall(const QString &) override;
+ ProString fixLibFlag(const ProString &lib) override;
- virtual bool findLibraries(bool linkPrl, bool mergeLflags);
- virtual QString escapeFilePath(const QString &path) const;
+ bool findLibraries(bool linkPrl, bool mergeLflags) override;
+ QString escapeFilePath(const QString &path) const override;
ProString escapeFilePath(const ProString &path) const { return MakefileGenerator::escapeFilePath(path); }
- virtual QStringList &findDependencies(const QString &);
- virtual void init();
+ QStringList &findDependencies(const QString &) override;
+ void init() override;
- virtual void writeDefaultVariables(QTextStream &t);
- virtual void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags);
+ void writeDefaultVariables(QTextStream &t) override;
+ void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags) override;
void writeMakeParts(QTextStream &);
- bool writeMakefile(QTextStream &);
+ bool writeMakefile(QTextStream &) override;
private:
void init2();
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index ecb0de3b52..ab946fa439 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -280,11 +280,11 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
if (destd.endsWith('\\'))
destd += '\\';
t << "DESTDIR = " << destd << endl;
- t << "TARGET = " << fileVar("TARGET") << endl; // ### mixed use!
+ t << "TARGET = " << fileVar("TARGET") << endl;
if(project->isActiveConfig("plugin")) {
t << "TARGETD = " << fileVar("TARGET") << endl;
} else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty()) {
- t << "TARGETA = " << fileVar("TARGETA") << endl; // ### mixed use!
+ t << "TARGETA = " << fileVar("TARGETA") << endl;
if(!project->isEmpty("QMAKE_BUNDLE")) {
t << "TARGETD = " << fileVar("TARGET_x.y") << endl;
t << "TARGET0 = " << fileVar("TARGET_") << endl;
@@ -346,7 +346,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << mkdir_p_asstring("$(@D)", false) << "\n\t"
<< "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@\n\n";
- static const char * const src[] = { "SOURCES", "GENERATED_SOURCES", 0 };
+ static const char * const src[] = { "SOURCES", "GENERATED_SOURCES", nullptr };
for (int x = 0; src[x]; x++) {
const ProStringList &l = project->values(src[x]);
for (ProStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
@@ -502,7 +502,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\n\t" << var("QMAKE_POST_LINK");
t << endl << endl;
} else {
- t << "$(TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) "
+ t << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) "
<< target_deps << ' ' << depVar("POST_TARGETDEPS") << "\n\t";
if (project->first("TEMPLATE") != "aux") {
if (!destdir.isEmpty())
@@ -515,7 +515,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
}
t << endl << endl;
}
- allDeps = " $(TARGET)";
+ allDeps = ' ' + depVar("TARGET");
} else if(!project->isActiveConfig("staticlib")) {
QString destdir_r = project->first("DESTDIR").toQString(), incr_deps;
if(!project->isEmpty("QMAKE_BUNDLE")) {
@@ -580,14 +580,14 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
}
//real target
- t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS") << ' '
+ t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS") << ' '
<< incr_deps << " $(SUBLIBS) " << target_deps << ' ' << depVar("POST_TARGETDEPS");
} else {
- t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS")
+ t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
<< " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps
<< ' ' << depVar("POST_TARGETDEPS");
}
- allDeps = ' ' + destdir_d + "$(TARGET)";
+ allDeps = ' ' + destdir_d + depVar("TARGET");
if(!destdir.isEmpty())
t << "\n\t" << mkdir_p_asstring(destdir, false);
if(!project->isEmpty("QMAKE_PRE_LINK"))
@@ -604,7 +604,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\n\t" << var("QMAKE_POST_LINK");
t << endl << endl;
} else if(!project->isEmpty("QMAKE_BUNDLE")) {
- bundledFiles << destdir_r + "$(TARGET)";
+ bundledFiles << destdir_r + var("TARGET");
t << "\n\t"
<< "-$(DEL_FILE) $(TARGET) $(TARGET0) $(DESTDIR)$(TARGET0)\n\t"
<< var("QMAKE_LINK_SHLIB_CMD") << "\n\t"
@@ -669,8 +669,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << endl << endl;
if (! project->isActiveConfig("plugin")) {
- t << "staticlib: $(TARGETA)\n\n";
- t << "$(TARGETA): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) $(OBJCOMP)";
+ t << "staticlib: " << depVar("TARGETA") << "\n\n";
+ t << depVar("TARGETA") << ": " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) $(OBJCOMP)";
if(do_incremental)
t << " $(INCREMENTAL_OBJECTS)";
t << ' ' << depVar("POST_TARGETDEPS") << "\n\t";
@@ -690,11 +690,11 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
QString destdir_r = project->first("DESTDIR").toQString();
QString destdir_d = escapeDependencyPath(destdir_r);
QString destdir = escapeFilePath(destdir_r);
- allDeps = ' ' + destdir_d + "$(TARGET)"
+ allDeps = ' ' + destdir_d + depVar("TARGET")
+ varGlue("QMAKE_AR_SUBLIBS", ' ' + destdir_d, ' ' + destdir_d, "");
t << "staticlib: " << destdir_d << "$(TARGET)\n\n";
if(project->isEmpty("QMAKE_AR_SUBLIBS")) {
- t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS")
+ t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
<< " $(OBJECTS) $(OBJCOMP) " << depVar("POST_TARGETDEPS") << "\n\t";
if(!destdir.isEmpty())
t << mkdir_p_asstring(destdir, false) << "\n\t";
@@ -719,7 +719,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
QString ar;
ProString lib = destdir + escapeFilePath(*libit);
if((*libit) == "$(TARGET)") {
- t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS")
+ t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
<< ' ' << depVar("POST_TARGETDEPS") << valList(escapeDependencyPaths(build)) << "\n\t";
ar = project->first("QMAKE_AR_CMD").toQString();
ar.replace(QLatin1String("$(OBJECTS)"), escapeFilePaths(build).join(' '));
@@ -1244,7 +1244,8 @@ void UnixMakefileGenerator::init2()
if(!project->isEmpty("TARGET"))
project->values("TARGET").first().prepend(project->first("DESTDIR"));
} else if (project->isActiveConfig("staticlib")) {
- project->values("TARGET").first().prepend(project->first("QMAKE_PREFIX_STATICLIB"));
+ project->values("PRL_TARGET") =
+ project->values("TARGET").first().prepend(project->first("QMAKE_PREFIX_STATICLIB"));
project->values("TARGET").first() += "." + project->first("QMAKE_EXTENSION_STATICLIB");
if(project->values("QMAKE_AR_CMD").isEmpty())
project->values("QMAKE_AR_CMD").append("$(AR) $(DESTDIR)$(TARGET) $(OBJECTS)");
@@ -1278,6 +1279,7 @@ void UnixMakefileGenerator::init2()
QString prefix;
if(!project->isActiveConfig("no_plugin_name_prefix"))
prefix = "lib";
+ project->values("PRL_TARGET").prepend(prefix + project->first("TARGET"));
project->values("TARGET_x.y.z").append(prefix +
project->first("TARGET") + "." +
project->first("QMAKE_EXTENSION_PLUGIN"));
@@ -1291,6 +1293,7 @@ void UnixMakefileGenerator::init2()
"." + project->first("VER_MAJ"));
project->values("TARGET") = project->values("TARGET_x.y.z");
} else if (!project->isEmpty("QMAKE_HPUX_SHLIB")) {
+ project->values("PRL_TARGET").prepend("lib" + project->first("TARGET"));
project->values("TARGET_").append("lib" + project->first("TARGET") + ".sl");
if(project->isActiveConfig("lib_version_first"))
project->values("TARGET_x").append("lib" + project->first("VER_MAJ") + "." +
@@ -1300,6 +1303,7 @@ void UnixMakefileGenerator::init2()
project->first("VER_MAJ"));
project->values("TARGET") = project->values("TARGET_x");
} else if (!project->isEmpty("QMAKE_AIX_SHLIB")) {
+ project->values("PRL_TARGET").prepend("lib" + project->first("TARGET"));
project->values("TARGET_").append(project->first("QMAKE_PREFIX_STATICLIB") + project->first("TARGET")
+ "." + project->first("QMAKE_EXTENSION_STATICLIB"));
if(project->isActiveConfig("lib_version_first")) {
@@ -1331,6 +1335,7 @@ void UnixMakefileGenerator::init2()
}
project->values("TARGET") = project->values("TARGET_x.y.z");
} else {
+ project->values("PRL_TARGET").prepend("lib" + project->first("TARGET"));
project->values("TARGET_").append("lib" + project->first("TARGET") + "." +
project->first("QMAKE_EXTENSION_SHLIB"));
if(project->isActiveConfig("lib_version_first")) {
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp
index 6fcfe96380..13412e971a 100644
--- a/qmake/generators/win32/mingw_make.cpp
+++ b/qmake/generators/win32/mingw_make.cpp
@@ -73,6 +73,19 @@ MingwMakefileGenerator::parseLibFlag(const ProString &flag, ProString *arg)
return MakefileGenerator::parseLibFlag(flag, arg);
}
+bool MingwMakefileGenerator::processPrlFileBase(QString &origFile, const QStringRef &origName,
+ const QStringRef &fixedBase, int slashOff)
+{
+ if (origName.startsWith("lib")) {
+ QString newFixedBase = fixedBase.left(slashOff) + fixedBase.mid(slashOff + 3);
+ if (Win32MakefileGenerator::processPrlFileBase(origFile, origName,
+ QStringRef(&newFixedBase), slashOff)) {
+ return true;
+ }
+ }
+ return Win32MakefileGenerator::processPrlFileBase(origFile, origName, fixedBase, slashOff);
+}
+
bool MingwMakefileGenerator::writeMakefile(QTextStream &t)
{
writeHeader(t);
@@ -191,8 +204,6 @@ void MingwMakefileGenerator::init()
return;
}
- project->values("TARGET_PRL").append(project->first("TARGET"));
-
processVars();
project->values("QMAKE_LIBS") += project->values("RES_FILE");
@@ -312,8 +323,9 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t)
{
t << "first: all\n";
t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName()))
- << ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n";
- t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
+ << ' ' << depVar("ALL_DEPS") << ' ' << depVar("DEST_TARGET") << "\n\n";
+ t << depVar("DEST_TARGET") << ": "
+ << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
if (project->first("TEMPLATE") == "aux") {
t << "\n\n";
return;
diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h
index 6f041cfd4a..5da5b24088 100644
--- a/qmake/generators/win32/mingw_make.h
+++ b/qmake/generators/win32/mingw_make.h
@@ -40,25 +40,27 @@ public:
~MingwMakefileGenerator();
protected:
using MakefileGenerator::escapeDependencyPath;
- virtual QString escapeDependencyPath(const QString &path) const;
- virtual ProString fixLibFlag(const ProString &lib);
- virtual QString getManifestFileForRcFile() const;
- bool writeMakefile(QTextStream &);
- void init();
- virtual QString installRoot() const;
+ QString escapeDependencyPath(const QString &path) const override;
+ ProString fixLibFlag(const ProString &lib) override;
+ bool processPrlFileBase(QString &origFile, const QStringRef &origName,
+ const QStringRef &fixedBase, int slashOff) override;
+ QString getManifestFileForRcFile() const override;
+ bool writeMakefile(QTextStream &) override;
+ void init() override;
+ QString installRoot() const override;
private:
void writeMingwParts(QTextStream &);
- void writeIncPart(QTextStream &t);
- void writeLibsPart(QTextStream &t);
- void writeObjectsPart(QTextStream &t);
- void writeBuildRulesPart(QTextStream &t);
- void writeRcFilePart(QTextStream &t);
+ void writeIncPart(QTextStream &t) override;
+ void writeLibsPart(QTextStream &t) override;
+ void writeObjectsPart(QTextStream &t) override;
+ void writeBuildRulesPart(QTextStream &t) override;
+ void writeRcFilePart(QTextStream &t) override;
- QStringList &findDependencies(const QString &file);
+ QStringList &findDependencies(const QString &file) override;
QString preCompHeaderOut;
- virtual LibFlagType parseLibFlag(const ProString &flag, ProString *arg);
+ LibFlagType parseLibFlag(const ProString &flag, ProString *arg) override;
QString objectsLinkLine;
};
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index 082f357d32..ad2976aa01 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -1207,7 +1207,7 @@ static inline QString toString(midlCharOption option)
static inline QString toString(midlErrorCheckOption option)
{
switch (option) {
- case midlAlignNotSet:
+ case midlEnableCustom:
break;
case midlDisableAll:
return "None";
diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h
index 2e77537916..ce5711f2da 100644
--- a/qmake/generators/win32/msbuild_objectmodel.h
+++ b/qmake/generators/win32/msbuild_objectmodel.h
@@ -72,7 +72,7 @@ public:
return Uindex;
}
- void addElement(const QString &filepath, const VCFilterFile &allInfo){
+ void addElement(const QString &filepath, const VCFilterFile &allInfo) override {
QString newNodeName(filepath);
int index = pathIndex(filepath);
@@ -89,7 +89,7 @@ public:
n->addElement(filepath.mid(index+1), allInfo);
}
- void removeElements() {
+ void removeElements() override {
ChildrenMap::ConstIterator it = children.constBegin();
ChildrenMap::ConstIterator end = children.constEnd();
for( ; it != end; it++) {
@@ -100,8 +100,8 @@ public:
}
void generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName, VCProject &tool,
- const QString &filter);
- bool hasElements() {
+ const QString &filter) override;
+ bool hasElements() override {
return children.size() != 0;
}
};
@@ -124,7 +124,7 @@ public:
return Uindex;
}
- void addElement(const QString &filepath, const VCFilterFile &allInfo){
+ void addElement(const QString &filepath, const VCFilterFile &allInfo) override {
QString newKey(filepath);
int index = pathIndex(filepath);
@@ -136,13 +136,13 @@ public:
children.insert(newKey + "\0" + allInfo.file, allInfo);
}
- void removeElements() {
+ void removeElements() override {
children.clear();
}
void generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName, VCProject &proj,
- const QString &filter);
- bool hasElements() {
+ const QString &filter) override;
+ bool hasElements() override {
return children.size() != 0;
}
};
@@ -150,20 +150,20 @@ public:
class VCXProjectWriter : public VCProjectWriter
{
public:
- void write(XmlOutput &, VCProjectSingleConfig &);
- void write(XmlOutput &, VCProject &);
-
- void write(XmlOutput &, const VCCLCompilerTool &);
- void write(XmlOutput &, const VCLinkerTool &);
- void write(XmlOutput &, const VCMIDLTool &);
- void write(XmlOutput &, const VCCustomBuildTool &);
- void write(XmlOutput &, const VCLibrarianTool &);
- void write(XmlOutput &, const VCResourceCompilerTool &);
- void write(XmlOutput &, const VCEventTool &);
- void write(XmlOutput &, const VCDeploymentTool &);
- void write(XmlOutput &, const VCWinDeployQtTool &);
- void write(XmlOutput &, const VCConfiguration &);
- void write(XmlOutput &, VCFilter &);
+ void write(XmlOutput &, VCProjectSingleConfig &) override;
+ void write(XmlOutput &, VCProject &) override;
+
+ void write(XmlOutput &, const VCCLCompilerTool &) override;
+ void write(XmlOutput &, const VCLinkerTool &) override;
+ void write(XmlOutput &, const VCMIDLTool &) override;
+ void write(XmlOutput &, const VCCustomBuildTool &) override;
+ void write(XmlOutput &, const VCLibrarianTool &) override;
+ void write(XmlOutput &, const VCResourceCompilerTool &) override;
+ void write(XmlOutput &, const VCEventTool &) override;
+ void write(XmlOutput &, const VCDeploymentTool &) override;
+ void write(XmlOutput &, const VCWinDeployQtTool &) override;
+ void write(XmlOutput &, const VCConfiguration &) override;
+ void write(XmlOutput &, VCFilter &) override;
private:
struct OutputFilterData
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index 92b4eb5054..fa7ee1b98a 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -499,7 +499,7 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
QSet<QString> source_directories;
if (useInferenceRules) {
source_directories.insert(".");
- static const char * const directories[] = { "UI_SOURCES_DIR", "UI_DIR", 0 };
+ static const char * const directories[] = { "UI_SOURCES_DIR", "UI_DIR", nullptr };
for (int y = 0; directories[y]; y++) {
QString dirTemp = project->first(directories[y]).toQString();
if (dirTemp.endsWith("\\"))
@@ -507,7 +507,7 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
if(!dirTemp.isEmpty())
source_directories.insert(dirTemp);
}
- static const char * const srcs[] = { "SOURCES", "GENERATED_SOURCES", 0 };
+ static const char * const srcs[] = { "SOURCES", "GENERATED_SOURCES", nullptr };
for (int x = 0; srcs[x]; x++) {
const ProStringList &l = project->values(srcs[x]);
for (ProStringList::ConstIterator sit = l.begin(); sit != l.end(); ++sit) {
@@ -584,8 +584,9 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t)
t << "first: all\n";
t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName()))
- << ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n";
- t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
+ << ' ' << depVar("ALL_DEPS") << ' ' << depVar("DEST_TARGET") << "\n\n";
+ t << depVar("DEST_TARGET") << ": "
+ << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
if (templateName == "aux") {
t << "\n\n";
return;
diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h
index 67b609d0a6..67a56c7813 100644
--- a/qmake/generators/win32/msvc_nmake.h
+++ b/qmake/generators/win32/msvc_nmake.h
@@ -36,21 +36,21 @@ QT_BEGIN_NAMESPACE
class NmakeMakefileGenerator : public Win32MakefileGenerator
{
void writeNmakeParts(QTextStream &);
- bool writeMakefile(QTextStream &);
- void writeImplicitRulesPart(QTextStream &t);
- void writeBuildRulesPart(QTextStream &t);
+ bool writeMakefile(QTextStream &) override;
+ void writeImplicitRulesPart(QTextStream &t) override;
+ void writeBuildRulesPart(QTextStream &t) override;
void writeLinkCommand(QTextStream &t, const QString &extraFlags = QString(), const QString &extraInlineFileContent = QString());
void writeResponseFileFiles(QTextStream &t, const ProStringList &files);
int msvcVersion() const;
- void init();
+ void init() override;
static QStringList sourceFilesForImplicitRulesFilter();
protected:
- virtual void writeSubMakeCall(QTextStream &t, const QString &callPrefix,
- const QString &makeArguments);
- virtual QString defaultInstall(const QString &t);
- virtual QStringList &findDependencies(const QString &file);
- QString var(const ProKey &value) const;
+ void writeSubMakeCall(QTextStream &t, const QString &callPrefix,
+ const QString &makeArguments) override;
+ QString defaultInstall(const QString &t) override;
+ QStringList &findDependencies(const QString &file) override;
+ QString var(const ProKey &value) const override;
QString precompH, precompObj, precompPch;
QString precompObjC, precompPchC;
bool usePCH, usePCHC;
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 300792c5af..0406da584b 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -2185,7 +2185,7 @@ VCConfiguration::VCConfiguration()
// VCFilter ---------------------------------------------------------
VCFilter::VCFilter()
: ParseFiles(unset),
- Config(0)
+ Config(nullptr)
{
useCustomBuildTool = false;
useCompilerTool = false;
diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h
index 10d44970ff..9d1a170489 100644
--- a/qmake/generators/win32/msvc_objectmodel.h
+++ b/qmake/generators/win32/msvc_objectmodel.h
@@ -484,7 +484,7 @@ public:
// Functions
VCCLCompilerTool();
- bool parseOption(const char* option);
+ bool parseOption(const char* option) override;
// Variables
QStringList AdditionalIncludeDirectories;
@@ -581,7 +581,7 @@ public:
// Functions
VCLinkerTool();
- bool parseOption(const char* option);
+ bool parseOption(const char* option) override;
// Variables
QStringList AdditionalDependencies;
@@ -676,7 +676,7 @@ class VCManifestTool : public VCToolBase
public:
VCManifestTool();
- bool parseOption(const char* option);
+ bool parseOption(const char* option) override;
triState EmbedManifest;
};
@@ -687,7 +687,7 @@ public:
// Functions
VCMIDLTool();
- bool parseOption(const char* option);
+ bool parseOption(const char* option) override;
// Variables
QStringList AdditionalIncludeDirectories;
@@ -741,7 +741,7 @@ public:
// Functions
VCLibrarianTool();
- bool parseOption(const char*){ return false; }
+ bool parseOption(const char*) override { return false; }
// Variables
QStringList AdditionalDependencies;
@@ -762,7 +762,7 @@ public:
// Functions
VCCustomBuildTool();
- bool parseOption(const char*){ return false; }
+ bool parseOption(const char*) override { return false; }
// Variables
QStringList AdditionalDependencies;
@@ -781,7 +781,7 @@ public:
// Functions
VCResourceCompilerTool();
- bool parseOption(const char*){ return false; }
+ bool parseOption(const char*) override { return false; }
// Variables
QStringList AdditionalIncludeDirectories;
@@ -815,7 +815,7 @@ protected:
// Functions
VCEventTool(const QString &eventName);
- bool parseOption(const char*){ return false; }
+ bool parseOption(const char*) override { return false; }
public:
// Variables
@@ -851,7 +851,7 @@ public:
VCWinDeployQtTool() {}
protected:
- bool parseOption(const char *) { return false; }
+ bool parseOption(const char *) override { return false; }
public:
// Variables
@@ -1037,7 +1037,7 @@ public:
return Uindex;
}
- void addElement(const QString &filepath, const VCFilterFile &allInfo){
+ void addElement(const QString &filepath, const VCFilterFile &allInfo) override {
QString newNodeName(filepath);
int index = pathIndex(filepath);
@@ -1054,7 +1054,7 @@ public:
n->addElement(filepath.mid(index+1), allInfo);
}
- void removeElements() {
+ void removeElements() override {
ChildrenMap::ConstIterator it = children.constBegin();
ChildrenMap::ConstIterator end = children.constEnd();
for( ; it != end; it++) {
@@ -1064,8 +1064,8 @@ public:
children.clear();
}
- void generateXML(XmlOutput &xml, const QString &tagName, VCProject &tool, const QString &filter);
- bool hasElements() {
+ void generateXML(XmlOutput &xml, const QString &tagName, VCProject &tool, const QString &filter) override;
+ bool hasElements() override {
return children.size() != 0;
}
};
@@ -1088,7 +1088,7 @@ public:
return Uindex;
}
- void addElement(const QString &filepath, const VCFilterFile &allInfo){
+ void addElement(const QString &filepath, const VCFilterFile &allInfo) override {
QString newKey(filepath);
int index = pathIndex(filepath);
@@ -1100,12 +1100,12 @@ public:
children.insert(newKey + "\0" + allInfo.file, allInfo);
}
- void removeElements() {
+ void removeElements() override {
children.clear();
}
- void generateXML(XmlOutput &xml, const QString &tagName, VCProject &proj, const QString &filter);
- bool hasElements() {
+ void generateXML(XmlOutput &xml, const QString &tagName, VCProject &proj, const QString &filter) override;
+ bool hasElements() override {
return children.size() != 0;
}
};
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 24d1657552..73f0f35d1b 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -112,7 +112,7 @@ VcprojGenerator::VcprojGenerator()
: Win32MakefileGenerator(),
is64Bit(false),
customBuildToolFilterFileSuffix(QStringLiteral(".cbt")),
- projectWriter(0)
+ projectWriter(nullptr)
{
}
@@ -208,16 +208,6 @@ struct VcsolutionDepend {
QStringList dependencies;
};
-/* Disable optimization in getProjectUUID() due to a compiler
- * bug in MSVC 2010 that causes ASSERT: "&other != this" in the QString
- * copy constructor for non-empty file names at:
- * filename.isEmpty()?project->first("QMAKE_MAKEFILE"):filename */
-
-#ifdef Q_CC_MSVC
-# pragma optimize( "g", off )
-# pragma warning ( disable : 4748 )
-#endif
-
QUuid VcprojGenerator::getProjectUUID(const QString &filename)
{
bool validUUID = true;
@@ -249,10 +239,6 @@ QUuid VcprojGenerator::getProjectUUID(const QString &filename)
return uuid;
}
-#ifdef Q_CC_MSVC
-# pragma optimize( "g", on )
-#endif
-
QUuid VcprojGenerator::increaseUUID(const QUuid &id)
{
QUuid result(id);
@@ -1100,7 +1086,7 @@ void VcprojGenerator::initLinkerTool()
if (!project->values("DEF_FILE").isEmpty())
conf.linker.ModuleDefinitionFile = project->first("DEF_FILE").toQString();
- static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
+ static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
for (int i = 0; lflags[i]; i++) {
const auto libs = fixLibFlags(lflags[i]);
for (const ProString &lib : libs) {
@@ -1617,20 +1603,15 @@ QString VcprojGenerator::replaceExtraCompilerVariables(
bool VcprojGenerator::openOutput(QFile &file, const QString &/*build*/) const
{
- QString outdir;
- if(!file.fileName().isEmpty()) {
- QFileInfo fi(fileInfo(file.fileName()));
- if(fi.isDir())
- outdir = file.fileName() + QDir::separator();
- }
- if(!outdir.isEmpty() || file.fileName().isEmpty()) {
- ProString ext = project->first("VCPROJ_EXTENSION");
- if(project->first("TEMPLATE") == "vcsubdirs")
- ext = project->first("VCSOLUTION_EXTENSION");
- ProString outputName = project->first("TARGET");
- if (!project->first("MAKEFILE").isEmpty())
- outputName = project->first("MAKEFILE");
- file.setFileName(outdir + outputName + ext);
+ ProString fileName = file.fileName();
+ ProString extension = project->first("TEMPLATE") == "vcsubdirs"
+ ? project->first("VCSOLUTION_EXTENSION") : project->first("VCPROJ_EXTENSION");
+ if (!fileName.endsWith(extension)) {
+ if (fileName.isEmpty()) {
+ fileName = !project->first("MAKEFILE").isEmpty()
+ ? project->first("MAKEFILE") : project->first("TARGET");
+ }
+ file.setFileName(fileName + extension);
}
return Win32MakefileGenerator::openOutput(file, QString());
}
diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h
index 4882296b46..6af5ec7007 100644
--- a/qmake/generators/win32/msvc_vcproj.h
+++ b/qmake/generators/win32/msvc_vcproj.h
@@ -47,10 +47,10 @@ class VcprojGenerator : public Win32MakefileGenerator
bool is64Bit;
bool writeVcprojParts(QTextStream &);
- bool writeMakefile(QTextStream &);
- bool writeProjectMakefile();
+ bool writeMakefile(QTextStream &) override;
+ bool writeProjectMakefile() override;
- void init();
+ void init() override;
public:
VcprojGenerator();
@@ -70,14 +70,14 @@ public:
protected:
virtual VCProjectWriter *createProjectWriter();
- virtual bool doDepends() const { return false; } //never necesary
+ bool doDepends() const override { return false; } // Never necessary
using Win32MakefileGenerator::replaceExtraCompilerVariables;
- virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &, ReplaceFor);
- virtual bool supportsMetaBuild() { return true; }
- virtual bool supportsMergedBuilds() { return true; }
- virtual bool mergeBuildProject(MakefileGenerator *other);
+ QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &, ReplaceFor) override;
+ bool supportsMetaBuild() override { return true; }
+ bool supportsMergedBuilds() override { return true; }
+ bool mergeBuildProject(MakefileGenerator *other) override;
- virtual bool openOutput(QFile &file, const QString &build) const;
+ bool openOutput(QFile &file, const QString &build) const override;
virtual void initProject();
void initConfiguration();
diff --git a/qmake/generators/win32/msvc_vcxproj.h b/qmake/generators/win32/msvc_vcxproj.h
index 8f68348693..7e02b6c32f 100644
--- a/qmake/generators/win32/msvc_vcxproj.h
+++ b/qmake/generators/win32/msvc_vcxproj.h
@@ -39,7 +39,7 @@ public:
VcxprojGenerator();
protected:
- virtual VCProjectWriter *createProjectWriter();
+ VCProjectWriter *createProjectWriter() override;
};
QT_END_NAMESPACE
diff --git a/qmake/generators/win32/registry.cpp b/qmake/generators/win32/registry.cpp
index 7320cb0551..3391ab9512 100644
--- a/qmake/generators/win32/registry.cpp
+++ b/qmake/generators/win32/registry.cpp
@@ -77,7 +77,7 @@ QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned l
QString rSubkeyName = keyName(rSubkey);
QString rSubkeyPath = keyPath(rSubkey);
- HKEY handle = 0;
+ HKEY handle = nullptr;
LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0,
KEY_READ | options, &handle);
@@ -87,7 +87,7 @@ QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned l
// get the size and type of the value
DWORD dataType;
DWORD dataSize;
- res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize);
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, &dataType, nullptr, &dataSize);
if (res != ERROR_SUCCESS) {
RegCloseKey(handle);
return QString();
@@ -95,7 +95,7 @@ QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned l
// get the value
QByteArray data(dataSize, 0);
- res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0,
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, nullptr,
reinterpret_cast<unsigned char*>(data.data()), &dataSize);
if (res != ERROR_SUCCESS) {
RegCloseKey(handle);
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index bca27b7044..1388e120e7 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -84,7 +84,7 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
if (impexts.isEmpty())
impexts = project->values("QMAKE_EXTENSION_STATICLIB");
QList<QMakeLocalFileName> dirs;
- static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
+ static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
for (int i = 0; lflags[i]; i++) {
ProStringList &l = project->values(lflags[i]);
for (ProStringList::Iterator it = l.begin(); it != l.end();) {
@@ -106,7 +106,7 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin();
dir_it != dirs.end(); ++dir_it) {
QString cand = (*dir_it).real() + Option::dir_sep + lib;
- if (linkPrl && processPrlFile(cand)) {
+ if (linkPrl && processPrlFile(cand, true)) {
(*it) = cand;
goto found;
}
@@ -124,13 +124,13 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
} else if (linkPrl && type == LibFlagFile) {
QString lib = opt.toQString();
if (fileInfo(lib).isAbsolute()) {
- if (processPrlFile(lib))
+ if (processPrlFile(lib, false))
(*it) = lib;
} else {
for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin();
dir_it != dirs.end(); ++dir_it) {
QString cand = (*dir_it).real() + Option::dir_sep + lib;
- if (processPrlFile(cand)) {
+ if (processPrlFile(cand, false)) {
(*it) = cand;
break;
}
@@ -163,12 +163,30 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
return true;
}
+bool Win32MakefileGenerator::processPrlFileBase(QString &origFile, const QStringRef &origName,
+ const QStringRef &fixedBase, int slashOff)
+{
+ if (MakefileGenerator::processPrlFileBase(origFile, origName, fixedBase, slashOff))
+ return true;
+ for (int off = fixedBase.length(); off > slashOff; off--) {
+ if (!fixedBase.at(off - 1).isDigit()) {
+ if (off != fixedBase.length()) {
+ return MakefileGenerator::processPrlFileBase(
+ origFile, origName, fixedBase.left(off), slashOff);
+ }
+ break;
+ }
+ }
+ return false;
+}
+
void Win32MakefileGenerator::processVars()
{
if (project->first("TEMPLATE").endsWith("aux"))
return;
- project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
+ project->values("PRL_TARGET") =
+ project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
if (project->isEmpty("QMAKE_PROJECT_NAME"))
project->values("QMAKE_PROJECT_NAME") = project->values("QMAKE_ORIG_TARGET");
else if (project->first("TEMPLATE").startsWith("vc"))
@@ -422,7 +440,7 @@ void Win32MakefileGenerator::writeCleanParts(QTextStream &t)
{
t << "clean: compiler_clean " << depVar("CLEAN_DEPS");
{
- const char *clean_targets[] = { "OBJECTS", "QMAKE_CLEAN", "CLEAN_FILES", 0 };
+ const char *clean_targets[] = { "OBJECTS", "QMAKE_CLEAN", "CLEAN_FILES", nullptr };
for(int i = 0; clean_targets[i]; ++i) {
const ProStringList &list = project->values(clean_targets[i]);
const QString del_statement("-$(DEL_FILE)");
@@ -451,7 +469,7 @@ void Win32MakefileGenerator::writeCleanParts(QTextStream &t)
t << "distclean: clean " << depVar("DISTCLEAN_DEPS");
{
- const char *clean_targets[] = { "QMAKE_DISTCLEAN", 0 };
+ const char *clean_targets[] = { "QMAKE_DISTCLEAN", nullptr };
for(int i = 0; clean_targets[i]; ++i) {
const ProStringList &list = project->values(clean_targets[i]);
const QString del_statement("-$(DEL_FILE)");
@@ -563,7 +581,7 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t)
t << "DIST = " << fileVarList("DISTFILES") << ' '
<< fileVarList("HEADERS") << ' ' << fileVarList("SOURCES") << endl;
- t << "QMAKE_TARGET = " << fileVar("QMAKE_ORIG_TARGET") << endl;
+ t << "QMAKE_TARGET = " << fileVar("QMAKE_ORIG_TARGET") << endl; // unused
// The comment is important to maintain variable compatibility with Unix
// Makefiles, while not interpreting a trailing-slash as a linebreak
t << "DESTDIR = " << escapeFilePath(destDir) << " #avoid trailing-slash linebreak\n";
diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h
index b85a6b67df..4416951a09 100644
--- a/qmake/generators/win32/winmakefile.h
+++ b/qmake/generators/win32/winmakefile.h
@@ -39,7 +39,7 @@ public:
Win32MakefileGenerator();
~Win32MakefileGenerator();
protected:
- virtual QString defaultInstall(const QString &);
+ QString defaultInstall(const QString &) override;
virtual void writeCleanParts(QTextStream &t);
virtual void writeStandardParts(QTextStream &t);
virtual void writeIncPart(QTextStream &t);
@@ -48,16 +48,18 @@ protected:
virtual void writeImplicitRulesPart(QTextStream &t);
virtual void writeBuildRulesPart(QTextStream &);
using MakefileGenerator::escapeFilePath;
- virtual QString escapeFilePath(const QString &path) const;
+ QString escapeFilePath(const QString &path) const override;
using MakefileGenerator::escapeDependencyPath;
- virtual QString escapeDependencyPath(const QString &path) const;
+ QString escapeDependencyPath(const QString &path) const override;
virtual void writeRcFilePart(QTextStream &t);
- virtual bool findLibraries(bool linkPrl, bool mergeLflags);
+ bool findLibraries(bool linkPrl, bool mergeLflags) override;
- virtual LibFlagType parseLibFlag(const ProString &flag, ProString *arg);
- virtual ProString fixLibFlag(const ProString &lib);
+ LibFlagType parseLibFlag(const ProString &flag, ProString *arg) override;
+ ProString fixLibFlag(const ProString &lib) override;
+ bool processPrlFileBase(QString &origFile, const QStringRef &origName,
+ const QStringRef &fixedBase, int slashOff) override;
void processVars();
void fixTargetExt();
diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp
index fd84dff59d..2b2c6d0078 100644
--- a/qmake/library/ioutils.cpp
+++ b/qmake/library/ioutils.cpp
@@ -200,7 +200,7 @@ QString IoUtils::shellQuoteWin(const QString &arg)
# if defined(Q_OS_WIN)
static QString windowsErrorCode()
{
- wchar_t *string = 0;
+ wchar_t *string = nullptr;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
@@ -244,7 +244,7 @@ bool IoUtils::touchFile(const QString &targetFileName, const QString &referenceF
return false;
}
FILETIME ft;
- GetFileTime(rHand, 0, 0, &ft);
+ GetFileTime(rHand, NULL, NULL, &ft);
CloseHandle(rHand);
HANDLE wHand = CreateFile((wchar_t*)targetFileName.utf16(),
GENERIC_WRITE, FILE_SHARE_READ,
@@ -253,7 +253,7 @@ bool IoUtils::touchFile(const QString &targetFileName, const QString &referenceF
*errorString = fL1S("Cannot open %1: %2").arg(targetFileName, windowsErrorCode());
return false;
}
- SetFileTime(wHand, 0, 0, &ft);
+ SetFileTime(wHand, NULL, NULL, &ft);
CloseHandle(wHand);
# endif
return true;
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 1d7ebed3aa..2b09fc2074 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -78,12 +78,12 @@ public:
int sourceFile() const { return m_file; }
ProString &prepend(const ProString &other);
- ProString &append(const ProString &other, bool *pending = 0);
+ ProString &append(const ProString &other, bool *pending = nullptr);
ProString &append(const QString &other) { return append(ProString(other)); }
ProString &append(const QLatin1String other);
ProString &append(const char *other) { return append(QLatin1String(other)); }
ProString &append(QChar other);
- ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false);
+ ProString &append(const ProStringList &other, bool *pending = nullptr, bool skipEmpty1st = false);
ProString &operator+=(const ProString &other) { return append(other); }
ProString &operator+=(const QString &other) { return append(other); }
ProString &operator+=(const QLatin1String other) { return append(other); }
@@ -133,9 +133,9 @@ public:
bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; }
bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; }
bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; }
- int toLongLong(bool *ok = 0, int base = 10) const { return toQStringRef().toLongLong(ok, base); }
- int toInt(bool *ok = 0, int base = 10) const { return toQStringRef().toInt(ok, base); }
- short toShort(bool *ok = 0, int base = 10) const { return toQStringRef().toShort(ok, base); }
+ int toLongLong(bool *ok = nullptr, int base = 10) const { return toQStringRef().toLongLong(ok, base); }
+ int toInt(bool *ok = nullptr, int base = 10) const { return toQStringRef().toInt(ok, base); }
+ short toShort(bool *ok = nullptr, int base = 10) const { return toQStringRef().toShort(ok, base); }
uint hash() const { return m_hash; }
static uint hash(const QChar *p, int n);
@@ -229,6 +229,55 @@ inline bool operator!=(const QString &that, const ProString &other)
QTextStream &operator<<(QTextStream &t, const ProString &str);
+// This class manages read-only access to a ProString via a raw data QString
+// temporary, ensuring that the latter is accessed exclusively.
+class ProStringRoUser
+{
+public:
+ ProStringRoUser(QString &rs)
+ {
+ Q_ASSERT(rs.isDetached() || rs.isEmpty());
+ m_rs = &rs;
+ }
+ ProStringRoUser(const ProString &ps, QString &rs)
+ : ProStringRoUser(rs)
+ {
+ ps.toQString(rs);
+ }
+ // No destructor, as a RAII pattern cannot be used: references to the
+ // temporary string can legitimately outlive instances of this class
+ // (if they are held by Qt, e.g. in QRegExp).
+ QString &set(const ProString &ps) { return ps.toQString(*m_rs); }
+ QString &str() { return *m_rs; }
+
+protected:
+ QString *m_rs;
+};
+
+// This class manages read-write access to a ProString via a raw data QString
+// temporary, ensuring that the latter is accessed exclusively, and that raw
+// data does not leak outside its source's refcounting.
+class ProStringRwUser : public ProStringRoUser
+{
+public:
+ ProStringRwUser(QString &rs)
+ : ProStringRoUser(rs), m_ps(nullptr) {}
+ ProStringRwUser(const ProString &ps, QString &rs)
+ : ProStringRoUser(ps, rs), m_ps(&ps) {}
+ QString &set(const ProString &ps) { m_ps = &ps; return ProStringRoUser::set(ps); }
+ ProString extract(const QString &s) const
+ { return s.isSharedWith(*m_rs) ? *m_ps : ProString(s).setSource(*m_ps); }
+ ProString extract(const QString &s, const ProStringRwUser &other) const
+ {
+ if (other.m_ps && s.isSharedWith(*other.m_rs))
+ return *other.m_ps;
+ return extract(s);
+ }
+
+private:
+ const ProString *m_ps;
+};
+
class ProStringList : public QVector<ProString> {
public:
ProStringList() {}
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 6907dfc01d..f81bec158b 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -105,109 +105,138 @@ enum TestFunc {
T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE, T_RELOAD_PROPERTIES
};
+QMakeBuiltin::QMakeBuiltin(const QMakeBuiltinInit &d)
+ : index(d.func), minArgs(qMax(0, d.min_args)), maxArgs(d.max_args)
+{
+ static const char * const nstr[6] = { "no", "one", "two", "three", "four", "five" };
+ // For legacy reasons, there is actually no such thing as "no arguments"
+ // - there is only "empty first argument", which needs to be mapped back.
+ // -1 means "one, which may be empty", which is effectively zero, except
+ // for the error message if there are too many arguments.
+ int dmin = qAbs(d.min_args);
+ int dmax = d.max_args;
+ if (dmax == QMakeBuiltinInit::VarArgs) {
+ Q_ASSERT_X(dmin < 2, "init", d.name);
+ if (dmin == 1) {
+ Q_ASSERT_X(d.args != nullptr, "init", d.name);
+ usage = fL1S("%1(%2) requires at least one argument.")
+ .arg(fL1S(d.name), fL1S(d.args));
+ }
+ return;
+ }
+ int arange = dmax - dmin;
+ Q_ASSERT_X(arange >= 0, "init", d.name);
+ Q_ASSERT_X(d.args != nullptr, "init", d.name);
+ usage = arange > 1
+ ? fL1S("%1(%2) requires %3 to %4 arguments.")
+ .arg(fL1S(d.name), fL1S(d.args), fL1S(nstr[dmin]), fL1S(nstr[dmax]))
+ : arange > 0
+ ? fL1S("%1(%2) requires %3 or %4 arguments.")
+ .arg(fL1S(d.name), fL1S(d.args), fL1S(nstr[dmin]), fL1S(nstr[dmax]))
+ : dmax != 1
+ ? fL1S("%1(%2) requires %3 arguments.")
+ .arg(fL1S(d.name), fL1S(d.args), fL1S(nstr[dmax]))
+ : fL1S("%1(%2) requires one argument.")
+ .arg(fL1S(d.name), fL1S(d.args));
+}
+
void QMakeEvaluator::initFunctionStatics()
{
- static const struct {
- const char * const name;
- const ExpandFunc func;
- } expandInits[] = {
- { "member", E_MEMBER },
- { "str_member", E_STR_MEMBER },
- { "first", E_FIRST },
- { "take_first", E_TAKE_FIRST },
- { "last", E_LAST },
- { "take_last", E_TAKE_LAST },
- { "size", E_SIZE },
- { "str_size", E_STR_SIZE },
- { "cat", E_CAT },
- { "fromfile", E_FROMFILE },
- { "eval", E_EVAL },
- { "list", E_LIST },
- { "sprintf", E_SPRINTF },
- { "format_number", E_FORMAT_NUMBER },
- { "num_add", E_NUM_ADD },
- { "join", E_JOIN },
- { "split", E_SPLIT },
- { "basename", E_BASENAME },
- { "dirname", E_DIRNAME },
- { "section", E_SECTION },
- { "find", E_FIND },
- { "system", E_SYSTEM },
- { "unique", E_UNIQUE },
- { "sorted", E_SORTED },
- { "reverse", E_REVERSE },
- { "quote", E_QUOTE },
- { "escape_expand", E_ESCAPE_EXPAND },
- { "upper", E_UPPER },
- { "lower", E_LOWER },
- { "title", E_TITLE },
- { "re_escape", E_RE_ESCAPE },
- { "val_escape", E_VAL_ESCAPE },
- { "files", E_FILES },
- { "prompt", E_PROMPT },
- { "replace", E_REPLACE },
- { "sort_depends", E_SORT_DEPENDS },
- { "resolve_depends", E_RESOLVE_DEPENDS },
- { "enumerate_vars", E_ENUMERATE_VARS },
- { "shadowed", E_SHADOWED },
- { "absolute_path", E_ABSOLUTE_PATH },
- { "relative_path", E_RELATIVE_PATH },
- { "clean_path", E_CLEAN_PATH },
- { "system_path", E_SYSTEM_PATH },
- { "shell_path", E_SHELL_PATH },
- { "system_quote", E_SYSTEM_QUOTE },
- { "shell_quote", E_SHELL_QUOTE },
- { "getenv", E_GETENV },
+ static const QMakeBuiltinInit expandInits[] = {
+ { "member", E_MEMBER, 1, 3, "var, [start, [end]]" },
+ { "str_member", E_STR_MEMBER, -1, 3, "str, [start, [end]]" },
+ { "first", E_FIRST, 1, 1, "var" },
+ { "take_first", E_TAKE_FIRST, 1, 1, "var" },
+ { "last", E_LAST, 1, 1, "var" },
+ { "take_last", E_TAKE_LAST, 1, 1, "var" },
+ { "size", E_SIZE, 1, 1, "var" },
+ { "str_size", E_STR_SIZE, -1, 1, "str" },
+ { "cat", E_CAT, 1, 2, "file, [mode=true|blob|lines]" },
+ { "fromfile", E_FROMFILE, 2, 2, "file, var" },
+ { "eval", E_EVAL, 1, 1, "var" },
+ { "list", E_LIST, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "sprintf", E_SPRINTF, 1, QMakeBuiltinInit::VarArgs, "format, ..." },
+ { "format_number", E_FORMAT_NUMBER, 1, 2, "number, [options...]" },
+ { "num_add", E_NUM_ADD, 1, QMakeBuiltinInit::VarArgs, "num, ..." },
+ { "join", E_JOIN, 1, 4, "var, [glue, [before, [after]]]" },
+ { "split", E_SPLIT, 1, 2, "var, sep" },
+ { "basename", E_BASENAME, 1, 1, "var" },
+ { "dirname", E_DIRNAME, 1, 1, "var" },
+ { "section", E_SECTION, 3, 4, "var, sep, begin, [end]" },
+ { "find", E_FIND, 2, 2, "var, str" },
+ { "system", E_SYSTEM, 1, 3, "command, [mode], [stsvar]" },
+ { "unique", E_UNIQUE, 1, 1, "var" },
+ { "sorted", E_SORTED, 1, 1, "var" },
+ { "reverse", E_REVERSE, 1, 1, "var" },
+ { "quote", E_QUOTE, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "escape_expand", E_ESCAPE_EXPAND, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "upper", E_UPPER, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "lower", E_LOWER, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "title", E_TITLE, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "re_escape", E_RE_ESCAPE, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "val_escape", E_VAL_ESCAPE, 1, 1, "var" },
+ { "files", E_FILES, 1, 2, "pattern, [recursive=false]" },
+ { "prompt", E_PROMPT, 1, 2, "question, [decorate=true]" },
+ { "replace", E_REPLACE, 3, 3, "var, before, after" },
+ { "sort_depends", E_SORT_DEPENDS, 1, 4, "var, [prefix, [suffixes, [prio-suffix]]]" },
+ { "resolve_depends", E_RESOLVE_DEPENDS, 1, 4, "var, [prefix, [suffixes, [prio-suffix]]]" },
+ { "enumerate_vars", E_ENUMERATE_VARS, 0, 0, "" },
+ { "shadowed", E_SHADOWED, 1, 1, "path" },
+ { "absolute_path", E_ABSOLUTE_PATH, -1, 2, "path, [base]" },
+ { "relative_path", E_RELATIVE_PATH, -1, 2, "path, [base]" },
+ { "clean_path", E_CLEAN_PATH, -1, 1, "path" },
+ { "system_path", E_SYSTEM_PATH, -1, 1, "path" },
+ { "shell_path", E_SHELL_PATH, -1, 1, "path" },
+ { "system_quote", E_SYSTEM_QUOTE, -1, 1, "arg" },
+ { "shell_quote", E_SHELL_QUOTE, -1, 1, "arg" },
+ { "getenv", E_GETENV, 1, 1, "arg" },
};
statics.expands.reserve((int)(sizeof(expandInits)/sizeof(expandInits[0])));
for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i)
- statics.expands.insert(ProKey(expandInits[i].name), expandInits[i].func);
+ statics.expands.insert(ProKey(expandInits[i].name), QMakeBuiltin(expandInits[i]));
- static const struct {
- const char * const name;
- const TestFunc func;
- } testInits[] = {
- { "requires", T_REQUIRES },
- { "greaterThan", T_GREATERTHAN },
- { "lessThan", T_LESSTHAN },
- { "equals", T_EQUALS },
- { "isEqual", T_EQUALS },
- { "versionAtLeast", T_VERSION_AT_LEAST },
- { "versionAtMost", T_VERSION_AT_MOST },
- { "exists", T_EXISTS },
- { "export", T_EXPORT },
- { "clear", T_CLEAR },
- { "unset", T_UNSET },
- { "eval", T_EVAL },
- { "CONFIG", T_CONFIG },
- { "if", T_IF },
- { "isActiveConfig", T_CONFIG },
- { "system", T_SYSTEM },
- { "discard_from", T_DISCARD_FROM },
- { "defined", T_DEFINED },
- { "contains", T_CONTAINS },
- { "infile", T_INFILE },
- { "count", T_COUNT },
- { "isEmpty", T_ISEMPTY },
+ static const QMakeBuiltinInit testInits[] = {
+ { "requires", T_REQUIRES, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "greaterThan", T_GREATERTHAN, 2, 2, "var, val" },
+ { "lessThan", T_LESSTHAN, 2, 2, "var, val" },
+ { "equals", T_EQUALS, 2, 2, "var, val" },
+ { "isEqual", T_EQUALS, 2, 2, "var, val" },
+ { "versionAtLeast", T_VERSION_AT_LEAST, 2, 2, "var, version" },
+ { "versionAtMost", T_VERSION_AT_MOST, 2, 2, "var, version" },
+ { "exists", T_EXISTS, 1, 1, "file" },
+ { "export", T_EXPORT, 1, 1, "var" },
+ { "clear", T_CLEAR, 1, 1, "var" },
+ { "unset", T_UNSET, 1, 1, "var" },
+ { "eval", T_EVAL, 0, QMakeBuiltinInit::VarArgs, nullptr },
+ { "CONFIG", T_CONFIG, 1, 2, "config, [mutuals]" },
+ { "if", T_IF, 1, 1, "condition" },
+ { "isActiveConfig", T_CONFIG, 1, 2, "config, [mutuals]" },
+ { "system", T_SYSTEM, 1, 1, "exec" },
+ { "discard_from", T_DISCARD_FROM, 1, 1, "file" },
+ { "defined", T_DEFINED, 1, 2, "object, [\"test\"|\"replace\"|\"var\"]" },
+ { "contains", T_CONTAINS, 2, 3, "var, val, [mutuals]" },
+ { "infile", T_INFILE, 2, 3, "file, var, [values]" },
+ { "count", T_COUNT, 2, 3, "var, count, [op=operator]" },
+ { "isEmpty", T_ISEMPTY, 1, 1, "var" },
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- { "parseJson", T_PARSE_JSON },
+ { "parseJson", T_PARSE_JSON, 2, 2, "var, into" },
#endif
- { "load", T_LOAD },
- { "include", T_INCLUDE },
- { "debug", T_DEBUG },
- { "log", T_LOG },
- { "message", T_MESSAGE },
- { "warning", T_WARNING },
- { "error", T_ERROR },
- { "mkpath", T_MKPATH },
- { "write_file", T_WRITE_FILE },
- { "touch", T_TOUCH },
- { "cache", T_CACHE },
- { "reload_properties", T_RELOAD_PROPERTIES },
+ { "load", T_LOAD, 1, 2, "feature, [ignore_errors=false]" },
+ { "include", T_INCLUDE, 1, 3, "file, [into, [silent]]" },
+ { "debug", T_DEBUG, 2, 2, "level, message" },
+ { "log", T_LOG, 1, 1, "message" },
+ { "message", T_MESSAGE, 1, 1, "message" },
+ { "warning", T_WARNING, 1, 1, "message" },
+ { "error", T_ERROR, 0, 1, "message" },
+ { "mkpath", T_MKPATH, 1, 1, "path" },
+ { "write_file", T_WRITE_FILE, 1, 3, "name, [content var, [append] [exe]]" },
+ { "touch", T_TOUCH, 2, 2, "file, reffile" },
+ { "cache", T_CACHE, 0, 3, "[var], [set|add|sub] [transient] [super|stash], [srcvar]" },
+ { "reload_properties", T_RELOAD_PROPERTIES, 0, 0, "" },
};
statics.functions.reserve((int)(sizeof(testInits)/sizeof(testInits[0])));
for (unsigned i = 0; i < sizeof(testInits)/sizeof(testInits[0]); ++i)
- statics.functions.insert(ProKey(testInits[i].name), testInits[i].func);
+ statics.functions.insert(ProKey(testInits[i].name), QMakeBuiltin(testInits[i]));
}
static bool isTrue(const ProString &str)
@@ -234,8 +263,9 @@ QMakeEvaluator::getMemberArgs(const ProKey &func, int srclen, const ProStringLis
}
}
if (!ok) {
- evalError(fL1S("%1() argument 2 (start) '%2' invalid.")
- .arg(func.toQString(m_tmp1), start_str.toQString(m_tmp2)));
+ ProStringRoUser u1(func, m_tmp1);
+ ProStringRoUser u2(start_str, m_tmp2);
+ evalError(fL1S("%1() argument 2 (start) '%2' invalid.").arg(u1.str(), u2.str()));
return false;
}
} else {
@@ -243,8 +273,9 @@ QMakeEvaluator::getMemberArgs(const ProKey &func, int srclen, const ProStringLis
if (args.count() == 3)
*end = args.at(2).toInt(&ok);
if (!ok) {
- evalError(fL1S("%1() argument 3 (end) '%2' invalid.")
- .arg(func.toQString(m_tmp1), args.at(2).toQString(m_tmp2)));
+ ProStringRoUser u1(func, m_tmp1);
+ ProStringRoUser u2(args.at(2), m_tmp2);
+ evalError(fL1S("%1() argument 3 (end) '%2' invalid.").arg(u1.str(), u2.str()));
return false;
}
}
@@ -550,11 +581,33 @@ void QMakeEvaluator::populateDeps(
}
}
+QString QMakeEvaluator::filePathArg0(const ProStringList &args)
+{
+ ProStringRoUser u1(args.at(0), m_tmp1);
+ QString fn = resolvePath(u1.str());
+ fn.detach();
+ return fn;
+}
+
+QString QMakeEvaluator::filePathEnvArg0(const ProStringList &args)
+{
+ ProStringRoUser u1(args.at(0), m_tmp1);
+ QString fn = resolvePath(m_option->expandEnvVars(u1.str()));
+ fn.detach();
+ return fn;
+}
+
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
- int func_t, const ProKey &func, const ProStringList &args, ProStringList &ret)
+ const QMakeBuiltin &adef, const ProKey &func, const ProStringList &args, ProStringList &ret)
{
traceMsg("calling built-in $$%s(%s)", dbgKey(func), dbgSepStrList(args));
+ int asz = args.size() > 1 ? args.size() : args.at(0).isEmpty() ? 0 : 1;
+ if (asz < adef.minArgs || asz > adef.maxArgs) {
+ evalError(adef.usage);
+ return ReturnTrue;
+ }
+ int func_t = adef.index;
switch (func_t) {
case E_BASENAME:
case E_DIRNAME:
@@ -565,319 +618,264 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
int beg = 0;
int end = -1;
if (func_t == E_SECTION) {
- if (args.count() != 3 && args.count() != 4) {
- evalError(fL1S("section(var, sep, begin, end) requires three or four arguments."));
- } else {
- var = args[0];
- sep = args.at(1).toQString();
- beg = args.at(2).toInt();
- if (args.count() == 4)
- end = args.at(3).toInt();
- }
+ var = args[0];
+ sep = args.at(1).toQString();
+ beg = args.at(2).toInt();
+ if (args.count() == 4)
+ end = args.at(3).toInt();
} else {
- if (args.count() != 1) {
- evalError(fL1S("%1(var) requires one argument.").arg(func.toQStringView()));
- } else {
- var = args[0];
- regexp = true;
- sep = QLatin1String("[\\\\/]");
- if (func_t == E_DIRNAME)
- end = -2;
- else
- beg = -1;
- }
+ var = args[0];
+ regexp = true;
+ sep = QLatin1String("[\\\\/]");
+ if (func_t == E_DIRNAME)
+ end = -2;
+ else
+ beg = -1;
}
if (!var.isEmpty()) {
const auto strings = values(map(var));
if (regexp) {
QRegExp sepRx(sep);
for (const ProString &str : strings) {
- const QString &rstr = str.toQString(m_tmp[m_toggle ^= 1]).section(sepRx, beg, end);
- ret << (rstr.isSharedWith(m_tmp[m_toggle]) ? str : ProString(rstr).setSource(str));
+ ProStringRwUser u1(str, m_tmp[m_toggle ^= 1]);
+ ret << u1.extract(u1.str().section(sepRx, beg, end));
}
} else {
for (const ProString &str : strings) {
- const QString &rstr = str.toQString(m_tmp1).section(sep, beg, end);
- ret << (rstr.isSharedWith(m_tmp1) ? str : ProString(rstr).setSource(str));
+ ProStringRwUser u1(str, m_tmp1);
+ ret << u1.extract(u1.str().section(sep, beg, end));
}
}
}
break;
}
- case E_SPRINTF:
- if (args.count() < 1) {
- evalError(fL1S("sprintf(format, ...) requires at least one argument."));
- } else {
- QString tmp = args.at(0).toQString(m_tmp1);
- for (int i = 1; i < args.count(); ++i)
- tmp = tmp.arg(args.at(i).toQStringView());
- ret << (tmp.isSharedWith(m_tmp1) ? args.at(0) : ProString(tmp).setSource(args.at(0)));
- }
+ case E_SPRINTF: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ QString tmp = u1.str();
+ for (int i = 1; i < args.count(); ++i)
+ tmp = tmp.arg(args.at(i).toQStringView());
+ ret << u1.extract(tmp);
break;
- case E_FORMAT_NUMBER:
- if (args.count() > 2) {
- evalError(fL1S("format_number(number[, options...]) requires one or two arguments."));
- } else {
- int ibase = 10;
- int obase = 10;
- int width = 0;
- bool zeropad = false;
- bool leftalign = false;
- enum { DefaultSign, PadSign, AlwaysSign } sign = DefaultSign;
- if (args.count() >= 2) {
- const auto opts = split_value_list(args.at(1).toQStringRef());
- for (const ProString &opt : opts) {
- if (opt.startsWith(QLatin1String("ibase="))) {
- ibase = opt.mid(6).toInt();
- } else if (opt.startsWith(QLatin1String("obase="))) {
- obase = opt.mid(6).toInt();
- } else if (opt.startsWith(QLatin1String("width="))) {
- width = opt.mid(6).toInt();
- } else if (opt == QLatin1String("zeropad")) {
- zeropad = true;
- } else if (opt == QLatin1String("padsign")) {
- sign = PadSign;
- } else if (opt == QLatin1String("alwayssign")) {
- sign = AlwaysSign;
- } else if (opt == QLatin1String("leftalign")) {
- leftalign = true;
- } else {
- evalError(fL1S("format_number(): invalid format option %1.")
- .arg(opt.toQStringView()));
- goto formfail;
- }
+ }
+ case E_FORMAT_NUMBER: {
+ int ibase = 10;
+ int obase = 10;
+ int width = 0;
+ bool zeropad = false;
+ bool leftalign = false;
+ enum { DefaultSign, PadSign, AlwaysSign } sign = DefaultSign;
+ if (args.count() >= 2) {
+ const auto opts = split_value_list(args.at(1).toQStringRef());
+ for (const ProString &opt : opts) {
+ if (opt.startsWith(QLatin1String("ibase="))) {
+ ibase = opt.mid(6).toInt();
+ } else if (opt.startsWith(QLatin1String("obase="))) {
+ obase = opt.mid(6).toInt();
+ } else if (opt.startsWith(QLatin1String("width="))) {
+ width = opt.mid(6).toInt();
+ } else if (opt == QLatin1String("zeropad")) {
+ zeropad = true;
+ } else if (opt == QLatin1String("padsign")) {
+ sign = PadSign;
+ } else if (opt == QLatin1String("alwayssign")) {
+ sign = AlwaysSign;
+ } else if (opt == QLatin1String("leftalign")) {
+ leftalign = true;
+ } else {
+ evalError(fL1S("format_number(): invalid format option %1.")
+ .arg(opt.toQStringView()));
+ goto allfail;
}
}
- if (args.at(0).contains(QLatin1Char('.'))) {
- evalError(fL1S("format_number(): floats are currently not supported."));
- break;
+ }
+ if (args.at(0).contains(QLatin1Char('.'))) {
+ evalError(fL1S("format_number(): floats are currently not supported."));
+ break;
+ }
+ bool ok;
+ qlonglong num = args.at(0).toLongLong(&ok, ibase);
+ if (!ok) {
+ evalError(fL1S("format_number(): malformed number %2 for base %1.")
+ .arg(ibase).arg(args.at(0).toQStringView()));
+ break;
+ }
+ QString outstr;
+ if (num < 0) {
+ num = -num;
+ outstr = QLatin1Char('-');
+ } else if (sign == AlwaysSign) {
+ outstr = QLatin1Char('+');
+ } else if (sign == PadSign) {
+ outstr = QLatin1Char(' ');
+ }
+ QString numstr = QString::number(num, obase);
+ int space = width - outstr.length() - numstr.length();
+ if (space <= 0) {
+ outstr += numstr;
+ } else if (leftalign) {
+ outstr += numstr + QString(space, QLatin1Char(' '));
+ } else if (zeropad) {
+ outstr += QString(space, QLatin1Char('0')) + numstr;
+ } else {
+ outstr.prepend(QString(space, QLatin1Char(' ')));
+ outstr += numstr;
+ }
+ ret += ProString(outstr);
+ break;
+ }
+ case E_NUM_ADD: {
+ qlonglong sum = 0;
+ for (const ProString &arg : qAsConst(args)) {
+ if (arg.contains(QLatin1Char('.'))) {
+ evalError(fL1S("num_add(): floats are currently not supported."));
+ goto allfail;
}
bool ok;
- qlonglong num = args.at(0).toLongLong(&ok, ibase);
+ qlonglong num = arg.toLongLong(&ok);
if (!ok) {
- evalError(fL1S("format_number(): malformed number %2 for base %1.")
- .arg(ibase).arg(args.at(0).toQStringView()));
- break;
- }
- QString outstr;
- if (num < 0) {
- num = -num;
- outstr = QLatin1Char('-');
- } else if (sign == AlwaysSign) {
- outstr = QLatin1Char('+');
- } else if (sign == PadSign) {
- outstr = QLatin1Char(' ');
- }
- QString numstr = QString::number(num, obase);
- int space = width - outstr.length() - numstr.length();
- if (space <= 0) {
- outstr += numstr;
- } else if (leftalign) {
- outstr += numstr + QString(space, QLatin1Char(' '));
- } else if (zeropad) {
- outstr += QString(space, QLatin1Char('0')) + numstr;
- } else {
- outstr.prepend(QString(space, QLatin1Char(' ')));
- outstr += numstr;
+ evalError(fL1S("num_add(): malformed number %1.")
+ .arg(arg.toQStringView()));
+ goto allfail;
}
- ret += ProString(outstr);
+ sum += num;
}
- formfail:
- break;
- case E_NUM_ADD:
- if (args.count() < 1 || args.at(0).isEmpty()) {
- evalError(fL1S("num_add(num, ...) requires at least one argument."));
- } else {
- qlonglong sum = 0;
- for (const ProString &arg : qAsConst(args)) {
- if (arg.contains(QLatin1Char('.'))) {
- evalError(fL1S("num_add(): floats are currently not supported."));
- goto nafail;
- }
- bool ok;
- qlonglong num = arg.toLongLong(&ok);
- if (!ok) {
- evalError(fL1S("num_add(): malformed number %1.")
- .arg(arg.toQStringView()));
- goto nafail;
- }
- sum += num;
- }
- ret += ProString(QString::number(sum));
- }
- nafail:
+ ret += ProString(QString::number(sum));
break;
+ }
case E_JOIN: {
- if (args.count() < 1 || args.count() > 4) {
- evalError(fL1S("join(var, glue, before, after) requires one to four arguments."));
- } else {
- ProString glue, before, after;
- if (args.count() >= 2)
- glue = args.at(1);
- if (args.count() >= 3)
- before = args[2];
- if (args.count() == 4)
- after = args[3];
- const ProStringList &var = values(map(args.at(0)));
- if (!var.isEmpty()) {
- int src = currentFileId();
- for (const ProString &v : var)
- if (int s = v.sourceFile()) {
- src = s;
- break;
- }
- ret << ProString(before + var.join(glue) + after).setSource(src);
- }
+ ProString glue, before, after;
+ if (args.count() >= 2)
+ glue = args.at(1);
+ if (args.count() >= 3)
+ before = args[2];
+ if (args.count() == 4)
+ after = args[3];
+ const ProStringList &var = values(map(args.at(0)));
+ if (!var.isEmpty()) {
+ int src = currentFileId();
+ for (const ProString &v : var)
+ if (int s = v.sourceFile()) {
+ src = s;
+ break;
+ }
+ ret << ProString(before + var.join(glue) + after).setSource(src);
}
break;
}
- case E_SPLIT:
- if (args.count() < 1 || args.count() > 2) {
- evalError(fL1S("split(var, sep) requires one or two arguments."));
- } else {
- const QString &sep = (args.count() == 2) ? args.at(1).toQString(m_tmp1) : statics.field_sep;
- const auto vars = values(map(args.at(0)));
- for (const ProString &var : vars) {
- // FIXME: this is inconsistent with the "there are no empty strings" dogma.
- const auto splits = var.toQStringRef().split(sep, QString::KeepEmptyParts);
- for (const auto &splt : splits)
- ret << ProString(splt).setSource(var);
- }
+ case E_SPLIT: {
+ ProStringRoUser u1(m_tmp1);
+ const QString &sep = (args.count() == 2) ? u1.set(args.at(1)) : statics.field_sep;
+ const auto vars = values(map(args.at(0)));
+ for (const ProString &var : vars) {
+ // FIXME: this is inconsistent with the "there are no empty strings" dogma.
+ const auto splits = var.toQStringRef().split(sep, QString::KeepEmptyParts);
+ for (const auto &splt : splits)
+ ret << ProString(splt).setSource(var);
}
break;
- case E_MEMBER:
- if (args.count() < 1 || args.count() > 3) {
- evalError(fL1S("member(var, start, end) requires one to three arguments."));
- } else {
- const ProStringList &src = values(map(args.at(0)));
- int start, end;
- if (getMemberArgs(func, src.size(), args, &start, &end)) {
- ret.reserve(qAbs(end - start) + 1);
- if (start < end) {
- for (int i = start; i <= end && src.size() >= i; i++)
- ret += src.at(i);
- } else {
- for (int i = start; i >= end && src.size() >= i && i >= 0; i--)
- ret += src.at(i);
- }
+ }
+ case E_MEMBER: {
+ const ProStringList &src = values(map(args.at(0)));
+ int start, end;
+ if (getMemberArgs(func, src.size(), args, &start, &end)) {
+ ret.reserve(qAbs(end - start) + 1);
+ if (start < end) {
+ for (int i = start; i <= end && src.size() >= i; i++)
+ ret += src.at(i);
+ } else {
+ for (int i = start; i >= end && src.size() >= i && i >= 0; i--)
+ ret += src.at(i);
}
}
break;
- case E_STR_MEMBER:
- if (args.count() < 1 || args.count() > 3) {
- evalError(fL1S("str_member(str, start, end) requires one to three arguments."));
- } else {
- const ProString &src = args.at(0);
- int start, end;
- if (getMemberArgs(func, src.size(), args, &start, &end)) {
- QString res;
- res.reserve(qAbs(end - start) + 1);
- if (start < end) {
- for (int i = start; i <= end && src.size() >= i; i++)
- res += src.at(i);
- } else {
- for (int i = start; i >= end && src.size() >= i && i >= 0; i--)
- res += src.at(i);
- }
- ret += ProString(res);
+ }
+ case E_STR_MEMBER: {
+ const ProString &src = args.at(0);
+ int start, end;
+ if (getMemberArgs(func, src.size(), args, &start, &end)) {
+ QString res;
+ res.reserve(qAbs(end - start) + 1);
+ if (start < end) {
+ for (int i = start; i <= end && src.size() >= i; i++)
+ res += src.at(i);
+ } else {
+ for (int i = start; i >= end && src.size() >= i && i >= 0; i--)
+ res += src.at(i);
}
+ ret += ProString(res);
}
break;
+ }
case E_FIRST:
- case E_LAST:
- if (args.count() != 1) {
- evalError(fL1S("%1(var) requires one argument.").arg(func.toQStringView()));
- } else {
- const ProStringList &var = values(map(args.at(0)));
- if (!var.isEmpty()) {
- if (func_t == E_FIRST)
- ret.append(var[0]);
- else
- ret.append(var.last());
- }
+ case E_LAST: {
+ const ProStringList &var = values(map(args.at(0)));
+ if (!var.isEmpty()) {
+ if (func_t == E_FIRST)
+ ret.append(var[0]);
+ else
+ ret.append(var.last());
}
break;
+ }
case E_TAKE_FIRST:
- case E_TAKE_LAST:
- if (args.count() != 1) {
- evalError(fL1S("%1(var) requires one argument.").arg(func.toQStringView()));
- } else {
- ProStringList &var = valuesRef(map(args.at(0)));
- if (!var.isEmpty()) {
- if (func_t == E_TAKE_FIRST)
- ret.append(var.takeFirst());
- else
- ret.append(var.takeLast());
- }
+ case E_TAKE_LAST: {
+ ProStringList &var = valuesRef(map(args.at(0)));
+ if (!var.isEmpty()) {
+ if (func_t == E_TAKE_FIRST)
+ ret.append(var.takeFirst());
+ else
+ ret.append(var.takeLast());
}
break;
+ }
case E_SIZE:
- if (args.count() != 1)
- evalError(fL1S("size(var) requires one argument."));
- else
- ret.append(ProString(QString::number(values(map(args.at(0))).size())));
+ ret.append(ProString(QString::number(values(map(args.at(0))).size())));
break;
case E_STR_SIZE:
- if (args.count() != 1)
- evalError(fL1S("str_size(str) requires one argument."));
- else
- ret.append(ProString(QString::number(args.at(0).size())));
+ ret.append(ProString(QString::number(args.at(0).size())));
break;
- case E_CAT:
- if (args.count() < 1 || args.count() > 2) {
- evalError(fL1S("cat(file, singleline=true) requires one or two arguments."));
- } else {
- QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
- fn.detach();
-
- bool blob = false;
- bool lines = false;
- bool singleLine = true;
- if (args.count() > 1) {
- if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive))
- singleLine = false;
- else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive))
- blob = true;
- else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive))
- lines = true;
- }
-
- QFile qfile(fn);
- if (qfile.open(QIODevice::ReadOnly)) {
- QTextStream stream(&qfile);
- if (blob) {
- ret += ProString(stream.readAll());
- } else {
- while (!stream.atEnd()) {
- if (lines) {
- ret += ProString(stream.readLine());
- } else {
- const QString &line = stream.readLine();
- ret += split_value_list(QStringRef(&line).trimmed());
- if (!singleLine)
- ret += ProString("\n");
- }
+ case E_CAT: {
+ bool blob = false;
+ bool lines = false;
+ bool singleLine = true;
+ if (args.count() > 1) {
+ if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive))
+ singleLine = false;
+ else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive))
+ blob = true;
+ else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive))
+ lines = true;
+ }
+ QString fn = filePathEnvArg0(args);
+ QFile qfile(fn);
+ if (qfile.open(QIODevice::ReadOnly)) {
+ QTextStream stream(&qfile);
+ if (blob) {
+ ret += ProString(stream.readAll());
+ } else {
+ while (!stream.atEnd()) {
+ if (lines) {
+ ret += ProString(stream.readLine());
+ } else {
+ const QString &line = stream.readLine();
+ ret += split_value_list(QStringRef(&line).trimmed());
+ if (!singleLine)
+ ret += ProString("\n");
}
}
}
}
break;
- case E_FROMFILE:
- if (args.count() != 2) {
- evalError(fL1S("fromfile(file, variable) requires two arguments."));
- } else {
- ProValueMap vars;
- QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
- fn.detach();
- if (evaluateFileInto(fn, &vars, LoadProOnly) == ReturnTrue)
- ret = vars.value(map(args.at(1)));
- }
+ }
+ case E_FROMFILE: {
+ ProValueMap vars;
+ QString fn = filePathEnvArg0(args);
+ if (evaluateFileInto(fn, &vars, LoadProOnly) == ReturnTrue)
+ ret = vars.value(map(args.at(1)));
break;
+ }
case E_EVAL:
- if (args.count() != 1)
- evalError(fL1S("eval(variable) requires one argument."));
- else
- ret += values(map(args.at(0)));
+ ret += values(map(args.at(0)));
break;
case E_LIST: {
QString tmp;
@@ -888,84 +886,68 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
lst += split_value_list(arg.toQStringRef(), arg.sourceFile()); // Relies on deep copy
m_valuemapStack.top()[ret.at(0).toKey()] = lst;
break; }
- case E_FIND:
- if (args.count() != 2) {
- evalError(fL1S("find(var, str) requires two arguments."));
- } else {
- QRegExp regx(args.at(1).toQString());
- const auto vals = values(map(args.at(0)));
- for (const ProString &val : vals) {
- if (regx.indexIn(val.toQString(m_tmp[m_toggle ^= 1])) != -1)
- ret += val;
- }
+ case E_FIND: {
+ QRegExp regx(args.at(1).toQString());
+ const auto vals = values(map(args.at(0)));
+ for (const ProString &val : vals) {
+ ProStringRoUser u1(val, m_tmp[m_toggle ^= 1]);
+ if (regx.indexIn(u1.str()) != -1)
+ ret += val;
}
break;
- case E_SYSTEM:
- if (!m_skipLevel) {
- if (args.count() < 1 || args.count() > 3) {
- evalError(fL1S("system(command, [mode], [stsvar]) requires one to three arguments."));
+ }
+ case E_SYSTEM: {
+ if (m_skipLevel)
+ break;
+ bool blob = false;
+ bool lines = false;
+ bool singleLine = true;
+ if (args.count() > 1) {
+ if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive))
+ singleLine = false;
+ else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive))
+ blob = true;
+ else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive))
+ lines = true;
+ }
+ int exitCode;
+ QByteArray bytes = getCommandOutput(args.at(0).toQString(), &exitCode);
+ if (args.count() > 2 && !args.at(2).isEmpty()) {
+ m_valuemapStack.top()[args.at(2).toKey()] =
+ ProStringList(ProString(QString::number(exitCode)));
+ }
+ if (lines) {
+ QTextStream stream(bytes);
+ while (!stream.atEnd())
+ ret += ProString(stream.readLine());
+ } else {
+ QString output = QString::fromLocal8Bit(bytes);
+ if (blob) {
+ ret += ProString(output);
} else {
- bool blob = false;
- bool lines = false;
- bool singleLine = true;
- if (args.count() > 1) {
- if (!args.at(1).compare(QLatin1String("false"), Qt::CaseInsensitive))
- singleLine = false;
- else if (!args.at(1).compare(QLatin1String("blob"), Qt::CaseInsensitive))
- blob = true;
- else if (!args.at(1).compare(QLatin1String("lines"), Qt::CaseInsensitive))
- lines = true;
- }
- int exitCode;
- QByteArray bytes = getCommandOutput(args.at(0).toQString(), &exitCode);
- if (args.count() > 2 && !args.at(2).isEmpty()) {
- m_valuemapStack.top()[args.at(2).toKey()] =
- ProStringList(ProString(QString::number(exitCode)));
- }
- if (lines) {
- QTextStream stream(bytes);
- while (!stream.atEnd())
- ret += ProString(stream.readLine());
- } else {
- QString output = QString::fromLocal8Bit(bytes);
- if (blob) {
- ret += ProString(output);
- } else {
- output.replace(QLatin1Char('\t'), QLatin1Char(' '));
- if (singleLine)
- output.replace(QLatin1Char('\n'), QLatin1Char(' '));
- ret += split_value_list(QStringRef(&output));
- }
- }
+ output.replace(QLatin1Char('\t'), QLatin1Char(' '));
+ if (singleLine)
+ output.replace(QLatin1Char('\n'), QLatin1Char(' '));
+ ret += split_value_list(QStringRef(&output));
}
}
break;
+ }
case E_UNIQUE:
- if (args.count() != 1) {
- evalError(fL1S("unique(var) requires one argument."));
- } else {
- ret = values(map(args.at(0)));
- ret.removeDuplicates();
- }
+ ret = values(map(args.at(0)));
+ ret.removeDuplicates();
break;
case E_SORTED:
- if (args.count() != 1) {
- evalError(fL1S("sorted(var) requires one argument."));
- } else {
- ret = values(map(args.at(0)));
- std::sort(ret.begin(), ret.end());
- }
+ ret = values(map(args.at(0)));
+ std::sort(ret.begin(), ret.end());
break;
- case E_REVERSE:
- if (args.count() != 1) {
- evalError(fL1S("reverse(var) requires one argument."));
- } else {
- ProStringList var = values(args.at(0).toKey());
- for (int i = 0; i < var.size() / 2; i++)
- qSwap(var[i], var[var.size() - i - 1]);
- ret += var;
- }
+ case E_REVERSE: {
+ ProStringList var = values(args.at(0).toKey());
+ for (int i = 0; i < var.size() / 2; i++)
+ qSwap(var[i], var[var.size() - i - 1]);
+ ret += var;
break;
+ }
case E_QUOTE:
ret += args;
break;
@@ -1004,25 +986,23 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
break;
case E_RE_ESCAPE:
for (int i = 0; i < args.size(); ++i) {
- const QString &rstr = QRegExp::escape(args.at(i).toQString(m_tmp1));
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(i) : ProString(rstr).setSource(args.at(i)));
+ ProStringRwUser u1(args.at(i), m_tmp1);
+ ret << u1.extract(QRegExp::escape(u1.str()));
}
break;
- case E_VAL_ESCAPE:
- if (args.count() != 1) {
- evalError(fL1S("val_escape(var) requires one argument."));
- } else {
- const ProStringList &vals = values(args.at(0).toKey());
- ret.reserve(vals.size());
- for (const ProString &str : vals)
- ret += ProString(quoteValue(str));
- }
+ case E_VAL_ESCAPE: {
+ const ProStringList &vals = values(args.at(0).toKey());
+ ret.reserve(vals.size());
+ for (const ProString &str : vals)
+ ret += ProString(quoteValue(str));
break;
+ }
case E_UPPER:
case E_LOWER:
case E_TITLE:
for (int i = 0; i < args.count(); ++i) {
- QString rstr = args.at(i).toQString(m_tmp1);
+ ProStringRwUser u1(args.at(i), m_tmp1);
+ QString rstr = u1.str();
if (func_t == E_UPPER) {
rstr = rstr.toUpper();
} else {
@@ -1030,134 +1010,119 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
if (func_t == E_TITLE && rstr.length() > 0)
rstr[0] = rstr.at(0).toTitleCase();
}
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(i) : ProString(rstr).setSource(args.at(i)));
+ ret << u1.extract(rstr);
}
break;
- case E_FILES:
- if (args.count() != 1 && args.count() != 2) {
- evalError(fL1S("files(pattern, recursive=false) requires one or two arguments."));
+ case E_FILES: {
+ bool recursive = false;
+ if (args.count() == 2)
+ recursive = isTrue(args.at(1));
+ QStringList dirs;
+ ProStringRoUser u1(args.at(0), m_tmp1);
+ QString r = m_option->expandEnvVars(u1.str())
+ .replace(QLatin1Char('\\'), QLatin1Char('/'));
+ QString pfx;
+ if (IoUtils::isRelativePath(r)) {
+ pfx = currentDirectory();
+ if (!pfx.endsWith(QLatin1Char('/')))
+ pfx += QLatin1Char('/');
+ }
+ int slash = r.lastIndexOf(QLatin1Char('/'));
+ if (slash != -1) {
+ dirs.append(r.left(slash+1));
+ r = r.mid(slash+1);
} else {
- bool recursive = false;
- if (args.count() == 2)
- recursive = isTrue(args.at(1));
- QStringList dirs;
- QString r = m_option->expandEnvVars(args.at(0).toQString(m_tmp1))
- .replace(QLatin1Char('\\'), QLatin1Char('/'));
- QString pfx;
- if (IoUtils::isRelativePath(r)) {
- pfx = currentDirectory();
- if (!pfx.endsWith(QLatin1Char('/')))
- pfx += QLatin1Char('/');
- }
- int slash = r.lastIndexOf(QLatin1Char('/'));
- if (slash != -1) {
- dirs.append(r.left(slash+1));
- r = r.mid(slash+1);
- } else {
- dirs.append(QString());
- }
+ dirs.append(QString());
+ }
- r.detach(); // Keep m_tmp out of QRegExp's cache
- QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard);
- for (int d = 0; d < dirs.count(); d++) {
- QString dir = dirs[d];
- QDir qdir(pfx + dir);
- for (int i = 0; i < (int)qdir.count(); ++i) {
- if (qdir[i] == statics.strDot || qdir[i] == statics.strDotDot)
- continue;
- QString fname = dir + qdir[i];
- if (IoUtils::fileType(pfx + fname) == IoUtils::FileIsDir) {
- if (recursive)
- dirs.append(fname + QLatin1Char('/'));
- }
- if (regex.exactMatch(qdir[i]))
- ret += ProString(fname).setSource(currentFileId());
+ r.detach(); // Keep m_tmp out of QRegExp's cache
+ QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard);
+ for (int d = 0; d < dirs.count(); d++) {
+ QString dir = dirs[d];
+ QDir qdir(pfx + dir);
+ for (int i = 0; i < (int)qdir.count(); ++i) {
+ if (qdir[i] == statics.strDot || qdir[i] == statics.strDotDot)
+ continue;
+ QString fname = dir + qdir[i];
+ if (IoUtils::fileType(pfx + fname) == IoUtils::FileIsDir) {
+ if (recursive)
+ dirs.append(fname + QLatin1Char('/'));
}
+ if (regex.exactMatch(qdir[i]))
+ ret += ProString(fname).setSource(currentFileId());
}
}
break;
+ }
#ifdef PROEVALUATOR_FULL
case E_PROMPT: {
- if (args.count() != 1 && args.count() != 2) {
- evalError(fL1S("prompt(question, [decorate=true]) requires one or two arguments."));
-// } else if (currentFileName() == QLatin1String("-")) {
-// evalError(fL1S("prompt(question) cannot be used when '-o -' is used"));
+ ProStringRoUser u1(args.at(0), m_tmp1);
+ QString msg = m_option->expandEnvVars(u1.str());
+ bool decorate = true;
+ if (args.count() == 2)
+ decorate = isTrue(args.at(1));
+ if (decorate) {
+ if (!msg.endsWith(QLatin1Char('?')))
+ msg += QLatin1Char('?');
+ fprintf(stderr, "Project PROMPT: %s ", qPrintable(msg));
} else {
- QString msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp1));
- bool decorate = true;
- if (args.count() == 2)
- decorate = isTrue(args.at(1));
- if (decorate) {
- if (!msg.endsWith(QLatin1Char('?')))
- msg += QLatin1Char('?');
- fprintf(stderr, "Project PROMPT: %s ", qPrintable(msg));
- } else {
- fputs(qPrintable(msg), stderr);
- }
- QFile qfile;
- if (qfile.open(stdin, QIODevice::ReadOnly)) {
- QTextStream t(&qfile);
- const QString &line = t.readLine();
- if (t.atEnd()) {
- fputs("\n", stderr);
- evalError(fL1S("Unexpected EOF."));
- return ReturnError;
- }
- ret = split_value_list(QStringRef(&line));
+ fputs(qPrintable(msg), stderr);
+ }
+ QFile qfile;
+ if (qfile.open(stdin, QIODevice::ReadOnly)) {
+ QTextStream t(&qfile);
+ const QString &line = t.readLine();
+ if (t.atEnd()) {
+ fputs("\n", stderr);
+ evalError(fL1S("Unexpected EOF."));
+ return ReturnError;
}
+ ret = split_value_list(QStringRef(&line));
}
- break; }
+ break;
+ }
#endif
- case E_REPLACE:
- if (args.count() != 3 ) {
- evalError(fL1S("replace(var, before, after) requires three arguments."));
- } else {
- const QRegExp before(args.at(1).toQString());
- const QString &after(args.at(2).toQString(m_tmp2));
- const auto vals = values(map(args.at(0)));
- for (const ProString &val : vals) {
- QString rstr = val.toQString(m_tmp1);
- QString copy = rstr; // Force a detach on modify
- rstr.replace(before, after);
- ret << (rstr.isSharedWith(m_tmp1)
- ? val
- : rstr.isSharedWith(m_tmp2)
- ? args.at(2)
- : ProString(rstr).setSource(val));
- }
+ case E_REPLACE: {
+ const QRegExp before(args.at(1).toQString());
+ ProStringRwUser u2(args.at(2), m_tmp2);
+ const QString &after = u2.str();
+ const auto vals = values(map(args.at(0)));
+ for (const ProString &val : vals) {
+ ProStringRwUser u1(val, m_tmp1);
+ QString rstr = u1.str();
+ QString copy = rstr; // Force a detach on modify
+ rstr.replace(before, after);
+ ret << u1.extract(rstr, u2);
}
break;
+ }
case E_SORT_DEPENDS:
- case E_RESOLVE_DEPENDS:
- if (args.count() < 1 || args.count() > 4) {
- evalError(fL1S("%1(var, [prefix, [suffixes, [prio-suffix]]]) requires one to four arguments.")
- .arg(func.toQStringView()));
- } else {
- QHash<ProKey, QSet<ProKey> > dependencies;
- ProValueMap dependees;
- QMultiMap<int, ProString> rootSet;
- ProStringList orgList = values(args.at(0).toKey());
- ProString prefix = args.count() < 2 ? ProString() : args.at(1);
- ProString priosfx = args.count() < 4 ? ProString(".priority") : args.at(3);
- populateDeps(orgList, prefix,
- args.count() < 3 ? ProStringList(ProString(".depends"))
- : split_value_list(args.at(2).toQStringRef()),
- priosfx, dependencies, dependees, rootSet);
- while (!rootSet.isEmpty()) {
- QMultiMap<int, ProString>::iterator it = rootSet.begin();
- const ProString item = *it;
- rootSet.erase(it);
- if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item))
- ret.prepend(item);
- for (const ProString &dep : qAsConst(dependees[item.toKey()])) {
- QSet<ProKey> &dset = dependencies[dep.toKey()];
- dset.remove(item.toKey());
- if (dset.isEmpty())
- rootSet.insert(first(ProKey(prefix + dep + priosfx)).toInt(), dep);
- }
+ case E_RESOLVE_DEPENDS: {
+ QHash<ProKey, QSet<ProKey> > dependencies;
+ ProValueMap dependees;
+ QMultiMap<int, ProString> rootSet;
+ ProStringList orgList = values(args.at(0).toKey());
+ ProString prefix = args.count() < 2 ? ProString() : args.at(1);
+ ProString priosfx = args.count() < 4 ? ProString(".priority") : args.at(3);
+ populateDeps(orgList, prefix,
+ args.count() < 3 ? ProStringList(ProString(".depends"))
+ : split_value_list(args.at(2).toQStringRef()),
+ priosfx, dependencies, dependees, rootSet);
+ while (!rootSet.isEmpty()) {
+ QMultiMap<int, ProString>::iterator it = rootSet.begin();
+ const ProString item = *it;
+ rootSet.erase(it);
+ if ((func_t == E_RESOLVE_DEPENDS) || orgList.contains(item))
+ ret.prepend(item);
+ for (const ProString &dep : qAsConst(dependees[item.toKey()])) {
+ QSet<ProKey> &dset = dependencies[dep.toKey()];
+ dset.remove(item.toKey());
+ if (dset.isEmpty())
+ rootSet.insert(first(ProKey(prefix + dep + priosfx)).toInt(), dep);
}
}
break;
+ }
case E_ENUMERATE_VARS: {
QSet<ProString> keys;
for (const ProValueMap &vmap : qAsConst(m_valuemapStack))
@@ -1167,120 +1132,94 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
for (const ProString &key : qAsConst(keys))
ret << key;
break; }
- case E_SHADOWED:
- if (args.count() != 1) {
- evalError(fL1S("shadowed(path) requires one argument."));
- } else {
- QString rstr = m_option->shadowedPath(resolvePath(args.at(0).toQString(m_tmp1)));
- if (rstr.isEmpty())
- break;
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
- }
+ case E_SHADOWED: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ QString rstr = m_option->shadowedPath(resolvePath(u1.str()));
+ if (!rstr.isEmpty())
+ ret << u1.extract(rstr);
break;
- case E_ABSOLUTE_PATH:
- if (args.count() > 2) {
- evalError(fL1S("absolute_path(path[, base]) requires one or two arguments."));
- } else {
- QString arg = args.at(0).toQString(m_tmp1);
- QString baseDir = args.count() > 1
- ? IoUtils::resolvePath(currentDirectory(), args.at(1).toQString(m_tmp2))
- : currentDirectory();
- QString rstr = arg.isEmpty() ? baseDir : IoUtils::resolvePath(baseDir, arg);
- ret << (rstr.isSharedWith(m_tmp1)
- ? args.at(0)
- : args.count() > 1 && rstr.isSharedWith(m_tmp2)
- ? args.at(1)
- : ProString(rstr).setSource(args.at(0)));
- }
+ }
+ case E_ABSOLUTE_PATH: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ ProStringRwUser u2(m_tmp2);
+ QString baseDir = args.count() > 1
+ ? IoUtils::resolvePath(currentDirectory(), u2.set(args.at(1)))
+ : currentDirectory();
+ QString rstr = u1.str().isEmpty() ? baseDir : IoUtils::resolvePath(baseDir, u1.str());
+ ret << u1.extract(rstr, u2);
break;
- case E_RELATIVE_PATH:
- if (args.count() > 2) {
- evalError(fL1S("relative_path(path[, base]) requires one or two arguments."));
- } else {
- QString arg = args.at(0).toQString(m_tmp1);
- QString baseDir = args.count() > 1
- ? IoUtils::resolvePath(currentDirectory(), args.at(1).toQString(m_tmp2))
- : currentDirectory();
- QString absArg = arg.isEmpty() ? baseDir : IoUtils::resolvePath(baseDir, arg);
- QString rstr = QDir(baseDir).relativeFilePath(absArg);
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
- }
+ }
+ case E_RELATIVE_PATH: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ ProStringRoUser u2(m_tmp2);
+ QString baseDir = args.count() > 1
+ ? IoUtils::resolvePath(currentDirectory(), u2.set(args.at(1)))
+ : currentDirectory();
+ QString absArg = u1.str().isEmpty() ? baseDir : IoUtils::resolvePath(baseDir, u1.str());
+ QString rstr = QDir(baseDir).relativeFilePath(absArg);
+ ret << u1.extract(rstr);
break;
- case E_CLEAN_PATH:
- if (args.count() != 1) {
- evalError(fL1S("clean_path(path) requires one argument."));
- } else {
- QString rstr = QDir::cleanPath(args.at(0).toQString(m_tmp1));
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
- }
+ }
+ case E_CLEAN_PATH: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ ret << u1.extract(QDir::cleanPath(u1.str()));
break;
- case E_SYSTEM_PATH:
- if (args.count() != 1) {
- evalError(fL1S("system_path(path) requires one argument."));
- } else {
- QString rstr = args.at(0).toQString(m_tmp1);
+ }
+ case E_SYSTEM_PATH: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ QString rstr = u1.str();
#ifdef Q_OS_WIN
- rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
+ rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
#else
- rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
+ rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
#endif
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
- }
+ ret << u1.extract(rstr);
break;
- case E_SHELL_PATH:
- if (args.count() != 1) {
- evalError(fL1S("shell_path(path) requires one argument."));
+ }
+ case E_SHELL_PATH: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ QString rstr = u1.str();
+ if (m_dirSep.startsWith(QLatin1Char('\\'))) {
+ rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
} else {
- QString rstr = args.at(0).toQString(m_tmp1);
- if (m_dirSep.startsWith(QLatin1Char('\\'))) {
- rstr.replace(QLatin1Char('/'), QLatin1Char('\\'));
- } else {
- rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
+ rstr.replace(QLatin1Char('\\'), QLatin1Char('/'));
#ifdef Q_OS_WIN
- // Convert d:/foo/bar to msys-style /d/foo/bar.
- if (rstr.length() > 2 && rstr.at(1) == QLatin1Char(':') && rstr.at(2) == QLatin1Char('/')) {
- rstr[1] = rstr.at(0);
- rstr[0] = QLatin1Char('/');
- }
-#endif
+ // Convert d:/foo/bar to msys-style /d/foo/bar.
+ if (rstr.length() > 2 && rstr.at(1) == QLatin1Char(':') && rstr.at(2) == QLatin1Char('/')) {
+ rstr[1] = rstr.at(0);
+ rstr[0] = QLatin1Char('/');
}
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
+#endif
}
+ ret << u1.extract(rstr);
break;
- case E_SYSTEM_QUOTE:
- if (args.count() != 1) {
- evalError(fL1S("system_quote(arg) requires one argument."));
- } else {
- QString rstr = IoUtils::shellQuote(args.at(0).toQString(m_tmp1));
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
- }
+ }
+ case E_SYSTEM_QUOTE: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ ret << u1.extract(IoUtils::shellQuote(u1.str()));
break;
- case E_SHELL_QUOTE:
- if (args.count() != 1) {
- evalError(fL1S("shell_quote(arg) requires one argument."));
- } else {
- QString rstr = args.at(0).toQString(m_tmp1);
- if (m_dirSep.startsWith(QLatin1Char('\\')))
- rstr = IoUtils::shellQuoteWin(rstr);
- else
- rstr = IoUtils::shellQuoteUnix(rstr);
- ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0)));
- }
+ }
+ case E_SHELL_QUOTE: {
+ ProStringRwUser u1(args.at(0), m_tmp1);
+ QString rstr = u1.str();
+ if (m_dirSep.startsWith(QLatin1Char('\\')))
+ rstr = IoUtils::shellQuoteWin(rstr);
+ else
+ rstr = IoUtils::shellQuoteUnix(rstr);
+ ret << u1.extract(rstr);
break;
- case E_GETENV:
- if (args.count() != 1) {
- evalError(fL1S("getenv(arg) requires one argument."));
- } else {
- const ProString &var = args.at(0);
- const ProString &val = ProString(m_option->getEnv(var.toQString(m_tmp1)));
- ret << val;
- }
+ }
+ case E_GETENV: {
+ ProStringRoUser u1(args.at(0), m_tmp1);
+ ret << ProString(m_option->getEnv(u1.str()));
break;
+ }
default:
evalError(fL1S("Function '%1' is not implemented.").arg(func.toQStringView()));
break;
}
+ allfail:
return ReturnTrue;
}
@@ -1306,7 +1245,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::testFunc_cache(const ProStringList &
} else if (opt == QLatin1String("sub")) {
mode = CacheSub;
} else {
- evalError(fL1S("cache(): invalid flag %1.").arg(opt.toQString(m_tmp3)));
+ evalError(fL1S("cache(): invalid flag %1.").arg(opt.toQStringView()));
return ReturnFalse;
}
}
@@ -1450,17 +1389,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::testFunc_cache(const ProStringList &
}
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
- int func_t, const ProKey &function, const ProStringList &args)
+ const QMakeInternal::QMakeBuiltin &adef, const ProKey &function, const ProStringList &args)
{
traceMsg("calling built-in %s(%s)", dbgKey(function), dbgSepStrList(args));
+ int asz = args.size() > 1 ? args.size() : args.at(0).isEmpty() ? 0 : 1;
+ if (asz < adef.minArgs || asz > adef.maxArgs) {
+ evalError(adef.usage);
+ return ReturnFalse;
+ }
+ int func_t = adef.index;
switch (func_t) {
case T_DEFINED: {
- if (args.count() < 1 || args.count() > 2) {
- evalError(fL1S("defined(function, [\"test\"|\"replace\"|\"var\"])"
- " requires one or two arguments."));
- return ReturnFalse;
- }
const ProKey &var = args.at(0).toKey();
if (args.count() > 1) {
if (args[1] == QLatin1String("test")) {
@@ -1479,10 +1419,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|| m_functionDefs.testFunctions.contains(var));
}
case T_EXPORT: {
- if (args.count() != 1) {
- evalError(fL1S("export(variable) requires one argument."));
- return ReturnFalse;
- }
const ProKey &var = map(args.at(0));
for (ProValueMapStack::Iterator vmi = m_valuemapStack.end();
--vmi != m_valuemapStack.begin(); ) {
@@ -1503,15 +1439,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnTrue;
}
case T_DISCARD_FROM: {
- if (args.count() != 1 || args.at(0).isEmpty()) {
- evalError(fL1S("discard_from(file) requires one argument."));
- return ReturnFalse;
- }
if (m_valuemapStack.count() != 1) {
evalError(fL1S("discard_from() cannot be called from functions."));
return ReturnFalse;
}
- QString fn = resolvePath(args.at(0).toQString(m_tmp1));
+ ProStringRoUser u1(args.at(0), m_tmp1);
+ QString fn = resolvePath(u1.str());
QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
int pro = m_vfs->idForFileName(fn, flags | QMakeVfs::VfsAccessedOnly);
if (!pro)
@@ -1550,32 +1483,34 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
iif.removeAt(idx);
return ReturnTrue;
}
- case T_INFILE:
- if (args.count() < 2 || args.count() > 3) {
- evalError(fL1S("infile(file, var, [values]) requires two or three arguments."));
- } else {
- ProValueMap vars;
- QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
- fn.detach();
- VisitReturn ok = evaluateFileInto(fn, &vars, LoadProOnly);
- if (ok != ReturnTrue)
- return ok;
- if (args.count() == 2)
- return returnBool(vars.contains(map(args.at(1))));
- QRegExp regx;
- const QString &qry = args.at(2).toQString(m_tmp1);
- if (qry != QRegExp::escape(qry)) {
- QString copy = qry;
- copy.detach();
- regx.setPattern(copy);
- }
- const auto strings = vars.value(map(args.at(1)));
- for (const ProString &s : strings) {
- if ((!regx.isEmpty() && regx.exactMatch(s.toQString(m_tmp[m_toggle ^= 1]))) || s == qry)
+ case T_INFILE: {
+ ProValueMap vars;
+ QString fn = filePathEnvArg0(args);
+ VisitReturn ok = evaluateFileInto(fn, &vars, LoadProOnly);
+ if (ok != ReturnTrue)
+ return ok;
+ if (args.count() == 2)
+ return returnBool(vars.contains(map(args.at(1))));
+ QRegExp regx;
+ ProStringRoUser u1(args.at(2), m_tmp1);
+ const QString &qry = u1.str();
+ if (qry != QRegExp::escape(qry)) {
+ QString copy = qry;
+ copy.detach();
+ regx.setPattern(copy);
+ }
+ const auto strings = vars.value(map(args.at(1)));
+ for (const ProString &s : strings) {
+ if (s == qry)
+ return ReturnTrue;
+ if (!regx.isEmpty()) {
+ ProStringRoUser u2(s, m_tmp[m_toggle ^= 1]);
+ if (regx.exactMatch(u2.str()))
return ReturnTrue;
}
}
return ReturnFalse;
+ }
case T_REQUIRES:
#ifdef PROEVALUATOR_FULL
if (checkRequirements(args) == ReturnError)
@@ -1583,32 +1518,24 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
#endif
return ReturnFalse; // Another qmake breakage
case T_EVAL: {
- VisitReturn ret = ReturnFalse;
- QString contents = args.join(statics.field_sep);
- ProFile *pro = m_parser->parsedProBlock(QStringRef(&contents),
- 0, m_current.pro->fileName(), m_current.line);
- if (m_cumulative || pro->isOk()) {
- m_locationStack.push(m_current);
- visitProBlock(pro, pro->tokPtr());
- ret = ReturnTrue; // This return value is not too useful, but that's qmake
- m_current = m_locationStack.pop();
- }
- pro->deref();
- return ret;
- }
+ VisitReturn ret = ReturnFalse;
+ QString contents = args.join(statics.field_sep);
+ ProFile *pro = m_parser->parsedProBlock(QStringRef(&contents),
+ 0, m_current.pro->fileName(), m_current.line);
+ if (m_cumulative || pro->isOk()) {
+ m_locationStack.push(m_current);
+ visitProBlock(pro, pro->tokPtr());
+ ret = ReturnTrue; // This return value is not too useful, but that's qmake
+ m_current = m_locationStack.pop();
+ }
+ pro->deref();
+ return ret;
+ }
case T_IF: {
- if (args.count() != 1) {
- evalError(fL1S("if(condition) requires one argument."));
- return ReturnFalse;
- }
return evaluateConditional(args.at(0).toQStringRef(),
m_current.pro->fileName(), m_current.line);
}
case T_CONFIG: {
- if (args.count() < 1 || args.count() > 2) {
- evalError(fL1S("CONFIG(config) requires one or two arguments."));
- return ReturnFalse;
- }
if (args.count() == 1)
return returnBool(isActiveConfig(args.at(0).toQStringRef()));
const auto mutuals = args.at(1).toQStringRef().split(QLatin1Char('|'),
@@ -1624,12 +1551,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse;
}
case T_CONTAINS: {
- if (args.count() < 2 || args.count() > 3) {
- evalError(fL1S("contains(var, val) requires two or three arguments."));
- return ReturnFalse;
- }
-
- const QString &qry = args.at(1).toQString(m_tmp1);
+ ProStringRoUser u1(args.at(1), m_tmp1);
+ const QString &qry = u1.str();
QRegExp regx;
if (qry != QRegExp::escape(qry)) {
QString copy = qry;
@@ -1640,19 +1563,29 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (args.count() == 2) {
for (int i = 0; i < l.size(); ++i) {
const ProString &val = l[i];
- if ((!regx.isEmpty() && regx.exactMatch(val.toQString(m_tmp[m_toggle ^= 1]))) || val == qry)
+ if (val == qry)
return ReturnTrue;
+ if (!regx.isEmpty()) {
+ ProStringRoUser u2(val, m_tmp[m_toggle ^= 1]);
+ if (regx.exactMatch(u2.str()))
+ return ReturnTrue;
+ }
}
} else {
const auto mutuals = args.at(2).toQStringRef().split(QLatin1Char('|'),
QString::SkipEmptyParts);
for (int i = l.size() - 1; i >= 0; i--) {
- const ProString val = l[i];
+ const ProString &val = l[i];
for (int mut = 0; mut < mutuals.count(); mut++) {
if (val.toQStringRef() == mutuals[mut].trimmed()) {
- return returnBool((!regx.isEmpty()
- && regx.exactMatch(val.toQString(m_tmp[m_toggle ^= 1])))
- || val == qry);
+ if (val == qry)
+ return ReturnTrue;
+ if (!regx.isEmpty()) {
+ ProStringRoUser u2(val, m_tmp[m_toggle ^= 1]);
+ if (regx.exactMatch(u2.str()))
+ return ReturnTrue;
+ }
+ return ReturnFalse;
}
}
}
@@ -1660,10 +1593,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse;
}
case T_COUNT: {
- if (args.count() != 2 && args.count() != 3) {
- evalError(fL1S("count(var, count, op=\"equals\") requires two or three arguments."));
- return ReturnFalse;
- }
int cnt = values(map(args.at(0))).count();
int val = args.at(1).toInt();
if (args.count() == 3) {
@@ -1688,11 +1617,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
case T_GREATERTHAN:
case T_LESSTHAN: {
- if (args.count() != 2) {
- evalError(fL1S("%1(variable, value) requires two arguments.")
- .arg(function.toQStringView()));
- return ReturnFalse;
- }
const ProString &rhs = args.at(1);
const QString &lhs = values(map(args.at(0))).join(statics.field_sep);
bool ok;
@@ -1710,20 +1634,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return returnBool(lhs < rhs.toQStringRef());
}
case T_EQUALS:
- if (args.count() != 2) {
- evalError(fL1S("%1(variable, value) requires two arguments.")
- .arg(function.toQStringView()));
- return ReturnFalse;
- }
return returnBool(values(map(args.at(0))).join(statics.field_sep)
== args.at(1).toQStringView());
case T_VERSION_AT_LEAST:
case T_VERSION_AT_MOST: {
- if (args.count() != 2) {
- evalError(fL1S("%1(variable, versionNumber) requires two arguments.")
- .arg(function.toQStringView()));
- return ReturnFalse;
- }
const QVersionNumber lvn = QVersionNumber::fromString(values(args.at(0).toKey()).join('.'));
const QVersionNumber rvn = QVersionNumber::fromString(args.at(1).toQStringView());
if (func_t == T_VERSION_AT_LEAST)
@@ -1731,11 +1645,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return returnBool(lvn <= rvn);
}
case T_CLEAR: {
- if (args.count() != 1) {
- evalError(fL1S("%1(variable) requires one argument.")
- .arg(function.toQStringView()));
- return ReturnFalse;
- }
ProValueMap *hsh;
ProValueMap::Iterator it;
const ProKey &var = map(args.at(0));
@@ -1748,11 +1657,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnTrue;
}
case T_UNSET: {
- if (args.count() != 1) {
- evalError(fL1S("%1(variable) requires one argument.")
- .arg(function.toQStringView()));
- return ReturnFalse;
- }
ProValueMap *hsh;
ProValueMap::Iterator it;
const ProKey &var = map(args.at(0));
@@ -1768,23 +1672,15 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
case T_PARSE_JSON: {
- if (args.count() != 2) {
- evalError(fL1S("parseJson(variable, into) requires two arguments."));
- return ReturnFalse;
- }
-
QByteArray json = values(args.at(0).toKey()).join(QLatin1Char(' ')).toUtf8();
- QString parseInto = args.at(1).toQString(m_tmp2);
+ ProStringRoUser u1(args.at(1), m_tmp2);
+ QString parseInto = u1.str();
return parseJsonInto(json, parseInto, &m_valuemapStack.top());
}
#endif
case T_INCLUDE: {
- if (args.count() < 1 || args.count() > 3) {
- evalError(fL1S("include(file, [into, [silent]]) requires one, two or three arguments."));
- return ReturnFalse;
- }
QString parseInto;
- LoadFlags flags = 0;
+ LoadFlags flags;
if (m_cumulative)
flags = LoadSilent;
if (args.count() >= 2) {
@@ -1793,8 +1689,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
if (args.count() >= 3 && isTrue(args.at(2)))
flags = LoadSilent;
}
- QString fn = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
- fn.detach();
+ QString fn = filePathEnvArg0(args);
VisitReturn ok;
if (parseInto.isEmpty()) {
ok = evaluateFileChecked(fn, QMakeHandler::EvalIncludeFile, LoadProOnly | flags);
@@ -1812,9 +1707,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
for (ProValueMap::ConstIterator it = symbols.constBegin();
it != symbols.constEnd(); ++it) {
- const QString &ky = it.key().toQString(m_tmp1);
- if (!ky.startsWith(QLatin1Char('.')))
- newMap.insert(ProKey(parseInto + ky), it.value());
+ if (!it.key().startsWith(QLatin1Char('.')))
+ newMap.insert(ProKey(parseInto + it.key()), it.value());
}
m_valuemapStack.top() = newMap;
}
@@ -1824,13 +1718,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ok;
}
case T_LOAD: {
- bool ignore_error = false;
- if (args.count() == 2) {
- ignore_error = isTrue(args.at(1));
- } else if (args.count() != 1) {
- evalError(fL1S("load(feature) requires one or two arguments."));
- return ReturnFalse;
- }
+ bool ignore_error = (args.count() == 2 && isTrue(args.at(1)));
VisitReturn ok = evaluateFeatureFile(m_option->expandEnvVars(args.at(0).toQString()),
ignore_error);
if (ok == ReturnFalse && ignore_error)
@@ -1839,13 +1727,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
}
case T_DEBUG: {
#ifdef PROEVALUATOR_DEBUG
- if (args.count() != 2) {
- evalError(fL1S("debug(level, message) requires two arguments."));
- return ReturnFalse;
- }
int level = args.at(0).toInt();
if (level <= m_debugLevel) {
- const QString &msg = m_option->expandEnvVars(args.at(1).toQString(m_tmp2));
+ ProStringRoUser u1(args.at(1), m_tmp1);
+ const QString &msg = m_option->expandEnvVars(u1.str());
debugMsg(level, "Project DEBUG: %s", qPrintable(msg));
}
#endif
@@ -1855,33 +1740,26 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
case T_ERROR:
case T_WARNING:
case T_MESSAGE: {
- if (args.count() != 1) {
- evalError(fL1S("%1(message) requires one argument.")
- .arg(function.toQStringView()));
- return ReturnFalse;
- }
- const QString &msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp2));
+ ProStringRoUser u1(args.at(0), m_tmp1);
+ const QString &msg = m_option->expandEnvVars(u1.str());
if (!m_skipLevel) {
if (func_t == T_LOG) {
#ifdef PROEVALUATOR_FULL
fputs(msg.toLatin1().constData(), stderr);
#endif
} else if (!msg.isEmpty() || func_t != T_ERROR) {
+ ProStringRoUser u2(function, m_tmp2);
m_handler->fileMessage(
(func_t == T_ERROR ? QMakeHandler::ErrorMessage :
func_t == T_WARNING ? QMakeHandler::WarningMessage :
QMakeHandler::InfoMessage)
| (m_cumulative ? QMakeHandler::CumulativeEvalMessage : 0),
- fL1S("Project %1: %2").arg(function.toQString(m_tmp1).toUpper(), msg));
+ fL1S("Project %1: %2").arg(u2.str().toUpper(), msg));
}
}
return (func_t == T_ERROR && !m_cumulative) ? ReturnError : ReturnTrue;
}
case T_SYSTEM: {
- if (args.count() != 1) {
- evalError(fL1S("system(exec) requires one argument."));
- return ReturnFalse;
- }
#ifdef PROEVALUATOR_FULL
if (m_cumulative) // Anything else would be insanity
return ReturnFalse;
@@ -1905,19 +1783,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
#endif
}
case T_ISEMPTY: {
- if (args.count() != 1) {
- evalError(fL1S("isEmpty(var) requires one argument."));
- return ReturnFalse;
- }
return returnBool(values(map(args.at(0))).isEmpty());
}
case T_EXISTS: {
- if (args.count() != 1) {
- evalError(fL1S("exists(file) requires one argument."));
- return ReturnFalse;
- }
- const QString &file = resolvePath(m_option->expandEnvVars(args.at(0).toQString(m_tmp1)));
-
+ QString file = filePathEnvArg0(args);
// Don't use VFS here:
// - it supports neither listing nor even directories
// - it's unlikely that somebody would test for files they created themselves
@@ -1925,7 +1794,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnTrue;
int slsh = file.lastIndexOf(QLatin1Char('/'));
QString fn = file.mid(slsh+1);
- fn.detach();
if (fn.contains(QLatin1Char('*')) || fn.contains(QLatin1Char('?'))) {
QString dirstr = file.left(slsh+1);
dirstr.detach();
@@ -1936,13 +1804,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnFalse;
}
case T_MKPATH: {
- if (args.count() != 1) {
- evalError(fL1S("mkpath(file) requires one argument."));
- return ReturnFalse;
- }
#ifdef PROEVALUATOR_FULL
- QString fn = resolvePath(args.at(0).toQString(m_tmp1));
- fn.detach();
+ QString fn = filePathArg0(args);
if (!QDir::current().mkpath(fn)) {
evalError(fL1S("Cannot create directory %1.").arg(QDir::toNativeSeparators(fn)));
return ReturnFalse;
@@ -1951,10 +1814,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnTrue;
}
case T_WRITE_FILE: {
- if (args.count() > 3) {
- evalError(fL1S("write_file(name, [content var, [append] [exe]]) requires one to three arguments."));
- return ReturnFalse;
- }
QIODevice::OpenMode mode = QIODevice::Truncate;
QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
QString contents;
@@ -1970,24 +1829,21 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
} else if (opt == QLatin1String("exe")) {
flags |= QMakeVfs::VfsExecutable;
} else {
- evalError(fL1S("write_file(): invalid flag %1.").arg(opt.toQString(m_tmp3)));
+ evalError(fL1S("write_file(): invalid flag %1.").arg(opt.toQStringView()));
return ReturnFalse;
}
}
}
}
- QString path = resolvePath(args.at(0).toQString(m_tmp1));
- path.detach(); // make sure to not leak m_tmp1 into the map of written files.
+ QString path = filePathArg0(args);
return writeFile(QString(), path, mode, flags, contents);
}
case T_TOUCH: {
- if (args.count() != 2) {
- evalError(fL1S("touch(file, reffile) requires two arguments."));
- return ReturnFalse;
- }
#ifdef PROEVALUATOR_FULL
- const QString &tfn = resolvePath(args.at(0).toQString(m_tmp1));
- const QString &rfn = resolvePath(args.at(1).toQString(m_tmp2));
+ ProStringRoUser u1(args.at(0), m_tmp1);
+ ProStringRoUser u2(args.at(1), m_tmp2);
+ const QString &tfn = resolvePath(u1.str());
+ const QString &rfn = resolvePath(u2.str());
QString error;
if (!IoUtils::touchFile(tfn, rfn, &error)) {
evalError(error);
@@ -1997,10 +1853,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
return ReturnTrue;
}
case T_CACHE:
- if (args.count() > 3) {
- evalError(fL1S("cache(var, [set|add|sub] [transient] [super|stash], [srcvar]) requires one to three arguments."));
- return ReturnFalse;
- }
return testFunc_cache(args);
case T_RELOAD_PROPERTIES:
#ifdef QT_BUILD_QMAKE
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 6b23412327..432339d48e 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -118,7 +118,7 @@ bool operator==(const QMakeBaseKey &one, const QMakeBaseKey &two)
}
QMakeBaseEnv::QMakeBaseEnv()
- : evaluator(0)
+ : evaluator(nullptr)
{
#ifdef PROEVALUATOR_THREAD_SAFE
inProgress = false;
@@ -215,7 +215,7 @@ QMakeEvaluator::QMakeEvaluator(QMakeGlobals *option, QMakeParser *parser, QMakeV
initStatics();
// Configuration, more or less
- m_caller = 0;
+ m_caller = nullptr;
#ifdef PROEVALUATOR_CUMULATIVE
m_cumulative = false;
#endif
@@ -337,7 +337,8 @@ static void replaceInList(ProStringList *varlist,
const QRegExp &regexp, const QString &replace, bool global, QString &tmp)
{
for (ProStringList::Iterator varit = varlist->begin(); varit != varlist->end(); ) {
- QString val = varit->toQString(tmp);
+ ProStringRoUser u1(*varit, tmp);
+ QString val = u1.str();
QString copy = val; // Force detach and have a reference value
val.replace(regexp, replace);
if (!val.isSharedWith(copy) && val != copy) {
@@ -940,7 +941,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable(
if (varName == statics.strTEMPLATE)
setTemplate();
else if (varName == statics.strQMAKE_PLATFORM)
- m_featureRoots = 0;
+ m_featureRoots = nullptr;
else if (varName == statics.strQMAKE_DIR_SEP)
m_dirSep = first(varName);
else if (varName == statics.strQMAKESPEC) {
@@ -949,7 +950,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable(
if (IoUtils::isAbsolutePath(spec)) {
m_qmakespec = spec;
m_qmakespecName = IoUtils::fileName(m_qmakespec).toString();
- m_featureRoots = 0;
+ m_featureRoots = nullptr;
}
}
}
@@ -1336,7 +1337,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConfigFeatures()
bool finished = true;
ProStringList configs = values(statics.strCONFIG);
for (int i = configs.size() - 1; i >= 0; --i) {
- QString config = configs.at(i).toQString(m_tmp1).toLower();
+ ProStringRoUser u1(configs.at(i), m_tmp1);
+ QString config = u1.str().toLower();
if (!processed.contains(config)) {
config.detach();
processed.insert(config);
@@ -1592,7 +1594,7 @@ ProFile *QMakeEvaluator::currentProFile() const
{
if (m_profileStack.count() > 0)
return m_profileStack.top();
- return 0;
+ return nullptr;
}
int QMakeEvaluator::currentFileId() const
@@ -1640,7 +1642,8 @@ bool QMakeEvaluator::isActiveConfig(const QStringRef &config, bool regex)
// CONFIG variable
const auto configValues = values(statics.strCONFIG);
for (const ProString &configValue : configValues) {
- if (re.exactMatch(configValue.toQString(m_tmp[m_toggle ^= 1])))
+ ProStringRoUser u1(configValue, m_tmp[m_toggle ^= 1]);
+ if (re.exactMatch(u1.str()))
return true;
}
} else {
@@ -1749,9 +1752,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction(
if (val)
return ReturnTrue;
} else {
+ ProStringRoUser u1(function, m_tmp1);
evalError(fL1S("Unexpected return value from test '%1': %2.")
- .arg(function.toQString(m_tmp1))
- .arg(ret.join(QLatin1String(" :: "))));
+ .arg(u1.str(), ret.join(QLatin1String(" :: "))));
}
}
return ReturnFalse;
@@ -1762,12 +1765,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBoolFunction(
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
const ProKey &func, const ushort *&tokPtr)
{
- if (int func_t = statics.functions.value(func)) {
+ auto adef = statics.functions.constFind(func);
+ if (adef != statics.functions.constEnd()) {
//why don't the builtin functions just use args_list? --Sam
ProStringList args;
if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError)
return ReturnError;
- return evaluateBuiltinConditional(func_t, func, args);
+ return evaluateBuiltinConditional(*adef, func, args);
}
QHash<ProKey, ProFunctionDef>::ConstIterator it =
@@ -1788,12 +1792,13 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpandFunction(
const ProKey &func, const ushort *&tokPtr, ProStringList *ret)
{
- if (int func_t = statics.expands.value(func)) {
+ auto adef = statics.expands.constFind(func);
+ if (adef != statics.expands.constEnd()) {
//why don't the builtin functions just use args_list? --Sam
ProStringList args;
if (expandVariableReferences(tokPtr, 5, &args, true) == ReturnError)
return ReturnError;
- return evaluateBuiltinExpand(func_t, func, args, *ret);
+ return evaluateBuiltinExpand(*adef, func, args, *ret);
}
QHash<ProKey, ProFunctionDef>::ConstIterator it =
@@ -1869,7 +1874,7 @@ ProValueMap *QMakeEvaluator::findValues(const ProKey &variableName, ProValueMap:
if (first && isFunctParam(variableName))
break;
}
- return 0;
+ return nullptr;
}
ProStringList &QMakeEvaluator::valuesRef(const ProKey &variableName)
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index dc35e1ddab..f617681cbb 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -105,6 +105,8 @@ public:
const ProValueMap &top() const { return last(); }
};
+namespace QMakeInternal { struct QMakeBuiltin; }
+
class QMAKE_EXPORT QMakeEvaluator
{
public:
@@ -186,6 +188,8 @@ public:
int currentFileId() const;
QString resolvePath(const QString &fileName) const
{ return QMakeInternal::IoUtils::resolvePath(currentDirectory(), fileName); }
+ QString filePathArg0(const ProStringList &args);
+ QString filePathEnvArg0(const ProStringList &args);
VisitReturn evaluateFile(const QString &fileName, QMakeHandler::EvalFileType type,
LoadFlags flags);
@@ -214,8 +218,10 @@ public:
VisitReturn evaluateExpandFunction(const ProKey &function, const ushort *&tokPtr, ProStringList *ret);
VisitReturn evaluateConditionalFunction(const ProKey &function, const ushort *&tokPtr);
- VisitReturn evaluateBuiltinExpand(int func_t, const ProKey &function, const ProStringList &args, ProStringList &ret);
- VisitReturn evaluateBuiltinConditional(int func_t, const ProKey &function, const ProStringList &args);
+ VisitReturn evaluateBuiltinExpand(const QMakeInternal::QMakeBuiltin &adef,
+ const ProKey &function, const ProStringList &args, ProStringList &ret);
+ VisitReturn evaluateBuiltinConditional(const QMakeInternal::QMakeBuiltin &adef,
+ const ProKey &function, const ProStringList &args);
VisitReturn evaluateConditional(const QStringRef &cond, const QString &where, int line = -1);
#ifdef PROEVALUATOR_FULL
@@ -276,9 +282,9 @@ public:
#endif
struct Location {
- Location() : pro(0), line(0) {}
+ Location() : pro(nullptr), line(0) {}
Location(ProFile *_pro, ushort _line) : pro(_pro), line(_line) {}
- void clear() { pro = 0; line = 0; }
+ void clear() { pro = nullptr; line = 0; }
ProFile *pro;
ushort line;
};
diff --git a/qmake/library/qmakeevaluator_p.h b/qmake/library/qmakeevaluator_p.h
index f386a49108..f888bc5765 100644
--- a/qmake/library/qmakeevaluator_p.h
+++ b/qmake/library/qmakeevaluator_p.h
@@ -64,6 +64,22 @@ QT_BEGIN_NAMESPACE
namespace QMakeInternal {
+struct QMakeBuiltinInit
+{
+ const char *name;
+ int func;
+ enum { VarArgs = 1000 };
+ int min_args, max_args;
+ const char *args;
+};
+
+struct QMakeBuiltin
+{
+ QMakeBuiltin(const QMakeBuiltinInit &data);
+ QString usage;
+ int index, minArgs, maxArgs;
+};
+
struct QMakeStatics {
QString field_sep;
QString strtrue;
@@ -83,8 +99,8 @@ struct QMakeStatics {
#ifdef PROEVALUATOR_FULL
ProKey strREQUIRES;
#endif
- QHash<ProKey, int> expands;
- QHash<ProKey, int> functions;
+ QHash<ProKey, QMakeBuiltin> expands;
+ QHash<ProKey, QMakeBuiltin> functions;
QHash<ProKey, ProKey> varMap;
ProStringList fakeValue;
};
@@ -93,6 +109,8 @@ extern QMakeStatics statics;
}
+Q_DECLARE_TYPEINFO(QMakeInternal::QMakeBuiltin, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
#endif // QMAKEEVALUATOR_P_H
diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp
index 37608c7a15..4c8360b459 100644
--- a/qmake/library/qmakeparser.cpp
+++ b/qmake/library/qmakeparser.cpp
@@ -45,11 +45,17 @@ QT_BEGIN_NAMESPACE
//
///////////////////////////////////////////////////////////////////////
+ProFileCache::ProFileCache()
+{
+ QMakeVfs::ref();
+}
+
ProFileCache::~ProFileCache()
{
for (const Entry &ent : qAsConst(parsed_files))
if (ent.pro)
ent.pro->deref();
+ QMakeVfs::deref();
}
void ProFileCache::discardFile(const QString &fileName, QMakeVfs *vfs)
@@ -215,7 +221,7 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
pro->itemsRef()->squeeze();
pro->ref();
} else {
- pro = 0;
+ pro = nullptr;
}
ent->pro = pro;
#ifdef PROPARSER_THREAD_SAFE
@@ -234,7 +240,7 @@ ProFile *QMakeParser::parsedProFile(const QString &fileName, ParseFlags flags)
if (readFile(id, flags, &contents))
pro = parsedProBlock(QStringRef(&contents), id, fileName, 1, FullGrammar);
else
- pro = 0;
+ pro = nullptr;
}
return pro;
}
@@ -437,7 +443,7 @@ void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar
if (context == CtxPureValue) {
end = inend;
- cptr = 0;
+ cptr = nullptr;
lineCont = false;
indent = 0; // just gcc being stupid
goto nextChr;
@@ -449,7 +455,7 @@ void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar
// First, skip leading whitespace
for (indent = 0; ; ++cur, ++indent) {
if (cur == inend) {
- cur = 0;
+ cur = nullptr;
goto flushLine;
}
c = *cur;
@@ -1112,7 +1118,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
if (uc == ptr) {
// for(literal) (only "ever" would be legal if qmake was sane)
putTok(tokPtr, TokForLoop);
- putHashStr(tokPtr, (ushort *)0, (uint)0);
+ putHashStr(tokPtr, nullptr, (uint)0);
putBlockLen(tokPtr, 1 + 3 + nlen + 1);
putTok(tokPtr, TokHashLiteral);
putHashStr(tokPtr, uce + 2, nlen);
@@ -1135,7 +1141,7 @@ void QMakeParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int arg
} else if (argc == 1) {
// for(non-literal) (this wouldn't be here if qmake was sane)
putTok(tokPtr, TokForLoop);
- putHashStr(tokPtr, (ushort *)0, (uint)0);
+ putHashStr(tokPtr, nullptr, (uint)0);
uc = uce;
goto doFor;
}
diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h
index 3ae30dcf74..7b96d4e88f 100644
--- a/qmake/library/qmakeparser.h
+++ b/qmake/library/qmakeparser.h
@@ -110,7 +110,7 @@ private:
};
struct BlockScope {
- BlockScope() : start(0), braceLevel(0), special(false), inBranch(false), nest(NestNone) {}
+ BlockScope() : start(nullptr), braceLevel(0), special(false), inBranch(false), nest(NestNone) {}
BlockScope(const BlockScope &other) { *this = other; }
ushort *start; // Where this block started; store length here
int braceLevel; // Nesting of braces in scope
@@ -201,7 +201,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeParser::ParseFlags)
class QMAKE_EXPORT ProFileCache
{
public:
- ProFileCache() {}
+ ProFileCache();
~ProFileCache();
void discardFile(int id);
diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp
index 2239a2beec..3a54ef4023 100644
--- a/qmake/library/qmakevfs.cpp
+++ b/qmake/library/qmakevfs.cpp
@@ -52,11 +52,38 @@ QMakeVfs::QMakeVfs()
#ifndef QT_NO_TEXTCODEC
m_textCodec = 0;
#endif
+ ref();
+}
+
+QMakeVfs::~QMakeVfs()
+{
+ deref();
+}
+
+void QMakeVfs::ref()
+{
+#ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&s_mutex);
+#endif
+ ++s_refCount;
+}
+
+void QMakeVfs::deref()
+{
+#ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&s_mutex);
+#endif
+ if (!--s_refCount) {
+ s_fileIdCounter = 0;
+ s_fileIdMap.clear();
+ s_idFileMap.clear();
+ }
}
#ifdef PROPARSER_THREAD_SAFE
QMutex QMakeVfs::s_mutex;
#endif
+int QMakeVfs::s_refCount;
QAtomicInt QMakeVfs::s_fileIdCounter;
QHash<QString, int> QMakeVfs::s_fileIdMap;
QHash<int, QString> QMakeVfs::s_idFileMap;
@@ -114,16 +141,6 @@ QString QMakeVfs::fileNameForId(int id)
return s_idFileMap.value(id);
}
-void QMakeVfs::clearIds()
-{
-#ifdef PROEVALUATOR_THREAD_SAFE
- QMutexLocker locker(&s_mutex);
-#endif
- s_fileIdCounter = 0;
- s_fileIdMap.clear();
- s_idFileMap.clear();
-}
-
bool QMakeVfs::writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags,
const QString &contents, QString *errStr)
{
diff --git a/qmake/library/qmakevfs.h b/qmake/library/qmakevfs.h
index 1217225471..68c21a3d37 100644
--- a/qmake/library/qmakevfs.h
+++ b/qmake/library/qmakevfs.h
@@ -76,10 +76,13 @@ public:
Q_DECLARE_FLAGS(VfsFlags, VfsFlag)
QMakeVfs();
+ ~QMakeVfs();
+
+ static void ref();
+ static void deref();
int idForFileName(const QString &fn, VfsFlags flags);
QString fileNameForId(int id);
- static void clearIds();
bool writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr);
ReadResult readFile(int id, QString *contents, QString *errStr);
bool exists(const QString &fn, QMakeVfs::VfsFlags flags);
@@ -97,6 +100,7 @@ private:
#ifdef PROEVALUATOR_THREAD_SAFE
static QMutex s_mutex;
#endif
+ static int s_refCount;
static QAtomicInt s_fileIdCounter;
// Qt Creator's ProFile cache is a singleton to maximize its cross-project
// effectiveness (shared prf files from QtVersions).
diff --git a/qmake/main.cpp b/qmake/main.cpp
index 85709dc9bf..a4ef79227b 100644
--- a/qmake/main.cpp
+++ b/qmake/main.cpp
@@ -455,28 +455,22 @@ int runQMake(int argc, char **argv)
QString oldpwd = qmake_getpwd();
Option::output_dir = oldpwd; //for now this is the output dir
- if(Option::output.fileName() != "-") {
+ if (!Option::output.fileName().isEmpty() && Option::output.fileName() != "-") {
+ // The output 'filename', as given by the -o option, might include one
+ // or more directories, so we may need to rebase the output directory.
QFileInfo fi(Option::output);
- QString dir;
- if(fi.isDir()) {
- dir = fi.filePath();
- } else {
- QString tmp_dir = fi.path();
- if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir))
- dir = tmp_dir;
- }
-#ifdef Q_OS_MAC
- if (fi.fileName().endsWith(QLatin1String(".pbxproj"))
- && dir.endsWith(QLatin1String(".xcodeproj")))
- dir += QStringLiteral("/..");
-#endif
- if(!dir.isNull() && dir != ".")
- Option::output_dir = dir;
- if (QDir::isRelativePath(Option::output_dir)) {
- Option::output.setFileName(fi.fileName());
- Option::output_dir.prepend(oldpwd + QLatin1Char('/'));
+
+ QDir dir(QDir::cleanPath(fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath()));
+
+ // Don't treat Xcode project directory as part of OUT_PWD
+ if (dir.dirName().endsWith(QLatin1String(".xcodeproj"))) {
+ // Note: we're intentionally not using cdUp(), as the dir may not exist
+ dir.setPath(QDir::cleanPath(dir.filePath("..")));
}
- Option::output_dir = QDir::cleanPath(Option::output_dir);
+
+ Option::output_dir = dir.path();
+ QString absoluteFilePath = QDir::cleanPath(fi.absoluteFilePath());
+ Option::output.setFileName(absoluteFilePath.mid(Option::output_dir.length() + 1));
}
QMakeProperty prop;
@@ -552,7 +546,7 @@ int runQMake(int argc, char **argv)
exit_val = 5;
}
delete mkfile;
- mkfile = NULL;
+ mkfile = nullptr;
}
qmakeClearCaches();
return exit_val;
diff --git a/qmake/meta.cpp b/qmake/meta.cpp
index b47645b07f..2e8759b8ba 100644
--- a/qmake/meta.cpp
+++ b/qmake/meta.cpp
@@ -50,49 +50,19 @@ QMakeMetaInfo::readLib(const QString &meta_file)
return true;
}
- bool ret = false;
- if(!meta_file.isNull()) {
- if(meta_file.endsWith(Option::pkgcfg_ext)) {
- if((ret=readPkgCfgFile(meta_file)))
- meta_type = "pkgcfg";
- } else if(meta_file.endsWith(Option::libtool_ext)) {
- if((ret=readLibtoolFile(meta_file)))
- meta_type = "libtool";
- } else if(meta_file.endsWith(Option::prl_ext)) {
- QMakeProject proj;
- if (!proj.read(Option::normalizePath(meta_file), QMakeEvaluator::LoadProOnly))
- return false;
- meta_type = "qmake";
- vars = proj.variables();
- ret = true;
- } else {
- warn_msg(WarnLogic, "QMakeMetaInfo: unknown file format for %s",
- QDir::toNativeSeparators(meta_file).toLatin1().constData());
- }
- }
- if(ret)
- cache_vars.insert(meta_file, vars);
- return ret;
+ QMakeProject proj;
+ if (!proj.read(Option::normalizePath(meta_file), QMakeEvaluator::LoadProOnly))
+ return false;
+ vars = proj.variables();
+ cache_vars.insert(meta_file, vars);
+ return true;
}
QString
-QMakeMetaInfo::findLib(const QString &lib)
+QMakeMetaInfo::checkLib(const QString &lib)
{
- QString ret;
- QString extns[] = { Option::prl_ext, /*Option::pkgcfg_ext, Option::libtool_ext,*/ QString() };
- for(int extn = 0; !extns[extn].isNull(); extn++) {
- if(lib.endsWith(extns[extn]))
- ret = QFile::exists(lib) ? lib : QString();
- }
- if(ret.isNull()) {
- for(int extn = 0; !extns[extn].isNull(); extn++) {
- if(QFile::exists(lib + extns[extn])) {
- ret = lib + extns[extn];
- break;
- }
- }
- }
+ QString ret = QFile::exists(lib) ? lib : QString();
if(ret.isNull()) {
debug_msg(2, "QMakeMetaInfo: Cannot find info file for %s", lib.toLatin1().constData());
} else {
@@ -101,79 +71,4 @@ QMakeMetaInfo::findLib(const QString &lib)
return ret;
}
-
-bool
-QMakeMetaInfo::readLibtoolFile(const QString &f)
-{
- /* I can just run the .la through the .pro parser since they are compatible.. */
- QMakeProject proj;
- QString nf = Option::normalizePath(f);
- if (!proj.read(nf, QMakeEvaluator::LoadProOnly))
- return false;
- QString dirf = nf.section(QLatin1Char('/'), 0, -2);
- if(dirf == nf)
- dirf = "";
- else if(!dirf.isEmpty() && !dirf.endsWith(Option::output_dir))
- dirf += QLatin1Char('/');
- const ProValueMap &v = proj.variables();
- for (ProValueMap::ConstIterator it = v.begin(); it != v.end(); ++it) {
- ProStringList lst = it.value();
- if(lst.count() == 1 && (lst.first().startsWith("'") || lst.first().startsWith("\"")) &&
- lst.first().endsWith(QString(lst.first().at(0))))
- lst = ProStringList(lst.first().mid(1, lst.first().length() - 2));
- if(!vars.contains("QMAKE_PRL_TARGET") &&
- (it.key() == "dlname" || it.key() == "library_names" || it.key() == "old_library")) {
- ProString dir = v["libdir"].first();
- if ((dir.startsWith('\'') || dir.startsWith('"')) && dir.endsWith(dir.at(0)))
- dir = dir.mid(1, dir.length() - 2);
- dir = dir.trimmed();
- if(!dir.isEmpty() && !dir.endsWith(QLatin1Char('/')))
- dir += QLatin1Char('/');
- if(lst.count() == 1)
- lst = ProStringList(lst.first().toQString().split(" "));
- for (ProStringList::Iterator lst_it = lst.begin(); lst_it != lst.end(); ++lst_it) {
- bool found = false;
- QString dirs[] = { "", dir.toQString(), dirf, dirf + ".libs/", "(term)" };
- for(int i = 0; !found && dirs[i] != "(term)"; i++) {
- if(QFile::exists(dirs[i] + (*lst_it))) {
- QString targ = dirs[i] + (*lst_it);
- if(QDir::isRelativePath(targ))
- targ.prepend(qmake_getpwd() + QLatin1Char('/'));
- vars["QMAKE_PRL_TARGET"] << targ;
- found = true;
- }
- }
- if(found)
- break;
- }
- } else if(it.key() == "dependency_libs") {
- if(lst.count() == 1) {
- ProString dep = lst.first();
- if ((dep.startsWith('\'') || dep.startsWith('"')) && dep.endsWith(dep.at(0)))
- dep = dep.mid(1, dep.length() - 2);
- lst = ProStringList(dep.trimmed().toQString().split(" "));
- }
- for (ProStringList::Iterator lit = lst.begin(); lit != lst.end(); ++lit) {
- if((*lit).startsWith("-R")) {
- if(!conf->isEmpty("QMAKE_LFLAGS_RPATH"))
- (*lit) = conf->first("QMAKE_LFLAGS_RPATH") + (*lit).mid(2);
- }
- }
- ProStringList &prlLibs = vars["QMAKE_PRL_LIBS"];
- for (const ProString &s : qAsConst(lst)) {
- prlLibs.removeAll(s);
- prlLibs.append(s);
- }
- }
- }
- return true;
-}
-
-bool
-QMakeMetaInfo::readPkgCfgFile(const QString &f)
-{
- fprintf(stderr, "Must implement reading in pkg-config files (%s)!!!\n", f.toLatin1().constData());
- return false;
-}
-
QT_END_NAMESPACE
diff --git a/qmake/meta.h b/qmake/meta.h
index dd53cdc7a3..4721085fd2 100644
--- a/qmake/meta.h
+++ b/qmake/meta.h
@@ -41,20 +41,16 @@ class QMakeProject;
class QMakeMetaInfo
{
- bool readLibtoolFile(const QString &f);
- bool readPkgCfgFile(const QString &f);
QMakeProject *conf;
ProValueMap vars;
- QString meta_type;
static QHash<QString, ProValueMap> cache_vars;
public:
QMakeMetaInfo(QMakeProject *_conf);
// These functions expect the path to be normalized
- static QString findLib(const QString &lib);
+ static QString checkLib(const QString &lib);
bool readLib(const QString &meta_file);
- QString type() const;
bool isEmpty(const ProKey &v);
ProStringList &values(const ProKey &v);
ProString first(const ProKey &v);
@@ -64,9 +60,6 @@ public:
inline bool QMakeMetaInfo::isEmpty(const ProKey &v)
{ return !vars.contains(v) || vars[v].isEmpty(); }
-inline QString QMakeMetaInfo::type() const
-{ return meta_type; }
-
inline ProStringList &QMakeMetaInfo::values(const ProKey &v)
{ return vars[v]; }
diff --git a/qmake/option.cpp b/qmake/option.cpp
index baad644280..dcebeadcb8 100644
--- a/qmake/option.cpp
+++ b/qmake/option.cpp
@@ -507,7 +507,7 @@ QString
Option::fixString(QString string, uchar flags)
{
//const QString orig_string = string;
- static QHash<FixStringCacheKey, QString> *cache = 0;
+ static QHash<FixStringCacheKey, QString> *cache = nullptr;
if(!cache) {
cache = new QHash<FixStringCacheKey, QString>;
qmakeAddCacheClear(qmakeDeleteCacheClear<QHash<FixStringCacheKey, QString> >, (void**)&cache);
@@ -635,7 +635,7 @@ public:
QMakeCacheClearItem(qmakeCacheClearFunc f, void **d) : func(f), data(d) { }
~QMakeCacheClearItem() {
(*func)(*data);
- *data = 0;
+ *data = nullptr;
}
};
static QList<QMakeCacheClearItem*> cache_items;
diff --git a/qmake/option.h b/qmake/option.h
index eaa3706b24..25b2d64aaa 100644
--- a/qmake/option.h
+++ b/qmake/option.h
@@ -60,12 +60,12 @@ class QMakeProject;
class EvalHandler : public QMakeHandler {
public:
- void message(int type, const QString &msg, const QString &fileName, int lineNo);
+ void message(int type, const QString &msg, const QString &fileName, int lineNo) override;
- void fileMessage(int type, const QString &msg);
+ void fileMessage(int type, const QString &msg) override;
- void aboutToEval(ProFile *, ProFile *, EvalFileType);
- void doneWithEval(ProFile *);
+ void aboutToEval(ProFile *, ProFile *, EvalFileType) override;
+ void doneWithEval(ProFile *) override;
};
struct Option
@@ -108,7 +108,7 @@ struct Option
};
//both of these must be called..
- static int init(int argc=0, char **argv=0); //parse cmdline
+ static int init(int argc = 0, char **argv = nullptr); //parse cmdline
static void prepareProject(const QString &pfile);
static bool postProcessProject(QMakeProject *);
diff --git a/qmake/project.cpp b/qmake/project.cpp
index e6bdb04bfb..1bc9b352b5 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -82,8 +82,9 @@ bool QMakeProject::test(const ProKey &func, const QList<ProStringList> &args)
{
m_current.clear();
- if (int func_t = statics.functions.value(func))
- return boolRet(evaluateBuiltinConditional(func_t, func, prepareBuiltinArgs(args)));
+ auto adef = statics.functions.constFind(func);
+ if (adef != statics.functions.constEnd())
+ return boolRet(evaluateBuiltinConditional(*adef, func, prepareBuiltinArgs(args)));
QHash<ProKey, ProFunctionDef>::ConstIterator it =
m_functionDefs.testFunctions.constFind(func);
@@ -99,9 +100,10 @@ QStringList QMakeProject::expand(const ProKey &func, const QList<ProStringList>
{
m_current.clear();
- if (int func_t = statics.expands.value(func)) {
+ auto adef = statics.expands.constFind(func);
+ if (adef != statics.expands.constEnd()) {
ProStringList ret;
- if (evaluateBuiltinExpand(func_t, func, prepareBuiltinArgs(args), ret) == ReturnError)
+ if (evaluateBuiltinExpand(*adef, func, prepareBuiltinArgs(args), ret) == ReturnError)
exit(3);
return ret.toQStringList();
}
diff --git a/qmake/property.cpp b/qmake/property.cpp
index 9a8db8904d..c0a3ec0dab 100644
--- a/qmake/property.cpp
+++ b/qmake/property.cpp
@@ -68,7 +68,7 @@ static const struct {
{ "QMAKE_XSPEC", QLibraryInfo::TargetSpecPath, true, true },
};
-QMakeProperty::QMakeProperty() : settings(0)
+QMakeProperty::QMakeProperty() : settings(nullptr)
{
reload();
}
@@ -99,7 +99,7 @@ void QMakeProperty::reload()
QMakeProperty::~QMakeProperty()
{
delete settings;
- settings = 0;
+ settings = nullptr;
}
void QMakeProperty::initSettings()
diff --git a/src/3rdparty/double-conversion/bignum-dtoa.cc b/src/3rdparty/double-conversion/bignum-dtoa.cc
index f1ad7a5ae8..526f96edf5 100644
--- a/src/3rdparty/double-conversion/bignum-dtoa.cc
+++ b/src/3rdparty/double-conversion/bignum-dtoa.cc
@@ -25,12 +25,12 @@
// (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 <math.h>
+#include <cmath>
-#include "bignum-dtoa.h"
+#include <double-conversion/bignum-dtoa.h>
-#include "bignum.h"
-#include "ieee.h"
+#include <double-conversion/bignum.h>
+#include <double-conversion/ieee.h>
namespace double_conversion {
diff --git a/src/3rdparty/double-conversion/bignum-dtoa.h b/src/3rdparty/double-conversion/bignum-dtoa.h
index 34b961992d..9d15ce3dce 100644
--- a/src/3rdparty/double-conversion/bignum-dtoa.h
+++ b/src/3rdparty/double-conversion/bignum-dtoa.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_
#define DOUBLE_CONVERSION_BIGNUM_DTOA_H_
-#include "utils.h"
+#include <double-conversion/utils.h>
namespace double_conversion {
diff --git a/src/3rdparty/double-conversion/bignum.cc b/src/3rdparty/double-conversion/bignum.cc
index 2743d67e8d..a7bc86d0c0 100644
--- a/src/3rdparty/double-conversion/bignum.cc
+++ b/src/3rdparty/double-conversion/bignum.cc
@@ -25,13 +25,13 @@
// (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 "bignum.h"
-#include "utils.h"
+#include <double-conversion/bignum.h>
+#include <double-conversion/utils.h>
namespace double_conversion {
Bignum::Bignum()
- : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
+ : bigits_buffer_(), bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
for (int i = 0; i < kBigitCapacity; ++i) {
bigits_[i] = 0;
}
@@ -104,7 +104,7 @@ void Bignum::AssignDecimalString(Vector<const char> value) {
const int kMaxUint64DecimalDigits = 19;
Zero();
int length = value.length();
- int pos = 0;
+ unsigned int pos = 0;
// Let's just say that each digit needs 4 bits.
while (length >= kMaxUint64DecimalDigits) {
uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits);
@@ -445,26 +445,27 @@ void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
mask >>= 2;
uint64_t this_value = base;
- bool delayed_multipliciation = false;
+ bool delayed_multiplication = false;
const uint64_t max_32bits = 0xFFFFFFFF;
while (mask != 0 && this_value <= max_32bits) {
this_value = this_value * this_value;
// Verify that there is enough space in this_value to perform the
// multiplication. The first bit_size bits must be 0.
if ((power_exponent & mask) != 0) {
+ ASSERT(bit_size > 0);
uint64_t base_bits_mask =
~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1);
bool high_bits_zero = (this_value & base_bits_mask) == 0;
if (high_bits_zero) {
this_value *= base;
} else {
- delayed_multipliciation = true;
+ delayed_multiplication = true;
}
}
mask >>= 1;
}
AssignUInt64(this_value);
- if (delayed_multipliciation) {
+ if (delayed_multiplication) {
MultiplyByUInt32(base);
}
diff --git a/src/3rdparty/double-conversion/bignum.h b/src/3rdparty/double-conversion/bignum.h
index 5ec3544f57..238a351196 100644
--- a/src/3rdparty/double-conversion/bignum.h
+++ b/src/3rdparty/double-conversion/bignum.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_BIGNUM_H_
#define DOUBLE_CONVERSION_BIGNUM_H_
-#include "utils.h"
+#include <double-conversion/utils.h>
namespace double_conversion {
@@ -49,7 +49,6 @@ class Bignum {
void AssignPowerUInt16(uint16_t base, int exponent);
- void AddUInt16(uint16_t operand);
void AddUInt64(uint64_t operand);
void AddBignum(const Bignum& other);
// Precondition: this >= other.
@@ -137,7 +136,7 @@ class Bignum {
// The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
int exponent_;
- DISALLOW_COPY_AND_ASSIGN(Bignum);
+ DC_DISALLOW_COPY_AND_ASSIGN(Bignum);
};
} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/cached-powers.cc b/src/3rdparty/double-conversion/cached-powers.cc
index 9536f26927..6f771e9c73 100644
--- a/src/3rdparty/double-conversion/cached-powers.cc
+++ b/src/3rdparty/double-conversion/cached-powers.cc
@@ -25,13 +25,13 @@
// (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 <stdarg.h>
-#include <limits.h>
-#include <math.h>
+#include <climits>
+#include <cmath>
+#include <cstdarg>
-#include "utils.h"
+#include <double-conversion/utils.h>
-#include "cached-powers.h"
+#include <double-conversion/cached-powers.h>
namespace double_conversion {
@@ -131,7 +131,6 @@ static const CachedPower kCachedPowers[] = {
{UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340},
};
-static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers);
static const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent.
static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10)
// Difference between the decimal exponents in the table above.
@@ -144,14 +143,12 @@ void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
int max_exponent,
DiyFp* power,
int* decimal_exponent) {
- (void)max_exponent; // Silence unused parameter warning in release builds
- (void)kCachedPowersLength; // Silence unused parameter warning in release builds
int kQ = DiyFp::kSignificandSize;
double k = ceil((min_exponent + kQ - 1) * kD_1_LOG2_10);
int foo = kCachedPowersOffset;
int index =
(foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1;
- ASSERT(0 <= index && index < kCachedPowersLength);
+ ASSERT(0 <= index && index < static_cast<int>(ARRAY_SIZE(kCachedPowers)));
CachedPower cached_power = kCachedPowers[index];
ASSERT(min_exponent <= cached_power.binary_exponent);
(void) max_exponent; // Mark variable as used.
diff --git a/src/3rdparty/double-conversion/cached-powers.h b/src/3rdparty/double-conversion/cached-powers.h
index 61a50614cf..eabff4a15a 100644
--- a/src/3rdparty/double-conversion/cached-powers.h
+++ b/src/3rdparty/double-conversion/cached-powers.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_CACHED_POWERS_H_
#define DOUBLE_CONVERSION_CACHED_POWERS_H_
-#include "diy-fp.h"
+#include <double-conversion/diy-fp.h>
namespace double_conversion {
diff --git a/src/3rdparty/double-conversion/diy-fp.cc b/src/3rdparty/double-conversion/diy-fp.cc
index ddd1891b16..82b0d08af4 100644
--- a/src/3rdparty/double-conversion/diy-fp.cc
+++ b/src/3rdparty/double-conversion/diy-fp.cc
@@ -26,8 +26,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "diy-fp.h"
-#include "utils.h"
+#include <double-conversion/diy-fp.h>
+#include <double-conversion/utils.h>
namespace double_conversion {
diff --git a/src/3rdparty/double-conversion/diy-fp.h b/src/3rdparty/double-conversion/diy-fp.h
index 9dcf8fbdba..e2011d43e5 100644
--- a/src/3rdparty/double-conversion/diy-fp.h
+++ b/src/3rdparty/double-conversion/diy-fp.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_DIY_FP_H_
#define DOUBLE_CONVERSION_DIY_FP_H_
-#include "utils.h"
+#include <double-conversion/utils.h>
namespace double_conversion {
@@ -42,7 +42,7 @@ class DiyFp {
static const int kSignificandSize = 64;
DiyFp() : f_(0), e_(0) {}
- DiyFp(uint64_t f, int e) : f_(f), e_(e) {}
+ DiyFp(uint64_t significand, int exponent) : f_(significand), e_(exponent) {}
// this = this - other.
// The exponents of both numbers must be the same and the significand of this
@@ -76,22 +76,22 @@ class DiyFp {
void Normalize() {
ASSERT(f_ != 0);
- uint64_t f = f_;
- int e = e_;
+ uint64_t significand = f_;
+ int exponent = e_;
// This method is mainly called for normalizing boundaries. In general
// boundaries need to be shifted by 10 bits. We thus optimize for this case.
const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
- while ((f & k10MSBits) == 0) {
- f <<= 10;
- e -= 10;
+ while ((significand & k10MSBits) == 0) {
+ significand <<= 10;
+ exponent -= 10;
}
- while ((f & kUint64MSB) == 0) {
- f <<= 1;
- e--;
+ while ((significand & kUint64MSB) == 0) {
+ significand <<= 1;
+ exponent--;
}
- f_ = f;
- e_ = e;
+ f_ = significand;
+ e_ = exponent;
}
static DiyFp Normalize(const DiyFp& a) {
diff --git a/src/3rdparty/double-conversion/double-conversion.cc b/src/3rdparty/double-conversion/double-conversion.cc
index 909985be82..ecd1a5ef3f 100644
--- a/src/3rdparty/double-conversion/double-conversion.cc
+++ b/src/3rdparty/double-conversion/double-conversion.cc
@@ -25,17 +25,18 @@
// (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 <limits.h>
-#include <math.h>
+#include <climits>
+#include <locale>
+#include <cmath>
-#include "double-conversion.h"
+#include <double-conversion/double-conversion.h>
-#include "bignum-dtoa.h"
-#include "fast-dtoa.h"
-#include "fixed-dtoa.h"
-#include "ieee.h"
-#include "strtod.h"
-#include "utils.h"
+#include <double-conversion/bignum-dtoa.h>
+#include <double-conversion/fast-dtoa.h>
+#include <double-conversion/fixed-dtoa.h>
+#include <double-conversion/ieee.h>
+#include <double-conversion/strtod.h>
+#include <double-conversion/utils.h>
namespace double_conversion {
@@ -118,7 +119,7 @@ void DoubleToStringConverter::CreateDecimalRepresentation(
StringBuilder* result_builder) const {
// Create a representation that is padded with zeros if needed.
if (decimal_point <= 0) {
- // "0.00000decimal_rep".
+ // "0.00000decimal_rep" or "0.000decimal_rep00".
result_builder->AddCharacter('0');
if (digits_after_point > 0) {
result_builder->AddCharacter('.');
@@ -129,7 +130,7 @@ void DoubleToStringConverter::CreateDecimalRepresentation(
result_builder->AddPadding('0', remaining_digits);
}
} else if (decimal_point >= length) {
- // "decimal_rep0000.00000" or "decimal_rep.0000"
+ // "decimal_rep0000.00000" or "decimal_rep.0000".
result_builder->AddSubstring(decimal_digits, length);
result_builder->AddPadding('0', decimal_point - length);
if (digits_after_point > 0) {
@@ -137,7 +138,7 @@ void DoubleToStringConverter::CreateDecimalRepresentation(
result_builder->AddPadding('0', digits_after_point);
}
} else {
- // "decima.l_rep000"
+ // "decima.l_rep000".
ASSERT(digits_after_point > 0);
result_builder->AddSubstring(decimal_digits, decimal_point);
result_builder->AddCharacter('.');
@@ -414,21 +415,55 @@ void DoubleToStringConverter::DoubleToAscii(double v,
}
+namespace {
+
+inline char ToLower(char ch) {
+ static const std::ctype<char>& cType =
+ std::use_facet<std::ctype<char> >(std::locale::classic());
+ return cType.tolower(ch);
+}
+
+inline char Pass(char ch) {
+ return ch;
+}
+
+template <class Iterator, class Converter>
+static inline bool ConsumeSubStringImpl(Iterator* current,
+ Iterator end,
+ const char* substring,
+ Converter converter) {
+ ASSERT(converter(**current) == *substring);
+ for (substring++; *substring != '\0'; substring++) {
+ ++*current;
+ if (*current == end || converter(**current) != *substring) {
+ return false;
+ }
+ }
+ ++*current;
+ return true;
+}
+
// Consumes the given substring from the iterator.
// Returns false, if the substring does not match.
template <class Iterator>
static bool ConsumeSubString(Iterator* current,
Iterator end,
- const char* substring) {
- ASSERT(**current == *substring);
- for (substring++; *substring != '\0'; substring++) {
- ++*current;
- if (*current == end || **current != *substring) return false;
+ const char* substring,
+ bool allow_case_insensibility) {
+ if (allow_case_insensibility) {
+ return ConsumeSubStringImpl(current, end, substring, ToLower);
+ } else {
+ return ConsumeSubStringImpl(current, end, substring, Pass);
}
- ++*current;
- return true;
}
+// Consumes first character of the str is equal to ch
+inline bool ConsumeFirstCharacter(char ch,
+ const char* str,
+ bool case_insensibility) {
+ return case_insensibility ? ToLower(ch) == str[0] : ch == str[0];
+}
+} // namespace
// Maximum number of significant digits in decimal representation.
// The longest possible double in decimal representation is
@@ -494,10 +529,17 @@ static double SignedZero(bool sign) {
// because it constant-propagated the radix and concluded that the last
// condition was always true. By moving it into a separate function the
// compiler wouldn't warn anymore.
+#if _MSC_VER
+#pragma optimize("",off)
static bool IsDecimalDigitForRadix(int c, int radix) {
return '0' <= c && c <= '9' && (c - '0') < radix;
}
-
+#pragma optimize("",on)
+#else
+static bool inline IsDecimalDigitForRadix(int c, int radix) {
+ return '0' <= c && c <= '9' && (c - '0') < radix;
+}
+#endif
// Returns true if 'c' is a character digit that is valid for the given radix.
// The 'a_character' should be 'a' or 'A'.
//
@@ -509,17 +551,86 @@ static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
return radix > 10 && c >= a_character && c < a_character + radix - 10;
}
+// Returns true, when the iterator is equal to end.
+template<class Iterator>
+static bool Advance (Iterator* it, char separator, int base, Iterator& end) {
+ if (separator == StringToDoubleConverter::kNoSeparator) {
+ ++(*it);
+ return *it == end;
+ }
+ if (!isDigit(**it, base)) {
+ ++(*it);
+ return *it == end;
+ }
+ ++(*it);
+ if (*it == end) return true;
+ if (*it + 1 == end) return false;
+ if (**it == separator && isDigit(*(*it + 1), base)) {
+ ++(*it);
+ }
+ return *it == end;
+}
+
+// Checks whether the string in the range start-end is a hex-float string.
+// This function assumes that the leading '0x'/'0X' is already consumed.
+//
+// Hex float strings are of one of the following forms:
+// - hex_digits+ 'p' ('+'|'-')? exponent_digits+
+// - hex_digits* '.' hex_digits+ 'p' ('+'|'-')? exponent_digits+
+// - hex_digits+ '.' 'p' ('+'|'-')? exponent_digits+
+template<class Iterator>
+static bool IsHexFloatString(Iterator start,
+ Iterator end,
+ char separator,
+ bool allow_trailing_junk) {
+ ASSERT(start != end);
+
+ Iterator current = start;
+
+ bool saw_digit = false;
+ while (isDigit(*current, 16)) {
+ saw_digit = true;
+ if (Advance(&current, separator, 16, end)) return false;
+ }
+ if (*current == '.') {
+ if (Advance(&current, separator, 16, end)) return false;
+ while (isDigit(*current, 16)) {
+ saw_digit = true;
+ if (Advance(&current, separator, 16, end)) return false;
+ }
+ if (!saw_digit) return false; // Only the '.', but no digits.
+ }
+ if (*current != 'p' && *current != 'P') return false;
+ if (Advance(&current, separator, 16, end)) return false;
+ if (*current == '+' || *current == '-') {
+ if (Advance(&current, separator, 16, end)) return false;
+ }
+ if (!isDigit(*current, 10)) return false;
+ if (Advance(&current, separator, 16, end)) return true;
+ while (isDigit(*current, 10)) {
+ if (Advance(&current, separator, 16, end)) return true;
+ }
+ return allow_trailing_junk || !AdvanceToNonspace(&current, end);
+}
+
// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
+//
+// If parse_as_hex_float is true, then the string must be a valid
+// hex-float.
template <int radix_log_2, class Iterator>
static double RadixStringToIeee(Iterator* current,
Iterator end,
bool sign,
+ char separator,
+ bool parse_as_hex_float,
bool allow_trailing_junk,
double junk_string_value,
bool read_as_double,
bool* result_is_junk) {
ASSERT(*current != end);
+ ASSERT(!parse_as_hex_float ||
+ IsHexFloatString(*current, end, separator, allow_trailing_junk));
const int kDoubleSize = Double::kSignificandSize;
const int kSingleSize = Single::kSignificandSize;
@@ -527,27 +638,39 @@ static double RadixStringToIeee(Iterator* current,
*result_is_junk = true;
+ int64_t number = 0;
+ int exponent = 0;
+ const int radix = (1 << radix_log_2);
+ // Whether we have encountered a '.' and are parsing the decimal digits.
+ // Only relevant if parse_as_hex_float is true.
+ bool post_decimal = false;
+
// Skip leading 0s.
while (**current == '0') {
- ++(*current);
- if (*current == end) {
+ if (Advance(current, separator, radix, end)) {
*result_is_junk = false;
return SignedZero(sign);
}
}
- int64_t number = 0;
- int exponent = 0;
- const int radix = (1 << radix_log_2);
-
- do {
+ while (true) {
int digit;
if (IsDecimalDigitForRadix(**current, radix)) {
digit = static_cast<char>(**current) - '0';
+ if (post_decimal) exponent -= radix_log_2;
} else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
digit = static_cast<char>(**current) - 'a' + 10;
+ if (post_decimal) exponent -= radix_log_2;
} else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
digit = static_cast<char>(**current) - 'A' + 10;
+ if (post_decimal) exponent -= radix_log_2;
+ } else if (parse_as_hex_float && **current == '.') {
+ post_decimal = true;
+ Advance(current, separator, radix, end);
+ ASSERT(*current != end);
+ continue;
+ } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
+ break;
} else {
if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
break;
@@ -570,17 +693,26 @@ static double RadixStringToIeee(Iterator* current,
int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
number >>= overflow_bits_count;
- exponent = overflow_bits_count;
+ exponent += overflow_bits_count;
bool zero_tail = true;
for (;;) {
- ++(*current);
- if (*current == end || !isDigit(**current, radix)) break;
+ if (Advance(current, separator, radix, end)) break;
+ if (parse_as_hex_float && **current == '.') {
+ // Just run over the '.'. We are just trying to see whether there is
+ // a non-zero digit somewhere.
+ Advance(current, separator, radix, end);
+ ASSERT(*current != end);
+ post_decimal = true;
+ }
+ if (!isDigit(**current, radix)) break;
zero_tail = zero_tail && **current == '0';
- exponent += radix_log_2;
+ if (!post_decimal) exponent += radix_log_2;
}
- if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
+ if (!parse_as_hex_float &&
+ !allow_trailing_junk &&
+ AdvanceToNonspace(current, end)) {
return junk_string_value;
}
@@ -602,15 +734,37 @@ static double RadixStringToIeee(Iterator* current,
}
break;
}
- ++(*current);
- } while (*current != end);
+ if (Advance(current, separator, radix, end)) break;
+ }
ASSERT(number < ((int64_t)1 << kSignificandSize));
ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
*result_is_junk = false;
- if (exponent == 0) {
+ if (parse_as_hex_float) {
+ ASSERT(**current == 'p' || **current == 'P');
+ Advance(current, separator, radix, end);
+ ASSERT(*current != end);
+ bool is_negative = false;
+ if (**current == '+') {
+ Advance(current, separator, radix, end);
+ ASSERT(*current != end);
+ } else if (**current == '-') {
+ is_negative = true;
+ Advance(current, separator, radix, end);
+ ASSERT(*current != end);
+ }
+ int written_exponent = 0;
+ while (IsDecimalDigitForRadix(**current, 10)) {
+ written_exponent = 10 * written_exponent + **current - '0';
+ if (Advance(current, separator, radix, end)) break;
+ }
+ if (is_negative) written_exponent = -written_exponent;
+ exponent += written_exponent;
+ }
+
+ if (exponent == 0 || number == 0) {
if (sign) {
if (number == 0) return -0.0;
number = -number;
@@ -619,10 +773,10 @@ static double RadixStringToIeee(Iterator* current,
}
ASSERT(number != 0);
- return Double(DiyFp(number, exponent)).value();
+ double result = Double(DiyFp(number, exponent)).value();
+ return sign ? -result : result;
}
-
template <class Iterator>
double StringToDoubleConverter::StringToIeee(
Iterator input,
@@ -638,6 +792,7 @@ double StringToDoubleConverter::StringToIeee(
const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
+ const bool allow_case_insensibility = (flags_ & ALLOW_CASE_INSENSIBILITY) != 0;
// To make sure that iterator dereferencing is valid the following
// convention is used:
@@ -687,8 +842,8 @@ double StringToDoubleConverter::StringToIeee(
}
if (infinity_symbol_ != NULL) {
- if (*current == infinity_symbol_[0]) {
- if (!ConsumeSubString(&current, end, infinity_symbol_)) {
+ if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensibility)) {
+ if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensibility)) {
return junk_string_value_;
}
@@ -706,8 +861,8 @@ double StringToDoubleConverter::StringToIeee(
}
if (nan_symbol_ != NULL) {
- if (*current == nan_symbol_[0]) {
- if (!ConsumeSubString(&current, end, nan_symbol_)) {
+ if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensibility)) {
+ if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensibility)) {
return junk_string_value_;
}
@@ -726,8 +881,7 @@ double StringToDoubleConverter::StringToIeee(
bool leading_zero = false;
if (*current == '0') {
- ++current;
- if (current == end) {
+ if (Advance(&current, separator_, 10, end)) {
*processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
@@ -735,16 +889,24 @@ double StringToDoubleConverter::StringToIeee(
leading_zero = true;
// It could be hexadecimal value.
- if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
+ if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) &&
+ (*current == 'x' || *current == 'X')) {
++current;
- if (current == end || !isDigit(*current, 16)) {
- return junk_string_value_; // "0x".
+
+ bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
+ IsHexFloatString(current, end, separator_, allow_trailing_junk);
+
+ if (current == end) return junk_string_value_; // "0x"
+ if (!parse_as_hex_float && !isDigit(*current, 16)) {
+ return junk_string_value_;
}
bool result_is_junk;
double result = RadixStringToIeee<4>(&current,
end,
sign,
+ separator_,
+ parse_as_hex_float,
allow_trailing_junk,
junk_string_value_,
read_as_double,
@@ -758,8 +920,7 @@ double StringToDoubleConverter::StringToIeee(
// Ignore leading zeros in the integer part.
while (*current == '0') {
- ++current;
- if (current == end) {
+ if (Advance(&current, separator_, 10, end)) {
*processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
@@ -780,8 +941,7 @@ double StringToDoubleConverter::StringToIeee(
nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
}
octal = octal && *current < '8';
- ++current;
- if (current == end) goto parsing_done;
+ if (Advance(&current, separator_, 10, end)) goto parsing_done;
}
if (significant_digits == 0) {
@@ -792,8 +952,7 @@ double StringToDoubleConverter::StringToIeee(
if (octal && !allow_trailing_junk) return junk_string_value_;
if (octal) goto parsing_done;
- ++current;
- if (current == end) {
+ if (Advance(&current, separator_, 10, end)) {
if (significant_digits == 0 && !leading_zero) {
return junk_string_value_;
} else {
@@ -806,8 +965,7 @@ double StringToDoubleConverter::StringToIeee(
// Integer part consists of 0 or is absent. Significant digits start after
// leading zeros (if any).
while (*current == '0') {
- ++current;
- if (current == end) {
+ if (Advance(&current, separator_, 10, end)) {
*processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
@@ -827,8 +985,7 @@ double StringToDoubleConverter::StringToIeee(
// Ignore insignificant digits in the fractional part.
nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
}
- ++current;
- if (current == end) goto parsing_done;
+ if (Advance(&current, separator_, 10, end)) goto parsing_done;
}
}
@@ -844,20 +1001,23 @@ double StringToDoubleConverter::StringToIeee(
if (*current == 'e' || *current == 'E') {
if (octal && !allow_trailing_junk) return junk_string_value_;
if (octal) goto parsing_done;
+ Iterator junk_begin = current;
++current;
if (current == end) {
if (allow_trailing_junk) {
+ current = junk_begin;
goto parsing_done;
} else {
return junk_string_value_;
}
}
- char sign = '+';
+ char exponen_sign = '+';
if (*current == '+' || *current == '-') {
- sign = static_cast<char>(*current);
+ exponen_sign = static_cast<char>(*current);
++current;
if (current == end) {
if (allow_trailing_junk) {
+ current = junk_begin;
goto parsing_done;
} else {
return junk_string_value_;
@@ -867,6 +1027,7 @@ double StringToDoubleConverter::StringToIeee(
if (current == end || *current < '0' || *current > '9') {
if (allow_trailing_junk) {
+ current = junk_begin;
goto parsing_done;
} else {
return junk_string_value_;
@@ -888,7 +1049,7 @@ double StringToDoubleConverter::StringToIeee(
++current;
} while (current != end && *current >= '0' && *current <= '9');
- exponent += (sign == '-' ? -num : num);
+ exponent += (exponen_sign == '-' ? -num : num);
}
if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
@@ -911,6 +1072,8 @@ double StringToDoubleConverter::StringToIeee(
result = RadixStringToIeee<3>(&start,
buffer + buffer_pos,
sign,
+ separator_,
+ false, // Don't parse as hex_float.
allow_trailing_junk,
junk_string_value_,
read_as_double,
diff --git a/src/3rdparty/double-conversion/double-conversion.pri b/src/3rdparty/double-conversion/double-conversion.pri
index 3207169689..6564f960d4 100644
--- a/src/3rdparty/double-conversion/double-conversion.pri
+++ b/src/3rdparty/double-conversion/double-conversion.pri
@@ -1,4 +1,4 @@
-INCLUDEPATH += $$PWD/include $$PWD/include/double-conversion
+INCLUDEPATH += $$PWD/.. $$PWD/include $$PWD/include/double-conversion
SOURCES += \
$$PWD/bignum.cc \
$$PWD/bignum-dtoa.cc \
diff --git a/src/3rdparty/double-conversion/fast-dtoa.cc b/src/3rdparty/double-conversion/fast-dtoa.cc
index 61350383a9..e5c222291f 100644
--- a/src/3rdparty/double-conversion/fast-dtoa.cc
+++ b/src/3rdparty/double-conversion/fast-dtoa.cc
@@ -25,11 +25,11 @@
// (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 "fast-dtoa.h"
+#include <double-conversion/fast-dtoa.h>
-#include "cached-powers.h"
-#include "diy-fp.h"
-#include "ieee.h"
+#include <double-conversion/cached-powers.h>
+#include <double-conversion/diy-fp.h>
+#include <double-conversion/ieee.h>
namespace double_conversion {
diff --git a/src/3rdparty/double-conversion/fast-dtoa.h b/src/3rdparty/double-conversion/fast-dtoa.h
index 5f1e8eee5e..ac4317c04d 100644
--- a/src/3rdparty/double-conversion/fast-dtoa.h
+++ b/src/3rdparty/double-conversion/fast-dtoa.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_FAST_DTOA_H_
#define DOUBLE_CONVERSION_FAST_DTOA_H_
-#include "utils.h"
+#include <double-conversion/utils.h>
namespace double_conversion {
diff --git a/src/3rdparty/double-conversion/fixed-dtoa.cc b/src/3rdparty/double-conversion/fixed-dtoa.cc
index aef65fdc21..8c111aca64 100644
--- a/src/3rdparty/double-conversion/fixed-dtoa.cc
+++ b/src/3rdparty/double-conversion/fixed-dtoa.cc
@@ -25,10 +25,10 @@
// (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 <math.h>
+#include <cmath>
-#include "fixed-dtoa.h"
-#include "ieee.h"
+#include <double-conversion/fixed-dtoa.h>
+#include <double-conversion/ieee.h>
namespace double_conversion {
@@ -98,7 +98,7 @@ class UInt128 {
return high_bits_ == 0 && low_bits_ == 0;
}
- int BitAt(int position) {
+ int BitAt(int position) const {
if (position >= 64) {
return static_cast<int>(high_bits_ >> (position - 64)) & 1;
} else {
@@ -259,7 +259,8 @@ static void FillFractionals(uint64_t fractionals, int exponent,
fractionals -= static_cast<uint64_t>(digit) << point;
}
// If the first bit after the point is set we have to round up.
- if (((fractionals >> (point - 1)) & 1) == 1) {
+ ASSERT(fractionals == 0 || point - 1 >= 0);
+ if ((fractionals != 0) && ((fractionals >> (point - 1)) & 1) == 1) {
RoundUp(buffer, length, decimal_point);
}
} else { // We need 128 bits.
diff --git a/src/3rdparty/double-conversion/fixed-dtoa.h b/src/3rdparty/double-conversion/fixed-dtoa.h
index 3bdd08e21f..a9436fc9f6 100644
--- a/src/3rdparty/double-conversion/fixed-dtoa.h
+++ b/src/3rdparty/double-conversion/fixed-dtoa.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_
#define DOUBLE_CONVERSION_FIXED_DTOA_H_
-#include "utils.h"
+#include <double-conversion/utils.h>
namespace double_conversion {
diff --git a/src/3rdparty/double-conversion/ieee.h b/src/3rdparty/double-conversion/ieee.h
index 661141d1a8..baaeced31c 100644
--- a/src/3rdparty/double-conversion/ieee.h
+++ b/src/3rdparty/double-conversion/ieee.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_DOUBLE_H_
#define DOUBLE_CONVERSION_DOUBLE_H_
-#include "diy-fp.h"
+#include <double-conversion/diy-fp.h>
namespace double_conversion {
@@ -99,7 +99,7 @@ class Double {
}
double PreviousDouble() const {
- if (d64_ == (kInfinity | kSignMask)) return -Double::Infinity();
+ if (d64_ == (kInfinity | kSignMask)) return -Infinity();
if (Sign() < 0) {
return Double(d64_ + 1).value();
} else {
@@ -257,7 +257,7 @@ class Double {
(biased_exponent << kPhysicalSignificandSize);
}
- DISALLOW_COPY_AND_ASSIGN(Double);
+ DC_DISALLOW_COPY_AND_ASSIGN(Double);
};
class Single {
@@ -394,7 +394,7 @@ class Single {
const uint32_t d32_;
- DISALLOW_COPY_AND_ASSIGN(Single);
+ DC_DISALLOW_COPY_AND_ASSIGN(Single);
};
} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/include/double-conversion/double-conversion.h b/src/3rdparty/double-conversion/include/double-conversion/double-conversion.h
index 6bdfa8d25d..7495d17a1d 100644
--- a/src/3rdparty/double-conversion/include/double-conversion/double-conversion.h
+++ b/src/3rdparty/double-conversion/include/double-conversion/double-conversion.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
-#include "utils.h"
+#include <double-conversion/utils.h>
namespace double_conversion {
@@ -294,13 +294,18 @@ class DoubleToStringConverter {
// should be at least kBase10MaximalLength + 1 characters long.
static const int kBase10MaximalLength = 17;
- // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or
- // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v'
- // after it has been casted to a single-precision float. That is, in this
- // mode static_cast<float>(v) must not be NaN, +Infinity or -Infinity.
+ // Converts the given double 'v' to digit characters. 'v' must not be NaN,
+ // +Infinity, or -Infinity. In SHORTEST_SINGLE-mode this restriction also
+ // applies to 'v' after it has been casted to a single-precision float. That
+ // is, in this mode static_cast<float>(v) must not be NaN, +Infinity or
+ // -Infinity.
//
// The result should be interpreted as buffer * 10^(point-length).
//
+ // The digits are written to the buffer in the platform's charset, which is
+ // often UTF-8 (with ASCII-range digits) but may be another charset, such
+ // as EBCDIC.
+ //
// The output depends on the given mode:
// - SHORTEST: produce the least amount of digits for which the internal
// identity requirement is still satisfied. If the digits are printed
@@ -374,7 +379,7 @@ class DoubleToStringConverter {
const int max_leading_padding_zeroes_in_precision_mode_;
const int max_trailing_padding_zeroes_in_precision_mode_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
+ DC_DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
};
@@ -389,9 +394,13 @@ class StringToDoubleConverter {
ALLOW_TRAILING_JUNK = 4,
ALLOW_LEADING_SPACES = 8,
ALLOW_TRAILING_SPACES = 16,
- ALLOW_SPACES_AFTER_SIGN = 32
+ ALLOW_SPACES_AFTER_SIGN = 32,
+ ALLOW_CASE_INSENSIBILITY = 64,
+ ALLOW_HEX_FLOATS = 128,
};
+ static const uc16 kNoSeparator = '\0';
+
// Flags should be a bit-or combination of the possible Flags-enum.
// - NO_FLAGS: no special flags.
// - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
@@ -421,6 +430,13 @@ class StringToDoubleConverter {
// - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
// Ex: StringToDouble("- 123.2") -> -123.2.
// StringToDouble("+ 123.2") -> 123.2
+ // - ALLOW_CASE_INSENSIBILITY: ignore case of characters for special values:
+ // infinity and nan.
+ // - ALLOW_HEX_FLOATS: allows hexadecimal float literals.
+ // This *must* start with "0x" and separate the exponent with "p".
+ // Examples: 0x1.2p3 == 9.0
+ // 0x10.1p0 == 16.0625
+ // ALLOW_HEX and ALLOW_HEX_FLOATS are indendent.
//
// empty_string_value is returned when an empty string is given as input.
// If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
@@ -445,6 +461,12 @@ class StringToDoubleConverter {
// - they must not have the same first character.
// - they must not start with digits.
//
+ // If the separator character is not kNoSeparator, then that specific
+ // character is ignored when in between two valid digits of the significant.
+ // It is not allowed to appear in the exponent.
+ // It is not allowed to lead or trail the number.
+ // It is not allowed to appear twice next to each other.
+ //
// Examples:
// flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
// empty_string_value = 0.0,
@@ -484,16 +506,26 @@ class StringToDoubleConverter {
// StringToDouble("01239E45") -> 1239e45.
// StringToDouble("-infinity") -> NaN // junk_string_value.
// StringToDouble("NaN") -> NaN // junk_string_value.
+ //
+ // flags = NO_FLAGS,
+ // separator = ' ':
+ // StringToDouble("1 2 3 4") -> 1234.0
+ // StringToDouble("1 2") -> NaN // junk_string_value
+ // StringToDouble("1 000 000.0") -> 1000000.0
+ // StringToDouble("1.000 000") -> 1.0
+ // StringToDouble("1.0e1 000") -> NaN // junk_string_value
StringToDoubleConverter(int flags,
double empty_string_value,
double junk_string_value,
const char* infinity_symbol,
- const char* nan_symbol)
+ const char* nan_symbol,
+ uc16 separator = kNoSeparator)
: flags_(flags),
empty_string_value_(empty_string_value),
junk_string_value_(junk_string_value),
infinity_symbol_(infinity_symbol),
- nan_symbol_(nan_symbol) {
+ nan_symbol_(nan_symbol),
+ separator_(separator) {
}
// Performs the conversion.
@@ -528,6 +560,7 @@ class StringToDoubleConverter {
const double junk_string_value_;
const char* const infinity_symbol_;
const char* const nan_symbol_;
+ const uc16 separator_;
template <class Iterator>
double StringToIeee(Iterator start_pointer,
@@ -535,7 +568,7 @@ class StringToDoubleConverter {
bool read_as_double,
int* processed_characters_count) const;
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
+ DC_DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
};
} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/include/double-conversion/utils.h b/src/3rdparty/double-conversion/include/double-conversion/utils.h
index 20bfd36c84..7622fe6162 100644
--- a/src/3rdparty/double-conversion/include/double-conversion/utils.h
+++ b/src/3rdparty/double-conversion/include/double-conversion/utils.h
@@ -28,25 +28,35 @@
#ifndef DOUBLE_CONVERSION_UTILS_H_
#define DOUBLE_CONVERSION_UTILS_H_
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
-#include <assert.h>
+#include <cassert>
#ifndef ASSERT
-# if defined(WINCE) || defined(_WIN32_WCE)
-# define ASSERT(condition)
-# else
-# define ASSERT(condition) \
+#define ASSERT(condition) \
assert(condition);
-# endif
#endif
#ifndef UNIMPLEMENTED
-# define UNIMPLEMENTED() (exit(-1))
+#define UNIMPLEMENTED() (abort())
+#endif
+#ifndef DOUBLE_CONVERSION_NO_RETURN
+#ifdef _MSC_VER
+#define DOUBLE_CONVERSION_NO_RETURN __declspec(noreturn)
+#else
+#define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn))
+#endif
#endif
#ifndef UNREACHABLE
-# define UNREACHABLE() (exit(-1))
+#ifdef _MSC_VER
+void DOUBLE_CONVERSION_NO_RETURN abort_noreturn();
+inline void abort_noreturn() { abort(); }
+#define UNREACHABLE() (abort_noreturn())
+#else
+#define UNREACHABLE() (abort())
+#endif
#endif
+
// Double operations detection based on target architecture.
// Linux uses a 80bit wide floating point stack on x86. This induces double
// rounding, which in turn leads to wrong results.
@@ -57,16 +67,38 @@
// the output of the division with the expected result. (Inlining must be
// disabled.)
// On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
+//
+// For example:
+/*
+// -- in div.c
+double Div_double(double x, double y) { return x / y; }
+
+// -- in main.c
+double Div_double(double x, double y); // Forward declaration.
+
+int main(int argc, char** argv) {
+ return Div_double(89255.0, 1e22) == 89255e-22;
+}
+*/
+// Run as follows ./main || echo "correct"
+//
+// If it prints "correct" then the architecture should be here, in the "correct" section.
#if defined(_M_X64) || defined(__x86_64__) || \
- defined(__ARMEL__) || defined(__avr32__) || _M_ARM_FP || \
+ defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \
defined(__hppa__) || defined(__ia64__) || \
defined(__mips__) || \
defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
+ defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
defined(__SH4__) || defined(__alpha__) || \
defined(_MIPS_ARCH_MIPS32R2) || \
- defined(__AARCH64EL__)
+ defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
+ defined(__riscv) || defined(__EMSCRIPTEN__) || \
+ defined(__or1k__)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
+#elif defined(__mc68000__) || \
+ defined(__pnacl__) || defined(__native_client__)
+#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
#if defined(_WIN32)
// Windows uses a 64bit wide floating point stack.
@@ -81,12 +113,6 @@
#error Target architecture was not detected as supported by Double-Conversion.
#endif
-#if defined(__GNUC__)
-#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
-#else
-#define DOUBLE_CONVERSION_UNUSED
-#endif
-
#if defined(_WIN32) && !defined(__MINGW32__)
typedef signed char int8_t;
@@ -125,8 +151,8 @@ typedef uint16_t uc16;
// A macro to disallow the evil copy constructor and operator= functions
// This should be used in the private: declarations for a class
-#ifndef DISALLOW_COPY_AND_ASSIGN
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+#ifndef DC_DISALLOW_COPY_AND_ASSIGN
+#define DC_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#endif
@@ -137,10 +163,10 @@ typedef uint16_t uc16;
// This should be used in the private: declarations for a class
// that wants to prevent anyone from instantiating it. This is
// especially useful for classes containing only static methods.
-#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS
-#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+#ifndef DC_DISALLOW_IMPLICIT_CONSTRUCTORS
+#define DC_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
TypeName(); \
- DISALLOW_COPY_AND_ASSIGN(TypeName)
+ DC_DISALLOW_COPY_AND_ASSIGN(TypeName)
#endif
namespace double_conversion {
@@ -172,8 +198,8 @@ template <typename T>
class Vector {
public:
Vector() : start_(NULL), length_(0) {}
- Vector(T* data, int length) : start_(data), length_(length) {
- ASSERT(length == 0 || (length > 0 && data != NULL));
+ Vector(T* data, int len) : start_(data), length_(len) {
+ ASSERT(len == 0 || (len > 0 && data != NULL));
}
// Returns a vector using the same backing storage as this one,
@@ -215,8 +241,8 @@ class Vector {
// buffer bounds on all operations in debug mode.
class StringBuilder {
public:
- StringBuilder(char* buffer, int size)
- : buffer_(buffer, size), position_(0) { }
+ StringBuilder(char* buffer, int buffer_size)
+ : buffer_(buffer, buffer_size), position_(0) { }
~StringBuilder() { if (!is_finalized()) Finalize(); }
@@ -282,7 +308,7 @@ class StringBuilder {
bool is_finalized() const { return position_ < 0; }
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
+ DC_DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
};
// The type-based aliasing rule allows the compiler to assume that pointers of
@@ -313,8 +339,12 @@ template <class Dest, class Source>
inline Dest BitCast(const Source& source) {
// Compile time assertion: sizeof(Dest) == sizeof(Source)
// A compile error here means your Dest and Source have different sizes.
- DOUBLE_CONVERSION_UNUSED
- typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
+#if __cplusplus >= 201103L
+ static_assert(sizeof(Dest) == sizeof(Source),
+ "source and destination size mismatch");
+#else
+ typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
+#endif
Dest dest;
memmove(&dest, &source, sizeof(dest));
diff --git a/src/3rdparty/double-conversion/qt_attribution.json b/src/3rdparty/double-conversion/qt_attribution.json
index 92118ac779..1d244a69b4 100644
--- a/src/3rdparty/double-conversion/qt_attribution.json
+++ b/src/3rdparty/double-conversion/qt_attribution.json
@@ -5,8 +5,8 @@
"QtUsage": "Used in Qt Core. Configure with -system-doubleconversion or -no-doubleconversion to avoid.",
"Homepage": "https://github.com/google/double-conversion",
- "Version": "2.0.1",
- "DownloadLocation": "https://github.com/google/double-conversion/commit/2fb03de56faa32bbba5e02222528e7b760f71d77",
+ "Version": "3.1.1",
+ "DownloadLocation": "https://github.com/google/double-conversion/commit/4199ef3d456ed0549e5665cf4186f0ee6210db3b",
"License": "BSD 3-clause \"New\" or \"Revised\" License",
"LicenseId": "BSD-3-Clause",
"LicenseFile": "LICENSE",
diff --git a/src/3rdparty/double-conversion/strtod.cc b/src/3rdparty/double-conversion/strtod.cc
index 34717562bd..e8cc13f2de 100644
--- a/src/3rdparty/double-conversion/strtod.cc
+++ b/src/3rdparty/double-conversion/strtod.cc
@@ -25,13 +25,13 @@
// (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 <stdarg.h>
-#include <limits.h>
+#include <climits>
+#include <cstdarg>
-#include "strtod.h"
-#include "bignum.h"
-#include "cached-powers.h"
-#include "ieee.h"
+#include <double-conversion/bignum.h>
+#include <double-conversion/cached-powers.h>
+#include <double-conversion/ieee.h>
+#include <double-conversion/strtod.h>
namespace double_conversion {
@@ -205,7 +205,7 @@ static bool DoubleStrtod(Vector<const char> trimmed,
// Note that the ARM simulator is compiled for 32bits. It therefore exhibits
// the same problem.
return false;
-#endif
+#else
if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
int read_digits;
// The trimmed input fits into a double.
@@ -243,6 +243,7 @@ static bool DoubleStrtod(Vector<const char> trimmed,
}
}
return false;
+#endif
}
@@ -286,7 +287,7 @@ static bool DiyFpStrtod(Vector<const char> buffer,
const int kDenominator = 1 << kDenominatorLog;
// Move the remaining decimals into the exponent.
exponent += remaining_decimals;
- int error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
+ uint64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
int old_e = input.e();
input.Normalize();
@@ -471,6 +472,30 @@ double Strtod(Vector<const char> buffer, int exponent) {
}
}
+static float SanitizedDoubletof(double d) {
+ ASSERT(d >= 0.0);
+ // ASAN has a sanitize check that disallows casting doubles to floats if
+ // they are too big.
+ // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#available-checks
+ // The behavior should be covered by IEEE 754, but some projects use this
+ // flag, so work around it.
+ float max_finite = 3.4028234663852885981170418348451692544e+38;
+ // The half-way point between the max-finite and infinity value.
+ // Since infinity has an even significand everything equal or greater than
+ // this value should become infinity.
+ double half_max_finite_infinity =
+ 3.40282356779733661637539395458142568448e+38;
+ if (d >= max_finite) {
+ if (d >= half_max_finite_infinity) {
+ return Single::Infinity();
+ } else {
+ return max_finite;
+ }
+ } else {
+ return static_cast<float>(d);
+ }
+}
+
float Strtof(Vector<const char> buffer, int exponent) {
char copy_buffer[kMaxSignificantDecimalDigits];
Vector<const char> trimmed;
@@ -482,7 +507,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
double double_guess;
bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
- float float_guess = static_cast<float>(double_guess);
+ float float_guess = SanitizedDoubletof(double_guess);
if (float_guess == double_guess) {
// This shortcut triggers for integer values.
return float_guess;
@@ -505,15 +530,15 @@ float Strtof(Vector<const char> buffer, int exponent) {
double double_next = Double(double_guess).NextDouble();
double double_previous = Double(double_guess).PreviousDouble();
- float f1 = static_cast<float>(double_previous);
+ float f1 = SanitizedDoubletof(double_previous);
float f2 = float_guess;
- float f3 = static_cast<float>(double_next);
+ float f3 = SanitizedDoubletof(double_next);
float f4;
if (is_correct) {
f4 = f3;
} else {
double double_next2 = Double(double_next).NextDouble();
- f4 = static_cast<float>(double_next2);
+ f4 = SanitizedDoubletof(double_next2);
}
(void) f2; // Mark variable as used.
ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
@@ -528,7 +553,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
(f1 == f2 && f2 != f3 && f3 == f4) ||
(f1 == f2 && f2 == f3 && f3 != f4));
- // guess and next are the two possible canditates (in the same way that
+ // guess and next are the two possible candidates (in the same way that
// double_guess was the lower candidate for a double-precision guess).
float guess = f1;
float next = f4;
diff --git a/src/3rdparty/double-conversion/strtod.h b/src/3rdparty/double-conversion/strtod.h
index ed0293b8f5..322651621f 100644
--- a/src/3rdparty/double-conversion/strtod.h
+++ b/src/3rdparty/double-conversion/strtod.h
@@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_STRTOD_H_
#define DOUBLE_CONVERSION_STRTOD_H_
-#include "utils.h"
+#include <double-conversion/utils.h>
namespace double_conversion {
diff --git a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jar b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jar
index 2b338a935b..f6b961fd5a 100644
--- a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jar
+++ b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties
index 4244097b7b..bf3de21830 100644
--- a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties
+++ b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Mon Feb 20 10:43:22 EST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.4-bin.zip
diff --git a/src/3rdparty/gradle/gradlew b/src/3rdparty/gradle/gradlew
index eeff5ccf0e..cccdd3d517 100755
--- a/src/3rdparty/gradle/gradlew
+++ b/src/3rdparty/gradle/gradlew
@@ -28,16 +28,16 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS="-Xmx1024m -Dfile.encoding=UTF-8"
+DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -155,7 +155,7 @@ if $cygwin ; then
fi
# Escape application args
-save ( ) {
+save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
diff --git a/src/3rdparty/gradle/gradlew.bat b/src/3rdparty/gradle/gradlew.bat
index 65b35a4602..f9553162f1 100644
--- a/src/3rdparty/gradle/gradlew.bat
+++ b/src/3rdparty/gradle/gradlew.bat
@@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=-Xmx1024m -Dfile.encoding=UTF-8
+set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json
index 0cf6a746f5..2f1aed8a87 100644
--- a/src/3rdparty/harfbuzz-ng/qt_attribution.json
+++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json
@@ -2,7 +2,7 @@
"Id": "harfbuzz-ng",
"Name": "HarfBuzz-NG",
"QDocModule": "qtgui",
- "QtUsage": "Optionally used in Qt GUI. Configure with -system-harfbuzz or -qt-harfbuzz to avoid.",
+ "QtUsage": "Optionally used in Qt GUI. Configure with -system-harfbuzz to force the use of the system library, or -qt-harfbuzz to link statically to the library that is bundled with your Qt version.",
"Description": "HarfBuzz is an OpenType text shaping engine.",
"Homepage": "http://harfbuzz.org",
diff --git a/src/3rdparty/harfbuzz/qt_attribution.json b/src/3rdparty/harfbuzz/qt_attribution.json
index 51449f2adb..986171fb7b 100644
--- a/src/3rdparty/harfbuzz/qt_attribution.json
+++ b/src/3rdparty/harfbuzz/qt_attribution.json
@@ -2,7 +2,7 @@
"Id": "harfbuzz",
"Name": "HarfBuzz",
"QDocModule": "qtgui",
- "QtUsage": "Optionally used in Qt GUI. Configure with -system-harfbuzz or -qt-harfbuzz to avoid.",
+ "QtUsage": "Optionally used in Qt GUI. Configure with -system-harfbuzz to force the use of the system library, or -no-harfbuzz to disable the use of HarfBuzz entirely.",
"License": "MIT License",
"LicenseId": "MIT",
diff --git a/src/3rdparty/libjpeg.pri b/src/3rdparty/libjpeg.pri
index a61f28dc5a..0d35bf8941 100644
--- a/src/3rdparty/libjpeg.pri
+++ b/src/3rdparty/libjpeg.pri
@@ -7,10 +7,8 @@ DEFINES += \
JPEG_LIB_VERSION=80 \
SIZEOF_SIZE_T=__SIZEOF_SIZE_T__
-#Disable warnings in 3rdparty code due to unused arguments
-contains(QMAKE_CC, gcc): {
- QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter -Wno-main
-}
+# Disable warnings in 3rdparty code due to unused arguments
+gcc: QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter -Wno-main
INCLUDEPATH += $$PWD/libjpeg/src
diff --git a/src/3rdparty/tinycbor/.gitignore b/src/3rdparty/tinycbor/.gitignore
new file mode 100644
index 0000000000..3272de3326
--- /dev/null
+++ b/src/3rdparty/tinycbor/.gitignore
@@ -0,0 +1,81 @@
+# Frequent generated files
+callgrind.out.*
+pcviewer.cfg
+*~
+*.a
+*.la
+*.core
+*.d
+*.dylib
+*.moc
+*.o
+*.obj
+*.orig
+*.swp
+*.rej
+*.so
+*.so.*
+*.pbxuser
+*.mode1
+*.mode1v3
+*_pch.h.cpp
+*_resource.rc
+.#*
+*.*#
+core
+.qmake.cache
+.qmake.stash
+.qmake.vars
+.device.vars
+tags
+.DS_Store
+*.debug
+Makefile*
+*.prl
+*.app
+*.pro.user*
+*.qmlproject.user*
+*.gcov
+*.gcda
+*.gcno
+*.flc
+.*.swp
+tinycbor.pc
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.vcxproj
+*.vcxproj.filters
+*.vcxproj.user
+*.exe.embed.manifest
+*.exe_manifest.rc
+*.exe_manifest.res
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# INTEGRITY generated files
+*.gpj
+*.int
+*.ael
+*.dla
+*.dnm
+*.dep
+*.map
+
+bin
+doc
+lib
+src/cjson
+src/doxygen.log
+!/Makefile
+.config
diff --git a/src/3rdparty/tinycbor/LICENSE b/src/3rdparty/tinycbor/LICENSE
new file mode 100644
index 0000000000..4aad977ceb
--- /dev/null
+++ b/src/3rdparty/tinycbor/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Intel Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/3rdparty/tinycbor/README b/src/3rdparty/tinycbor/README
new file mode 100644
index 0000000000..167efa06e2
--- /dev/null
+++ b/src/3rdparty/tinycbor/README
@@ -0,0 +1,13 @@
+Concise Binary Object Representation (CBOR) Library
+---------------------------------------------------
+
+To build TinyCBOR:
+
+ make
+
+If you want to change the compiler or pass extra compiler flags:
+
+ make CC=clang CFLAGS="-m32 -Oz" LDFLAGS="-m32"
+
+Documentation: https://intel.github.io/tinycbor/current/
+
diff --git a/src/3rdparty/tinycbor/VERSION b/src/3rdparty/tinycbor/VERSION
new file mode 100644
index 0000000000..a918a2aa18
--- /dev/null
+++ b/src/3rdparty/tinycbor/VERSION
@@ -0,0 +1 @@
+0.6.0
diff --git a/src/3rdparty/tinycbor/qt_attribution.json b/src/3rdparty/tinycbor/qt_attribution.json
new file mode 100644
index 0000000000..1d61534861
--- /dev/null
+++ b/src/3rdparty/tinycbor/qt_attribution.json
@@ -0,0 +1,14 @@
+{
+ "Id": "tinycbor",
+ "Name": "TinyCBOR",
+ "QDocModule": "qtcore",
+ "QtUsage": "Used for QCborStreamReader and QCborStreamWriter.",
+
+ "Description": "Concise Binary Object Representation (CBOR) Library",
+ "Homepage": "https://github.com/intel/tinycbor",
+ "License": "MIT License",
+ "LicenseId": "MIT",
+ "LicenseFile": "LICENSE",
+ "Version": "0.6+patches",
+ "Copyright": "Copyright (C) 2018 Intel Corporation"
+}
diff --git a/src/3rdparty/tinycbor/src/cbor.h b/src/3rdparty/tinycbor/src/cbor.h
new file mode 100644
index 0000000000..5c7ba74e39
--- /dev/null
+++ b/src/3rdparty/tinycbor/src/cbor.h
@@ -0,0 +1,722 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef CBOR_H
+#define CBOR_H
+
+#ifndef assert
+#include <assert.h>
+#endif
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "tinycbor-version.h"
+
+#define TINYCBOR_VERSION ((TINYCBOR_VERSION_MAJOR << 16) | (TINYCBOR_VERSION_MINOR << 8) | TINYCBOR_VERSION_PATCH)
+
+#ifdef __cplusplus
+extern "C" {
+#else
+#include <stdbool.h>
+#endif
+
+#ifndef SIZE_MAX
+/* Some systems fail to define SIZE_MAX in <stdint.h>, even though C99 requires it...
+ * Conversion from signed to unsigned is defined in 6.3.1.3 (Signed and unsigned integers) p2,
+ * which says: "the value is converted by repeatedly adding or subtracting one more than the
+ * maximum value that can be represented in the new type until the value is in the range of the
+ * new type."
+ * So -1 gets converted to size_t by adding SIZE_MAX + 1, which results in SIZE_MAX.
+ */
+# define SIZE_MAX ((size_t)-1)
+#endif
+
+#ifndef CBOR_API
+# define CBOR_API
+#endif
+#ifndef CBOR_PRIVATE_API
+# define CBOR_PRIVATE_API
+#endif
+#ifndef CBOR_INLINE_API
+# if defined(__cplusplus)
+# define CBOR_INLINE inline
+# define CBOR_INLINE_API inline
+# else
+# define CBOR_INLINE_API static CBOR_INLINE
+# if defined(_MSC_VER)
+# define CBOR_INLINE __inline
+# elif defined(__GNUC__)
+# define CBOR_INLINE __inline__
+# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+# define CBOR_INLINE inline
+# else
+# define CBOR_INLINE
+# endif
+# endif
+#endif
+
+typedef enum CborType {
+ CborIntegerType = 0x00,
+ CborByteStringType = 0x40,
+ CborTextStringType = 0x60,
+ CborArrayType = 0x80,
+ CborMapType = 0xa0,
+ CborTagType = 0xc0,
+ CborSimpleType = 0xe0,
+ CborBooleanType = 0xf5,
+ CborNullType = 0xf6,
+ CborUndefinedType = 0xf7,
+ CborHalfFloatType = 0xf9,
+ CborFloatType = 0xfa,
+ CborDoubleType = 0xfb,
+
+ CborInvalidType = 0xff /* equivalent to the break byte, so it will never be used */
+} CborType;
+
+typedef uint64_t CborTag;
+typedef enum CborKnownTags {
+ CborDateTimeStringTag = 0,
+ CborUnixTime_tTag = 1,
+ CborPositiveBignumTag = 2,
+ CborNegativeBignumTag = 3,
+ CborDecimalTag = 4,
+ CborBigfloatTag = 5,
+ CborCOSE_Encrypt0Tag = 16,
+ CborCOSE_Mac0Tag = 17,
+ CborCOSE_Sign1Tag = 18,
+ CborExpectedBase64urlTag = 21,
+ CborExpectedBase64Tag = 22,
+ CborExpectedBase16Tag = 23,
+ CborEncodedCborTag = 24,
+ CborUrlTag = 32,
+ CborBase64urlTag = 33,
+ CborBase64Tag = 34,
+ CborRegularExpressionTag = 35,
+ CborMimeMessageTag = 36,
+ CborCOSE_EncryptTag = 96,
+ CborCOSE_MacTag = 97,
+ CborCOSE_SignTag = 98,
+ CborSignatureTag = 55799
+} CborKnownTags;
+
+/* #define the constants so we can check with #ifdef */
+#define CborDateTimeStringTag CborDateTimeStringTag
+#define CborUnixTime_tTag CborUnixTime_tTag
+#define CborPositiveBignumTag CborPositiveBignumTag
+#define CborNegativeBignumTag CborNegativeBignumTag
+#define CborDecimalTag CborDecimalTag
+#define CborBigfloatTag CborBigfloatTag
+#define CborCOSE_Encrypt0Tag CborCOSE_Encrypt0Tag
+#define CborCOSE_Mac0Tag CborCOSE_Mac0Tag
+#define CborCOSE_Sign1Tag CborCOSE_Sign1Tag
+#define CborExpectedBase64urlTag CborExpectedBase64urlTag
+#define CborExpectedBase64Tag CborExpectedBase64Tag
+#define CborExpectedBase16Tag CborExpectedBase16Tag
+#define CborEncodedCborTag CborEncodedCborTag
+#define CborUrlTag CborUrlTag
+#define CborBase64urlTag CborBase64urlTag
+#define CborBase64Tag CborBase64Tag
+#define CborRegularExpressionTag CborRegularExpressionTag
+#define CborMimeMessageTag CborMimeMessageTag
+#define CborCOSE_EncryptTag CborCOSE_EncryptTag
+#define CborCOSE_MacTag CborCOSE_MacTag
+#define CborCOSE_SignTag CborCOSE_SignTag
+#define CborSignatureTag CborSignatureTag
+
+/* Error API */
+
+typedef enum CborError {
+ CborNoError = 0,
+
+ /* errors in all modes */
+ CborUnknownError,
+ CborErrorUnknownLength, /* request for length in array, map, or string with indeterminate length */
+ CborErrorAdvancePastEOF,
+ CborErrorIO,
+
+ /* parser errors streaming errors */
+ CborErrorGarbageAtEnd = 256,
+ CborErrorUnexpectedEOF,
+ CborErrorUnexpectedBreak,
+ CborErrorUnknownType, /* can only happen in major type 7 */
+ CborErrorIllegalType, /* type not allowed here */
+ CborErrorIllegalNumber,
+ CborErrorIllegalSimpleType, /* types of value less than 32 encoded in two bytes */
+ CborErrorNoMoreStringChunks,
+
+ /* parser errors in strict mode parsing only */
+ CborErrorUnknownSimpleType = 512,
+ CborErrorUnknownTag,
+ CborErrorInappropriateTagForType,
+ CborErrorDuplicateObjectKeys,
+ CborErrorInvalidUtf8TextString,
+ CborErrorExcludedType,
+ CborErrorExcludedValue,
+ CborErrorImproperValue,
+ CborErrorOverlongEncoding,
+ CborErrorMapKeyNotString,
+ CborErrorMapNotSorted,
+ CborErrorMapKeysNotUnique,
+
+ /* encoder errors */
+ CborErrorTooManyItems = 768,
+ CborErrorTooFewItems,
+
+ /* internal implementation errors */
+ CborErrorDataTooLarge = 1024,
+ CborErrorNestingTooDeep,
+ CborErrorUnsupportedType,
+ CborErrorUnimplementedValidation,
+
+ /* errors in converting to JSON */
+ CborErrorJsonObjectKeyIsAggregate = 1280,
+ CborErrorJsonObjectKeyNotString,
+ CborErrorJsonNotImplemented,
+
+ CborErrorOutOfMemory = (int) (~0U / 2 + 1),
+ CborErrorInternalError = (int) (~0U / 2) /* INT_MAX on two's complement machines */
+} CborError;
+
+CBOR_API const char *cbor_error_string(CborError error);
+
+/* Encoder API */
+
+typedef enum CborEncoderAppendType
+{
+ CborEncoderAppendCborData = 0,
+ CborEncoderAppendStringData = 1
+} CborEncoderAppendType;
+
+typedef CborError (*CborEncoderWriteFunction)(void *, const void *, size_t, CborEncoderAppendType);
+
+enum CborEncoderFlags
+{
+ CborIteratorFlag_WriterFunction = 0x01,
+ CborIteratorFlag_ContainerIsMap_ = 0x20
+};
+
+struct CborEncoder
+{
+ union {
+ uint8_t *ptr;
+ ptrdiff_t bytes_needed;
+ CborEncoderWriteFunction writer;
+ } data;
+ uint8_t *end;
+ size_t remaining;
+ int flags;
+};
+typedef struct CborEncoder CborEncoder;
+
+static const size_t CborIndefiniteLength = SIZE_MAX;
+
+#ifndef CBOR_NO_ENCODER_API
+CBOR_API void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags);
+CBOR_API void cbor_encoder_init_writer(CborEncoder *encoder, CborEncoderWriteFunction writer, void *);
+CBOR_API CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value);
+CBOR_API CborError cbor_encode_int(CborEncoder *encoder, int64_t value);
+CBOR_API CborError cbor_encode_negative_int(CborEncoder *encoder, uint64_t absolute_value);
+CBOR_API CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value);
+CBOR_API CborError cbor_encode_tag(CborEncoder *encoder, CborTag tag);
+CBOR_API CborError cbor_encode_text_string(CborEncoder *encoder, const char *string, size_t length);
+CBOR_INLINE_API CborError cbor_encode_text_stringz(CborEncoder *encoder, const char *string)
+{ return cbor_encode_text_string(encoder, string, strlen(string)); }
+CBOR_API CborError cbor_encode_byte_string(CborEncoder *encoder, const uint8_t *string, size_t length);
+CBOR_API CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value);
+
+CBOR_INLINE_API CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
+{ return cbor_encode_simple_value(encoder, (int)value - 1 + (CborBooleanType & 0x1f)); }
+CBOR_INLINE_API CborError cbor_encode_null(CborEncoder *encoder)
+{ return cbor_encode_simple_value(encoder, CborNullType & 0x1f); }
+CBOR_INLINE_API CborError cbor_encode_undefined(CborEncoder *encoder)
+{ return cbor_encode_simple_value(encoder, CborUndefinedType & 0x1f); }
+
+CBOR_INLINE_API CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
+{ return cbor_encode_floating_point(encoder, CborHalfFloatType, value); }
+CBOR_INLINE_API CborError cbor_encode_float(CborEncoder *encoder, float value)
+{ return cbor_encode_floating_point(encoder, CborFloatType, &value); }
+CBOR_INLINE_API CborError cbor_encode_double(CborEncoder *encoder, double value)
+{ return cbor_encode_floating_point(encoder, CborDoubleType, &value); }
+
+CBOR_API CborError cbor_encoder_create_array(CborEncoder *encoder, CborEncoder *arrayEncoder, size_t length);
+CBOR_API CborError cbor_encoder_create_map(CborEncoder *encoder, CborEncoder *mapEncoder, size_t length);
+CBOR_API CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *containerEncoder);
+CBOR_API CborError cbor_encoder_close_container_checked(CborEncoder *encoder, const CborEncoder *containerEncoder);
+
+CBOR_INLINE_API uint8_t *_cbor_encoder_get_buffer_pointer(const CborEncoder *encoder)
+{
+ return encoder->data.ptr;
+}
+
+CBOR_INLINE_API size_t cbor_encoder_get_buffer_size(const CborEncoder *encoder, const uint8_t *buffer)
+{
+ return (size_t)(encoder->data.ptr - buffer);
+}
+
+CBOR_INLINE_API size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *encoder)
+{
+ return encoder->end ? 0 : (size_t)encoder->data.bytes_needed;
+}
+#endif /* CBOR_NO_ENCODER_API */
+
+/* Parser API */
+
+enum CborParserGlobalFlags
+{
+ CborParserFlag_ExternalSource = 0x01
+};
+
+enum CborParserIteratorFlags
+{
+ /* used for all types, but not during string chunk iteration
+ * (values are static-asserted, don't change) */
+ CborIteratorFlag_IntegerValueIs64Bit = 0x01,
+ CborIteratorFlag_IntegerValueTooLarge = 0x02,
+
+ /* used only for CborIntegerType */
+ CborIteratorFlag_NegativeInteger = 0x04,
+
+ /* used only during string iteration */
+ CborIteratorFlag_BeforeFirstStringChunk = 0x04,
+ CborIteratorFlag_IteratingStringChunks = 0x08,
+
+ /* used for arrays, maps and strings, including during chunk iteration */
+ CborIteratorFlag_UnknownLength = 0x10,
+
+ /* used for maps, but must be kept for all types
+ * (ContainerIsMap value must be CborMapType - CborArrayType) */
+ CborIteratorFlag_ContainerIsMap = 0x20,
+ CborIteratorFlag_NextIsMapKey = 0x40
+};
+
+struct CborValue;
+struct CborParserOperations
+{
+ bool (*can_read_bytes)(void *token, size_t len);
+ void *(*read_bytes)(void *token, void *dst, size_t offset, size_t len);
+ void (*advance_bytes)(void *token, size_t len);
+ CborError (*transfer_string)(void *token, const void **userptr, size_t offset, size_t len);
+};
+
+struct CborParser
+{
+ union {
+ const uint8_t *end;
+ const struct CborParserOperations *ops;
+ } source;
+ enum CborParserGlobalFlags flags;
+};
+typedef struct CborParser CborParser;
+
+struct CborValue
+{
+ const CborParser *parser;
+ union {
+ const uint8_t *ptr;
+ void *token;
+ } source;
+ uint32_t remaining;
+ uint16_t extra;
+ uint8_t type;
+ uint8_t flags;
+};
+typedef struct CborValue CborValue;
+
+#ifndef CBOR_NO_PARSER_API
+CBOR_API CborError cbor_parser_init(const uint8_t *buffer, size_t size, uint32_t flags, CborParser *parser, CborValue *it);
+CBOR_API CborError cbor_parser_init_reader(const struct CborParserOperations *ops, CborParser *parser, CborValue *it, void *token);
+
+CBOR_API CborError cbor_value_validate_basic(const CborValue *it);
+
+CBOR_INLINE_API bool cbor_value_at_end(const CborValue *it)
+{ return it->remaining == 0; }
+CBOR_INLINE_API const uint8_t *cbor_value_get_next_byte(const CborValue *it)
+{ return it->source.ptr; }
+CBOR_API CborError cbor_value_reparse(CborValue *it);
+CBOR_API CborError cbor_value_advance_fixed(CborValue *it);
+CBOR_API CborError cbor_value_advance(CborValue *it);
+CBOR_INLINE_API bool cbor_value_is_container(const CborValue *it)
+{ return it->type == CborArrayType || it->type == CborMapType; }
+CBOR_API CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed);
+CBOR_API CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed);
+
+CBOR_PRIVATE_API uint64_t _cbor_value_decode_int64_internal(const CborValue *value);
+CBOR_INLINE_API uint64_t _cbor_value_extract_int64_helper(const CborValue *value)
+{
+ return value->flags & CborIteratorFlag_IntegerValueTooLarge ?
+ _cbor_value_decode_int64_internal(value) : value->extra;
+}
+
+CBOR_INLINE_API bool cbor_value_is_valid(const CborValue *value)
+{ return value && value->type != CborInvalidType; }
+CBOR_INLINE_API CborType cbor_value_get_type(const CborValue *value)
+{ return (CborType)value->type; }
+
+/* Null & undefined type */
+CBOR_INLINE_API bool cbor_value_is_null(const CborValue *value)
+{ return value->type == CborNullType; }
+CBOR_INLINE_API bool cbor_value_is_undefined(const CborValue *value)
+{ return value->type == CborUndefinedType; }
+
+/* Booleans */
+CBOR_INLINE_API bool cbor_value_is_boolean(const CborValue *value)
+{ return value->type == CborBooleanType; }
+CBOR_INLINE_API CborError cbor_value_get_boolean(const CborValue *value, bool *result)
+{
+ assert(cbor_value_is_boolean(value));
+ *result = !!value->extra;
+ return CborNoError;
+}
+
+/* Simple types */
+CBOR_INLINE_API bool cbor_value_is_simple_type(const CborValue *value)
+{ return value->type == CborSimpleType; }
+CBOR_INLINE_API CborError cbor_value_get_simple_type(const CborValue *value, uint8_t *result)
+{
+ assert(cbor_value_is_simple_type(value));
+ *result = (uint8_t)value->extra;
+ return CborNoError;
+}
+
+/* Integers */
+CBOR_INLINE_API bool cbor_value_is_integer(const CborValue *value)
+{ return value->type == CborIntegerType; }
+CBOR_INLINE_API bool cbor_value_is_unsigned_integer(const CborValue *value)
+{ return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger) == 0; }
+CBOR_INLINE_API bool cbor_value_is_negative_integer(const CborValue *value)
+{ return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger); }
+
+CBOR_INLINE_API CborError cbor_value_get_raw_integer(const CborValue *value, uint64_t *result)
+{
+ assert(cbor_value_is_integer(value));
+ *result = _cbor_value_extract_int64_helper(value);
+ return CborNoError;
+}
+
+CBOR_INLINE_API CborError cbor_value_get_uint64(const CborValue *value, uint64_t *result)
+{
+ assert(cbor_value_is_unsigned_integer(value));
+ *result = _cbor_value_extract_int64_helper(value);
+ return CborNoError;
+}
+
+CBOR_INLINE_API CborError cbor_value_get_int64(const CborValue *value, int64_t *result)
+{
+ assert(cbor_value_is_integer(value));
+ *result = (int64_t) _cbor_value_extract_int64_helper(value);
+ if (value->flags & CborIteratorFlag_NegativeInteger)
+ *result = -*result - 1;
+ return CborNoError;
+}
+
+CBOR_INLINE_API CborError cbor_value_get_int(const CborValue *value, int *result)
+{
+ assert(cbor_value_is_integer(value));
+ *result = (int) _cbor_value_extract_int64_helper(value);
+ if (value->flags & CborIteratorFlag_NegativeInteger)
+ *result = -*result - 1;
+ return CborNoError;
+}
+
+CBOR_API CborError cbor_value_get_int64_checked(const CborValue *value, int64_t *result);
+CBOR_API CborError cbor_value_get_int_checked(const CborValue *value, int *result);
+
+CBOR_INLINE_API bool cbor_value_is_length_known(const CborValue *value)
+{ return (value->flags & CborIteratorFlag_UnknownLength) == 0; }
+
+/* Tags */
+CBOR_INLINE_API bool cbor_value_is_tag(const CborValue *value)
+{ return value->type == CborTagType; }
+CBOR_INLINE_API CborError cbor_value_get_tag(const CborValue *value, CborTag *result)
+{
+ assert(cbor_value_is_tag(value));
+ *result = _cbor_value_extract_int64_helper(value);
+ return CborNoError;
+}
+CBOR_API CborError cbor_value_skip_tag(CborValue *it);
+
+/* Strings */
+CBOR_INLINE_API bool cbor_value_is_byte_string(const CborValue *value)
+{ return value->type == CborByteStringType; }
+CBOR_INLINE_API bool cbor_value_is_text_string(const CborValue *value)
+{ return value->type == CborTextStringType; }
+
+CBOR_INLINE_API CborError cbor_value_get_string_length(const CborValue *value, size_t *length)
+{
+ uint64_t v;
+ assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
+ if (!cbor_value_is_length_known(value))
+ return CborErrorUnknownLength;
+ v = _cbor_value_extract_int64_helper(value);
+ *length = (size_t)v;
+ if (*length != v)
+ return CborErrorDataTooLarge;
+ return CborNoError;
+}
+
+CBOR_PRIVATE_API CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
+ size_t *buflen, CborValue *next);
+CBOR_PRIVATE_API CborError _cbor_value_dup_string(const CborValue *value, void **buffer,
+ size_t *buflen, CborValue *next);
+
+CBOR_API CborError cbor_value_calculate_string_length(const CborValue *value, size_t *length);
+
+CBOR_INLINE_API CborError cbor_value_copy_text_string(const CborValue *value, char *buffer,
+ size_t *buflen, CborValue *next)
+{
+ assert(cbor_value_is_text_string(value));
+ return _cbor_value_copy_string(value, buffer, buflen, next);
+}
+CBOR_INLINE_API CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer,
+ size_t *buflen, CborValue *next)
+{
+ assert(cbor_value_is_byte_string(value));
+ return _cbor_value_copy_string(value, buffer, buflen, next);
+}
+
+CBOR_INLINE_API CborError cbor_value_dup_text_string(const CborValue *value, char **buffer,
+ size_t *buflen, CborValue *next)
+{
+ assert(cbor_value_is_text_string(value));
+ return _cbor_value_dup_string(value, (void **)buffer, buflen, next);
+}
+CBOR_INLINE_API CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer,
+ size_t *buflen, CborValue *next)
+{
+ assert(cbor_value_is_byte_string(value));
+ return _cbor_value_dup_string(value, (void **)buffer, buflen, next);
+}
+
+CBOR_PRIVATE_API CborError _cbor_value_get_string_chunk_size(const CborValue *value, size_t *len);
+CBOR_INLINE_API CborError cbor_value_get_string_chunk_size(const CborValue *value, size_t *len)
+{
+ assert(value->flags & CborIteratorFlag_IteratingStringChunks);
+ return _cbor_value_get_string_chunk_size(value, len);
+}
+
+CBOR_INLINE_API bool cbor_value_string_iteration_at_end(const CborValue *value)
+{
+ size_t dummy;
+ return cbor_value_get_string_chunk_size(value, &dummy) == CborErrorNoMoreStringChunks;
+}
+
+CBOR_PRIVATE_API CborError _cbor_value_begin_string_iteration(CborValue *value);
+CBOR_INLINE_API CborError cbor_value_begin_string_iteration(CborValue *value)
+{
+ assert(cbor_value_is_text_string(value) || cbor_value_is_byte_string(value));
+ assert(!(value->flags & CborIteratorFlag_IteratingStringChunks));
+ return _cbor_value_begin_string_iteration(value);
+}
+
+CBOR_PRIVATE_API CborError _cbor_value_finish_string_iteration(CborValue *value);
+CBOR_INLINE_API CborError cbor_value_finish_string_iteration(CborValue *value)
+{
+ assert(cbor_value_string_iteration_at_end(value));
+ return _cbor_value_finish_string_iteration(value);
+}
+
+CBOR_PRIVATE_API CborError _cbor_value_get_string_chunk(const CborValue *value, const void **bufferptr,
+ size_t *len, CborValue *next);
+CBOR_INLINE_API CborError cbor_value_get_text_string_chunk(const CborValue *value, const char **bufferptr,
+ size_t *len, CborValue *next)
+{
+ assert(cbor_value_is_text_string(value));
+ return _cbor_value_get_string_chunk(value, (const void **)bufferptr, len, next);
+}
+CBOR_INLINE_API CborError cbor_value_get_byte_string_chunk(const CborValue *value, const uint8_t **bufferptr,
+ size_t *len, CborValue *next)
+{
+ assert(cbor_value_is_byte_string(value));
+ return _cbor_value_get_string_chunk(value, (const void **)bufferptr, len, next);
+}
+
+CBOR_API CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result);
+
+/* Maps and arrays */
+CBOR_INLINE_API bool cbor_value_is_array(const CborValue *value)
+{ return value->type == CborArrayType; }
+CBOR_INLINE_API bool cbor_value_is_map(const CborValue *value)
+{ return value->type == CborMapType; }
+
+CBOR_INLINE_API CborError cbor_value_get_array_length(const CborValue *value, size_t *length)
+{
+ uint64_t v;
+ assert(cbor_value_is_array(value));
+ if (!cbor_value_is_length_known(value))
+ return CborErrorUnknownLength;
+ v = _cbor_value_extract_int64_helper(value);
+ *length = (size_t)v;
+ if (*length != v)
+ return CborErrorDataTooLarge;
+ return CborNoError;
+}
+
+CBOR_INLINE_API CborError cbor_value_get_map_length(const CborValue *value, size_t *length)
+{
+ uint64_t v;
+ assert(cbor_value_is_map(value));
+ if (!cbor_value_is_length_known(value))
+ return CborErrorUnknownLength;
+ v = _cbor_value_extract_int64_helper(value);
+ *length = (size_t)v;
+ if (*length != v)
+ return CborErrorDataTooLarge;
+ return CborNoError;
+}
+
+CBOR_API CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element);
+
+/* Floating point */
+CBOR_INLINE_API bool cbor_value_is_half_float(const CborValue *value)
+{ return value->type == CborHalfFloatType; }
+CBOR_INLINE_API CborError cbor_value_get_half_float(const CborValue *value, void *result)
+{
+ assert(cbor_value_is_half_float(value));
+ assert((value->flags & CborIteratorFlag_IntegerValueTooLarge) == 0);
+
+ /* size has been computed already */
+ memcpy(result, &value->extra, sizeof(value->extra));
+ return CborNoError;
+}
+
+CBOR_INLINE_API bool cbor_value_is_float(const CborValue *value)
+{ return value->type == CborFloatType; }
+CBOR_INLINE_API CborError cbor_value_get_float(const CborValue *value, float *result)
+{
+ uint32_t data;
+ assert(cbor_value_is_float(value));
+ assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
+ data = (uint32_t)_cbor_value_decode_int64_internal(value);
+ memcpy(result, &data, sizeof(*result));
+ return CborNoError;
+}
+
+CBOR_INLINE_API bool cbor_value_is_double(const CborValue *value)
+{ return value->type == CborDoubleType; }
+CBOR_INLINE_API CborError cbor_value_get_double(const CborValue *value, double *result)
+{
+ uint64_t data;
+ assert(cbor_value_is_double(value));
+ assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
+ data = _cbor_value_decode_int64_internal(value);
+ memcpy(result, &data, sizeof(*result));
+ return CborNoError;
+}
+
+/* Validation API */
+#ifndef CBOR_NO_VALIDATION_API
+
+enum CborValidationFlags {
+ /* Bit mapping:
+ * bits 0-7 (8 bits): canonical format
+ * bits 8-11 (4 bits): canonical format & strict mode
+ * bits 12-20 (8 bits): strict mode
+ * bits 21-31 (10 bits): other
+ */
+
+ CborValidateShortestIntegrals = 0x0001,
+ CborValidateShortestFloatingPoint = 0x0002,
+ CborValidateShortestNumbers = CborValidateShortestIntegrals | CborValidateShortestFloatingPoint,
+ CborValidateNoIndeterminateLength = 0x0100,
+ CborValidateMapIsSorted = 0x0200 | CborValidateNoIndeterminateLength,
+
+ CborValidateCanonicalFormat = 0x0fff,
+
+ CborValidateMapKeysAreUnique = 0x1000 | CborValidateMapIsSorted,
+ CborValidateTagUse = 0x2000,
+ CborValidateUtf8 = 0x4000,
+
+ CborValidateStrictMode = 0xfff00,
+
+ CborValidateMapKeysAreString = 0x100000,
+ CborValidateNoUndefined = 0x200000,
+ CborValidateNoTags = 0x400000,
+ CborValidateFiniteFloatingPoint = 0x800000,
+ /* unused = 0x1000000, */
+ /* unused = 0x2000000, */
+
+ CborValidateNoUnknownSimpleTypesSA = 0x4000000,
+ CborValidateNoUnknownSimpleTypes = 0x8000000 | CborValidateNoUnknownSimpleTypesSA,
+ CborValidateNoUnknownTagsSA = 0x10000000,
+ CborValidateNoUnknownTagsSR = 0x20000000 | CborValidateNoUnknownTagsSA,
+ CborValidateNoUnknownTags = 0x40000000 | CborValidateNoUnknownTagsSR,
+
+ CborValidateCompleteData = (int)0x80000000,
+
+ CborValidateStrictest = (int)~0U,
+ CborValidateBasic = 0
+};
+
+CBOR_API CborError cbor_value_validate(const CborValue *it, uint32_t flags);
+#endif /* CBOR_NO_VALIDATION_API */
+
+/* Human-readable (dump) API */
+#ifndef CBOR_NO_PRETTY_API
+
+enum CborPrettyFlags {
+ CborPrettyNumericEncodingIndicators = 0x01,
+ CborPrettyTextualEncodingIndicators = 0,
+
+ CborPrettyIndicateIndeterminateLength = 0x02,
+ CborPrettyIndicateIndetermineLength = CborPrettyIndicateIndeterminateLength, /* deprecated */
+ CborPrettyIndicateOverlongNumbers = 0x04,
+
+ CborPrettyShowStringFragments = 0x100,
+ CborPrettyMergeStringFragments = 0,
+
+ CborPrettyDefaultFlags = CborPrettyIndicateIndeterminateLength
+};
+
+typedef CborError (*CborStreamFunction)(void *token, const char *fmt, ...)
+#ifdef __GNUC__
+ __attribute__((__format__(printf, 2, 3)))
+#endif
+;
+
+CBOR_API CborError cbor_value_to_pretty_stream(CborStreamFunction streamFunction, void *token, CborValue *value, int flags);
+
+/* The following API requires a hosted C implementation (uses FILE*) */
+#if !defined(__STDC_HOSTED__) || __STDC_HOSTED__-0 == 1
+CBOR_API CborError cbor_value_to_pretty_advance_flags(FILE *out, CborValue *value, int flags);
+CBOR_API CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value);
+CBOR_INLINE_API CborError cbor_value_to_pretty(FILE *out, const CborValue *value)
+{
+ CborValue copy = *value;
+ return cbor_value_to_pretty_advance_flags(out, &copy, CborPrettyDefaultFlags);
+}
+#endif /* __STDC_HOSTED__ check */
+
+#endif /* CBOR_NO_PRETTY_API */
+
+#endif /* CBOR_NO_PARSER_API */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CBOR_H */
+
diff --git a/src/3rdparty/tinycbor/src/cborencoder.c b/src/3rdparty/tinycbor/src/cborencoder.c
new file mode 100644
index 0000000000..52a4025be1
--- /dev/null
+++ b/src/3rdparty/tinycbor/src/cborencoder.c
@@ -0,0 +1,677 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE 1
+#endif
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE 1
+#endif
+#ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+#endif
+
+#include "cbor.h"
+#include "cborinternal_p.h"
+#include "compilersupport_p.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * \defgroup CborEncoding Encoding to CBOR
+ * \brief Group of functions used to encode data to CBOR.
+ *
+ * CborEncoder is used to encode data into a CBOR stream. The outermost
+ * CborEncoder is initialized by calling cbor_encoder_init(), with the buffer
+ * where the CBOR stream will be stored. The outermost CborEncoder is usually
+ * used to encode exactly one item, most often an array or map. It is possible
+ * to encode more than one item, but care must then be taken on the decoder
+ * side to ensure the state is reset after each item was decoded.
+ *
+ * Nested CborEncoder objects are created using cbor_encoder_create_array() and
+ * cbor_encoder_create_map(), later closed with cbor_encoder_close_container()
+ * or cbor_encoder_close_container_checked(). The pairs of creation and closing
+ * must be exactly matched and their parameters are always the same.
+ *
+ * CborEncoder writes directly to the user-supplied buffer, without extra
+ * buffering. CborEncoder does not allocate memory and CborEncoder objects are
+ * usually created on the stack of the encoding functions.
+ *
+ * The example below initializes a CborEncoder object with a buffer and encodes
+ * a single integer.
+ *
+ * \code
+ * uint8_t buf[16];
+ * CborEncoder encoder;
+ * cbor_encoder_init(&encoder, &buf, sizeof(buf), 0);
+ * cbor_encode_int(&encoder, some_value);
+ * \endcode
+ *
+ * As explained before, usually the outermost CborEncoder object is used to add
+ * one array or map, which in turn contains multiple elements. The example
+ * below creates a CBOR map with one element: a key "foo" and a boolean value.
+ *
+ * \code
+ * uint8_t buf[16];
+ * CborEncoder encoder, mapEncoder;
+ * cbor_encoder_init(&encoder, &buf, sizeof(buf), 0);
+ * cbor_encoder_create_map(&encoder, &mapEncoder, 1);
+ * cbor_encode_text_stringz(&mapEncoder, "foo");
+ * cbor_encode_boolean(&mapEncoder, some_value);
+ * cbor_encoder_close_container(&encoder, &mapEncoder);
+ * \endcode
+ *
+ * <h3 class="groupheader">Error checking and buffer size</h3>
+ *
+ * All functions operating on CborEncoder return a condition of type CborError.
+ * If the encoding was successful, they return CborNoError. Some functions do
+ * extra checking on the input provided and may return some other error
+ * conditions (for example, cbor_encode_simple_value() checks that the type is
+ * of the correct type).
+ *
+ * In addition, all functions check whether the buffer has enough bytes to
+ * encode the item being appended. If that is not possible, they return
+ * CborErrorOutOfMemory.
+ *
+ * It is possible to continue with the encoding of data past the first function
+ * that returns CborErrorOutOfMemory. CborEncoder functions will not overrun
+ * the buffer, but will instead count how many more bytes are needed to
+ * complete the encoding. At the end, you can obtain that count by calling
+ * cbor_encoder_get_extra_bytes_needed().
+ *
+ * \section1 Finalizing the encoding
+ *
+ * Once all items have been appended and the containers have all been properly
+ * closed, the user-supplied buffer will contain the CBOR stream and may be
+ * immediately used. To obtain the size of the buffer, call
+ * cbor_encoder_get_buffer_size() with the original buffer pointer.
+ *
+ * The example below illustrates how one can encode an item with error checking
+ * and then pass on the buffer for network sending.
+ *
+ * \code
+ * uint8_t buf[16];
+ * CborError err;
+ * CborEncoder encoder, mapEncoder;
+ * cbor_encoder_init(&encoder, &buf, sizeof(buf), 0);
+ * err = cbor_encoder_create_map(&encoder, &mapEncoder, 1);
+ * if (!err)
+ * return err;
+ * err = cbor_encode_text_stringz(&mapEncoder, "foo");
+ * if (!err)
+ * return err;
+ * err = cbor_encode_boolean(&mapEncoder, some_value);
+ * if (!err)
+ * return err;
+ * err = cbor_encoder_close_container_checked(&encoder, &mapEncoder);
+ * if (!err)
+ * return err;
+ *
+ * size_t len = cbor_encoder_get_buffer_size(&encoder, buf);
+ * send_payload(buf, len);
+ * return CborNoError;
+ * \endcode
+ *
+ * Finally, the example below expands on the one above and also
+ * deals with dynamically growing the buffer if the initial allocation wasn't
+ * big enough. Note the two places where the error checking was replaced with
+ * an cbor_assertion, showing where the author assumes no error can occur.
+ *
+ * \code
+ * uint8_t *encode_string_array(const char **strings, int n, size_t *bufsize)
+ * {
+ * CborError err;
+ * CborEncoder encoder, arrayEncoder;
+ * size_t size = 256;
+ * uint8_t *buf = NULL;
+ *
+ * while (1) {
+ * int i;
+ * size_t more_bytes;
+ * uint8_t *nbuf = realloc(buf, size);
+ * if (nbuf == NULL)
+ * goto error;
+ * buf = nbuf;
+ *
+ * cbor_encoder_init(&encoder, &buf, size, 0);
+ * err = cbor_encoder_create_array(&encoder, &arrayEncoder, n);
+ * cbor_assert(err); // can't fail, the buffer is always big enough
+ *
+ * for (i = 0; i < n; ++i) {
+ * err = cbor_encode_text_stringz(&arrayEncoder, strings[i]);
+ * if (err && err != CborErrorOutOfMemory)
+ * goto error;
+ * }
+ *
+ * err = cbor_encoder_close_container_checked(&encoder, &arrayEncoder);
+ * cbor_assert(err); // shouldn't fail!
+ *
+ * more_bytes = cbor_encoder_get_extra_bytes_needed(encoder);
+ * if (more_size) {
+ * // buffer wasn't big enough, try again
+ * size += more_bytes;
+ * continue;
+ * }
+ *
+ * *bufsize = cbor_encoder_get_buffer_size(encoder, buf);
+ * return buf;
+ * }
+ * error:
+ * free(buf);
+ * return NULL;
+ * }
+ * \endcode
+ */
+
+/**
+ * \addtogroup CborEncoding
+ * @{
+ */
+
+/**
+ * \struct CborEncoder
+ * Structure used to encode to CBOR.
+ */
+
+/**
+ * Initializes a CborEncoder structure \a encoder by pointing it to buffer \a
+ * buffer of size \a size. The \a flags field is currently unused and must be
+ * zero.
+ */
+void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags)
+{
+ encoder->data.ptr = buffer;
+ encoder->end = buffer + size;
+ encoder->remaining = 2;
+ encoder->flags = flags;
+}
+
+void cbor_encoder_init_writer(CborEncoder *encoder, CborEncoderWriteFunction writer, void *token)
+{
+#ifdef CBOR_ENCODER_WRITE_FUNCTION
+ (void) writer;
+#else
+ encoder->data.writer = writer;
+#endif
+ encoder->end = (uint8_t *)token;
+ encoder->remaining = 2;
+ encoder->flags = CborIteratorFlag_WriterFunction;
+}
+
+static inline void put16(void *where, uint16_t v)
+{
+ v = cbor_htons(v);
+ memcpy(where, &v, sizeof(v));
+}
+
+/* Note: Since this is currently only used in situations where OOM is the only
+ * valid error, we KNOW this to be true. Thus, this function now returns just 'true',
+ * but if in the future, any function starts returning a non-OOM error, this will need
+ * to be changed to the test. At the moment, this is done to prevent more branches
+ * being created in the tinycbor output */
+static inline bool isOomError(CborError err)
+{
+ if (CBOR_ENCODER_WRITER_CONTROL < 0)
+ return true;
+
+ /* CborErrorOutOfMemory is the only negative error code, intentionally
+ * so we can write the test like this */
+ return (int)err < 0;
+}
+
+static inline void put32(void *where, uint32_t v)
+{
+ v = cbor_htonl(v);
+ memcpy(where, &v, sizeof(v));
+}
+
+static inline void put64(void *where, uint64_t v)
+{
+ v = cbor_htonll(v);
+ memcpy(where, &v, sizeof(v));
+}
+
+static inline bool would_overflow(CborEncoder *encoder, size_t len)
+{
+ ptrdiff_t remaining = (ptrdiff_t)encoder->end;
+ remaining -= remaining ? (ptrdiff_t)encoder->data.ptr : encoder->data.bytes_needed;
+ remaining -= (ptrdiff_t)len;
+ return unlikely(remaining < 0);
+}
+
+static inline void advance_ptr(CborEncoder *encoder, size_t n)
+{
+ if (encoder->end)
+ encoder->data.ptr += n;
+ else
+ encoder->data.bytes_needed += n;
+}
+
+static inline CborError append_to_buffer(CborEncoder *encoder, const void *data, size_t len,
+ CborEncoderAppendType appendType)
+{
+ if (CBOR_ENCODER_WRITER_CONTROL >= 0) {
+ if (encoder->flags & CborIteratorFlag_WriterFunction || CBOR_ENCODER_WRITER_CONTROL != 0) {
+# ifdef CBOR_ENCODER_WRITE_FUNCTION
+ return CBOR_ENCODER_WRITE_FUNCTION(encoder->end, data, len, appendType);
+# else
+ return encoder->data.writer(encoder->end, data, len, appendType);
+# endif
+ }
+ }
+
+#if CBOR_ENCODER_WRITER_CONTROL <= 0
+ if (would_overflow(encoder, len)) {
+ if (encoder->end != NULL) {
+ len -= encoder->end - encoder->data.ptr;
+ encoder->end = NULL;
+ encoder->data.bytes_needed = 0;
+ }
+
+ advance_ptr(encoder, len);
+ return CborErrorOutOfMemory;
+ }
+
+ memcpy(encoder->data.ptr, data, len);
+ encoder->data.ptr += len;
+#endif
+ return CborNoError;
+}
+
+static inline CborError append_byte_to_buffer(CborEncoder *encoder, uint8_t byte)
+{
+ return append_to_buffer(encoder, &byte, 1, CborEncoderAppendCborData);
+}
+
+static inline CborError encode_number_no_update(CborEncoder *encoder, uint64_t ui, uint8_t shiftedMajorType)
+{
+ /* Little-endian would have been so much more convenient here:
+ * We could just write at the beginning of buf but append_to_buffer
+ * only the necessary bytes.
+ * Since it has to be big endian, do it the other way around:
+ * write from the end. */
+ uint64_t buf[2];
+ uint8_t *const bufend = (uint8_t *)buf + sizeof(buf);
+ uint8_t *bufstart = bufend - 1;
+ put64(buf + 1, ui); /* we probably have a bunch of zeros in the beginning */
+
+ if (ui < Value8Bit) {
+ *bufstart += shiftedMajorType;
+ } else {
+ uint8_t more = 0;
+ if (ui > 0xffU)
+ ++more;
+ if (ui > 0xffffU)
+ ++more;
+ if (ui > 0xffffffffU)
+ ++more;
+ bufstart -= (size_t)1 << more;
+ *bufstart = shiftedMajorType + Value8Bit + more;
+ }
+
+ return append_to_buffer(encoder, bufstart, bufend - bufstart, CborEncoderAppendCborData);
+}
+
+static inline void saturated_decrement(CborEncoder *encoder)
+{
+ if (encoder->remaining)
+ --encoder->remaining;
+}
+
+static inline CborError encode_number(CborEncoder *encoder, uint64_t ui, uint8_t shiftedMajorType)
+{
+ saturated_decrement(encoder);
+ return encode_number_no_update(encoder, ui, shiftedMajorType);
+}
+
+/**
+ * Appends the unsigned 64-bit integer \a value to the CBOR stream provided by
+ * \a encoder.
+ *
+ * \sa cbor_encode_negative_int, cbor_encode_int
+ */
+CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value)
+{
+ return encode_number(encoder, value, UnsignedIntegerType << MajorTypeShift);
+}
+
+/**
+ * Appends the negative 64-bit integer whose absolute value is \a
+ * absolute_value to the CBOR stream provided by \a encoder.
+ *
+ * If the value \a absolute_value is zero, this function encodes -2^64.
+ *
+ * \sa cbor_encode_uint, cbor_encode_int
+ */
+CborError cbor_encode_negative_int(CborEncoder *encoder, uint64_t absolute_value)
+{
+ return encode_number(encoder, absolute_value - 1, NegativeIntegerType << MajorTypeShift);
+}
+
+/**
+ * Appends the signed 64-bit integer \a value to the CBOR stream provided by
+ * \a encoder.
+ *
+ * \sa cbor_encode_negative_int, cbor_encode_uint
+ */
+CborError cbor_encode_int(CborEncoder *encoder, int64_t value)
+{
+ /* adapted from code in RFC 7049 appendix C (pseudocode) */
+ uint64_t ui = value >> 63; /* extend sign to whole length */
+ uint8_t majorType = ui & 0x20; /* extract major type */
+ ui ^= value; /* complement negatives */
+ return encode_number(encoder, ui, majorType);
+}
+
+/**
+ * Appends the CBOR Simple Type of value \a value to the CBOR stream provided by
+ * \a encoder.
+ *
+ * This function may return error CborErrorIllegalSimpleType if the \a value
+ * variable contains a number that is not a valid simple type.
+ */
+CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value)
+{
+#ifndef CBOR_ENCODER_NO_CHECK_USER
+ /* check if this is a valid simple type */
+ if (value >= HalfPrecisionFloat && value <= Break)
+ return CborErrorIllegalSimpleType;
+#endif
+ return encode_number(encoder, value, SimpleTypesType << MajorTypeShift);
+}
+
+/**
+ * Appends the floating-point value of type \a fpType and pointed to by \a
+ * value to the CBOR stream provided by \a encoder. The value of \a fpType must
+ * be one of CborHalfFloatType, CborFloatType or CborDoubleType, otherwise the
+ * behavior of this function is undefined.
+ *
+ * This function is useful for code that needs to pass through floating point
+ * values but does not wish to have the actual floating-point code.
+ *
+ * \sa cbor_encode_half_float, cbor_encode_float, cbor_encode_double
+ */
+CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value)
+{
+ unsigned size;
+ uint8_t buf[1 + sizeof(uint64_t)];
+ cbor_assert(fpType == CborHalfFloatType || fpType == CborFloatType || fpType == CborDoubleType);
+ buf[0] = fpType;
+
+ size = 2U << (fpType - CborHalfFloatType);
+ if (size == 8)
+ put64(buf + 1, *(const uint64_t*)value);
+ else if (size == 4)
+ put32(buf + 1, *(const uint32_t*)value);
+ else
+ put16(buf + 1, *(const uint16_t*)value);
+ saturated_decrement(encoder);
+ return append_to_buffer(encoder, buf, size + 1, CborEncoderAppendCborData);
+}
+
+/**
+ * Appends the CBOR tag \a tag to the CBOR stream provided by \a encoder.
+ *
+ * \sa CborTag
+ */
+CborError cbor_encode_tag(CborEncoder *encoder, CborTag tag)
+{
+ /* tags don't count towards the number of elements in an array or map */
+ return encode_number_no_update(encoder, tag, TagType << MajorTypeShift);
+}
+
+static CborError encode_string(CborEncoder *encoder, size_t length, uint8_t shiftedMajorType, const void *string)
+{
+ CborError err = encode_number(encoder, length, shiftedMajorType);
+ if (err && !isOomError(err))
+ return err;
+ return append_to_buffer(encoder, string, length, CborEncoderAppendStringData);
+}
+
+/**
+ * \fn CborError cbor_encode_text_stringz(CborEncoder *encoder, const char *string)
+ *
+ * Appends the null-terminated text string \a string to the CBOR stream
+ * provided by \a encoder. CBOR requires that \a string be valid UTF-8, but
+ * TinyCBOR makes no verification of correctness. The terminating null is not
+ * included in the stream.
+ *
+ * \sa cbor_encode_text_string, cbor_encode_byte_string
+ */
+
+/**
+ * Appends the text string \a string of length \a length to the CBOR stream
+ * provided by \a encoder. CBOR requires that \a string be valid UTF-8, but
+ * TinyCBOR makes no verification of correctness.
+ *
+ * \sa CborError cbor_encode_text_stringz, cbor_encode_byte_string
+ */
+CborError cbor_encode_byte_string(CborEncoder *encoder, const uint8_t *string, size_t length)
+{
+ return encode_string(encoder, length, ByteStringType << MajorTypeShift, string);
+}
+
+/**
+ * Appends the byte string \a string of length \a length to the CBOR stream
+ * provided by \a encoder. CBOR byte strings are arbitrary raw data.
+ *
+ * \sa cbor_encode_text_stringz, cbor_encode_text_string
+ */
+CborError cbor_encode_text_string(CborEncoder *encoder, const char *string, size_t length)
+{
+ return encode_string(encoder, length, TextStringType << MajorTypeShift, string);
+}
+
+#ifdef __GNUC__
+__attribute__((noinline))
+#endif
+static CborError create_container(CborEncoder *encoder, CborEncoder *container, size_t length, uint8_t shiftedMajorType)
+{
+ CborError err;
+ container->data.ptr = encoder->data.ptr;
+ container->end = encoder->end;
+ saturated_decrement(encoder);
+ container->remaining = length + 1; /* overflow ok on CborIndefiniteLength */
+
+ cbor_static_assert((int)CborIteratorFlag_ContainerIsMap_ == (int)CborIteratorFlag_ContainerIsMap);
+ cbor_static_assert(((MapType << MajorTypeShift) & CborIteratorFlag_ContainerIsMap) == CborIteratorFlag_ContainerIsMap);
+ cbor_static_assert(((ArrayType << MajorTypeShift) & CborIteratorFlag_ContainerIsMap) == 0);
+ container->flags = shiftedMajorType & CborIteratorFlag_ContainerIsMap;
+ if (CBOR_ENCODER_WRITER_CONTROL == 0)
+ container->flags |= encoder->flags & CborIteratorFlag_WriterFunction;
+
+ if (length == CborIndefiniteLength) {
+ container->flags |= CborIteratorFlag_UnknownLength;
+ err = append_byte_to_buffer(container, shiftedMajorType + IndefiniteLength);
+ } else {
+ if (shiftedMajorType & CborIteratorFlag_ContainerIsMap)
+ container->remaining += length;
+ err = encode_number_no_update(container, length, shiftedMajorType);
+ }
+ return err;
+}
+
+/**
+ * Creates a CBOR array in the CBOR stream provided by \a encoder and
+ * initializes \a arrayEncoder so that items can be added to the array using
+ * the CborEncoder functions. The array must be terminated by calling either
+ * cbor_encoder_close_container() or cbor_encoder_close_container_checked()
+ * with the same \a encoder and \a arrayEncoder parameters.
+ *
+ * The number of items inserted into the array must be exactly \a length items,
+ * otherwise the stream is invalid. If the number of items is not known when
+ * creating the array, the constant \ref CborIndefiniteLength may be passed as
+ * length instead.
+ *
+ * \sa cbor_encoder_create_map
+ */
+CborError cbor_encoder_create_array(CborEncoder *encoder, CborEncoder *arrayEncoder, size_t length)
+{
+ return create_container(encoder, arrayEncoder, length, ArrayType << MajorTypeShift);
+}
+
+/**
+ * Creates a CBOR map in the CBOR stream provided by \a encoder and
+ * initializes \a mapEncoder so that items can be added to the map using
+ * the CborEncoder functions. The map must be terminated by calling either
+ * cbor_encoder_close_container() or cbor_encoder_close_container_checked()
+ * with the same \a encoder and \a mapEncoder parameters.
+ *
+ * The number of pair of items inserted into the map must be exactly \a length
+ * items, otherwise the stream is invalid. If the number is not known
+ * when creating the map, the constant \ref CborIndefiniteLength may be passed as
+ * length instead.
+ *
+ * \b{Implementation limitation:} TinyCBOR cannot encode more than SIZE_MAX/2
+ * key-value pairs in the stream. If the length \a length is larger than this
+ * value (and is not \ref CborIndefiniteLength), this function returns error
+ * CborErrorDataTooLarge.
+ *
+ * \sa cbor_encoder_create_array
+ */
+CborError cbor_encoder_create_map(CborEncoder *encoder, CborEncoder *mapEncoder, size_t length)
+{
+ if (length != CborIndefiniteLength && length > SIZE_MAX / 2)
+ return CborErrorDataTooLarge;
+ return create_container(encoder, mapEncoder, length, MapType << MajorTypeShift);
+}
+
+/**
+ * Closes the CBOR container (array or map) provided by \a containerEncoder and
+ * updates the CBOR stream provided by \a encoder. Both parameters must be the
+ * same as were passed to cbor_encoder_create_array() or
+ * cbor_encoder_create_map().
+ *
+ * Since version 0.5, this function verifies that the number of items (or pairs
+ * of items, in the case of a map) was correct. It is no longer necessary to call
+ * cbor_encoder_close_container_checked() instead.
+ *
+ * \sa cbor_encoder_create_array(), cbor_encoder_create_map()
+ */
+CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *containerEncoder)
+{
+ if (encoder->end && !(encoder->flags & CborIteratorFlag_WriterFunction))
+ encoder->data.ptr = containerEncoder->data.ptr;
+ else
+ encoder->data.bytes_needed = containerEncoder->data.bytes_needed;
+ encoder->end = containerEncoder->end;
+ if (containerEncoder->flags & CborIteratorFlag_UnknownLength)
+ return append_byte_to_buffer(encoder, BreakByte);
+
+ if (containerEncoder->remaining != 1)
+ return containerEncoder->remaining == 0 ? CborErrorTooManyItems : CborErrorTooFewItems;
+
+ if (!encoder->end)
+ return CborErrorOutOfMemory; /* keep the state */
+ return CborNoError;
+}
+
+/**
+ * \fn CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
+ *
+ * Appends the boolean value \a value to the CBOR stream provided by \a encoder.
+ */
+
+/**
+ * \fn CborError cbor_encode_null(CborEncoder *encoder)
+ *
+ * Appends the CBOR type representing a null value to the CBOR stream provided
+ * by \a encoder.
+ *
+ * \sa cbor_encode_undefined()
+ */
+
+/**
+ * \fn CborError cbor_encode_undefined(CborEncoder *encoder)
+ *
+ * Appends the CBOR type representing an undefined value to the CBOR stream
+ * provided by \a encoder.
+ *
+ * \sa cbor_encode_null()
+ */
+
+/**
+ * \fn CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
+ *
+ * Appends the IEEE 754 half-precision (16-bit) floating point value pointed to
+ * by \a value to the CBOR stream provided by \a encoder.
+ *
+ * \sa cbor_encode_floating_point(), cbor_encode_float(), cbor_encode_double()
+ */
+
+/**
+ * \fn CborError cbor_encode_float(CborEncoder *encoder, float value)
+ *
+ * Appends the IEEE 754 single-precision (32-bit) floating point value \a value
+ * to the CBOR stream provided by \a encoder.
+ *
+ * \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_double()
+ */
+
+/**
+ * \fn CborError cbor_encode_double(CborEncoder *encoder, double value)
+ *
+ * Appends the IEEE 754 double-precision (64-bit) floating point value \a value
+ * to the CBOR stream provided by \a encoder.
+ *
+ * \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_float()
+ */
+
+/**
+ * \fn size_t cbor_encoder_get_buffer_size(const CborEncoder *encoder, const uint8_t *buffer)
+ *
+ * Returns the total size of the buffer starting at \a buffer after the
+ * encoding finished without errors. The \a encoder and \a buffer arguments
+ * must be the same as supplied to cbor_encoder_init().
+ *
+ * If the encoding process had errors, the return value of this function is
+ * meaningless. If the only errors were CborErrorOutOfMemory, instead use
+ * cbor_encoder_get_extra_bytes_needed() to find out by how much to grow the
+ * buffer before encoding again.
+ *
+ * See \ref CborEncoding for an example of using this function.
+ *
+ * \sa cbor_encoder_init(), cbor_encoder_get_extra_bytes_needed(), CborEncoding
+ */
+
+/**
+ * \fn size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *encoder)
+ *
+ * Returns how many more bytes the original buffer supplied to
+ * cbor_encoder_init() needs to be extended by so that no CborErrorOutOfMemory
+ * condition will happen for the encoding. If the buffer was big enough, this
+ * function returns 0. The \a encoder must be the original argument as passed
+ * to cbor_encoder_init().
+ *
+ * This function is usually called after an encoding sequence ended with one or
+ * more CborErrorOutOfMemory errors, but no other error. If any other error
+ * happened, the return value of this function is meaningless.
+ *
+ * See \ref CborEncoding for an example of using this function.
+ *
+ * \sa cbor_encoder_init(), cbor_encoder_get_buffer_size(), CborEncoding
+ */
+
+/** @} */
diff --git a/src/3rdparty/tinycbor/src/cborerrorstrings.c b/src/3rdparty/tinycbor/src/cborerrorstrings.c
new file mode 100644
index 0000000000..1dd8ae25bd
--- /dev/null
+++ b/src/3rdparty/tinycbor/src/cborerrorstrings.c
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#include "cbor.h"
+
+#ifndef _
+# define _(msg) msg
+#endif
+
+/**
+ * \enum CborError
+ * \ingroup CborGlobals
+ * The CborError enum contains the possible error values used by the CBOR encoder and decoder.
+ *
+ * TinyCBOR functions report success by returning CborNoError, or one error
+ * condition by returning one of the values below. One exception is the
+ * out-of-memory condition (CborErrorOutOfMemory), which the functions for \ref
+ * CborEncoding may report in bit-wise OR with other conditions.
+ *
+ * This technique allows code to determine whether the only error condition was
+ * a lack of buffer space, which may not be a fatal condition if the buffer can
+ * be resized. Additionally, the functions for \ref CborEncoding may continue
+ * to be used even after CborErrorOutOfMemory is returned, and instead they
+ * will simply calculate the extra space needed.
+ *
+ * \value CborNoError No error occurred
+ * \omitvalue CborUnknownError
+ * \value CborErrorUnknownLength Request for the length of an array, map or string whose length is not provided in the CBOR stream
+ * \value CborErrorAdvancePastEOF Not enough data in the stream to decode item (decoding would advance past end of stream)
+ * \value CborErrorIO An I/O error occurred, probably due to an out-of-memory situation
+ * \value CborErrorGarbageAtEnd Bytes exist past the end of the CBOR stream
+ * \value CborErrorUnexpectedEOF End of stream reached unexpectedly
+ * \value CborErrorUnexpectedBreak A CBOR break byte was found where not expected
+ * \value CborErrorUnknownType An unknown type (future extension to CBOR) was found in the stream
+ * \value CborErrorIllegalType An invalid type was found while parsing a chunked CBOR string
+ * \value CborErrorIllegalNumber An illegal initial byte (encoding unspecified additional information) was found
+ * \value CborErrorIllegalSimpleType An illegal encoding of a CBOR Simple Type of value less than 32 was found
+ * \omitvalue CborErrorUnknownSimpleType
+ * \omitvalue CborErrorUnknownTag
+ * \omitvalue CborErrorInappropriateTagForType
+ * \omitvalue CborErrorDuplicateObjectKeys
+ * \value CborErrorInvalidUtf8TextString Illegal UTF-8 encoding found while parsing CBOR Text String
+ * \value CborErrorTooManyItems Too many items were added to CBOR map or array of pre-determined length
+ * \value CborErrorTooFewItems Too few items were added to CBOR map or array of pre-determined length
+ * \value CborErrorDataTooLarge Data item size exceeds TinyCBOR's implementation limits
+ * \value CborErrorNestingTooDeep Data item nesting exceeds TinyCBOR's implementation limits
+ * \omitvalue CborErrorUnsupportedType
+ * \value CborErrorJsonObjectKeyIsAggregate Conversion to JSON failed because the key in a map is a CBOR map or array
+ * \value CborErrorJsonObjectKeyNotString Conversion to JSON failed because the key in a map is not a text string
+ * \value CborErrorOutOfMemory During CBOR encoding, the buffer provided is insufficient for encoding the data item;
+ * in other situations, TinyCBOR failed to allocate memory
+ * \value CborErrorInternalError An internal error occurred in TinyCBOR
+ */
+
+/**
+ * \ingroup CborGlobals
+ * Returns the error string corresponding to the CBOR error condition \a error.
+ */
+const char *cbor_error_string(CborError error)
+{
+ switch (error) {
+ case CborNoError:
+ return "";
+
+ case CborUnknownError:
+ return _("unknown error");
+
+ case CborErrorOutOfMemory:
+ return _("out of memory/need more memory");
+
+ case CborErrorUnknownLength:
+ return _("unknown length (attempted to get the length of a map/array/string of indeterminate length");
+
+ case CborErrorAdvancePastEOF:
+ return _("attempted to advance past EOF");
+
+ case CborErrorIO:
+ return _("I/O error");
+
+ case CborErrorGarbageAtEnd:
+ return _("garbage after the end of the content");
+
+ case CborErrorUnexpectedEOF:
+ return _("unexpected end of data");
+
+ case CborErrorUnexpectedBreak:
+ return _("unexpected 'break' byte");
+
+ case CborErrorUnknownType:
+ return _("illegal byte (encodes future extension type)");
+
+ case CborErrorIllegalType:
+ return _("mismatched string type in chunked string");
+
+ case CborErrorIllegalNumber:
+ return _("illegal initial byte (encodes unspecified additional information)");
+
+ case CborErrorIllegalSimpleType:
+ return _("illegal encoding of simple type smaller than 32");
+
+ case CborErrorNoMoreStringChunks:
+ return _("no more byte or text strings available");
+
+ case CborErrorUnknownSimpleType:
+ return _("unknown simple type");
+
+ case CborErrorUnknownTag:
+ return _("unknown tag");
+
+ case CborErrorInappropriateTagForType:
+ return _("inappropriate tag for type");
+
+ case CborErrorDuplicateObjectKeys:
+ return _("duplicate keys in object");
+
+ case CborErrorInvalidUtf8TextString:
+ return _("invalid UTF-8 content in string");
+
+ case CborErrorExcludedType:
+ return _("excluded type found");
+
+ case CborErrorExcludedValue:
+ return _("excluded value found");
+
+ case CborErrorImproperValue:
+ case CborErrorOverlongEncoding:
+ return _("value encoded in non-canonical form");
+
+ case CborErrorMapKeyNotString:
+ case CborErrorJsonObjectKeyNotString:
+ return _("key in map is not a string");
+
+ case CborErrorMapNotSorted:
+ return _("map is not sorted");
+
+ case CborErrorMapKeysNotUnique:
+ return _("map keys are not unique");
+
+ case CborErrorTooManyItems:
+ return _("too many items added to encoder");
+
+ case CborErrorTooFewItems:
+ return _("too few items added to encoder");
+
+ case CborErrorDataTooLarge:
+ return _("internal error: data too large");
+
+ case CborErrorNestingTooDeep:
+ return _("internal error: too many nested containers found in recursive function");
+
+ case CborErrorUnsupportedType:
+ return _("unsupported type");
+
+ case CborErrorUnimplementedValidation:
+ return _("validation not implemented for the current parser state");
+
+ case CborErrorJsonObjectKeyIsAggregate:
+ return _("conversion to JSON failed: key in object is an array or map");
+
+ case CborErrorJsonNotImplemented:
+ return _("conversion to JSON failed: open_memstream unavailable");
+
+ case CborErrorInternalError:
+ return _("internal error");
+ }
+ return cbor_error_string(CborUnknownError);
+}
diff --git a/src/3rdparty/tinycbor/src/cborinternal_p.h b/src/3rdparty/tinycbor/src/cborinternal_p.h
new file mode 100644
index 0000000000..c5fe63003f
--- /dev/null
+++ b/src/3rdparty/tinycbor/src/cborinternal_p.h
@@ -0,0 +1,314 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef CBORINTERNAL_P_H
+#define CBORINTERNAL_P_H
+
+#include "compilersupport_p.h"
+
+#ifndef CBOR_NO_FLOATING_POINT
+# include <float.h>
+# include <math.h>
+#else
+# ifndef CBOR_NO_HALF_FLOAT_TYPE
+# define CBOR_NO_HALF_FLOAT_TYPE 1
+# endif
+#endif
+
+#ifndef CBOR_NO_HALF_FLOAT_TYPE
+# ifdef __F16C__
+# include <immintrin.h>
+static inline unsigned short encode_half(double val)
+{
+ return _cvtss_sh((float)val, 3);
+}
+static inline double decode_half(unsigned short half)
+{
+ return _cvtsh_ss(half);
+}
+# else
+/* software implementation of float-to-fp16 conversions */
+static inline unsigned short encode_half(double val)
+{
+ uint64_t v;
+ int sign, exp, mant;
+ memcpy(&v, &val, sizeof(v));
+ sign = v >> 63 << 15;
+ exp = (v >> 52) & 0x7ff;
+ mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */
+ exp -= 1023;
+ if (exp == 1024) {
+ /* infinity or NaN */
+ exp = 16;
+ mant >>= 1;
+ } else if (exp >= 16) {
+ /* overflow, as largest number */
+ exp = 15;
+ mant = 1023;
+ } else if (exp >= -14) {
+ /* regular normal */
+ } else if (exp >= -24) {
+ /* subnormal */
+ mant |= 1024;
+ mant >>= -(exp + 14);
+ exp = -15;
+ } else {
+ /* underflow, make zero */
+ return 0;
+ }
+
+ /* safe cast here as bit operations above guarantee not to overflow */
+ return (unsigned short)(sign | ((exp + 15) << 10) | mant);
+}
+
+/* this function was copied & adapted from RFC 7049 Appendix D */
+static inline double decode_half(unsigned short half)
+{
+ int exp = (half >> 10) & 0x1f;
+ int mant = half & 0x3ff;
+ double val;
+ if (exp == 0) val = ldexp(mant, -24);
+ else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
+ else val = mant == 0 ? INFINITY : NAN;
+ return half & 0x8000 ? -val : val;
+}
+# endif
+#endif /* CBOR_NO_HALF_FLOAT_TYPE */
+
+#ifndef CBOR_INTERNAL_API
+# define CBOR_INTERNAL_API
+#endif
+
+#ifndef CBOR_PARSER_MAX_RECURSIONS
+# define CBOR_PARSER_MAX_RECURSIONS 1024
+#endif
+
+#ifndef CBOR_ENCODER_WRITER_CONTROL
+# define CBOR_ENCODER_WRITER_CONTROL 0
+#endif
+#ifndef CBOR_PARSER_READER_CONTROL
+# define CBOR_PARSER_READER_CONTROL 0
+#endif
+
+/*
+ * CBOR Major types
+ * Encoded in the high 3 bits of the descriptor byte
+ * See http://tools.ietf.org/html/rfc7049#section-2.1
+ */
+typedef enum CborMajorTypes {
+ UnsignedIntegerType = 0U,
+ NegativeIntegerType = 1U,
+ ByteStringType = 2U,
+ TextStringType = 3U,
+ ArrayType = 4U,
+ MapType = 5U, /* a.k.a. object */
+ TagType = 6U,
+ SimpleTypesType = 7U
+} CborMajorTypes;
+
+/*
+ * CBOR simple and floating point types
+ * Encoded in the low 8 bits of the descriptor byte when the
+ * Major Type is 7.
+ */
+typedef enum CborSimpleTypes {
+ FalseValue = 20,
+ TrueValue = 21,
+ NullValue = 22,
+ UndefinedValue = 23,
+ SimpleTypeInNextByte = 24, /* not really a simple type */
+ HalfPrecisionFloat = 25, /* ditto */
+ SinglePrecisionFloat = 26, /* ditto */
+ DoublePrecisionFloat = 27, /* ditto */
+ Break = 31
+} CborSimpleTypes;
+
+enum {
+ SmallValueBitLength = 5U,
+ SmallValueMask = (1U << SmallValueBitLength) - 1, /* 31 */
+ Value8Bit = 24U,
+ Value16Bit = 25U,
+ Value32Bit = 26U,
+ Value64Bit = 27U,
+ IndefiniteLength = 31U,
+
+ MajorTypeShift = SmallValueBitLength,
+ MajorTypeMask = (int) (~0U << MajorTypeShift),
+
+ BreakByte = (unsigned)Break | (SimpleTypesType << MajorTypeShift)
+};
+
+static inline void copy_current_position(CborValue *dst, const CborValue *src)
+{
+ /* This "if" is here for pedantry only: the two branches should perform
+ * the same memory operation. */
+ if (src->parser->flags & CborParserFlag_ExternalSource)
+ dst->source.token = src->source.token;
+ else
+ dst->source.ptr = src->source.ptr;
+}
+
+static inline bool can_read_bytes(const CborValue *it, size_t n)
+{
+ if (CBOR_PARSER_READER_CONTROL >= 0) {
+ if (it->parser->flags & CborParserFlag_ExternalSource || CBOR_PARSER_READER_CONTROL != 0) {
+#ifdef CBOR_PARSER_CAN_READ_BYTES_FUNCTION
+ return CBOR_PARSER_CAN_READ_BYTES_FUNCTION(it->source.token, n);
+#else
+ return it->parser->source.ops->can_read_bytes(it->source.token, n);
+#endif
+ }
+ }
+
+ /* Convert the pointer subtraction to size_t since end >= ptr
+ * (this prevents issues with (ptrdiff_t)n becoming negative).
+ */
+ return (size_t)(it->parser->source.end - it->source.ptr) >= n;
+}
+
+static inline void advance_bytes(CborValue *it, size_t n)
+{
+ if (CBOR_PARSER_READER_CONTROL >= 0) {
+ if (it->parser->flags & CborParserFlag_ExternalSource || CBOR_PARSER_READER_CONTROL != 0) {
+#ifdef CBOR_PARSER_ADVANCE_BYTES_FUNCTION
+ CBOR_PARSER_ADVANCE_BYTES_FUNCTION(it->source.token, n);
+#else
+ it->parser->source.ops->advance_bytes(it->source.token, n);
+#endif
+ return;
+ }
+ }
+
+ it->source.ptr += n;
+}
+
+static inline CborError transfer_string(CborValue *it, const void **ptr, size_t offset, size_t len)
+{
+ if (CBOR_PARSER_READER_CONTROL >= 0) {
+ if (it->parser->flags & CborParserFlag_ExternalSource || CBOR_PARSER_READER_CONTROL != 0) {
+#ifdef CBOR_PARSER_TRANSFER_STRING_FUNCTION
+ return CBOR_PARSER_TRANSFER_STRING_FUNCTION(it->source.token, ptr, offset, len);
+#else
+ return it->parser->source.ops->transfer_string(it->source.token, ptr, offset, len);
+#endif
+ }
+ }
+
+ it->source.ptr += offset;
+ if (can_read_bytes(it, len)) {
+ *CONST_CAST(const void **, ptr) = it->source.ptr;
+ it->source.ptr += len;
+ return CborNoError;
+ }
+ return CborErrorUnexpectedEOF;
+}
+
+static inline void *read_bytes_unchecked(const CborValue *it, void *dst, size_t offset, size_t n)
+{
+ if (CBOR_PARSER_READER_CONTROL >= 0) {
+ if (it->parser->flags & CborParserFlag_ExternalSource || CBOR_PARSER_READER_CONTROL != 0) {
+#ifdef CBOR_PARSER_READ_BYTES_FUNCTION
+ return CBOR_PARSER_READ_BYTES_FUNCTION(it->source.token, dst, offset, n);
+#else
+ return it->parser->source.ops->read_bytes(it->source.token, dst, offset, n);
+#endif
+ }
+ }
+
+ return memcpy(dst, it->source.ptr + offset, n);
+}
+
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+#endif
+static inline void *read_bytes(const CborValue *it, void *dst, size_t offset, size_t n)
+{
+ if (can_read_bytes(it, offset + n))
+ return read_bytes_unchecked(it, dst, offset, n);
+ return NULL;
+}
+
+static inline uint16_t read_uint8(const CborValue *it, size_t offset)
+{
+ uint8_t result;
+ read_bytes_unchecked(it, &result, offset, sizeof(result));
+ return result;
+}
+
+static inline uint16_t read_uint16(const CborValue *it, size_t offset)
+{
+ uint16_t result;
+ read_bytes_unchecked(it, &result, offset, sizeof(result));
+ return cbor_ntohs(result);
+}
+
+static inline uint32_t read_uint32(const CborValue *it, size_t offset)
+{
+ uint32_t result;
+ read_bytes_unchecked(it, &result, offset, sizeof(result));
+ return cbor_ntohl(result);
+}
+
+static inline uint64_t read_uint64(const CborValue *it, size_t offset)
+{
+ uint64_t result;
+ read_bytes_unchecked(it, &result, offset, sizeof(result));
+ return cbor_ntohll(result);
+}
+
+static inline CborError extract_number_checked(const CborValue *it, uint64_t *value, size_t *bytesUsed)
+{
+ uint8_t descriptor;
+ size_t bytesNeeded = 0;
+
+ /* We've already verified that there's at least one byte to be read */
+ read_bytes_unchecked(it, &descriptor, 0, 1);
+ descriptor &= SmallValueMask;
+ if (descriptor < Value8Bit) {
+ *value = descriptor;
+ } else if (unlikely(descriptor > Value64Bit)) {
+ return CborErrorIllegalNumber;
+ } else {
+ bytesNeeded = (size_t)(1 << (descriptor - Value8Bit));
+ if (!can_read_bytes(it, 1 + bytesNeeded))
+ return CborErrorUnexpectedEOF;
+ if (descriptor <= Value16Bit) {
+ if (descriptor == Value16Bit)
+ *value = read_uint16(it, 1);
+ else
+ *value = read_uint8(it, 1);
+ } else {
+ if (descriptor == Value32Bit)
+ *value = read_uint32(it, 1);
+ else
+ *value = read_uint64(it, 1);
+ }
+ }
+
+ if (bytesUsed)
+ *bytesUsed = bytesNeeded;
+ return CborNoError;
+}
+
+#endif /* CBORINTERNAL_P_H */
diff --git a/src/3rdparty/tinycbor/src/cborjson.h b/src/3rdparty/tinycbor/src/cborjson.h
new file mode 100644
index 0000000000..8ff27b9202
--- /dev/null
+++ b/src/3rdparty/tinycbor/src/cborjson.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef CBORJSON_H
+#define CBORJSON_H
+
+#include "cbor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Conversion to JSON */
+enum CborToJsonFlags
+{
+ CborConvertAddMetadata = 1,
+ CborConvertTagsToObjects = 2,
+ CborConvertIgnoreTags = 0,
+
+ CborConvertObeyByteStringTags = 0,
+ CborConvertByteStringsToBase64Url = 4,
+
+ CborConvertRequireMapStringKeys = 0,
+ CborConvertStringifyMapKeys = 8,
+
+ CborConvertDefaultFlags = 0
+};
+
+CBOR_API CborError cbor_value_to_json_advance(FILE *out, CborValue *value, int flags);
+CBOR_INLINE_API CborError cbor_value_to_json(FILE *out, const CborValue *value, int flags)
+{
+ CborValue copy = *value;
+ return cbor_value_to_json_advance(out, &copy, flags);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CBORJSON_H */
+
diff --git a/src/3rdparty/tinycbor/src/cborparser.c b/src/3rdparty/tinycbor/src/cborparser.c
new file mode 100644
index 0000000000..971230ea61
--- /dev/null
+++ b/src/3rdparty/tinycbor/src/cborparser.c
@@ -0,0 +1,1526 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE 1
+#endif
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE 1
+#endif
+#ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+#endif
+
+#include "cbor.h"
+#include "cborinternal_p.h"
+#include "compilersupport_p.h"
+
+#include <string.h>
+
+/**
+ * \defgroup CborParsing Parsing CBOR streams
+ * \brief Group of functions used to parse CBOR streams.
+ *
+ * TinyCBOR provides functions for pull-based stream parsing of a CBOR-encoded
+ * payload. The main data type for the parsing is a CborValue, which behaves
+ * like an iterator and can be used to extract the encoded data. It is first
+ * initialized with a call to cbor_parser_init() and is usually used to extract
+ * exactly one item, most often an array or map.
+ *
+ * Nested CborValue objects can be parsed using cbor_value_enter_container().
+ * Each call to cbor_value_enter_container() must be matched by a call to
+ * cbor_value_leave_container(), with the exact same parameters.
+ *
+ * The example below initializes a CborParser object, begins the parsing with a
+ * CborValue and decodes a single integer:
+ *
+ * \code
+ * int extract_int(const uint8_t *buffer, size_t len)
+ * {
+ * CborParser parser;
+ * CborValue value;
+ * int result;
+ * cbor_parser_init(buffer, len, 0, &parser, &value);
+ * cbor_value_get_int(&value, &result);
+ * return result;
+ * }
+ * \endcode
+ *
+ * The code above does no error checking, which means it assumes the data comes
+ * from a source trusted to send one properly-encoded integer. The following
+ * example does the exact same operation, but includes error checking and
+ * returns 0 on parsing failure:
+ *
+ * \code
+ * int extract_int(const uint8_t *buffer, size_t len)
+ * {
+ * CborParser parser;
+ * CborValue value;
+ * int result;
+ * if (cbor_parser_init(buffer, len, 0, &parser, &value) != CborNoError)
+ * return 0;
+ * if (!cbor_value_is_integer(&value) ||
+ * cbor_value_get_int(&value, &result) != CborNoError)
+ * return 0;
+ * return result;
+ * }
+ * \endcode
+ *
+ * Note, in the example above, that one can't distinguish a parsing failure
+ * from an encoded value of zero. Reporting a parsing error is left as an
+ * exercise to the reader.
+ *
+ * The code above does not execute a range-check either: it is possible that
+ * the value decoded from the CBOR stream encodes a number larger than what can
+ * be represented in a variable of type \c{int}. If detecting that case is
+ * important, the code should call cbor_value_get_int_checked() instead.
+ *
+ * <h3 class="groupheader">Memory and parsing constraints</h3>
+ *
+ * TinyCBOR is designed to run with little memory and with minimal overhead.
+ * Except where otherwise noted, the parser functions always run on constant
+ * time (O(1)), do not recurse and never allocate memory (thus, stack usage is
+ * bounded and is O(1)).
+ *
+ * <h3 class="groupheader">Error handling and preconditions</h3>
+ *
+ * All functions operating on a CborValue return a CborError condition, with
+ * CborNoError standing for the normal situation in which no parsing error
+ * occurred. All functions may return parsing errors in case the stream cannot
+ * be decoded properly, be it due to corrupted data or due to reaching the end
+ * of the input buffer.
+ *
+ * Error conditions must not be ignored. All decoder functions have undefined
+ * behavior if called after an error has been reported, and may crash.
+ *
+ * Some functions are also documented to have preconditions, like
+ * cbor_value_get_int() requiring that the input be an integral value.
+ * Violation of preconditions also results in undefined behavior and the
+ * program may crash.
+ */
+
+/**
+ * \addtogroup CborParsing
+ * @{
+ */
+
+/**
+ * \struct CborValue
+ *
+ * This type contains one value parsed from the CBOR stream. Each CborValue
+ * behaves as an iterator in a StAX-style parser.
+ *
+ * \if privatedocs
+ * Implementation details: the CborValue contains these fields:
+ * \list
+ * \li ptr: pointer to the actual data
+ * \li flags: flags from the decoder
+ * \li extra: partially decoded integer value (0, 1 or 2 bytes)
+ * \li remaining: remaining items in this collection after this item or UINT32_MAX if length is unknown
+ * \endlist
+ * \endif
+ */
+
+static uint64_t extract_number_and_advance(CborValue *it)
+{
+ /* This function is only called after we've verified that the number
+ * here is valid, so we can just use _cbor_value_extract_int64_helper. */
+ uint8_t descriptor;
+ uint64_t v = _cbor_value_extract_int64_helper(it);
+
+ read_bytes_unchecked(it, &descriptor, 0, 1);
+ descriptor &= SmallValueMask;
+
+ size_t bytesNeeded = descriptor < Value8Bit ? 0 : (1 << (descriptor - Value8Bit));
+ advance_bytes(it, bytesNeeded + 1);
+
+ return v;
+}
+
+static bool is_fixed_type(uint8_t type)
+{
+ return type != CborTextStringType && type != CborByteStringType && type != CborArrayType &&
+ type != CborMapType;
+}
+
+static CborError preparse_value(CborValue *it)
+{
+ enum {
+ /* flags to keep */
+ FlagsToKeep = CborIteratorFlag_ContainerIsMap | CborIteratorFlag_NextIsMapKey
+ };
+ uint8_t descriptor;
+
+ /* are we at the end? */
+ it->type = CborInvalidType;
+ it->flags &= FlagsToKeep;
+ if (!read_bytes(it, &descriptor, 0, 1))
+ return CborErrorUnexpectedEOF;
+
+ uint8_t type = descriptor & MajorTypeMask;
+ it->type = type;
+ it->extra = (descriptor &= SmallValueMask);
+
+ if (descriptor > Value64Bit) {
+ if (unlikely(descriptor != IndefiniteLength))
+ return type == CborSimpleType ? CborErrorUnknownType : CborErrorIllegalNumber;
+ if (likely(!is_fixed_type(type))) {
+ /* special case */
+ it->flags |= CborIteratorFlag_UnknownLength;
+ it->type = type;
+ return CborNoError;
+ }
+ return type == CborSimpleType ? CborErrorUnexpectedBreak : CborErrorIllegalNumber;
+ }
+
+ size_t bytesNeeded = descriptor < Value8Bit ? 0 : (1 << (descriptor - Value8Bit));
+
+ if (bytesNeeded) {
+ if (!can_read_bytes(it, bytesNeeded + 1))
+ return CborErrorUnexpectedEOF;
+
+ it->extra = 0;
+
+ /* read up to 16 bits into it->extra */
+ if (bytesNeeded <= 2) {
+ read_bytes_unchecked(it, &it->extra, 1, bytesNeeded);
+ if (bytesNeeded == 2)
+ it->extra = cbor_ntohs(it->extra);
+ } else {
+ cbor_static_assert(CborIteratorFlag_IntegerValueTooLarge == (Value32Bit & 3));
+ cbor_static_assert((CborIteratorFlag_IntegerValueIs64Bit |
+ CborIteratorFlag_IntegerValueTooLarge) == (Value64Bit & 3));
+ it->flags |= (descriptor & 3);
+ }
+ }
+
+ uint8_t majortype = type >> MajorTypeShift;
+ if (majortype == NegativeIntegerType) {
+ it->flags |= CborIteratorFlag_NegativeInteger;
+ it->type = CborIntegerType;
+ } else if (majortype == SimpleTypesType) {
+ switch (descriptor) {
+ case FalseValue:
+ it->extra = false;
+ it->type = CborBooleanType;
+ break;
+
+ case SinglePrecisionFloat:
+ case DoublePrecisionFloat:
+ it->flags |= CborIteratorFlag_IntegerValueTooLarge;
+ /* fall through */
+ case TrueValue:
+ case NullValue:
+ case UndefinedValue:
+ case HalfPrecisionFloat:
+ read_bytes_unchecked(it, &it->type, 0, 1);
+ break;
+
+ case SimpleTypeInNextByte:
+#ifndef CBOR_PARSER_NO_STRICT_CHECKS
+ if (unlikely(it->extra < 32)) {
+ it->type = CborInvalidType;
+ return CborErrorIllegalSimpleType;
+ }
+#endif
+ break;
+
+ case 28:
+ case 29:
+ case 30:
+ case Break:
+ cbor_assert(false); /* these conditions can't be reached */
+ return CborErrorUnexpectedBreak;
+ }
+ }
+
+ return CborNoError;
+}
+
+static CborError preparse_next_value_nodecrement(CborValue *it)
+{
+ uint8_t byte;
+ if (it->remaining == UINT32_MAX && read_bytes(it, &byte, 0, 1) && byte == (uint8_t)BreakByte) {
+ /* end of map or array */
+ if ((it->flags & CborIteratorFlag_ContainerIsMap && it->flags & CborIteratorFlag_NextIsMapKey)
+ || it->type == CborTagType) {
+ /* but we weren't expecting it! */
+ return CborErrorUnexpectedBreak;
+ }
+ it->type = CborInvalidType;
+ it->remaining = 0;
+ it->flags |= CborIteratorFlag_UnknownLength; /* leave_container must consume the Break */
+ return CborNoError;
+ }
+
+ return preparse_value(it);
+}
+
+static CborError preparse_next_value(CborValue *it)
+{
+ /* tags don't count towards item totals or whether we've successfully
+ * read a map's key or value */
+ bool itemCounts = it->type != CborTagType;
+
+ if (it->remaining != UINT32_MAX) {
+ if (itemCounts && --it->remaining == 0) {
+ it->type = CborInvalidType;
+ it->flags &= ~CborIteratorFlag_UnknownLength; /* no Break to consume */
+ return CborNoError;
+ }
+ }
+ if (itemCounts) {
+ /* toggle the flag indicating whether this was a map key */
+ it->flags ^= CborIteratorFlag_NextIsMapKey;
+ }
+ return preparse_next_value_nodecrement(it);
+}
+
+static CborError advance_internal(CborValue *it)
+{
+ uint64_t length = extract_number_and_advance(it);
+
+ if (it->type == CborByteStringType || it->type == CborTextStringType) {
+ cbor_assert(length == (size_t)length);
+ cbor_assert((it->flags & CborIteratorFlag_UnknownLength) == 0);
+ advance_bytes(it, length);
+ }
+
+ return preparse_next_value(it);
+}
+
+/** \internal
+ *
+ * Decodes the CBOR integer value when it is larger than the 16 bits available
+ * in value->extra. This function requires that value->flags have the
+ * CborIteratorFlag_IntegerValueTooLarge flag set.
+ *
+ * This function is also used to extract single- and double-precision floating
+ * point values (SinglePrecisionFloat == Value32Bit and DoublePrecisionFloat ==
+ * Value64Bit).
+ */
+uint64_t _cbor_value_decode_int64_internal(const CborValue *value)
+{
+ cbor_assert(value->flags & CborIteratorFlag_IntegerValueTooLarge ||
+ value->type == CborFloatType || value->type == CborDoubleType);
+ if (value->flags & CborIteratorFlag_IntegerValueIs64Bit)
+ return read_uint64(value, 1);
+
+ return read_uint32(value, 1);
+}
+
+/**
+ * Initializes the CBOR parser for parsing \a size bytes beginning at \a
+ * buffer. Parsing will use flags set in \a flags. The iterator to the first
+ * element is returned in \a it.
+ *
+ * The \a parser structure needs to remain valid throughout the decoding
+ * process. It is not thread-safe to share one CborParser among multiple
+ * threads iterating at the same time, but the object can be copied so multiple
+ * threads can iterate.
+ */
+CborError cbor_parser_init(const uint8_t *buffer, size_t size, uint32_t flags, CborParser *parser, CborValue *it)
+{
+ memset(parser, 0, sizeof(*parser));
+ parser->source.end = buffer + size;
+ parser->flags = (enum CborParserGlobalFlags)flags;
+ it->parser = parser;
+ it->source.ptr = buffer;
+ it->remaining = 1; /* there's one type altogether, usually an array or map */
+ it->flags = 0;
+ return preparse_value(it);
+}
+
+CborError cbor_parser_init_reader(const struct CborParserOperations *ops, CborParser *parser, CborValue *it, void *token)
+{
+ memset(parser, 0, sizeof(*parser));
+ parser->source.ops = ops;
+ parser->flags = CborParserFlag_ExternalSource;
+ it->parser = parser;
+ it->source.token = token;
+ it->remaining = 1;
+ return preparse_value(it);
+}
+
+/**
+ * \fn bool cbor_value_at_end(const CborValue *it)
+ *
+ * Returns true if \a it has reached the end of the iteration, usually when
+ * advancing after the last item in an array or map.
+ *
+ * In the case of the outermost CborValue object, this function returns true
+ * after decoding a single element. A pointer to the first byte of the
+ * remaining data (if any) can be obtained with cbor_value_get_next_byte().
+ *
+ * \sa cbor_value_advance(), cbor_value_is_valid(), cbor_value_get_next_byte()
+ */
+
+/**
+ * \fn const uint8_t *cbor_value_get_next_byte(const CborValue *it)
+ *
+ * Returns a pointer to the next byte that would be decoded if this CborValue
+ * object were advanced.
+ *
+ * This function is useful if cbor_value_at_end() returns true for the
+ * outermost CborValue: the pointer returned is the first byte of the data
+ * remaining in the buffer, if any. Code can decide whether to begin decoding a
+ * new CBOR data stream from this point, or parse some other data appended to
+ * the same buffer.
+ *
+ * This function may be used even after a parsing error. If that occurred,
+ * then this function returns a pointer to where the parsing error occurred.
+ * Note that the error recovery is not precise and the pointer may not indicate
+ * the exact byte containing bad data.
+ *
+ * This function makes sense only when using a linear buffer (that is, when the
+ * parser is initialize by cbor_parser_init()). If using an external source,
+ * this function may return garbage; instead, consult the external source itself
+ * to find out more details about the presence of more data.
+ *
+ * \sa cbor_value_at_end()
+ */
+
+CborError cbor_value_reparse(CborValue *it)
+{
+ if (it->flags & CborIteratorFlag_IteratingStringChunks)
+ return CborNoError;
+ return preparse_next_value_nodecrement(it);
+}
+
+/**
+ * \fn bool cbor_value_is_valid(const CborValue *it)
+ *
+ * Returns true if the iterator \a it contains a valid value. Invalid iterators
+ * happen when iteration reaches the end of a container (see \ref
+ * cbor_value_at_end()) or when a search function resulted in no matches.
+ *
+ * \sa cbor_value_advance(), cbor_value_at_end(), cbor_value_get_type()
+ */
+
+/**
+ * Performs a basic validation of the CBOR stream pointed by \a it and returns
+ * the error it found. If no error was found, it returns CborNoError and the
+ * application can iterate over the items with certainty that no other errors
+ * will appear during parsing.
+ *
+ * A basic validation checks for:
+ * \list
+ * \li absence of undefined additional information bytes;
+ * \li well-formedness of all numbers, lengths, and simple values;
+ * \li string contents match reported sizes;
+ * \li arrays and maps contain the number of elements they are reported to have;
+ * \endlist
+ *
+ * For further checks, see cbor_value_validate().
+ *
+ * This function has the same timing and memory requirements as
+ * cbor_value_advance().
+ *
+ * \sa cbor_value_validate(), cbor_value_advance()
+ */
+CborError cbor_value_validate_basic(const CborValue *it)
+{
+ CborValue value = *it;
+ return cbor_value_advance(&value);
+}
+
+/**
+ * Advances the CBOR value \a it by one fixed-size position. Fixed-size types
+ * are: integers, tags, simple types (including boolean, null and undefined
+ * values) and floating point types.
+ *
+ * If the type is not of fixed size, this function has undefined behavior. Code
+ * must be sure that the current type is one of the fixed-size types before
+ * calling this function. This function is provided because it can guarantee
+ * that it runs in constant time (O(1)).
+ *
+ * If the caller is not able to determine whether the type is fixed or not, code
+ * can use the cbor_value_advance() function instead.
+ *
+ * \sa cbor_value_at_end(), cbor_value_advance(), cbor_value_enter_container(), cbor_value_leave_container()
+ */
+CborError cbor_value_advance_fixed(CborValue *it)
+{
+ cbor_assert(it->type != CborInvalidType);
+ cbor_assert(is_fixed_type(it->type));
+ if (!it->remaining)
+ return CborErrorAdvancePastEOF;
+ return advance_internal(it);
+}
+
+static CborError advance_recursive(CborValue *it, int nestingLevel)
+{
+ CborError err;
+ CborValue recursed;
+
+ if (is_fixed_type(it->type))
+ return advance_internal(it);
+
+ if (!cbor_value_is_container(it)) {
+ size_t len = SIZE_MAX;
+ return _cbor_value_copy_string(it, NULL, &len, it);
+ }
+
+ /* map or array */
+ if (nestingLevel == 0)
+ return CborErrorNestingTooDeep;
+
+ err = cbor_value_enter_container(it, &recursed);
+ if (err)
+ return err;
+ while (!cbor_value_at_end(&recursed)) {
+ err = advance_recursive(&recursed, nestingLevel - 1);
+ if (err)
+ return err;
+ }
+ return cbor_value_leave_container(it, &recursed);
+}
+
+
+/**
+ * Advances the CBOR value \a it by one element, skipping over containers.
+ * Unlike cbor_value_advance_fixed(), this function can be called on a CBOR
+ * value of any type. However, if the type is a container (map or array) or a
+ * string with a chunked payload, this function will not run in constant time
+ * and will recurse into itself (it will run on O(n) time for the number of
+ * elements or chunks and will use O(n) memory for the number of nested
+ * containers).
+ *
+ * The number of recursions can be limited at compile time to avoid stack
+ * exhaustion in constrained systems.
+ *
+ * \sa cbor_value_at_end(), cbor_value_advance_fixed(), cbor_value_enter_container(), cbor_value_leave_container()
+ */
+CborError cbor_value_advance(CborValue *it)
+{
+ cbor_assert(it->type != CborInvalidType);
+ if (!it->remaining)
+ return CborErrorAdvancePastEOF;
+ return advance_recursive(it, CBOR_PARSER_MAX_RECURSIONS);
+}
+
+/**
+ * \fn bool cbor_value_is_tag(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR tag.
+ *
+ * \sa cbor_value_get_tag(), cbor_value_skip_tag()
+ */
+
+/**
+ * \fn CborError cbor_value_get_tag(const CborValue *value, CborTag *result)
+ *
+ * Retrieves the CBOR tag value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to a CBOR tag value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_tag is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_tag()
+ */
+
+/**
+ * Advances the CBOR value \a it until it no longer points to a tag. If \a it is
+ * already not pointing to a tag, then this function returns it unchanged.
+ *
+ * This function does not run in constant time: it will run on O(n) for n being
+ * the number of tags. It does use constant memory (O(1) memory requirements).
+ *
+ * \sa cbor_value_advance_fixed(), cbor_value_advance()
+ */
+CborError cbor_value_skip_tag(CborValue *it)
+{
+ while (cbor_value_is_tag(it)) {
+ CborError err = cbor_value_advance_fixed(it);
+ if (err)
+ return err;
+ }
+ return CborNoError;
+}
+
+/**
+ * \fn bool cbor_value_is_container(const CborValue *it)
+ *
+ * Returns true if the \a it value is a container and requires recursion in
+ * order to decode (maps and arrays), false otherwise.
+ */
+
+/**
+ * Creates a CborValue iterator pointing to the first element of the container
+ * represented by \a it and saves it in \a recursed. The \a it container object
+ * needs to be kept and passed again to cbor_value_leave_container() in order
+ * to continue iterating past this container.
+ *
+ * The \a it CborValue iterator must point to a container.
+ *
+ * \sa cbor_value_is_container(), cbor_value_leave_container(), cbor_value_advance()
+ */
+CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed)
+{
+ cbor_static_assert(CborIteratorFlag_ContainerIsMap == (CborMapType & ~CborArrayType));
+ cbor_assert(cbor_value_is_container(it));
+ *recursed = *it;
+
+ if (it->flags & CborIteratorFlag_UnknownLength) {
+ recursed->remaining = UINT32_MAX;
+ advance_bytes(recursed, 1);
+ } else {
+ uint64_t len = extract_number_and_advance(recursed);
+
+ recursed->remaining = (uint32_t)len;
+ if (recursed->remaining != len || len == UINT32_MAX) {
+ /* back track the pointer to indicate where the error occurred */
+ copy_current_position(recursed, it);
+ return CborErrorDataTooLarge;
+ }
+ if (recursed->type == CborMapType) {
+ /* maps have keys and values, so we need to multiply by 2 */
+ if (recursed->remaining > UINT32_MAX / 2) {
+ /* back track the pointer to indicate where the error occurred */
+ copy_current_position(recursed, it);
+ return CborErrorDataTooLarge;
+ }
+ recursed->remaining *= 2;
+ }
+ if (len == 0) {
+ /* the case of the empty container */
+ recursed->type = CborInvalidType;
+ return CborNoError;
+ }
+ }
+ recursed->flags = (recursed->type & CborIteratorFlag_ContainerIsMap);
+ return preparse_next_value_nodecrement(recursed);
+}
+
+/**
+ * Updates \a it to point to the next element after the container. The \a
+ * recursed object needs to point to the element obtained either by advancing
+ * the last element of the container (via cbor_value_advance(),
+ * cbor_value_advance_fixed(), a nested cbor_value_leave_container(), or the \c
+ * next pointer from cbor_value_copy_string() or cbor_value_dup_string()).
+ *
+ * The \a it and \a recursed parameters must be the exact same as passed to
+ * cbor_value_enter_container().
+ *
+ * \sa cbor_value_enter_container(), cbor_value_at_end()
+ */
+CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed)
+{
+ cbor_assert(cbor_value_is_container(it));
+ cbor_assert(recursed->type == CborInvalidType);
+
+ copy_current_position(it, recursed);
+ if (recursed->flags & CborIteratorFlag_UnknownLength)
+ advance_bytes(it, 1);
+ return preparse_next_value(it);
+}
+
+
+/**
+ * \fn CborType cbor_value_get_type(const CborValue *value)
+ *
+ * Returns the type of the CBOR value that the iterator \a value points to. If
+ * \a value does not point to a valid value, this function returns \ref
+ * CborInvalidType.
+ *
+ * TinyCBOR also provides functions to test directly if a given CborValue object
+ * is of a given type, like cbor_value_is_text_string() and cbor_value_is_null().
+ *
+ * \sa cbor_value_is_valid()
+ */
+
+/**
+ * \fn bool cbor_value_is_null(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR null type.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_undefined()
+ */
+
+/**
+ * \fn bool cbor_value_is_undefined(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR undefined type.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_null()
+ */
+
+/**
+ * \fn bool cbor_value_is_boolean(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR boolean
+ * type (true or false).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_boolean()
+ */
+
+/**
+ * \fn CborError cbor_value_get_boolean(const CborValue *value, bool *result)
+ *
+ * Retrieves the boolean value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to a boolean value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_boolean is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_boolean()
+ */
+
+/**
+ * \fn bool cbor_value_is_simple_type(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR Simple Type
+ * type (other than true, false, null and undefined).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_simple_type()
+ */
+
+/**
+ * \fn CborError cbor_value_get_simple_type(const CborValue *value, uint8_t *result)
+ *
+ * Retrieves the CBOR Simple Type value that \a value points to and stores it
+ * in \a result. If the iterator \a value does not point to a simple_type
+ * value, the behavior is undefined, so checking with \ref cbor_value_get_type
+ * or with \ref cbor_value_is_simple_type is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_simple_type()
+ */
+
+/**
+ * \fn bool cbor_value_is_integer(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR integer
+ * type.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_int, cbor_value_get_int64, cbor_value_get_uint64, cbor_value_get_raw_integer
+ */
+
+/**
+ * \fn bool cbor_value_is_unsigned_integer(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR unsigned
+ * integer type (positive values or zero).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_uint64()
+ */
+
+/**
+ * \fn bool cbor_value_is_negative_integer(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR negative
+ * integer type.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_int, cbor_value_get_int64, cbor_value_get_raw_integer
+ */
+
+/**
+ * \fn CborError cbor_value_get_int(const CborValue *value, int *result)
+ *
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * Note that this function does not do range-checking: integral values that do
+ * not fit in a variable of type \c{int} are silently truncated to fit. Use
+ * cbor_value_get_int_checked() if that is not acceptable.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer()
+ */
+
+/**
+ * \fn CborError cbor_value_get_int64(const CborValue *value, int64_t *result)
+ *
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * Note that this function does not do range-checking: integral values that do
+ * not fit in a variable of type \c{int64_t} are silently truncated to fit. Use
+ * cbor_value_get_int64_checked() that is not acceptable.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer()
+ */
+
+/**
+ * \fn CborError cbor_value_get_uint64(const CborValue *value, uint64_t *result)
+ *
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an unsigned integer
+ * value, the behavior is undefined, so checking with \ref cbor_value_get_type
+ * or with \ref cbor_value_is_unsigned_integer is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_unsigned_integer()
+ */
+
+/**
+ * \fn CborError cbor_value_get_raw_integer(const CborValue *value, uint64_t *result)
+ *
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * This function is provided because CBOR negative integers can assume values
+ * that cannot be represented with normal 64-bit integer variables.
+ *
+ * If the integer is unsigned (that is, if cbor_value_is_unsigned_integer()
+ * returns true), then \a result will contain the actual value. If the integer
+ * is negative, then \a result will contain the absolute value of that integer,
+ * minus one. That is, \c {actual = -result - 1}. On architectures using two's
+ * complement for representation of negative integers, it is equivalent to say
+ * that \a result will contain the bitwise negation of the actual value.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer()
+ */
+
+/**
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * Unlike \ref cbor_value_get_int64(), this function performs a check to see if the
+ * stored integer fits in \a result without data loss. If the number is outside
+ * the valid range for the data type, this function returns the recoverable
+ * error CborErrorDataTooLarge. In that case, use either
+ * cbor_value_get_uint64() (if the number is positive) or
+ * cbor_value_get_raw_integer().
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer(), cbor_value_get_int64()
+ */
+CborError cbor_value_get_int64_checked(const CborValue *value, int64_t *result)
+{
+ uint64_t v;
+ cbor_assert(cbor_value_is_integer(value));
+ v = _cbor_value_extract_int64_helper(value);
+
+ /* Check before converting, as the standard says (C11 6.3.1.3 paragraph 3):
+ * "[if] the new type is signed and the value cannot be represented in it; either the
+ * result is implementation-defined or an implementation-defined signal is raised."
+ *
+ * The range for int64_t is -2^63 to 2^63-1 (int64_t is required to be
+ * two's complement, C11 7.20.1.1 paragraph 3), which in CBOR is
+ * represented the same way, differing only on the "sign bit" (the major
+ * type).
+ */
+
+ if (unlikely(v > (uint64_t)INT64_MAX))
+ return CborErrorDataTooLarge;
+
+ *result = v;
+ if (value->flags & CborIteratorFlag_NegativeInteger)
+ *result = -*result - 1;
+ return CborNoError;
+}
+
+/**
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * Unlike \ref cbor_value_get_int(), this function performs a check to see if the
+ * stored integer fits in \a result without data loss. If the number is outside
+ * the valid range for the data type, this function returns the recoverable
+ * error CborErrorDataTooLarge. In that case, use one of the other integer
+ * functions to obtain the value.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer(), cbor_value_get_int64(),
+ * cbor_value_get_uint64(), cbor_value_get_int64_checked(), cbor_value_get_raw_integer()
+ */
+CborError cbor_value_get_int_checked(const CborValue *value, int *result)
+{
+ uint64_t v;
+ cbor_assert(cbor_value_is_integer(value));
+ v = _cbor_value_extract_int64_helper(value);
+
+ /* Check before converting, as the standard says (C11 6.3.1.3 paragraph 3):
+ * "[if] the new type is signed and the value cannot be represented in it; either the
+ * result is implementation-defined or an implementation-defined signal is raised."
+ *
+ * But we can convert from signed to unsigned without fault (paragraph 2).
+ *
+ * The range for int is implementation-defined and int is not guaranteed to use
+ * two's complement representation (although int32_t is).
+ */
+
+ if (value->flags & CborIteratorFlag_NegativeInteger) {
+ if (unlikely(v > (unsigned) -(INT_MIN + 1)))
+ return CborErrorDataTooLarge;
+
+ *result = (int)v;
+ *result = -*result - 1;
+ } else {
+ if (unlikely(v > (uint64_t)INT_MAX))
+ return CborErrorDataTooLarge;
+
+ *result = (int)v;
+ }
+ return CborNoError;
+
+}
+
+/**
+ * \fn bool cbor_value_is_length_known(const CborValue *value)
+ *
+ * Returns true if the length of this type is known without calculation. That
+ * is, if the length of this CBOR string, map or array is encoded in the data
+ * stream, this function returns true. If the length is not encoded, it returns
+ * false.
+ *
+ * If the length is known, code can call cbor_value_get_string_length(),
+ * cbor_value_get_array_length() or cbor_value_get_map_length() to obtain the
+ * length. If the length is not known but is necessary, code can use the
+ * cbor_value_calculate_string_length() function (no equivalent function is
+ * provided for maps and arrays).
+ */
+
+/**
+ * \fn bool cbor_value_is_text_string(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR text
+ * string. CBOR text strings are UTF-8 encoded and usually contain
+ * human-readable text.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_string_length(), cbor_value_calculate_string_length(),
+ * cbor_value_copy_text_string(), cbor_value_dup_text_string()
+ */
+
+/**
+ * \fn bool cbor_value_is_byte_string(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR text
+ * string. CBOR byte strings are binary data with no specified encoding or
+ * format.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_string_length(), cbor_value_calculate_string_length(),
+ * cbor_value_copy_byte_string(), cbor_value_dup_byte_string()
+ */
+
+/**
+ * \fn CborError cbor_value_get_string_length(const CborValue *value, size_t *length)
+ *
+ * Extracts the length of the byte or text string that \a value points to and
+ * stores it in \a result. If the iterator \a value does not point to a text
+ * string or a byte string, the behaviour is undefined, so checking with \ref
+ * cbor_value_get_type, with \ref cbor_value_is_text_string or \ref
+ * cbor_value_is_byte_string is recommended.
+ *
+ * If the length of this string is not encoded in the CBOR data stream, this
+ * function will return the recoverable error CborErrorUnknownLength. You may
+ * also check whether that is the case by using cbor_value_is_length_known().
+ *
+ * If the length of the string is required but the length was not encoded, use
+ * cbor_value_calculate_string_length(), but note that that function does not
+ * run in constant time.
+ *
+ * \note On 32-bit platforms, this function will return error condition of \ref
+ * CborErrorDataTooLarge if the stream indicates a length that is too big to
+ * fit in 32-bit.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_length_known(), cbor_value_calculate_string_length()
+ */
+
+/**
+ * Calculates the length of the byte or text string that \a value points to and
+ * stores it in \a len. If the iterator \a value does not point to a text
+ * string or a byte string, the behaviour is undefined, so checking with \ref
+ * cbor_value_get_type, with \ref cbor_value_is_text_string or \ref
+ * cbor_value_is_byte_string is recommended.
+ *
+ * This function is different from cbor_value_get_string_length() in that it
+ * calculates the length even for strings sent in chunks. For that reason, this
+ * function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It does use constant memory (O(1)).
+ *
+ * \note On 32-bit platforms, this function will return error condition of \ref
+ * CborErrorDataTooLarge if the stream indicates a length that is too big to
+ * fit in 32-bit.
+ *
+ * \sa cbor_value_get_string_length(), cbor_value_copy_text_string(), cbor_value_copy_byte_string(), cbor_value_is_length_known()
+ */
+CborError cbor_value_calculate_string_length(const CborValue *value, size_t *len)
+{
+ *len = SIZE_MAX;
+ return _cbor_value_copy_string(value, NULL, len, NULL);
+}
+
+CborError _cbor_value_begin_string_iteration(CborValue *it)
+{
+ it->flags |= CborIteratorFlag_IteratingStringChunks |
+ CborIteratorFlag_BeforeFirstStringChunk;
+ if (!cbor_value_is_length_known(it)) {
+ /* chunked string: we're before the first chunk;
+ * advance to the first chunk */
+ advance_bytes(it, 1);
+ }
+
+ return CborNoError;
+}
+
+CborError _cbor_value_finish_string_iteration(CborValue *it)
+{
+ if (!cbor_value_is_length_known(it))
+ advance_bytes(it, 1); /* skip the Break */
+
+ return preparse_next_value(it);
+}
+
+static CborError get_string_chunk_size(const CborValue *it, size_t *offset, size_t *len)
+{
+ uint8_t descriptor;
+ size_t bytesNeeded = 1;
+
+ if (cbor_value_is_length_known(it) && (it->flags & CborIteratorFlag_BeforeFirstStringChunk) == 0)
+ return CborErrorNoMoreStringChunks;
+
+ /* are we at the end? */
+ if (!read_bytes(it, &descriptor, 0, 1))
+ return CborErrorUnexpectedEOF;
+
+ if (descriptor == BreakByte)
+ return CborErrorNoMoreStringChunks;
+ if ((descriptor & MajorTypeMask) != it->type)
+ return CborErrorIllegalType;
+
+ /* find the string length */
+ descriptor &= SmallValueMask;
+ if (descriptor < Value8Bit) {
+ *len = descriptor;
+ } else if (unlikely(descriptor > Value64Bit)) {
+ return CborErrorIllegalNumber;
+ } else {
+ uint64_t val;
+ bytesNeeded = (size_t)(1 << (descriptor - Value8Bit));
+ if (!can_read_bytes(it, 1 + bytesNeeded))
+ return CborErrorUnexpectedEOF;
+
+ if (descriptor <= Value16Bit) {
+ if (descriptor == Value16Bit)
+ val = read_uint16(it, 1);
+ else
+ val = read_uint8(it, 1);
+ } else {
+ if (descriptor == Value32Bit)
+ val = read_uint32(it, 1);
+ else
+ val = read_uint64(it, 1);
+ }
+
+ *len = val;
+ if (*len != val)
+ return CborErrorDataTooLarge;
+
+ ++bytesNeeded;
+ }
+
+ *offset = bytesNeeded;
+ return CborNoError;
+}
+
+CborError _cbor_value_get_string_chunk_size(const CborValue *value, size_t *len)
+{
+ size_t offset;
+ return get_string_chunk_size(value, &offset, len);
+}
+
+static CborError get_string_chunk(CborValue *it, const void **bufferptr, size_t *len)
+{
+ size_t offset;
+ CborError err = get_string_chunk_size(it, &offset, len);
+ if (err)
+ return err;
+
+ /* we're good, transfer the string now */
+ err = transfer_string(it, bufferptr, offset, *len);
+ if (err)
+ return err;
+
+ /* we've iterated at least once */
+ it->flags &= ~CborIteratorFlag_BeforeFirstStringChunk;
+ return CborNoError;
+}
+
+/**
+ * \fn CborError cbor_value_get_text_string_chunk(const CborValue *value, const char **bufferptr, size_t *len, CborValue *next)
+ *
+ * Extracts one text string chunk pointed to by \a value and stores a pointer
+ * to the data in \a buffer and the size in \a len, which must not be null. If
+ * no more chunks are available, then \a bufferptr will be set to null. This
+ * function may be used to iterate over any string without causing its contents
+ * to be copied to a separate buffer, like the convenience function
+ * cbor_value_copy_text_string() does.
+ *
+ * It is designed to be used in code like:
+ *
+ * \code
+ * if (cbor_value_is_text_string(value)) {
+ * char *ptr;
+ * size_t len;
+ * while (1) {
+ * err = cbor_value_get_text_string_chunk(value, &ptr, &len, &value));
+ * if (err) return err;
+ * if (ptr == NULL) return CborNoError;
+ * consume(ptr, len);
+ * }
+ * }
+ * \endcode
+ *
+ * If the iterator \a value does not point to a text string, the behaviour is
+ * undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_text_string is recommended.
+ *
+ * The \a next pointer, if not null, will be updated to point to the next item
+ * after this string. During iteration, the pointer must only be passed back
+ * again to this function; passing it to any other function in this library
+ * results in undefined behavior. If there are no more chunks to be read from
+ * \a value, then \a next will be set to the next item after this string; if \a
+ * value points to the last item, then \a next will be invalid.
+ *
+ * \note This function does not perform UTF-8 validation on the incoming text
+ * string.
+ *
+ * \sa cbor_value_dup_text_string(), cbor_value_copy_text_string(), cbor_value_caculate_string_length(), cbor_value_get_byte_string_chunk()
+ */
+
+/**
+ * \fn CborError cbor_value_get_byte_string_chunk(const CborValue *value, const char **bufferptr, size_t *len, CborValue *next)
+ *
+ * Extracts one byte string chunk pointed to by \a value and stores a pointer
+ * to the data in \a buffer and the size in \a len, which must not be null. If
+ * no more chunks are available, then \a bufferptr will be set to null. This
+ * function may be used to iterate over any string without causing its contents
+ * to be copied to a separate buffer, like the convenience function
+ * cbor_value_copy_byte_string() does.
+ *
+ * It is designed to be used in code like:
+ *
+ * \code
+ * if (cbor_value_is_byte_string(value)) {
+ * char *ptr;
+ * size_t len;
+ * while (1) {
+ * err = cbor_value_get_byte_string_chunk(value, &ptr, &len, &value));
+ * if (err) return err;
+ * if (ptr == NULL) return CborNoError;
+ * consume(ptr, len);
+ * }
+ * }
+ * \endcode
+ *
+ * If the iterator \a value does not point to a byte string, the behaviour is
+ * undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_byte_string is recommended.
+ *
+ * The \a next pointer, if not null, will be updated to point to the next item
+ * after this string. During iteration, the pointer must only be passed back
+ * again to this function; passing it to any other function in this library
+ * results in undefined behavior. If there are no more chunks to be read from
+ * \a value, then \a next will be set to the next item after this string; if \a
+ * value points to the last item, then \a next will be invalid.
+ *
+ * \sa cbor_value_dup_byte_string(), cbor_value_copy_byte_string(), cbor_value_caculate_string_length(), cbor_value_get_text_string_chunk()
+ */
+
+CborError _cbor_value_get_string_chunk(const CborValue *value, const void **bufferptr,
+ size_t *len, CborValue *next)
+{
+ CborValue tmp;
+ if (!next)
+ next = &tmp;
+ *next = *value;
+ return get_string_chunk(next, bufferptr, len);
+}
+
+/* We return uintptr_t so that we can pass memcpy directly as the iteration
+ * function. The choice is to optimize for memcpy, which is used in the base
+ * parser API (cbor_value_copy_string), while memcmp is used in convenience API
+ * only. */
+typedef uintptr_t (*IterateFunction)(char *, const uint8_t *, size_t);
+
+static uintptr_t iterate_noop(char *dest, const uint8_t *src, size_t len)
+{
+ (void)dest;
+ (void)src;
+ (void)len;
+ return true;
+}
+
+static uintptr_t iterate_memcmp(char *s1, const uint8_t *s2, size_t len)
+{
+ return memcmp(s1, (const char *)s2, len) == 0;
+}
+
+static uintptr_t iterate_memcpy(char *dest, const uint8_t *src, size_t len)
+{
+ return (uintptr_t)memcpy(dest, src, len);
+}
+
+static CborError iterate_string_chunks(const CborValue *value, char *buffer, size_t *buflen,
+ bool *result, CborValue *next, IterateFunction func)
+{
+ CborError err;
+ CborValue tmp;
+ size_t total = 0;
+ const void *ptr;
+
+ cbor_assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
+ if (!next)
+ next = &tmp;
+ *next = *value;
+ *result = true;
+
+ err = _cbor_value_begin_string_iteration(next);
+ if (err)
+ return err;
+
+ while (1) {
+ size_t newTotal;
+ size_t chunkLen;
+ err = get_string_chunk(next, &ptr, &chunkLen);
+ if (err == CborErrorNoMoreStringChunks)
+ break;
+ if (err)
+ return err;
+
+ if (unlikely(add_check_overflow(total, chunkLen, &newTotal)))
+ return CborErrorDataTooLarge;
+
+ if (*result && *buflen >= newTotal)
+ *result = !!func(buffer + total, (const uint8_t *)ptr, chunkLen);
+ else
+ *result = false;
+
+ total = newTotal;
+ }
+
+ /* is there enough room for the ending NUL byte? */
+ if (*result && *buflen > total) {
+ uint8_t nul[] = { 0 };
+ *result = !!func(buffer + total, nul, 1);
+ }
+ *buflen = total;
+ return _cbor_value_finish_string_iteration(next);
+}
+
+/**
+ * \fn CborError cbor_value_copy_text_string(const CborValue *value, char *buffer, size_t *buflen, CborValue *next)
+ *
+ * Copies the string pointed to by \a value into the buffer provided at \a buffer
+ * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not
+ * copy anything and will only update the \a next value.
+ *
+ * If the iterator \a value does not point to a text string, the behaviour is
+ * undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_text_string is recommended.
+ *
+ * If the provided buffer length was too small, this function returns an error
+ * condition of \ref CborErrorOutOfMemory. If you need to calculate the length
+ * of the string in order to preallocate a buffer, use
+ * cbor_value_calculate_string_length().
+ *
+ * On success, this function sets the number of bytes copied to \c{*buflen}. If
+ * the buffer is large enough, this function will insert a null byte after the
+ * last copied byte, to facilitate manipulation of text strings. That byte is
+ * not included in the returned value of \c{*buflen}. If there was no space for
+ * the terminating null, no error is returned, so callers must check the value
+ * of *buflen after the call, before relying on the '\0'; if it has not been
+ * changed by the call, there is no '\0'-termination on the buffer's contents.
+ *
+ * The \a next pointer, if not null, will be updated to point to the next item
+ * after this string. If \a value points to the last item, then \a next will be
+ * invalid.
+ *
+ * This function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It requires constant memory (O(1)).
+ *
+ * \note This function does not perform UTF-8 validation on the incoming text
+ * string.
+ *
+ * \sa cbor_value_get_text_string_chunk() cbor_value_dup_text_string(), cbor_value_copy_byte_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length()
+ */
+
+/**
+ * \fn CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer, size_t *buflen, CborValue *next)
+ *
+ * Copies the string pointed by \a value into the buffer provided at \a buffer
+ * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not
+ * copy anything and will only update the \a next value.
+ *
+ * If the iterator \a value does not point to a byte string, the behaviour is
+ * undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_byte_string is recommended.
+ *
+ * If the provided buffer length was too small, this function returns an error
+ * condition of \ref CborErrorOutOfMemory. If you need to calculate the length
+ * of the string in order to preallocate a buffer, use
+ * cbor_value_calculate_string_length().
+ *
+ * On success, this function sets the number of bytes copied to \c{*buflen}. If
+ * the buffer is large enough, this function will insert a null byte after the
+ * last copied byte, to facilitate manipulation of null-terminated strings.
+ * That byte is not included in the returned value of \c{*buflen}.
+ *
+ * The \a next pointer, if not null, will be updated to point to the next item
+ * after this string. If \a value points to the last item, then \a next will be
+ * invalid.
+ *
+ * This function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It requires constant memory (O(1)).
+ *
+ * \sa cbor_value_get_byte_string_chunk(), cbor_value_dup_text_string(), cbor_value_copy_text_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length()
+ */
+
+CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
+ size_t *buflen, CborValue *next)
+{
+ bool copied_all;
+ CborError err = iterate_string_chunks(value, (char*)buffer, buflen, &copied_all, next,
+ buffer ? iterate_memcpy : iterate_noop);
+ return err ? err :
+ copied_all ? CborNoError : CborErrorOutOfMemory;
+}
+
+/**
+ * Compares the entry \a value with the string \a string and stores the result
+ * in \a result. If the value is different from \a string \a result will
+ * contain \c false.
+ *
+ * The entry at \a value may be a tagged string. If \a value is not a string or
+ * a tagged string, the comparison result will be false.
+ *
+ * CBOR requires text strings to be encoded in UTF-8, but this function does
+ * not validate either the strings in the stream or the string \a string to be
+ * matched. Moreover, comparison is done on strict codepoint comparison,
+ * without any Unicode normalization.
+ *
+ * This function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It requires constant memory (O(1)).
+ *
+ * \sa cbor_value_skip_tag(), cbor_value_copy_text_string()
+ */
+CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result)
+{
+ size_t len;
+ CborValue copy = *value;
+ CborError err = cbor_value_skip_tag(&copy);
+ if (err)
+ return err;
+ if (!cbor_value_is_text_string(&copy)) {
+ *result = false;
+ return CborNoError;
+ }
+
+ len = strlen(string);
+ return iterate_string_chunks(&copy, CONST_CAST(char *, string), &len, result, NULL, iterate_memcmp);
+}
+
+/**
+ * \fn bool cbor_value_is_array(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR array.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_map()
+ */
+
+/**
+ * \fn CborError cbor_value_get_array_length(const CborValue *value, size_t *length)
+ *
+ * Extracts the length of the CBOR array that \a value points to and stores it
+ * in \a result. If the iterator \a value does not point to a CBOR array, the
+ * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_array is recommended.
+ *
+ * If the length of this array is not encoded in the CBOR data stream, this
+ * function will return the recoverable error CborErrorUnknownLength. You may
+ * also check whether that is the case by using cbor_value_is_length_known().
+ *
+ * \note On 32-bit platforms, this function will return error condition of \ref
+ * CborErrorDataTooLarge if the stream indicates a length that is too big to
+ * fit in 32-bit.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_length_known()
+ */
+
+/**
+ * \fn bool cbor_value_is_map(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR map.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_array()
+ */
+
+/**
+ * \fn CborError cbor_value_get_map_length(const CborValue *value, size_t *length)
+ *
+ * Extracts the length of the CBOR map that \a value points to and stores it in
+ * \a result. If the iterator \a value does not point to a CBOR map, the
+ * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_map is recommended.
+ *
+ * If the length of this map is not encoded in the CBOR data stream, this
+ * function will return the recoverable error CborErrorUnknownLength. You may
+ * also check whether that is the case by using cbor_value_is_length_known().
+ *
+ * \note On 32-bit platforms, this function will return error condition of \ref
+ * CborErrorDataTooLarge if the stream indicates a length that is too big to
+ * fit in 32-bit.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_length_known()
+ */
+
+/**
+ * Attempts to find the value in map \a map that corresponds to the text string
+ * entry \a string. If the iterator \a value does not point to a CBOR map, the
+ * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_map is recommended.
+ *
+ * If the item is found, it is stored in \a result. If no item is found
+ * matching the key, then \a result will contain an element of type \ref
+ * CborInvalidType. Matching is performed using
+ * cbor_value_text_string_equals(), so tagged strings will also match.
+ *
+ * This function has a time complexity of O(n) where n is the number of
+ * elements in the map to be searched. In addition, this function is has O(n)
+ * memory requirement based on the number of nested containers (maps or arrays)
+ * found as elements of this map.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_text_string_equals(), cbor_value_advance()
+ */
+CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element)
+{
+ CborError err;
+ size_t len = strlen(string);
+ cbor_assert(cbor_value_is_map(map));
+ err = cbor_value_enter_container(map, element);
+ if (err)
+ goto error;
+
+ while (!cbor_value_at_end(element)) {
+ /* find the non-tag so we can compare */
+ err = cbor_value_skip_tag(element);
+ if (err)
+ goto error;
+ if (cbor_value_is_text_string(element)) {
+ bool equals;
+ size_t dummyLen = len;
+ err = iterate_string_chunks(element, CONST_CAST(char *, string), &dummyLen,
+ &equals, element, iterate_memcmp);
+ if (err)
+ goto error;
+ if (equals)
+ return preparse_value(element);
+ } else {
+ /* skip this key */
+ err = cbor_value_advance(element);
+ if (err)
+ goto error;
+ }
+
+ /* skip this value */
+ err = cbor_value_skip_tag(element);
+ if (err)
+ goto error;
+ err = cbor_value_advance(element);
+ if (err)
+ goto error;
+ }
+
+ /* not found */
+ element->type = CborInvalidType;
+ return CborNoError;
+
+error:
+ element->type = CborInvalidType;
+ return err;
+}
+
+/**
+ * \fn bool cbor_value_is_float(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR
+ * single-precision floating point (32-bit).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_double(), cbor_value_is_half_float()
+ */
+
+/**
+ * \fn CborError cbor_value_get_float(const CborValue *value, float *result)
+ *
+ * Retrieves the CBOR single-precision floating point (32-bit) value that \a
+ * value points to and stores it in \a result. If the iterator \a value does
+ * not point to a single-precision floating point value, the behavior is
+ * undefined, so checking with \ref cbor_value_get_type or with \ref
+ * cbor_value_is_float is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_float(), cbor_value_get_double()
+ */
+
+/**
+ * \fn bool cbor_value_is_double(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR
+ * double-precision floating point (64-bit).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_float(), cbor_value_is_half_float()
+ */
+
+/**
+ * \fn CborError cbor_value_get_double(const CborValue *value, float *result)
+ *
+ * Retrieves the CBOR double-precision floating point (64-bit) value that \a
+ * value points to and stores it in \a result. If the iterator \a value does
+ * not point to a double-precision floating point value, the behavior is
+ * undefined, so checking with \ref cbor_value_get_type or with \ref
+ * cbor_value_is_double is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_double(), cbor_value_get_float()
+ */
+
+/**
+ * \fn bool cbor_value_is_half_float(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR
+ * single-precision floating point (16-bit).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_double(), cbor_value_is_float()
+ */
+
+/**
+ * \fn CborError cbor_value_get_half_float(const CborValue *value, void *result)
+ *
+ * Retrieves the CBOR half-precision floating point (16-bit) value that \a
+ * value points to and stores it in \a result. If the iterator \a value does
+ * not point to a half-precision floating point value, the behavior is
+ * undefined, so checking with \ref cbor_value_get_type or with \ref
+ * cbor_value_is_half_float is recommended.
+ *
+ * Note: since the C language does not have a standard type for half-precision
+ * floating point, this function takes a \c{void *} as a parameter for the
+ * storage area, which must be at least 16 bits wide.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_half_float(), cbor_value_get_float()
+ */
+
+/** @} */
diff --git a/src/3rdparty/tinycbor/src/compilersupport_p.h b/src/3rdparty/tinycbor/src/compilersupport_p.h
new file mode 100644
index 0000000000..2b9491d34d
--- /dev/null
+++ b/src/3rdparty/tinycbor/src/compilersupport_p.h
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef COMPILERSUPPORT_H
+#define COMPILERSUPPORT_H
+
+#include "cbor.h"
+
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+#endif
+#ifndef _DEFAULT_SOURCE
+# define _DEFAULT_SOURCE
+#endif
+#ifndef assert
+# include <assert.h>
+#endif
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifndef __cplusplus
+# include <stdbool.h>
+#endif
+
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L || __cpp_static_assert >= 200410
+# define cbor_static_assert(x) static_assert(x, #x)
+#elif !defined(__cplusplus) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) && (__STDC_VERSION__ > 199901L)
+# define cbor_static_assert(x) _Static_assert(x, #x)
+#else
+# define cbor_static_assert(x) ((void)sizeof(char[2*!!(x) - 1]))
+#endif
+#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
+/* inline is a keyword */
+#else
+/* use the definition from cbor.h */
+# define inline CBOR_INLINE
+#endif
+
+#ifdef NDEBUG
+# define cbor_assert(cond) do { if (!(cond)) unreachable(); } while (0)
+#else
+# define cbor_assert(cond) assert(cond)
+#endif
+
+#ifndef STRINGIFY
+#define STRINGIFY(x) STRINGIFY2(x)
+#endif
+#define STRINGIFY2(x) #x
+
+#if !defined(UINT32_MAX) || !defined(INT64_MAX)
+/* C89? We can define UINT32_MAX portably, but not INT64_MAX */
+# error "Your system has stdint.h but that doesn't define UINT32_MAX or INT64_MAX"
+#endif
+
+#ifndef DBL_DECIMAL_DIG
+/* DBL_DECIMAL_DIG is C11 */
+# define DBL_DECIMAL_DIG 17
+#endif
+#define DBL_DECIMAL_DIG_STR STRINGIFY(DBL_DECIMAL_DIG)
+
+#if defined(__GNUC__) && defined(__i386__) && !defined(__iamcu__)
+# define CBOR_INTERNAL_API_CC __attribute__((regparm(3)))
+#elif defined(_MSC_VER) && defined(_M_IX86)
+# define CBOR_INTERNAL_API_CC __fastcall
+#else
+# define CBOR_INTERNAL_API_CC
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) || \
+ (__has_builtin(__builtin_bswap64) && __has_builtin(__builtin_bswap32))
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define cbor_ntohll __builtin_bswap64
+# define cbor_htonll __builtin_bswap64
+# define cbor_ntohl __builtin_bswap32
+# define cbor_htonl __builtin_bswap32
+# ifdef __INTEL_COMPILER
+# define cbor_ntohs _bswap16
+# define cbor_htons _bswap16
+# elif (__GNUC__ * 100 + __GNUC_MINOR__ >= 608) || __has_builtin(__builtin_bswap16)
+# define cbor_ntohs __builtin_bswap16
+# define cbor_htons __builtin_bswap16
+# else
+# define cbor_ntohs(x) (((uint16_t)x >> 8) | ((uint16_t)x << 8))
+# define cbor_htons cbor_ntohs
+# endif
+# else
+# define cbor_ntohll
+# define cbor_htonll
+# define cbor_ntohl
+# define cbor_htonl
+# define cbor_ntohs
+# define cbor_htons
+# endif
+#elif defined(__sun)
+# include <sys/byteorder.h>
+#elif defined(_MSC_VER)
+/* MSVC, which implies Windows, which implies little-endian and sizeof(long) == 4 */
+# include <stdlib.h>
+# define cbor_ntohll _byteswap_uint64
+# define cbor_htonll _byteswap_uint64
+# define cbor_ntohl _byteswap_ulong
+# define cbor_htonl _byteswap_ulong
+# define cbor_ntohs _byteswap_ushort
+# define cbor_htons _byteswap_ushort
+#endif
+#ifndef cbor_ntohs
+# include <arpa/inet.h>
+# define cbor_ntohs ntohs
+# define cbor_htons htons
+#endif
+#ifndef cbor_ntohl
+# include <arpa/inet.h>
+# define cbor_ntohl ntohl
+# define cbor_htonl htonl
+#endif
+#ifndef cbor_ntohll
+# define cbor_ntohll ntohll
+# define cbor_htonll htonll
+/* ntohll isn't usually defined */
+# ifndef ntohll
+# if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
+ (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \
+ (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
+ (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \
+ defined(__ARMEB__) || defined(__MIPSEB__) || defined(__s390__) || defined(__sparc__)
+# define ntohll
+# define htonll
+# elif (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
+ (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
+ (defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && BYTE_ORDER == LITTLE_ENDIAN) || \
+ defined(_LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \
+ defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64)
+# define ntohll(x) ((ntohl((uint32_t)(x)) * UINT64_C(0x100000000)) + (ntohl((x) >> 32)))
+# define htonll ntohll
+# else
+# error "Unable to determine byte order!"
+# endif
+# endif
+#endif
+
+
+#ifdef __cplusplus
+# define CONST_CAST(t, v) const_cast<t>(v)
+#else
+/* C-style const_cast without triggering a warning with -Wcast-qual */
+# define CONST_CAST(t, v) (t)(uintptr_t)(v)
+#endif
+
+#ifdef __GNUC__
+#ifndef likely
+# define likely(x) __builtin_expect(!!(x), 1)
+#endif
+#ifndef unlikely
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+# define unreachable() __builtin_unreachable()
+#elif defined(_MSC_VER)
+# define likely(x) (x)
+# define unlikely(x) (x)
+# define unreachable() __assume(0)
+#else
+# define likely(x) (x)
+# define unlikely(x) (x)
+# define unreachable() do {} while (0)
+#endif
+
+static inline bool add_check_overflow(size_t v1, size_t v2, size_t *r)
+{
+#if ((defined(__GNUC__) && (__GNUC__ >= 5)) && !defined(__INTEL_COMPILER)) || __has_builtin(__builtin_add_overflow)
+ return __builtin_add_overflow(v1, v2, r);
+#else
+ /* unsigned additions are well-defined */
+ *r = v1 + v2;
+ return v1 > v1 + v2;
+#endif
+}
+
+#endif /* COMPILERSUPPORT_H */
+
diff --git a/src/3rdparty/tinycbor/src/tinycbor-version.h b/src/3rdparty/tinycbor/src/tinycbor-version.h
new file mode 100644
index 0000000000..c26560cce8
--- /dev/null
+++ b/src/3rdparty/tinycbor/src/tinycbor-version.h
@@ -0,0 +1,3 @@
+#define TINYCBOR_VERSION_MAJOR 0
+#define TINYCBOR_VERSION_MINOR 6
+#define TINYCBOR_VERSION_PATCH 0
diff --git a/src/3rdparty/tinycbor/tests/.gitignore b/src/3rdparty/tinycbor/tests/.gitignore
new file mode 100644
index 0000000000..e65577d287
--- /dev/null
+++ b/src/3rdparty/tinycbor/tests/.gitignore
@@ -0,0 +1,15 @@
+Makefile
+debug
+moc_predefs.h
+release
+target_wrapper.*
+
+# The executables
+cpp/cpp
+cpp/cpp.exe
+encoder/encoder
+encoder/encoder.exe
+parser/parser
+parser/parser.exe
+tojson/tojson
+tojson/tojson.exe
diff --git a/src/3rdparty/tinycbor/tests/encoder/data.cpp b/src/3rdparty/tinycbor/tests/encoder/data.cpp
new file mode 100644
index 0000000000..c33fb605aa
--- /dev/null
+++ b/src/3rdparty/tinycbor/tests/encoder/data.cpp
@@ -0,0 +1,310 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#include <QtTest>
+
+static float myNaNf()
+{
+ uint32_t v = 0x7fc00000;
+ float f;
+ memcpy(&f, &v, sizeof(f));
+ Q_ASSERT(qIsNaN(f));
+ return f;
+}
+
+static float myInff()
+{
+ uint32_t v = 0x7f800000;
+ float f;
+ memcpy(&f, &v, sizeof(f));
+ Q_ASSERT(qIsInf(f));
+ return f;
+}
+
+static float myNInff()
+{
+ uint32_t v = 0xff800000;
+ float f;
+ memcpy(&f, &v, sizeof(f));
+ Q_ASSERT(qIsInf(f));
+ return f;
+}
+
+static double myNaN()
+{
+ uint64_t v = UINT64_C(0x7ff8000000000000);
+ double f;
+ memcpy(&f, &v, sizeof(f));
+ Q_ASSERT(qIsNaN(f));
+ return f;
+}
+
+static double myInf()
+{
+ uint64_t v = UINT64_C(0x7ff0000000000000);
+ double f;
+ memcpy(&f, &v, sizeof(f));
+ Q_ASSERT(qIsInf(f));
+ return f;
+}
+
+static double myNInf()
+{
+ uint64_t v = UINT64_C(0xfff0000000000000);
+ double f;
+ memcpy(&f, &v, sizeof(f));
+ Q_ASSERT(qIsInf(f));
+ return f;
+}
+
+template <size_t N> QByteArray raw(const char (&data)[N])
+{
+ return QByteArray::fromRawData(data, N - 1);
+}
+
+struct NegativeInteger { quint64 abs; };
+Q_DECLARE_METATYPE(NegativeInteger)
+
+struct SimpleType { uint8_t type; };
+Q_DECLARE_METATYPE(SimpleType)
+
+struct Float16Standin { uint16_t val; };
+Q_DECLARE_METATYPE(Float16Standin)
+
+struct Tag { CborTag tag; QVariant tagged; };
+Q_DECLARE_METATYPE(Tag)
+
+template <typename... Args>
+QVariant make_list(const Args &... args)
+{
+ return QVariantList{args...};
+}
+
+typedef QVector<QPair<QVariant, QVariant>> Map;
+Q_DECLARE_METATYPE(Map)
+QVariant make_map(const std::initializer_list<QPair<QVariant, QVariant>> &list)
+{
+ return QVariant::fromValue(Map(list));
+}
+
+struct IndeterminateLengthArray : QVariantList { using QVariantList::QVariantList; };
+struct IndeterminateLengthMap : Map { using Map::Map; };
+Q_DECLARE_METATYPE(IndeterminateLengthArray)
+Q_DECLARE_METATYPE(IndeterminateLengthMap)
+
+QVariant make_ilarray(const std::initializer_list<QVariant> &list)
+{
+ return QVariant::fromValue(IndeterminateLengthArray(list));
+}
+
+QVariant make_ilmap(const std::initializer_list<QPair<QVariant, QVariant>> &list)
+{
+ return QVariant::fromValue(IndeterminateLengthMap(list));
+}
+
+void addColumns()
+{
+ QTest::addColumn<QByteArray>("output");
+ QTest::addColumn<QVariant>("input");
+}
+
+void addFixedData()
+{
+ // unsigned integers
+ QTest::newRow("0U") << raw("\x00") << QVariant(0U);
+ QTest::newRow("1U") << raw("\x01") << QVariant(1U);
+ QTest::newRow("10U") << raw("\x0a") << QVariant(10U);
+ QTest::newRow("23U") << raw("\x17") << QVariant(23U);
+ QTest::newRow("24U") << raw("\x18\x18") << QVariant(24U);
+ QTest::newRow("255U") << raw("\x18\xff") << QVariant(255U);
+ QTest::newRow("256U") << raw("\x19\x01\x00") << QVariant(256U);
+ QTest::newRow("65535U") << raw("\x19\xff\xff") << QVariant(65535U);
+ QTest::newRow("65536U") << raw("\x1a\0\1\x00\x00") << QVariant(65536U);
+ QTest::newRow("4294967295U") << raw("\x1a\xff\xff\xff\xff") << QVariant(4294967295U);
+ QTest::newRow("4294967296U") << raw("\x1b\0\0\0\1\0\0\0\0") << QVariant(Q_UINT64_C(4294967296));
+ QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
+ << QVariant(std::numeric_limits<quint64>::max());
+
+ // signed integers containing non-negative numbers
+ QTest::newRow("0") << raw("\x00") << QVariant(0);
+ QTest::newRow("1") << raw("\x01") << QVariant(1);
+ QTest::newRow("10") << raw("\x0a") << QVariant(10);
+ QTest::newRow("23") << raw("\x17") << QVariant(23);
+ QTest::newRow("24") << raw("\x18\x18") << QVariant(24);
+ QTest::newRow("255") << raw("\x18\xff") << QVariant(255);
+ QTest::newRow("256") << raw("\x19\x01\x00") << QVariant(256);
+ QTest::newRow("65535") << raw("\x19\xff\xff") << QVariant(65535);
+ QTest::newRow("65536") << raw("\x1a\0\1\x00\x00") << QVariant(65536);
+ QTest::newRow("4294967295") << raw("\x1a\xff\xff\xff\xff") << QVariant(Q_INT64_C(4294967295));
+ QTest::newRow("4294967296") << raw("\x1b\0\0\0\1\0\0\0\0") << QVariant(Q_INT64_C(4294967296));
+
+ // signed integers containing negative numbers
+ QTest::newRow("-1") << raw("\x20") << QVariant(-1);
+ QTest::newRow("-2") << raw("\x21") << QVariant(-2);
+ QTest::newRow("-24") << raw("\x37") << QVariant(-24);
+ QTest::newRow("-25") << raw("\x38\x18") << QVariant(-25);
+ QTest::newRow("-UINT8_MAX") << raw("\x38\xff") << QVariant(-256);
+ QTest::newRow("-UINT8_MAX-1") << raw("\x39\x01\x00") << QVariant(-257);
+ QTest::newRow("-UINT16_MAX") << raw("\x39\xff\xff") << QVariant(-65536);
+ QTest::newRow("-UINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << QVariant(-65537);
+ QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << QVariant(Q_INT64_C(-4294967296));
+ QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << QVariant(Q_INT64_C(-4294967297));
+
+ // negative integers
+ auto neg = [](quint64 v) { return QVariant::fromValue<NegativeInteger>({v}); };
+ QTest::newRow("negative1") << raw("\x20") << neg(1);
+ QTest::newRow("negative2") << raw("\x21") << neg(2);
+ QTest::newRow("negative24") << raw("\x37") << neg(24);
+ QTest::newRow("negative25") << raw("\x38\x18") << neg(25);
+ QTest::newRow("negativeUINT8_MAX") << raw("\x38\xff") << neg(256);
+ QTest::newRow("negativeUINT8_MAX-1") << raw("\x39\x01\x00") << neg(257);
+ QTest::newRow("negativeUINT16_MAX") << raw("\x39\xff\xff") << neg(65536);
+ QTest::newRow("negativeUINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << neg(65537);
+ QTest::newRow("negativeUINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << neg(Q_UINT64_C(4294967296));
+ QTest::newRow("negativeUINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << neg(Q_UINT64_C(4294967297));
+ QTest::newRow("negativeUINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
+ << neg(std::numeric_limits<quint64>::max());
+ QTest::newRow("negativeUINT64_MAX+1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff") << neg(0);
+
+ QTest::newRow("simple0") << raw("\xe0") << QVariant::fromValue(SimpleType{0});
+ QTest::newRow("simple19") << raw("\xf3") << QVariant::fromValue(SimpleType{19});
+ QTest::newRow("false") << raw("\xf4") << QVariant(false);
+ QTest::newRow("true") << raw("\xf5") << QVariant(true);
+ QTest::newRow("null") << raw("\xf6") << QVariant::fromValue<void *>(nullptr);
+ QTest::newRow("undefined") << raw("\xf7") << QVariant();
+ QTest::newRow("simple32") << raw("\xf8\x20") << QVariant::fromValue(SimpleType{32});
+ QTest::newRow("simple255") << raw("\xf8\xff") << QVariant::fromValue(SimpleType{255});
+
+ // floating point
+#if QT_VERSION < QT_VERSION_CHECK(5, 9, 0)
+ QTest::newRow("0.f16") << raw("\xf9\0\0") << QVariant::fromValue(Float16Standin{0x0000});
+#else
+ QTest::newRow("0.f16") << raw("\xf9\0\0") << QVariant::fromValue(qfloat16(0));
+ QTest::newRow("-1.f16") << raw("\xf9\xbc\0") << QVariant::fromValue(qfloat16(-1));
+ QTest::newRow("1.5f16") << raw("\xf9\x3e\0") << QVariant::fromValue(qfloat16(1.5));
+ QTest::newRow("nan_f16") << raw("\xf9\x7e\0") << QVariant::fromValue<qfloat16>(myNaNf());
+ QTest::newRow("-inf_f16") << raw("\xf9\xfc\0") << QVariant::fromValue<qfloat16>(myNInff());
+ QTest::newRow("+inf_f16") << raw("\xf9\x7c\0") << QVariant::fromValue<qfloat16>(myInff());
+#endif
+
+ QTest::newRow("0.f") << raw("\xfa\0\0\0\0") << QVariant::fromValue(0.f);
+ QTest::newRow("0.") << raw("\xfb\0\0\0\0\0\0\0\0") << QVariant(0.);
+ QTest::newRow("-1.f") << raw("\xfa\xbf\x80\0\0") << QVariant::fromValue(-1.f);
+ QTest::newRow("-1.") << raw("\xfb\xbf\xf0\0\0\0\0\0\0") << QVariant(-1.);
+ QTest::newRow("16777215.f") << raw("\xfa\x4b\x7f\xff\xff") << QVariant::fromValue(16777215.f);
+ QTest::newRow("16777215.") << raw("\xfb\x41\x6f\xff\xff\xe0\0\0\0") << QVariant::fromValue(16777215.);
+ QTest::newRow("-16777215.f") << raw("\xfa\xcb\x7f\xff\xff") << QVariant(-16777215.f);
+ QTest::newRow("-16777215.") << raw("\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << QVariant::fromValue(-16777215.);
+
+ QTest::newRow("nan_f") << raw("\xfa\x7f\xc0\0\0") << QVariant::fromValue<float>(myNaNf());
+ QTest::newRow("nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << QVariant(myNaN());
+ QTest::newRow("-inf_f") << raw("\xfa\xff\x80\0\0") << QVariant::fromValue<float>(myNInff());
+ QTest::newRow("-inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << QVariant(myNInf());
+ QTest::newRow("+inf_f") << raw("\xfa\x7f\x80\0\0") << QVariant::fromValue<float>(myInff());
+ QTest::newRow("+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << QVariant(myInf());
+}
+
+void addStringsData()
+{
+ // byte strings
+ QTest::newRow("emptybytestring") << raw("\x40") << QVariant(QByteArray(""));
+ QTest::newRow("bytestring1") << raw("\x41 ") << QVariant(QByteArray(" "));
+ QTest::newRow("bytestring1-nul") << raw("\x41\0") << QVariant(QByteArray("", 1));
+ QTest::newRow("bytestring5") << raw("\x45Hello") << QVariant(QByteArray("Hello"));
+ QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234")
+ << QVariant(QByteArray("123456789012345678901234"));
+ QTest::newRow("bytestring256") << raw("\x59\1\0") + QByteArray(256, '3')
+ << QVariant(QByteArray(256, '3'));
+
+ // text strings
+ QTest::newRow("emptytextstring") << raw("\x60") << QVariant("");
+ QTest::newRow("textstring1") << raw("\x61 ") << QVariant(" ");
+ QTest::newRow("textstring1-nul") << raw("\x61\0") << QVariant(QString::fromLatin1("", 1));
+ QTest::newRow("textstring5") << raw("\x65Hello") << QVariant("Hello");
+ QTest::newRow("textstring24") << raw("\x78\x18""123456789012345678901234")
+ << QVariant("123456789012345678901234");
+ QTest::newRow("textstring256") << raw("\x79\1\0") + QByteArray(256, '3')
+ << QVariant(QString(256, '3'));
+}
+
+void addArraysAndMaps()
+{
+ QTest::newRow("emptyarray") << raw("\x80") << make_list();
+ QTest::newRow("emptymap") << raw("\xa0") << make_map({});
+
+ QTest::newRow("array-0") << raw("\x81\0") << make_list(0);
+ QTest::newRow("array-{0-0}") << raw("\x82\0\0") << make_list(0, 0);
+ QTest::newRow("array-Hello") << raw("\x81\x65Hello") << make_list("Hello");
+ QTest::newRow("array-array-0") << raw("\x81\x81\0") << make_list(make_list(0));
+ QTest::newRow("array-array-{0-0}") << raw("\x81\x82\0\0") << make_list(make_list(0, 0));
+ QTest::newRow("array-array-0-0") << raw("\x82\x81\0\0") << make_list(make_list(0),0);
+ QTest::newRow("array-array-Hello") << raw("\x81\x81\x65Hello") << make_list(make_list("Hello"));
+
+ QTest::newRow("map-0:0") << raw("\xa1\0\0") << make_map({{0,0}});
+ QTest::newRow("map-0:0-1:1") << raw("\xa2\0\0\1\1") << make_map({{0,0}, {1,1}});
+ QTest::newRow("map-0:{map-0:0-1:1}") << raw("\xa1\0\xa2\0\0\1\1") << make_map({{0, make_map({{0,0}, {1,1}})}});
+
+ QTest::newRow("array-map1") << raw("\x81\xa1\0\0") << make_list(make_map({{0,0}}));
+ QTest::newRow("array-map2") << raw("\x82\xa1\0\0\xa1\1\1") << make_list(make_map({{0,0}}), make_map({{1,1}}));
+
+ QTest::newRow("map-array1") << raw("\xa1\x62oc\x81\0") << make_map({{"oc", make_list(0)}});
+ QTest::newRow("map-array2") << raw("\xa1\x62oc\x84\0\1\2\3") << make_map({{"oc", make_list(0, 1, 2, 3)}});
+ QTest::newRow("map-array3") << raw("\xa2\x62oc\x82\0\1\2\3") << make_map({{"oc", make_list(0, 1)}, {2, 3}});
+
+ // indeterminate length
+ QTest::newRow("_emptyarray") << raw("\x9f\xff") << QVariant::fromValue(IndeterminateLengthArray{});
+ QTest::newRow("_emptymap") << raw("\xbf\xff") << make_ilmap({});
+
+ QTest::newRow("_array-0") << raw("\x9f\0\xff") << make_ilarray({0});
+ QTest::newRow("_array-{0-0}") << raw("\x9f\0\0\xff") << make_ilarray({0, 0});
+ QTest::newRow("_array-Hello") << raw("\x9f\x65Hello\xff") << make_ilarray({"Hello"});
+ QTest::newRow("_array-array-0") << raw("\x9f\x81\0\xff") << make_ilarray({make_list(0)});
+ QTest::newRow("_array-_array-0") << raw("\x9f\x9f\0\xff\xff") << make_ilarray({make_ilarray({0})});
+ QTest::newRow("_array-_array-{0-0}") << raw("\x9f\x9f\0\0\xff\xff") << make_ilarray({make_ilarray({0, 0})});
+ QTest::newRow("_array-_array-0-0") << raw("\x9f\x9f\0\xff\0\xff") << make_ilarray({make_ilarray({0}),0});
+ QTest::newRow("_array-_array-Hello") << raw("\x9f\x9f\x65Hello\xff\xff") << make_ilarray({make_ilarray({"Hello"})});
+
+ QTest::newRow("_map-0:0") << raw("\xbf\0\0\xff") << make_ilmap({{0,0}});
+ QTest::newRow("_map-0:0-1:1") << raw("\xbf\0\0\1\1\xff") << make_ilmap({{0,0}, {1,1}});
+ QTest::newRow("_map-0:{map-0:0-1:1}") << raw("\xbf\0\xa2\0\0\1\1\xff") << make_ilmap({{0, make_map({{0,0}, {1,1}})}});
+ QTest::newRow("_map-0:{_map-0:0-1:1}") << raw("\xbf\0\xbf\0\0\1\1\xff\xff") << make_ilmap({{0, make_ilmap({{0,0}, {1,1}})}});
+
+ QTest::newRow("_array-map1") << raw("\x9f\xa1\0\0\xff") << make_ilarray({make_map({{0,0}})});
+ QTest::newRow("_array-_map1") << raw("\x9f\xbf\0\0\xff\xff") << make_ilarray({make_ilmap({{0,0}})});
+ QTest::newRow("_array-map2") << raw("\x9f\xa1\0\0\xa1\1\1\xff") << make_ilarray({make_map({{0,0}}), make_map({{1,1}})});
+ QTest::newRow("_array-_map2") << raw("\x9f\xbf\0\0\xff\xbf\1\1\xff\xff") << make_ilarray({make_ilmap({{0,0}}), make_ilmap({{1,1}})});
+
+ QTest::newRow("_map-array1") << raw("\xbf\x62oc\x81\0\xff") << make_ilmap({{"oc", make_list(0)}});
+ QTest::newRow("_map-_array1") << raw("\xbf\x62oc\x9f\0\xff\xff") << make_ilmap({{"oc", make_ilarray({0})}});
+ QTest::newRow("_map-array2") << raw("\xbf\x62oc\x84\0\1\2\3\xff") << make_ilmap({{"oc", make_list(0, 1, 2, 3)}});
+ QTest::newRow("_map-_array2") << raw("\xbf\x62oc\x9f\0\1\2\3\xff\xff") << make_ilmap({{"oc", make_ilarray({0, 1, 2, 3})}});
+ QTest::newRow("_map-array3") << raw("\xbf\x62oc\x82\0\1\2\3\xff") << make_ilmap({{"oc", make_list(0, 1)}, {2, 3}});
+ QTest::newRow("_map-_array3") << raw("\xbf\x62oc\x9f\0\1\xff\2\3\xff") << make_ilmap({{"oc", make_ilarray({0, 1})}, {2, 3}});
+
+ // tagged
+ QTest::newRow("array-1(0)") << raw("\x81\xc1\0") << make_list(QVariant::fromValue(Tag{1, 0}));
+ QTest::newRow("array-1(map)") << raw("\x81\xc1\xa0") << make_list(QVariant::fromValue(Tag{1, make_map({})}));
+ QTest::newRow("map-1(2):3(4)") << raw("\xa1\xc1\2\xc3\4") << make_map({{QVariant::fromValue(Tag{1, 2}), QVariant::fromValue(Tag{3, 4})}});
+}
+
diff --git a/src/3rdparty/tinycbor/tests/encoder/encoder.pro b/src/3rdparty/tinycbor/tests/encoder/encoder.pro
new file mode 100644
index 0000000000..62d9b7e409
--- /dev/null
+++ b/src/3rdparty/tinycbor/tests/encoder/encoder.pro
@@ -0,0 +1,9 @@
+SOURCES += tst_encoder.cpp
+
+CONFIG += testcase parallel_test c++11
+QT = core testlib
+
+INCLUDEPATH += ../../src
+msvc: POST_TARGETDEPS = ../../lib/tinycbor.lib
+else: POST_TARGETDEPS += ../../lib/libtinycbor.a
+LIBS += $$POST_TARGETDEPS
diff --git a/src/3rdparty/tinycbor/tests/encoder/tst_encoder.cpp b/src/3rdparty/tinycbor/tests/encoder/tst_encoder.cpp
new file mode 100644
index 0000000000..f30c522601
--- /dev/null
+++ b/src/3rdparty/tinycbor/tests/encoder/tst_encoder.cpp
@@ -0,0 +1,496 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#include <QtTest>
+#include "cbor.h"
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+#include <qfloat16.h>
+#endif
+
+Q_DECLARE_METATYPE(CborError)
+namespace QTest {
+template<> char *toString<CborError>(const CborError &err)
+{
+ return qstrdup(cbor_error_string(err));
+}
+}
+
+class tst_Encoder : public QObject
+{
+ Q_OBJECT
+private slots:
+ void fixed_data();
+ void fixed();
+ void strings_data();
+ void strings() { fixed(); }
+ void arraysAndMaps_data();
+ void arraysAndMaps() { fixed(); }
+ void tags_data();
+ void tags();
+ void arrays_data() { tags_data(); }
+ void arrays();
+ void maps_data() { tags_data(); }
+ void maps();
+
+ void writerApi_data() { tags_data(); }
+ void writerApi();
+ void writerApiFail_data() { tags_data(); }
+ void writerApiFail();
+ void shortBuffer_data() { tags_data(); }
+ void shortBuffer();
+ void tooShortArrays_data() { tags_data(); }
+ void tooShortArrays();
+ void tooShortMaps_data() { tags_data(); }
+ void tooShortMaps();
+ void tooBigArrays_data() { tags_data(); }
+ void tooBigArrays();
+ void tooBigMaps_data() { tags_data(); }
+ void tooBigMaps();
+ void illegalSimpleType_data();
+ void illegalSimpleType();
+};
+
+#include "tst_encoder.moc"
+#include "data.cpp"
+
+static inline bool isOomError(CborError err)
+{
+ return err == CborErrorOutOfMemory;
+}
+
+CborError encodeVariant(CborEncoder *encoder, const QVariant &v)
+{
+ int type = v.userType();
+ switch (type) {
+ case QVariant::Int:
+ case QVariant::LongLong:
+ return cbor_encode_int(encoder, v.toLongLong());
+
+ case QVariant::UInt:
+ case QVariant::ULongLong:
+ return cbor_encode_uint(encoder, v.toULongLong());
+
+ case QVariant::Bool:
+ return cbor_encode_boolean(encoder, v.toBool());
+
+ case QVariant::Invalid:
+ return cbor_encode_undefined(encoder);
+
+ case QMetaType::VoidStar:
+ return cbor_encode_null(encoder);
+
+ case QVariant::Double:
+ return cbor_encode_double(encoder, v.toDouble());
+
+ case QMetaType::Float:
+ return cbor_encode_float(encoder, v.toFloat());
+
+ case QVariant::String: {
+ QByteArray string = v.toString().toUtf8();
+ return cbor_encode_text_string(encoder, string.constData(), string.length());
+ }
+
+ case QVariant::ByteArray: {
+ QByteArray string = v.toByteArray();
+ return cbor_encode_byte_string(encoder, reinterpret_cast<const quint8 *>(string.constData()), string.length());
+ }
+
+ default:
+ if (type == qMetaTypeId<NegativeInteger>())
+ return cbor_encode_negative_int(encoder, v.value<NegativeInteger>().abs);
+ if (type == qMetaTypeId<SimpleType>())
+ return cbor_encode_simple_value(encoder, v.value<SimpleType>().type);
+#if QT_VERSION < QT_VERSION_CHECK(5, 9, 0)
+ if (type == qMetaTypeId<Float16Standin>())
+ return cbor_encode_half_float(encoder, v.constData());
+#else
+ if (type == qMetaTypeId<qfloat16>())
+ return cbor_encode_half_float(encoder, v.constData());
+#endif
+ if (type == qMetaTypeId<Tag>()) {
+ CborError err = cbor_encode_tag(encoder, v.value<Tag>().tag);
+ if (err && !isOomError(err))
+ return err;
+ return static_cast<CborError>(err | encodeVariant(encoder, v.value<Tag>().tagged));
+ }
+ if (type == QVariant::List || type == qMetaTypeId<IndeterminateLengthArray>()) {
+ CborEncoder sub;
+ QVariantList list = v.toList();
+ size_t len = list.length();
+ if (type == qMetaTypeId<IndeterminateLengthArray>()) {
+ len = CborIndefiniteLength;
+ list = v.value<IndeterminateLengthArray>();
+ }
+ CborError err = cbor_encoder_create_array(encoder, &sub, len);
+ if (err && !isOomError(err))
+ return err;
+ foreach (const QVariant &v2, list) {
+ err = static_cast<CborError>(err | encodeVariant(&sub, v2));
+ if (err && !isOomError(err))
+ return err;
+ }
+ return cbor_encoder_close_container_checked(encoder, &sub);
+ }
+ if (type == qMetaTypeId<Map>() || type == qMetaTypeId<IndeterminateLengthMap>()) {
+ CborEncoder sub;
+ Map map = v.value<Map>();
+ size_t len = map.length();
+ if (type == qMetaTypeId<IndeterminateLengthMap>()) {
+ len = CborIndefiniteLength;
+ map = v.value<IndeterminateLengthMap>();
+ }
+ CborError err = cbor_encoder_create_map(encoder, &sub, len);
+ if (err && !isOomError(err))
+ return err;
+ for (auto pair : map) {
+ err = static_cast<CborError>(err | encodeVariant(&sub, pair.first));
+ if (err && !isOomError(err))
+ return err;
+ err = static_cast<CborError>(err | encodeVariant(&sub, pair.second));
+ if (err && !isOomError(err))
+ return err;
+ }
+ return cbor_encoder_close_container_checked(encoder, &sub);
+ }
+ }
+ return CborErrorUnknownType;
+}
+
+void compare(const QVariant &input, const QByteArray &output)
+{
+ QByteArray buffer(output.length(), Qt::Uninitialized);
+ uint8_t *bufptr = reinterpret_cast<quint8 *>(buffer.data());
+ CborEncoder encoder;
+ cbor_encoder_init(&encoder, bufptr, buffer.length(), 0);
+
+ QCOMPARE(encodeVariant(&encoder, input), CborNoError);
+ QCOMPARE(encoder.remaining, size_t(1));
+ QCOMPARE(cbor_encoder_get_extra_bytes_needed(&encoder), size_t(0));
+
+ buffer.resize(int(cbor_encoder_get_buffer_size(&encoder, bufptr)));
+ QCOMPARE(buffer, output);
+}
+
+void tst_Encoder::fixed_data()
+{
+ addColumns();
+ addFixedData();
+}
+
+void tst_Encoder::fixed()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+ compare(input, output);
+}
+
+void tst_Encoder::strings_data()
+{
+ addColumns();
+ addStringsData();
+}
+
+void tst_Encoder::arraysAndMaps_data()
+{
+ addColumns();
+ addArraysAndMaps();
+}
+
+void tst_Encoder::tags_data()
+{
+ addColumns();
+ addFixedData();
+ addStringsData();
+ addArraysAndMaps();
+}
+
+void tst_Encoder::tags()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+
+ compare(QVariant::fromValue(Tag{1, input}), "\xc1" + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{24, input}), "\xd8\x18" + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{255, input}), "\xd8\xff" + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{256, input}), raw("\xd9\1\0") + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{CborSignatureTag, input}), raw("\xd9\xd9\xf7") + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{65535, input}), raw("\xd9\xff\xff") + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{65536, input}), raw("\xda\0\1\0\0") + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{UINT32_MAX, input}), raw("\xda\xff\xff\xff\xff") + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{UINT32_MAX + Q_UINT64_C(1), input}), raw("\xdb\0\0\0\1\0\0\0\0") + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(QVariant::fromValue(Tag{UINT64_MAX, input}), raw("\xdb\xff\xff\xff\xff\xff\xff\xff\xff") + output);
+ if (QTest::currentTestFailed()) return;
+
+ // nested tags
+ compare(QVariant::fromValue(Tag{1, QVariant::fromValue(Tag{1, input})}), "\xc1\xc1" + output);
+}
+
+void tst_Encoder::arrays()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+
+ compare(make_list(input), "\x81" + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(make_list(input, input), "\x82" + output + output);
+ if (QTest::currentTestFailed()) return;
+
+ {
+ QVariantList list{input};
+ QByteArray longoutput = output;
+
+ // make a list with 32 elements (1 << 5)
+ for (int i = 0; i < 5; ++i) {
+ list += list;
+ longoutput += longoutput;
+ }
+ compare(list, "\x98\x20" + longoutput);
+ if (QTest::currentTestFailed()) return;
+
+ // now 256 elements (32 << 3)
+ for (int i = 0; i < 3; ++i) {
+ list += list;
+ longoutput += longoutput;
+ }
+ compare(list, raw("\x99\1\0") + longoutput);
+ if (QTest::currentTestFailed()) return;
+ }
+
+ // nested lists
+ compare(make_list(make_list(input)), "\x81\x81" + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(make_list(make_list(input, input)), "\x81\x82" + output + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(make_list(make_list(input), input), "\x82\x81" + output + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(make_list(make_list(input), make_list(input)), "\x82\x81" + output + "\x81" + output);
+}
+
+void tst_Encoder::maps()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+
+ compare(make_map({{1, input}}), "\xa1\1" + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(make_map({{1, input}, {input, 24}}), "\xa2\1" + output + output + "\x18\x18");
+ if (QTest::currentTestFailed()) return;
+
+ compare(make_map({{input, input}}), "\xa1" + output + output);
+ if (QTest::currentTestFailed()) return;
+
+ {
+ Map map{{1, input}};
+ QByteArray longoutput = "\1" + output;
+
+ // make a map with 32 elements (1 << 5)
+ for (int i = 0; i < 5; ++i) {
+ map += map;
+ longoutput += longoutput;
+ }
+ compare(QVariant::fromValue(map), "\xb8\x20" + longoutput);
+ if (QTest::currentTestFailed()) return;
+
+ // now 256 elements (32 << 3)
+ for (int i = 0; i < 3; ++i) {
+ map += map;
+ longoutput += longoutput;
+ }
+ compare(QVariant::fromValue(map), raw("\xb9\1\0") + longoutput);
+ if (QTest::currentTestFailed()) return;
+ }
+
+ // nested maps
+ compare(make_map({{1, make_map({{2, input}})}}), "\xa1\1\xa1\2" + output);
+ if (QTest::currentTestFailed()) return;
+
+ compare(make_map({{1, make_map({{2, input}, {input, false}})}}), "\xa1\1\xa2\2" + output + output + "\xf4");
+ if (QTest::currentTestFailed()) return;
+
+ compare(make_map({{1, make_map({{2, input}})}, {input, false}}), "\xa2\1\xa1\2" + output + output + "\xf4");
+ if (QTest::currentTestFailed()) return;
+}
+
+void tst_Encoder::writerApi()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+
+ // instead of writing to a QByteArray like all other tests, write to a QBuffer
+ QBuffer buffer;
+ buffer.open(QIODevice::ReadWrite);
+ auto callback = [](void *token, const void *data, size_t len, CborEncoderAppendType) {
+ auto buffer = static_cast<QBuffer *>(token);
+ buffer->write(static_cast<const char *>(data), len);
+ return CborNoError;
+ };
+
+ CborEncoder encoder;
+ cbor_encoder_init_writer(&encoder, callback, &buffer);
+ QCOMPARE(encodeVariant(&encoder, input), CborNoError);
+
+ buffer.reset();
+ QCOMPARE(buffer.readAll(), output);
+}
+
+void tst_Encoder::writerApiFail()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+
+ // same as above, but we'll produce an error during writing and we expect
+ // it to be returned
+ int callCount = 0;
+ auto callback = [](void *token, const void *, size_t, CborEncoderAppendType) {
+ ++*static_cast<int *>(token);
+ return CborErrorIO;
+ };
+
+ CborEncoder encoder;
+ cbor_encoder_init_writer(&encoder, callback, &callCount);
+ QCOMPARE(encodeVariant(&encoder, input), CborErrorIO);
+ QCOMPARE(callCount, 1);
+}
+
+void tst_Encoder::shortBuffer()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+ QByteArray buffer(output.length(), Qt::Uninitialized);
+
+ for (int len = 0; len < output.length(); ++len) {
+ CborEncoder encoder;
+ cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), len, 0);
+ QCOMPARE(encodeVariant(&encoder, input), CborErrorOutOfMemory);
+ QVERIFY(cbor_encoder_get_extra_bytes_needed(&encoder) != 0);
+ QCOMPARE(len + cbor_encoder_get_extra_bytes_needed(&encoder), size_t(output.length()));
+ }
+}
+
+void tst_Encoder::tooShortArrays()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+ QByteArray buffer(output.length() + 1, Qt::Uninitialized);
+
+ CborEncoder encoder, container;
+ cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), buffer.length(), 0);
+ QCOMPARE(cbor_encoder_create_array(&encoder, &container, 2), CborNoError);
+ QCOMPARE(encodeVariant(&container, input), CborNoError);
+ QCOMPARE(container.remaining, size_t(2));
+ QCOMPARE(cbor_encoder_close_container_checked(&encoder, &container), CborErrorTooFewItems);
+}
+
+void tst_Encoder::tooShortMaps()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+ QByteArray buffer(output.length() + 1, Qt::Uninitialized);
+
+ CborEncoder encoder, container;
+ cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), buffer.length(), 0);
+ QCOMPARE(cbor_encoder_create_map(&encoder, &container, 2), CborNoError);
+ QCOMPARE(encodeVariant(&container, input), CborNoError);
+ QCOMPARE(container.remaining, size_t(4));
+ QCOMPARE(cbor_encoder_close_container_checked(&encoder, &container), CborErrorTooFewItems);
+}
+
+void tst_Encoder::tooBigArrays()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+ QByteArray buffer(output.length() * 2 + 1, Qt::Uninitialized);
+
+ CborEncoder encoder, container;
+ cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), buffer.length(), 0);
+ QCOMPARE(cbor_encoder_create_array(&encoder, &container, 1), CborNoError);
+ QCOMPARE(encodeVariant(&container, input), CborNoError);
+ QCOMPARE(encodeVariant(&container, input), CborNoError);
+ QCOMPARE(container.remaining, size_t(0));
+ QCOMPARE(cbor_encoder_close_container_checked(&encoder, &container), CborErrorTooManyItems);
+}
+
+void tst_Encoder::tooBigMaps()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+ QByteArray buffer(output.length() * 3 + 1, Qt::Uninitialized);
+
+ CborEncoder encoder, container;
+ cbor_encoder_init(&encoder, reinterpret_cast<quint8 *>(buffer.data()), buffer.length(), 0);
+ QCOMPARE(cbor_encoder_create_map(&encoder, &container, 1), CborNoError);
+ QCOMPARE(encodeVariant(&container, input), CborNoError);
+ QCOMPARE(encodeVariant(&container, input), CborNoError);
+ QCOMPARE(encodeVariant(&container, input), CborNoError);
+ QCOMPARE(container.remaining, size_t(0));
+ QCOMPARE(cbor_encoder_close_container_checked(&encoder, &container), CborErrorTooManyItems);
+}
+
+void tst_Encoder::illegalSimpleType_data()
+{
+ QTest::addColumn<int>("type");
+ QTest::newRow("half-float") << 25;
+ QTest::newRow("float") << 26;
+ QTest::newRow("double") << 27;
+ QTest::newRow("28") << 28;
+ QTest::newRow("29") << 29;
+ QTest::newRow("30") << 30;
+ QTest::newRow("31") << 31;
+}
+
+void tst_Encoder::illegalSimpleType()
+{
+ QFETCH(int, type);
+
+ quint8 buf[2];
+ CborEncoder encoder;
+ cbor_encoder_init(&encoder, buf, sizeof(buf), 0);
+ QCOMPARE(cbor_encode_simple_value(&encoder, type), CborErrorIllegalSimpleType);
+}
+
+QTEST_MAIN(tst_Encoder)
diff --git a/src/3rdparty/tinycbor/tests/parser/data.cpp b/src/3rdparty/tinycbor/tests/parser/data.cpp
new file mode 100644
index 0000000000..0ab0e47be4
--- /dev/null
+++ b/src/3rdparty/tinycbor/tests/parser/data.cpp
@@ -0,0 +1,573 @@
+#include <QtTest>
+#include <limits>
+#include <cbor.h>
+
+Q_DECLARE_METATYPE(CborError)
+
+template <size_t N> QByteArray raw(const char (&data)[N])
+{
+ return QByteArray::fromRawData(data, N - 1);
+}
+
+void addIntegers()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<quint64>("expectedRaw");
+ QTest::addColumn<qint64>("expectedValue");
+ QTest::addColumn<bool>("isNegative");
+ QTest::addColumn<bool>("inInt64Range");
+
+ // unsigned integers
+ QTest::newRow("0") << raw("\x00") << Q_UINT64_C(0) << Q_INT64_C(0) << false << true;
+ QTest::newRow("1") << raw("\x01") << Q_UINT64_C(1) << Q_INT64_C(1) << false << true;
+ QTest::newRow("10") << raw("\x0a") << Q_UINT64_C(10) << Q_INT64_C(10) << false << true;
+ QTest::newRow("23") << raw("\x17") << Q_UINT64_C(23) << Q_INT64_C(23) << false << true;
+ QTest::newRow("24") << raw("\x18\x18") << Q_UINT64_C(24) << Q_INT64_C(24) << false << true;
+ QTest::newRow("UINT8_MAX") << raw("\x18\xff") << Q_UINT64_C(255) << Q_INT64_C(255) << false << true;
+ QTest::newRow("UINT8_MAX+1") << raw("\x19\x01\x00") << Q_UINT64_C(256) << Q_INT64_C(256) << false << true;
+ QTest::newRow("UINT16_MAX") << raw("\x19\xff\xff") << Q_UINT64_C(65535) << Q_INT64_C(65535) << false << true;
+ QTest::newRow("UINT16_MAX+1") << raw("\x1a\0\1\x00\x00") << Q_UINT64_C(65536) << Q_INT64_C(65536) << false << true;
+ QTest::newRow("UINT32_MAX") << raw("\x1a\xff\xff\xff\xff") << Q_UINT64_C(4294967295) << Q_INT64_C(4294967295) << false << true;
+ QTest::newRow("UINT32_MAX+1") << raw("\x1b\0\0\0\1\0\0\0\0") << Q_UINT64_C(4294967296) << Q_INT64_C(4294967296) << false << true;
+ QTest::newRow("INT64_MAX") << raw("\x1b" "\x7f\xff\xff\xff" "\xff\xff\xff\xff")
+ << quint64(std::numeric_limits<qint64>::max())
+ << std::numeric_limits<qint64>::max() << false << true;
+ QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
+ << std::numeric_limits<quint64>::max() << qint64(-123456) << false << false;
+
+ // negative integers
+ QTest::newRow("-1") << raw("\x20") << Q_UINT64_C(0) << Q_INT64_C(-1) << true << true;
+ QTest::newRow("-2") << raw("\x21") << Q_UINT64_C(1) << Q_INT64_C(-2) << true << true;
+ QTest::newRow("-24") << raw("\x37") << Q_UINT64_C(23) << Q_INT64_C(-24) << true << true;
+ QTest::newRow("-25") << raw("\x38\x18") << Q_UINT64_C(24) << Q_INT64_C(-25) << true << true;
+ QTest::newRow("-UINT8_MAX") << raw("\x38\xff") << Q_UINT64_C(255) << Q_INT64_C(-256) << true << true;
+ QTest::newRow("-UINT8_MAX-1") << raw("\x39\x01\x00") << Q_UINT64_C(256) << Q_INT64_C(-257) << true << true;
+ QTest::newRow("-UINT16_MAX") << raw("\x39\xff\xff") << Q_UINT64_C(65535) << Q_INT64_C(-65536) << true << true;
+ QTest::newRow("-UINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << Q_UINT64_C(65536) << Q_INT64_C(-65537) << true << true;
+ QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << Q_UINT64_C(4294967295) << Q_INT64_C(-4294967296) << true << true;
+ QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << Q_UINT64_C(4294967296) << Q_INT64_C(-4294967297) << true << true;
+ QTest::newRow("INT64_MIN+1") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xfe")
+ << quint64(std::numeric_limits<qint64>::max() - 1)
+ << (std::numeric_limits<qint64>::min() + 1)
+ << true << true;
+ QTest::newRow("INT64_MIN") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xff")
+ << quint64(std::numeric_limits<qint64>::max())
+ << std::numeric_limits<qint64>::min()
+ << true << true;
+ QTest::newRow("INT64_MIN-1") << raw("\x3b\x80\0\0\0""\0\0\0\0") << Q_UINT64_C(9223372036854775808) << qint64(-123456) << true << false;
+ QTest::newRow("-UINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
+ << (std::numeric_limits<quint64>::max() - 1) << qint64(-123456) << true << false;
+ QTest::newRow("-UINT64_MAX+1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
+ << std::numeric_limits<quint64>::max() << qint64(-123456) << true << false;
+}
+
+void addColumns()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QString>("expected");
+ QTest::addColumn<int>("n"); // some aux integer, not added in all columns
+}
+
+void addFixedData()
+{
+ // unsigned integers
+ QTest::newRow("0") << raw("\x00") << "0";
+ QTest::newRow("1") << raw("\x01") << "1";
+ QTest::newRow("10") << raw("\x0a") << "10";
+ QTest::newRow("23") << raw("\x17") << "23";
+ QTest::newRow("24") << raw("\x18\x18") << "24";
+ QTest::newRow("UINT8_MAX") << raw("\x18\xff") << "255";
+ QTest::newRow("UINT8_MAX+1") << raw("\x19\x01\x00") << "256";
+ QTest::newRow("UINT16_MAX") << raw("\x19\xff\xff") << "65535";
+ QTest::newRow("UINT16_MAX+1") << raw("\x1a\0\1\x00\x00") << "65536";
+ QTest::newRow("UINT32_MAX") << raw("\x1a\xff\xff\xff\xff") << "4294967295";
+ QTest::newRow("UINT32_MAX+1") << raw("\x1b\0\0\0\1\0\0\0\0") << "4294967296";
+ QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
+ << QString::number(std::numeric_limits<uint64_t>::max());
+
+ // negative integers
+ QTest::newRow("-1") << raw("\x20") << "-1";
+ QTest::newRow("-2") << raw("\x21") << "-2";
+ QTest::newRow("-24") << raw("\x37") << "-24";
+ QTest::newRow("-25") << raw("\x38\x18") << "-25";
+ QTest::newRow("-UINT8_MAX") << raw("\x38\xff") << "-256";
+ QTest::newRow("-UINT8_MAX-1") << raw("\x39\x01\x00") << "-257";
+ QTest::newRow("-UINT16_MAX") << raw("\x39\xff\xff") << "-65536";
+ QTest::newRow("-UINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << "-65537";
+ QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << "-4294967296";
+ QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << "-4294967297";
+ QTest::newRow("INT64_MIN+1") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xfe")
+ << QString::number(std::numeric_limits<int64_t>::min() + 1);
+ QTest::newRow("INT64_MIN") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xff")
+ << QString::number(std::numeric_limits<int64_t>::min());
+ QTest::newRow("INT64_MIN-1") << raw("\x3b\x80\0\0\0""\0\0\0\0") << "-9223372036854775809";
+ QTest::newRow("-UINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
+ << '-' + QString::number(std::numeric_limits<uint64_t>::max());
+ QTest::newRow("-UINT64_MAX+1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
+ << "-18446744073709551616";
+
+ // overlongs
+ QTest::newRow("0*1") << raw("\x18\x00") << "0_0";
+ QTest::newRow("0*2") << raw("\x19\x00\x00") << "0_1";
+ QTest::newRow("0*4") << raw("\x1a\0\0\0\0") << "0_2";
+ QTest::newRow("0*8") << raw("\x1b\0\0\0\0\0\0\0\0") << "0_3";
+ QTest::newRow("-1*1") << raw("\x38\x00") << "-1_0";
+ QTest::newRow("-1*2") << raw("\x39\x00\x00") << "-1_1";
+ QTest::newRow("-1*4") << raw("\x3a\0\0\0\0") << "-1_2";
+ QTest::newRow("-1*8") << raw("\x3b\0\0\0\0\0\0\0\0") << "-1_3";
+
+ QTest::newRow("simple0") << raw("\xe0") << "simple(0)";
+ QTest::newRow("simple19") << raw("\xf3") << "simple(19)";
+ QTest::newRow("false") << raw("\xf4") << "false";
+ QTest::newRow("true") << raw("\xf5") << "true";
+ QTest::newRow("null") << raw("\xf6") << "null";
+ QTest::newRow("undefined") << raw("\xf7") << "undefined";
+ QTest::newRow("simple32") << raw("\xf8\x20") << "simple(32)";
+ QTest::newRow("simple255") << raw("\xf8\xff") << "simple(255)";
+
+ // floating point
+
+ QTest::newRow("0.f16") << raw("\xf9\0\0") << "0.f16";
+ QTest::newRow("0.f") << raw("\xfa\0\0\0\0") << "0.f";
+ QTest::newRow("0.") << raw("\xfb\0\0\0\0\0\0\0\0") << "0.";
+ QTest::newRow("-1.f16") << raw("\xf9\xbc\x00") << "-1.f16";
+ QTest::newRow("-1.f") << raw("\xfa\xbf\x80\0\0") << "-1.f";
+ QTest::newRow("-1.") << raw("\xfb\xbf\xf0\0\0\0\0\0\0") << "-1.";
+ QTest::newRow("65504.f16") << raw("\xf9\x7b\xff") << "65504.f16";
+ QTest::newRow("16777215.f") << raw("\xfa\x4b\x7f\xff\xff") << "16777215.f";
+ QTest::newRow("16777215.") << raw("\xfb\x41\x6f\xff\xff\xe0\0\0\0") << "16777215.";
+ QTest::newRow("-16777215.f") << raw("\xfa\xcb\x7f\xff\xff") << "-16777215.f";
+ QTest::newRow("-16777215.") << raw("\xfb\xc1\x6f\xff\xff\xe0\0\0\0") << "-16777215.";
+
+ QTest::newRow("0.5f16") << raw("\xf9\x38\0") << "0.5f16";
+ QTest::newRow("0.5f") << raw("\xfa\x3f\0\0\0") << "0.5f";
+ QTest::newRow("0.5") << raw("\xfb\x3f\xe0\0\0\0\0\0\0") << "0.5";
+ QTest::newRow("2.f16^11-1") << raw("\xf9\x67\xff") << "2047.f16";
+ QTest::newRow("2.f^24-1") << raw("\xfa\x4b\x7f\xff\xff") << "16777215.f";
+ QTest::newRow("2.^53-1") << raw("\xfb\x43\x3f\xff\xff""\xff\xff\xff\xff") << "9007199254740991.";
+ QTest::newRow("2.f^64-epsilon") << raw("\xfa\x5f\x7f\xff\xff") << "18446742974197923840.f";
+ QTest::newRow("2.^64-epsilon") << raw("\xfb\x43\xef\xff\xff""\xff\xff\xff\xff") << "18446744073709549568.";
+ QTest::newRow("2.f^64") << raw("\xfa\x5f\x80\0\0") << "1.8446744073709552e+19f";
+ QTest::newRow("2.^64") << raw("\xfb\x43\xf0\0\0\0\0\0\0") << "1.8446744073709552e+19";
+
+ QTest::newRow("nan_f16") << raw("\xf9\x7e\x00") << "nan";
+ QTest::newRow("nan_f") << raw("\xfa\x7f\xc0\0\0") << "nan";
+ QTest::newRow("nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << "nan";
+ QTest::newRow("-inf_f16") << raw("\xf9\xfc\x00") << "-inf";
+ QTest::newRow("-inf_f") << raw("\xfa\xff\x80\0\0") << "-inf";
+ QTest::newRow("-inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << "-inf";
+ QTest::newRow("+inf_f16") << raw("\xf9\x7c\x00") << "inf";
+ QTest::newRow("+inf_f") << raw("\xfa\x7f\x80\0\0") << "inf";
+ QTest::newRow("+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << "inf";
+
+}
+
+void addNonChunkedStringsData()
+{
+ // byte strings
+ QTest::newRow("emptybytestring") << raw("\x40") << "h''";
+ QTest::newRow("bytestring1") << raw("\x41 ") << "h'20'";
+ QTest::newRow("bytestring1-nul") << raw("\x41\0") << "h'00'";
+ QTest::newRow("bytestring5") << raw("\x45Hello") << "h'48656c6c6f'";
+ QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234")
+ << "h'313233343536373839303132333435363738393031323334'";
+ QTest::newRow("bytestring256") << raw("\x59\1\0") + QByteArray(256, '3')
+ << "h'" + QString(256 * 2, '3') + '\'';
+
+ // text strings
+ QTest::newRow("emptytextstring") << raw("\x60") << "\"\"";
+ QTest::newRow("textstring1") << raw("\x61 ") << "\" \"";
+ QTest::newRow("textstring1-nul") << raw("\x61\0") << "\"\\u0000\"";
+ QTest::newRow("textstring5") << raw("\x65Hello") << "\"Hello\"";
+ QTest::newRow("textstring24") << raw("\x78\x18""123456789012345678901234")
+ << "\"123456789012345678901234\"";
+ QTest::newRow("textstring256") << raw("\x79\1\0") + QByteArray(256, '3')
+ << '"' + QString(256, '3') + '"';
+
+ // some strings with UTF-8 content
+ // we had a bug in the pretty dumper - see issue #54
+ QTest::newRow("textstringutf8-2char") << raw("\x62\xc2\xa0") << "\"\\u00A0\"";
+ QTest::newRow("textstringutf8-2char2") << raw("\x64\xc2\xa0\xc2\xa9") << "\"\\u00A0\\u00A9\"";
+ QTest::newRow("textstringutf8-3char") << raw("\x63\xe2\x88\x80") << "\"\\u2200\"";
+ QTest::newRow("textstringutf8-4char") << raw("\x64\xf0\x90\x88\x83") << "\"\\uD800\\uDE03\"";
+
+ // strings with overlong length
+ QTest::newRow("emptybytestring*1") << raw("\x58\x00") << "h''_0";
+ QTest::newRow("emptytextstring*1") << raw("\x78\x00") << "\"\"_0";
+ QTest::newRow("emptybytestring*2") << raw("\x59\x00\x00") << "h''_1";
+ QTest::newRow("emptytextstring*2") << raw("\x79\x00\x00") << "\"\"_1";
+ QTest::newRow("emptybytestring*4") << raw("\x5a\0\0\0\0") << "h''_2";
+ QTest::newRow("emptytextstring*4") << raw("\x7a\0\0\0\0") << "\"\"_2";
+ QTest::newRow("emptybytestring*8") << raw("\x5b\0\0\0\0\0\0\0\0") << "h''_3";
+ QTest::newRow("emptytextstring*8") << raw("\x7b\0\0\0\0\0\0\0\0") << "\"\"_3";
+ QTest::newRow("bytestring5*1") << raw("\x58\x05Hello") << "h'48656c6c6f'_0";
+ QTest::newRow("textstring5*1") << raw("\x78\x05Hello") << "\"Hello\"_0";
+ QTest::newRow("bytestring5*2") << raw("\x59\0\5Hello") << "h'48656c6c6f'_1";
+ QTest::newRow("textstring5*2") << raw("\x79\0\x05Hello") << "\"Hello\"_1";
+ QTest::newRow("bytestring5*4") << raw("\x5a\0\0\0\5Hello") << "h'48656c6c6f'_2";
+ QTest::newRow("textstring5*4") << raw("\x7a\0\0\0\x05Hello") << "\"Hello\"_2";
+ QTest::newRow("bytestring5*8") << raw("\x5b\0\0\0\0\0\0\0\5Hello") << "h'48656c6c6f'_3";
+ QTest::newRow("textstring5*8") << raw("\x7b\0\0\0\0\0\0\0\x05Hello") << "\"Hello\"_3";
+
+}
+
+void addStringsData()
+{
+ addNonChunkedStringsData();
+
+ // strings with undefined length
+ QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "(_ )";
+ QTest::newRow("_emptytextstring") << raw("\x7f\xff") << "(_ )";
+ QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << "(_ h'')";
+ QTest::newRow("_emptytextstring2") << raw("\x7f\x60\xff") << "(_ \"\")";
+ QTest::newRow("_emptybytestring2*1") << raw("\x5f\x58\x00\xff") << "(_ h''_0)";
+ QTest::newRow("_emptytextstring2*1") << raw("\x7f\x78\x00\xff") << "(_ \"\"_0)";
+ QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << "(_ h'', h'')";
+ QTest::newRow("_emptytextstring3") << raw("\x7f\x60\x60\xff") << "(_ \"\", \"\")";
+ QTest::newRow("_emptybytestring3*2") << raw("\x5f\x59\x00\x00\x40\xff") << "(_ h''_1, h'')";
+ QTest::newRow("_emptytextstring3*2") << raw("\x7f\x79\x00\x00\x60\xff") << "(_ \"\"_1, \"\")";
+ QTest::newRow("_bytestring5x2") << raw("\x5f\x43Hel\x42lo\xff") << "(_ h'48656c', h'6c6f')";
+ QTest::newRow("_textstring5x2") << raw("\x7f\x63Hel\x62lo\xff") << "(_ \"Hel\", \"lo\")";
+ QTest::newRow("_bytestring5x2*8*4") << raw("\x5f\x5b\0\0\0\0\0\0\0\3Hel\x5a\0\0\0\2lo\xff") << "(_ h'48656c'_3, h'6c6f'_2)";
+ QTest::newRow("_textstring5x2*8*4") << raw("\x7f\x7b\0\0\0\0\0\0\0\3Hel\x7a\0\0\0\2lo\xff") << "(_ \"Hel\"_3, \"lo\"_2)";
+ QTest::newRow("_bytestring5x5") << raw("\x5f\x41H\x41""e\x41l\x41l\x41o\xff") << "(_ h'48', h'65', h'6c', h'6c', h'6f')";
+ QTest::newRow("_textstring5x5") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "(_ \"H\", \"e\", \"l\", \"l\", \"o\")";
+ QTest::newRow("_bytestring5x6") << raw("\x5f\x41H\x41""e\x40\x41l\x41l\x41o\xff") << "(_ h'48', h'65', h'', h'6c', h'6c', h'6f')";
+ QTest::newRow("_textstring5x6") << raw("\x7f\x61H\x61""e\x61l\x60\x61l\x61o\xff") << "(_ \"H\", \"e\", \"l\", \"\", \"l\", \"o\")";
+}
+
+void addTagsData()
+{
+ // since parseOne() works recursively for tags, we can't test lone tags
+ QTest::newRow("tag0") << raw("\xc0\x00") << "0(0)";
+ QTest::newRow("tag1") << raw("\xc1\x00") << "1(0)";
+ QTest::newRow("tag24") << raw("\xd8\x18\x00") << "24(0)";
+ QTest::newRow("tag255") << raw("\xd8\xff\x00") << "255(0)";
+ QTest::newRow("tag256") << raw("\xd9\1\0\x00") << "256(0)";
+ QTest::newRow("tag65535") << raw("\xd9\xff\xff\x00") << "65535(0)";
+ QTest::newRow("tag65536") << raw("\xda\0\1\0\0\x00") << "65536(0)";
+ QTest::newRow("tagUINT32_MAX-1") << raw("\xda\xff\xff\xff\xff\x00") << "4294967295(0)";
+ QTest::newRow("tagUINT32_MAX") << raw("\xdb\0\0\0\1\0\0\0\0\x00") << "4294967296(0)";
+ QTest::newRow("tagUINT64_MAX") << raw("\xdb" "\xff\xff\xff\xff" "\xff\xff\xff\xff" "\x00")
+ << QString::number(std::numeric_limits<uint64_t>::max()) + "(0)";
+
+ // overlong tags
+ QTest::newRow("tag0*1") << raw("\xd8\0\x00") << "0_0(0)";
+ QTest::newRow("tag0*2") << raw("\xd9\0\0\x00") << "0_1(0)";
+ QTest::newRow("tag0*4") << raw("\xda\0\0\0\0\x00") << "0_2(0)";
+ QTest::newRow("tag0*8") << raw("\xdb\0\0\0\0\0\0\0\0\x00") << "0_3(0)";
+
+ // tag other things
+ QTest::newRow("unixtime") << raw("\xc1\x1a\x55\x4b\xbf\xd3") << "1(1431027667)";
+ QTest::newRow("rfc3339date") << raw("\xc0\x78\x19" "2015-05-07 12:41:07-07:00")
+ << "0(\"2015-05-07 12:41:07-07:00\")";
+ QTest::newRow("tag6+false") << raw("\xc6\xf4") << "6(false)";
+ QTest::newRow("tag25+true") << raw("\xd8\x19\xf5") << "25(true)";
+ QTest::newRow("tag256+null") << raw("\xd9\1\0\xf6") << "256(null)";
+ QTest::newRow("tag65536+simple32") << raw("\xda\0\1\0\0\xf8\x20") << "65536(simple(32))";
+ QTest::newRow("float+unixtime") << raw("\xc1\xfa\x4e\xaa\x97\x80") << "1(1431027712.f)";
+ QTest::newRow("double+unixtime") << raw("\xc1\xfb" "\x41\xd5\x52\xef" "\xf4\xc7\xce\xfe")
+ << "1(1431027667.1220088)";
+}
+
+void addEmptyContainersData()
+{
+ QTest::newRow("emptyarray") << raw("\x80") << "[]" << 0;
+ QTest::newRow("emptymap") << raw("\xa0") << "{}" << 0;
+ QTest::newRow("_emptyarray") << raw("\x9f\xff") << "[_ ]" << -1;
+ QTest::newRow("_emptymap") << raw("\xbf\xff") << "{_ }" << -1;
+}
+
+void addMapMixedData()
+{
+ QTest::newRow("map-0-24") << raw("\xa1\0\x18\x18") << "{0: 24}" << 1;
+ QTest::newRow("map-0*1-24") << raw("\xa1\x18\0\x18\x18") << "{0_0: 24}" << 1;
+ QTest::newRow("map-0*1-24*2") << raw("\xa1\x18\0\x19\0\x18") << "{0_0: 24_1}" << 1;
+ QTest::newRow("map-0*4-24*2") << raw("\xa1\x1a\0\0\0\0\x19\0\x18") << "{0_2: 24_1}" << 1;
+ QTest::newRow("map-24-0") << raw("\xa1\x18\x18\0") << "{24: 0}" << 1;
+ QTest::newRow("map-24-0*1") << raw("\xa1\x18\x18\x18\0") << "{24: 0_0}" << 1;
+ QTest::newRow("map-255-65535") << raw("\xa1\x18\xff\x19\xff\xff") << "{255: 65535}" << 1;
+
+ QTest::newRow("_map-0-24") << raw("\xbf\0\x18\x18\xff") << "{_ 0: 24}" << 1;
+ QTest::newRow("_map-0*1-24") << raw("\xbf\x18\0\x18\x18\xff") << "{_ 0_0: 24}" << 1;
+ QTest::newRow("_map-0*1-24*2") << raw("\xbf\x18\0\x19\0\x18\xff") << "{_ 0_0: 24_1}" << 1;
+ QTest::newRow("_map-0*4-24*2") << raw("\xbf\x1a\0\0\0\0\x19\0\x18\xff") << "{_ 0_2: 24_1}" << 1;
+ QTest::newRow("_map-24-0") << raw("\xbf\x18\x18\0\xff") << "{_ 24: 0}" << 1;
+ QTest::newRow("_map-24-0*1") << raw("\xbf\x18\x18\x18\0\xff") << "{_ 24: 0_0}" << 1;
+ QTest::newRow("_map-255-65535") << raw("\xbf\x18\xff\x19\xff\xff\xff") << "{_ 255: 65535}" << 1;
+}
+
+void addChunkedStringData()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QString>("concatenated");
+ QTest::addColumn<QStringList>("chunks");
+
+ // non-chunked:
+ QTest::newRow("emptybytestring") << raw("\x40") << "h''" << QStringList{"h''"};
+ QTest::newRow("bytestring1") << raw("\x41 ") << "h'20'" << QStringList{"h'20'"};
+ QTest::newRow("emptytextstring") << raw("\x60") << "\"\"" << QStringList{"\"\""};
+ QTest::newRow("textstring1") << raw("\x61 ") << "\" \"" << QStringList{"\" \""};
+
+ // empty chunked:
+ QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "h''" << QStringList{};
+ QTest::newRow("_emptytextstring") << raw("\x7f\xff") << "\"\"" << QStringList{};
+ QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << "h''" << QStringList{"h''"};
+ QTest::newRow("_emptytextstring2") << raw("\x7f\x60\xff") << "\"\"" << QStringList{"\"\""};
+ QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << "h''" << QStringList{"h''", "h''"};
+ QTest::newRow("_emptytextstring3") << raw("\x7f\x60\x60\xff") << "\"\"" << QStringList{"\"\"", "\"\""};
+
+ // regular chunks
+ QTest::newRow("_bytestring1") << raw("\x5f\x41 \xff") << "h'20'" << QStringList{"h'20'"};
+ QTest::newRow("_bytestring2") << raw("\x5f\x41 \x41z\xff") << "h'207a'" << QStringList{"h'20'", "h'7a'"};
+ QTest::newRow("_bytestring3") << raw("\x5f\x41 \x58\x18""123456789012345678901234\x41z\xff")
+ << "h'203132333435363738393031323334353637383930313233347a'"
+ << QStringList{"h'20'", "h'313233343536373839303132333435363738393031323334'", "h'7a'"};
+
+ QTest::newRow("_textstring1") << raw("\x7f\x61 \xff") << "\" \"" << QStringList{"\" \""};
+ QTest::newRow("_textstring2") << raw("\x7f\x61 \x61z\xff") << "\" z\"" << QStringList{"\" \"", "\"z\""};
+ QTest::newRow("_textstring3") << raw("\x7f\x61 \x78\x18""123456789012345678901234\x61z\xff")
+ << "\" 123456789012345678901234z\""
+ << QStringList{"\" \"", "\"123456789012345678901234\"", "\"z\""};
+}
+
+void addValidationColumns()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("flags"); // future
+ QTest::addColumn<CborError>("expectedError");
+}
+
+void addValidationData()
+{
+ // illegal numbers are future extension points
+ QTest::newRow("illegal-number-in-unsigned-1") << raw("\x81\x1c") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-unsigned-2") << raw("\x81\x1d") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-unsigned-3") << raw("\x81\x1e") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-unsigned-4") << raw("\x81\x1f") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-negative-1") << raw("\x81\x3c") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-negative-2") << raw("\x81\x3d") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-negative-3") << raw("\x81\x3e") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-negative-4") << raw("\x81\x3f") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-bytearray-length-1") << raw("\x81\x5c") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-bytearray-length-2") << raw("\x81\x5d") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-bytearray-length-3") << raw("\x81\x5e") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-string-length-1") << raw("\x81\x7c") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-string-length-2") << raw("\x81\x7d") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-string-length-3") << raw("\x81\x7e") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-array-length-1") << raw("\x81\x9c") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-array-length-2") << raw("\x81\x9d") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-array-length-3") << raw("\x81\x9e") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-map-length-1") << raw("\x81\xbc") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-map-length-2") << raw("\x81\xbd") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-map-length-3") << raw("\x81\xbe") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-tag-1") << raw("\x81\xdc") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-tag-2") << raw("\x81\xdd") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-tag-3") << raw("\x81\xde") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("illegal-number-in-tag-4") << raw("\x81\xdf") << 0 << CborErrorIllegalNumber;
+
+ QTest::newRow("unsigned-too-short-1-0") << raw("\x81\x18") << 0 << CborErrorUnexpectedEOF; // requires 1 byte, 0 given
+ QTest::newRow("unsigned-too-short-2-0") << raw("\x81\x19") << 0 << CborErrorUnexpectedEOF; // requires 2 bytes, 0 given
+ QTest::newRow("unsigned-too-short-2-1") << raw("\x81\x19\x01") << 0 << CborErrorUnexpectedEOF; // etc
+ QTest::newRow("unsigned-too-short-4-0") << raw("\x81\x1a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("unsigned-too-short-4-3") << raw("\x81\x1a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("unsigned-too-short-8-0") << raw("\x81\x1b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("unsigned-too-short-8-7") << raw("\x81\x1b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("negative-length-too-short-1-0") << raw("\x81\x38") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("negative-length-too-short-2-0") << raw("\x81\x39") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("negative-length-too-short-2-1") << raw("\x81\x39\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("negative-length-too-short-4-0") << raw("\x81\x3a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("negative-length-too-short-4-3") << raw("\x81\x3a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("negative-length-too-short-8-0") << raw("\x81\x3b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("negative-length-too-short-8-7") << raw("\x81\x3b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-length-too-short-1-0") << raw("\x81\x58") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-length-too-short-2-0") << raw("\x81\x59") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-length-too-short-2-1") << raw("\x81\x59\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-length-too-short-4-0") << raw("\x81\x5a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-length-too-short-4-3") << raw("\x81\x5a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-length-too-short-8-0") << raw("\x81\x5b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-length-too-short-8-7") << raw("\x81\x5b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-length-too-short-1-0") << raw("\x81\x78") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-length-too-short-2-0") << raw("\x81\x79") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-length-too-short-2-1") << raw("\x81\x79\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-length-too-short-4-0") << raw("\x81\x7a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-length-too-short-4-3") << raw("\x81\x7a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-length-too-short-8-0") << raw("\x81\x7b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-length-too-short-8-7") << raw("\x81\x7b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-length-too-short-1-0") << raw("\x81\x5f\x58") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-length-too-short-2-0") << raw("\x81\x5f\x59") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-length-too-short-2-1") << raw("\x81\x5f\x59\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-length-too-short-4-0") << raw("\x81\x5f\x5a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-length-too-short-4-3") << raw("\x81\x5f\x5a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-length-too-short-8-0") << raw("\x81\x5f\x5b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-length-too-short-8-7") << raw("\x81\x5f\x5b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-length-too-short-1-0") << raw("\x81\x7f\x78") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-length-too-short-2-0") << raw("\x81\x7f\x79") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-length-too-short-2-1") << raw("\x81\x7f\x79\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-length-too-short-4-0") << raw("\x81\x7f\x7a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-length-too-short-4-3") << raw("\x81\x7f\x7a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-length-too-short-8-0") << raw("\x81\x7f\x7b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-length-too-short-8-7") << raw("\x81\x7f\x7b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-2-length-too-short-1-0") << raw("\x81\x5f\x40\x58") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-2-length-too-short-2-0") << raw("\x81\x5f\x40\x59") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-2-length-too-short-2-1") << raw("\x81\x5f\x40\x59\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-2-length-too-short-4-0") << raw("\x81\x5f\x40\x5a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-2-length-too-short-4-3") << raw("\x81\x5f\x40\x5a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-2-length-too-short-8-0") << raw("\x81\x5f\x40\x5b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-2-length-too-short-8-7") << raw("\x81\x5f\x40\x5b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-2-length-too-short-1-0") << raw("\x81\x7f\x60\x78") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-2-length-too-short-2-0") << raw("\x81\x7f\x60\x79") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-2-length-too-short-2-1") << raw("\x81\x7f\x60\x79\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-2-length-too-short-4-0") << raw("\x81\x7f\x60\x7a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-2-length-too-short-4-3") << raw("\x81\x7f\x60\x7a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-2-length-too-short-8-0") << raw("\x81\x7f\x60\x7b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-2-length-too-short-8-7") << raw("\x81\x7f\x60\x7b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-length-too-short-1-0") << raw("\x81\x98") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-length-too-short-2-0") << raw("\x81\x99") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-length-too-short-2-1") << raw("\x81\x99\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-length-too-short-4-0") << raw("\x81\x9a") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-length-too-short-4-3") << raw("\x81\x9a\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-length-too-short-8-0") << raw("\x81\x9b") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-length-too-short-8-7") << raw("\x81\x9b\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-length-too-short-1-0") << raw("\x81\xb8") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-length-too-short-2-0") << raw("\x81\xb9") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-length-too-short-2-1") << raw("\x81\xb9\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-length-too-short-4-0") << raw("\x81\xba") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-length-too-short-4-3") << raw("\x81\xba\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-length-too-short-8-0") << raw("\x81\xbb") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-length-too-short-8-7") << raw("\x81\xbb\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("tag-too-short-1-0") << raw("\x81\xd8") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("tag-too-short-2-0") << raw("\x81\xd9") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("tag-too-short-2-1") << raw("\x81\xd9\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("tag-too-short-4-0") << raw("\x81\xda") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("tag-too-short-4-3") << raw("\x81\xda\x01\x02\x03") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("tag-too-short-8-0") << raw("\x81\xdb") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("tag-too-short-8-7") << raw("\x81\xdb\1\2\3\4\5\6\7") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("fp16-too-short1") << raw("\x81\xf9") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("fp16-too-short2") << raw("\x81\xf9\x00") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("float-too-short1") << raw("\x81\xfa") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("float-too-short2") << raw("\x81\xfa\0\0\0") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("double-too-short1") << raw("\x81\xfb") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("double-too-short2") << raw("\x81\xfb\0\0\0\0\0\0\0") << 0 << CborErrorUnexpectedEOF;
+
+ QTest::newRow("bytearray-too-short1") << raw("\x81\x42z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-too-short2") << raw("\x81\x58\x02z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-too-short3") << raw("\x81\x5a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-too-short4") << raw("\x81\x5b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-too-short1") << raw("\x81\x62z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-too-short2") << raw("\x81\x78\x02z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-too-short3") << raw("\x81\x7a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-too-short4") << raw("\x81\x7b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-too-short1") << raw("\x81\x5f\x42z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-too-short2") << raw("\x81\x5f\x58\x02z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-too-short3") << raw("\x81\x5f\x5a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-too-short4") << raw("\x81\x5f\x5b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-too-short1") << raw("\x81\x7f\x62z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-too-short2") << raw("\x81\x7f\x78\x02z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-too-short3") << raw("\x81\x7f\x7a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-too-short4") << raw("\x81\x7f\x7b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-too-short1x2") << raw("\x81\x5f\x40\x42z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-too-short2x2") << raw("\x81\x5f\x40\x58\x02z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-too-short3x2") << raw("\x81\x5f\x40\x5a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-chunked-too-short4x2") << raw("\x81\x5f\x40\x5b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-too-short1x2") << raw("\x81\x7f\x60\x62z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-too-short2x2") << raw("\x81\x7f\x60\x78\x02z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-too-short3x2") << raw("\x81\x7f\x60\x7a\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunked-too-short4x2") << raw("\x81\x7f\x60\x7b\0\0\0\0\0\0\0\2z") << 0 << CborErrorUnexpectedEOF;
+
+ QTest::newRow("bytearray-no-break1") << raw("\x81\x5f") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("bytearray-no-break2") << raw("\x81\x5f\x40") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-no-break1") << raw("\x81\x7f") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-no-break2") << raw("\x81\x7f\x60") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-no-break1") << raw("\x81\x9f") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("array-no-break2") << raw("\x81\x9f\0") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-no-break1") << raw("\x81\xbf") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-no-break2") << raw("\x81\xbf\0\0") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("map-break-after-key") << raw("\x81\xbf\0\xff") << 0 << CborErrorUnexpectedBreak;
+ QTest::newRow("map-break-after-value-tag") << raw("\x81\xbf\0\xc0\xff") << 0 << CborErrorUnexpectedBreak;
+ QTest::newRow("map-break-after-value-tag2") << raw("\x81\xbf\0\xd8\x20\xff") << 0 << CborErrorUnexpectedBreak;
+
+ // check for pointer additions wrapping over the limit of the address space
+ CborError tooLargeOn32bit = (sizeof(void *) == 4) ? CborErrorDataTooLarge : CborErrorUnexpectedEOF;
+ // on 32-bit systems, this is a -1
+ QTest::newRow("bytearray-wraparound1") << raw("\x81\x5a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-wraparound1") << raw("\x81\x7a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF;
+ // on 32-bit systems, a 4GB addition could be dropped
+ QTest::newRow("bytearray-wraparound2") << raw("\x81\x5b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit;
+ QTest::newRow("string-wraparound2") << raw("\x81\x7b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit;
+ // on 64-bit systems, this could be a -1
+ QTest::newRow("bytearray-wraparound3") << raw("\x81\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit;
+ QTest::newRow("string-wraparound3") << raw("\x81\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit;
+
+ // ditto on chunks
+ QTest::newRow("bytearray-chunk-wraparound1") << raw("\x81\x5f\x5a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("string-chunk-wraparound1") << raw("\x81\x7f\x7a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF;
+ // on 32-bit systems, a 4GB addition could be dropped
+ QTest::newRow("bytearray-chunk-wraparound2") << raw("\x81\x5f\x5b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit;
+ QTest::newRow("string-chunk-wraparound2") << raw("\x81\x7f\x7b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit;
+ // on 64-bit systems, this could be a -1
+ QTest::newRow("bytearray-chunk-wraparound3") << raw("\x81\x5f\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit;
+ QTest::newRow("string-chunk-wraparound3") << raw("\x81\x7f\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit;
+
+ QTest::newRow("eof-after-array") << raw("\x81") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("eof-after-array2") << raw("\x81\x78\x20") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("eof-after-array-element") << raw("\x81\x82\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("eof-after-object") << raw("\x81\xa1") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("eof-after-object2") << raw("\x81\xb8\x20") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("eof-after-object-key") << raw("\x81\xa1\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("eof-after-object-value") << raw("\x81\xa2\x01\x01") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("eof-after-tag") << raw("\x81\xc0") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("eof-after-tag2") << raw("\x81\xd8\x20") << 0 << CborErrorUnexpectedEOF;
+
+ // major type 7 has future types
+ QTest::newRow("future-type-28") << raw("\x81\xfc") << 0 << CborErrorUnknownType;
+ QTest::newRow("future-type-29") << raw("\x81\xfd") << 0 << CborErrorUnknownType;
+ QTest::newRow("future-type-30") << raw("\x81\xfe") << 0 << CborErrorUnknownType;
+ QTest::newRow("unexpected-break") << raw("\x81\xff") << 0 << CborErrorUnexpectedBreak;
+ QTest::newRow("illegal-simple-0") << raw("\x81\xf8\0") << 0 << CborErrorIllegalSimpleType;
+ QTest::newRow("illegal-simple-31") << raw("\x81\xf8\x1f") << 0 << CborErrorIllegalSimpleType;
+
+ // not only too big (UINT_MAX or UINT_MAX+1 in size), but also incomplete
+ if (sizeof(size_t) < sizeof(uint64_t)) {
+ QTest::newRow("bytearray-too-big1") << raw("\x81\x5b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge;
+ QTest::newRow("string-too-big1") << raw("\x81\x7b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge;
+ }
+ QTest::newRow("array-too-big1") << raw("\x81\x9a\xff\xff\xff\xff\0\0\0\0") << 0 << CborErrorDataTooLarge;
+ QTest::newRow("array-too-big2") << raw("\x81\x9b\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge;
+ QTest::newRow("object-too-big1") << raw("\x81\xba\xff\xff\xff\xff\0\0\0\0") << 0 << CborErrorDataTooLarge;
+ QTest::newRow("object-too-big2") << raw("\x81\xbb\0\0\0\1\0\0\0\0") << 0 << CborErrorDataTooLarge;
+
+ QTest::newRow("no-break-for-array0") << raw("\x81\x9f") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("no-break-for-array1") << raw("\x81\x9f\x01") << 0 << CborErrorUnexpectedEOF;
+
+ QTest::newRow("no-break-string0") << raw("\x81\x7f") << 0 << CborErrorUnexpectedEOF;
+ QTest::newRow("no-break-string1") << raw("\x81\x7f\x61Z") << 0 << CborErrorUnexpectedEOF;
+
+ QTest::newRow("nested-indefinite-length-bytearrays") << raw("\x81\x5f\x5f\xff\xff") << 0 << CborErrorIllegalNumber;
+ QTest::newRow("nested-indefinite-length-strings") << raw("\x81\x7f\x7f\xff\xff") << 0 << CborErrorIllegalNumber;
+
+ QTest::newRow("string-chunk-unsigned") << raw("\x81\x7f\0\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-negative") << raw("\x81\x7f\x20\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-bytearray") << raw("\x81\x7f\x40\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-array") << raw("\x81\x7f\x80\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-map") << raw("\x81\x7f\xa0\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-tag") << raw("\x81\x7f\xc0\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-tagged-string") << raw("\x81\x7f\xc0\x60\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-simple0") << raw("\x81\x7f\xe0\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-false") << raw("\x81\x7f\xf4\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-true") << raw("\x81\x7f\xf5\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-null") << raw("\x81\x7f\xf6\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("string-chunk-undefined") << raw("\x81\x7f\xf7\xff") << 0 << CborErrorIllegalType;
+
+ QTest::newRow("bytearray-chunk-string") << raw("\x81\x5f\x60\xff") << 0 << CborErrorIllegalType;
+ QTest::newRow("bytearray-chunk-tagged-bytearray") << raw("\x81\x7f\xc0\x40\xff") << 0 << CborErrorIllegalType;
+
+ // RFC 7049 Section 2.2.2 "Indefinite-Length Byte Strings and Text Strings" says
+ // Text strings with indefinite lengths act the same as byte strings
+ // with indefinite lengths, except that all their chunks MUST be
+ // definite-length text strings. Note that this implies that the bytes
+ // of a single UTF-8 character cannot be spread between chunks: a new
+ // chunk can only be started at a character boundary.
+ // This test technically tests the dumper, not the parser.
+ QTest::newRow("string-utf8-chunk-split") << raw("\x81\x7f\x61\xc2\x61\xa0\xff") << 0 << CborErrorInvalidUtf8TextString;
+}
diff --git a/src/3rdparty/tinycbor/tests/parser/parser.pro b/src/3rdparty/tinycbor/tests/parser/parser.pro
new file mode 100644
index 0000000000..a61291a9e4
--- /dev/null
+++ b/src/3rdparty/tinycbor/tests/parser/parser.pro
@@ -0,0 +1,10 @@
+SOURCES += tst_parser.cpp ../../src/cborparser.c
+
+CONFIG += testcase parallel_test c++11
+QT = core testlib
+DEFINES += CBOR_PARSER_MAX_RECURSIONS=16
+
+INCLUDEPATH += ../../src
+msvc: POST_TARGETDEPS = ../../lib/tinycbor.lib
+else: POST_TARGETDEPS += ../../lib/libtinycbor.a
+LIBS += $$POST_TARGETDEPS
diff --git a/src/3rdparty/tinycbor/tests/parser/tst_parser.cpp b/src/3rdparty/tinycbor/tests/parser/tst_parser.cpp
new file mode 100644
index 0000000000..74c480bc51
--- /dev/null
+++ b/src/3rdparty/tinycbor/tests/parser/tst_parser.cpp
@@ -0,0 +1,1667 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _XOPEN_SOURCE 700
+#include <QtTest>
+#include "cbor.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+namespace QTest {
+template<> char *toString<CborError>(const CborError &err)
+{
+ return qstrdup(cbor_error_string(err));
+}
+}
+
+class tst_Parser : public QObject
+{
+ Q_OBJECT
+private slots:
+ void initParserEmpty();
+
+ // parsing API
+ void integers_data();
+ void integers();
+ void fixed_data();
+ void fixed();
+ void strings_data();
+ void strings() { fixed(); }
+ void tags_data();
+ void tags() { fixed(); }
+ void tagTags_data() { tags_data(); }
+ void tagTags();
+ void emptyContainers_data();
+ void emptyContainers();
+ void arrays_data();
+ void arrays();
+ void undefLengthArrays_data() { arrays_data(); }
+ void undefLengthArrays();
+ void nestedArrays_data() { arrays_data(); }
+ void nestedArrays();
+ void maps_data();
+ void maps();
+ void undefLengthMaps_data() { maps_data(); }
+ void undefLengthMaps();
+ void nestedMaps_data() { maps_data(); }
+ void nestedMaps();
+ void mapMixed_data();
+ void mapMixed() { arrays(); }
+ void mapsAndArrays_data() { arrays_data(); }
+ void mapsAndArrays();
+
+ void readerApi_data() { arrays_data(); }
+ void readerApi();
+ void reparse_data();
+ void reparse();
+
+ // chunked string API
+ void chunkedString_data();
+ void chunkedString();
+ void chunkedStringInUndefArray_data() { chunkedString_data(); }
+ void chunkedStringInUndefArray();
+
+ // convenience API
+ void stringLength_data();
+ void stringLength();
+ void stringCompare_data();
+ void stringCompare();
+ void mapFind_data();
+ void mapFind();
+
+ // validation & errors
+ void checkedIntegers_data();
+ void checkedIntegers();
+ void validation_data();
+ void validation();
+ void strictValidation_data();
+ void strictValidation();
+ void incompleteData_data();
+ void incompleteData();
+ void endPointer_data();
+ void endPointer();
+ void recursionLimit_data();
+ void recursionLimit();
+};
+
+static CborError qstring_printf(void *out, const char *fmt, ...)
+{
+ auto str = static_cast<QString *>(out);
+ va_list va;
+ va_start(va, fmt);
+ *str += QString::vasprintf(fmt, va);
+ va_end(va);
+ return CborNoError;
+};
+
+CborError parseOne(CborValue *it, QString *parsed)
+{
+ int flags = CborPrettyShowStringFragments | CborPrettyIndicateIndeterminateLength |
+ CborPrettyIndicateOverlongNumbers;
+
+ parsed->clear();
+ return cbor_value_to_pretty_stream(qstring_printf, parsed, it, flags);
+}
+
+CborError parseOneChunk(CborValue *it, QString *parsed)
+{
+ CborError err;
+ CborType ourType = cbor_value_get_type(it);
+ if (ourType == CborByteStringType) {
+ const uint8_t *bytes;
+ size_t len;
+ err = cbor_value_get_byte_string_chunk(it, &bytes, &len, it);
+ if (err)
+ return err;
+
+ if (bytes)
+ *parsed = QString::fromLatin1("h'" +
+ QByteArray::fromRawData(reinterpret_cast<const char *>(bytes), len).toHex() +
+ '\'');
+ } else if (ourType == CborTextStringType) {
+ const char *text;
+ size_t len;
+ err = cbor_value_get_text_string_chunk(it, &text, &len, it);
+ if (err)
+ return err;
+
+ if (text)
+ *parsed = '"' + QString::fromUtf8(text, len) + '"';
+ } else {
+ Q_ASSERT(false);
+ }
+ return err;
+}
+
+void tst_Parser::initParserEmpty()
+{
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init((const quint8 *)"", 0, 0, &parser, &first);
+ QCOMPARE(err, CborErrorUnexpectedEOF);
+}
+
+bool compareFailed = true;
+void compareOne_real(const QByteArray &data, const QString &expected, int line, int n = -1)
+{
+ compareFailed = true;
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
+
+ if (cbor_value_get_type(&first) == CborArrayType) {
+ size_t len;
+ if (n >= 0) {
+ QVERIFY(cbor_value_is_length_known(&first));
+ QCOMPARE(cbor_value_get_array_length(&first, &len), CborNoError);
+ QCOMPARE(len, size_t(len));
+ } else {
+ QVERIFY(!cbor_value_is_length_known(&first));
+ QCOMPARE(cbor_value_get_array_length(&first, &len), CborErrorUnknownLength);
+ }
+ } else if (cbor_value_get_type(&first) == CborMapType) {
+ size_t len;
+ if (n >= 0) {
+ QVERIFY(cbor_value_is_length_known(&first));
+ QCOMPARE(cbor_value_get_map_length(&first, &len), CborNoError);
+ QCOMPARE(len, size_t(len));
+ } else {
+ QVERIFY(!cbor_value_is_length_known(&first));
+ QCOMPARE(cbor_value_get_map_length(&first, &len), CborErrorUnknownLength);
+ }
+ } else if (cbor_value_is_text_string(&first) || cbor_value_is_byte_string(&first)) {
+ size_t len;
+ QCOMPARE(cbor_value_calculate_string_length(&first, &len), CborNoError);
+ if (cbor_value_is_length_known(&first)) {
+ size_t len2;
+ QCOMPARE(cbor_value_get_string_length(&first, &len2), CborNoError);
+ QCOMPARE(len2, len);
+ } else {
+ QCOMPARE(cbor_value_get_string_length(&first, &len), CborErrorUnknownLength);
+ }
+ }
+
+ CborError err2 = cbor_value_validate_basic(&first);
+
+ QString decoded;
+ err = parseOne(&first, &decoded);
+ QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) +
+ "\"; decoded stream:\n" + decoded.toLatin1());
+ QCOMPARE(decoded, expected);
+
+ // check that the errors are the same
+ QCOMPARE(err2, err);
+
+ // check that we consumed everything
+ QCOMPARE((void*)cbor_value_get_next_byte(&first), (void*)data.constEnd());
+
+ compareFailed = false;
+}
+#define compareOne(data, expected) compareOne_real(data, expected, __LINE__)
+#define compareOneSize(n, data, expected) compareOne_real(data, expected, __LINE__, n)
+
+#include "data.cpp"
+
+void tst_Parser::integers_data()
+{
+ addIntegers();
+}
+
+void tst_Parser::integers()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(bool, isNegative);
+ QFETCH(quint64, expectedRaw);
+ QFETCH(qint64, expectedValue);
+ QFETCH(bool, inInt64Range);
+
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QVERIFY(cbor_value_is_integer(&first));
+
+ uint64_t raw;
+ cbor_value_get_raw_integer(&first, &raw);
+ QCOMPARE(quint64(raw), expectedRaw);
+
+ if (isNegative) {
+ QVERIFY(cbor_value_is_negative_integer(&first));
+ QVERIFY(!cbor_value_is_unsigned_integer(&first));
+ } else {
+ QVERIFY(!cbor_value_is_negative_integer(&first));
+ QVERIFY(cbor_value_is_unsigned_integer(&first));
+ }
+
+ int64_t value;
+ if (inInt64Range) {
+ cbor_value_get_int64(&first, &value);
+ QCOMPARE(qint64(value), expectedValue);
+ }
+
+ err = cbor_value_get_int64_checked(&first, &value);
+ QCOMPARE(err, inInt64Range ? CborNoError : CborErrorDataTooLarge);
+
+ int ivalue;
+ bool inIntRange = inInt64Range && (expectedValue == int(expectedValue));
+ err = cbor_value_get_int_checked(&first, &ivalue);
+ QCOMPARE(err, inIntRange ? CborNoError : CborErrorDataTooLarge);
+}
+
+void tst_Parser::fixed_data()
+{
+ addColumns();
+ addFixedData();
+}
+
+void tst_Parser::fixed()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ compareOne(data, expected);
+}
+
+void tst_Parser::strings_data()
+{
+ addColumns();
+ addStringsData();
+}
+
+void tst_Parser::tags_data()
+{
+ addColumns();
+ addTagsData();
+}
+
+void tst_Parser::tagTags()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ compareOne("\xd9\xd9\xf7" + data, "55799(" + expected + ')');
+ if (!compareFailed)
+ compareOne("\xd9\xd9\xf7" "\xd9\xd9\xf7" + data, "55799(55799(" + expected + "))");
+}
+
+void tst_Parser::emptyContainers_data()
+{
+ addColumns();
+ addEmptyContainersData();
+}
+
+void tst_Parser::emptyContainers()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ QFETCH(int, n);
+
+ compareOneSize(n, data, expected);
+}
+
+void tst_Parser::arrays_data()
+{
+ addColumns();
+ addFixedData();
+ addStringsData();
+ addTagsData();
+}
+
+void tst_Parser::arrays()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ compareOneSize(1, "\x81" + data, '[' + expected + ']');
+ if (compareFailed) return;
+
+ compareOneSize(2, "\x82" + data + data, '[' + expected + ", " + expected + ']');
+ if (compareFailed) return;
+
+ // overlong length
+ compareOneSize(1, "\x98\1" + data, "[_0 " + expected + ']');
+ if (compareFailed) return;
+ compareOneSize(1, raw("\x99\0\1") + data, "[_1 " + expected + ']');
+ if (compareFailed) return;
+ compareOneSize(1, raw("\x9a\0\0\0\1") + data, "[_2 " + expected + ']');
+ if (compareFailed) return;
+ compareOneSize(1, raw("\x9b\0\0\0\0\0\0\0\1") + data, "[_3 " + expected + ']');
+ if (compareFailed) return;
+
+ // medium-sized array: 32 elements (1 << 5)
+ expected += ", ";
+ for (int i = 0; i < 5; ++i) {
+ data += data;
+ expected += expected;
+ }
+ expected.chop(2); // remove the last ", "
+ compareOneSize(32, "\x98\x20" + data, '[' + expected + ']');
+ if (compareFailed) return;
+
+ // large array: 256 elements (32 << 3)
+ expected += ", ";
+ for (int i = 0; i < 3; ++i) {
+ data += data;
+ expected += expected;
+ }
+ expected.chop(2); // remove the last ", "
+ compareOneSize(256, raw("\x99\1\0") + data, '[' + expected + ']');
+ if (compareFailed) return;
+}
+
+void tst_Parser::undefLengthArrays()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ compareOne("\x9f" + data + "\xff", "[_ " + expected + ']');
+ if (compareFailed) return;
+
+ compareOne("\x9f" + data + data + "\xff", "[_ " + expected + ", " + expected + ']');
+}
+
+void tst_Parser::nestedArrays()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ compareOneSize(1, "\x81\x81" + data, "[[" + expected + "]]");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\x81\x81\x81" + data, "[[[" + expected + "]]]");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\x81\x82" + data + data, "[[" + expected + ", " + expected + "]]");
+ if (compareFailed) return;
+
+ compareOneSize(2, "\x82\x81" + data + data, "[[" + expected + "], " + expected + "]");
+ if (compareFailed) return;
+
+ compareOneSize(2, "\x82\x81" + data + '\x81' + data, "[[" + expected + "], [" + expected + "]]");
+ if (compareFailed) return;
+
+ // undefined length
+ compareOneSize(-1, "\x9f\x9f" + data + data + "\xff\xff", "[_ [_ " + expected + ", " + expected + "]]");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\x9f\x9f" + data + "\xff\x9f" + data + "\xff\xff", "[_ [_ " + expected + "], [_ " + expected + "]]");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\x9f\x9f" + data + data + "\xff\x9f" + data + "\xff\xff",
+ "[_ [_ " + expected + ", " + expected + "], [_ " + expected + "]]");
+ if (compareFailed) return;
+
+ // mix them
+ compareOneSize(1, "\x81\x9f" + data + "\xff", "[[_ " + expected + "]]");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\x9f\x81" + data + "\xff", "[_ [" + expected + "]]");
+}
+
+void tst_Parser::maps_data()
+{
+ arrays_data();
+}
+
+void tst_Parser::maps()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ // integer key
+ compareOneSize(1, "\xa1\1" + data, "{1: " + expected + '}');
+ if (compareFailed) return;
+
+ // string key
+ compareOneSize(1, "\xa1\x65" "Hello" + data, "{\"Hello\": " + expected + '}');
+ if (compareFailed) return;
+
+ // map to self
+ compareOneSize(1, "\xa1" + data + data, '{' + expected + ": " + expected + '}');
+ if (compareFailed) return;
+
+ // two integer keys
+ compareOneSize(2, "\xa2\1" + data + "\2" + data, "{1: " + expected + ", 2: " + expected + '}');
+ if (compareFailed) return;
+
+ // OneSize integer and OneSize string key
+ compareOneSize(2, "\xa2\1" + data + "\x65" "Hello" + data, "{1: " + expected + ", \"Hello\": " + expected + '}');
+ if (compareFailed) return;
+}
+
+void tst_Parser::undefLengthMaps()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ // integer key
+ compareOne("\xbf\1" + data + '\xff', "{_ 1: " + expected + '}');
+ if (compareFailed) return;
+
+ compareOne("\xbf\1" + data + '\2' + data + '\xff', "{_ 1: " + expected + ", 2: " + expected + '}');
+ if (compareFailed) return;
+
+ compareOne("\xbf\1" + data + "\x65Hello" + data + '\xff', "{_ 1: " + expected + ", \"Hello\": " + expected + '}');
+ if (compareFailed) return;
+
+ compareOne("\xbf\x65Hello" + data + '\1' + data + '\xff', "{_ \"Hello\": " + expected + ", 1: " + expected + '}');
+}
+
+void tst_Parser::nestedMaps()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ // nested maps as values
+ compareOneSize(1, "\xa1\1\xa1\2" + data, "{1: {2: " + expected + "}}");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\xa1\x65Hello\xa1\2" + data, "{\"Hello\": {2: " + expected + "}}");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\xa1\1\xa2\2" + data + '\x20' + data, "{1: {2: " + expected + ", -1: " + expected + "}}");
+ if (compareFailed) return;
+
+ compareOneSize(2, "\xa2\1\xa1\2" + data + "\2\xa1\x20" + data, "{1: {2: " + expected + "}, 2: {-1: " + expected + "}}");
+ if (compareFailed) return;
+
+ // nested maps as keys
+ compareOneSize(1, "\xa1\xa1\xf4" + data + "\xf5", "{{false: " + expected + "}: true}");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\xa1\xa1" + data + data + "\xa1" + data + data,
+ "{{" + expected + ": " + expected + "}: {" + expected + ": " + expected + "}}");
+ if (compareFailed) return;
+
+ // undefined length
+ compareOneSize(-1, "\xbf\1\xbf\2" + data + "\xff\xff", "{_ 1: {_ 2: " + expected + "}}");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\xbf\1\xbf\2" + data + '\x20' + data + "\xff\xff", "{_ 1: {_ 2: " + expected + ", -1: " + expected + "}}");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\xbf\1\xbf\2" + data + "\xff\2\xbf\x20" + data + "\xff\xff",
+ "{_ 1: {_ 2: " + expected + "}, 2: {_ -1: " + expected + "}}");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\xbf\xbf" + data + data + "\xff\xbf" + data + data + "\xff\xff",
+ "{_ {_ " + expected + ": " + expected + "}: {_ " + expected + ": " + expected + "}}");
+ if (compareFailed) return;
+
+ // mix them
+ compareOneSize(1, "\xa1\1\xbf\2" + data + "\xff", "{1: {_ 2: " + expected + "}}");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\xbf\1\xa1\2" + data + "\xff", "{_ 1: {2: " + expected + "}}");
+ if (compareFailed) return;
+}
+
+void tst_Parser::mapMixed_data()
+{
+ addColumns();
+ addMapMixedData();
+}
+
+void tst_Parser::mapsAndArrays()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ // arrays of maps
+ compareOneSize(1, "\x81\xa1\1" + data, "[{1: " + expected + "}]");
+ if (compareFailed) return;
+
+ compareOneSize(2, "\x82\xa1\1" + data + "\xa1\2" + data, "[{1: " + expected + "}, {2: " + expected + "}]");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\x81\xa2\1" + data + "\2" + data, "[{1: " + expected + ", 2: " + expected + "}]");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\x9f\xa1\1" + data + "\xff", "[_ {1: " + expected + "}]");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\x81\xbf\1" + data + "\xff", "[{_ 1: " + expected + "}]");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\x9f\xbf\1" + data + "\xff\xff", "[_ {_ 1: " + expected + "}]");
+ if (compareFailed) return;
+
+ // maps of arrays
+ compareOneSize(1, "\xa1\1\x81" + data, "{1: [" + expected + "]}");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\xa1\1\x82" + data + data, "{1: [" + expected + ", " + expected + "]}");
+ if (compareFailed) return;
+
+ compareOneSize(2, "\xa2\1\x81" + data + "\x65Hello\x81" + data, "{1: [" + expected + "], \"Hello\": [" + expected + "]}");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\xa1\1\x9f" + data + "\xff", "{1: [_ " + expected + "]}");
+ if (compareFailed) return;
+
+ compareOneSize(1, "\xa1\1\x9f" + data + data + "\xff", "{1: [_ " + expected + ", " + expected + "]}");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\xbf\1\x81" + data + "\xff", "{_ 1: [" + expected + "]}");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\xbf\1\x9f" + data + "\xff\xff", "{_ 1: [_ " + expected + "]}");
+ if (compareFailed) return;
+
+ compareOneSize(-1, "\xbf\1\x9f" + data + data + "\xff\xff", "{_ 1: [_ " + expected + ", " + expected + "]}");
+ if (compareFailed) return;
+
+ // mixed with indeterminate length strings
+ compareOneSize(-1, "\xbf\1\x9f" + data + "\xff\x65Hello\xbf" + data + "\x7f\xff\xff\xff",
+ "{_ 1: [_ " + expected + "], \"Hello\": {_ " + expected + ": (_ )}}");
+}
+
+struct Input {
+ QByteArray data;
+ int consumed;
+};
+
+static const CborParserOperations byteArrayOps = {
+ /* can_read_bytes = */ [](void *token, size_t len) {
+ auto input = static_cast<Input *>(token);
+ return input->data.size() - input->consumed >= int(len);
+ },
+ /* read_bytes = */ [](void *token, void *dst, size_t offset, size_t len) {
+ auto input = static_cast<Input *>(token);
+ return memcpy(dst, input->data.constData() + input->consumed + offset, len);
+ },
+ /* advance_bytes = */ [](void *token, size_t len) {
+ auto input = static_cast<Input *>(token);
+ input->consumed += int(len);
+ },
+ /* transfer_string = */ [](void *token, const void **userptr, size_t offset, size_t len) {
+ // ###
+ auto input = static_cast<Input *>(token);
+ if (input->data.size() - input->consumed < int(len + offset))
+ return CborErrorUnexpectedEOF;
+ input->consumed += int(offset);
+ *userptr = input->data.constData() + input->consumed;
+ input->consumed += int(len);
+ return CborNoError;
+ }
+};
+
+void tst_Parser::readerApi()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ Input input = { data, 0 };
+
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init_reader(&byteArrayOps, &parser, &first, &input);
+ QCOMPARE(err, CborNoError);
+
+ QString decoded;
+ err = parseOne(&first, &decoded);
+ QCOMPARE(err, CborNoError);
+ QCOMPARE(decoded, expected);
+
+ // check we consumed everything
+ QCOMPARE(input.consumed, data.size());
+}
+
+void tst_Parser::reparse_data()
+{
+ // only one-item rows
+ addColumns();
+ addFixedData();
+}
+
+void tst_Parser::reparse()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ Input input = { QByteArray(), 0 };
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init_reader(&byteArrayOps, &parser, &first, &input);
+ QCOMPARE(err, CborErrorUnexpectedEOF);
+
+ for (int i = 0; i < data.size(); ++i) {
+ input.data = data.left(i);
+ err = cbor_value_reparse(&first);
+ if (err != CborErrorUnexpectedEOF)
+ qDebug() << "At" << i;
+ QCOMPARE(err, CborErrorUnexpectedEOF);
+ QCOMPARE(input.consumed, 0);
+ }
+
+ // now it should work
+ input.data = data;
+ err = cbor_value_reparse(&first);
+ QCOMPARE(err, CborNoError);
+
+ QString decoded;
+ err = parseOne(&first, &decoded);
+ QCOMPARE(err, CborNoError);
+ QCOMPARE(decoded, expected);
+
+ // check we consumed everything
+ QCOMPARE(input.consumed, data.size());
+}
+
+void tst_Parser::chunkedString_data()
+{
+ addChunkedStringData();
+}
+
+static void chunkedStringTest(const QByteArray &data, const QString &concatenated,
+ QStringList &chunks, CborType ourType)
+{
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ CborValue value;
+ QVERIFY(cbor_value_is_array(&first));
+ err = cbor_value_enter_container(&first, &value);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QVERIFY(cbor_value_is_byte_string(&value) || cbor_value_is_text_string(&value));
+
+ CborValue copy = value;
+
+ err = cbor_value_begin_string_iteration(&value);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ forever {
+ QString decoded;
+ err = parseOneChunk(&value, &decoded);
+ if (err == CborErrorNoMoreStringChunks)
+ break; // last chunk
+
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ QVERIFY2(!chunks.isEmpty(), "Too many chunks");
+ QString expected = chunks.takeFirst();
+ QCOMPARE(decoded, expected);
+ }
+
+ err = cbor_value_finish_string_iteration(&value);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QVERIFY2(chunks.isEmpty(), "Too few chunks");
+
+ // compare to the concatenated data
+ {
+ size_t n;
+ err = cbor_value_calculate_string_length(&copy, &n);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ QByteArray buffer(n, Qt::Uninitialized);
+ QString formatted;
+ if (cbor_value_is_byte_string(&copy)) {
+ err = cbor_value_copy_byte_string(&copy, (uint8_t *)buffer.data(), &n, nullptr);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QCOMPARE(int(n), buffer.size());
+
+ formatted = QString::fromLatin1("h'" + buffer.toHex() + '\'');
+ } else {
+ err = cbor_value_copy_text_string(&copy, buffer.data(), &n, nullptr);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QCOMPARE(int(n), buffer.size());
+
+ formatted = '"' + QString::fromUtf8(buffer.data(), n) + '"';
+ }
+ QCOMPARE(formatted, concatenated);
+ }
+
+ // confirm that the extra string we appended is still here
+ QVERIFY(!cbor_value_at_end(&value));
+ QCOMPARE(cbor_value_get_type(&value), ourType);
+ size_t len;
+ err = cbor_value_get_string_length(&value, &len);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QCOMPARE(len, size_t(0));
+
+ err = cbor_value_advance(&value);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ // confirm EOF
+ QVERIFY(cbor_value_at_end(&value));
+
+ err = cbor_value_leave_container(&first, &value);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QCOMPARE((void*)cbor_value_get_next_byte(&first), (void*)data.constEnd());
+}
+
+void tst_Parser::chunkedString()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, concatenated);
+ QFETCH(QStringList, chunks);
+
+ // Make this an array of two entries, with the second an empty byte or text string
+ CborType ourType = CborType(data.at(0) & 0xe0);
+ data.prepend(char(0x82));
+ data.append(ourType);
+
+ chunkedStringTest(data, concatenated, chunks, ourType);
+}
+
+void tst_Parser::chunkedStringInUndefArray()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, concatenated);
+ QFETCH(QStringList, chunks);
+
+ // Make this an array of undefined length entries, with the second entry an empty byte or text string
+ CborType ourType = CborType(data.at(0) & 0xe0);
+ data.prepend(char(0x9f));
+ data.append(ourType);
+ data.append(char(0xff));
+
+ chunkedStringTest(data, concatenated, chunks, ourType);
+}
+
+void tst_Parser::stringLength_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("expected");
+
+ QTest::newRow("emptybytestring") << raw("\x40") << 0;
+ QTest::newRow("bytestring1") << raw("\x41 ") << 1;
+ QTest::newRow("bytestring1-nul") << raw("\x41\0") << 1;
+ QTest::newRow("bytestring5") << raw("\x45Hello") << 5;
+ QTest::newRow("bytestring24") << raw("\x58\x18""123456789012345678901234") << 24;
+ QTest::newRow("bytestring256") << raw("\x59\1\0") + QByteArray(256, '3') << 256;
+
+ // text strings
+ QTest::newRow("emptytextstring") << raw("\x60") << 0;
+ QTest::newRow("textstring1") << raw("\x61 ") << 1;
+ QTest::newRow("textstring1-nul") << raw("\x61\0") << 1;
+ QTest::newRow("textstring5") << raw("\x65Hello") << 5;
+ QTest::newRow("textstring24") << raw("\x78\x18""123456789012345678901234") << 24;
+ QTest::newRow("textstring256") << raw("\x79\1\0") + QByteArray(256, '3') << 256;
+
+ // strings with overlong length
+ QTest::newRow("emptybytestring*1") << raw("\x58\x00") << 0;
+ QTest::newRow("emptytextstring*1") << raw("\x78\x00") << 0;
+ QTest::newRow("emptybytestring*2") << raw("\x59\x00\x00") << 0;
+ QTest::newRow("emptytextstring*2") << raw("\x79\x00\x00") << 0;
+ QTest::newRow("emptybytestring*4") << raw("\x5a\0\0\0\0") << 0;
+ QTest::newRow("emptytextstring*4") << raw("\x7a\0\0\0\0") << 0;
+ QTest::newRow("emptybytestring*8") << raw("\x5b\0\0\0\0\0\0\0\0") << 0;
+ QTest::newRow("emptytextstring*8") << raw("\x7b\0\0\0\0\0\0\0\0") << 0;
+ QTest::newRow("bytestring5*1") << raw("\x58\x05Hello") << 5;
+ QTest::newRow("textstring5*1") << raw("\x78\x05Hello") << 5;
+ QTest::newRow("bytestring5*2") << raw("\x59\0\5Hello") << 5;
+ QTest::newRow("textstring5*2") << raw("\x79\0\x05Hello") << 5;
+ QTest::newRow("bytestring5*4") << raw("\x5a\0\0\0\5Hello") << 5;
+ QTest::newRow("textstring5*4") << raw("\x7a\0\0\0\x05Hello") << 5;
+ QTest::newRow("bytestring5*8") << raw("\x5b\0\0\0\0\0\0\0\5Hello") << 5;
+ QTest::newRow("textstring5*8") << raw("\x7b\0\0\0\0\0\0\0\x05Hello") << 5;
+
+ // strings with undefined length
+ QTest::newRow("_emptybytestring") << raw("\x5f\xff") << 0;
+ QTest::newRow("_emptytextstring") << raw("\x7f\xff") << 0;
+ QTest::newRow("_emptybytestring2") << raw("\x5f\x40\xff") << 0;
+ QTest::newRow("_emptytextstring2") << raw("\x7f\x60\xff") << 0;
+ QTest::newRow("_emptybytestring3") << raw("\x5f\x40\x40\xff") << 0;
+ QTest::newRow("_emptytextstring3") << raw("\x7f\x60\x60\xff") << 0;
+ QTest::newRow("_bytestring5*2") << raw("\x5f\x43Hel\x42lo\xff") << 5;
+ QTest::newRow("_textstring5*2") << raw("\x7f\x63Hel\x62lo\xff") << 5;
+ QTest::newRow("_bytestring5*5") << raw("\x5f\x41H\x41""e\x41l\x41l\x41o\xff") << 5;
+ QTest::newRow("_textstring5*5") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << 5;
+ QTest::newRow("_bytestring5*6") << raw("\x5f\x41H\x41""e\x40\x41l\x41l\x41o\xff") << 5;
+ QTest::newRow("_textstring5*6") << raw("\x7f\x61H\x61""e\x61l\x60\x61l\x61o\xff") << 5;
+}
+
+void tst_Parser::stringLength()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, expected);
+
+ CborParser parser;
+ CborValue value;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ size_t result;
+ err = cbor_value_calculate_string_length(&value, &result);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QCOMPARE(result, size_t(expected));
+
+ if (cbor_value_is_length_known(&value)) {
+ QCOMPARE(cbor_value_get_string_length(&value, &result), CborNoError);
+ QCOMPARE(result, size_t(expected));
+ }
+
+}
+
+void tst_Parser::stringCompare_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<bool>("expected");
+
+ // compare empty to empty
+ QTest::newRow("empty-empty") << raw("\x60") << QString() << true;
+ QTest::newRow("_empty-empty") << raw("\x7f\xff") << QString() << true;
+ QTest::newRow("_empty*1-empty") << raw("\x7f\x60\xff") << QString() << true;
+ QTest::newRow("_empty*2-empty") << raw("\x7f\x60\x60\xff") << QString() << true;
+
+ // compare empty to non-empty
+ QTest::newRow("empty-nonempty") << raw("\x60") << "Hello" << false;
+ QTest::newRow("_empty-nonempty") << raw("\x7f\xff") << "Hello" << false;
+ QTest::newRow("_empty*1-nonempty") << raw("\x7f\x60\xff") << "Hello" << false;
+ QTest::newRow("_empty*2-nonempty") << raw("\x7f\x60\x60\xff") << "Hello" << false;
+
+ // compare same strings
+ QTest::newRow("same-short-short") << raw("\x65Hello") << "Hello" << true;
+ QTest::newRow("same-_short*1-short") << raw("\x7f\x65Hello\xff") << "Hello" << true;
+ QTest::newRow("same-_short*2-short") << raw("\x7f\x63Hel\x62lo\xff") << "Hello" << true;
+ QTest::newRow("same-_short*5-short") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "Hello" << true;
+ QTest::newRow("same-_short*8-short") << raw("\x7f\x61H\x60\x61""e\x60\x61l\x61l\x60\x61o\xff") << "Hello" << true;
+ QTest::newRow("same-long-long") << raw("\x78\x2aGood morning, good afternoon and goodnight")
+ << "Good morning, good afternoon and goodnight" << true;
+ QTest::newRow("same-_long*1-long") << raw("\x7f\x78\x2aGood morning, good afternoon and goodnight\xff")
+ << "Good morning, good afternoon and goodnight" << true;
+ QTest::newRow("same-_long*2-long") << raw("\x7f\x78\x1cGood morning, good afternoon\x6e and goodnight\xff")
+ << "Good morning, good afternoon and goodnight" << true;
+
+ // compare different strings (same length)
+ QTest::newRow("diff-same-length-short-short") << raw("\x65Hello") << "World" << false;
+ QTest::newRow("diff-same-length-_short*1-short") << raw("\x7f\x65Hello\xff") << "World" << false;
+ QTest::newRow("diff-same-length-_short*2-short") << raw("\x7f\x63Hel\x62lo\xff") << "World" << false;
+ QTest::newRow("diff-same-length-_short*5-short") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "World" << false;
+ QTest::newRow("diff-same-length-_short*8-short") << raw("\x7f\x61H\x60\x61""e\x60\x61l\x61l\x60\x61o\xff") << "World" << false;
+ QTest::newRow("diff-same-length-long-long") << raw("\x78\x2aGood morning, good afternoon and goodnight")
+ << "Good morning, good afternoon and goodnight, world" << false;
+ QTest::newRow("diff-same-length-_long*1-long") << raw("\x7f\x78\x2aGood morning, good afternoon and goodnight\xff")
+ << "Good morning, good afternoon and goodnight, world" << false;
+ QTest::newRow("diff-same-length-_long*2-long") << raw("\x7f\x78\x1cGood morning, good afternoon\x6e and goodnight\xff")
+ << "Good morning, good afternoon and goodnight, world" << false;
+
+ // compare different strings (different length)
+ QTest::newRow("diff-diff-length-short-short") << raw("\x65Hello") << "Hello World" << false;
+ QTest::newRow("diff-diff-length-_short*1-short") << raw("\x7f\x65Hello\xff") << "Hello World" << false;
+ QTest::newRow("diff-diff-length-_short*2-short") << raw("\x7f\x63Hel\x62lo\xff") << "Hello World" << false;
+ QTest::newRow("diff-diff-length-_short*5-short") << raw("\x7f\x61H\x61""e\x61l\x61l\x61o\xff") << "Hello World" << false;
+ QTest::newRow("diff-diff-length-_short*8-short") << raw("\x7f\x61H\x60\x61""e\x60\x61l\x61l\x60\x61o\xff") << "Hello World" << false;
+ QTest::newRow("diff-diff-length-long-long") << raw("\x78\x2aGood morning, good afternoon and goodnight")
+ << "Good morning, good afternoon and goodnight World" << false;
+ QTest::newRow("diff-diff-length-_long*1-long") << raw("\x7f\x78\x2aGood morning, good afternoon and goodnight\xff")
+ << "Good morning, good afternoon and goodnight World" << false;
+ QTest::newRow("diff-diff-length-_long*2-long") << raw("\x7f\x78\x1cGood morning, good afternoon\x6e and goodnight\xff")
+ << "Good morning, good afternoon and goodnight World" << false;
+
+ // compare against non-strings
+ QTest::newRow("unsigned") << raw("\0") << "0" << false;
+ QTest::newRow("negative") << raw("\x20") << "-1" << false;
+ QTest::newRow("emptybytestring") << raw("\x40") << "" << false;
+ QTest::newRow("_emptybytestring") << raw("\x5f\xff") << "" << false;
+ QTest::newRow("shortbytestring") << raw("\x45Hello") << "Hello" << false;
+ QTest::newRow("longbytestring") << raw("\x58\x2aGood morning, good afternoon and goodnight")
+ << "Good morning, good afternoon and goodnight" << false;
+ QTest::newRow("emptyarray") << raw("\x80") << "" << false;
+ QTest::newRow("emptymap") << raw("\xa0") << "" << false;
+ QTest::newRow("array") << raw("\x81\x65Hello") << "Hello" << false;
+ QTest::newRow("map") << raw("\xa1\x65Hello\x65World") << "Hello World" << false;
+ QTest::newRow("false") << raw("\xf4") << "false" << false;
+ QTest::newRow("true") << raw("\xf5") << "true" << false;
+ QTest::newRow("null") << raw("\xf6") << "null" << false;
+}
+
+void compareOneString(const QByteArray &data, const QString &string, bool expected, int line)
+{
+ compareFailed = true;
+
+ CborParser parser;
+ CborValue value;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
+ QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
+
+ bool result;
+ QByteArray bastring = string.toUtf8();
+ err = cbor_value_text_string_equals(&value, bastring.constData(), &result);
+ QVERIFY2(!err, QByteArray::number(line) + ": Got error \"" + cbor_error_string(err) + "\"");
+ QCOMPARE(result, expected);
+
+ if (expected) {
+ size_t len;
+ cbor_value_skip_tag(&value);
+ if (cbor_value_is_length_known(&value)) {
+ QCOMPARE(cbor_value_get_string_length(&value, &len), CborNoError);
+ QCOMPARE(int(len), bastring.size());
+ }
+ QCOMPARE(cbor_value_calculate_string_length(&value, &len), CborNoError);
+ QCOMPARE(int(len), bastring.size());
+ }
+
+ compareFailed = false;
+}
+#define compareOneString(data, string, expected) compareOneString(data, string, expected, __LINE__)
+
+void tst_Parser::stringCompare()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, string);
+ QFETCH(bool, expected);
+
+ compareOneString(data, string, expected);
+ if (compareFailed) return;
+
+ // tag it
+ compareOneString("\xc1" + data, string, expected);
+ if (compareFailed) return;
+
+ compareOneString("\xc1\xc2" + data, string, expected);
+}
+
+void tst_Parser::mapFind_data()
+{
+ // Rules:
+ // we are searching for string "needle"
+ // if present, the value should be the string "haystack" (with tag 42)
+
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<bool>("expected");
+
+ QTest::newRow("emptymap") << raw("\xa0") << false;
+ QTest::newRow("_emptymap") << raw("\xbf\xff") << false;
+
+ // maps not containing our items
+ QTest::newRow("absent-unsigned-unsigned") << raw("\xa1\0\0") << false;
+ QTest::newRow("absent-taggedunsigned-unsigned") << raw("\xa1\xc0\0\0") << false;
+ QTest::newRow("absent-unsigned-taggedunsigned") << raw("\xa1\0\xc0\0") << false;
+ QTest::newRow("absent-taggedunsigned-taggedunsigned") << raw("\xa1\xc0\0\xc0\0") << false;
+ QTest::newRow("absent-string-unsigned") << raw("\xa1\x68haystack\0") << false;
+ QTest::newRow("absent-taggedstring-unsigned") << raw("\xa1\xc0\x68haystack\0") << false;
+ QTest::newRow("absent-string-taggedunsigned") << raw("\xa1\x68haystack\xc0\0") << false;
+ QTest::newRow("absent-taggedstring-taggedunsigned") << raw("\xa1\xc0\x68haystack\xc0\0") << false;
+ QTest::newRow("absent-string-string") << raw("\xa1\x68haystack\x66needle") << false;
+ QTest::newRow("absent-string-taggedstring") << raw("\xa1\x68haystack\xc0\x66needle") << false;
+ QTest::newRow("absent-taggedstring-string") << raw("\xa1\xc0\x68haystack\x66needle") << false;
+ QTest::newRow("absent-string-taggedstring") << raw("\xa1\xc0\x68haystack\xc0\x66needle") << false;
+
+ QTest::newRow("absent-string-emptyarray") << raw("\xa1\x68haystack\x80") << false;
+ QTest::newRow("absent-string-_emptyarray") << raw("\xa1\x68haystack\x9f\xff") << false;
+ QTest::newRow("absent-string-array1") << raw("\xa1\x68haystack\x81\0") << false;
+ QTest::newRow("absent-string-array2") << raw("\xa1\x68haystack\x85\0\1\2\3\4") << false;
+ QTest::newRow("absent-string-array3") << raw("\xa1\x68haystack\x85\x63one\x63two\x65three\x64""four\x64""five") << false;
+
+ QTest::newRow("absent-string-emptymap") << raw("\xa1\x68haystack\xa0") << false;
+ QTest::newRow("absent-string-_emptymap") << raw("\xa1\x68haystack\xbf\xff") << false;
+ QTest::newRow("absent-string-map") << raw("\xa1\x68haystack\xa1\x68haystack\x66needle") << false;
+ QTest::newRow("absent-string-map2") << raw("\xa1\x68haystack\xa1\x68haystack\x66needle\61z\62yx") << false;
+
+ // maps containing our items
+ QTest::newRow("alone") << raw("\xa1\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("tagged") << raw("\xa1\xc1\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("doubletagged") << raw("\xa1\xc1\xc2\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("chunked") << raw("\xa1\x7f\x66needle\xff\xd8\x2a\x68haystack") << true;
+ QTest::newRow("chunked*2") << raw("\xa1\x7f\x60\x66needle\xff\xd8\x2a\x68haystack") << true;
+ QTest::newRow("chunked*2bis") << raw("\xa1\x7f\x66needle\x60\xff\xd8\x2a\x68haystack") << true;
+ QTest::newRow("chunked*3") << raw("\xa1\x7f\x62ne\x62""ed\x62le\xff\xd8\x2a\x68haystack") << true;
+ QTest::newRow("chunked*8") << raw("\xa1\x7f\x61n\x61""e\x60\x61""e\x61""d\x60\x62le\x60\xff\xd8\x2a\x68haystack") << true;
+
+ QTest::newRow("1before") << raw("\xa2\x68haystack\x66needle\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("tagged-1before") << raw("\xa2\xc1\x68haystack\x66needle\xc1\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("doubletagged-1before2") << raw("\xa2\xc1\xc2\x68haystack\x66needle\xc1\xc2\x66needle\xd8\x2a\x68haystack") << true;
+
+ QTest::newRow("arraybefore") << raw("\xa2\x61z\x80\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("nestedarraybefore") << raw("\xa2\x61z\x81\x81\0\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("arrayarraybefore") << raw("\xa2\x82\1\2\x80\x66needle\xd8\x2a\x68haystack") << true;
+
+ QTest::newRow("mapbefore") << raw("\xa2\x61z\xa0\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("nestedmapbefore") << raw("\xa2\x61z\xa1\0\x81\0\x66needle\xd8\x2a\x68haystack") << true;
+ QTest::newRow("mapmapbefore") << raw("\xa2\xa1\1\2\xa0\x66needle\xd8\x2a\x68haystack") << true;
+}
+
+void tst_Parser::mapFind()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(bool, expected);
+
+ CborParser parser;
+ CborValue value;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ CborValue element;
+ err = cbor_value_map_find_value(&value, "needle", &element);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ if (expected) {
+ QCOMPARE(int(element.type), int(CborTagType));
+
+ CborTag tag;
+ err = cbor_value_get_tag(&element, &tag);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QCOMPARE(int(tag), 42);
+
+ bool equals;
+ err = cbor_value_text_string_equals(&element, "haystack", &equals);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QVERIFY(equals);
+ } else {
+ QCOMPARE(int(element.type), int(CborInvalidType));
+ }
+}
+
+void tst_Parser::checkedIntegers_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QVariant>("result"); // QVariant so we can note numbers out of int64_t range
+
+ QTest::newRow("0") << raw("\x00") << QVariant(Q_INT64_C(0));
+ QTest::newRow("1") << raw("\x01") << QVariant(Q_INT64_C(1));
+ QTest::newRow("10") << raw("\x0a") << QVariant(Q_INT64_C(10));
+ QTest::newRow("23") << raw("\x17") << QVariant(Q_INT64_C(23));
+ QTest::newRow("24") << raw("\x18\x18") << QVariant(Q_INT64_C(24));
+ QTest::newRow("UINT8_MAX") << raw("\x18\xff") << QVariant(Q_INT64_C(255));
+ QTest::newRow("UINT8_MAX+1") << raw("\x19\x01\x00") << QVariant(Q_INT64_C(256));
+ QTest::newRow("UINT16_MAX") << raw("\x19\xff\xff") << QVariant(Q_INT64_C(65535));
+ QTest::newRow("UINT16_MAX+1") << raw("\x1a\0\1\x00\x00") << QVariant(Q_INT64_C(65536));
+ QTest::newRow("INT32_MAX") << raw("\x1a\x7f\xff\xff\xff") << QVariant(Q_INT64_C(2147483647));
+ QTest::newRow("INT32_MAX+1") << raw("\x1a\x80\x00\x00\x00") << QVariant(Q_INT64_C(2147483648));
+ QTest::newRow("UINT32_MAX") << raw("\x1a\xff\xff\xff\xff") << QVariant(Q_INT64_C(4294967295));
+ QTest::newRow("UINT32_MAX+1") << raw("\x1b\0\0\0\1\0\0\0\0") << QVariant(Q_INT64_C(4294967296));
+ QTest::newRow("UINT64_MAX") << raw("\x1b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
+ << QVariant(); // out of range
+
+ // negative integers
+ QTest::newRow("-1") << raw("\x20") << QVariant(Q_INT64_C(-1));
+ QTest::newRow("-2") << raw("\x21") << QVariant(Q_INT64_C(-2));
+ QTest::newRow("-24") << raw("\x37") << QVariant(Q_INT64_C(-24));
+ QTest::newRow("-25") << raw("\x38\x18") << QVariant(Q_INT64_C(-25));
+ QTest::newRow("-UINT8_MAX") << raw("\x38\xff") << QVariant(Q_INT64_C(-256));
+ QTest::newRow("-UINT8_MAX-1") << raw("\x39\x01\x00") << QVariant(Q_INT64_C(-257));
+ QTest::newRow("-UINT16_MAX") << raw("\x39\xff\xff") << QVariant(Q_INT64_C(-65536));
+ QTest::newRow("-UINT16_MAX-1") << raw("\x3a\0\1\x00\x00") << QVariant(Q_INT64_C(-65537));
+ QTest::newRow("INT32_MIN") << raw("\x3a\x7f\xff\xff\xff") << QVariant(Q_INT64_C(-2147483648));
+ QTest::newRow("INT32_MIN-1") << raw("\x3a\x80\x00\x00\x00") << QVariant(Q_INT64_C(-2147483649));
+ QTest::newRow("-UINT32_MAX") << raw("\x3a\xff\xff\xff\xff") << QVariant(Q_INT64_C(-4294967296));
+ QTest::newRow("-UINT32_MAX-1") << raw("\x3b\0\0\0\1\0\0\0\0") << QVariant(Q_INT64_C(-4294967297));
+ QTest::newRow("INT64_MIN+1") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xfe")
+ << QVariant(std::numeric_limits<qint64>::min() + 1);
+ QTest::newRow("INT64_MIN") << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xff")
+ << QVariant(std::numeric_limits<qint64>::min());
+ QTest::newRow("INT64_MIN-1") << raw("\x3b\x80\0\0\0""\0\0\0\0") << QVariant(); // out of range
+ QTest::newRow("-UINT64_MAX") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xfe")
+ << QVariant(); // out of range
+ QTest::newRow("-UINT64_MAX+1") << raw("\x3b" "\xff\xff\xff\xff" "\xff\xff\xff\xff")
+ << QVariant(); // out of range
+}
+
+void tst_Parser::checkedIntegers()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QVariant, result);
+ int64_t expected = result.toLongLong();
+
+ CborParser parser;
+ CborValue value;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &value);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ int64_t v;
+ err = cbor_value_get_int64_checked(&value, &v);
+ if (result.isNull()) {
+ QCOMPARE(err, CborErrorDataTooLarge);
+ } else {
+ QCOMPARE(v, expected);
+ }
+
+ int v2;
+ err = cbor_value_get_int_checked(&value, &v2);
+ if (result.isNull() || expected < std::numeric_limits<int>::min() || expected > std::numeric_limits<int>::max()) {
+ QCOMPARE(err, CborErrorDataTooLarge);
+ } else {
+ QCOMPARE(int64_t(v2), expected);
+ }
+}
+
+void tst_Parser::validation_data()
+{
+ addValidationColumns();
+ addValidationData();
+}
+
+void tst_Parser::validation()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, flags);
+ QFETCH(CborError, expectedError);
+
+ QString decoded;
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), flags, &parser, &first);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ CborError err2 = cbor_value_validate_basic(&first);
+ CborError err3 = cbor_value_validate(&first, CborValidateBasic);
+ err = parseOne(&first, &decoded);
+ QCOMPARE(err, expectedError);
+ if (!QByteArray(QTest::currentDataTag()).contains("utf8")) {
+ QCOMPARE(err2, expectedError);
+ QCOMPARE(err3, expectedError);
+ }
+}
+
+void tst_Parser::strictValidation_data()
+{
+ addValidationColumns();
+
+ // Canonical validation - fixed types
+ QTest::newRow("unsigned-0") << raw("\x00") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("unsigned-24") << raw("\x18\x18") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("unsigned-256") << raw("\x19\1\0") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("unsigned-65536") << raw("\x1a\0\1\0\0") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("unsigned-4294967296") << raw("\x1b\0\0\0\1\0\0\0\0") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("overlong-unsigned-0*1") << raw("\x18\x00") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-0*2") << raw("\x19\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-0*4") << raw("\x1a\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-0*8") << raw("\x1b\0\0\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-24*2") << raw("\x19\0\x18") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-24*4") << raw("\x1a\0\0\0\x18") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-24*8") << raw("\x1b\0\0\0\0\0\0\0\x18") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-256*4") << raw("\x1a\0\0\1\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-256*8") << raw("\x1b\0\0\0\0\0\0\1\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-unsigned-65536*8") << raw("\x1b\0\0\0\0\0\1\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("negative-1") << raw("\x20") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("negative-25") << raw("\x38\x38") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("negative-257") << raw("\x39\1\0") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("negative-65537") << raw("\x3a\0\1\0\0") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("negative-4294967297") << raw("\x3b\0\0\0\1\0\0\0\0") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("overlong-negative-1*1") << raw("\x38\x00") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-1*2") << raw("\x39\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-1*4") << raw("\x3a\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-1*8") << raw("\x3b\0\0\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-25*2") << raw("\x39\0\x18") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-25*4") << raw("\x3a\0\0\0\x18") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-25*8") << raw("\x3b\0\0\0\0\0\0\0\x18") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-257*4") << raw("\x3a\0\0\1\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-257*8") << raw("\x3b\0\0\0\0\0\0\1\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-negative-65537*8") << raw("\x3b\0\0\0\0\0\1\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("simple-0") << raw("\xe0") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("false") << raw("\xf4") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("true") << raw("\xf5") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("null") << raw("\xf6") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("undefined") << raw("\xf7") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("simple-32") << raw("\xf8\x20") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("fp-nan") << raw("\xf9\x7e\00") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("fp--inf") << raw("\xf9\xfc\00") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("fp-+inf") << raw("\xf9\x7c\00") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("overlong-fp-nan_f") << raw("\xfa\x7f\xc0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-fp--inf_f") << raw("\xfa\xff\x80\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-fp-+inf_f") << raw("\xfa\x7f\x80\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-fp-nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-fp--inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-fp-+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+
+ // canonical - lengths
+ QByteArray data24(24, 0x20); // also decodes as -1
+ QByteArray data256(256, 0x40); // also decodes as h''
+ QByteArray data65536(65536, 0x60);// also decodes as ""
+ QTest::newRow("bytearray-0") << raw("\x40") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("bytearray-24") << (raw("\x58\x18") + data24) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("bytearray-256") << (raw("\x59\1\0") + data256) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("bytearray-65536") << (raw("\x5a\0\1\0\0") + data65536) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("_bytearray-0") << raw("\x5f\xff") << int(CborValidateCanonicalFormat) << CborErrorUnknownLength;
+ QTest::newRow("overlong-bytearray-0*1") << raw("\x58\x00") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-0*2") << raw("\x59\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-0*4") << raw("\x5a\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-0*8") << raw("\x5b\0\0\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-24*2") << (raw("\x59\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-24*4") << (raw("\x5a\0\0\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-24*8") << (raw("\x5b\0\0\0\0\0\0\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-256*4") << (raw("\x5a\0\0\1\0") + data256) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-256*8") << (raw("\x5b\0\0\0\0\0\0\1\0") + data256) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-bytearray-65536*8") << (raw("\x5b\0\0\0\0\0\1\0\0") + data65536) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("string-0") << raw("\x60") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("string-24") << (raw("\x78\x18") + data24) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("string-256") << (raw("\x79\1\0") + data256) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("string-65536") << (raw("\x7a\0\1\0\0") + data65536) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("_string-0") << raw("\x7f\xff") << int(CborValidateCanonicalFormat) << CborErrorUnknownLength;
+ QTest::newRow("overlong-string-0*1") << raw("\x78\x00") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-0*2") << raw("\x79\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-0*4") << raw("\x7a\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-0*8") << raw("\x7b\0\0\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-24*2") << (raw("\x79\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-24*4") << (raw("\x7a\0\0\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-24*8") << (raw("\x7b\0\0\0\0\0\0\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-256*4") << (raw("\x7a\0\0\1\0") + data256) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-256*8") << (raw("\x7b\0\0\0\0\0\0\1\0") + data256) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-string-65536*8") << (raw("\x7b\0\0\0\0\0\1\0\0") + data65536) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("array-0") << raw("\x80") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("array-24") << (raw("\x98\x18") + data24) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("array-256") << (raw("\x99\1\0") + data256) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("array-65536") << (raw("\x9a\0\1\0\0") + data65536) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("_array-0") << raw("\x9f\xff") << int(CborValidateCanonicalFormat) << CborErrorUnknownLength;
+ QTest::newRow("overlong-array-0*1") << raw("\x98\x00") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-0*2") << raw("\x99\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-0*4") << raw("\x9a\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-0*8") << raw("\x9b\0\0\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-24*2") << (raw("\x99\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-24*4") << (raw("\x9a\0\0\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-24*8") << (raw("\x9b\0\0\0\0\0\0\0\x18") + data24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-256*4") << (raw("\x9a\0\0\1\0") + data256) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-256*8") << (raw("\x9b\0\0\0\0\0\0\1\0") + data256) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-array-65536*8") << (raw("\x9b\0\0\0\0\0\1\0\0") + data65536) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+
+ // we need unique, sorted, string keys for map
+ // we'll make all key-value pairs a total of 4 bytes
+ char mapentry[] = { 0x62, 0, 0, 0x20 };
+ QByteArray mapdata24(24 * sizeof(mapentry), Qt::Uninitialized);
+ QByteArray mapdata256(256 * sizeof(mapentry), Qt::Uninitialized);
+ char *mapdata24ptr = mapdata24.data();
+ char *mapdata256ptr = mapdata256.data();
+ for (int i = 0; i < 256; ++i) {
+ mapentry[1] = 'A' + (i >> 4);
+ mapentry[2] = 'a' + (i & 0xf);
+ memcpy(mapdata256ptr + i * sizeof(mapentry), mapentry, sizeof(mapentry));
+ if (i < 24)
+ memcpy(mapdata24ptr + i * sizeof(mapentry), mapentry, sizeof(mapentry));
+ }
+ QTest::newRow("map-0") << raw("\xa0") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("map-24") << (raw("\xb8\x18") + mapdata24) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("map-256") << (raw("\xb9\1\0") + mapdata256) << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("_map-0") << raw("\xbf\xff") << int(CborValidateCanonicalFormat) << CborErrorUnknownLength;
+ QTest::newRow("overlong-map-0*1") << raw("\xb8\x00") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-map-0*2") << raw("\xb9\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-map-0*4") << raw("\xba\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-map-0*8") << raw("\xbb\0\0\0\0\0\0\0\0") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-map-24*2") << (raw("\xb9\0\x18") + mapdata24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-map-24*4") << (raw("\xba\0\0\0\x18") + mapdata24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-map-24*8") << (raw("\xbb\0\0\0\0\0\0\0\x18") + mapdata24) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-map-256*4") << (raw("\xba\0\0\1\0") + mapdata256) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-map-256*8") << (raw("\xbb\0\0\0\0\0\0\1\0") + mapdata256) << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("unsorted-length-map-UU") << raw("\xa2\1\1\0\0") << int(CborValidateCanonicalFormat) << CborErrorMapNotSorted;
+ QTest::newRow("unsorted-length-map-UUU") << raw("\xa3\1\1\1\1\0\0") << int(CborValidateCanonicalFormat) << CborErrorMapNotSorted;
+ QTest::newRow("unsorted-length-map-SS") << raw("\xa2\x61z\1\x60\0") << int(CborValidateCanonicalFormat) << CborErrorMapNotSorted;
+ QTest::newRow("unsorted-length-map-SSS") << raw("\xa3\x61z\1\x61z\2\x60\0") << int(CborValidateCanonicalFormat) << CborErrorMapNotSorted;
+ QTest::newRow("unsorted-length-map-SB") << raw("\xa2\x61z\1\x40\0") << int(CborValidateCanonicalFormat) << CborErrorMapNotSorted;
+ QTest::newRow("unsorted-length-map-AS") << raw("\xa2\x83\0\x20\x45Hello\1\x60\0") << int(CborValidateCanonicalFormat) << CborErrorMapNotSorted;
+ QTest::newRow("unsorted-content-map-SS") << raw("\xa2\x61z\1\x61y\0") << int(CborValidateCanonicalFormat) << CborErrorMapNotSorted;
+ QTest::newRow("unsorted-content-map-AS") << raw("\xa2\x81\x21\1\x61\x21\0") << int(CborValidateCanonicalFormat) << CborErrorMapNotSorted;
+
+ QTest::newRow("tag-0") << raw("\xc0\x60") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("tag-24") << raw("\xd8\x18\x40") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("tag-65536") << raw("\xda\0\1\0\0\x60") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("tag-4294967296") << raw("\xdb\0\0\0\1\0\0\0\0\x60") << int(CborValidateCanonicalFormat) << CborNoError;
+ QTest::newRow("overlong-tag-0*1") << raw("\xd8\x00\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-0*2") << raw("\xd9\0\0\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-0*4") << raw("\xda\0\0\0\0\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-0*8") << raw("\xdb\0\0\0\0\0\0\0\0\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-24*2") << raw("\xd9\0\x18\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-24*4") << raw("\xda\0\0\0\x18\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-24*8") << raw("\xdb\0\0\0\0\0\0\0\x18\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-256*4") << raw("\xda\0\0\1\0\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-256*8") << raw("\xdb\0\0\0\0\0\0\1\0\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-tag-65536*8") << raw("\xdb\0\0\0\0\0\1\0\0\x60") << int(CborValidateCanonicalFormat) << CborErrorOverlongEncoding;
+
+ // non-canonical: string length in chunked transfer
+ QTest::newRow("overlong-_bytearray-0*1") << raw("\x5f\x58\x00\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-0*2") << raw("\x5f\x59\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-0*4") << raw("\x5f\x5a\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-0*8") << raw("\x5f\x5b\0\0\0\0\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-24*2") << (raw("\x5f\x59\0\x18") + data24 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-24*4") << (raw("\x5f\x5a\0\0\0\x18") + data24 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-24*8") << (raw("\x5f\x5b\0\0\0\0\0\0\0\x18") + data24 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-256*4") << (raw("\x5f\x5a\0\0\1\0") + data256 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-256*8") << (raw("\x5f\x5b\0\0\0\0\0\0\1\0") + data256 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearray-65536*8") << (raw("\x5f\x5b\0\0\0\0\0\1\0\0") + data65536 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearrayx2-0*1") << raw("\x5f\x40\x58\x00\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearrayx2-0*2") << raw("\x5f\x40\x59\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearrayx2-0*4") << raw("\x5f\x40\x5a\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_bytearrayx2-0*8") << raw("\x5f\x40\x5b\0\0\0\0\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-0*1") << raw("\x7f\x78\x00\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-0*2") << raw("\x7f\x79\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-0*4") << raw("\x7f\x7a\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-0*8") << raw("\x7f\x7b\0\0\0\0\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-24*2") << (raw("\x7f\x79\0\x18") + data24 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-24*4") << (raw("\x7f\x7a\0\0\0\x18") + data24 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-24*8") << (raw("\x7f\x7b\0\0\0\0\0\0\0\x18") + data24 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-256*4") << (raw("\x7f\x7a\0\0\1\0") + data256 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-256*8") << (raw("\x7f\x7b\0\0\0\0\0\0\1\0") + data256 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_string-65536*8") << (raw("\x7f\x7b\0\0\0\0\0\1\0\0") + data65536 + '\xff') << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_stringx2-0*1") << raw("\x7f\x60\x78\x00\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_stringx2-0*2") << raw("\x7f\x60\x79\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_stringx2-0*4") << raw("\x7f\x60\x7a\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+ QTest::newRow("overlong-_stringx2-0*8") << raw("\x7f\x60\x7b\0\0\0\0\0\0\0\0\xff") << int(CborValidateShortestNumbers) << CborErrorOverlongEncoding;
+
+ // strict mode
+ QTest::newRow("invalid-utf8-1char") << raw("\x61\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-2chars-1") << raw("\x62\xc2\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-2chars-2") << raw("\x62\xc3\xdf") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-2chars-3") << raw("\x62\xc7\xf0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-3chars-1") << raw("\x63\xe0\xa0\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-3chars-2") << raw("\x63\xe0\xc0\xa0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-4chars-1") << raw("\x64\xf0\x90\x80\xc0") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-4chars-2") << raw("\x64\xf0\x90\xc0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-4chars-3") << raw("\x64\xf0\xc0\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-hi-surrogate") << raw("\x63\xed\xa0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-lo-surrogate") << raw("\x63\xed\xb0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-surrogate-pair") << raw("\x66\xed\xa0\x80\xed\xb0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-non-unicode-1") << raw("\x64\xf4\x90\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-non-unicode-2") << raw("\x65\xf8\x88\x80\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-non-unicode-3") << raw("\x66\xfc\x84\x80\x80\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-non-unicode-4") << raw("\x66\xfd\xbf\xbf\xbf\xbf\xbf") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-fe") << raw("\x61\xfe") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-ff") << raw("\x61\xff") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-1-2") << raw("\x62\xc1\x81") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-1-3") << raw("\x63\xe0\x81\x81") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-1-4") << raw("\x64\xf0\x80\x81\x81") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-1-5") << raw("\x65\xf8\x80\x80\x81\x81") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-1-6") << raw("\x66\xfc\x80\x80\x80\x81\x81") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-2-3") << raw("\x63\xe0\x82\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-2-4") << raw("\x64\xf0\x80\x82\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-2-5") << raw("\x65\xf8\x80\x80\x82\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-2-6") << raw("\x66\xfc\x80\x80\x80\x82\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-3-4") << raw("\x64\xf0\x80\xa0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-3-5") << raw("\x65\xf8\x80\x80\xa0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-3-6") << raw("\x66\xfc\x80\x80\x80\xa0\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-4-5") << raw("\x65\xf8\x80\x84\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+ QTest::newRow("invalid-utf8-overlong-4-6") << raw("\x66\xfc\x80\x80\x84\x80\x80") << int(CborValidateStrictMode) << CborErrorInvalidUtf8TextString;
+
+ QTest::newRow("nonunique-content-map-UU") << raw("\xa2\0\1\0\2") << int(CborValidateStrictMode) << CborErrorMapKeysNotUnique;
+ QTest::newRow("nonunique-content-map-SS") << raw("\xa2\x61z\1\x61z\2") << int(CborValidateStrictMode) << CborErrorMapKeysNotUnique;
+ QTest::newRow("nonunique-content-map-AA") << raw("\xa2\x81\x65Hello\1\x81\x65Hello\2") << int(CborValidateStrictMode) << CborErrorMapKeysNotUnique;
+
+ QTest::newRow("tag-0-unsigned") << raw("\xc0\x00") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-0-bytearray") << raw("\xc0\x40") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-0-string") << raw("\xc0\x60") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-0-tag-0-string") << raw("\xc0\xc0\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-1-unsigned") << raw("\xc1\x00") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-1-negative") << raw("\xc1\x20") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-1-bytearray") << raw("\xc1\x40") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-2-bytearray") << raw("\xc2\x40") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-2-string") << raw("\xc2\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-3-bytearray") << raw("\xc3\x40") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-3-string") << raw("\xc3\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-4-string") << raw("\xc4\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-4-array") << raw("\xc4\x82\0\1") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-5-string") << raw("\xc5\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-5-array") << raw("\xc5\x82\0\1") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-21-bytearray") << raw("\xd5\x40") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-21-string") << raw("\xd5\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-21-array") << raw("\xd5\x80") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-21-map") << raw("\xd5\xa0") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-22-bytearray") << raw("\xd6\x40") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-22-string") << raw("\xd6\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-22-array") << raw("\xd6\x80") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-22-map") << raw("\xd6\xa0") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-23-bytearray") << raw("\xd7\x40") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-23-string") << raw("\xd7\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-23-array") << raw("\xd7\x80") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-23-map") << raw("\xd7\xa0") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-24-bytearray") << raw("\xd8\x18\x40") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-24-string") << raw("\xd8\x18\x60") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-32-bytearray") << raw("\xd8\x20\x40") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-32-string") << raw("\xd8\x20\x60") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-33-bytearray") << raw("\xd8\x21\x40") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-33-string") << raw("\xd8\x21\x60") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-34-bytearray") << raw("\xd8\x22\x40") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-34-string") << raw("\xd8\x22\x60") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-35-bytearray") << raw("\xd8\x23\x40") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-35-string") << raw("\xd8\x23\x60") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-36-bytearray") << raw("\xd8\x24\x40") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-36-string") << raw("\xd8\x24\x60") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-unsigned") << raw("\xd9\xd9\xf7\x00") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-negative") << raw("\xd9\xd9\xf7\x20") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-bytearray") << raw("\xd9\xd9\xf7\x40") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-string") << raw("\xd9\xd9\xf7\x60") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-array") << raw("\xd9\xd9\xf7\x80") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-map") << raw("\xd9\xd9\xf7\xa0") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-tag-0-unsigned") << raw("\xd9\xd9\xf7\xc0\x00") << int(CborValidateStrictMode) << CborErrorInappropriateTagForType;
+ QTest::newRow("tag-55799-tag-0-string") << raw("\xd9\xd9\xf7\xc0\x60") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-simple0") << raw("\xd9\xd9\xf7\xe0") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-false") << raw("\xd9\xd9\xf7\xf4") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-true") << raw("\xd9\xd9\xf7\xf5") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-null") << raw("\xd9\xd9\xf7\xf6") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-undefined") << raw("\xd9\xd9\xf7\xf7") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-simple32") << raw("\xd9\xd9\xf7\xf8\x20") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-half") << raw("\xd9\xd9\xf7\xf9\0\0") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-float") << raw("\xd9\xd9\xf7\xfa\0\0\0\0") << int(CborValidateStrictMode) << CborNoError;
+ QTest::newRow("tag-55799-double") << raw("\xd9\xd9\xf7\xfb\0\0\0\0\0\0\0\0") << int(CborValidateStrictMode) << CborNoError;
+
+ // excluded non-finite
+ QTest::newRow("excluded-fp-nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp-nan_f") << raw("\xfa\x7f\xc0\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp--inf_f") << raw("\xfa\xff\x80\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp--inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp-+inf_f") << raw("\xfa\x7f\x80\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp-+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+
+ // excluded undefined
+ QTest::newRow("no-undefined") << raw("\xf7") << int(CborValidateNoUndefined) << CborErrorExcludedType;
+
+ // exclude non-finite
+ QTest::newRow("excluded-fp-nan_f16") << raw("\xf9\x7e\00") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp--inf_f16") << raw("\xf9\xfc\00") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp-+inf_f16") << raw("\xf9\x7c\00") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp-nan_f") << raw("\xfa\x7f\xc0\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp--inf_f") << raw("\xfa\xff\x80\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp-+inf_f") << raw("\xfa\x7f\x80\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp-nan") << raw("\xfb\x7f\xf8\0\0\0\0\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp--inf") << raw("\xfb\xff\xf0\0\0\0\0\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+ QTest::newRow("excluded-fp-+inf") << raw("\xfb\x7f\xf0\0\0\0\0\0\0") << int(CborValidateFiniteFloatingPoint) << CborErrorExcludedValue;
+
+ // exclude non-string keys in maps
+ QTest::newRow("excluded-map-unsigned") << raw("\xa1\x00\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-negative") << raw("\xa1\x20\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-bytearray") << raw("\xa1\x40\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("map-string") << raw("\xa1\x60\1") << int(CborValidateMapKeysAreString) << CborNoError;
+ QTest::newRow("map-tag-0-string") << raw("\xa1\xc0\x60\1") << int(CborValidateMapKeysAreString) << CborNoError;
+ QTest::newRow("excluded-map-array") << raw("\xa1\x80\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-map") << raw("\xa1\xa0\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-simple-0") << raw("\xa1\xe0\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-false") << raw("\xa1\xf4\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-true") << raw("\xa1\xf5\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-null") << raw("\xa1\xf6\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-undefined") << raw("\xa1\xf7\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-half") << raw("\xa1\xf9\0\0\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-float") << raw("\xa1\xfa\0\0\0\0\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+ QTest::newRow("excluded-map-double") << raw("\xa1\xfb\0\0\0\0\0\0\0\0\1") << int(CborValidateMapKeysAreString) << CborErrorMapKeyNotString;
+
+ // unknown simple types
+ QTest::newRow("unknown-simple-type-0") << raw("\xe0") << int(CborValidateNoUnknownSimpleTypes) << CborErrorUnknownSimpleType;
+ QTest::newRow("unknown-simple-type-32") << raw("\xf8\x20") << int(CborValidateNoUnknownSimpleTypes) << CborErrorUnknownSimpleType;
+ QTest::newRow("allowed-simple-type-32") << raw("\xf8\x20") << int(CborValidateNoUnknownSimpleTypesSA) << CborNoError;
+
+ // unknown tags
+ QTest::newRow("unknown-tag-6") << raw("\xc6\x60") << int(CborValidateNoUnknownTags) << CborErrorUnknownTag;
+ QTest::newRow("unknown-tag-31") << raw("\xd8\x1f\x60") << int(CborValidateNoUnknownTags) << CborErrorUnknownTag;
+ QTest::newRow("unknown-tag-256") << raw("\xd9\1\0\x60") << int(CborValidateNoUnknownTags) << CborErrorUnknownTag;
+ QTest::newRow("unknown-tag-65536") << raw("\xda\0\1\0\0\x60") << int(CborValidateNoUnknownTags) << CborErrorUnknownTag;
+ QTest::newRow("unknown-tag-4294967296") << raw("\xdb\0\0\0\1\0\0\0\0\x60") << int(CborValidateNoUnknownTags) << CborErrorUnknownTag;
+ QTest::newRow("allowed-tag-31") << raw("\xd8\x1f\x60") << int(CborValidateNoUnknownTagsSA) << CborNoError;
+ QTest::newRow("allowed-tag-256") << raw("\xd9\1\0\x60") << int(CborValidateNoUnknownTagsSR) << CborNoError;
+
+ // excluded tags
+ QTest::newRow("excluded-tag-0") << raw("\xc0\x60") << int(CborValidateNoTags) << CborErrorExcludedType;
+ QTest::newRow("excluded-tag-24") << raw("\xd8\x18\x40") << int(CborValidateNoTags) << CborErrorExcludedType;
+ QTest::newRow("excluded-tag-55799") << raw("\xd9\xd9\xf7\x60") << int(CborValidateNoTags) << CborErrorExcludedType;
+
+ // complete data
+ QTest::newRow("garbage-data-0") << raw("\0\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-1") << raw("\x20\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-2") << raw("\x40\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-3") << raw("\x60\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-4") << raw("\x80\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-5") << raw("\xa0\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-6") << raw("\xc0\x60\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-7") << raw("\xf4\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-f16") << raw("\xf9\0\0\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-f32") << raw("\xfa\0\0\0\0\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+ QTest::newRow("garbage-data-f64") << raw("\xfb\0\0\0\0\0\0\0\0\1") << int(CborValidateCompleteData) << CborErrorGarbageAtEnd;
+}
+
+void tst_Parser::strictValidation()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, flags);
+ QFETCH(CborError, expectedError);
+
+ QString decoded;
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ err = cbor_value_validate(&first, flags);
+ QCOMPARE(err, expectedError);
+}
+
+void tst_Parser::incompleteData_data()
+{
+ addColumns();
+ addFixedData();
+ addStringsData();
+ addTagsData();
+ addMapMixedData();
+}
+
+void tst_Parser::incompleteData()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+
+ for (int len = 0; len < data.length() - 1; ++len) {
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), len, 0, &parser, &first);
+ if (!err) {
+ QString decoded;
+ err = parseOne(&first, &decoded);
+ }
+ if (err != CborErrorUnexpectedEOF)
+ qDebug() << "Length is" << len;
+ QCOMPARE(err, CborErrorUnexpectedEOF);
+ }
+}
+
+void tst_Parser::endPointer_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("offset");
+
+ QTest::newRow("number1") << raw("\x81\x01\x01") << 2;
+ QTest::newRow("number24") << raw("\x81\x18\x18\x01") << 3;
+ QTest::newRow("string") << raw("\x81\x61Z\x01") << 3;
+ QTest::newRow("indefinite-string") << raw("\x81\x7f\x61Z\xff\x01") << 5;
+ QTest::newRow("array") << raw("\x81\x02\x01") << 2;
+ QTest::newRow("indefinite-array") << raw("\x81\x9f\x02\xff\x01") << 4;
+ QTest::newRow("object") << raw("\x81\xa1\x03\x02\x01") << 4;
+ QTest::newRow("indefinite-object") << raw("\x81\xbf\x03\x02\xff\x01") << 5;
+}
+
+void tst_Parser::endPointer()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, offset);
+
+ QString decoded;
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ err = parseOne(&first, &decoded);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ QCOMPARE(int(cbor_value_get_next_byte(&first) - reinterpret_cast<const quint8 *>(data.constBegin())), offset);
+}
+
+void tst_Parser::recursionLimit_data()
+{
+ static const int recursions = CBOR_PARSER_MAX_RECURSIONS + 2;
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("array") << QByteArray(recursions, '\x81') + '\x20';
+ QTest::newRow("_array") << QByteArray(recursions, '\x9f') + '\x20' + QByteArray(recursions, '\xff');
+
+ QByteArray data;
+ for (int i = 0; i < recursions; ++i)
+ data += "\xa1\x65Hello";
+ data += '\2';
+ QTest::newRow("map-recursive-values") << data;
+
+ data.clear();
+ for (int i = 0; i < recursions; ++i)
+ data += "\xbf\x65World";
+ data += '\2';
+ for (int i = 0; i < recursions; ++i)
+ data += "\xff";
+ QTest::newRow("_map-recursive-values") << data;
+
+ data = QByteArray(recursions, '\xa1');
+ data += '\2';
+ for (int i = 0; i < recursions; ++i)
+ data += "\x7f\x64quux\xff";
+ QTest::newRow("map-recursive-keys") << data;
+
+ data = QByteArray(recursions, '\xbf');
+ data += '\2';
+ for (int i = 0; i < recursions; ++i)
+ data += "\1\xff";
+ QTest::newRow("_map-recursive-keys") << data;
+
+ data.clear();
+ for (int i = 0; i < recursions / 2; ++i)
+ data += "\x81\xa1\1";
+ data += '\2';
+ QTest::newRow("mixed") << data;
+}
+
+void tst_Parser::recursionLimit()
+{
+ QFETCH(QByteArray, data);
+
+ CborParser parser;
+ CborValue first;
+ CborError err = cbor_parser_init(reinterpret_cast<const quint8 *>(data.constData()), data.length(), 0, &parser, &first);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+
+ // check that it is valid:
+ CborValue it = first;
+ {
+ QString dummy;
+ err = parseOne(&it, &dummy);
+ QVERIFY2(!err, QByteArray("Got error \"") + cbor_error_string(err) + "\"");
+ }
+
+ it = first;
+ err = cbor_value_advance(&it);
+ QCOMPARE(err, CborErrorNestingTooDeep);
+
+ it = first;
+ if (cbor_value_is_map(&it)) {
+ CborValue dummy;
+ err = cbor_value_map_find_value(&it, "foo", &dummy);
+ QCOMPARE(err, CborErrorNestingTooDeep);
+ }
+}
+
+QTEST_MAIN(tst_Parser)
+#include "tst_parser.moc"
diff --git a/src/3rdparty/wasm/DejaVuSans.ttf b/src/3rdparty/wasm/DejaVuSans.ttf
new file mode 100644
index 0000000000..7e411a71be
--- /dev/null
+++ b/src/3rdparty/wasm/DejaVuSans.ttf
Binary files differ
diff --git a/src/3rdparty/wasm/LICENSE b/src/3rdparty/wasm/LICENSE
new file mode 100644
index 0000000000..4f9e8544b7
--- /dev/null
+++ b/src/3rdparty/wasm/LICENSE
@@ -0,0 +1,15 @@
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license (“Fontsâ€) and associated documentation files (the “Font Softwareâ€), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:
+
+The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words “Bitstream†or the word “Veraâ€.
+
+This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the “Bitstream Vera†names.
+
+The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED “AS ISâ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the names of GNOME, the GNOME Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the GNOME Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.
diff --git a/src/3rdparty/wasm/Vera.ttf b/src/3rdparty/wasm/Vera.ttf
new file mode 100644
index 0000000000..58cd6b5e61
--- /dev/null
+++ b/src/3rdparty/wasm/Vera.ttf
Binary files differ
diff --git a/src/3rdparty/wasm/qt_attribution.json b/src/3rdparty/wasm/qt_attribution.json
new file mode 100644
index 0000000000..184e2968cd
--- /dev/null
+++ b/src/3rdparty/wasm/qt_attribution.json
@@ -0,0 +1,21 @@
+{
+ "Id": "vera_font",
+ "Name": "Vera",
+ "QDocModule": "qtcore",
+ "QtUsage": "Used for WebAssembly platform.",
+
+ "License": "Bitstream",
+ "LicenseFile": "LICENSE",
+ "Copyright": "Copyright (C) 2003 Bitstream,Inc"
+},
+{
+ "Id": "dejayvu",
+ "Name": "DejaVuSans",
+ "QDocModule": "qtcore",
+ "QtUsage": "Used for WebAssembly platform.",
+
+ "License": "Bitstream",
+ "LicenseFile": "LICENSE",
+ "Copyright": "Copyright (C) 2003 Bitstream,Inc"
+}
+
diff --git a/src/3rdparty/xcb/README b/src/3rdparty/xcb/README
index d7c8eba294..9e8ea30b51 100644
--- a/src/3rdparty/xcb/README
+++ b/src/3rdparty/xcb/README
@@ -1,15 +1,19 @@
Contains the header and sources files from selected xcb libraries:
- libxcb-1.5 together with xcb-proto-1.6 (sync, xfixes, randr, xinerama sources)
+ libxcb-1.9.1 together with xcb-proto-1.8 (randr, render, shape, shm, sync,
+ xfixes, xinerama sources)
# libxkbcommon-x11 requires libxcb-xkb >= 1.10
libxcb-1.10 together with xcb-proto-1.10 (xkb sources)
+ libxcb-1.13 together with xcb-proto-1.13 (xinput sources with removed
+ Pointer Barriers API and SendExtensionEvent API)
libxcb-util-image-0.3.9
libxcb-util-keysyms-0.3.9
libxcb-util-renderutil-0.3.8
libxcb-util-wm-0.3.9
The 'include' directory was obtained by compiling and installing all of the modules.
-They have been tested to run also with libxcb 1.5 (the oldest version we support).
+When upgrading the bundled xcb headers, they must be tested to run also with the
+minimal supported libxcb version, which currently is 1.9.1.
Use the -qt-xcb configure option to use the files instead of system xcb libraries.
See src/plugins/platforms/xcb/README for details.
diff --git a/src/3rdparty/xcb/include/xcb/randr.h b/src/3rdparty/xcb/include/xcb/randr.h
index 1035c4043c..4f4f2104cf 100644
--- a/src/3rdparty/xcb/include/xcb/randr.h
+++ b/src/3rdparty/xcb/include/xcb/randr.h
@@ -1379,6 +1379,9 @@ xcb_randr_screen_size_next (xcb_randr_screen_size_iterator_t *i /**< */);
xcb_generic_iterator_t
xcb_randr_screen_size_end (xcb_randr_screen_size_iterator_t i /**< */);
+int
+xcb_randr_refresh_rates_sizeof (const void *_buffer /**< */);
+
/*****************************************************************************
**
@@ -1462,7 +1465,7 @@ xcb_generic_iterator_t
xcb_randr_refresh_rates_end (xcb_randr_refresh_rates_iterator_t i /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1487,7 +1490,7 @@ xcb_randr_query_version (xcb_connection_t *c /**< */,
uint32_t minor_version /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1546,7 +1549,7 @@ xcb_randr_query_version_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1579,7 +1582,7 @@ xcb_randr_set_screen_config (xcb_connection_t *c /**< */,
uint16_t rate /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1646,7 +1649,7 @@ xcb_randr_set_screen_config_reply (xcb_connection_t *c /**
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1674,7 +1677,7 @@ xcb_randr_select_input_checked (xcb_connection_t *c /**< */,
uint16_t enable /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1698,8 +1701,11 @@ xcb_randr_select_input (xcb_connection_t *c /**< */,
xcb_window_t window /**< */,
uint16_t enable /**< */);
+int
+xcb_randr_get_screen_info_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1722,7 +1728,7 @@ xcb_randr_get_screen_info (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1844,7 +1850,7 @@ xcb_randr_get_screen_info_reply (xcb_connection_t *c /**< */
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1867,7 +1873,7 @@ xcb_randr_get_screen_size_range (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1924,7 +1930,7 @@ xcb_randr_get_screen_size_range_reply (xcb_connection_t
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1958,7 +1964,7 @@ xcb_randr_set_screen_size_checked (xcb_connection_t *c /**< */,
uint32_t mm_height /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2031,8 +2037,11 @@ xcb_randr_mode_info_next (xcb_randr_mode_info_iterator_t *i /**< */);
xcb_generic_iterator_t
xcb_randr_mode_info_end (xcb_randr_mode_info_iterator_t i /**< */);
+int
+xcb_randr_get_screen_resources_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2055,7 +2064,7 @@ xcb_randr_get_screen_resources (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2267,8 +2276,11 @@ xcb_randr_get_screen_resources_reply (xcb_connection_t *
xcb_randr_get_screen_resources_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_get_output_info_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2293,7 +2305,7 @@ xcb_randr_get_output_info (xcb_connection_t *c /**< */,
xcb_timestamp_t config_timestamp /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2507,8 +2519,11 @@ xcb_randr_get_output_info_reply (xcb_connection_t *c /**< */
xcb_randr_get_output_info_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_list_output_properties_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2531,7 +2546,7 @@ xcb_randr_list_output_properties (xcb_connection_t *c /**< */,
xcb_randr_output_t output /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2626,8 +2641,11 @@ xcb_randr_list_output_properties_reply (xcb_connection_t
xcb_randr_list_output_properties_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_query_output_property_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2652,7 +2670,7 @@ xcb_randr_query_output_property (xcb_connection_t *c /**< */,
xcb_atom_t property /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2749,8 +2767,12 @@ xcb_randr_query_output_property_reply (xcb_connection_t
xcb_randr_query_output_property_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_configure_output_property_sizeof (const void *_buffer /**< */,
+ uint32_t values_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2786,7 +2808,7 @@ xcb_randr_configure_output_property_checked (xcb_connection_t *c /**< */,
const int32_t *values /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2818,8 +2840,11 @@ xcb_randr_configure_output_property (xcb_connection_t *c /**< */,
uint32_t values_len /**< */,
const int32_t *values /**< */);
+int
+xcb_randr_change_output_property_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2857,7 +2882,7 @@ xcb_randr_change_output_property_checked (xcb_connection_t *c /**< */,
const void *data /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2892,7 +2917,7 @@ xcb_randr_change_output_property (xcb_connection_t *c /**< */,
const void *data /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2920,7 +2945,7 @@ xcb_randr_delete_output_property_checked (xcb_connection_t *c /**< */,
xcb_atom_t property /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2944,8 +2969,11 @@ xcb_randr_delete_output_property (xcb_connection_t *c /**< */,
xcb_randr_output_t output /**< */,
xcb_atom_t property /**< */);
+int
+xcb_randr_get_output_property_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2980,7 +3008,7 @@ xcb_randr_get_output_property (xcb_connection_t *c /**< */,
uint8_t pending /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3087,8 +3115,12 @@ xcb_randr_get_output_property_reply (xcb_connection_t *c
xcb_randr_get_output_property_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_create_mode_sizeof (const void *_buffer /**< */,
+ uint32_t name_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3117,7 +3149,7 @@ xcb_randr_create_mode (xcb_connection_t *c /**< */,
const char *name /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3180,7 +3212,7 @@ xcb_randr_create_mode_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3206,7 +3238,7 @@ xcb_randr_destroy_mode_checked (xcb_connection_t *c /**< */,
xcb_randr_mode_t mode /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3229,7 +3261,7 @@ xcb_randr_destroy_mode (xcb_connection_t *c /**< */,
xcb_randr_mode_t mode /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3257,7 +3289,7 @@ xcb_randr_add_output_mode_checked (xcb_connection_t *c /**< */,
xcb_randr_mode_t mode /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3282,7 +3314,7 @@ xcb_randr_add_output_mode (xcb_connection_t *c /**< */,
xcb_randr_mode_t mode /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3310,7 +3342,7 @@ xcb_randr_delete_output_mode_checked (xcb_connection_t *c /**< */,
xcb_randr_mode_t mode /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3334,8 +3366,11 @@ xcb_randr_delete_output_mode (xcb_connection_t *c /**< */,
xcb_randr_output_t output /**< */,
xcb_randr_mode_t mode /**< */);
+int
+xcb_randr_get_crtc_info_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3360,7 +3395,7 @@ xcb_randr_get_crtc_info (xcb_connection_t *c /**< */,
xcb_timestamp_t config_timestamp /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3496,8 +3531,12 @@ xcb_randr_get_crtc_info_reply (xcb_connection_t *c /**< */,
xcb_randr_get_crtc_info_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_set_crtc_config_sizeof (const void *_buffer /**< */,
+ uint32_t outputs_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3536,7 +3575,7 @@ xcb_randr_set_crtc_config (xcb_connection_t *c /**< */,
const xcb_randr_output_t *outputs /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3609,7 +3648,7 @@ xcb_randr_set_crtc_config_reply (xcb_connection_t *c /**< */
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3632,7 +3671,7 @@ xcb_randr_get_crtc_gamma_size (xcb_connection_t *c /**< */,
xcb_randr_crtc_t crtc /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3688,8 +3727,11 @@ xcb_randr_get_crtc_gamma_size_reply (xcb_connection_t *c
xcb_randr_get_crtc_gamma_size_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_get_crtc_gamma_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3712,7 +3754,7 @@ xcb_randr_get_crtc_gamma (xcb_connection_t *c /**< */,
xcb_randr_crtc_t crtc /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3885,8 +3927,11 @@ xcb_randr_get_crtc_gamma_reply (xcb_connection_t *c /**< */,
xcb_randr_get_crtc_gamma_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_set_crtc_gamma_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3920,7 +3965,7 @@ xcb_randr_set_crtc_gamma_checked (xcb_connection_t *c /**< */,
const uint16_t *blue /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3950,8 +3995,11 @@ xcb_randr_set_crtc_gamma (xcb_connection_t *c /**< */,
const uint16_t *green /**< */,
const uint16_t *blue /**< */);
+int
+xcb_randr_get_screen_resources_current_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3974,7 +4022,7 @@ xcb_randr_get_screen_resources_current (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4186,8 +4234,12 @@ xcb_randr_get_screen_resources_current_reply (xcb_connection_t
xcb_randr_get_screen_resources_current_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_randr_set_crtc_transform_sizeof (const void *_buffer /**< */,
+ uint32_t filter_params_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4223,7 +4275,7 @@ xcb_randr_set_crtc_transform_checked (xcb_connection_t *c /**< */,
const xcb_render_fixed_t *filter_params /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4255,8 +4307,11 @@ xcb_randr_set_crtc_transform (xcb_connection_t *c /**< */,
uint32_t filter_params_len /**< */,
const xcb_render_fixed_t *filter_params /**< */);
+int
+xcb_randr_get_crtc_transform_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4279,7 +4334,7 @@ xcb_randr_get_crtc_transform (xcb_connection_t *c /**< */,
xcb_randr_crtc_t crtc /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4492,7 +4547,7 @@ xcb_randr_get_crtc_transform_reply (xcb_connection_t *c /
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4515,7 +4570,7 @@ xcb_randr_get_panning (xcb_connection_t *c /**< */,
xcb_randr_crtc_t crtc /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4572,7 +4627,7 @@ xcb_randr_get_panning_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4621,7 +4676,7 @@ xcb_randr_set_panning (xcb_connection_t *c /**< */,
int16_t border_bottom /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4704,7 +4759,7 @@ xcb_randr_set_panning_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4732,7 +4787,7 @@ xcb_randr_set_output_primary_checked (xcb_connection_t *c /**< */,
xcb_randr_output_t output /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4757,7 +4812,7 @@ xcb_randr_set_output_primary (xcb_connection_t *c /**< */,
xcb_randr_output_t output /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4780,7 +4835,7 @@ xcb_randr_get_output_primary (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
diff --git a/src/3rdparty/xcb/include/xcb/render.h b/src/3rdparty/xcb/include/xcb/render.h
index 0f96ca1fbc..eb7f0424d5 100644
--- a/src/3rdparty/xcb/include/xcb/render.h
+++ b/src/3rdparty/xcb/include/xcb/render.h
@@ -20,7 +20,7 @@ extern "C" {
#endif
#define XCB_RENDER_MAJOR_VERSION 0
-#define XCB_RENDER_MINOR_VERSION 10
+#define XCB_RENDER_MINOR_VERSION 11
extern xcb_extension_t xcb_render_id;
@@ -71,7 +71,22 @@ typedef enum xcb_render_pict_op_t {
XCB_RENDER_PICT_OP_CONJOINT_OUT_REVERSE,
XCB_RENDER_PICT_OP_CONJOINT_ATOP,
XCB_RENDER_PICT_OP_CONJOINT_ATOP_REVERSE,
- XCB_RENDER_PICT_OP_CONJOINT_XOR
+ XCB_RENDER_PICT_OP_CONJOINT_XOR,
+ XCB_RENDER_PICT_OP_MULTIPLY = 48,
+ XCB_RENDER_PICT_OP_SCREEN,
+ XCB_RENDER_PICT_OP_OVERLAY,
+ XCB_RENDER_PICT_OP_DARKEN,
+ XCB_RENDER_PICT_OP_LIGHTEN,
+ XCB_RENDER_PICT_OP_COLOR_DODGE,
+ XCB_RENDER_PICT_OP_COLOR_BURN,
+ XCB_RENDER_PICT_OP_HARD_LIGHT,
+ XCB_RENDER_PICT_OP_SOFT_LIGHT,
+ XCB_RENDER_PICT_OP_DIFFERENCE,
+ XCB_RENDER_PICT_OP_EXCLUSION,
+ XCB_RENDER_PICT_OP_HSL_HUE,
+ XCB_RENDER_PICT_OP_HSL_SATURATION,
+ XCB_RENDER_PICT_OP_HSL_COLOR,
+ XCB_RENDER_PICT_OP_HSL_LUMINOSITY
} xcb_render_pict_op_t;
typedef enum xcb_render_poly_edge_t {
@@ -1453,6 +1468,9 @@ xcb_render_pictvisual_next (xcb_render_pictvisual_iterator_t *i /**< */);
xcb_generic_iterator_t
xcb_render_pictvisual_end (xcb_render_pictvisual_iterator_t i /**< */);
+int
+xcb_render_pictdepth_sizeof (const void *_buffer /**< */);
+
/*****************************************************************************
**
@@ -1535,6 +1553,9 @@ xcb_render_pictdepth_next (xcb_render_pictdepth_iterator_t *i /**< */);
xcb_generic_iterator_t
xcb_render_pictdepth_end (xcb_render_pictdepth_iterator_t i /**< */);
+int
+xcb_render_pictscreen_sizeof (const void *_buffer /**< */);
+
/*****************************************************************************
**
@@ -1906,7 +1927,7 @@ xcb_generic_iterator_t
xcb_render_glyphinfo_end (xcb_render_glyphinfo_iterator_t i /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1931,7 +1952,7 @@ xcb_render_query_version (xcb_connection_t *c /**< */,
uint32_t client_minor_version /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1989,8 +2010,11 @@ xcb_render_query_version_reply (xcb_connection_t *c /**< */,
xcb_render_query_version_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_render_query_pict_formats_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2011,7 +2035,7 @@ xcb_render_query_pict_formats_cookie_t
xcb_render_query_pict_formats (xcb_connection_t *c /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2169,8 +2193,11 @@ xcb_render_query_pict_formats_reply (xcb_connection_t *c
xcb_render_query_pict_formats_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_render_query_pict_index_values_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2193,7 +2220,7 @@ xcb_render_query_pict_index_values (xcb_connection_t *c /**< */,
xcb_render_pictformat_t format /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2288,8 +2315,11 @@ xcb_render_query_pict_index_values_reply (xcb_connection_t
xcb_render_query_pict_index_values_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_render_create_picture_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2323,7 +2353,7 @@ xcb_render_create_picture_checked (xcb_connection_t *c /**< */,
const uint32_t *value_list /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2353,8 +2383,11 @@ xcb_render_create_picture (xcb_connection_t *c /**< */,
uint32_t value_mask /**< */,
const uint32_t *value_list /**< */);
+int
+xcb_render_change_picture_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2384,7 +2417,7 @@ xcb_render_change_picture_checked (xcb_connection_t *c /**< */,
const uint32_t *value_list /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2410,8 +2443,12 @@ xcb_render_change_picture (xcb_connection_t *c /**< */,
uint32_t value_mask /**< */,
const uint32_t *value_list /**< */);
+int
+xcb_render_set_picture_clip_rectangles_sizeof (const void *_buffer /**< */,
+ uint32_t rectangles_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2445,7 +2482,7 @@ xcb_render_set_picture_clip_rectangles_checked (xcb_connection_t *c /**< *
const xcb_rectangle_t *rectangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2476,7 +2513,7 @@ xcb_render_set_picture_clip_rectangles (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rectangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2502,7 +2539,7 @@ xcb_render_free_picture_checked (xcb_connection_t *c /**< */,
xcb_render_picture_t picture /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2525,7 +2562,7 @@ xcb_render_free_picture (xcb_connection_t *c /**< */,
xcb_render_picture_t picture /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2573,7 +2610,7 @@ xcb_render_composite_checked (xcb_connection_t *c /**< */,
uint16_t height /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2617,8 +2654,12 @@ xcb_render_composite (xcb_connection_t *c /**< */,
uint16_t width /**< */,
uint16_t height /**< */);
+int
+xcb_render_trapezoids_sizeof (const void *_buffer /**< */,
+ uint32_t traps_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2658,7 +2699,7 @@ xcb_render_trapezoids_checked (xcb_connection_t *c /**< */,
const xcb_render_trapezoid_t *traps /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2694,8 +2735,12 @@ xcb_render_trapezoids (xcb_connection_t *c /**< */,
uint32_t traps_len /**< */,
const xcb_render_trapezoid_t *traps /**< */);
+int
+xcb_render_triangles_sizeof (const void *_buffer /**< */,
+ uint32_t triangles_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2735,7 +2780,7 @@ xcb_render_triangles_checked (xcb_connection_t *c /**< */,
const xcb_render_triangle_t *triangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2771,8 +2816,12 @@ xcb_render_triangles (xcb_connection_t *c /**< */,
uint32_t triangles_len /**< */,
const xcb_render_triangle_t *triangles /**< */);
+int
+xcb_render_tri_strip_sizeof (const void *_buffer /**< */,
+ uint32_t points_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2812,7 +2861,7 @@ xcb_render_tri_strip_checked (xcb_connection_t *c /**< */,
const xcb_render_pointfix_t *points /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2848,8 +2897,12 @@ xcb_render_tri_strip (xcb_connection_t *c /**< */,
uint32_t points_len /**< */,
const xcb_render_pointfix_t *points /**< */);
+int
+xcb_render_tri_fan_sizeof (const void *_buffer /**< */,
+ uint32_t points_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2889,7 +2942,7 @@ xcb_render_tri_fan_checked (xcb_connection_t *c /**< */,
const xcb_render_pointfix_t *points /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2926,7 +2979,7 @@ xcb_render_tri_fan (xcb_connection_t *c /**< */,
const xcb_render_pointfix_t *points /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2954,7 +3007,7 @@ xcb_render_create_glyph_set_checked (xcb_connection_t *c /**< */,
xcb_render_pictformat_t format /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2979,7 +3032,7 @@ xcb_render_create_glyph_set (xcb_connection_t *c /**< */,
xcb_render_pictformat_t format /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3007,7 +3060,7 @@ xcb_render_reference_glyph_set_checked (xcb_connection_t *c /**< */,
xcb_render_glyphset_t existing /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3032,7 +3085,7 @@ xcb_render_reference_glyph_set (xcb_connection_t *c /**< */,
xcb_render_glyphset_t existing /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3058,7 +3111,7 @@ xcb_render_free_glyph_set_checked (xcb_connection_t *c /**< */,
xcb_render_glyphset_t glyphset /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3080,8 +3133,12 @@ xcb_void_cookie_t
xcb_render_free_glyph_set (xcb_connection_t *c /**< */,
xcb_render_glyphset_t glyphset /**< */);
+int
+xcb_render_add_glyphs_sizeof (const void *_buffer /**< */,
+ uint32_t data_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3117,7 +3174,7 @@ xcb_render_add_glyphs_checked (xcb_connection_t *c /**< */,
const uint8_t *data /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3149,8 +3206,12 @@ xcb_render_add_glyphs (xcb_connection_t *c /**< */,
uint32_t data_len /**< */,
const uint8_t *data /**< */);
+int
+xcb_render_free_glyphs_sizeof (const void *_buffer /**< */,
+ uint32_t glyphs_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3180,7 +3241,7 @@ xcb_render_free_glyphs_checked (xcb_connection_t *c /**< */,
const xcb_render_glyph_t *glyphs /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3206,8 +3267,12 @@ xcb_render_free_glyphs (xcb_connection_t *c /**< */,
uint32_t glyphs_len /**< */,
const xcb_render_glyph_t *glyphs /**< */);
+int
+xcb_render_composite_glyphs_8_sizeof (const void *_buffer /**< */,
+ uint32_t glyphcmds_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3249,7 +3314,7 @@ xcb_render_composite_glyphs_8_checked (xcb_connection_t *c /**< */,
const uint8_t *glyphcmds /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3287,8 +3352,12 @@ xcb_render_composite_glyphs_8 (xcb_connection_t *c /**< */,
uint32_t glyphcmds_len /**< */,
const uint8_t *glyphcmds /**< */);
+int
+xcb_render_composite_glyphs_16_sizeof (const void *_buffer /**< */,
+ uint32_t glyphcmds_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3330,7 +3399,7 @@ xcb_render_composite_glyphs_16_checked (xcb_connection_t *c /**< */,
const uint8_t *glyphcmds /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3368,8 +3437,12 @@ xcb_render_composite_glyphs_16 (xcb_connection_t *c /**< */,
uint32_t glyphcmds_len /**< */,
const uint8_t *glyphcmds /**< */);
+int
+xcb_render_composite_glyphs_32_sizeof (const void *_buffer /**< */,
+ uint32_t glyphcmds_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3411,7 +3484,7 @@ xcb_render_composite_glyphs_32_checked (xcb_connection_t *c /**< */,
const uint8_t *glyphcmds /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3449,8 +3522,12 @@ xcb_render_composite_glyphs_32 (xcb_connection_t *c /**< */,
uint32_t glyphcmds_len /**< */,
const uint8_t *glyphcmds /**< */);
+int
+xcb_render_fill_rectangles_sizeof (const void *_buffer /**< */,
+ uint32_t rects_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3484,7 +3561,7 @@ xcb_render_fill_rectangles_checked (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rects /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3515,7 +3592,7 @@ xcb_render_fill_rectangles (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rects /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3547,7 +3624,7 @@ xcb_render_create_cursor_checked (xcb_connection_t *c /**< */,
uint16_t y /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3619,7 +3696,7 @@ xcb_generic_iterator_t
xcb_render_transform_end (xcb_render_transform_iterator_t i /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3647,7 +3724,7 @@ xcb_render_set_picture_transform_checked (xcb_connection_t *c /**< */,
xcb_render_transform_t transform /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3671,8 +3748,11 @@ xcb_render_set_picture_transform (xcb_connection_t *c /**< */,
xcb_render_picture_t picture /**< */,
xcb_render_transform_t transform /**< */);
+int
+xcb_render_query_filters_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3695,7 +3775,7 @@ xcb_render_query_filters (xcb_connection_t *c /**< */,
xcb_drawable_t drawable /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3816,8 +3896,12 @@ xcb_render_query_filters_reply (xcb_connection_t *c /**< */,
xcb_render_query_filters_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_render_set_picture_filter_sizeof (const void *_buffer /**< */,
+ uint32_t values_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3851,7 +3935,7 @@ xcb_render_set_picture_filter_checked (xcb_connection_t *c /**< */,
const xcb_render_fixed_t *values /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3924,8 +4008,12 @@ xcb_render_animcursorelt_next (xcb_render_animcursorelt_iterator_t *i /**< */);
xcb_generic_iterator_t
xcb_render_animcursorelt_end (xcb_render_animcursorelt_iterator_t i /**< */);
+int
+xcb_render_create_anim_cursor_sizeof (const void *_buffer /**< */,
+ uint32_t cursors_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -3955,7 +4043,7 @@ xcb_render_create_anim_cursor_checked (xcb_connection_t *c /**<
const xcb_render_animcursorelt_t *cursors /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4067,8 +4155,12 @@ xcb_render_trap_next (xcb_render_trap_iterator_t *i /**< */);
xcb_generic_iterator_t
xcb_render_trap_end (xcb_render_trap_iterator_t i /**< */);
+int
+xcb_render_add_traps_sizeof (const void *_buffer /**< */,
+ uint32_t traps_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4102,7 +4194,7 @@ xcb_render_add_traps_checked (xcb_connection_t *c /**< */,
const xcb_render_trap_t *traps /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4133,7 +4225,7 @@ xcb_render_add_traps (xcb_connection_t *c /**< */,
const xcb_render_trap_t *traps /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4161,7 +4253,7 @@ xcb_render_create_solid_fill_checked (xcb_connection_t *c /**< */,
xcb_render_color_t color /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4185,8 +4277,11 @@ xcb_render_create_solid_fill (xcb_connection_t *c /**< */,
xcb_render_picture_t picture /**< */,
xcb_render_color_t color /**< */);
+int
+xcb_render_create_linear_gradient_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4222,7 +4317,7 @@ xcb_render_create_linear_gradient_checked (xcb_connection_t *c /**< */,
const xcb_render_color_t *colors /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4254,8 +4349,11 @@ xcb_render_create_linear_gradient (xcb_connection_t *c /**< */,
const xcb_render_fixed_t *stops /**< */,
const xcb_render_color_t *colors /**< */);
+int
+xcb_render_create_radial_gradient_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4295,7 +4393,7 @@ xcb_render_create_radial_gradient_checked (xcb_connection_t *c /**< */,
const xcb_render_color_t *colors /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4331,8 +4429,11 @@ xcb_render_create_radial_gradient (xcb_connection_t *c /**< */,
const xcb_render_fixed_t *stops /**< */,
const xcb_render_color_t *colors /**< */);
+int
+xcb_render_create_conical_gradient_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -4368,7 +4469,7 @@ xcb_render_create_conical_gradient_checked (xcb_connection_t *c /**< */
const xcb_render_color_t *colors /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
diff --git a/src/3rdparty/xcb/include/xcb/shape.h b/src/3rdparty/xcb/include/xcb/shape.h
index 107d2ff748..63919b42c7 100644
--- a/src/3rdparty/xcb/include/xcb/shape.h
+++ b/src/3rdparty/xcb/include/xcb/shape.h
@@ -393,7 +393,7 @@ xcb_generic_iterator_t
xcb_shape_kind_end (xcb_shape_kind_iterator_t i /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -414,7 +414,7 @@ xcb_shape_query_version_cookie_t
xcb_shape_query_version (xcb_connection_t *c /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -468,8 +468,12 @@ xcb_shape_query_version_reply (xcb_connection_t *c /**< */,
xcb_shape_query_version_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_shape_rectangles_sizeof (const void *_buffer /**< */,
+ uint32_t rectangles_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -509,7 +513,7 @@ xcb_shape_rectangles_checked (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rectangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -546,7 +550,7 @@ xcb_shape_rectangles (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rectangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -582,7 +586,7 @@ xcb_shape_mask_checked (xcb_connection_t *c /**< */,
xcb_pixmap_t source_bitmap /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -615,7 +619,7 @@ xcb_shape_mask (xcb_connection_t *c /**< */,
xcb_pixmap_t source_bitmap /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -653,7 +657,7 @@ xcb_shape_combine_checked (xcb_connection_t *c /**< */,
xcb_window_t source_window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -688,7 +692,7 @@ xcb_shape_combine (xcb_connection_t *c /**< */,
xcb_window_t source_window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -720,7 +724,7 @@ xcb_shape_offset_checked (xcb_connection_t *c /**< */,
int16_t y_offset /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -749,7 +753,7 @@ xcb_shape_offset (xcb_connection_t *c /**< */,
int16_t y_offset /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -772,7 +776,7 @@ xcb_shape_query_extents (xcb_connection_t *c /**< */,
xcb_window_t destination_window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -829,7 +833,7 @@ xcb_shape_query_extents_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -857,7 +861,7 @@ xcb_shape_select_input_checked (xcb_connection_t *c /**< */,
uint8_t enable /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -882,7 +886,7 @@ xcb_shape_select_input (xcb_connection_t *c /**< */,
uint8_t enable /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -905,7 +909,7 @@ xcb_shape_input_selected (xcb_connection_t *c /**< */,
xcb_window_t destination_window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -961,8 +965,11 @@ xcb_shape_input_selected_reply (xcb_connection_t *c /**< */,
xcb_shape_input_selected_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_shape_get_rectangles_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -987,7 +994,7 @@ xcb_shape_get_rectangles (xcb_connection_t *c /**< */,
xcb_shape_kind_t source_kind /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
diff --git a/src/3rdparty/xcb/include/xcb/shm.h b/src/3rdparty/xcb/include/xcb/shm.h
index bcb60d81f1..315f37e9b9 100644
--- a/src/3rdparty/xcb/include/xcb/shm.h
+++ b/src/3rdparty/xcb/include/xcb/shm.h
@@ -255,7 +255,7 @@ xcb_generic_iterator_t
xcb_shm_seg_end (xcb_shm_seg_iterator_t i /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -276,7 +276,7 @@ xcb_shm_query_version_cookie_t
xcb_shm_query_version (xcb_connection_t *c /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -331,7 +331,7 @@ xcb_shm_query_version_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -361,7 +361,7 @@ xcb_shm_attach_checked (xcb_connection_t *c /**< */,
uint8_t read_only /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -388,7 +388,7 @@ xcb_shm_attach (xcb_connection_t *c /**< */,
uint8_t read_only /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -414,7 +414,7 @@ xcb_shm_detach_checked (xcb_connection_t *c /**< */,
xcb_shm_seg_t shmseg /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -437,7 +437,7 @@ xcb_shm_detach (xcb_connection_t *c /**< */,
xcb_shm_seg_t shmseg /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -491,7 +491,7 @@ xcb_shm_put_image_checked (xcb_connection_t *c /**< */,
uint32_t offset /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -542,7 +542,7 @@ xcb_shm_put_image (xcb_connection_t *c /**< */,
uint32_t offset /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -581,7 +581,7 @@ xcb_shm_get_image (xcb_connection_t *c /**< */,
uint32_t offset /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -654,7 +654,7 @@ xcb_shm_get_image_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -692,7 +692,7 @@ xcb_shm_create_pixmap_checked (xcb_connection_t *c /**< */,
uint32_t offset /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
diff --git a/src/3rdparty/xcb/include/xcb/sync.h b/src/3rdparty/xcb/include/xcb/sync.h
index 50665c2865..3d0069d7ef 100644
--- a/src/3rdparty/xcb/include/xcb/sync.h
+++ b/src/3rdparty/xcb/include/xcb/sync.h
@@ -20,7 +20,7 @@ extern "C" {
#endif
#define XCB_SYNC_MAJOR_VERSION 3
-#define XCB_SYNC_MINOR_VERSION 0
+#define XCB_SYNC_MINOR_VERSION 1
extern xcb_extension_t xcb_sync_id;
@@ -52,6 +52,17 @@ typedef struct xcb_sync_counter_iterator_t {
int index; /**< */
} xcb_sync_counter_iterator_t;
+typedef uint32_t xcb_sync_fence_t;
+
+/**
+ * @brief xcb_sync_fence_iterator_t
+ **/
+typedef struct xcb_sync_fence_iterator_t {
+ xcb_sync_fence_t *data; /**< */
+ int rem; /**< */
+ int index; /**< */
+} xcb_sync_fence_iterator_t;
+
typedef enum xcb_sync_testtype_t {
XCB_SYNC_TESTTYPE_POSITIVE_TRANSITION,
XCB_SYNC_TESTTYPE_NEGATIVE_TRANSITION,
@@ -458,6 +469,104 @@ typedef struct xcb_sync_get_priority_reply_t {
int32_t priority; /**< */
} xcb_sync_get_priority_reply_t;
+/** Opcode for xcb_sync_create_fence. */
+#define XCB_SYNC_CREATE_FENCE 14
+
+/**
+ * @brief xcb_sync_create_fence_request_t
+ **/
+typedef struct xcb_sync_create_fence_request_t {
+ uint8_t major_opcode; /**< */
+ uint8_t minor_opcode; /**< */
+ uint16_t length; /**< */
+ xcb_drawable_t drawable; /**< */
+ xcb_sync_fence_t fence; /**< */
+ uint8_t initially_triggered; /**< */
+} xcb_sync_create_fence_request_t;
+
+/** Opcode for xcb_sync_trigger_fence. */
+#define XCB_SYNC_TRIGGER_FENCE 15
+
+/**
+ * @brief xcb_sync_trigger_fence_request_t
+ **/
+typedef struct xcb_sync_trigger_fence_request_t {
+ uint8_t major_opcode; /**< */
+ uint8_t minor_opcode; /**< */
+ uint16_t length; /**< */
+ xcb_sync_fence_t fence; /**< */
+} xcb_sync_trigger_fence_request_t;
+
+/** Opcode for xcb_sync_reset_fence. */
+#define XCB_SYNC_RESET_FENCE 16
+
+/**
+ * @brief xcb_sync_reset_fence_request_t
+ **/
+typedef struct xcb_sync_reset_fence_request_t {
+ uint8_t major_opcode; /**< */
+ uint8_t minor_opcode; /**< */
+ uint16_t length; /**< */
+ xcb_sync_fence_t fence; /**< */
+} xcb_sync_reset_fence_request_t;
+
+/** Opcode for xcb_sync_destroy_fence. */
+#define XCB_SYNC_DESTROY_FENCE 17
+
+/**
+ * @brief xcb_sync_destroy_fence_request_t
+ **/
+typedef struct xcb_sync_destroy_fence_request_t {
+ uint8_t major_opcode; /**< */
+ uint8_t minor_opcode; /**< */
+ uint16_t length; /**< */
+ xcb_sync_fence_t fence; /**< */
+} xcb_sync_destroy_fence_request_t;
+
+/**
+ * @brief xcb_sync_query_fence_cookie_t
+ **/
+typedef struct xcb_sync_query_fence_cookie_t {
+ unsigned int sequence; /**< */
+} xcb_sync_query_fence_cookie_t;
+
+/** Opcode for xcb_sync_query_fence. */
+#define XCB_SYNC_QUERY_FENCE 18
+
+/**
+ * @brief xcb_sync_query_fence_request_t
+ **/
+typedef struct xcb_sync_query_fence_request_t {
+ uint8_t major_opcode; /**< */
+ uint8_t minor_opcode; /**< */
+ uint16_t length; /**< */
+ xcb_sync_fence_t fence; /**< */
+} xcb_sync_query_fence_request_t;
+
+/**
+ * @brief xcb_sync_query_fence_reply_t
+ **/
+typedef struct xcb_sync_query_fence_reply_t {
+ uint8_t response_type; /**< */
+ uint8_t pad0; /**< */
+ uint16_t sequence; /**< */
+ uint32_t length; /**< */
+ uint8_t triggered; /**< */
+ uint8_t pad1[23]; /**< */
+} xcb_sync_query_fence_reply_t;
+
+/** Opcode for xcb_sync_await_fence. */
+#define XCB_SYNC_AWAIT_FENCE 19
+
+/**
+ * @brief xcb_sync_await_fence_request_t
+ **/
+typedef struct xcb_sync_await_fence_request_t {
+ uint8_t major_opcode; /**< */
+ uint8_t minor_opcode; /**< */
+ uint16_t length; /**< */
+} xcb_sync_await_fence_request_t;
+
/** Opcode for xcb_sync_counter_notify. */
#define XCB_SYNC_COUNTER_NOTIFY 0
@@ -583,6 +692,49 @@ xcb_sync_counter_end (xcb_sync_counter_iterator_t i /**< */);
/**
* Get the next element of the iterator
+ * @param i Pointer to a xcb_sync_fence_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_sync_fence_t)
+ */
+
+/*****************************************************************************
+ **
+ ** void xcb_sync_fence_next
+ **
+ ** @param xcb_sync_fence_iterator_t *i
+ ** @returns void
+ **
+ *****************************************************************************/
+
+void
+xcb_sync_fence_next (xcb_sync_fence_iterator_t *i /**< */);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_sync_fence_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_generic_iterator_t xcb_sync_fence_end
+ **
+ ** @param xcb_sync_fence_iterator_t i
+ ** @returns xcb_generic_iterator_t
+ **
+ *****************************************************************************/
+
+xcb_generic_iterator_t
+xcb_sync_fence_end (xcb_sync_fence_iterator_t i /**< */);
+
+/**
+ * Get the next element of the iterator
* @param i Pointer to a xcb_sync_int64_iterator_t
*
* Get the next element in the iterator. The member rem is
@@ -624,6 +776,9 @@ xcb_sync_int64_next (xcb_sync_int64_iterator_t *i /**< */);
xcb_generic_iterator_t
xcb_sync_int64_end (xcb_sync_int64_iterator_t i /**< */);
+int
+xcb_sync_systemcounter_sizeof (const void *_buffer /**< */);
+
/*****************************************************************************
**
@@ -793,7 +948,7 @@ xcb_generic_iterator_t
xcb_sync_waitcondition_end (xcb_sync_waitcondition_iterator_t i /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -818,7 +973,7 @@ xcb_sync_initialize (xcb_connection_t *c /**< */,
uint8_t desired_minor_version /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -876,8 +1031,11 @@ xcb_sync_initialize_reply (xcb_connection_t *c /**< */,
xcb_sync_initialize_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_sync_list_system_counters_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -898,7 +1056,7 @@ xcb_sync_list_system_counters_cookie_t
xcb_sync_list_system_counters (xcb_connection_t *c /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -979,7 +1137,7 @@ xcb_sync_list_system_counters_reply (xcb_connection_t *c
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1007,7 +1165,7 @@ xcb_sync_create_counter_checked (xcb_connection_t *c /**< */,
xcb_sync_int64_t initial_value /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1032,7 +1190,7 @@ xcb_sync_create_counter (xcb_connection_t *c /**< */,
xcb_sync_int64_t initial_value /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1058,7 +1216,7 @@ xcb_sync_destroy_counter_checked (xcb_connection_t *c /**< */,
xcb_sync_counter_t counter /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1081,7 +1239,7 @@ xcb_sync_destroy_counter (xcb_connection_t *c /**< */,
xcb_sync_counter_t counter /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1104,7 +1262,7 @@ xcb_sync_query_counter (xcb_connection_t *c /**< */,
xcb_sync_counter_t counter /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1160,8 +1318,12 @@ xcb_sync_query_counter_reply (xcb_connection_t *c /**< */,
xcb_sync_query_counter_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_sync_await_sizeof (const void *_buffer /**< */,
+ uint32_t wait_list_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1189,7 +1351,7 @@ xcb_sync_await_checked (xcb_connection_t *c /**< */,
const xcb_sync_waitcondition_t *wait_list /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1214,7 +1376,7 @@ xcb_sync_await (xcb_connection_t *c /**< */,
const xcb_sync_waitcondition_t *wait_list /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1242,7 +1404,7 @@ xcb_sync_change_counter_checked (xcb_connection_t *c /**< */,
xcb_sync_int64_t amount /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1267,7 +1429,7 @@ xcb_sync_change_counter (xcb_connection_t *c /**< */,
xcb_sync_int64_t amount /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1295,7 +1457,7 @@ xcb_sync_set_counter_checked (xcb_connection_t *c /**< */,
xcb_sync_int64_t value /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1319,8 +1481,11 @@ xcb_sync_set_counter (xcb_connection_t *c /**< */,
xcb_sync_counter_t counter /**< */,
xcb_sync_int64_t value /**< */);
+int
+xcb_sync_create_alarm_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1350,7 +1515,7 @@ xcb_sync_create_alarm_checked (xcb_connection_t *c /**< */,
const uint32_t *value_list /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1376,8 +1541,11 @@ xcb_sync_create_alarm (xcb_connection_t *c /**< */,
uint32_t value_mask /**< */,
const uint32_t *value_list /**< */);
+int
+xcb_sync_change_alarm_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1407,7 +1575,7 @@ xcb_sync_change_alarm_checked (xcb_connection_t *c /**< */,
const uint32_t *value_list /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1434,7 +1602,7 @@ xcb_sync_change_alarm (xcb_connection_t *c /**< */,
const uint32_t *value_list /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1460,7 +1628,7 @@ xcb_sync_destroy_alarm_checked (xcb_connection_t *c /**< */,
xcb_sync_alarm_t alarm /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1483,7 +1651,7 @@ xcb_sync_destroy_alarm (xcb_connection_t *c /**< */,
xcb_sync_alarm_t alarm /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1506,7 +1674,7 @@ xcb_sync_query_alarm (xcb_connection_t *c /**< */,
xcb_sync_alarm_t alarm /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1563,7 +1731,7 @@ xcb_sync_query_alarm_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1591,7 +1759,7 @@ xcb_sync_set_priority_checked (xcb_connection_t *c /**< */,
int32_t priority /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1616,7 +1784,7 @@ xcb_sync_set_priority (xcb_connection_t *c /**< */,
int32_t priority /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1639,7 +1807,7 @@ xcb_sync_get_priority (xcb_connection_t *c /**< */,
uint32_t id /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1695,6 +1863,347 @@ xcb_sync_get_priority_reply (xcb_connection_t *c /**< */,
xcb_sync_get_priority_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_create_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_drawable_t drawable
+ ** @param xcb_sync_fence_t fence
+ ** @param uint8_t initially_triggered
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_create_fence_checked (xcb_connection_t *c /**< */,
+ xcb_drawable_t drawable /**< */,
+ xcb_sync_fence_t fence /**< */,
+ uint8_t initially_triggered /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_create_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_drawable_t drawable
+ ** @param xcb_sync_fence_t fence
+ ** @param uint8_t initially_triggered
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_create_fence (xcb_connection_t *c /**< */,
+ xcb_drawable_t drawable /**< */,
+ xcb_sync_fence_t fence /**< */,
+ uint8_t initially_triggered /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_trigger_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_trigger_fence_checked (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_trigger_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_trigger_fence (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_reset_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_reset_fence_checked (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_reset_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_reset_fence (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_destroy_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_destroy_fence_checked (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_destroy_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_destroy_fence (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_sync_query_fence_cookie_t xcb_sync_query_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_sync_query_fence_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_sync_query_fence_cookie_t
+xcb_sync_query_fence (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_sync_query_fence_cookie_t xcb_sync_query_fence_unchecked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_sync_query_fence_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_sync_query_fence_cookie_t
+xcb_sync_query_fence_unchecked (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_sync_query_fence_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_sync_query_fence_reply_t * xcb_sync_query_fence_reply
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_query_fence_cookie_t cookie
+ ** @param xcb_generic_error_t **e
+ ** @returns xcb_sync_query_fence_reply_t *
+ **
+ *****************************************************************************/
+
+xcb_sync_query_fence_reply_t *
+xcb_sync_query_fence_reply (xcb_connection_t *c /**< */,
+ xcb_sync_query_fence_cookie_t cookie /**< */,
+ xcb_generic_error_t **e /**< */);
+
+int
+xcb_sync_await_fence_sizeof (const void *_buffer /**< */,
+ uint32_t fence_list_len /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_await_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param uint32_t fence_list_len
+ ** @param const xcb_sync_fence_t *fence_list
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_await_fence_checked (xcb_connection_t *c /**< */,
+ uint32_t fence_list_len /**< */,
+ const xcb_sync_fence_t *fence_list /**< */);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_await_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param uint32_t fence_list_len
+ ** @param const xcb_sync_fence_t *fence_list
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_await_fence (xcb_connection_t *c /**< */,
+ uint32_t fence_list_len /**< */,
+ const xcb_sync_fence_t *fence_list /**< */);
+
#ifdef __cplusplus
}
diff --git a/src/3rdparty/xcb/include/xcb/xfixes.h b/src/3rdparty/xcb/include/xcb/xfixes.h
index 4d7eb0900a..b67aa85135 100644
--- a/src/3rdparty/xcb/include/xcb/xfixes.h
+++ b/src/3rdparty/xcb/include/xcb/xfixes.h
@@ -683,7 +683,7 @@ typedef struct xcb_xfixes_show_cursor_request_t {
} xcb_xfixes_show_cursor_request_t;
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -708,7 +708,7 @@ xcb_xfixes_query_version (xcb_connection_t *c /**< */,
uint32_t client_minor_version /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -767,7 +767,7 @@ xcb_xfixes_query_version_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -799,7 +799,7 @@ xcb_xfixes_change_save_set_checked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -828,7 +828,7 @@ xcb_xfixes_change_save_set (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -858,7 +858,7 @@ xcb_xfixes_select_selection_input_checked (xcb_connection_t *c /**< */,
uint32_t event_mask /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -885,7 +885,7 @@ xcb_xfixes_select_selection_input (xcb_connection_t *c /**< */,
uint32_t event_mask /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -913,7 +913,7 @@ xcb_xfixes_select_cursor_input_checked (xcb_connection_t *c /**< */,
uint32_t event_mask /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -937,8 +937,11 @@ xcb_xfixes_select_cursor_input (xcb_connection_t *c /**< */,
xcb_window_t window /**< */,
uint32_t event_mask /**< */);
+int
+xcb_xfixes_get_cursor_image_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -959,7 +962,7 @@ xcb_xfixes_get_cursor_image_cookie_t
xcb_xfixes_get_cursor_image (xcb_connection_t *c /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1095,8 +1098,12 @@ xcb_xfixes_region_next (xcb_xfixes_region_iterator_t *i /**< */);
xcb_generic_iterator_t
xcb_xfixes_region_end (xcb_xfixes_region_iterator_t i /**< */);
+int
+xcb_xfixes_create_region_sizeof (const void *_buffer /**< */,
+ uint32_t rectangles_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1126,7 +1133,7 @@ xcb_xfixes_create_region_checked (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rectangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1153,7 +1160,7 @@ xcb_xfixes_create_region (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rectangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1181,7 +1188,7 @@ xcb_xfixes_create_region_from_bitmap_checked (xcb_connection_t *c /**< */,
xcb_pixmap_t bitmap /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1206,7 +1213,7 @@ xcb_xfixes_create_region_from_bitmap (xcb_connection_t *c /**< */,
xcb_pixmap_t bitmap /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1236,7 +1243,7 @@ xcb_xfixes_create_region_from_window_checked (xcb_connection_t *c /**< */,
xcb_shape_kind_t kind /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1263,7 +1270,7 @@ xcb_xfixes_create_region_from_window (xcb_connection_t *c /**< */,
xcb_shape_kind_t kind /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1291,7 +1298,7 @@ xcb_xfixes_create_region_from_gc_checked (xcb_connection_t *c /**< */,
xcb_gcontext_t gc /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1316,7 +1323,7 @@ xcb_xfixes_create_region_from_gc (xcb_connection_t *c /**< */,
xcb_gcontext_t gc /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1344,7 +1351,7 @@ xcb_xfixes_create_region_from_picture_checked (xcb_connection_t *c /**< */,
xcb_render_picture_t picture /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1369,7 +1376,7 @@ xcb_xfixes_create_region_from_picture (xcb_connection_t *c /**< */,
xcb_render_picture_t picture /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1395,7 +1402,7 @@ xcb_xfixes_destroy_region_checked (xcb_connection_t *c /**< */,
xcb_xfixes_region_t region /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1417,8 +1424,12 @@ xcb_void_cookie_t
xcb_xfixes_destroy_region (xcb_connection_t *c /**< */,
xcb_xfixes_region_t region /**< */);
+int
+xcb_xfixes_set_region_sizeof (const void *_buffer /**< */,
+ uint32_t rectangles_len /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1448,7 +1459,7 @@ xcb_xfixes_set_region_checked (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rectangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1475,7 +1486,7 @@ xcb_xfixes_set_region (xcb_connection_t *c /**< */,
const xcb_rectangle_t *rectangles /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1503,7 +1514,7 @@ xcb_xfixes_copy_region_checked (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1528,7 +1539,7 @@ xcb_xfixes_copy_region (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1558,7 +1569,7 @@ xcb_xfixes_union_region_checked (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1585,7 +1596,7 @@ xcb_xfixes_union_region (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1615,7 +1626,7 @@ xcb_xfixes_intersect_region_checked (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1642,7 +1653,7 @@ xcb_xfixes_intersect_region (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1672,7 +1683,7 @@ xcb_xfixes_subtract_region_checked (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1699,7 +1710,7 @@ xcb_xfixes_subtract_region (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1729,7 +1740,7 @@ xcb_xfixes_invert_region_checked (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1756,7 +1767,7 @@ xcb_xfixes_invert_region (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1786,7 +1797,7 @@ xcb_xfixes_translate_region_checked (xcb_connection_t *c /**< */,
int16_t dy /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1813,7 +1824,7 @@ xcb_xfixes_translate_region (xcb_connection_t *c /**< */,
int16_t dy /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1841,7 +1852,7 @@ xcb_xfixes_region_extents_checked (xcb_connection_t *c /**< */,
xcb_xfixes_region_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1865,8 +1876,11 @@ xcb_xfixes_region_extents (xcb_connection_t *c /**< */,
xcb_xfixes_region_t source /**< */,
xcb_xfixes_region_t destination /**< */);
+int
+xcb_xfixes_fetch_region_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1889,7 +1903,7 @@ xcb_xfixes_fetch_region (xcb_connection_t *c /**< */,
xcb_xfixes_region_t region /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -1985,7 +1999,7 @@ xcb_xfixes_fetch_region_reply (xcb_connection_t *c /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2017,7 +2031,7 @@ xcb_xfixes_set_gc_clip_region_checked (xcb_connection_t *c /**< */,
int16_t y_origin /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2046,7 +2060,7 @@ xcb_xfixes_set_gc_clip_region (xcb_connection_t *c /**< */,
int16_t y_origin /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2080,7 +2094,7 @@ xcb_xfixes_set_window_shape_region_checked (xcb_connection_t *c /**< */,
xcb_xfixes_region_t region /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2111,7 +2125,7 @@ xcb_xfixes_set_window_shape_region (xcb_connection_t *c /**< */,
xcb_xfixes_region_t region /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2143,7 +2157,7 @@ xcb_xfixes_set_picture_clip_region_checked (xcb_connection_t *c /**< */,
int16_t y_origin /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2171,8 +2185,11 @@ xcb_xfixes_set_picture_clip_region (xcb_connection_t *c /**< */,
int16_t x_origin /**< */,
int16_t y_origin /**< */);
+int
+xcb_xfixes_set_cursor_name_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2202,7 +2219,7 @@ xcb_xfixes_set_cursor_name_checked (xcb_connection_t *c /**< */,
const char *name /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2228,8 +2245,11 @@ xcb_xfixes_set_cursor_name (xcb_connection_t *c /**< */,
uint16_t nbytes /**< */,
const char *name /**< */);
+int
+xcb_xfixes_get_cursor_name_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2252,7 +2272,7 @@ xcb_xfixes_get_cursor_name (xcb_connection_t *c /**< */,
xcb_cursor_t cursor /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2347,8 +2367,11 @@ xcb_xfixes_get_cursor_name_reply (xcb_connection_t *c /**<
xcb_xfixes_get_cursor_name_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_xfixes_get_cursor_image_and_name_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2369,7 +2392,7 @@ xcb_xfixes_get_cursor_image_and_name_cookie_t
xcb_xfixes_get_cursor_image_and_name (xcb_connection_t *c /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2502,7 +2525,7 @@ xcb_xfixes_get_cursor_image_and_name_reply (xcb_connection_t
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2530,7 +2553,7 @@ xcb_xfixes_change_cursor_checked (xcb_connection_t *c /**< */,
xcb_cursor_t destination /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2554,8 +2577,11 @@ xcb_xfixes_change_cursor (xcb_connection_t *c /**< */,
xcb_cursor_t source /**< */,
xcb_cursor_t destination /**< */);
+int
+xcb_xfixes_change_cursor_by_name_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2585,7 +2611,7 @@ xcb_xfixes_change_cursor_by_name_checked (xcb_connection_t *c /**< */,
const char *name /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2612,7 +2638,7 @@ xcb_xfixes_change_cursor_by_name (xcb_connection_t *c /**< */,
const char *name /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2648,7 +2674,7 @@ xcb_xfixes_expand_region_checked (xcb_connection_t *c /**< */,
uint16_t bottom /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2681,7 +2707,7 @@ xcb_xfixes_expand_region (xcb_connection_t *c /**< */,
uint16_t bottom /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2707,7 +2733,7 @@ xcb_xfixes_hide_cursor_checked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2730,7 +2756,7 @@ xcb_xfixes_hide_cursor (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
@@ -2756,7 +2782,7 @@ xcb_xfixes_show_cursor_checked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
diff --git a/src/3rdparty/xcb/include/xcb/xinerama.h b/src/3rdparty/xcb/include/xcb/xinerama.h
index 74da5458d2..f18a96c791 100644
--- a/src/3rdparty/xcb/include/xcb/xinerama.h
+++ b/src/3rdparty/xcb/include/xcb/xinerama.h
@@ -21,7 +21,7 @@ extern "C" {
#define XCB_XINERAMA_MAJOR_VERSION 1
#define XCB_XINERAMA_MINOR_VERSION 1
-
+
extern xcb_extension_t xcb_xinerama_id;
/**
@@ -246,12 +246,12 @@ typedef struct xcb_xinerama_query_screens_reply_t {
/*****************************************************************************
**
** void xcb_xinerama_screen_info_next
- **
+ **
** @param xcb_xinerama_screen_info_iterator_t *i
** @returns void
**
*****************************************************************************/
-
+
void
xcb_xinerama_screen_info_next (xcb_xinerama_screen_info_iterator_t *i /**< */);
@@ -268,47 +268,47 @@ xcb_xinerama_screen_info_next (xcb_xinerama_screen_info_iterator_t *i /**< */);
/*****************************************************************************
**
** xcb_generic_iterator_t xcb_xinerama_screen_info_end
- **
+ **
** @param xcb_xinerama_screen_info_iterator_t i
** @returns xcb_generic_iterator_t
**
*****************************************************************************/
-
+
xcb_generic_iterator_t
xcb_xinerama_screen_info_end (xcb_xinerama_screen_info_iterator_t i /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
*/
/*****************************************************************************
**
** xcb_xinerama_query_version_cookie_t xcb_xinerama_query_version
- **
+ **
** @param xcb_connection_t *c
** @param uint8_t major
** @param uint8_t minor
** @returns xcb_xinerama_query_version_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_query_version_cookie_t
xcb_xinerama_query_version (xcb_connection_t *c /**< */,
uint8_t major /**< */,
uint8_t minor /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
* This form can be used only if the request will cause
* a reply to be generated. Any returned error will be
* placed in the event queue.
@@ -317,14 +317,14 @@ xcb_xinerama_query_version (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_query_version_cookie_t xcb_xinerama_query_version_unchecked
- **
+ **
** @param xcb_connection_t *c
** @param uint8_t major
** @param uint8_t minor
** @returns xcb_xinerama_query_version_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_query_version_cookie_t
xcb_xinerama_query_version_unchecked (xcb_connection_t *c /**< */,
uint8_t major /**< */,
@@ -337,7 +337,7 @@ xcb_xinerama_query_version_unchecked (xcb_connection_t *c /**< */,
* @param e The xcb_generic_error_t supplied
*
* Returns the reply of the request asked by
- *
+ *
* The parameter @p e supplied to this function must be NULL if
* xcb_xinerama_query_version_unchecked(). is used.
* Otherwise, it stores the error if any.
@@ -348,49 +348,49 @@ xcb_xinerama_query_version_unchecked (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_query_version_reply_t * xcb_xinerama_query_version_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_query_version_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_query_version_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_query_version_reply_t *
xcb_xinerama_query_version_reply (xcb_connection_t *c /**< */,
xcb_xinerama_query_version_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
*/
/*****************************************************************************
**
** xcb_xinerama_get_state_cookie_t xcb_xinerama_get_state
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @returns xcb_xinerama_get_state_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_state_cookie_t
xcb_xinerama_get_state (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
* This form can be used only if the request will cause
* a reply to be generated. Any returned error will be
* placed in the event queue.
@@ -399,13 +399,13 @@ xcb_xinerama_get_state (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_state_cookie_t xcb_xinerama_get_state_unchecked
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @returns xcb_xinerama_get_state_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_state_cookie_t
xcb_xinerama_get_state_unchecked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
@@ -417,7 +417,7 @@ xcb_xinerama_get_state_unchecked (xcb_connection_t *c /**< */,
* @param e The xcb_generic_error_t supplied
*
* Returns the reply of the request asked by
- *
+ *
* The parameter @p e supplied to this function must be NULL if
* xcb_xinerama_get_state_unchecked(). is used.
* Otherwise, it stores the error if any.
@@ -428,49 +428,49 @@ xcb_xinerama_get_state_unchecked (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_state_reply_t * xcb_xinerama_get_state_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_get_state_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_get_state_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_get_state_reply_t *
xcb_xinerama_get_state_reply (xcb_connection_t *c /**< */,
xcb_xinerama_get_state_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
*/
/*****************************************************************************
**
** xcb_xinerama_get_screen_count_cookie_t xcb_xinerama_get_screen_count
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @returns xcb_xinerama_get_screen_count_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_count_cookie_t
xcb_xinerama_get_screen_count (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
* This form can be used only if the request will cause
* a reply to be generated. Any returned error will be
* placed in the event queue.
@@ -479,13 +479,13 @@ xcb_xinerama_get_screen_count (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_count_cookie_t xcb_xinerama_get_screen_count_unchecked
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @returns xcb_xinerama_get_screen_count_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_count_cookie_t
xcb_xinerama_get_screen_count_unchecked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */);
@@ -497,7 +497,7 @@ xcb_xinerama_get_screen_count_unchecked (xcb_connection_t *c /**< */,
* @param e The xcb_generic_error_t supplied
*
* Returns the reply of the request asked by
- *
+ *
* The parameter @p e supplied to this function must be NULL if
* xcb_xinerama_get_screen_count_unchecked(). is used.
* Otherwise, it stores the error if any.
@@ -508,51 +508,51 @@ xcb_xinerama_get_screen_count_unchecked (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_count_reply_t * xcb_xinerama_get_screen_count_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_get_screen_count_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_get_screen_count_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_count_reply_t *
xcb_xinerama_get_screen_count_reply (xcb_connection_t *c /**< */,
xcb_xinerama_get_screen_count_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
*/
/*****************************************************************************
**
** xcb_xinerama_get_screen_size_cookie_t xcb_xinerama_get_screen_size
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @param uint32_t screen
** @returns xcb_xinerama_get_screen_size_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_size_cookie_t
xcb_xinerama_get_screen_size (xcb_connection_t *c /**< */,
xcb_window_t window /**< */,
uint32_t screen /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
* This form can be used only if the request will cause
* a reply to be generated. Any returned error will be
* placed in the event queue.
@@ -561,14 +561,14 @@ xcb_xinerama_get_screen_size (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_size_cookie_t xcb_xinerama_get_screen_size_unchecked
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @param uint32_t screen
** @returns xcb_xinerama_get_screen_size_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_size_cookie_t
xcb_xinerama_get_screen_size_unchecked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */,
@@ -581,7 +581,7 @@ xcb_xinerama_get_screen_size_unchecked (xcb_connection_t *c /**< */,
* @param e The xcb_generic_error_t supplied
*
* Returns the reply of the request asked by
- *
+ *
* The parameter @p e supplied to this function must be NULL if
* xcb_xinerama_get_screen_size_unchecked(). is used.
* Otherwise, it stores the error if any.
@@ -592,47 +592,47 @@ xcb_xinerama_get_screen_size_unchecked (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_size_reply_t * xcb_xinerama_get_screen_size_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_get_screen_size_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_get_screen_size_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_size_reply_t *
xcb_xinerama_get_screen_size_reply (xcb_connection_t *c /**< */,
xcb_xinerama_get_screen_size_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
*/
/*****************************************************************************
**
** xcb_xinerama_is_active_cookie_t xcb_xinerama_is_active
- **
+ **
** @param xcb_connection_t *c
** @returns xcb_xinerama_is_active_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_is_active_cookie_t
xcb_xinerama_is_active (xcb_connection_t *c /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
* This form can be used only if the request will cause
* a reply to be generated. Any returned error will be
* placed in the event queue.
@@ -641,12 +641,12 @@ xcb_xinerama_is_active (xcb_connection_t *c /**< */);
/*****************************************************************************
**
** xcb_xinerama_is_active_cookie_t xcb_xinerama_is_active_unchecked
- **
+ **
** @param xcb_connection_t *c
** @returns xcb_xinerama_is_active_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_is_active_cookie_t
xcb_xinerama_is_active_unchecked (xcb_connection_t *c /**< */);
@@ -657,7 +657,7 @@ xcb_xinerama_is_active_unchecked (xcb_connection_t *c /**< */);
* @param e The xcb_generic_error_t supplied
*
* Returns the reply of the request asked by
- *
+ *
* The parameter @p e supplied to this function must be NULL if
* xcb_xinerama_is_active_unchecked(). is used.
* Otherwise, it stores the error if any.
@@ -668,47 +668,50 @@ xcb_xinerama_is_active_unchecked (xcb_connection_t *c /**< */);
/*****************************************************************************
**
** xcb_xinerama_is_active_reply_t * xcb_xinerama_is_active_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_is_active_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_is_active_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_is_active_reply_t *
xcb_xinerama_is_active_reply (xcb_connection_t *c /**< */,
xcb_xinerama_is_active_cookie_t cookie /**< */,
xcb_generic_error_t **e /**< */);
+int
+xcb_xinerama_query_screens_sizeof (const void *_buffer /**< */);
+
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
*/
/*****************************************************************************
**
** xcb_xinerama_query_screens_cookie_t xcb_xinerama_query_screens
- **
+ **
** @param xcb_connection_t *c
** @returns xcb_xinerama_query_screens_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_query_screens_cookie_t
xcb_xinerama_query_screens (xcb_connection_t *c /**< */);
/**
- * Delivers a request to the X server
+ *
* @param c The connection
* @return A cookie
*
* Delivers a request to the X server.
- *
+ *
* This form can be used only if the request will cause
* a reply to be generated. Any returned error will be
* placed in the event queue.
@@ -717,12 +720,12 @@ xcb_xinerama_query_screens (xcb_connection_t *c /**< */);
/*****************************************************************************
**
** xcb_xinerama_query_screens_cookie_t xcb_xinerama_query_screens_unchecked
- **
+ **
** @param xcb_connection_t *c
** @returns xcb_xinerama_query_screens_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_query_screens_cookie_t
xcb_xinerama_query_screens_unchecked (xcb_connection_t *c /**< */);
@@ -730,12 +733,12 @@ xcb_xinerama_query_screens_unchecked (xcb_connection_t *c /**< */);
/*****************************************************************************
**
** xcb_xinerama_screen_info_t * xcb_xinerama_query_screens_screen_info
- **
+ **
** @param const xcb_xinerama_query_screens_reply_t *R
** @returns xcb_xinerama_screen_info_t *
**
*****************************************************************************/
-
+
xcb_xinerama_screen_info_t *
xcb_xinerama_query_screens_screen_info (const xcb_xinerama_query_screens_reply_t *R /**< */);
@@ -743,12 +746,12 @@ xcb_xinerama_query_screens_screen_info (const xcb_xinerama_query_screens_reply_t
/*****************************************************************************
**
** int xcb_xinerama_query_screens_screen_info_length
- **
+ **
** @param const xcb_xinerama_query_screens_reply_t *R
** @returns int
**
*****************************************************************************/
-
+
int
xcb_xinerama_query_screens_screen_info_length (const xcb_xinerama_query_screens_reply_t *R /**< */);
@@ -756,12 +759,12 @@ xcb_xinerama_query_screens_screen_info_length (const xcb_xinerama_query_screens_
/*****************************************************************************
**
** xcb_xinerama_screen_info_iterator_t xcb_xinerama_query_screens_screen_info_iterator
- **
+ **
** @param const xcb_xinerama_query_screens_reply_t *R
** @returns xcb_xinerama_screen_info_iterator_t
**
*****************************************************************************/
-
+
xcb_xinerama_screen_info_iterator_t
xcb_xinerama_query_screens_screen_info_iterator (const xcb_xinerama_query_screens_reply_t *R /**< */);
@@ -772,7 +775,7 @@ xcb_xinerama_query_screens_screen_info_iterator (const xcb_xinerama_query_screen
* @param e The xcb_generic_error_t supplied
*
* Returns the reply of the request asked by
- *
+ *
* The parameter @p e supplied to this function must be NULL if
* xcb_xinerama_query_screens_unchecked(). is used.
* Otherwise, it stores the error if any.
@@ -783,14 +786,14 @@ xcb_xinerama_query_screens_screen_info_iterator (const xcb_xinerama_query_screen
/*****************************************************************************
**
** xcb_xinerama_query_screens_reply_t * xcb_xinerama_query_screens_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_query_screens_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_query_screens_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_query_screens_reply_t *
xcb_xinerama_query_screens_reply (xcb_connection_t *c /**< */,
xcb_xinerama_query_screens_cookie_t cookie /**< */,
diff --git a/src/3rdparty/xcb/include/xcb/xinput.h b/src/3rdparty/xcb/include/xcb/xinput.h
new file mode 100644
index 0000000000..9420047c71
--- /dev/null
+++ b/src/3rdparty/xcb/include/xcb/xinput.h
@@ -0,0 +1,9306 @@
+/*
+ * This file generated automatically from xinput.xml by c_client.py.
+ * Edit at your peril.
+ */
+
+/**
+ * @defgroup XCB_Input_API XCB Input API
+ * @brief Input XCB Protocol Implementation.
+ * @{
+ **/
+
+#ifndef __XINPUT_H
+#define __XINPUT_H
+
+#include "xcb.h"
+#include "xfixes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XCB_INPUT_MAJOR_VERSION 2
+#define XCB_INPUT_MINOR_VERSION 3
+
+extern xcb_extension_t xcb_input_id;
+
+typedef uint32_t xcb_input_event_class_t;
+
+/**
+ * @brief xcb_input_event_class_iterator_t
+ **/
+typedef struct xcb_input_event_class_iterator_t {
+ xcb_input_event_class_t *data;
+ int rem;
+ int index;
+} xcb_input_event_class_iterator_t;
+
+typedef uint8_t xcb_input_key_code_t;
+
+/**
+ * @brief xcb_input_key_code_iterator_t
+ **/
+typedef struct xcb_input_key_code_iterator_t {
+ xcb_input_key_code_t *data;
+ int rem;
+ int index;
+} xcb_input_key_code_iterator_t;
+
+typedef uint16_t xcb_input_device_id_t;
+
+/**
+ * @brief xcb_input_device_id_iterator_t
+ **/
+typedef struct xcb_input_device_id_iterator_t {
+ xcb_input_device_id_t *data;
+ int rem;
+ int index;
+} xcb_input_device_id_iterator_t;
+
+typedef int32_t xcb_input_fp1616_t;
+
+/**
+ * @brief xcb_input_fp1616_iterator_t
+ **/
+typedef struct xcb_input_fp1616_iterator_t {
+ xcb_input_fp1616_t *data;
+ int rem;
+ int index;
+} xcb_input_fp1616_iterator_t;
+
+/**
+ * @brief xcb_input_fp3232_t
+ **/
+typedef struct xcb_input_fp3232_t {
+ int32_t integral;
+ uint32_t frac;
+} xcb_input_fp3232_t;
+
+/**
+ * @brief xcb_input_fp3232_iterator_t
+ **/
+typedef struct xcb_input_fp3232_iterator_t {
+ xcb_input_fp3232_t *data;
+ int rem;
+ int index;
+} xcb_input_fp3232_iterator_t;
+
+/**
+ * @brief xcb_input_get_extension_version_cookie_t
+ **/
+typedef struct xcb_input_get_extension_version_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_extension_version_cookie_t;
+
+/** Opcode for xcb_input_get_extension_version. */
+#define XCB_INPUT_GET_EXTENSION_VERSION 1
+
+/**
+ * @brief xcb_input_get_extension_version_request_t
+ **/
+typedef struct xcb_input_get_extension_version_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint16_t name_len;
+ uint8_t pad0[2];
+} xcb_input_get_extension_version_request_t;
+
+/**
+ * @brief xcb_input_get_extension_version_reply_t
+ **/
+typedef struct xcb_input_get_extension_version_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t server_major;
+ uint16_t server_minor;
+ uint8_t present;
+ uint8_t pad0[19];
+} xcb_input_get_extension_version_reply_t;
+
+typedef enum xcb_input_device_use_t {
+ XCB_INPUT_DEVICE_USE_IS_X_POINTER = 0,
+ XCB_INPUT_DEVICE_USE_IS_X_KEYBOARD = 1,
+ XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_DEVICE = 2,
+ XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_KEYBOARD = 3,
+ XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_POINTER = 4
+} xcb_input_device_use_t;
+
+typedef enum xcb_input_input_class_t {
+ XCB_INPUT_INPUT_CLASS_KEY = 0,
+ XCB_INPUT_INPUT_CLASS_BUTTON = 1,
+ XCB_INPUT_INPUT_CLASS_VALUATOR = 2,
+ XCB_INPUT_INPUT_CLASS_FEEDBACK = 3,
+ XCB_INPUT_INPUT_CLASS_PROXIMITY = 4,
+ XCB_INPUT_INPUT_CLASS_FOCUS = 5,
+ XCB_INPUT_INPUT_CLASS_OTHER = 6
+} xcb_input_input_class_t;
+
+typedef enum xcb_input_valuator_mode_t {
+ XCB_INPUT_VALUATOR_MODE_RELATIVE = 0,
+ XCB_INPUT_VALUATOR_MODE_ABSOLUTE = 1
+} xcb_input_valuator_mode_t;
+
+/**
+ * @brief xcb_input_device_info_t
+ **/
+typedef struct xcb_input_device_info_t {
+ xcb_atom_t device_type;
+ uint8_t device_id;
+ uint8_t num_class_info;
+ uint8_t device_use;
+ uint8_t pad0;
+} xcb_input_device_info_t;
+
+/**
+ * @brief xcb_input_device_info_iterator_t
+ **/
+typedef struct xcb_input_device_info_iterator_t {
+ xcb_input_device_info_t *data;
+ int rem;
+ int index;
+} xcb_input_device_info_iterator_t;
+
+/**
+ * @brief xcb_input_key_info_t
+ **/
+typedef struct xcb_input_key_info_t {
+ uint8_t class_id;
+ uint8_t len;
+ xcb_input_key_code_t min_keycode;
+ xcb_input_key_code_t max_keycode;
+ uint16_t num_keys;
+ uint8_t pad0[2];
+} xcb_input_key_info_t;
+
+/**
+ * @brief xcb_input_key_info_iterator_t
+ **/
+typedef struct xcb_input_key_info_iterator_t {
+ xcb_input_key_info_t *data;
+ int rem;
+ int index;
+} xcb_input_key_info_iterator_t;
+
+/**
+ * @brief xcb_input_button_info_t
+ **/
+typedef struct xcb_input_button_info_t {
+ uint8_t class_id;
+ uint8_t len;
+ uint16_t num_buttons;
+} xcb_input_button_info_t;
+
+/**
+ * @brief xcb_input_button_info_iterator_t
+ **/
+typedef struct xcb_input_button_info_iterator_t {
+ xcb_input_button_info_t *data;
+ int rem;
+ int index;
+} xcb_input_button_info_iterator_t;
+
+/**
+ * @brief xcb_input_axis_info_t
+ **/
+typedef struct xcb_input_axis_info_t {
+ uint32_t resolution;
+ int32_t minimum;
+ int32_t maximum;
+} xcb_input_axis_info_t;
+
+/**
+ * @brief xcb_input_axis_info_iterator_t
+ **/
+typedef struct xcb_input_axis_info_iterator_t {
+ xcb_input_axis_info_t *data;
+ int rem;
+ int index;
+} xcb_input_axis_info_iterator_t;
+
+/**
+ * @brief xcb_input_valuator_info_t
+ **/
+typedef struct xcb_input_valuator_info_t {
+ uint8_t class_id;
+ uint8_t len;
+ uint8_t axes_len;
+ uint8_t mode;
+ uint32_t motion_size;
+} xcb_input_valuator_info_t;
+
+/**
+ * @brief xcb_input_valuator_info_iterator_t
+ **/
+typedef struct xcb_input_valuator_info_iterator_t {
+ xcb_input_valuator_info_t *data;
+ int rem;
+ int index;
+} xcb_input_valuator_info_iterator_t;
+
+/**
+ * @brief xcb_input_input_info_info_t
+ **/
+typedef struct xcb_input_input_info_info_t {
+ struct {
+ xcb_input_key_code_t min_keycode;
+ xcb_input_key_code_t max_keycode;
+ uint16_t num_keys;
+ uint8_t pad0[2];
+ } key;
+ struct {
+ uint16_t num_buttons;
+ } button;
+ struct {
+ uint8_t axes_len;
+ uint8_t mode;
+ uint32_t motion_size;
+ xcb_input_axis_info_t *axes;
+ } valuator;
+} xcb_input_input_info_info_t;
+
+/**
+ * @brief xcb_input_input_info_t
+ **/
+typedef struct xcb_input_input_info_t {
+ uint8_t class_id;
+ uint8_t len;
+} xcb_input_input_info_t;
+
+void *
+xcb_input_input_info_info (const xcb_input_input_info_t *R);
+
+/**
+ * @brief xcb_input_input_info_iterator_t
+ **/
+typedef struct xcb_input_input_info_iterator_t {
+ xcb_input_input_info_t *data;
+ int rem;
+ int index;
+} xcb_input_input_info_iterator_t;
+
+/**
+ * @brief xcb_input_device_name_t
+ **/
+typedef struct xcb_input_device_name_t {
+ uint8_t len;
+} xcb_input_device_name_t;
+
+/**
+ * @brief xcb_input_device_name_iterator_t
+ **/
+typedef struct xcb_input_device_name_iterator_t {
+ xcb_input_device_name_t *data;
+ int rem;
+ int index;
+} xcb_input_device_name_iterator_t;
+
+/**
+ * @brief xcb_input_list_input_devices_cookie_t
+ **/
+typedef struct xcb_input_list_input_devices_cookie_t {
+ unsigned int sequence;
+} xcb_input_list_input_devices_cookie_t;
+
+/** Opcode for xcb_input_list_input_devices. */
+#define XCB_INPUT_LIST_INPUT_DEVICES 2
+
+/**
+ * @brief xcb_input_list_input_devices_request_t
+ **/
+typedef struct xcb_input_list_input_devices_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+} xcb_input_list_input_devices_request_t;
+
+/**
+ * @brief xcb_input_list_input_devices_reply_t
+ **/
+typedef struct xcb_input_list_input_devices_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t devices_len;
+ uint8_t pad0[23];
+} xcb_input_list_input_devices_reply_t;
+
+typedef uint8_t xcb_input_event_type_base_t;
+
+/**
+ * @brief xcb_input_event_type_base_iterator_t
+ **/
+typedef struct xcb_input_event_type_base_iterator_t {
+ xcb_input_event_type_base_t *data;
+ int rem;
+ int index;
+} xcb_input_event_type_base_iterator_t;
+
+/**
+ * @brief xcb_input_input_class_info_t
+ **/
+typedef struct xcb_input_input_class_info_t {
+ uint8_t class_id;
+ xcb_input_event_type_base_t event_type_base;
+} xcb_input_input_class_info_t;
+
+/**
+ * @brief xcb_input_input_class_info_iterator_t
+ **/
+typedef struct xcb_input_input_class_info_iterator_t {
+ xcb_input_input_class_info_t *data;
+ int rem;
+ int index;
+} xcb_input_input_class_info_iterator_t;
+
+/**
+ * @brief xcb_input_open_device_cookie_t
+ **/
+typedef struct xcb_input_open_device_cookie_t {
+ unsigned int sequence;
+} xcb_input_open_device_cookie_t;
+
+/** Opcode for xcb_input_open_device. */
+#define XCB_INPUT_OPEN_DEVICE 3
+
+/**
+ * @brief xcb_input_open_device_request_t
+ **/
+typedef struct xcb_input_open_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_open_device_request_t;
+
+/**
+ * @brief xcb_input_open_device_reply_t
+ **/
+typedef struct xcb_input_open_device_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t num_classes;
+ uint8_t pad0[23];
+} xcb_input_open_device_reply_t;
+
+/** Opcode for xcb_input_close_device. */
+#define XCB_INPUT_CLOSE_DEVICE 4
+
+/**
+ * @brief xcb_input_close_device_request_t
+ **/
+typedef struct xcb_input_close_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_close_device_request_t;
+
+/**
+ * @brief xcb_input_set_device_mode_cookie_t
+ **/
+typedef struct xcb_input_set_device_mode_cookie_t {
+ unsigned int sequence;
+} xcb_input_set_device_mode_cookie_t;
+
+/** Opcode for xcb_input_set_device_mode. */
+#define XCB_INPUT_SET_DEVICE_MODE 5
+
+/**
+ * @brief xcb_input_set_device_mode_request_t
+ **/
+typedef struct xcb_input_set_device_mode_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t mode;
+ uint8_t pad0[2];
+} xcb_input_set_device_mode_request_t;
+
+/**
+ * @brief xcb_input_set_device_mode_reply_t
+ **/
+typedef struct xcb_input_set_device_mode_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_set_device_mode_reply_t;
+
+/** Opcode for xcb_input_select_extension_event. */
+#define XCB_INPUT_SELECT_EXTENSION_EVENT 6
+
+/**
+ * @brief xcb_input_select_extension_event_request_t
+ **/
+typedef struct xcb_input_select_extension_event_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+ uint16_t num_classes;
+ uint8_t pad0[2];
+} xcb_input_select_extension_event_request_t;
+
+/**
+ * @brief xcb_input_get_selected_extension_events_cookie_t
+ **/
+typedef struct xcb_input_get_selected_extension_events_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_selected_extension_events_cookie_t;
+
+/** Opcode for xcb_input_get_selected_extension_events. */
+#define XCB_INPUT_GET_SELECTED_EXTENSION_EVENTS 7
+
+/**
+ * @brief xcb_input_get_selected_extension_events_request_t
+ **/
+typedef struct xcb_input_get_selected_extension_events_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+} xcb_input_get_selected_extension_events_request_t;
+
+/**
+ * @brief xcb_input_get_selected_extension_events_reply_t
+ **/
+typedef struct xcb_input_get_selected_extension_events_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t num_this_classes;
+ uint16_t num_all_classes;
+ uint8_t pad0[20];
+} xcb_input_get_selected_extension_events_reply_t;
+
+typedef enum xcb_input_propagate_mode_t {
+ XCB_INPUT_PROPAGATE_MODE_ADD_TO_LIST = 0,
+ XCB_INPUT_PROPAGATE_MODE_DELETE_FROM_LIST = 1
+} xcb_input_propagate_mode_t;
+
+/** Opcode for xcb_input_change_device_dont_propagate_list. */
+#define XCB_INPUT_CHANGE_DEVICE_DONT_PROPAGATE_LIST 8
+
+/**
+ * @brief xcb_input_change_device_dont_propagate_list_request_t
+ **/
+typedef struct xcb_input_change_device_dont_propagate_list_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+ uint16_t num_classes;
+ uint8_t mode;
+ uint8_t pad0;
+} xcb_input_change_device_dont_propagate_list_request_t;
+
+/**
+ * @brief xcb_input_get_device_dont_propagate_list_cookie_t
+ **/
+typedef struct xcb_input_get_device_dont_propagate_list_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_device_dont_propagate_list_cookie_t;
+
+/** Opcode for xcb_input_get_device_dont_propagate_list. */
+#define XCB_INPUT_GET_DEVICE_DONT_PROPAGATE_LIST 9
+
+/**
+ * @brief xcb_input_get_device_dont_propagate_list_request_t
+ **/
+typedef struct xcb_input_get_device_dont_propagate_list_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+} xcb_input_get_device_dont_propagate_list_request_t;
+
+/**
+ * @brief xcb_input_get_device_dont_propagate_list_reply_t
+ **/
+typedef struct xcb_input_get_device_dont_propagate_list_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t num_classes;
+ uint8_t pad0[22];
+} xcb_input_get_device_dont_propagate_list_reply_t;
+
+/**
+ * @brief xcb_input_device_time_coord_t
+ **/
+typedef struct xcb_input_device_time_coord_t {
+ xcb_timestamp_t time;
+} xcb_input_device_time_coord_t;
+
+/**
+ * @brief xcb_input_device_time_coord_iterator_t
+ **/
+typedef struct xcb_input_device_time_coord_iterator_t {
+ xcb_input_device_time_coord_t *data;
+ int rem;
+ int index;
+ uint8_t num_axes; /**< */
+} xcb_input_device_time_coord_iterator_t;
+
+/**
+ * @brief xcb_input_get_device_motion_events_cookie_t
+ **/
+typedef struct xcb_input_get_device_motion_events_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_device_motion_events_cookie_t;
+
+/** Opcode for xcb_input_get_device_motion_events. */
+#define XCB_INPUT_GET_DEVICE_MOTION_EVENTS 10
+
+/**
+ * @brief xcb_input_get_device_motion_events_request_t
+ **/
+typedef struct xcb_input_get_device_motion_events_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_timestamp_t start;
+ xcb_timestamp_t stop;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_get_device_motion_events_request_t;
+
+/**
+ * @brief xcb_input_get_device_motion_events_reply_t
+ **/
+typedef struct xcb_input_get_device_motion_events_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint32_t num_events;
+ uint8_t num_axes;
+ uint8_t device_mode;
+ uint8_t pad0[18];
+} xcb_input_get_device_motion_events_reply_t;
+
+/**
+ * @brief xcb_input_change_keyboard_device_cookie_t
+ **/
+typedef struct xcb_input_change_keyboard_device_cookie_t {
+ unsigned int sequence;
+} xcb_input_change_keyboard_device_cookie_t;
+
+/** Opcode for xcb_input_change_keyboard_device. */
+#define XCB_INPUT_CHANGE_KEYBOARD_DEVICE 11
+
+/**
+ * @brief xcb_input_change_keyboard_device_request_t
+ **/
+typedef struct xcb_input_change_keyboard_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_change_keyboard_device_request_t;
+
+/**
+ * @brief xcb_input_change_keyboard_device_reply_t
+ **/
+typedef struct xcb_input_change_keyboard_device_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_change_keyboard_device_reply_t;
+
+/**
+ * @brief xcb_input_change_pointer_device_cookie_t
+ **/
+typedef struct xcb_input_change_pointer_device_cookie_t {
+ unsigned int sequence;
+} xcb_input_change_pointer_device_cookie_t;
+
+/** Opcode for xcb_input_change_pointer_device. */
+#define XCB_INPUT_CHANGE_POINTER_DEVICE 12
+
+/**
+ * @brief xcb_input_change_pointer_device_request_t
+ **/
+typedef struct xcb_input_change_pointer_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t x_axis;
+ uint8_t y_axis;
+ uint8_t device_id;
+ uint8_t pad0;
+} xcb_input_change_pointer_device_request_t;
+
+/**
+ * @brief xcb_input_change_pointer_device_reply_t
+ **/
+typedef struct xcb_input_change_pointer_device_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_change_pointer_device_reply_t;
+
+/**
+ * @brief xcb_input_grab_device_cookie_t
+ **/
+typedef struct xcb_input_grab_device_cookie_t {
+ unsigned int sequence;
+} xcb_input_grab_device_cookie_t;
+
+/** Opcode for xcb_input_grab_device. */
+#define XCB_INPUT_GRAB_DEVICE 13
+
+/**
+ * @brief xcb_input_grab_device_request_t
+ **/
+typedef struct xcb_input_grab_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t grab_window;
+ xcb_timestamp_t time;
+ uint16_t num_classes;
+ uint8_t this_device_mode;
+ uint8_t other_device_mode;
+ uint8_t owner_events;
+ uint8_t device_id;
+ uint8_t pad0[2];
+} xcb_input_grab_device_request_t;
+
+/**
+ * @brief xcb_input_grab_device_reply_t
+ **/
+typedef struct xcb_input_grab_device_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_grab_device_reply_t;
+
+/** Opcode for xcb_input_ungrab_device. */
+#define XCB_INPUT_UNGRAB_DEVICE 14
+
+/**
+ * @brief xcb_input_ungrab_device_request_t
+ **/
+typedef struct xcb_input_ungrab_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_timestamp_t time;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_ungrab_device_request_t;
+
+typedef enum xcb_input_modifier_device_t {
+ XCB_INPUT_MODIFIER_DEVICE_USE_X_KEYBOARD = 255
+} xcb_input_modifier_device_t;
+
+/** Opcode for xcb_input_grab_device_key. */
+#define XCB_INPUT_GRAB_DEVICE_KEY 15
+
+/**
+ * @brief xcb_input_grab_device_key_request_t
+ **/
+typedef struct xcb_input_grab_device_key_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t grab_window;
+ uint16_t num_classes;
+ uint16_t modifiers;
+ uint8_t modifier_device;
+ uint8_t grabbed_device;
+ uint8_t key;
+ uint8_t this_device_mode;
+ uint8_t other_device_mode;
+ uint8_t owner_events;
+ uint8_t pad0[2];
+} xcb_input_grab_device_key_request_t;
+
+/** Opcode for xcb_input_ungrab_device_key. */
+#define XCB_INPUT_UNGRAB_DEVICE_KEY 16
+
+/**
+ * @brief xcb_input_ungrab_device_key_request_t
+ **/
+typedef struct xcb_input_ungrab_device_key_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t grabWindow;
+ uint16_t modifiers;
+ uint8_t modifier_device;
+ uint8_t key;
+ uint8_t grabbed_device;
+} xcb_input_ungrab_device_key_request_t;
+
+/** Opcode for xcb_input_grab_device_button. */
+#define XCB_INPUT_GRAB_DEVICE_BUTTON 17
+
+/**
+ * @brief xcb_input_grab_device_button_request_t
+ **/
+typedef struct xcb_input_grab_device_button_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t grab_window;
+ uint8_t grabbed_device;
+ uint8_t modifier_device;
+ uint16_t num_classes;
+ uint16_t modifiers;
+ uint8_t this_device_mode;
+ uint8_t other_device_mode;
+ uint8_t button;
+ uint8_t owner_events;
+ uint8_t pad0[2];
+} xcb_input_grab_device_button_request_t;
+
+/** Opcode for xcb_input_ungrab_device_button. */
+#define XCB_INPUT_UNGRAB_DEVICE_BUTTON 18
+
+/**
+ * @brief xcb_input_ungrab_device_button_request_t
+ **/
+typedef struct xcb_input_ungrab_device_button_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t grab_window;
+ uint16_t modifiers;
+ uint8_t modifier_device;
+ uint8_t button;
+ uint8_t grabbed_device;
+ uint8_t pad0[3];
+} xcb_input_ungrab_device_button_request_t;
+
+typedef enum xcb_input_device_input_mode_t {
+ XCB_INPUT_DEVICE_INPUT_MODE_ASYNC_THIS_DEVICE = 0,
+ XCB_INPUT_DEVICE_INPUT_MODE_SYNC_THIS_DEVICE = 1,
+ XCB_INPUT_DEVICE_INPUT_MODE_REPLAY_THIS_DEVICE = 2,
+ XCB_INPUT_DEVICE_INPUT_MODE_ASYNC_OTHER_DEVICES = 3,
+ XCB_INPUT_DEVICE_INPUT_MODE_ASYNC_ALL = 4,
+ XCB_INPUT_DEVICE_INPUT_MODE_SYNC_ALL = 5
+} xcb_input_device_input_mode_t;
+
+/** Opcode for xcb_input_allow_device_events. */
+#define XCB_INPUT_ALLOW_DEVICE_EVENTS 19
+
+/**
+ * @brief xcb_input_allow_device_events_request_t
+ **/
+typedef struct xcb_input_allow_device_events_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_timestamp_t time;
+ uint8_t mode;
+ uint8_t device_id;
+ uint8_t pad0[2];
+} xcb_input_allow_device_events_request_t;
+
+/**
+ * @brief xcb_input_get_device_focus_cookie_t
+ **/
+typedef struct xcb_input_get_device_focus_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_device_focus_cookie_t;
+
+/** Opcode for xcb_input_get_device_focus. */
+#define XCB_INPUT_GET_DEVICE_FOCUS 20
+
+/**
+ * @brief xcb_input_get_device_focus_request_t
+ **/
+typedef struct xcb_input_get_device_focus_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_get_device_focus_request_t;
+
+/**
+ * @brief xcb_input_get_device_focus_reply_t
+ **/
+typedef struct xcb_input_get_device_focus_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ xcb_window_t focus;
+ xcb_timestamp_t time;
+ uint8_t revert_to;
+ uint8_t pad0[15];
+} xcb_input_get_device_focus_reply_t;
+
+/** Opcode for xcb_input_set_device_focus. */
+#define XCB_INPUT_SET_DEVICE_FOCUS 21
+
+/**
+ * @brief xcb_input_set_device_focus_request_t
+ **/
+typedef struct xcb_input_set_device_focus_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t focus;
+ xcb_timestamp_t time;
+ uint8_t revert_to;
+ uint8_t device_id;
+ uint8_t pad0[2];
+} xcb_input_set_device_focus_request_t;
+
+typedef enum xcb_input_feedback_class_t {
+ XCB_INPUT_FEEDBACK_CLASS_KEYBOARD = 0,
+ XCB_INPUT_FEEDBACK_CLASS_POINTER = 1,
+ XCB_INPUT_FEEDBACK_CLASS_STRING = 2,
+ XCB_INPUT_FEEDBACK_CLASS_INTEGER = 3,
+ XCB_INPUT_FEEDBACK_CLASS_LED = 4,
+ XCB_INPUT_FEEDBACK_CLASS_BELL = 5
+} xcb_input_feedback_class_t;
+
+/**
+ * @brief xcb_input_kbd_feedback_state_t
+ **/
+typedef struct xcb_input_kbd_feedback_state_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint16_t pitch;
+ uint16_t duration;
+ uint32_t led_mask;
+ uint32_t led_values;
+ uint8_t global_auto_repeat;
+ uint8_t click;
+ uint8_t percent;
+ uint8_t pad0;
+ uint8_t auto_repeats[32];
+} xcb_input_kbd_feedback_state_t;
+
+/**
+ * @brief xcb_input_kbd_feedback_state_iterator_t
+ **/
+typedef struct xcb_input_kbd_feedback_state_iterator_t {
+ xcb_input_kbd_feedback_state_t *data;
+ int rem;
+ int index;
+} xcb_input_kbd_feedback_state_iterator_t;
+
+/**
+ * @brief xcb_input_ptr_feedback_state_t
+ **/
+typedef struct xcb_input_ptr_feedback_state_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint8_t pad0[2];
+ uint16_t accel_num;
+ uint16_t accel_denom;
+ uint16_t threshold;
+} xcb_input_ptr_feedback_state_t;
+
+/**
+ * @brief xcb_input_ptr_feedback_state_iterator_t
+ **/
+typedef struct xcb_input_ptr_feedback_state_iterator_t {
+ xcb_input_ptr_feedback_state_t *data;
+ int rem;
+ int index;
+} xcb_input_ptr_feedback_state_iterator_t;
+
+/**
+ * @brief xcb_input_integer_feedback_state_t
+ **/
+typedef struct xcb_input_integer_feedback_state_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint32_t resolution;
+ int32_t min_value;
+ int32_t max_value;
+} xcb_input_integer_feedback_state_t;
+
+/**
+ * @brief xcb_input_integer_feedback_state_iterator_t
+ **/
+typedef struct xcb_input_integer_feedback_state_iterator_t {
+ xcb_input_integer_feedback_state_t *data;
+ int rem;
+ int index;
+} xcb_input_integer_feedback_state_iterator_t;
+
+/**
+ * @brief xcb_input_string_feedback_state_t
+ **/
+typedef struct xcb_input_string_feedback_state_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint16_t max_symbols;
+ uint16_t num_keysyms;
+} xcb_input_string_feedback_state_t;
+
+/**
+ * @brief xcb_input_string_feedback_state_iterator_t
+ **/
+typedef struct xcb_input_string_feedback_state_iterator_t {
+ xcb_input_string_feedback_state_t *data;
+ int rem;
+ int index;
+} xcb_input_string_feedback_state_iterator_t;
+
+/**
+ * @brief xcb_input_bell_feedback_state_t
+ **/
+typedef struct xcb_input_bell_feedback_state_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint8_t percent;
+ uint8_t pad0[3];
+ uint16_t pitch;
+ uint16_t duration;
+} xcb_input_bell_feedback_state_t;
+
+/**
+ * @brief xcb_input_bell_feedback_state_iterator_t
+ **/
+typedef struct xcb_input_bell_feedback_state_iterator_t {
+ xcb_input_bell_feedback_state_t *data;
+ int rem;
+ int index;
+} xcb_input_bell_feedback_state_iterator_t;
+
+/**
+ * @brief xcb_input_led_feedback_state_t
+ **/
+typedef struct xcb_input_led_feedback_state_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint32_t led_mask;
+ uint32_t led_values;
+} xcb_input_led_feedback_state_t;
+
+/**
+ * @brief xcb_input_led_feedback_state_iterator_t
+ **/
+typedef struct xcb_input_led_feedback_state_iterator_t {
+ xcb_input_led_feedback_state_t *data;
+ int rem;
+ int index;
+} xcb_input_led_feedback_state_iterator_t;
+
+/**
+ * @brief xcb_input_feedback_state_data_t
+ **/
+typedef struct xcb_input_feedback_state_data_t {
+ struct {
+ uint16_t pitch;
+ uint16_t duration;
+ uint32_t led_mask;
+ uint32_t led_values;
+ uint8_t global_auto_repeat;
+ uint8_t click;
+ uint8_t percent;
+ uint8_t pad0;
+ uint8_t auto_repeats[32];
+ } keyboard;
+ struct {
+ uint8_t pad1[2];
+ uint16_t accel_num;
+ uint16_t accel_denom;
+ uint16_t threshold;
+ } pointer;
+ struct {
+ uint16_t max_symbols;
+ uint16_t num_keysyms;
+ xcb_keysym_t *keysyms;
+ } string;
+ struct {
+ uint32_t resolution;
+ int32_t min_value;
+ int32_t max_value;
+ } integer;
+ struct {
+ uint32_t led_mask;
+ uint32_t led_values;
+ } led;
+ struct {
+ uint8_t percent;
+ uint8_t pad2[3];
+ uint16_t pitch;
+ uint16_t duration;
+ } bell;
+} xcb_input_feedback_state_data_t;
+
+/**
+ * @brief xcb_input_feedback_state_t
+ **/
+typedef struct xcb_input_feedback_state_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+} xcb_input_feedback_state_t;
+
+void *
+xcb_input_feedback_state_data (const xcb_input_feedback_state_t *R);
+
+/**
+ * @brief xcb_input_feedback_state_iterator_t
+ **/
+typedef struct xcb_input_feedback_state_iterator_t {
+ xcb_input_feedback_state_t *data;
+ int rem;
+ int index;
+} xcb_input_feedback_state_iterator_t;
+
+/**
+ * @brief xcb_input_get_feedback_control_cookie_t
+ **/
+typedef struct xcb_input_get_feedback_control_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_feedback_control_cookie_t;
+
+/** Opcode for xcb_input_get_feedback_control. */
+#define XCB_INPUT_GET_FEEDBACK_CONTROL 22
+
+/**
+ * @brief xcb_input_get_feedback_control_request_t
+ **/
+typedef struct xcb_input_get_feedback_control_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_get_feedback_control_request_t;
+
+/**
+ * @brief xcb_input_get_feedback_control_reply_t
+ **/
+typedef struct xcb_input_get_feedback_control_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t num_feedbacks;
+ uint8_t pad0[22];
+} xcb_input_get_feedback_control_reply_t;
+
+/**
+ * @brief xcb_input_kbd_feedback_ctl_t
+ **/
+typedef struct xcb_input_kbd_feedback_ctl_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ xcb_input_key_code_t key;
+ uint8_t auto_repeat_mode;
+ int8_t key_click_percent;
+ int8_t bell_percent;
+ int16_t bell_pitch;
+ int16_t bell_duration;
+ uint32_t led_mask;
+ uint32_t led_values;
+} xcb_input_kbd_feedback_ctl_t;
+
+/**
+ * @brief xcb_input_kbd_feedback_ctl_iterator_t
+ **/
+typedef struct xcb_input_kbd_feedback_ctl_iterator_t {
+ xcb_input_kbd_feedback_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_kbd_feedback_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_ptr_feedback_ctl_t
+ **/
+typedef struct xcb_input_ptr_feedback_ctl_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint8_t pad0[2];
+ int16_t num;
+ int16_t denom;
+ int16_t threshold;
+} xcb_input_ptr_feedback_ctl_t;
+
+/**
+ * @brief xcb_input_ptr_feedback_ctl_iterator_t
+ **/
+typedef struct xcb_input_ptr_feedback_ctl_iterator_t {
+ xcb_input_ptr_feedback_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_ptr_feedback_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_integer_feedback_ctl_t
+ **/
+typedef struct xcb_input_integer_feedback_ctl_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ int32_t int_to_display;
+} xcb_input_integer_feedback_ctl_t;
+
+/**
+ * @brief xcb_input_integer_feedback_ctl_iterator_t
+ **/
+typedef struct xcb_input_integer_feedback_ctl_iterator_t {
+ xcb_input_integer_feedback_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_integer_feedback_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_string_feedback_ctl_t
+ **/
+typedef struct xcb_input_string_feedback_ctl_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint8_t pad0[2];
+ uint16_t num_keysyms;
+} xcb_input_string_feedback_ctl_t;
+
+/**
+ * @brief xcb_input_string_feedback_ctl_iterator_t
+ **/
+typedef struct xcb_input_string_feedback_ctl_iterator_t {
+ xcb_input_string_feedback_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_string_feedback_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_bell_feedback_ctl_t
+ **/
+typedef struct xcb_input_bell_feedback_ctl_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ int8_t percent;
+ uint8_t pad0[3];
+ int16_t pitch;
+ int16_t duration;
+} xcb_input_bell_feedback_ctl_t;
+
+/**
+ * @brief xcb_input_bell_feedback_ctl_iterator_t
+ **/
+typedef struct xcb_input_bell_feedback_ctl_iterator_t {
+ xcb_input_bell_feedback_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_bell_feedback_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_led_feedback_ctl_t
+ **/
+typedef struct xcb_input_led_feedback_ctl_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+ uint32_t led_mask;
+ uint32_t led_values;
+} xcb_input_led_feedback_ctl_t;
+
+/**
+ * @brief xcb_input_led_feedback_ctl_iterator_t
+ **/
+typedef struct xcb_input_led_feedback_ctl_iterator_t {
+ xcb_input_led_feedback_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_led_feedback_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_feedback_ctl_data_t
+ **/
+typedef struct xcb_input_feedback_ctl_data_t {
+ struct {
+ xcb_input_key_code_t key;
+ uint8_t auto_repeat_mode;
+ int8_t key_click_percent;
+ int8_t bell_percent;
+ int16_t bell_pitch;
+ int16_t bell_duration;
+ uint32_t led_mask;
+ uint32_t led_values;
+ } keyboard;
+ struct {
+ uint8_t pad0[2];
+ int16_t num;
+ int16_t denom;
+ int16_t threshold;
+ } pointer;
+ struct {
+ uint8_t pad1[2];
+ uint16_t num_keysyms;
+ xcb_keysym_t *keysyms;
+ } string;
+ struct {
+ int32_t int_to_display;
+ } integer;
+ struct {
+ uint32_t led_mask;
+ uint32_t led_values;
+ } led;
+ struct {
+ int8_t percent;
+ uint8_t pad2[3];
+ int16_t pitch;
+ int16_t duration;
+ } bell;
+} xcb_input_feedback_ctl_data_t;
+
+/**
+ * @brief xcb_input_feedback_ctl_t
+ **/
+typedef struct xcb_input_feedback_ctl_t {
+ uint8_t class_id;
+ uint8_t feedback_id;
+ uint16_t len;
+} xcb_input_feedback_ctl_t;
+
+void *
+xcb_input_feedback_ctl_data (const xcb_input_feedback_ctl_t *R);
+
+/**
+ * @brief xcb_input_feedback_ctl_iterator_t
+ **/
+typedef struct xcb_input_feedback_ctl_iterator_t {
+ xcb_input_feedback_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_feedback_ctl_iterator_t;
+
+typedef enum xcb_input_change_feedback_control_mask_t {
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_KEY_CLICK_PERCENT = 1,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_PERCENT = 2,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_PITCH = 4,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_DURATION = 8,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_LED = 16,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_LED_MODE = 32,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_KEY = 64,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_AUTO_REPEAT_MODE = 128,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_STRING = 1,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_INTEGER = 1,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_ACCEL_NUM = 1,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_ACCEL_DENOM = 2,
+ XCB_INPUT_CHANGE_FEEDBACK_CONTROL_MASK_THRESHOLD = 4
+} xcb_input_change_feedback_control_mask_t;
+
+/** Opcode for xcb_input_change_feedback_control. */
+#define XCB_INPUT_CHANGE_FEEDBACK_CONTROL 23
+
+/**
+ * @brief xcb_input_change_feedback_control_request_t
+ **/
+typedef struct xcb_input_change_feedback_control_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint32_t mask;
+ uint8_t device_id;
+ uint8_t feedback_id;
+ uint8_t pad0[2];
+} xcb_input_change_feedback_control_request_t;
+
+/**
+ * @brief xcb_input_get_device_key_mapping_cookie_t
+ **/
+typedef struct xcb_input_get_device_key_mapping_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_device_key_mapping_cookie_t;
+
+/** Opcode for xcb_input_get_device_key_mapping. */
+#define XCB_INPUT_GET_DEVICE_KEY_MAPPING 24
+
+/**
+ * @brief xcb_input_get_device_key_mapping_request_t
+ **/
+typedef struct xcb_input_get_device_key_mapping_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ xcb_input_key_code_t first_keycode;
+ uint8_t count;
+ uint8_t pad0;
+} xcb_input_get_device_key_mapping_request_t;
+
+/**
+ * @brief xcb_input_get_device_key_mapping_reply_t
+ **/
+typedef struct xcb_input_get_device_key_mapping_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t keysyms_per_keycode;
+ uint8_t pad0[23];
+} xcb_input_get_device_key_mapping_reply_t;
+
+/** Opcode for xcb_input_change_device_key_mapping. */
+#define XCB_INPUT_CHANGE_DEVICE_KEY_MAPPING 25
+
+/**
+ * @brief xcb_input_change_device_key_mapping_request_t
+ **/
+typedef struct xcb_input_change_device_key_mapping_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ xcb_input_key_code_t first_keycode;
+ uint8_t keysyms_per_keycode;
+ uint8_t keycode_count;
+} xcb_input_change_device_key_mapping_request_t;
+
+/**
+ * @brief xcb_input_get_device_modifier_mapping_cookie_t
+ **/
+typedef struct xcb_input_get_device_modifier_mapping_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_device_modifier_mapping_cookie_t;
+
+/** Opcode for xcb_input_get_device_modifier_mapping. */
+#define XCB_INPUT_GET_DEVICE_MODIFIER_MAPPING 26
+
+/**
+ * @brief xcb_input_get_device_modifier_mapping_request_t
+ **/
+typedef struct xcb_input_get_device_modifier_mapping_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_get_device_modifier_mapping_request_t;
+
+/**
+ * @brief xcb_input_get_device_modifier_mapping_reply_t
+ **/
+typedef struct xcb_input_get_device_modifier_mapping_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t keycodes_per_modifier;
+ uint8_t pad0[23];
+} xcb_input_get_device_modifier_mapping_reply_t;
+
+/**
+ * @brief xcb_input_set_device_modifier_mapping_cookie_t
+ **/
+typedef struct xcb_input_set_device_modifier_mapping_cookie_t {
+ unsigned int sequence;
+} xcb_input_set_device_modifier_mapping_cookie_t;
+
+/** Opcode for xcb_input_set_device_modifier_mapping. */
+#define XCB_INPUT_SET_DEVICE_MODIFIER_MAPPING 27
+
+/**
+ * @brief xcb_input_set_device_modifier_mapping_request_t
+ **/
+typedef struct xcb_input_set_device_modifier_mapping_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t keycodes_per_modifier;
+ uint8_t pad0[2];
+} xcb_input_set_device_modifier_mapping_request_t;
+
+/**
+ * @brief xcb_input_set_device_modifier_mapping_reply_t
+ **/
+typedef struct xcb_input_set_device_modifier_mapping_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_set_device_modifier_mapping_reply_t;
+
+/**
+ * @brief xcb_input_get_device_button_mapping_cookie_t
+ **/
+typedef struct xcb_input_get_device_button_mapping_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_device_button_mapping_cookie_t;
+
+/** Opcode for xcb_input_get_device_button_mapping. */
+#define XCB_INPUT_GET_DEVICE_BUTTON_MAPPING 28
+
+/**
+ * @brief xcb_input_get_device_button_mapping_request_t
+ **/
+typedef struct xcb_input_get_device_button_mapping_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_get_device_button_mapping_request_t;
+
+/**
+ * @brief xcb_input_get_device_button_mapping_reply_t
+ **/
+typedef struct xcb_input_get_device_button_mapping_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t map_size;
+ uint8_t pad0[23];
+} xcb_input_get_device_button_mapping_reply_t;
+
+/**
+ * @brief xcb_input_set_device_button_mapping_cookie_t
+ **/
+typedef struct xcb_input_set_device_button_mapping_cookie_t {
+ unsigned int sequence;
+} xcb_input_set_device_button_mapping_cookie_t;
+
+/** Opcode for xcb_input_set_device_button_mapping. */
+#define XCB_INPUT_SET_DEVICE_BUTTON_MAPPING 29
+
+/**
+ * @brief xcb_input_set_device_button_mapping_request_t
+ **/
+typedef struct xcb_input_set_device_button_mapping_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t map_size;
+ uint8_t pad0[2];
+} xcb_input_set_device_button_mapping_request_t;
+
+/**
+ * @brief xcb_input_set_device_button_mapping_reply_t
+ **/
+typedef struct xcb_input_set_device_button_mapping_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_set_device_button_mapping_reply_t;
+
+/**
+ * @brief xcb_input_key_state_t
+ **/
+typedef struct xcb_input_key_state_t {
+ uint8_t class_id;
+ uint8_t len;
+ uint8_t num_keys;
+ uint8_t pad0;
+ uint8_t keys[32];
+} xcb_input_key_state_t;
+
+/**
+ * @brief xcb_input_key_state_iterator_t
+ **/
+typedef struct xcb_input_key_state_iterator_t {
+ xcb_input_key_state_t *data;
+ int rem;
+ int index;
+} xcb_input_key_state_iterator_t;
+
+/**
+ * @brief xcb_input_button_state_t
+ **/
+typedef struct xcb_input_button_state_t {
+ uint8_t class_id;
+ uint8_t len;
+ uint8_t num_buttons;
+ uint8_t pad0;
+ uint8_t buttons[32];
+} xcb_input_button_state_t;
+
+/**
+ * @brief xcb_input_button_state_iterator_t
+ **/
+typedef struct xcb_input_button_state_iterator_t {
+ xcb_input_button_state_t *data;
+ int rem;
+ int index;
+} xcb_input_button_state_iterator_t;
+
+typedef enum xcb_input_valuator_state_mode_mask_t {
+ XCB_INPUT_VALUATOR_STATE_MODE_MASK_DEVICE_MODE_ABSOLUTE = 1,
+ XCB_INPUT_VALUATOR_STATE_MODE_MASK_OUT_OF_PROXIMITY = 2
+} xcb_input_valuator_state_mode_mask_t;
+
+/**
+ * @brief xcb_input_valuator_state_t
+ **/
+typedef struct xcb_input_valuator_state_t {
+ uint8_t class_id;
+ uint8_t len;
+ uint8_t num_valuators;
+ uint8_t mode;
+} xcb_input_valuator_state_t;
+
+/**
+ * @brief xcb_input_valuator_state_iterator_t
+ **/
+typedef struct xcb_input_valuator_state_iterator_t {
+ xcb_input_valuator_state_t *data;
+ int rem;
+ int index;
+} xcb_input_valuator_state_iterator_t;
+
+/**
+ * @brief xcb_input_input_state_data_t
+ **/
+typedef struct xcb_input_input_state_data_t {
+ struct {
+ uint8_t num_keys;
+ uint8_t pad0;
+ uint8_t keys[32];
+ } key;
+ struct {
+ uint8_t num_buttons;
+ uint8_t pad1;
+ uint8_t buttons[32];
+ } button;
+ struct {
+ uint8_t num_valuators;
+ uint8_t mode;
+ int32_t *valuators;
+ } valuator;
+} xcb_input_input_state_data_t;
+
+/**
+ * @brief xcb_input_input_state_t
+ **/
+typedef struct xcb_input_input_state_t {
+ uint8_t class_id;
+ uint8_t len;
+} xcb_input_input_state_t;
+
+void *
+xcb_input_input_state_data (const xcb_input_input_state_t *R);
+
+/**
+ * @brief xcb_input_input_state_iterator_t
+ **/
+typedef struct xcb_input_input_state_iterator_t {
+ xcb_input_input_state_t *data;
+ int rem;
+ int index;
+} xcb_input_input_state_iterator_t;
+
+/**
+ * @brief xcb_input_query_device_state_cookie_t
+ **/
+typedef struct xcb_input_query_device_state_cookie_t {
+ unsigned int sequence;
+} xcb_input_query_device_state_cookie_t;
+
+/** Opcode for xcb_input_query_device_state. */
+#define XCB_INPUT_QUERY_DEVICE_STATE 30
+
+/**
+ * @brief xcb_input_query_device_state_request_t
+ **/
+typedef struct xcb_input_query_device_state_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_query_device_state_request_t;
+
+/**
+ * @brief xcb_input_query_device_state_reply_t
+ **/
+typedef struct xcb_input_query_device_state_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t num_classes;
+ uint8_t pad0[23];
+} xcb_input_query_device_state_reply_t;
+
+/** Opcode for xcb_input_device_bell. */
+#define XCB_INPUT_DEVICE_BELL 32
+
+/**
+ * @brief xcb_input_device_bell_request_t
+ **/
+typedef struct xcb_input_device_bell_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t feedback_id;
+ uint8_t feedback_class;
+ int8_t percent;
+} xcb_input_device_bell_request_t;
+
+/**
+ * @brief xcb_input_set_device_valuators_cookie_t
+ **/
+typedef struct xcb_input_set_device_valuators_cookie_t {
+ unsigned int sequence;
+} xcb_input_set_device_valuators_cookie_t;
+
+/** Opcode for xcb_input_set_device_valuators. */
+#define XCB_INPUT_SET_DEVICE_VALUATORS 33
+
+/**
+ * @brief xcb_input_set_device_valuators_request_t
+ **/
+typedef struct xcb_input_set_device_valuators_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t first_valuator;
+ uint8_t num_valuators;
+ uint8_t pad0;
+} xcb_input_set_device_valuators_request_t;
+
+/**
+ * @brief xcb_input_set_device_valuators_reply_t
+ **/
+typedef struct xcb_input_set_device_valuators_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_set_device_valuators_reply_t;
+
+typedef enum xcb_input_device_control_t {
+ XCB_INPUT_DEVICE_CONTROL_RESOLUTION = 1,
+ XCB_INPUT_DEVICE_CONTROL_ABS_CALIB = 2,
+ XCB_INPUT_DEVICE_CONTROL_CORE = 3,
+ XCB_INPUT_DEVICE_CONTROL_ENABLE = 4,
+ XCB_INPUT_DEVICE_CONTROL_ABS_AREA = 5
+} xcb_input_device_control_t;
+
+/**
+ * @brief xcb_input_device_resolution_state_t
+ **/
+typedef struct xcb_input_device_resolution_state_t {
+ uint16_t control_id;
+ uint16_t len;
+ uint32_t num_valuators;
+} xcb_input_device_resolution_state_t;
+
+/**
+ * @brief xcb_input_device_resolution_state_iterator_t
+ **/
+typedef struct xcb_input_device_resolution_state_iterator_t {
+ xcb_input_device_resolution_state_t *data;
+ int rem;
+ int index;
+} xcb_input_device_resolution_state_iterator_t;
+
+/**
+ * @brief xcb_input_device_abs_calib_state_t
+ **/
+typedef struct xcb_input_device_abs_calib_state_t {
+ uint16_t control_id;
+ uint16_t len;
+ int32_t min_x;
+ int32_t max_x;
+ int32_t min_y;
+ int32_t max_y;
+ uint32_t flip_x;
+ uint32_t flip_y;
+ uint32_t rotation;
+ uint32_t button_threshold;
+} xcb_input_device_abs_calib_state_t;
+
+/**
+ * @brief xcb_input_device_abs_calib_state_iterator_t
+ **/
+typedef struct xcb_input_device_abs_calib_state_iterator_t {
+ xcb_input_device_abs_calib_state_t *data;
+ int rem;
+ int index;
+} xcb_input_device_abs_calib_state_iterator_t;
+
+/**
+ * @brief xcb_input_device_abs_area_state_t
+ **/
+typedef struct xcb_input_device_abs_area_state_t {
+ uint16_t control_id;
+ uint16_t len;
+ uint32_t offset_x;
+ uint32_t offset_y;
+ uint32_t width;
+ uint32_t height;
+ uint32_t screen;
+ uint32_t following;
+} xcb_input_device_abs_area_state_t;
+
+/**
+ * @brief xcb_input_device_abs_area_state_iterator_t
+ **/
+typedef struct xcb_input_device_abs_area_state_iterator_t {
+ xcb_input_device_abs_area_state_t *data;
+ int rem;
+ int index;
+} xcb_input_device_abs_area_state_iterator_t;
+
+/**
+ * @brief xcb_input_device_core_state_t
+ **/
+typedef struct xcb_input_device_core_state_t {
+ uint16_t control_id;
+ uint16_t len;
+ uint8_t status;
+ uint8_t iscore;
+ uint8_t pad0[2];
+} xcb_input_device_core_state_t;
+
+/**
+ * @brief xcb_input_device_core_state_iterator_t
+ **/
+typedef struct xcb_input_device_core_state_iterator_t {
+ xcb_input_device_core_state_t *data;
+ int rem;
+ int index;
+} xcb_input_device_core_state_iterator_t;
+
+/**
+ * @brief xcb_input_device_enable_state_t
+ **/
+typedef struct xcb_input_device_enable_state_t {
+ uint16_t control_id;
+ uint16_t len;
+ uint8_t enable;
+ uint8_t pad0[3];
+} xcb_input_device_enable_state_t;
+
+/**
+ * @brief xcb_input_device_enable_state_iterator_t
+ **/
+typedef struct xcb_input_device_enable_state_iterator_t {
+ xcb_input_device_enable_state_t *data;
+ int rem;
+ int index;
+} xcb_input_device_enable_state_iterator_t;
+
+/**
+ * @brief xcb_input_device_state_data_t
+ **/
+typedef struct xcb_input_device_state_data_t {
+ struct {
+ uint32_t num_valuators;
+ uint32_t *resolution_values;
+ uint32_t *resolution_min;
+ uint32_t *resolution_max;
+ } resolution;
+ struct {
+ int32_t min_x;
+ int32_t max_x;
+ int32_t min_y;
+ int32_t max_y;
+ uint32_t flip_x;
+ uint32_t flip_y;
+ uint32_t rotation;
+ uint32_t button_threshold;
+ } abs_calib;
+ struct {
+ uint8_t status;
+ uint8_t iscore;
+ uint8_t pad0[2];
+ } core;
+ struct {
+ uint8_t enable;
+ uint8_t pad1[3];
+ } enable;
+ struct {
+ uint32_t offset_x;
+ uint32_t offset_y;
+ uint32_t width;
+ uint32_t height;
+ uint32_t screen;
+ uint32_t following;
+ } abs_area;
+} xcb_input_device_state_data_t;
+
+/**
+ * @brief xcb_input_device_state_t
+ **/
+typedef struct xcb_input_device_state_t {
+ uint16_t control_id;
+ uint16_t len;
+} xcb_input_device_state_t;
+
+void *
+xcb_input_device_state_data (const xcb_input_device_state_t *R);
+
+/**
+ * @brief xcb_input_device_state_iterator_t
+ **/
+typedef struct xcb_input_device_state_iterator_t {
+ xcb_input_device_state_t *data;
+ int rem;
+ int index;
+} xcb_input_device_state_iterator_t;
+
+/**
+ * @brief xcb_input_get_device_control_cookie_t
+ **/
+typedef struct xcb_input_get_device_control_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_device_control_cookie_t;
+
+/** Opcode for xcb_input_get_device_control. */
+#define XCB_INPUT_GET_DEVICE_CONTROL 34
+
+/**
+ * @brief xcb_input_get_device_control_request_t
+ **/
+typedef struct xcb_input_get_device_control_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint16_t control_id;
+ uint8_t device_id;
+ uint8_t pad0;
+} xcb_input_get_device_control_request_t;
+
+/**
+ * @brief xcb_input_get_device_control_reply_t
+ **/
+typedef struct xcb_input_get_device_control_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_get_device_control_reply_t;
+
+/**
+ * @brief xcb_input_device_resolution_ctl_t
+ **/
+typedef struct xcb_input_device_resolution_ctl_t {
+ uint16_t control_id;
+ uint16_t len;
+ uint8_t first_valuator;
+ uint8_t num_valuators;
+ uint8_t pad0[2];
+} xcb_input_device_resolution_ctl_t;
+
+/**
+ * @brief xcb_input_device_resolution_ctl_iterator_t
+ **/
+typedef struct xcb_input_device_resolution_ctl_iterator_t {
+ xcb_input_device_resolution_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_device_resolution_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_device_abs_calib_ctl_t
+ **/
+typedef struct xcb_input_device_abs_calib_ctl_t {
+ uint16_t control_id;
+ uint16_t len;
+ int32_t min_x;
+ int32_t max_x;
+ int32_t min_y;
+ int32_t max_y;
+ uint32_t flip_x;
+ uint32_t flip_y;
+ uint32_t rotation;
+ uint32_t button_threshold;
+} xcb_input_device_abs_calib_ctl_t;
+
+/**
+ * @brief xcb_input_device_abs_calib_ctl_iterator_t
+ **/
+typedef struct xcb_input_device_abs_calib_ctl_iterator_t {
+ xcb_input_device_abs_calib_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_device_abs_calib_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_device_abs_area_ctrl_t
+ **/
+typedef struct xcb_input_device_abs_area_ctrl_t {
+ uint16_t control_id;
+ uint16_t len;
+ uint32_t offset_x;
+ uint32_t offset_y;
+ int32_t width;
+ int32_t height;
+ int32_t screen;
+ uint32_t following;
+} xcb_input_device_abs_area_ctrl_t;
+
+/**
+ * @brief xcb_input_device_abs_area_ctrl_iterator_t
+ **/
+typedef struct xcb_input_device_abs_area_ctrl_iterator_t {
+ xcb_input_device_abs_area_ctrl_t *data;
+ int rem;
+ int index;
+} xcb_input_device_abs_area_ctrl_iterator_t;
+
+/**
+ * @brief xcb_input_device_core_ctrl_t
+ **/
+typedef struct xcb_input_device_core_ctrl_t {
+ uint16_t control_id;
+ uint16_t len;
+ uint8_t status;
+ uint8_t pad0[3];
+} xcb_input_device_core_ctrl_t;
+
+/**
+ * @brief xcb_input_device_core_ctrl_iterator_t
+ **/
+typedef struct xcb_input_device_core_ctrl_iterator_t {
+ xcb_input_device_core_ctrl_t *data;
+ int rem;
+ int index;
+} xcb_input_device_core_ctrl_iterator_t;
+
+/**
+ * @brief xcb_input_device_enable_ctrl_t
+ **/
+typedef struct xcb_input_device_enable_ctrl_t {
+ uint16_t control_id;
+ uint16_t len;
+ uint8_t enable;
+ uint8_t pad0[3];
+} xcb_input_device_enable_ctrl_t;
+
+/**
+ * @brief xcb_input_device_enable_ctrl_iterator_t
+ **/
+typedef struct xcb_input_device_enable_ctrl_iterator_t {
+ xcb_input_device_enable_ctrl_t *data;
+ int rem;
+ int index;
+} xcb_input_device_enable_ctrl_iterator_t;
+
+/**
+ * @brief xcb_input_device_ctl_data_t
+ **/
+typedef struct xcb_input_device_ctl_data_t {
+ struct {
+ uint8_t first_valuator;
+ uint8_t num_valuators;
+ uint8_t pad0[2];
+ uint32_t *resolution_values;
+ } resolution;
+ struct {
+ int32_t min_x;
+ int32_t max_x;
+ int32_t min_y;
+ int32_t max_y;
+ uint32_t flip_x;
+ uint32_t flip_y;
+ uint32_t rotation;
+ uint32_t button_threshold;
+ } abs_calib;
+ struct {
+ uint8_t status;
+ uint8_t pad1[3];
+ } core;
+ struct {
+ uint8_t enable;
+ uint8_t pad2[3];
+ } enable;
+ struct {
+ uint32_t offset_x;
+ uint32_t offset_y;
+ int32_t width;
+ int32_t height;
+ int32_t screen;
+ uint32_t following;
+ } abs_area;
+} xcb_input_device_ctl_data_t;
+
+/**
+ * @brief xcb_input_device_ctl_t
+ **/
+typedef struct xcb_input_device_ctl_t {
+ uint16_t control_id;
+ uint16_t len;
+} xcb_input_device_ctl_t;
+
+void *
+xcb_input_device_ctl_data (const xcb_input_device_ctl_t *R);
+
+/**
+ * @brief xcb_input_device_ctl_iterator_t
+ **/
+typedef struct xcb_input_device_ctl_iterator_t {
+ xcb_input_device_ctl_t *data;
+ int rem;
+ int index;
+} xcb_input_device_ctl_iterator_t;
+
+/**
+ * @brief xcb_input_change_device_control_cookie_t
+ **/
+typedef struct xcb_input_change_device_control_cookie_t {
+ unsigned int sequence;
+} xcb_input_change_device_control_cookie_t;
+
+/** Opcode for xcb_input_change_device_control. */
+#define XCB_INPUT_CHANGE_DEVICE_CONTROL 35
+
+/**
+ * @brief xcb_input_change_device_control_request_t
+ **/
+typedef struct xcb_input_change_device_control_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint16_t control_id;
+ uint8_t device_id;
+ uint8_t pad0;
+} xcb_input_change_device_control_request_t;
+
+/**
+ * @brief xcb_input_change_device_control_reply_t
+ **/
+typedef struct xcb_input_change_device_control_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad0[23];
+} xcb_input_change_device_control_reply_t;
+
+/**
+ * @brief xcb_input_list_device_properties_cookie_t
+ **/
+typedef struct xcb_input_list_device_properties_cookie_t {
+ unsigned int sequence;
+} xcb_input_list_device_properties_cookie_t;
+
+/** Opcode for xcb_input_list_device_properties. */
+#define XCB_INPUT_LIST_DEVICE_PROPERTIES 36
+
+/**
+ * @brief xcb_input_list_device_properties_request_t
+ **/
+typedef struct xcb_input_list_device_properties_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_list_device_properties_request_t;
+
+/**
+ * @brief xcb_input_list_device_properties_reply_t
+ **/
+typedef struct xcb_input_list_device_properties_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t num_atoms;
+ uint8_t pad0[22];
+} xcb_input_list_device_properties_reply_t;
+
+typedef enum xcb_input_property_format_t {
+ XCB_INPUT_PROPERTY_FORMAT_8_BITS = 8,
+ XCB_INPUT_PROPERTY_FORMAT_16_BITS = 16,
+ XCB_INPUT_PROPERTY_FORMAT_32_BITS = 32
+} xcb_input_property_format_t;
+
+/**
+ * @brief xcb_input_change_device_property_items_t
+ **/
+typedef struct xcb_input_change_device_property_items_t {
+ uint8_t *data8;
+ uint16_t *data16;
+ uint32_t *data32;
+} xcb_input_change_device_property_items_t;
+
+/** Opcode for xcb_input_change_device_property. */
+#define XCB_INPUT_CHANGE_DEVICE_PROPERTY 37
+
+/**
+ * @brief xcb_input_change_device_property_request_t
+ **/
+typedef struct xcb_input_change_device_property_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_atom_t property;
+ xcb_atom_t type;
+ uint8_t device_id;
+ uint8_t format;
+ uint8_t mode;
+ uint8_t pad0;
+ uint32_t num_items;
+} xcb_input_change_device_property_request_t;
+
+/** Opcode for xcb_input_delete_device_property. */
+#define XCB_INPUT_DELETE_DEVICE_PROPERTY 38
+
+/**
+ * @brief xcb_input_delete_device_property_request_t
+ **/
+typedef struct xcb_input_delete_device_property_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_atom_t property;
+ uint8_t device_id;
+ uint8_t pad0[3];
+} xcb_input_delete_device_property_request_t;
+
+/**
+ * @brief xcb_input_get_device_property_cookie_t
+ **/
+typedef struct xcb_input_get_device_property_cookie_t {
+ unsigned int sequence;
+} xcb_input_get_device_property_cookie_t;
+
+/** Opcode for xcb_input_get_device_property. */
+#define XCB_INPUT_GET_DEVICE_PROPERTY 39
+
+/**
+ * @brief xcb_input_get_device_property_request_t
+ **/
+typedef struct xcb_input_get_device_property_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_atom_t property;
+ xcb_atom_t type;
+ uint32_t offset;
+ uint32_t len;
+ uint8_t device_id;
+ uint8_t _delete;
+ uint8_t pad0[2];
+} xcb_input_get_device_property_request_t;
+
+/**
+ * @brief xcb_input_get_device_property_items_t
+ **/
+typedef struct xcb_input_get_device_property_items_t {
+ uint8_t *data8;
+ uint16_t *data16;
+ uint32_t *data32;
+} xcb_input_get_device_property_items_t;
+
+/**
+ * @brief xcb_input_get_device_property_reply_t
+ **/
+typedef struct xcb_input_get_device_property_reply_t {
+ uint8_t response_type;
+ uint8_t xi_reply_type;
+ uint16_t sequence;
+ uint32_t length;
+ xcb_atom_t type;
+ uint32_t bytes_after;
+ uint32_t num_items;
+ uint8_t format;
+ uint8_t device_id;
+ uint8_t pad0[10];
+} xcb_input_get_device_property_reply_t;
+
+typedef enum xcb_input_device_t {
+ XCB_INPUT_DEVICE_ALL = 0,
+ XCB_INPUT_DEVICE_ALL_MASTER = 1
+} xcb_input_device_t;
+
+/**
+ * @brief xcb_input_group_info_t
+ **/
+typedef struct xcb_input_group_info_t {
+ uint8_t base;
+ uint8_t latched;
+ uint8_t locked;
+ uint8_t effective;
+} xcb_input_group_info_t;
+
+/**
+ * @brief xcb_input_group_info_iterator_t
+ **/
+typedef struct xcb_input_group_info_iterator_t {
+ xcb_input_group_info_t *data;
+ int rem;
+ int index;
+} xcb_input_group_info_iterator_t;
+
+/**
+ * @brief xcb_input_modifier_info_t
+ **/
+typedef struct xcb_input_modifier_info_t {
+ uint32_t base;
+ uint32_t latched;
+ uint32_t locked;
+ uint32_t effective;
+} xcb_input_modifier_info_t;
+
+/**
+ * @brief xcb_input_modifier_info_iterator_t
+ **/
+typedef struct xcb_input_modifier_info_iterator_t {
+ xcb_input_modifier_info_t *data;
+ int rem;
+ int index;
+} xcb_input_modifier_info_iterator_t;
+
+/**
+ * @brief xcb_input_xi_query_pointer_cookie_t
+ **/
+typedef struct xcb_input_xi_query_pointer_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_query_pointer_cookie_t;
+
+/** Opcode for xcb_input_xi_query_pointer. */
+#define XCB_INPUT_XI_QUERY_POINTER 40
+
+/**
+ * @brief xcb_input_xi_query_pointer_request_t
+ **/
+typedef struct xcb_input_xi_query_pointer_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_query_pointer_request_t;
+
+/**
+ * @brief xcb_input_xi_query_pointer_reply_t
+ **/
+typedef struct xcb_input_xi_query_pointer_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ xcb_window_t root;
+ xcb_window_t child;
+ xcb_input_fp1616_t root_x;
+ xcb_input_fp1616_t root_y;
+ xcb_input_fp1616_t win_x;
+ xcb_input_fp1616_t win_y;
+ uint8_t same_screen;
+ uint8_t pad1;
+ uint16_t buttons_len;
+ xcb_input_modifier_info_t mods;
+ xcb_input_group_info_t group;
+} xcb_input_xi_query_pointer_reply_t;
+
+/** Opcode for xcb_input_xi_warp_pointer. */
+#define XCB_INPUT_XI_WARP_POINTER 41
+
+/**
+ * @brief xcb_input_xi_warp_pointer_request_t
+ **/
+typedef struct xcb_input_xi_warp_pointer_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t src_win;
+ xcb_window_t dst_win;
+ xcb_input_fp1616_t src_x;
+ xcb_input_fp1616_t src_y;
+ uint16_t src_width;
+ uint16_t src_height;
+ xcb_input_fp1616_t dst_x;
+ xcb_input_fp1616_t dst_y;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_warp_pointer_request_t;
+
+/** Opcode for xcb_input_xi_change_cursor. */
+#define XCB_INPUT_XI_CHANGE_CURSOR 42
+
+/**
+ * @brief xcb_input_xi_change_cursor_request_t
+ **/
+typedef struct xcb_input_xi_change_cursor_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+ xcb_cursor_t cursor;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_change_cursor_request_t;
+
+typedef enum xcb_input_hierarchy_change_type_t {
+ XCB_INPUT_HIERARCHY_CHANGE_TYPE_ADD_MASTER = 1,
+ XCB_INPUT_HIERARCHY_CHANGE_TYPE_REMOVE_MASTER = 2,
+ XCB_INPUT_HIERARCHY_CHANGE_TYPE_ATTACH_SLAVE = 3,
+ XCB_INPUT_HIERARCHY_CHANGE_TYPE_DETACH_SLAVE = 4
+} xcb_input_hierarchy_change_type_t;
+
+typedef enum xcb_input_change_mode_t {
+ XCB_INPUT_CHANGE_MODE_ATTACH = 1,
+ XCB_INPUT_CHANGE_MODE_FLOAT = 2
+} xcb_input_change_mode_t;
+
+/**
+ * @brief xcb_input_add_master_t
+ **/
+typedef struct xcb_input_add_master_t {
+ uint16_t type;
+ uint16_t len;
+ uint16_t name_len;
+ uint8_t send_core;
+ uint8_t enable;
+} xcb_input_add_master_t;
+
+/**
+ * @brief xcb_input_add_master_iterator_t
+ **/
+typedef struct xcb_input_add_master_iterator_t {
+ xcb_input_add_master_t *data;
+ int rem;
+ int index;
+} xcb_input_add_master_iterator_t;
+
+/**
+ * @brief xcb_input_remove_master_t
+ **/
+typedef struct xcb_input_remove_master_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t deviceid;
+ uint8_t return_mode;
+ uint8_t pad0;
+ xcb_input_device_id_t return_pointer;
+ xcb_input_device_id_t return_keyboard;
+} xcb_input_remove_master_t;
+
+/**
+ * @brief xcb_input_remove_master_iterator_t
+ **/
+typedef struct xcb_input_remove_master_iterator_t {
+ xcb_input_remove_master_t *data;
+ int rem;
+ int index;
+} xcb_input_remove_master_iterator_t;
+
+/**
+ * @brief xcb_input_attach_slave_t
+ **/
+typedef struct xcb_input_attach_slave_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t deviceid;
+ xcb_input_device_id_t master;
+} xcb_input_attach_slave_t;
+
+/**
+ * @brief xcb_input_attach_slave_iterator_t
+ **/
+typedef struct xcb_input_attach_slave_iterator_t {
+ xcb_input_attach_slave_t *data;
+ int rem;
+ int index;
+} xcb_input_attach_slave_iterator_t;
+
+/**
+ * @brief xcb_input_detach_slave_t
+ **/
+typedef struct xcb_input_detach_slave_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_detach_slave_t;
+
+/**
+ * @brief xcb_input_detach_slave_iterator_t
+ **/
+typedef struct xcb_input_detach_slave_iterator_t {
+ xcb_input_detach_slave_t *data;
+ int rem;
+ int index;
+} xcb_input_detach_slave_iterator_t;
+
+/**
+ * @brief xcb_input_hierarchy_change_data_t
+ **/
+typedef struct xcb_input_hierarchy_change_data_t {
+ struct {
+ uint16_t name_len;
+ uint8_t send_core;
+ uint8_t enable;
+ char *name;
+ } add_master;
+ struct {
+ xcb_input_device_id_t deviceid;
+ uint8_t return_mode;
+ uint8_t pad1;
+ xcb_input_device_id_t return_pointer;
+ xcb_input_device_id_t return_keyboard;
+ } remove_master;
+ struct {
+ xcb_input_device_id_t deviceid;
+ xcb_input_device_id_t master;
+ } attach_slave;
+ struct {
+ xcb_input_device_id_t deviceid;
+ uint8_t pad2[2];
+ } detach_slave;
+} xcb_input_hierarchy_change_data_t;
+
+/**
+ * @brief xcb_input_hierarchy_change_t
+ **/
+typedef struct xcb_input_hierarchy_change_t {
+ uint16_t type;
+ uint16_t len;
+} xcb_input_hierarchy_change_t;
+
+void *
+xcb_input_hierarchy_change_data (const xcb_input_hierarchy_change_t *R);
+
+/**
+ * @brief xcb_input_hierarchy_change_iterator_t
+ **/
+typedef struct xcb_input_hierarchy_change_iterator_t {
+ xcb_input_hierarchy_change_t *data;
+ int rem;
+ int index;
+} xcb_input_hierarchy_change_iterator_t;
+
+/** Opcode for xcb_input_xi_change_hierarchy. */
+#define XCB_INPUT_XI_CHANGE_HIERARCHY 43
+
+/**
+ * @brief xcb_input_xi_change_hierarchy_request_t
+ **/
+typedef struct xcb_input_xi_change_hierarchy_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint8_t num_changes;
+ uint8_t pad0[3];
+} xcb_input_xi_change_hierarchy_request_t;
+
+/** Opcode for xcb_input_xi_set_client_pointer. */
+#define XCB_INPUT_XI_SET_CLIENT_POINTER 44
+
+/**
+ * @brief xcb_input_xi_set_client_pointer_request_t
+ **/
+typedef struct xcb_input_xi_set_client_pointer_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_set_client_pointer_request_t;
+
+/**
+ * @brief xcb_input_xi_get_client_pointer_cookie_t
+ **/
+typedef struct xcb_input_xi_get_client_pointer_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_get_client_pointer_cookie_t;
+
+/** Opcode for xcb_input_xi_get_client_pointer. */
+#define XCB_INPUT_XI_GET_CLIENT_POINTER 45
+
+/**
+ * @brief xcb_input_xi_get_client_pointer_request_t
+ **/
+typedef struct xcb_input_xi_get_client_pointer_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+} xcb_input_xi_get_client_pointer_request_t;
+
+/**
+ * @brief xcb_input_xi_get_client_pointer_reply_t
+ **/
+typedef struct xcb_input_xi_get_client_pointer_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t set;
+ uint8_t pad1;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad2[20];
+} xcb_input_xi_get_client_pointer_reply_t;
+
+typedef enum xcb_input_xi_event_mask_t {
+ XCB_INPUT_XI_EVENT_MASK_DEVICE_CHANGED = 2,
+ XCB_INPUT_XI_EVENT_MASK_KEY_PRESS = 4,
+ XCB_INPUT_XI_EVENT_MASK_KEY_RELEASE = 8,
+ XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS = 16,
+ XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE = 32,
+ XCB_INPUT_XI_EVENT_MASK_MOTION = 64,
+ XCB_INPUT_XI_EVENT_MASK_ENTER = 128,
+ XCB_INPUT_XI_EVENT_MASK_LEAVE = 256,
+ XCB_INPUT_XI_EVENT_MASK_FOCUS_IN = 512,
+ XCB_INPUT_XI_EVENT_MASK_FOCUS_OUT = 1024,
+ XCB_INPUT_XI_EVENT_MASK_HIERARCHY = 2048,
+ XCB_INPUT_XI_EVENT_MASK_PROPERTY = 4096,
+ XCB_INPUT_XI_EVENT_MASK_RAW_KEY_PRESS = 8192,
+ XCB_INPUT_XI_EVENT_MASK_RAW_KEY_RELEASE = 16384,
+ XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_PRESS = 32768,
+ XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_RELEASE = 65536,
+ XCB_INPUT_XI_EVENT_MASK_RAW_MOTION = 131072,
+ XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN = 262144,
+ XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE = 524288,
+ XCB_INPUT_XI_EVENT_MASK_TOUCH_END = 1048576,
+ XCB_INPUT_XI_EVENT_MASK_TOUCH_OWNERSHIP = 2097152,
+ XCB_INPUT_XI_EVENT_MASK_RAW_TOUCH_BEGIN = 4194304,
+ XCB_INPUT_XI_EVENT_MASK_RAW_TOUCH_UPDATE = 8388608,
+ XCB_INPUT_XI_EVENT_MASK_RAW_TOUCH_END = 16777216,
+ XCB_INPUT_XI_EVENT_MASK_BARRIER_HIT = 33554432,
+ XCB_INPUT_XI_EVENT_MASK_BARRIER_LEAVE = 67108864
+} xcb_input_xi_event_mask_t;
+
+/**
+ * @brief xcb_input_event_mask_t
+ **/
+typedef struct xcb_input_event_mask_t {
+ xcb_input_device_id_t deviceid;
+ uint16_t mask_len;
+} xcb_input_event_mask_t;
+
+/**
+ * @brief xcb_input_event_mask_iterator_t
+ **/
+typedef struct xcb_input_event_mask_iterator_t {
+ xcb_input_event_mask_t *data;
+ int rem;
+ int index;
+} xcb_input_event_mask_iterator_t;
+
+/** Opcode for xcb_input_xi_select_events. */
+#define XCB_INPUT_XI_SELECT_EVENTS 46
+
+/**
+ * @brief xcb_input_xi_select_events_request_t
+ **/
+typedef struct xcb_input_xi_select_events_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+ uint16_t num_mask;
+ uint8_t pad0[2];
+} xcb_input_xi_select_events_request_t;
+
+/**
+ * @brief xcb_input_xi_query_version_cookie_t
+ **/
+typedef struct xcb_input_xi_query_version_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_query_version_cookie_t;
+
+/** Opcode for xcb_input_xi_query_version. */
+#define XCB_INPUT_XI_QUERY_VERSION 47
+
+/**
+ * @brief xcb_input_xi_query_version_request_t
+ **/
+typedef struct xcb_input_xi_query_version_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ uint16_t major_version;
+ uint16_t minor_version;
+} xcb_input_xi_query_version_request_t;
+
+/**
+ * @brief xcb_input_xi_query_version_reply_t
+ **/
+typedef struct xcb_input_xi_query_version_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t major_version;
+ uint16_t minor_version;
+ uint8_t pad1[20];
+} xcb_input_xi_query_version_reply_t;
+
+typedef enum xcb_input_device_class_type_t {
+ XCB_INPUT_DEVICE_CLASS_TYPE_KEY = 0,
+ XCB_INPUT_DEVICE_CLASS_TYPE_BUTTON = 1,
+ XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR = 2,
+ XCB_INPUT_DEVICE_CLASS_TYPE_SCROLL = 3,
+ XCB_INPUT_DEVICE_CLASS_TYPE_TOUCH = 8
+} xcb_input_device_class_type_t;
+
+typedef enum xcb_input_device_type_t {
+ XCB_INPUT_DEVICE_TYPE_MASTER_POINTER = 1,
+ XCB_INPUT_DEVICE_TYPE_MASTER_KEYBOARD = 2,
+ XCB_INPUT_DEVICE_TYPE_SLAVE_POINTER = 3,
+ XCB_INPUT_DEVICE_TYPE_SLAVE_KEYBOARD = 4,
+ XCB_INPUT_DEVICE_TYPE_FLOATING_SLAVE = 5
+} xcb_input_device_type_t;
+
+typedef enum xcb_input_scroll_flags_t {
+ XCB_INPUT_SCROLL_FLAGS_NO_EMULATION = 1,
+ XCB_INPUT_SCROLL_FLAGS_PREFERRED = 2
+} xcb_input_scroll_flags_t;
+
+typedef enum xcb_input_scroll_type_t {
+ XCB_INPUT_SCROLL_TYPE_VERTICAL = 1,
+ XCB_INPUT_SCROLL_TYPE_HORIZONTAL = 2
+} xcb_input_scroll_type_t;
+
+typedef enum xcb_input_touch_mode_t {
+ XCB_INPUT_TOUCH_MODE_DIRECT = 1,
+ XCB_INPUT_TOUCH_MODE_DEPENDENT = 2
+} xcb_input_touch_mode_t;
+
+/**
+ * @brief xcb_input_button_class_t
+ **/
+typedef struct xcb_input_button_class_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t sourceid;
+ uint16_t num_buttons;
+} xcb_input_button_class_t;
+
+/**
+ * @brief xcb_input_button_class_iterator_t
+ **/
+typedef struct xcb_input_button_class_iterator_t {
+ xcb_input_button_class_t *data;
+ int rem;
+ int index;
+} xcb_input_button_class_iterator_t;
+
+/**
+ * @brief xcb_input_key_class_t
+ **/
+typedef struct xcb_input_key_class_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t sourceid;
+ uint16_t num_keys;
+} xcb_input_key_class_t;
+
+/**
+ * @brief xcb_input_key_class_iterator_t
+ **/
+typedef struct xcb_input_key_class_iterator_t {
+ xcb_input_key_class_t *data;
+ int rem;
+ int index;
+} xcb_input_key_class_iterator_t;
+
+/**
+ * @brief xcb_input_scroll_class_t
+ **/
+typedef struct xcb_input_scroll_class_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t sourceid;
+ uint16_t number;
+ uint16_t scroll_type;
+ uint8_t pad0[2];
+ uint32_t flags;
+ xcb_input_fp3232_t increment;
+} xcb_input_scroll_class_t;
+
+/**
+ * @brief xcb_input_scroll_class_iterator_t
+ **/
+typedef struct xcb_input_scroll_class_iterator_t {
+ xcb_input_scroll_class_t *data;
+ int rem;
+ int index;
+} xcb_input_scroll_class_iterator_t;
+
+/**
+ * @brief xcb_input_touch_class_t
+ **/
+typedef struct xcb_input_touch_class_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t sourceid;
+ uint8_t mode;
+ uint8_t num_touches;
+} xcb_input_touch_class_t;
+
+/**
+ * @brief xcb_input_touch_class_iterator_t
+ **/
+typedef struct xcb_input_touch_class_iterator_t {
+ xcb_input_touch_class_t *data;
+ int rem;
+ int index;
+} xcb_input_touch_class_iterator_t;
+
+/**
+ * @brief xcb_input_valuator_class_t
+ **/
+typedef struct xcb_input_valuator_class_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t sourceid;
+ uint16_t number;
+ xcb_atom_t label;
+ xcb_input_fp3232_t min;
+ xcb_input_fp3232_t max;
+ xcb_input_fp3232_t value;
+ uint32_t resolution;
+ uint8_t mode;
+ uint8_t pad0[3];
+} xcb_input_valuator_class_t;
+
+/**
+ * @brief xcb_input_valuator_class_iterator_t
+ **/
+typedef struct xcb_input_valuator_class_iterator_t {
+ xcb_input_valuator_class_t *data;
+ int rem;
+ int index;
+} xcb_input_valuator_class_iterator_t;
+
+/**
+ * @brief xcb_input_device_class_data_t
+ **/
+typedef struct xcb_input_device_class_data_t {
+ struct {
+ uint16_t num_keys;
+ uint32_t *keys;
+ } key;
+ struct {
+ uint16_t num_buttons;
+ uint32_t *state;
+ xcb_atom_t *labels;
+ } button;
+ struct {
+ uint16_t number;
+ xcb_atom_t label;
+ xcb_input_fp3232_t min;
+ xcb_input_fp3232_t max;
+ xcb_input_fp3232_t value;
+ uint32_t resolution;
+ uint8_t mode;
+ uint8_t pad0[3];
+ } valuator;
+ struct {
+ uint16_t number;
+ uint16_t scroll_type;
+ uint8_t pad1[2];
+ uint32_t flags;
+ xcb_input_fp3232_t increment;
+ } scroll;
+ struct {
+ uint8_t mode;
+ uint8_t num_touches;
+ } touch;
+} xcb_input_device_class_data_t;
+
+/**
+ * @brief xcb_input_device_class_t
+ **/
+typedef struct xcb_input_device_class_t {
+ uint16_t type;
+ uint16_t len;
+ xcb_input_device_id_t sourceid;
+} xcb_input_device_class_t;
+
+void *
+xcb_input_device_class_data (const xcb_input_device_class_t *R);
+
+/**
+ * @brief xcb_input_device_class_iterator_t
+ **/
+typedef struct xcb_input_device_class_iterator_t {
+ xcb_input_device_class_t *data;
+ int rem;
+ int index;
+} xcb_input_device_class_iterator_t;
+
+/**
+ * @brief xcb_input_xi_device_info_t
+ **/
+typedef struct xcb_input_xi_device_info_t {
+ xcb_input_device_id_t deviceid;
+ uint16_t type;
+ xcb_input_device_id_t attachment;
+ uint16_t num_classes;
+ uint16_t name_len;
+ uint8_t enabled;
+ uint8_t pad0;
+} xcb_input_xi_device_info_t;
+
+/**
+ * @brief xcb_input_xi_device_info_iterator_t
+ **/
+typedef struct xcb_input_xi_device_info_iterator_t {
+ xcb_input_xi_device_info_t *data;
+ int rem;
+ int index;
+} xcb_input_xi_device_info_iterator_t;
+
+/**
+ * @brief xcb_input_xi_query_device_cookie_t
+ **/
+typedef struct xcb_input_xi_query_device_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_query_device_cookie_t;
+
+/** Opcode for xcb_input_xi_query_device. */
+#define XCB_INPUT_XI_QUERY_DEVICE 48
+
+/**
+ * @brief xcb_input_xi_query_device_request_t
+ **/
+typedef struct xcb_input_xi_query_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_query_device_request_t;
+
+/**
+ * @brief xcb_input_xi_query_device_reply_t
+ **/
+typedef struct xcb_input_xi_query_device_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t num_infos;
+ uint8_t pad1[22];
+} xcb_input_xi_query_device_reply_t;
+
+/** Opcode for xcb_input_xi_set_focus. */
+#define XCB_INPUT_XI_SET_FOCUS 49
+
+/**
+ * @brief xcb_input_xi_set_focus_request_t
+ **/
+typedef struct xcb_input_xi_set_focus_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+ xcb_timestamp_t time;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_set_focus_request_t;
+
+/**
+ * @brief xcb_input_xi_get_focus_cookie_t
+ **/
+typedef struct xcb_input_xi_get_focus_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_get_focus_cookie_t;
+
+/** Opcode for xcb_input_xi_get_focus. */
+#define XCB_INPUT_XI_GET_FOCUS 50
+
+/**
+ * @brief xcb_input_xi_get_focus_request_t
+ **/
+typedef struct xcb_input_xi_get_focus_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_get_focus_request_t;
+
+/**
+ * @brief xcb_input_xi_get_focus_reply_t
+ **/
+typedef struct xcb_input_xi_get_focus_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ xcb_window_t focus;
+ uint8_t pad1[20];
+} xcb_input_xi_get_focus_reply_t;
+
+typedef enum xcb_input_grab_owner_t {
+ XCB_INPUT_GRAB_OWNER_NO_OWNER = 0,
+ XCB_INPUT_GRAB_OWNER_OWNER = 1
+} xcb_input_grab_owner_t;
+
+/**
+ * @brief xcb_input_xi_grab_device_cookie_t
+ **/
+typedef struct xcb_input_xi_grab_device_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_grab_device_cookie_t;
+
+/** Opcode for xcb_input_xi_grab_device. */
+#define XCB_INPUT_XI_GRAB_DEVICE 51
+
+/**
+ * @brief xcb_input_xi_grab_device_request_t
+ **/
+typedef struct xcb_input_xi_grab_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+ xcb_timestamp_t time;
+ xcb_cursor_t cursor;
+ xcb_input_device_id_t deviceid;
+ uint8_t mode;
+ uint8_t paired_device_mode;
+ uint8_t owner_events;
+ uint8_t pad0;
+ uint16_t mask_len;
+} xcb_input_xi_grab_device_request_t;
+
+/**
+ * @brief xcb_input_xi_grab_device_reply_t
+ **/
+typedef struct xcb_input_xi_grab_device_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ uint8_t status;
+ uint8_t pad1[23];
+} xcb_input_xi_grab_device_reply_t;
+
+/** Opcode for xcb_input_xi_ungrab_device. */
+#define XCB_INPUT_XI_UNGRAB_DEVICE 52
+
+/**
+ * @brief xcb_input_xi_ungrab_device_request_t
+ **/
+typedef struct xcb_input_xi_ungrab_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_timestamp_t time;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_ungrab_device_request_t;
+
+typedef enum xcb_input_event_mode_t {
+ XCB_INPUT_EVENT_MODE_ASYNC_DEVICE = 0,
+ XCB_INPUT_EVENT_MODE_SYNC_DEVICE = 1,
+ XCB_INPUT_EVENT_MODE_REPLAY_DEVICE = 2,
+ XCB_INPUT_EVENT_MODE_ASYNC_PAIRED_DEVICE = 3,
+ XCB_INPUT_EVENT_MODE_ASYNC_PAIR = 4,
+ XCB_INPUT_EVENT_MODE_SYNC_PAIR = 5,
+ XCB_INPUT_EVENT_MODE_ACCEPT_TOUCH = 6,
+ XCB_INPUT_EVENT_MODE_REJECT_TOUCH = 7
+} xcb_input_event_mode_t;
+
+/** Opcode for xcb_input_xi_allow_events. */
+#define XCB_INPUT_XI_ALLOW_EVENTS 53
+
+/**
+ * @brief xcb_input_xi_allow_events_request_t
+ **/
+typedef struct xcb_input_xi_allow_events_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_timestamp_t time;
+ xcb_input_device_id_t deviceid;
+ uint8_t event_mode;
+ uint8_t pad0;
+ uint32_t touchid;
+ xcb_window_t grab_window;
+} xcb_input_xi_allow_events_request_t;
+
+typedef enum xcb_input_grab_mode_22_t {
+ XCB_INPUT_GRAB_MODE_22_SYNC = 0,
+ XCB_INPUT_GRAB_MODE_22_ASYNC = 1,
+ XCB_INPUT_GRAB_MODE_22_TOUCH = 2
+} xcb_input_grab_mode_22_t;
+
+typedef enum xcb_input_grab_type_t {
+ XCB_INPUT_GRAB_TYPE_BUTTON = 0,
+ XCB_INPUT_GRAB_TYPE_KEYCODE = 1,
+ XCB_INPUT_GRAB_TYPE_ENTER = 2,
+ XCB_INPUT_GRAB_TYPE_FOCUS_IN = 3,
+ XCB_INPUT_GRAB_TYPE_TOUCH_BEGIN = 4
+} xcb_input_grab_type_t;
+
+typedef enum xcb_input_modifier_mask_t {
+ XCB_INPUT_MODIFIER_MASK_ANY = 2147483648
+} xcb_input_modifier_mask_t;
+
+/**
+ * @brief xcb_input_grab_modifier_info_t
+ **/
+typedef struct xcb_input_grab_modifier_info_t {
+ uint32_t modifiers;
+ uint8_t status;
+ uint8_t pad0[3];
+} xcb_input_grab_modifier_info_t;
+
+/**
+ * @brief xcb_input_grab_modifier_info_iterator_t
+ **/
+typedef struct xcb_input_grab_modifier_info_iterator_t {
+ xcb_input_grab_modifier_info_t *data;
+ int rem;
+ int index;
+} xcb_input_grab_modifier_info_iterator_t;
+
+/**
+ * @brief xcb_input_xi_passive_grab_device_cookie_t
+ **/
+typedef struct xcb_input_xi_passive_grab_device_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_passive_grab_device_cookie_t;
+
+/** Opcode for xcb_input_xi_passive_grab_device. */
+#define XCB_INPUT_XI_PASSIVE_GRAB_DEVICE 54
+
+/**
+ * @brief xcb_input_xi_passive_grab_device_request_t
+ **/
+typedef struct xcb_input_xi_passive_grab_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_timestamp_t time;
+ xcb_window_t grab_window;
+ xcb_cursor_t cursor;
+ uint32_t detail;
+ xcb_input_device_id_t deviceid;
+ uint16_t num_modifiers;
+ uint16_t mask_len;
+ uint8_t grab_type;
+ uint8_t grab_mode;
+ uint8_t paired_device_mode;
+ uint8_t owner_events;
+ uint8_t pad0[2];
+} xcb_input_xi_passive_grab_device_request_t;
+
+/**
+ * @brief xcb_input_xi_passive_grab_device_reply_t
+ **/
+typedef struct xcb_input_xi_passive_grab_device_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t num_modifiers;
+ uint8_t pad1[22];
+} xcb_input_xi_passive_grab_device_reply_t;
+
+/** Opcode for xcb_input_xi_passive_ungrab_device. */
+#define XCB_INPUT_XI_PASSIVE_UNGRAB_DEVICE 55
+
+/**
+ * @brief xcb_input_xi_passive_ungrab_device_request_t
+ **/
+typedef struct xcb_input_xi_passive_ungrab_device_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t grab_window;
+ uint32_t detail;
+ xcb_input_device_id_t deviceid;
+ uint16_t num_modifiers;
+ uint8_t grab_type;
+ uint8_t pad0[3];
+} xcb_input_xi_passive_ungrab_device_request_t;
+
+/**
+ * @brief xcb_input_xi_list_properties_cookie_t
+ **/
+typedef struct xcb_input_xi_list_properties_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_list_properties_cookie_t;
+
+/** Opcode for xcb_input_xi_list_properties. */
+#define XCB_INPUT_XI_LIST_PROPERTIES 56
+
+/**
+ * @brief xcb_input_xi_list_properties_request_t
+ **/
+typedef struct xcb_input_xi_list_properties_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+} xcb_input_xi_list_properties_request_t;
+
+/**
+ * @brief xcb_input_xi_list_properties_reply_t
+ **/
+typedef struct xcb_input_xi_list_properties_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t num_properties;
+ uint8_t pad1[22];
+} xcb_input_xi_list_properties_reply_t;
+
+/**
+ * @brief xcb_input_xi_change_property_items_t
+ **/
+typedef struct xcb_input_xi_change_property_items_t {
+ uint8_t *data8;
+ uint16_t *data16;
+ uint32_t *data32;
+} xcb_input_xi_change_property_items_t;
+
+/** Opcode for xcb_input_xi_change_property. */
+#define XCB_INPUT_XI_CHANGE_PROPERTY 57
+
+/**
+ * @brief xcb_input_xi_change_property_request_t
+ **/
+typedef struct xcb_input_xi_change_property_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_input_device_id_t deviceid;
+ uint8_t mode;
+ uint8_t format;
+ xcb_atom_t property;
+ xcb_atom_t type;
+ uint32_t num_items;
+} xcb_input_xi_change_property_request_t;
+
+/** Opcode for xcb_input_xi_delete_property. */
+#define XCB_INPUT_XI_DELETE_PROPERTY 58
+
+/**
+ * @brief xcb_input_xi_delete_property_request_t
+ **/
+typedef struct xcb_input_xi_delete_property_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_input_device_id_t deviceid;
+ uint8_t pad0[2];
+ xcb_atom_t property;
+} xcb_input_xi_delete_property_request_t;
+
+/**
+ * @brief xcb_input_xi_get_property_cookie_t
+ **/
+typedef struct xcb_input_xi_get_property_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_get_property_cookie_t;
+
+/** Opcode for xcb_input_xi_get_property. */
+#define XCB_INPUT_XI_GET_PROPERTY 59
+
+/**
+ * @brief xcb_input_xi_get_property_request_t
+ **/
+typedef struct xcb_input_xi_get_property_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_input_device_id_t deviceid;
+ uint8_t _delete;
+ uint8_t pad0;
+ xcb_atom_t property;
+ xcb_atom_t type;
+ uint32_t offset;
+ uint32_t len;
+} xcb_input_xi_get_property_request_t;
+
+/**
+ * @brief xcb_input_xi_get_property_items_t
+ **/
+typedef struct xcb_input_xi_get_property_items_t {
+ uint8_t *data8;
+ uint16_t *data16;
+ uint32_t *data32;
+} xcb_input_xi_get_property_items_t;
+
+/**
+ * @brief xcb_input_xi_get_property_reply_t
+ **/
+typedef struct xcb_input_xi_get_property_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ xcb_atom_t type;
+ uint32_t bytes_after;
+ uint32_t num_items;
+ uint8_t format;
+ uint8_t pad1[11];
+} xcb_input_xi_get_property_reply_t;
+
+/**
+ * @brief xcb_input_xi_get_selected_events_cookie_t
+ **/
+typedef struct xcb_input_xi_get_selected_events_cookie_t {
+ unsigned int sequence;
+} xcb_input_xi_get_selected_events_cookie_t;
+
+/** Opcode for xcb_input_xi_get_selected_events. */
+#define XCB_INPUT_XI_GET_SELECTED_EVENTS 60
+
+/**
+ * @brief xcb_input_xi_get_selected_events_request_t
+ **/
+typedef struct xcb_input_xi_get_selected_events_request_t {
+ uint8_t major_opcode;
+ uint8_t minor_opcode;
+ uint16_t length;
+ xcb_window_t window;
+} xcb_input_xi_get_selected_events_request_t;
+
+/**
+ * @brief xcb_input_xi_get_selected_events_reply_t
+ **/
+typedef struct xcb_input_xi_get_selected_events_reply_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t num_masks;
+ uint8_t pad1[22];
+} xcb_input_xi_get_selected_events_reply_t;
+
+/** Opcode for xcb_input_device_valuator. */
+#define XCB_INPUT_DEVICE_VALUATOR 0
+
+/**
+ * @brief xcb_input_device_valuator_event_t
+ **/
+typedef struct xcb_input_device_valuator_event_t {
+ uint8_t response_type;
+ uint8_t device_id;
+ uint16_t sequence;
+ uint16_t device_state;
+ uint8_t num_valuators;
+ uint8_t first_valuator;
+ int32_t valuators[6];
+} xcb_input_device_valuator_event_t;
+
+typedef enum xcb_input_more_events_mask_t {
+ XCB_INPUT_MORE_EVENTS_MASK_MORE_EVENTS = 128
+} xcb_input_more_events_mask_t;
+
+/** Opcode for xcb_input_device_key_press. */
+#define XCB_INPUT_DEVICE_KEY_PRESS 1
+
+/**
+ * @brief xcb_input_device_key_press_event_t
+ **/
+typedef struct xcb_input_device_key_press_event_t {
+ uint8_t response_type;
+ uint8_t detail;
+ uint16_t sequence;
+ xcb_timestamp_t time;
+ xcb_window_t root;
+ xcb_window_t event;
+ xcb_window_t child;
+ int16_t root_x;
+ int16_t root_y;
+ int16_t event_x;
+ int16_t event_y;
+ uint16_t state;
+ uint8_t same_screen;
+ uint8_t device_id;
+} xcb_input_device_key_press_event_t;
+
+/** Opcode for xcb_input_device_key_release. */
+#define XCB_INPUT_DEVICE_KEY_RELEASE 2
+
+typedef xcb_input_device_key_press_event_t xcb_input_device_key_release_event_t;
+
+/** Opcode for xcb_input_device_button_press. */
+#define XCB_INPUT_DEVICE_BUTTON_PRESS 3
+
+typedef xcb_input_device_key_press_event_t xcb_input_device_button_press_event_t;
+
+/** Opcode for xcb_input_device_button_release. */
+#define XCB_INPUT_DEVICE_BUTTON_RELEASE 4
+
+typedef xcb_input_device_key_press_event_t xcb_input_device_button_release_event_t;
+
+/** Opcode for xcb_input_device_motion_notify. */
+#define XCB_INPUT_DEVICE_MOTION_NOTIFY 5
+
+typedef xcb_input_device_key_press_event_t xcb_input_device_motion_notify_event_t;
+
+/** Opcode for xcb_input_device_focus_in. */
+#define XCB_INPUT_DEVICE_FOCUS_IN 6
+
+/**
+ * @brief xcb_input_device_focus_in_event_t
+ **/
+typedef struct xcb_input_device_focus_in_event_t {
+ uint8_t response_type;
+ uint8_t detail;
+ uint16_t sequence;
+ xcb_timestamp_t time;
+ xcb_window_t window;
+ uint8_t mode;
+ uint8_t device_id;
+ uint8_t pad0[18];
+} xcb_input_device_focus_in_event_t;
+
+/** Opcode for xcb_input_device_focus_out. */
+#define XCB_INPUT_DEVICE_FOCUS_OUT 7
+
+typedef xcb_input_device_focus_in_event_t xcb_input_device_focus_out_event_t;
+
+/** Opcode for xcb_input_proximity_in. */
+#define XCB_INPUT_PROXIMITY_IN 8
+
+typedef xcb_input_device_key_press_event_t xcb_input_proximity_in_event_t;
+
+/** Opcode for xcb_input_proximity_out. */
+#define XCB_INPUT_PROXIMITY_OUT 9
+
+typedef xcb_input_device_key_press_event_t xcb_input_proximity_out_event_t;
+
+typedef enum xcb_input_classes_reported_mask_t {
+ XCB_INPUT_CLASSES_REPORTED_MASK_OUT_OF_PROXIMITY = 128,
+ XCB_INPUT_CLASSES_REPORTED_MASK_DEVICE_MODE_ABSOLUTE = 64,
+ XCB_INPUT_CLASSES_REPORTED_MASK_REPORTING_VALUATORS = 4,
+ XCB_INPUT_CLASSES_REPORTED_MASK_REPORTING_BUTTONS = 2,
+ XCB_INPUT_CLASSES_REPORTED_MASK_REPORTING_KEYS = 1
+} xcb_input_classes_reported_mask_t;
+
+/** Opcode for xcb_input_device_state_notify. */
+#define XCB_INPUT_DEVICE_STATE_NOTIFY 10
+
+/**
+ * @brief xcb_input_device_state_notify_event_t
+ **/
+typedef struct xcb_input_device_state_notify_event_t {
+ uint8_t response_type;
+ uint8_t device_id;
+ uint16_t sequence;
+ xcb_timestamp_t time;
+ uint8_t num_keys;
+ uint8_t num_buttons;
+ uint8_t num_valuators;
+ uint8_t classes_reported;
+ uint8_t buttons[4];
+ uint8_t keys[4];
+ uint32_t valuators[3];
+} xcb_input_device_state_notify_event_t;
+
+/** Opcode for xcb_input_device_mapping_notify. */
+#define XCB_INPUT_DEVICE_MAPPING_NOTIFY 11
+
+/**
+ * @brief xcb_input_device_mapping_notify_event_t
+ **/
+typedef struct xcb_input_device_mapping_notify_event_t {
+ uint8_t response_type;
+ uint8_t device_id;
+ uint16_t sequence;
+ uint8_t request;
+ xcb_input_key_code_t first_keycode;
+ uint8_t count;
+ uint8_t pad0;
+ xcb_timestamp_t time;
+ uint8_t pad1[20];
+} xcb_input_device_mapping_notify_event_t;
+
+typedef enum xcb_input_change_device_t {
+ XCB_INPUT_CHANGE_DEVICE_NEW_POINTER = 0,
+ XCB_INPUT_CHANGE_DEVICE_NEW_KEYBOARD = 1
+} xcb_input_change_device_t;
+
+/** Opcode for xcb_input_change_device_notify. */
+#define XCB_INPUT_CHANGE_DEVICE_NOTIFY 12
+
+/**
+ * @brief xcb_input_change_device_notify_event_t
+ **/
+typedef struct xcb_input_change_device_notify_event_t {
+ uint8_t response_type;
+ uint8_t device_id;
+ uint16_t sequence;
+ xcb_timestamp_t time;
+ uint8_t request;
+ uint8_t pad0[23];
+} xcb_input_change_device_notify_event_t;
+
+/** Opcode for xcb_input_device_key_state_notify. */
+#define XCB_INPUT_DEVICE_KEY_STATE_NOTIFY 13
+
+/**
+ * @brief xcb_input_device_key_state_notify_event_t
+ **/
+typedef struct xcb_input_device_key_state_notify_event_t {
+ uint8_t response_type;
+ uint8_t device_id;
+ uint16_t sequence;
+ uint8_t keys[28];
+} xcb_input_device_key_state_notify_event_t;
+
+/** Opcode for xcb_input_device_button_state_notify. */
+#define XCB_INPUT_DEVICE_BUTTON_STATE_NOTIFY 14
+
+/**
+ * @brief xcb_input_device_button_state_notify_event_t
+ **/
+typedef struct xcb_input_device_button_state_notify_event_t {
+ uint8_t response_type;
+ uint8_t device_id;
+ uint16_t sequence;
+ uint8_t buttons[28];
+} xcb_input_device_button_state_notify_event_t;
+
+typedef enum xcb_input_device_change_t {
+ XCB_INPUT_DEVICE_CHANGE_ADDED = 0,
+ XCB_INPUT_DEVICE_CHANGE_REMOVED = 1,
+ XCB_INPUT_DEVICE_CHANGE_ENABLED = 2,
+ XCB_INPUT_DEVICE_CHANGE_DISABLED = 3,
+ XCB_INPUT_DEVICE_CHANGE_UNRECOVERABLE = 4,
+ XCB_INPUT_DEVICE_CHANGE_CONTROL_CHANGED = 5
+} xcb_input_device_change_t;
+
+/** Opcode for xcb_input_device_presence_notify. */
+#define XCB_INPUT_DEVICE_PRESENCE_NOTIFY 15
+
+/**
+ * @brief xcb_input_device_presence_notify_event_t
+ **/
+typedef struct xcb_input_device_presence_notify_event_t {
+ uint8_t response_type;
+ uint8_t pad0;
+ uint16_t sequence;
+ xcb_timestamp_t time;
+ uint8_t devchange;
+ uint8_t device_id;
+ uint16_t control;
+ uint8_t pad1[20];
+} xcb_input_device_presence_notify_event_t;
+
+/** Opcode for xcb_input_device_property_notify. */
+#define XCB_INPUT_DEVICE_PROPERTY_NOTIFY 16
+
+/**
+ * @brief xcb_input_device_property_notify_event_t
+ **/
+typedef struct xcb_input_device_property_notify_event_t {
+ uint8_t response_type;
+ uint8_t state;
+ uint16_t sequence;
+ xcb_timestamp_t time;
+ xcb_atom_t property;
+ uint8_t pad0[19];
+ uint8_t device_id;
+} xcb_input_device_property_notify_event_t;
+
+typedef enum xcb_input_change_reason_t {
+ XCB_INPUT_CHANGE_REASON_SLAVE_SWITCH = 1,
+ XCB_INPUT_CHANGE_REASON_DEVICE_CHANGE = 2
+} xcb_input_change_reason_t;
+
+/** Opcode for xcb_input_device_changed. */
+#define XCB_INPUT_DEVICE_CHANGED 1
+
+/**
+ * @brief xcb_input_device_changed_event_t
+ **/
+typedef struct xcb_input_device_changed_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint16_t num_classes;
+ xcb_input_device_id_t sourceid;
+ uint8_t reason;
+ uint8_t pad0[11];
+ uint32_t full_sequence;
+} xcb_input_device_changed_event_t;
+
+typedef enum xcb_input_key_event_flags_t {
+ XCB_INPUT_KEY_EVENT_FLAGS_KEY_REPEAT = 65536
+} xcb_input_key_event_flags_t;
+
+/** Opcode for xcb_input_key_press. */
+#define XCB_INPUT_KEY_PRESS 2
+
+/**
+ * @brief xcb_input_key_press_event_t
+ **/
+typedef struct xcb_input_key_press_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint32_t detail;
+ xcb_window_t root;
+ xcb_window_t event;
+ xcb_window_t child;
+ uint32_t full_sequence;
+ xcb_input_fp1616_t root_x;
+ xcb_input_fp1616_t root_y;
+ xcb_input_fp1616_t event_x;
+ xcb_input_fp1616_t event_y;
+ uint16_t buttons_len;
+ uint16_t valuators_len;
+ xcb_input_device_id_t sourceid;
+ uint8_t pad0[2];
+ uint32_t flags;
+ xcb_input_modifier_info_t mods;
+ xcb_input_group_info_t group;
+} xcb_input_key_press_event_t;
+
+/** Opcode for xcb_input_key_release. */
+#define XCB_INPUT_KEY_RELEASE 3
+
+typedef xcb_input_key_press_event_t xcb_input_key_release_event_t;
+
+typedef enum xcb_input_pointer_event_flags_t {
+ XCB_INPUT_POINTER_EVENT_FLAGS_POINTER_EMULATED = 65536
+} xcb_input_pointer_event_flags_t;
+
+/** Opcode for xcb_input_button_press. */
+#define XCB_INPUT_BUTTON_PRESS 4
+
+/**
+ * @brief xcb_input_button_press_event_t
+ **/
+typedef struct xcb_input_button_press_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint32_t detail;
+ xcb_window_t root;
+ xcb_window_t event;
+ xcb_window_t child;
+ uint32_t full_sequence;
+ xcb_input_fp1616_t root_x;
+ xcb_input_fp1616_t root_y;
+ xcb_input_fp1616_t event_x;
+ xcb_input_fp1616_t event_y;
+ uint16_t buttons_len;
+ uint16_t valuators_len;
+ xcb_input_device_id_t sourceid;
+ uint8_t pad0[2];
+ uint32_t flags;
+ xcb_input_modifier_info_t mods;
+ xcb_input_group_info_t group;
+} xcb_input_button_press_event_t;
+
+/** Opcode for xcb_input_button_release. */
+#define XCB_INPUT_BUTTON_RELEASE 5
+
+typedef xcb_input_button_press_event_t xcb_input_button_release_event_t;
+
+/** Opcode for xcb_input_motion. */
+#define XCB_INPUT_MOTION 6
+
+typedef xcb_input_button_press_event_t xcb_input_motion_event_t;
+
+typedef enum xcb_input_notify_mode_t {
+ XCB_INPUT_NOTIFY_MODE_NORMAL = 0,
+ XCB_INPUT_NOTIFY_MODE_GRAB = 1,
+ XCB_INPUT_NOTIFY_MODE_UNGRAB = 2,
+ XCB_INPUT_NOTIFY_MODE_WHILE_GRABBED = 3,
+ XCB_INPUT_NOTIFY_MODE_PASSIVE_GRAB = 4,
+ XCB_INPUT_NOTIFY_MODE_PASSIVE_UNGRAB = 5
+} xcb_input_notify_mode_t;
+
+typedef enum xcb_input_notify_detail_t {
+ XCB_INPUT_NOTIFY_DETAIL_ANCESTOR = 0,
+ XCB_INPUT_NOTIFY_DETAIL_VIRTUAL = 1,
+ XCB_INPUT_NOTIFY_DETAIL_INFERIOR = 2,
+ XCB_INPUT_NOTIFY_DETAIL_NONLINEAR = 3,
+ XCB_INPUT_NOTIFY_DETAIL_NONLINEAR_VIRTUAL = 4,
+ XCB_INPUT_NOTIFY_DETAIL_POINTER = 5,
+ XCB_INPUT_NOTIFY_DETAIL_POINTER_ROOT = 6,
+ XCB_INPUT_NOTIFY_DETAIL_NONE = 7
+} xcb_input_notify_detail_t;
+
+/** Opcode for xcb_input_enter. */
+#define XCB_INPUT_ENTER 7
+
+/**
+ * @brief xcb_input_enter_event_t
+ **/
+typedef struct xcb_input_enter_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ xcb_input_device_id_t sourceid;
+ uint8_t mode;
+ uint8_t detail;
+ xcb_window_t root;
+ xcb_window_t event;
+ xcb_window_t child;
+ uint32_t full_sequence;
+ xcb_input_fp1616_t root_x;
+ xcb_input_fp1616_t root_y;
+ xcb_input_fp1616_t event_x;
+ xcb_input_fp1616_t event_y;
+ uint8_t same_screen;
+ uint8_t focus;
+ uint16_t buttons_len;
+ xcb_input_modifier_info_t mods;
+ xcb_input_group_info_t group;
+} xcb_input_enter_event_t;
+
+/** Opcode for xcb_input_leave. */
+#define XCB_INPUT_LEAVE 8
+
+typedef xcb_input_enter_event_t xcb_input_leave_event_t;
+
+/** Opcode for xcb_input_focus_in. */
+#define XCB_INPUT_FOCUS_IN 9
+
+typedef xcb_input_enter_event_t xcb_input_focus_in_event_t;
+
+/** Opcode for xcb_input_focus_out. */
+#define XCB_INPUT_FOCUS_OUT 10
+
+typedef xcb_input_enter_event_t xcb_input_focus_out_event_t;
+
+typedef enum xcb_input_hierarchy_mask_t {
+ XCB_INPUT_HIERARCHY_MASK_MASTER_ADDED = 1,
+ XCB_INPUT_HIERARCHY_MASK_MASTER_REMOVED = 2,
+ XCB_INPUT_HIERARCHY_MASK_SLAVE_ADDED = 4,
+ XCB_INPUT_HIERARCHY_MASK_SLAVE_REMOVED = 8,
+ XCB_INPUT_HIERARCHY_MASK_SLAVE_ATTACHED = 16,
+ XCB_INPUT_HIERARCHY_MASK_SLAVE_DETACHED = 32,
+ XCB_INPUT_HIERARCHY_MASK_DEVICE_ENABLED = 64,
+ XCB_INPUT_HIERARCHY_MASK_DEVICE_DISABLED = 128
+} xcb_input_hierarchy_mask_t;
+
+/**
+ * @brief xcb_input_hierarchy_info_t
+ **/
+typedef struct xcb_input_hierarchy_info_t {
+ xcb_input_device_id_t deviceid;
+ xcb_input_device_id_t attachment;
+ uint8_t type;
+ uint8_t enabled;
+ uint8_t pad0[2];
+ uint32_t flags;
+} xcb_input_hierarchy_info_t;
+
+/**
+ * @brief xcb_input_hierarchy_info_iterator_t
+ **/
+typedef struct xcb_input_hierarchy_info_iterator_t {
+ xcb_input_hierarchy_info_t *data;
+ int rem;
+ int index;
+} xcb_input_hierarchy_info_iterator_t;
+
+/** Opcode for xcb_input_hierarchy. */
+#define XCB_INPUT_HIERARCHY 11
+
+/**
+ * @brief xcb_input_hierarchy_event_t
+ **/
+typedef struct xcb_input_hierarchy_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint32_t flags;
+ uint16_t num_infos;
+ uint8_t pad0[10];
+ uint32_t full_sequence;
+} xcb_input_hierarchy_event_t;
+
+typedef enum xcb_input_property_flag_t {
+ XCB_INPUT_PROPERTY_FLAG_DELETED = 0,
+ XCB_INPUT_PROPERTY_FLAG_CREATED = 1,
+ XCB_INPUT_PROPERTY_FLAG_MODIFIED = 2
+} xcb_input_property_flag_t;
+
+/** Opcode for xcb_input_property. */
+#define XCB_INPUT_PROPERTY 12
+
+/**
+ * @brief xcb_input_property_event_t
+ **/
+typedef struct xcb_input_property_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ xcb_atom_t property;
+ uint8_t what;
+ uint8_t pad0[11];
+ uint32_t full_sequence;
+} xcb_input_property_event_t;
+
+/** Opcode for xcb_input_raw_key_press. */
+#define XCB_INPUT_RAW_KEY_PRESS 13
+
+/**
+ * @brief xcb_input_raw_key_press_event_t
+ **/
+typedef struct xcb_input_raw_key_press_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint32_t detail;
+ xcb_input_device_id_t sourceid;
+ uint16_t valuators_len;
+ uint32_t flags;
+ uint8_t pad0[4];
+ uint32_t full_sequence;
+} xcb_input_raw_key_press_event_t;
+
+/** Opcode for xcb_input_raw_key_release. */
+#define XCB_INPUT_RAW_KEY_RELEASE 14
+
+typedef xcb_input_raw_key_press_event_t xcb_input_raw_key_release_event_t;
+
+/** Opcode for xcb_input_raw_button_press. */
+#define XCB_INPUT_RAW_BUTTON_PRESS 15
+
+/**
+ * @brief xcb_input_raw_button_press_event_t
+ **/
+typedef struct xcb_input_raw_button_press_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint32_t detail;
+ xcb_input_device_id_t sourceid;
+ uint16_t valuators_len;
+ uint32_t flags;
+ uint8_t pad0[4];
+ uint32_t full_sequence;
+} xcb_input_raw_button_press_event_t;
+
+/** Opcode for xcb_input_raw_button_release. */
+#define XCB_INPUT_RAW_BUTTON_RELEASE 16
+
+typedef xcb_input_raw_button_press_event_t xcb_input_raw_button_release_event_t;
+
+/** Opcode for xcb_input_raw_motion. */
+#define XCB_INPUT_RAW_MOTION 17
+
+typedef xcb_input_raw_button_press_event_t xcb_input_raw_motion_event_t;
+
+typedef enum xcb_input_touch_event_flags_t {
+ XCB_INPUT_TOUCH_EVENT_FLAGS_TOUCH_PENDING_END = 65536,
+ XCB_INPUT_TOUCH_EVENT_FLAGS_TOUCH_EMULATING_POINTER = 131072
+} xcb_input_touch_event_flags_t;
+
+/** Opcode for xcb_input_touch_begin. */
+#define XCB_INPUT_TOUCH_BEGIN 18
+
+/**
+ * @brief xcb_input_touch_begin_event_t
+ **/
+typedef struct xcb_input_touch_begin_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint32_t detail;
+ xcb_window_t root;
+ xcb_window_t event;
+ xcb_window_t child;
+ uint32_t full_sequence;
+ xcb_input_fp1616_t root_x;
+ xcb_input_fp1616_t root_y;
+ xcb_input_fp1616_t event_x;
+ xcb_input_fp1616_t event_y;
+ uint16_t buttons_len;
+ uint16_t valuators_len;
+ xcb_input_device_id_t sourceid;
+ uint8_t pad0[2];
+ uint32_t flags;
+ xcb_input_modifier_info_t mods;
+ xcb_input_group_info_t group;
+} xcb_input_touch_begin_event_t;
+
+/** Opcode for xcb_input_touch_update. */
+#define XCB_INPUT_TOUCH_UPDATE 19
+
+typedef xcb_input_touch_begin_event_t xcb_input_touch_update_event_t;
+
+/** Opcode for xcb_input_touch_end. */
+#define XCB_INPUT_TOUCH_END 20
+
+typedef xcb_input_touch_begin_event_t xcb_input_touch_end_event_t;
+
+typedef enum xcb_input_touch_ownership_flags_t {
+ XCB_INPUT_TOUCH_OWNERSHIP_FLAGS_NONE = 0
+} xcb_input_touch_ownership_flags_t;
+
+/** Opcode for xcb_input_touch_ownership. */
+#define XCB_INPUT_TOUCH_OWNERSHIP 21
+
+/**
+ * @brief xcb_input_touch_ownership_event_t
+ **/
+typedef struct xcb_input_touch_ownership_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint32_t touchid;
+ xcb_window_t root;
+ xcb_window_t event;
+ xcb_window_t child;
+ uint32_t full_sequence;
+ xcb_input_device_id_t sourceid;
+ uint8_t pad0[2];
+ uint32_t flags;
+ uint8_t pad1[8];
+} xcb_input_touch_ownership_event_t;
+
+/** Opcode for xcb_input_raw_touch_begin. */
+#define XCB_INPUT_RAW_TOUCH_BEGIN 22
+
+/**
+ * @brief xcb_input_raw_touch_begin_event_t
+ **/
+typedef struct xcb_input_raw_touch_begin_event_t {
+ uint8_t response_type;
+ uint8_t extension;
+ uint16_t sequence;
+ uint32_t length;
+ uint16_t event_type;
+ xcb_input_device_id_t deviceid;
+ xcb_timestamp_t time;
+ uint32_t detail;
+ xcb_input_device_id_t sourceid;
+ uint16_t valuators_len;
+ uint32_t flags;
+ uint8_t pad0[4];
+ uint32_t full_sequence;
+} xcb_input_raw_touch_begin_event_t;
+
+/** Opcode for xcb_input_raw_touch_update. */
+#define XCB_INPUT_RAW_TOUCH_UPDATE 23
+
+typedef xcb_input_raw_touch_begin_event_t xcb_input_raw_touch_update_event_t;
+
+/** Opcode for xcb_input_raw_touch_end. */
+#define XCB_INPUT_RAW_TOUCH_END 24
+
+typedef xcb_input_raw_touch_begin_event_t xcb_input_raw_touch_end_event_t;
+
+/** Opcode for xcb_input_barrier_hit. */
+#define XCB_INPUT_BARRIER_HIT 25
+
+/** Opcode for xcb_input_barrier_leave. */
+#define XCB_INPUT_BARRIER_LEAVE 26
+
+/** Opcode for xcb_input_device. */
+#define XCB_INPUT_DEVICE 0
+
+/**
+ * @brief xcb_input_device_error_t
+ **/
+typedef struct xcb_input_device_error_t {
+ uint8_t response_type;
+ uint8_t error_code;
+ uint16_t sequence;
+} xcb_input_device_error_t;
+
+/** Opcode for xcb_input_event. */
+#define XCB_INPUT_EVENT 1
+
+/**
+ * @brief xcb_input_event_error_t
+ **/
+typedef struct xcb_input_event_error_t {
+ uint8_t response_type;
+ uint8_t error_code;
+ uint16_t sequence;
+} xcb_input_event_error_t;
+
+/** Opcode for xcb_input_mode. */
+#define XCB_INPUT_MODE 2
+
+/**
+ * @brief xcb_input_mode_error_t
+ **/
+typedef struct xcb_input_mode_error_t {
+ uint8_t response_type;
+ uint8_t error_code;
+ uint16_t sequence;
+} xcb_input_mode_error_t;
+
+/** Opcode for xcb_input_device_busy. */
+#define XCB_INPUT_DEVICE_BUSY 3
+
+/**
+ * @brief xcb_input_device_busy_error_t
+ **/
+typedef struct xcb_input_device_busy_error_t {
+ uint8_t response_type;
+ uint8_t error_code;
+ uint16_t sequence;
+} xcb_input_device_busy_error_t;
+
+/** Opcode for xcb_input_class. */
+#define XCB_INPUT_CLASS 4
+
+/**
+ * @brief xcb_input_class_error_t
+ **/
+typedef struct xcb_input_class_error_t {
+ uint8_t response_type;
+ uint8_t error_code;
+ uint16_t sequence;
+} xcb_input_class_error_t;
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_event_class_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_event_class_t)
+ */
+void
+xcb_input_event_class_next (xcb_input_event_class_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_event_class_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_event_class_end (xcb_input_event_class_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_key_code_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_key_code_t)
+ */
+void
+xcb_input_key_code_next (xcb_input_key_code_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_key_code_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_key_code_end (xcb_input_key_code_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_id_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_id_t)
+ */
+void
+xcb_input_device_id_next (xcb_input_device_id_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_id_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_id_end (xcb_input_device_id_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_fp1616_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_fp1616_t)
+ */
+void
+xcb_input_fp1616_next (xcb_input_fp1616_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_fp1616_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_fp1616_end (xcb_input_fp1616_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_fp3232_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_fp3232_t)
+ */
+void
+xcb_input_fp3232_next (xcb_input_fp3232_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_fp3232_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_fp3232_end (xcb_input_fp3232_iterator_t i);
+
+int
+xcb_input_get_extension_version_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_extension_version_cookie_t
+xcb_input_get_extension_version (xcb_connection_t *c,
+ uint16_t name_len,
+ const char *name);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_extension_version_cookie_t
+xcb_input_get_extension_version_unchecked (xcb_connection_t *c,
+ uint16_t name_len,
+ const char *name);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_extension_version_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_extension_version_reply_t *
+xcb_input_get_extension_version_reply (xcb_connection_t *c,
+ xcb_input_get_extension_version_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_info_t)
+ */
+void
+xcb_input_device_info_next (xcb_input_device_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_info_end (xcb_input_device_info_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_key_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_key_info_t)
+ */
+void
+xcb_input_key_info_next (xcb_input_key_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_key_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_key_info_end (xcb_input_key_info_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_button_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_button_info_t)
+ */
+void
+xcb_input_button_info_next (xcb_input_button_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_button_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_button_info_end (xcb_input_button_info_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_axis_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_axis_info_t)
+ */
+void
+xcb_input_axis_info_next (xcb_input_axis_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_axis_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_axis_info_end (xcb_input_axis_info_iterator_t i);
+
+int
+xcb_input_valuator_info_sizeof (const void *_buffer);
+
+xcb_input_axis_info_t *
+xcb_input_valuator_info_axes (const xcb_input_valuator_info_t *R);
+
+int
+xcb_input_valuator_info_axes_length (const xcb_input_valuator_info_t *R);
+
+xcb_input_axis_info_iterator_t
+xcb_input_valuator_info_axes_iterator (const xcb_input_valuator_info_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_valuator_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_valuator_info_t)
+ */
+void
+xcb_input_valuator_info_next (xcb_input_valuator_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_valuator_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_valuator_info_end (xcb_input_valuator_info_iterator_t i);
+
+xcb_input_axis_info_t *
+xcb_input_input_info_info_valuator_axes (const xcb_input_input_info_info_t *S);
+
+int
+xcb_input_input_info_info_valuator_axes_length (const xcb_input_input_info_t *R,
+ const xcb_input_input_info_info_t *S);
+
+xcb_input_axis_info_iterator_t
+xcb_input_input_info_info_valuator_axes_iterator (const xcb_input_input_info_t *R,
+ const xcb_input_input_info_info_t *S);
+
+int
+xcb_input_input_info_info_serialize (void **_buffer,
+ uint8_t class_id,
+ const xcb_input_input_info_info_t *_aux);
+
+int
+xcb_input_input_info_info_unpack (const void *_buffer,
+ uint8_t class_id,
+ xcb_input_input_info_info_t *_aux);
+
+int
+xcb_input_input_info_info_sizeof (const void *_buffer,
+ uint8_t class_id);
+
+int
+xcb_input_input_info_sizeof (const void *_buffer);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_input_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_input_info_t)
+ */
+void
+xcb_input_input_info_next (xcb_input_input_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_input_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_input_info_end (xcb_input_input_info_iterator_t i);
+
+int
+xcb_input_device_name_sizeof (const void *_buffer);
+
+char *
+xcb_input_device_name_string (const xcb_input_device_name_t *R);
+
+int
+xcb_input_device_name_string_length (const xcb_input_device_name_t *R);
+
+xcb_generic_iterator_t
+xcb_input_device_name_string_end (const xcb_input_device_name_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_name_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_name_t)
+ */
+void
+xcb_input_device_name_next (xcb_input_device_name_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_name_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_name_end (xcb_input_device_name_iterator_t i);
+
+int
+xcb_input_list_input_devices_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_list_input_devices_cookie_t
+xcb_input_list_input_devices (xcb_connection_t *c);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_list_input_devices_cookie_t
+xcb_input_list_input_devices_unchecked (xcb_connection_t *c);
+
+xcb_input_device_info_t *
+xcb_input_list_input_devices_devices (const xcb_input_list_input_devices_reply_t *R);
+
+int
+xcb_input_list_input_devices_devices_length (const xcb_input_list_input_devices_reply_t *R);
+
+xcb_input_device_info_iterator_t
+xcb_input_list_input_devices_devices_iterator (const xcb_input_list_input_devices_reply_t *R);
+
+int
+xcb_input_list_input_devices_infos_length (const xcb_input_list_input_devices_reply_t *R);
+
+xcb_input_input_info_iterator_t
+xcb_input_list_input_devices_infos_iterator (const xcb_input_list_input_devices_reply_t *R);
+
+int
+xcb_input_list_input_devices_names_length (const xcb_input_list_input_devices_reply_t *R);
+
+xcb_str_iterator_t
+xcb_input_list_input_devices_names_iterator (const xcb_input_list_input_devices_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_list_input_devices_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_list_input_devices_reply_t *
+xcb_input_list_input_devices_reply (xcb_connection_t *c,
+ xcb_input_list_input_devices_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_event_type_base_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_event_type_base_t)
+ */
+void
+xcb_input_event_type_base_next (xcb_input_event_type_base_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_event_type_base_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_event_type_base_end (xcb_input_event_type_base_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_input_class_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_input_class_info_t)
+ */
+void
+xcb_input_input_class_info_next (xcb_input_input_class_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_input_class_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_input_class_info_end (xcb_input_input_class_info_iterator_t i);
+
+int
+xcb_input_open_device_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_open_device_cookie_t
+xcb_input_open_device (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_open_device_cookie_t
+xcb_input_open_device_unchecked (xcb_connection_t *c,
+ uint8_t device_id);
+
+xcb_input_input_class_info_t *
+xcb_input_open_device_class_info (const xcb_input_open_device_reply_t *R);
+
+int
+xcb_input_open_device_class_info_length (const xcb_input_open_device_reply_t *R);
+
+xcb_input_input_class_info_iterator_t
+xcb_input_open_device_class_info_iterator (const xcb_input_open_device_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_open_device_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_open_device_reply_t *
+xcb_input_open_device_reply (xcb_connection_t *c,
+ xcb_input_open_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_close_device_checked (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_close_device (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_set_device_mode_cookie_t
+xcb_input_set_device_mode (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t mode);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_set_device_mode_cookie_t
+xcb_input_set_device_mode_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t mode);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_set_device_mode_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_set_device_mode_reply_t *
+xcb_input_set_device_mode_reply (xcb_connection_t *c,
+ xcb_input_set_device_mode_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_select_extension_event_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_select_extension_event_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_classes,
+ const xcb_input_event_class_t *classes);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_select_extension_event (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_classes,
+ const xcb_input_event_class_t *classes);
+
+xcb_input_event_class_t *
+xcb_input_select_extension_event_classes (const xcb_input_select_extension_event_request_t *R);
+
+int
+xcb_input_select_extension_event_classes_length (const xcb_input_select_extension_event_request_t *R);
+
+xcb_generic_iterator_t
+xcb_input_select_extension_event_classes_end (const xcb_input_select_extension_event_request_t *R);
+
+int
+xcb_input_get_selected_extension_events_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_selected_extension_events_cookie_t
+xcb_input_get_selected_extension_events (xcb_connection_t *c,
+ xcb_window_t window);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_selected_extension_events_cookie_t
+xcb_input_get_selected_extension_events_unchecked (xcb_connection_t *c,
+ xcb_window_t window);
+
+xcb_input_event_class_t *
+xcb_input_get_selected_extension_events_this_classes (const xcb_input_get_selected_extension_events_reply_t *R);
+
+int
+xcb_input_get_selected_extension_events_this_classes_length (const xcb_input_get_selected_extension_events_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_get_selected_extension_events_this_classes_end (const xcb_input_get_selected_extension_events_reply_t *R);
+
+xcb_input_event_class_t *
+xcb_input_get_selected_extension_events_all_classes (const xcb_input_get_selected_extension_events_reply_t *R);
+
+int
+xcb_input_get_selected_extension_events_all_classes_length (const xcb_input_get_selected_extension_events_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_get_selected_extension_events_all_classes_end (const xcb_input_get_selected_extension_events_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_selected_extension_events_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_selected_extension_events_reply_t *
+xcb_input_get_selected_extension_events_reply (xcb_connection_t *c,
+ xcb_input_get_selected_extension_events_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_change_device_dont_propagate_list_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_change_device_dont_propagate_list_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_classes,
+ uint8_t mode,
+ const xcb_input_event_class_t *classes);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_change_device_dont_propagate_list (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_classes,
+ uint8_t mode,
+ const xcb_input_event_class_t *classes);
+
+xcb_input_event_class_t *
+xcb_input_change_device_dont_propagate_list_classes (const xcb_input_change_device_dont_propagate_list_request_t *R);
+
+int
+xcb_input_change_device_dont_propagate_list_classes_length (const xcb_input_change_device_dont_propagate_list_request_t *R);
+
+xcb_generic_iterator_t
+xcb_input_change_device_dont_propagate_list_classes_end (const xcb_input_change_device_dont_propagate_list_request_t *R);
+
+int
+xcb_input_get_device_dont_propagate_list_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_device_dont_propagate_list_cookie_t
+xcb_input_get_device_dont_propagate_list (xcb_connection_t *c,
+ xcb_window_t window);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_device_dont_propagate_list_cookie_t
+xcb_input_get_device_dont_propagate_list_unchecked (xcb_connection_t *c,
+ xcb_window_t window);
+
+xcb_input_event_class_t *
+xcb_input_get_device_dont_propagate_list_classes (const xcb_input_get_device_dont_propagate_list_reply_t *R);
+
+int
+xcb_input_get_device_dont_propagate_list_classes_length (const xcb_input_get_device_dont_propagate_list_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_get_device_dont_propagate_list_classes_end (const xcb_input_get_device_dont_propagate_list_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_device_dont_propagate_list_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_device_dont_propagate_list_reply_t *
+xcb_input_get_device_dont_propagate_list_reply (xcb_connection_t *c,
+ xcb_input_get_device_dont_propagate_list_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_device_time_coord_sizeof (const void *_buffer,
+ uint8_t num_axes);
+
+int32_t *
+xcb_input_device_time_coord_axisvalues (const xcb_input_device_time_coord_t *R);
+
+int
+xcb_input_device_time_coord_axisvalues_length (const xcb_input_device_time_coord_t *R,
+ uint8_t num_axes);
+
+xcb_generic_iterator_t
+xcb_input_device_time_coord_axisvalues_end (const xcb_input_device_time_coord_t *R,
+ uint8_t num_axes);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_time_coord_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_time_coord_t)
+ */
+void
+xcb_input_device_time_coord_next (xcb_input_device_time_coord_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_time_coord_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_time_coord_end (xcb_input_device_time_coord_iterator_t i);
+
+int
+xcb_input_get_device_motion_events_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_device_motion_events_cookie_t
+xcb_input_get_device_motion_events (xcb_connection_t *c,
+ xcb_timestamp_t start,
+ xcb_timestamp_t stop,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_device_motion_events_cookie_t
+xcb_input_get_device_motion_events_unchecked (xcb_connection_t *c,
+ xcb_timestamp_t start,
+ xcb_timestamp_t stop,
+ uint8_t device_id);
+
+int
+xcb_input_get_device_motion_events_events_length (const xcb_input_get_device_motion_events_reply_t *R);
+
+xcb_input_device_time_coord_iterator_t
+xcb_input_get_device_motion_events_events_iterator (const xcb_input_get_device_motion_events_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_device_motion_events_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_device_motion_events_reply_t *
+xcb_input_get_device_motion_events_reply (xcb_connection_t *c,
+ xcb_input_get_device_motion_events_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_change_keyboard_device_cookie_t
+xcb_input_change_keyboard_device (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_change_keyboard_device_cookie_t
+xcb_input_change_keyboard_device_unchecked (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_change_keyboard_device_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_change_keyboard_device_reply_t *
+xcb_input_change_keyboard_device_reply (xcb_connection_t *c,
+ xcb_input_change_keyboard_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_change_pointer_device_cookie_t
+xcb_input_change_pointer_device (xcb_connection_t *c,
+ uint8_t x_axis,
+ uint8_t y_axis,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_change_pointer_device_cookie_t
+xcb_input_change_pointer_device_unchecked (xcb_connection_t *c,
+ uint8_t x_axis,
+ uint8_t y_axis,
+ uint8_t device_id);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_change_pointer_device_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_change_pointer_device_reply_t *
+xcb_input_change_pointer_device_reply (xcb_connection_t *c,
+ xcb_input_change_pointer_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_grab_device_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_grab_device_cookie_t
+xcb_input_grab_device (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ xcb_timestamp_t time,
+ uint16_t num_classes,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t owner_events,
+ uint8_t device_id,
+ const xcb_input_event_class_t *classes);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_grab_device_cookie_t
+xcb_input_grab_device_unchecked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ xcb_timestamp_t time,
+ uint16_t num_classes,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t owner_events,
+ uint8_t device_id,
+ const xcb_input_event_class_t *classes);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_grab_device_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_grab_device_reply_t *
+xcb_input_grab_device_reply (xcb_connection_t *c,
+ xcb_input_grab_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_ungrab_device_checked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_ungrab_device (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ uint8_t device_id);
+
+int
+xcb_input_grab_device_key_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_grab_device_key_checked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint16_t num_classes,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t grabbed_device,
+ uint8_t key,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t owner_events,
+ const xcb_input_event_class_t *classes);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_grab_device_key (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint16_t num_classes,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t grabbed_device,
+ uint8_t key,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t owner_events,
+ const xcb_input_event_class_t *classes);
+
+xcb_input_event_class_t *
+xcb_input_grab_device_key_classes (const xcb_input_grab_device_key_request_t *R);
+
+int
+xcb_input_grab_device_key_classes_length (const xcb_input_grab_device_key_request_t *R);
+
+xcb_generic_iterator_t
+xcb_input_grab_device_key_classes_end (const xcb_input_grab_device_key_request_t *R);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_ungrab_device_key_checked (xcb_connection_t *c,
+ xcb_window_t grabWindow,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t key,
+ uint8_t grabbed_device);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_ungrab_device_key (xcb_connection_t *c,
+ xcb_window_t grabWindow,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t key,
+ uint8_t grabbed_device);
+
+int
+xcb_input_grab_device_button_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_grab_device_button_checked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint8_t grabbed_device,
+ uint8_t modifier_device,
+ uint16_t num_classes,
+ uint16_t modifiers,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t button,
+ uint8_t owner_events,
+ const xcb_input_event_class_t *classes);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_grab_device_button (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint8_t grabbed_device,
+ uint8_t modifier_device,
+ uint16_t num_classes,
+ uint16_t modifiers,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t button,
+ uint8_t owner_events,
+ const xcb_input_event_class_t *classes);
+
+xcb_input_event_class_t *
+xcb_input_grab_device_button_classes (const xcb_input_grab_device_button_request_t *R);
+
+int
+xcb_input_grab_device_button_classes_length (const xcb_input_grab_device_button_request_t *R);
+
+xcb_generic_iterator_t
+xcb_input_grab_device_button_classes_end (const xcb_input_grab_device_button_request_t *R);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_ungrab_device_button_checked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t button,
+ uint8_t grabbed_device);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_ungrab_device_button (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t button,
+ uint8_t grabbed_device);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_allow_device_events_checked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ uint8_t mode,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_allow_device_events (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ uint8_t mode,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_device_focus_cookie_t
+xcb_input_get_device_focus (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_device_focus_cookie_t
+xcb_input_get_device_focus_unchecked (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_device_focus_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_device_focus_reply_t *
+xcb_input_get_device_focus_reply (xcb_connection_t *c,
+ xcb_input_get_device_focus_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_set_device_focus_checked (xcb_connection_t *c,
+ xcb_window_t focus,
+ xcb_timestamp_t time,
+ uint8_t revert_to,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_set_device_focus (xcb_connection_t *c,
+ xcb_window_t focus,
+ xcb_timestamp_t time,
+ uint8_t revert_to,
+ uint8_t device_id);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_kbd_feedback_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_kbd_feedback_state_t)
+ */
+void
+xcb_input_kbd_feedback_state_next (xcb_input_kbd_feedback_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_kbd_feedback_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_kbd_feedback_state_end (xcb_input_kbd_feedback_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_ptr_feedback_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_ptr_feedback_state_t)
+ */
+void
+xcb_input_ptr_feedback_state_next (xcb_input_ptr_feedback_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_ptr_feedback_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_ptr_feedback_state_end (xcb_input_ptr_feedback_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_integer_feedback_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_integer_feedback_state_t)
+ */
+void
+xcb_input_integer_feedback_state_next (xcb_input_integer_feedback_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_integer_feedback_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_integer_feedback_state_end (xcb_input_integer_feedback_state_iterator_t i);
+
+int
+xcb_input_string_feedback_state_sizeof (const void *_buffer);
+
+xcb_keysym_t *
+xcb_input_string_feedback_state_keysyms (const xcb_input_string_feedback_state_t *R);
+
+int
+xcb_input_string_feedback_state_keysyms_length (const xcb_input_string_feedback_state_t *R);
+
+xcb_generic_iterator_t
+xcb_input_string_feedback_state_keysyms_end (const xcb_input_string_feedback_state_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_string_feedback_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_string_feedback_state_t)
+ */
+void
+xcb_input_string_feedback_state_next (xcb_input_string_feedback_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_string_feedback_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_string_feedback_state_end (xcb_input_string_feedback_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_bell_feedback_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_bell_feedback_state_t)
+ */
+void
+xcb_input_bell_feedback_state_next (xcb_input_bell_feedback_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_bell_feedback_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_bell_feedback_state_end (xcb_input_bell_feedback_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_led_feedback_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_led_feedback_state_t)
+ */
+void
+xcb_input_led_feedback_state_next (xcb_input_led_feedback_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_led_feedback_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_led_feedback_state_end (xcb_input_led_feedback_state_iterator_t i);
+
+xcb_keysym_t *
+xcb_input_feedback_state_data_string_keysyms (const xcb_input_feedback_state_data_t *S);
+
+int
+xcb_input_feedback_state_data_string_keysyms_length (const xcb_input_feedback_state_t *R,
+ const xcb_input_feedback_state_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_feedback_state_data_string_keysyms_end (const xcb_input_feedback_state_t *R,
+ const xcb_input_feedback_state_data_t *S);
+
+int
+xcb_input_feedback_state_data_serialize (void **_buffer,
+ uint8_t class_id,
+ const xcb_input_feedback_state_data_t *_aux);
+
+int
+xcb_input_feedback_state_data_unpack (const void *_buffer,
+ uint8_t class_id,
+ xcb_input_feedback_state_data_t *_aux);
+
+int
+xcb_input_feedback_state_data_sizeof (const void *_buffer,
+ uint8_t class_id);
+
+int
+xcb_input_feedback_state_sizeof (const void *_buffer);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_feedback_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_feedback_state_t)
+ */
+void
+xcb_input_feedback_state_next (xcb_input_feedback_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_feedback_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_feedback_state_end (xcb_input_feedback_state_iterator_t i);
+
+int
+xcb_input_get_feedback_control_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_feedback_control_cookie_t
+xcb_input_get_feedback_control (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_feedback_control_cookie_t
+xcb_input_get_feedback_control_unchecked (xcb_connection_t *c,
+ uint8_t device_id);
+
+int
+xcb_input_get_feedback_control_feedbacks_length (const xcb_input_get_feedback_control_reply_t *R);
+
+xcb_input_feedback_state_iterator_t
+xcb_input_get_feedback_control_feedbacks_iterator (const xcb_input_get_feedback_control_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_feedback_control_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_feedback_control_reply_t *
+xcb_input_get_feedback_control_reply (xcb_connection_t *c,
+ xcb_input_get_feedback_control_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_kbd_feedback_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_kbd_feedback_ctl_t)
+ */
+void
+xcb_input_kbd_feedback_ctl_next (xcb_input_kbd_feedback_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_kbd_feedback_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_kbd_feedback_ctl_end (xcb_input_kbd_feedback_ctl_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_ptr_feedback_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_ptr_feedback_ctl_t)
+ */
+void
+xcb_input_ptr_feedback_ctl_next (xcb_input_ptr_feedback_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_ptr_feedback_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_ptr_feedback_ctl_end (xcb_input_ptr_feedback_ctl_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_integer_feedback_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_integer_feedback_ctl_t)
+ */
+void
+xcb_input_integer_feedback_ctl_next (xcb_input_integer_feedback_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_integer_feedback_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_integer_feedback_ctl_end (xcb_input_integer_feedback_ctl_iterator_t i);
+
+int
+xcb_input_string_feedback_ctl_sizeof (const void *_buffer);
+
+xcb_keysym_t *
+xcb_input_string_feedback_ctl_keysyms (const xcb_input_string_feedback_ctl_t *R);
+
+int
+xcb_input_string_feedback_ctl_keysyms_length (const xcb_input_string_feedback_ctl_t *R);
+
+xcb_generic_iterator_t
+xcb_input_string_feedback_ctl_keysyms_end (const xcb_input_string_feedback_ctl_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_string_feedback_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_string_feedback_ctl_t)
+ */
+void
+xcb_input_string_feedback_ctl_next (xcb_input_string_feedback_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_string_feedback_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_string_feedback_ctl_end (xcb_input_string_feedback_ctl_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_bell_feedback_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_bell_feedback_ctl_t)
+ */
+void
+xcb_input_bell_feedback_ctl_next (xcb_input_bell_feedback_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_bell_feedback_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_bell_feedback_ctl_end (xcb_input_bell_feedback_ctl_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_led_feedback_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_led_feedback_ctl_t)
+ */
+void
+xcb_input_led_feedback_ctl_next (xcb_input_led_feedback_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_led_feedback_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_led_feedback_ctl_end (xcb_input_led_feedback_ctl_iterator_t i);
+
+xcb_keysym_t *
+xcb_input_feedback_ctl_data_string_keysyms (const xcb_input_feedback_ctl_data_t *S);
+
+int
+xcb_input_feedback_ctl_data_string_keysyms_length (const xcb_input_feedback_ctl_t *R,
+ const xcb_input_feedback_ctl_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_feedback_ctl_data_string_keysyms_end (const xcb_input_feedback_ctl_t *R,
+ const xcb_input_feedback_ctl_data_t *S);
+
+int
+xcb_input_feedback_ctl_data_serialize (void **_buffer,
+ uint8_t class_id,
+ const xcb_input_feedback_ctl_data_t *_aux);
+
+int
+xcb_input_feedback_ctl_data_unpack (const void *_buffer,
+ uint8_t class_id,
+ xcb_input_feedback_ctl_data_t *_aux);
+
+int
+xcb_input_feedback_ctl_data_sizeof (const void *_buffer,
+ uint8_t class_id);
+
+int
+xcb_input_feedback_ctl_sizeof (const void *_buffer);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_feedback_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_feedback_ctl_t)
+ */
+void
+xcb_input_feedback_ctl_next (xcb_input_feedback_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_feedback_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_feedback_ctl_end (xcb_input_feedback_ctl_iterator_t i);
+
+int
+xcb_input_change_feedback_control_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_change_feedback_control_checked (xcb_connection_t *c,
+ uint32_t mask,
+ uint8_t device_id,
+ uint8_t feedback_id,
+ xcb_input_feedback_ctl_t *feedback);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_change_feedback_control (xcb_connection_t *c,
+ uint32_t mask,
+ uint8_t device_id,
+ uint8_t feedback_id,
+ xcb_input_feedback_ctl_t *feedback);
+
+xcb_input_feedback_ctl_t *
+xcb_input_change_feedback_control_feedback (const xcb_input_change_feedback_control_request_t *R);
+
+int
+xcb_input_get_device_key_mapping_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_device_key_mapping_cookie_t
+xcb_input_get_device_key_mapping (xcb_connection_t *c,
+ uint8_t device_id,
+ xcb_input_key_code_t first_keycode,
+ uint8_t count);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_device_key_mapping_cookie_t
+xcb_input_get_device_key_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ xcb_input_key_code_t first_keycode,
+ uint8_t count);
+
+xcb_keysym_t *
+xcb_input_get_device_key_mapping_keysyms (const xcb_input_get_device_key_mapping_reply_t *R);
+
+int
+xcb_input_get_device_key_mapping_keysyms_length (const xcb_input_get_device_key_mapping_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_get_device_key_mapping_keysyms_end (const xcb_input_get_device_key_mapping_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_device_key_mapping_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_device_key_mapping_reply_t *
+xcb_input_get_device_key_mapping_reply (xcb_connection_t *c,
+ xcb_input_get_device_key_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_change_device_key_mapping_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_change_device_key_mapping_checked (xcb_connection_t *c,
+ uint8_t device_id,
+ xcb_input_key_code_t first_keycode,
+ uint8_t keysyms_per_keycode,
+ uint8_t keycode_count,
+ const xcb_keysym_t *keysyms);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_change_device_key_mapping (xcb_connection_t *c,
+ uint8_t device_id,
+ xcb_input_key_code_t first_keycode,
+ uint8_t keysyms_per_keycode,
+ uint8_t keycode_count,
+ const xcb_keysym_t *keysyms);
+
+xcb_keysym_t *
+xcb_input_change_device_key_mapping_keysyms (const xcb_input_change_device_key_mapping_request_t *R);
+
+int
+xcb_input_change_device_key_mapping_keysyms_length (const xcb_input_change_device_key_mapping_request_t *R);
+
+xcb_generic_iterator_t
+xcb_input_change_device_key_mapping_keysyms_end (const xcb_input_change_device_key_mapping_request_t *R);
+
+int
+xcb_input_get_device_modifier_mapping_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_device_modifier_mapping_cookie_t
+xcb_input_get_device_modifier_mapping (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_device_modifier_mapping_cookie_t
+xcb_input_get_device_modifier_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id);
+
+uint8_t *
+xcb_input_get_device_modifier_mapping_keymaps (const xcb_input_get_device_modifier_mapping_reply_t *R);
+
+int
+xcb_input_get_device_modifier_mapping_keymaps_length (const xcb_input_get_device_modifier_mapping_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_get_device_modifier_mapping_keymaps_end (const xcb_input_get_device_modifier_mapping_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_device_modifier_mapping_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_device_modifier_mapping_reply_t *
+xcb_input_get_device_modifier_mapping_reply (xcb_connection_t *c,
+ xcb_input_get_device_modifier_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_set_device_modifier_mapping_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_set_device_modifier_mapping_cookie_t
+xcb_input_set_device_modifier_mapping (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t keycodes_per_modifier,
+ const uint8_t *keymaps);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_set_device_modifier_mapping_cookie_t
+xcb_input_set_device_modifier_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t keycodes_per_modifier,
+ const uint8_t *keymaps);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_set_device_modifier_mapping_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_set_device_modifier_mapping_reply_t *
+xcb_input_set_device_modifier_mapping_reply (xcb_connection_t *c,
+ xcb_input_set_device_modifier_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_get_device_button_mapping_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_device_button_mapping_cookie_t
+xcb_input_get_device_button_mapping (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_device_button_mapping_cookie_t
+xcb_input_get_device_button_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id);
+
+uint8_t *
+xcb_input_get_device_button_mapping_map (const xcb_input_get_device_button_mapping_reply_t *R);
+
+int
+xcb_input_get_device_button_mapping_map_length (const xcb_input_get_device_button_mapping_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_get_device_button_mapping_map_end (const xcb_input_get_device_button_mapping_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_device_button_mapping_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_device_button_mapping_reply_t *
+xcb_input_get_device_button_mapping_reply (xcb_connection_t *c,
+ xcb_input_get_device_button_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_set_device_button_mapping_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_set_device_button_mapping_cookie_t
+xcb_input_set_device_button_mapping (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t map_size,
+ const uint8_t *map);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_set_device_button_mapping_cookie_t
+xcb_input_set_device_button_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t map_size,
+ const uint8_t *map);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_set_device_button_mapping_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_set_device_button_mapping_reply_t *
+xcb_input_set_device_button_mapping_reply (xcb_connection_t *c,
+ xcb_input_set_device_button_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_key_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_key_state_t)
+ */
+void
+xcb_input_key_state_next (xcb_input_key_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_key_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_key_state_end (xcb_input_key_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_button_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_button_state_t)
+ */
+void
+xcb_input_button_state_next (xcb_input_button_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_button_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_button_state_end (xcb_input_button_state_iterator_t i);
+
+int
+xcb_input_valuator_state_sizeof (const void *_buffer);
+
+int32_t *
+xcb_input_valuator_state_valuators (const xcb_input_valuator_state_t *R);
+
+int
+xcb_input_valuator_state_valuators_length (const xcb_input_valuator_state_t *R);
+
+xcb_generic_iterator_t
+xcb_input_valuator_state_valuators_end (const xcb_input_valuator_state_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_valuator_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_valuator_state_t)
+ */
+void
+xcb_input_valuator_state_next (xcb_input_valuator_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_valuator_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_valuator_state_end (xcb_input_valuator_state_iterator_t i);
+
+int32_t *
+xcb_input_input_state_data_valuator_valuators (const xcb_input_input_state_data_t *S);
+
+int
+xcb_input_input_state_data_valuator_valuators_length (const xcb_input_input_state_t *R,
+ const xcb_input_input_state_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_input_state_data_valuator_valuators_end (const xcb_input_input_state_t *R,
+ const xcb_input_input_state_data_t *S);
+
+int
+xcb_input_input_state_data_serialize (void **_buffer,
+ uint8_t class_id,
+ const xcb_input_input_state_data_t *_aux);
+
+int
+xcb_input_input_state_data_unpack (const void *_buffer,
+ uint8_t class_id,
+ xcb_input_input_state_data_t *_aux);
+
+int
+xcb_input_input_state_data_sizeof (const void *_buffer,
+ uint8_t class_id);
+
+int
+xcb_input_input_state_sizeof (const void *_buffer);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_input_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_input_state_t)
+ */
+void
+xcb_input_input_state_next (xcb_input_input_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_input_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_input_state_end (xcb_input_input_state_iterator_t i);
+
+int
+xcb_input_query_device_state_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_query_device_state_cookie_t
+xcb_input_query_device_state (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_query_device_state_cookie_t
+xcb_input_query_device_state_unchecked (xcb_connection_t *c,
+ uint8_t device_id);
+
+int
+xcb_input_query_device_state_classes_length (const xcb_input_query_device_state_reply_t *R);
+
+xcb_input_input_state_iterator_t
+xcb_input_query_device_state_classes_iterator (const xcb_input_query_device_state_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_query_device_state_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_query_device_state_reply_t *
+xcb_input_query_device_state_reply (xcb_connection_t *c,
+ xcb_input_query_device_state_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_device_bell_checked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t feedback_id,
+ uint8_t feedback_class,
+ int8_t percent);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_device_bell (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t feedback_id,
+ uint8_t feedback_class,
+ int8_t percent);
+
+int
+xcb_input_set_device_valuators_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_set_device_valuators_cookie_t
+xcb_input_set_device_valuators (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t first_valuator,
+ uint8_t num_valuators,
+ const int32_t *valuators);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_set_device_valuators_cookie_t
+xcb_input_set_device_valuators_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t first_valuator,
+ uint8_t num_valuators,
+ const int32_t *valuators);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_set_device_valuators_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_set_device_valuators_reply_t *
+xcb_input_set_device_valuators_reply (xcb_connection_t *c,
+ xcb_input_set_device_valuators_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_device_resolution_state_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_device_resolution_state_resolution_values (const xcb_input_device_resolution_state_t *R);
+
+int
+xcb_input_device_resolution_state_resolution_values_length (const xcb_input_device_resolution_state_t *R);
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_state_resolution_values_end (const xcb_input_device_resolution_state_t *R);
+
+uint32_t *
+xcb_input_device_resolution_state_resolution_min (const xcb_input_device_resolution_state_t *R);
+
+int
+xcb_input_device_resolution_state_resolution_min_length (const xcb_input_device_resolution_state_t *R);
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_state_resolution_min_end (const xcb_input_device_resolution_state_t *R);
+
+uint32_t *
+xcb_input_device_resolution_state_resolution_max (const xcb_input_device_resolution_state_t *R);
+
+int
+xcb_input_device_resolution_state_resolution_max_length (const xcb_input_device_resolution_state_t *R);
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_state_resolution_max_end (const xcb_input_device_resolution_state_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_resolution_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_resolution_state_t)
+ */
+void
+xcb_input_device_resolution_state_next (xcb_input_device_resolution_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_resolution_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_resolution_state_end (xcb_input_device_resolution_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_abs_calib_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_abs_calib_state_t)
+ */
+void
+xcb_input_device_abs_calib_state_next (xcb_input_device_abs_calib_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_abs_calib_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_abs_calib_state_end (xcb_input_device_abs_calib_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_abs_area_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_abs_area_state_t)
+ */
+void
+xcb_input_device_abs_area_state_next (xcb_input_device_abs_area_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_abs_area_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_abs_area_state_end (xcb_input_device_abs_area_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_core_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_core_state_t)
+ */
+void
+xcb_input_device_core_state_next (xcb_input_device_core_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_core_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_core_state_end (xcb_input_device_core_state_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_enable_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_enable_state_t)
+ */
+void
+xcb_input_device_enable_state_next (xcb_input_device_enable_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_enable_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_enable_state_end (xcb_input_device_enable_state_iterator_t i);
+
+uint32_t *
+xcb_input_device_state_data_resolution_resolution_values (const xcb_input_device_state_data_t *S);
+
+int
+xcb_input_device_state_data_resolution_resolution_values_length (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_device_state_data_resolution_resolution_values_end (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S);
+
+uint32_t *
+xcb_input_device_state_data_resolution_resolution_min (const xcb_input_device_state_data_t *S);
+
+int
+xcb_input_device_state_data_resolution_resolution_min_length (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_device_state_data_resolution_resolution_min_end (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S);
+
+uint32_t *
+xcb_input_device_state_data_resolution_resolution_max (const xcb_input_device_state_data_t *S);
+
+int
+xcb_input_device_state_data_resolution_resolution_max_length (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_device_state_data_resolution_resolution_max_end (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S);
+
+int
+xcb_input_device_state_data_serialize (void **_buffer,
+ uint16_t control_id,
+ const xcb_input_device_state_data_t *_aux);
+
+int
+xcb_input_device_state_data_unpack (const void *_buffer,
+ uint16_t control_id,
+ xcb_input_device_state_data_t *_aux);
+
+int
+xcb_input_device_state_data_sizeof (const void *_buffer,
+ uint16_t control_id);
+
+int
+xcb_input_device_state_sizeof (const void *_buffer);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_state_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_state_t)
+ */
+void
+xcb_input_device_state_next (xcb_input_device_state_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_state_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_state_end (xcb_input_device_state_iterator_t i);
+
+int
+xcb_input_get_device_control_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_device_control_cookie_t
+xcb_input_get_device_control (xcb_connection_t *c,
+ uint16_t control_id,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_device_control_cookie_t
+xcb_input_get_device_control_unchecked (xcb_connection_t *c,
+ uint16_t control_id,
+ uint8_t device_id);
+
+xcb_input_device_state_t *
+xcb_input_get_device_control_control (const xcb_input_get_device_control_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_device_control_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_device_control_reply_t *
+xcb_input_get_device_control_reply (xcb_connection_t *c,
+ xcb_input_get_device_control_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_device_resolution_ctl_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_device_resolution_ctl_resolution_values (const xcb_input_device_resolution_ctl_t *R);
+
+int
+xcb_input_device_resolution_ctl_resolution_values_length (const xcb_input_device_resolution_ctl_t *R);
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_ctl_resolution_values_end (const xcb_input_device_resolution_ctl_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_resolution_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_resolution_ctl_t)
+ */
+void
+xcb_input_device_resolution_ctl_next (xcb_input_device_resolution_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_resolution_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_resolution_ctl_end (xcb_input_device_resolution_ctl_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_abs_calib_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_abs_calib_ctl_t)
+ */
+void
+xcb_input_device_abs_calib_ctl_next (xcb_input_device_abs_calib_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_abs_calib_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_abs_calib_ctl_end (xcb_input_device_abs_calib_ctl_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_abs_area_ctrl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_abs_area_ctrl_t)
+ */
+void
+xcb_input_device_abs_area_ctrl_next (xcb_input_device_abs_area_ctrl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_abs_area_ctrl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_abs_area_ctrl_end (xcb_input_device_abs_area_ctrl_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_core_ctrl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_core_ctrl_t)
+ */
+void
+xcb_input_device_core_ctrl_next (xcb_input_device_core_ctrl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_core_ctrl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_core_ctrl_end (xcb_input_device_core_ctrl_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_enable_ctrl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_enable_ctrl_t)
+ */
+void
+xcb_input_device_enable_ctrl_next (xcb_input_device_enable_ctrl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_enable_ctrl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_enable_ctrl_end (xcb_input_device_enable_ctrl_iterator_t i);
+
+uint32_t *
+xcb_input_device_ctl_data_resolution_resolution_values (const xcb_input_device_ctl_data_t *S);
+
+int
+xcb_input_device_ctl_data_resolution_resolution_values_length (const xcb_input_device_ctl_t *R,
+ const xcb_input_device_ctl_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_device_ctl_data_resolution_resolution_values_end (const xcb_input_device_ctl_t *R,
+ const xcb_input_device_ctl_data_t *S);
+
+int
+xcb_input_device_ctl_data_serialize (void **_buffer,
+ uint16_t control_id,
+ const xcb_input_device_ctl_data_t *_aux);
+
+int
+xcb_input_device_ctl_data_unpack (const void *_buffer,
+ uint16_t control_id,
+ xcb_input_device_ctl_data_t *_aux);
+
+int
+xcb_input_device_ctl_data_sizeof (const void *_buffer,
+ uint16_t control_id);
+
+int
+xcb_input_device_ctl_sizeof (const void *_buffer);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_ctl_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_ctl_t)
+ */
+void
+xcb_input_device_ctl_next (xcb_input_device_ctl_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_ctl_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_ctl_end (xcb_input_device_ctl_iterator_t i);
+
+int
+xcb_input_change_device_control_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_change_device_control_cookie_t
+xcb_input_change_device_control (xcb_connection_t *c,
+ uint16_t control_id,
+ uint8_t device_id,
+ xcb_input_device_ctl_t *control);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_change_device_control_cookie_t
+xcb_input_change_device_control_unchecked (xcb_connection_t *c,
+ uint16_t control_id,
+ uint8_t device_id,
+ xcb_input_device_ctl_t *control);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_change_device_control_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_change_device_control_reply_t *
+xcb_input_change_device_control_reply (xcb_connection_t *c,
+ xcb_input_change_device_control_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_list_device_properties_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_list_device_properties_cookie_t
+xcb_input_list_device_properties (xcb_connection_t *c,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_list_device_properties_cookie_t
+xcb_input_list_device_properties_unchecked (xcb_connection_t *c,
+ uint8_t device_id);
+
+xcb_atom_t *
+xcb_input_list_device_properties_atoms (const xcb_input_list_device_properties_reply_t *R);
+
+int
+xcb_input_list_device_properties_atoms_length (const xcb_input_list_device_properties_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_list_device_properties_atoms_end (const xcb_input_list_device_properties_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_list_device_properties_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_list_device_properties_reply_t *
+xcb_input_list_device_properties_reply (xcb_connection_t *c,
+ xcb_input_list_device_properties_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+uint8_t *
+xcb_input_change_device_property_items_data_8 (const xcb_input_change_device_property_items_t *S);
+
+int
+xcb_input_change_device_property_items_data_8_length (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_change_device_property_items_data_8_end (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S);
+
+uint16_t *
+xcb_input_change_device_property_items_data_16 (const xcb_input_change_device_property_items_t *S);
+
+int
+xcb_input_change_device_property_items_data_16_length (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_change_device_property_items_data_16_end (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S);
+
+uint32_t *
+xcb_input_change_device_property_items_data_32 (const xcb_input_change_device_property_items_t *S);
+
+int
+xcb_input_change_device_property_items_data_32_length (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_change_device_property_items_data_32_end (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S);
+
+int
+xcb_input_change_device_property_items_serialize (void **_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ const xcb_input_change_device_property_items_t *_aux);
+
+int
+xcb_input_change_device_property_items_unpack (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ xcb_input_change_device_property_items_t *_aux);
+
+int
+xcb_input_change_device_property_items_sizeof (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format);
+
+int
+xcb_input_change_device_property_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_change_device_property_checked (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint8_t device_id,
+ uint8_t format,
+ uint8_t mode,
+ uint32_t num_items,
+ const void *items);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_change_device_property (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint8_t device_id,
+ uint8_t format,
+ uint8_t mode,
+ uint32_t num_items,
+ const void *items);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_change_device_property_aux_checked (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint8_t device_id,
+ uint8_t format,
+ uint8_t mode,
+ uint32_t num_items,
+ const xcb_input_change_device_property_items_t *items);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_change_device_property_aux (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint8_t device_id,
+ uint8_t format,
+ uint8_t mode,
+ uint32_t num_items,
+ const xcb_input_change_device_property_items_t *items);
+
+void *
+xcb_input_change_device_property_items (const xcb_input_change_device_property_request_t *R);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_delete_device_property_checked (xcb_connection_t *c,
+ xcb_atom_t property,
+ uint8_t device_id);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_delete_device_property (xcb_connection_t *c,
+ xcb_atom_t property,
+ uint8_t device_id);
+
+uint8_t *
+xcb_input_get_device_property_items_data_8 (const xcb_input_get_device_property_items_t *S);
+
+int
+xcb_input_get_device_property_items_data_8_length (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_get_device_property_items_data_8_end (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S);
+
+uint16_t *
+xcb_input_get_device_property_items_data_16 (const xcb_input_get_device_property_items_t *S);
+
+int
+xcb_input_get_device_property_items_data_16_length (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_get_device_property_items_data_16_end (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S);
+
+uint32_t *
+xcb_input_get_device_property_items_data_32 (const xcb_input_get_device_property_items_t *S);
+
+int
+xcb_input_get_device_property_items_data_32_length (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_get_device_property_items_data_32_end (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S);
+
+int
+xcb_input_get_device_property_items_serialize (void **_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ const xcb_input_get_device_property_items_t *_aux);
+
+int
+xcb_input_get_device_property_items_unpack (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ xcb_input_get_device_property_items_t *_aux);
+
+int
+xcb_input_get_device_property_items_sizeof (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format);
+
+int
+xcb_input_get_device_property_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_get_device_property_cookie_t
+xcb_input_get_device_property (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t offset,
+ uint32_t len,
+ uint8_t device_id,
+ uint8_t _delete);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_get_device_property_cookie_t
+xcb_input_get_device_property_unchecked (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t offset,
+ uint32_t len,
+ uint8_t device_id,
+ uint8_t _delete);
+
+void *
+xcb_input_get_device_property_items (const xcb_input_get_device_property_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_get_device_property_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_get_device_property_reply_t *
+xcb_input_get_device_property_reply (xcb_connection_t *c,
+ xcb_input_get_device_property_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_group_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_group_info_t)
+ */
+void
+xcb_input_group_info_next (xcb_input_group_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_group_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_group_info_end (xcb_input_group_info_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_modifier_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_modifier_info_t)
+ */
+void
+xcb_input_modifier_info_next (xcb_input_modifier_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_modifier_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_modifier_info_end (xcb_input_modifier_info_iterator_t i);
+
+int
+xcb_input_xi_query_pointer_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_query_pointer_cookie_t
+xcb_input_xi_query_pointer (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_query_pointer_cookie_t
+xcb_input_xi_query_pointer_unchecked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_input_device_id_t deviceid);
+
+uint32_t *
+xcb_input_xi_query_pointer_buttons (const xcb_input_xi_query_pointer_reply_t *R);
+
+int
+xcb_input_xi_query_pointer_buttons_length (const xcb_input_xi_query_pointer_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_xi_query_pointer_buttons_end (const xcb_input_xi_query_pointer_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_query_pointer_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_query_pointer_reply_t *
+xcb_input_xi_query_pointer_reply (xcb_connection_t *c,
+ xcb_input_xi_query_pointer_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_warp_pointer_checked (xcb_connection_t *c,
+ xcb_window_t src_win,
+ xcb_window_t dst_win,
+ xcb_input_fp1616_t src_x,
+ xcb_input_fp1616_t src_y,
+ uint16_t src_width,
+ uint16_t src_height,
+ xcb_input_fp1616_t dst_x,
+ xcb_input_fp1616_t dst_y,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_warp_pointer (xcb_connection_t *c,
+ xcb_window_t src_win,
+ xcb_window_t dst_win,
+ xcb_input_fp1616_t src_x,
+ xcb_input_fp1616_t src_y,
+ uint16_t src_width,
+ uint16_t src_height,
+ xcb_input_fp1616_t dst_x,
+ xcb_input_fp1616_t dst_y,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_change_cursor_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_cursor_t cursor,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_change_cursor (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_cursor_t cursor,
+ xcb_input_device_id_t deviceid);
+
+int
+xcb_input_add_master_sizeof (const void *_buffer);
+
+char *
+xcb_input_add_master_name (const xcb_input_add_master_t *R);
+
+int
+xcb_input_add_master_name_length (const xcb_input_add_master_t *R);
+
+xcb_generic_iterator_t
+xcb_input_add_master_name_end (const xcb_input_add_master_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_add_master_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_add_master_t)
+ */
+void
+xcb_input_add_master_next (xcb_input_add_master_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_add_master_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_add_master_end (xcb_input_add_master_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_remove_master_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_remove_master_t)
+ */
+void
+xcb_input_remove_master_next (xcb_input_remove_master_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_remove_master_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_remove_master_end (xcb_input_remove_master_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_attach_slave_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_attach_slave_t)
+ */
+void
+xcb_input_attach_slave_next (xcb_input_attach_slave_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_attach_slave_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_attach_slave_end (xcb_input_attach_slave_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_detach_slave_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_detach_slave_t)
+ */
+void
+xcb_input_detach_slave_next (xcb_input_detach_slave_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_detach_slave_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_detach_slave_end (xcb_input_detach_slave_iterator_t i);
+
+char *
+xcb_input_hierarchy_change_data_add_master_name (const xcb_input_hierarchy_change_data_t *S);
+
+int
+xcb_input_hierarchy_change_data_add_master_name_length (const xcb_input_hierarchy_change_t *R,
+ const xcb_input_hierarchy_change_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_hierarchy_change_data_add_master_name_end (const xcb_input_hierarchy_change_t *R,
+ const xcb_input_hierarchy_change_data_t *S);
+
+int
+xcb_input_hierarchy_change_data_serialize (void **_buffer,
+ uint16_t type,
+ const xcb_input_hierarchy_change_data_t *_aux);
+
+int
+xcb_input_hierarchy_change_data_unpack (const void *_buffer,
+ uint16_t type,
+ xcb_input_hierarchy_change_data_t *_aux);
+
+int
+xcb_input_hierarchy_change_data_sizeof (const void *_buffer,
+ uint16_t type);
+
+int
+xcb_input_hierarchy_change_sizeof (const void *_buffer);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_hierarchy_change_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_hierarchy_change_t)
+ */
+void
+xcb_input_hierarchy_change_next (xcb_input_hierarchy_change_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_hierarchy_change_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_hierarchy_change_end (xcb_input_hierarchy_change_iterator_t i);
+
+int
+xcb_input_xi_change_hierarchy_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_change_hierarchy_checked (xcb_connection_t *c,
+ uint8_t num_changes,
+ const xcb_input_hierarchy_change_t *changes);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_change_hierarchy (xcb_connection_t *c,
+ uint8_t num_changes,
+ const xcb_input_hierarchy_change_t *changes);
+
+int
+xcb_input_xi_change_hierarchy_changes_length (const xcb_input_xi_change_hierarchy_request_t *R);
+
+xcb_input_hierarchy_change_iterator_t
+xcb_input_xi_change_hierarchy_changes_iterator (const xcb_input_xi_change_hierarchy_request_t *R);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_set_client_pointer_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_set_client_pointer (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_get_client_pointer_cookie_t
+xcb_input_xi_get_client_pointer (xcb_connection_t *c,
+ xcb_window_t window);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_get_client_pointer_cookie_t
+xcb_input_xi_get_client_pointer_unchecked (xcb_connection_t *c,
+ xcb_window_t window);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_get_client_pointer_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_get_client_pointer_reply_t *
+xcb_input_xi_get_client_pointer_reply (xcb_connection_t *c,
+ xcb_input_xi_get_client_pointer_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_event_mask_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_event_mask_mask (const xcb_input_event_mask_t *R);
+
+int
+xcb_input_event_mask_mask_length (const xcb_input_event_mask_t *R);
+
+xcb_generic_iterator_t
+xcb_input_event_mask_mask_end (const xcb_input_event_mask_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_event_mask_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_event_mask_t)
+ */
+void
+xcb_input_event_mask_next (xcb_input_event_mask_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_event_mask_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_event_mask_end (xcb_input_event_mask_iterator_t i);
+
+int
+xcb_input_xi_select_events_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_select_events_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_mask,
+ const xcb_input_event_mask_t *masks);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_select_events (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_mask,
+ const xcb_input_event_mask_t *masks);
+
+int
+xcb_input_xi_select_events_masks_length (const xcb_input_xi_select_events_request_t *R);
+
+xcb_input_event_mask_iterator_t
+xcb_input_xi_select_events_masks_iterator (const xcb_input_xi_select_events_request_t *R);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_query_version_cookie_t
+xcb_input_xi_query_version (xcb_connection_t *c,
+ uint16_t major_version,
+ uint16_t minor_version);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_query_version_cookie_t
+xcb_input_xi_query_version_unchecked (xcb_connection_t *c,
+ uint16_t major_version,
+ uint16_t minor_version);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_query_version_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_query_version_reply_t *
+xcb_input_xi_query_version_reply (xcb_connection_t *c,
+ xcb_input_xi_query_version_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_button_class_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_button_class_state (const xcb_input_button_class_t *R);
+
+int
+xcb_input_button_class_state_length (const xcb_input_button_class_t *R);
+
+xcb_generic_iterator_t
+xcb_input_button_class_state_end (const xcb_input_button_class_t *R);
+
+xcb_atom_t *
+xcb_input_button_class_labels (const xcb_input_button_class_t *R);
+
+int
+xcb_input_button_class_labels_length (const xcb_input_button_class_t *R);
+
+xcb_generic_iterator_t
+xcb_input_button_class_labels_end (const xcb_input_button_class_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_button_class_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_button_class_t)
+ */
+void
+xcb_input_button_class_next (xcb_input_button_class_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_button_class_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_button_class_end (xcb_input_button_class_iterator_t i);
+
+int
+xcb_input_key_class_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_key_class_keys (const xcb_input_key_class_t *R);
+
+int
+xcb_input_key_class_keys_length (const xcb_input_key_class_t *R);
+
+xcb_generic_iterator_t
+xcb_input_key_class_keys_end (const xcb_input_key_class_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_key_class_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_key_class_t)
+ */
+void
+xcb_input_key_class_next (xcb_input_key_class_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_key_class_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_key_class_end (xcb_input_key_class_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_scroll_class_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_scroll_class_t)
+ */
+void
+xcb_input_scroll_class_next (xcb_input_scroll_class_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_scroll_class_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_scroll_class_end (xcb_input_scroll_class_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_touch_class_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_touch_class_t)
+ */
+void
+xcb_input_touch_class_next (xcb_input_touch_class_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_touch_class_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_touch_class_end (xcb_input_touch_class_iterator_t i);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_valuator_class_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_valuator_class_t)
+ */
+void
+xcb_input_valuator_class_next (xcb_input_valuator_class_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_valuator_class_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_valuator_class_end (xcb_input_valuator_class_iterator_t i);
+
+uint32_t *
+xcb_input_device_class_data_key_keys (const xcb_input_device_class_data_t *S);
+
+int
+xcb_input_device_class_data_key_keys_length (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_device_class_data_key_keys_end (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S);
+
+uint32_t *
+xcb_input_device_class_data_button_state (const xcb_input_device_class_data_t *S);
+
+int
+xcb_input_device_class_data_button_state_length (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_device_class_data_button_state_end (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S);
+
+xcb_atom_t *
+xcb_input_device_class_data_button_labels (const xcb_input_device_class_data_t *S);
+
+int
+xcb_input_device_class_data_button_labels_length (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S);
+
+xcb_generic_iterator_t
+xcb_input_device_class_data_button_labels_end (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S);
+
+int
+xcb_input_device_class_data_serialize (void **_buffer,
+ uint16_t type,
+ const xcb_input_device_class_data_t *_aux);
+
+int
+xcb_input_device_class_data_unpack (const void *_buffer,
+ uint16_t type,
+ xcb_input_device_class_data_t *_aux);
+
+int
+xcb_input_device_class_data_sizeof (const void *_buffer,
+ uint16_t type);
+
+int
+xcb_input_device_class_sizeof (const void *_buffer);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_device_class_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_device_class_t)
+ */
+void
+xcb_input_device_class_next (xcb_input_device_class_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_device_class_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_device_class_end (xcb_input_device_class_iterator_t i);
+
+int
+xcb_input_xi_device_info_sizeof (const void *_buffer);
+
+char *
+xcb_input_xi_device_info_name (const xcb_input_xi_device_info_t *R);
+
+int
+xcb_input_xi_device_info_name_length (const xcb_input_xi_device_info_t *R);
+
+xcb_generic_iterator_t
+xcb_input_xi_device_info_name_end (const xcb_input_xi_device_info_t *R);
+
+int
+xcb_input_xi_device_info_classes_length (const xcb_input_xi_device_info_t *R);
+
+xcb_input_device_class_iterator_t
+xcb_input_xi_device_info_classes_iterator (const xcb_input_xi_device_info_t *R);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_xi_device_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_xi_device_info_t)
+ */
+void
+xcb_input_xi_device_info_next (xcb_input_xi_device_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_xi_device_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_xi_device_info_end (xcb_input_xi_device_info_iterator_t i);
+
+int
+xcb_input_xi_query_device_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_query_device_cookie_t
+xcb_input_xi_query_device (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_query_device_cookie_t
+xcb_input_xi_query_device_unchecked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid);
+
+int
+xcb_input_xi_query_device_infos_length (const xcb_input_xi_query_device_reply_t *R);
+
+xcb_input_xi_device_info_iterator_t
+xcb_input_xi_query_device_infos_iterator (const xcb_input_xi_query_device_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_query_device_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_query_device_reply_t *
+xcb_input_xi_query_device_reply (xcb_connection_t *c,
+ xcb_input_xi_query_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_set_focus_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_set_focus (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_get_focus_cookie_t
+xcb_input_xi_get_focus (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_get_focus_cookie_t
+xcb_input_xi_get_focus_unchecked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_get_focus_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_get_focus_reply_t *
+xcb_input_xi_get_focus_reply (xcb_connection_t *c,
+ xcb_input_xi_get_focus_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_xi_grab_device_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_grab_device_cookie_t
+xcb_input_xi_grab_device (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_timestamp_t time,
+ xcb_cursor_t cursor,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t paired_device_mode,
+ uint8_t owner_events,
+ uint16_t mask_len,
+ const uint32_t *mask);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_grab_device_cookie_t
+xcb_input_xi_grab_device_unchecked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_timestamp_t time,
+ xcb_cursor_t cursor,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t paired_device_mode,
+ uint8_t owner_events,
+ uint16_t mask_len,
+ const uint32_t *mask);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_grab_device_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_grab_device_reply_t *
+xcb_input_xi_grab_device_reply (xcb_connection_t *c,
+ xcb_input_xi_grab_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_ungrab_device_checked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_ungrab_device (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_allow_events_checked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid,
+ uint8_t event_mode,
+ uint32_t touchid,
+ xcb_window_t grab_window);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_allow_events (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid,
+ uint8_t event_mode,
+ uint32_t touchid,
+ xcb_window_t grab_window);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_grab_modifier_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_grab_modifier_info_t)
+ */
+void
+xcb_input_grab_modifier_info_next (xcb_input_grab_modifier_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_grab_modifier_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_grab_modifier_info_end (xcb_input_grab_modifier_info_iterator_t i);
+
+int
+xcb_input_xi_passive_grab_device_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_passive_grab_device_cookie_t
+xcb_input_xi_passive_grab_device (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_window_t grab_window,
+ xcb_cursor_t cursor,
+ uint32_t detail,
+ xcb_input_device_id_t deviceid,
+ uint16_t num_modifiers,
+ uint16_t mask_len,
+ uint8_t grab_type,
+ uint8_t grab_mode,
+ uint8_t paired_device_mode,
+ uint8_t owner_events,
+ const uint32_t *mask,
+ const uint32_t *modifiers);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_passive_grab_device_cookie_t
+xcb_input_xi_passive_grab_device_unchecked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_window_t grab_window,
+ xcb_cursor_t cursor,
+ uint32_t detail,
+ xcb_input_device_id_t deviceid,
+ uint16_t num_modifiers,
+ uint16_t mask_len,
+ uint8_t grab_type,
+ uint8_t grab_mode,
+ uint8_t paired_device_mode,
+ uint8_t owner_events,
+ const uint32_t *mask,
+ const uint32_t *modifiers);
+
+xcb_input_grab_modifier_info_t *
+xcb_input_xi_passive_grab_device_modifiers (const xcb_input_xi_passive_grab_device_reply_t *R);
+
+int
+xcb_input_xi_passive_grab_device_modifiers_length (const xcb_input_xi_passive_grab_device_reply_t *R);
+
+xcb_input_grab_modifier_info_iterator_t
+xcb_input_xi_passive_grab_device_modifiers_iterator (const xcb_input_xi_passive_grab_device_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_passive_grab_device_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_passive_grab_device_reply_t *
+xcb_input_xi_passive_grab_device_reply (xcb_connection_t *c,
+ xcb_input_xi_passive_grab_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_xi_passive_ungrab_device_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_passive_ungrab_device_checked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint32_t detail,
+ xcb_input_device_id_t deviceid,
+ uint16_t num_modifiers,
+ uint8_t grab_type,
+ const uint32_t *modifiers);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_passive_ungrab_device (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint32_t detail,
+ xcb_input_device_id_t deviceid,
+ uint16_t num_modifiers,
+ uint8_t grab_type,
+ const uint32_t *modifiers);
+
+uint32_t *
+xcb_input_xi_passive_ungrab_device_modifiers (const xcb_input_xi_passive_ungrab_device_request_t *R);
+
+int
+xcb_input_xi_passive_ungrab_device_modifiers_length (const xcb_input_xi_passive_ungrab_device_request_t *R);
+
+xcb_generic_iterator_t
+xcb_input_xi_passive_ungrab_device_modifiers_end (const xcb_input_xi_passive_ungrab_device_request_t *R);
+
+int
+xcb_input_xi_list_properties_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_list_properties_cookie_t
+xcb_input_xi_list_properties (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_list_properties_cookie_t
+xcb_input_xi_list_properties_unchecked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid);
+
+xcb_atom_t *
+xcb_input_xi_list_properties_properties (const xcb_input_xi_list_properties_reply_t *R);
+
+int
+xcb_input_xi_list_properties_properties_length (const xcb_input_xi_list_properties_reply_t *R);
+
+xcb_generic_iterator_t
+xcb_input_xi_list_properties_properties_end (const xcb_input_xi_list_properties_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_list_properties_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_list_properties_reply_t *
+xcb_input_xi_list_properties_reply (xcb_connection_t *c,
+ xcb_input_xi_list_properties_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+uint8_t *
+xcb_input_xi_change_property_items_data_8 (const xcb_input_xi_change_property_items_t *S);
+
+int
+xcb_input_xi_change_property_items_data_8_length (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_xi_change_property_items_data_8_end (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S);
+
+uint16_t *
+xcb_input_xi_change_property_items_data_16 (const xcb_input_xi_change_property_items_t *S);
+
+int
+xcb_input_xi_change_property_items_data_16_length (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_xi_change_property_items_data_16_end (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S);
+
+uint32_t *
+xcb_input_xi_change_property_items_data_32 (const xcb_input_xi_change_property_items_t *S);
+
+int
+xcb_input_xi_change_property_items_data_32_length (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_xi_change_property_items_data_32_end (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S);
+
+int
+xcb_input_xi_change_property_items_serialize (void **_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ const xcb_input_xi_change_property_items_t *_aux);
+
+int
+xcb_input_xi_change_property_items_unpack (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ xcb_input_xi_change_property_items_t *_aux);
+
+int
+xcb_input_xi_change_property_items_sizeof (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format);
+
+int
+xcb_input_xi_change_property_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_change_property_checked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t format,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t num_items,
+ const void *items);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_change_property (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t format,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t num_items,
+ const void *items);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_change_property_aux_checked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t format,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t num_items,
+ const xcb_input_xi_change_property_items_t *items);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_change_property_aux (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t format,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t num_items,
+ const xcb_input_xi_change_property_items_t *items);
+
+void *
+xcb_input_xi_change_property_items (const xcb_input_xi_change_property_request_t *R);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will not cause
+ * a reply to be generated. Any returned error will be
+ * saved for handling by xcb_request_check().
+ */
+xcb_void_cookie_t
+xcb_input_xi_delete_property_checked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ xcb_atom_t property);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_void_cookie_t
+xcb_input_xi_delete_property (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ xcb_atom_t property);
+
+uint8_t *
+xcb_input_xi_get_property_items_data_8 (const xcb_input_xi_get_property_items_t *S);
+
+int
+xcb_input_xi_get_property_items_data_8_length (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_xi_get_property_items_data_8_end (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S);
+
+uint16_t *
+xcb_input_xi_get_property_items_data_16 (const xcb_input_xi_get_property_items_t *S);
+
+int
+xcb_input_xi_get_property_items_data_16_length (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_xi_get_property_items_data_16_end (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S);
+
+uint32_t *
+xcb_input_xi_get_property_items_data_32 (const xcb_input_xi_get_property_items_t *S);
+
+int
+xcb_input_xi_get_property_items_data_32_length (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S);
+
+xcb_generic_iterator_t
+xcb_input_xi_get_property_items_data_32_end (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S);
+
+int
+xcb_input_xi_get_property_items_serialize (void **_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ const xcb_input_xi_get_property_items_t *_aux);
+
+int
+xcb_input_xi_get_property_items_unpack (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ xcb_input_xi_get_property_items_t *_aux);
+
+int
+xcb_input_xi_get_property_items_sizeof (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format);
+
+int
+xcb_input_xi_get_property_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_get_property_cookie_t
+xcb_input_xi_get_property (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t _delete,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t offset,
+ uint32_t len);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_get_property_cookie_t
+xcb_input_xi_get_property_unchecked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t _delete,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t offset,
+ uint32_t len);
+
+void *
+xcb_input_xi_get_property_items (const xcb_input_xi_get_property_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_get_property_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_get_property_reply_t *
+xcb_input_xi_get_property_reply (xcb_connection_t *c,
+ xcb_input_xi_get_property_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_xi_get_selected_events_sizeof (const void *_buffer);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ */
+xcb_input_xi_get_selected_events_cookie_t
+xcb_input_xi_get_selected_events (xcb_connection_t *c,
+ xcb_window_t window);
+
+/**
+ *
+ * @param c The connection
+ * @return A cookie
+ *
+ * Delivers a request to the X server.
+ *
+ * This form can be used only if the request will cause
+ * a reply to be generated. Any returned error will be
+ * placed in the event queue.
+ */
+xcb_input_xi_get_selected_events_cookie_t
+xcb_input_xi_get_selected_events_unchecked (xcb_connection_t *c,
+ xcb_window_t window);
+
+int
+xcb_input_xi_get_selected_events_masks_length (const xcb_input_xi_get_selected_events_reply_t *R);
+
+xcb_input_event_mask_iterator_t
+xcb_input_xi_get_selected_events_masks_iterator (const xcb_input_xi_get_selected_events_reply_t *R);
+
+/**
+ * Return the reply
+ * @param c The connection
+ * @param cookie The cookie
+ * @param e The xcb_generic_error_t supplied
+ *
+ * Returns the reply of the request asked by
+ *
+ * The parameter @p e supplied to this function must be NULL if
+ * xcb_input_xi_get_selected_events_unchecked(). is used.
+ * Otherwise, it stores the error if any.
+ *
+ * The returned value must be freed by the caller using free().
+ */
+xcb_input_xi_get_selected_events_reply_t *
+xcb_input_xi_get_selected_events_reply (xcb_connection_t *c,
+ xcb_input_xi_get_selected_events_cookie_t cookie /**< */,
+ xcb_generic_error_t **e);
+
+int
+xcb_input_device_changed_sizeof (const void *_buffer);
+
+int
+xcb_input_device_changed_classes_length (const xcb_input_device_changed_event_t *R);
+
+xcb_input_device_class_iterator_t
+xcb_input_device_changed_classes_iterator (const xcb_input_device_changed_event_t *R);
+
+int
+xcb_input_key_press_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_key_press_button_mask (const xcb_input_key_press_event_t *R);
+
+int
+xcb_input_key_press_button_mask_length (const xcb_input_key_press_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_key_press_button_mask_end (const xcb_input_key_press_event_t *R);
+
+uint32_t *
+xcb_input_key_press_valuator_mask (const xcb_input_key_press_event_t *R);
+
+int
+xcb_input_key_press_valuator_mask_length (const xcb_input_key_press_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_key_press_valuator_mask_end (const xcb_input_key_press_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_key_press_axisvalues (const xcb_input_key_press_event_t *R);
+
+int
+xcb_input_key_press_axisvalues_length (const xcb_input_key_press_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_key_press_axisvalues_iterator (const xcb_input_key_press_event_t *R);
+
+int
+xcb_input_key_release_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_button_press_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_button_press_button_mask (const xcb_input_button_press_event_t *R);
+
+int
+xcb_input_button_press_button_mask_length (const xcb_input_button_press_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_button_press_button_mask_end (const xcb_input_button_press_event_t *R);
+
+uint32_t *
+xcb_input_button_press_valuator_mask (const xcb_input_button_press_event_t *R);
+
+int
+xcb_input_button_press_valuator_mask_length (const xcb_input_button_press_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_button_press_valuator_mask_end (const xcb_input_button_press_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_button_press_axisvalues (const xcb_input_button_press_event_t *R);
+
+int
+xcb_input_button_press_axisvalues_length (const xcb_input_button_press_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_button_press_axisvalues_iterator (const xcb_input_button_press_event_t *R);
+
+int
+xcb_input_button_release_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_motion_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_enter_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_enter_buttons (const xcb_input_enter_event_t *R);
+
+int
+xcb_input_enter_buttons_length (const xcb_input_enter_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_enter_buttons_end (const xcb_input_enter_event_t *R);
+
+int
+xcb_input_leave_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_focus_in_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_focus_out_sizeof (const void *_buffer /**< */);
+
+/**
+ * Get the next element of the iterator
+ * @param i Pointer to a xcb_input_hierarchy_info_iterator_t
+ *
+ * Get the next element in the iterator. The member rem is
+ * decreased by one. The member data points to the next
+ * element. The member index is increased by sizeof(xcb_input_hierarchy_info_t)
+ */
+void
+xcb_input_hierarchy_info_next (xcb_input_hierarchy_info_iterator_t *i);
+
+/**
+ * Return the iterator pointing to the last element
+ * @param i An xcb_input_hierarchy_info_iterator_t
+ * @return The iterator pointing to the last element
+ *
+ * Set the current element in the iterator to the last element.
+ * The member rem is set to 0. The member data points to the
+ * last element.
+ */
+xcb_generic_iterator_t
+xcb_input_hierarchy_info_end (xcb_input_hierarchy_info_iterator_t i);
+
+int
+xcb_input_hierarchy_sizeof (const void *_buffer);
+
+xcb_input_hierarchy_info_t *
+xcb_input_hierarchy_infos (const xcb_input_hierarchy_event_t *R);
+
+int
+xcb_input_hierarchy_infos_length (const xcb_input_hierarchy_event_t *R);
+
+xcb_input_hierarchy_info_iterator_t
+xcb_input_hierarchy_infos_iterator (const xcb_input_hierarchy_event_t *R);
+
+int
+xcb_input_raw_key_press_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_raw_key_press_valuator_mask (const xcb_input_raw_key_press_event_t *R);
+
+int
+xcb_input_raw_key_press_valuator_mask_length (const xcb_input_raw_key_press_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_raw_key_press_valuator_mask_end (const xcb_input_raw_key_press_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_raw_key_press_axisvalues (const xcb_input_raw_key_press_event_t *R);
+
+int
+xcb_input_raw_key_press_axisvalues_length (const xcb_input_raw_key_press_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_key_press_axisvalues_iterator (const xcb_input_raw_key_press_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_raw_key_press_axisvalues_raw (const xcb_input_raw_key_press_event_t *R);
+
+int
+xcb_input_raw_key_press_axisvalues_raw_length (const xcb_input_raw_key_press_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_key_press_axisvalues_raw_iterator (const xcb_input_raw_key_press_event_t *R);
+
+int
+xcb_input_raw_key_release_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_raw_button_press_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_raw_button_press_valuator_mask (const xcb_input_raw_button_press_event_t *R);
+
+int
+xcb_input_raw_button_press_valuator_mask_length (const xcb_input_raw_button_press_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_raw_button_press_valuator_mask_end (const xcb_input_raw_button_press_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_raw_button_press_axisvalues (const xcb_input_raw_button_press_event_t *R);
+
+int
+xcb_input_raw_button_press_axisvalues_length (const xcb_input_raw_button_press_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_button_press_axisvalues_iterator (const xcb_input_raw_button_press_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_raw_button_press_axisvalues_raw (const xcb_input_raw_button_press_event_t *R);
+
+int
+xcb_input_raw_button_press_axisvalues_raw_length (const xcb_input_raw_button_press_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_button_press_axisvalues_raw_iterator (const xcb_input_raw_button_press_event_t *R);
+
+int
+xcb_input_raw_button_release_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_raw_motion_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_touch_begin_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_touch_begin_button_mask (const xcb_input_touch_begin_event_t *R);
+
+int
+xcb_input_touch_begin_button_mask_length (const xcb_input_touch_begin_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_touch_begin_button_mask_end (const xcb_input_touch_begin_event_t *R);
+
+uint32_t *
+xcb_input_touch_begin_valuator_mask (const xcb_input_touch_begin_event_t *R);
+
+int
+xcb_input_touch_begin_valuator_mask_length (const xcb_input_touch_begin_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_touch_begin_valuator_mask_end (const xcb_input_touch_begin_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_touch_begin_axisvalues (const xcb_input_touch_begin_event_t *R);
+
+int
+xcb_input_touch_begin_axisvalues_length (const xcb_input_touch_begin_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_touch_begin_axisvalues_iterator (const xcb_input_touch_begin_event_t *R);
+
+int
+xcb_input_touch_update_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_touch_end_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_raw_touch_begin_sizeof (const void *_buffer);
+
+uint32_t *
+xcb_input_raw_touch_begin_valuator_mask (const xcb_input_raw_touch_begin_event_t *R);
+
+int
+xcb_input_raw_touch_begin_valuator_mask_length (const xcb_input_raw_touch_begin_event_t *R);
+
+xcb_generic_iterator_t
+xcb_input_raw_touch_begin_valuator_mask_end (const xcb_input_raw_touch_begin_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_raw_touch_begin_axisvalues (const xcb_input_raw_touch_begin_event_t *R);
+
+int
+xcb_input_raw_touch_begin_axisvalues_length (const xcb_input_raw_touch_begin_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_touch_begin_axisvalues_iterator (const xcb_input_raw_touch_begin_event_t *R);
+
+xcb_input_fp3232_t *
+xcb_input_raw_touch_begin_axisvalues_raw (const xcb_input_raw_touch_begin_event_t *R);
+
+int
+xcb_input_raw_touch_begin_axisvalues_raw_length (const xcb_input_raw_touch_begin_event_t *R);
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_touch_begin_axisvalues_raw_iterator (const xcb_input_raw_touch_begin_event_t *R);
+
+int
+xcb_input_raw_touch_update_sizeof (const void *_buffer /**< */);
+
+int
+xcb_input_raw_touch_end_sizeof (const void *_buffer /**< */);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/**
+ * @}
+ */
diff --git a/src/3rdparty/xcb/libxcb/randr.c b/src/3rdparty/xcb/libxcb/randr.c
index 1956ee033e..0232af802f 100644
--- a/src/3rdparty/xcb/libxcb/randr.c
+++ b/src/3rdparty/xcb/libxcb/randr.c
@@ -3,10 +3,17 @@
* Edit at your peril.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <stddef.h> /* for offsetof() */
#include "xcbext.h"
#include "randr.h"
+
+#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)
#include "xproto.h"
#include "render.h"
@@ -164,6 +171,35 @@ xcb_randr_screen_size_end (xcb_randr_screen_size_iterator_t i /**< */)
return ret;
}
+int
+xcb_randr_refresh_rates_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_refresh_rates_t *_aux = (xcb_randr_refresh_rates_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_refresh_rates_t);
+ xcb_tmp += xcb_block_len;
+ /* rates */
+ xcb_block_len += _aux->nRates * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -230,10 +266,11 @@ void
xcb_randr_refresh_rates_next (xcb_randr_refresh_rates_iterator_t *i /**< */)
{
xcb_randr_refresh_rates_t *R = i->data;
- xcb_generic_iterator_t child = xcb_randr_refresh_rates_rates_end(R);
+ xcb_generic_iterator_t child;
+ child.data = (xcb_randr_refresh_rates_t *)(((char *)R) + xcb_randr_refresh_rates_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
--i->rem;
i->data = (xcb_randr_refresh_rates_t *) child.data;
- i->index = child.index;
}
@@ -293,6 +330,7 @@ xcb_randr_query_version (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -332,6 +370,7 @@ xcb_randr_query_version_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -404,6 +443,7 @@ xcb_randr_set_screen_config (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -456,6 +496,7 @@ xcb_randr_set_screen_config_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -516,6 +557,7 @@ xcb_randr_select_input_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -556,10 +598,57 @@ xcb_randr_select_input (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_randr_get_screen_info_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_get_screen_info_reply_t *_aux = (xcb_randr_get_screen_info_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_randr_get_screen_info_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* sizes */
+ xcb_block_len += _aux->nSizes * sizeof(xcb_randr_screen_size_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_screen_size_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* rates */
+ for(i=0; i<(_aux->nInfo - _aux->nSizes); i++) {
+ xcb_tmp_len = xcb_randr_refresh_rates_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_randr_refresh_rates_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -592,6 +681,7 @@ xcb_randr_get_screen_info (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -628,6 +718,7 @@ xcb_randr_get_screen_info_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -773,6 +864,7 @@ xcb_randr_get_screen_size_range (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -809,6 +901,7 @@ xcb_randr_get_screen_size_range_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -877,6 +970,7 @@ xcb_randr_set_screen_size_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -925,6 +1019,7 @@ xcb_randr_set_screen_size (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -967,6 +1062,71 @@ xcb_randr_mode_info_end (xcb_randr_mode_info_iterator_t i /**< */)
return ret;
}
+int
+xcb_randr_get_screen_resources_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_get_screen_resources_reply_t *_aux = (xcb_randr_get_screen_resources_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_get_screen_resources_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* crtcs */
+ xcb_block_len += _aux->num_crtcs * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_crtc_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* outputs */
+ xcb_block_len += _aux->num_outputs * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_output_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* modes */
+ xcb_block_len += _aux->num_modes * sizeof(xcb_randr_mode_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_mode_info_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* names */
+ xcb_block_len += _aux->names_len * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -999,6 +1159,7 @@ xcb_randr_get_screen_resources (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1035,6 +1196,7 @@ xcb_randr_get_screen_resources_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1273,6 +1435,71 @@ xcb_randr_get_screen_resources_reply (xcb_connection_t *
return (xcb_randr_get_screen_resources_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_get_output_info_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_get_output_info_reply_t *_aux = (xcb_randr_get_output_info_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_get_output_info_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* crtcs */
+ xcb_block_len += _aux->num_crtcs * sizeof(xcb_randr_output_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_crtc_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* modes */
+ xcb_block_len += _aux->num_modes * sizeof(xcb_randr_output_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_mode_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* clones */
+ xcb_block_len += _aux->num_clones * sizeof(xcb_randr_output_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_output_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* name */
+ xcb_block_len += _aux->name_len * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1308,6 +1535,7 @@ xcb_randr_get_output_info (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1347,6 +1575,7 @@ xcb_randr_get_output_info_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1585,6 +1814,35 @@ xcb_randr_get_output_info_reply (xcb_connection_t *c /**< */
return (xcb_randr_get_output_info_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_list_output_properties_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_list_output_properties_reply_t *_aux = (xcb_randr_list_output_properties_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_list_output_properties_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* atoms */
+ xcb_block_len += _aux->num_atoms * sizeof(xcb_atom_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_atom_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1617,6 +1875,7 @@ xcb_randr_list_output_properties (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1653,6 +1912,7 @@ xcb_randr_list_output_properties_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1729,6 +1989,35 @@ xcb_randr_list_output_properties_reply (xcb_connection_t
return (xcb_randr_list_output_properties_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_query_output_property_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_query_output_property_reply_t *_aux = (xcb_randr_query_output_property_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_query_output_property_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* validValues */
+ xcb_block_len += _aux->length * sizeof(int32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1764,6 +2053,7 @@ xcb_randr_query_output_property (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1803,6 +2093,7 @@ xcb_randr_query_output_property_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1879,6 +2170,35 @@ xcb_randr_query_output_property_reply (xcb_connection_t
return (xcb_randr_query_output_property_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_configure_output_property_sizeof (const void *_buffer /**< */,
+ uint32_t values_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_configure_output_property_request_t);
+ xcb_tmp += xcb_block_len;
+ /* values */
+ xcb_block_len += values_len * sizeof(int32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1925,10 +2245,12 @@ xcb_randr_configure_output_property_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* int32_t values */
xcb_parts[4].iov_base = (char *) values;
xcb_parts[4].iov_len = values_len * sizeof(int32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1979,14 +2301,45 @@ xcb_randr_configure_output_property (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* int32_t values */
xcb_parts[4].iov_base = (char *) values;
xcb_parts[4].iov_len = values_len * sizeof(int32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_randr_change_output_property_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_change_output_property_request_t *_aux = (xcb_randr_change_output_property_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_change_output_property_request_t);
+ xcb_tmp += xcb_block_len;
+ /* data */
+ xcb_block_len += ((_aux->num_units * _aux->format) / 8) * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2037,10 +2390,12 @@ xcb_randr_change_output_property_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* void data */
xcb_parts[4].iov_base = (char *) data;
xcb_parts[4].iov_len = ((num_units * format) / 8) * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2095,10 +2450,12 @@ xcb_randr_change_output_property (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* void data */
xcb_parts[4].iov_base = (char *) data;
xcb_parts[4].iov_len = ((num_units * format) / 8) * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2138,6 +2495,7 @@ xcb_randr_delete_output_property_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2177,10 +2535,40 @@ xcb_randr_delete_output_property (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_randr_get_output_property_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_get_output_property_reply_t *_aux = (xcb_randr_get_output_property_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_get_output_property_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* data */
+ xcb_block_len += (_aux->num_items * (_aux->format / 8)) * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2232,6 +2620,7 @@ xcb_randr_get_output_property (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2287,6 +2676,7 @@ xcb_randr_get_output_property_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2363,6 +2753,35 @@ xcb_randr_get_output_property_reply (xcb_connection_t *c
return (xcb_randr_get_output_property_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_create_mode_sizeof (const void *_buffer /**< */,
+ uint32_t name_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_create_mode_request_t);
+ xcb_tmp += xcb_block_len;
+ /* name */
+ xcb_block_len += name_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2402,10 +2821,12 @@ xcb_randr_create_mode (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char name */
xcb_parts[4].iov_base = (char *) name;
xcb_parts[4].iov_len = name_len * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2449,10 +2870,12 @@ xcb_randr_create_mode_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char name */
xcb_parts[4].iov_base = (char *) name;
xcb_parts[4].iov_len = name_len * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2509,6 +2932,7 @@ xcb_randr_destroy_mode_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2545,6 +2969,7 @@ xcb_randr_destroy_mode (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2584,6 +3009,7 @@ xcb_randr_add_output_mode_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2623,6 +3049,7 @@ xcb_randr_add_output_mode (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2662,6 +3089,7 @@ xcb_randr_delete_output_mode_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2701,10 +3129,52 @@ xcb_randr_delete_output_mode (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_randr_get_crtc_info_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_get_crtc_info_reply_t *_aux = (xcb_randr_get_crtc_info_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_get_crtc_info_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* outputs */
+ xcb_block_len += _aux->num_outputs * sizeof(xcb_randr_output_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_output_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* possible */
+ xcb_block_len += _aux->num_possible_outputs * sizeof(xcb_randr_output_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_output_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2740,6 +3210,7 @@ xcb_randr_get_crtc_info (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2779,6 +3250,7 @@ xcb_randr_get_crtc_info_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2909,6 +3381,35 @@ xcb_randr_get_crtc_info_reply (xcb_connection_t *c /**< */,
return (xcb_randr_get_crtc_info_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_set_crtc_config_sizeof (const void *_buffer /**< */,
+ uint32_t outputs_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_set_crtc_config_request_t);
+ xcb_tmp += xcb_block_len;
+ /* outputs */
+ xcb_block_len += outputs_len * sizeof(xcb_randr_output_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_output_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2964,10 +3465,12 @@ xcb_randr_set_crtc_config (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_randr_output_t outputs */
xcb_parts[4].iov_base = (char *) outputs;
xcb_parts[4].iov_len = outputs_len * sizeof(xcb_timestamp_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3027,10 +3530,12 @@ xcb_randr_set_crtc_config_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_randr_output_t outputs */
xcb_parts[4].iov_base = (char *) outputs;
xcb_parts[4].iov_len = outputs_len * sizeof(xcb_timestamp_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3087,6 +3592,7 @@ xcb_randr_get_crtc_gamma_size (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3123,6 +3629,7 @@ xcb_randr_get_crtc_gamma_size_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3147,6 +3654,59 @@ xcb_randr_get_crtc_gamma_size_reply (xcb_connection_t *c
return (xcb_randr_get_crtc_gamma_size_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_get_crtc_gamma_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_get_crtc_gamma_reply_t *_aux = (xcb_randr_get_crtc_gamma_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_get_crtc_gamma_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* red */
+ xcb_block_len += _aux->size * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* green */
+ xcb_block_len += _aux->size * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* blue */
+ xcb_block_len += _aux->size * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3179,6 +3739,7 @@ xcb_randr_get_crtc_gamma (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3215,6 +3776,7 @@ xcb_randr_get_crtc_gamma_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3399,6 +3961,59 @@ xcb_randr_get_crtc_gamma_reply (xcb_connection_t *c /**< */,
return (xcb_randr_get_crtc_gamma_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_set_crtc_gamma_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_set_crtc_gamma_request_t *_aux = (xcb_randr_set_crtc_gamma_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_set_crtc_gamma_request_t);
+ xcb_tmp += xcb_block_len;
+ /* red */
+ xcb_block_len += _aux->size * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* green */
+ xcb_block_len += _aux->size * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* blue */
+ xcb_block_len += _aux->size * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3441,18 +4056,22 @@ xcb_randr_set_crtc_gamma_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint16_t red */
xcb_parts[4].iov_base = (char *) red;
xcb_parts[4].iov_len = size * sizeof(uint16_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* uint16_t green */
xcb_parts[6].iov_base = (char *) green;
xcb_parts[6].iov_len = size * sizeof(uint16_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+ /* uint16_t blue */
xcb_parts[8].iov_base = (char *) blue;
xcb_parts[8].iov_len = size * sizeof(uint16_t);
xcb_parts[9].iov_base = 0;
xcb_parts[9].iov_len = -xcb_parts[8].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3499,22 +4118,91 @@ xcb_randr_set_crtc_gamma (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint16_t red */
xcb_parts[4].iov_base = (char *) red;
xcb_parts[4].iov_len = size * sizeof(uint16_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* uint16_t green */
xcb_parts[6].iov_base = (char *) green;
xcb_parts[6].iov_len = size * sizeof(uint16_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+ /* uint16_t blue */
xcb_parts[8].iov_base = (char *) blue;
xcb_parts[8].iov_len = size * sizeof(uint16_t);
xcb_parts[9].iov_base = 0;
xcb_parts[9].iov_len = -xcb_parts[8].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_randr_get_screen_resources_current_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_get_screen_resources_current_reply_t *_aux = (xcb_randr_get_screen_resources_current_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_get_screen_resources_current_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* crtcs */
+ xcb_block_len += _aux->num_crtcs * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_crtc_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* outputs */
+ xcb_block_len += _aux->num_outputs * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_output_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* modes */
+ xcb_block_len += _aux->num_modes * sizeof(xcb_randr_mode_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_randr_mode_info_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* names */
+ xcb_block_len += _aux->names_len * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3547,6 +4235,7 @@ xcb_randr_get_screen_resources_current (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3583,6 +4272,7 @@ xcb_randr_get_screen_resources_current_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3821,6 +4511,48 @@ xcb_randr_get_screen_resources_current_reply (xcb_connection_t
return (xcb_randr_get_screen_resources_current_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_randr_set_crtc_transform_sizeof (const void *_buffer /**< */,
+ uint32_t filter_params_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_set_crtc_transform_request_t *_aux = (xcb_randr_set_crtc_transform_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_set_crtc_transform_request_t);
+ xcb_tmp += xcb_block_len;
+ /* filter_name */
+ xcb_block_len += _aux->filter_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* filter_params */
+ xcb_block_len += filter_params_len * sizeof(xcb_render_fixed_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_fixed_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3866,14 +4598,17 @@ xcb_randr_set_crtc_transform_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char filter_name */
xcb_parts[4].iov_base = (char *) filter_name;
xcb_parts[4].iov_len = filter_len * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_fixed_t filter_params */
xcb_parts[6].iov_base = (char *) filter_params;
xcb_parts[6].iov_len = filter_params_len * sizeof(xcb_render_fixed_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3923,18 +4658,86 @@ xcb_randr_set_crtc_transform (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char filter_name */
xcb_parts[4].iov_base = (char *) filter_name;
xcb_parts[4].iov_len = filter_len * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_fixed_t filter_params */
xcb_parts[6].iov_base = (char *) filter_params;
xcb_parts[6].iov_len = filter_params_len * sizeof(xcb_render_fixed_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_randr_get_crtc_transform_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_randr_get_crtc_transform_reply_t *_aux = (xcb_randr_get_crtc_transform_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_randr_get_crtc_transform_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* pending_filter_name */
+ xcb_block_len += _aux->pending_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* pending_params */
+ xcb_block_len += _aux->pending_nparams * sizeof(xcb_render_fixed_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_fixed_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* current_filter_name */
+ xcb_block_len += _aux->current_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* current_params */
+ xcb_block_len += _aux->current_nparams * sizeof(xcb_render_fixed_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_fixed_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3967,6 +4770,7 @@ xcb_randr_get_crtc_transform (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4003,6 +4807,7 @@ xcb_randr_get_crtc_transform_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4273,6 +5078,7 @@ xcb_randr_get_panning (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4309,6 +5115,7 @@ xcb_randr_get_panning_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4404,6 +5211,7 @@ xcb_randr_set_panning (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4479,6 +5287,7 @@ xcb_randr_set_panning_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4538,6 +5347,7 @@ xcb_randr_set_output_primary_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4577,6 +5387,7 @@ xcb_randr_set_output_primary (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4613,6 +5424,7 @@ xcb_randr_get_output_primary (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4649,6 +5461,7 @@ xcb_randr_get_output_primary_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
diff --git a/src/3rdparty/xcb/libxcb/render.c b/src/3rdparty/xcb/libxcb/render.c
index b251f8814c..7e5379cfcf 100644
--- a/src/3rdparty/xcb/libxcb/render.c
+++ b/src/3rdparty/xcb/libxcb/render.c
@@ -3,10 +3,17 @@
* Edit at your peril.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <stddef.h> /* for offsetof() */
#include "xcbext.h"
#include "render.h"
+
+#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)
#include "xproto.h"
xcb_extension_t xcb_render_id = { "RENDER", 0 };
@@ -315,6 +322,35 @@ xcb_render_pictvisual_end (xcb_render_pictvisual_iterator_t i /**< */)
return ret;
}
+int
+xcb_render_pictdepth_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_pictdepth_t *_aux = (xcb_render_pictdepth_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_pictdepth_t);
+ xcb_tmp += xcb_block_len;
+ /* visuals */
+ xcb_block_len += _aux->num_visuals * sizeof(xcb_render_pictvisual_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_pictvisual_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -381,10 +417,11 @@ void
xcb_render_pictdepth_next (xcb_render_pictdepth_iterator_t *i /**< */)
{
xcb_render_pictdepth_t *R = i->data;
- xcb_generic_iterator_t child = xcb_render_pictvisual_end(xcb_render_pictdepth_visuals_iterator(R));
+ xcb_generic_iterator_t child;
+ child.data = (xcb_render_pictdepth_t *)(((char *)R) + xcb_render_pictdepth_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
--i->rem;
i->data = (xcb_render_pictdepth_t *) child.data;
- i->index = child.index;
}
@@ -409,6 +446,40 @@ xcb_render_pictdepth_end (xcb_render_pictdepth_iterator_t i /**< */)
return ret;
}
+int
+xcb_render_pictscreen_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_pictscreen_t *_aux = (xcb_render_pictscreen_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_render_pictscreen_t);
+ xcb_tmp += xcb_block_len;
+ /* depths */
+ for(i=0; i<_aux->num_depths; i++) {
+ xcb_tmp_len = xcb_render_pictdepth_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_render_pictdepth_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -459,10 +530,11 @@ void
xcb_render_pictscreen_next (xcb_render_pictscreen_iterator_t *i /**< */)
{
xcb_render_pictscreen_t *R = i->data;
- xcb_generic_iterator_t child = xcb_render_pictdepth_end(xcb_render_pictscreen_depths_iterator(R));
+ xcb_generic_iterator_t child;
+ child.data = (xcb_render_pictscreen_t *)(((char *)R) + xcb_render_pictscreen_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
--i->rem;
i->data = (xcb_render_pictscreen_t *) child.data;
- i->index = child.index;
}
@@ -788,6 +860,7 @@ xcb_render_query_version (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -827,6 +900,7 @@ xcb_render_query_version_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -851,6 +925,64 @@ xcb_render_query_version_reply (xcb_connection_t *c /**< */,
return (xcb_render_query_version_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_render_query_pict_formats_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_query_pict_formats_reply_t *_aux = (xcb_render_query_pict_formats_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_render_query_pict_formats_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* formats */
+ xcb_block_len += _aux->num_formats * sizeof(xcb_render_pictforminfo_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_pictforminfo_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* screens */
+ for(i=0; i<_aux->num_screens; i++) {
+ xcb_tmp_len = xcb_render_pictscreen_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_render_pictscreen_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* subpixels */
+ xcb_block_len += _aux->num_subpixel * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -880,6 +1012,7 @@ xcb_render_query_pict_formats (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -913,6 +1046,7 @@ xcb_render_query_pict_formats_unchecked (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1080,6 +1214,35 @@ xcb_render_query_pict_formats_reply (xcb_connection_t *c
return (xcb_render_query_pict_formats_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_render_query_pict_index_values_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_query_pict_index_values_reply_t *_aux = (xcb_render_query_pict_index_values_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_query_pict_index_values_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* values */
+ xcb_block_len += _aux->num_values * sizeof(xcb_render_indexvalue_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_indexvalue_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1112,6 +1275,7 @@ xcb_render_query_pict_index_values (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1148,6 +1312,7 @@ xcb_render_query_pict_index_values_unchecked (xcb_connection_t *c /**< *
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1224,6 +1389,35 @@ xcb_render_query_pict_index_values_reply (xcb_connection_t
return (xcb_render_query_pict_index_values_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_render_create_picture_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_create_picture_request_t *_aux = (xcb_render_create_picture_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_create_picture_request_t);
+ xcb_tmp += xcb_block_len;
+ /* value_list */
+ xcb_block_len += xcb_popcount(_aux->value_mask) * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1267,10 +1461,12 @@ xcb_render_create_picture_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t value_list */
xcb_parts[4].iov_base = (char *) value_list;
xcb_parts[4].iov_len = xcb_popcount(value_mask) * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1318,14 +1514,45 @@ xcb_render_create_picture (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t value_list */
xcb_parts[4].iov_base = (char *) value_list;
xcb_parts[4].iov_len = xcb_popcount(value_mask) * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_change_picture_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_change_picture_request_t *_aux = (xcb_render_change_picture_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_change_picture_request_t);
+ xcb_tmp += xcb_block_len;
+ /* value_list */
+ xcb_block_len += xcb_popcount(_aux->value_mask) * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1363,10 +1590,12 @@ xcb_render_change_picture_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t value_list */
xcb_parts[4].iov_base = (char *) value_list;
xcb_parts[4].iov_len = xcb_popcount(value_mask) * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1408,14 +1637,45 @@ xcb_render_change_picture (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t value_list */
xcb_parts[4].iov_base = (char *) value_list;
xcb_parts[4].iov_len = xcb_popcount(value_mask) * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_set_picture_clip_rectangles_sizeof (const void *_buffer /**< */,
+ uint32_t rectangles_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_set_picture_clip_rectangles_request_t);
+ xcb_tmp += xcb_block_len;
+ /* rectangles */
+ xcb_block_len += rectangles_len * sizeof(xcb_rectangle_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_rectangle_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1458,10 +1718,12 @@ xcb_render_set_picture_clip_rectangles_checked (xcb_connection_t *c /**< *
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rectangles */
xcb_parts[4].iov_base = (char *) rectangles;
xcb_parts[4].iov_len = rectangles_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1508,10 +1770,12 @@ xcb_render_set_picture_clip_rectangles (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rectangles */
xcb_parts[4].iov_base = (char *) rectangles;
xcb_parts[4].iov_len = rectangles_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1548,6 +1812,7 @@ xcb_render_free_picture_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1584,6 +1849,7 @@ xcb_render_free_picture (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1654,6 +1920,7 @@ xcb_render_composite_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1724,10 +1991,40 @@ xcb_render_composite (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_trapezoids_sizeof (const void *_buffer /**< */,
+ uint32_t traps_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_trapezoids_request_t);
+ xcb_tmp += xcb_block_len;
+ /* traps */
+ xcb_block_len += traps_len * sizeof(xcb_render_trapezoid_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_trapezoid_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1780,10 +2077,12 @@ xcb_render_trapezoids_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_trapezoid_t traps */
xcb_parts[4].iov_base = (char *) traps;
xcb_parts[4].iov_len = traps_len * sizeof(xcb_render_trapezoid_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1840,14 +2139,45 @@ xcb_render_trapezoids (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_trapezoid_t traps */
xcb_parts[4].iov_base = (char *) traps;
xcb_parts[4].iov_len = traps_len * sizeof(xcb_render_trapezoid_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_triangles_sizeof (const void *_buffer /**< */,
+ uint32_t triangles_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_triangles_request_t);
+ xcb_tmp += xcb_block_len;
+ /* triangles */
+ xcb_block_len += triangles_len * sizeof(xcb_render_triangle_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_triangle_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1900,10 +2230,12 @@ xcb_render_triangles_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_triangle_t triangles */
xcb_parts[4].iov_base = (char *) triangles;
xcb_parts[4].iov_len = triangles_len * sizeof(xcb_render_triangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1960,14 +2292,45 @@ xcb_render_triangles (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_triangle_t triangles */
xcb_parts[4].iov_base = (char *) triangles;
xcb_parts[4].iov_len = triangles_len * sizeof(xcb_render_triangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_tri_strip_sizeof (const void *_buffer /**< */,
+ uint32_t points_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_tri_strip_request_t);
+ xcb_tmp += xcb_block_len;
+ /* points */
+ xcb_block_len += points_len * sizeof(xcb_render_pointfix_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_pointfix_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2020,10 +2383,12 @@ xcb_render_tri_strip_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_pointfix_t points */
xcb_parts[4].iov_base = (char *) points;
xcb_parts[4].iov_len = points_len * sizeof(xcb_render_pointfix_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2080,14 +2445,45 @@ xcb_render_tri_strip (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_pointfix_t points */
xcb_parts[4].iov_base = (char *) points;
xcb_parts[4].iov_len = points_len * sizeof(xcb_render_pointfix_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_tri_fan_sizeof (const void *_buffer /**< */,
+ uint32_t points_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_tri_fan_request_t);
+ xcb_tmp += xcb_block_len;
+ /* points */
+ xcb_block_len += points_len * sizeof(xcb_render_pointfix_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_pointfix_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2140,10 +2536,12 @@ xcb_render_tri_fan_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_pointfix_t points */
xcb_parts[4].iov_base = (char *) points;
xcb_parts[4].iov_len = points_len * sizeof(xcb_render_pointfix_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2200,10 +2598,12 @@ xcb_render_tri_fan (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_pointfix_t points */
xcb_parts[4].iov_base = (char *) points;
xcb_parts[4].iov_len = points_len * sizeof(xcb_render_pointfix_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2243,6 +2643,7 @@ xcb_render_create_glyph_set_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2282,6 +2683,7 @@ xcb_render_create_glyph_set (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2321,6 +2723,7 @@ xcb_render_reference_glyph_set_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2360,6 +2763,7 @@ xcb_render_reference_glyph_set (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2396,6 +2800,7 @@ xcb_render_free_glyph_set_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2432,10 +2837,65 @@ xcb_render_free_glyph_set (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_add_glyphs_sizeof (const void *_buffer /**< */,
+ uint32_t data_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_add_glyphs_request_t *_aux = (xcb_render_add_glyphs_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_add_glyphs_request_t);
+ xcb_tmp += xcb_block_len;
+ /* glyphids */
+ xcb_block_len += _aux->glyphs_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* glyphs */
+ xcb_block_len += _aux->glyphs_len * sizeof(xcb_render_glyphinfo_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_glyphinfo_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* data */
+ xcb_block_len += data_len * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2479,18 +2939,22 @@ xcb_render_add_glyphs_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t glyphids */
xcb_parts[4].iov_base = (char *) glyphids;
xcb_parts[4].iov_len = glyphs_len * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_glyphinfo_t glyphs */
xcb_parts[6].iov_base = (char *) glyphs;
xcb_parts[6].iov_len = glyphs_len * sizeof(xcb_render_glyphinfo_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+ /* uint8_t data */
xcb_parts[8].iov_base = (char *) data;
xcb_parts[8].iov_len = data_len * sizeof(uint8_t);
xcb_parts[9].iov_base = 0;
xcb_parts[9].iov_len = -xcb_parts[8].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2538,22 +3002,55 @@ xcb_render_add_glyphs (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t glyphids */
xcb_parts[4].iov_base = (char *) glyphids;
xcb_parts[4].iov_len = glyphs_len * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_glyphinfo_t glyphs */
xcb_parts[6].iov_base = (char *) glyphs;
xcb_parts[6].iov_len = glyphs_len * sizeof(xcb_render_glyphinfo_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+ /* uint8_t data */
xcb_parts[8].iov_base = (char *) data;
xcb_parts[8].iov_len = data_len * sizeof(uint8_t);
xcb_parts[9].iov_base = 0;
xcb_parts[9].iov_len = -xcb_parts[8].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_free_glyphs_sizeof (const void *_buffer /**< */,
+ uint32_t glyphs_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_free_glyphs_request_t);
+ xcb_tmp += xcb_block_len;
+ /* glyphs */
+ xcb_block_len += glyphs_len * sizeof(xcb_render_glyph_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_glyph_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2590,10 +3087,12 @@ xcb_render_free_glyphs_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_glyph_t glyphs */
xcb_parts[4].iov_base = (char *) glyphs;
xcb_parts[4].iov_len = glyphs_len * sizeof(xcb_render_glyph_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2634,14 +3133,45 @@ xcb_render_free_glyphs (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_glyph_t glyphs */
xcb_parts[4].iov_base = (char *) glyphs;
xcb_parts[4].iov_len = glyphs_len * sizeof(xcb_render_glyph_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_composite_glyphs_8_sizeof (const void *_buffer /**< */,
+ uint32_t glyphcmds_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_composite_glyphs_8_request_t);
+ xcb_tmp += xcb_block_len;
+ /* glyphcmds */
+ xcb_block_len += glyphcmds_len * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2697,10 +3227,12 @@ xcb_render_composite_glyphs_8_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t glyphcmds */
xcb_parts[4].iov_base = (char *) glyphcmds;
xcb_parts[4].iov_len = glyphcmds_len * sizeof(uint8_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2760,14 +3292,45 @@ xcb_render_composite_glyphs_8 (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t glyphcmds */
xcb_parts[4].iov_base = (char *) glyphcmds;
xcb_parts[4].iov_len = glyphcmds_len * sizeof(uint8_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_composite_glyphs_16_sizeof (const void *_buffer /**< */,
+ uint32_t glyphcmds_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_composite_glyphs_16_request_t);
+ xcb_tmp += xcb_block_len;
+ /* glyphcmds */
+ xcb_block_len += glyphcmds_len * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2823,10 +3386,12 @@ xcb_render_composite_glyphs_16_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t glyphcmds */
xcb_parts[4].iov_base = (char *) glyphcmds;
xcb_parts[4].iov_len = glyphcmds_len * sizeof(uint8_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2886,14 +3451,45 @@ xcb_render_composite_glyphs_16 (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t glyphcmds */
xcb_parts[4].iov_base = (char *) glyphcmds;
xcb_parts[4].iov_len = glyphcmds_len * sizeof(uint8_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_composite_glyphs_32_sizeof (const void *_buffer /**< */,
+ uint32_t glyphcmds_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_composite_glyphs_32_request_t);
+ xcb_tmp += xcb_block_len;
+ /* glyphcmds */
+ xcb_block_len += glyphcmds_len * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2949,10 +3545,12 @@ xcb_render_composite_glyphs_32_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t glyphcmds */
xcb_parts[4].iov_base = (char *) glyphcmds;
xcb_parts[4].iov_len = glyphcmds_len * sizeof(uint8_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3012,14 +3610,45 @@ xcb_render_composite_glyphs_32 (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t glyphcmds */
xcb_parts[4].iov_base = (char *) glyphcmds;
xcb_parts[4].iov_len = glyphcmds_len * sizeof(uint8_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_fill_rectangles_sizeof (const void *_buffer /**< */,
+ uint32_t rects_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_fill_rectangles_request_t);
+ xcb_tmp += xcb_block_len;
+ /* rects */
+ xcb_block_len += rects_len * sizeof(xcb_rectangle_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_rectangle_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3063,10 +3692,12 @@ xcb_render_fill_rectangles_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rects */
xcb_parts[4].iov_base = (char *) rects;
xcb_parts[4].iov_len = rects_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3114,10 +3745,12 @@ xcb_render_fill_rectangles (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rects */
xcb_parts[4].iov_base = (char *) rects;
xcb_parts[4].iov_len = rects_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3163,6 +3796,7 @@ xcb_render_create_cursor_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3208,6 +3842,7 @@ xcb_render_create_cursor (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3285,6 +3920,7 @@ xcb_render_set_picture_transform_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3324,10 +3960,57 @@ xcb_render_set_picture_transform (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_query_filters_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_query_filters_reply_t *_aux = (xcb_render_query_filters_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_render_query_filters_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* aliases */
+ xcb_block_len += _aux->num_aliases * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* filters */
+ for(i=0; i<_aux->num_filters; i++) {
+ xcb_tmp_len = xcb_str_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_str_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3360,6 +4043,7 @@ xcb_render_query_filters (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3396,6 +4080,7 @@ xcb_render_query_filters_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3509,6 +4194,48 @@ xcb_render_query_filters_reply (xcb_connection_t *c /**< */,
return (xcb_render_query_filters_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_render_set_picture_filter_sizeof (const void *_buffer /**< */,
+ uint32_t values_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_set_picture_filter_request_t *_aux = (xcb_render_set_picture_filter_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_set_picture_filter_request_t);
+ xcb_tmp += xcb_block_len;
+ /* filter */
+ xcb_block_len += _aux->filter_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* values */
+ xcb_block_len += values_len * sizeof(xcb_render_fixed_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_fixed_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3551,14 +4278,17 @@ xcb_render_set_picture_filter_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char filter */
xcb_parts[4].iov_base = (char *) filter;
xcb_parts[4].iov_len = filter_len * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_fixed_t values */
xcb_parts[6].iov_base = (char *) values;
xcb_parts[6].iov_len = values_len * sizeof(xcb_render_fixed_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3605,14 +4335,17 @@ xcb_render_set_picture_filter (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char filter */
xcb_parts[4].iov_base = (char *) filter;
xcb_parts[4].iov_len = filter_len * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_fixed_t values */
xcb_parts[6].iov_base = (char *) values;
xcb_parts[6].iov_len = values_len * sizeof(xcb_render_fixed_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3655,6 +4388,35 @@ xcb_render_animcursorelt_end (xcb_render_animcursorelt_iterator_t i /**< */)
return ret;
}
+int
+xcb_render_create_anim_cursor_sizeof (const void *_buffer /**< */,
+ uint32_t cursors_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_create_anim_cursor_request_t);
+ xcb_tmp += xcb_block_len;
+ /* cursors */
+ xcb_block_len += cursors_len * sizeof(xcb_render_animcursorelt_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_animcursorelt_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3691,10 +4453,12 @@ xcb_render_create_anim_cursor_checked (xcb_connection_t *c /**<
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_animcursorelt_t cursors */
xcb_parts[4].iov_base = (char *) cursors;
xcb_parts[4].iov_len = cursors_len * sizeof(xcb_render_animcursorelt_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3735,10 +4499,12 @@ xcb_render_create_anim_cursor (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_animcursorelt_t cursors */
xcb_parts[4].iov_base = (char *) cursors;
xcb_parts[4].iov_len = cursors_len * sizeof(xcb_render_animcursorelt_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3819,6 +4585,35 @@ xcb_render_trap_end (xcb_render_trap_iterator_t i /**< */)
return ret;
}
+int
+xcb_render_add_traps_sizeof (const void *_buffer /**< */,
+ uint32_t traps_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_add_traps_request_t);
+ xcb_tmp += xcb_block_len;
+ /* traps */
+ xcb_block_len += traps_len * sizeof(xcb_render_trap_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_trap_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -3861,10 +4656,12 @@ xcb_render_add_traps_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_trap_t traps */
xcb_parts[4].iov_base = (char *) traps;
xcb_parts[4].iov_len = traps_len * sizeof(xcb_render_trap_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3911,10 +4708,12 @@ xcb_render_add_traps (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_trap_t traps */
xcb_parts[4].iov_base = (char *) traps;
xcb_parts[4].iov_len = traps_len * sizeof(xcb_render_trap_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3954,6 +4753,7 @@ xcb_render_create_solid_fill_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -3993,10 +4793,52 @@ xcb_render_create_solid_fill (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_create_linear_gradient_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_create_linear_gradient_request_t *_aux = (xcb_render_create_linear_gradient_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_create_linear_gradient_request_t);
+ xcb_tmp += xcb_block_len;
+ /* stops */
+ xcb_block_len += _aux->num_stops * sizeof(xcb_render_fixed_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_fixed_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* colors */
+ xcb_block_len += _aux->num_stops * sizeof(xcb_render_color_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_color_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -4042,14 +4884,17 @@ xcb_render_create_linear_gradient_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_fixed_t stops */
xcb_parts[4].iov_base = (char *) stops;
xcb_parts[4].iov_len = num_stops * sizeof(xcb_render_fixed_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_color_t colors */
xcb_parts[6].iov_base = (char *) colors;
xcb_parts[6].iov_len = num_stops * sizeof(xcb_render_color_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4099,18 +4944,62 @@ xcb_render_create_linear_gradient (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_fixed_t stops */
xcb_parts[4].iov_base = (char *) stops;
xcb_parts[4].iov_len = num_stops * sizeof(xcb_render_fixed_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_color_t colors */
xcb_parts[6].iov_base = (char *) colors;
xcb_parts[6].iov_len = num_stops * sizeof(xcb_render_color_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_create_radial_gradient_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_create_radial_gradient_request_t *_aux = (xcb_render_create_radial_gradient_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_create_radial_gradient_request_t);
+ xcb_tmp += xcb_block_len;
+ /* stops */
+ xcb_block_len += _aux->num_stops * sizeof(xcb_render_fixed_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_fixed_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* colors */
+ xcb_block_len += _aux->num_stops * sizeof(xcb_render_color_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_color_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -4162,14 +5051,17 @@ xcb_render_create_radial_gradient_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_fixed_t stops */
xcb_parts[4].iov_base = (char *) stops;
xcb_parts[4].iov_len = num_stops * sizeof(xcb_render_fixed_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_color_t colors */
xcb_parts[6].iov_base = (char *) colors;
xcb_parts[6].iov_len = num_stops * sizeof(xcb_render_color_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4225,18 +5117,62 @@ xcb_render_create_radial_gradient (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_fixed_t stops */
xcb_parts[4].iov_base = (char *) stops;
xcb_parts[4].iov_len = num_stops * sizeof(xcb_render_fixed_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_color_t colors */
xcb_parts[6].iov_base = (char *) colors;
xcb_parts[6].iov_len = num_stops * sizeof(xcb_render_color_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_render_create_conical_gradient_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_render_create_conical_gradient_request_t *_aux = (xcb_render_create_conical_gradient_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_render_create_conical_gradient_request_t);
+ xcb_tmp += xcb_block_len;
+ /* stops */
+ xcb_block_len += _aux->num_stops * sizeof(xcb_render_fixed_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_fixed_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* colors */
+ xcb_block_len += _aux->num_stops * sizeof(xcb_render_color_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_render_color_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -4282,14 +5218,17 @@ xcb_render_create_conical_gradient_checked (xcb_connection_t *c /**< */
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_fixed_t stops */
xcb_parts[4].iov_base = (char *) stops;
xcb_parts[4].iov_len = num_stops * sizeof(xcb_render_fixed_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_color_t colors */
xcb_parts[6].iov_base = (char *) colors;
xcb_parts[6].iov_len = num_stops * sizeof(xcb_render_color_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -4339,14 +5278,17 @@ xcb_render_create_conical_gradient (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_render_fixed_t stops */
xcb_parts[4].iov_base = (char *) stops;
xcb_parts[4].iov_len = num_stops * sizeof(xcb_render_fixed_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* xcb_render_color_t colors */
xcb_parts[6].iov_base = (char *) colors;
xcb_parts[6].iov_len = num_stops * sizeof(xcb_render_color_t);
xcb_parts[7].iov_base = 0;
xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
diff --git a/src/3rdparty/xcb/libxcb/shape.c b/src/3rdparty/xcb/libxcb/shape.c
index 948522581e..98621c4983 100644
--- a/src/3rdparty/xcb/libxcb/shape.c
+++ b/src/3rdparty/xcb/libxcb/shape.c
@@ -3,10 +3,17 @@
* Edit at your peril.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <stddef.h> /* for offsetof() */
#include "xcbext.h"
#include "shape.h"
+
+#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)
#include "xproto.h"
xcb_extension_t xcb_shape_id = { "SHAPE", 0 };
@@ -116,6 +123,7 @@ xcb_shape_query_version (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -149,6 +157,7 @@ xcb_shape_query_version_unchecked (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -173,6 +182,35 @@ xcb_shape_query_version_reply (xcb_connection_t *c /**< */,
return (xcb_shape_query_version_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_shape_rectangles_sizeof (const void *_buffer /**< */,
+ uint32_t rectangles_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_shape_rectangles_request_t);
+ xcb_tmp += xcb_block_len;
+ /* rectangles */
+ xcb_block_len += rectangles_len * sizeof(xcb_rectangle_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_rectangle_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -225,10 +263,12 @@ xcb_shape_rectangles_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rectangles */
xcb_parts[4].iov_base = (char *) rectangles;
xcb_parts[4].iov_len = rectangles_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -285,10 +325,12 @@ xcb_shape_rectangles (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rectangles */
xcb_parts[4].iov_base = (char *) rectangles;
xcb_parts[4].iov_len = rectangles_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -341,6 +383,7 @@ xcb_shape_mask_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -393,6 +436,7 @@ xcb_shape_mask (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -448,6 +492,7 @@ xcb_shape_combine_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -503,6 +548,7 @@ xcb_shape_combine (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -549,6 +595,7 @@ xcb_shape_offset_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -595,6 +642,7 @@ xcb_shape_offset (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -631,6 +679,7 @@ xcb_shape_query_extents (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -667,6 +716,7 @@ xcb_shape_query_extents_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -727,6 +777,7 @@ xcb_shape_select_input_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -767,6 +818,7 @@ xcb_shape_select_input (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -803,6 +855,7 @@ xcb_shape_input_selected (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -839,6 +892,7 @@ xcb_shape_input_selected_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -863,6 +917,35 @@ xcb_shape_input_selected_reply (xcb_connection_t *c /**< */,
return (xcb_shape_input_selected_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_shape_get_rectangles_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_shape_get_rectangles_reply_t *_aux = (xcb_shape_get_rectangles_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_shape_get_rectangles_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* rectangles */
+ xcb_block_len += _aux->rectangles_len * sizeof(xcb_rectangle_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_rectangle_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -899,6 +982,7 @@ xcb_shape_get_rectangles (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -939,6 +1023,7 @@ xcb_shape_get_rectangles_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
diff --git a/src/3rdparty/xcb/libxcb/shm.c b/src/3rdparty/xcb/libxcb/shm.c
index c1637a8654..0a1c238732 100644
--- a/src/3rdparty/xcb/libxcb/shm.c
+++ b/src/3rdparty/xcb/libxcb/shm.c
@@ -3,10 +3,17 @@
* Edit at your peril.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <stddef.h> /* for offsetof() */
#include "xcbext.h"
#include "shm.h"
+
+#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)
#include "xproto.h"
xcb_extension_t xcb_shm_id = { "MIT-SHM", 0 };
@@ -78,6 +85,7 @@ xcb_shm_query_version (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -111,6 +119,7 @@ xcb_shm_query_version_unchecked (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -174,6 +183,7 @@ xcb_shm_attach_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -217,6 +227,7 @@ xcb_shm_attach (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -253,6 +264,7 @@ xcb_shm_detach_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -289,6 +301,7 @@ xcb_shm_detach (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -368,6 +381,7 @@ xcb_shm_put_image_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -447,6 +461,7 @@ xcb_shm_put_image (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -508,6 +523,7 @@ xcb_shm_get_image (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -569,6 +585,7 @@ xcb_shm_get_image_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -644,6 +661,7 @@ xcb_shm_create_pixmap_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -699,6 +717,7 @@ xcb_shm_create_pixmap (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
diff --git a/src/3rdparty/xcb/libxcb/support_libxcb_versions_where_xcb_sumof_not_available.patch b/src/3rdparty/xcb/libxcb/support_libxcb_versions_where_xcb_sumof_not_available.patch
deleted file mode 100644
index a73e633e73..0000000000
--- a/src/3rdparty/xcb/libxcb/support_libxcb_versions_where_xcb_sumof_not_available.patch
+++ /dev/null
@@ -1,273 +0,0 @@
-diff --git a/src/3rdparty/xcb/libxcb/support_libxcb_versions_where_xcb_sumof_not_available.patch b/src/3rdparty/xcb/libxcb/support_libxcb_versions_where_xcb_sumof_not_available.patch
-index f63719d..e69de29 100644
---- a/src/3rdparty/xcb/libxcb/support_libxcb_versions_where_xcb_sumof_not_available.patch
-+++ b/src/3rdparty/xcb/libxcb/support_libxcb_versions_where_xcb_sumof_not_available.patch
-@@ -1,134 +0,0 @@
--diff --git a/src/3rdparty/xcb/libxcb/xkb.c b/src/3rdparty/xcb/libxcb/xkb.c
--index d55bd76..2e3a24a 100644
----- a/src/3rdparty/xcb/libxcb/xkb.c
--+++ b/src/3rdparty/xcb/libxcb/xkb.c
--@@ -18,6 +18,15 @@
--
-- xcb_extension_t xcb_xkb_id = { "XKEYBOARD", 0 };
--
--+int qt_xcb_sumof(uint8_t *list, int len)
--+{
--+ int i, s = 0;
--+ for(i=0; i<len; i++) {
--+ s += *list;
--+ list++;
--+ }
--+ return s;
--+}
--
-- /*****************************************************************************
-- **
--@@ -9025,7 +9034,7 @@ int
-- xcb_xkb_get_names_value_list_kt_level_names_length (const xcb_xkb_get_names_reply_t *R /**< */,
-- const xcb_xkb_get_names_value_list_t *S /**< */)
-- {
--- return xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
--+ return (/* valueList */ S->nLevelsPerType, R->nTypes);
-- }
--
--
--@@ -9043,7 +9052,7 @@ xcb_xkb_get_names_value_list_kt_level_names_end (const xcb_xkb_get_names_reply_t
-- const xcb_xkb_get_names_value_list_t *S /**< */)
-- {
-- xcb_generic_iterator_t i;
--- i.data = /* valueList */ S->ktLevelNames + xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
--+ i.data = /* valueList */ S->ktLevelNames + qt_xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
-- i.rem = 0;
-- i.index = (char *) i.data - (char *) S;
-- return i;
--@@ -9508,8 +9517,8 @@ xcb_xkb_get_names_value_list_serialize (void **_
-- xcb_block_len = 0;
-- /* ktLevelNames */
-- xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
--- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
--- xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
--+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
--+ xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
-- xcb_parts_idx++;
-- xcb_align_to = ALIGNOF(xcb_atom_t);
-- }
--@@ -9762,7 +9771,7 @@ xcb_xkb_get_names_value_list_unpack (const void *_buffer /
-- xcb_block_len = 0;
-- /* ktLevelNames */
-- _aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
--- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
--+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
-- xcb_tmp += xcb_block_len;
-- xcb_align_to = ALIGNOF(xcb_atom_t);
-- }
--@@ -10139,7 +10148,7 @@ int
-- xcb_xkb_set_names_values_kt_level_names_length (const xcb_xkb_set_names_request_t *R /**< */,
-- const xcb_xkb_set_names_values_t *S /**< */)
-- {
--- return xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
--+ return qt_xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
-- }
--
--
--@@ -10157,7 +10166,7 @@ xcb_xkb_set_names_values_kt_level_names_end (const xcb_xkb_set_names_request_t *
-- const xcb_xkb_set_names_values_t *S /**< */)
-- {
-- xcb_generic_iterator_t i;
--- i.data = /* values */ S->ktLevelNames + xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
--+ i.data = /* values */ S->ktLevelNames + qt_xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
-- i.rem = 0;
-- i.index = (char *) i.data - (char *) S;
-- return i;
--@@ -10607,8 +10616,8 @@ xcb_xkb_set_names_values_serialize (void **_buffer
-- xcb_block_len = 0;
-- /* ktLevelNames */
-- xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
--- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
--- xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
--+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
--+ xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-- xcb_parts_idx++;
-- xcb_align_to = ALIGNOF(xcb_atom_t);
-- }
--@@ -10849,7 +10858,7 @@ xcb_xkb_set_names_values_unpack (const void *_buffer /**< */,
-- xcb_block_len = 0;
-- /* ktLevelNames */
-- _aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
--- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
--+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-- xcb_tmp += xcb_block_len;
-- xcb_align_to = ALIGNOF(xcb_atom_t);
-- }
--@@ -12872,7 +12881,7 @@ int
-- xcb_xkb_get_kbd_by_name_replies_key_names_value_list_kt_level_names_length (const xcb_xkb_get_kbd_by_name_reply_t *R /**< */,
-- const xcb_xkb_get_kbd_by_name_replies_t *S /**< */)
-- {
--- return xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
--+ return qt_xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
-- }
--
--
--@@ -12890,7 +12899,7 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_kt_level_names_end (const x
-- const xcb_xkb_get_kbd_by_name_replies_t *S /**< */)
-- {
-- xcb_generic_iterator_t i;
--- i.data = /* replies */ S->key_names.valueList.ktLevelNames + xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
--+ i.data = /* replies */ S->key_names.valueList.ktLevelNames + qt_xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
-- i.rem = 0;
-- i.index = (char *) i.data - (char *) S;
-- return i;
--@@ -13340,8 +13349,8 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_serialize (void
-- xcb_block_len = 0;
-- /* ktLevelNames */
-- xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
--- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
--- xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
--+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
--+ xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-- xcb_parts_idx++;
-- xcb_align_to = ALIGNOF(xcb_atom_t);
-- }
--@@ -13582,7 +13591,7 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_unpack (const void
-- xcb_block_len = 0;
-- /* ktLevelNames */
-- _aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
--- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
--+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-- xcb_tmp += xcb_block_len;
-- xcb_align_to = ALIGNOF(xcb_atom_t);
-- }
-diff --git a/src/3rdparty/xcb/libxcb/xkb.c b/src/3rdparty/xcb/libxcb/xkb.c
-index d55bd76..ff025f6 100644
---- a/src/3rdparty/xcb/libxcb/xkb.c
-+++ b/src/3rdparty/xcb/libxcb/xkb.c
-@@ -18,6 +18,15 @@
-
- xcb_extension_t xcb_xkb_id = { "XKEYBOARD", 0 };
-
-+int qt_xcb_sumof(uint8_t *list, int len)
-+{
-+ int i, s = 0;
-+ for(i=0; i<len; i++) {
-+ s += *list;
-+ list++;
-+ }
-+ return s;
-+}
-
- /*****************************************************************************
- **
-@@ -9025,7 +9034,7 @@ int
- xcb_xkb_get_names_value_list_kt_level_names_length (const xcb_xkb_get_names_reply_t *R /**< */,
- const xcb_xkb_get_names_value_list_t *S /**< */)
- {
-- return xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
-+ return qt_xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
- }
-
-
-@@ -9043,7 +9052,7 @@ xcb_xkb_get_names_value_list_kt_level_names_end (const xcb_xkb_get_names_reply_t
- const xcb_xkb_get_names_value_list_t *S /**< */)
- {
- xcb_generic_iterator_t i;
-- i.data = /* valueList */ S->ktLevelNames + xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
-+ i.data = /* valueList */ S->ktLevelNames + qt_xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
- i.rem = 0;
- i.index = (char *) i.data - (char *) S;
- return i;
-@@ -9508,8 +9517,8 @@ xcb_xkb_get_names_value_list_serialize (void **_
- xcb_block_len = 0;
- /* ktLevelNames */
- xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
-- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
-- xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
-+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
-+ xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
- xcb_parts_idx++;
- xcb_align_to = ALIGNOF(xcb_atom_t);
- }
-@@ -9762,7 +9771,7 @@ xcb_xkb_get_names_value_list_unpack (const void *_buffer /
- xcb_block_len = 0;
- /* ktLevelNames */
- _aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
-- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
-+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
- xcb_tmp += xcb_block_len;
- xcb_align_to = ALIGNOF(xcb_atom_t);
- }
-@@ -10139,7 +10148,7 @@ int
- xcb_xkb_set_names_values_kt_level_names_length (const xcb_xkb_set_names_request_t *R /**< */,
- const xcb_xkb_set_names_values_t *S /**< */)
- {
-- return xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
-+ return qt_xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
- }
-
-
-@@ -10157,7 +10166,7 @@ xcb_xkb_set_names_values_kt_level_names_end (const xcb_xkb_set_names_request_t *
- const xcb_xkb_set_names_values_t *S /**< */)
- {
- xcb_generic_iterator_t i;
-- i.data = /* values */ S->ktLevelNames + xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
-+ i.data = /* values */ S->ktLevelNames + qt_xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
- i.rem = 0;
- i.index = (char *) i.data - (char *) S;
- return i;
-@@ -10607,8 +10616,8 @@ xcb_xkb_set_names_values_serialize (void **_buffer
- xcb_block_len = 0;
- /* ktLevelNames */
- xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
-- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-- xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-+ xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
- xcb_parts_idx++;
- xcb_align_to = ALIGNOF(xcb_atom_t);
- }
-@@ -10849,7 +10858,7 @@ xcb_xkb_set_names_values_unpack (const void *_buffer /**< */,
- xcb_block_len = 0;
- /* ktLevelNames */
- _aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
-- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
- xcb_tmp += xcb_block_len;
- xcb_align_to = ALIGNOF(xcb_atom_t);
- }
-@@ -12872,7 +12881,7 @@ int
- xcb_xkb_get_kbd_by_name_replies_key_names_value_list_kt_level_names_length (const xcb_xkb_get_kbd_by_name_reply_t *R /**< */,
- const xcb_xkb_get_kbd_by_name_replies_t *S /**< */)
- {
-- return xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
-+ return qt_xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
- }
-
-
-@@ -12890,7 +12899,7 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_kt_level_names_end (const x
- const xcb_xkb_get_kbd_by_name_replies_t *S /**< */)
- {
- xcb_generic_iterator_t i;
-- i.data = /* replies */ S->key_names.valueList.ktLevelNames + xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
-+ i.data = /* replies */ S->key_names.valueList.ktLevelNames + qt_xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
- i.rem = 0;
- i.index = (char *) i.data - (char *) S;
- return i;
-@@ -13340,8 +13349,8 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_serialize (void
- xcb_block_len = 0;
- /* ktLevelNames */
- xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
-- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-- xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-+ xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
- xcb_parts_idx++;
- xcb_align_to = ALIGNOF(xcb_atom_t);
- }
-@@ -13582,7 +13591,7 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_unpack (const void
- xcb_block_len = 0;
- /* ktLevelNames */
- _aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
-- xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
-+ xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
- xcb_tmp += xcb_block_len;
- xcb_align_to = ALIGNOF(xcb_atom_t);
- }
diff --git a/src/3rdparty/xcb/libxcb/sync.c b/src/3rdparty/xcb/libxcb/sync.c
index 408a263d2b..1f352756d8 100644
--- a/src/3rdparty/xcb/libxcb/sync.c
+++ b/src/3rdparty/xcb/libxcb/sync.c
@@ -3,10 +3,17 @@
* Edit at your peril.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <stddef.h> /* for offsetof() */
#include "xcbext.h"
#include "sync.h"
+
+#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)
#include "xproto.h"
xcb_extension_t xcb_sync_id = { "SYNC", 0 };
@@ -90,6 +97,44 @@ xcb_sync_counter_end (xcb_sync_counter_iterator_t i /**< */)
/*****************************************************************************
**
+ ** void xcb_sync_fence_next
+ **
+ ** @param xcb_sync_fence_iterator_t *i
+ ** @returns void
+ **
+ *****************************************************************************/
+
+void
+xcb_sync_fence_next (xcb_sync_fence_iterator_t *i /**< */)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_sync_fence_t);
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_generic_iterator_t xcb_sync_fence_end
+ **
+ ** @param xcb_sync_fence_iterator_t i
+ ** @returns xcb_generic_iterator_t
+ **
+ *****************************************************************************/
+
+xcb_generic_iterator_t
+xcb_sync_fence_end (xcb_sync_fence_iterator_t i /**< */)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+
+/*****************************************************************************
+ **
** void xcb_sync_int64_next
**
** @param xcb_sync_int64_iterator_t *i
@@ -125,6 +170,35 @@ xcb_sync_int64_end (xcb_sync_int64_iterator_t i /**< */)
return ret;
}
+int
+xcb_sync_systemcounter_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_sync_systemcounter_t *_aux = (xcb_sync_systemcounter_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_sync_systemcounter_t);
+ xcb_tmp += xcb_block_len;
+ /* name */
+ xcb_block_len += _aux->name_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -191,10 +265,11 @@ void
xcb_sync_systemcounter_next (xcb_sync_systemcounter_iterator_t *i /**< */)
{
xcb_sync_systemcounter_t *R = i->data;
- xcb_generic_iterator_t child = xcb_sync_systemcounter_name_end(R);
+ xcb_generic_iterator_t child;
+ child.data = (xcb_sync_systemcounter_t *)(((char *)R) + xcb_sync_systemcounter_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
--i->rem;
i->data = (xcb_sync_systemcounter_t *) child.data;
- i->index = child.index;
}
@@ -330,6 +405,7 @@ xcb_sync_initialize (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -369,6 +445,7 @@ xcb_sync_initialize_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -393,6 +470,40 @@ xcb_sync_initialize_reply (xcb_connection_t *c /**< */,
return (xcb_sync_initialize_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_sync_list_system_counters_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_sync_list_system_counters_reply_t *_aux = (xcb_sync_list_system_counters_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_sync_list_system_counters_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* counters */
+ for(i=0; i<_aux->counters_len; i++) {
+ xcb_tmp_len = xcb_sync_systemcounter_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_sync_systemcounter_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -422,6 +533,7 @@ xcb_sync_list_system_counters (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -455,6 +567,7 @@ xcb_sync_list_system_counters_unchecked (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -550,6 +663,7 @@ xcb_sync_create_counter_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -589,6 +703,7 @@ xcb_sync_create_counter (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -625,6 +740,7 @@ xcb_sync_destroy_counter_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -661,6 +777,7 @@ xcb_sync_destroy_counter (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -697,6 +814,7 @@ xcb_sync_query_counter (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -733,6 +851,7 @@ xcb_sync_query_counter_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -757,6 +876,35 @@ xcb_sync_query_counter_reply (xcb_connection_t *c /**< */,
return (xcb_sync_query_counter_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_sync_await_sizeof (const void *_buffer /**< */,
+ uint32_t wait_list_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_sync_await_request_t);
+ xcb_tmp += xcb_block_len;
+ /* wait_list */
+ xcb_block_len += wait_list_len * sizeof(xcb_sync_waitcondition_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_sync_waitcondition_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -790,10 +938,12 @@ xcb_sync_await_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_sync_waitcondition_t wait_list */
xcb_parts[4].iov_base = (char *) wait_list;
xcb_parts[4].iov_len = wait_list_len * sizeof(xcb_sync_waitcondition_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -831,10 +981,12 @@ xcb_sync_await (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_sync_waitcondition_t wait_list */
xcb_parts[4].iov_base = (char *) wait_list;
xcb_parts[4].iov_len = wait_list_len * sizeof(xcb_sync_waitcondition_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -874,6 +1026,7 @@ xcb_sync_change_counter_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -913,6 +1066,7 @@ xcb_sync_change_counter (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -952,6 +1106,7 @@ xcb_sync_set_counter_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -991,10 +1146,40 @@ xcb_sync_set_counter (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_sync_create_alarm_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_sync_create_alarm_request_t *_aux = (xcb_sync_create_alarm_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_sync_create_alarm_request_t);
+ xcb_tmp += xcb_block_len;
+ /* value_list */
+ xcb_block_len += xcb_popcount(_aux->value_mask) * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1032,10 +1217,12 @@ xcb_sync_create_alarm_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t value_list */
xcb_parts[4].iov_base = (char *) value_list;
xcb_parts[4].iov_len = xcb_popcount(value_mask) * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1077,14 +1264,45 @@ xcb_sync_create_alarm (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t value_list */
xcb_parts[4].iov_base = (char *) value_list;
xcb_parts[4].iov_len = xcb_popcount(value_mask) * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_sync_change_alarm_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_sync_change_alarm_request_t *_aux = (xcb_sync_change_alarm_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_sync_change_alarm_request_t);
+ xcb_tmp += xcb_block_len;
+ /* value_list */
+ xcb_block_len += xcb_popcount(_aux->value_mask) * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1122,10 +1340,12 @@ xcb_sync_change_alarm_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t value_list */
xcb_parts[4].iov_base = (char *) value_list;
xcb_parts[4].iov_len = xcb_popcount(value_mask) * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1167,10 +1387,12 @@ xcb_sync_change_alarm (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t value_list */
xcb_parts[4].iov_base = (char *) value_list;
xcb_parts[4].iov_len = xcb_popcount(value_mask) * sizeof(uint32_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1207,6 +1429,7 @@ xcb_sync_destroy_alarm_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1243,6 +1466,7 @@ xcb_sync_destroy_alarm (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1279,6 +1503,7 @@ xcb_sync_query_alarm (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1315,6 +1540,7 @@ xcb_sync_query_alarm_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1374,6 +1600,7 @@ xcb_sync_set_priority_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1413,6 +1640,7 @@ xcb_sync_set_priority (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1449,6 +1677,7 @@ xcb_sync_get_priority (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1485,6 +1714,7 @@ xcb_sync_get_priority_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1509,3 +1739,520 @@ xcb_sync_get_priority_reply (xcb_connection_t *c /**< */,
return (xcb_sync_get_priority_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_create_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_drawable_t drawable
+ ** @param xcb_sync_fence_t fence
+ ** @param uint8_t initially_triggered
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_create_fence_checked (xcb_connection_t *c /**< */,
+ xcb_drawable_t drawable /**< */,
+ xcb_sync_fence_t fence /**< */,
+ uint8_t initially_triggered /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_CREATE_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_create_fence_request_t xcb_out;
+
+ xcb_out.drawable = drawable;
+ xcb_out.fence = fence;
+ xcb_out.initially_triggered = initially_triggered;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_create_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_drawable_t drawable
+ ** @param xcb_sync_fence_t fence
+ ** @param uint8_t initially_triggered
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_create_fence (xcb_connection_t *c /**< */,
+ xcb_drawable_t drawable /**< */,
+ xcb_sync_fence_t fence /**< */,
+ uint8_t initially_triggered /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_CREATE_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_create_fence_request_t xcb_out;
+
+ xcb_out.drawable = drawable;
+ xcb_out.fence = fence;
+ xcb_out.initially_triggered = initially_triggered;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_trigger_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_trigger_fence_checked (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_TRIGGER_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_trigger_fence_request_t xcb_out;
+
+ xcb_out.fence = fence;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_trigger_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_trigger_fence (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_TRIGGER_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_trigger_fence_request_t xcb_out;
+
+ xcb_out.fence = fence;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_reset_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_reset_fence_checked (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_RESET_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_reset_fence_request_t xcb_out;
+
+ xcb_out.fence = fence;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_reset_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_reset_fence (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_RESET_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_reset_fence_request_t xcb_out;
+
+ xcb_out.fence = fence;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_destroy_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_destroy_fence_checked (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_DESTROY_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_destroy_fence_request_t xcb_out;
+
+ xcb_out.fence = fence;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_destroy_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_destroy_fence (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_DESTROY_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_destroy_fence_request_t xcb_out;
+
+ xcb_out.fence = fence;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_sync_query_fence_cookie_t xcb_sync_query_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_sync_query_fence_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_sync_query_fence_cookie_t
+xcb_sync_query_fence (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_QUERY_FENCE,
+ /* isvoid */ 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_sync_query_fence_cookie_t xcb_ret;
+ xcb_sync_query_fence_request_t xcb_out;
+
+ xcb_out.fence = fence;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_sync_query_fence_cookie_t xcb_sync_query_fence_unchecked
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_fence_t fence
+ ** @returns xcb_sync_query_fence_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_sync_query_fence_cookie_t
+xcb_sync_query_fence_unchecked (xcb_connection_t *c /**< */,
+ xcb_sync_fence_t fence /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 2,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_QUERY_FENCE,
+ /* isvoid */ 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_sync_query_fence_cookie_t xcb_ret;
+ xcb_sync_query_fence_request_t xcb_out;
+
+ xcb_out.fence = fence;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_sync_query_fence_reply_t * xcb_sync_query_fence_reply
+ **
+ ** @param xcb_connection_t *c
+ ** @param xcb_sync_query_fence_cookie_t cookie
+ ** @param xcb_generic_error_t **e
+ ** @returns xcb_sync_query_fence_reply_t *
+ **
+ *****************************************************************************/
+
+xcb_sync_query_fence_reply_t *
+xcb_sync_query_fence_reply (xcb_connection_t *c /**< */,
+ xcb_sync_query_fence_cookie_t cookie /**< */,
+ xcb_generic_error_t **e /**< */)
+{
+ return (xcb_sync_query_fence_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_sync_await_fence_sizeof (const void *_buffer /**< */,
+ uint32_t fence_list_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_sync_await_fence_request_t);
+ xcb_tmp += xcb_block_len;
+ /* fence_list */
+ xcb_block_len += fence_list_len * sizeof(xcb_sync_fence_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_sync_fence_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_await_fence_checked
+ **
+ ** @param xcb_connection_t *c
+ ** @param uint32_t fence_list_len
+ ** @param const xcb_sync_fence_t *fence_list
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_await_fence_checked (xcb_connection_t *c /**< */,
+ uint32_t fence_list_len /**< */,
+ const xcb_sync_fence_t *fence_list /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 4,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_AWAIT_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_await_fence_request_t xcb_out;
+
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_sync_fence_t fence_list */
+ xcb_parts[4].iov_base = (char *) fence_list;
+ xcb_parts[4].iov_len = fence_list_len * sizeof(xcb_sync_fence_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+
+/*****************************************************************************
+ **
+ ** xcb_void_cookie_t xcb_sync_await_fence
+ **
+ ** @param xcb_connection_t *c
+ ** @param uint32_t fence_list_len
+ ** @param const xcb_sync_fence_t *fence_list
+ ** @returns xcb_void_cookie_t
+ **
+ *****************************************************************************/
+
+xcb_void_cookie_t
+xcb_sync_await_fence (xcb_connection_t *c /**< */,
+ uint32_t fence_list_len /**< */,
+ const xcb_sync_fence_t *fence_list /**< */)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ /* count */ 4,
+ /* ext */ &xcb_sync_id,
+ /* opcode */ XCB_SYNC_AWAIT_FENCE,
+ /* isvoid */ 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_sync_await_fence_request_t xcb_out;
+
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_sync_fence_t fence_list */
+ xcb_parts[4].iov_base = (char *) fence_list;
+ xcb_parts[4].iov_len = fence_list_len * sizeof(xcb_sync_fence_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
diff --git a/src/3rdparty/xcb/libxcb/xfixes.c b/src/3rdparty/xcb/libxcb/xfixes.c
index 541918ce16..4c0dc84b64 100644
--- a/src/3rdparty/xcb/libxcb/xfixes.c
+++ b/src/3rdparty/xcb/libxcb/xfixes.c
@@ -3,10 +3,17 @@
* Edit at your peril.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <stddef.h> /* for offsetof() */
#include "xcbext.h"
#include "xfixes.h"
+
+#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)
#include "xproto.h"
#include "render.h"
#include "shape.h"
@@ -48,6 +55,7 @@ xcb_xfixes_query_version (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -87,6 +95,7 @@ xcb_xfixes_query_version_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -153,6 +162,7 @@ xcb_xfixes_change_save_set_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -199,6 +209,7 @@ xcb_xfixes_change_save_set (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -241,6 +252,7 @@ xcb_xfixes_select_selection_input_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -283,6 +295,7 @@ xcb_xfixes_select_selection_input (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -322,6 +335,7 @@ xcb_xfixes_select_cursor_input_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -361,10 +375,40 @@ xcb_xfixes_select_cursor_input (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_xfixes_get_cursor_image_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_xfixes_get_cursor_image_reply_t *_aux = (xcb_xfixes_get_cursor_image_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xfixes_get_cursor_image_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* cursor_image */
+ xcb_block_len += (_aux->width * _aux->height) * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -394,6 +438,7 @@ xcb_xfixes_get_cursor_image (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -427,6 +472,7 @@ xcb_xfixes_get_cursor_image_unchecked (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -541,6 +587,35 @@ xcb_xfixes_region_end (xcb_xfixes_region_iterator_t i /**< */)
return ret;
}
+int
+xcb_xfixes_create_region_sizeof (const void *_buffer /**< */,
+ uint32_t rectangles_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xfixes_create_region_request_t);
+ xcb_tmp += xcb_block_len;
+ /* rectangles */
+ xcb_block_len += rectangles_len * sizeof(xcb_rectangle_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_rectangle_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -577,10 +652,12 @@ xcb_xfixes_create_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rectangles */
xcb_parts[4].iov_base = (char *) rectangles;
xcb_parts[4].iov_len = rectangles_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -621,10 +698,12 @@ xcb_xfixes_create_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rectangles */
xcb_parts[4].iov_base = (char *) rectangles;
xcb_parts[4].iov_len = rectangles_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -664,6 +743,7 @@ xcb_xfixes_create_region_from_bitmap_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -703,6 +783,7 @@ xcb_xfixes_create_region_from_bitmap (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -746,6 +827,7 @@ xcb_xfixes_create_region_from_window_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -789,6 +871,7 @@ xcb_xfixes_create_region_from_window (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -828,6 +911,7 @@ xcb_xfixes_create_region_from_gc_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -867,6 +951,7 @@ xcb_xfixes_create_region_from_gc (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -906,6 +991,7 @@ xcb_xfixes_create_region_from_picture_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -945,6 +1031,7 @@ xcb_xfixes_create_region_from_picture (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -981,6 +1068,7 @@ xcb_xfixes_destroy_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1017,10 +1105,40 @@ xcb_xfixes_destroy_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_xfixes_set_region_sizeof (const void *_buffer /**< */,
+ uint32_t rectangles_len /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xfixes_set_region_request_t);
+ xcb_tmp += xcb_block_len;
+ /* rectangles */
+ xcb_block_len += rectangles_len * sizeof(xcb_rectangle_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_rectangle_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1057,10 +1175,12 @@ xcb_xfixes_set_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rectangles */
xcb_parts[4].iov_base = (char *) rectangles;
xcb_parts[4].iov_len = rectangles_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1101,10 +1221,12 @@ xcb_xfixes_set_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_rectangle_t rectangles */
xcb_parts[4].iov_base = (char *) rectangles;
xcb_parts[4].iov_len = rectangles_len * sizeof(xcb_rectangle_t);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1144,6 +1266,7 @@ xcb_xfixes_copy_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1183,6 +1306,7 @@ xcb_xfixes_copy_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1225,6 +1349,7 @@ xcb_xfixes_union_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1267,6 +1392,7 @@ xcb_xfixes_union_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1309,6 +1435,7 @@ xcb_xfixes_intersect_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1351,6 +1478,7 @@ xcb_xfixes_intersect_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1393,6 +1521,7 @@ xcb_xfixes_subtract_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1435,6 +1564,7 @@ xcb_xfixes_subtract_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1477,6 +1607,7 @@ xcb_xfixes_invert_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1519,6 +1650,7 @@ xcb_xfixes_invert_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1561,6 +1693,7 @@ xcb_xfixes_translate_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1603,6 +1736,7 @@ xcb_xfixes_translate_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1642,6 +1776,7 @@ xcb_xfixes_region_extents_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1681,10 +1816,40 @@ xcb_xfixes_region_extents (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_xfixes_fetch_region_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_xfixes_fetch_region_reply_t *_aux = (xcb_xfixes_fetch_region_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xfixes_fetch_region_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* rectangles */
+ xcb_block_len += (_aux->length / 2) * sizeof(xcb_rectangle_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_rectangle_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -1717,6 +1882,7 @@ xcb_xfixes_fetch_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1753,6 +1919,7 @@ xcb_xfixes_fetch_region_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1870,6 +2037,7 @@ xcb_xfixes_set_gc_clip_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1915,6 +2083,7 @@ xcb_xfixes_set_gc_clip_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -1964,6 +2133,7 @@ xcb_xfixes_set_window_shape_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2013,6 +2183,7 @@ xcb_xfixes_set_window_shape_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2058,6 +2229,7 @@ xcb_xfixes_set_picture_clip_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2103,10 +2275,40 @@ xcb_xfixes_set_picture_clip_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_xfixes_set_cursor_name_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_xfixes_set_cursor_name_request_t *_aux = (xcb_xfixes_set_cursor_name_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xfixes_set_cursor_name_request_t);
+ xcb_tmp += xcb_block_len;
+ /* name */
+ xcb_block_len += _aux->nbytes * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2145,10 +2347,12 @@ xcb_xfixes_set_cursor_name_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char name */
xcb_parts[4].iov_base = (char *) name;
xcb_parts[4].iov_len = nbytes * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2191,14 +2395,45 @@ xcb_xfixes_set_cursor_name (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char name */
xcb_parts[4].iov_base = (char *) name;
xcb_parts[4].iov_len = nbytes * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_xfixes_get_cursor_name_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_xfixes_get_cursor_name_reply_t *_aux = (xcb_xfixes_get_cursor_name_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xfixes_get_cursor_name_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* name */
+ xcb_block_len += _aux->nbytes * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2231,6 +2466,7 @@ xcb_xfixes_get_cursor_name (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2267,6 +2503,7 @@ xcb_xfixes_get_cursor_name_unchecked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2343,6 +2580,47 @@ xcb_xfixes_get_cursor_name_reply (xcb_connection_t *c /**<
return (xcb_xfixes_get_cursor_name_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_xfixes_get_cursor_image_and_name_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_xfixes_get_cursor_image_and_name_reply_t *_aux = (xcb_xfixes_get_cursor_image_and_name_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xfixes_get_cursor_image_and_name_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* name */
+ xcb_block_len += _aux->nbytes * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* cursor_image */
+ xcb_block_len += (_aux->width * _aux->height) * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2372,6 +2650,7 @@ xcb_xfixes_get_cursor_image_and_name (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2405,6 +2684,7 @@ xcb_xfixes_get_cursor_image_and_name_unchecked (xcb_connection_t *c /**< */)
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2570,6 +2850,7 @@ xcb_xfixes_change_cursor_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2609,10 +2890,40 @@ xcb_xfixes_change_cursor (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
+int
+xcb_xfixes_change_cursor_by_name_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_xfixes_change_cursor_by_name_request_t *_aux = (xcb_xfixes_change_cursor_by_name_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xfixes_change_cursor_by_name_request_t);
+ xcb_tmp += xcb_block_len;
+ /* name */
+ xcb_block_len += _aux->nbytes * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
@@ -2651,10 +2962,12 @@ xcb_xfixes_change_cursor_by_name_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char name */
xcb_parts[4].iov_base = (char *) name;
xcb_parts[4].iov_len = nbytes * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2697,10 +3010,12 @@ xcb_xfixes_change_cursor_by_name (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char name */
xcb_parts[4].iov_base = (char *) name;
xcb_parts[4].iov_len = nbytes * sizeof(char);
xcb_parts[5].iov_base = 0;
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2752,6 +3067,7 @@ xcb_xfixes_expand_region_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2803,6 +3119,7 @@ xcb_xfixes_expand_region (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2839,6 +3156,7 @@ xcb_xfixes_hide_cursor_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2875,6 +3193,7 @@ xcb_xfixes_hide_cursor (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2911,6 +3230,7 @@ xcb_xfixes_show_cursor_checked (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -2947,6 +3267,7 @@ xcb_xfixes_show_cursor (xcb_connection_t *c /**< */,
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
diff --git a/src/3rdparty/xcb/libxcb/xinerama.c b/src/3rdparty/xcb/libxcb/xinerama.c
index 05b6b73707..e660be267b 100644
--- a/src/3rdparty/xcb/libxcb/xinerama.c
+++ b/src/3rdparty/xcb/libxcb/xinerama.c
@@ -3,10 +3,17 @@
* Edit at your peril.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <stddef.h> /* for offsetof() */
#include "xcbext.h"
#include "xinerama.h"
+
+#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)
#include "xproto.h"
xcb_extension_t xcb_xinerama_id = { "XINERAMA", 0 };
@@ -15,12 +22,12 @@ xcb_extension_t xcb_xinerama_id = { "XINERAMA", 0 };
/*****************************************************************************
**
** void xcb_xinerama_screen_info_next
- **
+ **
** @param xcb_xinerama_screen_info_iterator_t *i
** @returns void
**
*****************************************************************************/
-
+
void
xcb_xinerama_screen_info_next (xcb_xinerama_screen_info_iterator_t *i /**< */)
{
@@ -33,12 +40,12 @@ xcb_xinerama_screen_info_next (xcb_xinerama_screen_info_iterator_t *i /**< */)
/*****************************************************************************
**
** xcb_generic_iterator_t xcb_xinerama_screen_info_end
- **
+ **
** @param xcb_xinerama_screen_info_iterator_t i
** @returns xcb_generic_iterator_t
**
*****************************************************************************/
-
+
xcb_generic_iterator_t
xcb_xinerama_screen_info_end (xcb_xinerama_screen_info_iterator_t i /**< */)
{
@@ -53,14 +60,14 @@ xcb_xinerama_screen_info_end (xcb_xinerama_screen_info_iterator_t i /**< */)
/*****************************************************************************
**
** xcb_xinerama_query_version_cookie_t xcb_xinerama_query_version
- **
+ **
** @param xcb_connection_t *c
** @param uint8_t major
** @param uint8_t minor
** @returns xcb_xinerama_query_version_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_query_version_cookie_t
xcb_xinerama_query_version (xcb_connection_t *c /**< */,
uint8_t major /**< */,
@@ -72,18 +79,19 @@ xcb_xinerama_query_version (xcb_connection_t *c /**< */,
/* opcode */ XCB_XINERAMA_QUERY_VERSION,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_query_version_cookie_t xcb_ret;
xcb_xinerama_query_version_request_t xcb_out;
-
+
xcb_out.major = major;
xcb_out.minor = minor;
-
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -92,14 +100,14 @@ xcb_xinerama_query_version (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_query_version_cookie_t xcb_xinerama_query_version_unchecked
- **
+ **
** @param xcb_connection_t *c
** @param uint8_t major
** @param uint8_t minor
** @returns xcb_xinerama_query_version_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_query_version_cookie_t
xcb_xinerama_query_version_unchecked (xcb_connection_t *c /**< */,
uint8_t major /**< */,
@@ -111,18 +119,19 @@ xcb_xinerama_query_version_unchecked (xcb_connection_t *c /**< */,
/* opcode */ XCB_XINERAMA_QUERY_VERSION,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_query_version_cookie_t xcb_ret;
xcb_xinerama_query_version_request_t xcb_out;
-
+
xcb_out.major = major;
xcb_out.minor = minor;
-
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -131,14 +140,14 @@ xcb_xinerama_query_version_unchecked (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_query_version_reply_t * xcb_xinerama_query_version_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_query_version_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_query_version_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_query_version_reply_t *
xcb_xinerama_query_version_reply (xcb_connection_t *c /**< */,
xcb_xinerama_query_version_cookie_t cookie /**< */,
@@ -151,13 +160,13 @@ xcb_xinerama_query_version_reply (xcb_connection_t *c /**<
/*****************************************************************************
**
** xcb_xinerama_get_state_cookie_t xcb_xinerama_get_state
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @returns xcb_xinerama_get_state_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_state_cookie_t
xcb_xinerama_get_state (xcb_connection_t *c /**< */,
xcb_window_t window /**< */)
@@ -168,17 +177,18 @@ xcb_xinerama_get_state (xcb_connection_t *c /**< */,
/* opcode */ XCB_XINERAMA_GET_STATE,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_get_state_cookie_t xcb_ret;
xcb_xinerama_get_state_request_t xcb_out;
-
+
xcb_out.window = window;
-
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -187,13 +197,13 @@ xcb_xinerama_get_state (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_state_cookie_t xcb_xinerama_get_state_unchecked
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @returns xcb_xinerama_get_state_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_state_cookie_t
xcb_xinerama_get_state_unchecked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */)
@@ -204,17 +214,18 @@ xcb_xinerama_get_state_unchecked (xcb_connection_t *c /**< */,
/* opcode */ XCB_XINERAMA_GET_STATE,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_get_state_cookie_t xcb_ret;
xcb_xinerama_get_state_request_t xcb_out;
-
+
xcb_out.window = window;
-
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -223,14 +234,14 @@ xcb_xinerama_get_state_unchecked (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_state_reply_t * xcb_xinerama_get_state_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_get_state_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_get_state_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_get_state_reply_t *
xcb_xinerama_get_state_reply (xcb_connection_t *c /**< */,
xcb_xinerama_get_state_cookie_t cookie /**< */,
@@ -243,13 +254,13 @@ xcb_xinerama_get_state_reply (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_count_cookie_t xcb_xinerama_get_screen_count
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @returns xcb_xinerama_get_screen_count_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_count_cookie_t
xcb_xinerama_get_screen_count (xcb_connection_t *c /**< */,
xcb_window_t window /**< */)
@@ -260,17 +271,18 @@ xcb_xinerama_get_screen_count (xcb_connection_t *c /**< */,
/* opcode */ XCB_XINERAMA_GET_SCREEN_COUNT,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_get_screen_count_cookie_t xcb_ret;
xcb_xinerama_get_screen_count_request_t xcb_out;
-
+
xcb_out.window = window;
-
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -279,13 +291,13 @@ xcb_xinerama_get_screen_count (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_count_cookie_t xcb_xinerama_get_screen_count_unchecked
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @returns xcb_xinerama_get_screen_count_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_count_cookie_t
xcb_xinerama_get_screen_count_unchecked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */)
@@ -296,17 +308,18 @@ xcb_xinerama_get_screen_count_unchecked (xcb_connection_t *c /**< */,
/* opcode */ XCB_XINERAMA_GET_SCREEN_COUNT,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_get_screen_count_cookie_t xcb_ret;
xcb_xinerama_get_screen_count_request_t xcb_out;
-
+
xcb_out.window = window;
-
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -315,14 +328,14 @@ xcb_xinerama_get_screen_count_unchecked (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_count_reply_t * xcb_xinerama_get_screen_count_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_get_screen_count_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_get_screen_count_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_count_reply_t *
xcb_xinerama_get_screen_count_reply (xcb_connection_t *c /**< */,
xcb_xinerama_get_screen_count_cookie_t cookie /**< */,
@@ -335,14 +348,14 @@ xcb_xinerama_get_screen_count_reply (xcb_connection_t *c
/*****************************************************************************
**
** xcb_xinerama_get_screen_size_cookie_t xcb_xinerama_get_screen_size
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @param uint32_t screen
** @returns xcb_xinerama_get_screen_size_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_size_cookie_t
xcb_xinerama_get_screen_size (xcb_connection_t *c /**< */,
xcb_window_t window /**< */,
@@ -354,18 +367,19 @@ xcb_xinerama_get_screen_size (xcb_connection_t *c /**< */,
/* opcode */ XCB_XINERAMA_GET_SCREEN_SIZE,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_get_screen_size_cookie_t xcb_ret;
xcb_xinerama_get_screen_size_request_t xcb_out;
-
+
xcb_out.window = window;
xcb_out.screen = screen;
-
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -374,14 +388,14 @@ xcb_xinerama_get_screen_size (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_size_cookie_t xcb_xinerama_get_screen_size_unchecked
- **
+ **
** @param xcb_connection_t *c
** @param xcb_window_t window
** @param uint32_t screen
** @returns xcb_xinerama_get_screen_size_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_size_cookie_t
xcb_xinerama_get_screen_size_unchecked (xcb_connection_t *c /**< */,
xcb_window_t window /**< */,
@@ -393,18 +407,19 @@ xcb_xinerama_get_screen_size_unchecked (xcb_connection_t *c /**< */,
/* opcode */ XCB_XINERAMA_GET_SCREEN_SIZE,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_get_screen_size_cookie_t xcb_ret;
xcb_xinerama_get_screen_size_request_t xcb_out;
-
+
xcb_out.window = window;
xcb_out.screen = screen;
-
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -413,14 +428,14 @@ xcb_xinerama_get_screen_size_unchecked (xcb_connection_t *c /**< */,
/*****************************************************************************
**
** xcb_xinerama_get_screen_size_reply_t * xcb_xinerama_get_screen_size_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_get_screen_size_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_get_screen_size_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_get_screen_size_reply_t *
xcb_xinerama_get_screen_size_reply (xcb_connection_t *c /**< */,
xcb_xinerama_get_screen_size_cookie_t cookie /**< */,
@@ -433,12 +448,12 @@ xcb_xinerama_get_screen_size_reply (xcb_connection_t *c /
/*****************************************************************************
**
** xcb_xinerama_is_active_cookie_t xcb_xinerama_is_active
- **
+ **
** @param xcb_connection_t *c
** @returns xcb_xinerama_is_active_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_is_active_cookie_t
xcb_xinerama_is_active (xcb_connection_t *c /**< */)
{
@@ -448,16 +463,17 @@ xcb_xinerama_is_active (xcb_connection_t *c /**< */)
/* opcode */ XCB_XINERAMA_IS_ACTIVE,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_is_active_cookie_t xcb_ret;
xcb_xinerama_is_active_request_t xcb_out;
-
-
+
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -466,12 +482,12 @@ xcb_xinerama_is_active (xcb_connection_t *c /**< */)
/*****************************************************************************
**
** xcb_xinerama_is_active_cookie_t xcb_xinerama_is_active_unchecked
- **
+ **
** @param xcb_connection_t *c
** @returns xcb_xinerama_is_active_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_is_active_cookie_t
xcb_xinerama_is_active_unchecked (xcb_connection_t *c /**< */)
{
@@ -481,16 +497,17 @@ xcb_xinerama_is_active_unchecked (xcb_connection_t *c /**< */)
/* opcode */ XCB_XINERAMA_IS_ACTIVE,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_is_active_cookie_t xcb_ret;
xcb_xinerama_is_active_request_t xcb_out;
-
-
+
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -499,14 +516,14 @@ xcb_xinerama_is_active_unchecked (xcb_connection_t *c /**< */)
/*****************************************************************************
**
** xcb_xinerama_is_active_reply_t * xcb_xinerama_is_active_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_is_active_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_is_active_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_is_active_reply_t *
xcb_xinerama_is_active_reply (xcb_connection_t *c /**< */,
xcb_xinerama_is_active_cookie_t cookie /**< */,
@@ -515,16 +532,45 @@ xcb_xinerama_is_active_reply (xcb_connection_t *c /**< */,
return (xcb_xinerama_is_active_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
}
+int
+xcb_xinerama_query_screens_sizeof (const void *_buffer /**< */)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_xinerama_query_screens_reply_t *_aux = (xcb_xinerama_query_screens_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to;
+
+
+ xcb_block_len += sizeof(xcb_xinerama_query_screens_reply_t);
+ xcb_tmp += xcb_block_len;
+ /* screen_info */
+ xcb_block_len += _aux->number * sizeof(xcb_xinerama_screen_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_xinerama_screen_info_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
/*****************************************************************************
**
** xcb_xinerama_query_screens_cookie_t xcb_xinerama_query_screens
- **
+ **
** @param xcb_connection_t *c
** @returns xcb_xinerama_query_screens_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_query_screens_cookie_t
xcb_xinerama_query_screens (xcb_connection_t *c /**< */)
{
@@ -534,16 +580,17 @@ xcb_xinerama_query_screens (xcb_connection_t *c /**< */)
/* opcode */ XCB_XINERAMA_QUERY_SCREENS,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_query_screens_cookie_t xcb_ret;
xcb_xinerama_query_screens_request_t xcb_out;
-
-
+
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -552,12 +599,12 @@ xcb_xinerama_query_screens (xcb_connection_t *c /**< */)
/*****************************************************************************
**
** xcb_xinerama_query_screens_cookie_t xcb_xinerama_query_screens_unchecked
- **
+ **
** @param xcb_connection_t *c
** @returns xcb_xinerama_query_screens_cookie_t
**
*****************************************************************************/
-
+
xcb_xinerama_query_screens_cookie_t
xcb_xinerama_query_screens_unchecked (xcb_connection_t *c /**< */)
{
@@ -567,16 +614,17 @@ xcb_xinerama_query_screens_unchecked (xcb_connection_t *c /**< */)
/* opcode */ XCB_XINERAMA_QUERY_SCREENS,
/* isvoid */ 0
};
-
+
struct iovec xcb_parts[4];
xcb_xinerama_query_screens_cookie_t xcb_ret;
xcb_xinerama_query_screens_request_t xcb_out;
-
-
+
+
xcb_parts[2].iov_base = (char *) &xcb_out;
xcb_parts[2].iov_len = sizeof(xcb_out);
xcb_parts[3].iov_base = 0;
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
return xcb_ret;
}
@@ -585,12 +633,12 @@ xcb_xinerama_query_screens_unchecked (xcb_connection_t *c /**< */)
/*****************************************************************************
**
** xcb_xinerama_screen_info_t * xcb_xinerama_query_screens_screen_info
- **
+ **
** @param const xcb_xinerama_query_screens_reply_t *R
** @returns xcb_xinerama_screen_info_t *
**
*****************************************************************************/
-
+
xcb_xinerama_screen_info_t *
xcb_xinerama_query_screens_screen_info (const xcb_xinerama_query_screens_reply_t *R /**< */)
{
@@ -601,12 +649,12 @@ xcb_xinerama_query_screens_screen_info (const xcb_xinerama_query_screens_reply_t
/*****************************************************************************
**
** int xcb_xinerama_query_screens_screen_info_length
- **
+ **
** @param const xcb_xinerama_query_screens_reply_t *R
** @returns int
**
*****************************************************************************/
-
+
int
xcb_xinerama_query_screens_screen_info_length (const xcb_xinerama_query_screens_reply_t *R /**< */)
{
@@ -617,12 +665,12 @@ xcb_xinerama_query_screens_screen_info_length (const xcb_xinerama_query_screens_
/*****************************************************************************
**
** xcb_xinerama_screen_info_iterator_t xcb_xinerama_query_screens_screen_info_iterator
- **
+ **
** @param const xcb_xinerama_query_screens_reply_t *R
** @returns xcb_xinerama_screen_info_iterator_t
**
*****************************************************************************/
-
+
xcb_xinerama_screen_info_iterator_t
xcb_xinerama_query_screens_screen_info_iterator (const xcb_xinerama_query_screens_reply_t *R /**< */)
{
@@ -637,14 +685,14 @@ xcb_xinerama_query_screens_screen_info_iterator (const xcb_xinerama_query_screen
/*****************************************************************************
**
** xcb_xinerama_query_screens_reply_t * xcb_xinerama_query_screens_reply
- **
+ **
** @param xcb_connection_t *c
** @param xcb_xinerama_query_screens_cookie_t cookie
** @param xcb_generic_error_t **e
** @returns xcb_xinerama_query_screens_reply_t *
**
*****************************************************************************/
-
+
xcb_xinerama_query_screens_reply_t *
xcb_xinerama_query_screens_reply (xcb_connection_t *c /**< */,
xcb_xinerama_query_screens_cookie_t cookie /**< */,
diff --git a/src/3rdparty/xcb/libxcb/xinput.c b/src/3rdparty/xcb/libxcb/xinput.c
new file mode 100644
index 0000000000..0edfde656c
--- /dev/null
+++ b/src/3rdparty/xcb/libxcb/xinput.c
@@ -0,0 +1,14156 @@
+/*
+ * This file generated automatically from xinput.xml by c_client.py.
+ * Edit at your peril.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stddef.h> /* for offsetof() */
+#include "xcbext.h"
+#include "xinput.h"
+
+#define ALIGNOF(type) offsetof(struct { char dummy; type member; }, member)
+#include "xfixes.h"
+
+xcb_extension_t xcb_input_id = { "XInputExtension", 0 };
+
+void
+xcb_input_event_class_next (xcb_input_event_class_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_event_class_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_event_class_end (xcb_input_event_class_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_key_code_next (xcb_input_key_code_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_key_code_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_key_code_end (xcb_input_key_code_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_device_id_next (xcb_input_device_id_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_id_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_id_end (xcb_input_device_id_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_fp1616_next (xcb_input_fp1616_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_fp1616_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_fp1616_end (xcb_input_fp1616_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_fp3232_next (xcb_input_fp3232_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_fp3232_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_fp3232_end (xcb_input_fp3232_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_get_extension_version_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_extension_version_request_t *_aux = (xcb_input_get_extension_version_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_get_extension_version_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* name */
+ xcb_block_len += _aux->name_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_extension_version_cookie_t
+xcb_input_get_extension_version (xcb_connection_t *c,
+ uint16_t name_len,
+ const char *name)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_EXTENSION_VERSION,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_get_extension_version_cookie_t xcb_ret;
+ xcb_input_get_extension_version_request_t xcb_out;
+
+ xcb_out.name_len = name_len;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char name */
+ xcb_parts[4].iov_base = (char *) name;
+ xcb_parts[4].iov_len = name_len * sizeof(char);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_extension_version_cookie_t
+xcb_input_get_extension_version_unchecked (xcb_connection_t *c,
+ uint16_t name_len,
+ const char *name)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_EXTENSION_VERSION,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_get_extension_version_cookie_t xcb_ret;
+ xcb_input_get_extension_version_request_t xcb_out;
+
+ xcb_out.name_len = name_len;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* char name */
+ xcb_parts[4].iov_base = (char *) name;
+ xcb_parts[4].iov_len = name_len * sizeof(char);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_extension_version_reply_t *
+xcb_input_get_extension_version_reply (xcb_connection_t *c,
+ xcb_input_get_extension_version_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_extension_version_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+void
+xcb_input_device_info_next (xcb_input_device_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_info_end (xcb_input_device_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_key_info_next (xcb_input_key_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_key_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_key_info_end (xcb_input_key_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_button_info_next (xcb_input_button_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_button_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_button_info_end (xcb_input_button_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_axis_info_next (xcb_input_axis_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_axis_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_axis_info_end (xcb_input_axis_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_valuator_info_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_valuator_info_t *_aux = (xcb_input_valuator_info_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_valuator_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* axes */
+ xcb_block_len += _aux->axes_len * sizeof(xcb_input_axis_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_axis_info_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_axis_info_t *
+xcb_input_valuator_info_axes (const xcb_input_valuator_info_t *R)
+{
+ return (xcb_input_axis_info_t *) (R + 1);
+}
+
+int
+xcb_input_valuator_info_axes_length (const xcb_input_valuator_info_t *R)
+{
+ return R->axes_len;
+}
+
+xcb_input_axis_info_iterator_t
+xcb_input_valuator_info_axes_iterator (const xcb_input_valuator_info_t *R)
+{
+ xcb_input_axis_info_iterator_t i;
+ i.data = (xcb_input_axis_info_t *) (R + 1);
+ i.rem = R->axes_len;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_valuator_info_next (xcb_input_valuator_info_iterator_t *i)
+{
+ xcb_input_valuator_info_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_valuator_info_t *)(((char *)R) + xcb_input_valuator_info_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_valuator_info_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_valuator_info_end (xcb_input_valuator_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_valuator_info_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+xcb_input_axis_info_t *
+xcb_input_input_info_info_valuator_axes (const xcb_input_input_info_info_t *S)
+{
+ return S->valuator.axes;
+}
+
+int
+xcb_input_input_info_info_valuator_axes_length (const xcb_input_input_info_t *R,
+ const xcb_input_input_info_info_t *S)
+{
+ return S->valuator.axes_len;
+}
+
+xcb_input_axis_info_iterator_t
+xcb_input_input_info_info_valuator_axes_iterator (const xcb_input_input_info_t *R,
+ const xcb_input_input_info_info_t *S)
+{
+ xcb_input_axis_info_iterator_t i;
+ i.data = S->valuator.axes;
+ i.rem = S->valuator.axes_len;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_input_info_info_serialize (void **_buffer,
+ uint8_t class_id,
+ const xcb_input_input_info_info_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 2;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[11];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(class_id == XCB_INPUT_INPUT_CLASS_KEY) {
+ /* xcb_input_input_info_info_t.key.min_keycode */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->key.min_keycode;
+ xcb_block_len += sizeof(xcb_input_key_code_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_key_code_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_key_code_t);
+ /* xcb_input_input_info_info_t.key.max_keycode */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->key.max_keycode;
+ xcb_block_len += sizeof(xcb_input_key_code_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_key_code_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_key_code_t);
+ /* xcb_input_input_info_info_t.key.num_keys */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->key.num_keys;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_input_info_info_t.key.pad0 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*2;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*2;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(class_id == XCB_INPUT_INPUT_CLASS_BUTTON) {
+ /* xcb_input_input_info_info_t.button.num_buttons */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->button.num_buttons;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ }
+ if(class_id == XCB_INPUT_INPUT_CLASS_VALUATOR) {
+ /* xcb_input_input_info_info_t.valuator.axes_len */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.axes_len;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_info_info_t.valuator.mode */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.mode;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_info_info_t.valuator.motion_size */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.motion_size;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* axes */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->valuator.axes;
+ xcb_block_len += _aux->valuator.axes_len * sizeof(xcb_input_axis_info_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->valuator.axes_len * sizeof(xcb_input_axis_info_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_axis_info_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_input_info_info_unpack (const void *_buffer,
+ uint8_t class_id,
+ xcb_input_input_info_info_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 2;
+
+
+ if(class_id == XCB_INPUT_INPUT_CLASS_KEY) {
+ /* xcb_input_input_info_info_t.key.min_keycode */
+ _aux->key.min_keycode = *(xcb_input_key_code_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_key_code_t);
+ xcb_tmp += sizeof(xcb_input_key_code_t);
+ xcb_align_to = ALIGNOF(xcb_input_key_code_t);
+ /* xcb_input_input_info_info_t.key.max_keycode */
+ _aux->key.max_keycode = *(xcb_input_key_code_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_key_code_t);
+ xcb_tmp += sizeof(xcb_input_key_code_t);
+ xcb_align_to = ALIGNOF(xcb_input_key_code_t);
+ /* xcb_input_input_info_info_t.key.num_keys */
+ _aux->key.num_keys = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_input_info_info_t.key.pad0 */
+ _aux->key.pad0[0] = *(uint8_t *)xcb_tmp;
+ _aux->key.pad0[1] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 2;
+ xcb_tmp += sizeof(uint8_t) * 2;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(class_id == XCB_INPUT_INPUT_CLASS_BUTTON) {
+ /* xcb_input_input_info_info_t.button.num_buttons */
+ _aux->button.num_buttons = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ }
+ if(class_id == XCB_INPUT_INPUT_CLASS_VALUATOR) {
+ /* xcb_input_input_info_info_t.valuator.axes_len */
+ _aux->valuator.axes_len = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_info_info_t.valuator.mode */
+ _aux->valuator.mode = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_info_info_t.valuator.motion_size */
+ _aux->valuator.motion_size = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* axes */
+ _aux->valuator.axes = (xcb_input_axis_info_t *)xcb_tmp;
+ xcb_block_len += _aux->valuator.axes_len * sizeof(xcb_input_axis_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_axis_info_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_input_info_info_sizeof (const void *_buffer,
+ uint8_t class_id)
+{
+ xcb_input_input_info_info_t _aux;
+ return xcb_input_input_info_info_unpack(_buffer, class_id, &_aux);
+}
+
+int
+xcb_input_input_info_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_input_info_t *_aux = (xcb_input_input_info_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_input_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* info */
+ xcb_block_len += xcb_input_input_info_info_sizeof(xcb_tmp, _aux->class_id);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+void *
+xcb_input_input_info_info (const xcb_input_input_info_t *R)
+{
+ return (void *) (R + 1);
+}
+
+void
+xcb_input_input_info_next (xcb_input_input_info_iterator_t *i)
+{
+ xcb_input_input_info_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_input_info_t *)(((char *)R) + xcb_input_input_info_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_input_info_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_input_info_end (xcb_input_input_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_input_info_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_device_name_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_device_name_t *_aux = (xcb_input_device_name_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_device_name_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* string */
+ xcb_block_len += _aux->len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+char *
+xcb_input_device_name_string (const xcb_input_device_name_t *R)
+{
+ return (char *) (R + 1);
+}
+
+int
+xcb_input_device_name_string_length (const xcb_input_device_name_t *R)
+{
+ return R->len;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_name_string_end (const xcb_input_device_name_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((char *) (R + 1)) + (R->len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_device_name_next (xcb_input_device_name_iterator_t *i)
+{
+ xcb_input_device_name_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_device_name_t *)(((char *)R) + xcb_input_device_name_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_device_name_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_name_end (xcb_input_device_name_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_device_name_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_list_input_devices_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_list_input_devices_reply_t *_aux = (xcb_input_list_input_devices_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ int xcb_pre_tmp_1; /* sumof length */
+ int xcb_pre_tmp_2; /* sumof loop counter */
+ int64_t xcb_pre_tmp_3; /* sumof sum */
+ const xcb_input_device_info_t* xcb_pre_tmp_4; /* sumof list ptr */
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_list_input_devices_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* devices */
+ xcb_block_len += _aux->devices_len * sizeof(xcb_input_device_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_device_info_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* infos */
+ /* sumof start */
+ xcb_pre_tmp_1 = _aux->devices_len;
+ xcb_pre_tmp_3 = 0;
+ xcb_pre_tmp_4 = xcb_input_list_input_devices_devices(_aux);
+ for (xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
+ xcb_pre_tmp_3 += xcb_pre_tmp_4->num_class_info;
+ xcb_pre_tmp_4++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_3 */
+ for(i=0; i<xcb_pre_tmp_3; i++) {
+ xcb_tmp_len = xcb_input_input_info_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_input_info_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* names */
+ for(i=0; i<_aux->devices_len; i++) {
+ xcb_tmp_len = xcb_str_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_str_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_list_input_devices_cookie_t
+xcb_input_list_input_devices (xcb_connection_t *c)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_LIST_INPUT_DEVICES,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_list_input_devices_cookie_t xcb_ret;
+ xcb_input_list_input_devices_request_t xcb_out;
+
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_list_input_devices_cookie_t
+xcb_input_list_input_devices_unchecked (xcb_connection_t *c)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_LIST_INPUT_DEVICES,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_list_input_devices_cookie_t xcb_ret;
+ xcb_input_list_input_devices_request_t xcb_out;
+
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_device_info_t *
+xcb_input_list_input_devices_devices (const xcb_input_list_input_devices_reply_t *R)
+{
+ return (xcb_input_device_info_t *) (R + 1);
+}
+
+int
+xcb_input_list_input_devices_devices_length (const xcb_input_list_input_devices_reply_t *R)
+{
+ return R->devices_len;
+}
+
+xcb_input_device_info_iterator_t
+xcb_input_list_input_devices_devices_iterator (const xcb_input_list_input_devices_reply_t *R)
+{
+ xcb_input_device_info_iterator_t i;
+ i.data = (xcb_input_device_info_t *) (R + 1);
+ i.rem = R->devices_len;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_list_input_devices_infos_length (const xcb_input_list_input_devices_reply_t *R)
+{
+ int xcb_pre_tmp_5; /* sumof length */
+ int xcb_pre_tmp_6; /* sumof loop counter */
+ int64_t xcb_pre_tmp_7; /* sumof sum */
+ const xcb_input_device_info_t* xcb_pre_tmp_8; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_5 = R->devices_len;
+ xcb_pre_tmp_7 = 0;
+ xcb_pre_tmp_8 = xcb_input_list_input_devices_devices(R);
+ for (xcb_pre_tmp_6 = 0; xcb_pre_tmp_6 < xcb_pre_tmp_5; xcb_pre_tmp_6++) {
+ xcb_pre_tmp_7 += xcb_pre_tmp_8->num_class_info;
+ xcb_pre_tmp_8++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_7 */
+ return xcb_pre_tmp_7;
+}
+
+xcb_input_input_info_iterator_t
+xcb_input_list_input_devices_infos_iterator (const xcb_input_list_input_devices_reply_t *R)
+{
+ xcb_input_input_info_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_device_info_end(xcb_input_list_input_devices_devices_iterator(R));
+ int xcb_pre_tmp_9; /* sumof length */
+ int xcb_pre_tmp_10; /* sumof loop counter */
+ int64_t xcb_pre_tmp_11; /* sumof sum */
+ const xcb_input_device_info_t* xcb_pre_tmp_12; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_9 = R->devices_len;
+ xcb_pre_tmp_11 = 0;
+ xcb_pre_tmp_12 = xcb_input_list_input_devices_devices(R);
+ for (xcb_pre_tmp_10 = 0; xcb_pre_tmp_10 < xcb_pre_tmp_9; xcb_pre_tmp_10++) {
+ xcb_pre_tmp_11 += xcb_pre_tmp_12->num_class_info;
+ xcb_pre_tmp_12++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_11 */
+ i.data = (xcb_input_input_info_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_input_info_t, prev.index));
+ i.rem = xcb_pre_tmp_11;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_list_input_devices_names_length (const xcb_input_list_input_devices_reply_t *R)
+{
+ return R->devices_len;
+}
+
+xcb_str_iterator_t
+xcb_input_list_input_devices_names_iterator (const xcb_input_list_input_devices_reply_t *R)
+{
+ xcb_str_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_input_info_end(xcb_input_list_input_devices_infos_iterator(R));
+ i.data = (xcb_str_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_str_t, prev.index));
+ i.rem = R->devices_len;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_list_input_devices_reply_t *
+xcb_input_list_input_devices_reply (xcb_connection_t *c,
+ xcb_input_list_input_devices_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_list_input_devices_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+void
+xcb_input_event_type_base_next (xcb_input_event_type_base_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_event_type_base_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_event_type_base_end (xcb_input_event_type_base_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_input_class_info_next (xcb_input_input_class_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_input_class_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_input_class_info_end (xcb_input_input_class_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_open_device_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_open_device_reply_t *_aux = (xcb_input_open_device_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_open_device_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* class_info */
+ xcb_block_len += _aux->num_classes * sizeof(xcb_input_input_class_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_input_class_info_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_open_device_cookie_t
+xcb_input_open_device (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_OPEN_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_open_device_cookie_t xcb_ret;
+ xcb_input_open_device_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_open_device_cookie_t
+xcb_input_open_device_unchecked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_OPEN_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_open_device_cookie_t xcb_ret;
+ xcb_input_open_device_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_input_class_info_t *
+xcb_input_open_device_class_info (const xcb_input_open_device_reply_t *R)
+{
+ return (xcb_input_input_class_info_t *) (R + 1);
+}
+
+int
+xcb_input_open_device_class_info_length (const xcb_input_open_device_reply_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_input_input_class_info_iterator_t
+xcb_input_open_device_class_info_iterator (const xcb_input_open_device_reply_t *R)
+{
+ xcb_input_input_class_info_iterator_t i;
+ i.data = (xcb_input_input_class_info_t *) (R + 1);
+ i.rem = R->num_classes;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_open_device_reply_t *
+xcb_input_open_device_reply (xcb_connection_t *c,
+ xcb_input_open_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_open_device_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_void_cookie_t
+xcb_input_close_device_checked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CLOSE_DEVICE,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_close_device_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_close_device (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CLOSE_DEVICE,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_close_device_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_mode_cookie_t
+xcb_input_set_device_mode (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t mode)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_MODE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_set_device_mode_cookie_t xcb_ret;
+ xcb_input_set_device_mode_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.mode = mode;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_mode_cookie_t
+xcb_input_set_device_mode_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t mode)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_MODE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_set_device_mode_cookie_t xcb_ret;
+ xcb_input_set_device_mode_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.mode = mode;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_mode_reply_t *
+xcb_input_set_device_mode_reply (xcb_connection_t *c,
+ xcb_input_set_device_mode_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_set_device_mode_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_select_extension_event_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_select_extension_event_request_t *_aux = (xcb_input_select_extension_event_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_select_extension_event_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* classes */
+ xcb_block_len += _aux->num_classes * sizeof(xcb_input_event_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_event_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_select_extension_event_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_classes,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SELECT_EXTENSION_EVENT,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_select_extension_event_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.num_classes = num_classes;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(xcb_input_event_class_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_select_extension_event (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_classes,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SELECT_EXTENSION_EVENT,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_select_extension_event_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.num_classes = num_classes;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(xcb_input_event_class_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_event_class_t *
+xcb_input_select_extension_event_classes (const xcb_input_select_extension_event_request_t *R)
+{
+ return (xcb_input_event_class_t *) (R + 1);
+}
+
+int
+xcb_input_select_extension_event_classes_length (const xcb_input_select_extension_event_request_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_generic_iterator_t
+xcb_input_select_extension_event_classes_end (const xcb_input_select_extension_event_request_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_input_event_class_t *) (R + 1)) + (R->num_classes);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_get_selected_extension_events_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_selected_extension_events_reply_t *_aux = (xcb_input_get_selected_extension_events_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_get_selected_extension_events_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* this_classes */
+ xcb_block_len += _aux->num_this_classes * sizeof(xcb_input_event_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_event_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* all_classes */
+ xcb_block_len += _aux->num_all_classes * sizeof(xcb_input_event_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_event_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_selected_extension_events_cookie_t
+xcb_input_get_selected_extension_events (xcb_connection_t *c,
+ xcb_window_t window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_SELECTED_EXTENSION_EVENTS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_selected_extension_events_cookie_t xcb_ret;
+ xcb_input_get_selected_extension_events_request_t xcb_out;
+
+ xcb_out.window = window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_selected_extension_events_cookie_t
+xcb_input_get_selected_extension_events_unchecked (xcb_connection_t *c,
+ xcb_window_t window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_SELECTED_EXTENSION_EVENTS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_selected_extension_events_cookie_t xcb_ret;
+ xcb_input_get_selected_extension_events_request_t xcb_out;
+
+ xcb_out.window = window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_event_class_t *
+xcb_input_get_selected_extension_events_this_classes (const xcb_input_get_selected_extension_events_reply_t *R)
+{
+ return (xcb_input_event_class_t *) (R + 1);
+}
+
+int
+xcb_input_get_selected_extension_events_this_classes_length (const xcb_input_get_selected_extension_events_reply_t *R)
+{
+ return R->num_this_classes;
+}
+
+xcb_generic_iterator_t
+xcb_input_get_selected_extension_events_this_classes_end (const xcb_input_get_selected_extension_events_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_input_event_class_t *) (R + 1)) + (R->num_this_classes);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_event_class_t *
+xcb_input_get_selected_extension_events_all_classes (const xcb_input_get_selected_extension_events_reply_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_get_selected_extension_events_this_classes_end(R);
+ return (xcb_input_event_class_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_event_class_t, prev.index) + 0);
+}
+
+int
+xcb_input_get_selected_extension_events_all_classes_length (const xcb_input_get_selected_extension_events_reply_t *R)
+{
+ return R->num_all_classes;
+}
+
+xcb_generic_iterator_t
+xcb_input_get_selected_extension_events_all_classes_end (const xcb_input_get_selected_extension_events_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_get_selected_extension_events_this_classes_end(R);
+ i.data = ((xcb_input_event_class_t *) ((char*) prev.data + XCB_TYPE_PAD(xcb_input_event_class_t, prev.index))) + (R->num_all_classes);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_get_selected_extension_events_reply_t *
+xcb_input_get_selected_extension_events_reply (xcb_connection_t *c,
+ xcb_input_get_selected_extension_events_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_selected_extension_events_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_change_device_dont_propagate_list_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_change_device_dont_propagate_list_request_t *_aux = (xcb_input_change_device_dont_propagate_list_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_change_device_dont_propagate_list_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* classes */
+ xcb_block_len += _aux->num_classes * sizeof(xcb_input_event_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_event_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_change_device_dont_propagate_list_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_classes,
+ uint8_t mode,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_DONT_PROPAGATE_LIST,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_device_dont_propagate_list_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.num_classes = num_classes;
+ xcb_out.mode = mode;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(xcb_input_event_class_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_change_device_dont_propagate_list (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_classes,
+ uint8_t mode,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_DONT_PROPAGATE_LIST,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_device_dont_propagate_list_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.num_classes = num_classes;
+ xcb_out.mode = mode;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(xcb_input_event_class_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_event_class_t *
+xcb_input_change_device_dont_propagate_list_classes (const xcb_input_change_device_dont_propagate_list_request_t *R)
+{
+ return (xcb_input_event_class_t *) (R + 1);
+}
+
+int
+xcb_input_change_device_dont_propagate_list_classes_length (const xcb_input_change_device_dont_propagate_list_request_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_generic_iterator_t
+xcb_input_change_device_dont_propagate_list_classes_end (const xcb_input_change_device_dont_propagate_list_request_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_input_event_class_t *) (R + 1)) + (R->num_classes);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_get_device_dont_propagate_list_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_device_dont_propagate_list_reply_t *_aux = (xcb_input_get_device_dont_propagate_list_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_get_device_dont_propagate_list_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* classes */
+ xcb_block_len += _aux->num_classes * sizeof(xcb_input_event_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_event_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_device_dont_propagate_list_cookie_t
+xcb_input_get_device_dont_propagate_list (xcb_connection_t *c,
+ xcb_window_t window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_DONT_PROPAGATE_LIST,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_dont_propagate_list_cookie_t xcb_ret;
+ xcb_input_get_device_dont_propagate_list_request_t xcb_out;
+
+ xcb_out.window = window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_dont_propagate_list_cookie_t
+xcb_input_get_device_dont_propagate_list_unchecked (xcb_connection_t *c,
+ xcb_window_t window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_DONT_PROPAGATE_LIST,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_dont_propagate_list_cookie_t xcb_ret;
+ xcb_input_get_device_dont_propagate_list_request_t xcb_out;
+
+ xcb_out.window = window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_event_class_t *
+xcb_input_get_device_dont_propagate_list_classes (const xcb_input_get_device_dont_propagate_list_reply_t *R)
+{
+ return (xcb_input_event_class_t *) (R + 1);
+}
+
+int
+xcb_input_get_device_dont_propagate_list_classes_length (const xcb_input_get_device_dont_propagate_list_reply_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_generic_iterator_t
+xcb_input_get_device_dont_propagate_list_classes_end (const xcb_input_get_device_dont_propagate_list_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_input_event_class_t *) (R + 1)) + (R->num_classes);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_get_device_dont_propagate_list_reply_t *
+xcb_input_get_device_dont_propagate_list_reply (xcb_connection_t *c,
+ xcb_input_get_device_dont_propagate_list_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_device_dont_propagate_list_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_device_time_coord_sizeof (const void *_buffer,
+ uint8_t num_axes)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_device_time_coord_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* axisvalues */
+ xcb_block_len += num_axes * sizeof(int32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+int32_t *
+xcb_input_device_time_coord_axisvalues (const xcb_input_device_time_coord_t *R)
+{
+ return (int32_t *) (R + 1);
+}
+
+int
+xcb_input_device_time_coord_axisvalues_length (const xcb_input_device_time_coord_t *R,
+ uint8_t num_axes)
+{
+ return num_axes;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_time_coord_axisvalues_end (const xcb_input_device_time_coord_t *R,
+ uint8_t num_axes)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((int32_t *) (R + 1)) + (num_axes);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_device_time_coord_next (xcb_input_device_time_coord_iterator_t *i)
+{
+ xcb_input_device_time_coord_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_device_time_coord_t *)(((char *)R) + xcb_input_device_time_coord_sizeof(R, i->num_axes));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_device_time_coord_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_time_coord_end (xcb_input_device_time_coord_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_device_time_coord_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_get_device_motion_events_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_device_motion_events_reply_t *_aux = (xcb_input_get_device_motion_events_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_get_device_motion_events_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* events */
+ for(i=0; i<_aux->num_events; i++) {
+ xcb_tmp_len = xcb_input_device_time_coord_sizeof(xcb_tmp, _aux->num_axes);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_device_time_coord_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_device_motion_events_cookie_t
+xcb_input_get_device_motion_events (xcb_connection_t *c,
+ xcb_timestamp_t start,
+ xcb_timestamp_t stop,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_MOTION_EVENTS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_motion_events_cookie_t xcb_ret;
+ xcb_input_get_device_motion_events_request_t xcb_out;
+
+ xcb_out.start = start;
+ xcb_out.stop = stop;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_motion_events_cookie_t
+xcb_input_get_device_motion_events_unchecked (xcb_connection_t *c,
+ xcb_timestamp_t start,
+ xcb_timestamp_t stop,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_MOTION_EVENTS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_motion_events_cookie_t xcb_ret;
+ xcb_input_get_device_motion_events_request_t xcb_out;
+
+ xcb_out.start = start;
+ xcb_out.stop = stop;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_get_device_motion_events_events_length (const xcb_input_get_device_motion_events_reply_t *R)
+{
+ return R->num_events;
+}
+
+xcb_input_device_time_coord_iterator_t
+xcb_input_get_device_motion_events_events_iterator (const xcb_input_get_device_motion_events_reply_t *R)
+{
+ xcb_input_device_time_coord_iterator_t i;
+ i.data = (xcb_input_device_time_coord_t *) (R + 1);
+ i.rem = R->num_events;
+ i.index = (char *) i.data - (char *) R;
+ i.num_axes = R->num_axes;
+ return i;
+}
+
+xcb_input_get_device_motion_events_reply_t *
+xcb_input_get_device_motion_events_reply (xcb_connection_t *c,
+ xcb_input_get_device_motion_events_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_device_motion_events_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_input_change_keyboard_device_cookie_t
+xcb_input_change_keyboard_device (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_KEYBOARD_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_change_keyboard_device_cookie_t xcb_ret;
+ xcb_input_change_keyboard_device_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_change_keyboard_device_cookie_t
+xcb_input_change_keyboard_device_unchecked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_KEYBOARD_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_change_keyboard_device_cookie_t xcb_ret;
+ xcb_input_change_keyboard_device_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_change_keyboard_device_reply_t *
+xcb_input_change_keyboard_device_reply (xcb_connection_t *c,
+ xcb_input_change_keyboard_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_change_keyboard_device_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_input_change_pointer_device_cookie_t
+xcb_input_change_pointer_device (xcb_connection_t *c,
+ uint8_t x_axis,
+ uint8_t y_axis,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_POINTER_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_change_pointer_device_cookie_t xcb_ret;
+ xcb_input_change_pointer_device_request_t xcb_out;
+
+ xcb_out.x_axis = x_axis;
+ xcb_out.y_axis = y_axis;
+ xcb_out.device_id = device_id;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_change_pointer_device_cookie_t
+xcb_input_change_pointer_device_unchecked (xcb_connection_t *c,
+ uint8_t x_axis,
+ uint8_t y_axis,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_POINTER_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_change_pointer_device_cookie_t xcb_ret;
+ xcb_input_change_pointer_device_request_t xcb_out;
+
+ xcb_out.x_axis = x_axis;
+ xcb_out.y_axis = y_axis;
+ xcb_out.device_id = device_id;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_change_pointer_device_reply_t *
+xcb_input_change_pointer_device_reply (xcb_connection_t *c,
+ xcb_input_change_pointer_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_change_pointer_device_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_grab_device_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_grab_device_request_t *_aux = (xcb_input_grab_device_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_grab_device_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* classes */
+ xcb_block_len += _aux->num_classes * sizeof(xcb_input_event_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_event_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_grab_device_cookie_t
+xcb_input_grab_device (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ xcb_timestamp_t time,
+ uint16_t num_classes,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t owner_events,
+ uint8_t device_id,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GRAB_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_grab_device_cookie_t xcb_ret;
+ xcb_input_grab_device_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.time = time;
+ xcb_out.num_classes = num_classes;
+ xcb_out.this_device_mode = this_device_mode;
+ xcb_out.other_device_mode = other_device_mode;
+ xcb_out.owner_events = owner_events;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(uint32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_grab_device_cookie_t
+xcb_input_grab_device_unchecked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ xcb_timestamp_t time,
+ uint16_t num_classes,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t owner_events,
+ uint8_t device_id,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GRAB_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_grab_device_cookie_t xcb_ret;
+ xcb_input_grab_device_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.time = time;
+ xcb_out.num_classes = num_classes;
+ xcb_out.this_device_mode = this_device_mode;
+ xcb_out.other_device_mode = other_device_mode;
+ xcb_out.owner_events = owner_events;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(uint32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_grab_device_reply_t *
+xcb_input_grab_device_reply (xcb_connection_t *c,
+ xcb_input_grab_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_grab_device_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_void_cookie_t
+xcb_input_ungrab_device_checked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_UNGRAB_DEVICE,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_ungrab_device_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_ungrab_device (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_UNGRAB_DEVICE,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_ungrab_device_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_grab_device_key_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_grab_device_key_request_t *_aux = (xcb_input_grab_device_key_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_grab_device_key_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* classes */
+ xcb_block_len += _aux->num_classes * sizeof(xcb_input_event_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_event_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_grab_device_key_checked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint16_t num_classes,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t grabbed_device,
+ uint8_t key,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t owner_events,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GRAB_DEVICE_KEY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_grab_device_key_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.num_classes = num_classes;
+ xcb_out.modifiers = modifiers;
+ xcb_out.modifier_device = modifier_device;
+ xcb_out.grabbed_device = grabbed_device;
+ xcb_out.key = key;
+ xcb_out.this_device_mode = this_device_mode;
+ xcb_out.other_device_mode = other_device_mode;
+ xcb_out.owner_events = owner_events;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(xcb_input_event_class_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_grab_device_key (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint16_t num_classes,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t grabbed_device,
+ uint8_t key,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t owner_events,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GRAB_DEVICE_KEY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_grab_device_key_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.num_classes = num_classes;
+ xcb_out.modifiers = modifiers;
+ xcb_out.modifier_device = modifier_device;
+ xcb_out.grabbed_device = grabbed_device;
+ xcb_out.key = key;
+ xcb_out.this_device_mode = this_device_mode;
+ xcb_out.other_device_mode = other_device_mode;
+ xcb_out.owner_events = owner_events;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(xcb_input_event_class_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_event_class_t *
+xcb_input_grab_device_key_classes (const xcb_input_grab_device_key_request_t *R)
+{
+ return (xcb_input_event_class_t *) (R + 1);
+}
+
+int
+xcb_input_grab_device_key_classes_length (const xcb_input_grab_device_key_request_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_generic_iterator_t
+xcb_input_grab_device_key_classes_end (const xcb_input_grab_device_key_request_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_input_event_class_t *) (R + 1)) + (R->num_classes);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_void_cookie_t
+xcb_input_ungrab_device_key_checked (xcb_connection_t *c,
+ xcb_window_t grabWindow,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t key,
+ uint8_t grabbed_device)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_UNGRAB_DEVICE_KEY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_ungrab_device_key_request_t xcb_out;
+
+ xcb_out.grabWindow = grabWindow;
+ xcb_out.modifiers = modifiers;
+ xcb_out.modifier_device = modifier_device;
+ xcb_out.key = key;
+ xcb_out.grabbed_device = grabbed_device;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_ungrab_device_key (xcb_connection_t *c,
+ xcb_window_t grabWindow,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t key,
+ uint8_t grabbed_device)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_UNGRAB_DEVICE_KEY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_ungrab_device_key_request_t xcb_out;
+
+ xcb_out.grabWindow = grabWindow;
+ xcb_out.modifiers = modifiers;
+ xcb_out.modifier_device = modifier_device;
+ xcb_out.key = key;
+ xcb_out.grabbed_device = grabbed_device;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_grab_device_button_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_grab_device_button_request_t *_aux = (xcb_input_grab_device_button_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_grab_device_button_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* classes */
+ xcb_block_len += _aux->num_classes * sizeof(xcb_input_event_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_event_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_grab_device_button_checked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint8_t grabbed_device,
+ uint8_t modifier_device,
+ uint16_t num_classes,
+ uint16_t modifiers,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t button,
+ uint8_t owner_events,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GRAB_DEVICE_BUTTON,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_grab_device_button_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.grabbed_device = grabbed_device;
+ xcb_out.modifier_device = modifier_device;
+ xcb_out.num_classes = num_classes;
+ xcb_out.modifiers = modifiers;
+ xcb_out.this_device_mode = this_device_mode;
+ xcb_out.other_device_mode = other_device_mode;
+ xcb_out.button = button;
+ xcb_out.owner_events = owner_events;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(xcb_input_event_class_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_grab_device_button (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint8_t grabbed_device,
+ uint8_t modifier_device,
+ uint16_t num_classes,
+ uint16_t modifiers,
+ uint8_t this_device_mode,
+ uint8_t other_device_mode,
+ uint8_t button,
+ uint8_t owner_events,
+ const xcb_input_event_class_t *classes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GRAB_DEVICE_BUTTON,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_grab_device_button_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.grabbed_device = grabbed_device;
+ xcb_out.modifier_device = modifier_device;
+ xcb_out.num_classes = num_classes;
+ xcb_out.modifiers = modifiers;
+ xcb_out.this_device_mode = this_device_mode;
+ xcb_out.other_device_mode = other_device_mode;
+ xcb_out.button = button;
+ xcb_out.owner_events = owner_events;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_class_t classes */
+ xcb_parts[4].iov_base = (char *) classes;
+ xcb_parts[4].iov_len = num_classes * sizeof(xcb_input_event_class_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_event_class_t *
+xcb_input_grab_device_button_classes (const xcb_input_grab_device_button_request_t *R)
+{
+ return (xcb_input_event_class_t *) (R + 1);
+}
+
+int
+xcb_input_grab_device_button_classes_length (const xcb_input_grab_device_button_request_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_generic_iterator_t
+xcb_input_grab_device_button_classes_end (const xcb_input_grab_device_button_request_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_input_event_class_t *) (R + 1)) + (R->num_classes);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_void_cookie_t
+xcb_input_ungrab_device_button_checked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t button,
+ uint8_t grabbed_device)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_UNGRAB_DEVICE_BUTTON,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_ungrab_device_button_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.modifiers = modifiers;
+ xcb_out.modifier_device = modifier_device;
+ xcb_out.button = button;
+ xcb_out.grabbed_device = grabbed_device;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_ungrab_device_button (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint16_t modifiers,
+ uint8_t modifier_device,
+ uint8_t button,
+ uint8_t grabbed_device)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_UNGRAB_DEVICE_BUTTON,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_ungrab_device_button_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.modifiers = modifiers;
+ xcb_out.modifier_device = modifier_device;
+ xcb_out.button = button;
+ xcb_out.grabbed_device = grabbed_device;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_allow_device_events_checked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ uint8_t mode,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_ALLOW_DEVICE_EVENTS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_allow_device_events_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.mode = mode;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_allow_device_events (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ uint8_t mode,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_ALLOW_DEVICE_EVENTS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_allow_device_events_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.mode = mode;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_focus_cookie_t
+xcb_input_get_device_focus (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_FOCUS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_focus_cookie_t xcb_ret;
+ xcb_input_get_device_focus_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_focus_cookie_t
+xcb_input_get_device_focus_unchecked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_FOCUS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_focus_cookie_t xcb_ret;
+ xcb_input_get_device_focus_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_focus_reply_t *
+xcb_input_get_device_focus_reply (xcb_connection_t *c,
+ xcb_input_get_device_focus_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_device_focus_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_void_cookie_t
+xcb_input_set_device_focus_checked (xcb_connection_t *c,
+ xcb_window_t focus,
+ xcb_timestamp_t time,
+ uint8_t revert_to,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_FOCUS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_set_device_focus_request_t xcb_out;
+
+ xcb_out.focus = focus;
+ xcb_out.time = time;
+ xcb_out.revert_to = revert_to;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_set_device_focus (xcb_connection_t *c,
+ xcb_window_t focus,
+ xcb_timestamp_t time,
+ uint8_t revert_to,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_FOCUS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_set_device_focus_request_t xcb_out;
+
+ xcb_out.focus = focus;
+ xcb_out.time = time;
+ xcb_out.revert_to = revert_to;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+void
+xcb_input_kbd_feedback_state_next (xcb_input_kbd_feedback_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_kbd_feedback_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_kbd_feedback_state_end (xcb_input_kbd_feedback_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_ptr_feedback_state_next (xcb_input_ptr_feedback_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_ptr_feedback_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_ptr_feedback_state_end (xcb_input_ptr_feedback_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_integer_feedback_state_next (xcb_input_integer_feedback_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_integer_feedback_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_integer_feedback_state_end (xcb_input_integer_feedback_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_string_feedback_state_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_string_feedback_state_t *_aux = (xcb_input_string_feedback_state_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_string_feedback_state_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* keysyms */
+ xcb_block_len += _aux->num_keysyms * sizeof(xcb_keysym_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_keysym_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_keysym_t *
+xcb_input_string_feedback_state_keysyms (const xcb_input_string_feedback_state_t *R)
+{
+ return (xcb_keysym_t *) (R + 1);
+}
+
+int
+xcb_input_string_feedback_state_keysyms_length (const xcb_input_string_feedback_state_t *R)
+{
+ return R->num_keysyms;
+}
+
+xcb_generic_iterator_t
+xcb_input_string_feedback_state_keysyms_end (const xcb_input_string_feedback_state_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_keysym_t *) (R + 1)) + (R->num_keysyms);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_string_feedback_state_next (xcb_input_string_feedback_state_iterator_t *i)
+{
+ xcb_input_string_feedback_state_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_string_feedback_state_t *)(((char *)R) + xcb_input_string_feedback_state_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_string_feedback_state_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_string_feedback_state_end (xcb_input_string_feedback_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_string_feedback_state_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+void
+xcb_input_bell_feedback_state_next (xcb_input_bell_feedback_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_bell_feedback_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_bell_feedback_state_end (xcb_input_bell_feedback_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_led_feedback_state_next (xcb_input_led_feedback_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_led_feedback_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_led_feedback_state_end (xcb_input_led_feedback_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+xcb_keysym_t *
+xcb_input_feedback_state_data_string_keysyms (const xcb_input_feedback_state_data_t *S)
+{
+ return S->string.keysyms;
+}
+
+int
+xcb_input_feedback_state_data_string_keysyms_length (const xcb_input_feedback_state_t *R,
+ const xcb_input_feedback_state_data_t *S)
+{
+ return S->string.num_keysyms;
+}
+
+xcb_generic_iterator_t
+xcb_input_feedback_state_data_string_keysyms_end (const xcb_input_feedback_state_t *R,
+ const xcb_input_feedback_state_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->string.keysyms + S->string.num_keysyms;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_feedback_state_data_serialize (void **_buffer,
+ uint8_t class_id,
+ const xcb_input_feedback_state_data_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[27];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_KEYBOARD) {
+ /* xcb_input_feedback_state_data_t.keyboard.pitch */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.pitch;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.keyboard.duration */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.duration;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.keyboard.led_mask */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.led_mask;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_state_data_t.keyboard.led_values */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.led_values;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_state_data_t.keyboard.global_auto_repeat */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.global_auto_repeat;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.keyboard.click */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.click;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.keyboard.percent */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.percent;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.keyboard.pad0 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &xcb_pad;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.keyboard.auto_repeats */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->keyboard.auto_repeats;
+ xcb_block_len += 32;
+ xcb_parts[xcb_parts_idx].iov_len = 32;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_POINTER) {
+ /* xcb_input_feedback_state_data_t.pointer.pad1 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*2;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*2;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.pointer.accel_num */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->pointer.accel_num;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.pointer.accel_denom */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->pointer.accel_denom;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.pointer.threshold */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->pointer.threshold;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_STRING) {
+ /* xcb_input_feedback_state_data_t.string.max_symbols */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->string.max_symbols;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.string.num_keysyms */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->string.num_keysyms;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* keysyms */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->string.keysyms;
+ xcb_block_len += _aux->string.num_keysyms * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->string.num_keysyms * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_keysym_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_INTEGER) {
+ /* xcb_input_feedback_state_data_t.integer.resolution */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->integer.resolution;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_state_data_t.integer.min_value */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->integer.min_value;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_feedback_state_data_t.integer.max_value */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->integer.max_value;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_LED) {
+ /* xcb_input_feedback_state_data_t.led.led_mask */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->led.led_mask;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_state_data_t.led.led_values */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->led.led_values;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_BELL) {
+ /* xcb_input_feedback_state_data_t.bell.percent */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->bell.percent;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.bell.pad2 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*3;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*3;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.bell.pitch */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->bell.pitch;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.bell.duration */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->bell.duration;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_feedback_state_data_unpack (const void *_buffer,
+ uint8_t class_id,
+ xcb_input_feedback_state_data_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_KEYBOARD) {
+ /* xcb_input_feedback_state_data_t.keyboard.pitch */
+ _aux->keyboard.pitch = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.keyboard.duration */
+ _aux->keyboard.duration = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.keyboard.led_mask */
+ _aux->keyboard.led_mask = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_state_data_t.keyboard.led_values */
+ _aux->keyboard.led_values = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_state_data_t.keyboard.global_auto_repeat */
+ _aux->keyboard.global_auto_repeat = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.keyboard.click */
+ _aux->keyboard.click = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.keyboard.percent */
+ _aux->keyboard.percent = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.keyboard.pad0 */
+ _aux->keyboard.pad0 = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.keyboard.auto_repeats */
+ memcpy(_aux->keyboard.auto_repeats, xcb_tmp, sizeof(uint8_t) * 32);
+ xcb_block_len += sizeof(uint8_t) * 32;
+ xcb_tmp += sizeof(uint8_t) * 32;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_POINTER) {
+ /* xcb_input_feedback_state_data_t.pointer.pad1 */
+ _aux->pointer.pad1[0] = *(uint8_t *)xcb_tmp;
+ _aux->pointer.pad1[1] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 2;
+ xcb_tmp += sizeof(uint8_t) * 2;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.pointer.accel_num */
+ _aux->pointer.accel_num = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.pointer.accel_denom */
+ _aux->pointer.accel_denom = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.pointer.threshold */
+ _aux->pointer.threshold = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_STRING) {
+ /* xcb_input_feedback_state_data_t.string.max_symbols */
+ _aux->string.max_symbols = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.string.num_keysyms */
+ _aux->string.num_keysyms = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* keysyms */
+ _aux->string.keysyms = (xcb_keysym_t *)xcb_tmp;
+ xcb_block_len += _aux->string.num_keysyms * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_keysym_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_INTEGER) {
+ /* xcb_input_feedback_state_data_t.integer.resolution */
+ _aux->integer.resolution = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_state_data_t.integer.min_value */
+ _aux->integer.min_value = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_feedback_state_data_t.integer.max_value */
+ _aux->integer.max_value = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_LED) {
+ /* xcb_input_feedback_state_data_t.led.led_mask */
+ _aux->led.led_mask = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_state_data_t.led.led_values */
+ _aux->led.led_values = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_BELL) {
+ /* xcb_input_feedback_state_data_t.bell.percent */
+ _aux->bell.percent = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.bell.pad2 */
+ _aux->bell.pad2[0] = *(uint8_t *)xcb_tmp;
+ _aux->bell.pad2[1] = *(uint8_t *)xcb_tmp;
+ _aux->bell.pad2[2] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 3;
+ xcb_tmp += sizeof(uint8_t) * 3;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_state_data_t.bell.pitch */
+ _aux->bell.pitch = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_feedback_state_data_t.bell.duration */
+ _aux->bell.duration = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_feedback_state_data_sizeof (const void *_buffer,
+ uint8_t class_id)
+{
+ xcb_input_feedback_state_data_t _aux;
+ return xcb_input_feedback_state_data_unpack(_buffer, class_id, &_aux);
+}
+
+int
+xcb_input_feedback_state_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_feedback_state_t *_aux = (xcb_input_feedback_state_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_feedback_state_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* data */
+ xcb_block_len += xcb_input_feedback_state_data_sizeof(xcb_tmp, _aux->class_id);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+void *
+xcb_input_feedback_state_data (const xcb_input_feedback_state_t *R)
+{
+ return (void *) (R + 1);
+}
+
+void
+xcb_input_feedback_state_next (xcb_input_feedback_state_iterator_t *i)
+{
+ xcb_input_feedback_state_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_feedback_state_t *)(((char *)R) + xcb_input_feedback_state_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_feedback_state_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_feedback_state_end (xcb_input_feedback_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_feedback_state_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_get_feedback_control_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_feedback_control_reply_t *_aux = (xcb_input_get_feedback_control_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_get_feedback_control_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* feedbacks */
+ for(i=0; i<_aux->num_feedbacks; i++) {
+ xcb_tmp_len = xcb_input_feedback_state_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_feedback_state_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_feedback_control_cookie_t
+xcb_input_get_feedback_control (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_FEEDBACK_CONTROL,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_feedback_control_cookie_t xcb_ret;
+ xcb_input_get_feedback_control_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_feedback_control_cookie_t
+xcb_input_get_feedback_control_unchecked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_FEEDBACK_CONTROL,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_feedback_control_cookie_t xcb_ret;
+ xcb_input_get_feedback_control_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_get_feedback_control_feedbacks_length (const xcb_input_get_feedback_control_reply_t *R)
+{
+ return R->num_feedbacks;
+}
+
+xcb_input_feedback_state_iterator_t
+xcb_input_get_feedback_control_feedbacks_iterator (const xcb_input_get_feedback_control_reply_t *R)
+{
+ xcb_input_feedback_state_iterator_t i;
+ i.data = (xcb_input_feedback_state_t *) (R + 1);
+ i.rem = R->num_feedbacks;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_get_feedback_control_reply_t *
+xcb_input_get_feedback_control_reply (xcb_connection_t *c,
+ xcb_input_get_feedback_control_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_feedback_control_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+void
+xcb_input_kbd_feedback_ctl_next (xcb_input_kbd_feedback_ctl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_kbd_feedback_ctl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_kbd_feedback_ctl_end (xcb_input_kbd_feedback_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_ptr_feedback_ctl_next (xcb_input_ptr_feedback_ctl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_ptr_feedback_ctl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_ptr_feedback_ctl_end (xcb_input_ptr_feedback_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_integer_feedback_ctl_next (xcb_input_integer_feedback_ctl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_integer_feedback_ctl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_integer_feedback_ctl_end (xcb_input_integer_feedback_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_string_feedback_ctl_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_string_feedback_ctl_t *_aux = (xcb_input_string_feedback_ctl_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_string_feedback_ctl_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* keysyms */
+ xcb_block_len += _aux->num_keysyms * sizeof(xcb_keysym_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_keysym_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_keysym_t *
+xcb_input_string_feedback_ctl_keysyms (const xcb_input_string_feedback_ctl_t *R)
+{
+ return (xcb_keysym_t *) (R + 1);
+}
+
+int
+xcb_input_string_feedback_ctl_keysyms_length (const xcb_input_string_feedback_ctl_t *R)
+{
+ return R->num_keysyms;
+}
+
+xcb_generic_iterator_t
+xcb_input_string_feedback_ctl_keysyms_end (const xcb_input_string_feedback_ctl_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_keysym_t *) (R + 1)) + (R->num_keysyms);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_string_feedback_ctl_next (xcb_input_string_feedback_ctl_iterator_t *i)
+{
+ xcb_input_string_feedback_ctl_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_string_feedback_ctl_t *)(((char *)R) + xcb_input_string_feedback_ctl_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_string_feedback_ctl_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_string_feedback_ctl_end (xcb_input_string_feedback_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_string_feedback_ctl_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+void
+xcb_input_bell_feedback_ctl_next (xcb_input_bell_feedback_ctl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_bell_feedback_ctl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_bell_feedback_ctl_end (xcb_input_bell_feedback_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_led_feedback_ctl_next (xcb_input_led_feedback_ctl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_led_feedback_ctl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_led_feedback_ctl_end (xcb_input_led_feedback_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+xcb_keysym_t *
+xcb_input_feedback_ctl_data_string_keysyms (const xcb_input_feedback_ctl_data_t *S)
+{
+ return S->string.keysyms;
+}
+
+int
+xcb_input_feedback_ctl_data_string_keysyms_length (const xcb_input_feedback_ctl_t *R,
+ const xcb_input_feedback_ctl_data_t *S)
+{
+ return S->string.num_keysyms;
+}
+
+xcb_generic_iterator_t
+xcb_input_feedback_ctl_data_string_keysyms_end (const xcb_input_feedback_ctl_t *R,
+ const xcb_input_feedback_ctl_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->string.keysyms + S->string.num_keysyms;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_feedback_ctl_data_serialize (void **_buffer,
+ uint8_t class_id,
+ const xcb_input_feedback_ctl_data_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[24];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_KEYBOARD) {
+ /* xcb_input_feedback_ctl_data_t.keyboard.key */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.key;
+ xcb_block_len += sizeof(xcb_input_key_code_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_key_code_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_key_code_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.auto_repeat_mode */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.auto_repeat_mode;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.key_click_percent */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.key_click_percent;
+ xcb_block_len += sizeof(int8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int8_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.bell_percent */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.bell_percent;
+ xcb_block_len += sizeof(int8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int8_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.bell_pitch */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.bell_pitch;
+ xcb_block_len += sizeof(int16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.bell_duration */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.bell_duration;
+ xcb_block_len += sizeof(int16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.led_mask */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.led_mask;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.led_values */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->keyboard.led_values;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_POINTER) {
+ /* xcb_input_feedback_ctl_data_t.pointer.pad0 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*2;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*2;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_ctl_data_t.pointer.num */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->pointer.num;
+ xcb_block_len += sizeof(int16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.pointer.denom */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->pointer.denom;
+ xcb_block_len += sizeof(int16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.pointer.threshold */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->pointer.threshold;
+ xcb_block_len += sizeof(int16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int16_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_STRING) {
+ /* xcb_input_feedback_ctl_data_t.string.pad1 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*2;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*2;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_ctl_data_t.string.num_keysyms */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->string.num_keysyms;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* keysyms */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->string.keysyms;
+ xcb_block_len += _aux->string.num_keysyms * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->string.num_keysyms * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_keysym_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_INTEGER) {
+ /* xcb_input_feedback_ctl_data_t.integer.int_to_display */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->integer.int_to_display;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_LED) {
+ /* xcb_input_feedback_ctl_data_t.led.led_mask */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->led.led_mask;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_ctl_data_t.led.led_values */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->led.led_values;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_BELL) {
+ /* xcb_input_feedback_ctl_data_t.bell.percent */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->bell.percent;
+ xcb_block_len += sizeof(int8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int8_t);
+ /* xcb_input_feedback_ctl_data_t.bell.pad2 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*3;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*3;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_ctl_data_t.bell.pitch */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->bell.pitch;
+ xcb_block_len += sizeof(int16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.bell.duration */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->bell.duration;
+ xcb_block_len += sizeof(int16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int16_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_feedback_ctl_data_unpack (const void *_buffer,
+ uint8_t class_id,
+ xcb_input_feedback_ctl_data_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_KEYBOARD) {
+ /* xcb_input_feedback_ctl_data_t.keyboard.key */
+ _aux->keyboard.key = *(xcb_input_key_code_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_key_code_t);
+ xcb_tmp += sizeof(xcb_input_key_code_t);
+ xcb_align_to = ALIGNOF(xcb_input_key_code_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.auto_repeat_mode */
+ _aux->keyboard.auto_repeat_mode = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.key_click_percent */
+ _aux->keyboard.key_click_percent = *(int8_t *)xcb_tmp;
+ xcb_block_len += sizeof(int8_t);
+ xcb_tmp += sizeof(int8_t);
+ xcb_align_to = ALIGNOF(int8_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.bell_percent */
+ _aux->keyboard.bell_percent = *(int8_t *)xcb_tmp;
+ xcb_block_len += sizeof(int8_t);
+ xcb_tmp += sizeof(int8_t);
+ xcb_align_to = ALIGNOF(int8_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.bell_pitch */
+ _aux->keyboard.bell_pitch = *(int16_t *)xcb_tmp;
+ xcb_block_len += sizeof(int16_t);
+ xcb_tmp += sizeof(int16_t);
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.bell_duration */
+ _aux->keyboard.bell_duration = *(int16_t *)xcb_tmp;
+ xcb_block_len += sizeof(int16_t);
+ xcb_tmp += sizeof(int16_t);
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.led_mask */
+ _aux->keyboard.led_mask = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_ctl_data_t.keyboard.led_values */
+ _aux->keyboard.led_values = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_POINTER) {
+ /* xcb_input_feedback_ctl_data_t.pointer.pad0 */
+ _aux->pointer.pad0[0] = *(uint8_t *)xcb_tmp;
+ _aux->pointer.pad0[1] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 2;
+ xcb_tmp += sizeof(uint8_t) * 2;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_ctl_data_t.pointer.num */
+ _aux->pointer.num = *(int16_t *)xcb_tmp;
+ xcb_block_len += sizeof(int16_t);
+ xcb_tmp += sizeof(int16_t);
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.pointer.denom */
+ _aux->pointer.denom = *(int16_t *)xcb_tmp;
+ xcb_block_len += sizeof(int16_t);
+ xcb_tmp += sizeof(int16_t);
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.pointer.threshold */
+ _aux->pointer.threshold = *(int16_t *)xcb_tmp;
+ xcb_block_len += sizeof(int16_t);
+ xcb_tmp += sizeof(int16_t);
+ xcb_align_to = ALIGNOF(int16_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_STRING) {
+ /* xcb_input_feedback_ctl_data_t.string.pad1 */
+ _aux->string.pad1[0] = *(uint8_t *)xcb_tmp;
+ _aux->string.pad1[1] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 2;
+ xcb_tmp += sizeof(uint8_t) * 2;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_ctl_data_t.string.num_keysyms */
+ _aux->string.num_keysyms = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* keysyms */
+ _aux->string.keysyms = (xcb_keysym_t *)xcb_tmp;
+ xcb_block_len += _aux->string.num_keysyms * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_keysym_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_INTEGER) {
+ /* xcb_input_feedback_ctl_data_t.integer.int_to_display */
+ _aux->integer.int_to_display = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_LED) {
+ /* xcb_input_feedback_ctl_data_t.led.led_mask */
+ _aux->led.led_mask = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_feedback_ctl_data_t.led.led_values */
+ _aux->led.led_values = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(class_id == XCB_INPUT_FEEDBACK_CLASS_BELL) {
+ /* xcb_input_feedback_ctl_data_t.bell.percent */
+ _aux->bell.percent = *(int8_t *)xcb_tmp;
+ xcb_block_len += sizeof(int8_t);
+ xcb_tmp += sizeof(int8_t);
+ xcb_align_to = ALIGNOF(int8_t);
+ /* xcb_input_feedback_ctl_data_t.bell.pad2 */
+ _aux->bell.pad2[0] = *(uint8_t *)xcb_tmp;
+ _aux->bell.pad2[1] = *(uint8_t *)xcb_tmp;
+ _aux->bell.pad2[2] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 3;
+ xcb_tmp += sizeof(uint8_t) * 3;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_feedback_ctl_data_t.bell.pitch */
+ _aux->bell.pitch = *(int16_t *)xcb_tmp;
+ xcb_block_len += sizeof(int16_t);
+ xcb_tmp += sizeof(int16_t);
+ xcb_align_to = ALIGNOF(int16_t);
+ /* xcb_input_feedback_ctl_data_t.bell.duration */
+ _aux->bell.duration = *(int16_t *)xcb_tmp;
+ xcb_block_len += sizeof(int16_t);
+ xcb_tmp += sizeof(int16_t);
+ xcb_align_to = ALIGNOF(int16_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_feedback_ctl_data_sizeof (const void *_buffer,
+ uint8_t class_id)
+{
+ xcb_input_feedback_ctl_data_t _aux;
+ return xcb_input_feedback_ctl_data_unpack(_buffer, class_id, &_aux);
+}
+
+int
+xcb_input_feedback_ctl_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_feedback_ctl_t *_aux = (xcb_input_feedback_ctl_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_feedback_ctl_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* data */
+ xcb_block_len += xcb_input_feedback_ctl_data_sizeof(xcb_tmp, _aux->class_id);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+void *
+xcb_input_feedback_ctl_data (const xcb_input_feedback_ctl_t *R)
+{
+ return (void *) (R + 1);
+}
+
+void
+xcb_input_feedback_ctl_next (xcb_input_feedback_ctl_iterator_t *i)
+{
+ xcb_input_feedback_ctl_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_feedback_ctl_t *)(((char *)R) + xcb_input_feedback_ctl_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_feedback_ctl_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_feedback_ctl_end (xcb_input_feedback_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_feedback_ctl_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_change_feedback_control_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_change_feedback_control_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* feedback */
+ xcb_block_len += xcb_input_feedback_ctl_sizeof(xcb_tmp);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_feedback_ctl_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_change_feedback_control_checked (xcb_connection_t *c,
+ uint32_t mask,
+ uint8_t device_id,
+ uint8_t feedback_id,
+ xcb_input_feedback_ctl_t *feedback)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_FEEDBACK_CONTROL,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_feedback_control_request_t xcb_out;
+
+ xcb_out.mask = mask;
+ xcb_out.device_id = device_id;
+ xcb_out.feedback_id = feedback_id;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_feedback_ctl_t feedback */
+ xcb_parts[4].iov_base = (char *) feedback;
+ xcb_parts[4].iov_len =
+ xcb_input_feedback_ctl_sizeof (feedback);
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_change_feedback_control (xcb_connection_t *c,
+ uint32_t mask,
+ uint8_t device_id,
+ uint8_t feedback_id,
+ xcb_input_feedback_ctl_t *feedback)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_FEEDBACK_CONTROL,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_feedback_control_request_t xcb_out;
+
+ xcb_out.mask = mask;
+ xcb_out.device_id = device_id;
+ xcb_out.feedback_id = feedback_id;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_feedback_ctl_t feedback */
+ xcb_parts[4].iov_base = (char *) feedback;
+ xcb_parts[4].iov_len =
+ xcb_input_feedback_ctl_sizeof (feedback);
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_feedback_ctl_t *
+xcb_input_change_feedback_control_feedback (const xcb_input_change_feedback_control_request_t *R)
+{
+ return (xcb_input_feedback_ctl_t *) (R + 1);
+}
+
+int
+xcb_input_get_device_key_mapping_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_device_key_mapping_reply_t *_aux = (xcb_input_get_device_key_mapping_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_get_device_key_mapping_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* keysyms */
+ xcb_block_len += _aux->length * sizeof(xcb_keysym_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_keysym_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_device_key_mapping_cookie_t
+xcb_input_get_device_key_mapping (xcb_connection_t *c,
+ uint8_t device_id,
+ xcb_input_key_code_t first_keycode,
+ uint8_t count)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_KEY_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_key_mapping_cookie_t xcb_ret;
+ xcb_input_get_device_key_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.first_keycode = first_keycode;
+ xcb_out.count = count;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_key_mapping_cookie_t
+xcb_input_get_device_key_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ xcb_input_key_code_t first_keycode,
+ uint8_t count)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_KEY_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_key_mapping_cookie_t xcb_ret;
+ xcb_input_get_device_key_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.first_keycode = first_keycode;
+ xcb_out.count = count;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_keysym_t *
+xcb_input_get_device_key_mapping_keysyms (const xcb_input_get_device_key_mapping_reply_t *R)
+{
+ return (xcb_keysym_t *) (R + 1);
+}
+
+int
+xcb_input_get_device_key_mapping_keysyms_length (const xcb_input_get_device_key_mapping_reply_t *R)
+{
+ return R->length;
+}
+
+xcb_generic_iterator_t
+xcb_input_get_device_key_mapping_keysyms_end (const xcb_input_get_device_key_mapping_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_keysym_t *) (R + 1)) + (R->length);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_get_device_key_mapping_reply_t *
+xcb_input_get_device_key_mapping_reply (xcb_connection_t *c,
+ xcb_input_get_device_key_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_device_key_mapping_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_change_device_key_mapping_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_change_device_key_mapping_request_t *_aux = (xcb_input_change_device_key_mapping_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_change_device_key_mapping_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* keysyms */
+ xcb_block_len += (_aux->keycode_count * _aux->keysyms_per_keycode) * sizeof(xcb_keysym_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_keysym_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_change_device_key_mapping_checked (xcb_connection_t *c,
+ uint8_t device_id,
+ xcb_input_key_code_t first_keycode,
+ uint8_t keysyms_per_keycode,
+ uint8_t keycode_count,
+ const xcb_keysym_t *keysyms)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_KEY_MAPPING,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_device_key_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.first_keycode = first_keycode;
+ xcb_out.keysyms_per_keycode = keysyms_per_keycode;
+ xcb_out.keycode_count = keycode_count;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_keysym_t keysyms */
+ xcb_parts[4].iov_base = (char *) keysyms;
+ xcb_parts[4].iov_len = (keycode_count * keysyms_per_keycode) * sizeof(xcb_keysym_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_change_device_key_mapping (xcb_connection_t *c,
+ uint8_t device_id,
+ xcb_input_key_code_t first_keycode,
+ uint8_t keysyms_per_keycode,
+ uint8_t keycode_count,
+ const xcb_keysym_t *keysyms)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_KEY_MAPPING,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_device_key_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.first_keycode = first_keycode;
+ xcb_out.keysyms_per_keycode = keysyms_per_keycode;
+ xcb_out.keycode_count = keycode_count;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_keysym_t keysyms */
+ xcb_parts[4].iov_base = (char *) keysyms;
+ xcb_parts[4].iov_len = (keycode_count * keysyms_per_keycode) * sizeof(xcb_keysym_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_keysym_t *
+xcb_input_change_device_key_mapping_keysyms (const xcb_input_change_device_key_mapping_request_t *R)
+{
+ return (xcb_keysym_t *) (R + 1);
+}
+
+int
+xcb_input_change_device_key_mapping_keysyms_length (const xcb_input_change_device_key_mapping_request_t *R)
+{
+ return (R->keycode_count * R->keysyms_per_keycode);
+}
+
+xcb_generic_iterator_t
+xcb_input_change_device_key_mapping_keysyms_end (const xcb_input_change_device_key_mapping_request_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_keysym_t *) (R + 1)) + ((R->keycode_count * R->keysyms_per_keycode));
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_get_device_modifier_mapping_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_device_modifier_mapping_reply_t *_aux = (xcb_input_get_device_modifier_mapping_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_get_device_modifier_mapping_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* keymaps */
+ xcb_block_len += (_aux->keycodes_per_modifier * 8) * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_device_modifier_mapping_cookie_t
+xcb_input_get_device_modifier_mapping (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_MODIFIER_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_modifier_mapping_cookie_t xcb_ret;
+ xcb_input_get_device_modifier_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_modifier_mapping_cookie_t
+xcb_input_get_device_modifier_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_MODIFIER_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_modifier_mapping_cookie_t xcb_ret;
+ xcb_input_get_device_modifier_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+uint8_t *
+xcb_input_get_device_modifier_mapping_keymaps (const xcb_input_get_device_modifier_mapping_reply_t *R)
+{
+ return (uint8_t *) (R + 1);
+}
+
+int
+xcb_input_get_device_modifier_mapping_keymaps_length (const xcb_input_get_device_modifier_mapping_reply_t *R)
+{
+ return (R->keycodes_per_modifier * 8);
+}
+
+xcb_generic_iterator_t
+xcb_input_get_device_modifier_mapping_keymaps_end (const xcb_input_get_device_modifier_mapping_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint8_t *) (R + 1)) + ((R->keycodes_per_modifier * 8));
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_get_device_modifier_mapping_reply_t *
+xcb_input_get_device_modifier_mapping_reply (xcb_connection_t *c,
+ xcb_input_get_device_modifier_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_device_modifier_mapping_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_set_device_modifier_mapping_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_set_device_modifier_mapping_request_t *_aux = (xcb_input_set_device_modifier_mapping_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_set_device_modifier_mapping_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* keymaps */
+ xcb_block_len += (_aux->keycodes_per_modifier * 8) * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_set_device_modifier_mapping_cookie_t
+xcb_input_set_device_modifier_mapping (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t keycodes_per_modifier,
+ const uint8_t *keymaps)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_MODIFIER_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_set_device_modifier_mapping_cookie_t xcb_ret;
+ xcb_input_set_device_modifier_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.keycodes_per_modifier = keycodes_per_modifier;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t keymaps */
+ xcb_parts[4].iov_base = (char *) keymaps;
+ xcb_parts[4].iov_len = (keycodes_per_modifier * 8) * sizeof(uint8_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_modifier_mapping_cookie_t
+xcb_input_set_device_modifier_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t keycodes_per_modifier,
+ const uint8_t *keymaps)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_MODIFIER_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_set_device_modifier_mapping_cookie_t xcb_ret;
+ xcb_input_set_device_modifier_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.keycodes_per_modifier = keycodes_per_modifier;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t keymaps */
+ xcb_parts[4].iov_base = (char *) keymaps;
+ xcb_parts[4].iov_len = (keycodes_per_modifier * 8) * sizeof(uint8_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_modifier_mapping_reply_t *
+xcb_input_set_device_modifier_mapping_reply (xcb_connection_t *c,
+ xcb_input_set_device_modifier_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_set_device_modifier_mapping_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_get_device_button_mapping_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_device_button_mapping_reply_t *_aux = (xcb_input_get_device_button_mapping_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_get_device_button_mapping_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* map */
+ xcb_block_len += _aux->map_size * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_device_button_mapping_cookie_t
+xcb_input_get_device_button_mapping (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_BUTTON_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_button_mapping_cookie_t xcb_ret;
+ xcb_input_get_device_button_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_button_mapping_cookie_t
+xcb_input_get_device_button_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_BUTTON_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_button_mapping_cookie_t xcb_ret;
+ xcb_input_get_device_button_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+uint8_t *
+xcb_input_get_device_button_mapping_map (const xcb_input_get_device_button_mapping_reply_t *R)
+{
+ return (uint8_t *) (R + 1);
+}
+
+int
+xcb_input_get_device_button_mapping_map_length (const xcb_input_get_device_button_mapping_reply_t *R)
+{
+ return R->map_size;
+}
+
+xcb_generic_iterator_t
+xcb_input_get_device_button_mapping_map_end (const xcb_input_get_device_button_mapping_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint8_t *) (R + 1)) + (R->map_size);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_get_device_button_mapping_reply_t *
+xcb_input_get_device_button_mapping_reply (xcb_connection_t *c,
+ xcb_input_get_device_button_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_device_button_mapping_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_set_device_button_mapping_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_set_device_button_mapping_request_t *_aux = (xcb_input_set_device_button_mapping_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_set_device_button_mapping_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* map */
+ xcb_block_len += _aux->map_size * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_set_device_button_mapping_cookie_t
+xcb_input_set_device_button_mapping (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t map_size,
+ const uint8_t *map)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_BUTTON_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_set_device_button_mapping_cookie_t xcb_ret;
+ xcb_input_set_device_button_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.map_size = map_size;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t map */
+ xcb_parts[4].iov_base = (char *) map;
+ xcb_parts[4].iov_len = map_size * sizeof(uint8_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_button_mapping_cookie_t
+xcb_input_set_device_button_mapping_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t map_size,
+ const uint8_t *map)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_BUTTON_MAPPING,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_set_device_button_mapping_cookie_t xcb_ret;
+ xcb_input_set_device_button_mapping_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.map_size = map_size;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint8_t map */
+ xcb_parts[4].iov_base = (char *) map;
+ xcb_parts[4].iov_len = map_size * sizeof(uint8_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_button_mapping_reply_t *
+xcb_input_set_device_button_mapping_reply (xcb_connection_t *c,
+ xcb_input_set_device_button_mapping_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_set_device_button_mapping_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+void
+xcb_input_key_state_next (xcb_input_key_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_key_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_key_state_end (xcb_input_key_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_button_state_next (xcb_input_button_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_button_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_button_state_end (xcb_input_button_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_valuator_state_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_valuator_state_t *_aux = (xcb_input_valuator_state_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_valuator_state_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* valuators */
+ xcb_block_len += _aux->num_valuators * sizeof(int32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+int32_t *
+xcb_input_valuator_state_valuators (const xcb_input_valuator_state_t *R)
+{
+ return (int32_t *) (R + 1);
+}
+
+int
+xcb_input_valuator_state_valuators_length (const xcb_input_valuator_state_t *R)
+{
+ return R->num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_valuator_state_valuators_end (const xcb_input_valuator_state_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((int32_t *) (R + 1)) + (R->num_valuators);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_valuator_state_next (xcb_input_valuator_state_iterator_t *i)
+{
+ xcb_input_valuator_state_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_valuator_state_t *)(((char *)R) + xcb_input_valuator_state_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_valuator_state_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_valuator_state_end (xcb_input_valuator_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_valuator_state_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int32_t *
+xcb_input_input_state_data_valuator_valuators (const xcb_input_input_state_data_t *S)
+{
+ return S->valuator.valuators;
+}
+
+int
+xcb_input_input_state_data_valuator_valuators_length (const xcb_input_input_state_t *R,
+ const xcb_input_input_state_data_t *S)
+{
+ return S->valuator.num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_input_state_data_valuator_valuators_end (const xcb_input_input_state_t *R,
+ const xcb_input_input_state_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->valuator.valuators + S->valuator.num_valuators;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_input_state_data_serialize (void **_buffer,
+ uint8_t class_id,
+ const xcb_input_input_state_data_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 2;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[11];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(class_id == XCB_INPUT_INPUT_CLASS_KEY) {
+ /* xcb_input_input_state_data_t.key.num_keys */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->key.num_keys;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.key.pad0 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &xcb_pad;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.key.keys */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->key.keys;
+ xcb_block_len += 32;
+ xcb_parts[xcb_parts_idx].iov_len = 32;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(class_id == XCB_INPUT_INPUT_CLASS_BUTTON) {
+ /* xcb_input_input_state_data_t.button.num_buttons */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->button.num_buttons;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.button.pad1 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &xcb_pad;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.button.buttons */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->button.buttons;
+ xcb_block_len += 32;
+ xcb_parts[xcb_parts_idx].iov_len = 32;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(class_id == XCB_INPUT_INPUT_CLASS_VALUATOR) {
+ /* xcb_input_input_state_data_t.valuator.num_valuators */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.num_valuators;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.valuator.mode */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.mode;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* valuators */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->valuator.valuators;
+ xcb_block_len += _aux->valuator.num_valuators * sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->valuator.num_valuators * sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_input_state_data_unpack (const void *_buffer,
+ uint8_t class_id,
+ xcb_input_input_state_data_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 2;
+
+
+ if(class_id == XCB_INPUT_INPUT_CLASS_KEY) {
+ /* xcb_input_input_state_data_t.key.num_keys */
+ _aux->key.num_keys = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.key.pad0 */
+ _aux->key.pad0 = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.key.keys */
+ memcpy(_aux->key.keys, xcb_tmp, sizeof(uint8_t) * 32);
+ xcb_block_len += sizeof(uint8_t) * 32;
+ xcb_tmp += sizeof(uint8_t) * 32;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(class_id == XCB_INPUT_INPUT_CLASS_BUTTON) {
+ /* xcb_input_input_state_data_t.button.num_buttons */
+ _aux->button.num_buttons = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.button.pad1 */
+ _aux->button.pad1 = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.button.buttons */
+ memcpy(_aux->button.buttons, xcb_tmp, sizeof(uint8_t) * 32);
+ xcb_block_len += sizeof(uint8_t) * 32;
+ xcb_tmp += sizeof(uint8_t) * 32;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(class_id == XCB_INPUT_INPUT_CLASS_VALUATOR) {
+ /* xcb_input_input_state_data_t.valuator.num_valuators */
+ _aux->valuator.num_valuators = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_input_state_data_t.valuator.mode */
+ _aux->valuator.mode = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* valuators */
+ _aux->valuator.valuators = (int32_t *)xcb_tmp;
+ xcb_block_len += _aux->valuator.num_valuators * sizeof(int32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(int32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_input_state_data_sizeof (const void *_buffer,
+ uint8_t class_id)
+{
+ xcb_input_input_state_data_t _aux;
+ return xcb_input_input_state_data_unpack(_buffer, class_id, &_aux);
+}
+
+int
+xcb_input_input_state_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_input_state_t *_aux = (xcb_input_input_state_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_input_state_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* data */
+ xcb_block_len += xcb_input_input_state_data_sizeof(xcb_tmp, _aux->class_id);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+void *
+xcb_input_input_state_data (const xcb_input_input_state_t *R)
+{
+ return (void *) (R + 1);
+}
+
+void
+xcb_input_input_state_next (xcb_input_input_state_iterator_t *i)
+{
+ xcb_input_input_state_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_input_state_t *)(((char *)R) + xcb_input_input_state_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_input_state_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_input_state_end (xcb_input_input_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_input_state_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_query_device_state_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_query_device_state_reply_t *_aux = (xcb_input_query_device_state_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_query_device_state_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* classes */
+ for(i=0; i<_aux->num_classes; i++) {
+ xcb_tmp_len = xcb_input_input_state_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_input_state_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_query_device_state_cookie_t
+xcb_input_query_device_state (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_QUERY_DEVICE_STATE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_query_device_state_cookie_t xcb_ret;
+ xcb_input_query_device_state_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_query_device_state_cookie_t
+xcb_input_query_device_state_unchecked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_QUERY_DEVICE_STATE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_query_device_state_cookie_t xcb_ret;
+ xcb_input_query_device_state_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_query_device_state_classes_length (const xcb_input_query_device_state_reply_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_input_input_state_iterator_t
+xcb_input_query_device_state_classes_iterator (const xcb_input_query_device_state_reply_t *R)
+{
+ xcb_input_input_state_iterator_t i;
+ i.data = (xcb_input_input_state_t *) (R + 1);
+ i.rem = R->num_classes;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_query_device_state_reply_t *
+xcb_input_query_device_state_reply (xcb_connection_t *c,
+ xcb_input_query_device_state_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_query_device_state_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_void_cookie_t
+xcb_input_device_bell_checked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t feedback_id,
+ uint8_t feedback_class,
+ int8_t percent)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_DEVICE_BELL,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_device_bell_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.feedback_id = feedback_id;
+ xcb_out.feedback_class = feedback_class;
+ xcb_out.percent = percent;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_device_bell (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t feedback_id,
+ uint8_t feedback_class,
+ int8_t percent)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_DEVICE_BELL,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_device_bell_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.feedback_id = feedback_id;
+ xcb_out.feedback_class = feedback_class;
+ xcb_out.percent = percent;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_set_device_valuators_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_set_device_valuators_request_t *_aux = (xcb_input_set_device_valuators_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_set_device_valuators_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* valuators */
+ xcb_block_len += _aux->num_valuators * sizeof(int32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_set_device_valuators_cookie_t
+xcb_input_set_device_valuators (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t first_valuator,
+ uint8_t num_valuators,
+ const int32_t *valuators)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_VALUATORS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_set_device_valuators_cookie_t xcb_ret;
+ xcb_input_set_device_valuators_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.first_valuator = first_valuator;
+ xcb_out.num_valuators = num_valuators;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* int32_t valuators */
+ xcb_parts[4].iov_base = (char *) valuators;
+ xcb_parts[4].iov_len = num_valuators * sizeof(int32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_valuators_cookie_t
+xcb_input_set_device_valuators_unchecked (xcb_connection_t *c,
+ uint8_t device_id,
+ uint8_t first_valuator,
+ uint8_t num_valuators,
+ const int32_t *valuators)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_SET_DEVICE_VALUATORS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_set_device_valuators_cookie_t xcb_ret;
+ xcb_input_set_device_valuators_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ xcb_out.first_valuator = first_valuator;
+ xcb_out.num_valuators = num_valuators;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* int32_t valuators */
+ xcb_parts[4].iov_base = (char *) valuators;
+ xcb_parts[4].iov_len = num_valuators * sizeof(int32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_set_device_valuators_reply_t *
+xcb_input_set_device_valuators_reply (xcb_connection_t *c,
+ xcb_input_set_device_valuators_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_set_device_valuators_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_device_resolution_state_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_device_resolution_state_t *_aux = (xcb_input_device_resolution_state_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_device_resolution_state_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* resolution_values */
+ xcb_block_len += _aux->num_valuators * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* resolution_min */
+ xcb_block_len += _aux->num_valuators * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* resolution_max */
+ xcb_block_len += _aux->num_valuators * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_device_resolution_state_resolution_values (const xcb_input_device_resolution_state_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_device_resolution_state_resolution_values_length (const xcb_input_device_resolution_state_t *R)
+{
+ return R->num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_state_resolution_values_end (const xcb_input_device_resolution_state_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->num_valuators);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+uint32_t *
+xcb_input_device_resolution_state_resolution_min (const xcb_input_device_resolution_state_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_device_resolution_state_resolution_values_end(R);
+ return (uint32_t *) ((char *) prev.data + XCB_TYPE_PAD(uint32_t, prev.index) + 0);
+}
+
+int
+xcb_input_device_resolution_state_resolution_min_length (const xcb_input_device_resolution_state_t *R)
+{
+ return R->num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_state_resolution_min_end (const xcb_input_device_resolution_state_t *R)
+{
+ xcb_generic_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_device_resolution_state_resolution_values_end(R);
+ i.data = ((uint32_t *) ((char*) prev.data + XCB_TYPE_PAD(uint32_t, prev.index))) + (R->num_valuators);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+uint32_t *
+xcb_input_device_resolution_state_resolution_max (const xcb_input_device_resolution_state_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_device_resolution_state_resolution_min_end(R);
+ return (uint32_t *) ((char *) prev.data + XCB_TYPE_PAD(uint32_t, prev.index) + 0);
+}
+
+int
+xcb_input_device_resolution_state_resolution_max_length (const xcb_input_device_resolution_state_t *R)
+{
+ return R->num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_state_resolution_max_end (const xcb_input_device_resolution_state_t *R)
+{
+ xcb_generic_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_device_resolution_state_resolution_min_end(R);
+ i.data = ((uint32_t *) ((char*) prev.data + XCB_TYPE_PAD(uint32_t, prev.index))) + (R->num_valuators);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_device_resolution_state_next (xcb_input_device_resolution_state_iterator_t *i)
+{
+ xcb_input_device_resolution_state_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_device_resolution_state_t *)(((char *)R) + xcb_input_device_resolution_state_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_device_resolution_state_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_state_end (xcb_input_device_resolution_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_device_resolution_state_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+void
+xcb_input_device_abs_calib_state_next (xcb_input_device_abs_calib_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_abs_calib_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_abs_calib_state_end (xcb_input_device_abs_calib_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_device_abs_area_state_next (xcb_input_device_abs_area_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_abs_area_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_abs_area_state_end (xcb_input_device_abs_area_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_device_core_state_next (xcb_input_device_core_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_core_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_core_state_end (xcb_input_device_core_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_device_enable_state_next (xcb_input_device_enable_state_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_enable_state_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_enable_state_end (xcb_input_device_enable_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+uint32_t *
+xcb_input_device_state_data_resolution_resolution_values (const xcb_input_device_state_data_t *S)
+{
+ return S->resolution.resolution_values;
+}
+
+int
+xcb_input_device_state_data_resolution_resolution_values_length (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S)
+{
+ return S->resolution.num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_state_data_resolution_resolution_values_end (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->resolution.resolution_values + S->resolution.num_valuators;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint32_t *
+xcb_input_device_state_data_resolution_resolution_min (const xcb_input_device_state_data_t *S)
+{
+ return S->resolution.resolution_min;
+}
+
+int
+xcb_input_device_state_data_resolution_resolution_min_length (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S)
+{
+ return S->resolution.num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_state_data_resolution_resolution_min_end (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->resolution.resolution_min + S->resolution.num_valuators;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint32_t *
+xcb_input_device_state_data_resolution_resolution_max (const xcb_input_device_state_data_t *S)
+{
+ return S->resolution.resolution_max;
+}
+
+int
+xcb_input_device_state_data_resolution_resolution_max_length (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S)
+{
+ return S->resolution.num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_state_data_resolution_resolution_max_end (const xcb_input_device_state_t *R,
+ const xcb_input_device_state_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->resolution.resolution_max + S->resolution.num_valuators;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_device_state_data_serialize (void **_buffer,
+ uint16_t control_id,
+ const xcb_input_device_state_data_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[27];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_RESOLUTION) {
+ /* xcb_input_device_state_data_t.resolution.num_valuators */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->resolution.num_valuators;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* resolution_values */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->resolution.resolution_values;
+ xcb_block_len += _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* resolution_min */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->resolution.resolution_min;
+ xcb_block_len += _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* resolution_max */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->resolution.resolution_max;
+ xcb_block_len += _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ABS_CALIB) {
+ /* xcb_input_device_state_data_t.abs_calib.min_x */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.min_x;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_state_data_t.abs_calib.max_x */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.max_x;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_state_data_t.abs_calib.min_y */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.min_y;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_state_data_t.abs_calib.max_y */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.max_y;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_state_data_t.abs_calib.flip_x */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.flip_x;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_calib.flip_y */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.flip_y;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_calib.rotation */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.rotation;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_calib.button_threshold */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.button_threshold;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_CORE) {
+ /* xcb_input_device_state_data_t.core.status */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->core.status;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_state_data_t.core.iscore */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->core.iscore;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_state_data_t.core.pad0 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*2;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*2;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ENABLE) {
+ /* xcb_input_device_state_data_t.enable.enable */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->enable.enable;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_state_data_t.enable.pad1 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*3;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*3;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ABS_AREA) {
+ /* xcb_input_device_state_data_t.abs_area.offset_x */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.offset_x;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.offset_y */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.offset_y;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.width */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.width;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.height */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.height;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.screen */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.screen;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.following */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.following;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_device_state_data_unpack (const void *_buffer,
+ uint16_t control_id,
+ xcb_input_device_state_data_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_RESOLUTION) {
+ /* xcb_input_device_state_data_t.resolution.num_valuators */
+ _aux->resolution.num_valuators = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* resolution_values */
+ _aux->resolution.resolution_values = (uint32_t *)xcb_tmp;
+ xcb_block_len += _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* resolution_min */
+ _aux->resolution.resolution_min = (uint32_t *)xcb_tmp;
+ xcb_block_len += _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* resolution_max */
+ _aux->resolution.resolution_max = (uint32_t *)xcb_tmp;
+ xcb_block_len += _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ABS_CALIB) {
+ /* xcb_input_device_state_data_t.abs_calib.min_x */
+ _aux->abs_calib.min_x = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_state_data_t.abs_calib.max_x */
+ _aux->abs_calib.max_x = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_state_data_t.abs_calib.min_y */
+ _aux->abs_calib.min_y = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_state_data_t.abs_calib.max_y */
+ _aux->abs_calib.max_y = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_state_data_t.abs_calib.flip_x */
+ _aux->abs_calib.flip_x = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_calib.flip_y */
+ _aux->abs_calib.flip_y = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_calib.rotation */
+ _aux->abs_calib.rotation = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_calib.button_threshold */
+ _aux->abs_calib.button_threshold = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_CORE) {
+ /* xcb_input_device_state_data_t.core.status */
+ _aux->core.status = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_state_data_t.core.iscore */
+ _aux->core.iscore = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_state_data_t.core.pad0 */
+ _aux->core.pad0[0] = *(uint8_t *)xcb_tmp;
+ _aux->core.pad0[1] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 2;
+ xcb_tmp += sizeof(uint8_t) * 2;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ENABLE) {
+ /* xcb_input_device_state_data_t.enable.enable */
+ _aux->enable.enable = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_state_data_t.enable.pad1 */
+ _aux->enable.pad1[0] = *(uint8_t *)xcb_tmp;
+ _aux->enable.pad1[1] = *(uint8_t *)xcb_tmp;
+ _aux->enable.pad1[2] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 3;
+ xcb_tmp += sizeof(uint8_t) * 3;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ABS_AREA) {
+ /* xcb_input_device_state_data_t.abs_area.offset_x */
+ _aux->abs_area.offset_x = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.offset_y */
+ _aux->abs_area.offset_y = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.width */
+ _aux->abs_area.width = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.height */
+ _aux->abs_area.height = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.screen */
+ _aux->abs_area.screen = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_state_data_t.abs_area.following */
+ _aux->abs_area.following = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_device_state_data_sizeof (const void *_buffer,
+ uint16_t control_id)
+{
+ xcb_input_device_state_data_t _aux;
+ return xcb_input_device_state_data_unpack(_buffer, control_id, &_aux);
+}
+
+int
+xcb_input_device_state_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_device_state_t *_aux = (xcb_input_device_state_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_device_state_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* data */
+ xcb_block_len += xcb_input_device_state_data_sizeof(xcb_tmp, _aux->control_id);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+void *
+xcb_input_device_state_data (const xcb_input_device_state_t *R)
+{
+ return (void *) (R + 1);
+}
+
+void
+xcb_input_device_state_next (xcb_input_device_state_iterator_t *i)
+{
+ xcb_input_device_state_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_device_state_t *)(((char *)R) + xcb_input_device_state_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_device_state_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_state_end (xcb_input_device_state_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_device_state_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_get_device_control_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_get_device_control_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* control */
+ xcb_block_len += xcb_input_device_state_sizeof(xcb_tmp);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_device_state_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_device_control_cookie_t
+xcb_input_get_device_control (xcb_connection_t *c,
+ uint16_t control_id,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_CONTROL,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_control_cookie_t xcb_ret;
+ xcb_input_get_device_control_request_t xcb_out;
+
+ xcb_out.control_id = control_id;
+ xcb_out.device_id = device_id;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_control_cookie_t
+xcb_input_get_device_control_unchecked (xcb_connection_t *c,
+ uint16_t control_id,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_CONTROL,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_control_cookie_t xcb_ret;
+ xcb_input_get_device_control_request_t xcb_out;
+
+ xcb_out.control_id = control_id;
+ xcb_out.device_id = device_id;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_device_state_t *
+xcb_input_get_device_control_control (const xcb_input_get_device_control_reply_t *R)
+{
+ return (xcb_input_device_state_t *) (R + 1);
+}
+
+xcb_input_get_device_control_reply_t *
+xcb_input_get_device_control_reply (xcb_connection_t *c,
+ xcb_input_get_device_control_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_device_control_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_device_resolution_ctl_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_device_resolution_ctl_t *_aux = (xcb_input_device_resolution_ctl_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_device_resolution_ctl_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* resolution_values */
+ xcb_block_len += _aux->num_valuators * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_device_resolution_ctl_resolution_values (const xcb_input_device_resolution_ctl_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_device_resolution_ctl_resolution_values_length (const xcb_input_device_resolution_ctl_t *R)
+{
+ return R->num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_ctl_resolution_values_end (const xcb_input_device_resolution_ctl_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->num_valuators);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_device_resolution_ctl_next (xcb_input_device_resolution_ctl_iterator_t *i)
+{
+ xcb_input_device_resolution_ctl_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_device_resolution_ctl_t *)(((char *)R) + xcb_input_device_resolution_ctl_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_device_resolution_ctl_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_resolution_ctl_end (xcb_input_device_resolution_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_device_resolution_ctl_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+void
+xcb_input_device_abs_calib_ctl_next (xcb_input_device_abs_calib_ctl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_abs_calib_ctl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_abs_calib_ctl_end (xcb_input_device_abs_calib_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_device_abs_area_ctrl_next (xcb_input_device_abs_area_ctrl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_abs_area_ctrl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_abs_area_ctrl_end (xcb_input_device_abs_area_ctrl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_device_core_ctrl_next (xcb_input_device_core_ctrl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_core_ctrl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_core_ctrl_end (xcb_input_device_core_ctrl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_device_enable_ctrl_next (xcb_input_device_enable_ctrl_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_device_enable_ctrl_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_enable_ctrl_end (xcb_input_device_enable_ctrl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+uint32_t *
+xcb_input_device_ctl_data_resolution_resolution_values (const xcb_input_device_ctl_data_t *S)
+{
+ return S->resolution.resolution_values;
+}
+
+int
+xcb_input_device_ctl_data_resolution_resolution_values_length (const xcb_input_device_ctl_t *R,
+ const xcb_input_device_ctl_data_t *S)
+{
+ return S->resolution.num_valuators;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_ctl_data_resolution_resolution_values_end (const xcb_input_device_ctl_t *R,
+ const xcb_input_device_ctl_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->resolution.resolution_values + S->resolution.num_valuators;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_device_ctl_data_serialize (void **_buffer,
+ uint16_t control_id,
+ const xcb_input_device_ctl_data_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[24];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_RESOLUTION) {
+ /* xcb_input_device_ctl_data_t.resolution.first_valuator */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->resolution.first_valuator;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_ctl_data_t.resolution.num_valuators */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->resolution.num_valuators;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_ctl_data_t.resolution.pad0 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*2;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*2;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* resolution_values */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->resolution.resolution_values;
+ xcb_block_len += _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ABS_CALIB) {
+ /* xcb_input_device_ctl_data_t.abs_calib.min_x */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.min_x;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.max_x */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.max_x;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.min_y */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.min_y;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.max_y */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.max_y;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.flip_x */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.flip_x;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.flip_y */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.flip_y;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.rotation */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.rotation;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.button_threshold */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_calib.button_threshold;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_CORE) {
+ /* xcb_input_device_ctl_data_t.core.status */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->core.status;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_ctl_data_t.core.pad1 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*3;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*3;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ENABLE) {
+ /* xcb_input_device_ctl_data_t.enable.enable */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->enable.enable;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_ctl_data_t.enable.pad2 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*3;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*3;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ABS_AREA) {
+ /* xcb_input_device_ctl_data_t.abs_area.offset_x */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.offset_x;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.offset_y */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.offset_y;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.width */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.width;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.height */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.height;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.screen */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.screen;
+ xcb_block_len += sizeof(int32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(int32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.following */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->abs_area.following;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_device_ctl_data_unpack (const void *_buffer,
+ uint16_t control_id,
+ xcb_input_device_ctl_data_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_RESOLUTION) {
+ /* xcb_input_device_ctl_data_t.resolution.first_valuator */
+ _aux->resolution.first_valuator = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_ctl_data_t.resolution.num_valuators */
+ _aux->resolution.num_valuators = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_ctl_data_t.resolution.pad0 */
+ _aux->resolution.pad0[0] = *(uint8_t *)xcb_tmp;
+ _aux->resolution.pad0[1] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 2;
+ xcb_tmp += sizeof(uint8_t) * 2;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* resolution_values */
+ _aux->resolution.resolution_values = (uint32_t *)xcb_tmp;
+ xcb_block_len += _aux->resolution.num_valuators * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ABS_CALIB) {
+ /* xcb_input_device_ctl_data_t.abs_calib.min_x */
+ _aux->abs_calib.min_x = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.max_x */
+ _aux->abs_calib.max_x = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.min_y */
+ _aux->abs_calib.min_y = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.max_y */
+ _aux->abs_calib.max_y = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.flip_x */
+ _aux->abs_calib.flip_x = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.flip_y */
+ _aux->abs_calib.flip_y = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.rotation */
+ _aux->abs_calib.rotation = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_calib.button_threshold */
+ _aux->abs_calib.button_threshold = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_CORE) {
+ /* xcb_input_device_ctl_data_t.core.status */
+ _aux->core.status = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_ctl_data_t.core.pad1 */
+ _aux->core.pad1[0] = *(uint8_t *)xcb_tmp;
+ _aux->core.pad1[1] = *(uint8_t *)xcb_tmp;
+ _aux->core.pad1[2] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 3;
+ xcb_tmp += sizeof(uint8_t) * 3;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ENABLE) {
+ /* xcb_input_device_ctl_data_t.enable.enable */
+ _aux->enable.enable = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_ctl_data_t.enable.pad2 */
+ _aux->enable.pad2[0] = *(uint8_t *)xcb_tmp;
+ _aux->enable.pad2[1] = *(uint8_t *)xcb_tmp;
+ _aux->enable.pad2[2] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 3;
+ xcb_tmp += sizeof(uint8_t) * 3;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(control_id == XCB_INPUT_DEVICE_CONTROL_ABS_AREA) {
+ /* xcb_input_device_ctl_data_t.abs_area.offset_x */
+ _aux->abs_area.offset_x = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.offset_y */
+ _aux->abs_area.offset_y = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.width */
+ _aux->abs_area.width = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.height */
+ _aux->abs_area.height = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.screen */
+ _aux->abs_area.screen = *(int32_t *)xcb_tmp;
+ xcb_block_len += sizeof(int32_t);
+ xcb_tmp += sizeof(int32_t);
+ xcb_align_to = ALIGNOF(int32_t);
+ /* xcb_input_device_ctl_data_t.abs_area.following */
+ _aux->abs_area.following = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_device_ctl_data_sizeof (const void *_buffer,
+ uint16_t control_id)
+{
+ xcb_input_device_ctl_data_t _aux;
+ return xcb_input_device_ctl_data_unpack(_buffer, control_id, &_aux);
+}
+
+int
+xcb_input_device_ctl_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_device_ctl_t *_aux = (xcb_input_device_ctl_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_device_ctl_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* data */
+ xcb_block_len += xcb_input_device_ctl_data_sizeof(xcb_tmp, _aux->control_id);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+void *
+xcb_input_device_ctl_data (const xcb_input_device_ctl_t *R)
+{
+ return (void *) (R + 1);
+}
+
+void
+xcb_input_device_ctl_next (xcb_input_device_ctl_iterator_t *i)
+{
+ xcb_input_device_ctl_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_device_ctl_t *)(((char *)R) + xcb_input_device_ctl_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_device_ctl_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_ctl_end (xcb_input_device_ctl_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_device_ctl_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_change_device_control_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_change_device_control_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* control */
+ xcb_block_len += xcb_input_device_ctl_sizeof(xcb_tmp);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_device_ctl_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_change_device_control_cookie_t
+xcb_input_change_device_control (xcb_connection_t *c,
+ uint16_t control_id,
+ uint8_t device_id,
+ xcb_input_device_ctl_t *control)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_CONTROL,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_change_device_control_cookie_t xcb_ret;
+ xcb_input_change_device_control_request_t xcb_out;
+
+ xcb_out.control_id = control_id;
+ xcb_out.device_id = device_id;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_device_ctl_t control */
+ xcb_parts[4].iov_base = (char *) control;
+ xcb_parts[4].iov_len =
+ xcb_input_device_ctl_sizeof (control);
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_change_device_control_cookie_t
+xcb_input_change_device_control_unchecked (xcb_connection_t *c,
+ uint16_t control_id,
+ uint8_t device_id,
+ xcb_input_device_ctl_t *control)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_CONTROL,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_change_device_control_cookie_t xcb_ret;
+ xcb_input_change_device_control_request_t xcb_out;
+
+ xcb_out.control_id = control_id;
+ xcb_out.device_id = device_id;
+ xcb_out.pad0 = 0;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_device_ctl_t control */
+ xcb_parts[4].iov_base = (char *) control;
+ xcb_parts[4].iov_len =
+ xcb_input_device_ctl_sizeof (control);
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_change_device_control_reply_t *
+xcb_input_change_device_control_reply (xcb_connection_t *c,
+ xcb_input_change_device_control_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_change_device_control_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_list_device_properties_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_list_device_properties_reply_t *_aux = (xcb_input_list_device_properties_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_list_device_properties_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* atoms */
+ xcb_block_len += _aux->num_atoms * sizeof(xcb_atom_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_atom_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_list_device_properties_cookie_t
+xcb_input_list_device_properties (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_LIST_DEVICE_PROPERTIES,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_list_device_properties_cookie_t xcb_ret;
+ xcb_input_list_device_properties_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_list_device_properties_cookie_t
+xcb_input_list_device_properties_unchecked (xcb_connection_t *c,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_LIST_DEVICE_PROPERTIES,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_list_device_properties_cookie_t xcb_ret;
+ xcb_input_list_device_properties_request_t xcb_out;
+
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_atom_t *
+xcb_input_list_device_properties_atoms (const xcb_input_list_device_properties_reply_t *R)
+{
+ return (xcb_atom_t *) (R + 1);
+}
+
+int
+xcb_input_list_device_properties_atoms_length (const xcb_input_list_device_properties_reply_t *R)
+{
+ return R->num_atoms;
+}
+
+xcb_generic_iterator_t
+xcb_input_list_device_properties_atoms_end (const xcb_input_list_device_properties_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_atom_t *) (R + 1)) + (R->num_atoms);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_list_device_properties_reply_t *
+xcb_input_list_device_properties_reply (xcb_connection_t *c,
+ xcb_input_list_device_properties_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_list_device_properties_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+uint8_t *
+xcb_input_change_device_property_items_data_8 (const xcb_input_change_device_property_items_t *S)
+{
+ return S->data8;
+}
+
+int
+xcb_input_change_device_property_items_data_8_length (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_change_device_property_items_data_8_end (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data8 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint16_t *
+xcb_input_change_device_property_items_data_16 (const xcb_input_change_device_property_items_t *S)
+{
+ return S->data16;
+}
+
+int
+xcb_input_change_device_property_items_data_16_length (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_change_device_property_items_data_16_end (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data16 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint32_t *
+xcb_input_change_device_property_items_data_32 (const xcb_input_change_device_property_items_t *S)
+{
+ return S->data32;
+}
+
+int
+xcb_input_change_device_property_items_data_32_length (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_change_device_property_items_data_32_end (const xcb_input_change_device_property_request_t *R,
+ const xcb_input_change_device_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data32 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_change_device_property_items_serialize (void **_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ const xcb_input_change_device_property_items_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[9];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(format == XCB_INPUT_PROPERTY_FORMAT_8_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data8 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data8;
+ xcb_block_len += num_items * sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_16_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data16 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data16;
+ xcb_block_len += num_items * sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_32_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data32 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data32;
+ xcb_block_len += num_items * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_change_device_property_items_unpack (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ xcb_input_change_device_property_items_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(format == XCB_INPUT_PROPERTY_FORMAT_8_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data8 */
+ _aux->data8 = (uint8_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_16_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data16 */
+ _aux->data16 = (uint16_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_32_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data32 */
+ _aux->data32 = (uint32_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_change_device_property_items_sizeof (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format)
+{
+ xcb_input_change_device_property_items_t _aux;
+ return xcb_input_change_device_property_items_unpack(_buffer, num_items, format, &_aux);
+}
+
+int
+xcb_input_change_device_property_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_change_device_property_request_t *_aux = (xcb_input_change_device_property_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_change_device_property_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* items */
+ xcb_block_len += xcb_input_change_device_property_items_sizeof(xcb_tmp, _aux->num_items, _aux->format);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_change_device_property_checked (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint8_t device_id,
+ uint8_t format,
+ uint8_t mode,
+ uint32_t num_items,
+ const void *items)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 3,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[5];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_device_property_request_t xcb_out;
+
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.device_id = device_id;
+ xcb_out.format = format;
+ xcb_out.mode = mode;
+ xcb_out.pad0 = 0;
+ xcb_out.num_items = num_items;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_change_device_property_items_t items */
+ xcb_parts[4].iov_base = (char *) items;
+ xcb_parts[4].iov_len =
+ xcb_input_change_device_property_items_sizeof (items, num_items, format);
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_change_device_property (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint8_t device_id,
+ uint8_t format,
+ uint8_t mode,
+ uint32_t num_items,
+ const void *items)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 3,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[5];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_device_property_request_t xcb_out;
+
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.device_id = device_id;
+ xcb_out.format = format;
+ xcb_out.mode = mode;
+ xcb_out.pad0 = 0;
+ xcb_out.num_items = num_items;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_change_device_property_items_t items */
+ xcb_parts[4].iov_base = (char *) items;
+ xcb_parts[4].iov_len =
+ xcb_input_change_device_property_items_sizeof (items, num_items, format);
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_change_device_property_aux_checked (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint8_t device_id,
+ uint8_t format,
+ uint8_t mode,
+ uint32_t num_items,
+ const xcb_input_change_device_property_items_t *items)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 3,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[5];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_device_property_request_t xcb_out;
+ void *xcb_aux0 = 0;
+
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.device_id = device_id;
+ xcb_out.format = format;
+ xcb_out.mode = mode;
+ xcb_out.pad0 = 0;
+ xcb_out.num_items = num_items;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_change_device_property_items_t items */
+ xcb_parts[4].iov_len =
+ xcb_input_change_device_property_items_serialize (&xcb_aux0, num_items, format, items);
+ xcb_parts[4].iov_base = xcb_aux0;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ free(xcb_aux0);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_change_device_property_aux (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint8_t device_id,
+ uint8_t format,
+ uint8_t mode,
+ uint32_t num_items,
+ const xcb_input_change_device_property_items_t *items)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 3,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_CHANGE_DEVICE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[5];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_change_device_property_request_t xcb_out;
+ void *xcb_aux0 = 0;
+
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.device_id = device_id;
+ xcb_out.format = format;
+ xcb_out.mode = mode;
+ xcb_out.pad0 = 0;
+ xcb_out.num_items = num_items;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_change_device_property_items_t items */
+ xcb_parts[4].iov_len =
+ xcb_input_change_device_property_items_serialize (&xcb_aux0, num_items, format, items);
+ xcb_parts[4].iov_base = xcb_aux0;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ free(xcb_aux0);
+ return xcb_ret;
+}
+
+void *
+xcb_input_change_device_property_items (const xcb_input_change_device_property_request_t *R)
+{
+ return (void *) (R + 1);
+}
+
+xcb_void_cookie_t
+xcb_input_delete_device_property_checked (xcb_connection_t *c,
+ xcb_atom_t property,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_DELETE_DEVICE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_delete_device_property_request_t xcb_out;
+
+ xcb_out.property = property;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_delete_device_property (xcb_connection_t *c,
+ xcb_atom_t property,
+ uint8_t device_id)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_DELETE_DEVICE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_delete_device_property_request_t xcb_out;
+
+ xcb_out.property = property;
+ xcb_out.device_id = device_id;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+uint8_t *
+xcb_input_get_device_property_items_data_8 (const xcb_input_get_device_property_items_t *S)
+{
+ return S->data8;
+}
+
+int
+xcb_input_get_device_property_items_data_8_length (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_get_device_property_items_data_8_end (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data8 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint16_t *
+xcb_input_get_device_property_items_data_16 (const xcb_input_get_device_property_items_t *S)
+{
+ return S->data16;
+}
+
+int
+xcb_input_get_device_property_items_data_16_length (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_get_device_property_items_data_16_end (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data16 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint32_t *
+xcb_input_get_device_property_items_data_32 (const xcb_input_get_device_property_items_t *S)
+{
+ return S->data32;
+}
+
+int
+xcb_input_get_device_property_items_data_32_length (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_get_device_property_items_data_32_end (const xcb_input_get_device_property_reply_t *R,
+ const xcb_input_get_device_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data32 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_get_device_property_items_serialize (void **_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ const xcb_input_get_device_property_items_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[9];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(format == XCB_INPUT_PROPERTY_FORMAT_8_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data8 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data8;
+ xcb_block_len += num_items * sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_16_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data16 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data16;
+ xcb_block_len += num_items * sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_32_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data32 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data32;
+ xcb_block_len += num_items * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_get_device_property_items_unpack (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ xcb_input_get_device_property_items_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(format == XCB_INPUT_PROPERTY_FORMAT_8_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data8 */
+ _aux->data8 = (uint8_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_16_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data16 */
+ _aux->data16 = (uint16_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_32_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data32 */
+ _aux->data32 = (uint32_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_get_device_property_items_sizeof (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format)
+{
+ xcb_input_get_device_property_items_t _aux;
+ return xcb_input_get_device_property_items_unpack(_buffer, num_items, format, &_aux);
+}
+
+int
+xcb_input_get_device_property_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_get_device_property_reply_t *_aux = (xcb_input_get_device_property_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_get_device_property_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* items */
+ xcb_block_len += xcb_input_get_device_property_items_sizeof(xcb_tmp, _aux->num_items, _aux->format);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_get_device_property_cookie_t
+xcb_input_get_device_property (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t offset,
+ uint32_t len,
+ uint8_t device_id,
+ uint8_t _delete)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_PROPERTY,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_property_cookie_t xcb_ret;
+ xcb_input_get_device_property_request_t xcb_out;
+
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.offset = offset;
+ xcb_out.len = len;
+ xcb_out.device_id = device_id;
+ xcb_out._delete = _delete;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_get_device_property_cookie_t
+xcb_input_get_device_property_unchecked (xcb_connection_t *c,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t offset,
+ uint32_t len,
+ uint8_t device_id,
+ uint8_t _delete)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_GET_DEVICE_PROPERTY,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_get_device_property_cookie_t xcb_ret;
+ xcb_input_get_device_property_request_t xcb_out;
+
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.offset = offset;
+ xcb_out.len = len;
+ xcb_out.device_id = device_id;
+ xcb_out._delete = _delete;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+void *
+xcb_input_get_device_property_items (const xcb_input_get_device_property_reply_t *R)
+{
+ return (void *) (R + 1);
+}
+
+xcb_input_get_device_property_reply_t *
+xcb_input_get_device_property_reply (xcb_connection_t *c,
+ xcb_input_get_device_property_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_get_device_property_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+void
+xcb_input_group_info_next (xcb_input_group_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_group_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_group_info_end (xcb_input_group_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_modifier_info_next (xcb_input_modifier_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_modifier_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_modifier_info_end (xcb_input_modifier_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_xi_query_pointer_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_query_pointer_reply_t *_aux = (xcb_input_xi_query_pointer_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_xi_query_pointer_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* buttons */
+ xcb_block_len += _aux->buttons_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_xi_query_pointer_cookie_t
+xcb_input_xi_query_pointer (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_QUERY_POINTER,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_query_pointer_cookie_t xcb_ret;
+ xcb_input_xi_query_pointer_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_query_pointer_cookie_t
+xcb_input_xi_query_pointer_unchecked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_QUERY_POINTER,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_query_pointer_cookie_t xcb_ret;
+ xcb_input_xi_query_pointer_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+uint32_t *
+xcb_input_xi_query_pointer_buttons (const xcb_input_xi_query_pointer_reply_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_xi_query_pointer_buttons_length (const xcb_input_xi_query_pointer_reply_t *R)
+{
+ return R->buttons_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_query_pointer_buttons_end (const xcb_input_xi_query_pointer_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->buttons_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_xi_query_pointer_reply_t *
+xcb_input_xi_query_pointer_reply (xcb_connection_t *c,
+ xcb_input_xi_query_pointer_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_query_pointer_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_void_cookie_t
+xcb_input_xi_warp_pointer_checked (xcb_connection_t *c,
+ xcb_window_t src_win,
+ xcb_window_t dst_win,
+ xcb_input_fp1616_t src_x,
+ xcb_input_fp1616_t src_y,
+ uint16_t src_width,
+ uint16_t src_height,
+ xcb_input_fp1616_t dst_x,
+ xcb_input_fp1616_t dst_y,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_WARP_POINTER,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_warp_pointer_request_t xcb_out;
+
+ xcb_out.src_win = src_win;
+ xcb_out.dst_win = dst_win;
+ xcb_out.src_x = src_x;
+ xcb_out.src_y = src_y;
+ xcb_out.src_width = src_width;
+ xcb_out.src_height = src_height;
+ xcb_out.dst_x = dst_x;
+ xcb_out.dst_y = dst_y;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_warp_pointer (xcb_connection_t *c,
+ xcb_window_t src_win,
+ xcb_window_t dst_win,
+ xcb_input_fp1616_t src_x,
+ xcb_input_fp1616_t src_y,
+ uint16_t src_width,
+ uint16_t src_height,
+ xcb_input_fp1616_t dst_x,
+ xcb_input_fp1616_t dst_y,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_WARP_POINTER,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_warp_pointer_request_t xcb_out;
+
+ xcb_out.src_win = src_win;
+ xcb_out.dst_win = dst_win;
+ xcb_out.src_x = src_x;
+ xcb_out.src_y = src_y;
+ xcb_out.src_width = src_width;
+ xcb_out.src_height = src_height;
+ xcb_out.dst_x = dst_x;
+ xcb_out.dst_y = dst_y;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_change_cursor_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_cursor_t cursor,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_CHANGE_CURSOR,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_change_cursor_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.cursor = cursor;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_change_cursor (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_cursor_t cursor,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_CHANGE_CURSOR,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_change_cursor_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.cursor = cursor;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_add_master_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_add_master_t *_aux = (xcb_input_add_master_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_add_master_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* name */
+ xcb_block_len += _aux->name_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+char *
+xcb_input_add_master_name (const xcb_input_add_master_t *R)
+{
+ return (char *) (R + 1);
+}
+
+int
+xcb_input_add_master_name_length (const xcb_input_add_master_t *R)
+{
+ return R->name_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_add_master_name_end (const xcb_input_add_master_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((char *) (R + 1)) + (R->name_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_add_master_next (xcb_input_add_master_iterator_t *i)
+{
+ xcb_input_add_master_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_add_master_t *)(((char *)R) + xcb_input_add_master_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_add_master_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_add_master_end (xcb_input_add_master_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_add_master_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+void
+xcb_input_remove_master_next (xcb_input_remove_master_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_remove_master_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_remove_master_end (xcb_input_remove_master_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_attach_slave_next (xcb_input_attach_slave_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_attach_slave_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_attach_slave_end (xcb_input_attach_slave_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_detach_slave_next (xcb_input_detach_slave_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_detach_slave_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_detach_slave_end (xcb_input_detach_slave_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+char *
+xcb_input_hierarchy_change_data_add_master_name (const xcb_input_hierarchy_change_data_t *S)
+{
+ return S->add_master.name;
+}
+
+int
+xcb_input_hierarchy_change_data_add_master_name_length (const xcb_input_hierarchy_change_t *R,
+ const xcb_input_hierarchy_change_data_t *S)
+{
+ return S->add_master.name_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_hierarchy_change_data_add_master_name_end (const xcb_input_hierarchy_change_t *R,
+ const xcb_input_hierarchy_change_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->add_master.name + S->add_master.name_len;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_hierarchy_change_data_serialize (void **_buffer,
+ uint16_t type,
+ const xcb_input_hierarchy_change_data_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[16];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(type == XCB_INPUT_HIERARCHY_CHANGE_TYPE_ADD_MASTER) {
+ /* xcb_input_hierarchy_change_data_t.add_master.name_len */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->add_master.name_len;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_hierarchy_change_data_t.add_master.send_core */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->add_master.send_core;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_hierarchy_change_data_t.add_master.enable */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->add_master.enable;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* name */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->add_master.name;
+ xcb_block_len += _aux->add_master.name_len * sizeof(char);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->add_master.name_len * sizeof(char);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(char);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(type == XCB_INPUT_HIERARCHY_CHANGE_TYPE_REMOVE_MASTER) {
+ /* xcb_input_hierarchy_change_data_t.remove_master.deviceid */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->remove_master.deviceid;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_device_id_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ /* xcb_input_hierarchy_change_data_t.remove_master.return_mode */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->remove_master.return_mode;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_hierarchy_change_data_t.remove_master.pad1 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &xcb_pad;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_hierarchy_change_data_t.remove_master.return_pointer */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->remove_master.return_pointer;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_device_id_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ /* xcb_input_hierarchy_change_data_t.remove_master.return_keyboard */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->remove_master.return_keyboard;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_device_id_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ }
+ if(type == XCB_INPUT_HIERARCHY_CHANGE_TYPE_ATTACH_SLAVE) {
+ /* xcb_input_hierarchy_change_data_t.attach_slave.deviceid */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->attach_slave.deviceid;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_device_id_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ /* xcb_input_hierarchy_change_data_t.attach_slave.master */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->attach_slave.master;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_device_id_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ }
+ if(type == XCB_INPUT_HIERARCHY_CHANGE_TYPE_DETACH_SLAVE) {
+ /* xcb_input_hierarchy_change_data_t.detach_slave.deviceid */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->detach_slave.deviceid;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_device_id_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ /* xcb_input_hierarchy_change_data_t.detach_slave.pad2 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*2;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*2;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_hierarchy_change_data_unpack (const void *_buffer,
+ uint16_t type,
+ xcb_input_hierarchy_change_data_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(type == XCB_INPUT_HIERARCHY_CHANGE_TYPE_ADD_MASTER) {
+ /* xcb_input_hierarchy_change_data_t.add_master.name_len */
+ _aux->add_master.name_len = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_hierarchy_change_data_t.add_master.send_core */
+ _aux->add_master.send_core = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_hierarchy_change_data_t.add_master.enable */
+ _aux->add_master.enable = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* name */
+ _aux->add_master.name = (char *)xcb_tmp;
+ xcb_block_len += _aux->add_master.name_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(type == XCB_INPUT_HIERARCHY_CHANGE_TYPE_REMOVE_MASTER) {
+ /* xcb_input_hierarchy_change_data_t.remove_master.deviceid */
+ _aux->remove_master.deviceid = *(xcb_input_device_id_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_tmp += sizeof(xcb_input_device_id_t);
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ /* xcb_input_hierarchy_change_data_t.remove_master.return_mode */
+ _aux->remove_master.return_mode = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_hierarchy_change_data_t.remove_master.pad1 */
+ _aux->remove_master.pad1 = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_hierarchy_change_data_t.remove_master.return_pointer */
+ _aux->remove_master.return_pointer = *(xcb_input_device_id_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_tmp += sizeof(xcb_input_device_id_t);
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ /* xcb_input_hierarchy_change_data_t.remove_master.return_keyboard */
+ _aux->remove_master.return_keyboard = *(xcb_input_device_id_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_tmp += sizeof(xcb_input_device_id_t);
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ }
+ if(type == XCB_INPUT_HIERARCHY_CHANGE_TYPE_ATTACH_SLAVE) {
+ /* xcb_input_hierarchy_change_data_t.attach_slave.deviceid */
+ _aux->attach_slave.deviceid = *(xcb_input_device_id_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_tmp += sizeof(xcb_input_device_id_t);
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ /* xcb_input_hierarchy_change_data_t.attach_slave.master */
+ _aux->attach_slave.master = *(xcb_input_device_id_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_tmp += sizeof(xcb_input_device_id_t);
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ }
+ if(type == XCB_INPUT_HIERARCHY_CHANGE_TYPE_DETACH_SLAVE) {
+ /* xcb_input_hierarchy_change_data_t.detach_slave.deviceid */
+ _aux->detach_slave.deviceid = *(xcb_input_device_id_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_device_id_t);
+ xcb_tmp += sizeof(xcb_input_device_id_t);
+ xcb_align_to = ALIGNOF(xcb_input_device_id_t);
+ /* xcb_input_hierarchy_change_data_t.detach_slave.pad2 */
+ _aux->detach_slave.pad2[0] = *(uint8_t *)xcb_tmp;
+ _aux->detach_slave.pad2[1] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 2;
+ xcb_tmp += sizeof(uint8_t) * 2;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_hierarchy_change_data_sizeof (const void *_buffer,
+ uint16_t type)
+{
+ xcb_input_hierarchy_change_data_t _aux;
+ return xcb_input_hierarchy_change_data_unpack(_buffer, type, &_aux);
+}
+
+int
+xcb_input_hierarchy_change_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_hierarchy_change_t *_aux = (xcb_input_hierarchy_change_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_hierarchy_change_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* data */
+ xcb_block_len += xcb_input_hierarchy_change_data_sizeof(xcb_tmp, _aux->type);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+void *
+xcb_input_hierarchy_change_data (const xcb_input_hierarchy_change_t *R)
+{
+ return (void *) (R + 1);
+}
+
+void
+xcb_input_hierarchy_change_next (xcb_input_hierarchy_change_iterator_t *i)
+{
+ xcb_input_hierarchy_change_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_hierarchy_change_t *)(((char *)R) + xcb_input_hierarchy_change_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_hierarchy_change_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_hierarchy_change_end (xcb_input_hierarchy_change_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_hierarchy_change_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_xi_change_hierarchy_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_change_hierarchy_request_t *_aux = (xcb_input_xi_change_hierarchy_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_xi_change_hierarchy_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* changes */
+ for(i=0; i<_aux->num_changes; i++) {
+ xcb_tmp_len = xcb_input_hierarchy_change_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_hierarchy_change_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_change_hierarchy_checked (xcb_connection_t *c,
+ uint8_t num_changes,
+ const xcb_input_hierarchy_change_t *changes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_CHANGE_HIERARCHY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_change_hierarchy_request_t xcb_out;
+ unsigned int xcb_tmp_len;
+ char *xcb_tmp;
+ unsigned int i;
+
+ xcb_out.num_changes = num_changes;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_hierarchy_change_t changes */
+ xcb_parts[4].iov_base = (char *) changes;
+ xcb_parts[4].iov_len = 0;
+ xcb_tmp = (char *)changes;
+ for(i=0; i<num_changes; i++) {
+ xcb_tmp_len = xcb_input_hierarchy_change_sizeof(xcb_tmp);
+ xcb_parts[4].iov_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_change_hierarchy (xcb_connection_t *c,
+ uint8_t num_changes,
+ const xcb_input_hierarchy_change_t *changes)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_CHANGE_HIERARCHY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_change_hierarchy_request_t xcb_out;
+ unsigned int xcb_tmp_len;
+ char *xcb_tmp;
+ unsigned int i;
+
+ xcb_out.num_changes = num_changes;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_hierarchy_change_t changes */
+ xcb_parts[4].iov_base = (char *) changes;
+ xcb_parts[4].iov_len = 0;
+ xcb_tmp = (char *)changes;
+ for(i=0; i<num_changes; i++) {
+ xcb_tmp_len = xcb_input_hierarchy_change_sizeof(xcb_tmp);
+ xcb_parts[4].iov_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_xi_change_hierarchy_changes_length (const xcb_input_xi_change_hierarchy_request_t *R)
+{
+ return R->num_changes;
+}
+
+xcb_input_hierarchy_change_iterator_t
+xcb_input_xi_change_hierarchy_changes_iterator (const xcb_input_xi_change_hierarchy_request_t *R)
+{
+ xcb_input_hierarchy_change_iterator_t i;
+ i.data = (xcb_input_hierarchy_change_t *) (R + 1);
+ i.rem = R->num_changes;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_set_client_pointer_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_SET_CLIENT_POINTER,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_set_client_pointer_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_set_client_pointer (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_SET_CLIENT_POINTER,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_set_client_pointer_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_get_client_pointer_cookie_t
+xcb_input_xi_get_client_pointer (xcb_connection_t *c,
+ xcb_window_t window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GET_CLIENT_POINTER,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_get_client_pointer_cookie_t xcb_ret;
+ xcb_input_xi_get_client_pointer_request_t xcb_out;
+
+ xcb_out.window = window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_get_client_pointer_cookie_t
+xcb_input_xi_get_client_pointer_unchecked (xcb_connection_t *c,
+ xcb_window_t window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GET_CLIENT_POINTER,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_get_client_pointer_cookie_t xcb_ret;
+ xcb_input_xi_get_client_pointer_request_t xcb_out;
+
+ xcb_out.window = window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_get_client_pointer_reply_t *
+xcb_input_xi_get_client_pointer_reply (xcb_connection_t *c,
+ xcb_input_xi_get_client_pointer_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_get_client_pointer_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_event_mask_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_event_mask_t *_aux = (xcb_input_event_mask_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_event_mask_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* mask */
+ xcb_block_len += _aux->mask_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_event_mask_mask (const xcb_input_event_mask_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_event_mask_mask_length (const xcb_input_event_mask_t *R)
+{
+ return R->mask_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_event_mask_mask_end (const xcb_input_event_mask_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->mask_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_event_mask_next (xcb_input_event_mask_iterator_t *i)
+{
+ xcb_input_event_mask_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_event_mask_t *)(((char *)R) + xcb_input_event_mask_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_event_mask_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_event_mask_end (xcb_input_event_mask_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_event_mask_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_xi_select_events_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_select_events_request_t *_aux = (xcb_input_xi_select_events_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_xi_select_events_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* masks */
+ for(i=0; i<_aux->num_mask; i++) {
+ xcb_tmp_len = xcb_input_event_mask_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_event_mask_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_select_events_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_mask,
+ const xcb_input_event_mask_t *masks)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_SELECT_EVENTS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_select_events_request_t xcb_out;
+ unsigned int xcb_tmp_len;
+ char *xcb_tmp;
+ unsigned int i;
+
+ xcb_out.window = window;
+ xcb_out.num_mask = num_mask;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_mask_t masks */
+ xcb_parts[4].iov_base = (char *) masks;
+ xcb_parts[4].iov_len = 0;
+ xcb_tmp = (char *)masks;
+ for(i=0; i<num_mask; i++) {
+ xcb_tmp_len = xcb_input_event_mask_sizeof(xcb_tmp);
+ xcb_parts[4].iov_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_select_events (xcb_connection_t *c,
+ xcb_window_t window,
+ uint16_t num_mask,
+ const xcb_input_event_mask_t *masks)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_SELECT_EVENTS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_select_events_request_t xcb_out;
+ unsigned int xcb_tmp_len;
+ char *xcb_tmp;
+ unsigned int i;
+
+ xcb_out.window = window;
+ xcb_out.num_mask = num_mask;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_event_mask_t masks */
+ xcb_parts[4].iov_base = (char *) masks;
+ xcb_parts[4].iov_len = 0;
+ xcb_tmp = (char *)masks;
+ for(i=0; i<num_mask; i++) {
+ xcb_tmp_len = xcb_input_event_mask_sizeof(xcb_tmp);
+ xcb_parts[4].iov_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_xi_select_events_masks_length (const xcb_input_xi_select_events_request_t *R)
+{
+ return R->num_mask;
+}
+
+xcb_input_event_mask_iterator_t
+xcb_input_xi_select_events_masks_iterator (const xcb_input_xi_select_events_request_t *R)
+{
+ xcb_input_event_mask_iterator_t i;
+ i.data = (xcb_input_event_mask_t *) (R + 1);
+ i.rem = R->num_mask;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_xi_query_version_cookie_t
+xcb_input_xi_query_version (xcb_connection_t *c,
+ uint16_t major_version,
+ uint16_t minor_version)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_QUERY_VERSION,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_query_version_cookie_t xcb_ret;
+ xcb_input_xi_query_version_request_t xcb_out;
+
+ xcb_out.major_version = major_version;
+ xcb_out.minor_version = minor_version;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_query_version_cookie_t
+xcb_input_xi_query_version_unchecked (xcb_connection_t *c,
+ uint16_t major_version,
+ uint16_t minor_version)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_QUERY_VERSION,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_query_version_cookie_t xcb_ret;
+ xcb_input_xi_query_version_request_t xcb_out;
+
+ xcb_out.major_version = major_version;
+ xcb_out.minor_version = minor_version;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_query_version_reply_t *
+xcb_input_xi_query_version_reply (xcb_connection_t *c,
+ xcb_input_xi_query_version_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_query_version_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_button_class_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_button_class_t *_aux = (xcb_input_button_class_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_button_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* state */
+ xcb_block_len += ((_aux->num_buttons + 31) / 32) * sizeof(xcb_atom_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* labels */
+ xcb_block_len += _aux->num_buttons * sizeof(xcb_atom_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_atom_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_button_class_state (const xcb_input_button_class_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_button_class_state_length (const xcb_input_button_class_t *R)
+{
+ return ((R->num_buttons + 31) / 32);
+}
+
+xcb_generic_iterator_t
+xcb_input_button_class_state_end (const xcb_input_button_class_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (((R->num_buttons + 31) / 32));
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_atom_t *
+xcb_input_button_class_labels (const xcb_input_button_class_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_button_class_state_end(R);
+ return (xcb_atom_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_atom_t, prev.index) + 0);
+}
+
+int
+xcb_input_button_class_labels_length (const xcb_input_button_class_t *R)
+{
+ return R->num_buttons;
+}
+
+xcb_generic_iterator_t
+xcb_input_button_class_labels_end (const xcb_input_button_class_t *R)
+{
+ xcb_generic_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_button_class_state_end(R);
+ i.data = ((xcb_atom_t *) ((char*) prev.data + XCB_TYPE_PAD(xcb_atom_t, prev.index))) + (R->num_buttons);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_button_class_next (xcb_input_button_class_iterator_t *i)
+{
+ xcb_input_button_class_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_button_class_t *)(((char *)R) + xcb_input_button_class_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_button_class_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_button_class_end (xcb_input_button_class_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_button_class_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_key_class_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_key_class_t *_aux = (xcb_input_key_class_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_key_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* keys */
+ xcb_block_len += _aux->num_keys * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_key_class_keys (const xcb_input_key_class_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_key_class_keys_length (const xcb_input_key_class_t *R)
+{
+ return R->num_keys;
+}
+
+xcb_generic_iterator_t
+xcb_input_key_class_keys_end (const xcb_input_key_class_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->num_keys);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_key_class_next (xcb_input_key_class_iterator_t *i)
+{
+ xcb_input_key_class_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_key_class_t *)(((char *)R) + xcb_input_key_class_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_key_class_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_key_class_end (xcb_input_key_class_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_key_class_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+void
+xcb_input_scroll_class_next (xcb_input_scroll_class_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_scroll_class_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_scroll_class_end (xcb_input_scroll_class_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_touch_class_next (xcb_input_touch_class_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_touch_class_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_touch_class_end (xcb_input_touch_class_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+void
+xcb_input_valuator_class_next (xcb_input_valuator_class_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_valuator_class_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_valuator_class_end (xcb_input_valuator_class_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+uint32_t *
+xcb_input_device_class_data_key_keys (const xcb_input_device_class_data_t *S)
+{
+ return S->key.keys;
+}
+
+int
+xcb_input_device_class_data_key_keys_length (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S)
+{
+ return S->key.num_keys;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_class_data_key_keys_end (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->key.keys + S->key.num_keys;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint32_t *
+xcb_input_device_class_data_button_state (const xcb_input_device_class_data_t *S)
+{
+ return S->button.state;
+}
+
+int
+xcb_input_device_class_data_button_state_length (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S)
+{
+ return ((S->button.num_buttons + 31) / 32);
+}
+
+xcb_generic_iterator_t
+xcb_input_device_class_data_button_state_end (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->button.state + ((S->button.num_buttons + 31) / 32);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+xcb_atom_t *
+xcb_input_device_class_data_button_labels (const xcb_input_device_class_data_t *S)
+{
+ return S->button.labels;
+}
+
+int
+xcb_input_device_class_data_button_labels_length (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S)
+{
+ return S->button.num_buttons;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_class_data_button_labels_end (const xcb_input_device_class_t *R,
+ const xcb_input_device_class_data_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->button.labels + S->button.num_buttons;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_device_class_data_serialize (void **_buffer,
+ uint16_t type,
+ const xcb_input_device_class_data_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 2;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[24];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_KEY) {
+ /* xcb_input_device_class_data_t.key.num_keys */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->key.num_keys;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* keys */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->key.keys;
+ xcb_block_len += _aux->key.num_keys * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->key.num_keys * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_BUTTON) {
+ /* xcb_input_device_class_data_t.button.num_buttons */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->button.num_buttons;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* state */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->button.state;
+ xcb_block_len += ((_aux->button.num_buttons + 31) / 32) * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = ((_aux->button.num_buttons + 31) / 32) * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* labels */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->button.labels;
+ xcb_block_len += _aux->button.num_buttons * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = _aux->button.num_buttons * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_atom_t);
+ }
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR) {
+ /* xcb_input_device_class_data_t.valuator.number */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.number;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_device_class_data_t.valuator.label */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.label;
+ xcb_block_len += sizeof(xcb_atom_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_atom_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_atom_t);
+ /* xcb_input_device_class_data_t.valuator.min */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.min;
+ xcb_block_len += sizeof(xcb_input_fp3232_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_fp3232_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* xcb_input_device_class_data_t.valuator.max */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.max;
+ xcb_block_len += sizeof(xcb_input_fp3232_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_fp3232_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* xcb_input_device_class_data_t.valuator.value */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.value;
+ xcb_block_len += sizeof(xcb_input_fp3232_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_fp3232_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* xcb_input_device_class_data_t.valuator.resolution */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.resolution;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_class_data_t.valuator.mode */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->valuator.mode;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_class_data_t.valuator.pad0 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*3;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*3;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_SCROLL) {
+ /* xcb_input_device_class_data_t.scroll.number */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->scroll.number;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_device_class_data_t.scroll.scroll_type */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->scroll.scroll_type;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_device_class_data_t.scroll.pad1 */
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_block_len += sizeof(uint8_t)*2;
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t)*2;
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_class_data_t.scroll.flags */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->scroll.flags;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_class_data_t.scroll.increment */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->scroll.increment;
+ xcb_block_len += sizeof(xcb_input_fp3232_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(xcb_input_fp3232_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ }
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_TOUCH) {
+ /* xcb_input_device_class_data_t.touch.mode */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->touch.mode;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_class_data_t.touch.num_touches */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) &_aux->touch.num_touches;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_device_class_data_unpack (const void *_buffer,
+ uint16_t type,
+ xcb_input_device_class_data_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 2;
+
+
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_KEY) {
+ /* xcb_input_device_class_data_t.key.num_keys */
+ _aux->key.num_keys = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* keys */
+ _aux->key.keys = (uint32_t *)xcb_tmp;
+ xcb_block_len += _aux->key.num_keys * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_BUTTON) {
+ /* xcb_input_device_class_data_t.button.num_buttons */
+ _aux->button.num_buttons = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* state */
+ _aux->button.state = (uint32_t *)xcb_tmp;
+ xcb_block_len += ((_aux->button.num_buttons + 31) / 32) * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* labels */
+ _aux->button.labels = (xcb_atom_t *)xcb_tmp;
+ xcb_block_len += _aux->button.num_buttons * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_atom_t);
+ }
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR) {
+ /* xcb_input_device_class_data_t.valuator.number */
+ _aux->valuator.number = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_device_class_data_t.valuator.label */
+ _aux->valuator.label = *(xcb_atom_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_atom_t);
+ xcb_tmp += sizeof(xcb_atom_t);
+ xcb_align_to = ALIGNOF(xcb_atom_t);
+ /* xcb_input_device_class_data_t.valuator.min */
+ _aux->valuator.min = *(xcb_input_fp3232_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_fp3232_t);
+ xcb_tmp += sizeof(xcb_input_fp3232_t);
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* xcb_input_device_class_data_t.valuator.max */
+ _aux->valuator.max = *(xcb_input_fp3232_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_fp3232_t);
+ xcb_tmp += sizeof(xcb_input_fp3232_t);
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* xcb_input_device_class_data_t.valuator.value */
+ _aux->valuator.value = *(xcb_input_fp3232_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_fp3232_t);
+ xcb_tmp += sizeof(xcb_input_fp3232_t);
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* xcb_input_device_class_data_t.valuator.resolution */
+ _aux->valuator.resolution = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_class_data_t.valuator.mode */
+ _aux->valuator.mode = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_class_data_t.valuator.pad0 */
+ _aux->valuator.pad0[0] = *(uint8_t *)xcb_tmp;
+ _aux->valuator.pad0[1] = *(uint8_t *)xcb_tmp;
+ _aux->valuator.pad0[2] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 3;
+ xcb_tmp += sizeof(uint8_t) * 3;
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_SCROLL) {
+ /* xcb_input_device_class_data_t.scroll.number */
+ _aux->scroll.number = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_device_class_data_t.scroll.scroll_type */
+ _aux->scroll.scroll_type = *(uint16_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint16_t);
+ xcb_tmp += sizeof(uint16_t);
+ xcb_align_to = ALIGNOF(uint16_t);
+ /* xcb_input_device_class_data_t.scroll.pad1 */
+ _aux->scroll.pad1[0] = *(uint8_t *)xcb_tmp;
+ _aux->scroll.pad1[1] = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t) * 2;
+ xcb_tmp += sizeof(uint8_t) * 2;
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_class_data_t.scroll.flags */
+ _aux->scroll.flags = *(uint32_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint32_t);
+ xcb_tmp += sizeof(uint32_t);
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* xcb_input_device_class_data_t.scroll.increment */
+ _aux->scroll.increment = *(xcb_input_fp3232_t *)xcb_tmp;
+ xcb_block_len += sizeof(xcb_input_fp3232_t);
+ xcb_tmp += sizeof(xcb_input_fp3232_t);
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ }
+ if(type == XCB_INPUT_DEVICE_CLASS_TYPE_TOUCH) {
+ /* xcb_input_device_class_data_t.touch.mode */
+ _aux->touch.mode = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ /* xcb_input_device_class_data_t.touch.num_touches */
+ _aux->touch.num_touches = *(uint8_t *)xcb_tmp;
+ xcb_block_len += sizeof(uint8_t);
+ xcb_tmp += sizeof(uint8_t);
+ xcb_align_to = ALIGNOF(uint8_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_device_class_data_sizeof (const void *_buffer,
+ uint16_t type)
+{
+ xcb_input_device_class_data_t _aux;
+ return xcb_input_device_class_data_unpack(_buffer, type, &_aux);
+}
+
+int
+xcb_input_device_class_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_device_class_t *_aux = (xcb_input_device_class_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_device_class_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* data */
+ xcb_block_len += xcb_input_device_class_data_sizeof(xcb_tmp, _aux->type);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+void *
+xcb_input_device_class_data (const xcb_input_device_class_t *R)
+{
+ return (void *) (R + 1);
+}
+
+void
+xcb_input_device_class_next (xcb_input_device_class_iterator_t *i)
+{
+ xcb_input_device_class_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_device_class_t *)(((char *)R) + xcb_input_device_class_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_device_class_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_device_class_end (xcb_input_device_class_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_device_class_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_xi_device_info_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_device_info_t *_aux = (xcb_input_xi_device_info_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_xi_device_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* name */
+ xcb_block_len += _aux->name_len * sizeof(char);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* classes */
+ for(i=0; i<_aux->num_classes; i++) {
+ xcb_tmp_len = xcb_input_device_class_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_device_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+char *
+xcb_input_xi_device_info_name (const xcb_input_xi_device_info_t *R)
+{
+ return (char *) (R + 1);
+}
+
+int
+xcb_input_xi_device_info_name_length (const xcb_input_xi_device_info_t *R)
+{
+ return R->name_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_device_info_name_end (const xcb_input_xi_device_info_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((char *) (R + 1)) + (R->name_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_xi_device_info_classes_length (const xcb_input_xi_device_info_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_input_device_class_iterator_t
+xcb_input_xi_device_info_classes_iterator (const xcb_input_xi_device_info_t *R)
+{
+ xcb_input_device_class_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_xi_device_info_name_end(R);
+ i.data = (xcb_input_device_class_t *) ((char *) prev.data + ((-prev.index) & (4 - 1)));
+ i.rem = R->num_classes;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+void
+xcb_input_xi_device_info_next (xcb_input_xi_device_info_iterator_t *i)
+{
+ xcb_input_xi_device_info_t *R = i->data;
+ xcb_generic_iterator_t child;
+ child.data = (xcb_input_xi_device_info_t *)(((char *)R) + xcb_input_xi_device_info_sizeof(R));
+ i->index = (char *) child.data - (char *) i->data;
+ --i->rem;
+ i->data = (xcb_input_xi_device_info_t *) child.data;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_device_info_end (xcb_input_xi_device_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ while(i.rem > 0)
+ xcb_input_xi_device_info_next(&i);
+ ret.data = i.data;
+ ret.rem = i.rem;
+ ret.index = i.index;
+ return ret;
+}
+
+int
+xcb_input_xi_query_device_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_query_device_reply_t *_aux = (xcb_input_xi_query_device_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_xi_query_device_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* infos */
+ for(i=0; i<_aux->num_infos; i++) {
+ xcb_tmp_len = xcb_input_xi_device_info_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_xi_device_info_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_xi_query_device_cookie_t
+xcb_input_xi_query_device (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_QUERY_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_query_device_cookie_t xcb_ret;
+ xcb_input_xi_query_device_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_query_device_cookie_t
+xcb_input_xi_query_device_unchecked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_QUERY_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_query_device_cookie_t xcb_ret;
+ xcb_input_xi_query_device_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_xi_query_device_infos_length (const xcb_input_xi_query_device_reply_t *R)
+{
+ return R->num_infos;
+}
+
+xcb_input_xi_device_info_iterator_t
+xcb_input_xi_query_device_infos_iterator (const xcb_input_xi_query_device_reply_t *R)
+{
+ xcb_input_xi_device_info_iterator_t i;
+ i.data = (xcb_input_xi_device_info_t *) (R + 1);
+ i.rem = R->num_infos;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_xi_query_device_reply_t *
+xcb_input_xi_query_device_reply (xcb_connection_t *c,
+ xcb_input_xi_query_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_query_device_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_void_cookie_t
+xcb_input_xi_set_focus_checked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_SET_FOCUS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_set_focus_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.time = time;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_set_focus (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_SET_FOCUS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_set_focus_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.time = time;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_get_focus_cookie_t
+xcb_input_xi_get_focus (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GET_FOCUS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_get_focus_cookie_t xcb_ret;
+ xcb_input_xi_get_focus_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_get_focus_cookie_t
+xcb_input_xi_get_focus_unchecked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GET_FOCUS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_get_focus_cookie_t xcb_ret;
+ xcb_input_xi_get_focus_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_get_focus_reply_t *
+xcb_input_xi_get_focus_reply (xcb_connection_t *c,
+ xcb_input_xi_get_focus_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_get_focus_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_xi_grab_device_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_grab_device_request_t *_aux = (xcb_input_xi_grab_device_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_xi_grab_device_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* mask */
+ xcb_block_len += _aux->mask_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_xi_grab_device_cookie_t
+xcb_input_xi_grab_device (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_timestamp_t time,
+ xcb_cursor_t cursor,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t paired_device_mode,
+ uint8_t owner_events,
+ uint16_t mask_len,
+ const uint32_t *mask)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GRAB_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_xi_grab_device_cookie_t xcb_ret;
+ xcb_input_xi_grab_device_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.time = time;
+ xcb_out.cursor = cursor;
+ xcb_out.deviceid = deviceid;
+ xcb_out.mode = mode;
+ xcb_out.paired_device_mode = paired_device_mode;
+ xcb_out.owner_events = owner_events;
+ xcb_out.pad0 = 0;
+ xcb_out.mask_len = mask_len;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t mask */
+ xcb_parts[4].iov_base = (char *) mask;
+ xcb_parts[4].iov_len = mask_len * sizeof(uint32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_grab_device_cookie_t
+xcb_input_xi_grab_device_unchecked (xcb_connection_t *c,
+ xcb_window_t window,
+ xcb_timestamp_t time,
+ xcb_cursor_t cursor,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t paired_device_mode,
+ uint8_t owner_events,
+ uint16_t mask_len,
+ const uint32_t *mask)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GRAB_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_input_xi_grab_device_cookie_t xcb_ret;
+ xcb_input_xi_grab_device_request_t xcb_out;
+
+ xcb_out.window = window;
+ xcb_out.time = time;
+ xcb_out.cursor = cursor;
+ xcb_out.deviceid = deviceid;
+ xcb_out.mode = mode;
+ xcb_out.paired_device_mode = paired_device_mode;
+ xcb_out.owner_events = owner_events;
+ xcb_out.pad0 = 0;
+ xcb_out.mask_len = mask_len;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t mask */
+ xcb_parts[4].iov_base = (char *) mask;
+ xcb_parts[4].iov_len = mask_len * sizeof(uint32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_grab_device_reply_t *
+xcb_input_xi_grab_device_reply (xcb_connection_t *c,
+ xcb_input_xi_grab_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_grab_device_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+xcb_void_cookie_t
+xcb_input_xi_ungrab_device_checked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_UNGRAB_DEVICE,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_ungrab_device_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_ungrab_device (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_UNGRAB_DEVICE,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_ungrab_device_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_allow_events_checked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid,
+ uint8_t event_mode,
+ uint32_t touchid,
+ xcb_window_t grab_window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_ALLOW_EVENTS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_allow_events_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.deviceid = deviceid;
+ xcb_out.event_mode = event_mode;
+ xcb_out.pad0 = 0;
+ xcb_out.touchid = touchid;
+ xcb_out.grab_window = grab_window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_allow_events (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_input_device_id_t deviceid,
+ uint8_t event_mode,
+ uint32_t touchid,
+ xcb_window_t grab_window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_ALLOW_EVENTS,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_allow_events_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.deviceid = deviceid;
+ xcb_out.event_mode = event_mode;
+ xcb_out.pad0 = 0;
+ xcb_out.touchid = touchid;
+ xcb_out.grab_window = grab_window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+void
+xcb_input_grab_modifier_info_next (xcb_input_grab_modifier_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_grab_modifier_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_grab_modifier_info_end (xcb_input_grab_modifier_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_xi_passive_grab_device_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_passive_grab_device_request_t *_aux = (xcb_input_xi_passive_grab_device_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_xi_passive_grab_device_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* mask */
+ xcb_block_len += _aux->mask_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* modifiers */
+ xcb_block_len += _aux->num_modifiers * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_xi_passive_grab_device_cookie_t
+xcb_input_xi_passive_grab_device (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_window_t grab_window,
+ xcb_cursor_t cursor,
+ uint32_t detail,
+ xcb_input_device_id_t deviceid,
+ uint16_t num_modifiers,
+ uint16_t mask_len,
+ uint8_t grab_type,
+ uint8_t grab_mode,
+ uint8_t paired_device_mode,
+ uint8_t owner_events,
+ const uint32_t *mask,
+ const uint32_t *modifiers)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 6,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_PASSIVE_GRAB_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[8];
+ xcb_input_xi_passive_grab_device_cookie_t xcb_ret;
+ xcb_input_xi_passive_grab_device_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.grab_window = grab_window;
+ xcb_out.cursor = cursor;
+ xcb_out.detail = detail;
+ xcb_out.deviceid = deviceid;
+ xcb_out.num_modifiers = num_modifiers;
+ xcb_out.mask_len = mask_len;
+ xcb_out.grab_type = grab_type;
+ xcb_out.grab_mode = grab_mode;
+ xcb_out.paired_device_mode = paired_device_mode;
+ xcb_out.owner_events = owner_events;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t mask */
+ xcb_parts[4].iov_base = (char *) mask;
+ xcb_parts[4].iov_len = mask_len * sizeof(uint32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* uint32_t modifiers */
+ xcb_parts[6].iov_base = (char *) modifiers;
+ xcb_parts[6].iov_len = num_modifiers * sizeof(uint32_t);
+ xcb_parts[7].iov_base = 0;
+ xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_passive_grab_device_cookie_t
+xcb_input_xi_passive_grab_device_unchecked (xcb_connection_t *c,
+ xcb_timestamp_t time,
+ xcb_window_t grab_window,
+ xcb_cursor_t cursor,
+ uint32_t detail,
+ xcb_input_device_id_t deviceid,
+ uint16_t num_modifiers,
+ uint16_t mask_len,
+ uint8_t grab_type,
+ uint8_t grab_mode,
+ uint8_t paired_device_mode,
+ uint8_t owner_events,
+ const uint32_t *mask,
+ const uint32_t *modifiers)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 6,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_PASSIVE_GRAB_DEVICE,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[8];
+ xcb_input_xi_passive_grab_device_cookie_t xcb_ret;
+ xcb_input_xi_passive_grab_device_request_t xcb_out;
+
+ xcb_out.time = time;
+ xcb_out.grab_window = grab_window;
+ xcb_out.cursor = cursor;
+ xcb_out.detail = detail;
+ xcb_out.deviceid = deviceid;
+ xcb_out.num_modifiers = num_modifiers;
+ xcb_out.mask_len = mask_len;
+ xcb_out.grab_type = grab_type;
+ xcb_out.grab_mode = grab_mode;
+ xcb_out.paired_device_mode = paired_device_mode;
+ xcb_out.owner_events = owner_events;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t mask */
+ xcb_parts[4].iov_base = (char *) mask;
+ xcb_parts[4].iov_len = mask_len * sizeof(uint32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+ /* uint32_t modifiers */
+ xcb_parts[6].iov_base = (char *) modifiers;
+ xcb_parts[6].iov_len = num_modifiers * sizeof(uint32_t);
+ xcb_parts[7].iov_base = 0;
+ xcb_parts[7].iov_len = -xcb_parts[6].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_grab_modifier_info_t *
+xcb_input_xi_passive_grab_device_modifiers (const xcb_input_xi_passive_grab_device_reply_t *R)
+{
+ return (xcb_input_grab_modifier_info_t *) (R + 1);
+}
+
+int
+xcb_input_xi_passive_grab_device_modifiers_length (const xcb_input_xi_passive_grab_device_reply_t *R)
+{
+ return R->num_modifiers;
+}
+
+xcb_input_grab_modifier_info_iterator_t
+xcb_input_xi_passive_grab_device_modifiers_iterator (const xcb_input_xi_passive_grab_device_reply_t *R)
+{
+ xcb_input_grab_modifier_info_iterator_t i;
+ i.data = (xcb_input_grab_modifier_info_t *) (R + 1);
+ i.rem = R->num_modifiers;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_xi_passive_grab_device_reply_t *
+xcb_input_xi_passive_grab_device_reply (xcb_connection_t *c,
+ xcb_input_xi_passive_grab_device_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_passive_grab_device_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_xi_passive_ungrab_device_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_passive_ungrab_device_request_t *_aux = (xcb_input_xi_passive_ungrab_device_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_xi_passive_ungrab_device_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* modifiers */
+ xcb_block_len += _aux->num_modifiers * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_passive_ungrab_device_checked (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint32_t detail,
+ xcb_input_device_id_t deviceid,
+ uint16_t num_modifiers,
+ uint8_t grab_type,
+ const uint32_t *modifiers)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_PASSIVE_UNGRAB_DEVICE,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_passive_ungrab_device_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.detail = detail;
+ xcb_out.deviceid = deviceid;
+ xcb_out.num_modifiers = num_modifiers;
+ xcb_out.grab_type = grab_type;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t modifiers */
+ xcb_parts[4].iov_base = (char *) modifiers;
+ xcb_parts[4].iov_len = num_modifiers * sizeof(uint32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_passive_ungrab_device (xcb_connection_t *c,
+ xcb_window_t grab_window,
+ uint32_t detail,
+ xcb_input_device_id_t deviceid,
+ uint16_t num_modifiers,
+ uint8_t grab_type,
+ const uint32_t *modifiers)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 4,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_PASSIVE_UNGRAB_DEVICE,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[6];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_passive_ungrab_device_request_t xcb_out;
+
+ xcb_out.grab_window = grab_window;
+ xcb_out.detail = detail;
+ xcb_out.deviceid = deviceid;
+ xcb_out.num_modifiers = num_modifiers;
+ xcb_out.grab_type = grab_type;
+ memset(xcb_out.pad0, 0, 3);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* uint32_t modifiers */
+ xcb_parts[4].iov_base = (char *) modifiers;
+ xcb_parts[4].iov_len = num_modifiers * sizeof(uint32_t);
+ xcb_parts[5].iov_base = 0;
+ xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+uint32_t *
+xcb_input_xi_passive_ungrab_device_modifiers (const xcb_input_xi_passive_ungrab_device_request_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_xi_passive_ungrab_device_modifiers_length (const xcb_input_xi_passive_ungrab_device_request_t *R)
+{
+ return R->num_modifiers;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_passive_ungrab_device_modifiers_end (const xcb_input_xi_passive_ungrab_device_request_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->num_modifiers);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_xi_list_properties_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_list_properties_reply_t *_aux = (xcb_input_xi_list_properties_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_xi_list_properties_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* properties */
+ xcb_block_len += _aux->num_properties * sizeof(xcb_atom_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_atom_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_xi_list_properties_cookie_t
+xcb_input_xi_list_properties (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_LIST_PROPERTIES,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_list_properties_cookie_t xcb_ret;
+ xcb_input_xi_list_properties_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_list_properties_cookie_t
+xcb_input_xi_list_properties_unchecked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_LIST_PROPERTIES,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_list_properties_cookie_t xcb_ret;
+ xcb_input_xi_list_properties_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_atom_t *
+xcb_input_xi_list_properties_properties (const xcb_input_xi_list_properties_reply_t *R)
+{
+ return (xcb_atom_t *) (R + 1);
+}
+
+int
+xcb_input_xi_list_properties_properties_length (const xcb_input_xi_list_properties_reply_t *R)
+{
+ return R->num_properties;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_list_properties_properties_end (const xcb_input_xi_list_properties_reply_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((xcb_atom_t *) (R + 1)) + (R->num_properties);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_xi_list_properties_reply_t *
+xcb_input_xi_list_properties_reply (xcb_connection_t *c,
+ xcb_input_xi_list_properties_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_list_properties_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+uint8_t *
+xcb_input_xi_change_property_items_data_8 (const xcb_input_xi_change_property_items_t *S)
+{
+ return S->data8;
+}
+
+int
+xcb_input_xi_change_property_items_data_8_length (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_change_property_items_data_8_end (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data8 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint16_t *
+xcb_input_xi_change_property_items_data_16 (const xcb_input_xi_change_property_items_t *S)
+{
+ return S->data16;
+}
+
+int
+xcb_input_xi_change_property_items_data_16_length (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_change_property_items_data_16_end (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data16 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint32_t *
+xcb_input_xi_change_property_items_data_32 (const xcb_input_xi_change_property_items_t *S)
+{
+ return S->data32;
+}
+
+int
+xcb_input_xi_change_property_items_data_32_length (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_change_property_items_data_32_end (const xcb_input_xi_change_property_request_t *R,
+ const xcb_input_xi_change_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data32 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_xi_change_property_items_serialize (void **_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ const xcb_input_xi_change_property_items_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[9];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(format == XCB_INPUT_PROPERTY_FORMAT_8_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data8 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data8;
+ xcb_block_len += num_items * sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_16_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data16 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data16;
+ xcb_block_len += num_items * sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_32_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data32 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data32;
+ xcb_block_len += num_items * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_xi_change_property_items_unpack (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ xcb_input_xi_change_property_items_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(format == XCB_INPUT_PROPERTY_FORMAT_8_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data8 */
+ _aux->data8 = (uint8_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_16_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data16 */
+ _aux->data16 = (uint16_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_32_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data32 */
+ _aux->data32 = (uint32_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_xi_change_property_items_sizeof (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format)
+{
+ xcb_input_xi_change_property_items_t _aux;
+ return xcb_input_xi_change_property_items_unpack(_buffer, num_items, format, &_aux);
+}
+
+int
+xcb_input_xi_change_property_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_change_property_request_t *_aux = (xcb_input_xi_change_property_request_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_xi_change_property_request_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* items */
+ xcb_block_len += xcb_input_xi_change_property_items_sizeof(xcb_tmp, _aux->num_items, _aux->format);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_change_property_checked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t format,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t num_items,
+ const void *items)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 3,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_CHANGE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[5];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_change_property_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ xcb_out.mode = mode;
+ xcb_out.format = format;
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.num_items = num_items;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_xi_change_property_items_t items */
+ xcb_parts[4].iov_base = (char *) items;
+ xcb_parts[4].iov_len =
+ xcb_input_xi_change_property_items_sizeof (items, num_items, format);
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_change_property (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t format,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t num_items,
+ const void *items)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 3,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_CHANGE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[5];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_change_property_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ xcb_out.mode = mode;
+ xcb_out.format = format;
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.num_items = num_items;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_xi_change_property_items_t items */
+ xcb_parts[4].iov_base = (char *) items;
+ xcb_parts[4].iov_len =
+ xcb_input_xi_change_property_items_sizeof (items, num_items, format);
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_change_property_aux_checked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t format,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t num_items,
+ const xcb_input_xi_change_property_items_t *items)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 3,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_CHANGE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[5];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_change_property_request_t xcb_out;
+ void *xcb_aux0 = 0;
+
+ xcb_out.deviceid = deviceid;
+ xcb_out.mode = mode;
+ xcb_out.format = format;
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.num_items = num_items;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_xi_change_property_items_t items */
+ xcb_parts[4].iov_len =
+ xcb_input_xi_change_property_items_serialize (&xcb_aux0, num_items, format, items);
+ xcb_parts[4].iov_base = xcb_aux0;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ free(xcb_aux0);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_change_property_aux (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t mode,
+ uint8_t format,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t num_items,
+ const xcb_input_xi_change_property_items_t *items)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 3,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_CHANGE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[5];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_change_property_request_t xcb_out;
+ void *xcb_aux0 = 0;
+
+ xcb_out.deviceid = deviceid;
+ xcb_out.mode = mode;
+ xcb_out.format = format;
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.num_items = num_items;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+ /* xcb_input_xi_change_property_items_t items */
+ xcb_parts[4].iov_len =
+ xcb_input_xi_change_property_items_serialize (&xcb_aux0, num_items, format, items);
+ xcb_parts[4].iov_base = xcb_aux0;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ free(xcb_aux0);
+ return xcb_ret;
+}
+
+void *
+xcb_input_xi_change_property_items (const xcb_input_xi_change_property_request_t *R)
+{
+ return (void *) (R + 1);
+}
+
+xcb_void_cookie_t
+xcb_input_xi_delete_property_checked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ xcb_atom_t property)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_DELETE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_delete_property_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+ xcb_out.property = property;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_void_cookie_t
+xcb_input_xi_delete_property (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ xcb_atom_t property)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_DELETE_PROPERTY,
+ .isvoid = 1
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_void_cookie_t xcb_ret;
+ xcb_input_xi_delete_property_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ memset(xcb_out.pad0, 0, 2);
+ xcb_out.property = property;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+uint8_t *
+xcb_input_xi_get_property_items_data_8 (const xcb_input_xi_get_property_items_t *S)
+{
+ return S->data8;
+}
+
+int
+xcb_input_xi_get_property_items_data_8_length (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_get_property_items_data_8_end (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data8 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint16_t *
+xcb_input_xi_get_property_items_data_16 (const xcb_input_xi_get_property_items_t *S)
+{
+ return S->data16;
+}
+
+int
+xcb_input_xi_get_property_items_data_16_length (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_get_property_items_data_16_end (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data16 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+uint32_t *
+xcb_input_xi_get_property_items_data_32 (const xcb_input_xi_get_property_items_t *S)
+{
+ return S->data32;
+}
+
+int
+xcb_input_xi_get_property_items_data_32_length (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S)
+{
+ return R->num_items;
+}
+
+xcb_generic_iterator_t
+xcb_input_xi_get_property_items_data_32_end (const xcb_input_xi_get_property_reply_t *R,
+ const xcb_input_xi_get_property_items_t *S)
+{
+ xcb_generic_iterator_t i;
+ i.data = S->data32 + R->num_items;
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) S;
+ return i;
+}
+
+int
+xcb_input_xi_get_property_items_serialize (void **_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ const xcb_input_xi_get_property_items_t *_aux)
+{
+ char *xcb_out = *_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+ unsigned int xcb_pad = 0;
+ char xcb_pad0[3] = {0, 0, 0};
+ struct iovec xcb_parts[9];
+ unsigned int xcb_parts_idx = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int i;
+ char *xcb_tmp;
+
+ if(format == XCB_INPUT_PROPERTY_FORMAT_8_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data8 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data8;
+ xcb_block_len += num_items * sizeof(uint8_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint8_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_16_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data16 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data16;
+ xcb_block_len += num_items * sizeof(uint16_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint16_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint16_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_32_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data32 */
+ xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->data32;
+ xcb_block_len += num_items * sizeof(uint32_t);
+ xcb_parts[xcb_parts_idx].iov_len = num_items * sizeof(uint32_t);
+ xcb_parts_idx++;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_parts[xcb_parts_idx].iov_base = xcb_pad0;
+ xcb_parts[xcb_parts_idx].iov_len = xcb_pad;
+ xcb_parts_idx++;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ if (NULL == xcb_out) {
+ /* allocate memory */
+ xcb_out = malloc(xcb_buffer_len);
+ *_buffer = xcb_out;
+ }
+
+ xcb_tmp = xcb_out;
+ for(i=0; i<xcb_parts_idx; i++) {
+ if (0 != xcb_parts[i].iov_base && 0 != xcb_parts[i].iov_len)
+ memcpy(xcb_tmp, xcb_parts[i].iov_base, xcb_parts[i].iov_len);
+ if (0 != xcb_parts[i].iov_len)
+ xcb_tmp += xcb_parts[i].iov_len;
+ }
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_xi_get_property_items_unpack (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format,
+ xcb_input_xi_get_property_items_t *_aux)
+{
+ char *xcb_tmp = (char *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+ unsigned int xcb_padding_offset = 0;
+
+
+ if(format == XCB_INPUT_PROPERTY_FORMAT_8_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data8 */
+ _aux->data8 = (uint8_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint8_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint8_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_16_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data16 */
+ _aux->data16 = (uint16_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint16_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint16_t);
+ xcb_align_to = 4;
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ }
+ if(format == XCB_INPUT_PROPERTY_FORMAT_32_BITS) {
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+ /* data32 */
+ _aux->data32 = (uint32_t *)xcb_tmp;
+ xcb_block_len += num_items * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ }
+ /* insert padding */
+ xcb_pad = -(xcb_block_len + xcb_padding_offset) & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ xcb_padding_offset = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_xi_get_property_items_sizeof (const void *_buffer,
+ uint32_t num_items,
+ uint8_t format)
+{
+ xcb_input_xi_get_property_items_t _aux;
+ return xcb_input_xi_get_property_items_unpack(_buffer, num_items, format, &_aux);
+}
+
+int
+xcb_input_xi_get_property_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_get_property_reply_t *_aux = (xcb_input_xi_get_property_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_xi_get_property_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* items */
+ xcb_block_len += xcb_input_xi_get_property_items_sizeof(xcb_tmp, _aux->num_items, _aux->format);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(char);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_xi_get_property_cookie_t
+xcb_input_xi_get_property (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t _delete,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t offset,
+ uint32_t len)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GET_PROPERTY,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_get_property_cookie_t xcb_ret;
+ xcb_input_xi_get_property_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ xcb_out._delete = _delete;
+ xcb_out.pad0 = 0;
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.offset = offset;
+ xcb_out.len = len;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_get_property_cookie_t
+xcb_input_xi_get_property_unchecked (xcb_connection_t *c,
+ xcb_input_device_id_t deviceid,
+ uint8_t _delete,
+ xcb_atom_t property,
+ xcb_atom_t type,
+ uint32_t offset,
+ uint32_t len)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GET_PROPERTY,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_get_property_cookie_t xcb_ret;
+ xcb_input_xi_get_property_request_t xcb_out;
+
+ xcb_out.deviceid = deviceid;
+ xcb_out._delete = _delete;
+ xcb_out.pad0 = 0;
+ xcb_out.property = property;
+ xcb_out.type = type;
+ xcb_out.offset = offset;
+ xcb_out.len = len;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+void *
+xcb_input_xi_get_property_items (const xcb_input_xi_get_property_reply_t *R)
+{
+ return (void *) (R + 1);
+}
+
+xcb_input_xi_get_property_reply_t *
+xcb_input_xi_get_property_reply (xcb_connection_t *c,
+ xcb_input_xi_get_property_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_get_property_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_xi_get_selected_events_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_xi_get_selected_events_reply_t *_aux = (xcb_input_xi_get_selected_events_reply_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_xi_get_selected_events_reply_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* masks */
+ for(i=0; i<_aux->num_masks; i++) {
+ xcb_tmp_len = xcb_input_event_mask_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_event_mask_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_xi_get_selected_events_cookie_t
+xcb_input_xi_get_selected_events (xcb_connection_t *c,
+ xcb_window_t window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GET_SELECTED_EVENTS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_get_selected_events_cookie_t xcb_ret;
+ xcb_input_xi_get_selected_events_request_t xcb_out;
+
+ xcb_out.window = window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+xcb_input_xi_get_selected_events_cookie_t
+xcb_input_xi_get_selected_events_unchecked (xcb_connection_t *c,
+ xcb_window_t window)
+{
+ static const xcb_protocol_request_t xcb_req = {
+ .count = 2,
+ .ext = &xcb_input_id,
+ .opcode = XCB_INPUT_XI_GET_SELECTED_EVENTS,
+ .isvoid = 0
+ };
+
+ struct iovec xcb_parts[4];
+ xcb_input_xi_get_selected_events_cookie_t xcb_ret;
+ xcb_input_xi_get_selected_events_request_t xcb_out;
+
+ xcb_out.window = window;
+
+ xcb_parts[2].iov_base = (char *) &xcb_out;
+ xcb_parts[2].iov_len = sizeof(xcb_out);
+ xcb_parts[3].iov_base = 0;
+ xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
+
+ xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
+ return xcb_ret;
+}
+
+int
+xcb_input_xi_get_selected_events_masks_length (const xcb_input_xi_get_selected_events_reply_t *R)
+{
+ return R->num_masks;
+}
+
+xcb_input_event_mask_iterator_t
+xcb_input_xi_get_selected_events_masks_iterator (const xcb_input_xi_get_selected_events_reply_t *R)
+{
+ xcb_input_event_mask_iterator_t i;
+ i.data = (xcb_input_event_mask_t *) (R + 1);
+ i.rem = R->num_masks;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_xi_get_selected_events_reply_t *
+xcb_input_xi_get_selected_events_reply (xcb_connection_t *c,
+ xcb_input_xi_get_selected_events_cookie_t cookie /**< */,
+ xcb_generic_error_t **e)
+{
+ return (xcb_input_xi_get_selected_events_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e);
+}
+
+int
+xcb_input_device_changed_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_device_changed_event_t *_aux = (xcb_input_device_changed_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ unsigned int i;
+ unsigned int xcb_tmp_len;
+
+ xcb_block_len += sizeof(xcb_input_device_changed_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* classes */
+ for(i=0; i<_aux->num_classes; i++) {
+ xcb_tmp_len = xcb_input_device_class_sizeof(xcb_tmp);
+ xcb_block_len += xcb_tmp_len;
+ xcb_tmp += xcb_tmp_len;
+ }
+ xcb_align_to = ALIGNOF(xcb_input_device_class_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+int
+xcb_input_device_changed_classes_length (const xcb_input_device_changed_event_t *R)
+{
+ return R->num_classes;
+}
+
+xcb_input_device_class_iterator_t
+xcb_input_device_changed_classes_iterator (const xcb_input_device_changed_event_t *R)
+{
+ xcb_input_device_class_iterator_t i;
+ i.data = (xcb_input_device_class_t *) (R + 1);
+ i.rem = R->num_classes;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_key_press_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_key_press_event_t *_aux = (xcb_input_key_press_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ int xcb_pre_tmp_1; /* sumof length */
+ int xcb_pre_tmp_2; /* sumof loop counter */
+ int64_t xcb_pre_tmp_3; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_4; /* sumof list ptr */
+
+ xcb_block_len += sizeof(xcb_input_key_press_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* button_mask */
+ xcb_block_len += _aux->buttons_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* valuator_mask */
+ xcb_block_len += _aux->valuators_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues */
+ /* sumof start */
+ xcb_pre_tmp_1 = _aux->valuators_len;
+ xcb_pre_tmp_3 = 0;
+ xcb_pre_tmp_4 = xcb_input_key_press_valuator_mask(_aux);
+ for (xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_4;
+ xcb_pre_tmp_3 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_4++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_3 */
+ xcb_block_len += xcb_pre_tmp_3 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_key_press_button_mask (const xcb_input_key_press_event_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_key_press_button_mask_length (const xcb_input_key_press_event_t *R)
+{
+ return R->buttons_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_key_press_button_mask_end (const xcb_input_key_press_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->buttons_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+uint32_t *
+xcb_input_key_press_valuator_mask (const xcb_input_key_press_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_key_press_button_mask_end(R);
+ return (uint32_t *) ((char *) prev.data + XCB_TYPE_PAD(uint32_t, prev.index) + 0);
+}
+
+int
+xcb_input_key_press_valuator_mask_length (const xcb_input_key_press_event_t *R)
+{
+ return R->valuators_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_key_press_valuator_mask_end (const xcb_input_key_press_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_key_press_button_mask_end(R);
+ i.data = ((uint32_t *) ((char*) prev.data + XCB_TYPE_PAD(uint32_t, prev.index))) + (R->valuators_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_key_press_axisvalues (const xcb_input_key_press_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_key_press_valuator_mask_end(R);
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_key_press_axisvalues_length (const xcb_input_key_press_event_t *R)
+{
+ int xcb_pre_tmp_5; /* sumof length */
+ int xcb_pre_tmp_6; /* sumof loop counter */
+ int64_t xcb_pre_tmp_7; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_8; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_5 = R->valuators_len;
+ xcb_pre_tmp_7 = 0;
+ xcb_pre_tmp_8 = xcb_input_key_press_valuator_mask(R);
+ for (xcb_pre_tmp_6 = 0; xcb_pre_tmp_6 < xcb_pre_tmp_5; xcb_pre_tmp_6++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_8;
+ xcb_pre_tmp_7 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_8++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_7 */
+ return xcb_pre_tmp_7;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_key_press_axisvalues_iterator (const xcb_input_key_press_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_key_press_valuator_mask_end(R);
+ int xcb_pre_tmp_9; /* sumof length */
+ int xcb_pre_tmp_10; /* sumof loop counter */
+ int64_t xcb_pre_tmp_11; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_12; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_9 = R->valuators_len;
+ xcb_pre_tmp_11 = 0;
+ xcb_pre_tmp_12 = xcb_input_key_press_valuator_mask(R);
+ for (xcb_pre_tmp_10 = 0; xcb_pre_tmp_10 < xcb_pre_tmp_9; xcb_pre_tmp_10++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_12;
+ xcb_pre_tmp_11 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_12++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_11 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_11;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_key_release_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_key_press_sizeof(_buffer);
+}
+
+int
+xcb_input_button_press_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_button_press_event_t *_aux = (xcb_input_button_press_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ int xcb_pre_tmp_1; /* sumof length */
+ int xcb_pre_tmp_2; /* sumof loop counter */
+ int64_t xcb_pre_tmp_3; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_4; /* sumof list ptr */
+
+ xcb_block_len += sizeof(xcb_input_button_press_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* button_mask */
+ xcb_block_len += _aux->buttons_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* valuator_mask */
+ xcb_block_len += _aux->valuators_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues */
+ /* sumof start */
+ xcb_pre_tmp_1 = _aux->valuators_len;
+ xcb_pre_tmp_3 = 0;
+ xcb_pre_tmp_4 = xcb_input_button_press_valuator_mask(_aux);
+ for (xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_4;
+ xcb_pre_tmp_3 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_4++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_3 */
+ xcb_block_len += xcb_pre_tmp_3 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_button_press_button_mask (const xcb_input_button_press_event_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_button_press_button_mask_length (const xcb_input_button_press_event_t *R)
+{
+ return R->buttons_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_button_press_button_mask_end (const xcb_input_button_press_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->buttons_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+uint32_t *
+xcb_input_button_press_valuator_mask (const xcb_input_button_press_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_button_press_button_mask_end(R);
+ return (uint32_t *) ((char *) prev.data + XCB_TYPE_PAD(uint32_t, prev.index) + 0);
+}
+
+int
+xcb_input_button_press_valuator_mask_length (const xcb_input_button_press_event_t *R)
+{
+ return R->valuators_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_button_press_valuator_mask_end (const xcb_input_button_press_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_button_press_button_mask_end(R);
+ i.data = ((uint32_t *) ((char*) prev.data + XCB_TYPE_PAD(uint32_t, prev.index))) + (R->valuators_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_button_press_axisvalues (const xcb_input_button_press_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_button_press_valuator_mask_end(R);
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_button_press_axisvalues_length (const xcb_input_button_press_event_t *R)
+{
+ int xcb_pre_tmp_5; /* sumof length */
+ int xcb_pre_tmp_6; /* sumof loop counter */
+ int64_t xcb_pre_tmp_7; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_8; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_5 = R->valuators_len;
+ xcb_pre_tmp_7 = 0;
+ xcb_pre_tmp_8 = xcb_input_button_press_valuator_mask(R);
+ for (xcb_pre_tmp_6 = 0; xcb_pre_tmp_6 < xcb_pre_tmp_5; xcb_pre_tmp_6++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_8;
+ xcb_pre_tmp_7 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_8++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_7 */
+ return xcb_pre_tmp_7;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_button_press_axisvalues_iterator (const xcb_input_button_press_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_button_press_valuator_mask_end(R);
+ int xcb_pre_tmp_9; /* sumof length */
+ int xcb_pre_tmp_10; /* sumof loop counter */
+ int64_t xcb_pre_tmp_11; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_12; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_9 = R->valuators_len;
+ xcb_pre_tmp_11 = 0;
+ xcb_pre_tmp_12 = xcb_input_button_press_valuator_mask(R);
+ for (xcb_pre_tmp_10 = 0; xcb_pre_tmp_10 < xcb_pre_tmp_9; xcb_pre_tmp_10++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_12;
+ xcb_pre_tmp_11 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_12++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_11 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_11;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_button_release_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_button_press_sizeof(_buffer);
+}
+
+int
+xcb_input_motion_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_button_press_sizeof(_buffer);
+}
+
+int
+xcb_input_enter_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_enter_event_t *_aux = (xcb_input_enter_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_enter_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* buttons */
+ xcb_block_len += _aux->buttons_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_enter_buttons (const xcb_input_enter_event_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_enter_buttons_length (const xcb_input_enter_event_t *R)
+{
+ return R->buttons_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_enter_buttons_end (const xcb_input_enter_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->buttons_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_leave_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_enter_sizeof(_buffer);
+}
+
+int
+xcb_input_focus_in_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_enter_sizeof(_buffer);
+}
+
+int
+xcb_input_focus_out_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_enter_sizeof(_buffer);
+}
+
+void
+xcb_input_hierarchy_info_next (xcb_input_hierarchy_info_iterator_t *i)
+{
+ --i->rem;
+ ++i->data;
+ i->index += sizeof(xcb_input_hierarchy_info_t);
+}
+
+xcb_generic_iterator_t
+xcb_input_hierarchy_info_end (xcb_input_hierarchy_info_iterator_t i)
+{
+ xcb_generic_iterator_t ret;
+ ret.data = i.data + i.rem;
+ ret.index = i.index + ((char *) ret.data - (char *) i.data);
+ ret.rem = 0;
+ return ret;
+}
+
+int
+xcb_input_hierarchy_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_hierarchy_event_t *_aux = (xcb_input_hierarchy_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+
+ xcb_block_len += sizeof(xcb_input_hierarchy_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* infos */
+ xcb_block_len += _aux->num_infos * sizeof(xcb_input_hierarchy_info_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_hierarchy_info_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+xcb_input_hierarchy_info_t *
+xcb_input_hierarchy_infos (const xcb_input_hierarchy_event_t *R)
+{
+ return (xcb_input_hierarchy_info_t *) (R + 1);
+}
+
+int
+xcb_input_hierarchy_infos_length (const xcb_input_hierarchy_event_t *R)
+{
+ return R->num_infos;
+}
+
+xcb_input_hierarchy_info_iterator_t
+xcb_input_hierarchy_infos_iterator (const xcb_input_hierarchy_event_t *R)
+{
+ xcb_input_hierarchy_info_iterator_t i;
+ i.data = (xcb_input_hierarchy_info_t *) (R + 1);
+ i.rem = R->num_infos;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_raw_key_press_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_raw_key_press_event_t *_aux = (xcb_input_raw_key_press_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ int xcb_pre_tmp_1; /* sumof length */
+ int xcb_pre_tmp_2; /* sumof loop counter */
+ int64_t xcb_pre_tmp_3; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_4; /* sumof list ptr */
+ int xcb_pre_tmp_5; /* sumof length */
+ int xcb_pre_tmp_6; /* sumof loop counter */
+ int64_t xcb_pre_tmp_7; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_8; /* sumof list ptr */
+
+ xcb_block_len += sizeof(xcb_input_raw_key_press_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* valuator_mask */
+ xcb_block_len += _aux->valuators_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues */
+ /* sumof start */
+ xcb_pre_tmp_1 = _aux->valuators_len;
+ xcb_pre_tmp_3 = 0;
+ xcb_pre_tmp_4 = xcb_input_raw_key_press_valuator_mask(_aux);
+ for (xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_4;
+ xcb_pre_tmp_3 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_4++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_3 */
+ xcb_block_len += xcb_pre_tmp_3 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues_raw */
+ /* sumof start */
+ xcb_pre_tmp_5 = _aux->valuators_len;
+ xcb_pre_tmp_7 = 0;
+ xcb_pre_tmp_8 = xcb_input_raw_key_press_valuator_mask(_aux);
+ for (xcb_pre_tmp_6 = 0; xcb_pre_tmp_6 < xcb_pre_tmp_5; xcb_pre_tmp_6++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_8;
+ xcb_pre_tmp_7 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_8++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_7 */
+ xcb_block_len += xcb_pre_tmp_7 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_raw_key_press_valuator_mask (const xcb_input_raw_key_press_event_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_raw_key_press_valuator_mask_length (const xcb_input_raw_key_press_event_t *R)
+{
+ return R->valuators_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_raw_key_press_valuator_mask_end (const xcb_input_raw_key_press_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->valuators_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_raw_key_press_axisvalues (const xcb_input_raw_key_press_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_raw_key_press_valuator_mask_end(R);
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_raw_key_press_axisvalues_length (const xcb_input_raw_key_press_event_t *R)
+{
+ int xcb_pre_tmp_9; /* sumof length */
+ int xcb_pre_tmp_10; /* sumof loop counter */
+ int64_t xcb_pre_tmp_11; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_12; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_9 = R->valuators_len;
+ xcb_pre_tmp_11 = 0;
+ xcb_pre_tmp_12 = xcb_input_raw_key_press_valuator_mask(R);
+ for (xcb_pre_tmp_10 = 0; xcb_pre_tmp_10 < xcb_pre_tmp_9; xcb_pre_tmp_10++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_12;
+ xcb_pre_tmp_11 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_12++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_11 */
+ return xcb_pre_tmp_11;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_key_press_axisvalues_iterator (const xcb_input_raw_key_press_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_raw_key_press_valuator_mask_end(R);
+ int xcb_pre_tmp_13; /* sumof length */
+ int xcb_pre_tmp_14; /* sumof loop counter */
+ int64_t xcb_pre_tmp_15; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_16; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_13 = R->valuators_len;
+ xcb_pre_tmp_15 = 0;
+ xcb_pre_tmp_16 = xcb_input_raw_key_press_valuator_mask(R);
+ for (xcb_pre_tmp_14 = 0; xcb_pre_tmp_14 < xcb_pre_tmp_13; xcb_pre_tmp_14++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_16;
+ xcb_pre_tmp_15 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_16++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_15 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_15;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_raw_key_press_axisvalues_raw (const xcb_input_raw_key_press_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_fp3232_end(xcb_input_raw_key_press_axisvalues_iterator(R));
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_raw_key_press_axisvalues_raw_length (const xcb_input_raw_key_press_event_t *R)
+{
+ int xcb_pre_tmp_17; /* sumof length */
+ int xcb_pre_tmp_18; /* sumof loop counter */
+ int64_t xcb_pre_tmp_19; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_20; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_17 = R->valuators_len;
+ xcb_pre_tmp_19 = 0;
+ xcb_pre_tmp_20 = xcb_input_raw_key_press_valuator_mask(R);
+ for (xcb_pre_tmp_18 = 0; xcb_pre_tmp_18 < xcb_pre_tmp_17; xcb_pre_tmp_18++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_20;
+ xcb_pre_tmp_19 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_20++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_19 */
+ return xcb_pre_tmp_19;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_key_press_axisvalues_raw_iterator (const xcb_input_raw_key_press_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_fp3232_end(xcb_input_raw_key_press_axisvalues_iterator(R));
+ int xcb_pre_tmp_21; /* sumof length */
+ int xcb_pre_tmp_22; /* sumof loop counter */
+ int64_t xcb_pre_tmp_23; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_24; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_21 = R->valuators_len;
+ xcb_pre_tmp_23 = 0;
+ xcb_pre_tmp_24 = xcb_input_raw_key_press_valuator_mask(R);
+ for (xcb_pre_tmp_22 = 0; xcb_pre_tmp_22 < xcb_pre_tmp_21; xcb_pre_tmp_22++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_24;
+ xcb_pre_tmp_23 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_24++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_23 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_23;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_raw_key_release_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_raw_key_press_sizeof(_buffer);
+}
+
+int
+xcb_input_raw_button_press_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_raw_button_press_event_t *_aux = (xcb_input_raw_button_press_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ int xcb_pre_tmp_1; /* sumof length */
+ int xcb_pre_tmp_2; /* sumof loop counter */
+ int64_t xcb_pre_tmp_3; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_4; /* sumof list ptr */
+ int xcb_pre_tmp_5; /* sumof length */
+ int xcb_pre_tmp_6; /* sumof loop counter */
+ int64_t xcb_pre_tmp_7; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_8; /* sumof list ptr */
+
+ xcb_block_len += sizeof(xcb_input_raw_button_press_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* valuator_mask */
+ xcb_block_len += _aux->valuators_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues */
+ /* sumof start */
+ xcb_pre_tmp_1 = _aux->valuators_len;
+ xcb_pre_tmp_3 = 0;
+ xcb_pre_tmp_4 = xcb_input_raw_button_press_valuator_mask(_aux);
+ for (xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_4;
+ xcb_pre_tmp_3 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_4++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_3 */
+ xcb_block_len += xcb_pre_tmp_3 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues_raw */
+ /* sumof start */
+ xcb_pre_tmp_5 = _aux->valuators_len;
+ xcb_pre_tmp_7 = 0;
+ xcb_pre_tmp_8 = xcb_input_raw_button_press_valuator_mask(_aux);
+ for (xcb_pre_tmp_6 = 0; xcb_pre_tmp_6 < xcb_pre_tmp_5; xcb_pre_tmp_6++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_8;
+ xcb_pre_tmp_7 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_8++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_7 */
+ xcb_block_len += xcb_pre_tmp_7 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_raw_button_press_valuator_mask (const xcb_input_raw_button_press_event_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_raw_button_press_valuator_mask_length (const xcb_input_raw_button_press_event_t *R)
+{
+ return R->valuators_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_raw_button_press_valuator_mask_end (const xcb_input_raw_button_press_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->valuators_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_raw_button_press_axisvalues (const xcb_input_raw_button_press_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_raw_button_press_valuator_mask_end(R);
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_raw_button_press_axisvalues_length (const xcb_input_raw_button_press_event_t *R)
+{
+ int xcb_pre_tmp_9; /* sumof length */
+ int xcb_pre_tmp_10; /* sumof loop counter */
+ int64_t xcb_pre_tmp_11; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_12; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_9 = R->valuators_len;
+ xcb_pre_tmp_11 = 0;
+ xcb_pre_tmp_12 = xcb_input_raw_button_press_valuator_mask(R);
+ for (xcb_pre_tmp_10 = 0; xcb_pre_tmp_10 < xcb_pre_tmp_9; xcb_pre_tmp_10++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_12;
+ xcb_pre_tmp_11 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_12++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_11 */
+ return xcb_pre_tmp_11;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_button_press_axisvalues_iterator (const xcb_input_raw_button_press_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_raw_button_press_valuator_mask_end(R);
+ int xcb_pre_tmp_13; /* sumof length */
+ int xcb_pre_tmp_14; /* sumof loop counter */
+ int64_t xcb_pre_tmp_15; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_16; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_13 = R->valuators_len;
+ xcb_pre_tmp_15 = 0;
+ xcb_pre_tmp_16 = xcb_input_raw_button_press_valuator_mask(R);
+ for (xcb_pre_tmp_14 = 0; xcb_pre_tmp_14 < xcb_pre_tmp_13; xcb_pre_tmp_14++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_16;
+ xcb_pre_tmp_15 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_16++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_15 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_15;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_raw_button_press_axisvalues_raw (const xcb_input_raw_button_press_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_fp3232_end(xcb_input_raw_button_press_axisvalues_iterator(R));
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_raw_button_press_axisvalues_raw_length (const xcb_input_raw_button_press_event_t *R)
+{
+ int xcb_pre_tmp_17; /* sumof length */
+ int xcb_pre_tmp_18; /* sumof loop counter */
+ int64_t xcb_pre_tmp_19; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_20; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_17 = R->valuators_len;
+ xcb_pre_tmp_19 = 0;
+ xcb_pre_tmp_20 = xcb_input_raw_button_press_valuator_mask(R);
+ for (xcb_pre_tmp_18 = 0; xcb_pre_tmp_18 < xcb_pre_tmp_17; xcb_pre_tmp_18++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_20;
+ xcb_pre_tmp_19 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_20++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_19 */
+ return xcb_pre_tmp_19;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_button_press_axisvalues_raw_iterator (const xcb_input_raw_button_press_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_fp3232_end(xcb_input_raw_button_press_axisvalues_iterator(R));
+ int xcb_pre_tmp_21; /* sumof length */
+ int xcb_pre_tmp_22; /* sumof loop counter */
+ int64_t xcb_pre_tmp_23; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_24; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_21 = R->valuators_len;
+ xcb_pre_tmp_23 = 0;
+ xcb_pre_tmp_24 = xcb_input_raw_button_press_valuator_mask(R);
+ for (xcb_pre_tmp_22 = 0; xcb_pre_tmp_22 < xcb_pre_tmp_21; xcb_pre_tmp_22++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_24;
+ xcb_pre_tmp_23 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_24++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_23 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_23;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_raw_button_release_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_raw_button_press_sizeof(_buffer);
+}
+
+int
+xcb_input_raw_motion_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_raw_button_press_sizeof(_buffer);
+}
+
+int
+xcb_input_touch_begin_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_touch_begin_event_t *_aux = (xcb_input_touch_begin_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ int xcb_pre_tmp_1; /* sumof length */
+ int xcb_pre_tmp_2; /* sumof loop counter */
+ int64_t xcb_pre_tmp_3; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_4; /* sumof list ptr */
+
+ xcb_block_len += sizeof(xcb_input_touch_begin_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* button_mask */
+ xcb_block_len += _aux->buttons_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* valuator_mask */
+ xcb_block_len += _aux->valuators_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues */
+ /* sumof start */
+ xcb_pre_tmp_1 = _aux->valuators_len;
+ xcb_pre_tmp_3 = 0;
+ xcb_pre_tmp_4 = xcb_input_touch_begin_valuator_mask(_aux);
+ for (xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_4;
+ xcb_pre_tmp_3 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_4++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_3 */
+ xcb_block_len += xcb_pre_tmp_3 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_touch_begin_button_mask (const xcb_input_touch_begin_event_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_touch_begin_button_mask_length (const xcb_input_touch_begin_event_t *R)
+{
+ return R->buttons_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_touch_begin_button_mask_end (const xcb_input_touch_begin_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->buttons_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+uint32_t *
+xcb_input_touch_begin_valuator_mask (const xcb_input_touch_begin_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_touch_begin_button_mask_end(R);
+ return (uint32_t *) ((char *) prev.data + XCB_TYPE_PAD(uint32_t, prev.index) + 0);
+}
+
+int
+xcb_input_touch_begin_valuator_mask_length (const xcb_input_touch_begin_event_t *R)
+{
+ return R->valuators_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_touch_begin_valuator_mask_end (const xcb_input_touch_begin_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_touch_begin_button_mask_end(R);
+ i.data = ((uint32_t *) ((char*) prev.data + XCB_TYPE_PAD(uint32_t, prev.index))) + (R->valuators_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_touch_begin_axisvalues (const xcb_input_touch_begin_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_touch_begin_valuator_mask_end(R);
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_touch_begin_axisvalues_length (const xcb_input_touch_begin_event_t *R)
+{
+ int xcb_pre_tmp_5; /* sumof length */
+ int xcb_pre_tmp_6; /* sumof loop counter */
+ int64_t xcb_pre_tmp_7; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_8; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_5 = R->valuators_len;
+ xcb_pre_tmp_7 = 0;
+ xcb_pre_tmp_8 = xcb_input_touch_begin_valuator_mask(R);
+ for (xcb_pre_tmp_6 = 0; xcb_pre_tmp_6 < xcb_pre_tmp_5; xcb_pre_tmp_6++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_8;
+ xcb_pre_tmp_7 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_8++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_7 */
+ return xcb_pre_tmp_7;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_touch_begin_axisvalues_iterator (const xcb_input_touch_begin_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_touch_begin_valuator_mask_end(R);
+ int xcb_pre_tmp_9; /* sumof length */
+ int xcb_pre_tmp_10; /* sumof loop counter */
+ int64_t xcb_pre_tmp_11; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_12; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_9 = R->valuators_len;
+ xcb_pre_tmp_11 = 0;
+ xcb_pre_tmp_12 = xcb_input_touch_begin_valuator_mask(R);
+ for (xcb_pre_tmp_10 = 0; xcb_pre_tmp_10 < xcb_pre_tmp_9; xcb_pre_tmp_10++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_12;
+ xcb_pre_tmp_11 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_12++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_11 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_11;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_touch_update_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_touch_begin_sizeof(_buffer);
+}
+
+int
+xcb_input_touch_end_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_touch_begin_sizeof(_buffer);
+}
+
+int
+xcb_input_raw_touch_begin_sizeof (const void *_buffer)
+{
+ char *xcb_tmp = (char *)_buffer;
+ const xcb_input_raw_touch_begin_event_t *_aux = (xcb_input_raw_touch_begin_event_t *)_buffer;
+ unsigned int xcb_buffer_len = 0;
+ unsigned int xcb_block_len = 0;
+ unsigned int xcb_pad = 0;
+ unsigned int xcb_align_to = 0;
+
+ int xcb_pre_tmp_1; /* sumof length */
+ int xcb_pre_tmp_2; /* sumof loop counter */
+ int64_t xcb_pre_tmp_3; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_4; /* sumof list ptr */
+ int xcb_pre_tmp_5; /* sumof length */
+ int xcb_pre_tmp_6; /* sumof loop counter */
+ int64_t xcb_pre_tmp_7; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_8; /* sumof list ptr */
+
+ xcb_block_len += sizeof(xcb_input_raw_touch_begin_event_t);
+ xcb_tmp += xcb_block_len;
+ xcb_buffer_len += xcb_block_len;
+ xcb_block_len = 0;
+ /* valuator_mask */
+ xcb_block_len += _aux->valuators_len * sizeof(uint32_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(uint32_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues */
+ /* sumof start */
+ xcb_pre_tmp_1 = _aux->valuators_len;
+ xcb_pre_tmp_3 = 0;
+ xcb_pre_tmp_4 = xcb_input_raw_touch_begin_valuator_mask(_aux);
+ for (xcb_pre_tmp_2 = 0; xcb_pre_tmp_2 < xcb_pre_tmp_1; xcb_pre_tmp_2++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_4;
+ xcb_pre_tmp_3 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_4++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_3 */
+ xcb_block_len += xcb_pre_tmp_3 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+ /* axisvalues_raw */
+ /* sumof start */
+ xcb_pre_tmp_5 = _aux->valuators_len;
+ xcb_pre_tmp_7 = 0;
+ xcb_pre_tmp_8 = xcb_input_raw_touch_begin_valuator_mask(_aux);
+ for (xcb_pre_tmp_6 = 0; xcb_pre_tmp_6 < xcb_pre_tmp_5; xcb_pre_tmp_6++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_8;
+ xcb_pre_tmp_7 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_8++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_7 */
+ xcb_block_len += xcb_pre_tmp_7 * sizeof(xcb_input_fp3232_t);
+ xcb_tmp += xcb_block_len;
+ xcb_align_to = ALIGNOF(xcb_input_fp3232_t);
+ /* insert padding */
+ xcb_pad = -xcb_block_len & (xcb_align_to - 1);
+ xcb_buffer_len += xcb_block_len + xcb_pad;
+ if (0 != xcb_pad) {
+ xcb_tmp += xcb_pad;
+ xcb_pad = 0;
+ }
+ xcb_block_len = 0;
+
+ return xcb_buffer_len;
+}
+
+uint32_t *
+xcb_input_raw_touch_begin_valuator_mask (const xcb_input_raw_touch_begin_event_t *R)
+{
+ return (uint32_t *) (R + 1);
+}
+
+int
+xcb_input_raw_touch_begin_valuator_mask_length (const xcb_input_raw_touch_begin_event_t *R)
+{
+ return R->valuators_len;
+}
+
+xcb_generic_iterator_t
+xcb_input_raw_touch_begin_valuator_mask_end (const xcb_input_raw_touch_begin_event_t *R)
+{
+ xcb_generic_iterator_t i;
+ i.data = ((uint32_t *) (R + 1)) + (R->valuators_len);
+ i.rem = 0;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_raw_touch_begin_axisvalues (const xcb_input_raw_touch_begin_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_raw_touch_begin_valuator_mask_end(R);
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_raw_touch_begin_axisvalues_length (const xcb_input_raw_touch_begin_event_t *R)
+{
+ int xcb_pre_tmp_9; /* sumof length */
+ int xcb_pre_tmp_10; /* sumof loop counter */
+ int64_t xcb_pre_tmp_11; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_12; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_9 = R->valuators_len;
+ xcb_pre_tmp_11 = 0;
+ xcb_pre_tmp_12 = xcb_input_raw_touch_begin_valuator_mask(R);
+ for (xcb_pre_tmp_10 = 0; xcb_pre_tmp_10 < xcb_pre_tmp_9; xcb_pre_tmp_10++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_12;
+ xcb_pre_tmp_11 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_12++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_11 */
+ return xcb_pre_tmp_11;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_touch_begin_axisvalues_iterator (const xcb_input_raw_touch_begin_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_raw_touch_begin_valuator_mask_end(R);
+ int xcb_pre_tmp_13; /* sumof length */
+ int xcb_pre_tmp_14; /* sumof loop counter */
+ int64_t xcb_pre_tmp_15; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_16; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_13 = R->valuators_len;
+ xcb_pre_tmp_15 = 0;
+ xcb_pre_tmp_16 = xcb_input_raw_touch_begin_valuator_mask(R);
+ for (xcb_pre_tmp_14 = 0; xcb_pre_tmp_14 < xcb_pre_tmp_13; xcb_pre_tmp_14++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_16;
+ xcb_pre_tmp_15 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_16++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_15 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_15;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+xcb_input_fp3232_t *
+xcb_input_raw_touch_begin_axisvalues_raw (const xcb_input_raw_touch_begin_event_t *R)
+{
+ xcb_generic_iterator_t prev = xcb_input_fp3232_end(xcb_input_raw_touch_begin_axisvalues_iterator(R));
+ return (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index) + 0);
+}
+
+int
+xcb_input_raw_touch_begin_axisvalues_raw_length (const xcb_input_raw_touch_begin_event_t *R)
+{
+ int xcb_pre_tmp_17; /* sumof length */
+ int xcb_pre_tmp_18; /* sumof loop counter */
+ int64_t xcb_pre_tmp_19; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_20; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_17 = R->valuators_len;
+ xcb_pre_tmp_19 = 0;
+ xcb_pre_tmp_20 = xcb_input_raw_touch_begin_valuator_mask(R);
+ for (xcb_pre_tmp_18 = 0; xcb_pre_tmp_18 < xcb_pre_tmp_17; xcb_pre_tmp_18++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_20;
+ xcb_pre_tmp_19 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_20++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_19 */
+ return xcb_pre_tmp_19;
+}
+
+xcb_input_fp3232_iterator_t
+xcb_input_raw_touch_begin_axisvalues_raw_iterator (const xcb_input_raw_touch_begin_event_t *R)
+{
+ xcb_input_fp3232_iterator_t i;
+ xcb_generic_iterator_t prev = xcb_input_fp3232_end(xcb_input_raw_touch_begin_axisvalues_iterator(R));
+ int xcb_pre_tmp_21; /* sumof length */
+ int xcb_pre_tmp_22; /* sumof loop counter */
+ int64_t xcb_pre_tmp_23; /* sumof sum */
+ const uint32_t* xcb_pre_tmp_24; /* sumof list ptr */
+ /* sumof start */
+ xcb_pre_tmp_21 = R->valuators_len;
+ xcb_pre_tmp_23 = 0;
+ xcb_pre_tmp_24 = xcb_input_raw_touch_begin_valuator_mask(R);
+ for (xcb_pre_tmp_22 = 0; xcb_pre_tmp_22 < xcb_pre_tmp_21; xcb_pre_tmp_22++) {
+ const uint32_t *xcb_listelement = xcb_pre_tmp_24;
+ xcb_pre_tmp_23 += xcb_popcount((*xcb_listelement));
+ xcb_pre_tmp_24++;
+ }
+ /* sumof end. Result is in xcb_pre_tmp_23 */
+ i.data = (xcb_input_fp3232_t *) ((char *) prev.data + XCB_TYPE_PAD(xcb_input_fp3232_t, prev.index));
+ i.rem = xcb_pre_tmp_23;
+ i.index = (char *) i.data - (char *) R;
+ return i;
+}
+
+int
+xcb_input_raw_touch_update_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_raw_touch_begin_sizeof(_buffer);
+}
+
+int
+xcb_input_raw_touch_end_sizeof (const void *_buffer /**< */)
+{
+ return xcb_input_raw_touch_begin_sizeof(_buffer);
+}
diff --git a/src/3rdparty/xcb/libxcb/xkb.c b/src/3rdparty/xcb/libxcb/xkb.c
index ff025f6b60..d55bd76f10 100644
--- a/src/3rdparty/xcb/libxcb/xkb.c
+++ b/src/3rdparty/xcb/libxcb/xkb.c
@@ -18,15 +18,6 @@
xcb_extension_t xcb_xkb_id = { "XKEYBOARD", 0 };
-int qt_xcb_sumof(uint8_t *list, int len)
-{
- int i, s = 0;
- for(i=0; i<len; i++) {
- s += *list;
- list++;
- }
- return s;
-}
/*****************************************************************************
**
@@ -9034,7 +9025,7 @@ int
xcb_xkb_get_names_value_list_kt_level_names_length (const xcb_xkb_get_names_reply_t *R /**< */,
const xcb_xkb_get_names_value_list_t *S /**< */)
{
- return qt_xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
+ return xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
}
@@ -9052,7 +9043,7 @@ xcb_xkb_get_names_value_list_kt_level_names_end (const xcb_xkb_get_names_reply_t
const xcb_xkb_get_names_value_list_t *S /**< */)
{
xcb_generic_iterator_t i;
- i.data = /* valueList */ S->ktLevelNames + qt_xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
+ i.data = /* valueList */ S->ktLevelNames + xcb_sumof(/* valueList */ S->nLevelsPerType, R->nTypes);
i.rem = 0;
i.index = (char *) i.data - (char *) S;
return i;
@@ -9517,8 +9508,8 @@ xcb_xkb_get_names_value_list_serialize (void **_
xcb_block_len = 0;
/* ktLevelNames */
xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
- xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
- xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
+ xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
+ xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
xcb_parts_idx++;
xcb_align_to = ALIGNOF(xcb_atom_t);
}
@@ -9771,7 +9762,7 @@ xcb_xkb_get_names_value_list_unpack (const void *_buffer /
xcb_block_len = 0;
/* ktLevelNames */
_aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
- xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
+ xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nTypes) * sizeof(xcb_atom_t);
xcb_tmp += xcb_block_len;
xcb_align_to = ALIGNOF(xcb_atom_t);
}
@@ -10148,7 +10139,7 @@ int
xcb_xkb_set_names_values_kt_level_names_length (const xcb_xkb_set_names_request_t *R /**< */,
const xcb_xkb_set_names_values_t *S /**< */)
{
- return qt_xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
+ return xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
}
@@ -10166,7 +10157,7 @@ xcb_xkb_set_names_values_kt_level_names_end (const xcb_xkb_set_names_request_t *
const xcb_xkb_set_names_values_t *S /**< */)
{
xcb_generic_iterator_t i;
- i.data = /* values */ S->ktLevelNames + qt_xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
+ i.data = /* values */ S->ktLevelNames + xcb_sumof(/* values */ S->nLevelsPerType, R->nKTLevels);
i.rem = 0;
i.index = (char *) i.data - (char *) S;
return i;
@@ -10616,8 +10607,8 @@ xcb_xkb_set_names_values_serialize (void **_buffer
xcb_block_len = 0;
/* ktLevelNames */
xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
- xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
- xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
+ xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
+ xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
xcb_parts_idx++;
xcb_align_to = ALIGNOF(xcb_atom_t);
}
@@ -10858,7 +10849,7 @@ xcb_xkb_set_names_values_unpack (const void *_buffer /**< */,
xcb_block_len = 0;
/* ktLevelNames */
_aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
- xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
+ xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
xcb_tmp += xcb_block_len;
xcb_align_to = ALIGNOF(xcb_atom_t);
}
@@ -12881,7 +12872,7 @@ int
xcb_xkb_get_kbd_by_name_replies_key_names_value_list_kt_level_names_length (const xcb_xkb_get_kbd_by_name_reply_t *R /**< */,
const xcb_xkb_get_kbd_by_name_replies_t *S /**< */)
{
- return qt_xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
+ return xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
}
@@ -12899,7 +12890,7 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_kt_level_names_end (const x
const xcb_xkb_get_kbd_by_name_replies_t *S /**< */)
{
xcb_generic_iterator_t i;
- i.data = /* replies */ S->key_names.valueList.ktLevelNames + qt_xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
+ i.data = /* replies */ S->key_names.valueList.ktLevelNames + xcb_sumof(/* replies */ S->key_names.valueList.nLevelsPerType, /* replies */ S->key_names.nKTLevels);
i.rem = 0;
i.index = (char *) i.data - (char *) S;
return i;
@@ -13349,8 +13340,8 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_serialize (void
xcb_block_len = 0;
/* ktLevelNames */
xcb_parts[xcb_parts_idx].iov_base = (char *) _aux->ktLevelNames;
- xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
- xcb_parts[xcb_parts_idx].iov_len = qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
+ xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
+ xcb_parts[xcb_parts_idx].iov_len = xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
xcb_parts_idx++;
xcb_align_to = ALIGNOF(xcb_atom_t);
}
@@ -13591,7 +13582,7 @@ xcb_xkb_get_kbd_by_name_replies_key_names_value_list_unpack (const void
xcb_block_len = 0;
/* ktLevelNames */
_aux->ktLevelNames = (xcb_atom_t *)xcb_tmp;
- xcb_block_len += qt_xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
+ xcb_block_len += xcb_sumof(_aux->nLevelsPerType, nKTLevels) * sizeof(xcb_atom_t);
xcb_tmp += xcb_block_len;
xcb_align_to = ALIGNOF(xcb_atom_t);
}
diff --git a/src/3rdparty/xkbcommon.pri b/src/3rdparty/xkbcommon.pri
index 1d953d8372..8259a8b8bd 100644
--- a/src/3rdparty/xkbcommon.pri
+++ b/src/3rdparty/xkbcommon.pri
@@ -1,4 +1,6 @@
-QMAKE_CFLAGS += -std=gnu99 -w
+# Requires GNU C extensions
+CONFIG -= strict_c
+
INCLUDEPATH += $$PWD/xkbcommon \
$$PWD/xkbcommon/xkbcommon \
$$PWD/xkbcommon/src \
diff --git a/src/android/jar/jar.pro b/src/android/jar/jar.pro
index 683866a345..bda15a0a00 100644
--- a/src/android/jar/jar.pro
+++ b/src/android/jar/jar.pro
@@ -19,7 +19,7 @@ JAVASOURCES += \
$$PATHPREFIX/QtNativeLibrariesDir.java \
$$PATHPREFIX/QtSurface.java \
$$PATHPREFIX/ExtractStyle.java \
- $$PATHPREFIX/EditMenu.java \
+ $$PATHPREFIX/EditContextView.java \
$$PATHPREFIX/EditPopupMenu.java \
$$PATHPREFIX/CursorHandle.java \
$$PATHPREFIX/QtThread.java
diff --git a/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java b/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java
index 4f2c06644d..788a5c2b3d 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java
@@ -142,7 +142,6 @@ public class CursorHandle implements ViewTreeObserver.OnPreDrawListener
m_cursorView = new CursorView(context, this);
m_cursorView.setImageDrawable(drawable);
- // m_layout.addView(m_cursorView);
m_popup = new PopupWindow(context, null, android.R.attr.textSelectHandleWindowStyle);
m_popup.setSplitTouchEnabled(true);
@@ -185,6 +184,14 @@ public class CursorHandle implements ViewTreeObserver.OnPreDrawListener
m_posY = y;
}
+ public int bottom()
+ {
+ initOverlay();
+ final int[] location = new int[2];
+ m_cursorView.getLocationOnScreen(location);
+ return location[1] + m_cursorView.getHeight();
+ }
+
public void hide() {
if (m_popup != null) {
m_popup.dismiss();
diff --git a/src/android/jar/src/org/qtproject/qt5/android/EditContextView.java b/src/android/jar/src/org/qtproject/qt5/android/EditContextView.java
new file mode 100644
index 0000000000..6d9987ca2a
--- /dev/null
+++ b/src/android/jar/src/org/qtproject/qt5/android/EditContextView.java
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 BogDan Vatra <bogdan@kde.org>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Android port of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android;
+
+
+import android.content.Context;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.R;
+
+import java.util.HashMap;
+
+public class EditContextView extends LinearLayout implements View.OnClickListener
+{
+ public static final int CUT_BUTTON = 1 << 0;
+ public static final int COPY_BUTTON = 1 << 1;
+ public static final int PASTE_BUTTON = 1 << 2;
+ public static final int SALL_BUTTON = 1 << 3;
+
+ HashMap<Integer, ContextButton> m_buttons = new HashMap<Integer, ContextButton>(4);
+ OnClickListener m_onClickListener;
+
+ public interface OnClickListener
+ {
+ void contextButtonClicked(int buttonId);
+ }
+
+ private class ContextButton extends TextView
+ {
+ public int m_buttonId;
+ public ContextButton(Context context, int stringId) {
+ super(context);
+ m_buttonId = stringId;
+ setText(stringId);
+ setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ setGravity(Gravity.CENTER);
+ setTextColor(getResources().getColor(R.color.widget_edittext_dark));
+ EditContextView.this.setBackground(getResources().getDrawable(R.drawable.editbox_background_normal));
+ float scale = getResources().getDisplayMetrics().density;
+ int hPadding = (int)(16 * scale + 0.5f);
+ int vPadding = (int)(8 * scale + 0.5f);
+ setPadding(hPadding, vPadding, hPadding, vPadding);
+ setOnClickListener(EditContextView.this);
+ }
+ }
+
+ @Override
+ public void onClick(View v)
+ {
+ ContextButton button = (ContextButton)v;
+ m_onClickListener.contextButtonClicked(button.m_buttonId);
+ }
+
+ void addButton(int id)
+ {
+ ContextButton button = new ContextButton(getContext(), id);
+ m_buttons.put(id, button);
+ addView(button);
+ }
+
+ public void updateButtons(int buttonsLayout)
+ {
+ m_buttons.get(R.string.cut).setVisibility((buttonsLayout & CUT_BUTTON) != 0 ? View.VISIBLE : View.GONE);
+ m_buttons.get(R.string.copy).setVisibility((buttonsLayout & COPY_BUTTON) != 0 ? View.VISIBLE : View.GONE);
+ m_buttons.get(R.string.paste).setVisibility((buttonsLayout & PASTE_BUTTON) != 0 ? View.VISIBLE : View.GONE);
+ m_buttons.get(R.string.selectAll).setVisibility((buttonsLayout & SALL_BUTTON) != 0 ? View.VISIBLE : View.GONE);
+ }
+
+ public EditContextView(Context context, OnClickListener onClickListener) {
+ super(context);
+ m_onClickListener = onClickListener;
+ setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ addButton(R.string.cut);
+ addButton(R.string.copy);
+ addButton(R.string.paste);
+ addButton(R.string.selectAll);
+ }
+}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/EditMenu.java b/src/android/jar/src/org/qtproject/qt5/android/EditMenu.java
deleted file mode 100644
index afe7797914..0000000000
--- a/src/android/jar/src/org/qtproject/qt5/android/EditMenu.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Android port of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-package org.qtproject.qt5.android;
-
-import android.view.ActionMode;
-import android.view.ActionMode.Callback;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.TypedArray;
-
-/**
- * The edit menu actions (when there is selection)
- */
-class EditMenu implements ActionMode.Callback {
-
- private final Activity m_activity;
- private ActionMode m_actionMode;
-
- public EditMenu(Activity activity) {
- m_activity = activity;
- }
-
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- mode.setTitle(null);
- mode.setSubtitle(null);
- mode.setTitleOptionalHint(true);
-
- Context context = m_activity;
- int[] attrs = {
- android.R.attr.actionModeSelectAllDrawable, android.R.attr.actionModeCutDrawable,
- android.R.attr.actionModeCopyDrawable, android.R.attr.actionModePasteDrawable
- };
- TypedArray a = context.getTheme().obtainStyledAttributes(attrs);
-
- menu.add(Menu.NONE, android.R.id.selectAll, Menu.NONE, android.R.string.selectAll)
- .setIcon(a.getResourceId(0, 0))
- .setAlphabeticShortcut('a')
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-
- menu.add(Menu.NONE, android.R.id.cut, Menu.NONE, android.R.string.cut)
- .setIcon(a.getResourceId(1, 0))
- .setAlphabeticShortcut('x')
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-
- menu.add(Menu.NONE, android.R.id.copy, Menu.NONE, android.R.string.copy)
- .setIcon(a.getResourceId(2, 0))
- .setAlphabeticShortcut('c')
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-
- menu.add(Menu.NONE, android.R.id.paste, Menu.NONE, android.R.string.paste)
- .setIcon(a.getResourceId(3, 0))
- .setAlphabeticShortcut('v')
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
-
- return true;
- }
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- return true;
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- m_actionMode = null;
- }
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-
- switch (item.getItemId()) {
- case android.R.id.cut:
- return QtNativeInputConnection.cut();
- case android.R.id.copy:
- return QtNativeInputConnection.copy();
- case android.R.id.paste:
- return QtNativeInputConnection.paste();
- case android.R.id.selectAll:
- return QtNativeInputConnection.selectAll();
- }
- return false;
- }
-
- public void hide()
- {
- if (m_actionMode != null) {
- m_actionMode.finish();
- }
- }
-
- public void show()
- {
- if (m_actionMode == null) {
- m_actionMode = m_activity.startActionMode(this);
- }
- }
-
- public boolean isShown()
- {
- return m_actionMode != null;
- }
-}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java b/src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java
index 246be1aeb2..d065cd8549 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2018 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt.io/licensing/
**
@@ -55,59 +56,51 @@ import android.view.ViewTreeObserver;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup;
+import android.R;
// Helper class that manages a cursor or selection handle
-public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, OnClickListener
+public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, EditContextView.OnClickListener
{
private View m_layout = null;
- private View m_view = null;
+ private EditContextView m_view = null;
private PopupWindow m_popup = null;
- private Activity m_activity;
private int m_posX;
private int m_posY;
+ private int m_buttons;
- public EditPopupMenu(Activity activity, View layout) {
- m_activity = activity;
+ public EditPopupMenu(Activity activity, View layout)
+ {
+ m_view = new EditContextView(activity, this);
m_layout = layout;
}
- private boolean initOverlay(){
- if (m_popup == null){
- Context context = m_layout.getContext();
- int[] attrs = { android.R.attr.textEditPasteWindowLayout };
- TypedArray a = context.getTheme().obtainStyledAttributes(attrs);
- final int layout = a.getResourceId(0, 0);
- LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- m_view = inflater.inflate(layout, null);
-
- final int size = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
- m_view.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
- m_view.measure(size, size);
- m_view.setOnClickListener(this);
-
- m_popup = new PopupWindow(context, null, android.R.attr.textSelectHandleWindowStyle);
- m_popup.setSplitTouchEnabled(true);
- m_popup.setClippingEnabled(false);
- m_popup.setContentView(m_view);
- m_popup.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
- m_popup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
-
- m_layout.getViewTreeObserver().addOnPreDrawListener(this);
- }
- return true;
+ private void initOverlay()
+ {
+ if (m_popup != null)
+ return;
+
+ Context context = m_layout.getContext();
+ m_popup = new PopupWindow(context, null, android.R.attr.textSelectHandleWindowStyle);
+ m_popup.setSplitTouchEnabled(true);
+ m_popup.setClippingEnabled(false);
+ m_popup.setContentView(m_view);
+ m_popup.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
+ m_popup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ m_layout.getViewTreeObserver().addOnPreDrawListener(this);
}
public int getHeight()
{
- initOverlay();
return m_view.getHeight();
}
// Show the handle at a given position (or move it if it is already shown)
- public void setPosition(final int x, final int y){
+ public void setPosition(final int x, final int y, final int buttons)
+ {
initOverlay();
+ m_view.updateButtons(buttons);
final int[] location = new int[2];
m_layout.getLocationOnScreen(location);
@@ -115,9 +108,12 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, OnClic
int y2 = y + location[1];
x2 -= m_view.getWidth() / 2 ;
+
+ if (m_layout.getWidth() < x + m_view.getWidth() / 2)
+ x2 = m_layout.getWidth() - m_view.getWidth();
+
if (x2 < 0)
x2 = 0;
- y2 -= m_view.getHeight();
if (m_popup.isShowing())
m_popup.update(x2, y2, -1, -1);
@@ -126,12 +122,13 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, OnClic
m_posX = x;
m_posY = y;
-
+ m_buttons = buttons;
}
public void hide() {
if (m_popup != null) {
m_popup.dismiss();
+ m_popup = null;
}
}
@@ -141,15 +138,27 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, OnClic
// For example if the keyboard appears.
// Adjust the position of the handle accordingly
if (m_popup != null && m_popup.isShowing())
- setPosition(m_posX, m_posY);
+ setPosition(m_posX, m_posY, m_buttons);
return true;
}
@Override
- public void onClick(View v) {
- QtNativeInputConnection.paste();
+ public void contextButtonClicked(int buttonId) {
+ switch (buttonId) {
+ case R.string.cut:
+ QtNativeInputConnection.cut();
+ break;
+ case R.string.copy:
+ QtNativeInputConnection.copy();
+ break;
+ case R.string.paste:
+ QtNativeInputConnection.paste();
+ break;
+ case R.string.selectAll:
+ QtNativeInputConnection.selectAll();
+ break;
+ }
hide();
}
}
-
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index fa7508921d..8f218d34f0 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -140,7 +140,6 @@ public class QtActivityDelegate
private QtEditText m_editText = null;
private InputMethodManager m_imm = null;
private boolean m_quitApp = true;
- private Process m_debuggerProcess = null; // debugger process
private View m_dummyView = null;
private boolean m_keyboardIsVisible = false;
public boolean m_backKeyPressedSent = false;
@@ -151,7 +150,6 @@ public class QtActivityDelegate
private CursorHandle m_cursorHandle;
private CursorHandle m_leftSelectionHandle;
private CursorHandle m_rightSelectionHandle;
- private EditMenu m_editMenu;
private EditPopupMenu m_editPopupMenu;
public void setFullScreen(boolean enterFullScreen)
@@ -484,77 +482,87 @@ public class QtActivityDelegate
}
// Values coming from QAndroidInputContext::CursorHandleShowMode
- private static final int CursorHandleNotShown = 0;
- private static final int CursorHandleShowNormal = 1;
- private static final int CursorHandleShowSelection = 2;
- private static final int CursorHandleShowPopup = 3;
+ private static final int CursorHandleNotShown = 0;
+ private static final int CursorHandleShowNormal = 1;
+ private static final int CursorHandleShowSelection = 2;
+ private static final int CursorHandleShowEdit = 0x100;
/* called from the C++ code when the position of the cursor or selection handles needs to
be adjusted.
mode is one of QAndroidInputContext::CursorHandleShowMode
*/
- public void updateHandles(int mode, int x1, int y1, int x2, int y2, boolean rtl)
+ public void updateHandles(int mode, int editX, int editY, int editButtons, int x1, int y1, int x2, int y2, boolean rtl)
{
- if (mode == CursorHandleNotShown) {
- if (m_cursorHandle != null)
- m_cursorHandle.hide();
- if (m_rightSelectionHandle != null) {
- m_rightSelectionHandle.hide();
- m_leftSelectionHandle.hide();
- m_rightSelectionHandle = null;
- m_leftSelectionHandle = null;
- }
- if (m_editMenu != null)
- m_editMenu.hide();
- if (m_editPopupMenu != null)
+ switch (mode & 0xff)
+ {
+ case CursorHandleNotShown:
+ if (m_cursorHandle != null) {
+ m_cursorHandle.hide();
+ m_cursorHandle = null;
+ }
+ if (m_rightSelectionHandle != null) {
+ m_rightSelectionHandle.hide();
+ m_leftSelectionHandle.hide();
+ m_rightSelectionHandle = null;
+ m_leftSelectionHandle = null;
+ }
m_editPopupMenu.hide();
- } else if (mode == CursorHandleShowNormal || mode == CursorHandleShowPopup) {
- if (m_cursorHandle == null) {
- m_cursorHandle = new CursorHandle(m_activity, m_layout, QtNative.IdCursorHandle,
- android.R.attr.textSelectHandle, false);
- }
- m_cursorHandle.setPosition(x1, y1);
- if (m_rightSelectionHandle != null) {
- m_rightSelectionHandle.hide();
- m_leftSelectionHandle.hide();
- m_rightSelectionHandle = null;
- m_leftSelectionHandle = null;
- }
- } else if (mode == CursorHandleShowSelection) {
- if (m_rightSelectionHandle == null) {
- m_leftSelectionHandle = new CursorHandle(m_activity, m_layout, QtNative.IdLeftHandle,
- !rtl ? android.R.attr.textSelectHandleLeft :
- android.R.attr.textSelectHandleRight,
- rtl);
- m_rightSelectionHandle = new CursorHandle(m_activity, m_layout, QtNative.IdRightHandle,
- !rtl ? android.R.attr.textSelectHandleRight :
- android.R.attr.textSelectHandleLeft,
- rtl);
- }
- m_leftSelectionHandle.setPosition(x1,y1);
- m_rightSelectionHandle.setPosition(x2,y2);
- if (m_cursorHandle != null)
- m_cursorHandle.hide();
-
- if (m_editMenu == null)
- m_editMenu = new EditMenu(m_activity);
- m_editMenu.show();
+ break;
+
+ case CursorHandleShowNormal:
+ if (m_cursorHandle == null) {
+ m_cursorHandle = new CursorHandle(m_activity, m_layout, QtNative.IdCursorHandle,
+ android.R.attr.textSelectHandle, false);
+ }
+ m_cursorHandle.setPosition(x1, y1);
+ if (m_rightSelectionHandle != null) {
+ m_rightSelectionHandle.hide();
+ m_leftSelectionHandle.hide();
+ m_rightSelectionHandle = null;
+ m_leftSelectionHandle = null;
+ }
+ break;
+
+ case CursorHandleShowSelection:
+ if (m_rightSelectionHandle == null) {
+ m_leftSelectionHandle = new CursorHandle(m_activity, m_layout, QtNative.IdLeftHandle,
+ !rtl ? android.R.attr.textSelectHandleLeft :
+ android.R.attr.textSelectHandleRight,
+ rtl);
+ m_rightSelectionHandle = new CursorHandle(m_activity, m_layout, QtNative.IdRightHandle,
+ !rtl ? android.R.attr.textSelectHandleRight :
+ android.R.attr.textSelectHandleLeft,
+ rtl);
+ }
+ m_leftSelectionHandle.setPosition(x1,y1);
+ m_rightSelectionHandle.setPosition(x2,y2);
+ if (m_cursorHandle != null) {
+ m_cursorHandle.hide();
+ m_cursorHandle = null;
+ }
+ mode |= CursorHandleShowEdit;
+ break;
}
- // show the edit popup menu
- if (mode == CursorHandleShowPopup && (m_editMenu == null || !m_editMenu.isShown())
- && QtNative.hasClipboardText()) {
- if (m_editPopupMenu == null)
- m_editPopupMenu = new EditPopupMenu(m_activity, m_layout);
- if (y2 < m_editPopupMenu.getHeight()) {
- // If the popup cannot be shown over the text, it must be shown under the anchors
- y2 = y1 + 2 * m_editPopupMenu.getHeight();
+ if (QtNative.hasClipboardText())
+ editButtons |= EditContextView.PASTE_BUTTON;
+ else
+ editButtons &= ~EditContextView.PASTE_BUTTON;
+
+ if ((mode & CursorHandleShowEdit) == CursorHandleShowEdit && editButtons != 0) {
+ editY -= m_editPopupMenu.getHeight();
+ if (editY < 0) {
+ if (m_cursorHandle != null)
+ editY = m_cursorHandle.bottom();
+ else if (m_leftSelectionHandle != null && m_rightSelectionHandle != null)
+ editY = Math.max(m_leftSelectionHandle.bottom(), m_rightSelectionHandle.bottom());
+ else
+ return;
}
- m_editPopupMenu.setPosition(x2, y2);
- } else if (m_editPopupMenu != null) {
+ m_editPopupMenu.setPosition(editX, editY, editButtons);
+ } else {
m_editPopupMenu.hide();
}
-
}
public boolean loadApplication(Activity activity, ClassLoader classLoader, Bundle loaderParams)
@@ -658,70 +666,6 @@ public class QtActivityDelegate
return true;
}
- public static void debugLog(String msg)
- {
- Log.i(QtNative.QtTAG, "DEBUGGER: " + msg);
- }
-
- private class DebugWaitRunnable implements Runnable {
-
- public DebugWaitRunnable(String pingPongSocket) throws IOException {
- socket = new LocalServerSocket(pingPongSocket);
- }
-
- public boolean wasFailure;
- private LocalServerSocket socket;
-
- public void run() {
- final int napTime = 200; // milliseconds between file accesses
- final int timeOut = 30000; // ms until we give up on ping and pong
- final int maxAttempts = timeOut / napTime;
-
- DataOutputStream outToClient = null;
- try {
- LocalSocket connectionFromClient = socket.accept();
- debugLog("Debug socket accepted");
- BufferedReader inFromClient =
- new BufferedReader(new InputStreamReader(connectionFromClient.getInputStream()));
- outToClient = new DataOutputStream(connectionFromClient.getOutputStream());
- outToClient.writeBytes("" + android.os.Process.myPid());
-
- for (int i = 0; i < maxAttempts; i++) {
- String clientData = inFromClient.readLine();
- debugLog("Incoming socket " + clientData);
- if (!clientData.isEmpty())
- break;
-
- if (connectionFromClient.isClosed()) {
- wasFailure = true;
- break;
- }
- Thread.sleep(napTime);
- }
- } catch (IOException ioEx) {
- ioEx.printStackTrace();
- wasFailure = true;
- Log.e(QtNative.QtTAG,"Can't start debugger" + ioEx.getMessage());
- } catch (InterruptedException interruptEx) {
- wasFailure = true;
- Log.e(QtNative.QtTAG,"Can't start debugger" + interruptEx.getMessage());
- } finally {
- try {
- if (outToClient != null)
- outToClient.close();
- } catch (IOException ignored) { }
- }
- }
-
- public void shutdown() throws IOException
- {
- wasFailure = true;
- try {
- socket.close();
- } catch (IOException ignored) { }
- }
- };
-
public boolean startApplication()
{
// start application
@@ -730,170 +674,6 @@ public class QtActivityDelegate
Bundle extras = m_activity.getIntent().getExtras();
if (extras != null) {
try {
- final String dc = "--Added-by-androiddeployqt--/debugger.command";
- String debuggerCommand =
- new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine();
- if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
- &&*/ extras.containsKey("debug_ping")
- && extras.getString("debug_ping").equals("true")) {
- try {
- String packagePath =
- m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(),
- PackageManager.GET_CONFIGURATIONS).dataDir + "/";
-
- debugLog("extra parameters: " + extras);
- String packageName = m_activity.getPackageName();
- String pingFile = extras.getString("ping_file");
- String pongFile = extras.getString("pong_file");
- String gdbserverSocket = extras.getString("gdbserver_socket");
- String gdbserverCommand = packagePath + debuggerCommand + gdbserverSocket;
- String pingSocket = extras.getString("ping_socket");
- boolean usePing = pingFile != null;
- boolean usePong = pongFile != null;
- boolean useSocket = gdbserverSocket != null;
- boolean usePingSocket = pingSocket != null;
- int napTime = 200; // milliseconds between file accesses
- int timeOut = 30000; // ms until we give up on ping and pong
- int maxAttempts = timeOut / napTime;
-
- if (gdbserverSocket != null) {
- debugLog("removing gdb socket " + gdbserverSocket);
- new File(gdbserverSocket).delete();
- }
-
- if (usePing) {
- debugLog("removing ping file " + pingFile);
- File ping = new File(pingFile);
- if (ping.exists()) {
- if (!ping.delete())
- debugLog("ping file cannot be deleted");
- }
- }
-
- if (usePong) {
- debugLog("removing pong file " + pongFile);
- File pong = new File(pongFile);
- if (pong.exists()) {
- if (!pong.delete())
- debugLog("pong file cannot be deleted");
- }
- }
-
- debugLog("starting " + gdbserverCommand);
- m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
- debugLog("gdbserver started");
-
- if (useSocket) {
- int i;
- for (i = 0; i < maxAttempts; ++i) {
- debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
- File file = new File(gdbserverSocket);
- if (file.exists()) {
- file.setReadable(true, false);
- file.setWritable(true, false);
- file.setExecutable(true, false);
- break;
- }
- Thread.sleep(napTime);
- }
-
- if (i == maxAttempts) {
- debugLog("time out when waiting for debug socket");
- return false;
- }
-
- debugLog("socket ok");
- } else {
- debugLog("socket not used");
- }
-
- if (usePingSocket) {
- DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket);
- Thread waitThread = new Thread(runnable);
- waitThread.start();
-
- int i;
- for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) {
- debugLog("Waiting for debug socket connect");
- debugLog("go to sleep");
- Thread.sleep(napTime);
- }
-
- if (i == maxAttempts) {
- debugLog("time out when waiting for ping socket");
- runnable.shutdown();
- return false;
- }
-
- if (runnable.wasFailure) {
- debugLog("Could not connect to debug client");
- return false;
- } else {
- debugLog("Got pid acknowledgment");
- }
- }
-
- if (usePing) {
- // Tell we are ready.
- debugLog("writing ping at " + pingFile);
- FileWriter writer = new FileWriter(pingFile);
- writer.write("" + android.os.Process.myPid());
- writer.close();
- File file = new File(pingFile);
- file.setReadable(true, false);
- file.setWritable(true, false);
- file.setExecutable(true, false);
- debugLog("wrote ping");
- } else {
- debugLog("ping not requested");
- }
-
- // Wait until other side is ready.
- if (usePong) {
- int i;
- for (i = 0; i < maxAttempts; ++i) {
- debugLog("waiting for pong at " + pongFile + ", attempt " + i);
- File file = new File(pongFile);
- if (file.exists()) {
- file.delete();
- break;
- }
- debugLog("go to sleep");
- Thread.sleep(napTime);
- }
- debugLog("Removing pingFile " + pingFile);
- new File(pingFile).delete();
-
- if (i == maxAttempts) {
- debugLog("time out when waiting for pong file");
- return false;
- }
-
- debugLog("got pong " + pongFile);
- } else {
- debugLog("pong not requested");
- }
-
- } catch (IOException ioe) {
- ioe.printStackTrace();
- } catch (SecurityException se) {
- se.printStackTrace();
- }
- }
-
- if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
- &&*/ extras.containsKey("qml_debug")
- && extras.getString("qml_debug").equals("true")) {
- String qmljsdebugger;
- if (extras.containsKey("qmljsdebugger")) {
- qmljsdebugger = extras.getString("qmljsdebugger");
- qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security
- } else {
- qmljsdebugger = "port:3768";
- }
- m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
- }
-
if (extras.containsKey("extraenvvars")) {
try {
m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8");
@@ -1008,6 +788,7 @@ public class QtActivityDelegate
return true;
}
});
+ m_editPopupMenu = new EditPopupMenu(m_activity, m_layout);
}
public void hideSplashScreen()
@@ -1081,8 +862,6 @@ public class QtActivityDelegate
if (m_quitApp) {
QtNative.terminateQt();
QtNative.setActivity(null, null);
- if (m_debuggerProcess != null)
- m_debuggerProcess.destroy();
QtNative.m_qtThread.exit();
System.exit(0);
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 3db3453263..61f6afe85d 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -469,10 +469,11 @@ public class QtNative
case MotionEvent.TOOL_TYPE_ERASER:
pointerType = 3; // QTabletEvent::Eraser
break;
- // TODO TOOL_TYPE_MOUSE
}
- if (m_tabletEventSupported && pointerType != 0) {
+ if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
+ sendMouseEvent(event, id);
+ } else if (m_tabletEventSupported && pointerType != 0) {
tabletEvent(id, event.getDeviceId(), event.getEventTime(), event.getAction(), pointerType,
event.getButtonState(), event.getX(), event.getY(), event.getPressure());
} else {
@@ -507,7 +508,22 @@ public class QtNative
static public void sendTrackballEvent(MotionEvent event, int id)
{
- switch (event.getAction()) {
+ sendMouseEvent(event,id);
+ }
+
+ static public boolean sendGenericMotionEvent(MotionEvent event, int id)
+ {
+ if (((event.getAction() & (MotionEvent.ACTION_SCROLL | MotionEvent.ACTION_HOVER_MOVE)) == 0)
+ || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != InputDevice.SOURCE_CLASS_POINTER) {
+ return false;
+ }
+
+ return sendMouseEvent(event, id);
+ }
+
+ static public boolean sendMouseEvent(MotionEvent event, int id)
+ {
+ switch (event.getActionMasked()) {
case MotionEvent.ACTION_UP:
mouseUp(id, (int) event.getX(), (int) event.getY());
break;
@@ -517,28 +533,27 @@ public class QtNative
m_oldx = (int) event.getX();
m_oldy = (int) event.getY();
break;
-
+ case MotionEvent.ACTION_HOVER_MOVE:
case MotionEvent.ACTION_MOVE:
- int dx = (int) (event.getX() - m_oldx);
- int dy = (int) (event.getY() - m_oldy);
- if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
+ if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
+ mouseMove(id, (int) event.getX(), (int) event.getY());
+ } else {
+ int dx = (int) (event.getX() - m_oldx);
+ int dy = (int) (event.getY() - m_oldy);
+ if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
mouseMove(id, (int) event.getX(), (int) event.getY());
m_oldx = (int) event.getX();
m_oldy = (int) event.getY();
+ }
}
break;
+ case MotionEvent.ACTION_SCROLL:
+ mouseWheel(id, (int) event.getX(), (int) event.getY(),
+ event.getAxisValue(MotionEvent.AXIS_HSCROLL), event.getAxisValue(MotionEvent.AXIS_VSCROLL));
+ break;
+ default:
+ return false;
}
- }
-
- static public boolean sendGenericMotionEvent(MotionEvent event, int id)
- {
- if (event.getActionMasked() != MotionEvent.ACTION_SCROLL
- || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != InputDevice.SOURCE_CLASS_POINTER) {
- return false;
- }
-
- mouseWheel(id, (int) event.getX(), (int) event.getY(),
- event.getAxisValue(MotionEvent.AXIS_HSCROLL), event.getAxisValue(MotionEvent.AXIS_VSCROLL));
return true;
}
@@ -585,6 +600,9 @@ public class QtNative
}
private static void updateHandles(final int mode,
+ final int editX,
+ final int editY,
+ final int editButtons,
final int x1,
final int y1,
final int x2,
@@ -594,7 +612,7 @@ public class QtNative
runAction(new Runnable() {
@Override
public void run() {
- m_activityDelegate.updateHandles(mode, x1, y1, x2, y2, rtl);
+ m_activityDelegate.updateHandles(mode, editX, editY, editButtons, x1, y1, x2, y2, rtl);
}
});
}
diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml
index 62e9d0f11c..c9eff264c4 100644
--- a/src/android/templates/AndroidManifest.xml
+++ b/src/android/templates/AndroidManifest.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --">
- <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation"
+ <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:label="-- %%INSERT_APP_NAME%% --"
android:screenOrientation="unspecified"
diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle
index 3a3e0cd165..8affd3c0b4 100644
--- a/src/android/templates/build.gradle
+++ b/src/android/templates/build.gradle
@@ -1,17 +1,17 @@
buildscript {
repositories {
+ google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.3'
+ classpath 'com.android.tools.build:gradle:3.0.1'
}
}
-allprojects {
- repositories {
- jcenter()
- }
+repositories {
+ google()
+ jcenter()
}
apply plugin: 'com.android.application'
diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri
index c1fad14951..8abdc24186 100644
--- a/src/angle/src/common/common.pri
+++ b/src/angle/src/common/common.pri
@@ -37,4 +37,9 @@ winrt|msvc {
}
}
+win32 {
+ VERSION = $$MODULE_VERSION
+ CONFIG += skip_target_version_ext
+}
+
static: DEFINES *= LIBGLESV2_EXPORT_H_ ANGLE_EXPORT=
diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake
index 819b48f973..581c99ed58 100644
--- a/src/corelib/Qt5CoreMacros.cmake
+++ b/src/corelib/Qt5CoreMacros.cmake
@@ -293,6 +293,49 @@ function(QT5_ADD_RESOURCES outfiles )
set(${outfiles} ${${outfiles}} PARENT_SCOPE)
endfunction()
+# qt5_add_big_resources(outfiles inputfile ... )
+
+function(QT5_ADD_BIG_RESOURCES outfiles )
+
+ set(options)
+ set(oneValueArgs)
+ set(multiValueArgs OPTIONS)
+
+ cmake_parse_arguments(_RCC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ set(rcc_files ${_RCC_UNPARSED_ARGUMENTS})
+ set(rcc_options ${_RCC_OPTIONS})
+
+ if("${rcc_options}" MATCHES "-binary")
+ message(WARNING "Use qt5_add_binary_resources for binary option")
+ endif()
+
+ foreach(it ${rcc_files})
+ get_filename_component(outfilename ${it} NAME_WE)
+ get_filename_component(infile ${it} ABSOLUTE)
+ set(tmpoutfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}tmp.cpp)
+ set(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.o)
+
+ _QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
+ set_source_files_properties(${infile} PROPERTIES SKIP_AUTORCC ON)
+ add_custom_command(OUTPUT ${tmpoutfile}
+ COMMAND ${Qt5Core_RCC_EXECUTABLE} ${rcc_options} --name ${outfilename} --pass 1 --output ${tmpoutfile} ${infile}
+ DEPENDS ${infile} ${_rc_depends} "${out_depends}" VERBATIM)
+ set_source_files_properties(${tmpoutfile} PROPERTIES SKIP_AUTOMOC ON)
+ set_source_files_properties(${tmpoutfile} PROPERTIES SKIP_AUTOUIC ON)
+ add_custom_target(big_resources_${outfilename} ALL DEPENDS ${tmpoutfile})
+ add_library(rcc_object_${outfilename} OBJECT ${tmpoutfile})
+ add_dependencies(rcc_object_${outfilename} big_resources_${outfilename})
+ add_custom_command(OUTPUT ${outfile}
+ COMMAND ${Qt5Core_RCC_EXECUTABLE}
+ ARGS ${rcc_options} --name ${outfilename} --pass 2 --temp $<TARGET_OBJECTS:rcc_object_${outfilename}> --output ${outfile} ${infile}
+ DEPENDS rcc_object_${outfilename}
+ VERBATIM)
+ list(APPEND ${outfiles} ${outfile})
+ endforeach()
+ set(${outfiles} ${${outfiles}} PARENT_SCOPE)
+endfunction()
+
set(_Qt5_COMPONENT_PATH "${CMAKE_CURRENT_LIST_DIR}/..")
if (NOT CMAKE_VERSION VERSION_LESS 2.8.9)
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index b3db200ed1..48983def79 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -215,9 +215,7 @@ typedef QList<QAbstractAnimation*>::ConstIterator AnimationListConstIt;
QUnifiedTimer drives animations indirectly, via QAbstractAnimationTimer.
*/
-#ifndef QT_NO_THREAD
Q_GLOBAL_STATIC(QThreadStorage<QUnifiedTimer *>, unifiedTimer)
-#endif
QUnifiedTimer::QUnifiedTimer() :
QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
@@ -234,18 +232,12 @@ QUnifiedTimer::QUnifiedTimer() :
QUnifiedTimer *QUnifiedTimer::instance(bool create)
{
QUnifiedTimer *inst;
-#ifndef QT_NO_THREAD
if (create && !unifiedTimer()->hasLocalData()) {
inst = new QUnifiedTimer;
unifiedTimer()->setLocalData(inst);
} else {
inst = unifiedTimer() ? unifiedTimer()->localData() : 0;
}
-#else
- Q_UNUSED(create);
- static QUnifiedTimer unifiedTimer;
- inst = &unifiedTimer;
-#endif
return inst;
}
@@ -554,7 +546,7 @@ bool QUnifiedTimer::canUninstallAnimationDriver(QAnimationDriver *d)
return d == driver && driver != &defaultDriver;
}
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
Q_GLOBAL_STATIC(QThreadStorage<QAnimationTimer *>, animationTimer)
#endif
@@ -569,7 +561,7 @@ QAnimationTimer::QAnimationTimer() :
QAnimationTimer *QAnimationTimer::instance(bool create)
{
QAnimationTimer *inst;
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
if (create && !animationTimer()->hasLocalData()) {
inst = new QAnimationTimer;
animationTimer()->setLocalData(inst);
diff --git a/src/corelib/codecs/qeucjpcodec_p.h b/src/corelib/codecs/qeucjpcodec_p.h
index 98ad286e9e..f2a9f923c8 100644
--- a/src/corelib/codecs/qeucjpcodec_p.h
+++ b/src/corelib/codecs/qeucjpcodec_p.h
@@ -94,12 +94,12 @@ public:
static QList<QByteArray> _aliases() { return QList<QByteArray>(); }
static int _mibEnum();
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
QEucJpCodec();
~QEucJpCodec();
diff --git a/src/corelib/codecs/qeuckrcodec_p.h b/src/corelib/codecs/qeuckrcodec_p.h
index 2cf950a350..bedf0cf822 100644
--- a/src/corelib/codecs/qeuckrcodec_p.h
+++ b/src/corelib/codecs/qeuckrcodec_p.h
@@ -90,12 +90,12 @@ public:
static QList<QByteArray> _aliases() { return QList<QByteArray>(); }
static int _mibEnum();
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
};
class QCP949Codec : public QTextCodec {
@@ -104,12 +104,12 @@ public:
static QList<QByteArray> _aliases();
static int _mibEnum();
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
};
#endif // QT_NO_BIG_CODECS
diff --git a/src/corelib/codecs/qgb18030codec_p.h b/src/corelib/codecs/qgb18030codec_p.h
index dd136aeddb..635150b18e 100644
--- a/src/corelib/codecs/qgb18030codec_p.h
+++ b/src/corelib/codecs/qgb18030codec_p.h
@@ -69,12 +69,12 @@ public:
static QList<QByteArray> _aliases() { return QList<QByteArray>(); }
static int _mibEnum() { return 114; }
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
};
class QGbkCodec : public QGb18030Codec {
@@ -85,12 +85,12 @@ public:
static QList<QByteArray> _aliases();
static int _mibEnum();
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
};
class QGb2312Codec : public QGb18030Codec {
@@ -101,11 +101,11 @@ public:
static QList<QByteArray> _aliases() { return QList<QByteArray>(); }
static int _mibEnum();
- QByteArray name() const { return _name(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
};
#endif // QT_NO_BIG_CODECS
diff --git a/src/corelib/codecs/qiconvcodec_p.h b/src/corelib/codecs/qiconvcodec_p.h
index 9b8500538b..7d192232d7 100644
--- a/src/corelib/codecs/qiconvcodec_p.h
+++ b/src/corelib/codecs/qiconvcodec_p.h
@@ -69,11 +69,11 @@ public:
QIconvCodec();
~QIconvCodec();
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
- QByteArray name() const;
- int mibEnum() const;
+ QByteArray name() const override;
+ int mibEnum() const override;
void init() const;
iconv_t createIconv_t(const char *to, const char *from) const;
diff --git a/src/corelib/codecs/qjiscodec_p.h b/src/corelib/codecs/qjiscodec_p.h
index 4db8728817..1ffe4a63f6 100644
--- a/src/corelib/codecs/qjiscodec_p.h
+++ b/src/corelib/codecs/qjiscodec_p.h
@@ -94,12 +94,12 @@ public:
static QList<QByteArray> _aliases();
static int _mibEnum();
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
QJisCodec();
~QJisCodec();
diff --git a/src/corelib/codecs/qjpunicode.cpp b/src/corelib/codecs/qjpunicode.cpp
index 0209843ecf..23112ce4d3 100644
--- a/src/corelib/codecs/qjpunicode.cpp
+++ b/src/corelib/codecs/qjpunicode.cpp
@@ -349,15 +349,15 @@ public:
// uint Jisx0201ToUnicode(uint h, uint l) const;
// uint Jisx0201LatinToUnicode(uint h, uint l) const;
// uint Jisx0201KanaToUnicode(uint h, uint l) const;
- uint jisx0208ToUnicode(uint h, uint l) const;
- uint jisx0212ToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const override;
+ uint jisx0212ToUnicode(uint h, uint l) const override;
// uint UnicodeToAscii(uint h, uint l) const;
// uint UnicodeToJisx0201(uint h, uint l) const;
// uint UnicodeToJisx0201Latin(uint h, uint l) const;
// uint UnicodeToJisx0201Kana(uint h, uint l) const;
- uint unicodeToJisx0208(uint h, uint l) const;
- uint unicodeToJisx0212(uint h, uint l) const;
+ uint unicodeToJisx0208(uint h, uint l) const override;
+ uint unicodeToJisx0212(uint h, uint l) const override;
};
uint QJpUnicodeConv_Unicode_ASCII::jisx0208ToUnicode(uint h, uint l) const
@@ -406,18 +406,18 @@ class QJpUnicodeConv_JISX0221_JISX0201 : public QJpUnicodeConv {
public:
QJpUnicodeConv_JISX0221_JISX0201(int r) : QJpUnicodeConv(r) {}
- uint asciiToUnicode(uint h, uint l) const;
+ uint asciiToUnicode(uint h, uint l) const override;
// uint Jisx0201ToUnicode(uint h, uint l) const;
// uint Jisx0201LatinToUnicode(uint h, uint l) const;
// uint Jisx0201KanaToUnicode(uint h, uint l) const;
- uint jisx0208ToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const override;
// uint Jisx0212ToUnicode(uint h, uint l) const;
- uint unicodeToAscii(uint h, uint l) const;
+ uint unicodeToAscii(uint h, uint l) const override;
// uint UnicodeToJisx0201(uint h, uint l) const;
// uint UnicodeToJisx0201Latin(uint h, uint l) const;
// uint UnicodeToJisx0201Kana(uint h, uint l) const;
- uint unicodeToJisx0208(uint h, uint l) const;
+ uint unicodeToJisx0208(uint h, uint l) const override;
// uint UnicodeToJisx0212(uint h, uint l) const;
};
@@ -462,17 +462,17 @@ public:
// uint AsciiToUnicode(uint h, uint l) const;
// uint Jisx0201ToUnicode(uint h, uint l) const;
- uint jisx0201LatinToUnicode(uint h, uint l) const;
+ uint jisx0201LatinToUnicode(uint h, uint l) const override;
// uint Jisx0201KanaToUnicode(uint h, uint l) const;
- uint jisx0208ToUnicode(uint h, uint l) const;
- uint jisx0212ToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const override;
+ uint jisx0212ToUnicode(uint h, uint l) const override;
// uint UnicodeToAscii(uint h, uint l) const;
// uint UnicodeToJisx0201(uint h, uint l) const;
- uint unicodeToJisx0201Latin(uint h, uint l) const;
+ uint unicodeToJisx0201Latin(uint h, uint l) const override;
// uint UnicodeToJisx0201Kana(uint h, uint l) const;
- uint unicodeToJisx0208(uint h, uint l) const;
- uint unicodeToJisx0212(uint h, uint l) const;
+ uint unicodeToJisx0208(uint h, uint l) const override;
+ uint unicodeToJisx0212(uint h, uint l) const override;
};
uint QJpUnicodeConv_JISX0221_ASCII::jisx0201LatinToUnicode(uint h, uint l) const
@@ -558,17 +558,17 @@ public:
// uint AsciiToUnicode(uint h, uint l) const;
// uint Jisx0201ToUnicode(uint h, uint l) const;
- uint jisx0201LatinToUnicode(uint h, uint l) const;
+ uint jisx0201LatinToUnicode(uint h, uint l) const override;
// uint Jisx0201KanaToUnicode(uint h, uint l) const;
- uint jisx0208ToUnicode(uint h, uint l) const;
- uint jisx0212ToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const override;
+ uint jisx0212ToUnicode(uint h, uint l) const override;
- uint unicodeToAscii(uint h, uint l) const;
+ uint unicodeToAscii(uint h, uint l) const override;
// uint UnicodeToJisx0201(uint h, uint l) const;
- uint unicodeToJisx0201Latin(uint h, uint l) const;
+ uint unicodeToJisx0201Latin(uint h, uint l) const override;
// uint UnicodeToJisx0201Kana(uint h, uint l) const;
- uint unicodeToJisx0208(uint h, uint l) const;
- uint unicodeToJisx0212(uint h, uint l) const;
+ uint unicodeToJisx0208(uint h, uint l) const override;
+ uint unicodeToJisx0212(uint h, uint l) const override;
};
uint QJpUnicodeConv_Sun::jisx0201LatinToUnicode(uint h, uint l) const
@@ -647,17 +647,17 @@ public:
// uint AsciiToUnicode(uint h, uint l) const;
// uint Jisx0201ToUnicode(uint h, uint l) const;
- uint jisx0201LatinToUnicode(uint h, uint l) const;
+ uint jisx0201LatinToUnicode(uint h, uint l) const override;
// uint Jisx0201KanaToUnicode(uint h, uint l) const;
- uint jisx0208ToUnicode(uint h, uint l) const;
- uint jisx0212ToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const override;
+ uint jisx0212ToUnicode(uint h, uint l) const override;
// uint UnicodeToAscii(uint h, uint l) const;
// uint UnicodeToJisx0201(uint h, uint l) const;
- uint unicodeToJisx0201Latin(uint h, uint l) const;
+ uint unicodeToJisx0201Latin(uint h, uint l) const override;
// uint UnicodeToJisx0201Kana(uint h, uint l) const;
- uint unicodeToJisx0208(uint h, uint l) const;
- uint unicodeToJisx0212(uint h, uint l) const;
+ uint unicodeToJisx0208(uint h, uint l) const override;
+ uint unicodeToJisx0212(uint h, uint l) const override;
};
uint QJpUnicodeConv_Microsoft::jisx0201LatinToUnicode(uint h, uint l) const
diff --git a/src/corelib/codecs/qsjiscodec_p.h b/src/corelib/codecs/qsjiscodec_p.h
index 7dfa6f7fe4..6257a7875c 100644
--- a/src/corelib/codecs/qsjiscodec_p.h
+++ b/src/corelib/codecs/qsjiscodec_p.h
@@ -94,12 +94,12 @@ public:
static QList<QByteArray> _aliases();
static int _mibEnum();
- QByteArray name() const { return _name(); }
- QList<QByteArray> aliases() const { return _aliases(); }
- int mibEnum() const { return _mibEnum(); }
+ QByteArray name() const override { return _name(); }
+ QList<QByteArray> aliases() const override { return _aliases(); }
+ int mibEnum() const override { return _mibEnum(); }
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
QSjisCodec();
~QSjisCodec();
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index 1541c498e6..adb84a1856 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -492,6 +493,24 @@ QTextCodec::QTextCodec()
*/
QTextCodec::~QTextCodec()
{
+ QCoreGlobalData *globalData = QCoreGlobalData::instance();
+ if (!globalData)
+ return;
+
+ globalData->codecForLocale.testAndSetRelaxed(this, nullptr);
+
+ QMutexLocker locker(textCodecsMutex());
+
+ globalData->allCodecs.removeOne(this);
+
+ auto it = globalData->codecCache.cbegin();
+
+ while (it != globalData->codecCache.cend()) {
+ if (it.value() == this)
+ it = globalData->codecCache.erase(it);
+ else
+ ++it;
+ }
}
/*!
@@ -1218,6 +1237,19 @@ bool QTextDecoder::hasFailure() const
return state.invalidChars != 0;
}
+/*!
+ \internal
+ \since 5.12
+
+ Determines whether the decoder needs more bytes to continue decoding. That
+ is, this signifies that the input string ended in the middle of a
+ multi-byte sequence. Note that it's possible some codecs do not report this.
+ */
+bool QTextDecoder::needsMoreData() const
+{
+ return state.remainingChars;
+}
+
QT_END_NAMESPACE
#endif // QT_NO_TEXTCODEC
diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h
index 8153bebac8..09d21166d8 100644
--- a/src/corelib/codecs/qtextcodec.h
+++ b/src/corelib/codecs/qtextcodec.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -162,6 +162,7 @@ public:
QString toUnicode(const QByteArray &ba);
void toUnicode(QString *target, const char *chars, int len);
bool hasFailure() const;
+ bool needsMoreData() const;
private:
const QTextCodec *c;
QTextCodec::ConverterState state;
diff --git a/src/corelib/codecs/qtextcodec_p.h b/src/corelib/codecs/qtextcodec_p.h
index f3c2d090c9..be0cab93e6 100644
--- a/src/corelib/codecs/qtextcodec_p.h
+++ b/src/corelib/codecs/qtextcodec_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_TEXTCODEC
-#if defined(Q_OS_MAC) || defined(Q_OS_ANDROID) || defined(Q_OS_QNX)
+#if defined(Q_OS_MAC) || defined(Q_OS_ANDROID) || defined(Q_OS_QNX) || defined(Q_OS_WASM)
#define QT_LOCALE_IS_UTF8
#endif
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
index ce1b092a54..26c68cdee5 100644
--- a/src/corelib/codecs/qutfcodec.cpp
+++ b/src/corelib/codecs/qutfcodec.cpp
@@ -102,6 +102,26 @@ static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const
return false;
}
}
+
+ if (end - src >= 8) {
+ // do eight characters at a time
+ __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src));
+ __m128i packed = _mm_packus_epi16(data, data);
+ __m128i nonAscii = _mm_cmpgt_epi8(packed, _mm_setzero_si128());
+
+ // store even non-ASCII
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(dst), packed);
+
+ uchar n = ~_mm_movemask_epi8(nonAscii);
+ if (n) {
+ nextAscii = src + qBitScanReverse(n) + 1;
+ n = qCountTrailingZeroBits(n);
+ dst += n;
+ src += n;
+ return false;
+ }
+ }
+
return src == end;
}
@@ -150,11 +170,52 @@ static inline bool simdDecodeAscii(ushort *&dst, const uchar *&nextAscii, const
return false;
}
+
+ if (end - src >= 8) {
+ __m128i data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(src));
+ uint n = _mm_movemask_epi8(data) & 0xff;
+ if (!n) {
+ // unpack and store
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), _mm_unpacklo_epi8(data, _mm_setzero_si128()));
+ } else {
+ while (!(n & 1)) {
+ *dst++ = *src++;
+ n >>= 1;
+ }
+
+ n = qBitScanReverse(n);
+ nextAscii = src + n + 1;
+ return false;
+ }
+ }
+
return src == end;
}
static inline const uchar *simdFindNonAscii(const uchar *src, const uchar *end, const uchar *&nextAscii)
{
+#ifdef __AVX2__
+ // do 32 characters at a time
+ // (this is similar to simdTestMask in qstring.cpp)
+ const __m256i mask = _mm256_set1_epi8(0x80);
+ for ( ; end - src >= 32; src += 32) {
+ __m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src));
+ if (_mm256_testz_si256(mask, data))
+ continue;
+
+ uint n = _mm256_movemask_epi8(data);
+ Q_ASSUME(n);
+
+ // find the next probable ASCII character
+ // we don't want to load 32 bytes again in this loop if we know there are non-ASCII
+ // characters still coming
+ nextAscii = src + qBitScanReverse(n) + 1;
+
+ // return the non-ASCII character
+ return src + qCountTrailingZeroBits(n);
+ }
+#endif
+
// do sixteen characters at a time
for ( ; end - src >= 16; src += 16) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
@@ -695,26 +756,16 @@ QByteArray QUtf16::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conv
char *data = d.data();
if (!state || !(state->flags & QTextCodec::IgnoreHeader)) {
QChar bom(QChar::ByteOrderMark);
- if (endian == BigEndianness) {
- data[0] = bom.row();
- data[1] = bom.cell();
- } else {
- data[0] = bom.cell();
- data[1] = bom.row();
- }
+ if (endian == BigEndianness)
+ qToBigEndian(bom.unicode(), data);
+ else
+ qToLittleEndian(bom.unicode(), data);
data += 2;
}
- if (endian == BigEndianness) {
- for (int i = 0; i < len; ++i) {
- *(data++) = uc[i].row();
- *(data++) = uc[i].cell();
- }
- } else {
- for (int i = 0; i < len; ++i) {
- *(data++) = uc[i].cell();
- *(data++) = uc[i].row();
- }
- }
+ if (endian == BigEndianness)
+ qToBigEndian<ushort>(uc, len, data);
+ else
+ qToLittleEndian<ushort>(uc, len, data);
if (state) {
state->remainingChars = 0;
@@ -830,20 +881,14 @@ QByteArray QUtf32::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conv
if (endian == BigEndianness) {
while (i.hasNext()) {
uint cp = i.next();
-
- *(data++) = cp >> 24;
- *(data++) = (cp >> 16) & 0xff;
- *(data++) = (cp >> 8) & 0xff;
- *(data++) = cp & 0xff;
+ qToBigEndian(cp, data);
+ data += 4;
}
} else {
while (i.hasNext()) {
uint cp = i.next();
-
- *(data++) = cp & 0xff;
- *(data++) = (cp >> 8) & 0xff;
- *(data++) = (cp >> 16) & 0xff;
- *(data++) = cp >> 24;
+ qToLittleEndian(cp, data);
+ data += 4;
}
}
diff --git a/src/corelib/codecs/qutfcodec_p.h b/src/corelib/codecs/qutfcodec_p.h
index 659a229dae..7405996fba 100644
--- a/src/corelib/codecs/qutfcodec_p.h
+++ b/src/corelib/codecs/qutfcodec_p.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
diff --git a/src/corelib/codecs/qwindowscodec_p.h b/src/corelib/codecs/qwindowscodec_p.h
index 2fd3c35378..1a74d618be 100644
--- a/src/corelib/codecs/qwindowscodec_p.h
+++ b/src/corelib/codecs/qwindowscodec_p.h
@@ -61,12 +61,12 @@ public:
QWindowsLocalCodec();
~QWindowsLocalCodec();
- QString convertToUnicode(const char *, int, ConverterState *) const;
- QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
+ QString convertToUnicode(const char *, int, ConverterState *) const override;
+ QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override;
QString convertToUnicodeCharByChar(const char *chars, int length, ConverterState *state) const;
- QByteArray name() const;
- int mibEnum() const;
+ QByteArray name() const override;
+ int mibEnum() const override;
};
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index dfb575da0d..183eb3a13e 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -64,13 +64,6 @@
"UCollator *collator = ucol_open(\"ru_RU\", &status);",
"if (!U_FAILURE(status))",
" ucol_close(collator);"
- ],
- "qmake": [
- "CONFIG += build_all",
- "CONFIG(debug, debug|release): \\",
- " LIBS += $$LIBS_DEBUG",
- "else: \\",
- " LIBS += $$LIBS_RELEASE"
]
},
"sources": [
@@ -488,7 +481,7 @@
},
"eventfd": {
"label": "eventfd",
- "condition": "tests.eventfd",
+ "condition": "!config.wasm && tests.eventfd",
"output": [ "feature" ]
},
"futimens": {
@@ -599,7 +592,7 @@
"poll_ppoll": {
"label": "Native ppoll()",
"emitIf": "!config.win32",
- "condition": "tests.ppoll",
+ "condition": "!config.wasm && tests.ppoll",
"output": [ "privateFeature" ]
},
"poll_pollts": {
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 7f62a6f1b0..2244020795 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -4,6 +4,7 @@ CONFIG += exceptions
MODULE = core # not corelib, as per project file
MODULE_CONFIG = moc resources
+qtConfig(gc_binaries): MODULE_CONFIG += gc_binaries
!isEmpty(QT_NAMESPACE): MODULE_DEFINES = QT_NAMESPACE=$$QT_NAMESPACE
TRACEPOINT_PROVIDER = $$PWD/qtcore.tracepoints
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index 2d7b9a9ac8..9d029e5d4d 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -440,6 +440,54 @@ QString global_greeting(int type)
//! [36]
+//! [qttrnnoop]
+static const char * const StatusClass::status_strings[] = {
+ QT_TR_N_NOOP("There are %n new message(s)"),
+ QT_TR_N_NOOP("There are %n total message(s)")
+};
+
+QString StatusClass::status(int type, int count)
+{
+ return tr(status_strings[type], nullptr, count);
+}
+//! [qttrnnoop]
+
+//! [qttranslatennoop]
+static const char * const greeting_strings[] = {
+ QT_TRANSLATE_N_NOOP("Welcome Msg", "Hello, you have %n message(s)"),
+ QT_TRANSLATE_N_NOOP("Welcome Msg", "Hi, you have %n message(s)")
+};
+
+QString global_greeting(int type, int msgcnt)
+{
+ return translate("Welcome Msg", greeting_strings[type], nullptr, msgcnt);
+}
+//! [qttranslatennoop]
+
+//! [qttranslatennoop3]
+static { const char * const source; const char * const comment; } status_strings[] = {
+ QT_TRANSLATE_N_NOOP3("Message Status", "Hello, you have %n message(s)",
+ "A login message status"),
+ QT_TRANSLATE_N_NOOP3("Message status", "You have %n new message(s)",
+ "A new message query status")
+};
+
+QString FriendlyConversation::greeting(int type, int count)
+{
+ return tr(status_strings[type].source,
+ status_strings[type].comment, count);
+}
+
+QString global_greeting(int type, int count)
+{
+ return qApp->translate("Message Status",
+ status_strings[type].source,
+ status_strings[type].comment,
+ count);
+}
+//! [qttranslatennoop3]
+
+
//! [qttrid]
//% "%n fooish bar(s) found.\n"
//% "Do you want to continue?"
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
index d163129d54..bd7cdaa681 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
@@ -353,9 +353,21 @@ long dec = str.toLong(&ok, 10); // dec == 0, ok == false
//! [38]
QByteArray string("1234.56");
-double a = string.toDouble(); // a == 1234.56
+bool ok;
+double a = string.toDouble(&ok); // a == 1234.56, ok == true
+
+string = "1234.56 Volt";
+a = str.toDouble(&ok); // a == 0, ok == false
//! [38]
+//! [38float]
+QByteArray string("1234.56");
+bool ok;
+float a = string.toFloat(&ok); // a == 1234.56, ok == true
+
+string = "1234.56 Volt";
+a = str.toFloat(&ok); // a == 0, ok == false
+//! [38float]
//! [39]
QByteArray text("Qt is great!");
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qeasingcurve.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qeasingcurve.cpp
index 97453e2b06..88f1e90713 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qeasingcurve.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qeasingcurve.cpp
@@ -48,11 +48,15 @@
**
****************************************************************************/
+//! [typedef]
+qreal myEasingFunction(qreal progress);
+//! [typedef]
+
//! [0]
QEasingCurve easing(QEasingCurve::InOutQuad);
- for (qreal t = 0.0; t < 1.0; t+=0.1)
- qWarning() << "Effective progress" << t << " is
+ for (qreal t = 0.0; t < 1.0; t += 0.1)
+ qWarning() << "Effective progress" << t << "is"
<< easing.valueForProgress(t);
//! [0]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
index 5f0a175374..28c66628b7 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp
@@ -350,4 +350,11 @@ while (i.hasNext()) {
//! [30]
}
+{
+//! [31]
+QString wildcard = QRegularExpression::wildcardToRegularExpression("*.jpeg");
+// wilcard == ".*\.jpeg"
+//! [31]
+}
+
}
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qscopeguard.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qscopeguard.cpp
new file mode 100644
index 0000000000..c8c5f694c6
--- /dev/null
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qscopeguard.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+void myComplexCodeWithMultipleReturnPoints(int v)
+{
+ // The lambda will be executed right before your function returns
+ auto cleanup = qScopeGuard([] { code you want executed goes HERE; });
+
+ if (v == -1)
+ return;
+
+ int v2 = code_that_might_through_exceptions();
+
+ if (v2 == -1)
+ return;
+
+ (...)
+}
+//! [0]
diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp
index c8842eec00..ac7fc7d078 100644
--- a/src/corelib/doc/snippets/qstring/main.cpp
+++ b/src/corelib/doc/snippets/qstring/main.cpp
@@ -853,6 +853,8 @@ void Widget::toDoubleFunction()
double d;
d = QString( "1234.56e-02" ).toDouble(&ok); // ok == true, d == 12.3456
+
+ d = QString( "1234.56e-02 Volt" ).toDouble(&ok); // ok == false, d == 0
//! [67]
//! [68]
@@ -875,6 +877,9 @@ void Widget::toFloatFunction()
bool ok;
QString str2 = "R2D2";
str2.toFloat(&ok); // returns 0.0, sets ok to false
+
+ QString str3 = "1234.56 Volt";
+ str3.toFloat(&ok); // returns 0.0, sets ok to false
//! [71]
}
diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
index 213caa6c59..fcf091458a 100644
--- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
+++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
@@ -321,8 +321,8 @@
callbacks, you'd have to find five different names and keep track
of the types yourself.
- \sa QLCDNumber, QObject::connect(), {Digital Clock Example}, and
- {Tetrix Example}.
+ \sa QLCDNumber, QObject::connect(), {Digital Clock Example},
+ {Tetrix Example}
\section1 Signals And Slots With Default Arguments
diff --git a/src/corelib/global/archdetect.cpp b/src/corelib/global/archdetect.cpp
index 6c1a026fa8..422df3ff90 100644
--- a/src/corelib/global/archdetect.cpp
+++ b/src/corelib/global/archdetect.cpp
@@ -51,6 +51,8 @@
# define ARCH_PROCESSOR "avr32"
#elif defined(Q_PROCESSOR_BLACKFIN)
# define ARCH_PROCESSOR "bfin"
+#elif defined(Q_PROCESSOR_WASM)
+# define ARCH_PROCESSOR "wasm"
#elif defined(Q_PROCESSOR_X86_32)
# define ARCH_PROCESSOR "i386"
#elif defined(Q_PROCESSOR_X86_64)
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index 2b4fd6d661..a4d132a4f4 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -29,6 +29,7 @@ HEADERS += \
SOURCES += \
global/archdetect.cpp \
+ global/qendian.cpp \
global/qglobal.cpp \
global/qlibraryinfo.cpp \
global/qmalloc.cpp \
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index f46ff73527..345ab9e8ad 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -206,6 +206,9 @@
# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
# endif
# endif
+# ifdef __EMSCRIPTEN__
+# define Q_CC_EMSCRIPTEN
+# endif
# else
/* Plain GCC */
# if Q_CC_GNU >= 405
@@ -898,7 +901,7 @@
/* C11 features supported in GCC 4.7: */
# define Q_COMPILER_STATIC_ASSERT
# endif
-# if Q_CC_GNU >= 409
+# if Q_CC_GNU >= 409 && defined(__has_include)
/* C11 features supported in GCC 4.9: */
# if __has_include(<threads.h>)
# define Q_COMPILER_THREAD_LOCAL
@@ -1152,6 +1155,19 @@
# define Q_REQUIRED_RESULT [[nodiscard]]
#endif
+#if defined(__cpp_enumerator_attributes) && __cpp_enumerator_attributes >= 201411
+#if defined(Q_CC_MSVC)
+// Can't mark enum values as __declspec(deprecated) with MSVC, also can't move
+// everything to [[deprecated]] because MSVC gives a compilation error when marking
+// friend methods of a class as [[deprecated("text")]], breaking qstring.h
+# define Q_DECL_ENUMERATOR_DEPRECATED [[deprecated]]
+# define Q_DECL_ENUMERATOR_DEPRECATED_X(x) [[deprecated(x)]]
+#else
+# define Q_DECL_ENUMERATOR_DEPRECATED Q_DECL_DEPRECATED
+# define Q_DECL_ENUMERATOR_DEPRECATED_X(x) Q_DECL_DEPRECATED_X(x)
+#endif
+#endif
+
/*
* Fallback macros to certain compiler features
*/
@@ -1186,6 +1202,12 @@
#ifndef Q_DECL_DEPRECATED_X
# define Q_DECL_DEPRECATED_X(text) Q_DECL_DEPRECATED
#endif
+#ifndef Q_DECL_ENUMERATOR_DEPRECATED
+# define Q_DECL_ENUMERATOR_DEPRECATED
+#endif
+#ifndef Q_DECL_ENUMERATOR_DEPRECATED_X
+# define Q_DECL_ENUMERATOR_DEPRECATED_X(x)
+#endif
#ifndef Q_DECL_EXPORT
# define Q_DECL_EXPORT
#endif
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index 499fd4c9e8..506c8513dc 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -104,6 +104,7 @@
#else
# define QT_FEATURE_renameat2 -1
#endif
+#define QT_FEATURE_settings -1
#define QT_FEATURE_sharedmemory -1
#define QT_FEATURE_slog2 -1
#ifdef __GLIBC_PREREQ
@@ -116,7 +117,7 @@
#define QT_FEATURE_systemsemaphore -1
#define QT_FEATURE_temporaryfile 1
#define QT_FEATURE_textdate 1
-#define QT_NO_THREAD
+#define QT_FEATURE_thread -1
#define QT_FEATURE_timezone -1
#define QT_FEATURE_topleveldomain -1
#define QT_NO_TRANSLATION
diff --git a/src/corelib/global/qendian.cpp b/src/corelib/global/qendian.cpp
new file mode 100644
index 0000000000..7fd6e13d3b
--- /dev/null
+++ b/src/corelib/global/qendian.cpp
@@ -0,0 +1,919 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qendian.h"
+
+#include "qalgorithms.h"
+#include <private/qsimd_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \headerfile <QtEndian>
+ \title Endian Conversion Functions
+ \ingroup funclists
+ \brief The <QtEndian> header provides functions to convert between
+ little and big endian representations of numbers.
+*/
+
+/*!
+ \fn template <typename T> T qFromUnaligned(const void *ptr)
+ \internal
+ \since 5.5
+
+ Loads a \c{T} from address \a ptr, which may be misaligned.
+
+ Use of this function avoids the undefined behavior that the C++ standard
+ otherwise attributes to unaligned loads.
+*/
+
+/*!
+ \fn template <typename T> void qToUnaligned(const T t, void *ptr)
+ \internal
+ \since 4.5
+
+ Stores \a t to address \a ptr, which may be misaligned.
+
+ Use of this function avoids the undefined behavior that the C++ standard
+ otherwise attributes to unaligned stores.
+*/
+
+
+/*!
+ \fn template <typename T> T qFromBigEndian(const void *src)
+ \since 4.3
+ \relates <QtEndian>
+
+ Reads a big-endian number from memory location \a src and returns the number in the
+ host byte order representation.
+ On CPU architectures where the host byte order is little-endian (such as x86) this
+ will swap the byte order; otherwise it will just read from \a src.
+
+ \note Template type \c{T} can either be a quint16, qint16, quint32, qint32,
+ quint64, or qint64. Other types of integers, e.g., qlong, are not
+ applicable.
+
+ \note Since Qt 5.7, the type of the \a src parameter is a void pointer.
+
+ There are no data alignment constraints for \a src.
+
+ \sa qFromLittleEndian()
+ \sa qToBigEndian()
+ \sa qToLittleEndian()
+*/
+/*!
+ \fn template <typename T> T qFromBigEndian(T src)
+ \since 4.3
+ \relates <QtEndian>
+ \overload
+
+ Converts \a src from big-endian byte order and returns the number in host byte order
+ representation of that number.
+ On CPU architectures where the host byte order is little-endian (such as x86) this
+ will return \a src with the byte order swapped; otherwise it will return \a src
+ unmodified.
+*/
+/*!
+ \fn template <typename T> T qFromBigEndian(const void *src, qsizetype count, void *dest)
+ \since 5.12
+ \relates <QtEndian>
+
+ Reads \a count big-endian numbers from memory location \a src and stores
+ them in the host byte order representation at \a dest. On CPU architectures
+ where the host byte order is little-endian (such as x86) this will swap the
+ byte order; otherwise it will just perform a \c memcpy from \a src to \a
+ dest.
+
+ \note Template type \c{T} can either be a quint16, qint16, quint32, qint32,
+ quint64, or qint64. Other types of integers, e.g., qlong, are not
+ applicable.
+
+ There are no data alignment constraints for \a src. However, \a dest is
+ expected to be naturally aligned for type \c{T}.
+
+ If \a src and \a dest can be the same pointer, this function will perform
+ an in-place swap (if necessary). If they are not the same, the memory
+ regions must not overlap.
+
+ \sa qFromLittleEndian()
+ \sa qToBigEndian()
+ \sa qToLittleEndian()
+*/
+/*!
+ \fn template <typename T> T qFromLittleEndian(const void *src)
+ \since 4.3
+ \relates <QtEndian>
+
+ Reads a little-endian number from memory location \a src and returns the number in
+ the host byte order representation.
+ On CPU architectures where the host byte order is big-endian (such as PowerPC) this
+ will swap the byte order; otherwise it will just read from \a src.
+
+ \note Template type \c{T} can either be a quint16, qint16, quint32, qint32,
+ quint64, or qint64. Other types of integers, e.g., qlong, are not
+ applicable.
+
+ \note Since Qt 5.7, the type of the \a src parameter is a void pointer.
+
+ There are no data alignment constraints for \a src.
+
+ \sa qFromBigEndian()
+ \sa qToBigEndian()
+ \sa qToLittleEndian()
+*/
+/*!
+ \fn template <typename T> T qFromLittleEndian(T src)
+ \since 4.3
+ \relates <QtEndian>
+ \overload
+
+ Converts \a src from little-endian byte order and returns the number in host byte
+ order representation of that number.
+ On CPU architectures where the host byte order is big-endian (such as PowerPC) this
+ will return \a src with the byte order swapped; otherwise it will return \a src
+ unmodified.
+*/
+/*!
+ \fn template <typename T> T qFromLittleEndian(const void *src, qsizetype count, void *dest)
+ \since 5.12
+ \relates <QtEndian>
+
+ Reads \a count little-endian numbers from memory location \a src and stores
+ them in the host byte order representation at \a dest. On CPU architectures
+ where the host byte order is big-endian (such as PowerPC) this will swap the
+ byte order; otherwise it will just perform a \c memcpy from \a src to \a
+ dest.
+
+ \note Template type \c{T} can either be a quint16, qint16, quint32, qint32,
+ quint64, or qint64. Other types of integers, e.g., qlong, are not
+ applicable.
+
+ There are no data alignment constraints for \a src. However, \a dest is
+ expected to be naturally aligned for type \c{T}.
+
+ If \a src and \a dest can be the same pointer, this function will perform
+ an in-place swap (if necessary). If they are not the same, the memory
+ regions must not overlap.
+
+ \sa qFromLittleEndian()
+ \sa qToBigEndian()
+ \sa qToLittleEndian()
+*/
+/*!
+ \fn template <typename T> void qToBigEndian(T src, void *dest)
+ \since 4.3
+ \relates <QtEndian>
+
+ Writes the number \a src with template type \c{T} to the memory location at \a dest
+ in big-endian byte order.
+
+ \note Template type \c{T} can either be a quint16, qint16, quint32, qint32,
+ quint64, or qint64. Other types of integers, e.g., qlong, are not
+ applicable.
+
+ There are no data alignment constraints for \a dest.
+
+ \note Since Qt 5.7, the type of the \a dest parameter is a void pointer.
+
+ \sa qFromBigEndian()
+ \sa qFromLittleEndian()
+ \sa qToLittleEndian()
+*/
+/*!
+ \fn template <typename T> T qToBigEndian(T src)
+ \since 4.3
+ \relates <QtEndian>
+ \overload
+
+ Converts \a src from host byte order and returns the number in big-endian byte order
+ representation of that number.
+ On CPU architectures where the host byte order is little-endian (such as x86) this
+ will return \a src with the byte order swapped; otherwise it will return \a src
+ unmodified.
+*/
+/*!
+ \fn template <typename T> T qToBigEndian(const void *src, qsizetype count, void *dest)
+ \since 5.12
+ \relates <QtEndian>
+
+ Reads \a count numbers from memory location \a src in the host byte order
+ and stores them in big-endian representation at \a dest. On CPU
+ architectures where the host byte order is little-endian (such as x86) this
+ will swap the byte order; otherwise it will just perform a \c memcpy from
+ \a src to \a dest.
+
+ \note Template type \c{T} can either be a quint16, qint16, quint32, qint32,
+ quint64, or qint64. Other types of integers, e.g., qlong, are not
+ applicable.
+
+ There are no data alignment constraints for \a dest. However, \a src is
+ expected to be naturally aligned for type \c{T}.
+
+ If \a src and \a dest can be the same pointer, this function will perform
+ an in-place swap (if necessary). If they are not the same, the memory
+ regions must not overlap.
+
+ \sa qFromLittleEndian()
+ \sa qToBigEndian()
+ \sa qToLittleEndian()
+*/
+/*!
+ \fn template <typename T> void qToLittleEndian(T src, void *dest)
+ \since 4.3
+ \relates <QtEndian>
+
+ Writes the number \a src with template type \c{T} to the memory location at \a dest
+ in little-endian byte order.
+
+ \note Template type \c{T} can either be a quint16, qint16, quint32, qint32,
+ quint64, or qint64. Other types of integers, e.g., qlong, are not
+ applicable.
+
+ There are no data alignment constraints for \a dest.
+
+ \note Since Qt 5.7, the type of the \a dest parameter is a void pointer.
+
+ \sa qFromBigEndian()
+ \sa qFromLittleEndian()
+ \sa qToBigEndian()
+*/
+/*!
+ \fn template <typename T> T qToLittleEndian(T src)
+ \since 4.3
+ \relates <QtEndian>
+ \overload
+
+ Converts \a src from host byte order and returns the number in little-endian byte
+ order representation of that number.
+ On CPU architectures where the host byte order is big-endian (such as PowerPC) this
+ will return \a src with the byte order swapped; otherwise it will return \a src
+ unmodified.
+*/
+/*!
+ \fn template <typename T> T qToLittleEndian(const void *src, qsizetype count, void *dest)
+ \since 5.12
+ \relates <QtEndian>
+
+ Reads \a count numbers from memory location \a src in the host byte order
+ and stores them in little-endian representation at \a dest. On CPU
+ architectures where the host byte order is big-endian (such as PowerPC)
+ this will swap the byte order; otherwise it will just perform a \c memcpy
+ from \a src to \a dest.
+
+ \note Template type \c{T} can either be a quint16, qint16, quint32, qint32,
+ quint64, or qint64. Other types of integers, e.g., qlong, are not
+ applicable.
+
+ There are no data alignment constraints for \a dest. However, \a src is
+ expected to be naturally aligned for type \c{T}.
+
+ If \a src and \a dest can be the same pointer, this function will perform
+ an in-place swap (if necessary). If they are not the same, the memory
+ regions must not overlap.
+
+ \sa qFromLittleEndian()
+ \sa qToBigEndian()
+ \sa qToLittleEndian()
+*/
+
+/*!
+ \class QLEInteger
+ \inmodule QtCore
+ \brief The QLEInteger class provides platform-independent little-endian integers.
+ \since 5.10
+
+ The template parameter \c T must be a C++ integer type:
+ \list
+ \li 8-bit: char, signed char, unsigned char, qint8, quint8
+ \li 16-bit: short, unsigned short, qint16, quint16, char16_t
+ \li 32-bit: int, unsigned int, qint32, quint32, char32_t
+ \li 64-bit: long long, unsigned long long, qint64, quint64
+ \li platform-specific size: long, unsigned long
+ \li pointer size: qintptr, quintptr, qptrdiff
+ \endlist
+
+ \note Using this class may be slower than using native integers, so only use it when
+ an exact endianness is needed.
+*/
+
+/*! \fn template <typename T> QLEInteger<T>::QLEInteger(T value)
+
+ Constructs a QLEInteger with the given \a value.
+*/
+
+/*! \fn template <typename T> QLEInteger &QLEInteger<T>::operator=(T i)
+
+ Assigns \a i to this QLEInteger and returns a reference to
+ this QLEInteger.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger<T>::operator T() const
+
+ Returns the value of this QLEInteger as a native integer.
+*/
+
+/*!
+ \fn template <typename T> bool QLEInteger<T>::operator==(QLEInteger other) const
+
+ Returns \c true if the value of this QLEInteger is equal to the value of \a other.
+*/
+
+/*!
+ \fn template <typename T> bool QLEInteger<T>::operator!=(QLEInteger other) const
+
+ Returns \c true if the value of this QLEInteger is not equal to the value of \a other.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator+=(T i)
+
+ Adds \a i to this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator-=(T i)
+
+ Subtracts \a i from this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator*=(T i)
+
+ Multiplies \a i with this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator/=(T i)
+
+ Divides this QLEInteger with \a i and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator%=(T i)
+
+ Sets this QLEInteger to the remainder of a division by \a i and
+ returns a reference to this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator>>=(T i)
+
+ Performs a left-shift by \a i on this QLEInteger and returns a
+ reference to this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator<<=(T i)
+
+ Performs a right-shift by \a i on this QLEInteger and returns a
+ reference to this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator|=(T i)
+
+ Performs a bitwise OR with \a i onto this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator&=(T i)
+
+ Performs a bitwise AND with \a i onto this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator^=(T i)
+
+ Performs a bitwise XOR with \a i onto this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator++()
+
+ Performs a prefix ++ (increment) on this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger QLEInteger<T>::operator++(int)
+
+ Performs a postfix ++ (increment) on this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger &QLEInteger<T>::operator--()
+
+ Performs a prefix -- (decrement) on this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger QLEInteger<T>::operator--(int)
+
+ Performs a postfix -- (decrement) on this QLEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger QLEInteger<T>::max()
+
+ Returns the maximum (finite) value representable by the numeric type T.
+*/
+
+/*!
+ \fn template <typename T> QLEInteger QLEInteger<T>::min()
+
+ Returns the minimum (finite) value representable by the numeric type T.
+*/
+
+/*!
+ \class QBEInteger
+ \inmodule QtCore
+ \brief The QBEInteger class provides platform-independent big-endian integers.
+ \since 5.10
+
+ The template parameter \c T must be a C++ integer type:
+ \list
+ \li 8-bit: char, signed char, unsigned char, qint8, quint8
+ \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11)
+ \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11)
+ \li 64-bit: long long, unsigned long long, qint64, quint64
+ \li platform-specific size: long, unsigned long
+ \li pointer size: qintptr, quintptr, qptrdiff
+ \endlist
+
+ \note Using this class may be slower than using native integers, so only use it when
+ an exact endianness is needed.
+*/
+
+/*! \fn template <typename T> QBEInteger<T>::QBEInteger(T value)
+
+ Constructs a QBEInteger with the given \a value.
+*/
+
+/*! \fn template <typename T> QBEInteger &QBEInteger<T>::operator=(T i)
+
+ Assigns \a i to this QBEInteger and returns a reference to
+ this QBEInteger.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger<T>::operator T() const
+
+ Returns the value of this QBEInteger as a native integer.
+*/
+
+/*!
+ \fn template <typename T> bool QBEInteger<T>::operator==(QBEInteger other) const
+
+ Returns \c true if the value of this QBEInteger is equal to the value of \a other.
+*/
+
+/*!
+ \fn template <typename T> bool QBEInteger<T>::operator!=(QBEInteger other) const
+
+ Returns \c true if the value of this QBEInteger is not equal to the value of \a other.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator+=(T i)
+
+ Adds \a i to this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator-=(T i)
+
+ Subtracts \a i from this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator*=(T i)
+
+ Multiplies \a i with this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator/=(T i)
+
+ Divides this QBEInteger with \a i and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator%=(T i)
+
+ Sets this QBEInteger to the remainder of a division by \a i and
+ returns a reference to this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator>>=(T i)
+
+ Performs a left-shift by \a i on this QBEInteger and returns a
+ reference to this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator<<=(T i)
+
+ Performs a right-shift by \a i on this QBEInteger and returns a
+ reference to this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator|=(T i)
+
+ Performs a bitwise OR with \a i onto this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator&=(T i)
+
+ Performs a bitwise AND with \a i onto this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator^=(T i)
+
+ Performs a bitwise XOR with \a i onto this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator++()
+
+ Performs a prefix ++ (increment) on this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger QBEInteger<T>::operator++(int)
+
+ Performs a postfix ++ (increment) on this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger &QBEInteger<T>::operator--()
+
+ Performs a prefix -- (decrement) on this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger QBEInteger<T>::operator--(int)
+
+ Performs a postfix -- (decrement) on this QBEInteger and returns a reference to
+ this object.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger QBEInteger<T>::max()
+
+ Returns the maximum (finite) value representable by the numeric type T.
+*/
+
+/*!
+ \fn template <typename T> QBEInteger QBEInteger<T>::min()
+
+ Returns the minimum (finite) value representable by the numeric type T.
+*/
+
+/*!
+ \typedef quint16_le
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QLEInteger<quint16>. This type is guaranteed to be stored in memory as
+ a 16-bit little-endian unsigned integer on all platforms supported by Qt.
+
+ \sa quint16
+*/
+
+/*!
+ \typedef quint32_le
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QLEInteger<quint32>. This type is guaranteed to be stored in memory as
+ a 32-bit little-endian unsigned integer on all platforms supported by Qt.
+
+ \sa quint32
+*/
+
+/*!
+ \typedef quint64_le
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QLEInteger<quint64>. This type is guaranteed to be stored in memory as
+ a 64-bit little-endian unsigned integer on all platforms supported by Qt.
+
+ \sa quint64
+*/
+
+/*!
+ \typedef quint16_be
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QBEInteger<quint16>. This type is guaranteed to be stored in memory as
+ a 16-bit big-endian unsigned integer on all platforms supported by Qt.
+
+ \sa quint16
+*/
+
+/*!
+ \typedef quint32_be
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QBEInteger<quint32>. This type is guaranteed to be stored in memory as
+ a 32-bit big-endian unsigned integer on all platforms supported by Qt.
+
+ \sa quint32
+*/
+
+/*!
+ \typedef quint64_be
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QBEInteger<quint64>. This type is guaranteed to be stored in memory as
+ a 64-bit big-endian unsigned integer on all platforms supported by Qt.
+
+ \sa quint64
+*/
+
+/*!
+ \typedef qint16_le
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QLEInteger<qint16>. This type is guaranteed to be stored in memory as
+ a 16-bit little-endian signed integer on all platforms supported by Qt.
+
+ \sa qint16
+*/
+
+/*!
+ \typedef qint32_le
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QLEInteger<qint32>. This type is guaranteed to be stored in memory as
+ a 32-bit little-endian signed integer on all platforms supported by Qt.
+
+ \sa qint32
+*/
+
+/*!
+ \typedef qint64_le
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QLEInteger<qint64>. This type is guaranteed to be stored in memory as
+ a 64-bit little-endian signed integer on all platforms supported by Qt.
+
+ \sa qint64
+*/
+
+/*!
+ \typedef qint16_be
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QBEInteger<qint16>. This type is guaranteed to be stored in memory as
+ a 16-bit big-endian signed integer on all platforms supported by Qt.
+
+ \sa qint16
+*/
+
+/*!
+ \typedef qint32_be
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QBEInteger<qint32>. This type is guaranteed to be stored in memory as
+ a 32-bit big-endian signed integer on all platforms supported by Qt.
+
+ \sa qint32
+*/
+
+/*!
+ \typedef qint64_be
+ \relates <QtEndian>
+ \since 5.10
+
+ Typedef for QBEInteger<qint64>. This type is guaranteed to be stored in memory as
+ a 64-bit big-endian signed integer on all platforms supported by Qt.
+
+ \sa qint64
+*/
+
+#if defined(__SSSE3__)
+using ShuffleMask = uchar[16];
+Q_DECL_ALIGN(16) static const ShuffleMask shuffleMasks[3] = {
+ // 16-bit
+ {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14},
+ // 32-bit
+ {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12},
+ // 64-bit
+ {7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8}
+};
+
+static size_t sseSwapLoop(const uchar *src, size_t bytes, uchar *dst,
+ const __m128i *shuffleMaskPtr) noexcept
+{
+ size_t i = 0;
+ const __m128i shuffleMask = _mm_load_si128(shuffleMaskPtr);
+
+# ifdef __AVX2__
+ const __m256i shuffleMask256 = _mm256_inserti128_si256(_mm256_castsi128_si256(shuffleMask), shuffleMask, 1);
+ for ( ; i + sizeof(__m256i) <= bytes; i += sizeof(__m256i)) {
+ __m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src + i));
+ data = _mm256_shuffle_epi8(data, shuffleMask256);
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst + i), data);
+ }
+# else
+ for ( ; i + 2 * sizeof(__m128i) <= bytes; i += 2 * sizeof(__m128i)) {
+ __m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i));
+ __m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i) + 1);
+ data1 = _mm_shuffle_epi8(data1, shuffleMask);
+ data2 = _mm_shuffle_epi8(data2, shuffleMask);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i), data1);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i) + 1, data2);
+ }
+# endif
+
+ if (i + sizeof(__m128i) <= bytes) {
+ __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i));
+ data = _mm_shuffle_epi8(data, shuffleMask);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i), data);
+ i += sizeof(__m128i);
+ }
+
+ return i;
+}
+
+template <typename T> static Q_ALWAYS_INLINE
+size_t simdSwapLoop(const uchar *src, size_t bytes, uchar *dst) noexcept
+{
+ auto shuffleMaskPtr = reinterpret_cast<const __m128i *>(shuffleMasks[0]);
+ shuffleMaskPtr += qCountTrailingZeroBits(sizeof(T)) - 1;
+ size_t i = sseSwapLoop(src, bytes, dst, shuffleMaskPtr);
+
+ // epilogue
+ for (size_t _i = 0 ; i < bytes && _i < sizeof(__m128i); i += sizeof(T), _i += sizeof(T))
+ qbswap(qFromUnaligned<T>(src + i), dst + i);
+
+ // return the total, so the bswapLoop below does nothing
+ return bytes;
+}
+#elif defined(__SSE2__)
+template <typename T> static
+size_t simdSwapLoop(const uchar *, size_t, uchar *) noexcept
+{
+ // no generic version: we can't do 32- and 64-bit swaps easily,
+ // so we won't try
+ return 0;
+}
+
+template <> size_t simdSwapLoop<quint16>(const uchar *src, size_t bytes, uchar *dst) noexcept
+{
+ auto swapEndian = [](__m128i &data) {
+ __m128i lows = _mm_srli_epi16(data, 8);
+ __m128i highs = _mm_slli_epi16(data, 8);
+ data = _mm_xor_si128(lows, highs);
+ };
+
+ size_t i = 0;
+ for ( ; i + 2 * sizeof(__m128i) <= bytes; i += 2 * sizeof(__m128i)) {
+ __m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i));
+ __m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i) + 1);
+ swapEndian(data1);
+ swapEndian(data2);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i), data1);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i) + 1, data2);
+ }
+
+ if (i + sizeof(__m128i) <= bytes) {
+ __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + i));
+ swapEndian(data);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + i), data);
+ i += sizeof(__m128i);
+ }
+
+ // epilogue
+ for (size_t _i = 0 ; i < bytes && _i < sizeof(__m128i); i += sizeof(quint16), _i += sizeof(quint16))
+ qbswap(qFromUnaligned<quint16>(src + i), dst + i);
+
+ // return the total, so the bswapLoop below does nothing
+ return bytes;
+}
+#else
+template <typename T> static Q_ALWAYS_INLINE
+size_t simdSwapLoop(const uchar *, size_t, uchar *) noexcept
+{
+ return 0;
+}
+#endif
+
+template <typename T> static Q_ALWAYS_INLINE
+void *bswapLoop(const uchar *src, size_t n, uchar *dst) noexcept
+{
+ // Buffers cannot partially overlap: either they're identical or totally
+ // disjoint (note: they can be adjacent).
+ if (src != dst) {
+ quintptr s = quintptr(src);
+ quintptr d = quintptr(dst);
+ if (s < d)
+ Q_ASSERT(s + n <= d);
+ else
+ Q_ASSERT(d + n <= s);
+ }
+
+ size_t i = simdSwapLoop<T>(src, n, dst);
+
+ for ( ; i < n; i += sizeof(T))
+ qbswap(qFromUnaligned<T>(src + i), dst + i);
+ return dst + i;
+}
+
+template <> void *qbswap<2>(const void *source, qsizetype n, void *dest) noexcept
+{
+ const uchar *src = reinterpret_cast<const uchar *>(source);
+ uchar *dst = reinterpret_cast<uchar *>(dest);
+
+ return bswapLoop<quint16>(src, n << 1, dst);
+}
+
+template <> void *qbswap<4>(const void *source, qsizetype n, void *dest) noexcept
+{
+ const uchar *src = reinterpret_cast<const uchar *>(source);
+ uchar *dst = reinterpret_cast<uchar *>(dest);
+
+ return bswapLoop<quint32>(src, n << 2, dst);
+}
+
+template <> void *qbswap<8>(const void *source, qsizetype n, void *dest) noexcept
+{
+ const uchar *src = reinterpret_cast<const uchar *>(source);
+ uchar *dst = reinterpret_cast<uchar *>(dest);
+
+ return bswapLoop<quint64>(src, n << 3, dst);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h
index a14fce23f8..1cc8a823d9 100644
--- a/src/corelib/global/qendian.h
+++ b/src/corelib/global/qendian.h
@@ -47,6 +47,11 @@
#include <stdlib.h>
#include <string.h>
+#ifdef min // MSVC
+#undef min
+#undef max
+#endif
+
QT_BEGIN_NAMESPACE
/*
@@ -157,6 +162,14 @@ template <typename T> inline void qbswap(const T src, void *dest)
qToUnaligned<T>(qbswap<T>(src), dest);
}
+template <int Size> void *qbswap(const void *source, qsizetype count, void *dest) noexcept;
+template<> inline void *qbswap<1>(const void *source, qsizetype count, void *dest) noexcept
+{
+ return source != dest ? memcpy(dest, source, size_t(count)) : dest;
+}
+template<> Q_CORE_EXPORT void *qbswap<2>(const void *source, qsizetype count, void *dest) noexcept;
+template<> Q_CORE_EXPORT void *qbswap<4>(const void *source, qsizetype count, void *dest) noexcept;
+template<> Q_CORE_EXPORT void *qbswap<8>(const void *source, qsizetype count, void *dest) noexcept;
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
@@ -172,6 +185,15 @@ template <typename T> inline void qToBigEndian(T src, void *dest)
{ qToUnaligned<T>(src, dest); }
template <typename T> inline void qToLittleEndian(T src, void *dest)
{ qbswap<T>(src, dest); }
+
+template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest)
+{ if (source != dest) memcpy(dest, source, count * sizeof(T)); }
+template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest)
+{ qbswap<sizeof(T)>(source, count, dest); }
+template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest)
+{ if (source != dest) memcpy(dest, source, count * sizeof(T)); }
+template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest)
+{ qbswap<sizeof(T)>(source, count, dest); }
#else // Q_LITTLE_ENDIAN
template <typename T> inline Q_DECL_CONSTEXPR T qToBigEndian(T source)
@@ -187,6 +209,14 @@ template <typename T> inline void qToBigEndian(T src, void *dest)
template <typename T> inline void qToLittleEndian(T src, void *dest)
{ qToUnaligned<T>(src, dest); }
+template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest)
+{ qbswap<sizeof(T)>(source, count, dest); }
+template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest)
+{ if (source != dest) memcpy(dest, source, count * sizeof(T)); }
+template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest)
+{ qbswap<sizeof(T)>(source, count, dest); }
+template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest)
+{ if (source != dest) memcpy(dest, source, count * sizeof(T)); }
#endif // Q_BYTE_ORDER == Q_BIG_ENDIAN
@@ -254,6 +284,27 @@ public:
{ return (*this = S::fromSpecial(val) & i); }
QSpecialInteger &operator ^=(T i)
{ return (*this = S::fromSpecial(val) ^ i); }
+ QSpecialInteger &operator ++()
+ { return (*this = S::fromSpecial(val) + 1); }
+ QSpecialInteger &operator --()
+ { return (*this = S::fromSpecial(val) - 1); }
+ QSpecialInteger operator ++(int)
+ {
+ QSpecialInteger<S> pre = *this;
+ *this += 1;
+ return pre;
+ }
+ QSpecialInteger operator --(int)
+ {
+ QSpecialInteger<S> pre = *this;
+ *this -= 1;
+ return pre;
+ }
+
+ static constexpr QSpecialInteger max()
+ { return QSpecialInteger(std::numeric_limits<T>::max()); }
+ static constexpr QSpecialInteger min()
+ { return QSpecialInteger(std::numeric_limits<T>::min()); }
};
template<typename T>
@@ -291,6 +342,13 @@ public:
QLEInteger &operator |=(T i);
QLEInteger &operator &=(T i);
QLEInteger &operator ^=(T i);
+ QLEInteger &operator ++();
+ QLEInteger &operator --();
+ QLEInteger &operator ++(int);
+ QLEInteger &operator --(int);
+
+ static constexpr QLEInteger max();
+ static constexpr QLEInteger min();
};
template<typename T>
@@ -311,6 +369,13 @@ public:
QBEInteger &operator |=(T i);
QBEInteger &operator &=(T i);
QBEInteger &operator ^=(T i);
+ QBEInteger &operator ++();
+ QBEInteger &operator --();
+ QBEInteger &operator ++(int);
+ QBEInteger &operator --(int);
+
+ static constexpr QBEInteger max();
+ static constexpr QBEInteger min();
};
#else
diff --git a/src/corelib/global/qendian.qdoc b/src/corelib/global/qendian.qdoc
deleted file mode 100644
index 65df25a205..0000000000
--- a/src/corelib/global/qendian.qdoc
+++ /dev/null
@@ -1,554 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \headerfile <QtEndian>
- \title Endian Conversion Functions
- \ingroup funclists
- \brief The <QtEndian> header provides functions to convert between
- little and big endian representations of numbers.
-*/
-
-/*!
- \fn template <typename T> T qFromUnaligned(const void *ptr)
- \internal
- \since 5.5
-
- Loads a \c{T} from address \a ptr, which may be misaligned.
-
- Use of this function avoids the undefined behavior that the C++ standard
- otherwise attributes to unaligned loads.
-*/
-
-/*!
- \fn template <typename T> void qToUnaligned(const T t, void *ptr)
- \internal
- \since 4.5
-
- Stores \a t to address \a ptr, which may be misaligned.
-
- Use of this function avoids the undefined behavior that the C++ standard
- otherwise attributes to unaligned stores.
-*/
-
-
-/*!
- \fn template <typename T> T qFromBigEndian(const void *src)
- \since 4.3
- \relates <QtEndian>
-
- Reads a big-endian number from memory location \a src and returns the number in the
- host byte order representation.
- On CPU architectures where the host byte order is little-endian (such as x86) this
- will swap the byte order; otherwise it will just read from \a src.
-
- \note Template type \c{T} can either be a qint16, qint32 or qint64. Other types of
- integers, e.g., qlong, are not applicable.
-
- \note Since Qt 5.7, the type of the \a src parameter is a void pointer.
-
- There are no data alignment constraints for \a src.
-
- \sa qFromLittleEndian()
- \sa qToBigEndian()
- \sa qToLittleEndian()
-*/
-/*!
- \fn template <typename T> T qFromBigEndian(T src)
- \since 4.3
- \relates <QtEndian>
- \overload
-
- Converts \a src from big-endian byte order and returns the number in host byte order
- representation of that number.
- On CPU architectures where the host byte order is little-endian (such as x86) this
- will return \a src with the byte order swapped; otherwise it will return \a src
- unmodified.
-*/
-/*!
- \fn template <typename T> T qFromLittleEndian(const void *src)
- \since 4.3
- \relates <QtEndian>
-
- Reads a little-endian number from memory location \a src and returns the number in
- the host byte order representation.
- On CPU architectures where the host byte order is big-endian (such as PowerPC) this
- will swap the byte order; otherwise it will just read from \a src.
-
- \note Template type \c{T} can either be a qint16, qint32 or qint64. Other types of
- integers, e.g., qlong, are not applicable.
-
- \note Since Qt 5.7, the type of the \a src parameter is a void pointer.
-
- There are no data alignment constraints for \a src.
-
- \sa qFromBigEndian()
- \sa qToBigEndian()
- \sa qToLittleEndian()
-*/
-/*!
- \fn template <typename T> T qFromLittleEndian(T src)
- \since 4.3
- \relates <QtEndian>
- \overload
-
- Converts \a src from little-endian byte order and returns the number in host byte
- order representation of that number.
- On CPU architectures where the host byte order is big-endian (such as PowerPC) this
- will return \a src with the byte order swapped; otherwise it will return \a src
- unmodified.
-*/
-/*!
- \fn template <typename T> void qToBigEndian(T src, void *dest)
- \since 4.3
- \relates <QtEndian>
-
- Writes the number \a src with template type \c{T} to the memory location at \a dest
- in big-endian byte order.
-
- Note that template type \c{T} can only be an integer data type (signed or unsigned).
-
- There are no data alignment constraints for \a dest.
-
- \note Since Qt 5.7, the type of the \a dest parameter is a void pointer.
-
- \sa qFromBigEndian()
- \sa qFromLittleEndian()
- \sa qToLittleEndian()
-*/
-/*!
- \fn template <typename T> T qToBigEndian(T src)
- \since 4.3
- \relates <QtEndian>
- \overload
-
- Converts \a src from host byte order and returns the number in big-endian byte order
- representation of that number.
- On CPU architectures where the host byte order is little-endian (such as x86) this
- will return \a src with the byte order swapped; otherwise it will return \a src
- unmodified.
-*/
-/*!
- \fn template <typename T> void qToLittleEndian(T src, void *dest)
- \since 4.3
- \relates <QtEndian>
-
- Writes the number \a src with template type \c{T} to the memory location at \a dest
- in little-endian byte order.
-
- Note that template type \c{T} can only be an integer data type (signed or unsigned).
-
- There are no data alignment constraints for \a dest.
-
- \note Since Qt 5.7, the type of the \a dest parameter is a void pointer.
-
- \sa qFromBigEndian()
- \sa qFromLittleEndian()
- \sa qToBigEndian()
-*/
-/*!
- \fn template <typename T> T qToLittleEndian(T src)
- \since 4.3
- \relates <QtEndian>
- \overload
-
- Converts \a src from host byte order and returns the number in little-endian byte
- order representation of that number.
- On CPU architectures where the host byte order is big-endian (such as PowerPC) this
- will return \a src with the byte order swapped; otherwise it will return \a src
- unmodified.
-*/
-
-/*!
- \class QLEInteger
- \inmodule QtCore
- \brief The QLEInteger class provides platform-independent little-endian integers.
- \since 5.10
-
- The template parameter \c T must be a C++ integer type:
- \list
- \li 8-bit: char, signed char, unsigned char, qint8, quint8
- \li 16-bit: short, unsigned short, qint16, quint16, char16_t
- \li 32-bit: int, unsigned int, qint32, quint32, char32_t
- \li 64-bit: long long, unsigned long long, qint64, quint64
- \li platform-specific size: long, unsigned long
- \li pointer size: qintptr, quintptr, qptrdiff
- \endlist
-
- \note Using this class may be slower than using native integers, so only use it when
- an exact endian is needed.
-*/
-
-/*! \fn template <typename T> QLEInteger<T>::QLEInteger(T value)
-
- Constructs a QLEInteger with the given \a value.
-*/
-
-/*! \fn template <typename T> QLEInteger &QLEInteger<T>::operator=(T i)
-
- Assigns \a i to this QLEInteger and returns a reference to
- this QLEInteger.
-*/
-
-/*!
- \fn template <typename T> QLEInteger<T>::operator T() const
-
- Returns the value of this QLEInteger as a native integer.
-*/
-
-/*!
- \fn template <typename T> bool QLEInteger<T>::operator==(QLEInteger other) const
-
- Returns \c true if the value of this QLEInteger is equal to the value of \a other.
-*/
-
-/*!
- \fn template <typename T> bool QLEInteger<T>::operator!=(QLEInteger other) const
-
- Returns \c true if the value of this QLEInteger is not equal to the value of \a other.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator+=(T i)
-
- Adds \a i to this QLEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator-=(T i)
-
- Subtracts \a i from this QLEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator*=(T i)
-
- Multiplies \a i with this QLEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator/=(T i)
-
- Divides this QLEInteger with \a i and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator%=(T i)
-
- Sets this QLEInteger to the remainder of a division by \a i and
- returns a reference to this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator>>=(T i)
-
- Performs a left-shift by \a i on this QLEInteger and returns a
- reference to this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator<<=(T i)
-
- Performs a right-shift by \a i on this QLEInteger and returns a
- reference to this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator|=(T i)
-
- Performs a bitwise OR with \a i onto this QLEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator&=(T i)
-
- Performs a bitwise AND with \a i onto this QLEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QLEInteger &QLEInteger<T>::operator^=(T i)
-
- Performs a bitwise XOR with \a i onto this QLEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \class QBEInteger
- \inmodule QtCore
- \brief The QBEInteger class provides platform-independent big-endian integers.
- \since 5.10
-
- The template parameter \c T must be a C++ integer type:
- \list
- \li 8-bit: char, signed char, unsigned char, qint8, quint8
- \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11)
- \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11)
- \li 64-bit: long long, unsigned long long, qint64, quint64
- \li platform-specific size: long, unsigned long
- \li pointer size: qintptr, quintptr, qptrdiff
- \endlist
-
- \note Using this class may be slower than using native integers, so only use it when
- an exact endian is needed.
-*/
-
-/*! \fn template <typename T> QBEInteger<T>::QBEInteger(T value)
-
- Constructs a QBEInteger with the given \a value.
-*/
-
-/*! \fn template <typename T> QBEInteger &QBEInteger<T>::operator=(T i)
-
- Assigns \a i to this QBEInteger and returns a reference to
- this QBEInteger.
-*/
-
-/*!
- \fn template <typename T> QBEInteger<T>::operator T() const
-
- Returns the value of this QBEInteger as a native integer.
-*/
-
-/*!
- \fn template <typename T> bool QBEInteger<T>::operator==(QBEInteger other) const
-
- Returns \c true if the value of this QBEInteger is equal to the value of \a other.
-*/
-
-/*!
- \fn template <typename T> bool QBEInteger<T>::operator!=(QBEInteger other) const
-
- Returns \c true if the value of this QBEInteger is not equal to the value of \a other.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator+=(T i)
-
- Adds \a i to this QBEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator-=(T i)
-
- Subtracts \a i from this QBEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator*=(T i)
-
- Multiplies \a i with this QBEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator/=(T i)
-
- Divides this QBEInteger with \a i and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator%=(T i)
-
- Sets this QBEInteger to the remainder of a division by \a i and
- returns a reference to this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator>>=(T i)
-
- Performs a left-shift by \a i on this QBEInteger and returns a
- reference to this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator<<=(T i)
-
- Performs a right-shift by \a i on this QBEInteger and returns a
- reference to this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator|=(T i)
-
- Performs a bitwise OR with \a i onto this QBEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator&=(T i)
-
- Performs a bitwise AND with \a i onto this QBEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \fn template <typename T> QBEInteger &QBEInteger<T>::operator^=(T i)
-
- Performs a bitwise XOR with \a i onto this QBEInteger and returns a reference to
- this object.
-*/
-
-/*!
- \typedef quint16_le
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QLEInteger<quint16>. This type is guaranteed to be stored in memory as
- a 16-bit little-endian unsigned integer on all platforms supported by Qt.
-
- \sa quint16
-*/
-
-/*!
- \typedef quint32_le
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QLEInteger<quint32>. This type is guaranteed to be stored in memory as
- a 32-bit little-endian unsigned integer on all platforms supported by Qt.
-
- \sa quint32
-*/
-
-/*!
- \typedef quint64_le
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QLEInteger<quint64>. This type is guaranteed to be stored in memory as
- a 64-bit little-endian unsigned integer on all platforms supported by Qt.
-
- \sa quint64
-*/
-
-/*!
- \typedef quint16_be
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QBEInteger<quint16>. This type is guaranteed to be stored in memory as
- a 16-bit big-endian unsigned integer on all platforms supported by Qt.
-
- \sa quint16
-*/
-
-/*!
- \typedef quint32_be
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QBEInteger<quint32>. This type is guaranteed to be stored in memory as
- a 32-bit big-endian unsigned integer on all platforms supported by Qt.
-
- \sa quint32
-*/
-
-/*!
- \typedef quint64_be
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QBEInteger<quint64>. This type is guaranteed to be stored in memory as
- a 64-bit big-endian unsigned integer on all platforms supported by Qt.
-
- \sa quint64
-*/
-
-/*!
- \typedef qint16_le
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QLEInteger<qint16>. This type is guaranteed to be stored in memory as
- a 16-bit little-endian signed integer on all platforms supported by Qt.
-
- \sa qint16
-*/
-
-/*!
- \typedef qint32_le
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QLEInteger<qint32>. This type is guaranteed to be stored in memory as
- a 32-bit little-endian signed integer on all platforms supported by Qt.
-
- \sa qint32
-*/
-
-/*!
- \typedef qint64_le
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QLEInteger<qint64>. This type is guaranteed to be stored in memory as
- a 64-bit little-endian signed integer on all platforms supported by Qt.
-
- \sa qint64
-*/
-
-/*!
- \typedef qint16_be
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QBEInteger<qint16>. This type is guaranteed to be stored in memory as
- a 16-bit big-endian signed integer on all platforms supported by Qt.
-
- \sa qint16
-*/
-
-/*!
- \typedef qint32_be
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QBEInteger<qint32>. This type is guaranteed to be stored in memory as
- a 32-bit big-endian signed integer on all platforms supported by Qt.
-
- \sa qint32
-*/
-
-/*!
- \typedef qint64_be
- \relates <QtEndian>
- \since 5.10
-
- Typedef for QBEInteger<qint64>. This type is guaranteed to be stored in memory as
- a 64-bit big-endian signed integer on all platforms supported by Qt.
-
- \sa qint64
-*/
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index b30d690025..a369bbe490 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -53,10 +53,6 @@
#include <qmutex.h>
-#ifndef QT_NO_QOBJECT
-#include <private/qthread_p.h>
-#endif
-
#include <stdlib.h>
#include <limits.h>
#include <stdarg.h>
@@ -650,7 +646,8 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
The remaining macros are convenience macros for larger operations:
The QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRANSLATE_NOOP3()
macros provide the possibility of marking strings for delayed
- translation.
+ translation. QT_TR_N_NOOP(), QT_TRANSLATE_N_NOOP(), and
+ QT_TRANSLATE_N_NOOP3() are numerator dependent variants of these.
The Q_ASSERT() and Q_ASSERT_X() enables warning messages of various
level of refinement. The Q_FOREACH() and foreach() macros
implement Qt's foreach loop.
@@ -3450,7 +3447,27 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) Q_DECL_NOEXCEPT
bool ok_ = true;
const char *endptr;
const qlonglong value = qstrtoll(buffer, &endptr, 0, &ok_);
- if (int(value) != value || *endptr != '\0') { // this is the check in QByteArray::toInt(), keep it in sync
+
+ // Keep the following checks in sync with QByteArray::toInt()
+ if (!ok_) {
+ if (ok)
+ *ok = false;
+ return 0;
+ }
+
+ if (*endptr != '\0') {
+ while (ascii_isspace(*endptr))
+ ++endptr;
+ }
+
+ if (*endptr != '\0') {
+ // we stopped at a non-digit character after converting some digits
+ if (ok)
+ *ok = false;
+ return 0;
+ }
+
+ if (int(value) != value) {
if (ok)
*ok = false;
return 0;
@@ -3755,6 +3772,71 @@ bool qunsetenv(const char *varName)
*/
/*!
+ \macro QT_TR_N_NOOP(sourceText)
+ \relates <QtGlobal>
+ \since 5.12
+
+ Marks the UTF-8 encoded string literal \a sourceText for numerator
+ dependent delayed translation in the current context (class).
+
+ The macro tells lupdate to collect the string, and expands to
+ \a sourceText itself.
+
+ The macro expands to \a sourceText.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttrnnoop
+
+ \sa QT_TR_NOOP, {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TRANSLATE_N_NOOP(context, sourceText)
+ \relates <QtGlobal>
+ \since 5.12
+
+ Marks the UTF-8 encoded string literal \a sourceText for numerator
+ dependent delayed translation in the given \a context.
+ The \a context is typically a class name and also needs to be
+ specified as a string literal.
+
+ The macro tells lupdate to collect the string, and expands to
+ \a sourceText itself.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttranslatennoop
+
+ \sa QT_TRANSLATE_NOOP(), QT_TRANSLATE_N_NOOP3(),
+ {Internationalization with Qt}
+*/
+
+/*!
+ \macro QT_TRANSLATE_N_NOOP3(context, sourceText, comment)
+ \relates <QtGlobal>
+ \since 5.12
+
+ Marks the UTF-8 encoded string literal \a sourceText for numerator
+ dependent delayed translation in the given \a context with the given
+ \a comment.
+ The \a context is typically a class and also needs to be specified
+ as a string literal. The string literal \a disambiguation should be
+ a short semantic tag to tell apart otherwise identical strings.
+
+ The macro tells lupdate to collect the string, and expands to an
+ anonymous struct of the two string literals passed as \a sourceText
+ and \a comment.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qttranslatennoop3
+
+ \sa QT_TR_NOOP(), QT_TRANSLATE_NOOP(), QT_TRANSLATE_NOOP3(),
+ {Internationalization with Qt}
+*/
+
+/*!
\fn QString qtTrId(const char *id, int n = -1)
\relates <QtGlobal>
\reentrant
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 3684c6b5de..b608489576 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1034,8 +1034,8 @@ for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \
# endif
#endif
-template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
-template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); }
+template <typename T> inline T *qGetPtrHelper(T *ptr) { return ptr; }
+template <typename Ptr> inline auto qGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
@@ -1064,6 +1064,10 @@ template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelpe
#ifndef QT_NO_TRANSLATION // ### Qt6: This should enclose the NOOPs above
+#define QT_TR_N_NOOP(x) x
+#define QT_TRANSLATE_N_NOOP(scope, x) x
+#define QT_TRANSLATE_N_NOOP3(scope, x, comment) {x, comment}
+
// Defined in qcoreapplication.cpp
// The better name qTrId() is reserved for an upcoming function which would
// return a much more powerful QStringFormatter instead of a QString.
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index 7a6dea9b92..555bdf04c1 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -55,7 +55,7 @@ enum GuardValues {
};
}
-#if defined(QT_NO_THREAD) || defined(Q_COMPILER_THREADSAFE_STATICS)
+#if !QT_CONFIG(thread) || defined(Q_COMPILER_THREADSAFE_STATICS)
// some compilers support thread-safe statics
// The IA-64 C++ ABI requires this, so we know that all GCC versions since 3.4
// support it. C++11 also requires this behavior.
diff --git a/src/corelib/global/qglobalstatic.qdoc b/src/corelib/global/qglobalstatic.qdoc
index 303709bb1d..dbea04ecab 100644
--- a/src/corelib/global/qglobalstatic.qdoc
+++ b/src/corelib/global/qglobalstatic.qdoc
@@ -264,7 +264,7 @@
[stmt.decl], but as of the time of this writing, only compilers based on
the IA-64 C++ ABI implemented it properly. The implementation requiring
thread-safe initialization is also used on the Qt bootstrapped tools, which
- define QT_NO_THREAD.
+ disable the "thread" feature.
The implementation requiring thread-safe initialization from the compiler
is the simplest: it creates the \a Type object as a function-local static
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 7444145e82..9f47b8eb98 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -2,7 +2,7 @@
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -61,6 +61,9 @@
#ifdef Q_OS_WIN
#include <qt_windows.h>
#endif
+#ifdef Q_CC_MSVC
+#include <intrin.h>
+#endif
#if QT_CONFIG(slog2)
#include <sys/slog2.h>
#endif
@@ -91,6 +94,10 @@
# include "private/qcore_unix_p.h"
#endif
+#ifdef Q_OS_WASM
+#include <emscripten/emscripten.h>
+#endif
+
#if QT_CONFIG(regularexpression)
# ifdef __UCLIBC__
# if __UCLIBC_HAS_BACKTRACE__
@@ -240,7 +247,7 @@ static bool systemHasStderr()
\internal
\sa systemHasStderr()
*/
-bool stderrHasConsoleAttached()
+static bool stderrHasConsoleAttached()
{
static const bool stderrHasConsoleAttached = []() -> bool {
if (!systemHasStderr())
@@ -1208,8 +1215,8 @@ void QMessagePattern::setPattern(const QString &pattern)
tokens[i] = backtraceTokenC;
QString backtraceSeparator = QStringLiteral("|");
int backtraceDepth = 5;
- QRegularExpression depthRx(QStringLiteral(" depth=(?|\"([^\"]*)\"|([^ }]*))"));
- QRegularExpression separatorRx(QStringLiteral(" separator=(?|\"([^\"]*)\"|([^ }]*))"));
+ static const QRegularExpression depthRx(QStringLiteral(" depth=(?|\"([^\"]*)\"|([^ }]*))"));
+ static const QRegularExpression separatorRx(QStringLiteral(" separator=(?|\"([^\"]*)\"|([^ }]*))"));
QRegularExpressionMatch m = depthRx.match(lexeme);
if (m.hasMatch()) {
int depth = m.capturedRef(1).toInt();
@@ -1295,8 +1302,7 @@ static QStringList backtraceFramesForLogMessage(int frameCount)
// The offset and function name are optional.
// This regexp tries to extract the library name (without the path) and the function name.
// This code is protected by QMessagePattern::mutex so it is thread safe on all compilers
- static QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"),
- QRegularExpression::OptimizeOnFirstUsageOption);
+ static const QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"));
QVarLengthArray<void*, 32> buffer(8 + frameCount);
int n = backtrace(buffer.data(), buffer.size());
@@ -1688,6 +1694,37 @@ static bool win_message_handler(QtMsgType type, const QMessageLogContext &contex
}
#endif
+#ifdef Q_OS_WASM
+static bool wasm_default_message_handler(QtMsgType type,
+ const QMessageLogContext &context,
+ const QString &message)
+{
+ if (shouldLogToStderr())
+ return false; // Leave logging up to stderr handler
+
+ QString formattedMessage = qFormatLogMessage(type, context, message);
+ int emOutputFlags = (EM_LOG_CONSOLE | EM_LOG_DEMANGLE);
+ QByteArray localMsg = message.toLocal8Bit();
+ switch (type) {
+ case QtDebugMsg:
+ break;
+ case QtInfoMsg:
+ break;
+ case QtWarningMsg:
+ emOutputFlags |= EM_LOG_WARN;
+ break;
+ case QtCriticalMsg:
+ emOutputFlags |= EM_LOG_ERROR;
+ break;
+ case QtFatalMsg:
+ emOutputFlags |= EM_LOG_ERROR;
+ }
+ emscripten_log(emOutputFlags, "%s\n", qPrintable(formattedMessage));
+
+ return true; // Prevent further output to stderr
+}
+#endif
+
#endif // Bootstrap check
// --------------------------------------------------------------------------
@@ -1731,8 +1768,9 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
# elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
handledStderr |= android_default_message_handler(type, context, message);
# elif defined(QT_USE_APPLE_UNIFIED_LOGGING)
- if (__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *))
- handledStderr |= AppleUnifiedLogger::messageHandler(type, context, message);
+ handledStderr |= AppleUnifiedLogger::messageHandler(type, context, message);
+# elif defined Q_OS_WASM
+ handledStderr |= wasm_default_message_handler(type, context, message);
# endif
#endif
@@ -1839,7 +1877,31 @@ static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const
Q_UNUSED(message);
#endif
+#ifdef Q_OS_WIN
+ // std::abort() in the MSVC runtime will call _exit(3) if the abort
+ // behavior is _WRITE_ABORT_MSG - see also _set_abort_behavior(). This is
+ // the default for a debug-mode build of the runtime. Worse, MinGW's
+ // std::abort() implementation (in msvcrt.dll) is basically a call to
+ // _exit(3) too. Unfortunately, _exit() and _Exit() *do* run the static
+ // destructors of objects in DLLs, a violation of the C++ standard (see
+ // [support.start.term]). So we bypass std::abort() and directly
+ // terminate the application.
+
+# ifdef Q_CC_MSVC
+ if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE))
+ __fastfail(FAST_FAIL_FATAL_APP_EXIT);
+# else
+ RaiseFailFastException(nullptr, nullptr, 0);
+# endif
+
+ // Fallback
+ TerminateProcess(GetCurrentProcess(), STATUS_FATAL_APP_EXIT);
+
+ // Tell the compiler the application has stopped.
+ Q_UNREACHABLE_IMPL();
+#else // !Q_OS_WIN
std::abort();
+#endif
}
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 31b1823690..dec2c44637 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -107,6 +107,7 @@ public:
KeyboardModifierMask = 0xfe000000
};
Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardModifiers)
//shorter names for shortcuts
// The use of all-caps identifiers has the potential for clashing with
@@ -163,6 +164,7 @@ public:
MouseButtonMask = 0xffffffff
};
Q_DECLARE_FLAGS(MouseButtons, MouseButton)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(MouseButtons)
enum Orientation {
Horizontal = 0x1,
@@ -170,6 +172,7 @@ public:
};
Q_DECLARE_FLAGS(Orientations, Orientation)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(Orientations)
enum FocusPolicy {
NoFocus = 0,
@@ -225,6 +228,7 @@ public:
};
Q_DECLARE_FLAGS(Alignment, AlignmentFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(Alignment)
enum TextFlag {
TextSingleLine = 0x0100,
@@ -308,6 +312,7 @@ public:
};
Q_DECLARE_FLAGS(WindowFlags, WindowType)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(WindowFlags)
enum WindowState {
WindowNoState = 0x00000000,
@@ -318,6 +323,7 @@ public:
};
Q_DECLARE_FLAGS(WindowStates, WindowState)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(WindowStates)
enum ApplicationState {
ApplicationSuspended = 0x00000000,
@@ -337,6 +343,7 @@ public:
};
Q_DECLARE_FLAGS(ScreenOrientations, ScreenOrientation)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ScreenOrientations)
enum WidgetAttribute {
WA_Disabled = 0,
@@ -479,6 +486,8 @@ public:
WA_ContentsMarginsRespectsSafeArea = 130,
+ WA_StyleSheetTarget = 131,
+
// Add new attributes before this line
WA_AttributeCount
};
@@ -553,6 +562,7 @@ public:
NoFormatConversion = 0x00000200
};
Q_DECLARE_FLAGS(ImageConversionFlags, ImageConversionFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ImageConversionFlags)
enum BGMode {
TransparentMode,
@@ -1210,6 +1220,7 @@ public:
};
Q_DECLARE_FLAGS(DockWidgetAreas, DockWidgetArea)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(DockWidgetAreas)
enum ToolBarArea {
LeftToolBarArea = 0x1,
@@ -1227,6 +1238,7 @@ public:
};
Q_DECLARE_FLAGS(ToolBarAreas, ToolBarArea)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ToolBarAreas)
enum DateFormat {
TextDate, // default Qt
@@ -1285,6 +1297,7 @@ public:
};
Q_DECLARE_FLAGS(Edges, Edge)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(Edges)
enum ConnectionType {
AutoConnection,
@@ -1387,6 +1400,7 @@ public:
ImQueryAll = 0xffffffff
};
Q_DECLARE_FLAGS(InputMethodQueries, InputMethodQuery)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(InputMethodQueries)
enum InputMethodHint {
ImhNone = 0x0,
@@ -1421,6 +1435,7 @@ public:
ImhExclusiveInputMask = 0xffff0000
};
Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(InputMethodHints)
enum EnterKeyType {
EnterKeyDefault,
@@ -1471,6 +1486,7 @@ public:
IgnoreAction = 0x0
};
Q_DECLARE_FLAGS(DropActions, DropAction)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(DropActions)
enum CheckState {
Unchecked,
@@ -1525,6 +1541,7 @@ public:
ItemIsUserTristate = 256
};
Q_DECLARE_FLAGS(ItemFlags, ItemFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(ItemFlags)
enum MatchFlag {
MatchExactly = 0,
@@ -1539,6 +1556,7 @@ public:
MatchRecursive = 64
};
Q_DECLARE_FLAGS(MatchFlags, MatchFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(MatchFlags)
typedef void * HANDLE;
#if QT_DEPRECATED_SINCE(5, 0)
@@ -1563,6 +1581,7 @@ public:
TextBrowserInteraction = TextSelectableByMouse | LinksAccessibleByMouse | LinksAccessibleByKeyboard
};
Q_DECLARE_FLAGS(TextInteractionFlags, TextInteractionFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(TextInteractionFlags)
enum EventPriority {
HighEventPriority = 1,
@@ -1614,6 +1633,7 @@ public:
TouchPointReleased = 0x08
};
Q_DECLARE_FLAGS(TouchPointStates, TouchPointState)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(TouchPointStates)
#ifndef QT_NO_GESTURES
enum GestureState
@@ -1645,6 +1665,7 @@ public:
IgnoredGesturesPropagateToParent = 0x04
};
Q_DECLARE_FLAGS(GestureFlags, GestureFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(GestureFlags)
enum NativeGestureType
{
@@ -1683,7 +1704,8 @@ public:
NoScrollPhase = 0,
ScrollBegin,
ScrollUpdate,
- ScrollEnd
+ ScrollEnd,
+ ScrollMomentum
};
enum MouseEventSource {
@@ -1698,6 +1720,7 @@ public:
MouseEventFlagMask = 0xFF
};
Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag)
+ Q_DECLARE_OPERATORS_FOR_FLAGS(MouseEventFlags)
enum ChecksumType {
ChecksumIso3309,
@@ -1800,29 +1823,6 @@ public:
#undef QT_Q_ENUM
#undef QT_Q_FLAG
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseButtons)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Orientations)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::KeyboardModifiers)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::WindowFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Alignment)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Edges)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ImageConversionFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::DockWidgetAreas)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ToolBarAreas)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::WindowStates)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ScreenOrientations)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::DropActions)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ItemFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodQueries)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates)
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseEventFlags)
-#ifndef QT_NO_GESTURES
-Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::GestureFlags)
-#endif
-
typedef bool (*qInternalCallback)(void **);
class Q_CORE_EXPORT QInternal {
@@ -1864,16 +1864,6 @@ public:
static bool activateCallbacks(Callback, void **);
};
-#if defined(Q_CLANG_QDOC)
-// Declared here for qdoc; actual declarations in qtextdocument.h
-namespace Qt
-{
- bool mightBeRichText(const QString&);
- QString convertFromPlainText(const QString &plain, WhiteSpaceMode mode = WhiteSpacePre);
- QTextCodec *codecForHtml(const QByteArray &ba);
-}
-#endif // Q_CLANG_QDOC
-
QT_END_NAMESPACE
#endif // QNAMESPACE_H
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index d6191d1585..42009e0b5e 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -245,7 +245,10 @@
QEvent::MouseMove, QEvent::TouchUpdate, and changes in window size and
position will be combined whenever they occur more frequently than the
application handles them, so that they don't accumulate and overwhelm the
- application later. On other platforms, the default is false.
+ application later.
+ On Windows 8 and above the default value is also true, but it only applies
+ to touch events. Mouse and window events remain unaffected by this flag.
+ On other platforms, the default is false.
(In the future, the compression feature may be implemented across platforms.)
You can test the attribute to see whether compression is enabled.
If your application needs to handle all events with no compression,
@@ -256,8 +259,9 @@
\value AA_CompressTabletEvents Enables compression of input events from tablet devices.
Notice that AA_CompressHighFrequencyEvents must be true for events compression
- to be enabled, and that this flag extends the former to tablet events. Its default
- value is false.
+ to be enabled, and that this flag extends the former to tablet events.
+ Currently supported on the X11 windowing system, Windows 8 and above.
+ The default value is false.
This value was added in Qt 5.10.
\value AA_DontCheckOpenGLContextThreadAffinity When making a context
@@ -383,7 +387,8 @@
\value AltModifier An Alt key on the keyboard is pressed.
\value MetaModifier A Meta key on the keyboard is pressed.
\value KeypadModifier A keypad button is pressed.
- \value GroupSwitchModifier X11 only. A Mode_switch key on the keyboard is pressed.
+ \value GroupSwitchModifier X11 only (unless activated on Windows by a command line argument).
+ A Mode_switch key on the keyboard is pressed.
\omitvalue KeyboardModifierMask
@@ -1155,7 +1160,12 @@
the widget's author.
\value WA_StyleSheet Indicates that the widget is styled using a
- \l{Qt Style Sheets}{style sheet}.
+ \l{Qt Style Sheets}{style sheet}. WA_StyleSheet is set whenever a widget
+ is subject to a style sheet, even if the style sheet did not affect the
+ widget appearance.
+
+ \value WA_StyleSheetTarget Indicates that the widget appearance was modified
+ by a \l{Qt Style Sheets}{style sheet}. WA_StyleSheet will also be set.
\value WA_TabletTracking Indicates that the widget has tablet
tracking enabled. See QWidget::tabletTracking.
@@ -3232,37 +3242,3 @@
\value ChecksumItuV41 Checksum calculation based on ITU-V.41.
*/
-
-/*!
- \fn bool Qt::mightBeRichText(const QString& text)
-
- Returns \c true if the string \a text is likely to be rich text;
- otherwise returns \c false.
-
- This function uses a fast and therefore simple heuristic. It
- mainly checks whether there is something that looks like a tag
- before the first line break. Although the result may be correct
- for common cases, there is no guarantee.
-
- This function is defined in the \c <QTextDocument> header file.
-*/
-
-/*!
- \fn QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode)
-
- Converts the plain text string \a plain to an HTML-formatted
- paragraph while preserving most of its look.
-
- \a mode defines how whitespace is handled.
-
- This function is defined in the \c <QTextDocument> header file.
-
- \sa escape(), mightBeRichText()
-*/
-
-/*!
- \fn QTextCodec *Qt::codecForHtml(const QByteArray &ba)
- \internal
-
- This function is defined in the \c <QTextDocument> header file.
-*/
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index 5f8a124bcc..9c8514f5a3 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -163,6 +163,58 @@ Q_DECL_CONST_FUNCTION static inline bool qt_is_finite(float f)
#ifndef Q_CLANG_QDOC
namespace {
+/*!
+ Returns true if the double \a v can be converted to type \c T, false if
+ it's out of range. If the conversion is successful, the converted value is
+ stored in \a value; if it was not successful, \a value will contain the
+ minimum or maximum of T, depending on the sign of \a d. If \c T is
+ unsigned, then \a value contains the absolute value of \a v.
+
+ This function works for v containing infinities, but not NaN. It's the
+ caller's responsibility to exclude that possibility before calling it.
+*/
+template <typename T> static inline bool convertDoubleTo(double v, T *value)
+{
+ Q_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
+
+ // The [conv.fpint] (7.10 Floating-integral conversions) section of the C++
+ // standard says only exact conversions are guaranteed. Converting
+ // integrals to floating-point with loss of precision has implementation-
+ // defined behavior whether the next higher or next lower is returned;
+ // converting FP to integral is UB if it can't be represented.
+ //
+ // That means we can't write UINT64_MAX+1. Writing ldexp(1, 64) would be
+ // correct, but Clang, ICC and MSVC don't realize that it's a constant and
+ // the math call stays in the compiled code.
+
+ double supremum;
+ if (std::numeric_limits<T>::is_signed) {
+ supremum = -1.0 * std::numeric_limits<T>::min(); // -1 * (-2^63) = 2^63, exact (for T = qint64)
+ *value = std::numeric_limits<T>::min();
+ if (v < std::numeric_limits<T>::min())
+ return false;
+ } else {
+ using ST = typename std::make_signed<T>::type;
+ supremum = -2.0 * std::numeric_limits<ST>::min(); // -2 * (-2^63) = 2^64, exact (for T = quint64)
+ v = fabs(v);
+ }
+
+ *value = std::numeric_limits<T>::max();
+ if (v >= supremum)
+ return false;
+
+ // Now we can convert, these two conversions cannot be UB
+ *value = T(v);
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
+
+ return *value == v;
+
+QT_WARNING_POP
+}
+
// Overflow math.
// This provides efficient implementations for int, unsigned, qsizetype and
// size_t. Implementations for 8- and 16-bit types will work but may not be as
diff --git a/src/corelib/global/qoperatingsystemversion_win.cpp b/src/corelib/global/qoperatingsystemversion_win.cpp
index 7659fb2550..2da190da48 100644
--- a/src/corelib/global/qoperatingsystemversion_win.cpp
+++ b/src/corelib/global/qoperatingsystemversion_win.cpp
@@ -103,7 +103,7 @@ static inline OSVERSIONINFOEX determineWinOsVersion()
// GetVersionEx() has been deprecated in Windows 8.1 and will return
// only Windows 8 from that version on, so use the kernel API function.
- pRtlGetVersion((LPOSVERSIONINFO) &result); // always returns STATUS_SUCCESS
+ pRtlGetVersion(reinterpret_cast<LPOSVERSIONINFO>(&result)); // always returns STATUS_SUCCESS
#else // !Q_OS_WINCE
GetVersionEx(&result);
#endif
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index 0b260d01e3..aaa27dff4a 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -57,7 +57,7 @@
optional and usually dependent on how the compiler was invoked. Variants
that are a superset of another should have a define for the superset.
- In addition to the procesor family, variants, and revisions, we also set
+ In addition to the processor family, variants, and revisions, we also set
Q_BYTE_ORDER appropriately for the target processor. For bi-endian
processors, we try to auto-detect the byte order using the __BIG_ENDIAN__,
__LITTLE_ENDIAN__, or __BYTE_ORDER__ preprocessor macros.
@@ -320,6 +320,12 @@
# endif
# define Q_BYTE_ORDER Q_BIG_ENDIAN
+// -- Web Assembly --
+#elif defined(__EMSCRIPTEN__)
+# define Q_PROCESSOR_WASM
+# define Q_PROCESSOR_X86 6 // enables SIMD support
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+# define Q_PROCESSOR_WORDSIZE 8
#endif
/*
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index ebf9864b15..a7d4aa303a 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -527,7 +527,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\code
QRandomGenerator prng1(1234), prng2(1234);
- Q_ASSERT(prng1.generate32() == prng2.generate32());
+ Q_ASSERT(prng1.generate() == prng2.generate());
Q_ASSERT(prng1.generate64() == prng2.generate64());
\endcode
@@ -553,8 +553,8 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
be easily used, as in the following example:
\code
- int x = QRandomGenerator::global()->generate32();
- int y = QRandomGenerator::global()->generate32();
+ int x = QRandomGenerator::global()->generate();
+ int y = QRandomGenerator::global()->generate();
int w = QRandomGenerator::global()->bounded(16384);
int h = QRandomGenerator::global()->bounded(16384);
\endcode
@@ -1298,7 +1298,7 @@ struct QRandEngine
};
}
-#if defined(QT_NO_THREAD) || defined(Q_OS_WIN)
+#if defined(Q_OS_WIN)
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
static inline QRandEngine *randTLS()
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index cacb95b674..aabe46f3c2 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -137,6 +137,8 @@
# define Q_OS_HPUX
#elif defined(__native_client__)
# define Q_OS_NACL
+#elif defined(__EMSCRIPTEN__)
+# define Q_OS_WASM
#elif defined(__linux__) || defined(__linux)
# define Q_OS_LINUX
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
diff --git a/src/corelib/global/qtrace_p.h b/src/corelib/global/qtrace_p.h
index ab8fc14af5..3d04a7311d 100644
--- a/src/corelib/global/qtrace_p.h
+++ b/src/corelib/global/qtrace_p.h
@@ -109,6 +109,8 @@
* qcoreapplication_baz above.
*/
+#include <QtCore/qglobal.h>
+
QT_BEGIN_NAMESPACE
#if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
diff --git a/src/corelib/global/qversiontagging.cpp b/src/corelib/global/qversiontagging.cpp
index cbfd93f135..b5e524bf4c 100644
--- a/src/corelib/global/qversiontagging.cpp
+++ b/src/corelib/global/qversiontagging.cpp
@@ -93,7 +93,16 @@ make_versioned_symbol(SYM, QT_VERSION_MAJOR, 11, "@");
make_versioned_symbol(SYM, QT_VERSION_MAJOR, 12, "@");
#endif
#if QT_VERSION_MINOR > 13
-// We don't expect there will be a Qt 5.13
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 13, "@");
+#endif
+#if QT_VERSION_MINOR > 14
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 14, "@");
+#endif
+#if QT_VERSION_MINOR > 15
+make_versioned_symbol(SYM, QT_VERSION_MAJOR, 15, "@");
+#endif
+#if QT_VERSION_MINOR > 16
+// We don't expect there will be a Qt 5.17
# error "Please update this file with more Qt versions."
#endif
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 013d531581..2e825d2373 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -939,14 +939,18 @@ void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value)
QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *meta, const char *name)
{
QDebugStateSaver saver(dbg);
+ dbg.nospace();
QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
const char *key = me.valueToKey(value);
- dbg.nospace() << meta->className() << "::" << name << '(';
- if (key)
+ if (key) {
+ if (const char *scope = me.scope())
+ dbg << scope << "::";
+ if (me.isScoped())
+ dbg << me.enumName() << "::";
dbg << key;
- else
- dbg << value;
- dbg << ')';
+ } else {
+ dbg << meta->className() << "::" << name << "(" << value << ")";
+ }
return dbg;
}
@@ -960,7 +964,7 @@ QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaO
const QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name));
if (const char *scope = me.scope())
debug << scope << "::";
- debug << me.name() << ">(" << me.valueToKeys(value) << ')';
+ debug << me.enumName() << ">(" << me.valueToKeys(value) << ')';
return debug;
}
#endif // !QT_NO_QOBJECT
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index ee8ef679a9..ae1869f89e 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -376,6 +376,19 @@ operator<<(QDebug dbg, T value)
return qt_QMetaEnum_debugOperator(dbg, typename QFlags<T>::Int(value), obj, name);
}
+template<typename T,
+ typename A = typename std::enable_if<std::is_enum<T>::value, void>::type,
+ typename B = typename std::enable_if<sizeof(T) <= sizeof(int), void>::type,
+ typename C = typename std::enable_if<!QtPrivate::IsQEnumHelper<T>::Value, void>::type,
+ typename D = typename std::enable_if<QtPrivate::IsQEnumHelper<QFlags<T>>::Value, void>::type>
+inline QDebug operator<<(QDebug dbg, T value)
+{
+ typedef QFlags<T> FlagsT;
+ const QMetaObject *obj = qt_getEnumMetaObject(FlagsT());
+ const char *name = qt_getEnumName(FlagsT());
+ return qt_QMetaEnum_debugOperator(dbg, typename FlagsT::Int(value), obj, name);
+}
+
template <class T>
inline typename std::enable_if<
QtPrivate::IsQEnumHelper<T>::Value || QtPrivate::IsQEnumHelper<QFlags<T> >::Value,
diff --git a/src/corelib/io/qdebug_p.h b/src/corelib/io/qdebug_p.h
index a1887655d2..dcb906d156 100644
--- a/src/corelib/io/qdebug_p.h
+++ b/src/corelib/io/qdebug_p.h
@@ -93,7 +93,7 @@ static inline void formatQEnum(QDebug &debug, QEnum value)
{
const QMetaObject *metaObject = qt_getEnumMetaObject(value);
const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(value)));
- if (const char *key = me.valueToKey(value))
+ if (const char *key = me.valueToKey(int(value)))
debug << key;
else
debug << int(value);
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 10aee73a2f..39422c3401 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -48,7 +48,9 @@
#include "qdiriterator.h"
#include "qdatetime.h"
#include "qstring.h"
-#include "qregexp.h"
+#if QT_CONFIG(regularexpression)
+# include <qregularexpression.h>
+#endif
#include "qvector.h"
#include "qvarlengtharray.h"
#include "qfilesystementry_p.h"
@@ -1038,7 +1040,7 @@ QStringList QDir::nameFilters() const
list of filters specified by \a nameFilters.
Each name filter is a wildcard (globbing) filter that understands
- \c{*} and \c{?} wildcards. (See \l{QRegExp wildcard matching}.)
+ \c{*} and \c{?} wildcards. (See \l{QRegularExpression wildcard matching}.)
For example, the following code sets three name filters on a QDir
to ensure that only files with extensions typically used for C++
@@ -2059,7 +2061,7 @@ QString QDir::homePath()
Returns the system's temporary directory.
- The directory is constructed using the absolute path of the temporary directory,
+ The directory is constructed using the absolute canonical path of the temporary directory,
ensuring that its path() will be the same as its absolutePath().
See tempPath() for details.
@@ -2068,7 +2070,7 @@ QString QDir::homePath()
*/
/*!
- Returns the absolute path of the system's temporary directory.
+ Returns the absolute canonical path of the system's temporary directory.
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
@@ -2110,7 +2112,7 @@ QString QDir::rootPath()
return QFileSystemEngine::rootPath();
}
-#ifndef QT_NO_REGEXP
+#if QT_CONFIG(regularexpression)
/*!
\overload
@@ -2118,13 +2120,18 @@ QString QDir::rootPath()
patterns in the list of \a filters; otherwise returns \c false. The
matching is case insensitive.
- \sa {QRegExp wildcard matching}, QRegExp::exactMatch(), entryList(), entryInfoList()
+ \sa {QRegularExpression Wildcard matching}, QRegularExpression::wildcardToRegularExpression(),
+ entryList(), entryInfoList()
*/
bool QDir::match(const QStringList &filters, const QString &fileName)
{
for (QStringList::ConstIterator sit = filters.constBegin(); sit != filters.constEnd(); ++sit) {
- QRegExp rx(*sit, Qt::CaseInsensitive, QRegExp::Wildcard);
- if (rx.exactMatch(fileName))
+ QString wildcard = QRegularExpression::wildcardToRegularExpression(*sit);
+ // Insensitive exact match
+ // (see Notes for QRegExp Users in QRegularExpression's documentation)
+ QRegularExpression rx(QRegularExpression::anchoredPattern(wildcard),
+ QRegularExpression::CaseInsensitiveOption);
+ if (rx.match(fileName).hasMatch())
return true;
}
return false;
@@ -2136,13 +2143,14 @@ bool QDir::match(const QStringList &filters, const QString &fileName)
contain multiple patterns separated by spaces or semicolons.
The matching is case insensitive.
- \sa {QRegExp wildcard matching}, QRegExp::exactMatch(), entryList(), entryInfoList()
+ \sa {QRegularExpression wildcard matching}, QRegularExpression::wildcardToRegularExpression,
+ entryList(), entryInfoList()
*/
bool QDir::match(const QString &filter, const QString &fileName)
{
return match(nameFiltersFromString(filter), fileName);
}
-#endif // QT_NO_REGEXP
+#endif // QT_CONFIG(regularexpression)
/*!
\internal
diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h
index 950a26f327..45c59d9e1d 100644
--- a/src/corelib/io/qdir.h
+++ b/src/corelib/io/qdir.h
@@ -206,7 +206,7 @@ public:
static inline QDir temp() { return QDir(tempPath()); }
static QString tempPath();
-#ifndef QT_NO_REGEXP
+#if QT_CONFIG(regularexpression)
static bool match(const QStringList &filters, const QString &fileName);
static bool match(const QString &filter, const QString &fileName);
#endif
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index deb4a9f220..0159bc4128 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -76,9 +76,7 @@
#endif
#if defined(Q_OS_DARWIN)
-# if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(101200, 100000, 100000, 30000)
-# include <sys/clonefile.h>
-# endif
+# include <sys/clonefile.h>
# include <copyfile.h>
// We cannot include <Foundation/Foundation.h> (it's an Objective-C header), but
// we need these declarations:
@@ -774,7 +772,7 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
QString canonicalPath = QDir::cleanPath(QFile::decodeName(ret));
free(ret);
return QFileSystemEntry(canonicalPath);
- } else if (errno == ENOENT) { // file doesn't exist
+ } else if (errno == ENOENT || errno == ENOTDIR) { // file doesn't exist
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
data.entryFlags &= ~(QFileSystemMetaData::ExistsAttribute);
return QFileSystemEntry();
@@ -853,16 +851,16 @@ QByteArray QFileSystemEngine::id(int id)
//static
QString QFileSystemEngine::resolveUserName(uint userId)
{
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
int size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
if (size_max == -1)
size_max = 1024;
QVarLengthArray<char, 1024> buf(size_max);
#endif
-#if !defined(Q_OS_INTEGRITY)
+#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_WASM)
struct passwd *pw = 0;
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS)
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS)
struct passwd entry;
getpwuid_r(userId, &entry, buf.data(), buf.size(), &pw);
#else
@@ -877,16 +875,16 @@ QString QFileSystemEngine::resolveUserName(uint userId)
//static
QString QFileSystemEngine::resolveGroupName(uint groupId)
{
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
int size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
if (size_max == -1)
size_max = 1024;
QVarLengthArray<char, 1024> buf(size_max);
#endif
-#if !defined(Q_OS_INTEGRITY)
+#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_WASM)
struct group *gr = 0;
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID) && (__ANDROID_API__ >= 24))
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID) && (__ANDROID_API__ >= 24))
size_max = sysconf(_SC_GETGR_R_SIZE_MAX);
if (size_max == -1)
size_max = 1024;
@@ -1258,20 +1256,18 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy
//static
bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
-#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(101200, 100000, 100000, 30000)
- if (__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) {
- if (::clonefile(source.nativeFilePath().constData(),
- target.nativeFilePath().constData(), 0) == 0)
- return true;
- error = QSystemError(errno, QSystemError::StandardLibraryError);
- return false;
- }
+#if defined(Q_OS_DARWIN)
+ if (::clonefile(source.nativeFilePath().constData(),
+ target.nativeFilePath().constData(), 0) == 0)
+ return true;
+ error = QSystemError(errno, QSystemError::StandardLibraryError);
+ return false;
#else
Q_UNUSED(source);
Q_UNUSED(target);
-#endif
error = QSystemError(ENOSYS, QSystemError::StandardLibraryError); //Function not implemented
return false;
+#endif
}
//static
@@ -1295,13 +1291,11 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy
}
#endif
#if defined(Q_OS_DARWIN) && defined(RENAME_EXCL)
- if (__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) {
- if (renameatx_np(AT_FDCWD, srcPath, AT_FDCWD, tgtPath, RENAME_EXCL) == 0)
- return true;
- if (errno != ENOTSUP) {
- error = QSystemError(errno, QSystemError::StandardLibraryError);
- return false;
- }
+ if (renameatx_np(AT_FDCWD, srcPath, AT_FDCWD, tgtPath, RENAME_EXCL) == 0)
+ return true;
+ if (errno != ENOTSUP) {
+ error = QSystemError(errno, QSystemError::StandardLibraryError);
+ return false;
}
#endif
@@ -1524,7 +1518,7 @@ QString QFileSystemEngine::tempPath()
temp = QLatin1String(_PATH_TMP);
}
}
- return QDir::cleanPath(temp);
+ return QDir(QDir::cleanPath(temp)).canonicalPath();
#endif
}
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index fadc058110..74081b4ffa 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -935,7 +935,7 @@ static bool tryFindFallback(const QFileSystemEntry &fname, QFileSystemMetaData &
bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data,
QFileSystemMetaData::MetaDataFlags what)
{
- HANDLE fHandle = (HANDLE)_get_osfhandle(fd);
+ auto fHandle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
if (fHandle != INVALID_HANDLE_VALUE) {
return fillMetaData(fHandle, data, what);
}
@@ -1014,7 +1014,8 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
WIN32_FIND_DATA findData;
// The memory structure for WIN32_FIND_DATA is same as WIN32_FILE_ATTRIBUTE_DATA
// for all members used by fillFindData().
- bool ok = ::GetFileAttributesEx((wchar_t*)fname.nativeFilePath().utf16(), GetFileExInfoStandard,
+ bool ok = ::GetFileAttributesEx(reinterpret_cast<const wchar_t*>(fname.nativeFilePath().utf16()),
+ GetFileExInfoStandard,
reinterpret_cast<WIN32_FILE_ATTRIBUTE_DATA *>(&findData));
if (ok) {
data.fillFromFindData(findData, false, fname.isDriveRoot());
@@ -1069,19 +1070,22 @@ static bool isDirPath(const QString &dirPath, bool *existed)
if (path.length() == 2 && path.at(1) == QLatin1Char(':'))
path += QLatin1Char('\\');
+ const QString longPath = QFSFileEnginePrivate::longFileName(path);
#ifndef Q_OS_WINRT
- DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16());
+ DWORD fileAttrib = ::GetFileAttributes(reinterpret_cast<const wchar_t*>(longPath.utf16()));
#else // Q_OS_WINRT
DWORD fileAttrib = INVALID_FILE_ATTRIBUTES;
WIN32_FILE_ATTRIBUTE_DATA data;
- if (::GetFileAttributesEx((const wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), GetFileExInfoStandard, &data))
+ if (::GetFileAttributesEx(reinterpret_cast<const wchar_t*>(longPath.utf16()),
+ GetFileExInfoStandard, &data)) {
fileAttrib = data.dwFileAttributes;
+ }
#endif // Q_OS_WINRT
if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
int errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
WIN32_FIND_DATA findData;
- if (getFindData(QFSFileEnginePrivate::longFileName(path), findData))
+ if (getFindData(longPath, findData))
fileAttrib = findData.dwFileAttributes;
}
}
@@ -1411,7 +1415,7 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per
if (mode == 0) // not supported
return false;
- bool ret = (::_wchmod((wchar_t*)entry.nativeFilePath().utf16(), mode) == 0);
+ bool ret = ::_wchmod(reinterpret_cast<const wchar_t*>(entry.nativeFilePath().utf16()), mode) == 0;
if(!ret)
error = QSystemError(errno, QSystemError::StandardLibraryError);
return ret;
diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp
index 2905a8e54e..6741282881 100644
--- a/src/corelib/io/qfilesystemiterator_win.cpp
+++ b/src/corelib/io/qfilesystemiterator_win.cpp
@@ -106,8 +106,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa
QLatin1String("\\\\") + parts.at(2), &uncShares)) {
if (uncShares.isEmpty())
return false; // No shares found in the server
- else
- uncFallback = true;
+ uncFallback = true;
}
}
}
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index 0254d0f7a1..f68fb67d79 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -499,7 +499,7 @@ bool QFseventsFileSystemWatcherEngine::startStream()
DEBUG() << "Starting stream with paths" << watchingState.watchedPaths.keys();
- NSMutableArray *pathsToWatch = [NSMutableArray arrayWithCapacity:watchingState.watchedPaths.size()];
+ NSMutableArray<NSString *> *pathsToWatch = [NSMutableArray<NSString *> arrayWithCapacity:watchingState.watchedPaths.size()];
for (PathRefCounts::const_iterator i = watchingState.watchedPaths.begin(), ei = watchingState.watchedPaths.end(); i != ei; ++i)
[pathsToWatch addObject:i.key().toNSString()];
diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp
index 9e43d11e71..91d0f7a228 100644
--- a/src/corelib/io/qfilesystemwatcher_win.cpp
+++ b/src/corelib/io/qfilesystemwatcher_win.cpp
@@ -57,6 +57,7 @@
# include <qcoreapplication.h>
# include <qdir.h>
# include <private/qeventdispatcher_win_p.h>
+# include <private/qthread_p.h>
# include <dbt.h>
# include <algorithm>
# include <vector>
@@ -308,7 +309,8 @@ void QWindowsRemovableDriveListener::addPath(const QString &p)
notify.dbch_size = sizeof(notify);
notify.dbch_devicetype = DBT_DEVTYP_HANDLE;
notify.dbch_handle = volumeHandle;
- QEventDispatcherWin32 *winEventDispatcher = static_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
+ QThreadData *currentData = QThreadData::current();
+ QEventDispatcherWin32 *winEventDispatcher = static_cast<QEventDispatcherWin32 *>(currentData->ensureEventDispatcher());
re.devNotify = RegisterDeviceNotification(winEventDispatcher->internalHwnd(),
&notify, DEVICE_NOTIFY_WINDOW_HANDLE);
// Empirically found: The notifications also work when the handle is immediately
@@ -665,7 +667,8 @@ void QWindowsFileSystemWatcherEngineThread::run()
if (m != '@')
DEBUG() << "QWindowsFileSystemWatcherEngine: unknown message sent to thread: " << char(m);
break;
- } else if (r > WAIT_OBJECT_0 && r < WAIT_OBJECT_0 + uint(handlesCopy.count())) {
+ }
+ if (r > WAIT_OBJECT_0 && r < WAIT_OBJECT_0 + uint(handlesCopy.count())) {
int at = r - WAIT_OBJECT_0;
Q_ASSERT(at < handlesCopy.count());
HANDLE handle = handlesCopy.at(at);
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index bbd262e2f9..90ad0126d6 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -82,12 +82,11 @@ static inline int openModeToOpenFlags(QIODevice::OpenMode mode)
if (QFSFileEnginePrivate::openModeCanCreate(mode))
oflags |= QT_OPEN_CREAT;
- if (mode & QFile::Append) {
+ if (mode & QFile::Truncate)
+ oflags |= QT_OPEN_TRUNC;
+
+ if (mode & QFile::Append)
oflags |= QT_OPEN_APPEND;
- } else if (mode & QFile::WriteOnly) {
- if ((mode & QFile::Truncate) || !(mode & QFile::ReadOnly))
- oflags |= QT_OPEN_TRUNC;
- }
if (mode & QFile::NewOnly)
oflags |= QT_OPEN_EXCL;
@@ -531,29 +530,32 @@ QByteArray QFSFileEngine::id() const
QString QFSFileEngine::fileName(FileName file) const
{
Q_D(const QFSFileEngine);
- if (file == BundleName) {
+ switch (file) {
+ case BundleName:
return QFileSystemEngine::bundleName(d->fileEntry);
- } else if (file == BaseName) {
+ case BaseName:
return d->fileEntry.fileName();
- } else if (file == PathName) {
+ case PathName:
return d->fileEntry.path();
- } else if (file == AbsoluteName || file == AbsolutePathName) {
+ case AbsoluteName:
+ case AbsolutePathName: {
QFileSystemEntry entry(QFileSystemEngine::absoluteName(d->fileEntry));
- if (file == AbsolutePathName) {
- return entry.path();
- }
- return entry.filePath();
- } else if (file == CanonicalName || file == CanonicalPathName) {
+ return file == AbsolutePathName ? entry.path() : entry.filePath();
+ }
+ case CanonicalName:
+ case CanonicalPathName: {
QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry, d->metaData));
- if (file == CanonicalPathName)
- return entry.path();
- return entry.filePath();
- } else if (file == LinkName) {
+ return file == CanonicalPathName ? entry.path() : entry.filePath();
+ }
+ case LinkName:
if (d->isSymlink()) {
QFileSystemEntry entry = QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData);
return entry.filePath();
}
return QString();
+ case DefaultName:
+ case NFileNames:
+ break;
}
return d->fileEntry.filePath();
}
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 8199f6a846..c1b8f00b4a 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -45,7 +45,6 @@
#include "qfile.h"
#include "qdir.h"
-#include "private/qmutexpool_p.h"
#include "qvarlengtharray.h"
#include "qdatetime.h"
#include "qt_windows.h"
@@ -591,7 +590,6 @@ bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) cons
bool QFSFileEngine::link(const QString &newName)
{
#if !defined(Q_OS_WINRT)
-# if QT_CONFIG(library)
bool ret = false;
QString linkName = newName;
@@ -600,23 +598,27 @@ bool QFSFileEngine::link(const QString &newName)
IShellLink *psl;
bool neededCoInit = false;
- HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void **>(&psl));
if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
neededCoInit = true;
- CoInitialize(NULL);
- hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
+ CoInitialize(nullptr);
+ hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void **>(&psl));
}
if (SUCCEEDED(hres)) {
- hres = psl->SetPath((wchar_t *)fileName(AbsoluteName).replace(QLatin1Char('/'), QLatin1Char('\\')).utf16());
+ const QString nativeAbsoluteName = fileName(AbsoluteName).replace(QLatin1Char('/'), QLatin1Char('\\'));
+ hres = psl->SetPath(reinterpret_cast<const wchar_t *>(nativeAbsoluteName.utf16()));
if (SUCCEEDED(hres)) {
- hres = psl->SetWorkingDirectory((wchar_t *)fileName(AbsolutePathName).replace(QLatin1Char('/'), QLatin1Char('\\')).utf16());
+ const QString nativeAbsolutePathName = fileName(AbsolutePathName).replace(QLatin1Char('/'), QLatin1Char('\\'));
+ hres = psl->SetWorkingDirectory(reinterpret_cast<const wchar_t *>(nativeAbsolutePathName.utf16()));
if (SUCCEEDED(hres)) {
IPersistFile *ppf;
- hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
+ hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void **>(&ppf));
if (SUCCEEDED(hres)) {
- hres = ppf->Save((wchar_t*)linkName.utf16(), TRUE);
+ hres = ppf->Save(reinterpret_cast<const wchar_t *>(linkName.utf16()), TRUE);
if (SUCCEEDED(hres))
ret = true;
ppf->Release();
@@ -632,10 +634,6 @@ bool QFSFileEngine::link(const QString &newName)
CoUninitialize();
return ret;
-# else // QT_CONFIG(library)
- Q_UNUSED(newName);
- return false;
-# endif // QT_CONFIG(library)
#else // !Q_OS_WINRT
Q_UNUSED(newName);
Q_UNIMPLEMENTED();
@@ -768,10 +766,9 @@ QString QFSFileEngine::fileName(FileName file) const
int slash = ret.lastIndexOf(QLatin1Char('/'));
if (slash < 0)
return ret;
- else if (ret.at(0) != QLatin1Char('/') && slash == 2)
+ if (ret.at(0) != QLatin1Char('/') && slash == 2)
return ret.left(3); // include the slash
- else
- return ret.left(slash > 0 ? slash : 1);
+ return ret.left(slash > 0 ? slash : 1);
}
return ret;
} else if (file == CanonicalName || file == CanonicalPathName) {
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 95a5fb27cf..5dd5f8031e 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -312,8 +312,9 @@ QIODevicePrivate::~QIODevicePrivate()
\value NotOpen The device is not open.
\value ReadOnly The device is open for reading.
- \value WriteOnly The device is open for writing. Note that this mode implies
- Truncate.
+ \value WriteOnly The device is open for writing. Note that, for file-system
+ subclasses (e.g. QFile), this mode implies Truncate unless
+ combined with ReadOnly, Append or NewOnly.
\value ReadWrite The device is open for reading and writing.
\value Append The device is opened in append mode so that all data is
written to the end of the file.
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index cd97268d71..9792d956cc 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -46,6 +46,11 @@
#include <QtCore/qdir.h>
#include <QtCore/qcoreapplication.h>
+#if QT_CONFIG(settings)
+#include <QtCore/qsettings.h>
+#include <QtCore/private/qsettings_p.h>
+#endif
+
// We can't use the default macros because this would lead to recursion.
// Instead let's define our own one that unconditionally logs...
#define debugMsg QMessageLogger(__FILE__, __LINE__, __FUNCTION__, "qt.core.logging").debug
@@ -230,7 +235,14 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line)
int equalPos = line.indexOf(QLatin1Char('='));
if (equalPos != -1) {
if (line.lastIndexOf(QLatin1Char('=')) == equalPos) {
- const auto pattern = line.left(equalPos).trimmed();
+ const auto key = line.left(equalPos).trimmed();
+#if QT_CONFIG(settings)
+ QString tmp;
+ QSettingsPrivate::iniUnescapedKey(key.toUtf8(), 0, key.length(), tmp);
+ QStringRef pattern = QStringRef(&tmp, 0, tmp.length());
+#else
+ QStringRef pattern = key;
+#endif
const auto valueStr = line.mid(equalPos + 1).trimmed();
int value = -1;
if (valueStr == QLatin1String("true"))
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 713af9bd40..7a2daa2a57 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -101,7 +101,6 @@ QT_END_NAMESPACE
#include <qdir.h>
#include <qlist.h>
#include <qmutex.h>
-#include <qsemaphore.h>
#include <qsocketnotifier.h>
#include <qthread.h>
#include <qelapsedtimer.h>
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 8c4e5b41b4..cb4b2f9f91 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -149,7 +149,26 @@ static void qt_create_pipe(Q_PIPE *pipe, bool isInputPipe)
}
// Wait until connection is in place.
- ConnectNamedPipe(hServer, NULL);
+ OVERLAPPED overlapped;
+ ZeroMemory(&overlapped, sizeof(overlapped));
+ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (ConnectNamedPipe(hServer, &overlapped) == 0) {
+ DWORD dwError = GetLastError();
+ switch (dwError) {
+ case ERROR_PIPE_CONNECTED:
+ break;
+ case ERROR_IO_PENDING:
+ WaitForSingleObject(overlapped.hEvent, INFINITE);
+ break;
+ default:
+ qErrnoWarning(dwError, "QProcess: ConnectNamedPipe failed.");
+ CloseHandle(overlapped.hEvent);
+ CloseHandle(hClient);
+ CloseHandle(hServer);
+ return;
+ }
+ }
+ CloseHandle(overlapped.hEvent);
if (isInputPipe) {
pipe[0] = hClient;
@@ -183,7 +202,8 @@ bool QProcessPrivate::openChannel(Channel &channel)
&stderrChannel.pipe[1], 0, TRUE, DUPLICATE_SAME_ACCESS);
}
- if (channel.type == Channel::Normal) {
+ switch (channel.type) {
+ case Channel::Normal:
// we're piping this channel to our own process
if (&channel == &stdinChannel) {
if (inputChannelMode != QProcess::ForwardedInputChannel) {
@@ -223,9 +243,8 @@ bool QProcessPrivate::openChannel(Channel &channel)
channel.reader->startAsyncRead();
}
}
-
return true;
- } else if (channel.type == Channel::Redirect) {
+ case Channel::Redirect: {
// we're redirecting the channel to/from a file
SECURITY_ATTRIBUTES secAtt = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
@@ -270,65 +289,65 @@ bool QProcessPrivate::openChannel(Channel &channel)
}
cleanup();
return false;
- } else {
+ }
+ case Channel::PipeSource: {
Q_ASSERT_X(channel.process, "QProcess::start", "Internal error");
+ // we are the source
+ Channel *source = &channel;
+ Channel *sink = &channel.process->stdinChannel;
+
+ if (source->pipe[1] != INVALID_Q_PIPE) {
+ // already constructed by the sink
+ // make it inheritable
+ HANDLE tmpHandle = source->pipe[1];
+ if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
+ GetCurrentProcess(), &source->pipe[1],
+ 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ return false;
+ }
- Channel *source;
- Channel *sink;
+ CloseHandle(tmpHandle);
+ return true;
+ }
- if (channel.type == Channel::PipeSource) {
- // we are the source
- source = &channel;
- sink = &channel.process->stdinChannel;
+ Q_ASSERT(source == &stdoutChannel);
+ Q_ASSERT(sink->process == this && sink->type == Channel::PipeSink);
- if (source->pipe[1] != INVALID_Q_PIPE) {
- // already constructed by the sink
- // make it inheritable
- HANDLE tmpHandle = source->pipe[1];
- if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
- GetCurrentProcess(), &source->pipe[1],
- 0, TRUE, DUPLICATE_SAME_ACCESS))
- return false;
+ qt_create_pipe(source->pipe, /* in = */ false); // source is stdout
+ sink->pipe[0] = source->pipe[0];
+ source->pipe[0] = INVALID_Q_PIPE;
- CloseHandle(tmpHandle);
- return true;
+ return true;
+ }
+ case Channel::PipeSink: { // we are the sink;
+ Q_ASSERT_X(channel.process, "QProcess::start", "Internal error");
+ Channel *source = &channel.process->stdoutChannel;
+ Channel *sink = &channel;
+
+ if (sink->pipe[0] != INVALID_Q_PIPE) {
+ // already constructed by the source
+ // make it inheritable
+ HANDLE tmpHandle = sink->pipe[0];
+ if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
+ GetCurrentProcess(), &sink->pipe[0],
+ 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ return false;
}
- Q_ASSERT(source == &stdoutChannel);
- Q_ASSERT(sink->process == this && sink->type == Channel::PipeSink);
-
- qt_create_pipe(source->pipe, /* in = */ false); // source is stdout
- sink->pipe[0] = source->pipe[0];
- source->pipe[0] = INVALID_Q_PIPE;
-
+ CloseHandle(tmpHandle);
return true;
- } else {
- // we are the sink;
- source = &channel.process->stdoutChannel;
- sink = &channel;
-
- if (sink->pipe[0] != INVALID_Q_PIPE) {
- // already constructed by the source
- // make it inheritable
- HANDLE tmpHandle = sink->pipe[0];
- if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
- GetCurrentProcess(), &sink->pipe[0],
- 0, TRUE, DUPLICATE_SAME_ACCESS))
- return false;
-
- CloseHandle(tmpHandle);
- return true;
- }
- Q_ASSERT(sink == &stdinChannel);
- Q_ASSERT(source->process == this && source->type == Channel::PipeSource);
+ }
+ Q_ASSERT(sink == &stdinChannel);
+ Q_ASSERT(source->process == this && source->type == Channel::PipeSource);
- qt_create_pipe(sink->pipe, /* in = */ true); // sink is stdin
- source->pipe[1] = sink->pipe[1];
- sink->pipe[1] = INVALID_Q_PIPE;
+ qt_create_pipe(sink->pipe, /* in = */ true); // sink is stdin
+ source->pipe[1] = sink->pipe[1];
+ sink->pipe[1] = INVALID_Q_PIPE;
- return true;
- }
+ return true;
}
+ } // switch (channel.type)
+ return false;
}
void QProcessPrivate::destroyPipe(Q_PIPE pipe[2])
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 7502fb57a3..367cd78d65 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -52,7 +52,9 @@
#include "qendian.h"
#include <qshareddata.h>
#include <qplatformdefs.h>
+#include <qendian.h>
#include "private/qabstractfileengine_p.h"
+#include "private/qsimd_p.h"
#include "private/qsystemerror_p.h"
#ifdef Q_OS_UNIX
@@ -629,17 +631,13 @@ inline QString QResourceRoot::name(int node) const
QString ret;
qint32 name_offset = qFromBigEndian<qint32>(tree + offset);
- const qint16 name_length = qFromBigEndian<qint16>(names + name_offset);
+ quint16 name_length = qFromBigEndian<qint16>(names + name_offset);
name_offset += 2;
name_offset += 4; //jump past hash
ret.resize(name_length);
QChar *strData = ret.data();
- for(int i = 0; i < name_length*2; i+=2) {
- QChar c(names[name_offset+i+1], names[name_offset+i]);
- *strData = c;
- ++strData;
- }
+ qFromBigEndian<ushort>(names + name_offset, name_length, strData);
return ret;
}
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 4b1b9888d8..391d2a49af 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -77,6 +77,10 @@
# include <ioLib.h>
#endif
+#ifdef Q_OS_WASM
+#include <emscripten.h>
+#endif
+
#include <algorithm>
#include <stdlib.h>
@@ -1544,6 +1548,13 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
perms |= QFile::ReadGroup | QFile::ReadOther;
QFile(confFile->name).setPermissions(perms);
}
+#ifdef Q_OS_WASM
+ EM_ASM(
+ // Sync sandbox filesystem to persistent database filesystem. See QTBUG-70002
+ FS.syncfs(false, function(err) {
+ });
+ );
+#endif
} else {
setStatus(QSettings::AccessError);
}
@@ -1694,10 +1705,10 @@ bool QConfFileSettingsPrivate::readIniFile(const QByteArray &data,
iniSection = iniSection.trimmed();
- if (qstricmp(iniSection.constData(), "general") == 0) {
+ if (iniSection.compare("general", Qt::CaseInsensitive) == 0) {
currentSection.clear();
} else {
- if (qstricmp(iniSection.constData(), "%general") == 0) {
+ if (iniSection.compare("%general", Qt::CaseInsensitive) == 0) {
currentSection = QLatin1String(iniSection.constData() + 1);
} else {
currentSection.clear();
@@ -1857,7 +1868,7 @@ bool QConfFileSettingsPrivate::writeIniFile(QIODevice &device, const ParsedSetti
if (realSection.isEmpty()) {
realSection = "[General]";
- } else if (qstricmp(realSection.constData(), "general") == 0) {
+ } else if (realSection.compare("general", Qt::CaseInsensitive) == 0) {
realSection = "[%General]";
} else {
realSection.prepend('[');
diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp
index aa14d8435a..28f01eae4d 100644
--- a/src/corelib/io/qsettings_mac.cpp
+++ b/src/corelib/io/qsettings_mac.cpp
@@ -355,15 +355,15 @@ public:
const QString &application);
~QMacSettingsPrivate();
- void remove(const QString &key);
- void set(const QString &key, const QVariant &value);
- bool get(const QString &key, QVariant *value) const;
- QStringList children(const QString &prefix, ChildSpec spec) const;
- void clear();
- void sync();
- void flush();
- bool isWritable() const;
- QString fileName() const;
+ void remove(const QString &key) override;
+ void set(const QString &key, const QVariant &value) override;
+ bool get(const QString &key, QVariant *value) const override;
+ QStringList children(const QString &prefix, ChildSpec spec) const override;
+ void clear() override;
+ void sync() override;
+ void flush() override;
+ bool isWritable() const override;
+ QString fileName() const override;
private:
struct SearchDomain
diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp
index edcae16776..1881d0dc7e 100644
--- a/src/corelib/io/qsettings_win.cpp
+++ b/src/corelib/io/qsettings_win.cpp
@@ -377,23 +377,24 @@ typedef QVector<RegistryKey> RegistryKeyList;
class QWinSettingsPrivate : public QSettingsPrivate
{
+ Q_DISABLE_COPY(QWinSettingsPrivate)
public:
QWinSettingsPrivate(QSettings::Scope scope, const QString &organization,
const QString &application, REGSAM access = 0);
QWinSettingsPrivate(QString rKey, REGSAM access = 0);
- ~QWinSettingsPrivate();
-
- void remove(const QString &uKey);
- void set(const QString &uKey, const QVariant &value);
- bool get(const QString &uKey, QVariant *value) const;
- QStringList children(const QString &uKey, ChildSpec spec) const;
- void clear();
- void sync();
- void flush();
- bool isWritable() const;
+ ~QWinSettingsPrivate() override;
+
+ void remove(const QString &uKey) override;
+ void set(const QString &uKey, const QVariant &value) override;
+ bool get(const QString &uKey, QVariant *value) const override;
+ QStringList children(const QString &uKey, ChildSpec spec) const override;
+ void clear() override;
+ void sync() override;
+ void flush() override;
+ bool isWritable() const override;
HKEY writeHandle() const;
bool readKey(HKEY parentHandle, const QString &rSubKey, QVariant *value) const;
- QString fileName() const;
+ QString fileName() const override;
private:
RegistryKeyList regList; // list of registry locations to search for keys
@@ -515,7 +516,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
case REG_SZ: {
QString s;
if (dataSize) {
- s = QString::fromWCharArray(((const wchar_t *)data.constData()));
+ s = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()));
}
if (value != 0)
*value = stringToVariant(s);
@@ -527,7 +528,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
if (dataSize) {
int i = 0;
for (;;) {
- QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i);
+ QString s = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()) + i);
i += s.length() + 1;
if (s.isEmpty())
@@ -544,7 +545,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
case REG_BINARY: {
QString s;
if (dataSize) {
- s = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2);
+ s = QString::fromWCharArray(reinterpret_cast<const wchar_t *>(data.constData()), data.size() / 2);
}
if (value != 0)
*value = stringToVariant(s);
@@ -555,7 +556,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
case REG_DWORD: {
Q_ASSERT(data.size() == sizeof(int));
int i;
- memcpy((char*)&i, data.constData(), sizeof(int));
+ memcpy(reinterpret_cast<char*>(&i), data.constData(), sizeof(int));
if (value != 0)
*value = i;
break;
@@ -564,7 +565,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
case REG_QWORD: {
Q_ASSERT(data.size() == sizeof(qint64));
qint64 i;
- memcpy((char*)&i, data.constData(), sizeof(qint64));
+ memcpy(reinterpret_cast<char*>(&i), data.constData(), sizeof(qint64));
if (value != 0)
*value = i;
break;
@@ -629,11 +630,9 @@ void QWinSettingsPrivate::remove(const QString &uKey)
deleteChildGroups(handle, access);
if (rKey.isEmpty()) {
- QStringList childKeys = childKeysOrGroups(handle, QSettingsPrivate::ChildKeys);
-
- for (int i = 0; i < childKeys.size(); ++i) {
- QString group = childKeys.at(i);
+ const QStringList childKeys = childKeysOrGroups(handle, QSettingsPrivate::ChildKeys);
+ for (const QString &group : childKeys) {
LONG res = RegDeleteValue(handle, reinterpret_cast<const wchar_t *>(group.utf16()));
if (res != ERROR_SUCCESS) {
qWarning("QSettings: RegDeleteValue failed on subkey \"%s\": %s",
@@ -688,12 +687,12 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
if (type == REG_BINARY) {
QString s = variantToString(value);
- regValueBuff = QByteArray((const char*)s.utf16(), s.length() * 2);
+ regValueBuff = QByteArray(reinterpret_cast<const char*>(s.utf16()), s.length() * 2);
} else {
QStringList::const_iterator it = l.constBegin();
for (; it != l.constEnd(); ++it) {
const QString &s = *it;
- regValueBuff += QByteArray((const char*)s.utf16(), (s.length() + 1) * 2);
+ regValueBuff += QByteArray(reinterpret_cast<const char*>(s.utf16()), (s.length() + 1) * 2);
}
regValueBuff.append((char)0);
regValueBuff.append((char)0);
@@ -705,7 +704,7 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
case QVariant::UInt: {
type = REG_DWORD;
qint32 i = value.toInt();
- regValueBuff = QByteArray((const char*)&i, sizeof(qint32));
+ regValueBuff = QByteArray(reinterpret_cast<const char*>(&i), sizeof(qint32));
break;
}
@@ -713,7 +712,7 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
case QVariant::ULongLong: {
type = REG_QWORD;
qint64 i = value.toLongLong();
- regValueBuff = QByteArray((const char*)&i, sizeof(qint64));
+ regValueBuff = QByteArray(reinterpret_cast<const char*>(&i), sizeof(qint64));
break;
}
@@ -725,11 +724,11 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
// string type. Otherwise we use REG_BINARY.
QString s = variantToString(value);
type = s.contains(QChar::Null) ? REG_BINARY : REG_SZ;
- if (type == REG_BINARY) {
- regValueBuff = QByteArray((const char*)s.utf16(), s.length() * 2);
- } else {
- regValueBuff = QByteArray((const char*)s.utf16(), (s.length() + 1) * 2);
- }
+ int length = s.length();
+ if (type == REG_SZ)
+ ++length;
+ regValueBuff = QByteArray(reinterpret_cast<const char *>(s.utf16()),
+ int(sizeof(wchar_t)) * length);
break;
}
}
@@ -754,8 +753,8 @@ bool QWinSettingsPrivate::get(const QString &uKey, QVariant *value) const
{
QString rKey = escapedKey(uKey);
- for (int i = 0; i < regList.size(); ++i) {
- HKEY handle = regList.at(i).handle();
+ for (const RegistryKey &r : regList) {
+ HKEY handle = r.handle();
if (handle != 0 && readKey(handle, rKey, value))
return true;
@@ -771,8 +770,8 @@ QStringList QWinSettingsPrivate::children(const QString &uKey, ChildSpec spec) c
NameSet result;
QString rKey = escapedKey(uKey);
- for (int i = 0; i < regList.size(); ++i) {
- HKEY parent_handle = regList.at(i).handle();
+ for (const RegistryKey &r : regList) {
+ HKEY parent_handle = r.handle();
if (parent_handle == 0)
continue;
HKEY handle = openKey(parent_handle, KEY_READ, rKey, access);
@@ -836,26 +835,32 @@ bool QWinSettingsPrivate::isWritable() const
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
{
- if (format == QSettings::NativeFormat)
+ switch (format) {
+ case QSettings::NativeFormat:
return new QWinSettingsPrivate(scope, organization, application);
- else if (format == QSettings::Registry32Format)
+ case QSettings::Registry32Format:
return new QWinSettingsPrivate(scope, organization, application, KEY_WOW64_32KEY);
- else if (format == QSettings::Registry64Format)
+ case QSettings::Registry64Format:
return new QWinSettingsPrivate(scope, organization, application, KEY_WOW64_64KEY);
- else
- return new QConfFileSettingsPrivate(format, scope, organization, application);
+ default:
+ break;
+ }
+ return new QConfFileSettingsPrivate(format, scope, organization, application);
}
QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format)
{
- if (format == QSettings::NativeFormat)
+ switch (format) {
+ case QSettings::NativeFormat:
return new QWinSettingsPrivate(fileName);
- else if (format == QSettings::Registry32Format)
+ case QSettings::Registry32Format:
return new QWinSettingsPrivate(fileName, KEY_WOW64_32KEY);
- else if (format == QSettings::Registry64Format)
+ case QSettings::Registry64Format:
return new QWinSettingsPrivate(fileName, KEY_WOW64_64KEY);
- else
- return new QConfFileSettingsPrivate(fileName, format);
+ default:
+ break;
+ }
+ return new QConfFileSettingsPrivate(fileName, format);
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qsettings_winrt.cpp b/src/corelib/io/qsettings_winrt.cpp
index 209b56d920..4c757f9dda 100644
--- a/src/corelib/io/qsettings_winrt.cpp
+++ b/src/corelib/io/qsettings_winrt.cpp
@@ -290,15 +290,15 @@ public:
QWinRTSettingsPrivate(const QString &rKey);
~QWinRTSettingsPrivate();
- void remove(const QString &uKey);
- void set(const QString &uKey, const QVariant &value);
- bool get(const QString &uKey, QVariant *value) const;
- QStringList children(const QString &uKey, ChildSpec spec) const;
- void clear();
- void sync();
- void flush();
- bool isWritable() const;
- QString fileName() const;
+ void remove(const QString &uKey) override;
+ void set(const QString &uKey, const QVariant &value) override;
+ bool get(const QString &uKey, QVariant *value) const override;
+ QStringList children(const QString &uKey, ChildSpec spec) const override;
+ void clear() override;
+ void sync() override;
+ void flush() override;
+ bool isWritable() const override;
+ QString fileName() const override;
private:
void init(QSettings::Scope scope);
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 438924bd80..e531505877 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -472,16 +472,10 @@ static inline QString webDavSslTag()
return QStringLiteral("@SSL");
}
-#ifdef Q_COMPILER_CLASS_ENUM
-# define colon_uchar : uchar
-#else
-# define colon_uchar
-#endif
-
class QUrlPrivate
{
public:
- enum Section colon_uchar {
+ enum Section : uchar {
Scheme = 0x01,
UserName = 0x02,
Password = 0x04,
@@ -496,7 +490,7 @@ public:
FullUrl = 0xff
};
- enum Flags colon_uchar {
+ enum Flags : uchar {
IsLocalFile = 0x01
};
@@ -616,7 +610,6 @@ public:
// 32-bit: 2 bytes tail padding available
// 64-bit: 6 bytes tail padding available
};
-#undef colon_uchar
inline QUrlPrivate::QUrlPrivate()
: ref(1), port(-1),
@@ -1203,15 +1196,13 @@ inline void QUrlPrivate::setQuery(const QString &value, int from, int iend)
inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions options) const
{
- // EncodeUnicode is the only flag that matters
- if ((options & QUrl::FullyDecoded) == QUrl::FullyDecoded)
- options = 0;
- else
- options &= QUrl::EncodeUnicode;
if (host.isEmpty())
return;
if (host.at(0).unicode() == '[') {
- // IPv6Address and IPvFuture address never require any transformation
+ // IPv6 addresses might contain a zone-id which needs to be recoded
+ if (options != 0)
+ if (qt_urlRecode(appendTo, host.constBegin(), host.constEnd(), options, 0))
+ return;
appendTo += host;
} else {
// this is either an IPv4Address or a reg-name
@@ -1278,31 +1269,44 @@ static const QChar *parseIpFuture(QString &host, const QChar *begin, const QChar
// ONLY the IPv6 address is parsed here, WITHOUT the brackets
static const QChar *parseIp6(QString &host, const QChar *begin, const QChar *end, QUrl::ParsingMode mode)
{
- QIPAddressUtils::IPv6Address address;
- const QChar *ret = QIPAddressUtils::parseIp6(address, begin, end);
- if (ret) {
+ // ### Update to use QStringView once QStringView::indexOf and QStringView::lastIndexOf exists
+ QString decoded;
+ if (mode == QUrl::TolerantMode) {
// this struct is kept in automatic storage because it's only 4 bytes
const ushort decodeColon[] = { decode(':'), 0 };
+ if (qt_urlRecode(decoded, begin, end, QUrl::ComponentFormattingOption::PrettyDecoded, decodeColon) == 0)
+ decoded = QString(begin, end-begin);
+ } else {
+ decoded = QString(begin, end-begin);
+ }
- // IPv6 failed parsing, check if it was a percent-encoded character in
- // the middle and try again
- QString decoded;
- if (mode == QUrl::TolerantMode && qt_urlRecode(decoded, begin, end, 0, decodeColon)) {
- // recurse
- // if the parsing fails again, the qt_urlRecode above will return 0
- ret = parseIp6(host, decoded.constBegin(), decoded.constEnd(), mode);
+ const QLatin1String zoneIdIdentifier("%25");
+ QIPAddressUtils::IPv6Address address;
+ QString zoneId;
- // we can't return ret, otherwise it would be dangling
- return ret ? end : 0;
- }
+ const QChar *endBeforeZoneId = decoded.constEnd();
+
+ int zoneIdPosition = decoded.indexOf(zoneIdIdentifier);
+ if ((zoneIdPosition != -1) && (decoded.lastIndexOf(zoneIdIdentifier) == zoneIdPosition)) {
+ zoneId = decoded.mid(zoneIdPosition + zoneIdIdentifier.size());
+ endBeforeZoneId = decoded.constBegin() + zoneIdPosition;
- // no transformation, nothing to re-parse
- return ret;
+ if (zoneId.isEmpty())
+ return end;
}
- host.reserve(host.size() + (end - begin));
+ const QChar *ret = QIPAddressUtils::parseIp6(address, decoded.constBegin(), endBeforeZoneId);
+ if (ret)
+ return begin + (ret - decoded.constBegin());
+
+ host.reserve(host.size() + (decoded.constEnd() - decoded.constBegin()));
host += QLatin1Char('[');
QIPAddressUtils::toString(host, address);
+
+ if (!zoneId.isEmpty()) {
+ host += zoneIdIdentifier;
+ host += zoneId;
+ }
host += QLatin1Char(']');
return 0;
}
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index a9b23babc0..443ae18b21 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -40,6 +40,7 @@
#include "qurl.h"
#include "private/qutfcodec_p.h"
#include "private/qtools_p.h"
+#include "private/qsimd_p.h"
QT_BEGIN_NAMESPACE
@@ -474,6 +475,88 @@ non_trivial:
return 0;
}
+/*
+ * Returns true if the input it checked (if it checked anything) is not
+ * encoded. A return of false indicates there's a percent at \a input that
+ * needs to be decoded.
+ */
+#ifdef __SSE2__
+static bool simdCheckNonEncoded(ushort *&output, const ushort *&input, const ushort *end)
+{
+# ifdef __AVX2__
+ const __m256i percents256 = _mm256_broadcastw_epi16(_mm_cvtsi32_si128('%'));
+ const __m128i percents = _mm256_castsi256_si128(percents256);
+# else
+ const __m128i percents = _mm_set1_epi16('%');
+# endif
+
+ uint idx = 0;
+ quint32 mask = 0;
+ if (input + 16 <= end) {
+ qptrdiff offset = 0;
+ for ( ; input + offset + 16 <= end; offset += 16) {
+# ifdef __AVX2__
+ // do 32 bytes at a time using AVX2
+ __m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(input + offset));
+ __m256i comparison = _mm256_cmpeq_epi16(data, percents256);
+ mask = _mm256_movemask_epi8(comparison);
+ _mm256_storeu_si256(reinterpret_cast<__m256i *>(output + offset), data);
+# else
+ // do 32 bytes at a time using unrolled SSE2
+ __m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(input + offset));
+ __m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(input + offset + 8));
+ __m128i comparison1 = _mm_cmpeq_epi16(data1, percents);
+ __m128i comparison2 = _mm_cmpeq_epi16(data2, percents);
+ uint mask1 = _mm_movemask_epi8(comparison1);
+ uint mask2 = _mm_movemask_epi8(comparison2);
+
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(output + offset), data1);
+ if (!mask1)
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(output + offset + 8), data2);
+ mask = mask1 | (mask2 << 16);
+# endif
+
+ if (mask) {
+ idx = qCountTrailingZeroBits(mask) / 2;
+ break;
+ }
+ }
+
+ input += offset;
+ if (output)
+ output += offset;
+ } else if (input + 8 <= end) {
+ // do 16 bytes at a time
+ __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(input));
+ __m128i comparison = _mm_cmpeq_epi16(data, percents);
+ mask = _mm_movemask_epi8(comparison);
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(output), data);
+ idx = qCountTrailingZeroBits(quint16(mask)) / 2;
+ } else if (input + 4 <= end) {
+ // do 8 bytes only
+ __m128i data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(input));
+ __m128i comparison = _mm_cmpeq_epi16(data, percents);
+ mask = _mm_movemask_epi8(comparison) & 0xffu;
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(output), data);
+ idx = qCountTrailingZeroBits(quint8(mask)) / 2;
+ } else {
+ // no percents found (because we didn't check)
+ return true;
+ }
+
+ // advance to the next non-encoded
+ input += idx;
+ output += idx;
+
+ return !mask;
+}
+#else
+static bool simdCheckNonEncoded(...)
+{
+ return true;
+}
+#endif
+
/*!
\since 5.0
\internal
@@ -497,16 +580,21 @@ non_trivial:
*/
static int decode(QString &appendTo, const ushort *begin, const ushort *end)
{
+ // fast check whether there's anything to be decoded in the first place
+ const ushort *input = QtPrivate::qustrchr(QStringView(begin, end), '%');
+ if (Q_LIKELY(input == end))
+ return 0; // nothing to do, it was already decoded!
+
+ // detach
const int origSize = appendTo.size();
- const ushort *input = begin;
- ushort *output = 0;
+ appendTo.resize(origSize + (end - begin));
+ ushort *output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize;
+ memcpy(static_cast<void *>(output), static_cast<const void *>(begin), (input - begin) * sizeof(ushort));
+ output += input - begin;
+
while (input != end) {
- if (*input != '%') {
- if (output)
- *output++ = *input;
- ++input;
- continue;
- }
+ // something was encoded
+ Q_ASSERT(*input == '%');
if (Q_UNLIKELY(end - input < 3 || !isHex(input[1]) || !isHex(input[2]))) {
// badly-encoded data
@@ -515,27 +603,27 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
return end - begin;
}
- if (Q_UNLIKELY(!output)) {
- // detach
- appendTo.resize(origSize + (end - begin));
- output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize;
- memcpy(static_cast<void *>(output), static_cast<const void *>(begin), (input - begin) * sizeof(ushort));
- output += input - begin;
- }
-
++input;
*output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]);
if (output[-1] >= 0x80)
output[-1] = QChar::ReplacementCharacter;
input += 2;
- }
- if (output) {
- int len = output - reinterpret_cast<ushort *>(appendTo.begin());
- appendTo.truncate(len);
- return len - origSize;
+ // search for the next percent, copying from input to output
+ if (simdCheckNonEncoded(output, input, end)) {
+ while (input != end) {
+ ushort uc = *input;
+ if (uc == '%')
+ break;
+ *output++ = uc;
+ ++input;
+ }
+ }
}
- return 0;
+
+ int len = output - reinterpret_cast<ushort *>(appendTo.begin());
+ appendTo.truncate(len);
+ return len - origSize;
}
template <size_t N>
@@ -603,6 +691,9 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
encoding, actionTable, false);
}
+// qstring.cpp
+bool qt_is_ascii(const char *&ptr, const char *end) Q_DECL_NOTHROW;
+
/*!
\internal
\since 5.0
@@ -623,12 +714,7 @@ QString qt_urlRecodeByteArray(const QByteArray &ba)
// control points below 0x20 are fine in QString
const char *in = ba.constData();
const char *const end = ba.constEnd();
- for ( ; in < end; ++in) {
- if (*in & 0x80)
- break;
- }
-
- if (in == end) {
+ if (qt_is_ascii(in, end)) {
// no non-ASCII found, we're safe to convert to QString
return QString::fromLatin1(ba, ba.size());
}
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index 2312d5ca63..15c9f52cf3 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -270,13 +270,11 @@ void QWindowsPipeReader::readFileCompleted(DWORD errorCode, DWORD numberOfBytesT
DWORD QWindowsPipeReader::checkPipeState()
{
DWORD bytes;
- if (PeekNamedPipe(handle, NULL, 0, NULL, &bytes, NULL)) {
+ if (PeekNamedPipe(handle, nullptr, 0, nullptr, &bytes, nullptr))
return bytes;
- } else {
- if (!pipeBroken) {
- pipeBroken = true;
- emit pipeClosed();
- }
+ if (!pipeBroken) {
+ pipeBroken = true;
+ emit pipeClosed();
}
return 0;
}
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 3a6f67521f..e816add91d 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -1866,6 +1866,23 @@ bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value
return false;
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \since 6.0
+ Removes the data stored in all the roles for the given \a index.
+ Returns \c{true} if successful; otherwise returns \c{false}.
+ The dataChanged() signal should be emitted if the data was successfully
+ removed.
+ The base class implementation returns \c{false}
+ \sa data(), itemData(), setData(), setItemData()
+*/
+bool QAbstractItemModel::clearItemData(const QModelIndex &index)
+{
+ Q_UNUSED(index);
+ return false;
+}
+#endif
+
/*!
\fn QVariant QAbstractItemModel::data(const QModelIndex &index, int role) const = 0
diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h
index 21171124f9..bec71b0606 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.h
+++ b/src/corelib/itemmodels/qabstractitemmodel.h
@@ -198,6 +198,9 @@ public:
virtual QMap<int, QVariant> itemData(const QModelIndex &index) const;
virtual bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ virtual bool clearItemData(const QModelIndex &index);
+#endif
virtual QStringList mimeTypes() const;
virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 6728f0106b..31b9bbc990 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -146,6 +146,133 @@ private:
int end;
};
+class RegularExpressionData {
+
+private:
+ enum class ExpressionType {
+ RegExp,
+#if QT_CONFIG(regularexpression)
+ RegularExpression
+#endif
+ };
+
+public:
+ RegularExpressionData() :
+ m_type(ExpressionType::RegExp)
+ {}
+
+#if QT_CONFIG(regularexpression)
+ QRegularExpression regularExpression() const
+ {
+ if (m_type == ExpressionType::RegularExpression)
+ return m_regularExpression;
+ return QRegularExpression();
+ }
+
+ void setRegularExpression(const QRegularExpression &rx)
+ {
+ m_type = ExpressionType::RegularExpression;
+ m_regularExpression = rx;
+ m_regExp = QRegExp();
+ }
+#endif
+
+ QRegExp regExp() const
+ {
+ if (m_type == ExpressionType::RegExp)
+ return m_regExp;
+ return QRegExp();
+ }
+
+ void setRegExp(const QRegExp &rx)
+ {
+ m_type = ExpressionType::RegExp;
+ m_regExp = rx;
+#if QT_CONFIG(regularexpression)
+ m_regularExpression = QRegularExpression();
+#endif
+
+ }
+
+ bool isEmpty() const
+ {
+ bool result = true;
+ switch (m_type) {
+ case ExpressionType::RegExp:
+ result = m_regExp.isEmpty();
+ break;
+#if QT_CONFIG(regularexpression)
+ case ExpressionType::RegularExpression:
+ result = m_regularExpression.pattern().isEmpty();
+ break;
+#endif
+ }
+ return result;
+ }
+
+ Qt::CaseSensitivity caseSensitivity() const
+ {
+ Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive;
+ switch (m_type) {
+ case ExpressionType::RegExp:
+ sensitivity = m_regExp.caseSensitivity();
+ break;
+#if QT_CONFIG(regularexpression)
+ case ExpressionType::RegularExpression:
+ {
+ QRegularExpression::PatternOptions options = m_regularExpression.patternOptions();
+ if (!(options & QRegularExpression::CaseInsensitiveOption))
+ sensitivity = Qt::CaseSensitive;
+ }
+ break;
+#endif
+ }
+ return sensitivity;
+ }
+
+ void setCaseSensitivity(Qt::CaseSensitivity cs)
+ {
+ switch (m_type) {
+ case ExpressionType::RegExp:
+ m_regExp.setCaseSensitivity(cs);
+ break;
+#if QT_CONFIG(regularexpression)
+ case ExpressionType::RegularExpression:
+ {
+ QRegularExpression::PatternOptions options = m_regularExpression.patternOptions();
+ options.setFlag(QRegularExpression::CaseInsensitiveOption, cs == Qt::CaseSensitive);
+ m_regularExpression.setPatternOptions(options);
+ }
+ break;
+#endif
+ }
+ }
+
+ bool hasMatch(const QString &str) const
+ {
+ bool result = false;
+ switch (m_type) {
+ case ExpressionType::RegExp:
+ result = str.contains(m_regExp);
+ break;
+#if QT_CONFIG(regularexpression)
+ case ExpressionType::RegularExpression:
+ result = str.contains(m_regularExpression);
+ break;
+#endif
+ }
+ return result;
+ }
+
+private:
+ ExpressionType m_type;
+ QRegExp m_regExp;
+#if QT_CONFIG(regularexpression)
+ QRegularExpression m_regularExpression;
+#endif
+};
+
+
class QSortFilterProxyModelPrivate : public QAbstractProxyModelPrivate
{
Q_DECLARE_PUBLIC(QSortFilterProxyModel)
@@ -171,7 +298,7 @@ public:
int filter_column;
int filter_role;
- QRegExp filter_regexp;
+ RegularExpressionData filter_data;
QModelIndex last_top_source;
bool filter_recursive;
@@ -574,6 +701,19 @@ QVector<QPair<int, int > > QSortFilterProxyModelPrivate::proxy_intervals_for_sou
proxy_intervals.append(QPair<int, int>(first_proxy_item, last_proxy_item));
}
std::stable_sort(proxy_intervals.begin(), proxy_intervals.end());
+ // Consolidate adjacent intervals
+ for (int i = proxy_intervals.size()-1; i > 0; --i) {
+ QPair<int, int> &interval = proxy_intervals[i];
+ QPair<int, int> &preceeding_interval = proxy_intervals[i - 1];
+ if (interval.first == preceeding_interval.second + 1) {
+ preceeding_interval.second = interval.second;
+ interval.first = interval.second = -1;
+ }
+ }
+ proxy_intervals.erase(
+ std::remove_if(proxy_intervals.begin(), proxy_intervals.end(),
+ [](QPair<int, int> &interval) { return interval.first < 0; }),
+ proxy_intervals.end());
return proxy_intervals;
}
@@ -1096,7 +1236,7 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes(
*/
void QSortFilterProxyModelPrivate::filter_about_to_be_changed(const QModelIndex &source_parent)
{
- if (!filter_regexp.pattern().isEmpty() &&
+ if (!filter_data.isEmpty() &&
source_index_mapping.constFind(source_parent) == source_index_mapping.constEnd())
create_mapping(source_parent);
}
@@ -1773,9 +1913,9 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved(
If a parent item doesn't match the filter, none of its children will be
shown.
- A common use case is to let the user specify the filter regexp, wildcard
- pattern, or fixed string in a QLineEdit and to connect the
- \l{QLineEdit::textChanged()}{textChanged()} signal to setFilterRegExp(),
+ A common use case is to let the user specify the filter regular expression,
+ wildcard pattern, or fixed string in a QLineEdit and to connect the
+ \l{QLineEdit::textChanged()}{textChanged()} signal to setFilterRegularExpression(),
setFilterWildcard(), or setFilterFixedString() to reapply the filter.
Custom filtering behavior can be achieved by reimplementing the
@@ -1812,6 +1952,21 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved(
\note Some general guidelines for subclassing models are available in the
\l{Model Subclassing Reference}.
+ \note With Qt 5, regular expression support has been improved through the
+ QRegularExpression class. QSortFilterProxyModel dating back prior to that
+ class creation, it originally supported only QRegExp. Since Qt 5.12,
+ QRegularExpression APIs have been added. Therefore, QRegExp APIs should be
+ considered deprecated and the QRegularExpression version should be used in
+ place.
+
+ \warning Don't mix calls to the getters and setters of different regexp types
+ as this will lead to unexpected results. For maximum compatibility, the original
+ implementation has been kept. Therefore, if, for example, a call to
+ setFilterRegularExpression is made followed by another one to
+ setFilterFixedString, the first call will setup a QRegularExpression object
+ to use as filter while the second will setup a QRegExp in FixedString mode.
+ However, this is an implementation detail that might change in the future.
+
\sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming},
{Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}, QIdentityProxyModel
*/
@@ -2424,17 +2579,47 @@ Qt::SortOrder QSortFilterProxyModel::sortOrder() const
QRegExp QSortFilterProxyModel::filterRegExp() const
{
Q_D(const QSortFilterProxyModel);
- return d->filter_regexp;
+ return d->filter_data.regExp();
}
void QSortFilterProxyModel::setFilterRegExp(const QRegExp &regExp)
{
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
- d->filter_regexp = regExp;
+ d->filter_data.setRegExp(regExp);
d->filter_changed();
}
+#if QT_CONFIG(regularexpression)
+/*!
+ \since 5.12
+ \property QSortFilterProxyModel::filterRegularExpression
+ \brief the QRegularExpression used to filter the contents of the source model
+
+ Setting this property overwrites the current
+ \l{QSortFilterProxyModel::filterCaseSensitivity}{filterCaseSensitivity}.
+ By default, the QRegularExpression is an empty string matching all contents.
+
+ If no QRegularExpression or an empty string is set, everything in the source
+ model will be accepted.
+
+ \sa filterCaseSensitivity, setFilterWildcard(), setFilterFixedString()
+*/
+QRegularExpression QSortFilterProxyModel::filterRegularExpression() const
+{
+ Q_D(const QSortFilterProxyModel);
+ return d->filter_data.regularExpression();
+}
+
+void QSortFilterProxyModel::setFilterRegularExpression(const QRegularExpression &regularExpression)
+{
+ Q_D(QSortFilterProxyModel);
+ d->filter_about_to_be_changed();
+ d->filter_data.setRegularExpression(regularExpression);
+ d->filter_changed();
+}
+#endif
+
/*!
\property QSortFilterProxyModel::filterKeyColumn
\brief the column where the key used to filter the contents of the
@@ -2470,16 +2655,16 @@ void QSortFilterProxyModel::setFilterKeyColumn(int column)
Qt::CaseSensitivity QSortFilterProxyModel::filterCaseSensitivity() const
{
Q_D(const QSortFilterProxyModel);
- return d->filter_regexp.caseSensitivity();
+ return d->filter_data.caseSensitivity();
}
void QSortFilterProxyModel::setFilterCaseSensitivity(Qt::CaseSensitivity cs)
{
Q_D(QSortFilterProxyModel);
- if (cs == d->filter_regexp.caseSensitivity())
+ if (cs == d->filter_data.caseSensitivity())
return;
d->filter_about_to_be_changed();
- d->filter_regexp.setCaseSensitivity(cs);
+ d->filter_data.setCaseSensitivity(cs);
d->filter_changed();
}
@@ -2545,11 +2730,33 @@ void QSortFilterProxyModel::setFilterRegExp(const QString &pattern)
{
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
- d->filter_regexp.setPatternSyntax(QRegExp::RegExp);
- d->filter_regexp.setPattern(pattern);
+ QRegExp rx(pattern);
+ d->filter_data.setRegExp(rx);
d->filter_changed();
}
+#if QT_CONFIG(regularexpression)
+/*!
+ \since 5.12
+
+ Sets the regular expression used to filter the contents
+ of the source model to \a pattern.
+
+ This method should be preferred for new code as it will use
+ QRegularExpression internally.
+
+ \sa setFilterCaseSensitivity(), setFilterWildcard(), setFilterFixedString(), filterRegularExpression()
+*/
+void QSortFilterProxyModel::setFilterRegularExpression(const QString &pattern)
+{
+ Q_D(QSortFilterProxyModel);
+ d->filter_about_to_be_changed();
+ QRegularExpression rx(pattern);
+ d->filter_data.setRegularExpression(rx);
+ d->filter_changed();
+}
+#endif
+
/*!
Sets the wildcard expression used to filter the contents
of the source model to the given \a pattern.
@@ -2560,8 +2767,8 @@ void QSortFilterProxyModel::setFilterWildcard(const QString &pattern)
{
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
- d->filter_regexp.setPatternSyntax(QRegExp::Wildcard);
- d->filter_regexp.setPattern(pattern);
+ QRegExp rx(pattern, d->filter_data.caseSensitivity(), QRegExp::Wildcard);
+ d->filter_data.setRegExp(rx);
d->filter_changed();
}
@@ -2575,8 +2782,8 @@ void QSortFilterProxyModel::setFilterFixedString(const QString &pattern)
{
Q_D(QSortFilterProxyModel);
d->filter_about_to_be_changed();
- d->filter_regexp.setPatternSyntax(QRegExp::FixedString);
- d->filter_regexp.setPattern(pattern);
+ QRegExp rx(pattern, d->filter_data.caseSensitivity(), QRegExp::FixedString);
+ d->filter_data.setRegExp(rx);
d->filter_changed();
}
@@ -2801,14 +3008,15 @@ bool QSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QMode
bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_D(const QSortFilterProxyModel);
- if (d->filter_regexp.isEmpty())
+
+ if (d->filter_data.isEmpty())
return true;
if (d->filter_column == -1) {
int column_count = d->model->columnCount(source_parent);
for (int column = 0; column < column_count; ++column) {
QModelIndex source_index = d->model->index(source_row, column, source_parent);
QString key = d->model->data(source_index, d->filter_role).toString();
- if (key.contains(d->filter_regexp))
+ if (d->filter_data.hasMatch(key))
return true;
}
return false;
@@ -2817,7 +3025,7 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
if (!source_index.isValid()) // the column may not exist
return true;
QString key = d->model->data(source_index, d->filter_role).toString();
- return key.contains(d->filter_regexp);
+ return d->filter_data.hasMatch(key);
}
/*!
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h
index 907ceb8e6d..1304a95d13 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.h
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.h
@@ -43,6 +43,10 @@
#include <QtCore/qabstractproxymodel.h>
#include <QtCore/qregexp.h>
+#if QT_CONFIG(regularexpression)
+# include <QtCore/qregularexpression.h>
+#endif
+
QT_REQUIRE_CONFIG(sortfilterproxymodel);
QT_BEGIN_NAMESPACE
@@ -59,6 +63,9 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
Q_OBJECT
Q_PROPERTY(QRegExp filterRegExp READ filterRegExp WRITE setFilterRegExp)
+#if QT_CONFIG(regularexpression)
+ Q_PROPERTY(QRegularExpression filterRegularExpression READ filterRegularExpression WRITE setFilterRegularExpression)
+#endif
Q_PROPERTY(int filterKeyColumn READ filterKeyColumn WRITE setFilterKeyColumn)
Q_PROPERTY(bool dynamicSortFilter READ dynamicSortFilter WRITE setDynamicSortFilter)
Q_PROPERTY(Qt::CaseSensitivity filterCaseSensitivity READ filterCaseSensitivity WRITE setFilterCaseSensitivity)
@@ -83,6 +90,11 @@ public:
QRegExp filterRegExp() const;
void setFilterRegExp(const QRegExp &regExp);
+#if QT_CONFIG(regularexpression)
+ QRegularExpression filterRegularExpression() const;
+ void setFilterRegularExpression(const QRegularExpression &regularExpression);
+#endif
+
int filterKeyColumn() const;
void setFilterKeyColumn(int column);
@@ -112,6 +124,9 @@ public:
public Q_SLOTS:
void setFilterRegExp(const QString &pattern);
+#if QT_CONFIG(regularexpression)
+ void setFilterRegularExpression(const QString &pattern);
+#endif
void setFilterWildcard(const QString &pattern);
void setFilterFixedString(const QString &pattern);
#if QT_DEPRECATED_SINCE(5, 11)
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index c528b16f9c..3f7bf3cd47 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -43,6 +43,7 @@ HEADERS += \
kernel/qsystemerror_p.h \
kernel/qmetatype_p.h \
kernel/qmetatypeswitcher_p.h \
+ kernel/qtestsupport_core.h
SOURCES += \
kernel/qabstracteventdispatcher.cpp \
@@ -69,7 +70,8 @@ SOURCES += \
kernel/qsystemsemaphore.cpp \
kernel/qpointer.cpp \
kernel/qmath.cpp \
- kernel/qsystemerror.cpp
+ kernel/qsystemerror.cpp \
+ kernel/qtestsupport_core.cpp
win32 {
SOURCES += \
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index 304a7bda08..655fe58f98 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -309,6 +309,15 @@ int QAbstractEventDispatcher::registerTimer(int interval, Qt::TimerType timerTyp
Wakes up the event loop.
+ \omit
+ ### FIXME - QTBUG-70229
+ On Unix and Glib event dispatchers, if the dispatcher is already awake when
+ this function is called, it is ensured that the current iteration won't block
+ waiting for more events, but will instead do another event loop iteration.
+
+ ### TODO - does other event dispatchers behave the same?
+ \endomit
+
\sa awake()
*/
diff --git a/src/corelib/kernel/qcfsocketnotifier.cpp b/src/corelib/kernel/qcfsocketnotifier.cpp
index 1fee2aa5fc..920ec9cd86 100644
--- a/src/corelib/kernel/qcfsocketnotifier.cpp
+++ b/src/corelib/kernel/qcfsocketnotifier.cpp
@@ -86,7 +86,7 @@ CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket)
if (!loopSource)
return 0;
- CFRunLoopAddSource(CFRunLoopGetMain(), loopSource, kCFRunLoopCommonModes);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), loopSource, kCFRunLoopCommonModes);
return loopSource;
}
@@ -96,7 +96,7 @@ CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket)
void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop)
{
Q_ASSERT(runloop);
- CFRunLoopRemoveSource(CFRunLoopGetMain(), runloop, kCFRunLoopCommonModes);
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runloop, kCFRunLoopCommonModes);
CFSocketDisableCallBacks(socket, kCFSocketReadCallBack);
CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack);
}
@@ -188,7 +188,7 @@ void QCFSocketNotifier::registerSocketNotifier(QSocketNotifier *notifier)
enableNotifiersObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeSources,
true, 0, enableSocketNotifiers, &context);
Q_ASSERT(enableNotifiersObserver);
- CFRunLoopAddObserver(CFRunLoopGetMain(), enableNotifiersObserver, kCFRunLoopCommonModes);
+ CFRunLoopAddObserver(CFRunLoopGetCurrent(), enableNotifiersObserver, kCFRunLoopCommonModes);
}
}
diff --git a/src/corelib/kernel/qcore_mac.cpp b/src/corelib/kernel/qcore_mac.cpp
index b5df0db232..e78b2d1171 100644
--- a/src/corelib/kernel/qcore_mac.cpp
+++ b/src/corelib/kernel/qcore_mac.cpp
@@ -42,6 +42,7 @@
#include "qhash.h"
#include "qpair.h"
+#include "qmutex.h"
#include "qvarlengtharray.h"
QT_BEGIN_NAMESPACE
@@ -64,6 +65,7 @@ QCFString::operator CFStringRef() const
#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
+QT_MAC_WEAK_IMPORT(_os_log_default);
bool AppleUnifiedLogger::messageHandler(QtMsgType msgType, const QMessageLogContext &context,
const QString &message, const QString &optionalSubsystem)
{
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 6b11e90a4e..4ca9c2e996 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -40,8 +40,13 @@
#include <private/qcore_mac_p.h>
-#ifdef Q_OS_OSX
-#include <AppKit/NSText.h>
+#ifdef Q_OS_MACOS
+# include <AppKit/AppKit.h>
+# if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
+@interface NSApplication (MojaveForwardDeclarations)
+@property (strong) NSAppearance *effectiveAppearance NS_AVAILABLE_MAC(10_14);
+@end
+# endif
#endif
#if defined(QT_PLATFORM_UIKIT)
@@ -91,19 +96,20 @@ QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TY
QT_END_NAMESPACE
QT_USE_NAMESPACE
@interface QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) : NSObject
-{
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) {
NSAutoreleasePool **m_pool;
}
--(id)initWithPool:(NSAutoreleasePool**)pool;
-@end
-@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker)
--(id)initWithPool:(NSAutoreleasePool**)pool
+
+- (instancetype)initWithPool:(NSAutoreleasePool **)pool
{
- if (self = [super init])
+ if ((self = [self init]))
m_pool = pool;
return self;
}
--(void)dealloc
+
+- (void)dealloc
{
if (*m_pool) {
// The pool is still valid, which means we're not being drained from
@@ -165,6 +171,16 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool)
}
#endif // !QT_NO_DEBUG_STREAM
+#ifdef Q_OS_MACOS
+bool qt_mac_applicationIsInDarkMode()
+{
+ if (__builtin_available(macOS 10.14, *))
+ return [NSApp.effectiveAppearance.name hasSuffix:@"DarkAqua"];
+ else
+ return false;
+}
+#endif
+
bool qt_apple_isApplicationExtension()
{
static bool isExtension = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSExtension"];
@@ -432,16 +448,23 @@ void qt_apple_check_os_version()
version / 10000, version / 100 % 100, version % 100};
const NSOperatingSystemVersion current = NSProcessInfo.processInfo.operatingSystemVersion;
if (![NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:required]) {
- fprintf(stderr, "You can't use this version of %s with this version of %s. "
- "You have %s %ld.%ld.%ld. Qt requires %s %ld.%ld.%ld or later.\n",
- (reinterpret_cast<const NSString *>(
- NSBundle.mainBundle.infoDictionary[@"CFBundleName"]).UTF8String),
- os,
- os, long(current.majorVersion), long(current.minorVersion), long(current.patchVersion),
- os, long(required.majorVersion), long(required.minorVersion), long(required.patchVersion));
- abort();
+ NSDictionary *plist = NSBundle.mainBundle.infoDictionary;
+ NSString *applicationName = plist[@"CFBundleDisplayName"];
+ if (!applicationName)
+ applicationName = plist[@"CFBundleName"];
+ if (!applicationName)
+ applicationName = NSProcessInfo.processInfo.processName;
+
+ fprintf(stderr, "Sorry, \"%s\" can not be run on this version of %s. "
+ "Qt requires %s %ld.%ld.%ld or later, you have %s %ld.%ld.%ld.\n",
+ applicationName.UTF8String, os,
+ os, long(required.majorVersion), long(required.minorVersion), long(required.patchVersion),
+ os, long(current.majorVersion), long(current.minorVersion), long(current.patchVersion));
+
+ exit(1);
}
}
+Q_CONSTRUCTOR_FUNCTION(qt_apple_check_os_version);
// -------------------------------------------------------------------------
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index af939abaac..b14a494296 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -51,18 +51,20 @@
// We mean it.
//
+#include "private/qglobal_p.h"
+
#ifndef __IMAGECAPTURE__
# define __IMAGECAPTURE__
#endif
+// --------------------------------------------------------------------------
+
#if defined(QT_BOOTSTRAPPED)
#include <ApplicationServices/ApplicationServices.h>
#else
#include <CoreFoundation/CoreFoundation.h>
#endif
-#include "private/qglobal_p.h"
-
#ifdef __OBJC__
#include <Foundation/Foundation.h>
#endif
@@ -76,6 +78,8 @@
#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
#endif
+#define QT_MAC_WEAK_IMPORT(symbol) extern "C" decltype(symbol) symbol __attribute__((weak_import));
+
QT_BEGIN_NAMESPACE
template <typename T, typename U, U (*RetainFunction)(U), void (*ReleaseFunction)(U)>
class QAppleRefCounted
@@ -148,16 +152,16 @@ private:
QString string;
};
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MACOS
Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
+Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode();
#endif
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool);
#endif
-Q_CORE_EXPORT void qt_apple_check_os_version();
Q_CORE_EXPORT bool qt_apple_isApplicationExtension();
#if defined(Q_OS_MACOS) && !defined(QT_BOOTSTRAPPED)
@@ -186,35 +190,153 @@ Q_CORE_EXPORT AppleApplication *qt_apple_sharedApplication();
// --------------------------------------------------------------------------
-#if !defined(QT_BOOTSTRAPPED) && (QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12) || !defined(Q_OS_MACOS))
+#if !defined(QT_BOOTSTRAPPED)
#define QT_USE_APPLE_UNIFIED_LOGGING
QT_END_NAMESPACE
#include <os/log.h>
-
-// The compiler isn't smart enough to realize that we're calling these functions
-// guarded by __builtin_available, so we need to also tag each function with the
-// runtime requirements.
-#include <os/availability.h>
-#define OS_LOG_AVAILABILITY API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT AppleUnifiedLogger
{
public:
static bool messageHandler(QtMsgType msgType, const QMessageLogContext &context, const QString &message,
- const QString &subsystem = QString()) OS_LOG_AVAILABILITY;
+ const QString &subsystem = QString());
private:
- static os_log_type_t logTypeForMessageType(QtMsgType msgType) OS_LOG_AVAILABILITY;
- static os_log_t cachedLog(const QString &subsystem, const QString &category) OS_LOG_AVAILABILITY;
+ static os_log_type_t logTypeForMessageType(QtMsgType msgType);
+ static os_log_t cachedLog(const QString &subsystem, const QString &category);
};
-#undef OS_LOG_AVAILABILITY
-
#endif
// --------------------------------------------------------------------------
+#if !defined(QT_BOOTSTRAPPED)
+
+QT_END_NAMESPACE
+#include <os/activity.h>
+QT_BEGIN_NAMESPACE
+
+template <typename T> using QAppleOsType = QAppleRefCounted<T, void *, os_retain, os_release>;
+
+class Q_CORE_EXPORT QAppleLogActivity
+{
+public:
+ QAppleLogActivity() : activity(nullptr) {}
+ QAppleLogActivity(os_activity_t activity) : activity(activity) {}
+ ~QAppleLogActivity() { if (activity) leave(); }
+
+ QAppleLogActivity(const QAppleLogActivity &) = delete;
+ QAppleLogActivity& operator=(const QAppleLogActivity &) = delete;
+
+ QAppleLogActivity(QAppleLogActivity&& other)
+ : activity(other.activity), state(other.state) { other.activity = nullptr; }
+
+ QAppleLogActivity& operator=(QAppleLogActivity &&other)
+ {
+ if (this != &other) {
+ activity = other.activity;
+ state = other.state;
+ other.activity = nullptr;
+ }
+ return *this;
+ }
+
+ QAppleLogActivity&& enter()
+ {
+ if (activity)
+ os_activity_scope_enter(static_cast<os_activity_t>(*this), &state);
+ return std::move(*this);
+ }
+
+ void leave() {
+ if (activity)
+ os_activity_scope_leave(&state);
+ }
+
+ operator os_activity_t()
+ {
+ return reinterpret_cast<os_activity_t>(static_cast<void *>(activity));
+ }
+
+private:
+ // Work around API_AVAILABLE not working for templates by using void*
+ QAppleOsType<void *> activity;
+ os_activity_scope_state_s state;
+};
+
+#define QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent) []() { \
+ if (!(condition)) \
+ return QAppleLogActivity(); \
+ return QAppleLogActivity(os_activity_create(description, parent, OS_ACTIVITY_FLAG_DEFAULT)); \
+ }()
+
+#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
+#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)
+
+#define QT_OVERLOADED_MACRO(MACRO, ...) _QT_OVERLOADED_MACRO(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__)
+#define _QT_OVERLOADED_MACRO(MACRO, ARGC) _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC)
+#define _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##ARGC
+
+#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(condition, description, parent) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent)
+#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(true, description, parent)
+#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__)
+
+QT_MAC_WEAK_IMPORT(_os_activity_current);
+#define QT_APPLE_LOG_ACTIVITY2(condition, description) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, OS_ACTIVITY_CURRENT)
+#define QT_APPLE_LOG_ACTIVITY1(description) QT_APPLE_LOG_ACTIVITY2(true, description)
+#define QT_APPLE_LOG_ACTIVITY(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY, __VA_ARGS__)
+
+#define QT_APPLE_SCOPED_LOG_ACTIVITY(...) QAppleLogActivity scopedLogActivity = QT_APPLE_LOG_ACTIVITY(__VA_ARGS__).enter();
+
+#endif // !defined(QT_BOOTSTRAPPED)
+
+// -------------------------------------------------------------------------
+
+#if defined( __OBJC__)
+class QMacScopedObserver
+{
+public:
+ QMacScopedObserver() {}
+
+ template<typename Functor>
+ QMacScopedObserver(id object, NSNotificationName name, Functor callback) {
+ observer = [[NSNotificationCenter defaultCenter] addObserverForName:name
+ object:object queue:nil usingBlock:^(NSNotification *) {
+ callback();
+ }
+ ];
+ }
+
+ QMacScopedObserver(const QMacScopedObserver& other) = delete;
+ QMacScopedObserver(QMacScopedObserver&& other) : observer(other.observer) {
+ other.observer = nil;
+ }
+
+ QMacScopedObserver &operator=(const QMacScopedObserver& other) = delete;
+ QMacScopedObserver &operator=(QMacScopedObserver&& other) {
+ if (this != &other) {
+ remove();
+ observer = other.observer;
+ other.observer = nil;
+ }
+ return *this;
+ }
+
+ void remove() {
+ if (observer)
+ [[NSNotificationCenter defaultCenter] removeObserver:observer];
+ observer = nil;
+ }
+ ~QMacScopedObserver() { remove(); }
+
+private:
+ id observer = nil;
+};
+#endif
+
+// -------------------------------------------------------------------------
+
QT_END_NAMESPACE
#endif // QCORE_MAC_P_H
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 4e32f90964..1350a7aa94 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -58,9 +58,11 @@
#include <qtextcodec.h>
#ifndef QT_NO_QOBJECT
#include <qthread.h>
-#include <qthreadpool.h>
#include <qthreadstorage.h>
#include <private/qthread_p.h>
+#if QT_CONFIG(thread)
+#include <qthreadpool.h>
+#endif
#endif
#include <qelapsedtimer.h>
#include <qlibraryinfo.h>
@@ -116,6 +118,10 @@
# include <taskLib.h>
#endif
+#ifdef Q_OS_WASM
+#include <emscripten.h>
+#endif
+
#ifdef QT_BOOTSTRAPPED
#include <private/qtrace_p.h>
#else
@@ -268,9 +274,7 @@ typedef QList<QtStartUpFunction> QStartUpFuncList;
Q_GLOBAL_STATIC(QStartUpFuncList, preRList)
typedef QList<QtCleanUpFunction> QVFuncList;
Q_GLOBAL_STATIC(QVFuncList, postRList)
-#ifndef QT_NO_QOBJECT
static QBasicMutex globalRoutinesMutex;
-#endif
/*!
\internal
@@ -289,9 +293,7 @@ void qAddPreRoutine(QtStartUpFunction p)
// Due to C++11 parallel dynamic initialization, this can be called
// from multiple threads.
-#ifndef QT_NO_THREAD
QMutexLocker locker(&globalRoutinesMutex);
-#endif
list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines
}
@@ -300,9 +302,7 @@ void qAddPostRoutine(QtCleanUpFunction p)
QVFuncList *list = postRList();
if (!list)
return;
-#ifndef QT_NO_THREAD
QMutexLocker locker(&globalRoutinesMutex);
-#endif
list->prepend(p);
}
@@ -311,9 +311,7 @@ void qRemovePostRoutine(QtCleanUpFunction p)
QVFuncList *list = postRList();
if (!list)
return;
-#ifndef QT_NO_THREAD
QMutexLocker locker(&globalRoutinesMutex);
-#endif
list->removeAll(p);
}
@@ -324,9 +322,7 @@ static void qt_call_pre_routines()
QVFuncList list;
{
-#ifndef QT_NO_THREAD
QMutexLocker locker(&globalRoutinesMutex);
-#endif
// Unlike qt_call_post_routines, we don't empty the list, because
// Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects
// the function to be executed every time QCoreApplication is created.
@@ -345,9 +341,7 @@ void Q_CORE_EXPORT qt_call_post_routines()
QVFuncList list;
{
// extract the current list and make the stored list empty
-#ifndef QT_NO_THREAD
QMutexLocker locker(&globalRoutinesMutex);
-#endif
qSwap(*postRList, list);
}
@@ -466,9 +460,6 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
, q_ptr(0)
#endif
{
-#if defined(Q_OS_DARWIN)
- qt_apple_check_os_version();
-#endif
app_compile_version = flags & 0xffffff;
static const char *const empty = "";
if (argc == 0 || argv == 0) {
@@ -499,6 +490,13 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
QCoreApplicationPrivate::~QCoreApplicationPrivate()
{
+#ifdef Q_OS_WASM
+ EM_ASM(
+ // unmount persistent directory as IDBFS
+ // see also QTBUG-70002
+ FS.unmount('/home/web_user');
+ );
+#endif
#ifndef QT_NO_QOBJECT
cleanupThreadData();
#endif
@@ -513,7 +511,7 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate()
void QCoreApplicationPrivate::cleanupThreadData()
{
if (threadData && !threadData_clean) {
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
void *data = &threadData->tls;
QThreadStorageData::finish((void **)data);
#endif
@@ -540,7 +538,7 @@ void QCoreApplicationPrivate::createEventDispatcher()
Q_Q(QCoreApplication);
QThreadData *data = QThreadData::current();
Q_ASSERT(!data->hasEventDispatcher());
- eventDispatcher = QThreadPrivate::createEventDispatcher(data);
+ eventDispatcher = data->createEventDispatcher();
eventDispatcher->setParent(q);
}
@@ -777,7 +775,7 @@ QCoreApplication::QCoreApplication(int &argc, char **argv
void QCoreApplicationPrivate::init()
{
- Q_TRACE(qcoreapplicationprivate_init_entry);
+ Q_TRACE(QCoreApplicationPrivate_init_entry);
#if defined(Q_OS_MACOS)
QMacAutoReleasePool pool;
@@ -790,6 +788,17 @@ void QCoreApplicationPrivate::init()
Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = q;
+#ifdef Q_OS_WASM
+ EM_ASM(
+ // mount and sync persistent filesystem to sandbox
+ FS.mount(IDBFS, {}, '/home/web_user');
+ FS.syncfs(true, function(err) {
+ if (err)
+ Module.print(err);
+ });
+ );
+#endif
+
// Store app name/version (so they're still available after QCoreApplication is destroyed)
if (!coreappdata()->applicationNameSet)
coreappdata()->application = appName();
@@ -872,7 +881,7 @@ void QCoreApplicationPrivate::init()
is_app_running = true; // No longer starting up.
#endif
- Q_TRACE(qcoreapplicationprivate_init_exit);
+ Q_TRACE(QCoreApplicationPrivate_init_exit);
}
/*!
@@ -888,7 +897,7 @@ QCoreApplication::~QCoreApplication()
QCoreApplicationPrivate::is_app_running = false;
#endif
-#if !defined(QT_NO_THREAD)
+#if QT_CONFIG(thread)
// Synchronize and stop the global thread pool threads.
QThreadPool *globalThreadPool = 0;
QT_TRY {
@@ -1185,16 +1194,31 @@ bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, Q
*/
bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
{
+ // Note: when adjusting the tracepoints in here
+ // consider adjusting QApplicationPrivate::notify_helper too.
+ Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type());
+
// send to all application event filters (only does anything in the main thread)
if (QCoreApplication::self
&& receiver->d_func()->threadData->thread == mainThread()
- && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event))
+ && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
+ Q_TRACE(QCoreApplication_notify_event_filtered, receiver, event, event->type());
return true;
+ }
// send to all receiver event filters
- if (sendThroughObjectEventFilters(receiver, event))
+ if (sendThroughObjectEventFilters(receiver, event)) {
+ Q_TRACE(QCoreApplication_notify_event_filtered, receiver, event, event->type());
return true;
+ }
+
+ Q_TRACE(QCoreApplication_notify_before_delivery, receiver, event, event->type());
+
// deliver the event
- return receiver->event(event);
+ const bool consumed = receiver->event(event);
+
+ Q_TRACE(QCoreApplication_notify_after_delivery, receiver, event, event->type(), consumed);
+
+ return consumed;
}
/*!
@@ -1399,6 +1423,7 @@ void QCoreApplication::exit(int returnCode)
QCoreApplication management of posted events
*****************************************************************************/
+#ifndef QT_NO_QOBJECT
/*!
\fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
@@ -1413,6 +1438,28 @@ void QCoreApplication::exit(int returnCode)
\sa postEvent(), notify()
*/
+bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
+{
+ Q_TRACE(QCoreApplication_sendEvent, receiver, event, event->type());
+
+ if (event)
+ event->spont = false;
+ return notifyInternal2(receiver, event);
+}
+
+/*!
+ \internal
+*/
+bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
+{
+ Q_TRACE(QCoreApplication_sendSpontaneousEvent, receiver, event, event->type());
+
+ if (event)
+ event->spont = true;
+ return notifyInternal2(receiver, event);
+}
+
+#endif // QT_NO_QOBJECT
/*!
\since 4.3
@@ -1441,6 +1488,8 @@ void QCoreApplication::exit(int returnCode)
*/
void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
{
+ Q_TRACE(QCoreApplication_postEvent_entry, receiver, event, event->type());
+
if (receiver == 0) {
qWarning("QCoreApplication::postEvent: Unexpected null receiver");
delete event;
@@ -1477,6 +1526,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
// if this is one of the compressible events, do compression
if (receiver->d_func()->postedEvents
&& self && self->compressEvent(event, receiver, &data->postEventList)) {
+ Q_TRACE(QCoreApplication_postEvent_event_compressed, receiver, event);
return;
}
@@ -1508,6 +1558,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
// delete the event on exceptions to protect against memory leaks till the event is
// properly owned in the postEventList
QScopedPointer<QEvent> eventDeleter(event);
+ Q_TRACE(QCoreApplication_postEvent_event_posted, receiver, event, event->type());
data->postEventList.addEvent(QPostEvent(receiver, event, priority));
eventDeleter.take();
event->posted = true;
@@ -1766,8 +1817,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
If \a receiver is null, the events of \a eventType are removed for
all objects. If \a eventType is 0, all the events are removed for
\a receiver. You should never call this function with \a eventType
- of 0. If you do call it in this way, be aware that killing events
- may cause \a receiver to break one or more invariants.
+ of 0.
\threadsafe
*/
@@ -1818,9 +1868,7 @@ void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
}
locker.unlock();
- for (int i = 0; i < events.count(); ++i) {
- delete events[i];
- }
+ qDeleteAll(events);
}
/*!
@@ -1889,7 +1937,7 @@ bool QCoreApplication::event(QEvent *e)
\value UnicodeUTF8 UTF-8.
\omitvalue Latin1
- \omitvalue DefaultCodec UTF-8.
+ \omitvalue DefaultCodec \omit UTF-8. \endomit
\omitvalue CodecForTr
\sa QObject::tr(), QString::fromUtf8()
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index a886c9d1d2..3581970765 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -229,14 +229,6 @@ private:
friend class QClassFactory;
};
-#ifndef QT_NO_QOBJECT
-inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
-{ if (event) event->spont = false; return notifyInternal2(receiver, event); }
-
-inline bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
-{ if (event) event->spont = true; return notifyInternal2(receiver, event); }
-#endif
-
#ifdef QT_NO_DEPRECATED
# define QT_DECLARE_DEPRECATED_TR_FUNCTIONS(context)
#else
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 00548365d2..0109e2c658 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -192,7 +192,7 @@ Q_CORE_EXPORT int qWinAppCmdShow() // get main window sho
#if defined(Q_OS_WIN) && !defined(QT_NO_DEBUG_STREAM)
/*****************************************************************************
Convenience functions for convert WM_* messages into human readable strings,
- including a nifty QDebug operator<< for simpel QDebug() << msg output.
+ including a nifty QDebug operator<< for simple QDebug() << msg output.
*****************************************************************************/
QT_BEGIN_INCLUDE_NAMESPACE
#include <windowsx.h>
@@ -207,10 +207,48 @@ QT_END_INCLUDE_NAMESPACE
// The values below should never change. Note that none of the usual
// WM_...FIRST & WM_...LAST values are in the list, as they normally have other
// WM_... representations
-struct KnownWM {
- uint WM;
- const char* str;
-} knownWM[] =
+
+template <class IntType>
+struct QWinMessageMapping {
+ IntType value;
+ const char *name;
+};
+
+#define FLAG_ENTRY(x) {x, #x} // for populating arrays
+
+// Looks up a value in a list of QWinMessageMapping
+template <class IntType>
+static const char *findWinMessageMapping(const QWinMessageMapping<IntType> *haystack,
+ size_t haystackSize,
+ IntType needle)
+{
+ for (auto p = haystack, end = haystack + haystackSize; p < end; ++p) {
+ if (p->value == needle)
+ return p->name;
+ }
+ return nullptr;
+}
+
+// Format flags using a mapping as "Flag1 | Flag2"...
+template <class IntType>
+static QString flagsValue(const QWinMessageMapping<IntType> *haystack,
+ size_t haystackSize, IntType value)
+{
+ QString result;
+ for (auto p = haystack, end = haystack + haystackSize; p < end; ++p) {
+ if ((p->value & value) == p->value) {
+ if (!result.isEmpty())
+ result += QLatin1String(" | ");
+ result += QLatin1String(p->name);
+ }
+ }
+ return result;
+}
+
+// Looks up the WM_ message in the table inside
+static const char *findWMstr(uint msg)
+{
+ static const QWinMessageMapping<uint> knownWM[] =
{{ 0x0000, "WM_NULL" },
{ 0x0001, "WM_CREATE" },
{ 0x0002, "WM_DESTROY" },
@@ -505,84 +543,146 @@ struct KnownWM {
{ 0x038E, "WM_PENWINFIRST + 14" },
{ 0x038F, "WM_PENWINLAST" },
{ 0x0400, "WM_USER" },
- { 0x8000, "WM_APP" },
- { 0,0 }}; // End of known messages
+ { 0x8000, "WM_APP" }
+ };
-// Looks up the WM_ message in the table above
-static const char* findWMstr(uint msg)
-{
- uint i = 0;
- const char* result = 0;
- // Known WM_'s
- while (knownWM[i].str && (knownWM[i].WM != msg))
- ++i;
- result = knownWM[i].str;
- return result;
-};
+ return findWinMessageMapping(knownWM, sizeof(knownWM) / sizeof(knownWM[0]), msg);
+}
-// Convenience function for converting flags and values into readable strings
-struct FLAG_STRING_STRUCT
+static const char *activateParameter(uint p)
{
- uint value;
- const char* str;
-};
+ static const QWinMessageMapping<uint> activeEnum[] = {
+ {WA_ACTIVE, "Activate"}, {WA_INACTIVE, "Deactivate"},
+ {WA_CLICKACTIVE, "Activate by mouseclick"}
+ };
-FLAG_STRING_STRUCT FLAG_STRING(uint value = 0, const char *c = 0)
+ return findWinMessageMapping(activeEnum, sizeof(activeEnum) / sizeof(activeEnum[0]), p);
+}
+
+static QString styleFlags(uint style)
{
- FLAG_STRING_STRUCT s = {value, c};
- return s;
+ static const QWinMessageMapping<uint> styleFlags[] = {
+ FLAG_ENTRY(WS_BORDER), FLAG_ENTRY(WS_CAPTION), FLAG_ENTRY(WS_CHILD),
+ FLAG_ENTRY(WS_CLIPCHILDREN), FLAG_ENTRY(WS_CLIPSIBLINGS),
+ FLAG_ENTRY(WS_DISABLED), FLAG_ENTRY(WS_DLGFRAME), FLAG_ENTRY(WS_GROUP),
+ FLAG_ENTRY(WS_HSCROLL), FLAG_ENTRY(WS_OVERLAPPED),
+ FLAG_ENTRY(WS_OVERLAPPEDWINDOW), FLAG_ENTRY(WS_ICONIC),
+ FLAG_ENTRY(WS_MAXIMIZE), FLAG_ENTRY(WS_MAXIMIZEBOX),
+ FLAG_ENTRY(WS_MINIMIZE), FLAG_ENTRY(WS_MINIMIZEBOX),
+ FLAG_ENTRY(WS_OVERLAPPEDWINDOW), FLAG_ENTRY(WS_POPUP),
+ FLAG_ENTRY(WS_POPUPWINDOW), FLAG_ENTRY(WS_SIZEBOX),
+ FLAG_ENTRY(WS_SYSMENU), FLAG_ENTRY(WS_TABSTOP), FLAG_ENTRY(WS_THICKFRAME),
+ FLAG_ENTRY(WS_TILED), FLAG_ENTRY(WS_TILEDWINDOW), FLAG_ENTRY(WS_VISIBLE),
+ FLAG_ENTRY(WS_VSCROLL)
+ };
+
+ return flagsValue(styleFlags, sizeof(styleFlags) / sizeof(styleFlags[0]), style);
}
-#define FLGSTR(x) FLAG_STRING(x, #x)
+static QString exStyleFlags(uint exStyle)
+{
+ static const QWinMessageMapping<uint> exStyleFlags[] = {
+ FLAG_ENTRY(WS_EX_ACCEPTFILES), FLAG_ENTRY(WS_EX_APPWINDOW),
+ FLAG_ENTRY(WS_EX_CLIENTEDGE), FLAG_ENTRY(WS_EX_DLGMODALFRAME),
+ FLAG_ENTRY(WS_EX_LEFT), FLAG_ENTRY(WS_EX_LEFTSCROLLBAR),
+ FLAG_ENTRY(WS_EX_LTRREADING), FLAG_ENTRY(WS_EX_MDICHILD),
+ FLAG_ENTRY(WS_EX_NOACTIVATE), FLAG_ENTRY(WS_EX_NOPARENTNOTIFY),
+ FLAG_ENTRY(WS_EX_OVERLAPPEDWINDOW), FLAG_ENTRY(WS_EX_PALETTEWINDOW),
+ FLAG_ENTRY(WS_EX_RIGHT), FLAG_ENTRY(WS_EX_RIGHTSCROLLBAR),
+ FLAG_ENTRY(WS_EX_RTLREADING), FLAG_ENTRY(WS_EX_STATICEDGE),
+ FLAG_ENTRY(WS_EX_TOOLWINDOW), FLAG_ENTRY(WS_EX_TOPMOST),
+ FLAG_ENTRY(WS_EX_TRANSPARENT), FLAG_ENTRY(WS_EX_WINDOWEDGE)
+ };
+
+ return flagsValue(exStyleFlags, sizeof(exStyleFlags) / sizeof(exStyleFlags[0]), exStyle);
+}
-// Returns an ORed (" | ") together string for the flags active in the actual
-// value. (...) must consist of FLAG_STRING, with a FLAG_STRING() as the last
-// value in the list passed to the function
-QString flagCheck(uint actual, ...)
+static const char *imeCommand(uint cmd)
{
- va_list ap;
- va_start(ap, actual);
+ static const QWinMessageMapping<uint> commands[] = {
+ FLAG_ENTRY(IMN_CHANGECANDIDATE), FLAG_ENTRY(IMN_CLOSECANDIDATE),
+ FLAG_ENTRY(IMN_CLOSESTATUSWINDOW), FLAG_ENTRY(IMN_GUIDELINE),
+ FLAG_ENTRY(IMN_OPENCANDIDATE), FLAG_ENTRY(IMN_OPENSTATUSWINDOW),
+ FLAG_ENTRY(IMN_SETCANDIDATEPOS), FLAG_ENTRY(IMN_SETCOMPOSITIONFONT),
+ FLAG_ENTRY(IMN_SETCOMPOSITIONWINDOW), FLAG_ENTRY(IMN_SETCONVERSIONMODE),
+ FLAG_ENTRY(IMN_SETOPENSTATUS), FLAG_ENTRY(IMN_SETSENTENCEMODE),
+ FLAG_ENTRY(IMN_SETSTATUSWINDOWPOS)
+ };
+
+ return findWinMessageMapping(commands, sizeof(commands) / sizeof(commands[0]), cmd);
+}
- QString result;
- int count = 0;
- FLAG_STRING_STRUCT v;
- while((v=va_arg(ap,FLAG_STRING_STRUCT)).str) {
- if ((actual & v.value) == v.value) {
- if (count++)
- result += QLatin1String(" | ");
- result += QString::fromLatin1(v.str);
- }
- }
- va_end(ap);
- return result;
-};
+static QString imeShowFlags(uint flags)
+{
+ static const QWinMessageMapping<uint> showFlags[] = {
+ FLAG_ENTRY(ISC_SHOWUICOMPOSITIONWINDOW),
+ FLAG_ENTRY(ISC_SHOWUICANDIDATEWINDOW),
+ FLAG_ENTRY(ISC_SHOWUICANDIDATEWINDOW << 1),
+ FLAG_ENTRY(ISC_SHOWUICANDIDATEWINDOW << 2),
+ FLAG_ENTRY(ISC_SHOWUICANDIDATEWINDOW << 3)
+ };
+
+ return flagsValue(showFlags, sizeof(showFlags) / sizeof(showFlags[0]), flags);
+}
-// Returns the string representation of the value in 'actual'. (...) must
-// consist of FLAG_STRING, with a FLAG_STRING() as the last value in the list
-// passed to the function
-QString valueCheck(uint actual, ...)
+static const char *wmSizeParam(uint p)
{
- va_list ap;
- va_start(ap, actual);
+ static const QWinMessageMapping<uint> sizeParams[] = {
+ FLAG_ENTRY(SIZE_MAXHIDE), FLAG_ENTRY(SIZE_MAXIMIZED),
+ FLAG_ENTRY(SIZE_MAXSHOW), FLAG_ENTRY(SIZE_MINIMIZED),
+ FLAG_ENTRY(SIZE_RESTORED)
+ };
- QString result;
- FLAG_STRING_STRUCT v;
- while((v=va_arg(ap,FLAG_STRING_STRUCT)).str && (actual != v.value))
- ;
- result = QString::fromLatin1(v.str);
+ return findWinMessageMapping(sizeParams, sizeof(sizeParams) / sizeof(sizeParams[0]), p);
+}
- va_end(ap);
- return result;
-};
+static QString virtualKeys(uint vk)
+{
+ static const QWinMessageMapping<uint> keys[] = {
+ FLAG_ENTRY(MK_CONTROL), FLAG_ENTRY(MK_LBUTTON), FLAG_ENTRY(MK_MBUTTON),
+ FLAG_ENTRY(MK_RBUTTON), FLAG_ENTRY(MK_SHIFT), FLAG_ENTRY(MK_XBUTTON1),
+ FLAG_ENTRY(MK_XBUTTON2)
+ };
-#ifdef Q_CC_BOR
+ return flagsValue(keys, sizeof(keys) / sizeof(keys[0]), vk);
+}
-QString decodeMSG(const MSG& msg)
+static QString winPosFlags(uint f)
{
- return QString::fromLatin1("THis is not supported on Borland");
+ static const QWinMessageMapping<uint> winPosValues[] = {
+ FLAG_ENTRY(SWP_DRAWFRAME), FLAG_ENTRY(SWP_FRAMECHANGED),
+ FLAG_ENTRY(SWP_HIDEWINDOW), FLAG_ENTRY(SWP_NOACTIVATE),
+ FLAG_ENTRY(SWP_NOCOPYBITS), FLAG_ENTRY(SWP_NOMOVE),
+ FLAG_ENTRY(SWP_NOOWNERZORDER), FLAG_ENTRY(SWP_NOREDRAW),
+ FLAG_ENTRY(SWP_NOREPOSITION), FLAG_ENTRY(SWP_NOSENDCHANGING),
+ FLAG_ENTRY(SWP_NOSIZE), FLAG_ENTRY(SWP_NOZORDER),
+ FLAG_ENTRY(SWP_SHOWWINDOW)
+ };
+
+ return flagsValue(winPosValues, sizeof(winPosValues) / sizeof(winPosValues[0]), f);
}
-#else
+static const char *winPosInsertAfter(quintptr h)
+{
+ static const QWinMessageMapping<quintptr> insertAfterValues[] = {
+ {quintptr(HWND_BOTTOM), "HWND_BOTTOM"},
+ {quintptr(HWND_NOTOPMOST), "HWND_NOTOPMOST"},
+ {quintptr(HWND_TOP), "HWND_TOP"},
+ {quintptr(HWND_TOPMOST), "HWND_TOPMOST"}
+ };
+ return findWinMessageMapping(insertAfterValues, sizeof(insertAfterValues) / sizeof(insertAfterValues[0]), h);
+}
+
+static const char *sessionMgrLogOffOption(uint p)
+{
+ static const QWinMessageMapping<uint> values[] = {
+ {ENDSESSION_CLOSEAPP, "Close application"},
+ {ENDSESSION_CRITICAL, "Force application end"},
+ {ENDSESSION_LOGOFF, "User logoff"}
+ };
+
+ return findWinMessageMapping(values, sizeof(values) / sizeof(values[0]), p);
+}
// Returns a "human readable" string representation of the MSG and the
// information it points to
@@ -590,400 +690,177 @@ QString decodeMSG(const MSG& msg)
{
const WPARAM wParam = msg.wParam;
const LPARAM lParam = msg.lParam;
- QString wmmsg = QString::fromLatin1(findWMstr(msg.message));
- // Unknown WM_, so use number
- if (wmmsg.isEmpty())
- wmmsg = QString::fromLatin1("WM_(%1)").arg(msg.message);
-
- const QString rawParameters = QString::asprintf("hwnd(0x%p) ", (void *)msg.hwnd);
+ QString message;
// Custom WM_'s
if (msg.message > WM_APP)
- wmmsg = QString::fromLatin1("WM_APP + %1").arg(msg.message - WM_APP);
+ message= QString::fromLatin1("WM_APP + %1").arg(msg.message - WM_APP);
else if (msg.message > WM_USER)
- wmmsg = QString::fromLatin1("WM_USER + %1").arg(msg.message - WM_USER);
+ message = QString::fromLatin1("WM_USER + %1").arg(msg.message - WM_USER);
+ else if (const char *wmmsgC = findWMstr(msg.message))
+ message = QString::fromLatin1(wmmsgC);
+ else
+ message = QString::fromLatin1("WM_(%1)").arg(msg.message); // Unknown WM_, so use number
+
+ // Yes, we want to give the WM_ names 20 chars of space before showing the
+ // decoded message, since some of the common messages are quite long, and
+ // we don't want the decoded information to vary in output position
+ if (message.size() < 20)
+ message.prepend(QString(20 - message.size(), QLatin1Char(' ')));
+ message += QLatin1String(": ");
+
+ const QString hwndS = QString::asprintf("(%p)", reinterpret_cast<void *>(msg.hwnd));
+ const QString wParamS = QString::asprintf("(%p)", reinterpret_cast<void *>(wParam));
+ const QString lParamS = QString::asprintf("(%p)", reinterpret_cast<void *>(lParam));
QString parameters;
switch (msg.message) {
-#ifdef WM_ACTIVATE
case WM_ACTIVATE:
- {
- QString activation = valueCheck(wParam,
- FLAG_STRING(WA_ACTIVE, "Activate"),
- FLAG_STRING(WA_INACTIVE, "Deactivate"),
- FLAG_STRING(WA_CLICKACTIVE, "Activate by mouseclick"),
- FLAG_STRING());
- parameters = QString::asprintf("%s Hwnd (0x%p)", activation.toLatin1().data(), (void *)msg.hwnd);
- }
+ if (const char *a = activateParameter(uint(wParam)))
+ parameters += QLatin1String(a);
+ parameters += QLatin1String(" Hwnd ") + hwndS;
break;
-#endif
-#ifdef WM_CAPTURECHANGED
case WM_CAPTURECHANGED:
- parameters = QString::asprintf("Hwnd gaining capture (0x%p)", (void *)lParam);
+ parameters = QLatin1String("Hwnd gaining capture ") + hwndS;
break;
-#endif
-#ifdef WM_CREATE
case WM_CREATE:
{
- LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
- QString styles = flagCheck(lpcs->style,
- FLGSTR(WS_BORDER),
- FLGSTR(WS_CAPTION),
- FLGSTR(WS_CHILD),
- FLGSTR(WS_CLIPCHILDREN),
- FLGSTR(WS_CLIPSIBLINGS),
- FLGSTR(WS_DISABLED),
- FLGSTR(WS_DLGFRAME),
- FLGSTR(WS_GROUP),
- FLGSTR(WS_HSCROLL),
- FLGSTR(WS_OVERLAPPED),
-#if defined(WS_OVERLAPPEDWINDOW) && (WS_OVERLAPPEDWINDOW != 0)
- FLGSTR(WS_OVERLAPPEDWINDOW),
-#endif
-#ifdef WS_ICONIC
- FLGSTR(WS_ICONIC),
-#endif
- FLGSTR(WS_MAXIMIZE),
- FLGSTR(WS_MAXIMIZEBOX),
- FLGSTR(WS_MINIMIZE),
- FLGSTR(WS_MINIMIZEBOX),
- FLGSTR(WS_OVERLAPPEDWINDOW),
- FLGSTR(WS_POPUP),
-#ifdef WS_POPUPWINDOW
- FLGSTR(WS_POPUPWINDOW),
-#endif
- FLGSTR(WS_SIZEBOX),
- FLGSTR(WS_SYSMENU),
- FLGSTR(WS_TABSTOP),
- FLGSTR(WS_THICKFRAME),
-#ifdef WS_TILED
- FLGSTR(WS_TILED),
-#endif
-#ifdef WS_TILEDWINDOW
- FLGSTR(WS_TILEDWINDOW),
-#endif
- FLGSTR(WS_VISIBLE),
- FLGSTR(WS_VSCROLL),
- FLAG_STRING());
-
- QString exStyles = flagCheck(lpcs->dwExStyle,
-#ifdef WS_EX_ACCEPTFILES
- FLGSTR(WS_EX_ACCEPTFILES),
-#endif
-#ifdef WS_EX_APPWINDOW
- FLGSTR(WS_EX_APPWINDOW),
-#endif
- FLGSTR(WS_EX_CLIENTEDGE),
- FLGSTR(WS_EX_DLGMODALFRAME),
-#ifdef WS_EX_LEFT
- FLGSTR(WS_EX_LEFT),
-#endif
- FLGSTR(WS_EX_LEFTSCROLLBAR),
-#ifdef WS_EX_LTRREADING
- FLGSTR(WS_EX_LTRREADING),
-#endif
-#ifdef WS_EX_MDICHILD
- FLGSTR(WS_EX_MDICHILD),
-#endif
-#ifdef WS_EX_NOACTIVATE
- FLGSTR(WS_EX_NOACTIVATE),
-#endif
-#ifdef WS_EX_NOANIMATION
- FLGSTR(WS_EX_NOANIMATION),
-#endif
- FLGSTR(WS_EX_NOPARENTNOTIFY),
- FLGSTR(WS_EX_OVERLAPPEDWINDOW),
-#ifdef WS_EX_PALETTEWINDOW
- FLGSTR(WS_EX_PALETTEWINDOW),
-#endif
-#ifdef WS_EX_RIGHT
- FLGSTR(WS_EX_RIGHT),
-#endif
-#ifdef WS_EX_RIGHTSCROLLBAR
- FLGSTR(WS_EX_RIGHTSCROLLBAR),
-#endif
-#ifdef WS_EX_RTLREADING
- FLGSTR(WS_EX_RTLREADING),
-#endif
- FLGSTR(WS_EX_STATICEDGE),
- FLGSTR(WS_EX_TOOLWINDOW),
- FLGSTR(WS_EX_TOPMOST),
-#ifdef WS_EX_TRANSPARENT
- FLGSTR(WS_EX_TRANSPARENT),
-#endif
- FLGSTR(WS_EX_WINDOWEDGE),
-#ifdef WS_EX_CAPTIONOKBTN
- FLGSTR(WS_EX_CAPTIONOKBTN),
-#endif
- FLAG_STRING());
-
+ auto lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
QString className;
- if (lpcs->lpszClass != 0) {
- if (HIWORD(lpcs->lpszClass) == 0) // Atom
- className = QString::number(LOWORD(lpcs->lpszClass), 16);
- else // String
- className = QString((QChar*)lpcs->lpszClass,
- (int)wcslen(reinterpret_cast<const wchar_t *>(lpcs->lpszClass)));
+ if (lpcs->lpszClass != nullptr) {
+ className = HIWORD(lpcs->lpszClass) == 0
+ ? QString::number(LOWORD(lpcs->lpszClass), 16) // Atom
+ : QString::fromWCharArray(lpcs->lpszClass);
}
- QString windowName;
- if (lpcs->lpszName != 0)
- windowName = QString((QChar*)lpcs->lpszName,
- (int)wcslen(reinterpret_cast<const wchar_t *>(lpcs->lpszName)));
+ const QString windowName = lpcs->lpszName
+ ? QString::fromWCharArray(lpcs->lpszName) : QString();
parameters = QString::asprintf("x,y(%4d,%4d) w,h(%4d,%4d) className(%s) windowName(%s) parent(0x%p) style(%s) exStyle(%s)",
- lpcs->x, lpcs->y, lpcs->cx, lpcs->cy, className.toLatin1().data(),
- windowName.toLatin1().data(), (void *)lpcs->hwndParent,
- styles.toLatin1().data(), exStyles.toLatin1().data());
+ lpcs->x, lpcs->y, lpcs->cx, lpcs->cy,
+ className.toLatin1().constData(),
+ windowName.toLatin1().constData(),
+ reinterpret_cast<void *>(lpcs->hwndParent),
+ styleFlags(uint(lpcs->style)).toLatin1().constData(),
+ exStyleFlags(lpcs->dwExStyle).toLatin1().constData());
}
break;
-#endif
-#ifdef WM_DESTROY
case WM_DESTROY:
- parameters = QString::asprintf("Destroy hwnd (0x%p)", (void *)msg.hwnd);
+ parameters = QLatin1String("Destroy hwnd ") + hwndS;
break;
-#endif
-#ifdef WM_IME_NOTIFY
case WM_IME_NOTIFY:
{
- QString imnCommand = valueCheck(wParam,
- FLGSTR(IMN_CHANGECANDIDATE),
- FLGSTR(IMN_CLOSECANDIDATE),
- FLGSTR(IMN_CLOSESTATUSWINDOW),
- FLGSTR(IMN_GUIDELINE),
- FLGSTR(IMN_OPENCANDIDATE),
- FLGSTR(IMN_OPENSTATUSWINDOW),
- FLGSTR(IMN_SETCANDIDATEPOS),
- FLGSTR(IMN_SETCOMPOSITIONFONT),
- FLGSTR(IMN_SETCOMPOSITIONWINDOW),
- FLGSTR(IMN_SETCONVERSIONMODE),
- FLGSTR(IMN_SETOPENSTATUS),
- FLGSTR(IMN_SETSENTENCEMODE),
- FLGSTR(IMN_SETSTATUSWINDOWPOS),
- FLAG_STRING());
- parameters = QString::asprintf("Command(%s : 0x%p)", imnCommand.toLatin1().data(), (void *)lParam);
+ parameters = QLatin1String("Command(");
+ if (const char *c = imeCommand(uint(wParam)))
+ parameters += QLatin1String(c);
+ parameters += QLatin1String(" : ") + lParamS;
}
break;
-#endif
-#ifdef WM_IME_SETCONTEXT
case WM_IME_SETCONTEXT:
- {
- bool fSet = (BOOL)wParam;
- DWORD fShow = (DWORD)lParam;
- QString showFlgs = flagCheck(fShow,
-#ifdef ISC_SHOWUICOMPOSITIONWINDOW
- FLGSTR(ISC_SHOWUICOMPOSITIONWINDOW),
-#endif
-#ifdef ISC_SHOWUIGUIDWINDOW
- FLGSTR(ISC_SHOWUIGUIDWINDOW),
-#endif
-#ifdef ISC_SHOWUISOFTKBD
- FLGSTR(ISC_SHOWUISOFTKBD),
-#endif
- FLGSTR(ISC_SHOWUICANDIDATEWINDOW),
- FLGSTR(ISC_SHOWUICANDIDATEWINDOW << 1),
- FLGSTR(ISC_SHOWUICANDIDATEWINDOW << 2),
- FLGSTR(ISC_SHOWUICANDIDATEWINDOW << 3),
- FLAG_STRING());
- parameters = QString::asprintf("Input context(%s) Show flags(%s)", (fSet? "Active" : "Inactive"), showFlgs.toLatin1().data());
- }
+ parameters = QLatin1String("Input context(")
+ + QLatin1String(wParam == TRUE ? "Active" : "Inactive")
+ + QLatin1String(") Show flags(")
+ + imeShowFlags(DWORD(lParam)) + QLatin1Char(')');
break;
-#endif
-#ifdef WM_KILLFOCUS
case WM_KILLFOCUS:
- parameters = QString::asprintf("Hwnd gaining keyboard focus (0x%p)", (void *)wParam);
+ parameters = QLatin1String("Hwnd gaining keyboard focus ") + wParamS;
break;
-#endif
-#ifdef WM_CHAR
case WM_CHAR:
-#endif
-#ifdef WM_IME_CHAR
case WM_IME_CHAR:
-#endif
-#ifdef WM_KEYDOWN
case WM_KEYDOWN:
-#endif
-#ifdef WM_KEYUP
case WM_KEYUP:
{
- int nVirtKey = (int)wParam;
- long lKeyData = (long)lParam;
+ const int nVirtKey = int(wParam);
+ const long lKeyData = long(lParam);
int repCount = (lKeyData & 0xffff); // Bit 0-15
int scanCode = (lKeyData & 0xf0000) >> 16; // Bit 16-23
bool contextCode = !!(lKeyData & 0x20000000); // Bit 29
bool prevState = !!(lKeyData & 0x40000000); // Bit 30
bool transState = !!(lKeyData & 0x80000000); // Bit 31
- parameters = QString::asprintf("Virual-key(0x%x) Scancode(%d) Rep(%d) Contextcode(%d), Prev state(%d), Trans state(%d)",
- nVirtKey, scanCode, repCount, contextCode, prevState, transState);
+ parameters = QString::asprintf("Virtual-key(0x%x) Scancode(%d) Rep(%d) Contextcode(%d), Prev state(%d), Trans state(%d)",
+ nVirtKey, scanCode, repCount,
+ contextCode, prevState, transState);
}
break;
-#endif
-#ifdef WM_INPUTLANGCHANGE
case WM_INPUTLANGCHANGE:
parameters = QStringLiteral("Keyboard layout changed");
break;
-#endif // WM_INPUTLANGCHANGE
-#ifdef WM_NCACTIVATE
case WM_NCACTIVATE:
- {
parameters = (msg.wParam? QLatin1String("Active Titlebar") : QLatin1String("Inactive Titlebar"));
- }
break;
-#endif
-#ifdef WM_MOUSEACTIVATE
case WM_MOUSEACTIVATE:
{
- QString mouseMsg = QString::fromLatin1(findWMstr(HIWORD(lParam)));
- parameters = QString::asprintf("TLW(0x%p) HittestCode(0x%x) MouseMsg(%s)", (void *)wParam, LOWORD(lParam), mouseMsg.toLatin1().data());
+ const char *mouseMsg = findWMstr(HIWORD(lParam));
+ parameters = QString::asprintf("TLW(0x%p) HittestCode(0x%x) MouseMsg(%s)",
+ reinterpret_cast<void *>(wParam),
+ LOWORD(lParam), mouseMsg ? mouseMsg : "");
}
break;
-#endif
-#ifdef WM_MOUSELEAVE
case WM_MOUSELEAVE:
break; // wParam & lParam not used
-#endif
-#ifdef WM_MOUSEHOVER
case WM_MOUSEHOVER:
-#endif
-#ifdef WM_MOUSEWHEEL
case WM_MOUSEWHEEL:
-#endif
-#ifdef WM_MOUSEHWHEEL
case WM_MOUSEHWHEEL:
-#endif
-#ifdef WM_LBUTTONDBLCLK
case WM_LBUTTONDBLCLK:
-#endif
-#ifdef WM_LBUTTONDOWN
case WM_LBUTTONDOWN:
-#endif
-#ifdef WM_LBUTTONUP
case WM_LBUTTONUP:
-#endif
-#ifdef WM_MBUTTONDBLCLK
case WM_MBUTTONDBLCLK:
-#endif
-#ifdef WM_MBUTTONDOWN
case WM_MBUTTONDOWN:
-#endif
-#ifdef WM_MBUTTONUP
case WM_MBUTTONUP:
-#endif
-#ifdef WM_RBUTTONDBLCLK
case WM_RBUTTONDBLCLK:
-#endif
-#ifdef WM_RBUTTONDOWN
case WM_RBUTTONDOWN:
-#endif
-#ifdef WM_RBUTTONUP
case WM_RBUTTONUP:
-#endif
-#ifdef WM_MOUSEMOVE
case WM_MOUSEMOVE:
- {
- QString vrtKeys = flagCheck(wParam,
- FLGSTR(MK_CONTROL),
- FLGSTR(MK_LBUTTON),
- FLGSTR(MK_MBUTTON),
- FLGSTR(MK_RBUTTON),
- FLGSTR(MK_SHIFT),
-#ifdef MK_XBUTTON1
- FLGSTR(MK_XBUTTON1),
-#endif
-#ifdef MK_XBUTTON2
- FLGSTR(MK_XBUTTON2),
-#endif
- FLAG_STRING());
- parameters = QString::asprintf("x,y(%4d,%4d) Virtual Keys(%s)", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), vrtKeys.toLatin1().data());
- }
+ parameters = QString::asprintf("x,y(%4d,%4d) Virtual Keys(",
+ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))
+ + virtualKeys(uint(wParam)) + QLatin1Char(')');
break;
-#endif
-#ifdef WM_MOVE
case WM_MOVE:
parameters = QString::asprintf("x,y(%4d,%4d)", LOWORD(lParam), HIWORD(lParam));
break;
-#endif
-#if defined(WM_PAINT) && defined(WM_ERASEBKGND)
case WM_ERASEBKGND:
case WM_PAINT:
- parameters = QString::asprintf("hdc(0x%p)", (void *)wParam);
+ parameters = QLatin1String("hdc") + wParamS;
break;
-#endif
-#ifdef WM_QUERYNEWPALETTE
case WM_QUERYNEWPALETTE:
break; // lParam & wParam are unused
-#endif
-#ifdef WM_SETCURSOR
case WM_SETCURSOR:
- {
- QString mouseMsg = QString::fromLatin1(findWMstr(HIWORD(lParam)));
- parameters = QString::asprintf("HitTestCode(0x%x) MouseMsg(%s)", LOWORD(lParam), mouseMsg.toLatin1().data());
- }
+ parameters = QString::asprintf("HitTestCode(0x%x) MouseMsg(", LOWORD(lParam));
+ if (const char *mouseMsg = findWMstr(HIWORD(lParam)))
+ parameters += QLatin1String(mouseMsg);
+ parameters += QLatin1Char(')');
break;
-#endif
-#ifdef WM_SETFOCUS
case WM_SETFOCUS:
- parameters = QString::asprintf("Lost Focus (0x%p)", (void *)wParam);
+ parameters = QLatin1String("Lost Focus ") + wParamS;
break;
-#endif
-#ifdef WM_SETTEXT
case WM_SETTEXT:
- parameters = QString::asprintf("Set Text (%s)", QString((QChar*)lParam, (int)wcslen(reinterpret_cast<const wchar_t *>(lParam))).toLatin1().data()); //Unicode string
+ parameters = QLatin1String("Set Text (")
+ + QString::fromWCharArray(reinterpret_cast<const wchar_t *>(lParam))
+ + QLatin1Char(')');
break;
-#endif
-#ifdef WM_SIZE
case WM_SIZE:
- {
- QString showMode = valueCheck(wParam,
- FLGSTR(SIZE_MAXHIDE),
- FLGSTR(SIZE_MAXIMIZED),
- FLGSTR(SIZE_MAXSHOW),
- FLGSTR(SIZE_MINIMIZED),
- FLGSTR(SIZE_RESTORED),
- FLAG_STRING());
-
- parameters = QString::asprintf("w,h(%4d,%4d) showmode(%s)", LOWORD(lParam), HIWORD(lParam), showMode.toLatin1().data());
- }
+ parameters = QString::asprintf("w,h(%4d,%4d) showmode(",
+ LOWORD(lParam), HIWORD(lParam));
+ if (const char *showMode = wmSizeParam(uint(wParam)))
+ parameters += QLatin1String(showMode);
+ parameters += QLatin1Char(')');
break;
-#endif
-#ifdef WM_WINDOWPOSCHANGED
case WM_WINDOWPOSCHANGED:
{
- LPWINDOWPOS winPos = (LPWINDOWPOS)lParam;
+ auto winPos = reinterpret_cast<LPWINDOWPOS>(lParam);
if (!winPos)
break;
- QString hwndAfter = valueCheck(quint64(winPos->hwndInsertAfter),
- FLAG_STRING((qptrdiff)HWND_BOTTOM, "HWND_BOTTOM"),
- FLAG_STRING((qptrdiff)HWND_NOTOPMOST, "HWND_NOTOPMOST"),
- FLAG_STRING((qptrdiff)HWND_TOP, "HWND_TOP"),
- FLAG_STRING((qptrdiff)HWND_TOPMOST, "HWND_TOPMOST"),
- FLAG_STRING());
- if (hwndAfter.isEmpty())
- hwndAfter = QString::number((quintptr)winPos->hwndInsertAfter, 16);
- QString flags = flagCheck(winPos->flags,
- FLGSTR(SWP_DRAWFRAME),
- FLGSTR(SWP_FRAMECHANGED),
- FLGSTR(SWP_HIDEWINDOW),
- FLGSTR(SWP_NOACTIVATE),
-#ifdef SWP_NOCOPYBITS
- FLGSTR(SWP_NOCOPYBITS),
-#endif
- FLGSTR(SWP_NOMOVE),
- FLGSTR(SWP_NOOWNERZORDER),
- FLGSTR(SWP_NOREDRAW),
- FLGSTR(SWP_NOREPOSITION),
-#ifdef SWP_NOSENDCHANGING
- FLGSTR(SWP_NOSENDCHANGING),
-#endif
- FLGSTR(SWP_NOSIZE),
- FLGSTR(SWP_NOZORDER),
- FLGSTR(SWP_SHOWWINDOW),
- FLAG_STRING());
- parameters = QString::asprintf("x,y(%4d,%4d) w,h(%4d,%4d) flags(%s) hwndAfter(%s)", winPos->x, winPos->y, winPos->cx, winPos->cy, flags.toLatin1().data(), hwndAfter.toLatin1().data());
+ const auto insertAfter = quintptr(winPos->hwndInsertAfter);
+ parameters = QString::asprintf("x,y(%4d,%4d) w,h(%4d,%4d) flags(%s) hwndAfter(",
+ winPos->x, winPos->y, winPos->cx, winPos->cy,
+ winPosFlags(winPos->flags).toLatin1().constData());
+ if (const char *h = winPosInsertAfter(insertAfter))
+ parameters += QLatin1String(h);
+ else
+ parameters += QString::number(insertAfter, 16);
+ parameters += QLatin1Char(')');
}
break;
-#endif
-#ifdef WM_QUERYENDSESSION
#ifndef ENDSESSION_CLOSEAPP
#define ENDSESSION_CLOSEAPP 0x00000001
#endif
@@ -991,34 +868,23 @@ QString decodeMSG(const MSG& msg)
#define ENDSESSION_CRITICAL 0x40000000
#endif
case WM_QUERYENDSESSION:
- {
- QString logoffOption = valueCheck(wParam,
- FLAG_STRING(ENDSESSION_CLOSEAPP, "Close application"),
- FLAG_STRING(ENDSESSION_CRITICAL, "Force application end"),
- FLAG_STRING(ENDSESSION_LOGOFF, "User logoff"),
- FLAG_STRING());
- parameters = QLatin1String("End session: ") + logoffOption;
- }
- break;
-#endif
+ parameters = QLatin1String("End session: ");
+ if (const char *logoffOption = sessionMgrLogOffOption(uint(wParam)))
+ parameters += QLatin1String(logoffOption);
+ break;
default:
- parameters = QString::asprintf("wParam(0x%p) lParam(0x%p)", (void *)wParam, (void *)lParam);
+ parameters = QLatin1String("wParam") + wParamS + QLatin1String(" lParam") + lParamS;
break;
}
- // Yes, we want to give the WM_ names 20 chars of space before showing the
- // decoded message, since some of the common messages are quite long, and
- // we don't want the decoded information to vary in output position
- QString message = QString::fromLatin1("%1: ").arg(wmmsg, 20);
- message += rawParameters;
- message += parameters;
- return message;
-}
-#endif
+ return message + QLatin1String("hwnd") + hwndS + QLatin1Char(' ') + parameters;
+}
QDebug operator<<(QDebug dbg, const MSG &msg)
{
QDebugStateSaver saver(dbg);
+ dbg.noquote();
+ dbg.nospace();
dbg << decodeMSG(msg);
return dbg;
}
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index 3d0a9dd05d..cacbb1e495 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -44,6 +44,8 @@
#include "qbasicatomic.h"
+#include <qtcore_tracepoints_p.h>
+
#include <limits>
QT_BEGIN_NAMESPACE
@@ -294,7 +296,9 @@ QT_BEGIN_NAMESPACE
*/
QEvent::QEvent(Type type)
: d(0), t(type), posted(false), spont(false), m_accept(true)
-{}
+{
+ Q_TRACE(QEvent_ctor, this, t);
+}
/*!
\internal
@@ -307,6 +311,7 @@ QEvent::QEvent(const QEvent &other)
: d(other.d), t(other.t), posted(other.posted), spont(other.spont),
m_accept(other.m_accept)
{
+ Q_TRACE(QEvent_ctor, this, t);
// if QEventPrivate becomes available, make sure to implement a
// virtual QEventPrivate *clone() const; function so we can copy here
Q_ASSERT_X(!d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere");
@@ -339,6 +344,7 @@ QEvent &QEvent::operator=(const QEvent &other)
QEvent::~QEvent()
{
+ Q_TRACE(QEvent_dtor, this, t);
if (posted && QCoreApplication::instance())
QCoreApplicationPrivate::removePostedEvent(this);
Q_ASSERT_X(!d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere");
diff --git a/src/corelib/kernel/qcoreglobaldata.cpp b/src/corelib/kernel/qcoreglobaldata.cpp
index e2087b9e64..88a45ef4ee 100644
--- a/src/corelib/kernel/qcoreglobaldata.cpp
+++ b/src/corelib/kernel/qcoreglobaldata.cpp
@@ -55,7 +55,10 @@ QCoreGlobalData::~QCoreGlobalData()
{
#if QT_CONFIG(textcodec)
codecForLocale = 0;
- for (QList<QTextCodec *>::const_iterator it = allCodecs.constBegin(); it != allCodecs.constEnd(); ++it)
+ QList<QTextCodec *> tmp = allCodecs;
+ allCodecs.clear();
+ codecCache.clear();
+ for (QList<QTextCodec *>::const_iterator it = tmp.constBegin(); it != tmp.constEnd(); ++it)
delete *it;
#endif
}
diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp
index 8a5bd5d681..66d0dce7e8 100644
--- a/src/corelib/kernel/qdeadlinetimer.cpp
+++ b/src/corelib/kernel/qdeadlinetimer.cpp
@@ -39,7 +39,6 @@
#include "qdeadlinetimer.h"
#include "qdeadlinetimer_p.h"
-#include <qpair.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h
index 6c10e1025e..1a4ee04a96 100644
--- a/src/corelib/kernel/qdeadlinetimer.h
+++ b/src/corelib/kernel/qdeadlinetimer.h
@@ -43,6 +43,7 @@
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmetatype.h>
#include <QtCore/qnamespace.h>
+#include <QtCore/qpair.h>
#ifdef max
// un-pollute the namespace. We need std::numeric_limits::max() and std::chrono::duration::max()
@@ -186,6 +187,10 @@ private:
unsigned type;
qint64 rawRemainingTimeNSecs() const Q_DECL_NOTHROW;
+
+public:
+ // This is not a public function, it's here only for Qt's internal convenience...
+ QPair<qint64, unsigned> _q_data() const { return qMakePair(t1, t2); }
};
Q_DECLARE_SHARED(QDeadlineTimer)
diff --git a/src/corelib/kernel/qelapsedtimer_win.cpp b/src/corelib/kernel/qelapsedtimer_win.cpp
index 0c380b2f6a..a63290d2f8 100644
--- a/src/corelib/kernel/qelapsedtimer_win.cpp
+++ b/src/corelib/kernel/qelapsedtimer_win.cpp
@@ -72,10 +72,9 @@ static inline qint64 ticksToNanoseconds(qint64 ticks)
qint64 seconds = ticks / counterFrequency;
qint64 nanoSeconds = (ticks - seconds * counterFrequency) * 1000000000 / counterFrequency;
return seconds * 1000000000 + nanoSeconds;
- } else {
- // GetTickCount(64) return milliseconds
- return ticks * 1000000;
}
+ // GetTickCount(64) returns milliseconds
+ return ticks * 1000000;
}
static inline qint64 nanosecondsToTicks(qint64 nsec)
@@ -83,10 +82,9 @@ static inline qint64 nanosecondsToTicks(qint64 nsec)
if (counterFrequency > 0) {
// QueryPerformanceCounter uses an arbitrary frequency
return double(nsec) * counterFrequency / 1000000000.;
- } else {
- // GetTickCount(64) uses milliseconds
- return nsec / 1000000;
}
+ // GetTickCount(64) uses milliseconds
+ return nsec / 1000000;
}
static quint64 getTickCount()
@@ -116,10 +114,7 @@ QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW
{
resolveCounterFrequency();
- if (counterFrequency > 0)
- return PerformanceCounter;
- else
- return TickCounter;
+ return counterFrequency > 0 ? PerformanceCounter : TickCounter;
}
bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW
diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm
index 503836d071..8881305b18 100644
--- a/src/corelib/kernel/qeventdispatcher_cf.mm
+++ b/src/corelib/kernel/qeventdispatcher_cf.mm
@@ -58,18 +58,36 @@
QT_USE_NAMESPACE
-@interface QT_MANGLE_NAMESPACE(RunLoopModeTracker) : NSObject {
- QStack<CFStringRef> m_runLoopModes;
-}
+/*!
+ During scroll view panning, and possibly other gestures, UIKit will
+ request a switch to UITrackingRunLoopMode via GSEventPushRunLoopMode,
+ which records the new runloop mode and stops the current runloop.
+
+ Unfortunately the runloop mode is just stored on an internal stack, used
+ when UIKit itself is running the runloop, and is not available through e.g.
+ CFRunLoopCopyCurrentMode, which only knows about the current running
+ runloop mode, not the requested future runloop mode.
+
+ To ensure that we pick up this new runloop mode and use it when calling
+ CFRunLoopRunInMode from processEvents, we listen for the notification
+ emitted by [UIApplication pushRunLoopMode:requester:].
+
+ Without this workaround we end up always running in the default runloop
+ mode, resulting in missing momentum-phases in UIScrollViews such as the
+ emoji keyboard.
+*/
+@interface QT_MANGLE_NAMESPACE(RunLoopModeTracker) : NSObject
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker);
-@implementation RunLoopModeTracker
+@implementation RunLoopModeTracker {
+ QStack<CFStringRef> m_runLoopModes;
+}
-- (id) init
+- (instancetype)init
{
- if (self = [super init]) {
+ if ((self = [super init])) {
m_runLoopModes.push(kCFRunLoopDefaultMode);
#if !defined(Q_OS_WATCHOS)
@@ -84,9 +102,9 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker);
return self;
}
-- (void) dealloc
+- (void)dealloc
{
- [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [NSNotificationCenter.defaultCenter removeObserver:self];
[super dealloc];
}
@@ -95,13 +113,13 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
{
for (NSString *key in dictionary) {
if (CFStringHasSuffix((CFStringRef)key, CFSTR("RunLoopMode")))
- return (CFStringRef)[dictionary objectForKey: key];
+ return (CFStringRef)dictionary[key];
}
return nil;
}
-- (void) receivedNotification:(NSNotification *) notification
+- (void)receivedNotification:(NSNotification *)notification
{
if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePushNotification"))) {
if (CFStringRef mode = runLoopMode(notification.userInfo))
@@ -111,7 +129,7 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
} else if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePopNotification"))) {
CFStringRef mode = runLoopMode(notification.userInfo);
- if (CFStringCompare(mode, [self currentMode], 0) == kCFCompareEqualTo)
+ if (CFStringCompare(mode, self.currentMode, 0) == kCFCompareEqualTo)
m_runLoopModes.pop();
else
qCWarning(lcEventDispatcher) << "Tried to pop run loop mode"
@@ -121,7 +139,7 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
}
}
-- (CFStringRef) currentMode
+- (CFStringRef)currentMode
{
return m_runLoopModes.top();
}
@@ -191,8 +209,16 @@ QEventDispatcherCoreFoundation::QEventDispatcherCoreFoundation(QObject *parent)
, m_blockedRunLoopTimer(0)
, m_overdueTimerScheduled(false)
{
- m_cfSocketNotifier.setHostEventDispatcher(this);
+}
+
+void QEventDispatcherCoreFoundation::startingUp()
+{
+ // The following code must run on the event dispatcher thread, so that
+ // CFRunLoopGetCurrent() returns the correct run loop.
+ Q_ASSERT(QThread::currentThread() == thread());
+ m_runLoop = QCFType<CFRunLoopRef>::constructFromGet(CFRunLoopGetCurrent());
+ m_cfSocketNotifier.setHostEventDispatcher(this);
m_postedEventsRunLoopSource.addToMode(kCFRunLoopCommonModes);
m_runLoopActivityObserver.addToMode(kCFRunLoopCommonModes);
}
@@ -233,6 +259,8 @@ QEventLoop *QEventDispatcherCoreFoundation::currentEventLoop() const
*/
bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlags flags)
{
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processEvents");
+
bool eventsProcessed = false;
if (flags & (QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers))
@@ -385,6 +413,8 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
bool QEventDispatcherCoreFoundation::processPostedEvents()
{
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processPostedEvents");
+
if (m_processEvents.processedPostedEvents && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
qCDebug(lcEventDispatcher) << "Already processed events this pass";
return false;
@@ -392,7 +422,8 @@ bool QEventDispatcherCoreFoundation::processPostedEvents()
m_processEvents.processedPostedEvents = true;
- qCDebug(lcEventDispatcher) << "Sending posted events for" << m_processEvents.flags;
+ qCDebug(lcEventDispatcher) << "Sending posted events for"
+ << QEventLoop::ProcessEventsFlags(m_processEvents.flags.load());
QCoreApplication::sendPostedEvents();
return true;
@@ -400,6 +431,8 @@ bool QEventDispatcherCoreFoundation::processPostedEvents()
void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer)
{
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processTimers");
+
if (m_processEvents.processedTimers && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
qCDebug(lcEventDispatcher) << "Already processed timers this pass";
m_processEvents.deferredUpdateTimers = true;
@@ -473,7 +506,7 @@ bool QEventDispatcherCoreFoundation::hasPendingEvents()
// 'maybeHasPendingEvents' in our case.
extern uint qGlobalPostedEventsCount();
- return qGlobalPostedEventsCount() || !CFRunLoopIsWaiting(CFRunLoopGetMain());
+ return qGlobalPostedEventsCount() || !CFRunLoopIsWaiting(m_runLoop);
}
void QEventDispatcherCoreFoundation::wakeUp()
@@ -493,7 +526,8 @@ void QEventDispatcherCoreFoundation::wakeUp()
}
m_postedEventsRunLoopSource.signal();
- CFRunLoopWakeUp(CFRunLoopGetMain());
+ if (m_runLoop)
+ CFRunLoopWakeUp(m_runLoop);
qCDebug(lcEventDispatcher) << "Signaled posted event run-loop source";
}
@@ -502,7 +536,7 @@ void QEventDispatcherCoreFoundation::interrupt()
{
qCDebug(lcEventDispatcher) << "Marking current processEvent as interrupted";
m_processEvents.wasInterrupted = true;
- CFRunLoopStop(CFRunLoopGetMain());
+ CFRunLoopStop(m_runLoop);
}
void QEventDispatcherCoreFoundation::flush()
@@ -597,7 +631,7 @@ void QEventDispatcherCoreFoundation::updateTimers()
processTimers(timer);
});
- CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimer, kCFRunLoopCommonModes);
+ CFRunLoopAddTimer(m_runLoop, m_runLoopTimer, kCFRunLoopCommonModes);
qCDebug(lcEventDispatcherTimers) << "Created new CFRunLoopTimer" << m_runLoopTimer;
} else {
diff --git a/src/corelib/kernel/qeventdispatcher_cf_p.h b/src/corelib/kernel/qeventdispatcher_cf_p.h
index a607ab7a15..26191d520c 100644
--- a/src/corelib/kernel/qeventdispatcher_cf_p.h
+++ b/src/corelib/kernel/qeventdispatcher_cf_p.h
@@ -208,24 +208,25 @@ class Q_CORE_EXPORT QEventDispatcherCoreFoundation : public QAbstractEventDispat
public:
explicit QEventDispatcherCoreFoundation(QObject *parent = 0);
+ void startingUp() override;
~QEventDispatcherCoreFoundation();
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
- bool hasPendingEvents();
+ bool processEvents(QEventLoop::ProcessEventsFlags flags) override;
+ bool hasPendingEvents() override;
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
+ void registerSocketNotifier(QSocketNotifier *notifier) override;
+ void unregisterSocketNotifier(QSocketNotifier *notifier) override;
- void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
- bool unregisterTimer(int timerId);
- bool unregisterTimers(QObject *object);
- QList<QAbstractEventDispatcher::TimerInfo> registeredTimers(QObject *object) const;
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) override;
+ bool unregisterTimer(int timerId) override;
+ bool unregisterTimers(QObject *object) override;
+ QList<QAbstractEventDispatcher::TimerInfo> registeredTimers(QObject *object) const override;
- int remainingTime(int timerId);
+ int remainingTime(int timerId) override;
- void wakeUp();
- void interrupt();
- void flush();
+ void wakeUp() override;
+ void interrupt() override;
+ void flush() override;
protected:
QEventLoop *currentEventLoop() const;
@@ -239,11 +240,11 @@ protected:
, processedPostedEvents(false), processedTimers(false)
, deferredWakeUp(false), deferredUpdateTimers(false) {}
- QEventLoop::ProcessEventsFlags flags;
- bool wasInterrupted;
- bool processedPostedEvents;
- bool processedTimers;
- bool deferredWakeUp;
+ QAtomicInt flags;
+ QAtomicInteger<char> wasInterrupted;
+ QAtomicInteger<char> processedPostedEvents;
+ QAtomicInteger<char> processedTimers;
+ QAtomicInteger<char> deferredWakeUp;
bool deferredUpdateTimers;
};
@@ -258,6 +259,7 @@ private:
QTimerInfoList m_timerInfoList;
CFRunLoopTimerRef m_runLoopTimer;
CFRunLoopTimerRef m_blockedRunLoopTimer;
+ QCFType<CFRunLoopRef> m_runLoop;
bool m_overdueTimerScheduled;
QCFSocketNotifier m_cfSocketNotifier;
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index a28f2e3f0a..535f86fefe 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -130,7 +130,7 @@ static void initThreadPipeFD(int fd)
bool QThreadPipe::init()
{
-#if defined(Q_OS_NACL)
+#if defined(Q_OS_NACL) || defined(Q_OS_WASM)
// do nothing.
#elif defined(Q_OS_VXWORKS)
qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf()));
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 330870f219..0bddf89b15 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -120,7 +120,7 @@ void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/,
{
if (!timerId) // sanity check
return;
- WinTimerInfo *t = (WinTimerInfo*)user;
+ auto t = reinterpret_cast<WinTimerInfo*>(user);
Q_ASSERT(t);
QCoreApplication::postEvent(t->dispatcher, new QTimerEvent(t->timerId));
}
@@ -141,20 +141,21 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
if (message == WM_TIMER)
KillTimer(hwnd, wp);
return 0;
- } else if (dispatcher->filterNativeEvent(QByteArrayLiteral("windows_dispatcher_MSG"), &msg, &result)) {
- return result;
}
+ if (dispatcher->filterNativeEvent(QByteArrayLiteral("windows_dispatcher_MSG"), &msg, &result))
+ return result;
#ifdef GWLP_USERDATA
- QEventDispatcherWin32 *q = (QEventDispatcherWin32 *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ auto q = reinterpret_cast<QEventDispatcherWin32 *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
#else
- QEventDispatcherWin32 *q = (QEventDispatcherWin32 *) GetWindowLong(hwnd, GWL_USERDATA);
+ auto q = reinterpret_cast<QEventDispatcherWin32 *>(GetWindowLong(hwnd, GWL_USERDATA));
#endif
QEventDispatcherWin32Private *d = 0;
if (q != 0)
d = q->d_func();
- if (message == WM_QT_SOCKETNOTIFIER) {
+ switch (message) {
+ case WM_QT_SOCKETNOTIFIER: {
// socket notifier message
int type = -1;
switch (WSAGETSELECTEVENT(lp)) {
@@ -202,7 +203,8 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
}
}
return 0;
- } else if (message == WM_QT_ACTIVATENOTIFIERS) {
+ }
+ case WM_QT_ACTIVATENOTIFIERS: {
Q_ASSERT(d != 0);
// Postpone activation if we have unhandled socket notifier messages
@@ -226,22 +228,25 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
}
d->activateNotifiersPosted = false;
return 0;
- } else if (message == WM_QT_SENDPOSTEDEVENTS
- // we also use a Windows timer to send posted events when the message queue is full
- || (message == WM_TIMER
- && d->sendPostedEventsWindowsTimerId != 0
- && wp == (uint)d->sendPostedEventsWindowsTimerId)) {
+ }
+ case WM_TIMER:
+ if (d->sendPostedEventsWindowsTimerId == 0
+ || wp != uint(d->sendPostedEventsWindowsTimerId)) {
+ Q_ASSERT(d != 0);
+ d->sendTimerEvent(wp);
+ return 0;
+ }
+ // we also use a Windows timer to send posted events when the message queue is full
+ Q_FALLTHROUGH();
+ case WM_QT_SENDPOSTEDEVENTS: {
const int localSerialNumber = d->serialNumber.load();
if (localSerialNumber != d->lastSerialNumber) {
d->lastSerialNumber = localSerialNumber;
q->sendPostedEvents();
}
return 0;
- } else if (message == WM_TIMER) {
- Q_ASSERT(d != 0);
- d->sendTimerEvent(wp);
- return 0;
}
+ } // switch (message)
return DefWindowProc(hwnd, message, wp, lp);
}
@@ -369,9 +374,9 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
}
#ifdef GWLP_USERDATA
- SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)eventDispatcher);
+ SetWindowLongPtr(wnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(eventDispatcher));
#else
- SetWindowLong(wnd, GWL_USERDATA, (LONG)eventDispatcher);
+ SetWindowLong(wnd, GWL_USERDATA, reinterpret_cast<LONG>(eventDispatcher));
#endif
return wnd;
@@ -522,6 +527,22 @@ QEventDispatcherWin32::~QEventDispatcherWin32()
{
}
+static bool isUserInputMessage(UINT message)
+{
+ return (message >= WM_KEYFIRST && message <= WM_KEYLAST)
+ || (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST)
+ || message == WM_MOUSEWHEEL
+ || message == WM_MOUSEHWHEEL
+ || message == WM_TOUCH
+#ifndef QT_NO_GESTURES
+ || message == WM_GESTURE
+ || message == WM_GESTURENOTIFY
+#endif
+// Pointer input: Exclude WM_NCPOINTERUPDATE .. WM_POINTERROUTEDRELEASED
+ || (message >= 0x0241 && message <= 0x0253)
+ || message == WM_CLOSE;
+}
+
bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherWin32);
@@ -562,19 +583,8 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
} else {
haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
if (haveMessage) {
- if ((flags & QEventLoop::ExcludeUserInputEvents)
- && ((msg.message >= WM_KEYFIRST
- && msg.message <= WM_KEYLAST)
- || (msg.message >= WM_MOUSEFIRST
- && msg.message <= WM_MOUSELAST)
- || msg.message == WM_MOUSEWHEEL
- || msg.message == WM_MOUSEHWHEEL
- || msg.message == WM_TOUCH
-#ifndef QT_NO_GESTURES
- || msg.message == WM_GESTURE
- || msg.message == WM_GESTURENOTIFY
-#endif
- || msg.message == WM_CLOSE)) {
+ if (flags.testFlag(QEventLoop::ExcludeUserInputEvents)
+ && isUserInputMessage(msg.message)) {
// queue user input events for later processing
d->queuedUserInputEvents.append(msg);
continue;
@@ -598,7 +608,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
if (haveMessage) {
// WinCE doesn't support hooks at all, so we have to call this by hand :(
if (!d->getMessageHook)
- (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg);
+ (void) qt_GetMessageHook(0, PM_REMOVE, reinterpret_cast<LPARAM>(&msg));
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
if (seenWM_QT_SENDPOSTEDEVENTS) {
@@ -678,7 +688,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
if (sockfd < 0) {
qWarning("QSocketNotifier: Internal error");
return;
- } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
+ }
+ if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
return;
}
@@ -738,7 +749,8 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
if (sockfd < 0) {
qWarning("QSocketNotifier: Internal error");
return;
- } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
+ }
+ if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
return;
}
@@ -784,7 +796,8 @@ void QEventDispatcherWin32::registerTimer(int timerId, int interval, Qt::TimerTy
if (timerId < 1 || interval < 0 || !object) {
qWarning("QEventDispatcherWin32::registerTimer: invalid arguments");
return;
- } else if (object->thread() != thread() || thread() != QThread::currentThread()) {
+ }
+ if (object->thread() != thread() || thread() != QThread::currentThread()) {
qWarning("QEventDispatcherWin32::registerTimer: timers cannot be started from another thread");
return;
}
@@ -881,8 +894,7 @@ QEventDispatcherWin32::registeredTimers(QObject *object) const
Q_D(const QEventDispatcherWin32);
QList<TimerInfo> list;
- for (int i = 0; i < d->timerVec.size(); ++i) {
- const WinTimerInfo *t = d->timerVec.at(i);
+ for (const WinTimerInfo *t : qAsConst(d->timerVec)) {
if (t && t->obj == object)
list << TimerInfo(t->timerId, t->interval, t->timerType);
}
@@ -979,17 +991,9 @@ int QEventDispatcherWin32::remainingTime(int timerId)
quint64 currentTime = qt_msectime();
- WinTimerInfo *t;
- for (int i=0; i<d->timerVec.size(); i++) {
- t = d->timerVec.at(i);
- if (t && t->timerId == timerId) { // timer found
- if (currentTime < t->timeout) {
- // time to wait
- return t->timeout - currentTime;
- } else {
- return 0;
- }
- }
+ for (const WinTimerInfo *t : qAsConst(d->timerVec)) {
+ if (t && t->timerId == timerId) // timer found, return time to wait
+ return t->timeout > currentTime ? t->timeout - currentTime : 0;
}
#ifndef QT_NO_DEBUG
@@ -1049,7 +1053,8 @@ void QEventDispatcherWin32::closingDown()
bool QEventDispatcherWin32::event(QEvent *e)
{
Q_D(QEventDispatcherWin32);
- if (e->type() == QEvent::ZeroTimerEvent) {
+ switch (e->type()) {
+ case QEvent::ZeroTimerEvent: {
QZeroTimerEvent *zte = static_cast<QZeroTimerEvent*>(e);
WinTimerInfo *t = d->timerDict.value(zte->timerId());
if (t) {
@@ -1071,9 +1076,12 @@ bool QEventDispatcherWin32::event(QEvent *e)
}
}
return true;
- } else if (e->type() == QEvent::Timer) {
- QTimerEvent *te = static_cast<QTimerEvent*>(e);
- d->sendTimerEvent(te->timerId());
+ }
+ case QEvent::Timer:
+ d->sendTimerEvent(static_cast<const QTimerEvent*>(e)->timerId());
+ break;
+ default:
+ break;
}
return QAbstractEventDispatcher::event(e);
}
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index 33753ed507..600c6c38fd 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -43,6 +43,8 @@
#include <QtCore/QThread>
#include <QtCore/QHash>
#include <QtCore/QMutex>
+#include <QtCore/QSemaphore>
+#include <QtCore/QSharedPointer>
#include <QtCore/qfunctions_winrt.h>
#include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
@@ -293,6 +295,26 @@ HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT ()> &
return QWinRTFunctions::await(op);
}
+HRESULT QEventDispatcherWinRT::runOnMainThread(const std::function<HRESULT()> &delegate, int timeout)
+{
+ if (QThread::currentThread() == QCoreApplication::instance()->thread())
+ return delegate();
+
+ auto semaphore = QSharedPointer<QSemaphore>(new QSemaphore);
+ auto ptrSemaphore = new QSharedPointer<QSemaphore>(semaphore);
+ auto result = QSharedPointer<HRESULT>(new HRESULT);
+ auto ptrResult = new QSharedPointer<HRESULT>(result);
+
+ QMetaObject::invokeMethod(QCoreApplication::instance(), [delegate, ptrSemaphore, ptrResult]() {
+ **ptrResult = delegate();
+ delete ptrResult;
+ (*ptrSemaphore)->release();
+ delete ptrSemaphore;
+ }, nullptr);
+
+ return semaphore->tryAcquire(1, timeout) ? *result : E_FAIL;
+}
+
bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherWinRT);
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
index f69bb9cf3f..8b998a7958 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt_p.h
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -75,6 +75,7 @@ public:
~QEventDispatcherWinRT();
static HRESULT runOnXamlThread(const std::function<HRESULT()> &delegate, bool waitForRun = true);
+ static HRESULT runOnMainThread(const std::function<HRESULT()> &delegate, int timeout = 100);
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index 6034698349..a6cc51621a 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -48,6 +48,10 @@
#include "qeventloop_p.h"
#include <private/qthread_p.h>
+#ifdef Q_OS_WASM
+#include <emscripten.h>
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -101,10 +105,8 @@ QEventLoop::QEventLoop(QObject *parent)
Q_D(QEventLoop);
if (!QCoreApplication::instance() && QCoreApplicationPrivate::threadRequiresCoreApplication()) {
qWarning("QEventLoop: Cannot be used without QApplication");
- } else if (!d->threadData->hasEventDispatcher()) {
- QAbstractEventDispatcher *eventDispatcher = QThreadPrivate::createEventDispatcher(d->threadData);
- d->threadData->eventDispatcher.storeRelease(eventDispatcher);
- eventDispatcher->startingUp();
+ } else {
+ d->threadData->ensureEventDispatcher();
}
}
@@ -210,6 +212,15 @@ int QEventLoop::exec(ProcessEventsFlags flags)
if (app && app->thread() == thread())
QCoreApplication::removePostedEvents(app, QEvent::Quit);
+#ifdef Q_OS_WASM
+ // Partial support for nested event loops: Make the runtime throw a JavaSrcript
+ // exception, which returns control to the browser while preserving the C++ stack.
+ // Event processing then continues as normal. The sleep call below never returns.
+ // QTBUG-70185
+ if (d->threadData->loopLevel > 1)
+ emscripten_sleep(1);
+#endif
+
while (!d->exit.loadAcquire())
processEvents(flags | WaitForMoreEvents | EventLoopExec);
@@ -271,6 +282,17 @@ void QEventLoop::exit(int returnCode)
d->returnCode.store(returnCode);
d->exit.storeRelease(true);
d->threadData->eventDispatcher.load()->interrupt();
+
+#ifdef Q_OS_WASM
+ // QEventLoop::exec() never returns in emscripten. We implement approximate behavior here.
+ // QTBUG-70185
+ if (d->threadData->loopLevel == 1) {
+ emscripten_force_exit(returnCode);
+ } else {
+ d->inExec = false;
+ --d->threadData->loopLevel;
+ }
+#endif
}
/*!
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 27138dd075..a6ee12ede1 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -50,7 +50,9 @@
#include <qthread.h>
#include <qvariant.h>
#include <qdebug.h>
+#if QT_CONFIG(thread)
#include <qsemaphore.h>
+#endif
#include "private/qobject_p.h"
#include "private/qmetaobject_p.h"
@@ -970,8 +972,23 @@ int QMetaObject::indexOfEnumerator(const char *name) const
const QMetaObject *m = this;
while (m) {
const QMetaObjectPrivate *d = priv(m->d.data);
+ const int intsPerEnum = d->revision >= 8 ? 5 : 4;
+ for (int i = d->enumeratorCount - 1; i >= 0; --i) {
+ const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i]);
+ if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) {
+ i += m->enumeratorOffset();
+ return i;
+ }
+ }
+ m = m->d.superdata;
+ }
+ // Check alias names:
+ m = this;
+ while (m) {
+ const QMetaObjectPrivate *d = priv(m->d.data);
+ const int intsPerEnum = d->revision >= 8 ? 5 : 4;
for (int i = d->enumeratorCount - 1; i >= 0; --i) {
- const char *prop = rawStringData(m, m->d.data[d->enumeratorData + 4*i]);
+ const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i + 1]);
if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) {
i += m->enumeratorOffset();
return i;
@@ -1086,10 +1103,11 @@ QMetaEnum QMetaObject::enumerator(int index) const
if (i < 0 && d.superdata)
return d.superdata->enumerator(index);
+ const int intsPerEnum = priv(d.data)->revision >= 8 ? 5 : 4;
QMetaEnum result;
if (i >= 0 && i < priv(d.data)->enumeratorCount) {
result.mobj = this;
- result.handle = priv(d.data)->enumeratorData + 4*i;
+ result.handle = priv(d.data)->enumeratorData + intsPerEnum * i;
}
return result;
}
@@ -1525,14 +1543,14 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *
QCoreApplication::postEvent(object, new QMetaCallEvent(slot, 0, -1, 1, types, args));
} else if (type == Qt::BlockingQueuedConnection) {
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
if (currentThread == objectThread)
qWarning("QMetaObject::invokeMethod: Dead lock detected");
QSemaphore semaphore;
QCoreApplication::postEvent(object, new QMetaCallEvent(slot, 0, -1, 0, 0, argv, &semaphore));
semaphore.acquire();
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
} else {
qWarning("QMetaObject::invokeMethod: Unknown connection type");
return false;
@@ -2257,7 +2275,7 @@ bool QMetaMethod::invoke(QObject *object,
: Qt::QueuedConnection;
}
-#ifdef QT_NO_THREAD
+#if !QT_CONFIG(thread)
if (connectionType == Qt::BlockingQueuedConnection) {
connectionType = Qt::DirectConnection;
}
@@ -2333,7 +2351,7 @@ bool QMetaMethod::invoke(QObject *object,
QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction,
0, -1, nargs, types, args));
} else { // blocking queued connection
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
if (currentThread == objectThread) {
qWarning("QMetaMethod::invoke: Dead lock detected in "
"BlockingQueuedConnection: Receiver is %s(%p)",
@@ -2344,7 +2362,7 @@ bool QMetaMethod::invoke(QObject *object,
QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction,
0, -1, 0, 0, param, &semaphore));
semaphore.acquire();
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
}
return true;
}
@@ -2552,12 +2570,15 @@ bool QMetaMethod::invokeOnGadget(void* gadget, QGenericReturnArgument returnValu
*/
/*!
- Returns the name of the enumerator (without the scope).
+ Returns the name of the type (without the scope).
+
+ For example, the Qt::Key enumeration has \c
+ Key as the type name and \l Qt as the scope.
- For example, the Qt::AlignmentFlag enumeration has \c
- AlignmentFlag as the name and \l Qt as the scope.
+ For flags this returns the name of the flag type, not the
+ name of the enum type.
- \sa isValid(), scope()
+ \sa isValid(), scope(), enumName()
*/
const char *QMetaEnum::name() const
{
@@ -2567,6 +2588,28 @@ const char *QMetaEnum::name() const
}
/*!
+ Returns the enum name of the flag (without the scope).
+
+ For example, the Qt::AlignmentFlag flag has \c
+ AlignmentFlag as the enum name, but \c Alignment as as the type name.
+ Non flag enums has the same type and enum names.
+
+ Enum names have the same scope as the type name.
+
+ \since 5.12
+ \sa isValid(), name()
+*/
+const char *QMetaEnum::enumName() const
+{
+ if (!mobj)
+ return 0;
+ const bool rev8p = priv(mobj->d.data)->revision >= 8;
+ if (rev8p)
+ return rawStringData(mobj, mobj->d.data[handle + 1]);
+ return name();
+}
+
+/*!
Returns the number of keys.
\sa key()
@@ -2575,10 +2618,10 @@ int QMetaEnum::keyCount() const
{
if (!mobj)
return 0;
- return mobj->d.data[handle + 2];
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
+ return mobj->d.data[handle + offset];
}
-
/*!
Returns the key with the given \a index, or 0 if no such key exists.
@@ -2588,8 +2631,9 @@ const char *QMetaEnum::key(int index) const
{
if (!mobj)
return 0;
- int count = mobj->d.data[handle + 2];
- int data = mobj->d.data[handle + 3];
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
+ int count = mobj->d.data[handle + offset];
+ int data = mobj->d.data[handle + offset + 1];
if (index >= 0 && index < count)
return rawStringData(mobj, mobj->d.data[data + 2*index]);
return 0;
@@ -2605,8 +2649,9 @@ int QMetaEnum::value(int index) const
{
if (!mobj)
return 0;
- int count = mobj->d.data[handle + 2];
- int data = mobj->d.data[handle + 3];
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
+ int count = mobj->d.data[handle + offset];
+ int data = mobj->d.data[handle + offset + 1];
if (index >= 0 && index < count)
return mobj->d.data[data + 2*index + 1];
return -1;
@@ -2624,7 +2669,8 @@ int QMetaEnum::value(int index) const
*/
bool QMetaEnum::isFlag() const
{
- return mobj && mobj->d.data[handle + 1] & EnumIsFlag;
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 2 : 1;
+ return mobj && mobj->d.data[handle + offset] & EnumIsFlag;
}
/*!
@@ -2635,7 +2681,8 @@ bool QMetaEnum::isFlag() const
*/
bool QMetaEnum::isScoped() const
{
- return mobj && mobj->d.data[handle + 1] & EnumIsScoped;
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 2 : 1;
+ return mobj && mobj->d.data[handle + offset] & EnumIsScoped;
}
/*!
@@ -2677,8 +2724,9 @@ int QMetaEnum::keyToValue(const char *key, bool *ok) const
scope = s - key - 1;
key += scope + 2;
}
- int count = mobj->d.data[handle + 2];
- int data = mobj->d.data[handle + 3];
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
+ int count = mobj->d.data[handle + offset];
+ int data = mobj->d.data[handle + offset + 1];
for (int i = 0; i < count; ++i) {
const QByteArray className = stringData(mobj, priv(mobj->d.data)->className);
if ((!scope || (className.size() == int(scope) && strncmp(qualified_key, className.constData(), scope) == 0))
@@ -2703,8 +2751,9 @@ const char* QMetaEnum::valueToKey(int value) const
{
if (!mobj)
return 0;
- int count = mobj->d.data[handle + 2];
- int data = mobj->d.data[handle + 3];
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
+ int count = mobj->d.data[handle + offset];
+ int data = mobj->d.data[handle + offset + 1];
for (int i = 0; i < count; ++i)
if (value == (int)mobj->d.data[data + 2*i + 1])
return rawStringData(mobj, mobj->d.data[data + 2*i]);
@@ -2735,8 +2784,9 @@ int QMetaEnum::keysToValue(const char *keys, bool *ok) const
return 0;
// ### TODO write proper code: do not allocate memory, so we can go nothrow
int value = 0;
- int count = mobj->d.data[handle + 2];
- int data = mobj->d.data[handle + 3];
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
+ int count = mobj->d.data[handle + offset];
+ int data = mobj->d.data[handle + offset + 1];
for (const QStringRef &untrimmed : splitKeys) {
const QStringRef trimmed = untrimmed.trimmed();
QByteArray qualified_key = trimmed.toLatin1();
@@ -2778,8 +2828,9 @@ QByteArray QMetaEnum::valueToKeys(int value) const
QByteArray keys;
if (!mobj)
return keys;
- int count = mobj->d.data[handle + 2];
- int data = mobj->d.data[handle + 3];
+ const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2;
+ int count = mobj->d.data[handle + offset];
+ int data = mobj->d.data[handle + offset + 1];
int v = value;
// reverse iterate to ensure values like Qt::Dialog=0x2|Qt::Window are processed first.
for (int i = count - 1; i >= 0; --i) {
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index 51df8faad3..51ace3d5f7 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -209,6 +209,7 @@ public:
Q_DECL_CONSTEXPR inline QMetaEnum() : mobj(nullptr), handle(0) {}
const char *name() const;
+ const char *enumName() const;
bool isFlag() const;
bool isScoped() const;
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 434ef84808..522bd78e42 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -60,6 +60,8 @@
#include <QtCore/qvarlengtharray.h>
QT_BEGIN_NAMESPACE
+// ### TODO Qt6: add a proper namespace with Q_NAMESPACE and use scoped enums
+// A namespace and scoped are needed to avoid enum clashes
enum PropertyFlags {
Invalid = 0x00000000,
@@ -103,7 +105,7 @@ enum MethodFlags {
MethodRevisioned = 0x80
};
-enum MetaObjectFlags {
+enum MetaObjectFlags { // keep it in sync with QMetaObjectBuilder::MetaObjectFlag enum
DynamicMetaObject = 0x01,
RequiresVariantMetaObject = 0x02,
PropertyAccessInStaticMetaCall = 0x04 // since Qt 5.5, property code is in the static metacall
@@ -171,7 +173,8 @@ class QMutex;
struct QMetaObjectPrivate
{
// revision 7 is Qt 5.0 everything lower is not supported
- enum { OutputRevision = 7 }; // Used by moc, qmetaobjectbuilder and qdbus
+ // revision 8 is Qt 5.12: It adds the enum name to QMetaEnum
+ enum { OutputRevision = 8 }; // Used by moc, qmetaobjectbuilder and qdbus
int revision;
int className;
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index e3b70638c6..d2030f0275 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -190,11 +190,12 @@ class QMetaEnumBuilderPrivate
{
public:
QMetaEnumBuilderPrivate(const QByteArray& _name)
- : name(_name), isFlag(false), isScoped(false)
+ : name(_name), enumName(_name), isFlag(false), isScoped(false)
{
}
QByteArray name;
+ QByteArray enumName;
bool isFlag;
bool isScoped;
QList<QByteArray> keys;
@@ -637,6 +638,7 @@ QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name)
QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype)
{
QMetaEnumBuilder en = addEnumerator(prototype.name());
+ en.setEnumName(prototype.enumName());
en.setIsFlag(prototype.isFlag());
en.setIsScoped(prototype.isScoped());
int count = prototype.keyCount();
@@ -1216,7 +1218,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
- int(d->methods.size()) // return "parameters" don't have names
- int(d->constructors.size()); // "this" parameters don't have names
if (buf) {
- Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QMetaObjectBuilder should generate the same version as moc");
+ Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QMetaObjectBuilder should generate the same version as moc");
pmeta->revision = QMetaObjectPrivate::OutputRevision;
pmeta->flags = d->flags;
pmeta->className = 0; // Class name is always the first string.
@@ -1244,7 +1246,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
pmeta->enumeratorCount = int(d->enumerators.size());
pmeta->enumeratorData = dataIndex;
- dataIndex += 4 * int(d->enumerators.size());
+ dataIndex += 5 * int(d->enumerators.size());
pmeta->constructorCount = int(d->constructors.size());
pmeta->constructorData = dataIndex;
@@ -1261,7 +1263,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
dataIndex += int(d->properties.size());
if (hasRevisionedProperties)
dataIndex += int(d->properties.size());
- dataIndex += 4 * int(d->enumerators.size());
+ dataIndex += 5 * int(d->enumerators.size());
dataIndex += 5 * int(d->constructors.size());
}
@@ -1410,15 +1412,17 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData);
for (const auto &enumerator : d->enumerators) {
int name = strings.enter(enumerator.name);
+ int enumName = strings.enter(enumerator.enumName);
int isFlag = enumerator.isFlag ? EnumIsFlag : 0;
int isScoped = enumerator.isScoped ? EnumIsScoped : 0;
int count = enumerator.keys.size();
int enumOffset = enumIndex;
if (buf) {
data[dataIndex] = name;
- data[dataIndex + 1] = isFlag | isScoped;
- data[dataIndex + 2] = count;
- data[dataIndex + 3] = enumOffset;
+ data[dataIndex + 1] = enumName;
+ data[dataIndex + 2] = isFlag | isScoped;
+ data[dataIndex + 3] = count;
+ data[dataIndex + 4] = enumOffset;
}
for (int key = 0; key < count; ++key) {
int keyIndex = strings.enter(enumerator.keys[key]);
@@ -1427,7 +1431,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
data[enumOffset++] = enumerator.values[key];
}
}
- dataIndex += 4;
+ dataIndex += 5;
enumIndex += 2 * count;
}
@@ -2599,7 +2603,7 @@ QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
*/
/*!
- Returns the name of the enumerator (without the scope).
+ Returns the type name of the enumerator (without the scope).
*/
QByteArray QMetaEnumBuilder::name() const
{
@@ -2611,6 +2615,33 @@ QByteArray QMetaEnumBuilder::name() const
}
/*!
+ Returns the enum name of the enumerator (without the scope).
+
+ \since 5.12
+*/
+QByteArray QMetaEnumBuilder::enumName() const
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d)
+ return d->enumName;
+ else
+ return QByteArray();
+}
+
+/*!
+ Sets this enumerator to have the enum name \c alias.
+
+ \since 5.12
+ \sa isFlag(), enumName()
+*/
+void QMetaEnumBuilder::setEnumName(const QByteArray &alias)
+{
+ QMetaEnumBuilderPrivate *d = d_func();
+ if (d)
+ d->enumName = alias;
+}
+
+/*!
Returns \c true if this enumerator is used as a flag; otherwise returns
false.
diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h
index 03b2afaebc..115ec835aa 100644
--- a/src/corelib/kernel/qmetaobjectbuilder_p.h
+++ b/src/corelib/kernel/qmetaobjectbuilder_p.h
@@ -93,8 +93,11 @@ public:
};
Q_DECLARE_FLAGS(AddMembers, AddMember)
- enum MetaObjectFlag {
- DynamicMetaObject = 0x01
+ // ### TODO Qt6: remove me and use the MetaObjectFlags enum from qmetaobject_p.h
+ enum MetaObjectFlag { // keep it in sync with enum MetaObjectFlags from qmetaobject_p.h
+ DynamicMetaObject = 0x01,
+ RequiresVariantMetaObject = 0x02,
+ PropertyAccessInStaticMetaCall = 0x04 // since Qt 5.5, property code is in the static metacall
};
Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
@@ -297,6 +300,9 @@ public:
QByteArray name() const;
+ QByteArray enumName() const;
+ void setEnumName(const QByteArray &alias);
+
bool isFlag() const;
void setIsFlag(bool value);
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index fc40668c9a..eb67544f21 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -65,6 +65,9 @@
# include "qjsonobject.h"
# include "qjsonarray.h"
# include "qjsondocument.h"
+# include "qcborvalue.h"
+# include "qcborarray.h"
+# include "qcbormap.h"
# include "qbytearraylist.h"
#endif
@@ -316,7 +319,7 @@ struct DefinedTypesFilter {
\omitvalue WeakPointerToQObject
\omitvalue TrackingPointerToQObject
\omitvalue WasDeclaredAsMetaType
- \omitvalue IsGadget This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5.
+ \omitvalue IsGadget \omit This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5. \endomit
\omitvalue PointerToGadget
*/
@@ -835,15 +838,14 @@ void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
}
#endif // QT_NO_DATASTREAM
-#if defined(Q_COMPILER_CONSTEXPR) || (defined(Q_CC_MSVC) && Q_CC_MSVC >= 1900)
// We don't officially support constexpr in MSVC 2015, but the limited support it
// has is enough for the code below.
-# define STRINGIFY_TYPE_NAME(MetaTypeName, TypeId, RealName) \
+#define STRINGIFY_TYPE_NAME(MetaTypeName, TypeId, RealName) \
#RealName "\0"
-# define CALCULATE_TYPE_LEN(MetaTypeName, TypeId, RealName) \
+#define CALCULATE_TYPE_LEN(MetaTypeName, TypeId, RealName) \
short(sizeof(#RealName)),
-# define MAP_TYPE_ID_TO_IDX(MetaTypeName, TypeId, RealName) \
+#define MAP_TYPE_ID_TO_IDX(MetaTypeName, TypeId, RealName) \
TypeId,
namespace {
@@ -911,10 +913,9 @@ template <int... TypeIds> struct MetaTypeOffsets<QtPrivate::IndexesList<TypeIds.
} // anonymous namespace
constexpr MetaTypeOffsets<QtPrivate::Indexes<QMetaType::HighestInternalId + 1>::Value> metaTypeNames {};
-# undef STRINGIFY_TYPE_NAME
-# undef CALCULATE_TYPE_LEN
-# undef MAP_TYPE_ID_TO_IDX
-#endif
+#undef STRINGIFY_TYPE_NAME
+#undef CALCULATE_TYPE_LEN
+#undef MAP_TYPE_ID_TO_IDX
/*!
Returns the type name associated with the given \a typeId, or a null
@@ -926,20 +927,8 @@ constexpr MetaTypeOffsets<QtPrivate::Indexes<QMetaType::HighestInternalId + 1>::
const char *QMetaType::typeName(int typeId)
{
const uint type = typeId;
-#define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \
- case QMetaType::MetaTypeName: return #RealName; break;
-
if (Q_LIKELY(type <= QMetaType::HighestInternalId)) {
-#if defined(Q_COMPILER_CONSTEXPR) || (defined(Q_CC_MSVC) && Q_CC_MSVC >= 1900)
return metaTypeNames[typeId];
-#else
- switch (QMetaType::Type(type)) {
- QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER)
- case QMetaType::UnknownType:
- case QMetaType::User:
- break;
- }
-#endif
} else if (Q_UNLIKELY(type < QMetaType::User)) {
return nullptr; // It can happen when someone cast int to QVariant::Type, we should not crash...
}
@@ -1065,45 +1054,40 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
return registerNormalizedType(normalizedTypeName, deleter, creator, destructor, constructor, size, flags, metaObject);
}
-
/*!
- \internal
- \since 5.0
- \overload
- Don't use, kept for binary compatibility
+ \internal
+ \since 5.12
- ### TODO Qt6: remove me
-*/
-int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter,
- Creator creator,
- Destructor destructor,
- Constructor constructor,
- int size, TypeFlags flags, const QMetaObject *metaObject)
+ Registers a user type for marshalling, with \a typeName, a
+ \a destructor, a \a constructor, and a \a size. Returns the
+ type's handle, or -1 if the type could not be registered.
+ */
+int QMetaType::registerType(const char *typeName,
+ TypedDestructor destructor,
+ TypedConstructor constructor,
+ int size,
+ TypeFlags flags,
+ const QMetaObject *metaObject)
{
- Q_UNUSED(deleter);
- Q_UNUSED(creator);
+#ifdef QT_NO_QOBJECT
+ NS(QByteArray) normalizedTypeName = typeName;
+#else
+ NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
+#endif
+
return registerNormalizedType(normalizedTypeName, destructor, constructor, size, flags, metaObject);
}
-/*!
- \internal
- \since 5.5
-
- Registers a user type for marshalling, with \a normalizedTypeName,
- a \a destructor, a \a constructor, and a \a size. Returns the type's
- handle, or -1 if the type could not be registered.
-
- \note normalizedTypeName is not checked for conformance with
- Qt's normalized format, so it must already conform.
- */
-int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
- Destructor destructor,
- Constructor constructor,
- int size, TypeFlags flags, const QMetaObject *metaObject)
+static int registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
+ QMetaType::Destructor destructor,
+ QMetaType::Constructor constructor,
+ QMetaType::TypedDestructor typedDestructor,
+ QMetaType::TypedConstructor typedConstructor,
+ int size, QMetaType::TypeFlags flags, const QMetaObject *metaObject)
{
QVector<QCustomTypeInfo> *ct = customTypes();
- if (!ct || normalizedTypeName.isEmpty() || !destructor || !constructor)
+ if (!ct || normalizedTypeName.isEmpty() || (!destructor && !typedDestructor) || (!constructor && !typedConstructor))
return -1;
int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
@@ -1111,13 +1095,13 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
int previousSize = 0;
QMetaType::TypeFlags::Int previousFlags = 0;
- if (idx == UnknownType) {
+ if (idx == QMetaType::UnknownType) {
QWriteLocker locker(customTypesLock());
int posInVector = -1;
idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
normalizedTypeName.size(),
&posInVector);
- if (idx == UnknownType) {
+ if (idx == QMetaType::UnknownType) {
QCustomTypeInfo inf;
inf.typeName = normalizedTypeName;
#ifndef QT_NO_DATASTREAM
@@ -1125,30 +1109,32 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
inf.saveOp = 0;
#endif
inf.alias = -1;
+ inf.typedConstructor = typedConstructor;
+ inf.typedDestructor = typedDestructor;
inf.constructor = constructor;
inf.destructor = destructor;
inf.size = size;
inf.flags = flags;
inf.metaObject = metaObject;
if (posInVector == -1) {
- idx = ct->size() + User;
+ idx = ct->size() + QMetaType::User;
ct->append(inf);
} else {
- idx = posInVector + User;
+ idx = posInVector + QMetaType::User;
ct->data()[posInVector] = inf;
}
return idx;
}
- if (idx >= User) {
- previousSize = ct->at(idx - User).size;
- previousFlags = ct->at(idx - User).flags;
+ if (idx >= QMetaType::User) {
+ previousSize = ct->at(idx - QMetaType::User).size;
+ previousFlags = ct->at(idx - QMetaType::User).flags;
// Set new/additional flags in case of old library/app.
// Ensures that older code works in conjunction with new Qt releases
// requiring the new flags.
if (flags != previousFlags) {
- QCustomTypeInfo &inf = ct->data()[idx - User];
+ QCustomTypeInfo &inf = ct->data()[idx - QMetaType::User];
inf.flags |= flags;
if (metaObject)
inf.metaObject = metaObject;
@@ -1156,7 +1142,7 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
}
}
- if (idx < User) {
+ if (idx < QMetaType::User) {
previousSize = QMetaType::sizeOf(idx);
previousFlags = QMetaType::typeFlags(idx);
}
@@ -1169,8 +1155,8 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
}
// these flags cannot change in a binary compatible way:
- const int binaryCompatibilityFlag = PointerToQObject | IsEnumeration | SharedPointerToQObject
- | WeakPointerToQObject | TrackingPointerToQObject;
+ const int binaryCompatibilityFlag = QMetaType::PointerToQObject | QMetaType::IsEnumeration | QMetaType::SharedPointerToQObject
+ | QMetaType::WeakPointerToQObject | QMetaType::TrackingPointerToQObject;
if (Q_UNLIKELY((previousFlags ^ flags) & binaryCompatibilityFlag)) {
const char *msg = "QMetaType::registerType: Binary compatibility break. "
@@ -1184,6 +1170,66 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
}
/*!
+ \internal
+ \since 5.0
+ \overload
+ Don't use, kept for binary compatibility
+
+ ### TODO Qt6: remove me
+*/
+int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter,
+ Creator creator,
+ Destructor destructor,
+ Constructor constructor,
+ int size, TypeFlags flags, const QMetaObject *metaObject)
+{
+ Q_UNUSED(deleter);
+ Q_UNUSED(creator);
+ return registerNormalizedType(normalizedTypeName, destructor, constructor, size, flags, metaObject);
+}
+
+
+/*!
+ \internal
+ \since 5.5
+
+ Registers a user type for marshalling, with \a normalizedTypeName,
+ a \a destructor, a \a constructor, and a \a size. Returns the type's
+ handle, or -1 if the type could not be registered.
+
+ \note normalizedTypeName is not checked for conformance with
+ Qt's normalized format, so it must already conform.
+
+ ### TODO Qt6: remove me
+ */
+int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
+ Destructor destructor,
+ Constructor constructor,
+ int size, TypeFlags flags, const QMetaObject *metaObject)
+{
+ return NS(registerNormalizedType)(normalizedTypeName, destructor, constructor, nullptr, nullptr, size, flags, metaObject);
+}
+
+/*!
+ \internal
+ \since 5.12
+
+ Registers a user type for marshalling, with \a normalizedTypeName,
+ a \a destructor, a \a constructor, and a \a size. Returns the type's
+ handle, or -1 if the type could not be registered.
+
+ \note normalizedTypeName is not checked for conformance with
+ Qt's normalized format, so it must already conform.
+ */
+int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
+ TypedDestructor destructor,
+ TypedConstructor constructor,
+ int size, TypeFlags flags, const QMetaObject *metaObject)
+{
+ return NS(registerNormalizedType)(normalizedTypeName, nullptr, nullptr, destructor, constructor, size, flags, metaObject);
+}
+
+/*!
\internal
\since 4.7
@@ -1360,6 +1406,9 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
case QMetaType::QJsonObject:
case QMetaType::QJsonArray:
case QMetaType::QJsonDocument:
+ case QMetaType::QCborValue:
+ case QMetaType::QCborArray:
+ case QMetaType::QCborMap:
return false;
case QMetaType::Nullptr:
stream << *static_cast<const std::nullptr_t *>(data);
@@ -1498,6 +1547,9 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
case QMetaType::QEasingCurve:
stream << *static_cast<const NS(QEasingCurve)*>(data);
break;
+ case QMetaType::QCborSimpleType:
+ stream << *static_cast<const quint8 *>(data);
+ break;
#endif // QT_BOOTSTRAPPED
case QMetaType::QFont:
case QMetaType::QPixmap:
@@ -1586,6 +1638,9 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
case QMetaType::QJsonObject:
case QMetaType::QJsonArray:
case QMetaType::QJsonDocument:
+ case QMetaType::QCborValue:
+ case QMetaType::QCborArray:
+ case QMetaType::QCborMap:
return false;
case QMetaType::Nullptr:
stream >> *static_cast<std::nullptr_t *>(data);
@@ -1730,6 +1785,9 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
case QMetaType::QEasingCurve:
stream >> *static_cast< NS(QEasingCurve)*>(data);
break;
+ case QMetaType::QCborSimpleType:
+ stream >> *static_cast<quint8 *>(data);
+ break;
#endif // QT_BOOTSTRAPPED
case QMetaType::QFont:
case QMetaType::QPixmap:
@@ -1849,14 +1907,19 @@ private:
static void *customTypeConstructor(const int type, void *where, const void *copy)
{
QMetaType::Constructor ctor;
+ QMetaType::TypedConstructor tctor;
const QVector<QCustomTypeInfo> * const ct = customTypes();
{
QReadLocker locker(customTypesLock());
if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
return 0;
- ctor = ct->at(type - QMetaType::User).constructor;
+ const auto &typeInfo = ct->at(type - QMetaType::User);
+ ctor = typeInfo.constructor;
+ tctor = typeInfo.typedConstructor;
}
- Q_ASSERT_X(ctor, "void *QMetaType::construct(int type, void *where, const void *copy)", "The type was not properly registered");
+ Q_ASSERT_X((ctor || tctor) , "void *QMetaType::construct(int type, void *where, const void *copy)", "The type was not properly registered");
+ if (Q_UNLIKELY(tctor))
+ return tctor(type, where, copy);
return ctor(where, copy);
}
@@ -1942,14 +2005,19 @@ private:
static void customTypeDestructor(const int type, void *where)
{
QMetaType::Destructor dtor;
+ QMetaType::TypedDestructor tdtor;
const QVector<QCustomTypeInfo> * const ct = customTypes();
{
QReadLocker locker(customTypesLock());
if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User))
return;
- dtor = ct->at(type - QMetaType::User).destructor;
+ const auto &typeInfo = ct->at(type - QMetaType::User);
+ dtor = typeInfo.destructor;
+ tdtor = typeInfo.typedDestructor;
}
- Q_ASSERT_X(dtor, "void QMetaType::destruct(int type, void *where)", "The type was not properly registered");
+ Q_ASSERT_X((dtor || tdtor), "void QMetaType::destruct(int type, void *where)", "The type was not properly registered");
+ if (Q_UNLIKELY(tdtor))
+ return tdtor(type, where);
dtor(where);
}
@@ -2362,10 +2430,12 @@ QMetaType QMetaType::typeInfo(const int type)
{
TypeInfo typeInfo(type);
QMetaTypeSwitcher::switcher<void>(typeInfo, type, 0);
- return typeInfo.info.constructor ? QMetaType(static_cast<ExtensionFlag>(QMetaType::CreateEx | QMetaType::DestroyEx)
- , static_cast<const QMetaTypeInterface *>(0) // typeInfo::info is a temporary variable, we can't return address of it.
- , 0 // unused
- , 0 // unused
+ return (typeInfo.info.constructor || typeInfo.info.typedConstructor)
+ ? QMetaType(static_cast<ExtensionFlag>(QMetaType::CreateEx | QMetaType::DestroyEx |
+ (typeInfo.info.typedConstructor ? QMetaType::ConstructEx | QMetaType::DestructEx : 0))
+ , static_cast<const QMetaTypeInterface *>(nullptr) // typeInfo::info is a temporary variable, we can't return address of it.
+ , typeInfo.info.typedConstructor
+ , typeInfo.info.typedDestructor
, typeInfo.info.saveOp
, typeInfo.info.loadOp
, typeInfo.info.constructor
@@ -2407,8 +2477,8 @@ QMetaType::QMetaType(const int typeId)
Copy constructs a QMetaType object.
*/
QMetaType::QMetaType(const QMetaType &other)
- : m_creator_unused(other.m_creator_unused)
- , m_deleter_unused(other.m_deleter_unused)
+ : m_typedConstructor(other.m_typedConstructor)
+ , m_typedDestructor(other.m_typedDestructor)
, m_saveOp(other.m_saveOp)
, m_loadOp(other.m_loadOp)
, m_constructor(other.m_constructor)
@@ -2423,8 +2493,8 @@ QMetaType::QMetaType(const QMetaType &other)
QMetaType &QMetaType::operator =(const QMetaType &other)
{
- m_creator_unused = other.m_creator_unused;
- m_deleter_unused = other.m_deleter_unused;
+ m_typedConstructor = other.m_typedConstructor;
+ m_typedDestructor = other.m_typedDestructor;
m_saveOp = other.m_saveOp;
m_loadOp = other.m_loadOp;
m_constructor = other.m_constructor;
@@ -2480,6 +2550,8 @@ void *QMetaType::createExtended(const void *copy) const
{
if (m_typeId == QMetaType::UnknownType)
return 0;
+ if (Q_UNLIKELY(m_typedConstructor && !m_constructor))
+ return m_typedConstructor(m_typeId, operator new(m_size), copy);
return m_constructor(operator new(m_size), copy);
}
@@ -2494,7 +2566,10 @@ void *QMetaType::createExtended(const void *copy) const
*/
void QMetaType::destroyExtended(void *data) const
{
- m_destructor(data);
+ if (Q_UNLIKELY(m_typedDestructor && !m_destructor))
+ m_typedDestructor(m_typeId, data);
+ else
+ m_destructor(data);
operator delete(data);
}
@@ -2507,9 +2582,9 @@ void QMetaType::destroyExtended(void *data) const
*/
void *QMetaType::constructExtended(void *where, const void *copy) const
{
- Q_UNUSED(where);
- Q_UNUSED(copy);
- return 0;
+ if (m_typedConstructor && !m_constructor)
+ return m_typedConstructor(m_typeId, where, copy);
+ return nullptr;
}
/*!
@@ -2521,7 +2596,8 @@ void *QMetaType::constructExtended(void *where, const void *copy) const
*/
void QMetaType::destructExtended(void *data) const
{
- Q_UNUSED(data);
+ if (m_typedDestructor && !m_destructor)
+ m_typedDestructor(m_typeId, data);
}
/*!
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index cf68752f85..ed7feee775 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
@@ -60,6 +61,9 @@
QT_BEGIN_NAMESPACE
+// from qcborcommon.h
+enum class QCborSimpleType : quint8;
+
template <typename T>
struct QMetaTypeId2;
@@ -85,6 +89,7 @@ inline Q_DECL_CONSTEXPR int qMetaTypeId();
F(Float, 38, float) \
F(SChar, 40, signed char) \
F(Nullptr, 51, std::nullptr_t) \
+ F(QCborSimpleType, 52, QCborSimpleType) \
#define QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(F)\
F(VoidStar, 31, void*) \
@@ -125,6 +130,9 @@ inline Q_DECL_CONSTEXPR int qMetaTypeId();
F(QJsonObject, 46, QJsonObject) \
F(QJsonArray, 47, QJsonArray) \
F(QJsonDocument, 48, QJsonDocument) \
+ F(QCborValue, 53, QCborValue) \
+ F(QCborArray, 54, QCborArray) \
+ F(QCborMap, 55, QCborMap) \
QT_FOR_EACH_STATIC_ITEMMODEL_CLASS(F)
#define QT_FOR_EACH_STATIC_CORE_POINTER(F)\
@@ -420,7 +428,7 @@ public:
QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
FirstCoreType = Bool,
- LastCoreType = Nullptr,
+ LastCoreType = QCborMap,
FirstGuiType = QFont,
LastGuiType = QPolygonF,
FirstWidgetsType = QSizePolicy,
@@ -450,13 +458,18 @@ public:
Void = 43,
Nullptr = 51,
QVariantMap = 8, QVariantList = 9, QVariantHash = 28,
+ QCborSimpleType = 52, QCborValue = 53, QCborArray = 54, QCborMap = 55,
+
+ // Gui types
QFont = 64, QPixmap = 65, QBrush = 66, QColor = 67, QPalette = 68,
QIcon = 69, QImage = 70, QPolygon = 71, QRegion = 72, QBitmap = 73,
QCursor = 74, QKeySequence = 75, QPen = 76, QTextLength = 77, QTextFormat = 78,
QMatrix = 79, QTransform = 80, QMatrix4x4 = 81, QVector2D = 82,
QVector3D = 83, QVector4D = 84, QQuaternion = 85, QPolygonF = 86,
+
+ // Widget types
QSizePolicy = 121,
- LastCoreType = Nullptr,
+ LastCoreType = QCborMap,
LastGuiType = QPolygonF,
User = 1024
};
@@ -480,8 +493,12 @@ public:
typedef void (*Deleter)(void *);
typedef void *(*Creator)(const void *);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
typedef void (*Destructor)(void *);
- typedef void *(*Constructor)(void *, const void *);
+ typedef void *(*Constructor)(void *, const void *); // TODO Qt6: remove me
+#endif
+ typedef void (*TypedDestructor)(int, void *);
+ typedef void *(*TypedConstructor)(int, void *, const void *);
typedef void (*SaveOperator)(QDataStream &, const void *);
typedef void (*LoadOperator)(QDataStream &, void *);
@@ -500,6 +517,12 @@ public:
int size,
QMetaType::TypeFlags flags,
const QMetaObject *metaObject);
+ static int registerType(const char *typeName,
+ TypedDestructor destructor,
+ TypedConstructor constructor,
+ int size,
+ QMetaType::TypeFlags flags,
+ const QMetaObject *metaObject);
static bool unregisterType(int type);
static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Deleter deleter,
Creator creator,
@@ -513,6 +536,11 @@ public:
int size,
QMetaType::TypeFlags flags,
const QMetaObject *metaObject);
+ static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, TypedDestructor destructor,
+ TypedConstructor constructor,
+ int size,
+ QMetaType::TypeFlags flags,
+ const QMetaObject *metaObject);
static int registerTypedef(const char *typeName, int aliasId);
static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId);
static int type(const char *typeName);
@@ -670,8 +698,8 @@ public:
private:
static QMetaType typeInfo(const int type);
inline QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
- Creator creator,
- Deleter deleter,
+ TypedConstructor creator,
+ TypedDestructor deleter,
SaveOperator saveOp,
LoadOperator loadOp,
Constructor constructor,
@@ -718,8 +746,8 @@ public:
static void unregisterConverterFunction(int from, int to);
private:
- Creator m_creator_unused;
- Deleter m_deleter_unused;
+ TypedConstructor m_typedConstructor;
+ TypedDestructor m_typedDestructor;
SaveOperator m_saveOp;
LoadOperator m_loadOp;
Constructor m_constructor;
@@ -2150,8 +2178,8 @@ QT_BEGIN_NAMESPACE
#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
- Creator creator,
- Deleter deleter,
+ TypedConstructor creator,
+ TypedDestructor deleter,
SaveOperator saveOp,
LoadOperator loadOp,
Constructor constructor,
@@ -2160,8 +2188,8 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI
uint theTypeFlags,
int typeId,
const QMetaObject *_metaObject)
- : m_creator_unused(creator)
- , m_deleter_unused(deleter)
+ : m_typedConstructor(creator)
+ , m_typedDestructor(deleter)
, m_saveOp(saveOp)
, m_loadOp(loadOp)
, m_constructor(constructor)
diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h
index cef20a5d12..94e9228778 100644
--- a/src/corelib/kernel/qmetatype_p.h
+++ b/src/corelib/kernel/qmetatype_p.h
@@ -126,11 +126,13 @@ class QMetaTypeInterface
public:
QMetaType::SaveOperator saveOp;
QMetaType::LoadOperator loadOp;
- QMetaType::Constructor constructor;
+ QMetaType::Constructor constructor; // TODO Qt6: remove me
QMetaType::Destructor destructor;
int size;
QMetaType::TypeFlags::Int flags;
const QMetaObject *metaObject;
+ QMetaType::TypedConstructor typedConstructor;
+ QMetaType::TypedDestructor typedDestructor;
};
#ifndef QT_NO_DATASTREAM
@@ -161,7 +163,9 @@ public:
/*destructor*/(QtMetaTypePrivate::QMetaTypeFunctionHelper<Type, QtMetaTypePrivate::TypeDefinition<Type>::IsAvailable>::Destruct), \
/*size*/(QTypeInfo<Type>::sizeOf), \
/*flags*/QtPrivate::QMetaTypeTypeFlags<Type>::Flags, \
- /*metaObject*/METAOBJECT_DELEGATE(Type) \
+ /*metaObject*/METAOBJECT_DELEGATE(Type), \
+ /*typedConstructor*/ nullptr, \
+ /*typedDestructor*/ nullptr \
}
@@ -184,7 +188,9 @@ public:
/*destructor*/ 0, \
/*size*/ 0, \
/*flags*/ 0, \
- /*metaObject*/ 0 \
+ /*metaObject*/ 0 , \
+ /*typedConstructor*/ nullptr, \
+ /*typedDestructor*/ nullptr \
}
namespace QtMetaTypePrivate {
@@ -196,6 +202,10 @@ struct TypeDefinition {
// Ignore these types, as incomplete
#ifdef QT_BOOTSTRAPPED
template<> struct TypeDefinition<QBitArray> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QCborArray> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QCborMap> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QCborSimpleType> { static const bool IsAvailable = false; };
+template<> struct TypeDefinition<QCborValue> { static const bool IsAvailable = false; };
template<> struct TypeDefinition<QEasingCurve> { static const bool IsAvailable = false; };
template<> struct TypeDefinition<QJsonArray> { static const bool IsAvailable = false; };
template<> struct TypeDefinition<QJsonDocument> { static const bool IsAvailable = false; };
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index c6fe787e03..3cb8c45b41 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -59,11 +59,14 @@
#include <qpair.h>
#include <qvarlengtharray.h>
#include <qset.h>
+#if QT_CONFIG(thread)
#include <qsemaphore.h>
+#endif
#include <qsharedpointer.h>
#include <private/qorderedmutexlocker_p.h>
#include <private/qhooks_p.h>
+#include <qtcore_tracepoints_p.h>
#include <new>
@@ -487,7 +490,7 @@ QMetaCallEvent::~QMetaCallEvent()
free(types_);
free(args_);
}
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
if (semaphore_)
semaphore_->release();
#endif
@@ -820,6 +823,7 @@ QObject::QObject(QObject *parent)
#endif
if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
+ Q_TRACE(QObject_ctor, this);
}
/*!
@@ -855,6 +859,7 @@ QObject::QObject(QObjectPrivate &dd, QObject *parent)
#endif
if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
+ Q_TRACE(QObject_ctor, this);
}
/*!
@@ -1030,6 +1035,8 @@ QObject::~QObject()
if (Q_UNLIKELY(qtHookData[QHooks::RemoveQObject]))
reinterpret_cast<QHooks::RemoveQObjectCallback>(qtHookData[QHooks::RemoveQObject])(this);
+ Q_TRACE(QObject_dtor, this);
+
if (d->parent) // remove it from parent object
d->setParent_helper(0);
}
@@ -3645,13 +3652,17 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
if (sender->d_func()->isDeclarativeSignalConnected(signal_index)
&& QAbstractDeclarativeData::signalEmitted) {
+ Q_TRACE(QMetaObject_activate_begin_declarative_signal, sender, signal_index);
QAbstractDeclarativeData::signalEmitted(sender->d_func()->declarativeData, sender,
signal_index, argv);
+ Q_TRACE(QMetaObject_activate_end_declarative_signal, sender, signal_index);
}
if (!sender->d_func()->isSignalConnected(signal_index, /*checkDeclarative =*/ false)
&& !qt_signal_spy_callback_set.signal_begin_callback
- && !qt_signal_spy_callback_set.signal_end_callback) {
+ && !qt_signal_spy_callback_set.signal_end_callback
+ && !Q_TRACE_ENABLED(QMetaObject_activate_begin_signal)
+ && !Q_TRACE_ENABLED(QMetaObject_activate_end_signal)) {
// The possible declarative connection is done, and nothing else is connected, so:
return;
}
@@ -3661,6 +3672,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index,
argv ? argv : empty_argv);
}
+ Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index);
{
QMutexLocker locker(signalSlotLock(sender));
@@ -3691,6 +3703,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
locker.unlock();
if (qt_signal_spy_callback_set.signal_end_callback != 0)
qt_signal_spy_callback_set.signal_end_callback(sender, signal_index);
+ Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
return;
}
@@ -3722,7 +3735,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
|| (c->connectionType == Qt::QueuedConnection)) {
queued_activate(sender, signal_index, c, argv ? argv : empty_argv, locker);
continue;
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
if (receiverInSameThread) {
qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
@@ -3751,7 +3764,9 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
c->slotObj->ref();
QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj);
locker.unlock();
+ Q_TRACE(QMetaObject_activate_begin_slot_functor, obj.data());
obj->call(receiver, argv ? argv : empty_argv);
+ Q_TRACE(QMetaObject_activate_end_slot_functor, obj.data());
// Make sure the slot object gets destroyed before the mutex is locked again, as the
// destructor of the slot object might also lock a mutex from the signalSlotLock() mutex pool,
@@ -3767,9 +3782,11 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
locker.unlock();
if (qt_signal_spy_callback_set.slot_begin_callback != 0)
qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv ? argv : empty_argv);
+ Q_TRACE(QMetaObject_activate_begin_slot, receiver, methodIndex);
callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
+ Q_TRACE(QMetaObject_activate_end_slot, receiver, methodIndex);
if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(receiver, methodIndex);
locker.relock();
@@ -3782,9 +3799,11 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
method,
argv ? argv : empty_argv);
}
+ Q_TRACE(QMetaObject_activate_begin_slot, receiver, method);
metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
+ Q_TRACE(QMetaObject_activate_end_slot, receiver, method);
if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(receiver, method);
@@ -3805,7 +3824,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
if (qt_signal_spy_callback_set.signal_end_callback != 0)
qt_signal_spy_callback_set.signal_end_callback(sender, signal_index);
-
+ Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
}
/*!
@@ -4534,6 +4553,11 @@ QDebug operator<<(QDebug dbg, const QObject *o)
invoked using QMetaObject::invokeMethod().
Since \c normalMethod() function is not registered in this way, it cannot
be invoked using QMetaObject::invokeMethod().
+
+ If an invokable member function returns a pointer to a QObject or a
+ subclass of QObject and it is invoked from QML, special ownership rules
+ apply. See \l{qtqml-cppintegration-data.html}{Data Type Conversion Between QML and C++}
+ for more information.
*/
/*!
@@ -4681,7 +4705,7 @@ void qDeleteInEventHandler(QObject *o)
The signal must be a function declared as a signal in the header.
The slot function can be any function or functor that can be connected
to the signal.
- A function can be connected to a given signal if the signal as at
+ A function can be connected to a given signal if the signal has at
least as many argument as the slot. A functor can be connected to a signal
if they have exactly the same number of arguments. There must exist implicit
conversion between the types of the corresponding arguments in the
@@ -4721,7 +4745,7 @@ void qDeleteInEventHandler(QObject *o)
The signal must be a function declared as a signal in the header.
The slot function can be any function or functor that can be connected
to the signal.
- A function can be connected to a given signal if the signal as at
+ A function can be connected to a given signal if the signal has at
least as many argument as the slot. A functor can be connected to a signal
if they have exactly the same number of arguments. There must exist implicit
conversion between the types of the corresponding arguments in the
@@ -4804,7 +4828,12 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
const int *types, const QMetaObject *senderMetaObject)
{
if (!sender || !receiver || !slotObj || !senderMetaObject) {
- qWarning("QObject::connect: invalid null parameter");
+ const char *senderString = sender ? sender->metaObject()->className()
+ : senderMetaObject ? senderMetaObject->className()
+ : "Unknown";
+ const char *receiverString = receiver ? receiver->metaObject()->className()
+ : "Unknown";
+ qWarning("QObject::connect(%s, %s): invalid null parameter", senderString, receiverString);
if (slotObj)
slotObj->destroyIfLastRef();
return QMetaObject::Connection();
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index a6ad00ea22..8afff1fb98 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -112,13 +112,31 @@ namespace QtPrivate {
The Functor<Func,N> struct is the helper to call a functor of N argument.
its call function is the same as the FunctionPointer::call function.
*/
- template <int...> struct IndexesList {};
- template <typename IndexList, int Right> struct IndexesAppend;
- template <int... Left, int Right> struct IndexesAppend<IndexesList<Left...>, Right>
- { typedef IndexesList<Left..., Right> Value; };
- template <int N> struct Indexes
- { typedef typename IndexesAppend<typename Indexes<N - 1>::Value, N - 1>::Value Value; };
- template <> struct Indexes<0> { typedef IndexesList<> Value; };
+ template<class T> using InvokeGenSeq = typename T::Type;
+
+ template<int...> struct IndexesList { using Type = IndexesList; };
+
+ template<int N, class S1, class S2> struct ConcatSeqImpl;
+
+ template<int N, int... I1, int... I2>
+ struct ConcatSeqImpl<N, IndexesList<I1...>, IndexesList<I2...>>
+ : IndexesList<I1..., (N + I2)...>{};
+
+ template<int N, class S1, class S2>
+ using ConcatSeq = InvokeGenSeq<ConcatSeqImpl<N, S1, S2>>;
+
+ template<int N> struct GenSeq;
+ template<int N> using makeIndexSequence = InvokeGenSeq<GenSeq<N>>;
+
+ template<int N>
+ struct GenSeq : ConcatSeq<N/2, makeIndexSequence<N/2>, makeIndexSequence<N - N/2>>{};
+
+ template<> struct GenSeq<0> : IndexesList<>{};
+ template<> struct GenSeq<1> : IndexesList<0>{};
+
+ template<int N>
+ struct Indexes { using Value = makeIndexSequence<N>; };
+
template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1, IsPointerToMemberFunction = false}; };
template <typename, typename, typename, typename> struct FunctorCall;
diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp
index be42a369c2..c1dba30e2b 100644
--- a/src/corelib/kernel/qsharedmemory_win.cpp
+++ b/src/corelib/kernel/qsharedmemory_win.cpp
@@ -101,7 +101,8 @@ HANDLE QSharedMemoryPrivate::handle()
#if defined(Q_OS_WINRT)
hand = OpenFileMappingFromApp(FILE_MAP_ALL_ACCESS, FALSE, reinterpret_cast<PCWSTR>(nativeKey.utf16()));
#else
- hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, (wchar_t*)nativeKey.utf16());
+ hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false,
+ reinterpret_cast<const wchar_t*>(nativeKey.utf16()));
#endif
if (!hand) {
setErrorString(function);
@@ -133,17 +134,16 @@ bool QSharedMemoryPrivate::create(int size)
// Create the file mapping.
#if defined(Q_OS_WINRT)
- hand = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, size, (PCWSTR)nativeKey.utf16());
+ hand = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, size,
+ reinterpret_cast<PCWSTR>(nativeKey.utf16()));
#else
- hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size, (wchar_t*)nativeKey.utf16());
+ hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, size,
+ reinterpret_cast<const wchar_t*>(nativeKey.utf16()));
#endif
setErrorString(function);
// hand is valid when it already exists unlike unix so explicitly check
- if (error == QSharedMemory::AlreadyExists || !hand)
- return false;
-
- return true;
+ return error != QSharedMemory::AlreadyExists && hand;
}
bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp
index fc825257ec..53c3136857 100644
--- a/src/corelib/kernel/qsystemerror.cpp
+++ b/src/corelib/kernel/qsystemerror.cpp
@@ -49,7 +49,7 @@
QT_BEGIN_NAMESPACE
-#if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \
+#if !defined(Q_OS_WIN) && QT_CONFIG(thread) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \
defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
namespace {
// There are two incompatible versions of strerror_r:
@@ -130,7 +130,7 @@ static QString standardLibraryErrorString(int errorCode)
s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device");
break;
default: {
- #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX)
+ #if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX)
QByteArray buf(1024, Qt::Uninitialized);
ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf);
#else
diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp
index 3395f5641e..2b35803291 100644
--- a/src/corelib/kernel/qsystemsemaphore_win.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_win.cpp
@@ -86,9 +86,12 @@ HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode)
// Create it if it doesn't already exists.
if (semaphore == 0) {
#if defined(Q_OS_WINRT)
- semaphore = CreateSemaphoreEx(0, initialValue, MAXLONG, (wchar_t*)fileName.utf16(), 0, SEMAPHORE_ALL_ACCESS);
+ semaphore = CreateSemaphoreEx(0, initialValue, MAXLONG,
+ reinterpret_cast<const wchar_t*>(fileName.utf16()),
+ 0, SEMAPHORE_ALL_ACCESS);
#else
- semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)fileName.utf16());
+ semaphore = CreateSemaphore(0, initialValue, MAXLONG,
+ reinterpret_cast<const wchar_t*>(fileName.utf16()));
#endif
if (semaphore == NULL)
setErrorString(QLatin1String("QSystemSemaphore::handle"));
diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp
index 86992ce10b..5437210699 100644
--- a/src/corelib/kernel/qtcore_eval.cpp
+++ b/src/corelib/kernel/qtcore_eval.cpp
@@ -168,7 +168,7 @@ public:
}
}
- void timerEvent(QTimerEvent *e) {
+ void timerEvent(QTimerEvent *e) override {
if (e->timerId() == warn) {
killTimer(warn);
fprintf(stderr, "%s\n", will_shutdown_1min);
diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp
new file mode 100644
index 0000000000..240e5795db
--- /dev/null
+++ b/src/corelib/kernel/qtestsupport_core.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestsupport_core.h"
+
+#ifdef Q_OS_WIN
+#include <qt_windows.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+Q_CORE_EXPORT void QTestPrivate::qSleep(int ms)
+{
+ Q_ASSERT(ms > 0);
+
+#if defined(Q_OS_WINRT)
+ WaitForSingleObjectEx(GetCurrentThread(), ms, true);
+#elif defined(Q_OS_WIN)
+ Sleep(uint(ms));
+#else
+ struct timespec ts = { time_t(ms / 1000), (ms % 1000) * 1000 * 1000 };
+ nanosleep(&ts, NULL);
+#endif
+}
+
+/*! \fn template <typename Functor> bool qWaitFor(Functor predicate, int timeout)
+ \relates QTest
+
+ Waits for \a timeout milliseconds or until the \a predicate returns true.
+
+ Returns \c true if the \a predicate returned true at any point, otherwise returns \c false.
+
+ Example:
+
+ \code
+ MyObject obj;
+ obj.startup();
+ QTest::qWaitFor([&]() {
+ return obj.isReady();
+ }, 3000);
+ \endcode
+
+ The code above will wait for the object to become ready, for a
+ maximum of three seconds.
+
+ \since 5.10
+*/
+
+
+/*! \fn void qWait(int ms)
+ \relates QTest
+
+ Waits for \a ms milliseconds. While waiting, events will be processed and
+ your test will stay responsive to user interface events or network communication.
+
+ Example:
+
+ \code
+ int i = 0;
+ while (myNetworkServerNotResponding() && i++ < 50)
+ QTest::qWait(250);
+ \endcode
+
+ The code above will wait until the network server is responding for a
+ maximum of about 12.5 seconds.
+
+ \sa QTest::qSleep(), QSignalSpy::wait()
+*/
+Q_CORE_EXPORT void QTest::qWait(int ms)
+{
+ // Ideally this method would be implemented in terms of qWaitFor, with
+ // a predicate that always returns false, but due to a compiler bug in
+ // GCC 6 we can't do that.
+
+ Q_ASSERT(QCoreApplication::instance());
+
+ QDeadlineTimer timer(ms, Qt::PreciseTimer);
+ int remaining = ms;
+ do {
+ QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
+ QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete);
+ remaining = timer.remainingTime();
+ if (remaining <= 0)
+ break;
+ QTestPrivate::qSleep(qMin(10, remaining));
+ remaining = timer.remainingTime();
+ } while (remaining > 0);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qtestsupport_core.h b/src/corelib/kernel/qtestsupport_core.h
new file mode 100644
index 0000000000..7fc0054580
--- /dev/null
+++ b/src/corelib/kernel/qtestsupport_core.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTSUPPORT_CORE_H
+#define QTESTSUPPORT_CORE_H
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdeadlinetimer.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QTestPrivate {
+Q_CORE_EXPORT void qSleep(int ms);
+}
+
+namespace QTest {
+
+template <typename Functor>
+Q_REQUIRED_RESULT static bool qWaitFor(Functor predicate, int timeout = 5000)
+{
+ // We should not spin the event loop in case the predicate is already true,
+ // otherwise we might send new events that invalidate the predicate.
+ if (predicate())
+ return true;
+
+ // qWait() is expected to spin the event loop, even when called with a small
+ // timeout like 1ms, so we we can't use a simple while-loop here based on
+ // the deadline timer not having timed out. Use do-while instead.
+
+ int remaining = timeout;
+ QDeadlineTimer deadline(remaining, Qt::PreciseTimer);
+
+ do {
+ QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+
+ remaining = deadline.remainingTime();
+ if (remaining > 0)
+ QTestPrivate::qSleep(qMin(10, remaining));
+
+ if (predicate())
+ return true;
+
+ remaining = deadline.remainingTime();
+ } while (remaining > 0);
+
+ return predicate(); // Last chance
+}
+
+Q_CORE_EXPORT void qWait(int ms);
+
+} // namespace QTest
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 3edd1f056e..90f29aa630 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -571,6 +571,48 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv
*/
/*!
+ \fn template<typename Functor> QMetaObject::Connection callOnTimeout(Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection)
+ \since 5.12
+ \overload
+
+ Creates a connection from the timeout() signal to \a functor, and returns a
+ handle to the connection.
+
+ This method is provided for convenience.
+ It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, functor, connectionType)}.
+
+ \sa QObject::connect(), timeout()
+*/
+
+/*!
+ \fn template<typename Functor> QMetaObject::Connection callOnTimeout(QObject *context, Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection)
+ \since 5.12
+ \overload callOnTimeout()
+
+ Creates a connection from the timeout() signal to \a functor to be placed in a specific
+ event loop of \a context, and returns a handle to the connection.
+
+ This method is provided for convenience. It's equivalent to calling
+ \c {QObject::connect(timer, &QTimer::timeout, context, functor, connectionType)}.
+
+ \sa QObject::connect(), timeout()
+*/
+
+/*!
+ \fn template<typename PointerToMemberFunction> QMetaObject::Connection callOnTimeout(QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType connectionType = Qt::AutoConnection)
+ \since 5.12
+ \overload callOnTimeout()
+
+ Creates a connection from the timeout() signal to the \a method in the \a receiver object. Returns
+ a handle to the connection.
+
+ This method is provided for convenience. It's equivalent to calling
+ \c {QObject::connect(timer, &QTimer::timeout, receiver, method, connectionType)}.
+
+ \sa QObject::connect(), timeout()
+*/
+
+/*!
\fn void QTimer::start(std::chrono::milliseconds msec)
\since 5.8
\overload
diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h
index e6db586aa0..66f317c567 100644
--- a/src/corelib/kernel/qtimer.h
+++ b/src/corelib/kernel/qtimer.h
@@ -96,6 +96,12 @@ public:
static void singleShot(int msec, const QObject *context, Functor functor);
template<typename Functor, int>
static void singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor);
+ template <typename Functor>
+ QMetaObject::Connection callOnTimeout(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
+ template <typename Functor>
+ QMetaObject::Connection callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
+ template <typename PointerToMemberFunction>
+ QMetaObject::Connection callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
#else
// singleShot to a QObject slot
template <typename Duration, typename Func1>
@@ -135,14 +141,14 @@ public:
template <typename Duration, typename Func1>
static inline typename std::enable_if<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
!std::is_same<const char*, Func1>::value, void>::type
- singleShot(Duration interval, QObject *context, Func1 slot)
+ singleShot(Duration interval, const QObject *context, Func1 slot)
{
singleShot(interval, defaultTypeFor(interval), context, std::move(slot));
}
template <typename Duration, typename Func1>
static inline typename std::enable_if<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction &&
!std::is_same<const char*, Func1>::value, void>::type
- singleShot(Duration interval, Qt::TimerType timerType, QObject *context, Func1 slot)
+ singleShot(Duration interval, Qt::TimerType timerType, const QObject *context, Func1 slot)
{
//compilation error if the slot has arguments.
typedef QtPrivate::FunctionPointer<Func1> SlotType;
@@ -152,6 +158,13 @@ public:
new QtPrivate::QFunctorSlotObject<Func1, 0,
typename QtPrivate::List_Left<void, 0>::Value, void>(std::move(slot)));
}
+
+ template <typename ... Args>
+ QMetaObject::Connection callOnTimeout(Args && ...args)
+ {
+ return QObject::connect(this, &QTimer::timeout, std::forward<Args>(args)... );
+ }
+
#endif
public Q_SLOTS:
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index c868f6d266..744bbfbff5 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -49,6 +49,7 @@
#include "qcoreapplication.h"
#include "qcoreapplication_p.h"
#include "qdatastream.h"
+#include "qendian.h"
#include "qfile.h"
#include "qmap.h"
#include "qalgorithms.h"
@@ -532,7 +533,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
// memory, so no need to use QFile to copy it again.
Q_ASSERT(!d->resource);
d->resource = new QResource(realname);
- if (resource->isValid() && !resource->isCompressed() && resource->size() > MagicLength
+ if (resource->isValid() && !resource->isCompressed() && resource->size() >= MagicLength
&& !memcmp(resource->data(), magic, MagicLength)) {
d->unmapLength = resource->size();
d->unmapPointer = reinterpret_cast<char *>(const_cast<uchar *>(resource->data()));
@@ -552,7 +553,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
return false;
qint64 fileSize = file.size();
- if (fileSize <= MagicLength || quint32(-1) <= fileSize)
+ if (fileSize < MagicLength || quint32(-1) <= fileSize)
return false;
{
@@ -857,8 +858,6 @@ bool QTranslatorPrivate::do_load(const uchar *data, int len, const QString &dire
data += blockLen;
}
- if (dependencies.isEmpty() && (!offsetArray || !messageArray))
- ok = false;
if (ok && !isValidNumerusRules(numerusRulesArray, numerusRulesLength))
ok = false;
if (ok) {
@@ -957,8 +956,8 @@ end:
return QString();
QString str = QString((const QChar *)tn, tn_length/2);
if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
- for (int i = 0; i < str.length(); ++i)
- str[i] = QChar((str.at(i).unicode() >> 8) + ((str.at(i).unicode() << 8) & 0xff00));
+ QChar *data = str.data();
+ qbswap<sizeof(QChar)>(data, str.length(), data);
}
return str;
}
@@ -1137,8 +1136,8 @@ QString QTranslator::translate(const char *context, const char *sourceText, cons
bool QTranslator::isEmpty() const
{
Q_D(const QTranslator);
- return !d->unmapPointer && !d->unmapLength && !d->messageArray &&
- !d->offsetArray && !d->contextArray && d->subTranslators.isEmpty();
+ return !d->messageArray && !d->offsetArray && !d->contextArray
+ && d->subTranslators.isEmpty();
}
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 57c25a9423..0b4c3f387f 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
** Contact: https://www.qt.io/licensing/
**
@@ -60,6 +60,9 @@
#include "qabstractitemmodel.h"
#endif
#ifndef QT_BOOTSTRAPPED
+#include "qcborarray.h"
+#include "qcborcommon.h"
+#include "qcbormap.h"
#include "qjsonvalue.h"
#include "qjsonobject.h"
#include "qjsonarray.h"
@@ -167,6 +170,8 @@ static qlonglong qMetaTypeNumber(const QVariant::Private *d)
#ifndef QT_BOOTSTRAPPED
case QMetaType::QJsonValue:
return v_cast<QJsonValue>(d)->toDouble();
+ case QMetaType::QCborValue:
+ return v_cast<QCborValue>(d)->toInteger();
#endif
}
Q_ASSERT(false);
@@ -205,6 +210,10 @@ static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
case QVariant::Bool:
return qlonglong(d->data.b);
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isInteger() && !v_cast<QCborValue>(d)->isDouble())
+ break;
+ return qMetaTypeNumber(d);
case QMetaType::QJsonValue:
if (!v_cast<QJsonValue>(d)->isDouble())
break;
@@ -229,7 +238,7 @@ static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
}
QMetaType typeInfo(d->type);
- if (typeInfo.flags() & QMetaType::IsEnumeration) {
+ if (typeInfo.flags() & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
switch (typeInfo.sizeOf()) {
case 1:
return d->is_shared ? *reinterpret_cast<signed char *>(d->data.shared->ptr) : d->data.sc;
@@ -261,6 +270,8 @@ static qreal qConvertToRealNumber(const QVariant::Private *d, bool *ok)
case QMetaType::ULong:
return qreal(qMetaTypeUNumber(d));
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ return v_cast<QCborValue>(d)->toDouble();
case QMetaType::QJsonValue:
return v_cast<QJsonValue>(d)->toDouble();
#endif
@@ -284,6 +295,12 @@ static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
case QVariant::Bool:
return qulonglong(d->data.b);
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isDouble())
+ return qulonglong(qConvertToRealNumber(d, ok));
+ if (!v_cast<QCborValue>(d)->isInteger())
+ return false;
+ return qulonglong(qMetaTypeNumber(d));
case QMetaType::QJsonValue:
if (!v_cast<QJsonValue>(d)->isDouble())
break;
@@ -391,6 +408,12 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
case QVariant::String:
*static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d));
break;
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isUrl()) {
+ *static_cast<QUrl *>(result) = v_cast<QCborValue>(d)->toUrl();
+ break;
+ }
+ return false;
default:
return false;
}
@@ -476,6 +499,11 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
else if (!v_cast<QJsonValue>(d)->isNull())
return false;
break;
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isContainer() || v_cast<QCborValue>(d)->isTag())
+ return false;
+ *str = v_cast<QCborValue>(d)->toVariant().toString();
+ break;
#endif
case QVariant::Uuid:
*str = v_cast<QUuid>(d)->toString();
@@ -621,6 +649,14 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
case QVariant::String:
*dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
break;
+# ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isDateTime())
+ *dt = v_cast<QCborValue>(d)->toDateTime();
+ else
+ return false;
+ break;
+# endif
#endif
case QVariant::Date:
*dt = QDateTime(*v_cast<QDate>(d));
@@ -668,6 +704,14 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
case QMetaType::Nullptr:
*ba = QByteArray();
break;
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (v_cast<QCborValue>(d)->isByteArray())
+ *ba = v_cast<QCborValue>(d)->toByteArray();
+ else
+ return false;
+ break;
+#endif
default:
#ifndef QT_NO_QOBJECT
{
@@ -746,6 +790,11 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
break;
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ *b = v_cast<QCborValue>(d)->toBool();
+ if (!v_cast<QCborValue>(d)->isBool())
+ return false;
+ break;
case QMetaType::QJsonValue:
*b = v_cast<QJsonValue>(d)->toBool(false);
if (!v_cast<QJsonValue>(d)->isBool())
@@ -789,6 +838,11 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*f = double(qMetaTypeUNumber(d));
break;
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ *f = v_cast<QCborValue>(d)->toDouble();
+ if (!v_cast<QCborValue>(d)->isDouble())
+ return false;
+ break;
case QMetaType::QJsonValue:
*f = v_cast<QJsonValue>(d)->toDouble(0.0);
if (!v_cast<QJsonValue>(d)->isDouble())
@@ -832,6 +886,11 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*f = float(qMetaTypeUNumber(d));
break;
#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ *f = v_cast<QCborValue>(d)->toDouble();
+ if (!v_cast<QCborValue>(d)->isDouble())
+ return false;
+ break;
case QMetaType::QJsonValue:
*f = v_cast<QJsonValue>(d)->toDouble(0.0);
if (!v_cast<QJsonValue>(d)->isDouble())
@@ -856,6 +915,12 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*static_cast<QVariantList *>(result) =
*static_cast<QList<QVariant> *>(d->data.shared->ptr);
#ifndef QT_BOOTSTRAPPED
+ } else if (d->type == QMetaType::QCborValue) {
+ if (!v_cast<QCborValue>(d)->isArray())
+ return false;
+ *static_cast<QVariantList *>(result) = v_cast<QCborValue>(d)->toArray().toVariantList();
+ } else if (d->type == QMetaType::QCborArray) {
+ *static_cast<QVariantList *>(result) = v_cast<QCborArray>(d)->toVariantList();
} else if (d->type == QMetaType::QJsonValue) {
if (!v_cast<QJsonValue>(d)->isArray())
return false;
@@ -878,6 +943,12 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
for (auto it = hash->begin(); it != end; ++it)
map->insertMulti(it.key(), it.value());
#ifndef QT_BOOTSTRAPPED
+ } else if (d->type == QMetaType::QCborValue) {
+ if (!v_cast<QCborValue>(d)->isMap())
+ return false;
+ *static_cast<QVariantMap *>(result) = v_cast<QCborValue>(d)->toMap().toVariantMap();
+ } else if (d->type == QMetaType::QCborMap) {
+ *static_cast<QVariantMap *>(result) = v_cast<QCborMap>(d)->toVariantMap();
} else if (d->type == QMetaType::QJsonValue) {
if (!v_cast<QJsonValue>(d)->isObject())
return false;
@@ -900,6 +971,12 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
for (auto it = map->begin(); it != end; ++it)
hash->insertMulti(it.key(), it.value());
#ifndef QT_BOOTSTRAPPED
+ } else if (d->type == QMetaType::QCborValue) {
+ if (!v_cast<QCborValue>(d)->isMap())
+ return false;
+ *static_cast<QVariantHash *>(result) = v_cast<QCborValue>(d)->toMap().toVariantHash();
+ } else if (d->type == QMetaType::QCborMap) {
+ *static_cast<QVariantHash *>(result) = v_cast<QCborMap>(d)->toVariantHash();
} else if (d->type == QMetaType::QJsonValue) {
if (!v_cast<QJsonValue>(d)->isObject())
return false;
@@ -950,11 +1027,36 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
case QVariant::ByteArray:
*static_cast<QUuid *>(result) = QUuid(*v_cast<QByteArray>(d));
break;
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isUuid())
+ return false;
+ *static_cast<QUuid *>(result) = v_cast<QCborValue>(d)->toUuid();
+ break;
+#endif
default:
return false;
}
break;
+ case QMetaType::Nullptr:
+ *static_cast<std::nullptr_t *>(result) = nullptr;
+ if (QMetaType::typeFlags(t) & (QMetaType::PointerToGadget | QMetaType::PointerToQObject)
+ || d->type == QMetaType::VoidStar) {
+ if (v_cast<const void *>(d) == nullptr)
+ break;
+ }
#ifndef QT_BOOTSTRAPPED
+ if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isNull())
+ break;
+#endif
+ return false;
+
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QRegularExpression:
+ if (d->type != QMetaType::QCborValue || !v_cast<QCborValue>(d)->isRegularExpression())
+ return false;
+ *static_cast<QRegularExpression *>(result) = v_cast<QCborValue>(d)->toRegularExpression();
+ break;
case QMetaType::QJsonValue:
switch (d->type) {
case QMetaType::Nullptr:
@@ -1005,6 +1107,15 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*static_cast<QJsonValue *>(result) = doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
break;
}
+ case QMetaType::QCborValue:
+ *static_cast<QJsonValue *>(result) = v_cast<QCborValue>(d)->toJsonValue();
+ break;
+ case QMetaType::QCborMap:
+ *static_cast<QJsonValue *>(result) = v_cast<QCborMap>(d)->toJsonObject();
+ break;
+ case QMetaType::QCborArray:
+ *static_cast<QJsonValue *>(result) = v_cast<QCborArray>(d)->toJsonArray();
+ break;
default:
*static_cast<QJsonValue *>(result) = QJsonValue(QJsonValue::Undefined);
return false;
@@ -1028,6 +1139,14 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
return false;
*static_cast<QJsonArray *>(result) = v_cast<QJsonDocument>(d)->array();
break;
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isArray())
+ return false;
+ *static_cast<QJsonArray *>(result) = v_cast<QCborValue>(d)->toArray().toJsonArray();
+ break;
+ case QMetaType::QCborArray:
+ *static_cast<QJsonArray *>(result) = v_cast<QCborArray>(d)->toJsonArray();
+ break;
default:
return false;
}
@@ -1050,11 +1169,177 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
return false;
*static_cast<QJsonObject *>(result) = v_cast<QJsonDocument>(d)->object();
break;
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isMap())
+ return false;
+ *static_cast<QJsonObject *>(result) = v_cast<QCborValue>(d)->toMap().toJsonObject();
+ break;
+ case QMetaType::QCborMap:
+ *static_cast<QJsonObject *>(result) = v_cast<QCborMap>(d)->toJsonObject();
+ break;
+ default:
+ return false;
+ }
+ break;
+ case QMetaType::QCborSimpleType:
+ if (d->type == QMetaType::QCborValue && v_cast<QCborValue>(d)->isSimpleType()) {
+ *static_cast<QCborSimpleType *>(result) = v_cast<QCborValue>(d)->toSimpleType();
+ break;
+ }
+ return false;
+ case QMetaType::QCborValue:
+ switch (d->type) {
+ case QMetaType::Nullptr:
+ *static_cast<QCborValue *>(result) = QCborValue(QCborValue::Null);
+ break;
+ case QVariant::Bool:
+ *static_cast<QCborValue *>(result) = QCborValue(d->data.b);
+ break;
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ case QMetaType::ULong:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong:
+ case QMetaType::UShort:
+ case QMetaType::UChar:
+ case QMetaType::Char:
+ case QMetaType::SChar:
+ case QMetaType::Short:
+ *static_cast<QCborValue *>(result) = QCborValue(qConvertToNumber(d, ok));
+ Q_ASSERT(ok);
+ break;
+ case QMetaType::Double:
+ case QMetaType::Float:
+ *static_cast<QCborValue *>(result) = QCborValue(qConvertToRealNumber(d, ok));
+ Q_ASSERT(ok);
+ break;
+ case QVariant::String:
+ *static_cast<QCborValue *>(result) = *v_cast<QString>(d);
+ break;
+ case QVariant::StringList:
+ *static_cast<QCborValue *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
+ break;
+ case QVariant::ByteArray:
+ *static_cast<QCborValue *>(result) = *v_cast<QByteArray>(d);
+ break;
+ case QVariant::Date:
+ *static_cast<QCborValue *>(result) = QCborValue(QDateTime(*v_cast<QDate>(d)));
+ break;
+ case QVariant::DateTime:
+ *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QDateTime>(d));
+ break;
+ case QVariant::Url:
+ *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUrl>(d));
+ break;
+ case QVariant::RegularExpression:
+ *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QRegularExpression>(d));
+ break;
+ case QVariant::Uuid:
+ *static_cast<QCborValue *>(result) = QCborValue(*v_cast<QUuid>(d));
+ break;
+ case QVariant::List:
+ *static_cast<QCborValue *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
+ break;
+ case QVariant::Map:
+ *static_cast<QCborValue *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
+ break;
+ case QVariant::Hash:
+ *static_cast<QCborValue *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
+ break;
+ case QMetaType::QJsonValue:
+ *static_cast<QCborValue *>(result) = QCborValue::fromJsonValue(*v_cast<QJsonValue>(d));
+ break;
+ case QMetaType::QJsonObject:
+ *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
+ break;
+ case QMetaType::QJsonArray:
+ *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
+ break;
+ case QMetaType::QJsonDocument: {
+ QJsonDocument doc = *v_cast<QJsonDocument>(d);
+ if (doc.isArray())
+ *static_cast<QCborValue *>(result) = QCborArray::fromJsonArray(doc.array());
+ else
+ *static_cast<QCborValue *>(result) = QCborMap::fromJsonObject(doc.object());
+ break;
+ }
+ case QMetaType::QCborSimpleType:
+ *static_cast<QCborValue *>(result) = *v_cast<QCborSimpleType>(d);
+ break;
+ case QMetaType::QCborMap:
+ *static_cast<QCborValue *>(result) = *v_cast<QCborMap>(d);
+ break;
+ case QMetaType::QCborArray:
+ *static_cast<QCborValue *>(result) = *v_cast<QCborArray>(d);
+ break;
+ default:
+ *static_cast<QCborValue *>(result) = {};
+ return false;
+ }
+ break;
+ case QMetaType::QCborArray:
+ switch (d->type) {
+ case QVariant::StringList:
+ *static_cast<QCborArray *>(result) = QCborArray::fromStringList(*v_cast<QStringList>(d));
+ break;
+ case QVariant::List:
+ *static_cast<QCborArray *>(result) = QCborArray::fromVariantList(*v_cast<QVariantList>(d));
+ break;
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isArray())
+ return false;
+ *static_cast<QCborArray *>(result) = v_cast<QCborValue>(d)->toArray();
+ break;
+ case QMetaType::QJsonDocument:
+ if (!v_cast<QJsonDocument>(d)->isArray())
+ return false;
+ *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonDocument>(d)->array());
+ break;
+ case QMetaType::QJsonValue:
+ if (!v_cast<QJsonValue>(d)->isArray())
+ return false;
+ *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(v_cast<QJsonValue>(d)->toArray());
+ break;
+ case QMetaType::QJsonArray:
+ *static_cast<QCborArray *>(result) = QCborArray::fromJsonArray(*v_cast<QJsonArray>(d));
+ break;
+ default:
+ return false;
+ }
+ break;
+ case QMetaType::QCborMap:
+ switch (d->type) {
+ case QVariant::Map:
+ *static_cast<QCborMap *>(result) = QCborMap::fromVariantMap(*v_cast<QVariantMap>(d));
+ break;
+ case QVariant::Hash:
+ *static_cast<QCborMap *>(result) = QCborMap::fromVariantHash(*v_cast<QVariantHash>(d));
+ break;
+ case QMetaType::QCborValue:
+ if (!v_cast<QCborValue>(d)->isMap())
+ return false;
+ *static_cast<QCborMap *>(result) = v_cast<QCborValue>(d)->toMap();
+ break;
+ case QMetaType::QJsonDocument:
+ if (v_cast<QJsonDocument>(d)->isArray())
+ return false;
+ *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonDocument>(d)->object());
+ break;
+ case QMetaType::QJsonValue:
+ if (!v_cast<QJsonValue>(d)->isObject())
+ return false;
+ *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(v_cast<QJsonValue>(d)->toObject());
+ break;
+ case QMetaType::QJsonObject:
+ *static_cast<QCborMap *>(result) = QCborMap::fromJsonObject(*v_cast<QJsonObject>(d));
+ break;
default:
return false;
}
break;
#endif
+
default:
#ifndef QT_NO_QOBJECT
if (d->type == QVariant::String || d->type == QVariant::ByteArray) {
@@ -1081,7 +1366,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
}
}
#endif
- if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration) {
+ if (QMetaType::typeFlags(t) & QMetaType::IsEnumeration || d->type == QMetaType::QCborSimpleType) {
qlonglong value = qConvertToNumber(d, ok);
if (*ok) {
switch (QMetaType::sizeOf(t)) {
@@ -1175,9 +1460,16 @@ static void customConstruct(QVariant::Private *d, const void *copy)
type.construct(&d->data.ptr, copy);
d->is_shared = false;
} else {
- void *ptr = type.create(copy);
+ // Private::Data contains long long, and long double is the biggest standard type.
+ const size_t maxAlignment =
+ qMax(Q_ALIGNOF(QVariant::Private::Data), Q_ALIGNOF(long double));
+ const size_t s = sizeof(QVariant::PrivateShared);
+ const size_t offset = s + ((s * maxAlignment - s) % maxAlignment);
+ void *data = operator new(offset + size);
+ void *ptr = static_cast<char *>(data) + offset;
+ type.construct(ptr, copy);
d->is_shared = true;
- d->data.shared = new QVariant::PrivateShared(ptr);
+ d->data.shared = new (data) QVariant::PrivateShared(ptr);
}
}
@@ -1186,8 +1478,9 @@ static void customClear(QVariant::Private *d)
if (!d->is_shared) {
QMetaType::destruct(d->type, &d->data.ptr);
} else {
- QMetaType::destroy(d->type, d->data.shared->ptr);
- delete d->data.shared;
+ QMetaType::destruct(d->type, d->data.shared->ptr);
+ d->data.shared->~PrivateShared();
+ operator delete(d->data.shared);
}
}
@@ -3272,15 +3565,66 @@ bool QVariant::canConvert(int targetTypeId) const
case QMetaType::QVariantList:
case QMetaType::QVariantMap:
case QMetaType::QVariantHash:
+ case QMetaType::QCborValue:
+ case QMetaType::QCborArray:
+ case QMetaType::QCborMap:
return true;
default:
return false;
}
}
if (currentType == QMetaType::QJsonArray)
- return targetTypeId == QMetaType::QVariantList;
+ return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue
+ || targetTypeId == QMetaType::QCborArray;
if (currentType == QMetaType::QJsonObject)
- return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash;
+ return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash
+ || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QCborMap;
+
+ if (currentType == QMetaType::QCborValue || targetTypeId == QMetaType::QCborValue) {
+ switch (currentType == QMetaType::QCborValue ? targetTypeId : currentType) {
+ case QMetaType::UnknownType:
+ case QMetaType::Nullptr:
+ case QMetaType::Bool:
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ case QMetaType::Double:
+ case QMetaType::Float:
+ case QMetaType::ULong:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong:
+ case QMetaType::UShort:
+ case QMetaType::UChar:
+ case QMetaType::Char:
+ case QMetaType::SChar:
+ case QMetaType::Short:
+ case QMetaType::QString:
+ case QMetaType::QByteArray:
+ case QMetaType::QDateTime:
+ case QMetaType::QUrl:
+ case QMetaType::QRegularExpression:
+ case QMetaType::QUuid:
+ case QMetaType::QVariantList:
+ case QMetaType::QVariantMap:
+ case QMetaType::QVariantHash:
+ case QMetaType::QJsonValue:
+ case QMetaType::QJsonArray:
+ case QMetaType::QJsonObject:
+ case QMetaType::QJsonDocument:
+ case QMetaType::QCborArray:
+ case QMetaType::QCborMap:
+ case QMetaType::QCborSimpleType:
+ return true;
+ default:
+ return false;
+ }
+ }
+ if (currentType == QMetaType::QCborArray)
+ return targetTypeId == QMetaType::QVariantList || targetTypeId == QMetaType::QCborValue
+ || targetTypeId == QMetaType::QJsonArray;
+ if (currentType == QMetaType::QCborMap)
+ return targetTypeId == QMetaType::QVariantMap || targetTypeId == QMetaType::QVariantHash
+ || targetTypeId == QMetaType::QCborValue || targetTypeId == QMetaType::QJsonObject;
// FIXME It should be LastCoreType intead of Uuid
if (currentType > int(QMetaType::QUuid) || targetTypeId > int(QMetaType::QUuid)) {
@@ -3380,7 +3724,7 @@ bool QVariant::convert(int targetTypeId)
create(targetTypeId, 0);
// Fail if the value is not initialized or was forced null by a previous failed convert.
- if (oldValue.d.is_null)
+ if (oldValue.d.is_null && oldValue.d.type != QMetaType::Nullptr)
return false;
if ((QMetaType::typeFlags(oldValue.userType()) & QMetaType::PointerToQObject) && (QMetaType::typeFlags(targetTypeId) & QMetaType::PointerToQObject)) {
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 9a5fc63d03..ff73c27b6e 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -633,6 +633,7 @@ public:
const_iterator &operator-=(int j);
const_iterator operator+(int j) const;
const_iterator operator-(int j) const;
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
};
friend struct const_iterator;
@@ -690,6 +691,7 @@ public:
const_iterator &operator-=(int j);
const_iterator operator+(int j) const;
const_iterator operator-(int j) const;
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
};
friend struct const_iterator;
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index 24de491326..85d4ad4fa9 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -157,7 +157,6 @@ void QWinEventNotifier::setHandle(HANDLE hEvent)
Q_D(QWinEventNotifier);
setEnabled(false);
d->handleToEvent = hEvent;
- d->signaledCount = 0;
}
/*!
@@ -209,10 +208,12 @@ void QWinEventNotifier::setEnabled(bool enable)
return;
}
- if (enable)
+ if (enable) {
+ d->signaledCount = 0;
eventDispatcher->registerEventNotifier(this);
- else
+ } else {
eventDispatcher->unregisterEventNotifier(this);
+ }
}
/*!
diff --git a/src/corelib/kernel/qwineventnotifier.h b/src/corelib/kernel/qwineventnotifier.h
index 624e77e638..71a1d29057 100644
--- a/src/corelib/kernel/qwineventnotifier.h
+++ b/src/corelib/kernel/qwineventnotifier.h
@@ -70,7 +70,7 @@ Q_SIGNALS:
void activated(HANDLE hEvent, QPrivateSignal);
protected:
- bool event(QEvent * e);
+ bool event(QEvent *e) override;
};
QT_END_NAMESPACE
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 68e3c8f10d..10b5c8eafd 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -151,7 +151,9 @@ void QMimeDatabasePrivate::loadProviders()
QVector<QMimeProviderBase *> QMimeDatabasePrivate::providers()
{
+#ifndef Q_OS_WASM // stub implementation always returns true
Q_ASSERT(!mutex.tryLock()); // caller should have locked mutex
+#endif
if (m_providers.isEmpty()) {
loadProviders();
m_lastCheck.start();
@@ -382,9 +384,12 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
// Disambiguate conflicting extensions (if magic matching found something)
if (candidateByData.isValid() && magicAccuracy > 0) {
- // "for glob_match in glob_matches:"
- // "if glob_match is subclass or equal to sniffed_type, use glob_match"
const QString sniffedMime = candidateByData.name();
+ // If the sniffedMime matches a glob match, use it
+ if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
+ *accuracyPtr = 100;
+ return candidateByData;
+ }
for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
if (inherits(m, sniffedMime)) {
// We have magic + pattern pointing to this, so it's a pretty good match
diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri
index a0e0d76044..13153e8d0a 100644
--- a/src/corelib/plugin/plugin.pri
+++ b/src/corelib/plugin/plugin.pri
@@ -4,6 +4,7 @@ HEADERS += \
plugin/qfactoryinterface.h \
plugin/qpluginloader.h \
plugin/qplugin.h \
+ plugin/qplugin_p.h \
plugin/quuid.h \
plugin/qfactoryloader_p.h
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index dc1424fd0c..35c64180d4 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -47,9 +47,12 @@
#include <qdebug.h>
#include "qmutex.h"
#include "qplugin.h"
+#include "qplugin_p.h"
#include "qpluginloader.h"
#include "private/qobject_p.h"
#include "private/qcoreapplication_p.h"
+#include "qcbormap.h"
+#include "qcborvalue.h"
#include "qjsondocument.h"
#include "qjsonvalue.h"
#include "qjsonobject.h"
@@ -64,22 +67,86 @@ static inline int metaDataSignatureLength()
return sizeof("QTMETADATA ") - 1;
}
-QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype sectionSize)
+static QJsonDocument jsonFromCborMetaData(const char *raw, qsizetype size, QString *errMsg)
+{
+ // extract the keys not stored in CBOR
+ int qt_metadataVersion = quint8(raw[0]);
+ int qt_version = qFromBigEndian<quint16>(raw + 1);
+ int qt_archRequirements = quint8(raw[3]);
+ if (Q_UNLIKELY(raw[-1] != '!' || qt_metadataVersion != 0)) {
+ *errMsg = QStringLiteral("Invalid metadata version");
+ return QJsonDocument();
+ }
+
+ raw += 4;
+ size -= 4;
+ QByteArray ba = QByteArray::fromRawData(raw, int(size));
+ QCborParserError err;
+ QCborValue metadata = QCborValue::fromCbor(ba, &err);
+
+ if (err.error != QCborError::NoError) {
+ *errMsg = QLatin1String("Metadata parsing error: ") + err.error.toString();
+ return QJsonDocument();
+ }
+
+ if (!metadata.isMap()) {
+ *errMsg = QStringLiteral("Unexpected metadata contents");
+ return QJsonDocument();
+ }
+
+ QJsonObject o;
+ o.insert(QLatin1String("version"), qt_version << 8);
+ o.insert(QLatin1String("debug"), bool(qt_archRequirements & 1));
+ o.insert(QLatin1String("archreq"), qt_archRequirements);
+
+ // convert the top-level map integer keys
+ for (auto it : metadata.toMap()) {
+ QString key;
+ if (it.first.isInteger()) {
+ switch (it.first.toInteger()) {
+#define CONVERT_TO_STRING(IntKey, StringKey, Description) \
+ case int(IntKey): key = QStringLiteral(StringKey); break;
+ QT_PLUGIN_FOREACH_METADATA(CONVERT_TO_STRING)
+#undef CONVERT_TO_STRING
+
+ case int(QtPluginMetaDataKeys::Requirements):
+ // special case: recreate the debug key
+ o.insert(QLatin1String("debug"), bool(it.second.toInteger() & 1));
+ key = QStringLiteral("archreq");
+ break;
+ }
+ } else {
+ key = it.first.toString();
+ }
+
+ if (!key.isEmpty())
+ o.insert(key, it.second.toJsonValue());
+ }
+ return QJsonDocument(o);
+}
+
+QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype sectionSize, QString *errMsg)
{
raw += metaDataSignatureLength();
sectionSize -= metaDataSignatureLength();
- // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h)
- uint size = qFromLittleEndian<uint>(raw + 8);
- // but the maximum size of binary JSON is 128 MB
- size = qMin(size, 128U * 1024 * 1024);
- // and it doesn't include the size of the header (8 bytes)
- size += 8;
- // finally, it can't be bigger than the file or section size
- size = qMin(sectionSize, qsizetype(size));
-
- QByteArray json(raw, size);
- return QJsonDocument::fromBinaryData(json);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ if (Q_UNLIKELY(raw[-1] == ' ')) {
+ // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h)
+ uint size = qFromLittleEndian<uint>(raw + 8);
+ // but the maximum size of binary JSON is 128 MB
+ size = qMin(size, 128U * 1024 * 1024);
+ // and it doesn't include the size of the header (8 bytes)
+ size += 8;
+ // finally, it can't be bigger than the file or section size
+ size = qMin(sectionSize, qsizetype(size));
+
+ QByteArray json(raw, size);
+ return QJsonDocument::fromBinaryData(json);
+ }
+#endif
+
+ return jsonFromCborMetaData(raw, sectionSize, errMsg);
}
class QFactoryLoaderPrivate : public QObjectPrivate
@@ -141,35 +208,33 @@ void QFactoryLoader::update()
QDir::Files);
QLibraryPrivate *library = 0;
-#ifdef Q_OS_MAC
- // Loading both the debug and release version of the cocoa plugins causes the objective-c runtime
- // to print "duplicate class definitions" warnings. Detect if QFactoryLoader is about to load both,
- // skip one of them (below).
- //
- // ### FIXME find a proper solution
- //
- const bool isLoadingDebugAndReleaseCocoa = plugins.contains(QLatin1String("libqcocoa_debug.dylib"))
- && plugins.contains(QLatin1String("libqcocoa.dylib"));
-#endif
for (int j = 0; j < plugins.count(); ++j) {
QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j));
#ifdef Q_OS_MAC
- if (isLoadingDebugAndReleaseCocoa) {
-#ifdef QT_DEBUG
- if (fileName.contains(QLatin1String("libqcocoa.dylib")))
- continue; // Skip release plugin in debug mode
-#else
- if (fileName.contains(QLatin1String("libqcocoa_debug.dylib")))
- continue; // Skip debug plugin in release mode
-#endif
+ const bool isDebugPlugin = fileName.endsWith(QLatin1String("_debug.dylib"));
+ const bool isDebugLibrary =
+ #ifdef QT_DEBUG
+ true;
+ #else
+ false;
+ #endif
+
+ // Skip mismatching plugins so that we don't end up loading both debug and release
+ // versions of the same Qt libraries (due to the plugin's dependencies).
+ if (isDebugPlugin != isDebugLibrary)
+ continue;
+#elif defined(Q_PROCESSOR_X86)
+ if (fileName.endsWith(QLatin1String(".avx2")) || fileName.endsWith(QLatin1String(".avx512"))) {
+ // ignore AVX2-optimized file, we'll do a bait-and-switch to it later
+ continue;
}
#endif
if (qt_debug_component()) {
qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName;
}
- Q_TRACE(qfactoryloader_update, fileName);
+ Q_TRACE(QFactoryLoader_update, fileName);
library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath());
if (!library->isPlugin()) {
diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h
index fe722999ae..7815ea0b5d 100644
--- a/src/corelib/plugin/qfactoryloader_p.h
+++ b/src/corelib/plugin/qfactoryloader_p.h
@@ -56,6 +56,7 @@
#include "QtCore/qobject.h"
#include "QtCore/qstringlist.h"
+#include "QtCore/qcborvalue.h"
#include "QtCore/qjsonobject.h"
#include "QtCore/qjsondocument.h"
#include "QtCore/qmap.h"
@@ -66,7 +67,7 @@
QT_BEGIN_NAMESPACE
-QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype size);
+QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype size, QString *errMsg);
class QFactoryLoaderPrivate;
class Q_CORE_EXPORT QFactoryLoader : public QObject
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 5256a09ff2..aa63ed1a6b 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -268,7 +268,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
*/
bool hasMetaData = false;
qsizetype pos = 0;
- char pattern[] = "qTMETADATA ";
+ char pattern[] = "qTMETADATA ";
pattern[0] = 'Q'; // Ensure the pattern "QTMETADATA" is not found in this library should QPluginLoader ever encounter it.
const ulong plen = qstrlen(pattern);
#if defined (Q_OF_ELF) && defined(Q_CC_GNU)
@@ -314,10 +314,14 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
bool ret = false;
- if (pos >= 0) {
- if (hasMetaData) {
- const char *data = filedata + pos;
- QJsonDocument doc = qJsonFromRawLibraryMetaData(data, qsizetype(fdlen));
+ if (pos >= 0 && hasMetaData) {
+ const char *data = filedata + pos;
+ QString errMsg;
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(data, fdlen, &errMsg);
+ if (doc.isNull()) {
+ qWarning("Found invalid metadata in lib %s: %s",
+ qPrintable(library), qPrintable(errMsg));
+ } else {
lib->metaData = doc.object();
if (qt_debug_component())
qWarning("Found metadata in lib %s, metadata=\n%s\n",
@@ -544,7 +548,7 @@ bool QLibraryPrivate::load()
if (fileName.isEmpty())
return false;
- Q_TRACE(qlibraryprivate_load_entry, fileName);
+ Q_TRACE(QLibraryPrivate_load_entry, fileName);
bool ret = load_sys();
if (qt_debug_component()) {
@@ -562,7 +566,7 @@ bool QLibraryPrivate::load()
installCoverageTool(this);
}
- Q_TRACE(qlibraryprivate_load_exit, ret);
+ Q_TRACE(QLibraryPrivate_load_exit, ret);
return ret;
}
@@ -679,20 +683,26 @@ bool QLibrary::isLibrary(const QString &fileName)
#endif
}
-typedef const char * (*QtPluginQueryVerificationDataFunction)();
-
-static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv)
+static bool qt_get_metadata(QLibraryPrivate *priv, QString *errMsg)
{
- const char *szData = 0;
- if (!pfn)
- return false;
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ auto getMetaData = [](QFunctionPointer fptr) {
+ auto f = reinterpret_cast<const char * (*)()>(fptr);
+ return qMakePair<const char *, size_t>(f(), INT_MAX);
+ };
+#else
+ auto getMetaData = [](QFunctionPointer fptr) {
+ auto f = reinterpret_cast<QPair<const char *, size_t> (*)()>(fptr);
+ return f();
+ };
+#endif
- szData = pfn();
- if (!szData)
+ QFunctionPointer pfn = priv->resolve("qt_plugin_query_metadata");
+ if (!pfn)
return false;
- // the data is already loaded, so the size doesn't matter
- QJsonDocument doc = qJsonFromRawLibraryMetaData(szData, INT_MAX);
+ auto metaData = getMetaData(pfn);
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(metaData.first, metaData.second, errMsg);
if (doc.isNull())
return false;
priv->metaData = doc.object();
@@ -735,9 +745,7 @@ void QLibraryPrivate::updatePluginState()
} else {
// library is already loaded (probably via QLibrary)
// simply get the target function and call it.
- QtPluginQueryVerificationDataFunction getMetaData = NULL;
- getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata");
- success = qt_get_metadata(getMetaData, this);
+ success = qt_get_metadata(this, &errorString);
}
if (!success) {
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 23b9ad6434..e03814984c 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -43,6 +44,7 @@
#include "qlibrary_p.h"
#include <qcoreapplication.h>
#include <private/qfilesystementry_p.h>
+#include <private/qsimd_p.h>
#include <dlfcn.h>
@@ -155,7 +157,7 @@ bool QLibraryPrivate::load_sys()
// Do not unload the library during dlclose(). Consequently, the
// library's specific static variables are not reinitialized if the
// library is reloaded with dlopen() at a later time.
-#ifdef RTLD_NODELETE
+#if defined(RTLD_NODELETE) && !defined(Q_OS_ANDROID)
if (loadHints & QLibrary::PreventUnloadHint) {
dlFlags |= RTLD_NODELETE;
}
@@ -178,6 +180,29 @@ bool QLibraryPrivate::load_sys()
prefixes.append(QString());
}
+#if defined(Q_PROCESSOR_X86) && !defined(Q_OS_DARWIN)
+ if (qCpuHasFeature(ArchHaswell)) {
+ auto transform = [](QStringList &list, void (*f)(QString *)) {
+ QStringList tmp;
+ qSwap(tmp, list);
+ list.reserve(tmp.size() * 2);
+ for (const QString &s : qAsConst(tmp)) {
+ QString modifiedPath = s;
+ f(&modifiedPath);
+ list.append(modifiedPath);
+ list.append(s);
+ }
+ };
+ if (pluginState == IsAPlugin) {
+ // add ".avx2" to each suffix in the list
+ transform(suffixes, [](QString *s) { s->append(QLatin1String(".avx2")); });
+ } else {
+ // prepend "haswell/" to each prefix in the list
+ transform(prefixes, [](QString *s) { s->prepend(QLatin1String("haswell/")); });
+ }
+ }
+#endif
+
bool retry = true;
for(int prefix = 0; retry && !pHnd && prefix < prefixes.size(); prefix++) {
for(int suffix = 0; retry && !pHnd && suffix < suffixes.size(); suffix++) {
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index 9368e53b3f..05a93d467e 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -97,10 +97,10 @@ bool QLibraryPrivate::load_sys()
for (const QString &attempt : qAsConst(attempts)) {
#ifndef Q_OS_WINRT
- pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16());
+ pHnd = LoadLibrary(reinterpret_cast<const wchar_t*>(QDir::toNativeSeparators(attempt).utf16()));
#else // Q_OS_WINRT
QString path = QDir::toNativeSeparators(QDir::current().relativeFilePath(attempt));
- pHnd = LoadPackagedLibrary((LPCWSTR)path.utf16(), 0);
+ pHnd = LoadPackagedLibrary(reinterpret_cast<LPCWSTR>(path.utf16()), 0);
if (pHnd)
qualifiedFileName = attempt;
#endif // !Q_OS_WINRT
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index b644d47856..5aca22497a 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -55,6 +55,21 @@ QT_BEGIN_NAMESPACE
# endif
#endif
+inline constexpr unsigned char qPluginArchRequirements()
+{
+ return 0
+#ifndef QT_NO_DEBUG
+ | 1
+#endif
+#ifdef __AVX2__
+ | 2
+# ifdef __AVX512F__
+ | 4
+# endif
+#endif
+ ;
+}
+
typedef QObject *(*QtPluginInstanceFunction)();
typedef const char *(*QtPluginMetaDataFunction)();
@@ -90,7 +105,6 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
# define QT_PLUGIN_METADATA_SECTION \
__declspec(allocate(".qtmetadata"))
#else
-# define QT_PLUGIN_VERIFICATION_SECTION
# define QT_PLUGIN_METADATA_SECTION
#endif
@@ -105,11 +119,21 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
}; \
static Static##PLUGIN##PluginInstance static##PLUGIN##Instance;
+#if defined(QT_PLUGIN_RESOURCE_INIT_FUNCTION)
+# define QT_PLUGIN_RESOURCE_INIT \
+ extern void QT_PLUGIN_RESOURCE_INIT_FUNCTION(); \
+ QT_PLUGIN_RESOURCE_INIT_FUNCTION();
+#else
+# define QT_PLUGIN_RESOURCE_INIT
+#endif
+
#define Q_PLUGIN_INSTANCE(IMPLEMENTATION) \
{ \
static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance; \
- if (!_instance) \
+ if (!_instance) { \
+ QT_PLUGIN_RESOURCE_INIT \
_instance = new IMPLEMENTATION; \
+ } \
return _instance; \
}
diff --git a/src/corelib/plugin/qplugin_p.h b/src/corelib/plugin/qplugin_p.h
new file mode 100644
index 0000000000..717129268b
--- /dev/null
+++ b/src/corelib/plugin/qplugin_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLUGIN_P_H
+#define QPLUGIN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+enum class QtPluginMetaDataKeys {
+ QtVersion,
+ Requirements,
+ IID,
+ ClassName,
+ MetaData
+};
+
+// F(IntKey, StringKey, Description)
+// Keep this list sorted in the order moc should output.
+#define QT_PLUGIN_FOREACH_METADATA(F) \
+ F(QtPluginMetaDataKeys::IID, "IID", "Plugin's Interface ID") \
+ F(QtPluginMetaDataKeys::ClassName, "className", "Plugin class name") \
+ F(QtPluginMetaDataKeys::MetaData, "MetaData", "Other meta data")
+
+QT_END_NAMESPACE
+
+#endif // QPLUGIN_P_H
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 83cbcd2b44..0f94bb6adf 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -475,10 +475,19 @@ QVector<QStaticPlugin> QPluginLoader::staticPlugins()
*/
QJsonObject QStaticPlugin::metaData() const
{
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// the data is already loaded, so this doesn't matter
qsizetype rawMetaDataSize = INT_MAX;
+ const char *ptr = rawMetaData();
+#else
+ auto ptr = static_cast<const char *>(rawMetaData);
+#endif
- return qJsonFromRawLibraryMetaData(rawMetaData(), rawMetaDataSize).object();
+ QString errMsg;
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(ptr, rawMetaDataSize, &errMsg);
+ Q_ASSERT(doc.isObject());
+ Q_ASSERT(errMsg.isEmpty());
+ return doc.object();
}
QT_END_NAMESPACE
diff --git a/src/corelib/plugin/qsystemlibrary.cpp b/src/corelib/plugin/qsystemlibrary.cpp
index 7c80fbbd42..1f8cef790c 100644
--- a/src/corelib/plugin/qsystemlibrary.cpp
+++ b/src/corelib/plugin/qsystemlibrary.cpp
@@ -121,7 +121,7 @@ HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirect
fullPathAttempt.append(QLatin1Char('\\'));
}
fullPathAttempt.append(fileName);
- HINSTANCE inst = ::LoadLibrary((const wchar_t *)fullPathAttempt.utf16());
+ HINSTANCE inst = ::LoadLibrary(reinterpret_cast<const wchar_t *>(fullPathAttempt.utf16()));
if (inst != 0)
return inst;
}
diff --git a/src/corelib/qtcore.tracepoints b/src/corelib/qtcore.tracepoints
index e6b666ac74..33734a4274 100644
--- a/src/corelib/qtcore.tracepoints
+++ b/src/corelib/qtcore.tracepoints
@@ -1,5 +1,34 @@
-qcoreapplicationprivate_init_entry()
-qcoreapplicationprivate_init_exit()
-qfactoryloader_update(const QString &fileName)
-qlibraryprivate_load_entry(const QString &fileName)
-qlibraryprivate_load_exit(bool success)
+QCoreApplicationPrivate_init_entry()
+QCoreApplicationPrivate_init_exit()
+
+QFactoryLoader_update(const QString &fileName)
+
+QLibraryPrivate_load_entry(const QString &fileName)
+QLibraryPrivate_load_exit(bool success)
+
+QEvent_ctor(QEvent *event, int type)
+QEvent_dtor(QEvent *event, int type)
+
+QCoreApplication_postEvent_entry(QObject *receiver, QEvent *event, int type)
+QCoreApplication_postEvent_event_compressed(QObject *receiver, QEvent *event)
+QCoreApplication_postEvent_event_posted(QObject *receiver, QEvent *event, int type)
+
+QCoreApplication_sendEvent(QObject *receiver, QEvent *event, int type)
+QCoreApplication_sendSpontaneousEvent(QObject *receiver, QEvent *event, int type)
+
+QCoreApplication_notify_entry(QObject *receiver, QEvent *event, int type)
+QCoreApplication_notify_event_filtered(QObject *receiver, QEvent *event, int type)
+QCoreApplication_notify_before_delivery(QObject *receiver, QEvent *event, int type)
+QCoreApplication_notify_after_delivery(QObject *receiver, QEvent *event, int type, bool consumed)
+
+QObject_ctor(QObject *object)
+QObject_dtor(QObject *object)
+
+QMetaObject_activate_begin_signal(QObject *sender, int signalIndex)
+QMetaObject_activate_end_signal(QObject *sender, int signalIndex)
+QMetaObject_activate_begin_slot(QObject *receiver, int slotIndex)
+QMetaObject_activate_end_slot(QObject *receiver, int slotIndex)
+QMetaObject_activate_begin_slot_functor(void *slotObject)
+QMetaObject_activate_end_slot_functor(void *slotObject)
+QMetaObject_activate_begin_declarative_signal(QObject *sender, int signalIndex)
+QMetaObject_activate_end_declarative_signal(QObject *sender, int signalIndex)
diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp
new file mode 100644
index 0000000000..921fcf2fca
--- /dev/null
+++ b/src/corelib/serialization/qcborarray.cpp
@@ -0,0 +1,1213 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcborarray.h"
+#include "qcborvalue_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QtCbor;
+
+/*!
+ \class QCborArray
+ \inmodule QtCore
+ \ingroup cbor
+ \reentrant
+ \since 5.12
+
+ \brief The QCborArray class is used to hold an array of CBOR elements.
+
+ This class can be used to hold one sequential container in CBOR (an array).
+ CBOR is the Concise Binary Object Representation, a very compact form of
+ binary data encoding that is a superset of JSON. It was created by the IETF
+ Constrained RESTful Environments (CoRE) WG, which has used it in many new
+ RFCs. It is meant to be used alongside the
+ \l{https://tools.ietf.org/html/rfc7252}{CoAP protocol}.
+
+ QCborArray is very similar to \l QVariantList and \l QJsonArray and its API
+ is almost identical to those two classes. It can also be converted to and
+ from those two, though there may be loss of information in some
+ conversions.
+
+ \sa QCborValue, QCborMap, QJsonArray, QList, QVector
+ */
+
+/*!
+ \typedef QCborArray::size_type
+
+ A typedef to qsizetype.
+ */
+
+/*!
+ \typedef QCborArray::difference_type
+
+ A typedef to qsizetype.
+ */
+
+/*!
+ \typedef QCborArray::value_type
+
+ The type of values that can be held in a QCborArray: that is, QCborValue.
+ */
+
+/*!
+ \typedef QCborArray::pointer
+
+ A typedef to \c{QCborValue *}, for compatibility with generic algorithms.
+ */
+
+/*!
+ \typedef QCborArray::const_pointer
+
+ A typedef to \c{const QCborValue *}, for compatibility with generic algorithms.
+ */
+
+/*!
+ \typedef QCborArray::reference
+
+ A typedef to \c{QCborValue &}, for compatibility with generic algorithms.
+ */
+
+/*!
+ \typedef QCborArray::const_reference
+
+ A typedef to \c{const QCborValue &}, for compatibility with generic algorithms.
+ */
+
+/*!
+ Constructs an empty QCborArray.
+ */
+QCborArray::QCborArray() noexcept
+ : d(nullptr)
+{
+}
+
+/*!
+ Copies the contents of \a other into this object.
+ */
+QCborArray::QCborArray(const QCborArray &other) noexcept
+ : d(other.d)
+{
+}
+
+/*!
+ \fn QCborArray::QCborArray(std::initializer_list<QCborValue> args)
+
+ Initializes this QCborArray from the C++ brace-enclosed list found in \a
+ args, as in the following example:
+
+ \code
+ QCborArray a = { null, 0, 1, 1.5, 2, "Hello", QByteArray("World") };
+ \endcode
+ */
+
+/*!
+ Destroys this QCborArray and frees any associated resources.
+ */
+QCborArray::~QCborArray()
+{
+}
+
+/*!
+ Replaces the contents of this array with that found in \a other, then
+ returns a reference to this object.
+ */
+QCborArray &QCborArray::operator=(const QCborArray &other) noexcept
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn void QCborArray::swap(QCborArray &other)
+
+ Swaps the contents of this object and \a other.
+ */
+
+/*!
+ \fn QCborValue QCborArray::toCborValue() const
+
+ Explicitly construcuts a \l QCborValue object that represents this array.
+ This function is usually not necessary since QCborValue has a constructor
+ for QCborArray, so the conversion is implicit.
+
+ Converting QCborArray to QCborValue allows it to be used in any context
+ where QCborValues can be used, including as items in QCborArrays and as keys
+ and mapped types in QCborMap. Converting an array to QCborValue allows
+ access to QCborValue::toCbor().
+
+ \sa QCborValue::QCborValue(const QCborArray &)
+ */
+
+/*!
+ Returns the size of this array.
+
+ \sa isEmpty()
+ */
+qsizetype QCborArray::size() const noexcept
+{
+ return d ? d->elements.size() : 0;
+}
+
+/*!
+ Empties this array.
+
+ \sa isEmpty()
+ */
+void QCborArray::clear()
+{
+ d.reset();
+}
+
+/*!
+ \fn bool QCborArray::isEmpty() const
+
+ Returns true if this QCborArray is empty (that is if size() is 0).
+
+ \sa size(), clear()
+ */
+
+/*!
+ Returns the QCborValue element at position \a i in the array.
+
+ If the array is smaller than \a i elements, this function returns a
+ QCborValue containing an undefined value. For that reason, it is not
+ possible with this function to tell apart the situation where the array is
+ not large enough from the case where the array starts with an undefined
+ value.
+
+ \sa operator[](), first(), last(), insert(), prepend(), append(),
+ removeAt(), takeAt()
+ */
+QCborValue QCborArray::at(qsizetype i) const
+{
+ if (!d || size_t(i) >= size_t(size()))
+ return QCborValue();
+ return d->valueAt(i);
+}
+
+/*!
+ \fn QCborValue QCborArray::first() const
+
+ Returns the first QCborValue of this array.
+
+ If the array is empty, this function returns a QCborValue containing an
+ undefined value. For that reason, it is not possible with this function to
+ tell apart the situation where the array is not large enough from the case
+ where the array ends with an undefined value.
+
+ \sa operator[](), at(), last(), insert(), prepend(), append(),
+ removeAt(), takeAt()
+ */
+
+/*!
+ \fn QCborValue QCborArray::last() const
+
+ Returns the last QCborValue of this array.
+
+ If the array is empty, this function returns a QCborValue containing an
+ undefined value. For that reason, it is not possible with this function to
+ tell apart the situation where the array is not large enough from the case
+ where the array ends with an undefined value.
+
+ \sa operator[](), at(), first(), insert(), prepend(), append(),
+ removeAt(), takeAt()
+ */
+
+/*!
+ \fn QCborValue QCborArray::operator[](qsizetype i) const
+
+ Returns the QCborValue element at position \a i in the array.
+
+ If the array is smaller than \a i elements, this function returns a
+ QCborValue containing an undefined value. For that reason, it is not
+ possible with this function to tell apart the situation where the array is
+ not large enough from the case where the array contains an undefined value
+ at position \a i.
+
+ \sa at(), first(), last(), insert(), prepend(), append(),
+ removeAt(), takeAt()
+ */
+
+/*!
+ \fn QCborValueRef QCborArray::first()
+
+ Returns a reference to the first QCborValue of this array. The array must
+ not be empty.
+
+ QCborValueRef has the exact same API as \l QCborValue, with one important
+ difference: if you assign new values to it, this map will be updated with
+ that new value.
+
+ \sa operator[](), at(), last(), insert(), prepend(), append(),
+ removeAt(), takeAt()
+ */
+
+/*!
+ \fn QCborValueRef QCborArray::last()
+
+ Returns a reference to the last QCborValue of this array. The array must
+ not be empty.
+
+ QCborValueRef has the exact same API as \l QCborValue, with one important
+ difference: if you assign new values to it, this map will be updated with
+ that new value.
+
+ \sa operator[](), at(), first(), insert(), prepend(), append(),
+ removeAt(), takeAt()
+ */
+
+/*!
+ \fn QCborValueRef QCborArray::operator[](qsizetype i)
+
+ Returns a reference to the QCborValue element at position \a i in the
+ array. The array must have at least \a i elements.
+
+ QCborValueRef has the exact same API as \l QCborValue, with one important
+ difference: if you assign new values to it, this map will be updated with
+ that new value.
+
+ \sa at(), first(), last(), insert(), prepend(), append(),
+ removeAt(), takeAt()
+ */
+
+/*!
+ \fn void QCborArray::insert(qsizetype i, const QCborValue &value)
+ \fn void QCborArray::insert(qsizetype i, QCborValue &&value)
+
+ Inserts \a value into the array at position \a i in this array. The array
+ must have at least \a i elements before the insertion.
+
+ \sa at(), operator[](), first(), last(), prepend(), append(),
+ removeAt(), takeAt(), extract()
+ */
+void QCborArray::insert(qsizetype i, const QCborValue &value)
+{
+ Q_ASSERT(size_t(i) <= size_t(size()) || i == -1);
+ if (i < 0)
+ i = size();
+ detach(qMax(i + 1, size()));
+ d->insertAt(i, value);
+}
+
+void QCborArray::insert(qsizetype i, QCborValue &&value)
+{
+ Q_ASSERT(size_t(i) <= size_t(size()) || i == -1);
+ if (i < 0)
+ i = size();
+ detach(qMax(i + 1, size()));
+ d->insertAt(i, value, QCborContainerPrivate::MoveContainer);
+ QCborContainerPrivate::resetValue(value);
+}
+
+/*!
+ \fn QCborValue QCborArray::extract(Iterator it)
+ \fn QCborValue QCborArray::extract(ConstIterator it)
+
+ Extracts a value from the array at the position indicated by iterator \a it
+ and returns the value so extracted.
+
+ \sa insert(), erase(), takeAt(), removeAt()
+ */
+QCborValue QCborArray::extract(iterator it)
+{
+ detach();
+
+ QCborValue v = d->extractAt(it.item.i);
+ d->removeAt(it.item.i);
+ return v;
+}
+
+/*!
+ \fn void QCborArray::prepend(const QCborValue &value)
+ \fn void QCborArray::prepend(QCborValue &&value)
+
+ Prepends \a value into the array before any other elements it may already
+ contain.
+
+ \sa at(), operator[](), first(), last(), insert(), append(),
+ removeAt(), takeAt()
+ */
+
+/*!
+ \fn void QCborArray::append(const QCborValue &value)
+ \fn void QCborArray::append(QCborValue &&value)
+
+ Appends \a value into the array after all other elements it may already
+ contain.
+
+ \sa at(), operator[](), first(), last(), insert(), prepend(),
+ removeAt(), takeAt()
+ */
+
+/*!
+ Removes the item at position \a i from the array. The array must have more
+ than \a i elements before the removal.
+
+ \sa takeAt(), removeFirst(), removeLast(), at(), operator[](), insert(),
+ prepend(), append()
+ */
+void QCborArray::removeAt(qsizetype i)
+{
+ detach(size());
+ d->removeAt(i);
+}
+
+/*!
+ \fn QCborValue QCborArray::takeAt(qsizetype i)
+
+ Removes the item at position \a i from the array and returns it. The array
+ must have more than \a i elements before the removal.
+
+ \sa removeAt(), removeFirst(), removeLast(), at(), operator[](), insert(),
+ prepend(), append()
+ */
+
+/*!
+ \fn void QCborArray::removeFirst()
+
+ Removes the first item in the array, making the second element become the
+ first. The array must not be empty before this call.
+
+ \sa removeAt(), takeFirst(), removeLast(), at(), operator[](), insert(),
+ prepend(), append()
+ */
+
+/*!
+ \fn void QCborArray::removeLast()
+
+ Removes the last item in the array. The array must not be empty before this
+ call.
+
+ \sa removeAt(), takeLast(), removeFirst(), at(), operator[](), insert(),
+ prepend(), append()
+ */
+
+/*!
+ \fn void QCborArray::takeFirst()
+
+ Removes the first item in the array and returns it, making the second
+ element become the first. The array must not be empty before this call.
+
+ \sa takeAt(), removeFirst(), removeLast(), at(), operator[](), insert(),
+ prepend(), append()
+ */
+
+/*!
+ \fn void QCborArray::takeLast()
+
+ Removes the last item in the array and returns it. The array must not be
+ empty before this call.
+
+ \sa takeAt(), removeLast(), removeFirst(), at(), operator[](), insert(),
+ prepend(), append()
+ */
+
+/*!
+ Returns true if this array contains an element that is equal to \a value.
+ */
+bool QCborArray::contains(const QCborValue &value) const
+{
+ for (qsizetype i = 0; i < size(); ++i) {
+ int cmp = d->compareElement(i, value);
+ if (cmp == 0)
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \fn int QCborArray::compare(const QCborArray &other) const
+
+ Compares this array and \a other, comparing each element in sequence, and
+ returns an integer that indicates whether this array should be sorted
+ before (if the result is negative) or after \a other (if the result is
+ positive). If this function returns 0, the two arrays are equal and contain
+ the same elements.
+
+ For more information on CBOR sorting order, see QCborValue::compare().
+
+ \sa QCborValue::compare(), QCborMap::compare(), operator==()
+ */
+
+/*!
+ \fn bool QCborArray::operator==(const QCborArray &other) const
+
+ Compares this array and \a other, comparing each element in sequence, and
+ returns true if both arrays contains the same elements, false otherwise.
+
+ For more information on CBOR equality in Qt, see, QCborValue::compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator!=(), operator<()
+ */
+
+/*!
+ \fn bool QCborArray::operator!=(const QCborArray &other) const
+
+ Compares this array and \a other, comparing each element in sequence, and
+ returns true if the two arrays' contents are different, false otherwise.
+
+ For more information on CBOR equality in Qt, see, QCborValue::compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator==(), operator<()
+ */
+
+/*!
+ \fn bool QCborArray::operator<(const QCborArray &other) const
+
+ Compares this array and \a other, comparing each element in sequence, and
+ returns true if this array should be sorted before \a other, false
+ otherwise.
+
+ For more information on CBOR sorting order, see QCborValue::compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator==(), operator!=()
+ */
+
+/*!
+ \typedef QCborArray::iterator
+
+ A synonym to QCborArray::Iterator.
+ */
+
+/*!
+ \typedef QCborArray::const_iterator
+
+ A synonym to QCborArray::ConstIterator.
+ */
+
+/*!
+ \fn QCborArray::iterator QCborArray::begin()
+
+ Returns an array iterator pointing to the first item in this array. If the
+ array is empty, then this function returns the same as end().
+
+ \sa constBegin(), end()
+ */
+
+/*!
+ \fn QCborArray::const_iterator QCborArray::begin() const
+
+ Returns an array iterator pointing to the first item in this array. If the
+ array is empty, then this function returns the same as end().
+
+ \sa constBegin(), constEnd()
+ */
+
+/*!
+ \fn QCborArray::const_iterator QCborArray::cbegin() const
+
+ Returns an array iterator pointing to the first item in this array. If the
+ array is empty, then this function returns the same as end().
+
+ \sa constBegin(), constEnd()
+ */
+
+/*!
+ \fn QCborArray::const_iterator QCborArray::constBegin() const
+
+ Returns an array iterator pointing to the first item in this array. If the
+ array is empty, then this function returns the same as end().
+
+ \sa begin(), constEnd()
+ */
+
+/*!
+ \fn QCborArray::iterator QCborArray::end()
+
+ Returns an array iterator pointing to just after the last element in this
+ array.
+
+ \sa begin(), constEnd()
+ */
+
+/*!
+ \fn QCborArray::const_iterator QCborArray::end() const
+
+ Returns an array iterator pointing to just after the last element in this
+ array.
+
+ \sa constBegin(), constEnd()
+ */
+
+/*!
+ \fn QCborArray::const_iterator QCborArray::cend() const
+
+ Returns an array iterator pointing to just after the last element in this
+ array.
+
+ \sa constBegin(), constEnd()
+ */
+
+/*!
+ \fn QCborArray::const_iterator QCborArray::constEnd() const
+
+ Returns an array iterator pointing to just after the last element in this
+ array.
+
+ \sa constBegin(), end()
+ */
+
+/*!
+ \fn QCborArray::iterator QCborArray::insert(iterator before, const QCborValue &value)
+ \fn QCborArray::iterator QCborArray::insert(const_iterator before, const QCborValue &value)
+ \overload
+
+ Inserts \a value into this array before element \a before and returns an
+ array iterator pointing to the just-inserted element.
+
+ \sa erase(), removeAt(), prepend(), append()
+ */
+
+/*!
+ \fn QCborArray::iterator QCborArray::erase(iterator it)
+ \fn QCborArray::iterator QCborArray::erase(const_iterator it)
+
+ Removes the element pointed to by the array iterator \a it from this array,
+ then returns an iterator to the next element (the one that took the same
+ position in the array that \a it used to occupy).
+
+ \sa insert(), removeAt(), takeAt(), takeFirst(), takeLast()
+ */
+
+/*!
+ \fn void QCborArray::push_back(const QCborValue &t)
+
+ Synonym for append(). This function is provided for compatibility with
+ generic code that uses the Standard Library API.
+
+ Appends the element \a t to this array.
+
+ \sa append(), push_front(), pop_back(), prepend(), insert()
+ */
+
+/*!
+ \fn void QCborArray::push_front(const QCborValue &t)
+
+ Synonym for prepend(). This function is provided for compatibility with
+ generic code that uses the Standard Library API.
+
+ Prepends the element \a t to this array.
+
+ \sa prepend(), push_back(), pop_front(), append(), insert()
+ */
+
+/*!
+ \fn void QCborArray::pop_front()
+
+ Synonym for removeFirst(). This function is provided for compatibility with
+ generic code that uses the Standard Library API.
+
+ Removes the first element of this array. The array must not be empty before
+ the removal
+
+ \sa removeFirst(), takeFirst(), pop_back(), push_front(), prepend(), insert()
+ */
+
+/*!
+ \fn void QCborArray::pop_back()
+
+ Synonym for removeLast(). This function is provided for compatibility with
+ generic code that uses the Standard Library API.
+
+ Removes the last element of this array. The array must not be empty before
+ the removal
+
+ \sa removeLast(), takeLast(), pop_front(), push_back(), append(), insert()
+ */
+
+/*!
+ \fn bool QCborArray::empty() const
+
+ Synonym for isEmpty(). This function is provided for compatibility with
+ generic code that uses the Standard Library API.
+
+ Returns true if this array is empty (size() == 0).
+
+ \sa isEmpty(), size()
+ */
+
+/*!
+ \fn QCborArray QCborArray::operator+(const QCborValue &v) const
+
+ Returns a new QCborArray containing the same elements as this array, plus
+ \a v appended as the last element.
+
+ \sa operator+=(), operator<<(), append()
+ */
+
+/*!
+ \fn QCborArray &QCborArray::operator+=(const QCborValue &v)
+
+ Appends \a v to this array and returns a reference to this array.
+
+ \sa append(), insert(), operator+(), operator<<()
+ */
+
+/*!
+ \fn QCborArray &QCborArray::operator<<(const QCborValue &v)
+
+ Appends \a v to this array and returns a reference to this array.
+
+ \sa append(), insert(), operator+(), operator+=()
+ */
+
+void QCborArray::detach(qsizetype reserved)
+{
+ d = QCborContainerPrivate::detach(d.data(), reserved ? reserved : size());
+}
+
+/*!
+ \class QCborArray::Iterator
+ \inmodule QtCore
+ \ingroup cbor
+ \since 5.12
+
+ \brief The QCborArray::Iterator class provides an STL-style non-const iterator for QCborArray.
+
+ QCborArray::Iterator allows you to iterate over a QCborArray and to modify
+ the array item associated with the iterator. If you want to iterate over a
+ const QCborArray, use QCborArray::ConstIterator instead. It is generally a
+ good practice to use QCborArray::ConstIterator on a non-const QCborArray as
+ well, unless you need to change the QCborArray through the iterator. Const
+ iterators are slightly faster and improve code readability.
+
+ Iterators are initialized by using a QCborArray function like
+ QCborArray::begin(), QCborArray::end(), or QCborArray::insert(). Iteration
+ is only possible after that.
+
+ Most QCborArray functions accept an integer index rather than an iterator.
+ For that reason, iterators are rarely useful in connection with QCborArray.
+ One place where STL-style iterators do make sense is as arguments to
+ \l{generic algorithms}.
+
+ Multiple iterators can be used on the same array. However, be aware that
+ any non-const function call performed on the QCborArray will render all
+ existing iterators undefined.
+
+ \sa QCborArray::ConstIterator
+*/
+
+/*!
+ \typedef QCborArray::Iterator::iterator_category
+
+ A synonym for \e {std::random_access_iterator_tag} indicating this iterator
+ is a random access iterator.
+ */
+
+/*!
+ \typedef QCborArray::Iterator::difference_type
+ \internal
+*/
+
+/*!
+ \typedef QCborArray::Iterator::value_type
+ \internal
+*/
+
+/*!
+ \typedef QCborArray::Iterator::reference
+ \internal
+*/
+
+/*!
+ \typedef QCborArray::Iterator::pointer
+ \internal
+*/
+
+/*!
+ \fn QCborArray::Iterator::Iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like operator*() and operator++() should not be called on an
+ uninitialized iterator. Use operator=() to assign a value to it before
+ using it.
+
+ \sa QCborArray::begin(), QCborArray::end()
+*/
+
+/*!
+ \fn QCborArray::Iterator::Iterator(const Iterator &other)
+
+ Makes a copy of \a other.
+ */
+
+/*!
+ \fn QCborArray::Iterator &QCborArray::Iterator::operator=(const Iterator &other)
+
+ Makes this iterator a copy of \a other and returns a reference to this iterator.
+ */
+
+/*!
+ \fn QCborValueRef QCborArray::Iterator::operator*() const
+
+ Returns a modifiable reference to the current item.
+
+ You can change the value of an item by using operator*() on the left side
+ of an assignment.
+
+ The return value is of type QCborValueRef, a helper class for QCborArray
+ and QCborMap. When you get an object of type QCborValueRef, you can use it
+ as if it were a reference to a QCborValue. If you assign to it, the
+ assignment will apply to the element in the QCborArray or QCborMap from
+ which you got the reference.
+*/
+
+/*!
+ \fn QCborValueRef *QCborArray::Iterator::operator->() const
+
+ Returns a pointer to a modifiable reference to the current item.
+*/
+
+/*!
+ \fn QCborValueRef QCborArray::Iterator::operator[](qsizetype j)
+
+ Returns a modifiable reference to the item at a position \a j steps forward
+ from the item pointed to by this iterator.
+
+ This function is provided to make QCborArray iterators behave like C++
+ pointers.
+
+ The return value is of type QCborValueRef, a helper class for QCborArray
+ and QCborMap. When you get an object of type QCborValueRef, you can use it
+ as if it were a reference to a QCborValue. If you assign to it, the
+ assignment will apply to the element in the QCborArray or QCborMap from
+ which you got the reference.
+
+ \sa operator+()
+*/
+
+/*!
+ \fn bool QCborArray::Iterator::operator==(const Iterator &other) const
+ \fn bool QCborArray::Iterator::operator==(const ConstIterator &other) const
+
+ Returns \c true if \a other points to the same entry in the array as this
+ iterator; otherwise returns \c false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QCborArray::Iterator::operator!=(const Iterator &other) const
+ \fn bool QCborArray::Iterator::operator!=(const ConstIterator &other) const
+
+ Returns \c true if \a other points to a different entry in the array than
+ this iterator; otherwise returns \c false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QCborArray::Iterator::operator<(const Iterator& other) const
+ \fn bool QCborArray::Iterator::operator<(const ConstIterator& other) const
+
+ Returns \c true if the entry in the array pointed to by this iterator
+ occurs before the entry pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QCborArray::Iterator::operator<=(const Iterator& other) const
+ \fn bool QCborArray::Iterator::operator<=(const ConstIterator& other) const
+
+ Returns \c true if the entry in the array pointed to by this iterator
+ occurs before or is the same entry as is pointed to by the \a other
+ iterator.
+*/
+
+/*!
+ \fn bool QCborArray::Iterator::operator>(const Iterator& other) const
+ \fn bool QCborArray::Iterator::operator>(const ConstIterator& other) const
+
+ Returns \c true if the entry in the array pointed to by this iterator
+ occurs after the entry pointed to by the \a other iterator.
+ */
+
+/*!
+ \fn bool QCborArray::Iterator::operator>=(const Iterator& other) const
+ \fn bool QCborArray::Iterator::operator>=(const ConstIterator& other) const
+
+ Returns \c true if the entry in the array pointed to by this iterator
+ occurs after or is the same entry as is pointed to by the \a other
+ iterator.
+*/
+
+/*!
+ \fn QCborArray::Iterator &QCborArray::Iterator::operator++()
+
+ The prefix ++ operator, \c{++it}, advances the iterator to the next item in
+ the array and returns this iterator.
+
+ Calling this function on QCborArray::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*!
+ \fn QCborArray::Iterator QCborArray::Iterator::operator++(int)
+ \overload
+
+ The postfix ++ operator, \c{it++}, advances the iterator to the next item
+ in the array and returns an iterator to the previously current item.
+*/
+
+/*!
+ \fn QCborArray::Iterator &QCborArray::Iterator::operator--()
+
+ The prefix -- operator, \c{--it}, makes the preceding item current and
+ returns this iterator.
+
+ Calling this function on QCborArray::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*!
+ \fn QCborArray::Iterator QCborArray::Iterator::operator--(int)
+ \overload
+
+ The postfix -- operator, \c{it--}, makes the preceding item current and
+ returns an iterator to the previously current item.
+*/
+
+/*!
+ \fn QCborArray::Iterator &QCborArray::Iterator::operator+=(qsizetype j)
+
+ Advances the iterator by \a j positions. If \a j is negative, the iterator
+ goes backward. Returns a reference to this iterator.
+
+ \sa operator-=(), operator+()
+*/
+
+/*!
+ \fn QCborArray::Iterator &QCborArray::Iterator::operator-=(qsizetype j)
+
+ Makes the iterator go back by \a j positions. If \a j is negative, the
+ iterator goes forward. Returns a reference to this iterator.
+
+ \sa operator+=(), operator-()
+*/
+
+/*!
+ \fn QCborArray::Iterator QCborArray::Iterator::operator+(qsizetype j) const
+
+ Returns an iterator to the item at position \a j steps forward from this
+ iterator. If \a j is negative, the iterator goes backward.
+
+ \sa operator-(), operator+=()
+*/
+
+/*!
+ \fn QCborArray::Iterator QCborArray::Iterator::operator-(qsizetype j) const
+
+ Returns an iterator to the item at position \a j steps backward from this
+ iterator. If \a j is negative, the iterator goes forward.
+
+ \sa operator+(), operator-=()
+*/
+
+/*!
+ \fn qsizetype QCborArray::Iterator::operator-(Iterator other) const
+
+ Returns the offset of this iterator relative to \a other.
+*/
+
+/*!
+ \class QCborArray::ConstIterator
+ \inmodule QtCore
+ \ingroup cbor
+ \since 5.12
+
+ \brief The QCborArray::ConstIterator class provides an STL-style const iterator for QCborArray.
+
+ QCborArray::ConstIterator allows you to iterate over a QCborArray. If you
+ want to modify the QCborArray as you iterate over it, use
+ QCborArray::Iterator instead. It is generally good practice to use
+ QCborArray::ConstIterator, even on a non-const QCborArray, when you don't
+ need to change the QCborArray through the iterator. Const iterators are
+ slightly faster and improves code readability.
+
+ Iterators are initialized by using a QCborArray function like
+ QCborArray::begin() or QCborArray::end(). Iteration is only possible after
+ that.
+
+ Most QCborArray functions accept an integer index rather than an iterator.
+ For that reason, iterators are rarely useful in connection with QCborArray.
+ One place where STL-style iterators do make sense is as arguments to
+ \l{generic algorithms}.
+
+ Multiple iterators can be used on the same array. However, be aware that
+ any non-const function call performed on the QCborArray will render all
+ existing iterators undefined.
+
+ \sa QCborArray::Iterator
+*/
+
+/*!
+ \fn QCborArray::ConstIterator::ConstIterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like operator*() and operator++() should not be called on an
+ uninitialized iterator. Use operator=() to assign a value to it before
+ using it.
+
+ \sa QCborArray::constBegin(), QCborArray::constEnd()
+*/
+
+/*!
+ \fn QCborArray::ConstIterator &QCborArray::ConstIterator::operator=(const ConstIterator &other)
+
+ Makes this iterator a copy of \a other and returns a reference to this iterator.
+*/
+
+/*!
+ \typedef QCborArray::ConstIterator::iterator_category
+
+ A synonym for \e {std::random_access_iterator_tag} indicating this iterator
+ is a random access iterator.
+*/
+
+/*!
+ \typedef QCborArray::ConstIterator::difference_type
+ \internal
+*/
+
+/*!
+ \typedef QCborArray::ConstIterator::value_type
+ \internal
+*/
+
+/*!
+ \typedef QCborArray::ConstIterator::reference
+ \internal
+*/
+
+/*!
+ \typedef QCborArray::ConstIterator::pointer
+ \internal
+*/
+
+/*!
+ \fn QCborArray::ConstIterator::ConstIterator(const ConstIterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ \fn QCborValue QCborArray::ConstIterator::operator*() const
+
+ Returns the current item.
+*/
+
+/*!
+ \fn const QCborValue *QCborArray::ConstIterator::operator->() const
+
+ Returns a pointer to the current item.
+*/
+
+/*!
+ \fn const QCborValueRef QCborArray::ConstIterator::operator[](qsizetype j)
+
+ Returns the item at a position \a j steps forward from the item pointed to
+ by this iterator.
+
+ This function is provided to make QCborArray iterators behave like C++
+ pointers.
+
+ \sa operator+()
+*/
+
+/*!
+ \fn bool QCborArray::ConstIterator::operator==(const Iterator &other) const
+ \fn bool QCborArray::ConstIterator::operator==(const ConstIterator &other) const
+
+ Returns \c true if \a other points to the same entry in the array as this
+ iterator; otherwise returns \c false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QCborArray::ConstIterator::operator!=(const Iterator &o) const
+ \fn bool QCborArray::ConstIterator::operator!=(const ConstIterator &o) const
+
+ Returns \c true if \a o points to a different entry in the array than
+ this iterator; otherwise returns \c false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QCborArray::ConstIterator::operator<(const Iterator &other) const
+ \fn bool QCborArray::ConstIterator::operator<(const ConstIterator &other) const
+
+ Returns \c true if the entry in the array pointed to by this iterator
+ occurs before the entry pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QCborArray::ConstIterator::operator<=(const Iterator &other) const
+ \fn bool QCborArray::ConstIterator::operator<=(const ConstIterator &other) const
+
+ Returns \c true if the entry in the array pointed to by this iterator
+ occurs before or is the same entry as is pointed to by the \a other
+ iterator.
+*/
+
+/*!
+ \fn bool QCborArray::ConstIterator::operator>(const Iterator &other) const
+ \fn bool QCborArray::ConstIterator::operator>(const ConstIterator &other) const
+
+ Returns \c true if the entry in the array pointed to by this iterator
+ occurs after the entry pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QCborArray::ConstIterator::operator>=(const Iterator &other) const
+ \fn bool QCborArray::ConstIterator::operator>=(const ConstIterator &other) const
+
+ Returns \c true if the entry in the array pointed to by this iterator
+ occurs after or is the same entry as is pointed to by the \a other
+ iterator.
+*/
+
+/*!
+ \fn QCborArray::ConstIterator &QCborArray::ConstIterator::operator++()
+
+ The prefix ++ operator, \c{++it}, advances the iterator to the next item in
+ the array and returns this iterator.
+
+ Calling this function on QCborArray::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*!
+ \fn QCborArray::ConstIterator QCborArray::ConstIterator::operator++(int)
+ \overload
+
+ The postfix ++ operator, \c{it++}, advances the iterator to the next item
+ in the array and returns an iterator to the previously current item.
+*/
+
+/*!
+ \fn QCborArray::ConstIterator &QCborArray::ConstIterator::operator--()
+
+ The prefix -- operator, \c{--it}, makes the preceding item current and
+ returns this iterator.
+
+ Calling this function on QCborArray::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*!
+ \fn QCborArray::ConstIterator QCborArray::ConstIterator::operator--(int)
+ \overload
+
+ The postfix -- operator, \c{it--}, makes the preceding item current and
+ returns an iterator to the previously current item.
+*/
+
+/*!
+ \fn QCborArray::ConstIterator &QCborArray::ConstIterator::operator+=(qsizetype j)
+
+ Advances the iterator by \a j positions. If \a j is negative, the iterator
+ goes backward. Returns a reference to this iterator.
+
+ \sa operator-=(), operator+()
+*/
+
+/*!
+ \fn QCborArray::ConstIterator &QCborArray::ConstIterator::operator-=(qsizetype j)
+
+ Makes the iterator go back by \a j positions. If \a j is negative, the
+ iterator goes forward. Returns a reference to this iterator.
+
+ \sa operator+=(), operator-()
+*/
+
+/*!
+ \fn QCborArray::ConstIterator QCborArray::ConstIterator::operator+(qsizetype j) const
+
+ Returns an iterator to the item at a position \a j steps forward from this
+ iterator. If \a j is negative, the iterator goes backward.
+
+ \sa operator-(), operator+=()
+*/
+
+/*!
+ \fn QCborArray::ConstIterator QCborArray::ConstIterator::operator-(qsizetype j) const
+
+ Returns an iterator to the item at a position \a j steps backward from this
+ iterator. If \a j is negative, the iterator goes forward.
+
+ \sa operator+(), operator-=()
+*/
+
+/*!
+ \fn qsizetype QCborArray::ConstIterator::operator-(ConstIterator other) const
+
+ Returns the offset of this iterator relative to \a other.
+*/
+
+uint qHash(const QCborArray &array, uint seed)
+{
+ return qHashRange(array.begin(), array.end(), seed);
+}
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug dbg, const QCborArray &a)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "QCborArray{";
+ const char *comma = "";
+ for (auto v : a) {
+ dbg << comma << v;
+ comma = ", ";
+ }
+ return dbg << '}';
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h
new file mode 100644
index 0000000000..f24bb41759
--- /dev/null
+++ b/src/corelib/serialization/qcborarray.h
@@ -0,0 +1,298 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCBORARRAY_H
+#define QCBORARRAY_H
+
+#include <QtCore/qcborvalue.h>
+
+#include <initializer_list>
+
+QT_BEGIN_NAMESPACE
+
+class QJsonArray;
+
+class QCborContainerPrivate;
+class Q_CORE_EXPORT QCborArray
+{
+public:
+ class ConstIterator;
+ class Iterator {
+ mutable QCborValueRef item;
+ friend class ConstIterator;
+ friend class QCborArray;
+ Iterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef qsizetype difference_type;
+ typedef QCborValue value_type;
+ typedef QCborValueRef reference;
+ typedef QCborValueRef *pointer;
+
+ Q_DECL_CONSTEXPR Iterator() = default;
+ Q_DECL_CONSTEXPR Iterator(const Iterator &) = default;
+ Iterator &operator=(const Iterator &other)
+ {
+ // rebind the reference
+ item.d = other.item.d;
+ item.i = other.item.i;
+ return *this;
+ }
+
+ QCborValueRef operator*() const { return item; }
+ QCborValueRef *operator->() const { return &item; }
+ QCborValueRef operator[](qsizetype j) { return { item.d, item.i + j }; }
+
+ bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
+ bool operator!=(const Iterator &o) const { return !(*this == o); }
+ bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
+ bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
+ bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
+ bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
+ bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
+ bool operator!=(const ConstIterator &o) const { return !(*this == o); }
+ bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
+ bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
+ bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
+ bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
+ Iterator &operator++() { ++item.i; return *this; }
+ Iterator operator++(int) { Iterator n = *this; ++item.i; return n; }
+ Iterator &operator--() { item.i--; return *this; }
+ Iterator operator--(int) { Iterator n = *this; item.i--; return n; }
+ Iterator &operator+=(qsizetype j) { item.i += j; return *this; }
+ Iterator &operator-=(qsizetype j) { item.i -= j; return *this; }
+ Iterator operator+(qsizetype j) const { return Iterator({ item.d, item.i + j }); }
+ Iterator operator-(qsizetype j) const { return Iterator({ item.d, item.i - j }); }
+ qsizetype operator-(Iterator j) const { return item.i - j.item.i; }
+ };
+
+ class ConstIterator {
+ QCborValueRef item;
+ friend class Iterator;
+ friend class QCborArray;
+ ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef qsizetype difference_type;
+ typedef const QCborValue value_type;
+ typedef const QCborValueRef reference;
+ typedef const QCborValueRef *pointer;
+
+ Q_DECL_CONSTEXPR ConstIterator() = default;
+ Q_DECL_CONSTEXPR ConstIterator(const ConstIterator &) = default;
+ ConstIterator &operator=(const ConstIterator &other)
+ {
+ // rebind the reference
+ item.d = other.item.d;
+ item.i = other.item.i;
+ return *this;
+ }
+
+ const QCborValueRef operator*() const { return item; }
+ const QCborValueRef *operator->() const { return &item; }
+ const QCborValueRef operator[](qsizetype j) { return { item.d, item.i + j }; }
+
+ bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
+ bool operator!=(const Iterator &o) const { return !(*this == o); }
+ bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
+ bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
+ bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
+ bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
+ bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
+ bool operator!=(const ConstIterator &o) const { return !(*this == o); }
+ bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
+ bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
+ bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
+ bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
+ ConstIterator &operator++() { ++item.i; return *this; }
+ ConstIterator operator++(int) { ConstIterator n = *this; ++item.i; return n; }
+ ConstIterator &operator--() { item.i--; return *this; }
+ ConstIterator operator--(int) { ConstIterator n = *this; item.i--; return n; }
+ ConstIterator &operator+=(qsizetype j) { item.i += j; return *this; }
+ ConstIterator &operator-=(qsizetype j) { item.i -= j; return *this; }
+ ConstIterator operator+(qsizetype j) const { return ConstIterator({ item.d, item.i + j }); }
+ ConstIterator operator-(qsizetype j) const { return ConstIterator({ item.d, item.i - j }); }
+ qsizetype operator-(ConstIterator j) const { return item.i - j.item.i; }
+ };
+
+ typedef qsizetype size_type;
+ typedef QCborValue value_type;
+ typedef value_type *pointer;
+ typedef const value_type *const_pointer;
+ typedef QCborValue &reference;
+ typedef const QCborValue &const_reference;
+ typedef qsizetype difference_type;
+
+ QCborArray() noexcept;
+ QCborArray(const QCborArray &other) noexcept;
+ QCborArray &operator=(const QCborArray &other) noexcept;
+ QCborArray(std::initializer_list<QCborValue> args)
+ : QCborArray()
+ {
+ detach(qsizetype(args.size()));
+ for (const QCborValue &v : args)
+ append(v);
+ }
+ ~QCborArray();
+
+ void swap(QCborArray &other) noexcept
+ {
+ qSwap(d, other.d);
+ }
+
+ QCborValue toCborValue() const { return *this; }
+
+ qsizetype size() const noexcept;
+ bool isEmpty() const { return size() == 0; }
+ void clear();
+
+ QCborValue at(qsizetype i) const;
+ QCborValue first() const { return at(0); }
+ QCborValue last() const { return at(size() - 1); }
+ QCborValue operator[](qsizetype i) const { return at(i); }
+ QCborValueRef first() { Q_ASSERT(!isEmpty()); return begin()[0]; }
+ QCborValueRef last() { Q_ASSERT(!isEmpty()); return begin()[size() - 1]; }
+ QCborValueRef operator[](qsizetype i) { Q_ASSERT(i < size()); return begin()[i]; }
+
+ void insert(qsizetype i, const QCborValue &value);
+ void insert(qsizetype i, QCborValue &&value);
+ void prepend(const QCborValue &value) { insert(0, value); }
+ void prepend(QCborValue &&value) { insert(0, std::move(value)); }
+ void append(const QCborValue &value) { insert(-1, value); }
+ void append(QCborValue &&value) { insert(-1, std::move(value)); }
+ QCborValue extract(ConstIterator it) { return extract(Iterator{ it.item.d, it.item.i }); }
+ QCborValue extract(Iterator it);
+ void removeAt(qsizetype i);
+ QCborValue takeAt(qsizetype i) { Q_ASSERT(i < size()); return extract(begin() + i); }
+ void removeFirst() { removeAt(0); }
+ void removeLast() { removeAt(size() - 1); }
+ QCborValue takeFirst() { return takeAt(0); }
+ QCborValue takeLast() { return takeAt(size() - 1); }
+
+ bool contains(const QCborValue &value) const;
+
+ int compare(const QCborArray &other) const noexcept Q_DECL_PURE_FUNCTION;
+#if 0 && QT_HAS_INCLUDE(<compare>)
+ std::strong_ordering operator<=>(const QCborArray &other) const
+ {
+ int c = compare(other);
+ if (c > 0) return std::strong_ordering::greater;
+ if (c == 0) return std::strong_ordering::equivalent;
+ return std::strong_ordering::less;
+ }
+#else
+ bool operator==(const QCborArray &other) const noexcept
+ { return compare(other) == 0; }
+ bool operator!=(const QCborArray &other) const noexcept
+ { return !(*this == other); }
+ bool operator<(const QCborArray &other) const
+ { return compare(other) < 0; }
+#endif
+
+ typedef Iterator iterator;
+ typedef ConstIterator const_iterator;
+ iterator begin() { detach(); return iterator{d.data(), 0}; }
+ const_iterator constBegin() const { return const_iterator{d.data(), 0}; }
+ const_iterator begin() const { return constBegin(); }
+ const_iterator cbegin() const { return constBegin(); }
+ iterator end() { detach(); return iterator{d.data(), size()}; }
+ const_iterator constEnd() const { return const_iterator{d.data(), size()}; }
+ const_iterator end() const { return constEnd(); }
+ const_iterator cend() const { return constEnd(); }
+ iterator insert(iterator before, const QCborValue &value)
+ { insert(before.item.i, value); return iterator{d.data(), before.item.i}; }
+ iterator insert(const_iterator before, const QCborValue &value)
+ { insert(before.item.i, value); return iterator{d.data(), before.item.i}; }
+ iterator erase(iterator it) { removeAt(it.item.i); return iterator{d.data(), it.item.i}; }
+ iterator erase(const_iterator it) { removeAt(it.item.i); return iterator{d.data(), it.item.i}; }
+
+ void push_back(const QCborValue &t) { append(t); }
+ void push_front(const QCborValue &t) { prepend(t); }
+ void pop_front() { removeFirst(); }
+ void pop_back() { removeLast(); }
+ bool empty() const { return isEmpty(); }
+
+ // convenience
+ QCborArray operator+(const QCborValue &v) const
+ { QCborArray n = *this; n += v; return n; }
+ QCborArray &operator+=(const QCborValue &v)
+ { append(v); return *this; }
+ QCborArray &operator<<(const QCborValue &v)
+ { append(v); return *this; }
+
+ static QCborArray fromStringList(const QStringList &list);
+ static QCborArray fromVariantList(const QVariantList &list);
+ static QCborArray fromJsonArray(const QJsonArray &array);
+ QVariantList toVariantList() const;
+ QJsonArray toJsonArray() const;
+
+private:
+ void detach(qsizetype reserve = 0);
+
+ friend QCborValue;
+ explicit QCborArray(QCborContainerPrivate &dd) noexcept;
+ QExplicitlySharedDataPointer<QCborContainerPrivate> d;
+};
+
+Q_DECLARE_SHARED(QCborArray)
+
+inline QCborValue::QCborValue(QCborArray &&a)
+ : n(-1), container(a.d.take()), t(Array)
+{
+}
+
+inline QCborArray QCborValueRef::toArray() const
+{
+ return concrete().toArray();
+}
+
+inline QCborArray QCborValueRef::toArray(const QCborArray &a) const
+{
+ return concrete().toArray(a);
+}
+
+Q_CORE_EXPORT uint qHash(const QCborArray &array, uint seed = 0);
+
+#if !defined(QT_NO_DEBUG_STREAM)
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborArray &a);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QCBORARRAY_H
diff --git a/src/corelib/serialization/qcborcommon.h b/src/corelib/serialization/qcborcommon.h
new file mode 100644
index 0000000000..9661cd70bb
--- /dev/null
+++ b/src/corelib/serialization/qcborcommon.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCBORCOMMON_H
+#define QCBORCOMMON_H
+
+#include <QtCore/qobjectdefs.h>
+#include <QtCore/qmetatype.h>
+#include <QtCore/qdebug.h>
+
+#if 0
+#pragma qt_class(QtCborCommon)
+#endif
+
+/* X11 headers use these values too, but as defines */
+#if defined(False) && defined(True)
+# define QT_X11_DEFINES_FOUND 1
+# undef True
+# undef False
+#endif
+
+QT_BEGIN_NAMESPACE
+
+enum class QCborSimpleType : quint8 {
+ False = 20,
+ True = 21,
+ Null = 22,
+ Undefined = 23
+};
+
+enum class QCborTag : quint64 {};
+enum class QCborKnownTags {
+ DateTimeString = 0,
+ UnixTime_t = 1,
+ PositiveBignum = 2,
+ NegativeBignum = 3,
+ Decimal = 4,
+ Bigfloat = 5,
+ COSE_Encrypt0 = 16,
+ COSE_Mac0 = 17,
+ COSE_Sign1 = 18,
+ ExpectedBase64url = 21,
+ ExpectedBase64 = 22,
+ ExpectedBase16 = 23,
+ EncodedCbor = 24,
+ Url = 32,
+ Base64url = 33,
+ Base64 = 34,
+ RegularExpression = 35,
+ MimeMessage = 36,
+ Uuid = 37,
+ COSE_Encrypt = 96,
+ COSE_Mac = 97,
+ COSE_Sign = 98,
+ Signature = 55799
+};
+
+inline bool operator==(QCborTag t, QCborKnownTags kt) { return quint64(t) == quint64(kt); }
+inline bool operator==(QCborKnownTags kt, QCborTag t) { return quint64(t) == quint64(kt); }
+inline bool operator!=(QCborTag t, QCborKnownTags kt) { return quint64(t) != quint64(kt); }
+inline bool operator!=(QCborKnownTags kt, QCborTag t) { return quint64(t) != quint64(kt); }
+
+struct Q_CORE_EXPORT QCborError
+{
+ Q_GADGET
+public:
+ enum Code : int {
+ UnknownError = 1,
+ AdvancePastEnd = 3,
+ InputOutputError = 4,
+ GarbageAtEnd = 256,
+ EndOfFile,
+ UnexpectedBreak,
+ UnknownType,
+ IllegalType,
+ IllegalNumber,
+ IllegalSimpleType,
+
+ InvalidUtf8String = 516,
+
+ DataTooLarge = 1024,
+ NestingTooDeep,
+ UnsupportedType,
+
+ NoError = 0
+ };
+ Q_ENUM(Code)
+
+ Code c;
+ operator Code() const { return c; }
+ QString toString() const;
+};
+
+#if !defined(QT_NO_DEBUG_STREAM)
+Q_CORE_EXPORT QDebug operator<<(QDebug, QCborSimpleType st);
+Q_CORE_EXPORT QDebug operator<<(QDebug, QCborKnownTags tg);
+Q_CORE_EXPORT QDebug operator<<(QDebug, QCborTag tg);
+#endif
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QCborTag)
+
+// To avoid changing namespace we need to reinstate defines, even though our .cpp
+// will then have to remove them again.
+#if defined(QT_X11_DEFINES_FOUND)
+# define True 1
+# define False 0
+#endif
+
+#endif // QCBORSTREAM_H
diff --git a/src/corelib/serialization/qcbordiagnostic.cpp b/src/corelib/serialization/qcbordiagnostic.cpp
new file mode 100644
index 0000000000..75feaded17
--- /dev/null
+++ b/src/corelib/serialization/qcbordiagnostic.cpp
@@ -0,0 +1,347 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcborvalue.h"
+#include "qcborvalue_p.h"
+
+#include "qcborarray.h"
+#include "qcbormap.h"
+
+#include <private/qnumeric_p.h>
+#include <qstack.h>
+#include <private/qtools_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+class DiagnosticNotation
+{
+public:
+ static QString create(const QCborValue &v, QCborValue::DiagnosticNotationOptions opts)
+ {
+ DiagnosticNotation dn(opts);
+ dn.appendValue(v);
+ return dn.result;
+ }
+
+private:
+ QStack<int> byteArrayFormatStack;
+ QString separator;
+ QString result;
+ QCborValue::DiagnosticNotationOptions opts;
+ int nestingLevel = 0;
+
+ struct Nest {
+ enum { IndentationWidth = 4 };
+ DiagnosticNotation *dn;
+ Nest(DiagnosticNotation *that) : dn(that)
+ {
+ ++dn->nestingLevel;
+ static const char indent[IndentationWidth + 1] = " ";
+ if (dn->opts & QCborValue::LineWrapped)
+ dn->separator += QLatin1String(indent, IndentationWidth);
+ }
+ ~Nest()
+ {
+ --dn->nestingLevel;
+ if (dn->opts & QCborValue::LineWrapped)
+ dn->separator.chop(IndentationWidth);
+ }
+ };
+
+ DiagnosticNotation(QCborValue::DiagnosticNotationOptions opts_)
+ : separator(QLatin1String(opts_ & QCborValue::LineWrapped ? "\n" : "")), opts(opts_)
+ {
+ byteArrayFormatStack.push(int(QCborKnownTags::ExpectedBase16));
+ }
+
+ void appendString(const QString &s);
+ void appendArray(const QCborArray &a);
+ void appendMap(const QCborMap &m);
+ void appendValue(const QCborValue &v);
+};
+}
+
+static QString makeFpString(double d)
+{
+ QString s;
+ quint64 v;
+ if (qt_is_inf(d)) {
+ s = (d < 0) ? QStringLiteral("-inf") : QStringLiteral("inf");
+ } else if (qt_is_nan(d)) {
+ s = QStringLiteral("nan");
+ } else if (convertDoubleTo(d, &v)) {
+ s = QString::fromLatin1("%1.0").arg(v);
+ if (d < 0)
+ s.prepend(QLatin1Char('-'));
+ } else {
+ s = QString::number(d, 'g', QLocale::FloatingPointShortest);
+ if (!s.contains(QLatin1Char('.')) && !s.contains('e'))
+ s += QLatin1Char('.');
+ }
+ return s;
+}
+
+static bool isByteArrayEncodingTag(QCborTag tag)
+{
+ switch (quint64(tag)) {
+ case quint64(QCborKnownTags::ExpectedBase16):
+ case quint64(QCborKnownTags::ExpectedBase64):
+ case quint64(QCborKnownTags::ExpectedBase64url):
+ return true;
+ }
+ return false;
+}
+
+void DiagnosticNotation::appendString(const QString &s)
+{
+ result += QLatin1Char('"');
+
+ const QChar *begin = s.begin();
+ const QChar *end = s.end();
+ while (begin < end) {
+ // find the longest span comprising only non-escaped characters
+ const QChar *ptr = begin;
+ for ( ; ptr < end; ++ptr) {
+ ushort uc = ptr->unicode();
+ if (uc == '\\' || uc == '"' || uc < ' ' || uc >= 0x7f)
+ break;
+ }
+
+ if (ptr != begin)
+ result.append(begin, ptr - begin);
+
+ if (ptr == end)
+ break;
+
+ // there's an escaped character
+ static const char escapeMap[16] = {
+ // The C escape characters \a \b \t \n \v \f and \r indexed by
+ // their ASCII values
+ 0, 0, 0, 0,
+ 0, 0, 0, 'a',
+ 'b', 't', 'n', 'v',
+ 'f', 'r', 0, 0
+ };
+ int buflen = 2;
+ QChar buf[10];
+ buf[0] = QLatin1Char('\\');
+ buf[1] = QChar::Null;
+ char16_t uc = ptr->unicode();
+
+ if (uc < sizeof(escapeMap))
+ buf[1] = QLatin1Char(escapeMap[uc]);
+ else if (uc == '"' || uc == '\\')
+ buf[1] = QChar(uc);
+
+ if (buf[1] == QChar::Null) {
+ using QtMiscUtils::toHexUpper;
+ if (ptr->isHighSurrogate() && (ptr + 1) != end && ptr[1].isLowSurrogate()) {
+ // properly-paired surrogates
+ ++ptr;
+ char32_t ucs4 = QChar::surrogateToUcs4(uc, ptr->unicode());
+ buf[1] = 'U';
+ buf[2] = '0'; // toHexUpper(ucs4 >> 28);
+ buf[3] = '0'; // toHexUpper(ucs4 >> 24);
+ buf[4] = toHexUpper(ucs4 >> 20);
+ buf[5] = toHexUpper(ucs4 >> 16);
+ buf[6] = toHexUpper(ucs4 >> 12);
+ buf[7] = toHexUpper(ucs4 >> 8);
+ buf[8] = toHexUpper(ucs4 >> 4);
+ buf[9] = toHexUpper(ucs4);
+ buflen = 10;
+ } else {
+ buf[1] = 'u';
+ buf[2] = toHexUpper(uc >> 12);
+ buf[3] = toHexUpper(uc >> 8);
+ buf[4] = toHexUpper(uc >> 4);
+ buf[5] = toHexUpper(uc);
+ buflen = 6;
+ }
+ }
+
+ result.append(buf, buflen);
+ begin = ptr + 1;
+ }
+
+ result += QLatin1Char('"');
+}
+
+void DiagnosticNotation::appendArray(const QCborArray &a)
+{
+ result += QLatin1Char('[');
+
+ // length 2 (including the space) when not line wrapping
+ QLatin1String commaValue(", ", opts & QCborValue::LineWrapped ? 1 : 2);
+ {
+ Nest n(this);
+ QLatin1String comma;
+ for (auto v : a) {
+ result += comma + separator;
+ comma = commaValue;
+ appendValue(v);
+ }
+ }
+
+ result += separator + QLatin1Char(']');
+}
+
+void DiagnosticNotation::appendMap(const QCborMap &m)
+{
+ result += QLatin1Char('{');
+
+ // length 2 (including the space) when not line wrapping
+ QLatin1String commaValue(", ", opts & QCborValue::LineWrapped ? 1 : 2);
+ {
+ Nest n(this);
+ QLatin1String comma;
+ for (auto v : m) {
+ result += comma + separator;
+ comma = commaValue;
+ appendValue(v.first);
+ result += QLatin1String(": ");
+ appendValue(v.second);
+ }
+ }
+
+ result += separator + QLatin1Char('}');
+};
+
+void DiagnosticNotation::appendValue(const QCborValue &v)
+{
+ switch (v.type()) {
+ case QCborValue::Integer:
+ result += QString::number(v.toInteger());
+ return;
+ case QCborValue::ByteArray:
+ switch (byteArrayFormatStack.top()) {
+ case int(QCborKnownTags::ExpectedBase16):
+ result += QString::fromLatin1("h'" +
+ v.toByteArray().toHex(opts & QCborValue::ExtendedFormat ? ' ' : '\0') +
+ '\'');
+ return;
+ case int(QCborKnownTags::ExpectedBase64):
+ result += QString::fromLatin1("b64'" + v.toByteArray().toBase64() + '\'');
+ return;
+ default:
+ case int(QCborKnownTags::ExpectedBase64url):
+ result += QString::fromLatin1("b64'" +
+ v.toByteArray().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals) +
+ '\'');
+ return;
+ }
+ case QCborValue::String:
+ return appendString(v.toString());
+ case QCborValue::Array:
+ return appendArray(v.toArray());
+ case QCborValue::Map:
+ return appendMap(v.toMap());
+ case QCborValue::False:
+ result += QLatin1String("false");
+ return;
+ case QCborValue::True:
+ result += QLatin1String("true");
+ return;
+ case QCborValue::Null:
+ result += QLatin1String("null");
+ return;
+ case QCborValue::Undefined:
+ result += QLatin1String("undefined");
+ return;
+ case QCborValue::Double:
+ result += makeFpString(v.toDouble());
+ return;
+ case QCborValue::Invalid:
+ result += QStringLiteral("<invalid>");
+ return;
+
+ default:
+ // Only tags, extended types, and simple types remain; see below.
+ break;
+ }
+
+ if (v.isTag()) {
+ // We handle all extended types as regular tags, so it won't matter
+ // whether we understand that tag or not.
+ bool byteArrayFormat = opts & QCborValue::ExtendedFormat && isByteArrayEncodingTag(v.tag());
+ if (byteArrayFormat)
+ byteArrayFormatStack.push(int(v.tag()));
+ result += QString::number(quint64(v.tag())) + QLatin1Char('(');
+ appendValue(v.taggedValue());
+ result += QLatin1Char(')');
+ if (byteArrayFormat)
+ byteArrayFormatStack.pop();
+ } else {
+ // must be a simple type
+ result += QString::fromLatin1("simple(%1)").arg(quint8(v.toSimpleType()));
+ }
+}
+
+/*!
+ Creates the diagnostic notation equivalent of this CBOR object and returns
+ it. The \a opts parameter controls the dialect of the notation. Diagnostic
+ notation is useful in debugging, to aid the developer in understanding what
+ value is stored in the QCborValue or in a CBOR stream. For that reason, the
+ Qt API provides no support for parsing the diagnostic back into the
+ in-memory format or CBOR stream, though the representation is unique and it
+ would be possible.
+
+ CBOR diagnostic notation is specified by
+ \l{https://tools.ietf.org/html/rfc7049#section-6}{section 6} of RFC 7049.
+ It is a text representation of the CBOR stream and it is very similar to
+ JSON, but it supports the CBOR types not found in JSON. The extended format
+ enabled by the \l{DiagnosticNotationOption}{ExtendedFormat} flag is
+ currently in some IETF drafts and its format is subject to change.
+
+ This function produces the equivalent representation of the stream that
+ toCbor() would produce, without any transformation option provided there.
+ This also implies this function may not produce a representation of the
+ stream that was used to create the object, if it was created using
+ fromCbor(), as that function may have applied transformations. For a
+ high-fidelity notation of a stream, without transformation, see the \c
+ cbordump example.
+
+ \sa toCbor(), QJsonDocument::toJson()
+ */
+QString QCborValue::toDiagnosticNotation(DiagnosticNotationOptions opts) const
+{
+ return DiagnosticNotation::create(*this, opts);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qcbormap.cpp b/src/corelib/serialization/qcbormap.cpp
new file mode 100644
index 0000000000..33f9249993
--- /dev/null
+++ b/src/corelib/serialization/qcbormap.cpp
@@ -0,0 +1,1766 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcbormap.h"
+#include "qcborvalue_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QtCbor;
+
+/*!
+ \class QCborMap
+ \inmodule QtCore
+ \ingroup cbor
+ \reentrant
+ \since 5.12
+
+ \brief The QCborMap class is used to hold an associative container representable in CBOR.
+
+ This class can be used to hold an associative container in CBOR, a map
+ between a key and a value type. CBOR is the Concise Binary Object
+ Representation, a very compact form of binary data encoding that is a
+ superset of JSON. It was created by the IETF Constrained RESTful
+ Environments (CoRE) WG, which has used it in many new RFCs. It is meant to
+ be used alongside the \l{https://tools.ietf.org/html/rfc7252}{CoAP
+ protocol}.
+
+ Unlike JSON and \l QVariantMap, CBOR map keys can be of any type, not just
+ strings. For that reason, QCborMap is effectively a map between QCborValue
+ keys to QCborValue value elements.
+
+ However, for all member functions that take a key parameter, QCborMap
+ provides overloads that will work efficiently with integers and strings. In
+ fact, the use of integer keys is encouraged, since they occupy fewer bytes
+ to transmit and are simpler to encode and decode. Newer protocols designed
+ by the IETF CoRE WG to work specifically with CBOR are known to use them.
+
+ QCborMap is not sorted, because of that, searching for keys has linear
+ complexity (O(n)). QCborMap actually keeps the elements in the order that
+ they were inserted, which means that it is possible to make sorted
+ QCborMaps by carefully inserting elements in sorted order. CBOR does not
+ require sorting, but recommends it.
+
+ QCborMap can also be converted to and from QVariantMap and QJsonObject.
+ However, when performing the conversion, any non-string keys will be
+ stringified using a one-way method that the conversion back to QCborMap
+ will not undo.
+
+ \sa QCborArray, QCborValue, QJsonDocument, QVariantMap
+ */
+
+/*!
+ \typedef QCborMap::value_type
+
+ The value that is stored in this container: a pair of QCborValues
+ */
+
+/*!
+ \typedef QCborMap::key_type
+
+ The key type for this map. Since QCborMap keys can be any CBOR type, this
+ is a QCborValue.
+ */
+
+/*!
+ \typedef QCborMap::mapped_type
+
+ The type that is mapped to (the value), that is, a QCborValue.
+ */
+
+/*!
+ \typedef QCborMap::size_type
+
+ The type that QCborMap uses for sizes.
+ */
+
+/*!
+ \typedef QCborMap::iterator
+
+ A synonym for QCborMap::Iterator.
+ */
+
+/*!
+ \typedef QCborMap::const_iterator
+
+ A synonym for QCborMap::ConstIterator
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::begin()
+
+ Returns a map iterator pointing to the first key-value pair of this map. If
+ this map is empty, the returned iterator will be the same as end().
+
+ \sa constBegin(), end()
+ */
+
+/*!
+ \fn QCborMap::const_iterator QCborMap::constBegin() const
+
+ Returns a map iterator pointing to the first key-value pair of this map. If
+ this map is empty, the returned iterator will be the same as constEnd().
+
+ \sa begin(), constEnd()
+ */
+
+/*!
+ \fn QCborMap::const_iterator QCborMap::begin() const
+
+ Returns a map iterator pointing to the first key-value pair of this map. If
+ this map is empty, the returned iterator will be the same as constEnd().
+
+ \sa begin(), constEnd()
+ */
+
+/*!
+ \fn QCborMap::const_iterator QCborMap::cbegin() const
+
+ Returns a map iterator pointing to the first key-value pair of this map. If
+ this map is empty, the returned iterator will be the same as constEnd().
+
+ \sa begin(), constEnd()
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::end()
+
+ Returns a map iterator representing an element just past the last element
+ in the map.
+
+ \sa begin(), constBegin(), find(), constFind()
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::constEnd() const
+
+ Returns a map iterator representing an element just past the last element
+ in the map.
+
+ \sa begin(), constBegin(), find(), constFind()
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::end() const
+
+ Returns a map iterator representing an element just past the last element
+ in the map.
+
+ \sa begin(), constBegin(), find(), constFind()
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::cend() const
+
+ Returns a map iterator representing an element just past the last element
+ in the map.
+
+ \sa begin(), constBegin(), find(), constFind()
+ */
+
+/*!
+ Constructs an empty CBOR Map object.
+
+ \sa isEmpty()
+ */
+QCborMap::QCborMap() noexcept
+ : d(nullptr)
+{
+}
+
+/*!
+ Creates a QCborMap object that is a copy of \a other.
+ */
+QCborMap::QCborMap(const QCborMap &other) noexcept
+ : d(other.d)
+{
+}
+
+/*!
+ \fn QCborMap::QCborMap(std::initializer_list<value_type> args)
+
+ Constructs a QCborMap with items from a brace-initialization list found in
+ \a args, as in the following example:
+
+ \code
+ QCborMap map = {
+ {0, "Hello"},
+ {1, "World"},
+ {"foo", nullptr},
+ {"bar", QCborArray{0, 1, 2, 3, 4}}
+ };
+ \endcode
+ */
+
+/*!
+ Destroys this QCborMap object and frees any associated resources it owns.
+ */
+QCborMap::~QCborMap()
+{
+}
+
+/*!
+ Replaces the contents of this object with a copy of \a other, then returns
+ a reference to this object.
+ */
+QCborMap &QCborMap::operator=(const QCborMap &other) noexcept
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn void QCborMap::swap(QCborMap &other)
+
+ Swaps the contents of this map and \a other.
+ */
+
+/*!
+ \fn QCborValue QCborMap::toCborValue() const
+
+ Explicitly constructs a \l QCborValue object that represents this map.
+ This function is usually not necessary since QCborValue has a constructor
+ for QCborMap, so the conversion is implicit.
+
+ Converting QCborMap to QCborValue allows it to be used in any context where
+ QCborValues can be used, including as keys and mapped types in QCborMap, as
+ well as QCborValue::toCbor().
+
+ \sa QCborValue::QCborValue(const QCborMap &)
+ */
+
+/*!
+ \fn bool QCborMap::isEmpty() const
+
+ Returns true if this map is empty (that is, size() is 0).
+
+ \sa size(), clear()
+ */
+
+/*!
+ Returns the number of elements in this map.
+
+ \sa isEmpty()
+ */
+qsizetype QCborMap::size() const noexcept
+{
+ return d ? d->elements.size() / 2 : 0;
+}
+
+/*!
+ Empties this map.
+
+ \sa isEmpty()
+ */
+void QCborMap::clear()
+{
+ d.reset();
+}
+
+/*!
+ Returns a list of all keys in this map.
+
+ \sa QMap::keys(), QHash::keys()
+ */
+QVector<QCborValue> QCborMap::keys() const
+{
+ QVector<QCborValue> result;
+ if (d) {
+ result.reserve(size());
+ for (qsizetype i = 0; i < d->elements.size(); i += 2)
+ result << d->valueAt(i);
+ }
+ return result;
+}
+
+/*!
+ \fn QCborValue QCborMap::value(qint64 key) const
+
+ Returns the QCborValue element in this map that corresponds to key \a key,
+ if there is one. CBOR recommends using integer keys, since they occupy less
+ space and are simpler to encode and decode.
+
+ If the map does not contain key \a key, this function returns a QCborValue
+ containing an undefined value. For that reason, it is not possible with
+ this function to tell apart the situation where the key was not present
+ from the situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one the return from function will reference. QCborMap does not allow
+ inserting duplicate keys, but it is possible to create such a map by
+ decoding a CBOR stream with them. They are usually not permitted and having
+ duplicate keys is usually an indication of a problem in the sender.
+
+ \sa operator[](qint64), find(qint64), constFind(qint64), remove(qint64), contains(qint64)
+ value(QLatin1String), value(const QString &), value(const QCborValue &)
+ */
+
+/*!
+ \fn QCborValue QCborMap::operator[](qint64 key) const
+
+ Returns the QCborValue element in this map that corresponds to key \a key,
+ if there is one. CBOR recommends using integer keys, since they occupy less
+ space and are simpler to encode and decode.
+
+ If the map does not contain key \a key, this function returns a QCborValue
+ containing an undefined value. For that reason, it is not possible with
+ this function to tell apart the situation where the key was not present
+ from the situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will return. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(qint64), find(qint64), constFind(qint64), remove(qint64), contains(qint64)
+ operator[](QLatin1String), operator[](const QString &), operator[](const QCborOperator[] &)
+ */
+
+/*!
+ \fn QCborValue QCborMap::take(qint64 key)
+
+ Removes the key \a key and the corresponding value from the map and returns
+ the value, if it is found. If the map contains no such key, this function does nothing.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will remove. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(qint64), operator[](qint64), find(qint64), contains(qint64),
+ take(QLatin1String), take(const QString &), take(const QCborValue &), insert()
+ */
+
+/*!
+ \fn void QCborMap::remove(qint64 key)
+
+ Removes the key \a key and the corresponding value from the map, if it is
+ found. If the map contains no such key, this function does nothing.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will remove. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(qint64), operator[](qint64), find(qint64), contains(qint64)
+ remove(QLatin1String), remove(const QString &), remove(const QCborValue &)
+ */
+
+/*!
+ \fn bool QCborMap::contains(qint64 key) const
+
+ Returns true if this map contains a key-value pair identified by key \a
+ key. CBOR recommends using integer keys, since they occupy less space and
+ are simpler to encode and decode.
+
+ \sa value(qint64), operator[](qint64), find(qint64), remove(qint64),
+ contains(QLatin1String), remove(const QString &), remove(const QCborValue &)
+ */
+
+/*!
+ Returns a QCborValueRef to the value in this map that corresponds to key \a
+ key. CBOR recommends using integer keys, since they occupy less space and
+ are simpler to encode and decode.
+
+ QCborValueRef has the exact same API as \l QCborValue, with one important
+ difference: if you assign new values to it, this map will be updated with
+ that new value.
+
+ If the map did not have a key equal to \a key, one is inserted and this
+ function returns a reference to the new value, which will be a QCborValue
+ with an undefined value. For that reason, it is not possible with this
+ function to tell apart the situation where the key was not present from the
+ situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one the return will reference. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(qint64), find(qint64), contains(qint64), remove(qint64),
+ operator[](QLatin1String), operator[](const QString &), operator[](const QCborValue &)
+ */
+QCborValueRef QCborMap::operator[](qint64 key)
+{
+ auto it = find(key);
+ if (it == constEnd()) {
+ // insert element
+ detach(it.item.i + 2);
+ d->append(key);
+ d->append(Undefined{});
+ }
+ return { d.data(), it.item.i };
+}
+
+/*!
+ \fn QCborValue QCborMap::value(QLatin1String key) const
+ \overload
+
+ Returns the QCborValue element in this map that corresponds to key \a key,
+ if there is one.
+
+ If the map does not contain key \a key, this function returns a QCborValue
+ containing an undefined value. For that reason, it is not possible with
+ this function to tell apart the situation where the key was not present
+ from the situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will return. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa operator[](QLatin1String), find(QLatin1String), constFind(QLatin1String),
+ remove(QLatin1String), contains(QLatin1String)
+ value(qint64), value(const QString &), value(const QCborValue &)
+ */
+
+/*!
+ \fn QCborValue QCborMap::operator[](QLatin1String key) const
+ \overload
+
+ Returns the QCborValue element in this map that corresponds to key \a key,
+ if there is one.
+
+ If the map does not contain key \a key, this function returns a QCborValue
+ containing an undefined value. For that reason, it is not possible with
+ this function to tell apart the situation where the key was not present
+ from the situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will return. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(QLatin1String), find(QLatin1String), constFind(QLatin1String),
+ remove(QLatin1String), contains(QLatin1String)
+ operator[](qint64), operator[](const QString &), operator[](const QCborOperator[] &)
+ */
+
+/*!
+ \fn QCborValue QCborMap::take(QLatin1String key)
+
+ Removes the key \a key and the corresponding value from the map and returns
+ the value, if it is found. If the map contains no such key, this function does nothing.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will remove. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(QLatin1String), operator[](QLatin1String), find(QLatin1String), contains(QLatin1String),
+ take(qint64), take(const QString &), take(const QCborValue &), insert()
+ */
+
+/*!
+ \fn void QCborMap::remove(QLatin1String key)
+ \overload
+
+ Removes the key \a key and the corresponding value from the map, if it is
+ found. If the map contains no such key, this function does nothing.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will remove. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(QLatin1String), operator[](QLatin1String), find(QLatin1String), contains(QLatin1String)
+ remove(qint64), remove(const QString &), remove(const QCborValue &)
+ */
+
+/*!
+ \fn bool QCborMap::contains(QLatin1String key) const
+ \overload
+
+ Returns true if this map contains a key-value pair identified by key \a
+ key.
+
+ \sa value(QLatin1String), operator[](QLatin1String), find(QLatin1String), remove(QLatin1String),
+ contains(qint64), remove(const QString &), remove(const QCborValue &)
+ */
+
+/*!
+ \overload
+
+ Returns a QCborValueRef to the value in this map that corresponds to key \a
+ key.
+
+ QCborValueRef has the exact same API as \l QCborValue, with one important
+ difference: if you assign new values to it, this map will be updated with
+ that new value.
+
+ If the map did not have a key equal to \a key, one is inserted and this
+ function returns a reference to the new value, which will be a QCborValue
+ with an undefined value. For that reason, it is not possible with this
+ function to tell apart the situation where the key was not present from the
+ situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one the return will reference. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(QLatin1String), find(QLatin1String), contains(QLatin1String), remove(QLatin1String),
+ operator[](qint64), operator[](const QString &), operator[](const QCborValue &)
+ */
+QCborValueRef QCborMap::operator[](QLatin1String key)
+{
+ auto it = find(key);
+ if (it == constEnd()) {
+ // insert element
+ detach(it.item.i + 2);
+ d->append(key);
+ d->append(Undefined{});
+ }
+ return { d.data(), it.item.i };
+}
+
+/*!
+ \fn QCborValue QCborMap::value(const QString &key) const
+ \overload
+
+ Returns the QCborValue element in this map that corresponds to key \a key,
+ if there is one.
+
+ If the map does not contain key \a key, this function returns a QCborValue
+ containing an undefined value. For that reason, it is not possible with
+ this function to tell apart the situation where the key was not present
+ from the situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will return. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa operator[](const QString &), find(const QString &), constFind(const QString &),
+ remove(const QString &), contains(const QString &)
+ value(qint64), value(QLatin1String), value(const QCborValue &)
+ */
+
+/*!
+ \fn QCborValue QCborMap::operator[](const QString &key) const
+ \overload
+
+ Returns the QCborValue element in this map that corresponds to key \a key,
+ if there is one.
+
+ If the map does not contain key \a key, this function returns a QCborValue
+ containing an undefined value. For that reason, it is not possible with
+ this function to tell apart the situation where the key was not present
+ from the situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will return. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QString &), find(const QString &), constFind(const QString &),
+ remove(const QString &), contains(const QString &)
+ operator[](qint64), operator[](QLatin1String), operator[](const QCborOperator[] &)
+ */
+
+/*!
+ \fn QCborValue QCborMap::take(const QString &key)
+
+ Removes the key \a key and the corresponding value from the map and returns
+ the value, if it is found. If the map contains no such key, this function does nothing.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will remove. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QString &), operator[](const QString &), find(const QString &), contains(const QString &),
+ take(QLatin1String), take(qint64), take(const QCborValue &), insert()
+ */
+
+/*!
+ \fn void QCborMap::remove(const QString &key)
+ \overload
+
+ Removes the key \a key and the corresponding value from the map, if it is
+ found. If the map contains no such key, this function does nothing.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will remove. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QString &), operator[](const QString &), find(const QString &),
+ contains(const QString &)
+ remove(qint64), remove(QLatin1String), remove(const QCborValue &)
+ */
+
+/*!
+ \fn bool QCborMap::contains(const QString &key) const
+ \overload
+
+ Returns true if this map contains a key-value pair identified by key \a
+ key.
+
+ \sa value(const QString &), operator[](const QString &), find(const QString &),
+ remove(const QString &),
+ contains(qint64), remove(QLatin1String), remove(const QCborValue &)
+ */
+
+/*!
+ \overload
+
+ Returns a QCborValueRef to the value in this map that corresponds to key \a
+ key.
+
+ QCborValueRef has the exact same API as \l QCborValue, with one important
+ difference: if you assign new values to it, this map will be updated with
+ that new value.
+
+ If the map did not have a key equal to \a key, one is inserted and this
+ function returns a reference to the new value, which will be a QCborValue
+ with an undefined value. For that reason, it is not possible with this
+ function to tell apart the situation where the key was not present from the
+ situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one the return will reference. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QString &), find(const QString &), contains(const QString &), remove(const QString &),
+ operator[](qint64), operator[](QLatin1String), operator[](const QCborValue &)
+ */
+QCborValueRef QCborMap::operator[](const QString & key)
+{
+ auto it = find(key);
+ if (it == constEnd()) {
+ // insert element
+ detach(it.item.i + 2);
+ d->append(key);
+ d->append(Undefined{});
+ }
+ return { d.data(), it.item.i };
+}
+
+/*!
+ \fn QCborValue QCborMap::value(const QCborValue &key) const
+
+ Returns the QCborValue element in this map that corresponds to key \a key,
+ if there is one.
+
+ If the map does not contain key \a key, this function returns a QCborValue
+ containing an undefined value. For that reason, it is not possible with
+ this function to tell apart the situation where the key was not present
+ from the situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will return. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa operator[](const QCborValue &), find(const QCborValue &), constFind(const QCborValue &),
+ remove(const QCborValue &), contains(const QCborValue &)
+ value(qint64), value(QLatin1String), value(const QString &)
+ */
+
+/*!
+ \fn QCborValue QCborMap::operator[](const QCborValue &key) const
+
+ Returns the QCborValue element in this map that corresponds to key \a key,
+ if there is one.
+
+ If the map does not contain key \a key, this function returns a QCborValue
+ containing an undefined value. For that reason, it is not possible with
+ this function to tell apart the situation where the key was not present
+ from the situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will return. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QCborValue &), find(const QCborValue &), constFind(const QCborValue &),
+ remove(const QCborValue &), contains(const QCborValue &)
+ operator[](qint64), operator[](QLatin1String), operator[](const QCborOperator[] &)
+ */
+
+/*!
+ \fn QCborValue QCborMap::take(const QCborValue &key)
+
+ Removes the key \a key and the corresponding value from the map and returns
+ the value, if it is found. If the map contains no such key, this function does nothing.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will remove. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &), contains(const QCborValue &),
+ take(QLatin1String), take(const QString &), take(qint64), insert()
+ */
+
+/*!
+ \fn void QCborMap::remove(const QCborValue &key)
+
+ Removes the key \a key and the corresponding value from the map, if it is
+ found. If the map contains no such key, this function does nothing.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will remove. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &),
+ contains(const QCborValue &)
+ remove(qint64), remove(QLatin1String), remove(const QString &)
+ */
+
+/*!
+ \fn bool QCborMap::contains(const QCborValue &key) const
+
+ Returns true if this map contains a key-value pair identified by key \a
+ key.
+
+ \sa value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &),
+ remove(const QCborValue &),
+ contains(qint64), remove(QLatin1String), remove(const QString &)
+ */
+
+/*!
+ \overload
+
+ Returns a QCborValueRef to the value in this map that corresponds to key \a
+ key.
+
+ QCborValueRef has the exact same API as \l QCborValue, with one important
+ difference: if you assign new values to it, this map will be updated with
+ that new value.
+
+ If the map did not have a key equal to \a key, one is inserted and this
+ function returns a reference to the new value, which will be a QCborValue
+ with an undefined value. For that reason, it is not possible with this
+ function to tell apart the situation where the key was not present from the
+ situation where the key was mapped to an undefined value.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one the return will reference. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QCborValue &), find(const QCborValue &), contains(const QCborValue &), remove(const QCborValue &),
+ operator[](qint64), operator[](QLatin1String), operator[](const QString &)
+ */
+QCborValueRef QCborMap::operator[](const QCborValue &key)
+{
+ auto it = find(key);
+ if (it == constEnd()) {
+ // insert element
+ detach(it.item.i + 2);
+ d->append(key);
+ d->append(Undefined{});
+ }
+ return { d.data(), it.item.i };
+}
+
+/*!
+ \fn QCborMap::iterator QCborMap::find(qint64 key)
+ \fn QCborMap::const_iterator QCborMap::find(qint64 key) const
+
+ Returns a map iterator to the key-value pair whose key is \a key, if the
+ map contains such a pair. If it doesn't, this function returns end().
+
+ CBOR recommends using integer keys, since they occupy less
+ space and are simpler to encode and decode.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will find. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(qint64), operator[](qint64), constFind(qint64), remove(qint64), contains(qint64)
+ value(QLatin1String), value(const QString &), value(const QCborValue &)
+ */
+QCborMap::iterator QCborMap::find(qint64 key)
+{
+ auto it = constFind(key);
+ if (it != constEnd())
+ detach();
+ return { d.data(), it.item.i };
+}
+
+/*!
+ \fn QCborMap::iterator QCborMap::find(QLatin1String key)
+ \fn QCborMap::const_iterator QCborMap::find(QLatin1String key) const
+ \overload
+
+ Returns a map iterator to the key-value pair whose key is \a key, if the
+ map contains such a pair. If it doesn't, this function returns end().
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will find. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(QLatin1String), operator[](QLatin1String), constFind(QLatin1String),
+ remove(QLatin1String), contains(QLatin1String)
+ value(qint64), value(const QString &), value(const QCborValue &)
+ */
+QCborMap::iterator QCborMap::find(QLatin1String key)
+{
+ auto it = constFind(key);
+ if (it != constEnd())
+ detach();
+ return { d.data(), it.item.i };
+}
+
+/*!
+ \fn QCborMap::iterator QCborMap::find(const QString & key)
+ \fn QCborMap::const_iterator QCborMap::find(const QString & key) const
+ \overload
+
+ Returns a map iterator to the key-value pair whose key is \a key, if the
+ map contains such a pair. If it doesn't, this function returns end().
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will find. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QString &), operator[](const QString &), constFind(const QString &),
+ remove(const QString &), contains(const QString &)
+ value(qint64), value(QLatin1String), value(const QCborValue &)
+ */
+QCborMap::iterator QCborMap::find(const QString & key)
+{
+ auto it = constFind(key);
+ if (it != constEnd())
+ detach();
+ return { d.data(), it.item.i };
+}
+
+/*!
+ \fn QCborMap::iterator QCborMap::find(const QCborValue &key)
+ \fn QCborMap::const_iterator QCborMap::find(const QCborValue &key) const
+ \overload
+
+ Returns a map iterator to the key-value pair whose key is \a key, if the
+ map contains such a pair. If it doesn't, this function returns end().
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will find. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QCborValue &), operator[](const QCborValue &), constFind(const QCborValue &),
+ remove(const QCborValue &), contains(const QCborValue &)
+ value(qint64), value(QLatin1String), value(const QString &)
+ */
+QCborMap::iterator QCborMap::find(const QCborValue &key)
+{
+ auto it = constFind(key);
+ if (it != constEnd())
+ detach();
+ return { d.data(), it.item.i };
+}
+
+/*!
+ Returns a map iterator to the key-value pair whose key is \a key, if the
+ map contains such a pair. If it doesn't, this function returns constEnd().
+
+ CBOR recommends using integer keys, since they occupy less
+ space and are simpler to encode and decode.
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will find. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(qint64), operator[](qint64), find(qint64), remove(qint64), contains(qint64)
+ value(QLatin1String), value(const QString &), value(const QCborValue &)
+ */
+QCborMap::const_iterator QCborMap::constFind(qint64 key) const
+{
+ for (qsizetype i = 0; i < 2 * size(); i += 2) {
+ const auto &e = d->elements.at(i);
+ if (e.type == QCborValue::Integer && e.value == key)
+ return { d.data(), i + 1 };
+ }
+ return constEnd();
+}
+
+/*!
+ \overload
+
+ Returns a map iterator to the key-value pair whose key is \a key, if the
+ map contains such a pair. If it doesn't, this function returns constEnd().
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will find. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(QLatin1String), operator[](QLatin1String), find(QLatin1String),
+ remove(QLatin1String), contains(QLatin1String)
+ value(qint64), value(const QString &), value(const QCborValue &)
+ */
+QCborMap::const_iterator QCborMap::constFind(QLatin1String key) const
+{
+ for (qsizetype i = 0; i < 2 * size(); i += 2) {
+ if (d->stringEqualsElement(i, key))
+ return { d.data(), i + 1 };
+ }
+ return constEnd();
+}
+
+/*!
+ \overload
+
+ Returns a map iterator to the key-value pair whose key is \a key, if the
+ map contains such a pair. If it doesn't, this function returns constEnd().
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will find. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QString &), operator[](const QString &), find(const QString &),
+ remove(const QString &), contains(const QString &)
+ value(qint64), value(QLatin1String), value(const QCborValue &)
+ */
+QCborMap::const_iterator QCborMap::constFind(const QString & key) const
+{
+ for (qsizetype i = 0; i < 2 * size(); i += 2) {
+ if (d->stringEqualsElement(i, key))
+ return { d.data(), i + 1 };
+ }
+ return constEnd();
+}
+
+/*!
+ \overload
+
+ Returns a map iterator to the key-value pair whose key is \a key, if the
+ map contains such a pair. If it doesn't, this function returns constEnd().
+
+ If the map contains more than one key equal to \a key, it is undefined
+ which one this function will find. QCborMap does not allow inserting
+ duplicate keys, but it is possible to create such a map by decoding a CBOR
+ stream with them. They are usually not permitted and having duplicate keys
+ is usually an indication of a problem in the sender.
+
+ \sa value(const QCborValue &), operator[](const QCborValue &), find(const QCborValue &),
+ remove(const QCborValue &), contains(const QCborValue &),
+ value(qint64), value(QLatin1String), value(const QString &)
+ */
+QCborMap::const_iterator QCborMap::constFind(const QCborValue &key) const
+{
+ for (qsizetype i = 0; i < 2 * size(); i += 2) {
+ int cmp = d->compareElement(i, key);
+ if (cmp == 0)
+ return { d.data(), i + 1 };
+ }
+ return constEnd();
+}
+
+/*!
+ \fn QCborMap::iterator QCborMap::insert(qint64 key, const QCborValue &value)
+ \overload
+
+ Inserts the key \a key and value \a value into this map and returns a map
+ iterator pointing to the newly inserted pair.
+
+ If the map already had a key equal to \a key, its value will be overwritten
+ by \a value.
+
+ \sa erase(), remove(qint64), value(qint64), operator[](qint64), find(qint64),
+ contains(qint64), take(qint64), extract()
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::insert(QLatin1String key, const QCborValue &value)
+ \overload
+
+ Inserts the key \a key and value \a value into this map and returns a map
+ iterator pointing to the newly inserted pair.
+
+ If the map already had a key equal to \a key, its value will be overwritten
+ by \a value.
+
+ \sa erase(), remove(QLatin1String), value(QLatin1String), operator[](QLatin1String),
+ find(QLatin1String), contains(QLatin1String), take(QLatin1String), extract()
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::insert(const QString &key, const QCborValue &value)
+ \overload
+
+ Inserts the key \a key and value \a value into this map and returns a map
+ iterator pointing to the newly inserted pair.
+
+ If the map already had a key equal to \a key, its value will be overwritten
+ by \a value.
+
+ \sa erase(), remove(const QString &), value(const QString &), operator[](const QString &),
+ find(const QString &), contains(const QString &), take(const QString &), extract()
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::insert(const QCborValue &key, const QCborValue &value)
+ \overload
+
+ Inserts the key \a key and value \a value into this map and returns a map
+ iterator pointing to the newly inserted pair.
+
+ If the map already had a key equal to \a key, its value will be overwritten
+ by \a value.
+
+ \sa erase(), remove(const QCborValue &), value(const QCborValue &), operator[](const QCborValue &),
+ find(const QCborValue &), contains(const QCborValue &), take(const QCborValue &), extract()
+ */
+
+/*!
+ \fn QCborMap::iterator QCborMap::insert(value_type v)
+ \overload
+
+ Inserts the key-value pair in \a v into this map and returns a map iterator
+ pointing to the newly inserted pair.
+
+ If the map already had a key equal to \c{v.first}, its value will be
+ overwritten by \c{v.second}.
+
+ \sa operator[], erase(), extract()
+ */
+
+
+/*!
+ \fn QCborMap::iterator QCborMap::erase(const_iterator it)
+
+ Removes the key-value pair pointed to by the map iterator \a it and returns a
+ pointer to the next element, after removal.
+
+ \sa remove(), begin(), end(), insert(), extract()
+ */
+
+/*!
+ \overload
+
+ Removes the key-value pair pointed to by the map iterator \a it and returns a
+ pointer to the next element, after removal.
+
+ \sa remove(), begin(), end(), insert()
+ */
+QCborMap::iterator QCborMap::erase(QCborMap::iterator it)
+{
+ detach();
+
+ // remove both key and value
+ // ### optimize?
+ d->removeAt(it.item.i - 1);
+ d->removeAt(it.item.i - 1);
+ return it;
+}
+
+/*!
+ \fn QCborValue QCborMap::extract(iterator it)
+ \fn QCborValue QCborMap::extract(const_iterator it)
+
+ Extracts a value from the map at the position indicated by iterator \a it
+ and returns the value so extracted.
+
+ \sa insert(), erase(), take(), remove()
+ */
+QCborValue QCborMap::extract(iterator it)
+{
+ detach();
+ QCborValue v = d->extractAt(it.item.i);
+ // remove both key and value
+ // ### optimize?
+ d->removeAt(it.item.i - 1);
+ d->removeAt(it.item.i - 1);
+
+ return v;
+}
+
+/*!
+ \fn bool QCborMap::empty() const
+
+ Synonym for isEmpty(). This function is provided for compatibility with
+ generic code that uses the Standard Library API.
+
+ Returns true if this map is empty (size() == 0).
+
+ \sa isEmpty(), size()
+ */
+
+/*!
+ \fn int QCborMap::compare(const QCborMap &other) const
+
+ Compares this map and \a other, comparing each element in sequence, and
+ returns an integer that indicates whether this map should be sorted prior
+ to (if the result is negative) or after \a other (if the result is
+ positive). If this function returns 0, the two maps are equal and contain
+ the same elements.
+
+ Note that CBOR maps are unordered, which means that two maps containing the
+ very same pairs but in different order will still compare differently. To
+ avoid this, it is recommended to insert elements into the map in a
+ predictable order, such as by ascending key value. In fact, maps with keys
+ in sorted order are required for Canonical CBOR representation.
+
+ For more information on CBOR sorting order, see QCborValue::compare().
+
+ \sa QCborValue::compare(), QCborArray::compare(), operator==()
+ */
+
+/*!
+ \fn bool QCborMap::operator==(const QCborMap &other) const
+
+ Compares this map and \a other, comparing each element in sequence, and
+ returns true if the two maps contains the same elements in the same order,
+ false otherwise.
+
+ Note that CBOR maps are unordered, which means that two maps containing the
+ very same pairs but in different order will still compare differently. To
+ avoid this, it is recommended to insert elements into the map in a
+ predictable order, such as by ascending key value. In fact, maps with keys
+ in sorted order are required for Canonical CBOR representation.
+
+ For more information on CBOR equality in Qt, see, QCborValue::compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator!=(), operator<()
+ */
+
+/*!
+ \fn bool QCborMap::operator!=(const QCborMap &other) const
+
+ Compares this map and \a other, comparing each element in sequence, and
+ returns true if the two maps contains any different elements or elements in
+ different orders, false otherwise.
+
+ Note that CBOR maps are unordered, which means that two maps containing the
+ very same pairs but in different order will still compare differently. To
+ avoid this, it is recommended to insert elements into the map in a
+ predictable order, such as by ascending key value. In fact, maps with keys
+ in sorted order are required for Canonical CBOR representation.
+
+ For more information on CBOR equality in Qt, see, QCborValue::compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator==(), operator<()
+ */
+
+/*!
+ \fn bool QCborMap::operator<(const QCborMap &other) const
+
+ Compares this map and \a other, comparing each element in sequence, and
+ returns true if this map should be sorted before \a other, false
+ otherwise.
+
+ Note that CBOR maps are unordered, which means that two maps containing the
+ very same pairs but in different order will still compare differently. To
+ avoid this, it is recommended to insert elements into the map in a
+ predictable order, such as by ascending key value. In fact, maps with keys
+ in sorted order are required for Canonical CBOR representation.
+
+ For more information on CBOR sorting order, see QCborValue::compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator==(), operator!=()
+ */
+
+void QCborMap::detach(qsizetype reserved)
+{
+ d = QCborContainerPrivate::detach(d.data(), reserved ? reserved : size() * 2);
+}
+
+/*!
+ \class QCborMap::Iterator
+ \inmodule QtCore
+ \ingroup cbor
+ \reentrant
+ \since 5.12
+
+ \brief The QCborMap::Iterator class provides an STL-style non-const iterator for QCborMap.
+
+ QCborMap::Iterator allows you to iterate over a QCborMap and to modify the
+ value (but not the key) stored under a particular key. If you want to
+ iterate over a const QCborMap, you should use QCborMap::ConstIterator. It
+ is generally good practice to use QCborMap::ConstIterator on a non-const
+ QCborMap as well, unless you need to change the QCborMap through the
+ iterator. Const iterators are slightly faster, and improve code
+ readability.
+
+ You must initialize the iterator using a QCborMap function like
+ QCborMap::begin(), QCborMap::end(), or QCborMap::find() before you can
+ start iterating..
+
+ Multiple iterators can be used on the same object. Existing iterators will however
+ become dangling once the object gets modified.
+
+ \sa QCborMap::ConstIterator
+*/
+
+/*!
+ \typedef QCborMap::Iterator::difference_type
+ \internal
+*/
+
+/*!
+ \typedef QCborMap::Iterator::iterator_category
+
+ A synonym for \e {std::random_access_iterator_tag} indicating
+ this iterator is a random-access iterator.
+*/
+
+/*!
+ \typedef QCborMap::Iterator::reference
+ \internal
+*/
+
+/*!
+ \typedef QCborMap::Iterator::value_type
+ \internal
+*/
+
+/*!
+ \typedef QCborMap::Iterator::pointer
+ \internal
+*/
+
+/*!
+ \fn QCborMap::Iterator::Iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like key(), value(), and operator++() must not be
+ called on an uninitialized iterator. Use operator=() to assign a
+ value to it before using it.
+
+ \sa QCborMap::begin(), QCborMap::end()
+*/
+
+/*!
+ \fn QCborMap::Iterator::Iterator(const Iterator &other)
+
+ Constructs an iterator as a copy of \a other.
+ */
+
+/*!
+ \fn QCborMap::Iterator &QCborMap::Iterator::operator=(const Iterator &other)
+
+ Makes this iterator a copy of \a other and returns a reference to this
+ iterator.
+ */
+
+/*!
+ \fn QCborValue QCborMap::Iterator::key() const
+
+ Returns the current item's key.
+
+ There is no direct way of changing an item's key through an iterator,
+ although it can be done by calling QCborMap::erase() followed by
+ QCborMap::insert().
+
+ \sa value()
+*/
+
+/*!
+ \fn QCborValueRef QCborMap::Iterator::value() const
+
+ Returns a modifiable reference to the current item's value.
+
+ You can change the value for a key by using value() on the left side of an
+ assignment.
+
+ The return value is of type QCborValueRef, a helper class for QCborArray
+ and QCborMap. When you get an object of type QCborValueRef, you can use it
+ as if it were a reference to a QCborValue. If you assign to it, the
+ assignment will apply to the element in the QCborArray or QCborMap from
+ which you got the reference.
+
+ \sa key(), operator*()
+*/
+
+/*!
+ \fn QCborMap::Iterator::value_type QCborMap::Iterator::operator*() const
+
+ Returns a pair containing the current item's key and a modifiable reference
+ to the current item's value.
+
+ The second element of the pair is of type QCborValueRef, a helper class for
+ QCborArray and QCborMap. When you get an object of type QCborValueRef, you
+ can use it as if it were a reference to a QCborValue. If you assign to it,
+ the assignment will apply to the element in the QCborArray or QCborMap from
+ which you got the reference.
+
+ \sa key(), value()
+*/
+
+/*!
+ \fn QCborValueRef *QCborMap::Iterator::operator->() const
+
+ Returns a pointer to a modifiable reference to the current pair's value.
+*/
+
+/*!
+ \fn bool QCborMap::Iterator::operator==(const Iterator &other) const
+ \fn bool QCborMap::Iterator::operator==(const ConstIterator &other) const
+
+ Returns \c true if \a other points to the same entry in the map as this
+ iterator; otherwise returns \c false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QCborMap::Iterator::operator!=(const Iterator &other) const
+ \fn bool QCborMap::Iterator::operator!=(const ConstIterator &other) const
+
+ Returns \c true if \a other points to a different entry in the map than
+ this iterator; otherwise returns \c false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QCborMap::Iterator::operator<(const Iterator& other) const
+ \fn bool QCborMap::Iterator::operator<(const ConstIterator& other) const
+
+ Returns \c true if the entry in the map pointed to by this iterator
+ occurs before the entry pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QCborMap::Iterator::operator<=(const Iterator& other) const
+ \fn bool QCborMap::Iterator::operator<=(const ConstIterator& other) const
+
+ Returns \c true if the entry in the map pointed to by this iterator
+ occurs before or is the same entry as is pointed to by the \a other
+ iterator.
+*/
+
+/*!
+ \fn bool QCborMap::Iterator::operator>(const Iterator& other) const
+ \fn bool QCborMap::Iterator::operator>(const ConstIterator& other) const
+
+ Returns \c true if the entry in the map pointed to by this iterator
+ occurs after the entry pointed to by the \a other iterator.
+ */
+
+/*!
+ \fn bool QCborMap::Iterator::operator>=(const Iterator& other) const
+ \fn bool QCborMap::Iterator::operator>=(const ConstIterator& other) const
+
+ Returns \c true if the entry in the map pointed to by this iterator
+ occurs after or is the same entry as is pointed to by the \a other
+ iterator.
+*/
+
+/*!
+ \fn QCborMap::Iterator &QCborMap::Iterator::operator++()
+
+ The prefix ++ operator, \c{++i}, advances the iterator to the next item in
+ the map and returns this iterator.
+
+ Calling this function on QCborMap::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*!
+ \fn QCborMap::Iterator QCborMap::Iterator::operator++(int)
+ \overload
+
+ The postfix ++ operator, \c{i++}, advances the iterator to the next item in
+ the map and returns an iterator to the previously current item.
+*/
+
+/*!
+ \fn QCborMap::Iterator QCborMap::Iterator::operator--()
+
+ The prefix -- operator, \c{--i}, makes the preceding item current and
+ returns this iterator.
+
+ Calling this function on QCborMap::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*!
+ \fn QCborMap::Iterator QCborMap::Iterator::operator--(int)
+ \overload
+
+ The postfix -- operator, \c{i--}, makes the preceding item current and
+ returns an iterator pointing to the previously current item.
+*/
+
+/*!
+ \fn QCborMap::Iterator QCborMap::Iterator::operator+(qsizetype j) const
+
+ Returns an iterator to the item at \a j positions forward from this
+ iterator. If \a j is negative, the iterator goes backward.
+
+ \sa operator-()
+*/
+
+/*!
+ \fn QCborMap::Iterator QCborMap::Iterator::operator-(qsizetype j) const
+
+ Returns an iterator to the item at \a j positions backward from this
+ iterator. If \a j is negative, the iterator goes forward.
+
+ \sa operator+()
+*/
+
+/*!
+ \fn qsizetype QCborMap::Iterator::operator-(QCborMap::Iterator j) const
+
+ Returns the position of the item at iterator \a j relative to the item
+ at this iterator. If the item at \a j is forward of this time, the returned
+ value is negative.
+
+ \sa operator+()
+*/
+
+/*!
+ \fn QCborMap::Iterator &QCborMap::Iterator::operator+=(qsizetype j)
+
+ Advances the iterator by \a j items. If \a j is negative, the iterator goes
+ backward. Returns a reference to this iterator.
+
+ \sa operator-=(), operator+()
+*/
+
+/*!
+ \fn QCborMap::Iterator &QCborMap::Iterator::operator-=(qsizetype j)
+
+ Makes the iterator go back by \a j items. If \a j is negative, the iterator
+ goes forward. Returns a reference to this iterator.
+
+ \sa operator+=(), operator-()
+*/
+
+/*!
+ \class QCborMap::ConstIterator
+ \inmodule QtCore
+ \ingroup cbor
+ \since 5.12
+
+ \brief The QCborMap::ConstIterator class provides an STL-style const iterator for QCborMap.
+
+ QCborMap::ConstIterator allows you to iterate over a QCborMap. If you want
+ to modify the QCborMap as you iterate over it, you must use
+ QCborMap::Iterator instead. It is generally good practice to use
+ QCborMap::ConstIterator, even on a non-const QCborMap, when you don't need
+ to change the QCborMap through the iterator. Const iterators are slightly
+ faster and improve code readability.
+
+ You must initialize the iterator using a QCborMap function like
+ QCborMap::begin(), QCborMap::end(), or QCborMap::find() before you can
+ start iterating..
+
+ Multiple iterators can be used on the same object. Existing iterators
+ will however become dangling if the object gets modified.
+
+ \sa QCborMap::Iterator
+*/
+
+/*!
+ \typedef QCborMap::ConstIterator::difference_type
+ \internal
+*/
+
+/*!
+ \typedef QCborMap::ConstIterator::iterator_category
+
+ A synonym for \e {std::random_access_iterator_tag} indicating
+ this iterator is a random-access iterator.
+*/
+
+/*!
+ \typedef QCborMap::ConstIterator::reference
+ \internal
+*/
+
+/*!
+ \typedef QCborMap::ConstIterator::value_type
+ \internal
+*/
+
+/*!
+ \typedef QCborMap::ConstIterator::pointer
+ \internal
+*/
+
+/*!
+ \fn QCborMap::ConstIterator::ConstIterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like key(), value(), and operator++() must not be
+ called on an uninitialized iterator. Use operator=() to assign a
+ value to it before using it.
+
+ \sa QCborMap::constBegin(), QCborMap::constEnd()
+*/
+
+/*!
+ \fn QCborMap::ConstIterator::ConstIterator(const ConstIterator &other)
+
+ Constructs an iterator as a copy of \a other.
+ */
+
+/*!
+ \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator=(const ConstIterator &other)
+
+ Makes this iterator a copy of \a other and returns a reference to this
+ iterator.
+ */
+
+/*!
+ \fn QString QCborMap::ConstIterator::key() const
+
+ Returns the current item's key.
+
+ \sa value()
+*/
+
+/*!
+ \fn QCborValue QCborMap::ConstIterator::value() const
+
+ Returns the current item's value.
+
+ \sa key(), operator*()
+*/
+
+/*!
+ \fn QCborMap::ConstIterator::value_type QCborMap::ConstIterator::operator*() const
+
+ Returns a pair containing the curent item's key and value.
+
+ \sa key(), value()
+ */
+
+/*!
+ \fn const QCborValueRef *QCborMap::ConstIterator::operator->() const
+
+ Returns a pointer to the current pair's value.
+ */
+
+/*!
+ \fn bool QCborMap::ConstIterator::operator==(const ConstIterator &other) const
+ \fn bool QCborMap::ConstIterator::operator==(const Iterator &other) const
+
+ Returns \c true if \a other points to the same entry in the map as this
+ iterator; otherwise returns \c false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QCborMap::ConstIterator::operator!=(const ConstIterator &other) const
+ \fn bool QCborMap::ConstIterator::operator!=(const Iterator &other) const
+
+ Returns \c true if \a other points to a different entry in the map than
+ this iterator; otherwise returns \c false.
+
+ \sa operator==()
+ */
+
+/*!
+ \fn bool QCborMap::ConstIterator::operator<(const Iterator &other) const
+ \fn bool QCborMap::ConstIterator::operator<(const ConstIterator &other) const
+
+ Returns \c true if the entry in the map pointed to by this iterator
+ occurs before the entry pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QCborMap::ConstIterator::operator<=(const Iterator &other) const
+ \fn bool QCborMap::ConstIterator::operator<=(const ConstIterator &other) const
+
+ Returns \c true if the entry in the map pointed to by this iterator
+ occurs before or is the same entry as is pointed to by the \a other
+ iterator.
+*/
+
+/*!
+ \fn bool QCborMap::ConstIterator::operator>(const Iterator &other) const
+ \fn bool QCborMap::ConstIterator::operator>(const ConstIterator &other) const
+
+ Returns \c true if the entry in the map pointed to by this iterator
+ occurs after the entry pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QCborMap::ConstIterator::operator>=(const Iterator &other) const
+ \fn bool QCborMap::ConstIterator::operator>=(const ConstIterator &other) const
+
+ Returns \c true if the entry in the map pointed to by this iterator
+ occurs after or is the same entry as is pointed to by the \a other
+ iterator.
+*/
+
+/*!
+ \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator++()
+
+ The prefix ++ operator, \c{++i}, advances the iterator to the next item in
+ the map and returns this iterator.
+
+ Calling this function on QCborMap::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*!
+ \fn QCborMap::ConstIterator QCborMap::ConstIterator::operator++(int)
+ \overload
+
+ The postfix ++ operator, \c{i++}, advances the iterator to the next item in
+ the map and returns an iterator to the previously current item.
+ */
+
+/*!
+ \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator--()
+
+ The prefix -- operator, \c{--i}, makes the preceding item current and
+ returns this iterator.
+
+ Calling this function on QCborMap::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*!
+ \fn QCborMap::ConstIterator QCborMap::ConstIterator::operator--(int)
+ \overload
+
+ The postfix -- operator, \c{i--}, makes the preceding item current and
+ returns an iterator pointing to the previously current item.
+ */
+
+/*!
+ \fn QCborMap::ConstIterator QCborMap::ConstIterator::operator+(qsizetype j) const
+
+ Returns an iterator to the item at \a j positions forward from this
+ iterator. If \a j is negative, the iterator goes backward.
+
+ \sa operator-()
+*/
+
+/*!
+ \fn QCborMap::ConstIterator QCborMap::ConstIterator::operator-(qsizetype j) const
+
+ Returns an iterator to the item at \a j positions backward from this
+ iterator. If \a j is negative, the iterator goes forward.
+
+ \sa operator+()
+*/
+
+/*!
+ \fn qsizetype QCborMap::ConstIterator::operator-(QCborMap::ConstIterator j) const
+
+ Returns the position of the item at iterator \a j relative to the item
+ at this iterator. If the item at \a j is forward of this time, the returned
+ value is negative.
+
+ \sa operator+()
+*/
+
+/*!
+ \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator+=(qsizetype j)
+
+ Advances the iterator by \a j items. If \a j is negative, the iterator goes
+ backward. Returns a reference to this iterator.
+
+ \sa operator-=(), operator+()
+*/
+
+/*!
+ \fn QCborMap::ConstIterator &QCborMap::ConstIterator::operator-=(qsizetype j)
+
+ Makes the iterator go back by \a j items. If \a j is negative, the iterator
+ goes forward. Returns a reference to this iterator.
+
+ \sa operator+=(), operator-()
+*/
+
+uint qHash(const QCborMap &map, uint seed)
+{
+ return qHashRange(map.begin(), map.end(), seed);
+}
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug dbg, const QCborMap &m)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "QCborMap{";
+ const char *open = "{";
+ for (auto pair : m) {
+ dbg << open << pair.first << ", " << pair.second << '}';
+ open = ", {";
+ }
+ return dbg << '}';
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h
new file mode 100644
index 0000000000..45ef430e40
--- /dev/null
+++ b/src/corelib/serialization/qcbormap.h
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCBORMAP_H
+#define QCBORMAP_H
+
+#include <QtCore/qcborvalue.h>
+#include <QtCore/qpair.h>
+
+#include <initializer_list>
+
+QT_BEGIN_NAMESPACE
+
+template <class Key, class T> class QMap;
+typedef QMap<QString, QVariant> QVariantMap;
+template <class Key, class T> class QHash;
+typedef QHash<QString, QVariant> QVariantHash;
+class QJsonObject;
+
+class QCborContainerPrivate;
+class Q_CORE_EXPORT QCborMap
+{
+public:
+ typedef QPair<QCborValue, QCborValue> value_type;
+ typedef QCborValue key_type;
+ typedef QCborValue mapped_type;
+ typedef qsizetype size_type;
+
+ class ConstIterator;
+ class Iterator {
+ mutable QCborValueRef item; // points to the value
+ friend class ConstIterator;
+ friend class QCborMap;
+ Iterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef qsizetype difference_type;
+ typedef QPair<const QCborValueRef, QCborValueRef> value_type;
+ typedef QPair<const QCborValueRef, QCborValueRef> reference;
+ typedef QPair<const QCborValueRef, QCborValueRef> pointer;
+
+ Q_DECL_CONSTEXPR Iterator() = default;
+ Q_DECL_CONSTEXPR Iterator(const Iterator &) = default;
+ Iterator &operator=(const Iterator &other)
+ {
+ // rebind the reference
+ item.d = other.item.d;
+ item.i = other.item.i;
+ return *this;
+ }
+
+ value_type operator*() const { return { {item.d, item.i - 1}, item }; }
+ QCborValueRef *operator->() const { return &item; }
+ QCborValue key() const { return QCborValueRef(item.d, item.i - 1); }
+ QCborValueRef value() const { return item; }
+
+ bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
+ bool operator!=(const Iterator &o) const { return !(*this == o); }
+ bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
+ bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
+ bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
+ bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
+ bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
+ bool operator!=(const ConstIterator &o) const { return !(*this == o); }
+ bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
+ bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
+ bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
+ bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
+ Iterator &operator++() { item.i += 2; return *this; }
+ Iterator operator++(int) { Iterator n = *this; item.i += 2; return n; }
+ Iterator &operator--() { item.i -= 2; return *this; }
+ Iterator operator--(int) { Iterator n = *this; item.i -= 2; return n; }
+ Iterator &operator+=(qsizetype j) { item.i += 2 * j; return *this; }
+ Iterator &operator-=(qsizetype j) { item.i -= 2 * j; return *this; }
+ Iterator operator+(qsizetype j) const { return Iterator({ item.d, item.i + 2 * j }); }
+ Iterator operator-(qsizetype j) const { return Iterator({ item.d, item.i - 2 * j }); }
+ qsizetype operator-(Iterator j) const { return (item.i - j.item.i) / 2; }
+ };
+
+ class ConstIterator {
+ QCborValueRef item; // points to the value
+ friend class Iterator;
+ friend class QCborMap;
+ ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {}
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef qsizetype difference_type;
+ typedef QPair<const QCborValueRef, const QCborValueRef> value_type;
+ typedef QPair<const QCborValueRef, const QCborValueRef> reference;
+ typedef QPair<const QCborValueRef, const QCborValueRef> pointer;
+
+ Q_DECL_CONSTEXPR ConstIterator() = default;
+ Q_DECL_CONSTEXPR ConstIterator(const ConstIterator &) = default;
+ ConstIterator &operator=(const ConstIterator &other)
+ {
+ // rebind the reference
+ item.d = other.item.d;
+ item.i = other.item.i;
+ return *this;
+ }
+
+ value_type operator*() const { return { {item.d, item.i - 1}, item }; }
+ const QCborValueRef *operator->() const { return &item; }
+ QCborValue key() const { return QCborValueRef(item.d, item.i - 1); }
+ QCborValueRef value() const { return item; }
+
+ bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
+ bool operator!=(const Iterator &o) const { return !(*this == o); }
+ bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
+ bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
+ bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
+ bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
+ bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; }
+ bool operator!=(const ConstIterator &o) const { return !(*this == o); }
+ bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; }
+ bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; }
+ bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; }
+ bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; }
+ ConstIterator &operator++() { item.i += 2; return *this; }
+ ConstIterator operator++(int) { ConstIterator n = *this; item.i += 2; return n; }
+ ConstIterator &operator--() { item.i -= 2; return *this; }
+ ConstIterator operator--(int) { ConstIterator n = *this; item.i -= 2; return n; }
+ ConstIterator &operator+=(qsizetype j) { item.i += 2 * j; return *this; }
+ ConstIterator &operator-=(qsizetype j) { item.i -= 2 * j; return *this; }
+ ConstIterator operator+(qsizetype j) const { return ConstIterator({ item.d, item.i + 2 * j }); }
+ ConstIterator operator-(qsizetype j) const { return ConstIterator({ item.d, item.i - 2 * j }); }
+ qsizetype operator-(ConstIterator j) const { return (item.i - j.item.i) / 2; }
+ };
+
+ QCborMap() noexcept;
+ QCborMap(const QCborMap &other) noexcept;
+ QCborMap &operator=(const QCborMap &other) noexcept;
+ QCborMap(std::initializer_list<value_type> args)
+ : QCborMap()
+ {
+ detach(args.size());
+ for (auto pair : args)
+ insert(pair.first, pair.second);
+ }
+ ~QCborMap();
+
+ void swap(QCborMap &other) noexcept
+ {
+ qSwap(d, other.d);
+ }
+
+ QCborValue toCborValue() const { return *this; }
+
+ qsizetype size() const noexcept Q_DECL_PURE_FUNCTION;
+ bool isEmpty() const { return size() == 0; }
+ void clear();
+ QVector<QCborValue> keys() const;
+
+ QCborValue value(qint64 key) const
+ { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
+ QCborValue value(QLatin1String key) const
+ { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
+ QCborValue value(const QString & key) const
+ { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
+ QCborValue value(const QCborValue &key) const
+ { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
+ QCborValue operator[](qint64 key) const
+ { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
+ QCborValue operator[](QLatin1String key) const
+ { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
+ QCborValue operator[](const QString & key) const
+ { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
+ QCborValue operator[](const QCborValue &key) const
+ { const_iterator it = find(key); return it == end() ? QCborValue() : it.value(); }
+ QCborValueRef operator[](qint64 key);
+ QCborValueRef operator[](QLatin1String key);
+ QCborValueRef operator[](const QString & key);
+ QCborValueRef operator[](const QCborValue &key);
+
+ QCborValue take(qint64 key)
+ { const_iterator it = constFind(key); if (it != constEnd()) return extract(it); return QCborValue(); }
+ QCborValue take(QLatin1String key)
+ { const_iterator it = constFind(key); if (it != constEnd()) return extract(it); return QCborValue(); }
+ QCborValue take(const QString &key)
+ { const_iterator it = constFind(key); if (it != constEnd()) return extract(it); return QCborValue(); }
+ QCborValue take(const QCborValue &key)
+ { const_iterator it = constFind(key); if (it != constEnd()) return extract(it); return QCborValue(); }
+ void remove(qint64 key)
+ { const_iterator it = constFind(key); if (it != constEnd()) erase(it); }
+ void remove(QLatin1String key)
+ { const_iterator it = constFind(key); if (it != constEnd()) erase(it); }
+ void remove(const QString & key)
+ { const_iterator it = constFind(key); if (it != constEnd()) erase(it); }
+ void remove(const QCborValue &key)
+ { const_iterator it = constFind(key); if (it != constEnd()) erase(it); }
+ bool contains(qint64 key) const
+ { const_iterator it = find(key); return it != end(); }
+ bool contains(QLatin1String key) const
+ { const_iterator it = find(key); return it != end(); }
+ bool contains(const QString & key) const
+ { const_iterator it = find(key); return it != end(); }
+ bool contains(const QCborValue &key) const
+ { const_iterator it = find(key); return it != end(); }
+
+ int compare(const QCborMap &other) const noexcept Q_DECL_PURE_FUNCTION;
+#if 0 && QT_HAS_INCLUDE(<compare>)
+ std::strong_ordering operator<=>(const QCborMap &other) const
+ {
+ int c = compare(other);
+ if (c > 0) return std::strong_ordering::greater;
+ if (c == 0) return std::strong_ordering::equivalent;
+ return std::strong_ordering::less;
+ }
+#else
+ bool operator==(const QCborMap &other) const noexcept
+ { return compare(other) == 0; }
+ bool operator!=(const QCborMap &other) const noexcept
+ { return !(*this == other); }
+ bool operator<(const QCborMap &other) const
+ { return compare(other) < 0; }
+#endif
+
+ typedef Iterator iterator;
+ typedef ConstIterator const_iterator;
+ iterator begin() { detach(); return iterator{d.data(), 1}; }
+ const_iterator constBegin() const { return const_iterator{d.data(), 1}; }
+ const_iterator begin() const { return constBegin(); }
+ const_iterator cbegin() const { return constBegin(); }
+ iterator end() { detach(); return iterator{d.data(), 2 * size() + 1}; }
+ const_iterator constEnd() const { return const_iterator{d.data(), 2 * size() + 1}; }
+ const_iterator end() const { return constEnd(); }
+ const_iterator cend() const { return constEnd(); }
+ iterator erase(iterator it);
+ iterator erase(const_iterator it) { return erase(iterator{ it.item.d, it.item.i }); }
+ QCborValue extract(iterator it);
+ QCborValue extract(const_iterator it) { return extract(iterator{ it.item.d, it.item.i }); }
+ bool empty() const { return isEmpty(); }
+
+ iterator find(qint64 key);
+ iterator find(QLatin1String key);
+ iterator find(const QString & key);
+ iterator find(const QCborValue &key);
+ const_iterator constFind(qint64 key) const;
+ const_iterator constFind(QLatin1String key) const;
+ const_iterator constFind(const QString & key) const;
+ const_iterator constFind(const QCborValue &key) const;
+ const_iterator find(qint64 key) const { return constFind(key); }
+ const_iterator find(QLatin1String key) const { return constFind(key); }
+ const_iterator find(const QString & key) const { return constFind(key); }
+ const_iterator find(const QCborValue &key) const { return constFind(key); }
+
+ iterator insert(qint64 key, const QCborValue &value_)
+ {
+ QCborValueRef v = operator[](key); // detaches
+ v = value_;
+ return { d.data(), v.i };
+ }
+ iterator insert(QLatin1String key, const QCborValue &value_)
+ {
+ QCborValueRef v = operator[](key); // detaches
+ v = value_;
+ return { d.data(), v.i };
+ }
+ iterator insert(const QString &key, const QCborValue &value_)
+ {
+ QCborValueRef v = operator[](key); // detaches
+ v = value_;
+ return { d.data(), v.i };
+ }
+ iterator insert(const QCborValue &key, const QCborValue &value_)
+ {
+ QCborValueRef v = operator[](key); // detaches
+ v = value_;
+ return { d.data(), v.i };
+ }
+ iterator insert(value_type v) { return insert(v.first, v.second); }
+
+ static QCborMap fromVariantMap(const QVariantMap &map);
+ static QCborMap fromVariantHash(const QVariantHash &hash);
+ static QCborMap fromJsonObject(const QJsonObject &o);
+ QVariantMap toVariantMap() const;
+ QVariantHash toVariantHash() const;
+ QJsonObject toJsonObject() const;
+
+private:
+ void detach(qsizetype reserve = 0);
+
+ friend QCborValue;
+ explicit QCborMap(QCborContainerPrivate &dd) noexcept;
+ QExplicitlySharedDataPointer<QCborContainerPrivate> d;
+};
+
+Q_DECLARE_SHARED(QCborMap)
+
+inline QCborValue::QCborValue(QCborMap &&m)
+ : n(-1), container(m.d.take()), t(Map)
+{
+}
+
+inline QCborMap QCborValueRef::toMap() const
+{
+ return concrete().toMap();
+}
+
+inline QCborMap QCborValueRef::toMap(const QCborMap &m) const
+{
+ return concrete().toMap(m);
+}
+
+Q_CORE_EXPORT uint qHash(const QCborMap &map, uint seed = 0);
+
+#if !defined(QT_NO_DEBUG_STREAM)
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborMap &m);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QCBORMAP_H
diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp
new file mode 100644
index 0000000000..aed286a11f
--- /dev/null
+++ b/src/corelib/serialization/qcborstream.cpp
@@ -0,0 +1,2954 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcborstream.h"
+
+#include <private/qnumeric_p.h>
+#include <private/qutfcodec_p.h>
+#include <qbuffer.h>
+#include <qdebug.h>
+#include <qstack.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_NO_DEBUG
+# define NDEBUG 1
+#endif
+#undef assert
+#define assert Q_ASSERT
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wunused-function")
+QT_WARNING_DISABLE_CLANG("-Wunused-function")
+QT_WARNING_DISABLE_CLANG("-Wundefined-internal")
+QT_WARNING_DISABLE_MSVC(4334) // '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
+
+#define CBOR_ENCODER_NO_CHECK_USER
+
+#define CBOR_NO_VALIDATION_API 1
+#define CBOR_NO_PRETTY_API 1
+#define CBOR_API static inline
+#define CBOR_PRIVATE_API static inline
+#define CBOR_INLINE_API static inline
+
+#include <cbor.h>
+
+static CborError qt_cbor_encoder_write_callback(void *token, const void *data, size_t len, CborEncoderAppendType);
+static bool qt_cbor_decoder_can_read(void *token, size_t len);
+static void qt_cbor_decoder_advance(void *token, size_t len);
+static void *qt_cbor_decoder_read(void *token, void *userptr, size_t offset, size_t len);
+static CborError qt_cbor_decoder_transfer_string(void *token, const void **userptr, size_t offset, size_t len);
+
+#define CBOR_ENCODER_WRITER_CONTROL 1
+#define CBOR_ENCODER_WRITE_FUNCTION qt_cbor_encoder_write_callback
+
+#define CBOR_PARSER_READER_CONTROL 1
+#define CBOR_PARSER_CAN_READ_BYTES_FUNCTION qt_cbor_decoder_can_read
+#define CBOR_PARSER_ADVANCE_BYTES_FUNCTION qt_cbor_decoder_advance
+#define CBOR_PARSER_TRANSFER_STRING_FUNCTION qt_cbor_decoder_transfer_string
+#define CBOR_PARSER_READ_BYTES_FUNCTION qt_cbor_decoder_read
+
+#include "../3rdparty/tinycbor/src/cborencoder.c"
+#include "../3rdparty/tinycbor/src/cborerrorstrings.c"
+#include "../3rdparty/tinycbor/src/cborparser.c"
+
+// silence compilers that complain about this being a static function declared
+// but never defined
+static CborError cbor_encoder_close_container_checked(CborEncoder*, const CborEncoder*)
+{
+ Q_UNREACHABLE();
+ return CborErrorInternalError;
+}
+static CborError _cbor_value_dup_string(const CborValue *, void **, size_t *, CborValue *)
+{
+ Q_UNREACHABLE();
+ return CborErrorInternalError;
+}
+QT_WARNING_POP
+
+Q_DECLARE_TYPEINFO(CborEncoder, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(CborValue, Q_PRIMITIVE_TYPE);
+
+// confirm our constants match TinyCBOR's
+Q_STATIC_ASSERT(int(QCborStreamReader::UnsignedInteger) == CborIntegerType);
+Q_STATIC_ASSERT(int(QCborStreamReader::ByteString) == CborByteStringType);
+Q_STATIC_ASSERT(int(QCborStreamReader::TextString) == CborTextStringType);
+Q_STATIC_ASSERT(int(QCborStreamReader::Array) == CborArrayType);
+Q_STATIC_ASSERT(int(QCborStreamReader::Map) == CborMapType);
+Q_STATIC_ASSERT(int(QCborStreamReader::Tag) == CborTagType);
+Q_STATIC_ASSERT(int(QCborStreamReader::SimpleType) == CborSimpleType);
+Q_STATIC_ASSERT(int(QCborStreamReader::HalfFloat) == CborHalfFloatType);
+Q_STATIC_ASSERT(int(QCborStreamReader::Float) == CborFloatType);
+Q_STATIC_ASSERT(int(QCborStreamReader::Double) == CborDoubleType);
+Q_STATIC_ASSERT(int(QCborStreamReader::Invalid) == CborInvalidType);
+
+/*!
+ \headerfile <QtCborCommon>
+
+ \brief The <QtCborCommon> header contains definitions common to both the
+ streaming classes (QCborStreamReader and QCborStreamWriter) and to
+ QCborValue.
+ */
+
+/*!
+ \enum QCborSimpleType
+ \relates <QtCborCommon>
+
+ This enum contains the possible "Simple Types" for CBOR. Simple Types range
+ from 0 to 255 and are types that carry no further value.
+
+ The following values are currently known:
+
+ \value False A "false" boolean.
+ \value True A "true" boolean.
+ \value Null Absence of value (null).
+ \value Undefined Missing or deleted value, usually an error.
+
+ Qt CBOR API supports encoding and decoding any Simple Type, whether one of
+ those above or any other value.
+
+ Applications should only use further values if a corresponding specification
+ has been published, otherwise interpretation and validation by the remote
+ may fail. Values 24 to 31 are reserved and must not be used.
+
+ The current authoritative list is maintained by IANA in the
+ \l{https://www.iana.org/assignments/cbor-simple-values/cbor-simple-values.xml}{Simple
+ Values registry}.
+
+ \sa QCborStreamWriter::append(QCborSimpleType), QCborStreamReader::isSimpleType(),
+ QCborStreamReader::toSimpleType(), QCborValue::isSimpleType(), QCborValue::toSimpleType()
+ */
+
+Q_CORE_EXPORT const char *qt_cbor_simpletype_id(QCborSimpleType st)
+{
+ switch (st) {
+ case QCborSimpleType::False:
+ return "False";
+ case QCborSimpleType::True:
+ return "True";
+ case QCborSimpleType::Null:
+ return "Null";
+ case QCborSimpleType::Undefined:
+ return "Undefined";
+ }
+ return nullptr;
+}
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug dbg, QCborSimpleType st)
+{
+ QDebugStateSaver saver(dbg);
+ const char *id = qt_cbor_simpletype_id(st);
+ if (id)
+ return dbg.nospace() << "QCborSimpleType::" << id;
+
+ return dbg.nospace() << "QCborSimpleType(" << uint(st) << ')';
+}
+#endif
+
+/*!
+ \enum QCborTag
+ \relates <QtCborCommon>
+
+ This enum contains no enumeration and is used only to provide type-safe
+ access to a CBOR tag.
+
+ CBOR tags are 64-bit numbers that are attached to generic CBOR types to
+ provide further semantic meaning. QCborTag may be constructed from an
+ enumeration found in QCborKnownTags or directly by providing the numeric
+ representation.
+
+ For example, the following creates a QCborValue containing a byte array
+ tagged with a tag 2.
+
+ \code
+ QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9));
+ \endcode
+
+ \sa QCborKnownTags, QCborStreamWriter::append(QCborTag),
+ QCborStreamReader::isTag(), QCborStreamReader::toTag(),
+ QCborValue::isTag(), QCborValue::tag()
+ */
+
+Q_CORE_EXPORT const char *qt_cbor_tag_id(QCborTag tag)
+{
+ // Casting to QCborKnownTags's underlying type will make the comparison
+ // below fail if the tag value is out of range.
+ auto n = std::underlying_type<QCborKnownTags>::type(tag);
+ if (QCborTag(n) == tag) {
+ switch (QCborKnownTags(n)) {
+ case QCborKnownTags::DateTimeString:
+ return "DateTimeString";
+ case QCborKnownTags::UnixTime_t:
+ return "UnixTime_t";
+ case QCborKnownTags::PositiveBignum:
+ return "PositiveBignum";
+ case QCborKnownTags::NegativeBignum:
+ return "NegativeBignum";
+ case QCborKnownTags::Decimal:
+ return "Decimal";
+ case QCborKnownTags::Bigfloat:
+ return "Bigfloat";
+ case QCborKnownTags::COSE_Encrypt0:
+ return "COSE_Encrypt0";
+ case QCborKnownTags::COSE_Mac0:
+ return "COSE_Mac0";
+ case QCborKnownTags::COSE_Sign1:
+ return "COSE_Sign1";
+ case QCborKnownTags::ExpectedBase64url:
+ return "ExpectedBase64url";
+ case QCborKnownTags::ExpectedBase64:
+ return "ExpectedBase64";
+ case QCborKnownTags::ExpectedBase16:
+ return "ExpectedBase16";
+ case QCborKnownTags::EncodedCbor:
+ return "EncodedCbor";
+ case QCborKnownTags::Url:
+ return "Url";
+ case QCborKnownTags::Base64url:
+ return "Base64url";
+ case QCborKnownTags::Base64:
+ return "Base64";
+ case QCborKnownTags::RegularExpression:
+ return "RegularExpression";
+ case QCborKnownTags::MimeMessage:
+ return "MimeMessage";
+ case QCborKnownTags::Uuid:
+ return "Uuid";
+ case QCborKnownTags::COSE_Encrypt:
+ return "COSE_Encrypt";
+ case QCborKnownTags::COSE_Mac:
+ return "COSE_Mac";
+ case QCborKnownTags::COSE_Sign:
+ return "COSE_Sign";
+ case QCborKnownTags::Signature:
+ return "Signature";
+ }
+ }
+ return nullptr;
+}
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug dbg, QCborTag tag)
+{
+ QDebugStateSaver saver(dbg);
+ const char *id = qt_cbor_tag_id(tag);
+ dbg.nospace() << "QCborTag(";
+ if (id)
+ dbg.nospace() << "QCborKnownTags::" << id;
+ else
+ dbg.nospace() << quint64(tag);
+
+ return dbg << ')';
+}
+#endif
+
+/*!
+ \enum QCborKnownTags
+ \relates <QtCborCommon>
+
+ This enum contains a list of CBOR tags, known at the time of the Qt
+ implementation. This list is not meant to be complete and contains only
+ tags that are either backed by an RFC or specifically used by the Qt
+ implementation.
+
+ The authoritative list is maintained by IANA in the
+ \l{https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml}{CBOR tag
+ registry}.
+
+ \value DateTimeString A date and time string, formatted according to RFC 3339, as refined
+ by RFC 4287. It is the same format as Qt::ISODate and
+ Qt::ISODateWithMs.
+ \value UnixTime_t A numerical representation of seconds elapsed since
+ 1970-01-01T00:00Z.
+ \value PositiveBignum A positive number of arbitrary length, encoded as a byte array in
+ network byte order. For example, the number 2\sup{64} is represented by
+ a byte array containing the byte value 0x01 followed by 8 zero bytes.
+ \value NegativeBignum A negative number of arbirary length, encoded as the absolute value
+ of that number, minus one. For example, a byte array containing
+ byte value 0x02 followed by 8 zero bytes represents the number
+ -2\sup{65} - 1.
+ \value Decimal A decimal fraction, encoded as an array of two integers: the first
+ is the exponent of the power of 10, the second the integral
+ mantissa. The value 273.15 would be encoded as array \c{[-2, 27315]}.
+ \value Bigfloat Similar to Decimal, but the exponent is a power of 2 instead.
+ \value COSE_Encrypt0 An \c Encrypt0 map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
+ (CBOR Object Signing and Encryption).
+ \value COSE_Mac0 A \c Mac0 map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
+ (CBOR Object Signing and Encryption).
+ \value COSE_Sign1 A \c Sign1 map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
+ (CBOR Object Signing and Encryption).
+ \value ExpectedBase64url Indicates that the byte array should be encoded using Base64url
+ if the stream is converted to JSON.
+ \value ExpectedBase64 Indicates that the byte array should be encoded using Base64
+ if the stream is converted to JSON.
+ \value ExpectedBase16 Indicates that the byte array should be encoded using Base16 (hex)
+ if the stream is converted to JSON.
+ \value EncodedCbor Indicates that the byte array contains a CBOR stream.
+ \value Url Indicates that the string contains a URL.
+ \value Base64url Indicates that the string contains data encoded using Base64url.
+ \value Base64 Indicates that the string contains data encoded using Base64.
+ \value RegularExpression Indicates that the string contains a Perl-Compatible Regular
+ Expression pattern.
+ \value MimeMessage Indicates that the string contains a MIME message (according to
+ \l{https://tools.ietf.org/html/rfc2045}){RFC 2045}.
+ \value Uuid Indicates that the byte array contains a UUID.
+ \value COSE_Encrypt An \c Encrypt map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
+ (CBOR Object Signing and Encryption).
+ \value COSE_Mac A \c Mac map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
+ (CBOR Object Signing and Encryption).
+ \value COSE_Sign A \c Sign map as specified by \l{https://tools.ietf.org/html/rfc8152}{RFC 8152}
+ (CBOR Object Signing and Encryption).
+ \value Signature No change in interpretation; this tag can be used as the outermost
+ tag in a CBOR stream as the file header.
+
+ The following tags are interpreted by QCborValue during decoding and will
+ produce objects with extended Qt types, and it will use those tags when
+ encoding the same extended types.
+
+ \value DateTimeString \l QDateTime
+ \value UnixTime_t \l QDateTime (only in decoding)
+ \value Url \l QUrl
+ \value Uuid \l QUuid
+
+ Additionally, if a QCborValue containing a QByteArray is tagged using one of
+ \c ExpectedBase64url, \c ExpectedBase64 or \c ExpectedBase16, QCborValue
+ will use the expected encoding when converting to JSON (see
+ QCborValue::toJsonValue).
+
+ \sa QCborTag, QCborStreamWriter::append(QCborTag),
+ QCborStreamReader::isTag(), QCborStreamReader::toTag(),
+ QCborValue::isTag(), QCborValue::tag()
+ */
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug dbg, QCborKnownTags tag)
+{
+ QDebugStateSaver saver(dbg);
+ const char *id = qt_cbor_tag_id(QCborTag(int(tag)));
+ if (id)
+ return dbg.nospace() << "QCborKnownTags::" << id;
+
+ return dbg.nospace() << "QCborKnownTags(" << int(tag) << ')';
+}
+#endif
+
+/*!
+ \class QCborError
+ \inmodule QtCore
+ \relates <QtCborCommon>
+ \reentrant
+ \since 5.12
+
+ \brief The QCborError class holds the error condition found while parsing or
+ validating a CBOR stream.
+
+ \sa QCborStreamReader, QCborValue, QCborParserError
+ */
+
+/*!
+ \enum QCborError::Code
+
+ This enum contains the possible error condition codes.
+
+ \value NoError No error was detected.
+ \value UnknownError An unknown error occurred and no further details are available.
+ \value AdvancePastEnd QCborStreamReader::next() was called but there are no more elements in
+ the current context.
+ \value InputOutputError An I/O error with the QIODevice occurred.
+ \value GarbageAtEnd Data was found in the input stream after the last element.
+ \value EndOfFile The end of the input stream was unexpectedly reached while processing an
+ element.
+ \value UnexpectedBreak The CBOR stream contains a Break where it is not allowed (data is
+ corrupt and the error is not recoverable).
+ \value UnknownType The CBOR stream contains an unknown/unparseable Type (data is corrupt
+ and the and the error is not recoverable).
+ \value IllegalType The CBOR stream contains a known type in a position it is not allowed
+ to exist (data is corrupt and the error is not recoverable).
+ \value IllegalNumber The CBOR stream appears to be encoding a number larger than 64-bit
+ (data is corrupt and the error is not recoverable).
+ \value IllegalSimpleType The CBOR stream contains a Simple Type encoded incorrectly (data is
+ corrupt and the error is not recoverable).
+ \value InvalidUtf8String The CBOR stream contains a text string that does not decode properly
+ as UTF (data is corrupt and the error is not recoverable).
+ \value DataTooLarge CBOR string, map or array is too big and cannot be parsed by Qt
+ (internal limitation, but the error is not recoverable).
+ \value NestingTooDeep Too many levels of arrays or maps encountered while processing the
+ input (internal limitation, but the error is not recoverable).
+ \value UnsupportedType The CBOR stream contains a known type that the implementation does not
+ support (internal limitation, but the error is not recoverable).
+ */
+
+/*!
+ \variable QCborError::c
+ \internal
+ */
+
+/*!
+ \fn QCborError::operator Code() const
+
+ Returns the error code that this QCborError object stores.
+ */
+
+/*!
+ Returns a text string that matches the error code in this QCborError object.
+
+ Note: the string is not translated. Applications whose interface allow users
+ to parse CBOR streams need to provide their own, translated strings.
+
+ \sa QCborError::Code
+ */
+QString QCborError::toString() const
+{
+ switch (c) {
+ case NoError:
+ Q_STATIC_ASSERT(int(NoError) == int(CborNoError));
+ return QString();
+
+ case UnknownError:
+ Q_STATIC_ASSERT(int(UnknownError) == int(CborUnknownError));
+ return QStringLiteral("Unknown error");
+ case AdvancePastEnd:
+ Q_STATIC_ASSERT(int(AdvancePastEnd) == int(CborErrorAdvancePastEOF));
+ return QStringLiteral("Read past end of buffer (more bytes needed)");
+ case InputOutputError:
+ Q_STATIC_ASSERT(int(InputOutputError) == int(CborErrorIO));
+ return QStringLiteral("Input/Output error");
+ case GarbageAtEnd:
+ Q_STATIC_ASSERT(int(GarbageAtEnd) == int(CborErrorGarbageAtEnd));
+ return QStringLiteral("Data found after the end of the stream");
+ case EndOfFile:
+ Q_STATIC_ASSERT(int(EndOfFile) == int(CborErrorUnexpectedEOF));
+ return QStringLiteral("Unexpected end of input data (more bytes needed)");
+ case UnexpectedBreak:
+ Q_STATIC_ASSERT(int(UnexpectedBreak) == int(CborErrorUnexpectedBreak));
+ return QStringLiteral("Invalid CBOR stream: unexpected 'break' byte");
+ case UnknownType:
+ Q_STATIC_ASSERT(int(UnknownType) == int(CborErrorUnknownType));
+ return QStringLiteral("Invalid CBOR stream: unknown type");
+ case IllegalType:
+ Q_STATIC_ASSERT(int(IllegalType) == int(CborErrorIllegalType));
+ return QStringLiteral("Invalid CBOR stream: illegal type found");
+ case IllegalNumber:
+ Q_STATIC_ASSERT(int(IllegalNumber) == int(CborErrorIllegalNumber));
+ return QStringLiteral("Invalid CBOR stream: illegal number encoding (future extension)");
+ case IllegalSimpleType:
+ Q_STATIC_ASSERT(int(IllegalSimpleType) == int(CborErrorIllegalSimpleType));
+ return QStringLiteral("Invalid CBOR stream: illegal simple type");
+ case InvalidUtf8String:
+ Q_STATIC_ASSERT(int(InvalidUtf8String) == int(CborErrorInvalidUtf8TextString));
+ return QStringLiteral("Invalid CBOR stream: invalid UTF-8 text string");
+ case DataTooLarge:
+ Q_STATIC_ASSERT(int(DataTooLarge) == int(CborErrorDataTooLarge));
+ return QStringLiteral("Internal limitation: data set too large");
+ case NestingTooDeep:
+ Q_STATIC_ASSERT(int(NestingTooDeep) == int(CborErrorNestingTooDeep));
+ return QStringLiteral("Internal limitation: data nesting too deep");
+ case UnsupportedType:
+ Q_STATIC_ASSERT(int(UnsupportedType) == int(CborErrorUnsupportedType));
+ return QStringLiteral("Internal limitation: unsupported type");
+ }
+
+ // get the error from TinyCBOR
+ CborError err = CborError(int(c));
+ return QString::fromLatin1(cbor_error_string(err));
+}
+
+/*!
+ \class QCborStreamWriter
+ \inmodule QtCore
+ \ingroup cbor
+ \reentrant
+ \since 5.12
+
+ \brief The QCborStreamWriter class is a simple CBOR encoder operating on a
+ one-way stream.
+
+ This class can be used to quickly encode a stream of CBOR content directly
+ to either a QByteArray or QIODevice. CBOR is the Concise Binary Object
+ Representation, a very compact form of binary data encoding that is
+ compatible with JSON. It was created by the IETF Constrained RESTful
+ Environments (CoRE) WG, which has used it in many new RFCs. It is meant to
+ be used alongside the \l{https://tools.ietf.org/html/rfc7252}{CoAP
+ protocol}.
+
+ QCborStreamWriter provides a StAX-like API, similar to that of
+ \l{QXmlStreamWriter}. It is rather low-level and requires a bit of knowledge
+ of CBOR encoding. For a simpler API, see \l{QCborValue} and especially the
+ encoding function QCborValue::toCbor().
+
+ The typical use of QCborStreamWriter is to create the object on the target
+ QByteArray or QIODevice, then call one of the append() overloads with the
+ desired type to be encoded. To create arrays and maps, QCborStreamWriter
+ provides startArray() and startMap() overloads, which must be terminated by
+ the corresponding endArray() and endMap() functions.
+
+ The following example encodes the equivalent of this JSON content:
+
+ \div{class="pre"}
+ {
+ "label": "journald",
+ "autoDetect": false,
+ "condition": "libs.journald",
+ "output": [ "privateFeature" ]
+ }
+ \enddiv
+
+ \code
+ writer.startMap(4); // 4 elements in the map
+
+ writer.append(QLatin1String("label"));
+ writer.append(QLatin1String("journald"));
+
+ writer.append(QLatin1String("autoDetect"));
+ writer.append(false);
+
+ writer.append(QLatin1String("condition"));
+ writer.append(QLatin1String("libs.journald"));
+
+ writer.append(QLatin1String("output"));
+ writer.startArray(1);
+ writer.append(QLatin1String("privateFeature"));
+ writer.endArray();
+
+ writer.endMap();
+ \endcode
+
+ \section1 CBOR support
+
+ QCborStreamWriter supports all CBOR features required to create canonical
+ and strict streams. It implements almost all of the features specified in
+ \l {https://tools.ietf.org/html/rfc7049}{RFC 7049}.
+
+ The following table lists the CBOR features that QCborStreamWriter supports.
+
+ \table
+ \header \li Feature \li Support
+ \row \li Unsigned numbers \li Yes (full range)
+ \row \li Negative numbers \li Yes (full range)
+ \row \li Byte strings \li Yes
+ \row \li Text strings \li Yes
+ \row \li Chunked strings \li No
+ \row \li Tags \li Yes (arbitrary)
+ \row \li Booleans \li Yes
+ \row \li Null \li Yes
+ \row \li Undefined \li Yes
+ \row \li Arbitrary simple values \li Yes
+ \row \li Half-precision float (16-bit) \li Yes
+ \row \li Single-precision float (32-bit) \li Yes
+ \row \li Double-precision float (64-bit) \li Yes
+ \row \li Infinities and NaN floating point \li Yes
+ \row \li Determinate-length arrays and maps \li Yes
+ \row \li Indeterminate-length arrays and maps \li Yes
+ \row \li Map key types other than strings and integers \li Yes (arbitrary)
+ \endtable
+
+ \section2 Canonical CBOR encoding
+
+ Canonical CBOR encoding is defined by
+ \l{https://tools.ietf.org/html/rfc7049#section-3.9}{Section 3.9 of RFC
+ 7049}. Canonical encoding is not a requirement for Qt's CBOR decoding
+ functionality, but it may be required for some protocols. In particular,
+ protocols that require the ability to reproduce the same stream identically
+ may require this.
+
+ In order to be considered "canonical", a CBOR stream must meet the
+ following requirements:
+
+ \list
+ \li Integers must be as small as possible. QCborStreamWriter always
+ does this (no user action is required and it is not possible
+ to write overlong integers).
+ \li Array, map and string lengths must be as short as possible. As
+ above, QCborStreamWriter automatically does this.
+ \li Arrays, maps and strings must use explicit length. QCborStreamWriter
+ always does this for strings; for arrays and maps, be sure to call
+ startArray() and startMap() overloads with explicit length.
+ \li Keys in every map must be sorted in ascending order. QCborStreamWriter
+ offers no help in this item: the developer must ensure that before
+ calling append() for the map pairs.
+ \li Floating point values should be as small as possible. QCborStreamWriter
+ will not convert floating point values; it is up to the developer
+ to perform this check prior to calling append() (see those functions'
+ examples).
+ \endlist
+
+ \section2 Strict CBOR mode
+
+ Strict mode is defined by
+ \l{https://tools.ietf.org/html/rfc7049#section-3.10}{Section 3.10 of RFC
+ 7049}. As for Canonical encoding above, QCborStreamWriter makes it possible
+ to create strict CBOR streams, but does not require them or validate that
+ the output is so.
+
+ \list
+ \li Keys in a map must be unique. QCborStreamWriter performs no validation
+ of map keys.
+ \li Tags may be required to be paired only with the correct types,
+ according to their specification. QCborStreamWriter performs no
+ validation of tag usage.
+ \li Text Strings must be properly-encoded UTF-8. QCborStreamWriter always
+ writes proper UTF-8 for strings added with append(), but performs no
+ validation for strings added with appendTextString().
+ \endlist
+
+ \section2 Invalid CBOR stream
+
+ It is also possible to misuse QCborStreamWriter and produce invalid CBOR
+ streams that will fail to be decoded by a receiver. The following actions
+ will produce invalid streams:
+
+ \list
+ \li Append a tag and not append the corresponding tagged value
+ (QCborStreamWriter produces no diagnostic).
+ \li Append too many or too few items to an array or map with explicit
+ length (endMap() and endArray() will return false and
+ QCborStreamWriter will log with qWarning()).
+ \endlist
+
+ \sa QCborStreamReader, QCborValue, QXmlStreamWriter
+ */
+
+class QCborStreamWriterPrivate
+{
+public:
+ static Q_CONSTEXPR quint64 IndefiniteLength = (std::numeric_limits<quint64>::max)();
+
+ QIODevice *device;
+ CborEncoder encoder;
+ QStack<CborEncoder> containerStack;
+ bool deleteDevice = false;
+
+ QCborStreamWriterPrivate(QIODevice *device)
+ : device(device)
+ {
+ cbor_encoder_init_writer(&encoder, qt_cbor_encoder_write_callback, this);
+ }
+
+ ~QCborStreamWriterPrivate()
+ {
+ if (deleteDevice)
+ delete device;
+ }
+
+ template <typename... Args> void executeAppend(CborError (*f)(CborEncoder *, Args...), Args... args)
+ {
+ f(&encoder, std::forward<Args>(args)...);
+ }
+
+ void createContainer(CborError (*f)(CborEncoder *, CborEncoder *, size_t), quint64 len = IndefiniteLength)
+ {
+ Q_STATIC_ASSERT(size_t(IndefiniteLength) == CborIndefiniteLength);
+ if (sizeof(len) != sizeof(size_t) && len != IndefiniteLength) {
+ if (Q_UNLIKELY(len >= CborIndefiniteLength)) {
+ // TinyCBOR can't do this in 32-bit mode
+ qWarning("QCborStreamWriter: container of size %llu is too big for a 32-bit build; "
+ "will use indeterminate length instead", len);
+ len = CborIndefiniteLength;
+ }
+ }
+
+ containerStack.push(encoder);
+ f(&containerStack.top(), &encoder, len);
+ }
+
+ bool closeContainer()
+ {
+ if (containerStack.isEmpty()) {
+ qWarning("QCborStreamWriter: closing map or array that wasn't open");
+ return false;
+ }
+
+ CborEncoder container = containerStack.pop();
+ CborError err = cbor_encoder_close_container(&container, &encoder);
+ encoder = container;
+
+ if (Q_UNLIKELY(err)) {
+ if (err == CborErrorTooFewItems)
+ qWarning("QCborStreamWriter: not enough items added to array or map");
+ else if (err == CborErrorTooManyItems)
+ qWarning("QCborStreamWriter: too many items added to array or map");
+ return false;
+ }
+
+ return true;
+ }
+};
+
+static CborError qt_cbor_encoder_write_callback(void *self, const void *data, size_t len, CborEncoderAppendType)
+{
+ auto that = static_cast<QCborStreamWriterPrivate *>(self);
+ if (!that->device)
+ return CborNoError;
+ qint64 written = that->device->write(static_cast<const char *>(data), len);
+ return (written == qsizetype(len) ? CborNoError : CborErrorIO);
+}
+
+/*!
+ Creates a QCborStreamWriter object that will write the stream to \a device.
+ The device must be opened before the first append() call is made. This
+ constructor can be used with any class that derives from QIODevice, such as
+ QFile, QProcess or QTcpSocket.
+
+ QCborStreamWriter has no buffering, so every append() call will result in
+ one or more calls to the device's \l {QIODevice::}{write()} method.
+
+ The following example writes an empty map to a file:
+
+ \code
+ QFile f("output", QIODevice::WriteOnly);
+ QCborStreamWriter writer(&f);
+ writer.startMap(0);
+ writer.endMap();
+ \endcode
+
+ QCborStreamWriter does not take ownership of \a device.
+
+ \sa device(), setDevice()
+ */
+QCborStreamWriter::QCborStreamWriter(QIODevice *device)
+ : d(new QCborStreamWriterPrivate(device))
+{
+}
+
+/*!
+ Creates a QCborStreamWriter object that will append the stream to \a data.
+ All streaming is done immediately to the byte array, without the need for
+ flushing any buffers.
+
+ The following example writes a number to a byte array then returns
+ it.
+
+ \code
+ QByteArray encodedNumber(qint64 value)
+ {
+ QByteArray ba;
+ QCborStreamWriter writer(&ba);
+ writer.append(value);
+ return ba;
+ }
+ \endcode
+
+ QCborStreamWriter does not take ownership of \a data.
+ */
+QCborStreamWriter::QCborStreamWriter(QByteArray *data)
+ : d(new QCborStreamWriterPrivate(new QBuffer(data)))
+{
+ d->deleteDevice = true;
+ d->device->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
+}
+
+/*!
+ Destroys this QCborStreamWriter object and frees any resources associated.
+
+ QCborStreamWriter does not perform error checking to see if all required
+ items were written to the stream prior to the object being destroyed. It is
+ the programmer's responsibility to ensure that it was done.
+ */
+QCborStreamWriter::~QCborStreamWriter()
+{
+}
+
+/*!
+ Replaces the device or byte array that this QCborStreamWriter object is
+ writing to with \a device.
+
+ \sa device()
+ */
+void QCborStreamWriter::setDevice(QIODevice *device)
+{
+ if (d->deleteDevice)
+ delete d->device;
+ d->device = device;
+ d->deleteDevice = false;
+}
+
+/*!
+ Returns the QIODevice that this QCborStreamWriter object is writing to. The
+ device must have previously been set with either the constructor or with
+ setDevice().
+
+ If this object was created by writing to a QByteArray, this function will
+ return an internal instance of QBuffer, which is owned by QCborStreamWriter.
+
+ \sa setDevice()
+ */
+QIODevice *QCborStreamWriter::device() const
+{
+ return d->device;
+}
+
+/*!
+ \overload
+
+ Appends the 64-bit unsigned value \a u to the CBOR stream, creating a CBOR
+ Unsigned Integer value. In the following example, we write the values 0,
+ 2\sup{32} and \c UINT64_MAX:
+
+ \code
+ writer.append(0U);
+ writer.append(Q_UINT64_C(4294967296));
+ writer.append(std::numeric_limits<quint64>::max());
+ \endcode
+
+ \sa QCborStreamReader::isUnsignedInteger(), QCborStreamReader::toUnsignedInteger()
+ */
+void QCborStreamWriter::append(quint64 u)
+{
+ d->executeAppend(cbor_encode_uint, uint64_t(u));
+}
+
+/*!
+ \overload
+
+ Appends the 64-bit signed value \a i to the CBOR stream. This will create
+ either a CBOR Unsigned Integer or CBOR NegativeInteger value based on the
+ sign of the parameter. In the following example, we write the values 0, -1,
+ 2\sup{32} and \c INT64_MAX:
+
+ \code
+ writer.append(0);
+ writer.append(-1);
+ writer.append(Q_INT64_C(4294967296));
+ writer.append(std::numeric_limits<qint64>::max());
+ \endcode
+
+ \sa QCborStreamReader::isInteger(), QCborStreamReader::toInteger()
+ */
+void QCborStreamWriter::append(qint64 i)
+{
+ d->executeAppend(cbor_encode_int, int64_t(i));
+}
+
+/*!
+ \overload
+
+ Appends the 64-bit negative value \a n to the CBOR stream.
+ QCborNegativeInteger is a 64-bit enum that holds the absolute value of the
+ negative number we want to write. If n is zero, the value written will be
+ equivalent to 2\sup{64} (that is, -18,446,744,073,709,551,616).
+
+ In the following example, we write the values -1, -2\sup{32} and INT64_MIN:
+ \code
+ writer.append(QCborNegativeInteger(1));
+ writer.append(QCborNegativeInteger(Q_INT64_C(4294967296)));
+ writer.append(QCborNegativeInteger(-quint64(std::numeric_limits<qint64>::min())));
+ \endcode
+
+ Note how this function can be used to encode numbers that cannot fit a
+ standard computer's 64-bit signed integer like \l qint64. That is, if \a n
+ is larger than \c{std::numeric_limits<qint64>::max()} or is 0, this will
+ represent a negative number smaller than
+ \c{std::numeric_limits<qint64>::min()}.
+
+ \sa QCborStreamReader::isNegativeInteger(), QCborStreamReader::toNegativeInteger()
+ */
+void QCborStreamWriter::append(QCborNegativeInteger n)
+{
+ d->executeAppend(cbor_encode_negative_int, uint64_t(n));
+}
+
+/*!
+ \fn void QCborStreamWriter::append(const QByteArray &ba)
+ \overload
+
+ Appends the byte array \a ba to the stream, creating a CBOR Byte String
+ value. QCborStreamWriter will attempt to write the entire string in one
+ chunk.
+
+ The following example will load and append the contents of a file to the
+ stream:
+
+ \code
+ void writeFile(QCborStreamWriter &writer, const QString &fileName)
+ {
+ QFile f(fileName);
+ if (f.open(QIODevice::ReadOnly))
+ writer.append(f.readAll());
+ }
+ \endcode
+
+ As the example shows, unlike JSON, CBOR requires no escaping for binary
+ content.
+
+ \sa appendByteString(), QCborStreamReader::isByteArray(),
+ QCborStreamReader::readByteArray()
+ */
+
+/*!
+ \overload
+
+ Appends the text string \a str to the stream, creating a CBOR Text String
+ value. QCborStreamWriter will attempt to write the entire string in one
+ chunk.
+
+ The following example appends a simple string to the stream:
+
+ \code
+ writer.append(QLatin1String("Hello, World"));
+ \endcode
+
+ \b{Performance note}: CBOR requires that all Text Strings be encoded in
+ UTF-8, so this function will iterate over the characters in the string to
+ determine whether the contents are US-ASCII or not. If the string is found
+ to contain characters outside of US-ASCII, it will allocate memory and
+ convert to UTF-8. If this check is unnecessary, use appendTextString()
+ instead.
+
+ \sa QCborStreamReader::isString(), QCborStreamReader::readString()
+ */
+void QCborStreamWriter::append(QLatin1String str)
+{
+ // We've got Latin-1 but CBOR wants UTF-8, so check if the string is the
+ // common subset (US-ASCII).
+ if (QtPrivate::isAscii(str)) {
+ // it is plain US-ASCII
+ appendTextString(str.latin1(), str.size());
+ } else {
+ // non-ASCII, so we need a pass-through UTF-16
+ append(QString(str));
+ }
+}
+
+/*!
+ \overload
+
+ Appends the text string \a str to the stream, creating a CBOR Text String
+ value. QCborStreamWriter will attempt to write the entire string in one
+ chunk.
+
+ The following example writes an arbitrary QString to the stream:
+
+ \code
+ void writeString(QCborStreamWriter &writer, const QString &str)
+ {
+ writer.append(str);
+ }
+ \endcode
+
+ \sa QCborStreamReader::isString(), QCborStreamReader::readString()
+ */
+void QCborStreamWriter::append(QStringView str)
+{
+ QByteArray utf8 = str.toUtf8();
+ appendTextString(utf8.constData(), utf8.size());
+}
+
+/*!
+ \overload
+
+ Appends the CBOR tag \a tag to the stream, creating a CBOR Tag value. All
+ tags must be followed by another type which they provide meaning for.
+
+ In the following example, we append a CBOR Tag 36 (Regular Expression) and a
+ QRegularExpression's pattern to the stream:
+
+ \code
+ void writeRxPattern(QCborStreamWriter &writer, const QRegularExpression &rx)
+ {
+ writer.append(QCborTag(36));
+ writer.append(rx.pattern());
+ }
+ \endcode
+
+ \sa QCborStreamReader::isTag(), QCborStreamReader::toTag()
+ */
+void QCborStreamWriter::append(QCborTag tag)
+{
+ d->executeAppend(cbor_encode_tag, CborTag(tag));
+}
+
+/*!
+ \fn void QCborStreamWriter::append(QCborKnownTags tag)
+ \overload
+
+ Appends the CBOR tag \a tag to the stream, creating a CBOR Tag value. All
+ tags must be followed by another type which they provide meaning for.
+
+ In the following example, we append a CBOR Tag 1 (Unix \c time_t) and an
+ integer representing the current time to the stream, obtained using the \c
+ time() function:
+
+ \code
+ void writeCurrentTime(QCborStreamWriter &writer)
+ {
+ writer.append(QCborKnownTags::UnixTime_t);
+ writer.append(time(nullptr));
+ }
+ \endcode
+
+ \sa QCborStreamReader::isTag(), QCborStreamReader::toTag()
+ */
+
+/*!
+ \overload
+
+ Appends the CBOR simple type \a st to the stream, creating a CBOR Simple
+ Type value. In the following example, we write the simple type for Null as
+ well as for type 32, which Qt has no support for.
+
+ \code
+ writer.append(QCborSimpleType::Null);
+ writer.append(QCborSimpleType(32));
+ \endcode
+
+ \note Using Simple Types for which there is no specification can lead to
+ validation errors by the remote receiver. In addition, simple type values 24
+ through 31 (inclusive) are reserved and must not be used.
+
+ \sa QCborStreamReader::isSimpleType(), QCborStreamReader::toSimpleType()
+ */
+void QCborStreamWriter::append(QCborSimpleType st)
+{
+ d->executeAppend(cbor_encode_simple_value, uint8_t(st));
+}
+
+/*!
+ \overload
+
+ Appends the floating point number \a f to the stream, creating a CBOR 16-bit
+ Half-Precision Floating Point value. The following code can be used to convert
+ a C++ \tt float to \c qfloat16 if there's no loss of precision and append it, or
+ instead append the \tt float.
+
+ \code
+ void writeFloat(QCborStreamWriter &writer, float f)
+ {
+ qfloat16 f16 = f;
+ if (qIsNaN(f) || f16 == f)
+ writer.append(f16);
+ else
+ writer.append(f);
+ }
+ \endcode
+
+ \sa QCborStreamReader::isFloat16(), QCborStreamReader::toFloat16()
+ */
+void QCborStreamWriter::append(qfloat16 f)
+{
+ d->executeAppend(cbor_encode_half_float, static_cast<const void *>(&f));
+}
+
+/*!
+ \overload
+
+ Appends the floating point number \a f to the stream, creating a CBOR 32-bit
+ Single-Precision Floating Point value. The following code can be used to convert
+ a C++ \tt double to \tt float if there's no loss of precision and append it, or
+ instead append the \tt double.
+
+ \code
+ void writeFloat(QCborStreamWriter &writer, double d)
+ {
+ float f = d;
+ if (qIsNaN(d) || d == f)
+ writer.append(f);
+ else
+ writer.append(d);
+ }
+ \endcode
+
+ \sa QCborStreamReader::isFloat(), QCborStreamReader::toFloat()
+ */
+void QCborStreamWriter::append(float f)
+{
+ d->executeAppend(cbor_encode_float, f);
+}
+
+/*!
+ \overload
+
+ Appends the floating point number \a d to the stream, creating a CBOR 64-bit
+ Double-Precision Floating Point value. QCborStreamWriter always appends the
+ number as-is, performing no check for whether the number is the canonical
+ form for NaN, an infinite, whether it is denormal or if it could be written
+ with a shorter format.
+
+ The following code performs all those checks, except for the denormal one,
+ which is expected to be taken into account by the system FPU or floating
+ point emulation directly.
+
+ \code
+ void writeDouble(QCborStreamWriter &writer, double d)
+ {
+ float f;
+ if (qIsNaN(d)) {
+ writer.append(qfloat16(qQNaN()));
+ } else if (qIsInf(d)) {
+ writer.append(d < 0 ? -qInf() : qInf());
+ } else if ((f = d) == d) {
+ qfloat16 f16 = f;
+ if (f16 == f)
+ writer.append(f16);
+ else
+ writer.append(f);
+ } else {
+ writer.append(d);
+ }
+ }
+ \endcode
+
+ Determining if a double can be converted to an integral with no loss of
+ precision is left as an exercise to the reader.
+
+ \sa QCborStreamReader::isDouble(), QCborStreamReader::toDouble()
+ */
+void QCborStreamWriter::append(double d)
+{
+ this->d->executeAppend(cbor_encode_double, d);
+}
+
+/*!
+ Appends \a len bytes of data starting from \a data to the stream, creating a
+ CBOR Byte String value. QCborStreamWriter will attempt to write the entire
+ string in one chunk.
+
+ Unlike the QByteArray overload of append(), this function is not limited by
+ QByteArray's size limits. However, note that neither
+ QCborStreamReader::readByteArray() nor QCborValue support reading CBOR
+ streams with byte arrays larger than 2 GB.
+
+ \sa append(), appendTextString(),
+ QCborStreamReader::isByteArray(), QCborStreamReader::readByteArray()
+ */
+void QCborStreamWriter::appendByteString(const char *data, qsizetype len)
+{
+ d->executeAppend(cbor_encode_byte_string, reinterpret_cast<const uint8_t *>(data), size_t(len));
+}
+
+/*!
+ Appends \a len bytes of text starting from \a utf8 to the stream, creating a
+ CBOR Text String value. QCborStreamWriter will attempt to write the entire
+ string in one chunk.
+
+ The string pointed to by \a utf8 is expected to be properly encoded UTF-8.
+ QCborStreamWriter performs no validation that this is the case.
+
+ Unlike the QLatin1String overload of append(), this function is not limited
+ to 2 GB. However, note that neither QCborStreamReader::readString() nor
+ QCborValue support reading CBOR streams with text strings larger than 2 GB.
+
+ \sa append(QLatin1String), append(QStringView),
+ QCborStreamReader::isString(), QCborStreamReader::readString()
+ */
+void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len)
+{
+ d->executeAppend(cbor_encode_text_string, utf8, size_t(len));
+}
+
+/*!
+ \fn void QCborStreamWriter::append(const char *str, qsizetype size)
+ \overload
+
+ Appends \a size bytes of text starting from \a str to the stream, creating a
+ CBOR Text String value. QCborStreamWriter will attempt to write the entire
+ string in one chunk. If \a size is -1, this function will write \c strlen(\a
+ str) bytes.
+
+ The string pointed to by \a str is expected to be properly encoded UTF-8.
+ QCborStreamWriter performs no validation that this is the case.
+
+ Unlike the QLatin1String overload of append(), this function is not limited
+ to 2 GB. However, note that neither QCborStreamReader nor QCborValue support
+ reading CBOR streams with text strings larger than 2 GB.
+
+ \sa append(QLatin1String), append(QStringView),
+ QCborStreamReader::isString(), QCborStreamReader::readString()
+ */
+
+/*!
+ \fn void QCborStreamWriter::append(bool b)
+ \overload
+
+ Appends the boolean value \a b to the stream, creating either a CBOR False
+ value or a CBOR True value. This function is equivalent to (and implemented
+ as):
+
+ \code
+ writer.append(b ? QCborSimpleType::True : QCborSimpleType::False);
+ \endcode
+
+ \sa appendNull(), appendUndefined(),
+ QCborStreamReader::isBool(), QCborStreamReader::toBool()
+ */
+
+/*!
+ \fn void QCborStreamWriter::append(std::nullptr_t)
+ \overload
+
+ Appends a CBOR Null value to the stream. This function is equivalent to (and
+ implemented as): The parameter is ignored.
+
+ \code
+ writer.append(QCborSimpleType::Null);
+ \endcode
+
+ \sa appendNull(), append(QCborSimpleType), QCborStreamReader::isNull()
+ */
+
+/*!
+ \fn void QCborStreamWriter::appendNull()
+
+ Appends a CBOR Null value to the stream. This function is equivalent to (and
+ implemented as):
+
+ \code
+ writer.append(QCborSimpleType::Null);
+ \endcode
+
+ \sa append(std::nullptr_t), append(QCborSimpleType), QCborStreamReader::isNull()
+ */
+
+/*!
+ \fn void QCborStreamWriter::appendUndefined()
+
+ Appends a CBOR Undefined value to the stream. This function is equivalent to (and
+ implemented as):
+
+ \code
+ writer.append(QCborSimpleType::Undefined);
+ \endcode
+
+ \sa append(QCborSimpleType), QCborStreamReader::isUndefined()
+ */
+
+/*!
+ Starts a CBOR Array with indeterminate length in the CBOR stream. Each
+ startArray() call must be paired with one endArray() call and the current
+ CBOR element extends until the end of the array.
+
+ The array created by this function has no explicit length. Instead, its
+ length is implied by the elements contained in it. Note, however, that use
+ of indeterminate-length arrays is not compliant with canonical CBOR encoding.
+
+ The following example appends elements from the linked list of strings
+ passed as input:
+
+ \code
+ void appendList(QCborStreamWriter &writer, const QLinkedList<QString> &list)
+ {
+ writer.startArray();
+ for (const QString &s : list)
+ writer.append(s);
+ writer.endArray();
+ }
+ \endcode
+
+ \sa startArray(quint64), endArray(), startMap(), QCborStreamReader::isArray(),
+ QCborStreamReader::isLengthKnown()
+ */
+void QCborStreamWriter::startArray()
+{
+ d->createContainer(cbor_encoder_create_array);
+}
+
+/*!
+ \overload
+
+ Starts a CBOR Array with explicit length of \a count items in the CBOR
+ stream. Each startArray call must be paired with one endArray() call and the
+ current CBOR element extends until the end of the array.
+
+ The array created by this function has an explicit length and therefore
+ exactly \a count items must be added to the CBOR stream. Adding fewer or
+ more items will result in failure during endArray() and the CBOR stream will
+ be corrupt. However, explicit-length arrays are required by canonical CBOR
+ encoding.
+
+ The following example appends all strings found in the \l QStringList passed as input:
+
+ \code
+ void appendList(QCborStreamWriter &writer, const QStringList &list)
+ {
+ writer.startArray(list.size());
+ for (const QString &s : list)
+ writer.append(s);
+ writer.endArray();
+ }
+ \endcode
+
+ \b{Size limitations}: The parameter to this function is quint64, which would
+ seem to allow up to 2\sup{64}-1 elements in the array. However, both
+ QCborStreamWriter and QCborStreamReader are currently limited to 2\sup{32}-2
+ items on 32-bit systems and 2\sup{64}-2 items on 64-bit ones. Also note that
+ QCborArray is currently limited to 2\sup{27} elements in any platform.
+
+ \sa startArray(), endArray(), startMap(), QCborStreamReader::isArray(),
+ QCborStreamReader::isLengthKnown()
+ */
+void QCborStreamWriter::startArray(quint64 count)
+{
+ d->createContainer(cbor_encoder_create_array, count);
+}
+
+/*!
+ Terminates the array started by either overload of startArray() and returns
+ true if the correct number of elements was added to the array. This function
+ must be called for every startArray() used.
+
+ A return of false indicates error in the application and an unrecoverable
+ error in this stream. QCborStreamWriter also writes a warning using
+ qWarning() if that happens.
+
+ Calling this function when the current container is not an array is also an
+ error, though QCborStreamWriter cannot currently detect this condition.
+
+ \sa startArray(), startArray(quint64), endMap()
+ */
+bool QCborStreamWriter::endArray()
+{
+ return d->closeContainer();
+}
+
+/*!
+ Starts a CBOR Map with indeterminate length in the CBOR stream. Each
+ startMap() call must be paired with one endMap() call and the current CBOR
+ element extends until the end of the map.
+
+ The map created by this function has no explicit length. Instead, its length
+ is implied by the elements contained in it. Note, however, that use of
+ indeterminate-length maps is not compliant with canonical CBOR encoding
+ (canonical encoding also requires keys to be unique and in sorted order).
+
+ The following example appends elements from the linked list of int and
+ string pairs passed as input:
+
+ \code
+ void appendMap(QCborStreamWriter &writer, const QLinkedList<QPair<int, QString>> &list)
+ {
+ writer.startMap();
+ for (const auto pair : list) {
+ writer.append(pair.first)
+ writer.append(pair.second);
+ }
+ writer.endMap();
+ }
+ \endcode
+
+ \sa startMap(quint64), endMap(), startArray(), QCborStreamReader::isMap(),
+ QCborStreamReader::isLengthKnown()
+ */
+void QCborStreamWriter::startMap()
+{
+ d->createContainer(cbor_encoder_create_map);
+}
+
+/*!
+ \overload
+
+ Starts a CBOR Map with explicit length of \a count items in the CBOR
+ stream. Each startMap call must be paired with one endMap() call and the
+ current CBOR element extends until the end of the map.
+
+ The map created by this function has an explicit length and therefore
+ exactly \a count pairs of items must be added to the CBOR stream. Adding
+ fewer or more items will result in failure during endMap() and the CBOR
+ stream will be corrupt. However, explicit-length map are required by
+ canonical CBOR encoding.
+
+ The following example appends all strings found in the \l QMap passed as input:
+
+ \code
+ void appendMap(QCborStreamWriter &writer, const QMap<int, QString> &map)
+ {
+ writer.startMap(map.size());
+ for (auto it = map.begin(); it != map.end(); ++it) {
+ writer.append(it.key());
+ writer.append(it.value());
+ }
+ writer.endMap();
+ }
+ \endcode
+
+ \b{Size limitations}: The parameter to this function is quint64, which would
+ seem to allow up to 2\sup{64}-1 pairs in the map. However, both
+ QCborStreamWriter and QCborStreamReader are currently limited to 2\sup{31}-1
+ items on 32-bit systems and 2\sup{63}-1 items on 64-bit ones. Also note that
+ QCborMap is currently limited to 2\sup{26} elements in any platform.
+
+ \sa startMap(), endMap(), startArray(), QCborStreamReader::isMap(),
+ QCborStreamReader::isLengthKnown()
+ */
+void QCborStreamWriter::startMap(quint64 count)
+{
+ d->createContainer(cbor_encoder_create_map, count);
+}
+
+/*!
+ Terminates the map started by either overload of startMap() and returns
+ true if the correct number of elements was added to the array. This function
+ must be called for every startMap() used.
+
+ A return of false indicates error in the application and an unrecoverable
+ error in this stream. QCborStreamWriter also writes a warning using
+ qWarning() if that happens.
+
+ Calling this function when the current container is not a map is also an
+ error, though QCborStreamWriter cannot currently detect this condition.
+
+ \sa startMap(), startMap(quint64), endArray()
+ */
+bool QCborStreamWriter::endMap()
+{
+ return d->closeContainer();
+}
+
+/*!
+ \class QCborStreamReader
+ \inmodule QtCore
+ \ingroup cbor
+ \reentrant
+ \since 5.12
+
+ \brief The QCborStreamReader class is a simple CBOR stream decoder, operating
+ on either a QByteArray or QIODevice.
+
+ This class can be used to decode a stream of CBOR content directly from
+ either a QByteArray or a QIODevice. CBOR is the Concise Binary Object
+ Representation, a very compact form of binary data encoding that is
+ compatible with JSON. It was created by the IETF Constrained RESTful
+ Environments (CoRE) WG, which has used it in many new RFCs. It is meant to
+ be used alongside the \l{https://tools.ietf.org/html/rfc7252}{CoAP
+ protocol}.
+
+ QCborStreamReader provides a StAX-like API, similar to that of
+ \l{QXmlStreamReader}. Using it requires a bit of knowledge of CBOR encoding.
+ For a simpler API, see \l{QCborValue} and especially the decoding function
+ QCborValue::fromCbor().
+
+ Typically, one creates a QCborStreamReader by passing the source QByteArray
+ or QIODevice as a parameter to the constructor, then pop elements off the
+ stream if there were no errors in decoding. There are three kinds of CBOR
+ types:
+
+ \table
+ \header \li Kind \li Types \li Behavior
+ \row \li Fixed-width \li Integers, Tags, Simple types, Floating point
+ \li Value is pre-parsed by QCborStreamReader, so accessor functions
+ are \c const. Must call next() to advance.
+ \row \li Strings \li Byte arrays, Text strings
+ \li Length (if known) is pre-parsed, but the string itself is not.
+ The accessor functions are not const and may allocate memory.
+ Once called, the accessor functions automatically advance to
+ the next element.
+ \row \li Containers \li Arrays, Maps
+ \li Length (if known) is pre-parsed. To access the elements, you
+ must call enterContainer(), read all elements, then call
+ leaveContainer(). That function advances to the next element.
+ \endtable
+
+ So a processor function typically looks like this:
+
+ \code
+ void handleStream(QCborStreamReader &reader)
+ {
+ switch (reader.type())
+ case QCborStreamReader::UnsignedInteger:
+ case QCborStreamReader::NegativeInteger:
+ case QCborStreamReader::SimpleType:
+ case QCborStreamReader::Float16:
+ case QCborStreamReader::Float:
+ case QCborStreamReader::Double:
+ handleFixedWidth(reader);
+ reader.next();
+ break;
+ case QCborStreamReader::ByteArray:
+ case QCborStreamReader::String:
+ handleString(reader);
+ break;
+ case QCborStreamReader::Array:
+ case QCborStreamReader::Map:
+ reader.enterContainer();
+ while (reader.lastError() == QCborError::NoError)
+ handleStream(reader);
+ if (reader.lastError() == QCborError::NoError)
+ reader.leaveContainer();
+ }
+ }
+ \endcode
+
+ \section1 CBOR support
+
+ The following table lists the CBOR features that QCborStreamReader supports.
+
+ \table
+ \header \li Feature \li Support
+ \row \li Unsigned numbers \li Yes (full range)
+ \row \li Negative numbers \li Yes (full range)
+ \row \li Byte strings \li Yes
+ \row \li Text strings \li Yes
+ \row \li Chunked strings \li Yes
+ \row \li Tags \li Yes (arbitrary)
+ \row \li Booleans \li Yes
+ \row \li Null \li Yes
+ \row \li Undefined \li Yes
+ \row \li Arbitrary simple values \li Yes
+ \row \li Half-precision float (16-bit) \li Yes
+ \row \li Single-precision float (32-bit) \li Yes
+ \row \li Double-precision float (64-bit) \li Yes
+ \row \li Infinities and NaN floating point \li Yes
+ \row \li Determinate-length arrays and maps \li Yes
+ \row \li Indeterminate-length arrays and maps \li Yes
+ \row \li Map key types other than strings and integers \li Yes (arbitrary)
+ \endtable
+
+ \section1 Dealing with invalid or incomplete CBOR streams
+
+ QCborStreamReader is capable of detecting corrupt input on its own. The
+ library it uses has been extensively tested against invalid input of any
+ kind and is quite able to report errors. If any is detected,
+ QCborStreamReader will set lastError() to a value besides
+ QCborError::NoError, indicating which situation was detected.
+
+ Most errors detected by QCborStreamReader during normal item parsing are not
+ recoverable. The code using QCborStreamReader may opt to handle the data
+ that was properly decoded or it can opt to discard the entire data.
+
+ The only recoverable error is QCborError::EndOfFile, which indicates that
+ more data is required in order to complete the parsing. This situation is
+ useful when data is being read from an asynchronous source, such as a pipe
+ (QProcess) or a socket (QTcpSocket, QUdpSocket, QNetworkReply, etc.). When
+ more data arrives, the surrounding code needs to call either addData(), if
+ parsing from a QByteArray, or reparse(), if it is instead reading directly
+ a the QIDOevice that now has more data available (see setDevice()).
+
+ \sa QCborStreamWriter, QCborValue, QXmlStreamReader
+ */
+
+/*!
+ \enum QCborStreamReader::Type
+
+ This enumeration contains all possible CBOR types as decoded by
+ QCborStreamReader. CBOR has 7 major types, plus a number of simple types
+ carrying no value, and floating point values.
+
+ \value UnsignedInteger (Major type 0) Ranges from 0 to 2\sup{64} - 1
+ (18,446,744,073,709,551,616)
+ \value NegativeInteger (Major type 1) Ranges from -1 to -2\sup{64}
+ (-18,446,744,073,709,551,616)
+ \value ByteArray (Major type 2) Arbitrary binary data.
+ \value ByteString An alias to ByteArray.
+ \value String (Major type 3) Unicode text, possibly containing NULs.
+ \value TextString An alias to String
+ \value Array (Major type 4) Array of heterogeneous items.
+ \value Map (Major type 5) Map/dictionary of heterogeneous items.
+ \value Tag (Major type 6) Numbers giving further semantic value
+ to generic CBOR items. See \l QCborTag for more information.
+ \value SimpleType (Major type 7) Types carrying no further value. Includes
+ booleans (true and false), null, undefined.
+ \value Float16 IEEE 754 half-precision floating point (\c qfloat16).
+ \value HalfFloat An alias to Float16.
+ \value Float IEEE 754 single-precision floating point (\tt float).
+ \value Double IEEE 754 double-precision floating point (\tt double).
+ \value Invalid Not a valid type, either due to parsing error or due to
+ reaching the end of an array or map.
+ */
+
+/*!
+ \enum QCborStreamReader::StringResultCode
+
+ This enum is returned by readString() and readByteArray() and is used to
+ indicate what the status of the parsing is.
+
+ \value EndOfString The parsing for the string is complete, with no error.
+ \value Ok The function returned data; there was no error.
+ \value Error Parsing failed with an error.
+ */
+
+/*!
+ \class QCborStreamReader::StringResult
+
+ This class is returned by readString() and readByteArray(), with either the
+ contents of the string that was read or an indication that the parsing is
+ done or found an error.
+
+ The contents of \l data are valid only if \l status is
+ \l{StringResultCode}{Ok}. Otherwise, it should be null.
+ */
+
+/*!
+ \variable Container QCborStreamReader::StringResult::data
+ Contains the actual data from the string if \l status is \c Ok.
+ */
+
+/*!
+ \variable QCborStreamReader::StringResultCode QCborStreamReader::StringResult::status
+ Contains the status of the attempt of reading the string from the stream.
+ */
+
+/*!
+ \fn QCborStreamReader::Type QCborStreamReader::type() const
+
+ Returns the type of the current element. It is one of the valid types or
+ Invalid.
+
+ \sa isValid(), isUnsignedInteger(), isNegativeInteger(), isInteger(),
+ isByteArray(), isString(), isArray(), isMap(), isTag(), isSimpleType(),
+ isBool(), isFalse(), isTrue(), isNull(), isUndefined(), isFloat16(),
+ isFloat(), isDouble()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isValid() const
+
+ Returns true if the current element is valid, false otherwise. The current
+ element may be invalid if there was a decoding error or we've just parsed
+ the last element in an array or map.
+
+ \note This function is not the opposite of isNull(). Null is a normal CBOR
+ type that must be handled by the application.
+
+ \sa type(), isInvalid()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isInvalid() const
+
+ Returns true if the current element is invalid, false otherwise. The current
+ element may be invalid if there was a decoding error or we've just parsed
+ the last element in an array or map.
+
+ \note This function is not to be confused with isNull(). Null is a normal
+ CBOR type that must be handled by the application.
+
+ \sa type(), isValid()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isUnsignedInteger() const
+
+ Returns true if the type of the current element is an unsigned integer (that
+ is if type() returns QCborStreamReader::UnsignedInteger). If this function
+ returns true, you may call toUnsignedInteger() or toInteger() to read that value.
+
+ \sa type(), toUnsignedInteger(), toInteger(), isInteger(), isNegativeInteger()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isNegativeInteger() const
+
+ Returns true if the type of the current element is a negative integer (that
+ is if type() returns QCborStreamReader::NegativeInteger). If this function
+ returns true, you may call toNegativeInteger() or toInteger() to read that value.
+
+ \sa type(), toNegativeInteger(), toInteger(), isInteger(), isUnsignedInteger()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isInteger() const
+
+ Returns true if the type of the current element is either an unsigned
+ integer or a negative one (that is, if type() returns
+ QCborStreamReader::UnsignedInteger or QCborStreamReader::NegativeInteger).
+ If this function returns true, you may call toInteger() to read that
+ value.
+
+ \sa type(), toInteger(), toUnsignedInteger(), toNegativeInteger(),
+ isUnsignedInteger(), isNegativeInteger()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isByteArray() const
+
+ Returns true if the type of the current element is a byte array (that is,
+ if type() returns QCborStreamReader::ByteArray). If this function returns
+ true, you may call readByteArray() to read that data.
+
+ \sa type(), readByteArray(), isString()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isString() const
+
+ Returns true if the type of the current element is a text string (that is,
+ if type() returns QCborStreamReader::String). If this function returns
+ true, you may call readString() to read that data.
+
+ \sa type(), readString(), isByteArray()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isArray() const
+
+ Returns true if the type of the current element is an array (that is,
+ if type() returns QCborStreamReader::Array). If this function returns
+ true, you may call enterContainer() to begin parsing that container.
+
+ When the current element is an array, you may also call isLengthKnown() to
+ find out if the array's size is explicit in the CBOR stream. If it is, that
+ size can be obtained by calling length().
+
+ The following example pre-allocates a QVariantList given the array's size
+ for more efficient decoding:
+
+ \code
+ QVariantList populateFromCbor(QCborStreamReader &reader)
+ {
+ QVariantList list;
+ if (reader.isLengthKnown())
+ list.reserve(reader.length());
+
+ reader.enterContainer();
+ while (reader.lastError() == QCborError::NoError && reader.hasNext())
+ list.append(readOneElement(reader));
+ if (reader.lastError() == QCborError::NoError)
+ reader.leaveContainer();
+ }
+ \endcode
+
+ \note The code above does not validate that the length is a sensible value.
+ If the input stream reports that the length is 1 billion elements, the above
+ function will try to allocate some 16 GB or more of RAM, which can lead to a
+ crash.
+
+ \sa type(), isMap(), isLengthKnown(), length(), enterContainer(), leaveContainer()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isMap() const
+
+ Returns true if the type of the current element is a map (that is, if type()
+ returns QCborStreamReader::Map). If this function returns true, you may call
+ enterContainer() to begin parsing that container.
+
+ When the current element is a map, you may also call isLengthKnown() to
+ find out if the map's size is explicit in the CBOR stream. If it is, that
+ size can be obtained by calling length().
+
+ The following example pre-allocates a QVariantMap given the map's size
+ for more efficient decoding:
+
+ \code
+ QVariantMap populateFromCbor(QCborStreamReader &reader)
+ {
+ QVariantMap map;
+ if (reader.isLengthKnown())
+ map.reserve(reader.length());
+
+ reader.enterContainer();
+ while (reader.lastError() == QCborError::NoError && reader.hasNext()) {
+ QString key = readElementAsString(reader);
+ map.insert(key, readOneElement(reader));
+ }
+ if (reader.lastError() == QCborError::NoError)
+ reader.leaveContainer();
+ }
+ \endcode
+
+ The example above uses a function called \c readElementAsString to read the
+ map's keys and obtain a string. That is because CBOR maps may contain any
+ type as keys, not just strings. User code needs to either perform this
+ conversion, reject non-string keys, or instead use a different container
+ besides \l QVariantMap and \l QVariantHash. For example, if the map is
+ expected to contain integer keys, which is recommended as it reduces stream
+ size and parsing, the correct container would be \c{\l{QMap}<int, QVariant>}
+ or \c{\l{QHash}<int, QVariant>}.
+
+ \note The code above does not validate that the length is a sensible value.
+ If the input stream reports that the length is 1 billion elements, the above
+ function will try to allocate some 24 GB or more of RAM, which can lead to a
+ crash.
+
+ \sa type(), isArray(), isLengthKnown(), length(), enterContainer(), leaveContainer()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isTag() const
+
+ Returns true if the type of the current element is a CBOR tag (that is,
+ if type() returns QCborStreamReader::Tag). If this function returns
+ true, you may call toTag() to read that data.
+
+ \sa type(), toTag()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isFloat16() const
+
+ Returns true if the type of the current element is an IEEE 754
+ half-precision floating point (that is, if type() returns
+ QCborStreamReader::Float16). If this function returns true, you may call
+ toFloat16() to read that data.
+
+ \sa type(), toFloat16(), isFloat(), isDouble()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isFloat() const
+
+ Returns true if the type of the current element is an IEEE 754
+ single-precision floating point (that is, if type() returns
+ QCborStreamReader::Float). If this function returns true, you may call
+ toFloat() to read that data.
+
+ \sa type(), toFloat(), isFloat16(), isDouble()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isDouble() const
+
+ Returns true if the type of the current element is an IEEE 754
+ double-precision floating point (that is, if type() returns
+ QCborStreamReader::Double). If this function returns true, you may call
+ toDouble() to read that data.
+
+ \sa type(), toDouble(), isFloat16(), isFloat()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isSimpleType() const
+
+ Returns true if the type of the current element is any CBOR simple type,
+ including a boolean value (true and false) as well as null and undefined. To
+ find out which simple type this is, call toSimpleType(). Alternatively, to
+ test for one specific simple type, call the overload that takes a
+ QCborSimpleType parameter.
+
+ CBOR simple types are types that do not carry extra value. There are 255
+ possibilities, but there are currently only four values that have defined
+ meaning. Code is not expected to cope with unknown simple types and may
+ simply discard the stream as invalid if it finds an unknown one.
+
+ \sa QCborSimpleType, type(), isSimpleType(QCborSimpleType), toSimpleType()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isSimpleType(QCborSimpleType st) const
+
+ Returns true if the type of the current element is the simple type \a st,
+ false otherwise. If this function returns true, then toSimpleType() will
+ return \a st.
+
+ CBOR simple types are types that do not carry extra value. There are 255
+ possibilities, but there are currently only four values that have defined
+ meaning. Code is not expected to cope with unknown simple types and may
+ simply discard the stream as invalid if it finds an unknown one.
+
+ \sa QCborSimpleType, type(), isSimpleType(), toSimpleType()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isFalse() const
+
+ Returns true if the current element is the \c false value, false if it is
+ anything else.
+
+ \sa type(), isTrue(), isBool(), toBool(), isSimpleType(), toSimpleType()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isTrue() const
+
+ Returns true if the current element is the \c true value, false if it is
+ anything else.
+
+ \sa type(), isFalse(), isBool(), toBool(), isSimpleType(), toSimpleType()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isBool() const
+
+ Returns true if the current element is a boolean value (\c true or \c
+ false), false if it is anything else. If this function returns true, you may
+ call toBool() to retrieve the value of the boolean. You may also call
+ toSimpleType() and compare to either QCborSimpleValue::True or
+ QCborSimpleValue::False.
+
+ \sa type(), isFalse(), isTrue(), toBool(), isSimpleType(), toSimpleType()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isNull() const
+
+ Returns true if the current element is the \c null value, false if it is
+ anything else. Null values may be used to indicate the absence of some
+ optional data.
+
+ \note This function is not the opposite of isValid(). A Null value is a
+ valid CBOR value.
+
+ \sa type(), isSimpleType(), toSimpleType()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isUndefined() const
+
+ Returns true if the current element is the \c undefined value, false if it
+ is anything else. Undefined values may be encoded to indicate that some
+ conversion failed or was not possible when creating the stream.
+ QCborStreamReader never performs any replacement and this function will only
+ return true if the stream contains an explicit undefined value.
+
+ \sa type(), isSimpleType(), toSimpleType()
+ */
+
+/*!
+ \fn bool QCborStreamReader::isContainer() const
+
+ Returns true if the current element is a container (that is, an array or a
+ map), false if it is anything else. If the current element is a container,
+ the isLengthKnown() function may be used to find out if the container's size
+ is explicit in the stream and, if so, length() can be used to get that size.
+
+ More importantly, for a container, the enterContainer() function is
+ available to begin iterating through the elements contained therein.
+
+ \sa type(), isArray(), isMap(), isLengthKnown(), length(), enterContainer(),
+ leaveContainer(), containerDepth()
+ */
+
+class QCborStreamReaderPrivate
+{
+public:
+ enum {
+ // 9 bytes is the maximum size for any integer, floating point or
+ // length in CBOR.
+ MaxCborIndividualSize = 9,
+ IdealIoBufferSize = 256
+ };
+
+ QIODevice *device;
+ QByteArray buffer;
+ QStack<CborValue> containerStack;
+
+ CborParser parser;
+ CborValue currentElement;
+ QCborError lastError = {};
+
+ QByteArray::size_type bufferStart;
+ bool corrupt = false;
+
+ QCborStreamReaderPrivate(const QByteArray &data)
+ : device(nullptr), buffer(data)
+ {
+ initDecoder();
+ }
+
+ QCborStreamReaderPrivate(QIODevice *device)
+ {
+ setDevice(device);
+ }
+
+ ~QCborStreamReaderPrivate()
+ {
+ }
+
+ void setDevice(QIODevice *dev)
+ {
+ buffer.clear();
+ device = dev;
+ initDecoder();
+ }
+
+ void initDecoder()
+ {
+ containerStack.clear();
+ bufferStart = 0;
+ if (device) {
+ buffer.clear();
+ buffer.reserve(IdealIoBufferSize); // sets the CapacityReserved flag
+ }
+
+ preread();
+ if (CborError err = cbor_parser_init_reader(nullptr, &parser, &currentElement, this))
+ handleError(err);
+ }
+
+ char *bufferPtr()
+ {
+ Q_ASSERT(buffer.isDetached());
+ return const_cast<char *>(buffer.constData()) + bufferStart;
+ }
+
+ void preread()
+ {
+ if (device && buffer.size() - bufferStart < MaxCborIndividualSize) {
+ // load more, but only if there's more to be read
+ qint64 avail = device->bytesAvailable();
+ Q_ASSERT(avail >= buffer.size());
+ if (avail == buffer.size())
+ return;
+
+ if (bufferStart)
+ device->skip(bufferStart); // skip what we've already parsed
+
+ if (buffer.size() != IdealIoBufferSize)
+ buffer.resize(IdealIoBufferSize);
+
+ bufferStart = 0;
+ qint64 read = device->peek(bufferPtr(), IdealIoBufferSize);
+ if (read < 0)
+ buffer.clear();
+ else if (read != IdealIoBufferSize)
+ buffer.truncate(read);
+ }
+ }
+
+ void handleError(CborError err) noexcept
+ {
+ Q_ASSERT(err);
+
+ // is the error fatal?
+ if (err != CborErrorUnexpectedEOF)
+ corrupt = true;
+
+ // our error codes are the same (for now)
+ lastError = { QCborError::Code(err) };
+ }
+
+ void updateBufferAfterString(qsizetype offset, qsizetype size)
+ {
+ Q_ASSERT(device);
+
+ bufferStart += offset;
+ qsizetype newStart = bufferStart + size;
+ qsizetype remainingInBuffer = buffer.size() - newStart;
+
+ if (remainingInBuffer <= 0) {
+ // We've read from the QIODevice more than what was in the buffer.
+ buffer.truncate(0);
+ } else {
+ // There's still data buffered, but we need to move it around.
+ char *ptr = buffer.data();
+ memmove(ptr, ptr + newStart, remainingInBuffer);
+ buffer.truncate(remainingInBuffer);
+ }
+
+ bufferStart = 0;
+ }
+
+ bool ensureStringIteration();
+};
+
+void qt_cbor_stream_set_error(QCborStreamReaderPrivate *d, QCborError error)
+{
+ d->handleError(CborError(error.c));
+}
+
+static inline bool qt_cbor_decoder_can_read(void *token, size_t len)
+{
+ Q_ASSERT(len <= QCborStreamReaderPrivate::MaxCborIndividualSize);
+ auto self = static_cast<QCborStreamReaderPrivate *>(token);
+
+ qint64 avail = self->buffer.size() - self->bufferStart;
+ return len <= quint64(avail);
+}
+
+static void qt_cbor_decoder_advance(void *token, size_t len)
+{
+ Q_ASSERT(len <= QCborStreamReaderPrivate::MaxCborIndividualSize);
+ auto self = static_cast<QCborStreamReaderPrivate *>(token);
+ Q_ASSERT(len <= size_t(self->buffer.size() - self->bufferStart));
+
+ self->bufferStart += int(len);
+ self->preread();
+}
+
+static void *qt_cbor_decoder_read(void *token, void *userptr, size_t offset, size_t len)
+{
+ Q_ASSERT(len == 1 || len == 2 || len == 4 || len == 8);
+ Q_ASSERT(offset == 0 || offset == 1);
+ auto self = static_cast<const QCborStreamReaderPrivate *>(token);
+
+ // we must have pre-read the data
+ Q_ASSERT(len + offset <= size_t(self->buffer.size() - self->bufferStart));
+ return memcpy(userptr, self->buffer.constData() + self->bufferStart + offset, len);
+}
+
+static CborError qt_cbor_decoder_transfer_string(void *token, const void **userptr, size_t offset, size_t len)
+{
+ auto self = static_cast<QCborStreamReaderPrivate *>(token);
+ Q_ASSERT(offset <= size_t(self->buffer.size()));
+ Q_STATIC_ASSERT(sizeof(size_t) >= sizeof(QByteArray::size_type));
+ Q_STATIC_ASSERT(sizeof(size_t) == sizeof(qsizetype));
+
+ // check that we will have enough data from the QIODevice before we advance
+ // (otherwise, we'd lose the length information)
+ qsizetype total;
+ if (len > size_t(std::numeric_limits<QByteArray::size_type>::max())
+ || add_overflow<qsizetype>(offset, len, &total))
+ return CborErrorDataTooLarge;
+
+ // our string transfer is just saving the offset to the userptr
+ *userptr = reinterpret_cast<void *>(offset);
+
+ qint64 avail = (self->device ? self->device->bytesAvailable() : self->buffer.size()) -
+ self->bufferStart;
+ return total > avail ? CborErrorUnexpectedEOF : CborNoError;
+}
+
+bool QCborStreamReaderPrivate::ensureStringIteration()
+{
+ if (currentElement.flags & CborIteratorFlag_IteratingStringChunks)
+ return true;
+
+ CborError err = cbor_value_begin_string_iteration(&currentElement);
+ if (!err)
+ return true;
+ handleError(err);
+ return false;
+}
+
+/*!
+ \internal
+ */
+inline void QCborStreamReader::preparse()
+{
+ if (lastError() == QCborError::NoError) {
+ type_ = cbor_value_get_type(&d->currentElement);
+
+ if (type_ != CborInvalidType) {
+ d->lastError = {};
+ // Undo the type mapping that TinyCBOR does (we have an explicit type
+ // for negative integer and we don't have separate types for Boolean,
+ // Null and Undefined).
+ if (type_ == CborBooleanType || type_ == CborNullType || type_ == CborUndefinedType) {
+ type_ = SimpleType;
+ value64 = quint8(d->buffer.at(d->bufferStart)) - CborSimpleType;
+ } else {
+ // Using internal TinyCBOR API!
+ value64 = _cbor_value_extract_int64_helper(&d->currentElement);
+
+ if (cbor_value_is_negative_integer(&d->currentElement))
+ type_ = quint8(QCborStreamReader::NegativeInteger);
+ }
+ }
+ } else {
+ type_ = Invalid;
+ }
+}
+
+/*!
+ Creates a QCborStreamReader object with no source data. After construction,
+ QCborStreamReader will report an error parsing.
+
+ You can add more data by calling addData() or by setting a different source
+ device using setDevice().
+
+ \sa addData(), isValid()
+ */
+QCborStreamReader::QCborStreamReader()
+ : QCborStreamReader(QByteArray())
+{
+}
+
+/*!
+ \overload
+
+ Creates a QCborStreamReader object with \a len bytes of data starting at \a
+ data. The pointer must remain valid until QCborStreamReader is destroyed.
+ */
+QCborStreamReader::QCborStreamReader(const char *data, qsizetype len)
+ : QCborStreamReader(QByteArray::fromRawData(data, len))
+{
+}
+
+/*!
+ \overload
+
+ Creates a QCborStreamReader object with \a len bytes of data starting at \a
+ data. The pointer must remain valid until QCborStreamReader is destroyed.
+ */
+QCborStreamReader::QCborStreamReader(const quint8 *data, qsizetype len)
+ : QCborStreamReader(QByteArray::fromRawData(reinterpret_cast<const char *>(data), len))
+{
+}
+
+/*!
+ \overload
+
+ Creates a QCborStreamReader object that will parse the CBOR stream found in
+ \a data.
+ */
+QCborStreamReader::QCborStreamReader(const QByteArray &data)
+ : d(new QCborStreamReaderPrivate(data))
+{
+ preparse();
+}
+
+/*!
+ \overload
+
+ Creates a QCborStreamReader object that will parse the CBOR stream found by
+ reading from \a device. QCborStreamReader does not take ownership of \a
+ device, so it must remain valid until this oject is destroyed.
+ */
+QCborStreamReader::QCborStreamReader(QIODevice *device)
+ : d(new QCborStreamReaderPrivate(device))
+{
+ preparse();
+}
+
+/*!
+ Destroys this QCborStreamReader object and frees any associated resources.
+ */
+QCborStreamReader::~QCborStreamReader()
+{
+}
+
+/*!
+ Sets the source of data to \a device, resetting the decoder to its initial
+ state.
+ */
+void QCborStreamReader::setDevice(QIODevice *device)
+{
+ d->setDevice(device);
+ preparse();
+}
+
+/*!
+ Returns the QIODevice that was set with either setDevice() or the
+ QCborStreamReader constructor. If this object was reading from a QByteArray,
+ this function returns nullptr instead.
+ */
+QIODevice *QCborStreamReader::device() const
+{
+ return d->device;
+}
+
+/*!
+ Adds \a data to the CBOR stream and reparses the current element. This
+ function is useful if the end of the data was previously reached while
+ processing the stream, but now more data is available.
+ */
+void QCborStreamReader::addData(const QByteArray &data)
+{
+ addData(data.constData(), data.size());
+}
+
+/*!
+ \fn void QCborStreamReader::addData(const quint8 *data, qsizetype len)
+ \overload
+
+ Adds \a len bytes of data starting at \a data to the CBOR stream and
+ reparses the current element. This function is useful if the end of the data
+ was previously reached while processing the stream, but now more data is
+ available.
+ */
+
+/*!
+ \overload
+
+ Adds \a len bytes of data starting at \a data to the CBOR stream and
+ reparses the current element. This function is useful if the end of the data
+ was previously reached while processing the stream, but now more data is
+ available.
+ */
+void QCborStreamReader::addData(const char *data, qsizetype len)
+{
+ if (!d->device) {
+ if (len > 0)
+ d->buffer.append(data, len);
+ reparse();
+ } else {
+ qWarning("QCborStreamReader: addData() with device()");
+ }
+}
+
+/*!
+ Reparses the current element. This function must be called when more data
+ becomes available in the source QIODevice after parsing failed due to
+ reaching the end of the input data before the end of the CBOR stream.
+
+ When reading from QByteArray(), the addData() function automatically calls
+ this function. Calling it when the reading had not failed is a no-op.
+ */
+void QCborStreamReader::reparse()
+{
+ d->lastError = {};
+ d->preread();
+ if (CborError err = cbor_value_reparse(&d->currentElement))
+ d->handleError(err);
+ else
+ preparse();
+}
+
+/*!
+ Clears the decoder state and resets the input source data to an empty byte
+ array. After this function is called, QCborStreamReader will be indicating
+ an error parsing.
+
+ Call addData() to add more data to be parsed.
+
+ \sa reset(), setDevice()
+ */
+void QCborStreamReader::clear()
+{
+ setDevice(nullptr);
+}
+
+/*!
+ Resets the source back to the beginning and clears the decoder state. If the
+ source data was a QByteArray, QCborStreamReader will restart from the
+ beginning of the array.
+
+ If the source data is a QIODevice, this function will call
+ QIODevice::reset(), which will seek to byte position 0. If the CBOR stream
+ is not found at the beginning of the device (e.g., beginning of a file),
+ then this function will likely do the wrong thing. Instead, position the
+ QIODevice to the right offset and call setDevice().
+
+ \sa clear(), setDevice()
+ */
+void QCborStreamReader::reset()
+{
+ if (d->device)
+ d->device->reset();
+ d->lastError = {};
+ d->initDecoder();
+ preparse();
+}
+
+/*!
+ Returns the last error in decoding the stream, if any. If no error
+ was encountered, this returns an QCborError::NoError.
+
+ \sa isValid()
+ */
+QCborError QCborStreamReader::lastError()
+{
+ return d->lastError;
+}
+
+/*!
+ Returns the offset in the input stream of the item currently being decoded.
+ The current offset is the number of decoded bytes so far only if the source
+ data is a QByteArray or it is a QIODevice that was positioned at its
+ beginning when decoding started.
+
+ \sa reset(), clear(), device()
+ */
+qint64 QCborStreamReader::currentOffset() const
+{
+ return (d->device ? d->device->pos() : 0) + d->bufferStart;
+}
+
+/*!
+ Returns the number of containers that this stream has entered with
+ enterContainer() but not yet left.
+
+ \sa enterContainer(), leaveContainer()
+ */
+int QCborStreamReader::containerDepth() const
+{
+ return d->containerStack.size();
+}
+
+/*!
+ Returns either QCborStreamReader::Array or QCborStreamReader::Map,
+ indicating whether the container that contains the current item was an array
+ or map, respectively. If we're currently parsing the root element, this
+ function returns QCborStreamReader::Invalid.
+
+ \sa containerDepth(), enterContainer()
+ */
+QCborStreamReader::Type QCborStreamReader::parentContainerType() const
+{
+ if (d->containerStack.isEmpty())
+ return Invalid;
+ return Type(cbor_value_get_type(&qAsConst(d->containerStack).top()));
+}
+
+/*!
+ Returns true if there are more items to be decoded in the current container
+ or false of we've reached its end. If we're parsing the root element,
+ hasNext() returning false indicates the parsing is complete; otherwise, if
+ the container depth is non-zero, then the outer code needs to call
+ leaveContainer().
+
+ \sa parentContainerType(), containerDepth(), leaveContainer()
+ */
+bool QCborStreamReader::hasNext() const noexcept
+{
+ return cbor_value_is_valid(&d->currentElement) &&
+ !cbor_value_at_end(&d->currentElement);
+}
+
+/*!
+ Advance the CBOR stream decoding one element. You should usually call this
+ function when parsing fixed-width basic elements (that is, integers, simple
+ values, tags and floating point values). But this function can be called
+ when the current item is a string, array or map too and it will skip over
+ that entire element, including all contained elements.
+
+ This function returns true if advancing was successful, false otherwise. It
+ may fail if the stream is corrupt, incomplete or if the nesting level of
+ arrays and maps exceeds \a maxRecursion. Calling this function when
+ hasNext() has returned false is also an error. If this function returns
+ false, lastError() will return the error code detailing what the failure
+ was.
+
+ \sa lastError(), isValid(), hasNext()
+ */
+bool QCborStreamReader::next(int maxRecursion)
+{
+ if (lastError() != QCborError::NoError)
+ return false;
+
+ if (!hasNext()) {
+ d->handleError(CborErrorAdvancePastEOF);
+ } else if (maxRecursion < 0) {
+ d->handleError(CborErrorNestingTooDeep);
+ } else if (isContainer()) {
+ // iterate over each element
+ enterContainer();
+ while (lastError() == QCborError::NoError && hasNext())
+ next(maxRecursion - 1);
+ if (lastError() == QCborError::NoError)
+ leaveContainer();
+ } else if (isString() || isByteArray()) {
+ auto r = _readByteArray_helper();
+ while (r.status == Ok) {
+ if (isString() && !QUtf8::isValidUtf8(r.data, r.data.size()).isValidUtf8) {
+ d->handleError(CborErrorInvalidUtf8TextString);
+ break;
+ }
+ r = _readByteArray_helper();
+ }
+ } else {
+ // fixed types
+ CborError err = cbor_value_advance_fixed(&d->currentElement);
+ if (err)
+ d->handleError(err);
+ }
+
+ preparse();
+ return d->lastError == QCborError::NoError;
+}
+
+/*!
+ Returns true if the length of the current array, map, byte array or string
+ is known (explicit in the CBOR stream), false otherwise. This function
+ should only be called if the element is one of those.
+
+ If the length is known, it may be obtained by calling length().
+
+ If the length of a map or an array is not known, it is implied by the number
+ of elements present in the stream. QCborStreamReader has no API to calculate
+ the length in that condition.
+
+ Strings and byte arrays may also have indeterminate length (that is, they
+ may be transmitted in multiple chunks). Those cannot currently be created
+ with QCborStreamWriter, but they could be with other encoders, so
+ QCborStreamReader supports them.
+
+ \sa length(), QCborStreamWriter::startArray(), QCborStreamWriter::startMap()
+ */
+bool QCborStreamReader::isLengthKnown() const noexcept
+{
+ return cbor_value_is_length_known(&d->currentElement);
+}
+
+/*!
+ Returns the length of the string or byte array, or the number of items in an
+ array or the number, of item pairs in a map, if known. This function must
+ not be called if the length is unknown (that is, if isLengthKnown() returned
+ false). It is an error to do that and it will cause QCborStreamReader to
+ stop parsing the input stream.
+
+ \sa isLengthKnown(), QCborStreamWriter::startArray(), QCborStreamWriter::startMap()
+ */
+quint64 QCborStreamReader::length() const
+{
+ CborError err;
+ switch (type()) {
+ case String:
+ case ByteArray:
+ case Map:
+ case Array:
+ if (isLengthKnown())
+ return value64;
+ err = CborErrorUnknownLength;
+ break;
+
+ default:
+ err = CborErrorIllegalType;
+ break;
+ }
+
+ d->handleError(err);
+ return quint64(-1);
+}
+
+/*!
+ \fn bool QCborStreamReader::enterContainer()
+
+ Enters the array or map that is the current item and prepares for iterating
+ the elements contained in the container. Returns true if entering the
+ container succeeded, false otherwise (usually, a parsing error). Each call
+ to enterContainer() must be paired with a call to leaveContainer().
+
+ This function may only be called if the current item is an array or a map
+ (that is, if isArray(), isMap() or isContainer() is true). Calling it in any
+ other condition is an error.
+
+ \sa leaveContainer(), isContainer(), isArray(), isMap()
+ */
+bool QCborStreamReader::_enterContainer_helper()
+{
+ d->containerStack.push(d->currentElement);
+ CborError err = cbor_value_enter_container(&d->containerStack.top(), &d->currentElement);
+ if (!err) {
+ preparse();
+ return true;
+ }
+ d->handleError(err);
+ return false;
+}
+
+/*!
+ Leaves the array or map whose items were being processed and positions the
+ decoder at the next item after the end of the container. Returns true if
+ leaving the container succeeded, false otherwise (usually, a parsing error).
+ Each call to enterContainer() must be paired with a call to
+ leaveContainer().
+
+ This function may only be called if hasNext() has returned false and
+ containerDepth() is not zero. Calling it in any other condition is an error.
+
+ \sa enterContainer(), parentContainerType(), containerDepth()
+ */
+bool QCborStreamReader::leaveContainer()
+{
+ if (d->containerStack.isEmpty()) {
+ qWarning("QCborStreamReader::leaveContainer: trying to leave top-level element");
+ return false;
+ }
+ if (d->corrupt)
+ return false;
+
+ CborValue container = d->containerStack.pop();
+ CborError err = cbor_value_leave_container(&container, &d->currentElement);
+ d->currentElement = container;
+ if (err) {
+ d->handleError(err);
+ return false;
+ }
+
+ preparse();
+ return true;
+}
+
+/*!
+ \fn bool QCborStreamReader::toBool() const
+
+ Returns the boolean value of the current element.
+
+ This function does not perform any type conversions, including from integer.
+ Therefore, it may only be called if isTrue(), isFalse() or isBool() returned
+ true; calling it in any other condition is an error.
+
+ \sa isBool(), isTrue(), isFalse(), toInteger()
+ */
+
+/*!
+ \fn QCborTag QCborStreamReader::toTag() const
+
+ Returns the tag value of the current element.
+
+ This function does not perform any type conversions, including from integer.
+ Therefore, it may only be called if isTag() is true; calling it in any other
+ condition is an error.
+
+ Tags are 64-bit numbers attached to generic CBOR types that give them
+ further meaning. For a list of known tags, see the \l QCborKnownTags
+ enumeration.
+
+ \sa isTag(), toInteger(), QCborKnownTags
+ */
+
+/*!
+ \fn quint64 QCborStreamReader::toUnsignedInteger() const
+
+ Returns the unsigned integer value of the current element.
+
+ This function does not perform any type conversions, including from boolean
+ or CBOR tag. Therefore, it may only be called if isUnsignedInteger() is
+ true; calling it in any other condition is an error.
+
+ This function may be used to obtain numbers beyond the range of the return
+ type of toInteger().
+
+ \sa type(), toInteger(), isUnsignedInteger(), isNegativeInteger()
+ */
+
+/*!
+ \fn QCborNegativeValue QCborStreamReader::toNegativeInteger() const
+
+ Returns the negative integer value of the current element.
+ QCborNegativeValue is a 64-bit unsigned integer containing the absolute
+ value of the negative number that was stored in the CBOR stream.
+ Additionally, QCborNegativeValue(0) represents the number -2\sup{64}.
+
+ This function does not perform any type conversions, including from boolean
+ or CBOR tag. Therefore, it may only be called if isNegativeInteger() is
+ true; calling it in any other condition is an error.
+
+ This function may be used to obtain numbers beyond the range of the return
+ type of toInteger(). However, use of negative numbers smaller than -2\sup{63}
+ is extremely discouraged.
+
+ \sa type(), toInteger(), isNegativeInteger(), isUnsignedInteger()
+ */
+
+/*!
+ \fn qint64 QCborStreamReader::toInteger() const
+
+ Returns the integer value of the current element, be it negative, positive
+ or zero. If the value is larger than 2\sup{63} - 1 or smaller than
+ -2\sup{63}, the returned value will overflow and will have an incorrect
+ sign. If handling those values is required, use toUnsignedInteger() or
+ toNegativeInteger() instead.
+
+ This function does not perform any type conversions, including from boolean
+ or CBOR tag. Therefore, it may only be called if isInteger() is true;
+ calling it in any other condition is an error.
+
+ \sa isInteger(), toUnsignedInteger(), toNegativeInteger()
+ */
+
+/*!
+ \fn QCborSimpleType QCborStreamReader::toSimpleType() const
+
+ Returns value of the current simple type.
+
+ This function does not perform any type conversions, including from integer.
+ Therefore, it may only be called if isSimpleType() is true; calling it in
+ any other condition is an error.
+
+ \sa isSimpleType(), isTrue(), isFalse(), isBool(), isNull(), isUndefined()
+ */
+
+/*!
+ \fn qfloat16 QCborStreamReader::toFloat16() const
+
+ Returns the 16-bit half-precision floating point value of the current element.
+
+ This function does not perform any type conversions, including from other
+ floating point types or from integer values. Therefore, it may only be
+ called if isFloat16() is true; calling it in any other condition is an
+ error.
+
+ \sa isFloat16(), toFloat(), toDouble()
+ */
+
+/*!
+ \fn float QCborStreamReader::toFloat() const
+
+ Returns the 32-bit single-precision floating point value of the current
+ element.
+
+ This function does not perform any type conversions, including from other
+ floating point types or from integer values. Therefore, it may only be
+ called if isFloat() is true; calling it in any other condition is an error.
+
+ \sa isFloat(), toFloat16(), toDouble()
+ */
+
+/*!
+ \fn double QCborStreamReader::toDouble() const
+
+ Returns the 64-bit double-precision floating point value of the current
+ element.
+
+ This function does not perform any type conversions, including from other
+ floating point types or from integer values. Therefore, it may only be
+ called if isDouble() is true; calling it in any other condition is an error.
+
+ \sa isDouble(), toFloat16(), toFloat()
+ */
+
+/*!
+ \fn QCborStreamReader::StringResult<QString> QCborStreamReader::readString()
+
+ Decodes one string chunk from the CBOR string and returns it. This function
+ is used for both regular and chunked string contents, so the caller must
+ always loop around calling this function, even if isLengthKnown() has
+ is true. The typical use of this function is as follows:
+
+ \code
+ QString decodeString(QCborStreamReader &reader)
+ {
+ QString result;
+ auto r = reader.readString();
+ while (r.code == QCborStreamReader::Ok) {
+ result += r.data;
+ r = reader.readString();
+ }
+
+ if (r.code == QCborStreamReader::Error) {
+ // handle error condition
+ result.clear();
+ }
+ return result;
+ }
+ \endcode
+
+ This function does not perform any type conversions, including from integers
+ or from byte arrays. Therefore, it may only be called if isString() returned
+ true; calling it in any other condition is an error.
+
+ \sa readByteArray(), isString(), readStringChunk()
+ */
+QCborStreamReader::StringResult<QString> QCborStreamReader::_readString_helper()
+{
+ auto r = _readByteArray_helper();
+ QCborStreamReader::StringResult<QString> result;
+ result.status = r.status;
+
+ if (r.status == Ok) {
+ QTextCodec::ConverterState cs;
+ result.data = QUtf8::convertToUnicode(r.data, r.data.size(), &cs);
+ if (cs.invalidChars == 0 && cs.remainingChars == 0)
+ return result;
+
+ d->handleError(CborErrorInvalidUtf8TextString);
+ result.data.clear();
+ result.status = Error;
+ return result;
+ }
+ return result;
+}
+
+/*!
+ \fn QCborStreamReader::StringResult<QString> QCborStreamReader::readByteArray()
+
+ Decodes one byte array chunk from the CBOR string and returns it. This
+ function is used for both regular and chunked contents, so the caller must
+ always loop around calling this function, even if isLengthKnown() has
+ is true. The typical use of this function is as follows:
+
+ \code
+ QBytearray decodeBytearray(QCborStreamReader &reader)
+ {
+ QBytearray result;
+ auto r = reader.readBytearray();
+ while (r.code == QCborStreamReader::Ok) {
+ result += r.data;
+ r = reader.readByteArray();
+ }
+
+ if (r.code == QCborStreamReader::Error) {
+ // handle error condition
+ result.clear();
+ }
+ return result;
+ }
+ \endcode
+
+ This function does not perform any type conversions, including from integers
+ or from strings. Therefore, it may only be called if isByteArray() is true;
+ calling it in any other condition is an error.
+
+ \sa readString(), isByteArray(), readStringChunk()
+ */
+QCborStreamReader::StringResult<QByteArray> QCborStreamReader::_readByteArray_helper()
+{
+ QCborStreamReader::StringResult<QByteArray> result;
+ result.status = Error;
+ qsizetype len = _currentStringChunkSize();
+ if (len < 0)
+ return result;
+
+ result.data.resize(len);
+ auto r = readStringChunk(result.data.data(), len);
+ Q_ASSERT(r.status != Ok || r.data == len);
+ result.status = r.status;
+ return result;
+}
+
+/*!
+ \fn qsizetype QCborStreamReader::currentStringChunkSize() const
+
+ Returns the size of the current text or byte string chunk. If the CBOR
+ stream contains a non-chunked string (that is, if isLengthKnown() returns
+ \c true), this function returns the size of the entire string, the same as
+ length().
+
+ This function is useful to pre-allocate the buffer whose pointer can be passed
+ to readStringChunk() later.
+
+ \sa readString(), readByteArray(), readStringChunk()
+ */
+qsizetype QCborStreamReader::_currentStringChunkSize() const
+{
+ if (!d->ensureStringIteration())
+ return -1;
+
+ size_t len;
+ CborError err = cbor_value_get_string_chunk_size(&d->currentElement, &len);
+ if (err == CborErrorNoMoreStringChunks)
+ return 0; // not a real error
+ else if (err)
+ d->handleError(err);
+ else if (qsizetype(len) < 0)
+ d->handleError(CborErrorDataTooLarge);
+ else
+ return qsizetype(len);
+ return -1;
+}
+
+/*!
+ Reads the current string chunk into the buffer pointed to by \a ptr, whose
+ size is \a maxlen. This function returns a \l StringResult object, with the
+ number of bytes copied into \a ptr saved in the \c \l StringResult::data
+ member. The \c \l StringResult::status member indicates whether there was
+ an error reading the string, whether data was copied or whether this was
+ the last chunk.
+
+ This function can be called for both \l String and \l ByteArray types.
+ For the latter, this function will read the same data that readByteArray()
+ would have returned. For strings, it returns the UTF-8 equivalent of the \l
+ QString that would have been returned.
+
+ This function is usually used alongside currentStringChunkSize() in a loop.
+ For example:
+
+ \code
+ QCborStreamReader<qsizetype> result;
+ do {
+ qsizetype size = reader.currentStringChunkSize();
+ qsizetype oldsize = buffer.size();
+ buffer.resize(oldsize + size);
+ result = reader.readStringChunk(buffer.data() + oldsize, size);
+ } while (result.status() == QCborStreamReader::Ok);
+ \endcode
+
+ Unlike readByteArray() and readString(), this function is not limited by
+ implementation limits of QByteArray and QString.
+
+ \note This function does not perform verification that the UTF-8 contents
+ are properly formatted. That means this function does not produce the
+ QCborError::InvalidUtf8String error, even when readString() does.
+
+ \sa currentStringChunkSize(), readString(), readByteArray(),
+ isString(), isByteArray()
+ */
+QCborStreamReader::StringResult<qsizetype>
+QCborStreamReader::readStringChunk(char *ptr, qsizetype maxlen)
+{
+ CborError err;
+ size_t len;
+ const void *content = nullptr;
+ QCborStreamReader::StringResult<qsizetype> result;
+ result.data = 0;
+ result.status = Error;
+
+ d->lastError = {};
+ if (!d->ensureStringIteration())
+ return result;
+
+#if 1
+ // Using internal TinyCBOR API!
+ err = _cbor_value_get_string_chunk(&d->currentElement, &content, &len, &d->currentElement);
+#else
+ // the above is effectively the same as:
+ if (cbor_value_is_byte_string(&currentElement))
+ err = cbor_value_get_byte_string_chunk(&d->currentElement, reinterpret_cast<const uint8_t **>(&content),
+ &len, &d->currentElement);
+ else
+ err = cbor_value_get_text_string_chunk(&d->currentElement, reinterpret_cast<const char **>(&content),
+ &len, &d->currentElement);
+#endif
+
+ // Range check: using implementation-defined behavior in converting an
+ // unsigned value out of range of the destination signed type (same as
+ // "len > size_t(std::numeric_limits<qsizetype>::max())", but generates
+ // better code with ICC and MSVC).
+ if (!err && qsizetype(len) < 0)
+ err = CborErrorDataTooLarge;
+
+ if (err) {
+ if (err == CborErrorNoMoreStringChunks) {
+ d->preread();
+ err = cbor_value_finish_string_iteration(&d->currentElement);
+ result.status = EndOfString;
+ }
+ if (err)
+ d->handleError(err);
+ else
+ preparse();
+ return result;
+ }
+
+ // Read the chunk into the user's buffer.
+ qint64 actuallyRead;
+ qptrdiff offset = qptrdiff(content);
+ qsizetype toRead = qsizetype(len);
+ qsizetype left = toRead - maxlen;
+ if (left < 0)
+ left = 0; // buffer bigger than string
+ else
+ toRead = maxlen; // buffer smaller than string
+
+ if (d->device) {
+ // This first skip can't fail because we've already read this many bytes.
+ d->device->skip(d->bufferStart + qptrdiff(content));
+ actuallyRead = d->device->read(ptr, toRead);
+
+ if (actuallyRead != toRead) {
+ actuallyRead = -1;
+ } else if (left) {
+ qint64 skipped = d->device->skip(left);
+ if (skipped != left)
+ actuallyRead = -1;
+ }
+
+ if (actuallyRead < 0) {
+ d->handleError(CborErrorIO);
+ return result;
+ }
+
+ d->updateBufferAfterString(offset, len);
+ } else {
+ actuallyRead = toRead;
+ memcpy(ptr, d->buffer.constData() + d->bufferStart + offset, toRead);
+ d->bufferStart += QByteArray::size_type(offset + len);
+ }
+
+ d->preread();
+ result.data = actuallyRead;
+ result.status = Ok;
+ return result;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qcborcommon.cpp"
+#include "moc_qcborstream.cpp"
diff --git a/src/corelib/serialization/qcborstream.h b/src/corelib/serialization/qcborstream.h
new file mode 100644
index 0000000000..3b13a309ab
--- /dev/null
+++ b/src/corelib/serialization/qcborstream.h
@@ -0,0 +1,267 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCBORSTREAM_H
+#define QCBORSTREAM_H
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qcborcommon.h>
+#include <QtCore/qfloat16.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringview.h>
+
+// See qcborcommon.h for why we check
+#if defined(QT_X11_DEFINES_FOUND)
+# undef True
+# undef False
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+
+enum class QCborNegativeInteger : quint64 {};
+
+class QCborStreamWriterPrivate;
+class Q_CORE_EXPORT QCborStreamWriter
+{
+public:
+ explicit QCborStreamWriter(QIODevice *device);
+ explicit QCborStreamWriter(QByteArray *data);
+ ~QCborStreamWriter();
+ Q_DISABLE_COPY(QCborStreamWriter)
+
+ void setDevice(QIODevice *device);
+ QIODevice *device() const;
+
+ void append(quint64 u);
+ void append(qint64 i);
+ void append(QCborNegativeInteger n);
+ void append(const QByteArray &ba) { appendByteString(ba.constData(), ba.size()); }
+ void append(QLatin1String str);
+ void append(QStringView str);
+ void append(QCborTag tag);
+ void append(QCborKnownTags tag) { append(QCborTag(tag)); }
+ void append(QCborSimpleType st);
+ void append(std::nullptr_t) { append(QCborSimpleType::Null); }
+ void append(qfloat16 f);
+ void append(float f);
+ void append(double d);
+
+ void appendByteString(const char *data, qsizetype len);
+ void appendTextString(const char *utf8, qsizetype len);
+
+ // convenience
+ void append(bool b) { append(b ? QCborSimpleType::True : QCborSimpleType::False); }
+ void appendNull() { append(QCborSimpleType::Null); }
+ void appendUndefined() { append(QCborSimpleType::Undefined); }
+
+#ifndef Q_QDOC
+ // overloads to make normal code not complain
+ void append(int i) { append(qint64(i)); }
+ void append(uint u) { append(quint64(u)); }
+#endif
+#ifndef QT_NO_CAST_FROM_ASCII
+ void append(const char *str, qsizetype size = -1)
+ { appendTextString(str, (str && size == -1) ? int(strlen(str)) : size); }
+#endif
+
+ void startArray();
+ void startArray(quint64 count);
+ bool endArray();
+ void startMap();
+ void startMap(quint64 count);
+ bool endMap();
+
+ // no API for encoding chunked strings
+
+private:
+ QScopedPointer<QCborStreamWriterPrivate> d;
+};
+
+class QCborStreamReaderPrivate;
+class Q_CORE_EXPORT QCborStreamReader
+{
+ Q_GADGET
+public:
+ enum Type : quint8 {
+ UnsignedInteger = 0x00,
+ NegativeInteger = 0x20,
+ ByteString = 0x40,
+ ByteArray = ByteString,
+ TextString = 0x60,
+ String = TextString,
+ Array = 0x80,
+ Map = 0xa0,
+ Tag = 0xc0,
+ SimpleType = 0xe0,
+ HalfFloat = 0xf9,
+ Float16 = HalfFloat,
+ Float = 0xfa,
+ Double = 0xfb,
+
+ Invalid = 0xff
+ };
+ Q_ENUM(Type)
+
+ enum StringResultCode {
+ EndOfString = 0,
+ Ok = 1,
+ Error = -1
+ };
+ template <typename Container> struct StringResult {
+ Container data;
+ StringResultCode status = Error;
+ };
+ Q_ENUM(StringResultCode)
+
+ QCborStreamReader();
+ QCborStreamReader(const char *data, qsizetype len);
+ QCborStreamReader(const quint8 *data, qsizetype len);
+ explicit QCborStreamReader(const QByteArray &data);
+ explicit QCborStreamReader(QIODevice *device);
+ ~QCborStreamReader();
+ Q_DISABLE_COPY(QCborStreamReader)
+
+ void setDevice(QIODevice *device);
+ QIODevice *device() const;
+ void addData(const QByteArray &data);
+ void addData(const char *data, qsizetype len);
+ void addData(const quint8 *data, qsizetype len)
+ { addData(reinterpret_cast<const char *>(data), len); }
+ void reparse();
+ void clear();
+ void reset();
+
+ QCborError lastError();
+
+ qint64 currentOffset() const;
+
+ bool isValid() const { return !isInvalid(); }
+
+ int containerDepth() const;
+ QCborStreamReader::Type parentContainerType() const;
+ bool hasNext() const noexcept Q_DECL_PURE_FUNCTION;
+ bool next(int maxRecursion = 10000);
+
+ Type type() const { return QCborStreamReader::Type(type_); }
+ bool isUnsignedInteger() const { return type() == UnsignedInteger; }
+ bool isNegativeInteger() const { return type() == NegativeInteger; }
+ bool isInteger() const { return quint8(type()) <= quint8(NegativeInteger); }
+ bool isByteArray() const { return type() == ByteArray; }
+ bool isString() const { return type() == String; }
+ bool isArray() const { return type() == Array; }
+ bool isMap() const { return type() == Map; }
+ bool isTag() const { return type() == Tag; }
+ bool isSimpleType() const { return type() == SimpleType; }
+ bool isFloat16() const { return type() == Float16; }
+ bool isFloat() const { return type() == Float; }
+ bool isDouble() const { return type() == Double; }
+ bool isInvalid() const { return type() == Invalid; }
+
+ bool isSimpleType(QCborSimpleType st) const { return isSimpleType() && toSimpleType() == st; }
+ bool isFalse() const { return isSimpleType(QCborSimpleType::False); }
+ bool isTrue() const { return isSimpleType(QCborSimpleType::True); }
+ bool isBool() const { return isFalse() || isTrue(); }
+ bool isNull() const { return isSimpleType(QCborSimpleType::Null); }
+ bool isUndefined() const { return isSimpleType(QCborSimpleType::Undefined); }
+
+ bool isLengthKnown() const noexcept Q_DECL_PURE_FUNCTION;
+ quint64 length() const;
+
+ bool isContainer() const { return isMap() || isArray(); }
+ bool enterContainer() { Q_ASSERT(isContainer()); return _enterContainer_helper(); }
+ bool leaveContainer();
+
+ StringResult<QString> readString() { Q_ASSERT(isString()); return _readString_helper(); }
+ StringResult<QByteArray> readByteArray(){ Q_ASSERT(isByteArray()); return _readByteArray_helper(); }
+ qsizetype currentStringChunkSize() const{ Q_ASSERT(isString() || isByteArray()); return _currentStringChunkSize(); }
+ StringResult<qsizetype> readStringChunk(char *ptr, qsizetype maxlen);
+
+ bool toBool() const { Q_ASSERT(isBool()); return value64 - int(QCborSimpleType::False); }
+ QCborTag toTag() const { Q_ASSERT(isTag()); return QCborTag(value64); }
+ quint64 toUnsignedInteger() const { Q_ASSERT(isUnsignedInteger()); return value64; }
+ QCborNegativeInteger toNegativeInteger() const { Q_ASSERT(isNegativeInteger()); return QCborNegativeInteger(value64 + 1); }
+ QCborSimpleType toSimpleType() const{ Q_ASSERT(isSimpleType()); return QCborSimpleType(value64); }
+ qfloat16 toFloat16() const { Q_ASSERT(isFloat16()); return _toFloatingPoint<qfloat16>(); }
+ float toFloat() const { Q_ASSERT(isFloat()); return _toFloatingPoint<float>(); }
+ double toDouble() const { Q_ASSERT(isDouble()); return _toFloatingPoint<double>(); }
+
+ qint64 toInteger() const
+ {
+ Q_ASSERT(isInteger());
+ qint64 v = qint64(value64);
+ if (isNegativeInteger())
+ return -v - 1;
+ return v;
+ }
+
+private:
+ void preparse();
+ bool _enterContainer_helper();
+ StringResult<QString> _readString_helper();
+ StringResult<QByteArray> _readByteArray_helper();
+ qsizetype _currentStringChunkSize() const;
+
+ template <typename FP> FP _toFloatingPoint() const noexcept
+ {
+ using UInt = typename QIntegerForSizeof<FP>::Unsigned;
+ UInt u = UInt(value64);
+ FP f;
+ memcpy(static_cast<void *>(&f), &u, sizeof(f));
+ return f;
+ }
+
+ friend QCborStreamReaderPrivate;
+ friend class QCborContainerPrivate;
+ quint64 value64;
+ QScopedPointer<QCborStreamReaderPrivate> d;
+ quint8 type_;
+ quint8 reserved[3] = {};
+};
+
+QT_END_NAMESPACE
+
+#if defined(QT_X11_DEFINES_FOUND)
+# define True 1
+# define False 0
+#endif
+
+#endif // QCBORSTREAM_H
diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp
new file mode 100644
index 0000000000..077a4754dc
--- /dev/null
+++ b/src/corelib/serialization/qcborvalue.cpp
@@ -0,0 +1,2477 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcborvalue.h"
+#include "qcborvalue_p.h"
+
+#include "qcborarray.h"
+#include "qcbormap.h"
+#include "qcborstream.h"
+
+#include <qendian.h>
+#include <qlocale.h>
+#include <private/qnumeric_p.h>
+#include <private/qsimd_p.h>
+
+#include <new>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCborValue
+ \inmodule QtCore
+ \ingroup cbor
+ \reentrant
+ \since 5.12
+
+ \brief The QCborValue class encapsulates a value in CBOR.
+
+ This class can be used to hold one of the many types available in CBOR.
+ CBOR is the Concise Binary Object Representation, a very compact form of
+ binary data encoding that is a superset of JSON. It was created by the IETF
+ Constrained RESTful Environments (CoRE) WG, which has used it in many
+ new RFCs. It is meant to be used alongside the
+ \l{https://tools.ietf.org/html/rfc7252}{CoAP protocol}.
+
+ CBOR has three groups of built-in types:
+
+ \list
+ \li Basic types: integers, floating point (double), boolean, null, etc.
+ \li String-like types: strings and byte arrays
+ \li Containers: arrays and maps
+ \endlist
+
+ Additionally, CBOR supports a form of type extensibility by associating a
+ "tag" to one of the above types to convey more information. For example, a
+ UUID is represented by a tag and a byte array containing the 16 bytes of
+ the UUID content. QCborValue supports creating and decoding several of those
+ extended types directly with Qt classes (like QUuid).
+
+ For the complete list, see \l QCborValue::Type. The type of a QCborValue can
+ be queried using type() or one of the "isXxxx" functions.
+
+ \section1 Extended types and tagged values
+
+ A tagged value is a normal QCborValue that is paired with a number that
+ is its tag. See \l QCborKnownTags for more information on what tags are in
+ the API as well as the full, official list. Such combinations form extended
+ types.
+
+ QCborValue has support for certain extended types in the API, like URL
+ (with \l QUrl) and UUID (with \l QUuid). Other extended types not supported
+ in the API are represented by a QCborValue of \l {Type}{Tag} type. The tag
+ can later be retrieved by tag() and the tagged value using taggedValue().
+
+ In order to support future compatibility, QCborValues containing extended
+ Qt types compare equal to the tag type of the same contents. In other
+ words, the following expression is true:
+
+ \code
+ QCborValue(uuid) == QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122());
+ \endcode
+
+ \section1 Undefined and null values
+
+ QCborValue can contain a value of "null", which is not of any specific type.
+ It resembles the C++ \c {std::nullptr_t} type, whose only possible value is
+ \c nullptr. QCborValue has a constructor taking such a type and creates a
+ null QCborValue.
+
+ Null values are used to indicate that an optional value is not present. In
+ that aspect, it is similar to the C++ Standard Library type \c
+ {std::optional} when that is disengaged. Unlike the C++ type, CBOR nulls
+ are simply of type "Null" and it is not possible to determine what concrete
+ type it is replacing.
+
+ QCborValue can also be of the undefined type, which represents a value of
+ "undefined". In fact, that is what the QCborValue default constructor
+ creates.
+
+ Undefined values are different from null values. While nulls are used to
+ indicate an optional value that is not provided, Undefined is usually
+ used to indicate that an expected value could not be provided, usually due
+ to an error or a precondition that could not be satisfied.
+
+ Such values are completely valid and may appear in CBOR streams, unlike
+ JSON content and QJsonValue's undefined bit. But like QJsonValue's
+ Undefined, it is returned by QCborArray::value() when out of range or
+ QCborMap::operator[] when the key is not found in the container. It is not
+ possible to tell such a case apart from the value of Undefined, so if that
+ is required, check the QCborArray size and use the QCborMap iterator API.
+
+ \section1 Simple types
+
+ CBOR supports additional simple types that, like Null and Undefined, carry
+ no other value. They are called interchangeably "Simple Types" and "Simple
+ Values". CBOR encodes booleans as two distinct types (one for \c true and
+ one for \c false), but QCborValue has a convenience API for them.
+
+ There are currently no other defined CBOR simple types. QCborValue supports
+ them simply by their number with API like isSimpleType() and
+ toSimpleType(), available for compatibility with future specifications
+ before the Qt API can be updated. Their use before such a specification is
+ discouraged, as other CBOR implementations may not support them fully.
+
+ \section1 CBOR support
+
+ QCborValue supports all CBOR features required to create canonical and
+ strict streams. It implements almost all of the features specified in \l
+ {https://tools.ietf.org/html/rfc7049}{RFC 7049}.
+
+ The following table lists the CBOR features that QCborValue supports.
+
+ \table
+ \header \li Feature \li Support
+ \row \li Unsigned numbers \li Yes (\l qint64 range)
+ \row \li Negative numbers \li Yes (\l qint64 range)
+ \row \li Byte strings \li Yes
+ \row \li Text strings \li Yes
+ \row \li Chunked strings \li See below
+ \row \li Tags \li Yes (arbitrary)
+ \row \li Booleans \li Yes
+ \row \li Null \li Yes
+ \row \li Undefined \li Yes
+ \row \li Arbitrary simple values \li Yes
+ \row \li Half-precision float (16-bit) \li Yes
+ \row \li Single-precision float (32-bit) \li Yes
+ \row \li Double-precision float (64-bit) \li Yes
+ \row \li Infinities and NaN floating point \li Yes
+ \row \li Determinate-length arrays and maps \li Yes
+ \row \li Indeterminate-length arrays and maps \li Yes
+ \row \li Map key types other than strings and integers \li Yes (arbitrary)
+ \endtable
+
+ Integers in QCborValue are limited to the range of the \l qint64 type. That
+ is, from -9,223,372,036,854,775,808 (-2\sup{63}) to
+ 9,223,372,036,854,775,807 (2\sup{63} - 1). CBOR itself can represent integer
+ values outside of this range, which QCborValue does not support. When
+ decoding a stream using fromCbor() containing one of those values,
+ QCborValue will convert automatically to \l {Type}{Double}, but that may
+ lose up to 11 bits of precision.
+
+ fromCbor() is able to decode chunked strings, but will always merge the
+ chunks together into a single QCborValue. For that reason, it always writes
+ non-chunked strings when using toCbor() (which is required by the Canonical
+ format anyway).
+
+ QCborValue will always convert half- and single-precision floating point
+ values in the CBOR stream to double-precision. The toCbor() function can
+ take a parameter indicating to recreate them.
+
+ \section1 QCborValueRef
+
+ QCborValueRef is a helper class for QCborArray and QCborMap. It is the type
+ you get when using one of the mutating APIs in those classes. Unlike
+ QCborValue, new values can be assigned to that class. When that is done, the
+ array or map it refers to will be modified with the new value. In all other
+ aspects, its API is identical to QCborValue.
+
+ \sa QCborArray, QCborMap, QCborStreamReader, QCborStreamWriter
+ QJsonValue, QJsonDocument
+ */
+
+/*!
+ \class QCborParserError
+ \inmodule QtCore
+ \ingroup cbor
+ \reentrant
+ \since 5.12
+
+ \brief The QCborParserError is used by QCborValue to report a parsing error.
+
+ This class is used by \l {QCborValue::fromCbor(const QByteArray &ba,
+ QCborParserError *error)} to report a parser error and the byte offset
+ where the error was detected.
+
+ \sa QCborValue, QCborError
+ */
+
+/*!
+ \variable qint64 QCborParserError::offset
+
+ This field contains the offset from the beginning of the data where the
+ error was detected. The offset should point to the beginning of the item
+ that contained the error, even if the error itself was elsewhere (for
+ example, for UTF-8 decoding issues).
+
+ \sa QCborValue::fromCbor()
+ */
+
+/*!
+ \variable QCborError QCborParserError::error
+
+ This field contains the error code that indicates what decoding problem was
+ found.
+
+ \sa QCborValue::fromCbor()
+ */
+
+/*!
+ \fn QString QCborParserError::errorString() const
+
+ Returns a string representation of the error code. This string is not
+ translated.
+
+ \sa QCborError::toString(), QCborValue::fromCbor()
+ */
+
+/*!
+ \enum QCborValue::EncodingOption
+
+ This enum is used in the options argument to toCbor(), modifying the
+ behavior of the encoder.
+
+ \omitvalue SortKeysInMaps
+ \value NoTransformation (Default) Performs no transformations.
+ \value UseFloat Tells the encoder to use IEEE 754 single-precision floating point
+ (that is, \c float) whenever possible.
+ \value UseFloat16 Tells the encoder to use IEEE 754 half-precision floating point
+ (that is, \c qfloat16), whenever possible. Implies \c UseFloat.
+ \value UseIntegers Tells the encoder to use integers whenever a value of type \l
+ {Type}{Double} contains an integer.
+
+ The use of \c UseFloat16 is required to encode the stream in Canonical
+ Format, but is not otherwise necessary.
+
+ \sa toCbor()
+ */
+
+/*!
+ \enum QCborValue::DiagnosticNotationOption
+
+ This enum is used in the option argument to toDiagnosticNotation(), to
+ modify the output format.
+
+ \value Compact Does not use any line-breaks, producing a compact representation.
+ \value LineWrapped Uses line-breaks, one QCborValue per line.
+ \value ExtendedFormat Uses some different options to represent values, not found in
+ RFC 7049. Those options are subject to change.
+
+ Currently, \c ExtendedFormat will change how byte arrays are represented.
+ Without it, they are always hex-encoded and without spaces. With it,
+ QCborValue::toCbor() will either use hex with spaces, base64 or base64url
+ encoding, depending on the context.
+
+ \sa toDiagnosticNotation()
+ */
+
+/*!
+ \enum QCborValue::Type
+
+ This enum represents the QCborValue type. It is returned by the type()
+ function.
+
+ The CBOR built-in types are:
+
+ \value Integer \c qint64: An integer value
+ \value ByteArray \l QByteArray: a byte array ("byte string")
+ \value String \l QString: a Unicode string ("text string")
+ \value Array \l QCborArray: an array of QCborValues
+ \value Map \l QCborMap: an associative container of QCborValues
+ \value SimpleType \l QCborSimpleType: one of several simple types/values
+ \value False \c bool: the simple type for value \c false
+ \value True \c bool: the simple type for value \c true
+ \value Null \c std::nullptr_t: the simple type for the null value
+ \value Undefined (no type) the simple type for the undefined value
+ \value Double \c double: a double-precision floating point
+ \value Invalid Not a valid value, this usually indicates a CBOR decoding error
+
+ Additionally, QCborValue can represent extended types:
+
+ \value Tag An unknown or unrecognized extended type, represented by its
+ tag (a \l QCborTag) and the tagged value (a QCborValue)
+ \value DateTime \l QDateTime: a date and time stamp
+ \value Url \l QUrl: a URL or URI
+ \value RegularExpression \l QRegularExpression: the pattern of a regular expression
+ \value Uuid \l QUuid: a UUID
+
+ \sa type()
+ */
+
+/*!
+ \fn QCborValue::QCborValue()
+
+ Creates a QCborValue of the \l {Type}{Undefined} type.
+
+ CBOR undefined values are used to indicate missing information, usually as
+ a result of a previous operation that did not complete as expected. They
+ are also used by the QCborArray and QCborMap API to indicate the searched
+ item was not found.
+
+ Undefined values are represented by the \l {QCborSimpleType}{Undefined
+ simple type}. Because of that, QCborValues with undefined values will also
+ return true for isSimpleType() and
+ \c{isSimpleType(QCborSimpleType::Undefined)}.
+
+ Undefined values are different from null values.
+
+ QCborValue objects with undefined values are also different from invalid
+ QCborValue objects. The API will not create invalid QCborValues, but they
+ may exist as a result of a parsing error.
+
+ \sa isUndefined(), isNull(), isSimpleType()
+ */
+
+/*!
+ \fn QCborValue::QCborValue(Type t_)
+
+ Creates a QCborValue of type \a t_. The value associated with such a type
+ (if any) will be default constructed.
+
+ \sa type()
+ */
+
+/*!
+ \fn QCborValue::QCborValue(std::nullptr_t)
+
+ Creates a QCborValue of the \l {Type}{Null} type.
+
+ CBOR null values are used to indicate optional values that were not
+ provided. They are distinct from undefined values, in that null values are
+ usually not the result of an earlier error or problem.
+
+ \sa isNull(), isUndefined(), isSimpleType()
+ */
+
+/*!
+ \fn QCborValue::QCborValue(bool b)
+
+ Creates a QCborValue with boolean value \a b. The value can later be
+ retrieved using toBool().
+
+ Internally, CBOR booleans are represented by a pair of types, one for true
+ and one for false. For that reason, boolean QCborValues will return true
+ for isSimpleType() and one of \c{isSimpleType(QCborSimpleType::False)} or
+ \c{isSimpleType(QCborSimpleType::True)}.
+
+ \sa toBool(), isBool(), isTrue(), isFalse(), isSimpleType()
+ */
+
+/*!
+ \fn QCborValue::QCborValue(qint64 i)
+
+ Creates a QCborValue with integer value \a i. The value can later be
+ retrieved using toInteger().
+
+ CBOR integer values are distinct from floating point values. Therefore,
+ QCborValue objects with integers will compare differently to QCborValue
+ objects containing floating-point, even if the values contained in the
+ objects are equivalent.
+
+ \sa toInteger(), isInteger(), isDouble()
+ */
+
+/*!
+ \fn QCborValue::QCborValue(double d)
+
+ Creates a QCborValue with floating point value \a d. The value can later be
+ retrieved using toDouble().
+
+ CBOR floating point values are distinct from integer values. Therefore,
+ QCborValue objects with integers will compare differently to QCborValue
+ objects containing floating-point, even if the values contained in the
+ objects are equivalent.
+
+ \sa toDouble(), isDouble(), isInteger()
+ */
+
+/*!
+ \fn QCborValue::QCborValue(QCborSimpleType st)
+
+ Creates a QCborValue of simple type \a st. The type can later later be retrieved
+ using toSimpleType() as well as isSimpleType(st).
+
+ CBOR simple types are types that do not have any associated value, like
+ C++'s \c{std::nullptr_t} type, whose only possible value is \c nullptr.
+
+ If \a st is \c{QCborSimpleType::Null}, the resulting QCborValue will be of
+ the \l{Type}{Null} type and similarly for \c{QCborSimpleType::Undefined}.
+ If \a st is \c{QCborSimpleType::False} or \c{QCborSimpleType::True}, the
+ created QCborValue will be a boolean containing a value of false or true,
+ respectively.
+
+ This function can be used with simple types not defined in the API. For
+ example, to create a QCborValue with simple type 12, one could write:
+
+ \code
+ QCborValue value(QCborSimpleType(12));
+ \endcode
+
+ Simple types should not be used until a specification for them has been
+ published, since other implementations may not support them properly.
+ Simple type values 24 to 31 are reserved and must not be used.
+
+ isSimpleType(), isNull(), isUndefined(), isTrue(), isFalse()
+ */
+
+/*!
+ \fn QCborValue::QCborValue(QCborKnownTags tag, const QCborValue &taggedValue)
+ \overload
+
+ Creates a QCborValue for the extended type represented by the tag value \a
+ tag, tagging value \a taggedValue. The tag can later be retrieved using
+ tag() and the tagged value using taggedValue().
+
+ \sa isTag(), tag(), taggedValue(), QCborKnownTags
+ */
+
+/*!
+ \fn QCborValue::~QCborValue()
+
+ Disposes of the current QCborValue object and frees any associated resources.
+ */
+
+/*!
+ \fn QCborValue::QCborValue(QCborValue &&other)
+ \overload
+
+ Moves the contents of the \a other CBorValue object into this one and frees
+ the resources of this one.
+ */
+
+/*!
+ \fn QCborValue &&QCborValue::operator=(QCborValue &&other)
+ \overload
+
+ Moves the contents of the \a other CBorValue object into this one and frees
+ the resources of this one. Returns a reference to this object.
+ */
+
+/*!
+ \fn void QCborValue::swap(QCborValue &other)
+
+ Swaps the contents of this QCborValue object and \a other.
+ */
+
+/*!
+ \fn QCborValue::Type QCborValue::type() const
+
+ Returns the type of this QCborValue. The type can also later be retrieved by one
+ of the "isXxx" functions.
+
+ \sa isInteger(), isByteArray(), isString(), isArray(), isMap(),
+ isTag(), isFalse(), isTrue(), isBool(), isNull(), isUndefined, isDouble(),
+ isDateTime(), isUrl(), isRegularExpression(), isUuid()
+ */
+
+/*!
+ \fn bool QCborValue::isInteger() const
+
+ Returns true if this QCborValue is of the integer type. The integer value
+ can be retrieved using toInteger().
+
+ \sa type(), toInteger()
+ */
+
+/*!
+ \fn bool QCborValue::isByteArray() const
+
+ Returns true if this QCborValue is of the byte array type. The byte array
+ value can be retrieved using toByteArray().
+
+ \sa type(), toByteArray()
+ */
+
+/*!
+ \fn bool QCborValue::isString() const
+
+ Returns true if this QCborValue is of the string type. The string value
+ can be retrieved using toString().
+
+ \sa type(), toString()
+ */
+
+/*!
+ \fn bool QCborValue::isArray() const
+
+ Returns true if this QCborValue is of the array type. The array value can
+ be retrieved using toArray().
+
+ \sa type(), toArray()
+ */
+
+/*!
+ \fn bool QCborValue::isMap() const
+
+ Returns true if this QCborValue is of the map type. The map value can be
+ retrieved using toMap().
+
+ \sa type(), toMap()
+ */
+
+/*!
+ \fn bool QCborValue::isTag() const
+
+ Returns true if this QCborValue is of the tag type. The tag value can be
+ retrieved using tag() and the tagged value using taggedValue().
+
+ This function also returns true for extended types that the API
+ recognizes. For code that handles extended types directly before the Qt API
+ is updated to support them, it is possible to recreate the tag + tagged
+ value pair by using taggedValue().
+
+ \sa type(), tag(), taggedValue(), taggedValue()
+ */
+
+/*!
+ \fn bool QCborValue::isFalse() const
+
+ Returns true if this QCborValue is a boolean with false value. This
+ function exists because, internally, CBOR booleans are stored as two
+ separate types, one for true and one for false.
+
+ \sa type(), isBool(), isTrue(), toBool()
+ */
+
+/*!
+ \fn bool QCborValue::isTrue() const
+
+ Returns true if this QCborValue is a boolean with true value. This
+ function exists because, internally, CBOR booleans are stored as two
+ separate types, one for false and one for true.
+
+ \sa type(), isBool(), isFalse(), toBool()
+ */
+
+/*!
+ \fn bool QCborValue::isBool() const
+
+ Returns true if this QCborValue is a boolean. The value can be retrieved
+ using toBool().
+
+ \sa type(), toBool(), isTrue(), isFalse()
+ */
+
+/*!
+ \fn bool QCborValue::isUndefined() const
+
+ Returns true if this QCborValue is of the undefined type.
+
+ CBOR undefined values are used to indicate missing information, usually as
+ a result of a previous operation that did not complete as expected. They
+ are also used by the QCborArray and QCborMap API to indicate the searched
+ item was not found.
+
+ Undefined values are distinct from null values.
+
+ QCborValue objects with undefined values are also different from invalid
+ QCborValue objects. The API will not create invalid QCborValues, but they
+ may exist as a result of a parsing error.
+
+ \sa type(), isNull(), isInvalid()
+ */
+
+/*!
+ \fn bool QCborValue::isNull() const
+
+ Returns true if this QCborValue is of the null type.
+
+ CBOR null values are used to indicate optional values that were not
+ provided. They are distinct from undefined values, in that null values are
+ usually not the result of an earlier error or problem.
+
+ Null values are distinct from undefined values and from invalid QCborValue
+ objects. The API will not create invalid QCborValues, but they may exist as
+ a result of a parsing error.
+
+ \sa type(), isUndefined(), isInvalid()
+ */
+
+/*!
+ \fn bool QCborValue::isDouble() const
+
+ Returns true if this QCborValue is of the floating-point type. The value
+ can be retrieved using toDouble().
+
+ \sa type(), toDouble()
+ */
+
+/*!
+ \fn bool QCborValue::isDateTime() const
+
+ Returns true if this QCborValue is of the date/time type. The value can be
+ retrieved using toDateTime(). Date/times are extended types that use the
+ tag \l{QCborKnownTags}{DateTime}.
+
+ Additionally, when decoding from a CBOR stream, QCborValue will interpret
+ tags of value \l{QCborKnownTags}{UnixTime_t} and convert them to the
+ equivalent date/time.
+
+ \sa type(), toDateTime()
+ */
+
+/*!
+ \fn bool QCborValue::isUrl() const
+
+ Returns true if this QCborValue is of the URL type. The URL value
+ can be retrieved using toUrl().
+
+ \sa type(), toUrl()
+ */
+
+/*!
+ \fn bool QCborValue::isRegularExpression() const
+
+ Returns true if this QCborValue contains a regular expression's pattern.
+ The pattern can be retrieved using toRegularExpression().
+
+ \sa type(), toRegularExpression()
+ */
+
+/*!
+ \fn bool QCborValue::isUuid() const
+
+ Returns true if this QCborValue contains a UUID. The value can be retrieved
+ using toUuid().
+
+ \sa type(), toUuid()
+ */
+
+/*!
+ \fn bool QCborValue::isInvalid() const
+
+ Returns true if this QCborValue is not of any valid type. Invalid
+ QCborValues are distinct from those with undefined values and they usually
+ represent a decoding error.
+
+ \sa isUndefined(), isNull()
+ */
+
+/*!
+ \fn bool QCborValue::isContainer() const
+
+ This convenience function returns true if the QCborValue is either an array
+ or a map.
+
+ \sa isArray(), isMap()
+ */
+
+/*!
+ \fn bool QCborValue::isSimpleType() const
+
+ Returns true if this QCborValue is of one of the CBOR simple types. The
+ type itself can later be retrieved using type(), even for types that don't have an
+ enumeration in the API. They can also be checked with the
+ \l{isSimpleType(QCborSimpleType)} overload.
+
+ \sa QCborSimpleType, isSimpleType(QCborSimpleType), toSimpleType()
+ */
+
+/*!
+ \fn bool QCborValue::isSimpleType(QCborSimpleType st) const
+ \overload
+
+ Returns true if this QCborValue is of a simple type and toSimpleType()
+ would return \a st, false otherwise. This function can be used to check for
+ any CBOR simple type, even those for which there is no enumeration in the
+ API. For example, for the simple type of value 12, you could write:
+
+ \code
+ value.isSimpleType(QCborSimpleType(12));
+ \endcode
+
+ \sa QCborValue::QCborValue(QCborSimpleType), isSimpleType(), isFalse(),
+ isTrue(), isNull, isUndefined(), toSimpleType()
+ */
+
+/*!
+ \fn QCborSimpleType QCborValue::toSimpleType(QCborSimpleType defaultValue) const
+
+ Returns the simple type this QCborValue is of, if it is a simple type. If
+ it is not a simple type, it returns \a defaultValue.
+
+ The following types are simple types and this function will return the
+ listed values:
+
+ \table
+ \row \li QCborValue::False \li QCborSimpleType::False
+ \row \li QCborValue::True \li QCborSimpleType::True
+ \row \li QCborValue::Null \li QCborSimpleType::Null
+ \row \li QCborValue::Undefined \li QCborSimpleType::Undefined
+ \endtable
+
+ \sa type(), isSimpleType(), isBool(), isTrue(), isFalse(), isTrue(),
+ isNull(), isUndefined()
+ */
+
+/*!
+ \fn qint64 QCborValue::toInteger(qint64 defaultValue) const
+
+ Returns the integer value stored in this QCborValue, if it is of the
+ integer type. If it is of the Double type, this function returns the
+ floating point value converted to integer. In any other case, it returns \a
+ defaultValue.
+
+ \sa isInteger(), isDouble(), toDouble()
+ */
+
+/*!
+ \fn bool QCborValue::toBool(bool defaultValue) const
+
+ Returns the boolean value stored in this QCborValue, if it is of a boolean
+ type. Otherwise, it returns \a defaultValue.
+
+ \sa isBool(), isTrue(), isFalse()
+ */
+
+/*!
+ \fn double QCborValue::toDouble(double defaultValue) const
+
+ Returns the floating point value stored in this QCborValue, if it is of the
+ Double type. If it is of the Integer type, this function returns the
+ integer value converted to double. In any other case, it returns \a
+ defaultValue.
+
+ \sa isDouble(), isInteger(), toInteger()
+ */
+
+using namespace QtCbor;
+
+// in qcborstream.cpp
+extern void qt_cbor_stream_set_error(QCborStreamReaderPrivate *d, QCborError error);
+
+static void writeDoubleToCbor(QCborStreamWriter &writer, double d, QCborValue::EncodingOptions opt)
+{
+ if (qt_is_nan(d)) {
+ if (opt & QCborValue::UseFloat16) {
+ if ((opt & QCborValue::UseFloat16) == QCborValue::UseFloat16)
+ return writer.append(qfloat16(qt_qnan()));
+ return writer.append(float(qt_qnan()));
+ }
+ return writer.append(qt_qnan());
+ }
+
+ if (qt_is_inf(d)) {
+ d = d > 0 ? qt_inf() : -qt_inf();
+ } else if (opt & QCborValue::UseIntegers) {
+ quint64 i;
+ if (convertDoubleTo(d, &i)) {
+ if (d < 0)
+ return writer.append(QCborNegativeInteger(i));
+ return writer.append(i);
+ }
+ }
+
+ if (opt & QCborValue::UseFloat16) {
+ float f = float(d);
+ if (f == d) {
+ // no data loss, we could use float
+ if ((opt & QCborValue::UseFloat16) == QCborValue::UseFloat16) {
+ qfloat16 f16 = f;
+ if (f16 == f)
+ return writer.append(f16);
+ }
+
+ return writer.append(f);
+ }
+ }
+
+ writer.append(d);
+}
+
+static inline int typeOrder(Element e1, Element e2)
+{
+ auto comparable = [](Element e) {
+ if (e.type >= 0x10000) // see QCborValue::isTag_helper()
+ return QCborValue::Tag;
+ return e.type;
+ };
+ return comparable(e1) - comparable(e2);
+}
+
+QCborContainerPrivate::~QCborContainerPrivate()
+{
+ // delete our elements
+ for (Element &e : elements) {
+ if (e.flags & Element::IsContainer)
+ e.container->deref();
+ }
+}
+
+void QCborContainerPrivate::compact(qsizetype reserved)
+{
+ if (usedData > data.size() / 2)
+ return;
+
+ // 50% savings if we recreate the byte data
+ // ### TBD
+ Q_UNUSED(reserved);
+}
+
+QCborContainerPrivate *QCborContainerPrivate::clone(QCborContainerPrivate *d, qsizetype reserved)
+{
+ if (!d) {
+ d = new QCborContainerPrivate;
+ } else {
+ d = new QCborContainerPrivate(*d);
+ if (reserved >= 0) {
+ d->elements.reserve(reserved);
+ d->compact(reserved);
+ }
+ for (auto &e : qAsConst(d->elements)) {
+ if (e.flags & Element::IsContainer)
+ e.container->ref.ref();
+ }
+ }
+ return d;
+}
+
+QCborContainerPrivate *QCborContainerPrivate::detach(QCborContainerPrivate *d, qsizetype reserved)
+{
+ if (!d || d->ref.load() != 1)
+ return clone(d, reserved);
+ return d;
+}
+
+// Copies or moves \a value into element at position \a e. If \a disp is
+// CopyContainer, then this function increases the reference count of the
+// container, but otherwise leaves it unmodified. If \a disp is MoveContainer,
+// then it transfers ownership (move semantics) and the caller must set
+// value.container back to nullptr.
+void QCborContainerPrivate::replaceAt_complex(Element &e, const QCborValue &value, ContainerDisposition disp)
+{
+ if (value.n < 0) {
+ // This QCborValue is an array, map, or tagged value (container points
+ // to itself).
+
+ // detect self-assignment
+ if (Q_UNLIKELY(this == value.container)) {
+ Q_ASSERT(ref.load() >= 2);
+ if (disp == MoveContainer)
+ ref.deref(); // not deref() because it can't drop to 0
+ QCborContainerPrivate *d = QCborContainerPrivate::clone(this);
+ d->elements.detach();
+ d->ref.store(1);
+ e.container = d;
+ } else {
+ e.container = value.container;
+ if (disp == CopyContainer)
+ e.container->ref.ref();
+ }
+
+ e.type = value.type();
+ e.flags = Element::IsContainer;
+ } else {
+ // String data, copy contents
+ e = value.container->elements.at(value.n);
+
+ // Copy string data, if any
+ if (const ByteData *b = value.container->byteData(value.n))
+ e.value = addByteData(b->byte(), b->len);
+
+ if (disp == MoveContainer)
+ value.container->deref();
+ }
+}
+
+// in qstring.cpp
+void qt_to_latin1_unchecked(uchar *dst, const ushort *uc, qsizetype len);
+
+Q_NEVER_INLINE void QCborContainerPrivate::appendAsciiString(const QString &s)
+{
+ qsizetype len = s.size();
+ QtCbor::Element e;
+ e.value = addByteData(nullptr, len);
+ e.type = QCborValue::String;
+ e.flags = Element::HasByteData | Element::StringIsAscii;
+ elements.append(e);
+
+ char *ptr = data.data() + e.value + sizeof(ByteData);
+ uchar *l = reinterpret_cast<uchar *>(ptr);
+ const ushort *uc = (const ushort *)s.unicode();
+ qt_to_latin1_unchecked(l, uc, len);
+}
+
+QCborValue QCborContainerPrivate::extractAt_complex(Element e)
+{
+ // create a new container for the returned value, containing the byte data
+ // from this element, if it's worth it
+ Q_ASSERT(e.flags & Element::HasByteData);
+ auto b = byteData(e);
+ auto container = new QCborContainerPrivate;
+
+ if (b->len + qsizetype(sizeof(*b)) < data.size() / 4) {
+ // make a shallow copy of the byte data
+ container->appendByteData(b->byte(), b->len, e.type, e.flags);
+ usedData -= b->len + qsizetype(sizeof(*b));
+ compact(elements.size());
+ } else {
+ // just share with the original byte data
+ container->data = data;
+ container->elements.reserve(1);
+ container->elements.append(e);
+ }
+
+ return makeValue(e.type, 0, container);
+}
+
+QT_WARNING_DISABLE_MSVC(4146) // unary minus operator applied to unsigned type, result still unsigned
+static int compareContainer(const QCborContainerPrivate *c1, const QCborContainerPrivate *c2);
+static int compareElementNoData(const Element &e1, const Element &e2)
+{
+ Q_ASSERT(e1.type == e2.type);
+
+ if (e1.type == QCborValue::Integer) {
+ // CBOR sorting order is 0, 1, 2, ..., INT64_MAX, -1, -2, -3, ... INT64_MIN
+ // So we transform:
+ // 0 -> 0
+ // 1 -> 1
+ // INT64_MAX -> INT64_MAX
+ // -1 -> INT64_MAX + 1 = INT64_MAX - (-1)
+ // -2 -> INT64_MAX + 2 = INT64_MAX - (-2)
+ // INT64_MIN -> UINT64_MAX = INT64_MAX - INT64_MIN
+ // Note how the unsigned arithmethic is well defined in C++ (it's
+ // always performed modulo 2^64).
+ auto makeSortable = [](qint64 v) {
+ quint64 u = quint64(v);
+ if (v < 0)
+ return quint64(std::numeric_limits<qint64>::max()) + (-u);
+ return u;
+ };
+ quint64 u1 = makeSortable(e1.value);
+ quint64 u2 = makeSortable(e2.value);
+ if (u1 < u2)
+ return -1;
+ if (u1 > u2)
+ return 1;
+ }
+
+ if (e1.type == QCborValue::Tag || e1.type == QCborValue::Double) {
+ // Perform unsigned comparisons for the tag value and floating point
+ quint64 u1 = quint64(e1.value);
+ quint64 u2 = quint64(e2.value);
+ if (u1 != u2)
+ return u1 < u2 ? -1 : 1;
+ }
+
+ // Any other type is equal at this point:
+ // - simple types carry no value
+ // - empty strings, arrays and maps
+ return 0;
+}
+
+static int compareElementRecursive(const QCborContainerPrivate *c1, const Element &e1,
+ const QCborContainerPrivate *c2, const Element &e2)
+{
+ int cmp = typeOrder(e1, e2);
+ if (cmp != 0)
+ return cmp;
+
+ if ((e1.flags & Element::IsContainer) || (e2.flags & Element::IsContainer))
+ return compareContainer(e1.flags & Element::IsContainer ? e1.container : nullptr,
+ e2.flags & Element::IsContainer ? e2.container : nullptr);
+
+ // string data?
+ const ByteData *b1 = c1 ? c1->byteData(e1) : nullptr;
+ const ByteData *b2 = c2 ? c2->byteData(e2) : nullptr;
+ if (b1 || b2) {
+ auto len1 = b1 ? b1->len : 0;
+ auto len2 = b2 ? b2->len : 0;
+
+ if (e1.flags & Element::StringIsUtf16)
+ len1 /= 2;
+ if (e2.flags & Element::StringIsUtf16)
+ len2 /= 2;
+ if (len1 == 0 || len2 == 0)
+ return len1 < len2 ? -1 : len1 == len2 ? 0 : 1;
+
+ // we definitely have data from this point forward
+ Q_ASSERT(b1);
+ Q_ASSERT(b2);
+
+ // Officially with CBOR, we sort first the string with the shortest
+ // UTF-8 length. The length of an ASCII string is the same as its UTF-8
+ // and UTF-16 ones, but the UTF-8 length of a string is bigger than the
+ // UTF-16 equivalent. Combinations are:
+ // 1) UTF-16 and UTF-16
+ // 2) UTF-16 and UTF-8 <=== this is the problem case
+ // 3) UTF-16 and US-ASCII
+ // 4) UTF-8 and UTF-8
+ // 5) UTF-8 and US-ASCII
+ // 6) US-ASCII and US-ASCII
+ if ((e1.flags & Element::StringIsUtf16) && (e2.flags & Element::StringIsUtf16)) {
+ // Case 1: both UTF-16, so lengths are comparable.
+ // (we can't use memcmp in little-endian machines)
+ if (len1 == len2)
+ return QtPrivate::compareStrings(b1->asStringView(), b2->asStringView());
+ return len1 < len2 ? -1 : 1;
+ }
+
+ if (!(e1.flags & Element::StringIsUtf16) && !(e2.flags & Element::StringIsUtf16)) {
+ // Cases 4, 5 and 6: neither is UTF-16, so lengths are comparable too
+ // (this case includes byte arrays too)
+ if (len1 == len2)
+ return memcmp(b1->byte(), b2->byte(), size_t(len1));
+ return len1 < len2 ? -1 : 1;
+ }
+
+ if (!(e1.flags & Element::StringIsAscii) || !(e2.flags & Element::StringIsAscii)) {
+ // Case 2: one of them is UTF-8 and the other is UTF-16, so lengths
+ // are NOT comparable. We need to convert to UTF-16 first...
+ auto string = [](const Element &e, const ByteData *b) {
+ return e.flags & Element::StringIsUtf16 ? b->asQStringRaw() : b->toUtf8String();
+ };
+
+ QString s1 = string(e1, b1);
+ QString s2 = string(e2, b2);
+ if (s1.size() == s2.size())
+ return s1.compare(s2);
+ return s1.size() < s2.size() ? -1 : 1;
+ }
+
+ // Case 3 (UTF-16 and US-ASCII) remains, so lengths are comparable again
+ if (len1 != len2)
+ return len1 < len2 ? -1 : 1;
+ if (e1.flags & Element::StringIsUtf16)
+ return QtPrivate::compareStrings(b1->asStringView(), b2->asLatin1());
+ return QtPrivate::compareStrings(b1->asLatin1(), b2->asStringView());
+ }
+
+ return compareElementNoData(e1, e2);
+}
+
+static int compareContainer(const QCborContainerPrivate *c1, const QCborContainerPrivate *c2)
+{
+ auto len1 = c1 ? c1->elements.size() : 0;
+ auto len2 = c2 ? c2->elements.size() : 0;
+ if (len1 != len2) {
+ // sort the shorter container first
+ return len1 < len2 ? -1 : 1;
+ }
+
+ for (qsizetype i = 0; i < len1; ++i) {
+ const Element &e1 = c1->elements.at(i);
+ const Element &e2 = c2->elements.at(i);
+ int cmp = QCborContainerPrivate::compareElement_helper(c1, e1, c2, e2);
+ if (cmp)
+ return cmp;
+ }
+
+ return 0;
+}
+
+inline int QCborContainerPrivate::compareElement_helper(const QCborContainerPrivate *c1, Element e1,
+ const QCborContainerPrivate *c2, Element e2)
+{
+ return compareElementRecursive(c1, e1, c2, e2);
+}
+
+/*!
+ \fn bool QCborValue::operator==(const QCborValue &other) const
+
+ Compares this value and \a other, and returns true if they hold the same
+ contents, false otherwise. If each QCborValue contains an array or map, the
+ comparison is recursive to elements contained in them.
+
+ For more information on CBOR equality in Qt, see, compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator!=(), operator<()
+ */
+
+/*!
+ \fn bool QCborValue::operator!=(const QCborValue &other) const
+
+ Compares this value and \a other, and returns true if contents differ,
+ false otherwise. If each QCborValue contains an array or map, the comparison
+ is recursive to elements contained in them.
+
+ For more information on CBOR equality in Qt, see, QCborValue::compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator==(), operator<()
+ */
+
+/*!
+ \fn bool QCborValue::operator<(const QCborValue &other) const
+
+ Compares this value and \a other, and returns true if this value should be
+ sorted before \a other, false otherwise. If each QCborValue contains an
+ array or map, the comparison is recursive to elements contained in them.
+
+ For more information on CBOR sorting order, see QCborValue::compare().
+
+ \sa compare(), QCborValue::operator==(), QCborMap::operator==(),
+ operator==(), operator!=()
+ */
+
+/*!
+ Compares this value and \a other, and returns an integer that indicates
+ whether this value should be sorted prior to (if the result is negative) or
+ after \a other (if the result is positive). If this function returns 0, the
+ two values are equal and hold the same contents.
+
+ If each QCborValue contains an array or map, the comparison is recursive to
+ elements contained in them.
+
+ \section3 Extended types
+
+ QCborValue compares equal a QCborValue containing an extended type, like
+ \l{Type}{Url} and \l{Type}{Url} and its equivalent tagged representation.
+ So, for example, the following expression is true:
+
+ \code
+ QCborValue(QUrl("https://example.com")) == QCborValue(QCborKnownTags::Url, "https://example.com");
+ \endcode
+
+ Do note that Qt types like \l QUrl and \l QDateTime will normalize and
+ otherwise modify their arguments. The expression above is true only because
+ the string on the right side is the normalized value that the QCborValue on
+ the left would take. If, for example, the "https" part were uppercase in
+ both sides, the comparison would fail. For information on normalizations
+ performed by QCborValue, please consult the documentation of the
+ constructor taking the Qt type in question.
+
+ \section3 Sorting order
+
+ Sorting order in CBOR is defined in RFC 7049
+ {https://tools.ietf.org/html/rfc7049#section-3.9}{section 3.9}, which
+ discusses the sorting of keys in a map when following the Canonical
+ encoding. According to the specification, "sorting is performed on the
+ bytes of the representation of the key data items" and lists as
+ consequences that:
+
+ \list
+ \li "If two keys have different lengths, the shorter one sorts earlier;"
+ \li "If two keys have the same length, the one with the lower value in
+ (byte-wise) lexical order sorts earlier."
+ \endlist
+
+ This results in surprising sorting of QCborValues, where the result of this
+ function is different from that which would later be retrieved by comparing the
+ contained elements. For example, the QCborValue containing string "zzz"
+ sorts before the QCborValue with string "foobar", even though when
+ comparing as \l{QString::compare()}{QStrings} or
+ \l{QByteArray}{QByteArrays} the "zzz" sorts after "foobar"
+ (dictionary order).
+
+ The specification does not clearly indicate what sorting order should be
+ done for values of different types (it says sorting should not pay
+ "attention to the 3/5 bit splitting for major types"). QCborValue makes the
+ assumption that types should be sorted too. The numeric values of the
+ QCborValue::Type enumeration are in that order, with the exception of the
+ extended types, which compare as their tagged equivalents.
+
+ \note Sorting order is preliminary and is subject to change. Applications
+ should not depend on the order returned by this function for the time
+ being.
+
+ \sa QCborArray::compare(), QCborMap::compare(), operator==()
+ */
+int QCborValue::compare(const QCborValue &other) const
+{
+ Element e1 = QCborContainerPrivate::elementFromValue(*this);
+ Element e2 = QCborContainerPrivate::elementFromValue(other);
+ return compareElementRecursive(container, e1, other.container, e2);
+}
+
+int QCborArray::compare(const QCborArray &other) const noexcept
+{
+ return compareContainer(d.data(), other.d.data());
+}
+
+int QCborMap::compare(const QCborMap &other) const noexcept
+{
+ return compareContainer(d.data(), other.d.data());
+}
+
+static void encodeToCbor(QCborStreamWriter &writer, const QCborContainerPrivate *d, qsizetype idx,
+ QCborValue::EncodingOptions opt)
+{
+ if (idx == -QCborValue::Array || idx == -QCborValue::Map) {
+ bool isArray = (idx == -QCborValue::Array);
+ qsizetype len = d ? d->elements.size() : 0;
+ if (isArray)
+ writer.startArray(quint64(len));
+ else
+ writer.startMap(quint64(len) / 2);
+
+ for (idx = 0; idx < len; ++idx)
+ encodeToCbor(writer, d, idx, opt);
+
+ if (isArray)
+ writer.endArray();
+ else
+ writer.endMap();
+ } else if (idx < 0) {
+ if (d->elements.size() != 2) {
+ // invalid state!
+ qWarning("QCborValue: invalid tag state; are you encoding something that was improperly decoded?");
+ return;
+ }
+
+ // write the tag and the tagged element
+ writer.append(QCborTag(d->elements.at(0).value));
+ encodeToCbor(writer, d, 1, opt);
+ } else {
+ // just one element
+ auto e = d->elements.at(idx);
+ const ByteData *b = d->byteData(idx);
+ switch (e.type) {
+ case QCborValue::Integer:
+ return writer.append(qint64(e.value));
+
+ case QCborValue::ByteArray:
+ if (b)
+ return writer.appendByteString(b->byte(), b->len);
+ return writer.appendByteString("", 0);
+
+ case QCborValue::String:
+ if (b) {
+ if (e.flags & Element::StringIsUtf16)
+ return writer.append(b->asStringView());
+ return writer.appendTextString(b->byte(), b->len);
+ }
+ return writer.append(QLatin1String());
+
+ case QCborValue::Array:
+ case QCborValue::Map:
+ case QCborValue::Tag:
+ // recurse
+ return encodeToCbor(writer,
+ e.flags & Element::IsContainer ? e.container : nullptr,
+ -qsizetype(e.type), opt);
+
+ case QCborValue::SimpleType:
+ case QCborValue::False:
+ case QCborValue::True:
+ case QCborValue::Null:
+ case QCborValue::Undefined:
+ break;
+
+ case QCborValue::Double:
+ return writeDoubleToCbor(writer, e.fpvalue(), opt);
+
+ case QCborValue::Invalid:
+ return;
+
+ case QCborValue::DateTime:
+ case QCborValue::Url:
+ case QCborValue::RegularExpression:
+ case QCborValue::Uuid:
+ // recurse as tag
+ return encodeToCbor(writer, e.container, -QCborValue::Tag, opt);
+ }
+
+ // maybe it's a simple type
+ int simpleType = e.type - QCborValue::SimpleType;
+ if (unsigned(simpleType) < 0x100)
+ return writer.append(QCborSimpleType(simpleType));
+
+ // if we got here, we've got an unknown type
+ qWarning("QCborValue: found unknown type 0x%x", e.type);
+ }
+}
+
+static inline double integerOutOfRange(const QCborStreamReader &reader)
+{
+ Q_ASSERT(reader.isInteger());
+ if (reader.isUnsignedInteger()) {
+ quint64 v = reader.toUnsignedInteger();
+ if (qint64(v) < 0)
+ return double(v);
+ } else {
+ quint64 v = quint64(reader.toNegativeInteger());
+ if (qint64(v - 1) < 0)
+ return -double(v);
+ }
+
+ // result is in range
+ return 0;
+}
+
+static Element decodeBasicValueFromCbor(QCborStreamReader &reader)
+{
+ Element e = {};
+
+ switch (reader.type()) {
+ case QCborStreamReader::UnsignedInteger:
+ case QCborStreamReader::NegativeInteger:
+ if (double d = integerOutOfRange(reader)) {
+ e.type = QCborValue::Double;
+ qToUnaligned(d, &e.value);
+ } else {
+ e.type = QCborValue::Integer;
+ e.value = reader.toInteger();
+ }
+ break;
+ case QCborStreamReader::SimpleType:
+ e.type = QCborValue::Type(quint8(reader.toSimpleType()) + 0x100);
+ break;
+ case QCborStreamReader::Float16:
+ e.type = QCborValue::Double;
+ qToUnaligned(double(reader.toFloat16()), &e.value);
+ break;
+ case QCborStreamReader::Float:
+ e.type = QCborValue::Double;
+ qToUnaligned(double(reader.toFloat()), &e.value);
+ break;
+ case QCborStreamReader::Double:
+ e.type = QCborValue::Double;
+ qToUnaligned(reader.toDouble(), &e.value);
+ break;
+
+ default:
+ Q_UNREACHABLE();
+ }
+
+ reader.next();
+ return e;
+}
+
+static inline QCborContainerPrivate *createContainerFromCbor(QCborStreamReader &reader)
+{
+ auto d = new QCborContainerPrivate;
+ d->ref.store(1);
+ d->decodeFromCbor(reader);
+ return d;
+}
+
+static QCborValue taggedValueFromCbor(QCborStreamReader &reader)
+{
+ auto d = new QCborContainerPrivate;
+ d->append(reader.toTag());
+ reader.next();
+
+ if (reader.lastError() == QCborError::NoError) {
+ // decode tagged value
+ d->decodeValueFromCbor(reader);
+ }
+
+ QCborValue::Type type = QCborValue::Tag;
+ if (reader.lastError() == QCborError::NoError) {
+ // post-process to create our extended types
+ qint64 tag = d->elements.at(0).value;
+ auto &e = d->elements[1];
+ const ByteData *b = d->byteData(e);
+
+ auto replaceByteData = [&](const char *buf, qsizetype len) {
+ d->data.clear();
+ d->usedData = 0;
+ e.flags = Element::HasByteData | Element::StringIsAscii;
+ e.value = d->addByteData(buf, len);
+ };
+
+ switch (tag) {
+ case qint64(QCborKnownTags::DateTimeString):
+ case qint64(QCborKnownTags::UnixTime_t): {
+ QDateTime dt;
+ if (tag == qint64(QCborKnownTags::DateTimeString) && b &&
+ e.type == QCborValue::String && (e.flags & Element::StringIsUtf16) == 0) {
+ // The data is supposed to be US-ASCII. If it isn't,
+ // QDateTime::fromString will fail anyway.
+ dt = QDateTime::fromString(b->asLatin1(), Qt::ISODateWithMs);
+ } else if (tag == qint64(QCborKnownTags::UnixTime_t) && e.type == QCborValue::Integer) {
+ dt = QDateTime::fromSecsSinceEpoch(e.value, Qt::UTC);
+ } else if (tag == qint64(QCborKnownTags::UnixTime_t) && e.type == QCborValue::Double) {
+ dt = QDateTime::fromMSecsSinceEpoch(qint64(e.fpvalue() * 1000), Qt::UTC);
+ }
+ if (dt.isValid()) {
+ QByteArray text = dt.toString(Qt::ISODateWithMs).toLatin1();
+ replaceByteData(text, text.size());
+ e.type = QCborValue::String;
+ d->elements[0].value = qint64(QCborKnownTags::DateTimeString);
+ type = QCborValue::DateTime;
+ }
+ break;
+ }
+
+ case qint64(QCborKnownTags::Url):
+ if (e.type == QCborValue::String) {
+ if (b) {
+ // normalize to a short (decoded) form, so as to save space
+ QUrl url(e.flags & Element::StringIsUtf16 ?
+ b->asQStringRaw() :
+ b->toUtf8String());
+ QByteArray encoded = url.toString(QUrl::DecodeReserved).toUtf8();
+ replaceByteData(encoded, encoded.size());
+ }
+ type = QCborValue::Url;
+ }
+ break;
+
+ case quint64(QCborKnownTags::RegularExpression):
+ if (e.type == QCborValue::String) {
+ // no normalization is necessary
+ type = QCborValue::RegularExpression;
+ }
+ break;
+
+ case qint64(QCborKnownTags::Uuid):
+ if (e.type == QCborValue::ByteArray) {
+ // force the size to 16
+ char buf[sizeof(QUuid)] = {};
+ if (b)
+ memcpy(buf, b->byte(), qMin(sizeof(buf), size_t(b->len)));
+ replaceByteData(buf, sizeof(buf));
+
+ type = QCborValue::Uuid;
+ }
+ break;
+ }
+ } else {
+ // decoding error
+ type = QCborValue::Invalid;
+ }
+
+ // note: may return invalid state!
+ return QCborContainerPrivate::makeValue(type, -1, d);
+}
+
+void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
+{
+ auto addByteData_local = [this](QByteArray::size_type len) -> qint64 {
+ // this duplicates a lot of addByteData, but with overflow checking
+ QByteArray::size_type newSize;
+ QByteArray::size_type increment = sizeof(QtCbor::ByteData);
+ QByteArray::size_type alignment = alignof(QtCbor::ByteData);
+ QByteArray::size_type offset = data.size();
+
+ // calculate the increment we want
+ if (add_overflow(increment, len, &increment))
+ return -1;
+
+ // align offset
+ if (add_overflow(offset, alignment - 1, &offset))
+ return -1;
+ offset &= ~(alignment - 1);
+
+ // and calculate the final size
+ if (add_overflow(offset, increment, &newSize))
+ return -1;
+
+ // since usedData <= data.size(), this can't overflow
+ usedData += increment;
+ data.resize(newSize);
+ return offset;
+ };
+ auto dataPtr = [this]() {
+ // Null happens when we're reading zero bytes.
+ Q_ASSERT(data.isNull() || data.isDetached());
+ return const_cast<char *>(data.constData());
+ };
+
+ Element e = {};
+ e.type = (reader.isByteArray() ? QCborValue::ByteArray : QCborValue::String);
+ if (reader.lastError() != QCborError::NoError)
+ return;
+
+ qsizetype rawlen = reader.currentStringChunkSize();
+ QByteArray::size_type len = rawlen;
+ if (rawlen < 0)
+ return; // error
+ if (len != rawlen) {
+ // truncation
+ qt_cbor_stream_set_error(reader.d.data(), { QCborError::DataTooLarge });
+ return;
+ }
+
+ // allocate space, but only if there will be data
+ if (len != 0 || !reader.isLengthKnown()) {
+ e.flags = Element::HasByteData;
+ e.value = addByteData_local(len);
+ if (e.value < 0) {
+ // overflow
+ qt_cbor_stream_set_error(reader.d.data(), { QCborError::DataTooLarge });
+ return;
+ }
+ }
+
+ // read chunks
+ bool isAscii = (e.type == QCborValue::String);
+ auto r = reader.readStringChunk(dataPtr() + e.value + sizeof(ByteData), len);
+ while (r.status == QCborStreamReader::Ok) {
+ if (e.type == QCborValue::String && len) {
+ // verify UTF-8 string validity
+ auto utf8result = QUtf8::isValidUtf8(dataPtr() + data.size() - len, len);
+ if (!utf8result.isValidUtf8) {
+ r.status = QCborStreamReader::Error;
+ qt_cbor_stream_set_error(reader.d.data(), { QCborError::InvalidUtf8String });
+ break;
+ }
+ isAscii = isAscii && utf8result.isValidAscii;
+ }
+
+ // allocate space for the next chunk
+ rawlen = reader.currentStringChunkSize();
+ len = rawlen;
+ if (len == rawlen) {
+ auto oldSize = data.size();
+ auto newSize = oldSize;
+ if (!add_overflow(newSize, len, &newSize)) {
+ if (newSize != oldSize)
+ data.resize(newSize);
+
+ // read the chunk
+ r = reader.readStringChunk(dataPtr() + oldSize, len);
+ continue;
+ }
+ }
+
+ // error
+ r.status = QCborStreamReader::Error;
+ qt_cbor_stream_set_error(reader.d.data(), { QCborError::DataTooLarge });
+ }
+
+ if (r.status == QCborStreamReader::Error) {
+ // There can only be errors if there was data to be read.
+ Q_ASSERT(e.flags & Element::HasByteData);
+ data.truncate(e.value);
+ return;
+ }
+
+ // update size
+ if (e.flags & Element::HasByteData) {
+ auto b = new (dataPtr() + e.value) ByteData;
+ b->len = data.size() - e.value - int(sizeof(*b));
+ usedData += b->len;
+
+ if (isAscii) {
+ // set the flag if it is US-ASCII only (as it often is)
+ Q_ASSERT(e.type == QCborValue::String);
+ e.flags |= Element::StringIsAscii;
+ }
+ }
+
+ elements.append(e);
+}
+
+void QCborContainerPrivate::decodeValueFromCbor(QCborStreamReader &reader)
+{
+ switch (reader.type()) {
+ case QCborStreamReader::UnsignedInteger:
+ case QCborStreamReader::NegativeInteger:
+ case QCborStreamReader::SimpleType:
+ case QCborStreamReader::Float16:
+ case QCborStreamReader::Float:
+ case QCborStreamReader::Double:
+ elements.append(decodeBasicValueFromCbor(reader));
+ break;
+
+ case QCborStreamReader::ByteArray:
+ case QCborStreamReader::String:
+ decodeStringFromCbor(reader);
+ break;
+
+ case QCborStreamReader::Array:
+ case QCborStreamReader::Map:
+ case QCborStreamReader::Tag:
+ return append(QCborValue::fromCbor(reader));
+
+ case QCborStreamReader::Invalid:
+ return; // probably a decode error
+ }
+}
+
+void QCborContainerPrivate::decodeFromCbor(QCborStreamReader &reader)
+{
+ int mapShift = reader.isMap() ? 1 : 0;
+ if (reader.isLengthKnown()) {
+ quint64 len = reader.length();
+
+ // Clamp allocation to 1M elements (avoids crashing due to corrupt
+ // stream or loss of precision when converting from quint64 to
+ // QVector::size_type).
+ len = qMin(len, quint64(1024 * 1024 - 1));
+ elements.reserve(qsizetype(len) << mapShift);
+ }
+
+ reader.enterContainer();
+ if (reader.lastError() != QCborError::NoError)
+ return;
+
+ while (reader.hasNext() && reader.lastError() == QCborError::NoError)
+ decodeValueFromCbor(reader);
+
+ if (reader.lastError() == QCborError::NoError)
+ reader.leaveContainer();
+}
+
+/*!
+ Creates a QCborValue with byte array value \a ba. The value can later be
+ retrieved using toByteArray().
+
+ \sa toByteArray(), isByteArray(), isString()
+ */
+QCborValue::QCborValue(const QByteArray &ba)
+ : n(0), container(new QCborContainerPrivate), t(ByteArray)
+{
+ container->appendByteData(ba.constData(), ba.size(), t);
+ container->ref.store(1);
+}
+
+/*!
+ Creates a QCborValue with string value \a s. The value can later be
+ retrieved using toString().
+
+ \sa toString(), isString(), isByteArray()
+ */
+QCborValue::QCborValue(const QString &s)
+ : n(0), container(new QCborContainerPrivate), t(String)
+{
+ container->append(s);
+ container->ref.store(1);
+}
+
+/*!
+ \overload
+
+ Creates a QCborValue with string value \a s. The value can later be
+ retrieved using toString().
+
+ \sa toString(), isString(), isByteArray()
+ */
+QCborValue::QCborValue(QLatin1String s)
+ : n(0), container(new QCborContainerPrivate), t(String)
+{
+ container->append(s);
+ container->ref.store(1);
+}
+
+/*!
+ \fn QCborValue::QCborValue(const QCborArray &a)
+ \fn QCborValue::QCborValue(QCborArray &&a)
+
+ Creates a QCborValue with the array \a a. The array can later be retrieved
+ using toArray().
+
+ \sa toArray(), isArray(), isMap()
+ */
+QCborValue::QCborValue(const QCborArray &a)
+ : n(-1), container(a.d.data()), t(Array)
+{
+ if (container)
+ container->ref.ref();
+}
+
+/*!
+ \fn QCborValue::QCborValue(const QCborMap &m)
+ \fn QCborValue::QCborValue(QCborMap &&m)
+
+ Creates a QCborValue with the map \a m. The map can later be retrieved
+ using toMap().
+
+ \sa toMap(), isMap(), isArray()
+ */
+QCborValue::QCborValue(const QCborMap &m)
+ : n(-1), container(m.d.data()), t(Map)
+{
+ if (container)
+ container->ref.ref();
+}
+
+/*!
+ \fn QCborValue::QCborValue(QCborTag t, const QCborValue &tv)
+ \fn QCborValue::QCborValue(QCborKnownTags t, const QCborValue &tv)
+
+ Creates a QCborValue for the extended type represented by the tag value \a
+ t, tagging value \a tv. The tag can later be retrieved using tag() and
+ the tagged value using taggedValue().
+
+ \sa isTag(), tag(), taggedValue(), QCborKnownTags
+ */
+QCborValue::QCborValue(QCborTag t, const QCborValue &tv)
+ : n(-1), container(new QCborContainerPrivate), t(Tag)
+{
+ container->ref.store(1);
+ container->append(t);
+ container->append(tv);
+}
+
+/*!
+ Copies the contents of \a other into this object.
+ */
+QCborValue::QCborValue(const QCborValue &other)
+ : n(other.n), container(other.container), t(other.t)
+{
+ if (container)
+ container->ref.ref();
+}
+
+/*!
+ Creates a QCborValue object of the date/time extended type and containing
+ the value represented by \a dt. The value can later be retrieved using
+ toDateTime().
+
+ The CBOR date/time types are extension types using tags: either a string
+ (in ISO date format) tagged as a \l{QCborKnownTags}{DateTime} or a number
+ (of seconds since the start of 1970, UTC) tagged as a
+ \l{QCborKnownTags}{UnixTime_t}. When parsing CBOR streams, QCborValue will
+ convert \l{QCborKnownTags}{UnixTime_t} to the string-based type.
+
+ \sa toDateTime(), isDateTime(), taggedValue()
+ */
+QCborValue::QCborValue(const QDateTime &dt)
+ : QCborValue(QCborKnownTags::DateTimeString, dt.toString(Qt::ISODateWithMs).toLatin1())
+{
+ // change types
+ t = DateTime;
+ container->elements[1].type = String;
+}
+
+/*!
+ Creates a QCborValue object of the URL extended type and containing the
+ value represented by \a url. The value can later be retrieved using toUrl().
+
+ The CBOR URL type is an extended type represented by a string tagged as an
+ \l{QCborKnownTags}{Url}.
+
+ \sa toUrl(), isUrl(), taggedValue()
+ */
+QCborValue::QCborValue(const QUrl &url)
+ : QCborValue(QCborKnownTags::Url, url.toString(QUrl::DecodeReserved).toUtf8())
+{
+ // change types
+ t = Url;
+ container->elements[1].type = String;
+}
+
+/*!
+ Creates a QCborValue object of the regular expression pattern extended type
+ and containing the value represented by \a rx. The value can later be retrieved
+ using toRegularExpression().
+
+ The CBOR regular expression type is an extended type represented by a
+ string tagged as an \l{QCborKnownTags}{RegularExpression}. Note that CBOR
+ regular expressions only store the patterns, so any flags that the
+ QRegularExpression object may carry will be lost.
+
+ \sa toRegularExpression(), isRegularExpression(), taggedValue()
+ */
+QCborValue::QCborValue(const QRegularExpression &rx)
+ : QCborValue(QCborKnownTags::RegularExpression, rx.pattern())
+{
+ // change type
+ t = RegularExpression;
+}
+
+/*!
+ Creates a QCborValue object of the UUID extended type and containing the
+ value represented by \a uuid. The value can later be retrieved using
+ toUuid().
+
+ The CBOR UUID type is an extended type represented by a byte array tagged
+ as an \l{QCborKnownTags}{Uuid}.
+
+ \sa toUuid(), isUuid(), taggedValue()
+ */
+QCborValue::QCborValue(const QUuid &uuid)
+ : QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122())
+{
+ // change our type
+ t = Uuid;
+}
+
+// destructor
+void QCborValue::dispose()
+{
+ container->deref();
+}
+
+/*!
+ Replaces the contents of this QCborObject with a copy of \a other.
+ */
+QCborValue &QCborValue::operator=(const QCborValue &other)
+{
+ if (other.container)
+ other.container->ref.ref();
+ if (container)
+ container->deref();
+
+ n = other.n;
+ container = other.container;
+ t = other.t;
+ return *this;
+}
+
+/*!
+ Returns the tag of this extended QCborValue object, if it is of the tag
+ type, \a defaultValue otherwise.
+
+ CBOR represents extended types by associating a number (the tag) with a
+ stored representation. This function returns that number. To retrieve the
+ representation, use taggedValue().
+
+ \sa isTag(), taggedValue(), isDateTime(), isUrl(), isRegularExpression(), isUuid()
+ */
+QCborTag QCborValue::tag(QCborTag defaultValue) const
+{
+ return isTag() && container && container->elements.size() == 2 ?
+ QCborTag(container->elements.at(0).value) : defaultValue;
+}
+
+/*!
+ Returns the tagged value of this extended QCborValue object, if it is of
+ the tag type, \a defaultValue otherwise.
+
+ CBOR represents extended types by associating a number (the tag) with a
+ stored representation. This function returns that representation. To
+ retrieve the tag, use tag().
+
+ \sa isTag(), tag(), isDateTime(), isUrl(), isRegularExpression(), isUuid()
+ */
+QCborValue QCborValue::taggedValue(const QCborValue &defaultValue) const
+{
+ return isTag() && container && container->elements.size() == 2 ?
+ container->valueAt(1) : defaultValue;
+}
+
+/*!
+ Returns the byte array value stored in this QCborValue, if it is of the byte
+ array type. Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to
+ QByteArray.
+
+ \sa isByteArray(), isString(), toString()
+ */
+QByteArray QCborValue::toByteArray(const QByteArray &defaultValue) const
+{
+ if (!container || !isByteArray())
+ return defaultValue;
+
+ Q_ASSERT(n >= 0);
+ return container->byteArrayAt(n);
+}
+
+/*!
+ Returns the string value stored in this QCborValue, if it is of the string
+ type. Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to
+ QString.
+
+ \sa isString(), isByteArray(), toByteArray()
+ */
+QString QCborValue::toString(const QString &defaultValue) const
+{
+ if (!container || !isString())
+ return defaultValue;
+
+ Q_ASSERT(n >= 0);
+ return container->stringAt(n);
+}
+
+/*!
+ Returns the date/time value stored in this QCborValue, if it is of the
+ date/time extended type. Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to
+ QDateTime.
+
+ \sa isDateTime(), isTag(), taggedValue()
+ */
+QDateTime QCborValue::toDateTime(const QDateTime &defaultValue) const
+{
+ if (!container || !isDateTime() || container->elements.size() != 2)
+ return defaultValue;
+
+ Q_ASSERT(n == -1);
+ const ByteData *byteData = container->byteData(1);
+ if (!byteData)
+ return defaultValue; // date/times are never empty, so this must be invalid
+
+ // Our data must be US-ASCII.
+ Q_ASSERT((container->elements.at(1).flags & Element::StringIsUtf16) == 0);
+ return QDateTime::fromString(byteData->asLatin1(), Qt::ISODateWithMs);
+}
+
+/*!
+ Returns the URL value stored in this QCborValue, if it is of the URL
+ extended type. Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to QUrl.
+
+ \sa isUrl(), isTag(), taggedValue()
+ */
+QUrl QCborValue::toUrl(const QUrl &defaultValue) const
+{
+ if (!container || !isUrl() || container->elements.size() != 2)
+ return defaultValue;
+
+ Q_ASSERT(n == -1);
+ const ByteData *byteData = container->byteData(1);
+ if (!byteData)
+ return QUrl(); // valid, empty URL
+
+ return QUrl::fromEncoded(byteData->asByteArrayView());
+}
+
+/*!
+ Returns the regular expression value stored in this QCborValue, if it is of
+ the regular expression pattern extended type. Otherwise, it returns \a
+ defaultValue.
+
+ Note that this function performs no conversion from other types to
+ QRegularExpression.
+
+ \sa isRegularExpression(), isTag(), taggedValue()
+ */
+QRegularExpression QCborValue::toRegularExpression(const QRegularExpression &defaultValue) const
+{
+ if (!container || !isRegularExpression() || container->elements.size() != 2)
+ return defaultValue;
+
+ Q_ASSERT(n == -1);
+ return QRegularExpression(container->stringAt(1));
+}
+
+/*!
+ Returns the UUID value stored in this QCborValue, if it is of the UUID
+ extended type. Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to QUuid.
+
+ \sa isUuid(), isTag(), taggedValue()
+ */
+QUuid QCborValue::toUuid(const QUuid &defaultValue) const
+{
+ if (!container || !isUuid() || container->elements.size() != 2)
+ return defaultValue;
+
+ Q_ASSERT(n == -1);
+ const ByteData *byteData = container->byteData(1);
+ if (!byteData)
+ return defaultValue; // UUIDs must always be 16 bytes, so this must be invalid
+
+ return QUuid::fromRfc4122(byteData->asByteArrayView());
+}
+
+QCborArray QCborValue::toArray() const
+{
+ return toArray(QCborArray());
+}
+
+/*!
+ Returns the array value stored in this QCborValue, if it is of the array
+ type. Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to
+ QCborArray.
+
+ \sa isArray(), isByteArray(), isMap(), isContainer(), toMap()
+ */
+QCborArray QCborValue::toArray(const QCborArray &defaultValue) const
+{
+ if (!isArray())
+ return defaultValue;
+ QCborContainerPrivate *dd = nullptr;
+ Q_ASSERT(n == -1 || container == nullptr);
+ if (n < 0)
+ dd = container;
+ return dd ? QCborArray(*dd) : defaultValue;
+}
+
+QCborMap QCborValue::toMap() const
+{
+ return toMap(QCborMap());
+}
+
+/*!
+ Returns the map value stored in this QCborValue, if it is of the map type.
+ Otherwise, it returns \a defaultValue.
+
+ Note that this function performs no conversion from other types to
+ QCborMap.
+
+ \sa isMap(), isArray(), isContainer(), toArray()
+ */
+QCborMap QCborValue::toMap(const QCborMap &defaultValue) const
+{
+ if (!isMap())
+ return defaultValue;
+ QCborContainerPrivate *dd = nullptr;
+ Q_ASSERT(n == -1 || container == nullptr);
+ if (n < 0)
+ dd = container;
+ return dd ? QCborMap(*dd) : defaultValue;
+}
+
+/*!
+ If this QCborValue is a QCborMap, searches elements for the value whose key
+ matches \a key. If there's no key matching \a key in the map or if this
+ QCborValue object is not a map, returns the undefined value.
+
+ This function is equivalent to:
+
+ \code
+ value.toMap().value(key);
+ \endcode
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+const QCborValue QCborValue::operator[](const QString &key) const
+{
+ if (isMap())
+ return toMap().value(key);
+ return QCborValue();
+}
+
+/*!
+ \overload
+
+ If this QCborValue is a QCborMap, searches elements for the value whose key
+ matches \a key. If there's no key matching \a key in the map or if this
+ QCborValue object is not a map, returns the undefined value.
+
+ This function is equivalent to:
+
+ \code
+ value.toMap().value(key);
+ \endcode
+
+ \sa operator[](qint64), QCborMap::operator[], QCborMap::value(),
+ QCborMap::find()
+ */
+const QCborValue QCborValue::operator[](QLatin1String key) const
+{
+ if (isMap())
+ return toMap().value(key);
+ return QCborValue();
+}
+
+/*!
+ If this QCborValue is a QCborMap, searches elements for the value whose key
+ matches \a key. If this is an array, returns the element whose index is \a
+ key. If there's no matching value in the array or map, or if this
+ QCborValue object is not an array or map, returns the undefined value.
+
+ \sa operator[], QCborMap::operator[], QCborMap::value(),
+ QCborMap::find(), QCborArray::operator[], QCborArray::at()
+ */
+
+const QCborValue QCborValue::operator[](qint64 key) const
+{
+ if (isMap())
+ return toMap().value(key);
+ if (isArray())
+ return toArray().at(key);
+ return QCborValue();
+}
+
+/*!
+ Decodes one item from the CBOR stream found in \a reader and returns the
+ equivalent representation. This function is recursive: if the item is a map
+ or array, it will decode all items found in that map or array, until the
+ outermost object is finished.
+
+ This function need not be used on the root element of a \l
+ QCborStreamReader. For example, the following code illustrates how to skip
+ the CBOR signature tag from the beginning of a file:
+
+ \code
+ if (reader.isTag() && reader.toTag() == QCborKnownTags::Signature)
+ reader.next();
+
+ QCborValue contents = QCborValue::fromCbor(reader);
+ \endcode
+
+ The returned value may be partially complete and indistinguishable from a
+ valid QCborValue even if the decoding failed. To determine if there was an
+ error, check if \l{QCborStreamReader::lastError()}{reader.lastError()} is
+ indicating an error condition. This function stops decoding immediately
+ after the first error.
+
+ \sa toCbor(), toDiagnosticNotation(), toVariant(), toJsonValue()
+ */
+QCborValue QCborValue::fromCbor(QCborStreamReader &reader)
+{
+ QCborValue result;
+ auto t = reader.type();
+ if (reader.lastError() != QCborError::NoError)
+ t = QCborStreamReader::Invalid;
+
+ switch (t) {
+ // basic types, no container needed:
+ case QCborStreamReader::UnsignedInteger:
+ case QCborStreamReader::NegativeInteger:
+ case QCborStreamReader::SimpleType:
+ case QCborStreamReader::Float16:
+ case QCborStreamReader::Float:
+ case QCborStreamReader::Double: {
+ Element e = decodeBasicValueFromCbor(reader);
+ result.n = e.value;
+ result.t = e.type;
+ break;
+ }
+
+ case QCborStreamReader::Invalid:
+ result.t = QCborValue::Invalid;
+ break; // probably a decode error
+
+ // strings
+ case QCborStreamReader::ByteArray:
+ case QCborStreamReader::String:
+ result.n = 0;
+ result.t = reader.isString() ? String : ByteArray;
+ result.container = new QCborContainerPrivate;
+ result.container->ref.ref();
+ result.container->decodeStringFromCbor(reader);
+ break;
+
+ // containers
+ case QCborStreamReader::Array:
+ case QCborStreamReader::Map:
+ result.n = -1;
+ result.t = reader.isArray() ? Array : Map;
+ result.container = createContainerFromCbor(reader);
+ break;
+
+ // tag
+ case QCborStreamReader::Tag:
+ result = taggedValueFromCbor(reader);
+ break;
+ }
+
+ return result;
+}
+
+/*!
+ \overload
+
+ Decodes one item from the CBOR stream found in the byte array \a ba and
+ returns the equivalent representation. This function is recursive: if the
+ item is a map or array, it will decode all items found in that map or
+ array, until the outermost object is finished.
+
+ This function stores the error state, if any, in the object pointed to by
+ \a error, along with the offset of where the error occurred. If no error
+ happened, it stores \l{QCborError}{NoError} in the error state and the
+ number of bytes that it consumed (that is, it stores the offset for the
+ first unused byte). Using that information makes it possible to parse
+ further data that may exist in the same byte array.
+
+ The returned value may be partially complete and indistinguishable from a
+ valid QCborValue even if the decoding failed. To determine if there was an
+ error, check if there was an error stored in \a error. This function stops
+ decoding immediately after the first error.
+
+ \sa toCbor(), toDiagnosticNotation(), toVariant(), toJsonValue()
+ */
+QCborValue QCborValue::fromCbor(const QByteArray &ba, QCborParserError *error)
+{
+ QCborStreamReader reader(ba);
+ QCborValue result = fromCbor(reader);
+ if (error) {
+ error->error = reader.lastError();
+ error->offset = reader.currentOffset();
+ }
+ return result;
+}
+
+/*!
+ \fn QCborValue QCborValue::fromCbor(const char *data, qsizetype len, QCborParserError *error)
+ \fn QCborValue QCborValue::fromCbor(const quint8 *data, qsizetype len, QCborParserError *error)
+ \overload
+
+ Converts \a len bytes of \a data to a QByteArray and then calls the
+ overload of this function that accepts a QByteArray, also passing \a error,
+ if provided.
+*/
+
+/*!
+ Encodes this QCborValue object to its CBOR representation, using the
+ options specified in \a opt, and return the byte array containing that
+ representation.
+
+ This function will not fail, except if this QCborValue or any of the
+ contained items, if this is a map or array, are invalid. Invalid types are
+ not produced normally by the API, but can result from decoding errors.
+
+ By default, this function performs no transformation on the values in the
+ QCborValue, writing all floating point directly as double-precision (\c
+ double) types. If the \l{EncodingOption}{UseFloat} option is specified, it
+ will use single precision (\c float) for any floating point value for which
+ there's no loss of precision in using that representation. That includes
+ infinities and NaN values.
+
+ Similarly, if \l{EncodingOption}{UseFloat16} is specified, this function
+ will try to use half-precision (\c qfloat16) floating point if the
+ conversion to that results in no loss of precision. This is always true for
+ infinities and NaN.
+
+ If \l{EncodingOption}{UseIntegers} is specified, it will use integers for
+ any floating point value that contains an actual integer.
+
+ \sa fromCbor(), fromVariant(), fromJsonValue()
+ */
+QByteArray QCborValue::toCbor(EncodingOptions opt)
+{
+ QByteArray result;
+ QCborStreamWriter writer(&result);
+ toCbor(writer, opt);
+ return result;
+}
+
+/*!
+ \overload
+
+ Encodes this QCborValue object to its CBOR representation, using the
+ options specified in \a opt, to the writer specified by \a writer. The same
+ writer can be used by multiple QCborValues, for example, in order to encode
+ different elements in a larger array.
+
+ This function will not fail, except if this QCborValue or any of the
+ contained items, if this is a map or array, are invalid. Invalid types are
+ not produced normally by the API, but can result from decoding errors.
+
+ By default, this function performs no transformation on the values in the
+ QCborValue, writing all floating point directly as double-precision
+ (binary64) types. If the \l{EncodingOption}{UseFloat} option is
+ specified, it will use single precision (binary32) for any floating point
+ value for which there's no loss of precision in using that representation.
+ That includes infinities and NaN values.
+
+ Similarly, if \l{EncodingOption}{UseFloat16} is specified, this function
+ will try to use half-precision (binary16) floating point if the conversion
+ to that results in no loss of precision. This is always true for infinities
+ and NaN.
+
+ If \l{EncodingOption}{UseIntegers} is specified, it will use integers
+ for any floating point value that contains an actual integer.
+
+ \sa fromCbor(), fromVariant(), fromJsonValue()
+ */
+Q_NEVER_INLINE void QCborValue::toCbor(QCborStreamWriter &writer, EncodingOptions opt)
+{
+ if (isContainer() || isTag())
+ return encodeToCbor(writer, container, -type(), opt);
+ if (container)
+ return encodeToCbor(writer, container, n, opt);
+
+ // very simple types
+ if (isSimpleType())
+ return writer.append(toSimpleType());
+
+ switch (type()) {
+ case Integer:
+ return writer.append(n);
+
+ case Double:
+ return writeDoubleToCbor(writer, fp_helper(), opt);
+
+ case Invalid:
+ return;
+
+ case SimpleType:
+ case False:
+ case True:
+ case Null:
+ case Undefined:
+ // handled by "if (isSimpleType())"
+ Q_UNREACHABLE();
+ break;
+
+ case ByteArray:
+ // Byte array with no container is empty
+ return writer.appendByteString("", 0);
+
+ case String:
+ // String with no container is empty
+ return writer.appendTextString("", 0);
+
+ case Array:
+ case Map:
+ case Tag:
+ // handled by "if (isContainer() || isTag())"
+ Q_UNREACHABLE();
+ break;
+
+ case DateTime:
+ case Url:
+ case RegularExpression:
+ case Uuid:
+ // not possible
+ Q_UNREACHABLE();
+ break;
+ }
+}
+
+void QCborValueRef::toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt)
+{
+ concrete().toCbor(writer, opt);
+}
+
+void QCborValueRef::assign(QCborValueRef that, const QCborValue &other)
+{
+ that.d->replaceAt(that.i, other);
+}
+
+void QCborValueRef::assign(QCborValueRef that, QCborValue &&other)
+{
+ that.d->replaceAt(that.i, other, QCborContainerPrivate::MoveContainer);
+}
+
+void QCborValueRef::assign(QCborValueRef that, const QCborValueRef other)
+{
+ // ### optimize?
+ assign(that, other.concrete());
+}
+
+QCborValue QCborValueRef::concrete(QCborValueRef self) noexcept
+{
+ return self.d->valueAt(self.i);
+}
+
+QCborValue::Type QCborValueRef::concreteType(QCborValueRef self) noexcept
+{
+ return self.d->elements.at(self.i).type;
+}
+
+inline QCborArray::QCborArray(QCborContainerPrivate &dd) noexcept
+ : d(&dd)
+{
+}
+
+inline QCborMap::QCborMap(QCborContainerPrivate &dd) noexcept
+ : d(&dd)
+{
+}
+
+uint qHash(const QCborValue &value, uint seed)
+{
+ switch (value.type()) {
+ case QCborValue::Integer:
+ return qHash(value.toInteger(), seed);
+ case QCborValue::ByteArray:
+ return qHash(value.toByteArray(), seed);
+ case QCborValue::String:
+ return qHash(value.toString(), seed);
+ case QCborValue::Array:
+ return qHash(value.toArray(), seed);
+ case QCborValue::Map:
+ return qHash(value.toMap(), seed);
+ case QCborValue::Tag: {
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, value.tag());
+ seed = hash(seed, value.taggedValue());
+ return seed;
+ }
+ case QCborValue::SimpleType:
+ break;
+ case QCborValue::False:
+ return qHash(false, seed);
+ case QCborValue::True:
+ return qHash(true, seed);
+ case QCborValue::Null:
+ return qHash(nullptr, seed);
+ case QCborValue::Undefined:
+ return seed;
+ case QCborValue::Double:
+ return qHash(value.toDouble(), seed);
+ case QCborValue::DateTime:
+ return qHash(value.toDateTime(), seed);
+ case QCborValue::Url:
+ return qHash(value.toUrl(), seed);
+ case QCborValue::RegularExpression:
+ return qHash(value.toRegularExpression(), seed);
+ case QCborValue::Uuid:
+ return qHash(value.toUuid(), seed);
+ case QCborValue::Invalid:
+ return seed;
+ }
+
+ Q_ASSERT(value.isSimpleType());
+ return qHash(value.toSimpleType(), seed);
+}
+
+#if !defined(QT_NO_DEBUG_STREAM)
+static QDebug debugContents(QDebug &dbg, const QCborValue &v)
+{
+ switch (v.type()) {
+ case QCborValue::Integer:
+ return dbg << v.toInteger();
+ case QCborValue::ByteArray:
+ return dbg << "QByteArray(" << v.toByteArray() << ')';
+ case QCborValue::String:
+ return dbg << v.toString();
+ case QCborValue::Array:
+ return dbg << v.toArray();
+ case QCborValue::Map:
+ return dbg << v.toMap();
+ case QCborValue::Tag:
+ dbg << v.tag() << ", ";
+ return debugContents(dbg, v.taggedValue());
+ case QCborValue::SimpleType:
+ break;
+ case QCborValue::True:
+ return dbg << true;
+ case QCborValue::False:
+ return dbg << false;
+ case QCborValue::Null:
+ return dbg << "nullptr";
+ case QCborValue::Undefined:
+ return dbg;
+ case QCborValue::Double: {
+ qint64 i = qint64(v.toDouble());
+ if (i == v.toDouble())
+ return dbg << i << ".0";
+ else
+ return dbg << v.toDouble();
+ }
+ case QCborValue::DateTime:
+ return dbg << v.toDateTime();
+ case QCborValue::Url:
+ return dbg << v.toUrl();
+ case QCborValue::RegularExpression:
+ return dbg << v.toRegularExpression();
+ case QCborValue::Uuid:
+ return dbg << v.toUuid();
+ case QCborValue::Invalid:
+ return dbg << "<invalid>";
+ }
+ if (v.isSimpleType())
+ return dbg << v.toSimpleType();
+ return dbg << "<unknown type " << hex << int(v.type()) << dec << '>';
+}
+QDebug operator<<(QDebug dbg, const QCborValue &v)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "QCborValue(";
+ return debugContents(dbg, v) << ')';
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "qcborarray.cpp"
+#include "qcbormap.cpp"
+
+#include "moc_qcborvalue.cpp"
diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h
new file mode 100644
index 0000000000..6d9ed0810a
--- /dev/null
+++ b/src/corelib/serialization/qcborvalue.h
@@ -0,0 +1,467 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCBORVALUE_H
+#define QCBORVALUE_H
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qcborcommon.h>
+#include <QtCore/qregularexpression.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringview.h>
+#include <QtCore/qurl.h>
+#include <QtCore/quuid.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qvector.h>
+
+// See qcborcommon.h for why we check
+#if defined(QT_X11_DEFINES_FOUND)
+# undef True
+# undef False
+#endif
+
+#if 0 && QT_HAS_INCLUDE(<compare>)
+# include <compare>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QCborArray;
+class QCborMap;
+class QCborStreamReader;
+class QCborStreamWriter;
+
+struct QCborParserError
+{
+ qint64 offset = 0;
+ QCborError error = {};
+
+ QString errorString() const { return error.toString(); }
+};
+
+class QCborContainerPrivate;
+class Q_CORE_EXPORT QCborValue
+{
+ Q_GADGET
+public:
+ enum EncodingOption {
+ SortKeysInMaps = 0x01,
+ UseFloat = 0x02,
+ UseFloat16 = UseFloat | 0x04,
+ UseIntegers = 0x08,
+
+ NoTransformation = 0
+ };
+ Q_DECLARE_FLAGS(EncodingOptions, EncodingOption)
+
+ enum DiagnosticNotationOption {
+ Compact = 0x00,
+ LineWrapped = 0x01,
+ ExtendedFormat = 0x02
+ };
+ Q_DECLARE_FLAGS(DiagnosticNotationOptions, DiagnosticNotationOption)
+
+ // different from QCborStreamReader::Type because we have more types
+ enum Type : int {
+ Integer = 0x00,
+ ByteArray = 0x40,
+ String = 0x60,
+ Array = 0x80,
+ Map = 0xa0,
+ Tag = 0xc0,
+
+ // range 0x100 - 0x1ff for Simple Types
+ SimpleType = 0x100,
+ False = SimpleType + int(QCborSimpleType::False),
+ True = SimpleType + int(QCborSimpleType::True),
+ Null = SimpleType + int(QCborSimpleType::Null),
+ Undefined = SimpleType + int(QCborSimpleType::Undefined),
+
+ Double = 0x202,
+
+ // extended (tagged) types
+ DateTime = 0x10000,
+ Url = 0x10020,
+ RegularExpression = 0x10023,
+ Uuid = 0x10025,
+
+ Invalid = -1
+ };
+ Q_ENUM(Type)
+
+ QCborValue() {}
+ QCborValue(Type t_) : t(t_) {}
+ QCborValue(std::nullptr_t) : t(Null) {}
+ QCborValue(bool b_) : t(b_ ? True : False) {}
+#ifndef Q_QDOC
+ QCborValue(int i) : QCborValue(qint64(i)) {}
+ QCborValue(unsigned u) : QCborValue(qint64(u)) {}
+#endif
+ QCborValue(qint64 i) : n(i), t(Integer) {}
+ QCborValue(double v) : t(Double) { memcpy(&n, &v, sizeof(n)); }
+ QCborValue(QCborSimpleType st) : t(type_helper(st)) {}
+
+ QCborValue(const QByteArray &ba);
+ QCborValue(const QString &s);
+ QCborValue(QLatin1String s);
+#ifndef QT_NO_CAST_FROM_ASCII
+ QT_ASCII_CAST_WARN QCborValue(const char *s) : QCborValue(QString::fromUtf8(s)) {}
+#endif
+ QCborValue(const QCborArray &a);
+ QCborValue(QCborArray &&a);
+ QCborValue(const QCborMap &m);
+ QCborValue(QCborMap &&m);
+ QCborValue(QCborTag tag, const QCborValue &taggedValue = QCborValue());
+ QCborValue(QCborKnownTags t_, const QCborValue &tv = QCborValue())
+ : QCborValue(QCborTag(t_), tv)
+ {}
+
+ explicit QCborValue(const QDateTime &dt);
+ explicit QCborValue(const QUrl &url);
+ explicit QCborValue(const QRegularExpression &rx);
+ explicit QCborValue(const QUuid &uuid);
+
+ ~QCborValue() { if (container) dispose(); }
+
+ // make sure const char* doesn't go call the bool constructor
+ QCborValue(const void *) = delete;
+
+ QCborValue(const QCborValue &other);
+ QCborValue(QCborValue &&other) noexcept
+ : n(other.n), container(other.container), t(other.t)
+ {
+ other.t = Undefined;
+ other.container = nullptr;
+ }
+ QCborValue &operator=(const QCborValue &other);
+ QCborValue &operator=(QCborValue &&other) noexcept
+ {
+ QCborValue tmp;
+ qSwap(*this, tmp);
+ qSwap(other, *this);
+ return *this;
+ }
+
+ void swap(QCborValue &other) noexcept
+ {
+ qSwap(n, other.n);
+ qSwap(container, other.container);
+ qSwap(t, other.t);
+ }
+
+ Type type() const { return t; }
+ bool isInteger() const { return type() == Integer; }
+ bool isByteArray() const { return type() == ByteArray; }
+ bool isString() const { return type() == String; }
+ bool isArray() const { return type() == Array; }
+ bool isMap() const { return type() == Map; }
+ bool isTag() const { return isTag_helper(type()); }
+ bool isFalse() const { return type() == False; }
+ bool isTrue() const { return type() == True; }
+ bool isBool() const { return isFalse() || isTrue(); }
+ bool isNull() const { return type() == Null; }
+ bool isUndefined() const { return type() == Undefined; }
+ bool isDouble() const { return type() == Double; }
+ bool isDateTime() const { return type() == DateTime; }
+ bool isUrl() const { return type() == Url; }
+ bool isRegularExpression() const { return type() == RegularExpression; }
+ bool isUuid() const { return type() == Uuid; }
+ bool isInvalid() const { return type() == Invalid; }
+ bool isContainer() const { return isMap() || isArray(); }
+
+ bool isSimpleType() const
+ {
+ return int(type()) >> 8 == int(SimpleType) >> 8;
+ }
+ bool isSimpleType(QCborSimpleType st) const
+ {
+ return type() == type_helper(st);
+ }
+ QCborSimpleType toSimpleType(QCborSimpleType defaultValue = QCborSimpleType::Undefined) const
+ {
+ return isSimpleType() ? QCborSimpleType(type() & 0xff) : defaultValue;
+ }
+
+ qint64 toInteger(qint64 defaultValue = 0) const
+ { return isInteger() ? value_helper() : isDouble() ? qint64(fp_helper()) : defaultValue; }
+ bool toBool(bool defaultValue = false) const
+ { return isBool() ? isTrue() : defaultValue; }
+ double toDouble(double defaultValue = 0) const
+ { return isDouble() ? fp_helper() : isInteger() ? double(value_helper()) : defaultValue; }
+
+ QCborTag tag(QCborTag defaultValue = QCborTag(-1)) const;
+ QCborValue taggedValue(const QCborValue &defaultValue = QCborValue()) const;
+
+ QByteArray toByteArray(const QByteArray &defaultValue = {}) const;
+ QString toString(const QString &defaultValue = {}) const;
+ QDateTime toDateTime(const QDateTime &defaultValue = {}) const;
+ QUrl toUrl(const QUrl &defaultValue = {}) const;
+ QRegularExpression toRegularExpression(const QRegularExpression &defaultValue = {}) const;
+ QUuid toUuid(const QUuid &defaultValue = {}) const;
+
+#ifdef Q_QDOC
+ QCborArray toArray(const QCborArray &a = {}) const;
+ QCborMap toMap(const QCborMap &m = {}) const;
+#else
+ // only forward-declared, need split functions
+ QCborArray toArray() const;
+ QCborArray toArray(const QCborArray &defaultValue) const;
+ QCborMap toMap() const;
+ QCborMap toMap(const QCborMap &defaultValue) const;
+#endif
+
+ const QCborValue operator[](const QString &key) const;
+ const QCborValue operator[](QLatin1String key) const;
+ const QCborValue operator[](qint64 key) const;
+
+ int compare(const QCborValue &other) const;
+#if 0 && QT_HAS_INCLUDE(<compare>)
+ std::strong_ordering operator<=>(const QCborValue &other) const
+ {
+ int c = compare(other);
+ if (c > 0) return std::partial_ordering::greater;
+ if (c == 0) return std::partial_ordering::equivalent;
+ return std::partial_ordering::less;
+ }
+#else
+ bool operator==(const QCborValue &other) const noexcept
+ { return compare(other) == 0; }
+ bool operator!=(const QCborValue &other) const noexcept
+ { return !(*this == other); }
+ bool operator<(const QCborValue &other) const
+ { return compare(other) < 0; }
+#endif
+
+ static QCborValue fromVariant(const QVariant &variant);
+ QVariant toVariant() const;
+ static QCborValue fromJsonValue(const QJsonValue &v);
+ QJsonValue toJsonValue() const;
+
+ static QCborValue fromCbor(QCborStreamReader &reader);
+ static QCborValue fromCbor(const QByteArray &ba, QCborParserError *error = nullptr);
+ static QCborValue fromCbor(const char *data, qsizetype len, QCborParserError *error = nullptr)
+ { return fromCbor(QByteArray(data, int(len)), error); }
+ static QCborValue fromCbor(const quint8 *data, qsizetype len, QCborParserError *error = nullptr)
+ { return fromCbor(QByteArray(reinterpret_cast<const char *>(data), int(len)), error); }
+ QByteArray toCbor(EncodingOptions opt = NoTransformation);
+ void toCbor(QCborStreamWriter &writer, EncodingOptions opt = NoTransformation);
+
+ QString toDiagnosticNotation(DiagnosticNotationOptions opts = Compact) const;
+
+private:
+ friend class QCborValueRef;
+ friend class QCborContainerPrivate;
+ qint64 n = 0;
+ QCborContainerPrivate *container = nullptr;
+ Type t = Undefined;
+
+ void dispose();
+ qint64 value_helper() const
+ {
+ return n;
+ }
+
+ double fp_helper() const
+ {
+ Q_STATIC_ASSERT(sizeof(double) == sizeof(n));
+ double d;
+ memcpy(&d, &n, sizeof(d));
+ return d;
+ }
+
+ Q_DECL_CONSTEXPR static Type type_helper(QCborSimpleType st)
+ {
+ return Type(quint8(st) | SimpleType);
+ }
+
+ Q_DECL_CONSTEXPR static bool isTag_helper(Type t)
+ {
+ return t == Tag || t >= 0x10000;
+ }
+};
+Q_DECLARE_SHARED(QCborValue)
+
+class Q_CORE_EXPORT QCborValueRef
+{
+public:
+ operator QCborValue() const { return concrete(); }
+
+ QCborValueRef(const QCborValueRef &) noexcept = default;
+ QCborValueRef(QCborValueRef &&) noexcept = default;
+ QCborValueRef &operator=(const QCborValue &other)
+ { assign(*this, other); return *this; }
+ QCborValueRef &operator=(QCborValue &&other)
+ { assign(*this, std::move(other)); other.container = nullptr; return *this; }
+ QCborValueRef &operator=(const QCborValueRef &other)
+ { assign(*this, other); return *this; }
+
+ QCborValue::Type type() const { return concreteType(); }
+ bool isInteger() const { return type() == QCborValue::Integer; }
+ bool isByteArray() const { return type() == QCborValue::ByteArray; }
+ bool isString() const { return type() == QCborValue::String; }
+ bool isArray() const { return type() == QCborValue::Array; }
+ bool isMap() const { return type() == QCborValue::Map; }
+ bool isTag() const { return QCborValue::isTag_helper(type()); }
+ bool isFalse() const { return type() == QCborValue::False; }
+ bool isTrue() const { return type() == QCborValue::True; }
+ bool isBool() const { return isFalse() || isTrue(); }
+ bool isNull() const { return type() == QCborValue::Null; }
+ bool isUndefined() const { return type() == QCborValue::Undefined; }
+ bool isDouble() const { return type() == QCborValue::Double; }
+ bool isDateTime() const { return type() == QCborValue::DateTime; }
+ bool isUrl() const { return type() == QCborValue::Url; }
+ bool isRegularExpression() const { return type() == QCborValue::RegularExpression; }
+ bool isUuid() const { return type() == QCborValue::Uuid; }
+ bool isInvalid() const { return type() == QCborValue::Invalid; }
+ bool isContainer() const { return isMap() || isArray(); }
+ bool isSimpleType() const
+ {
+ return type() >= QCborValue::SimpleType && type() < QCborValue::SimpleType + 0x100;
+ }
+ bool isSimpleType(QCborSimpleType st) const
+ {
+ return type() == QCborValue::type_helper(st);
+ }
+
+ QCborTag tag(QCborTag defaultValue = QCborTag(-1)) const
+ { return concrete().tag(defaultValue); }
+ QCborValue taggedValue(const QCborValue &defaultValue = QCborValue()) const
+ { return concrete().taggedValue(defaultValue); }
+
+ qint64 toInteger(qint64 defaultValue = 0) const
+ { return concrete().toInteger(defaultValue); }
+ bool toBool(bool defaultValue = false) const
+ { return concrete().toBool(defaultValue); }
+ double toDouble(double defaultValue = 0) const
+ { return concrete().toDouble(defaultValue); }
+
+ QByteArray toByteArray(const QByteArray &defaultValue = {}) const
+ { return concrete().toByteArray(defaultValue); }
+ QString toString(const QString &defaultValue = {}) const
+ { return concrete().toString(defaultValue); }
+ QDateTime toDateTime(const QDateTime &defaultValue = {}) const
+ { return concrete().toDateTime(defaultValue); }
+ QUrl toUrl(const QUrl &defaultValue = {}) const
+ { return concrete().toUrl(defaultValue); }
+ QRegularExpression toRegularExpression(const QRegularExpression &defaultValue = {}) const
+ { return concrete().toRegularExpression(defaultValue); }
+ QUuid toUuid(const QUuid &defaultValue = {}) const
+ { return concrete().toUuid(defaultValue); }
+
+#ifdef Q_QDOC
+ QCborArray toArray(const QCborArray &a = {}) const;
+ QCborMap toMap(const QCborMap &m = {}) const;
+#else
+ // only forward-declared, need split functions. Implemented in qcbor{array,map}.h
+ QCborArray toArray() const;
+ QCborArray toArray(const QCborArray &a) const;
+ QCborMap toMap() const;
+ QCborMap toMap(const QCborMap &m) const;
+#endif
+
+ int compare(const QCborValue &other) const
+ { return concrete().compare(other); }
+#if 0 && QT_HAS_INCLUDE(<compare>)
+ std::strong_ordering operator<=>(const QCborValue &other) const
+ {
+ int c = compare(other);
+ if (c > 0) return std::strong_ordering::greater;
+ if (c == 0) return std::strong_ordering::equivalent;
+ return std::strong_ordering::less;
+ }
+#else
+ bool operator==(const QCborValue &other) const
+ { return compare(other) == 0; }
+ bool operator!=(const QCborValue &other) const
+ { return !(*this == other); }
+ bool operator<(const QCborValue &other) const
+ { return compare(other) < 0; }
+#endif
+
+ QVariant toVariant() const { return concrete().toVariant(); }
+ QJsonValue toJsonValue() const;
+
+ QByteArray toCbor(QCborValue::EncodingOptions opt = QCborValue::NoTransformation)
+ { return concrete().toCbor(opt); }
+ void toCbor(QCborStreamWriter &writer, QCborValue::EncodingOptions opt = QCborValue::NoTransformation);
+
+ QString toDiagnosticNotation(QCborValue::DiagnosticNotationOptions opt = QCborValue::Compact)
+ { return concrete().toDiagnosticNotation(opt); }
+
+private:
+ friend class QCborArray;
+ friend class QCborMap;
+ friend class QCborContainerPrivate;
+ friend class QCborValueRefPtr;
+
+ // static so we can pass this by value
+ static void assign(QCborValueRef that, const QCborValue &other);
+ static void assign(QCborValueRef that, QCborValue &&other);
+ static void assign(QCborValueRef that, const QCborValueRef other);
+ static QCborValue concrete(QCborValueRef that) noexcept;
+ QCborValue concrete() const noexcept { return concrete(*this); }
+
+ static QCborValue::Type concreteType(QCborValueRef self) noexcept Q_DECL_PURE_FUNCTION;
+ QCborValue::Type concreteType() const noexcept { return concreteType(*this); }
+
+ // this will actually be invalid...
+ Q_DECL_CONSTEXPR QCborValueRef() : d(nullptr), i(0) {}
+
+ QCborValueRef(QCborContainerPrivate *dd, qsizetype ii)
+ : d(dd), i(ii)
+ {}
+ QCborContainerPrivate *d;
+ qsizetype i;
+};
+
+Q_CORE_EXPORT uint qHash(const QCborValue &value, uint seed = 0);
+
+#if !defined(QT_NO_DEBUG_STREAM)
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborValue &v);
+#endif
+
+QT_END_NAMESPACE
+
+#if defined(QT_X11_DEFINES_FOUND)
+# define True 1
+# define False 0
+#endif
+
+#endif // QCBORVALUE_H
diff --git a/src/corelib/serialization/qcborvalue_p.h b/src/corelib/serialization/qcborvalue_p.h
new file mode 100644
index 0000000000..3a28707056
--- /dev/null
+++ b/src/corelib/serialization/qcborvalue_p.h
@@ -0,0 +1,398 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCBORVALUE_P_H
+#define QCBORVALUE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API.
+// This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qcborvalue.h"
+
+#include <private/qglobal_p.h>
+#include <private/qutfcodec_p.h>
+
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtCbor {
+struct Undefined {};
+struct Element
+{
+ enum ValueFlag : quint32 {
+ IsContainer = 0x0001,
+ HasByteData = 0x0002,
+ StringIsUtf16 = 0x0004,
+ StringIsAscii = 0x0008
+ };
+ Q_DECLARE_FLAGS(ValueFlags, ValueFlag)
+
+ union {
+ qint64 value;
+ QCborContainerPrivate *container;
+ };
+ QCborValue::Type type;
+ ValueFlags flags = {};
+
+ Element(qint64 v = 0, QCborValue::Type t = QCborValue::Undefined, ValueFlags f = {})
+ : value(v), type(t), flags(f)
+ {}
+
+ Element(QCborContainerPrivate *d, QCborValue::Type t, ValueFlags f = {})
+ : container(d), type(t), flags(f | IsContainer)
+ {}
+
+ double fpvalue() const
+ {
+ double d;
+ memcpy(&d, &value, sizeof(d));
+ return d;
+ }
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(Element::ValueFlags)
+Q_STATIC_ASSERT(sizeof(Element) == 16);
+
+struct ByteData
+{
+ QByteArray::size_type len;
+
+ const char *byte() const { return reinterpret_cast<const char *>(this + 1); }
+ char *byte() { return reinterpret_cast<char *>(this + 1); }
+ const QChar *utf16() const { return reinterpret_cast<const QChar *>(this + 1); }
+ QChar *utf16() { return reinterpret_cast<QChar *>(this + 1); }
+
+ QByteArray toByteArray() const { return QByteArray(byte(), len); }
+ QString toString() const { return QString(utf16(), len / 2); }
+ QString toUtf8String() const { return QString::fromUtf8(byte(), len); }
+
+ QByteArray asByteArrayView() const { return QByteArray::fromRawData(byte(), len); }
+ QLatin1String asLatin1() const { return QLatin1String(byte(), len); }
+ QStringView asStringView() const{ return QStringView(utf16(), len / 2); }
+ QString asQStringRaw() const { return QString::fromRawData(utf16(), len / 2); }
+};
+Q_STATIC_ASSERT(std::is_pod<ByteData>::value);
+} // namespace QtCbor
+
+Q_DECLARE_TYPEINFO(QtCbor::Element, Q_PRIMITIVE_TYPE);
+
+class QCborContainerPrivate : public QSharedData
+{
+ friend class QExplicitlySharedDataPointer<QCborContainerPrivate>;
+ ~QCborContainerPrivate();
+
+public:
+ enum ContainerDisposition { CopyContainer, MoveContainer };
+
+ QByteArray::size_type usedData = 0;
+ QByteArray data;
+ QVector<QtCbor::Element> elements;
+
+ void deref() { if (!ref.deref()) delete this; }
+ void compact(qsizetype reserved);
+ static QCborContainerPrivate *clone(QCborContainerPrivate *d, qsizetype reserved = -1);
+ static QCborContainerPrivate *detach(QCborContainerPrivate *d, qsizetype reserved);
+
+ qptrdiff addByteData(const char *block, qsizetype len)
+ {
+ // This function does not do overflow checking, since the len parameter
+ // is expected to be trusted. There's another version of this function
+ // in decodeStringFromCbor(), which checks.
+
+ qptrdiff offset = data.size();
+
+ // align offset
+ offset += Q_ALIGNOF(QtCbor::ByteData) - 1;
+ offset &= ~(Q_ALIGNOF(QtCbor::ByteData) - 1);
+
+ qptrdiff increment = qptrdiff(sizeof(QtCbor::ByteData)) + len;
+
+ usedData += increment;
+ data.resize(offset + increment);
+
+ char *ptr = data.begin() + offset;
+ auto b = new (ptr) QtCbor::ByteData;
+ b->len = len;
+ if (block)
+ memcpy(b->byte(), block, len);
+
+ return offset;
+ }
+
+ const QtCbor::ByteData *byteData(QtCbor::Element e) const
+ {
+ if ((e.flags & QtCbor::Element::HasByteData) == 0)
+ return nullptr;
+
+ size_t offset = size_t(e.value);
+ Q_ASSERT((offset % Q_ALIGNOF(QtCbor::ByteData)) == 0);
+ Q_ASSERT(offset + sizeof(QtCbor::ByteData) <= size_t(data.size()));
+
+ auto b = reinterpret_cast<const QtCbor::ByteData *>(data.constData() + offset);
+ Q_ASSERT(offset + sizeof(*b) + size_t(b->len) <= size_t(data.size()));
+ return b;
+ }
+ const QtCbor::ByteData *byteData(qsizetype idx) const
+ {
+ return byteData(elements.at(idx));
+ }
+
+ QCborContainerPrivate *containerAt(qsizetype idx, QCborValue::Type type) const
+ {
+ const QtCbor::Element &e = elements.at(idx);
+ if (e.type != type || (e.flags & QtCbor::Element::IsContainer) == 0)
+ return nullptr;
+ return e.container;
+ }
+
+ void replaceAt_complex(QtCbor::Element &e, const QCborValue &value, ContainerDisposition disp);
+ void replaceAt_internal(QtCbor::Element &e, const QCborValue &value, ContainerDisposition disp)
+ {
+ if (value.container)
+ return replaceAt_complex(e, value, disp);
+
+ e.value = value.value_helper();
+ e.type = value.type();
+ if (value.isContainer())
+ e.container = nullptr;
+ }
+ void replaceAt(qsizetype idx, const QCborValue &value, ContainerDisposition disp = CopyContainer)
+ {
+ QtCbor::Element &e = elements[idx];
+ if (e.flags & QtCbor::Element::IsContainer) {
+ e.container->deref();
+ e.container = nullptr;
+ e.flags = {};
+ } else if (auto b = byteData(e)) {
+ usedData -= b->len + sizeof(QtCbor::ByteData);
+ }
+ replaceAt_internal(e, value, disp);
+ }
+ void insertAt(qsizetype idx, const QCborValue &value, ContainerDisposition disp = CopyContainer)
+ {
+ replaceAt_internal(*elements.insert(elements.begin() + idx, {}), value, disp);
+ }
+
+ void append(QtCbor::Undefined)
+ {
+ elements.append(QtCbor::Element());
+ }
+ void append(qint64 value)
+ {
+ elements.append(QtCbor::Element(value , QCborValue::Integer));
+ }
+ void append(QCborTag tag)
+ {
+ elements.append(QtCbor::Element(qint64(tag), QCborValue::Tag));
+ }
+ void appendByteData(const char *data, qsizetype len, QCborValue::Type type,
+ QtCbor::Element::ValueFlags extraFlags = {})
+ {
+ elements.append(QtCbor::Element(addByteData(data, len), type,
+ QtCbor::Element::HasByteData | extraFlags));
+ }
+ void append(QLatin1String s)
+ {
+ if (!QtPrivate::isAscii(s))
+ return append(QString(s));
+
+ // US-ASCII is a subset of UTF-8, so we can keep in 8-bit
+ appendByteData(s.latin1(), s.size(), QCborValue::String,
+ QtCbor::Element::StringIsAscii);
+ }
+ void appendAsciiString(const QString &s);
+ void append(const QString &s)
+ {
+ if (QtPrivate::isAscii(s))
+ appendAsciiString(s);
+ else
+ appendByteData(reinterpret_cast<const char *>(s.constData()), s.size() * 2,
+ QCborValue::String, QtCbor::Element::StringIsUtf16);
+ }
+ void append(const QCborValue &v)
+ {
+ insertAt(elements.size(), v);
+ }
+
+ QByteArray byteArrayAt(qsizetype idx) const
+ {
+ const auto &e = elements.at(idx);
+ const auto data = byteData(e);
+ if (!data)
+ return QByteArray();
+ return data->toByteArray();
+ }
+ QString stringAt(qsizetype idx) const
+ {
+ const auto &e = elements.at(idx);
+ const auto data = byteData(e);
+ if (!data)
+ return QString();
+ if (e.flags & QtCbor::Element::StringIsUtf16)
+ return data->toString();
+ if (e.flags & QtCbor::Element::StringIsAscii)
+ return data->asLatin1();
+ return data->toUtf8String();
+ }
+
+ static void resetValue(QCborValue &v)
+ {
+ v.container = nullptr;
+ }
+
+ static QCborValue makeValue(QCborValue::Type type, qint64 n, QCborContainerPrivate *d = nullptr,
+ ContainerDisposition disp = CopyContainer)
+ {
+ QCborValue result(type);
+ result.n = n;
+ result.container = d;
+ if (d && disp == CopyContainer)
+ d->ref.ref();
+ return result;
+ }
+
+ QCborValue valueAt(qsizetype idx) const
+ {
+ const auto &e = elements.at(idx);
+
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.type == QCborValue::Tag && e.container->elements.size() != 2) {
+ // invalid tags can be created due to incomplete parsing
+ return makeValue(QCborValue::Invalid, 0, nullptr);
+ }
+ return makeValue(e.type, -1, e.container);
+ } else if (e.flags & QtCbor::Element::HasByteData) {
+ return makeValue(e.type, idx, const_cast<QCborContainerPrivate *>(this));
+ }
+ return makeValue(e.type, e.value);
+ }
+ QCborValue extractAt_complex(QtCbor::Element e);
+ QCborValue extractAt(qsizetype idx)
+ {
+ QtCbor::Element e;
+ qSwap(e, elements[idx]);
+
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.type == QCborValue::Tag && e.container->elements.size() != 2) {
+ // invalid tags can be created due to incomplete parsing
+ e.container->deref();
+ return makeValue(QCborValue::Invalid, 0, nullptr);
+ }
+ return makeValue(e.type, -1, e.container, MoveContainer);
+ } else if (e.flags & QtCbor::Element::HasByteData) {
+ return extractAt_complex(e);
+ }
+ return makeValue(e.type, e.value);
+ }
+
+ static QtCbor::Element elementFromValue(const QCborValue &value)
+ {
+ if (value.n >= 0 && value.container)
+ return value.container->elements.at(value.n);
+
+ QtCbor::Element e;
+ e.value = value.n;
+ e.type = value.t;
+ if (value.container) {
+ e.container = value.container;
+ e.flags = QtCbor::Element::IsContainer;
+ }
+ return e;
+ }
+
+ bool stringEqualsElement(qsizetype idx, QLatin1String s) const
+ {
+ const auto &e = elements.at(idx);
+ if (e.type != QCborValue::String)
+ return false;
+
+ const QtCbor::ByteData *b = byteData(idx);
+ if (!b)
+ return s.isEmpty();
+
+ if (e.flags & QtCbor::Element::StringIsUtf16)
+ return QtPrivate::compareStrings(b->asStringView(), s) == 0;
+ return QUtf8::compareUtf8(b->byte(), b->len, s) == 0;
+ }
+ bool stringEqualsElement(qsizetype idx, const QString &s) const
+ {
+ const auto &e = elements.at(idx);
+ if (e.type != QCborValue::String)
+ return false;
+
+ const QtCbor::ByteData *b = byteData(idx);
+ if (!b)
+ return s.isEmpty();
+
+ if (e.flags & QtCbor::Element::StringIsUtf16)
+ return QtPrivate::compareStrings(b->asStringView(), s) == 0;
+ return QUtf8::compareUtf8(b->byte(), b->len, s.data(), s.size()) == 0;
+ }
+
+ static int compareElement_helper(const QCborContainerPrivate *c1, QtCbor::Element e1,
+ const QCborContainerPrivate *c2, QtCbor::Element e2);
+ int compareElement(qsizetype idx, const QCborValue &value) const
+ {
+ auto &e1 = elements.at(idx);
+ auto e2 = elementFromValue(value);
+ return compareElement_helper(this, e1, value.container, e2);
+ }
+
+ void removeAt(qsizetype idx)
+ {
+ replaceAt(idx, {});
+ elements.remove(idx);
+ }
+
+ void decodeValueFromCbor(QCborStreamReader &reader);
+ void decodeFromCbor(QCborStreamReader &reader);
+ void decodeStringFromCbor(QCborStreamReader &reader);
+};
+
+QT_END_NAMESPACE
+
+#endif // QCBORVALUE_P_H
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index 09e98cb2b4..c81da70e61 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -564,6 +564,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_9 Same as Qt_5_6
\value Qt_5_10 Same as Qt_5_6
\value Qt_5_11 Same as Qt_5_6
+ \value Qt_5_12 Version 18 (Qt 5.12)
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h
index 1775022355..eae0146553 100644
--- a/src/corelib/serialization/qdatastream.h
+++ b/src/corelib/serialization/qdatastream.h
@@ -98,10 +98,11 @@ public:
Qt_5_9 = Qt_5_8,
Qt_5_10 = Qt_5_9,
Qt_5_11 = Qt_5_10,
-#if QT_VERSION >= 0x050c00
+ Qt_5_12 = 18,
+#if QT_VERSION >= 0x050d00
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_11
+ Qt_DefaultCompiledVersion = Qt_5_12
};
enum ByteOrder {
diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h
index dc56a49084..feba1faac6 100644
--- a/src/corelib/serialization/qjson_p.h
+++ b/src/corelib/serialization/qjson_p.h
@@ -69,6 +69,9 @@
QT_BEGIN_NAMESPACE
+// in qstring.cpp
+void qt_to_latin1_unchecked(uchar *dst, const ushort *uc, qsizetype len);
+
/*
This defines a binary data structure for Json data. The data structure is optimised for fast reading
and minimum allocations. The whole data structure can be mmap'ed and used directly.
@@ -294,31 +297,10 @@ public:
int len = d->length = str.length();
uchar *l = (uchar *)d->latin1;
const ushort *uc = (const ushort *)str.unicode();
- int i = 0;
-#ifdef __SSE2__
- for ( ; i + 16 <= len; i += 16) {
- __m128i chunk1 = _mm_loadu_si128((__m128i*)&uc[i]); // load
- __m128i chunk2 = _mm_loadu_si128((__m128i*)&uc[i + 8]); // load
- // pack the two vector to 16 x 8bits elements
- const __m128i result = _mm_packus_epi16(chunk1, chunk2);
- _mm_storeu_si128((__m128i*)&l[i], result); // store
- }
-# ifdef Q_PROCESSOR_X86_64
- // we can do one more round, of 8 characters
- if (i + 8 <= len) {
- __m128i chunk = _mm_loadu_si128((__m128i*)&uc[i]); // load
- // pack with itself, we'll discard the high part anyway
- chunk = _mm_packus_epi16(chunk, chunk);
- // unaligned 64-bit store
- qToUnaligned(_mm_cvtsi128_si64(chunk), l + i);
- i += 8;
- }
-# endif
-#endif
- for ( ; i < len; ++i)
- l[i] = uc[i];
- for ( ; (quintptr)(l+i) & 0x3; ++i)
- l[i] = 0;
+ qt_to_latin1_unchecked(l, uc, len);
+
+ for ( ; (quintptr)(l+len) & 0x3; ++len)
+ l[len] = 0;
return *this;
}
diff --git a/src/corelib/serialization/qjsonarray.cpp b/src/corelib/serialization/qjsonarray.cpp
index 8ee9ce0de7..1187bb03a3 100644
--- a/src/corelib/serialization/qjsonarray.cpp
+++ b/src/corelib/serialization/qjsonarray.cpp
@@ -1237,6 +1237,10 @@ void QJsonArray::compact()
a = static_cast<QJsonPrivate::Array *>(d->header->root());
}
+uint qHash(const QJsonArray &array, uint seed)
+{
+ return qHashRange(array.begin(), array.end(), seed);
+}
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonArray &a)
diff --git a/src/corelib/serialization/qjsonarray.h b/src/corelib/serialization/qjsonarray.h
index 8d41138c97..5dff4a0aa9 100644
--- a/src/corelib/serialization/qjsonarray.h
+++ b/src/corelib/serialization/qjsonarray.h
@@ -265,6 +265,8 @@ private:
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonArray)
+Q_CORE_EXPORT uint qHash(const QJsonArray &array, uint seed = 0);
+
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
#endif
diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp
new file mode 100644
index 0000000000..158f1950d0
--- /dev/null
+++ b/src/corelib/serialization/qjsoncbor.cpp
@@ -0,0 +1,954 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcborvalue.h"
+#include "qcborvalue_p.h"
+
+#include "qcborarray.h"
+#include "qcbormap.h"
+#include "qjson_p.h"
+
+#include <private/qnumeric_p.h>
+#include <quuid.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QtCbor;
+
+static QJsonValue fpToJson(double v)
+{
+ return qt_is_finite(v) ? QJsonValue(v) : QJsonValue();
+}
+
+static QString simpleTypeString(QCborValue::Type t)
+{
+ int simpleType = t - QCborValue::SimpleType;
+ if (unsigned(simpleType) < 0x100)
+ return QString::fromLatin1("simple(%1)").arg(simpleType);
+
+ // if we got here, we got an unknown type
+ qWarning("QCborValue: found unknown type 0x%x", t);
+ return QString();
+
+}
+
+static QString encodeByteArray(const QCborContainerPrivate *d, qsizetype idx, QCborTag encoding)
+{
+ const ByteData *b = d->byteData(idx);
+ if (!b)
+ return QString();
+
+ QByteArray data = QByteArray::fromRawData(b->byte(), b->len);
+ if (encoding == QCborKnownTags::ExpectedBase16)
+ data = data.toHex();
+ else if (encoding == QCborKnownTags::ExpectedBase64)
+ data = data.toBase64();
+ else
+ data = data.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
+
+ return QString::fromLatin1(data, data.size());
+}
+
+static QString makeString(const QCborContainerPrivate *d, qsizetype idx);
+
+static QString maybeEncodeTag(const QCborContainerPrivate *d)
+{
+ qint64 tag = d->elements.at(0).value;
+ const Element &e = d->elements.at(1);
+ const ByteData *b = d->byteData(e);
+
+ switch (tag) {
+ case qint64(QCborKnownTags::DateTimeString):
+ case qint64(QCborKnownTags::Url):
+ if (e.type == QCborValue::String)
+ return makeString(d, 1);
+ break;
+
+ case qint64(QCborKnownTags::ExpectedBase64url):
+ case qint64(QCborKnownTags::ExpectedBase64):
+ case qint64(QCborKnownTags::ExpectedBase16):
+ if (e.type == QCborValue::ByteArray)
+ return encodeByteArray(d, 1, QCborTag(tag));
+ break;
+
+ case qint64(QCborKnownTags::Uuid):
+ if (e.type == QCborValue::ByteArray && b->len == sizeof(QUuid))
+ return QUuid::fromRfc4122(b->asByteArrayView()).toString(QUuid::WithoutBraces);
+ }
+
+ // don't know what to do, bail out
+ return QString();
+}
+
+static QString encodeTag(const QCborContainerPrivate *d)
+{
+ QString s;
+ if (!d || d->elements.size() != 2)
+ return s; // invalid (incomplete?) tag state
+
+ s = maybeEncodeTag(d);
+ if (s.isNull()) {
+ // conversion failed, ignore the tag and convert the tagged value
+ s = makeString(d, 1);
+ }
+ return s;
+}
+
+static Q_NEVER_INLINE QString makeString(const QCborContainerPrivate *d, qsizetype idx)
+{
+ const auto &e = d->elements.at(idx);
+
+ switch (e.type) {
+ case QCborValue::Integer:
+ return QString::number(qint64(e.value));
+
+ case QCborValue::Double:
+ return QString::number(e.fpvalue());
+
+ case QCborValue::ByteArray:
+ return encodeByteArray(d, idx, QCborTag(QCborKnownTags::ExpectedBase64url));
+
+ case QCborValue::String:
+ return d->stringAt(idx);
+
+ case QCborValue::Array:
+ case QCborValue::Map:
+ return d->valueAt(idx).toDiagnosticNotation(QCborValue::Compact);
+
+ case QCborValue::SimpleType:
+ break;
+
+ case QCborValue::False:
+ return QStringLiteral("false");
+
+ case QCborValue::True:
+ return QStringLiteral("true");
+
+ case QCborValue::Null:
+ return QStringLiteral("null");
+
+ case QCborValue::Undefined:
+ return QStringLiteral("undefined");
+
+ case QCborValue::Invalid:
+ return QString();
+
+ case QCborValue::Tag:
+ case QCborValue::DateTime:
+ case QCborValue::Url:
+ case QCborValue::RegularExpression:
+ case QCborValue::Uuid:
+ return encodeTag(e.flags & Element::IsContainer ? e.container : nullptr);
+ }
+
+ // maybe it's a simple type
+ return simpleTypeString(e.type);
+}
+
+static QJsonValue convertToJson(const QCborContainerPrivate *d, qsizetype idx);
+
+static QJsonArray convertToJsonArray(const QCborContainerPrivate *d)
+{
+ QJsonArray a;
+ if (d) {
+ for (qsizetype idx = 0; idx < d->elements.size(); ++idx)
+ a.append(convertToJson(d, idx));
+ }
+ return a;
+}
+
+static QJsonObject convertToJsonObject(const QCborContainerPrivate *d)
+{
+ QJsonObject o;
+ if (d) {
+ for (qsizetype idx = 0; idx < d->elements.size(); idx += 2)
+ o.insert(makeString(d, idx), convertToJson(d, idx + 1));
+ }
+ return o;
+}
+
+static QJsonValue convertExtendedTypeToJson(const QCborContainerPrivate *d)
+{
+ qint64 tag = d->elements.at(0).value;
+
+ switch (tag) {
+ case qint64(QCborKnownTags::Url):
+ // use the fullly-encoded URL form
+ if (d->elements.at(1).type == QCborValue::String)
+ return QUrl::fromEncoded(d->byteData(1)->asByteArrayView()).toString(QUrl::FullyEncoded);
+ Q_FALLTHROUGH();
+
+ case qint64(QCborKnownTags::DateTimeString):
+ case qint64(QCborKnownTags::ExpectedBase64url):
+ case qint64(QCborKnownTags::ExpectedBase64):
+ case qint64(QCborKnownTags::ExpectedBase16):
+ case qint64(QCborKnownTags::Uuid): {
+ // use the string conversion
+ QString s = maybeEncodeTag(d);
+ if (!s.isNull())
+ return s;
+ }
+ }
+
+ // for all other tags, ignore it and return the converted tagged item
+ return convertToJson(d, 1);
+}
+
+static QJsonValue convertToJson(const QCborContainerPrivate *d, qsizetype idx)
+{
+ // encoding the container itself
+ if (idx == -QCborValue::Array)
+ return convertToJsonArray(d);
+ if (idx == -QCborValue::Map)
+ return convertToJsonObject(d);
+ if (idx < 0) {
+ // tag-like type
+ if (!d || d->elements.size() != 2)
+ return QJsonValue::Undefined; // invalid state
+ return convertExtendedTypeToJson(d);
+ }
+
+ // an element in the container
+ const auto &e = d->elements.at(idx);
+ switch (e.type) {
+ case QCborValue::Integer:
+ return qint64(e.value);
+
+ case QCborValue::ByteArray:
+ case QCborValue::String:
+ case QCborValue::SimpleType:
+ // make string
+ break;
+
+ case QCborValue::Array:
+ case QCborValue::Map:
+ case QCborValue::Tag:
+ case QCborValue::DateTime:
+ case QCborValue::Url:
+ case QCborValue::RegularExpression:
+ case QCborValue::Uuid:
+ // recurse
+ return convertToJson(e.flags & Element::IsContainer ? e.container : nullptr, -e.type);
+
+ case QCborValue::Null:
+ return QJsonValue();
+
+ case QCborValue::Undefined:
+ case QCborValue::Invalid:
+ return QJsonValue(QJsonValue::Undefined);
+
+ case QCborValue::False:
+ return false;
+
+ case QCborValue::True:
+ return true;
+
+ case QCborValue::Double:
+ return fpToJson(e.fpvalue());
+ }
+
+ return makeString(d, idx);
+}
+
+/*!
+ Converts this QCborValue object to an equivalent representation in JSON and
+ returns it as a QJsonValue.
+
+ Please note that CBOR contains a richer and wider type set than JSON, so
+ some information may be lost in this conversion. The following table
+ compares CBOR types to JSON types and indicates whether information may be
+ lost or not.
+
+ \table
+ \header \li CBOR Type \li JSON Type \li Comments
+ \row \li Bool \li Bool \li No data loss possible
+ \row \li Double \li Number \li Infinities and NaN will be converted to Null;
+ no data loss for other values
+ \row \li Integer \li Number \li Data loss possible in the conversion if the
+ integer is larger than 2\sup{53} or smaller
+ than -2\sup{53}.
+ \row \li Null \li Null \li No data loss possible
+ \row \li Undefined \li Null \li Type information lost
+ \row \li String \li String \li No data loss possible
+ \row \li Byte Array \li String \li Converted to a lossless encoding like Base64url,
+ but the distinction between strings and byte
+ arrays is lost
+ \row \li Other simple types \li String \li Type information lost
+ \row \li Array \li Array \li Conversion applies to each contained value
+ \row \li Map \li Object \li Keys are converted to string; values converted
+ according to this table
+ \row \li Tags and extended types \li Special \li The tag number itself is lost and the tagged
+ value is converted to JSON
+ \endtable
+
+ For information on the conversion of CBOR map keys to string, see
+ QCborMap::toJsonObject().
+
+ If this QCborValue contains the undefined value, this function will return
+ an undefined QJsonValue too. Note that JSON does not support undefined
+ values and undefined QJsonValues are an extension to the specification.
+ They cannot be held in a QJsonArray or QJsonObject, but can be returned
+ from functions to indicate a failure. For all other intents and purposes,
+ they are the same as null.
+
+ \section3 Special handling of tags and extended types
+
+ Some tags are handled specially and change the transformation of the tagged
+ value from CBOR to JSON. The following table lists those special cases:
+
+ \table
+ \header \li Tag \li CBOR type \li Transformation
+ \row \li ExpectedBase64url \li Byte array \li Encodes the byte array as Base64url
+ \row \li ExpectedBase64 \li Byte array \li Encodes the byte array as Base64
+ \row \li ExpectedBase16 \li Byte array \li Encodes the byte array as hex
+ \row \li Url \li Url and String \li Uses QUrl::toEncoded() to normalize the
+ encoding to the URL's fully encoded format
+ \row \li Uuid \li Uuid and Byte array \li Uses QUuid::toString() to create
+ the string representation
+ \endtable
+
+ \sa fromJsonValue(), toVariant(), QCborArray::toJsonArray(), QCborMap::toJsonObject()
+ */
+QJsonValue QCborValue::toJsonValue() const
+{
+ if (container)
+ return convertToJson(container, n < 0 ? -type() : n);
+
+ // simple values
+ switch (type()) {
+ case Integer:
+ return n;
+
+ case Null:
+ return QJsonValue();
+
+ case False:
+ return false;
+
+ case True:
+ return true;
+
+ case Double:
+ return fpToJson(fp_helper());
+
+ case SimpleType:
+ break;
+
+ case Undefined:
+ case Invalid:
+ return QJsonValue(QJsonValue::Undefined);
+
+ case ByteArray:
+ case String:
+ // empty strings
+ return QString();
+
+ case Array:
+ // empty array
+ return QJsonArray();
+
+ case Map:
+ // empty map
+ return QJsonObject();
+
+ case Tag:
+ case DateTime:
+ case Url:
+ case RegularExpression:
+ case Uuid:
+ Q_UNREACHABLE();
+ return QJsonValue::Undefined;
+ }
+
+ return simpleTypeString(type());
+}
+
+QJsonValue QCborValueRef::toJsonValue() const
+{
+ return convertToJson(d, i);
+}
+
+/*!
+ Recursively converts every \l QCborValue element in this array to JSON
+ using QCborValue::toJsonValue() and returns the corresponding QJsonArray
+ composed of those elements.
+
+ Please note that CBOR contains a richer and wider type set than JSON, so
+ some information may be lost in this conversion. For more details on what
+ conversions are applied, see QCborValue::toJsonValue().
+
+ \sa fromJsonArray(), QCborValue::toJsonValue(), QCborMap::toJsonObject(), toVariantList()
+ */
+QJsonArray QCborArray::toJsonArray() const
+{
+ return convertToJsonArray(d.data());
+}
+
+/*!
+ Recursively converts every \l QCborValue value in this array to JSON using
+ QCborValue::toJsonValue() and creates a string key for all keys that aren't
+ strings, then returns the corresponding QJsonObject composed of those
+ associations.
+
+ Please note that CBOR contains a richer and wider type set than JSON, so
+ some information may be lost in this conversion. For more details on what
+ conversions are applied, see QCborValue::toJsonValue().
+
+ \section3 Map key conversion to string
+
+ JSON objects are defined as having string keys, unlike CBOR, so the
+ conversion of a QCborMap to QJsonObject will imply a step of
+ "stringification" of the key values. The conversion will use the special
+ handling of tags and extended types from above and will also convert the
+ rest of the types as follows:
+
+ \table
+ \header \li Type \li Transformation
+ \row \li Bool \li "true" and "false"
+ \row \li Null \li "null"
+ \row \li Undefined \li "undefined"
+ \row \li Integer \li The decimal string form of the number
+ \row \li Double \li The decimal string form of the number
+ \row \li Byte array \li Unless tagged differently (see above), encoded as
+ Base64url
+ \row \li Array \li Replaced by the compact form of its
+ \l{QCborValue::toDiagnosticNotation()}{Diagnostic notation}
+ \row \li Map \li Replaced by the compact form of its
+ \l{QCborValue::toDiagnosticNotation()}{Diagnostic notation}
+ \row \li Tags and extended types \li Tag number is dropped and the tagged value is converted
+ to string
+ \endtable
+
+ \sa fromJsonObject(), QCborValue::toJsonValue(), QCborArray::toJsonArray(), toVariantMap()
+ */
+QJsonObject QCborMap::toJsonObject() const
+{
+ return convertToJsonObject(d.data());
+}
+
+/*!
+ Converts this value to a native Qt type and returns the corresponding QVariant.
+
+ The following table lists the mapping performed between \l{Type}{QCborValue
+ types} and \l{QMetaType::Type}{Qt meta types}.
+
+ \table
+ \header \li CBOR Type \li Qt or C++ type \li Notes
+ \row \li Integer \li \l qint64 \li
+ \row \li Double \li \c double \li
+ \row \li Bool \li \c bool \li
+ \row \li Null \li \c std::nullptr_t \li
+ \row \li Undefined \li no type (QVariant()) \li
+ \row \li Byte array \li \l QByteArray \li
+ \row \li String \li \l QString \li
+ \row \li Array \li \l QVariantList \li Recursively converts all values
+ \row \li Map \li \l QVariantMap \li Key types are "stringified"
+ \row \li Other simple types \li \l QCborSimpleType \li
+ \row \li DateTime \li \l QDateTime \li
+ \row \li Url \li \l QUrl \li
+ \row \li RegularExpression \li \l QRegularExpression \li
+ \row \li Uuid \li \l QUuid \li
+ \row \li Other tags \li Special \li The tag is ignored and the tagged
+ value is converted using this
+ function
+ \endtable
+
+ Note that values in both CBOR Maps and Arrays are converted recursively
+ using this function too and placed in QVariantMap and QVariantList instead.
+ You will not find QCborMap and QCborArray stored inside the QVariants.
+
+ QVariantMaps have string keys, unlike CBOR, so the conversion of a QCborMap
+ to QVariantMap will imply a step of "stringification" of the key values.
+ See QCborMap::toJsonObject() for details.
+
+ \sa fromVariant(), toJsonValue(), QCborArray::toVariantList(), QCborMap::toVariantMap()
+ */
+QVariant QCborValue::toVariant() const
+{
+ switch (type()) {
+ case Integer:
+ return toInteger();
+
+ case Double:
+ return toDouble();
+
+ case SimpleType:
+ break;
+
+ case False:
+ case True:
+ return isTrue();
+
+ case Null:
+ return QVariant::fromValue(nullptr);
+
+ case Undefined:
+ return QVariant();
+
+ case ByteArray:
+ return toByteArray();
+
+ case String:
+ return toString();
+
+ case Array:
+ return toArray().toVariantList();
+
+ case Map:
+ return toMap().toVariantMap();
+
+ case Tag:
+ // ignore tags
+ return taggedValue().toVariant();
+
+ case DateTime:
+ return toDateTime();
+
+ case Url:
+ return toUrl();
+
+ case RegularExpression:
+ return toRegularExpression();
+
+ case Uuid:
+ return toUuid();
+
+ case Invalid:
+ return QVariant();
+ }
+
+ if (isSimpleType())
+ return QVariant::fromValue(toSimpleType());
+
+ Q_UNREACHABLE();
+ return QVariant();
+}
+
+/*!
+ Converts the JSON value contained in \a v into its corresponding CBOR value
+ and returns it. There is no data loss in converting from JSON to CBOR, as
+ the CBOR type set is richer than JSON's. Additionally, values converted to
+ CBOR using this function can be converted back to JSON using toJsonValue()
+ with no data loss.
+
+ The following table lists the mapping of JSON types to CBOR types:
+
+ \table
+ \header \li JSON Type \li CBOR Type
+ \row \li Bool \li Bool
+ \row \li Number \li Integer (if the number has no fraction and is in the \l qint64
+ range) or Double
+ \row \li String \li String
+ \row \li Array \li Array
+ \row \li Object \li Map
+ \row \li Null \li Null
+ \endtable
+
+ \l QJsonValue can also be undefined, indicating a previous operation that
+ failed to complete (for example, searching for a key not present in an
+ object). Undefined values are not JSON types and may not appear in JSON
+ arrays and objects, but this function does return the QCborValue undefined
+ value if the corresponding QJsonValue is undefined.
+
+ \sa toJsonValue(), fromVariant(), QCborArray::fromJsonArray(), QCborMap::fromJsonObject()
+ */
+QCborValue QCborValue::fromJsonValue(const QJsonValue &v)
+{
+ switch (v.type()) {
+ case QJsonValue::Bool:
+ return v.b;
+ case QJsonValue::Double:
+ if (v.dbl == qint64(v.dbl))
+ return qint64(v.dbl);
+ return v.dbl;
+ case QJsonValue::String:
+ return v.toString();
+ case QJsonValue::Array:
+ return QCborArray::fromJsonArray(v.toArray());
+ case QJsonValue::Object:
+ return QCborMap::fromJsonObject(v.toObject());
+ case QJsonValue::Null:
+ return nullptr;
+ case QJsonValue::Undefined:
+ break;
+ }
+ return QCborValue();
+}
+
+static void appendVariant(QCborContainerPrivate *d, const QVariant &variant)
+{
+ // Handle strings and byte arrays directly, to avoid creating a temporary
+ // dummy container to hold their data.
+ int type = variant.userType();
+ if (type == QVariant::String) {
+ d->append(variant.toString());
+ } else if (type == QVariant::ByteArray) {
+ QByteArray ba = variant.toByteArray();
+ d->appendByteData(ba.constData(), ba.size(), QCborValue::ByteArray);
+ } else {
+ // For everything else, use the function below.
+ d->append(QCborValue::fromVariant(variant));
+ }
+}
+
+/*!
+ Converts the QVariant \a variant into QCborValue and returns it.
+
+ QVariants may contain a large list of different meta types, many of which
+ have no corresponding representation in CBOR. That includes all
+ user-defined meta types. When preparing transmission using CBOR, it is
+ suggested to encode carefully each value to prevent loss of representation.
+
+ The following table lists the conversion this function will apply:
+
+ \table
+ \header \li Qt (C++) type \li CBOR type
+ \row \li invalid (QVariant()) \li Undefined
+ \row \li \c bool \li Bool
+ \row \li \c std::nullptr_t \li Null
+ \row \li \c short, \c ushort, \c int, \c uint, \l qint64 \li Integer
+ \row \li \l quint64 \li Integer, but they are cast to \c qint64 first so
+ values higher than 2\sup{63}-1 (\c INT64_MAX) will
+ be wrapped to negative
+ \row \li \c float, \c double \li Double
+ \row \li \l QByteArray \li ByteArray
+ \row \li \l QDateTime \li DateTime
+ \row \li \l QCborSimpleType \li Simple type
+ \row \li \l QJsonArray \li Array, converted using QCborArray::formJsonArray()
+ \row \li \l QJsonDocument \li Array or Map
+ \row \li \l QJsonObject \li Map, converted using QCborMap::fromJsonObject()
+ \row \li \l QJsonValue \li converted using fromJsonValue()
+ \row \li \l QRegularExpression \li RegularExpression
+ \row \li \l QString \li String
+ \row \li \l QStringList \li Array
+ \row \li \l QVariantHash \li Map
+ \row \li \l QVariantList \li Array
+ \row \li \l QVariantMap \li Map
+ \row \li \l QUrl \li Url
+ \row \li \l QUuid \li Uuid
+ \endtable
+
+ For any other types, this function will return Null if the QVariant itself
+ is null, and otherwise will try to convert to string using
+ QVariant::toString(). If the conversion to string fails, this function
+ returns Undefined.
+
+ Please note that the conversions via QVariant::toString() are subject to
+ change at any time. QCborValue may be extended in the future to support
+ more types, which will result in a change in how this function performs
+ conversions.
+
+ \sa toVariant(), fromJsonValue(), QCborArray::toVariantList(), QCborMap::toVariantMap()
+ */
+QCborValue QCborValue::fromVariant(const QVariant &variant)
+{
+ switch (variant.userType()) {
+ case QVariant::Invalid:
+ return {};
+ case QMetaType::Nullptr:
+ return nullptr;
+ case QVariant::Bool:
+ return variant.toBool();
+ case QMetaType::Short:
+ case QMetaType::UShort:
+ case QVariant::Int:
+ case QVariant::LongLong:
+ case QVariant::ULongLong:
+ case QVariant::UInt:
+ return variant.toLongLong();
+ case QMetaType::Float:
+ case QVariant::Double:
+ return variant.toDouble();
+ case QVariant::String:
+ return variant.toString();
+ case QVariant::StringList:
+ return QCborArray::fromStringList(variant.toStringList());
+ case QVariant::ByteArray:
+ return variant.toByteArray();
+ case QVariant::DateTime:
+ return QCborValue(variant.toDateTime());
+ case QVariant::Url:
+ return QCborValue(variant.toUrl());
+ case QVariant::Uuid:
+ return QCborValue(variant.toUuid());
+ case QVariant::List:
+ return QCborArray::fromVariantList(variant.toList());
+ case QVariant::Map:
+ return QCborMap::fromVariantMap(variant.toMap());
+ case QVariant::Hash:
+ return QCborMap::fromVariantHash(variant.toHash());
+#ifndef QT_BOOTSTRAPPED
+ case QVariant::RegularExpression:
+ return QCborValue(variant.toRegularExpression());
+ case QMetaType::QJsonValue:
+ return fromJsonValue(variant.toJsonValue());
+ case QMetaType::QJsonObject:
+ return QCborMap::fromJsonObject(variant.toJsonObject());
+ case QMetaType::QJsonArray:
+ return QCborArray::fromJsonArray(variant.toJsonArray());
+ case QMetaType::QJsonDocument: {
+ QJsonDocument doc = variant.toJsonDocument();
+ if (doc.isArray())
+ return QCborArray::fromJsonArray(doc.array());
+ return QCborMap::fromJsonObject(doc.object());
+ }
+ case QMetaType::QCborValue:
+ return variant.value<QCborValue>();
+ case QMetaType::QCborArray:
+ return variant.value<QCborArray>();
+ case QMetaType::QCborMap:
+ return variant.value<QCborMap>();
+ case QMetaType::QCborSimpleType:
+ return variant.value<QCborSimpleType>();
+#endif
+ default:
+ break;
+ }
+
+ if (variant.isNull())
+ return QCborValue(nullptr);
+
+ QString string = variant.toString();
+ if (string.isNull())
+ return QCborValue(); // undefined
+ return string;
+}
+
+/*!
+ Recursively converts each \l QCborValue in this array using
+ QCborValue::toVariant() and returns the QVariantList composed of the
+ converted items.
+
+ Conversion to \l QVariant is not completely lossless. Please see the
+ documentation in QCborValue::toVariant() for more information.
+
+ \sa fromVariantList(), fromStringList(), toJsonArray(),
+ QCborValue::toVariant(), QCborMap::toVariantMap()
+ */
+QVariantList QCborArray::toVariantList() const
+{
+ QVariantList retval;
+ retval.reserve(size());
+ for (qsizetype i = 0; i < size(); ++i)
+ retval.append(d->valueAt(i).toVariant());
+ return retval;
+}
+
+/*!
+ Returns a QCborArray containing all the strings found in the \a list list.
+
+ \sa fromVariantList(), fromJsonArray()
+ */
+QCborArray QCborArray::fromStringList(const QStringList &list)
+{
+ QCborArray a;
+ a.detach(list.size());
+ for (const QString &s : list)
+ a.d->append(s);
+ return a;
+}
+
+/*!
+ Converts all the items in the \a list to CBOR using
+ QCborValue::fromVariant() and returns the array composed of those elements.
+
+ Conversion from \l QVariant is not completely lossless. Please see the
+ documentation in QCborValue::fromVariant() for more information.
+
+ \sa toVariantList(), fromStringList(), fromJsonArray(), QCborMap::fromVariantMap()
+ */
+QCborArray QCborArray::fromVariantList(const QVariantList &list)
+{
+ QCborArray a;
+ a.detach(list.size());
+ for (const QVariant &v : list)
+ appendVariant(a.d.data(), v);
+ return a;
+}
+
+/*!
+ Converts all JSON items found in the \a array array to CBOR using
+ QCborValue::fromJson(), and returns the CBOR array composed of those
+ elements.
+
+ This conversion is lossless, as the CBOR type system is a superset of
+ JSON's. Moreover, the array returned by this function can be converted back
+ to the original \a array by using toJsonArray().
+
+ \sa toJsonArray(), toVariantList(), QCborValue::fromJsonValue(), QCborMap::fromJsonObject()
+ */
+QCborArray QCborArray::fromJsonArray(const QJsonArray &array)
+{
+ QCborArray a;
+ a.detach(array.size());
+ for (const QJsonValue v : array) {
+ if (v.isString())
+ a.d->append(v.toString());
+ else
+ a.d->append(QCborValue::fromJsonValue(v));
+ }
+ return a;
+}
+
+/*!
+ Converts the CBOR values to QVariant using QCborValue::toVariant() and
+ "stringifies" all the CBOR keys in this map, returning the QVariantMap that
+ results from that association list.
+
+ QVariantMaps have string keys, unlike CBOR, so the conversion of a QCborMap
+ to QVariantMap will imply a step of "stringification" of the key values.
+ See QCborMap::toJsonObject() for details.
+
+ In addition, the conversion to \l QVariant is not completely lossless.
+ Please see the documentation in QCborValue::toVariant() for more
+ information.
+
+ \sa fromVariantMap(), toVariantHash(), toJsonObject(), QCborValue::toVariant(),
+ QCborArray::toVariantList()
+ */
+QVariantMap QCborMap::toVariantMap() const
+{
+ QVariantMap retval;
+ for (qsizetype i = 0; i < 2 * size(); i += 2)
+ retval.insert(makeString(d.data(), i), d->valueAt(i + 1).toVariant());
+ return retval;
+}
+
+/*!
+ Converts the CBOR values to QVariant using QCborValue::toVariant() and
+ "stringifies" all the CBOR keys in this map, returning the QVariantHash that
+ results from that association list.
+
+ QVariantMaps have string keys, unlike CBOR, so the conversion of a QCborMap
+ to QVariantMap will imply a step of "stringification" of the key values.
+ See QCborMap::toJsonObject() for details.
+
+ In addition, the conversion to \l QVariant is not completely lossless.
+ Please see the documentation in QCborValue::toVariant() for more
+ information.
+
+ \sa fromVariantHash(), toVariantMap(), toJsonObject(), QCborValue::toVariant(),
+ QCborArray::toVariantList()
+ */
+QVariantHash QCborMap::toVariantHash() const
+{
+ QVariantHash retval;
+ retval.reserve(size());
+ for (qsizetype i = 0; i < 2 * size(); i += 2)
+ retval.insert(makeString(d.data(), i), d->valueAt(i + 1).toVariant());
+ return retval;
+}
+
+/*!
+ Converts all the items in \a map to CBOR using QCborValue::fromVariant()
+ and returns the map composed of those elements.
+
+ Conversion from \l QVariant is not completely lossless. Please see the
+ documentation in QCborValue::fromVariant() for more information.
+
+ \sa toVariantMap(), fromVariantHash(), fromJsonObject(), QCborValue::fromVariant()
+ */
+QCborMap QCborMap::fromVariantMap(const QVariantMap &map)
+{
+ QCborMap m;
+ m.detach(map.size());
+ QCborContainerPrivate *d = m.d.data();
+
+ auto it = map.begin();
+ auto end = map.end();
+ for ( ; it != end; ++it) {
+ d->append(it.key());
+ appendVariant(d, it.value());
+ }
+ return m;
+}
+
+/*!
+ Converts all the items in \a hash to CBOR using QCborValue::fromVariant()
+ and returns the map composed of those elements.
+
+ Conversion from \l QVariant is not completely lossless. Please see the
+ documentation in QCborValue::fromVariant() for more information.
+
+ \sa toVariantHash(), fromVariantMap(), fromJsonObject(), QCborValue::fromVariant()
+ */
+QCborMap QCborMap::fromVariantHash(const QVariantHash &hash)
+{
+ QCborMap m;
+ m.detach(hash.size());
+ QCborContainerPrivate *d = m.d.data();
+
+ auto it = hash.begin();
+ auto end = hash.end();
+ for ( ; it != end; ++it) {
+ d->append(it.key());
+ appendVariant(d, it.value());
+ }
+ return m;
+}
+
+/*!
+ Converts all JSON items found in the \a obj object to CBOR using
+ QCborValue::fromJson(), and returns the map composed of those elements.
+
+ This conversion is lossless, as the CBOR type system is a superset of
+ JSON's. Moreover, the map returned by this function can be converted back
+ to the original \a obj by using toJsonObject().
+
+ \sa toJsonObject(), toVariantMap(), QCborValue::fromJsonValue(), QCborArray::fromJsonArray()
+ */
+QCborMap QCborMap::fromJsonObject(const QJsonObject &obj)
+{
+ QCborMap m;
+ m.detach(obj.size());
+ QCborContainerPrivate *d = m.d.data();
+
+ auto it = obj.begin();
+ auto end = obj.end();
+ for ( ; it != end; ++it) {
+ d->append(it.key());
+ if (it.value().isString())
+ d->append(it.value().toString());
+ else
+ d->append(QCborValue::fromJsonValue(it.value()));
+ }
+ return m;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp
index 4a316c8a6f..950bec535b 100644
--- a/src/corelib/serialization/qjsonobject.cpp
+++ b/src/corelib/serialization/qjsonobject.cpp
@@ -1292,6 +1292,17 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val)
insert(e->key(), val);
}
+uint qHash(const QJsonObject &object, uint seed)
+{
+ QtPrivate::QHashCombine hash;
+ for (auto it = object.begin(), end = object.end(); it != end; ++it) {
+ const QString key = it.key();
+ const QJsonValue value = it.value();
+ seed = hash(seed, std::pair<const QString&, const QJsonValue&>(key, value));
+ }
+ return seed;
+}
+
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonObject &o)
{
diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h
index 610bce694c..be42d3747a 100644
--- a/src/corelib/serialization/qjsonobject.h
+++ b/src/corelib/serialization/qjsonobject.h
@@ -262,6 +262,8 @@ private:
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonObject)
+Q_CORE_EXPORT uint qHash(const QJsonObject &object, uint seed = 0);
+
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
#endif
diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp
index aa44305fce..2c04da4885 100644
--- a/src/corelib/serialization/qjsonvalue.cpp
+++ b/src/corelib/serialization/qjsonvalue.cpp
@@ -46,6 +46,11 @@
#include <qstringlist.h>
#include <qdebug.h>
+#ifndef QT_BOOTSTRAPPED
+# include <qcborarray.h>
+# include <qcbormap.h>
+#endif
+
#include "qjson_p.h"
QT_BEGIN_NAMESPACE
@@ -423,6 +428,25 @@ QJsonValue &QJsonValue::operator =(const QJsonValue &other)
\li QMetaType::QUuid
\endlist
\li QJsonValue::String. Since Qt 5.11, the resulting string will not include braces
+ \row
+ \li
+ \list
+ \li QMetaType::QCborValue
+ \endlist
+ \li Whichever type QCborValue::toJsonValue() returns.
+ \row
+ \li
+ \list
+ \li QMetaType::QCborArray
+ \endlist
+ \li QJsonValue::Array. See QCborValue::toJsonValue() for conversion restrictions.
+ \row
+ \li
+ \list
+ \li QMetaType::QCborMap
+ \endlist
+ \li QJsonValue::Map. See QCborValue::toJsonValue() for conversion restrictions and the
+ "stringification" of map keys.
\endtable
For all other QVariant types a conversion to a QString will be attempted. If the returned string
@@ -469,6 +493,12 @@ QJsonValue QJsonValue::fromVariant(const QVariant &variant)
QJsonDocument doc = variant.toJsonDocument();
return doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object());
}
+ case QMetaType::QCborValue:
+ return variant.value<QCborValue>().toJsonValue();
+ case QMetaType::QCborArray:
+ return variant.value<QCborArray>().toJsonArray();
+ case QMetaType::QCborMap:
+ return variant.value<QCborMap>().toJsonObject();
#endif
default:
break;
@@ -846,6 +876,28 @@ QJsonValue QJsonValueRef::toValue() const
return o->valueAt(index);
}
+uint qHash(const QJsonValue &value, uint seed)
+{
+ switch (value.type()) {
+ case QJsonValue::Null:
+ return qHash(nullptr, seed);
+ case QJsonValue::Bool:
+ return qHash(value.toBool(), seed);
+ case QJsonValue::Double:
+ return qHash(value.toDouble(), seed);
+ case QJsonValue::String:
+ return qHash(value.toString(), seed);
+ case QJsonValue::Array:
+ return qHash(value.toArray(), seed);
+ case QJsonValue::Object:
+ return qHash(value.toObject(), seed);
+ case QJsonValue::Undefined:
+ return seed;
+ }
+ Q_UNREACHABLE();
+ return 0;
+}
+
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonValue &o)
{
diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h
index 96538ebbf9..d8e121524d 100644
--- a/src/corelib/serialization/qjsonvalue.h
+++ b/src/corelib/serialization/qjsonvalue.h
@@ -150,6 +150,7 @@ private:
friend class QJsonPrivate::Value;
friend class QJsonArray;
friend class QJsonObject;
+ friend class QCborValue;
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
QJsonValue(QJsonPrivate::Data *d, QJsonPrivate::Base *b, const QJsonPrivate::Value& v);
@@ -246,6 +247,8 @@ public:
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonValue)
+Q_CORE_EXPORT uint qHash(const QJsonValue &value, uint seed = 0);
+
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
#endif
diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp
index ee3cb4efcb..05a5a55926 100644
--- a/src/corelib/serialization/qtextstream.cpp
+++ b/src/corelib/serialization/qtextstream.cpp
@@ -2595,6 +2595,21 @@ QTextStream &QTextStream::operator<<(const QString &string)
Writes \a string to the stream, and returns a reference to the
QTextStream.
+ \since 5.12
+*/
+QTextStream &QTextStream::operator<<(QStringView string)
+{
+ Q_D(QTextStream);
+ CHECK_VALID_STREAM(*this);
+ d->putString(string.cbegin(), int(string.size()));
+ return *this;
+}
+
+/*!
+ \overload
+
+ Writes \a string to the stream, and returns a reference to the
+ QTextStream.
*/
QTextStream &QTextStream::operator<<(QLatin1String string)
{
diff --git a/src/corelib/serialization/qtextstream.h b/src/corelib/serialization/qtextstream.h
index ee0b09419d..ee90d01779 100644
--- a/src/corelib/serialization/qtextstream.h
+++ b/src/corelib/serialization/qtextstream.h
@@ -184,6 +184,7 @@ public:
QTextStream &operator<<(float f);
QTextStream &operator<<(double f);
QTextStream &operator<<(const QString &s);
+ QTextStream &operator<<(QStringView s);
QTextStream &operator<<(QLatin1String s);
QTextStream &operator<<(const QStringRef &s);
QTextStream &operator<<(const QByteArray &array);
diff --git a/src/corelib/serialization/serialization.pri b/src/corelib/serialization/serialization.pri
index 3d039dc30f..4f2dc64e4f 100644
--- a/src/corelib/serialization/serialization.pri
+++ b/src/corelib/serialization/serialization.pri
@@ -1,6 +1,12 @@
# Qt data formats core module
HEADERS += \
+ serialization/qcborarray.h \
+ serialization/qcborcommon.h \
+ serialization/qcbormap.h \
+ serialization/qcborvalue.h \
+ serialization/qcborvalue_p.h \
+ serialization/qcborstream.h \
serialization/qdatastream.h \
serialization/qdatastream_p.h \
serialization/qjson_p.h \
@@ -17,8 +23,12 @@ HEADERS += \
serialization/qxmlutils_p.h
SOURCES += \
+ serialization/qcborstream.cpp \
+ serialization/qcbordiagnostic.cpp \
+ serialization/qcborvalue.cpp \
serialization/qdatastream.cpp \
serialization/qjson.cpp \
+ serialization/qjsoncbor.cpp \
serialization/qjsondocument.cpp \
serialization/qjsonobject.cpp \
serialization/qjsonarray.cpp \
@@ -28,3 +38,9 @@ SOURCES += \
serialization/qtextstream.cpp \
serialization/qxmlstream.cpp \
serialization/qxmlutils.cpp
+
+false: SOURCES += \
+ serialization/qcborarray.cpp \
+ serialization/qcbormap.cpp
+
+INCLUDEPATH += ../3rdparty/tinycbor/src
diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp
index d4fb214a31..ccf04d4799 100644
--- a/src/corelib/statemachine/qhistorystate.cpp
+++ b/src/corelib/statemachine/qhistorystate.cpp
@@ -126,6 +126,25 @@ QT_BEGIN_NAMESPACE
descendant state the parent was in the last time it was exited.
*/
+namespace {
+class DefaultStateTransition: public QAbstractTransition
+{
+ Q_OBJECT
+
+public:
+ DefaultStateTransition(QHistoryState *source, QAbstractState *target);
+
+protected:
+ // It doesn't matter whether this transition matches any event or not. It is always associated
+ // with a QHistoryState, and as soon as the state-machine detects that it enters a history
+ // state, it will handle this transition as a special case. The history state itself is never
+ // entered either: either the stored configuration will be used, or the target(s) of this
+ // transition are used.
+ bool eventTest(QEvent *event) override { Q_UNUSED(event); return false; }
+ void onTransition(QEvent *event) override { Q_UNUSED(event); }
+};
+}
+
QHistoryStatePrivate::QHistoryStatePrivate()
: QAbstractStatePrivate(HistoryState)
, defaultTransition(0)
@@ -312,4 +331,4 @@ bool QHistoryState::event(QEvent *e)
QT_END_NAMESPACE
#include "moc_qhistorystate.cpp"
-#include "moc_qhistorystate_p.cpp"
+#include "qhistorystate.moc"
diff --git a/src/corelib/statemachine/qhistorystate_p.h b/src/corelib/statemachine/qhistorystate_p.h
index d22e5c4aaf..18d571feb7 100644
--- a/src/corelib/statemachine/qhistorystate_p.h
+++ b/src/corelib/statemachine/qhistorystate_p.h
@@ -75,23 +75,6 @@ public:
QList<QAbstractState*> configuration;
};
-class DefaultStateTransition: public QAbstractTransition
-{
- Q_OBJECT
-
-public:
- DefaultStateTransition(QHistoryState *source, QAbstractState *target);
-
-protected:
- // It doesn't matter whether this transition matches any event or not. It is always associated
- // with a QHistoryState, and as soon as the state-machine detects that it enters a history
- // state, it will handle this transition as a special case. The history state itself is never
- // entered either: either the stored configuration will be used, or the target(s) of this
- // transition are used.
- bool eventTest(QEvent *event) override { Q_UNUSED(event); return false; }
- void onTransition(QEvent *event) override { Q_UNUSED(event); }
-};
-
QT_END_NAMESPACE
#endif // QHISTORYSTATE_P_H
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h
index af599c26db..a456dd9139 100644
--- a/src/corelib/thread/qfuture.h
+++ b/src/corelib/thread/qfuture.h
@@ -136,6 +136,7 @@ public:
inline const_iterator operator-(int j) const { return const_iterator(future, index - j); }
inline const_iterator &operator+=(int j) { index += j; return *this; }
inline const_iterator &operator-=(int j) { index -= j; return *this; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
private:
QFuture const * future;
int index;
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index 3dd236752c..d5e2401eee 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -178,7 +178,7 @@ public:
inline void reportResult(const T *result, int index = -1);
inline void reportResult(const T &result, int index = -1);
inline void reportResults(const QVector<T> &results, int beginIndex = -1, int count = -1);
- inline void reportFinished(const T *result = 0);
+ inline void reportFinished(const T *result = nullptr);
inline const T &resultReference(int index) const;
inline const T *resultPointer(int index) const;
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 63fb6f3efb..3881ac017e 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -42,8 +42,6 @@
#include "qplatformdefs.h"
#include "qmutex.h"
#include <qdebug.h>
-
-#ifndef QT_NO_THREAD
#include "qatomic.h"
#include "qelapsedtimer.h"
#include "qthread.h"
@@ -739,5 +737,3 @@ QT_END_NAMESPACE
#else
# include "qmutex_unix.cpp"
#endif
-
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 7cda53db5f..837355a602 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -54,7 +54,7 @@ class tst_QMutex;
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_THREAD) || defined(Q_CLANG_QDOC)
+#if QT_CONFIG(thread) || defined(Q_CLANG_QDOC)
#ifdef Q_OS_LINUX
# define QT_MUTEX_LOCK_NOEXCEPT Q_DECL_NOTHROW
@@ -250,7 +250,7 @@ private:
quintptr val;
};
-#else // QT_NO_THREAD && !Q_CLANG_QDOC
+#else // !QT_CONFIG(thread) && !Q_CLANG_QDOC
class Q_CORE_EXPORT QMutex
{
@@ -301,7 +301,7 @@ private:
typedef QMutex QBasicMutex;
-#endif // QT_NO_THREAD && !Q_CLANG_QDOC
+#endif // !QT_CONFIG(thread) && !Q_CLANG_QDOC
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
index d3d97ea108..507e72cb76 100644
--- a/src/corelib/thread/qmutex_linux.cpp
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -40,8 +40,6 @@
#include "qplatformdefs.h"
#include "qmutex.h"
-
-#ifndef QT_NO_THREAD
#include "qatomic.h"
#include "qmutex_p.h"
#include "qfutex_p.h"
@@ -54,7 +52,6 @@
# define FUTEX_PRIVATE_FLAG 0
#endif
-
QT_BEGIN_NAMESPACE
using namespace QtFutex;
@@ -183,5 +180,3 @@ void QBasicMutex::unlockInternal() Q_DECL_NOTHROW
}
QT_END_NAMESPACE
-
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qmutex_mac.cpp b/src/corelib/thread/qmutex_mac.cpp
index 67498611c9..9a8d9bc750 100644
--- a/src/corelib/thread/qmutex_mac.cpp
+++ b/src/corelib/thread/qmutex_mac.cpp
@@ -39,9 +39,6 @@
#include "qplatformdefs.h"
#include "qmutex.h"
-
-#if !defined(QT_NO_THREAD)
-
#include "qmutex_p.h"
#include <mach/mach.h>
@@ -89,5 +86,3 @@ void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
QT_END_NAMESPACE
-
-#endif //QT_NO_THREAD
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index 4e6f522a37..ec9bfc1152 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -58,6 +58,7 @@
#include <QtCore/qnamespace.h>
#include <QtCore/qmutex.h>
#include <QtCore/qatomic.h>
+#include <QtCore/qdeadlinetimer.h>
#if defined(Q_OS_MAC)
# include <mach/semaphore.h>
@@ -146,7 +147,7 @@ public:
// helper functions for qmutex_unix.cpp and qwaitcondition_unix.cpp
// they are in qwaitcondition_unix.cpp actually
void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where);
-void qt_abstime_for_timeout(struct timespec *ts, int timeout);
+void qt_abstime_for_timeout(struct timespec *ts, QDeadlineTimer deadline);
#endif
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 3e1e531be4..3ee24a292c 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -42,8 +42,6 @@
#include "qmutex.h"
#include "qstring.h"
#include "qelapsedtimer.h"
-
-#ifndef QT_NO_THREAD
#include "qatomic.h"
#include "qmutex_p.h"
#include <errno.h>
@@ -130,7 +128,7 @@ bool QMutexPrivate::wait(int timeout)
errorCode = pthread_cond_wait(&cond, &mutex);
} else {
timespec ti;
- qt_abstime_for_timeout(&ti, timeout);
+ qt_abstime_for_timeout(&ti, QDeadlineTimer(timeout));
errorCode = pthread_cond_timedwait(&cond, &mutex, &ti);
}
if (errorCode) {
@@ -159,5 +157,3 @@ void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
#endif
QT_END_NAMESPACE
-
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp
index 90b6989467..3f9e8da942 100644
--- a/src/corelib/thread/qmutexpool.cpp
+++ b/src/corelib/thread/qmutexpool.cpp
@@ -40,8 +40,6 @@
#include "qatomic.h"
#include "qmutexpool_p.h"
-#ifndef QT_NO_THREAD
-
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive))
@@ -148,5 +146,3 @@ QMutex *QMutexPool::globalInstanceGet(const void *address)
}
QT_END_NAMESPACE
-
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h
index 58d853b0e3..89d006ac29 100644
--- a/src/corelib/thread/qmutexpool_p.h
+++ b/src/corelib/thread/qmutexpool_p.h
@@ -56,7 +56,7 @@
#include "QtCore/qmutex.h"
#include "QtCore/qvarlengtharray.h"
-#ifndef QT_NO_THREAD
+QT_REQUIRE_CONFIG(thread);
QT_BEGIN_NAMESPACE
@@ -85,6 +85,4 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_THREAD
-
#endif // QMUTEXPOOL_P_H
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index 42befc4b80..21835ff592 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -42,7 +42,6 @@
#include "qplatformdefs.h"
#include "qreadwritelock.h"
-#ifndef QT_NO_THREAD
#include "qmutex.h"
#include "qthread.h"
#include "qwaitcondition.h"
@@ -781,5 +780,3 @@ void QReadWriteLockPrivate::release()
*/
QT_END_NAMESPACE
-
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qreadwritelock.h b/src/corelib/thread/qreadwritelock.h
index ecdb98f2f5..65fa76fd6d 100644
--- a/src/corelib/thread/qreadwritelock.h
+++ b/src/corelib/thread/qreadwritelock.h
@@ -45,7 +45,7 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
class QReadWriteLockPrivate;
@@ -174,7 +174,7 @@ inline QWriteLocker::QWriteLocker(QReadWriteLock *areadWriteLock)
#pragma warning( pop )
#endif
-#else // QT_NO_THREAD
+#else // QT_CONFIG(thread)
class Q_CORE_EXPORT QReadWriteLock
{
@@ -225,7 +225,7 @@ private:
Q_DISABLE_COPY(QWriteLocker)
};
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h
index 04dd45a2e1..31da2401c0 100644
--- a/src/corelib/thread/qreadwritelock_p.h
+++ b/src/corelib/thread/qreadwritelock_p.h
@@ -54,9 +54,9 @@
#include <QtCore/private/qglobal_p.h>
#include <QtCore/qhash.h>
-#include <QtCore/QWaitCondition>
+#include <QtCore/qwaitcondition.h>
-#ifndef QT_NO_THREAD
+QT_REQUIRE_CONFIG(thread);
QT_BEGIN_NAMESPACE
@@ -99,6 +99,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_THREAD
-
#endif // QREADWRITELOCK_P_H
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 74e0746f43..bb578ff617 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -39,8 +39,6 @@
****************************************************************************/
#include "qsemaphore.h"
-
-#ifndef QT_NO_THREAD
#include "qmutex.h"
#include "qfutex_p.h"
#include "qwaitcondition.h"
@@ -487,11 +485,9 @@ bool QSemaphore::tryAcquire(int n, int timeout)
QDeadlineTimer timer(timeout);
QMutexLocker locker(&d->mutex);
- qint64 remainingTime = timer.remainingTime();
- while (n > d->avail && remainingTime != 0) {
- if (!d->cond.wait(locker.mutex(), remainingTime))
+ while (n > d->avail && !timer.hasExpired()) {
+ if (!d->cond.wait(locker.mutex(), timer))
return false;
- remainingTime = timer.remainingTime();
}
if (n > d->avail)
return false;
@@ -648,5 +644,3 @@ bool QSemaphore::tryAcquire(int n, int timeout)
QT_END_NAMESPACE
-
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qsemaphore.h b/src/corelib/thread/qsemaphore.h
index 2639085e99..b830ff1bfd 100644
--- a/src/corelib/thread/qsemaphore.h
+++ b/src/corelib/thread/qsemaphore.h
@@ -42,10 +42,9 @@
#include <QtCore/qglobal.h>
-QT_BEGIN_NAMESPACE
-
+QT_REQUIRE_CONFIG(thread);
-#ifndef QT_NO_THREAD
+QT_BEGIN_NAMESPACE
class QSemaphorePrivate;
@@ -113,8 +112,6 @@ private:
int m_n;
};
-#endif // QT_NO_THREAD
-
QT_END_NAMESPACE
#endif // QSEMAPHORE_H
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 23606411ff..d2d6435004 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -103,7 +103,7 @@ QThreadData::~QThreadData()
void QThreadData::ref()
{
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
(void) _ref.ref();
Q_ASSERT(_ref.load() != 0);
#endif
@@ -111,12 +111,20 @@ void QThreadData::ref()
void QThreadData::deref()
{
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
if (!_ref.deref())
delete this;
#endif
}
+QAbstractEventDispatcher *QThreadData::createEventDispatcher()
+{
+ QAbstractEventDispatcher *ed = QThreadPrivate::createEventDispatcher(this);
+ eventDispatcher.storeRelease(ed);
+ ed->startingUp();
+ return ed;
+}
+
/*
QAdoptedThread
*/
@@ -126,7 +134,7 @@ QAdoptedThread::QAdoptedThread(QThreadData *data)
{
// thread should be running and not finished for the lifetime
// of the application (even if QCoreApplication goes away)
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
d_func()->running = true;
d_func()->finished = false;
init();
@@ -140,12 +148,13 @@ QAdoptedThread::~QAdoptedThread()
// fprintf(stderr, "~QAdoptedThread = %p\n", this);
}
+#if QT_CONFIG(thread)
void QAdoptedThread::run()
{
// this function should never be called
qFatal("QAdoptedThread::run(): Internal error, this implementation should never be called.");
}
-#ifndef QT_NO_THREAD
+
/*
QThreadPrivate
*/
@@ -747,31 +756,112 @@ int QThread::loopLevel() const
return d->data->eventLoops.size();
}
-#else // QT_NO_THREAD
+#else // QT_CONFIG(thread)
QThread::QThread(QObject *parent)
- : QObject(*(new QThreadPrivate), (QObject*)0){
+ : QObject(*(new QThreadPrivate), parent)
+{
Q_D(QThread);
d->data->thread = this;
}
+QThread::~QThread()
+{
+
+}
+
+void QThread::run()
+{
+
+}
+
+int QThread::exec()
+{
+ return 0;
+}
+
+void QThread::start(Priority priority)
+{
+ Q_D(QThread);
+ Q_UNUSED(priority);
+ d->running = true;
+}
+
+void QThread::terminate()
+{
+
+}
+
+void QThread::quit()
+{
+
+}
+
+bool QThread::wait(unsigned long time)
+{
+ Q_UNUSED(time);
+ return false;
+}
+
+bool QThread::event(QEvent* event)
+{
+ return QObject::event(event);
+}
+
+Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
+{
+ return Qt::HANDLE(currentThread());
+}
+
QThread *QThread::currentThread()
{
return QThreadData::current()->thread;
}
-QThreadData* QThreadData::current()
+int QThread::idealThreadCount() Q_DECL_NOTHROW
+{
+ return 1;
+}
+
+void QThread::yieldCurrentThread()
+{
+
+}
+
+bool QThread::isFinished() const
+{
+ return false;
+}
+
+bool QThread::isRunning() const
+{
+ Q_D(const QThread);
+ return d->running;
+}
+
+// No threads: so we can just use static variables
+static QThreadData *data = 0;
+
+QThreadData *QThreadData::current(bool createIfNecessary)
{
- static QThreadData *data = 0; // reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key));
- if (!data) {
- QScopedPointer<QThreadData> newdata(new QThreadData);
- newdata->thread = new QAdoptedThread(newdata.data());
- data = newdata.take();
+ if (!data && createIfNecessary) {
+ data = new QThreadData;
+ data->thread = new QAdoptedThread(data);
+ data->threadId.store(Qt::HANDLE(data->thread));
data->deref();
+ data->isAdopted = true;
+ if (!QCoreApplicationPrivate::theMainThread)
+ QCoreApplicationPrivate::theMainThread = data->thread.load();
}
return data;
}
+void QThreadData::clearCurrentThreadData()
+{
+ delete data;
+ data = 0;
+}
+
/*!
\internal
*/
@@ -783,7 +873,17 @@ QThread::QThread(QThreadPrivate &dd, QObject *parent)
d->data->thread = this;
}
-#endif // QT_NO_THREAD
+QThreadPrivate::QThreadPrivate(QThreadData *d) : data(d ? d : new QThreadData)
+{
+}
+
+QThreadPrivate::~QThreadPrivate()
+{
+ data->thread = nullptr; // prevent QThreadData from deleting the QThreadPrivate (again).
+ delete data;
+}
+
+#endif // QT_CONFIG(thread)
/*!
\since 5.0
@@ -820,6 +920,8 @@ void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
}
}
+#if QT_CONFIG(thread)
+
/*!
\reimp
*/
@@ -983,6 +1085,8 @@ QDaemonThread::~QDaemonThread()
{
}
+#endif // QT_CONFIG(thread)
+
QT_END_NAMESPACE
#include "moc_qthread.cpp"
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 3df76077e1..b6c5bf47d0 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -66,7 +66,6 @@ class QThreadData;
class QThreadPrivate;
class QAbstractEventDispatcher;
-#ifndef QT_NO_THREAD
class Q_CORE_EXPORT QThread : public QObject
{
Q_OBJECT
@@ -239,29 +238,6 @@ QThread *QThread::create(Function &&f)
#endif // QT_CONFIG(cxx11_future)
-#else // QT_NO_THREAD
-
-class Q_CORE_EXPORT QThread : public QObject
-{
-public:
- static Qt::HANDLE currentThreadId() { return Qt::HANDLE(currentThread()); }
- static QThread* currentThread();
-
-protected:
- QThread(QThreadPrivate &dd, QObject *parent = nullptr);
-
-private:
- explicit QThread(QObject *parent = nullptr);
- static QThread *instance;
-
- friend class QCoreApplication;
- friend class QThreadData;
- friend class QAdoptedThread;
- Q_DECLARE_PRIVATE(QThread)
-};
-
-#endif // QT_NO_THREAD
-
QT_END_NAMESPACE
#endif // QTHREAD_H
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 46294a5fc8..64e3f33191 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -57,7 +57,9 @@
#include "QtCore/qthread.h"
#include "QtCore/qmutex.h"
#include "QtCore/qstack.h"
+#if QT_CONFIG(thread)
#include "QtCore/qwaitcondition.h"
+#endif
#include "QtCore/qmap.h"
#include "QtCore/qcoreapplication.h"
#include "private/qobject_p.h"
@@ -141,7 +143,7 @@ private:
using QVector<QPostEvent>::insert;
};
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
class Q_CORE_EXPORT QDaemonThread : public QThread
{
@@ -210,15 +212,17 @@ public:
}
};
-#else // QT_NO_THREAD
+#else // QT_CONFIG(thread)
class QThreadPrivate : public QObjectPrivate
{
public:
- QThreadPrivate(QThreadData *d = 0) : data(d ? d : new QThreadData) {}
- ~QThreadPrivate() { delete data; }
+ QThreadPrivate(QThreadData *d = 0);
+ ~QThreadPrivate();
+ mutable QMutex mutex;
QThreadData *data;
+ bool running = false;
static void setCurrentThread(QThread*) {}
static QThread *threadForId(int) { return QThread::currentThread(); }
@@ -230,7 +234,7 @@ public:
Q_DECLARE_PUBLIC(QThread)
};
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
class QThreadData
{
@@ -247,7 +251,15 @@ public:
void ref();
void deref();
inline bool hasEventDispatcher() const
- { return eventDispatcher.load() != 0; }
+ { return eventDispatcher.load() != nullptr; }
+ QAbstractEventDispatcher *createEventDispatcher();
+ QAbstractEventDispatcher *ensureEventDispatcher()
+ {
+ QAbstractEventDispatcher *ed = eventDispatcher.load();
+ if (Q_LIKELY(ed))
+ return ed;
+ return createEventDispatcher();
+ }
bool canWaitLocked()
{
@@ -318,7 +330,9 @@ public:
void init();
private:
+#if QT_CONFIG(thread)
void run() override;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 9ad32b162d..329caa02ba 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -103,7 +103,7 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
Q_STATIC_ASSERT(sizeof(pthread_t) <= sizeof(Qt::HANDLE));
@@ -270,7 +270,7 @@ extern "C" {
typedef void*(*QtThreadCallback)(void*);
}
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *data)
{
@@ -295,7 +295,7 @@ QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *dat
#endif
}
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
static void setCurrentThreadName(const char *name)
@@ -339,13 +339,7 @@ void *QThreadPrivate::start(void *arg)
data->quitNow = thr->d_func()->exited;
}
- QAbstractEventDispatcher *eventDispatcher = data->eventDispatcher.load();
- if (!eventDispatcher) {
- eventDispatcher = createEventDispatcher(data);
- data->eventDispatcher.storeRelease(eventDispatcher);
- }
-
- eventDispatcher->startingUp();
+ data->ensureEventDispatcher();
#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
{
@@ -519,6 +513,8 @@ void QThread::yieldCurrentThread()
sched_yield();
}
+#endif // QT_CONFIG(thread)
+
static timespec makeTimespec(time_t secs, long nsecs)
{
struct timespec ts;
@@ -542,6 +538,8 @@ void QThread::usleep(unsigned long usecs)
qt_nanosleep(makeTimespec(usecs / 1000 / 1000, usecs % (1000*1000) * 1000));
}
+#if QT_CONFIG(thread)
+
#ifdef QT_HAS_THREAD_PRIORITY_SCHEDULING
#if defined(Q_OS_QNX)
static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority)
@@ -841,7 +839,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
#endif
}
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 4459ae87af..eebaf90d9b 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -61,9 +61,10 @@
# include <process.h>
#endif // Q_OS_WINRT
-#ifndef QT_NO_THREAD
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(thread)
+
#ifdef Q_OS_WINRT
inline DWORD qWinRTTlsAlloc() {
return FlsAlloc(0);
@@ -259,31 +260,27 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
}
const int handleIndex = offset + ret - WAIT_OBJECT_0;
- if (handleIndex == 0){
- // New handle to watch was added.
+ if (handleIndex == 0) // New handle to watch was added.
continue;
- } else {
-// printf("(qt) - qt_adopted_thread_watcher_function... called\n");
- const int qthreadIndex = handleIndex - 1;
+ const int qthreadIndex = handleIndex - 1;
- qt_adopted_thread_watcher_mutex.lock();
- QThreadData *data = QThreadData::get2(qt_adopted_qthreads.at(qthreadIndex));
- qt_adopted_thread_watcher_mutex.unlock();
- if (data->isAdopted) {
- QThread *thread = data->thread;
- Q_ASSERT(thread);
- QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
- Q_UNUSED(thread_p)
- Q_ASSERT(!thread_p->finished);
- thread_p->finish(thread);
- }
- data->deref();
-
- QMutexLocker lock(&qt_adopted_thread_watcher_mutex);
- CloseHandle(qt_adopted_thread_handles.at(handleIndex));
- qt_adopted_thread_handles.remove(handleIndex);
- qt_adopted_qthreads.remove(qthreadIndex);
+ qt_adopted_thread_watcher_mutex.lock();
+ QThreadData *data = QThreadData::get2(qt_adopted_qthreads.at(qthreadIndex));
+ qt_adopted_thread_watcher_mutex.unlock();
+ if (data->isAdopted) {
+ QThread *thread = data->thread;
+ Q_ASSERT(thread);
+ auto thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
+ Q_UNUSED(thread_p)
+ Q_ASSERT(!thread_p->finished);
+ QThreadPrivate::finish(thread);
}
+ data->deref();
+
+ QMutexLocker lock(&qt_adopted_thread_watcher_mutex);
+ CloseHandle(qt_adopted_thread_handles.at(handleIndex));
+ qt_adopted_thread_handles.remove(handleIndex);
+ qt_adopted_qthreads.remove(qthreadIndex);
}
QThreadData *threadData = reinterpret_cast<QThreadData *>(TlsGetValue(qt_current_thread_data_tls_index));
@@ -317,7 +314,8 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
__try
{
- RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR*)&info);
+ RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD),
+ reinterpret_cast<const ULONG_PTR*>(&info));
}
__except (EXCEPTION_CONTINUE_EXECUTION)
{
@@ -329,7 +327,7 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
** QThreadPrivate
*************************************************************************/
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *data)
{
@@ -341,7 +339,7 @@ QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *dat
#endif
}
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(void *arg) Q_DECL_NOEXCEPT
{
@@ -359,18 +357,12 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
data->quitNow = thr->d_func()->exited;
}
- QAbstractEventDispatcher *eventDispatcher = data->eventDispatcher.load();
- if (!eventDispatcher) {
- eventDispatcher = createEventDispatcher(data);
- data->eventDispatcher.storeRelease(eventDispatcher);
- }
-
- eventDispatcher->startingUp();
+ data->ensureEventDispatcher();
#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
QByteArray objectName = thr->objectName().toLocal8Bit();
- qt_set_thread_name((HANDLE)-1,
+ qt_set_thread_name(HANDLE(-1),
objectName.isEmpty() ?
thr->metaObject()->className() : objectName.constData());
#endif
@@ -449,6 +441,8 @@ void QThread::yieldCurrentThread()
#endif
}
+#endif // QT_CONFIG(thread)
+
void QThread::sleep(unsigned long secs)
{
::Sleep(secs * 1000);
@@ -464,6 +458,8 @@ void QThread::usleep(unsigned long usecs)
::Sleep((usecs / 1000) + 1);
}
+#if QT_CONFIG(thread)
+
void QThread::start(Priority priority)
{
Q_D(QThread);
@@ -509,12 +505,13 @@ void QThread::start(Priority priority)
this, CREATE_SUSPENDED, &(d->id));
#else
// MSVC -MD or -MDd or MinGW build
- d->handle = (Qt::HANDLE) CreateThread(NULL, d->stackSize, (LPTHREAD_START_ROUTINE)QThreadPrivate::start,
- this, CREATE_SUSPENDED, reinterpret_cast<LPDWORD>(&d->id));
+ d->handle = CreateThread(nullptr, d->stackSize,
+ reinterpret_cast<LPTHREAD_START_ROUTINE>(QThreadPrivate::start),
+ this, CREATE_SUSPENDED, reinterpret_cast<LPDWORD>(&d->id));
#endif // Q_OS_WINRT
if (!d->handle) {
- qErrnoWarning(errno, "QThread::start: Failed to create thread");
+ qErrnoWarning("QThread::start: Failed to create thread");
d->running = false;
d->finished = true;
return;
@@ -700,5 +697,6 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
}
}
+#endif // QT_CONFIG(thread)
+
QT_END_NAMESPACE
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index 157cbeaf4d..ea2c611082 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -43,8 +43,6 @@
#include <algorithm>
-#ifndef QT_NO_THREAD
-
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QThreadPool, theInstance)
@@ -730,5 +728,3 @@ void QThreadPool::cancel(QRunnable *runnable)
QT_END_NAMESPACE
#include "moc_qthreadpool.cpp"
-
-#endif
diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h
index 606e192768..cd27b7c08a 100644
--- a/src/corelib/thread/qthreadpool.h
+++ b/src/corelib/thread/qthreadpool.h
@@ -45,7 +45,7 @@
#include <QtCore/qthread.h>
#include <QtCore/qrunnable.h>
-#ifndef QT_NO_THREAD
+QT_REQUIRE_CONFIG(thread);
QT_BEGIN_NAMESPACE
@@ -97,6 +97,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_THREAD
-
#endif
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index d03ba9d77f..0e6a00d243 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -59,7 +59,7 @@
#include "QtCore/qqueue.h"
#include "private/qobject_p.h"
-#ifndef QT_NO_THREAD
+QT_REQUIRE_CONFIG(thread);
QT_BEGIN_NAMESPACE
@@ -184,5 +184,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_THREAD
#endif
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index c0b523a431..8b82118a5c 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -39,7 +39,6 @@
#include "qthreadstorage.h"
-#ifndef QT_NO_THREAD
#include "qthread.h"
#include "qthread_p.h"
#include "qmutex.h"
@@ -323,6 +322,4 @@ void QThreadStorageData::finish(void **p)
\sa localData(), hasLocalData()
*/
-#endif // QT_NO_THREAD
-
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthreadstorage.h b/src/corelib/thread/qthreadstorage.h
index fed41a0760..55fc482da3 100644
--- a/src/corelib/thread/qthreadstorage.h
+++ b/src/corelib/thread/qthreadstorage.h
@@ -42,7 +42,7 @@
#include <QtCore/qglobal.h>
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
QT_BEGIN_NAMESPACE
@@ -152,6 +152,81 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_THREAD
+#else // !QT_CONFIG(thread)
+
+#include <QtCore/qscopedpointer.h>
+
+#include <type_traits>
+
+template <typename T, typename U>
+inline bool qThreadStorage_hasLocalData(const QScopedPointer<T, U> &data)
+{
+ return !!data;
+}
+
+template <typename T, typename U>
+inline bool qThreadStorage_hasLocalData(const QScopedPointer<T*, U> &data)
+{
+ return !!data ? *data != nullptr : false;
+}
+
+template <typename T>
+inline void qThreadStorage_deleteLocalData(T *t)
+{
+ delete t;
+}
+
+template <typename T>
+inline void qThreadStorage_deleteLocalData(T **t)
+{
+ delete *t;
+ delete t;
+}
+
+template <class T>
+class QThreadStorage
+{
+private:
+ struct ScopedPointerThreadStorageDeleter
+ {
+ static inline void cleanup(T *t)
+ {
+ if (t == nullptr)
+ return;
+ qThreadStorage_deleteLocalData(t);
+ }
+ };
+ QScopedPointer<T, ScopedPointerThreadStorageDeleter> data;
+
+public:
+ QThreadStorage() = default;
+ ~QThreadStorage() = default;
+ QThreadStorage(const QThreadStorage &rhs) = delete;
+ QThreadStorage &operator=(const QThreadStorage &rhs) = delete;
+
+ inline bool hasLocalData() const
+ {
+ return qThreadStorage_hasLocalData(data);
+ }
+
+ inline T& localData()
+ {
+ if (!data)
+ data.reset(new T());
+ return *data;
+ }
+
+ inline T localData() const
+ {
+ return !!data ? *data : T();
+ }
+
+ inline void setLocalData(T t)
+ {
+ data.reset(new T(t));
+ }
+};
+
+#endif // QT_CONFIG(thread)
#endif // QTHREADSTORAGE_H
diff --git a/src/corelib/thread/qwaitcondition.h b/src/corelib/thread/qwaitcondition.h
index a0c6766833..11520e4cfe 100644
--- a/src/corelib/thread/qwaitcondition.h
+++ b/src/corelib/thread/qwaitcondition.h
@@ -46,9 +46,9 @@
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(thread)
-#ifndef QT_NO_THREAD
-
+class QDeadlineTimer;
class QWaitConditionPrivate;
class QMutex;
class QReadWriteLock;
@@ -59,8 +59,11 @@ public:
QWaitCondition();
~QWaitCondition();
+ // ### Qt 6: remove unsigned long overloads
bool wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX);
+ bool wait(QMutex *lockedMutex, QDeadlineTimer deadline);
bool wait(QReadWriteLock *lockedReadWriteLock, unsigned long time = ULONG_MAX);
+ bool wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline);
void wakeOne();
void wakeAll();
@@ -94,7 +97,7 @@ public:
void wakeAll() {}
};
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index 6adee5412e..c93328b4bc 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -44,6 +44,8 @@
#include "qreadwritelock.h"
#include "qatomic.h"
#include "qstring.h"
+#include "qdeadlinetimer.h"
+#include "private/qdeadlinetimer_p.h"
#include "qelapsedtimer.h"
#include "private/qcore_unix_p.h"
@@ -54,8 +56,6 @@
#include <sys/time.h>
#include <time.h>
-#ifndef QT_NO_THREAD
-
QT_BEGIN_NAMESPACE
#ifdef Q_OS_ANDROID
@@ -93,23 +93,25 @@ void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where)
pthread_condattr_destroy(&condattr);
}
-void qt_abstime_for_timeout(timespec *ts, int timeout)
+void qt_abstime_for_timeout(timespec *ts, QDeadlineTimer deadline)
{
#ifdef Q_OS_MAC
// on Mac, qt_gettime() (on qelapsedtimer_mac.cpp) returns ticks related to the Mach absolute time
// that doesn't work with pthread
// Mac also doesn't have clock_gettime
struct timeval tv;
+ qint64 nsec = deadline.remainingTimeNSecs();
gettimeofday(&tv, 0);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec * 1000;
-#else
- *ts = qt_gettime();
-#endif
+ ts->tv_sec = tv.tv_sec + nsec / (1000 * 1000 * 1000);
+ ts->tv_nsec = tv.tv_usec * 1000 + nsec % (1000 * 1000 * 1000);
- ts->tv_sec += timeout / 1000;
- ts->tv_nsec += timeout % 1000 * Q_UINT64_C(1000) * 1000;
normalizedTimespec(*ts);
+#else
+ // depends on QDeadlineTimer's internals!!
+ Q_STATIC_ASSERT(QDeadlineTimerNanosecondsInT2);
+ ts->tv_sec = deadline._q_data().first;
+ ts->tv_nsec = deadline._q_data().second;
+#endif
}
class QWaitConditionPrivate {
@@ -119,26 +121,27 @@ public:
int waiters;
int wakeups;
- int wait_relative(unsigned long time)
+ int wait_relative(QDeadlineTimer deadline)
{
timespec ti;
#ifdef Q_OS_ANDROID
- if (local_cond_timedwait_relative) {
- ti.tv_sec = time / 1000;
- ti.tv_nsec = time % 1000 * Q_UINT64_C(1000) * 1000;
+ if (!local_condattr_setclock && local_cond_timedwait_relative) {
+ qint64 nsec = deadline.remainingTimeNSecs();
+ ti.tv_sec = nsec / (1000 * 1000 * 1000);
+ ti.tv_nsec = nsec - ti.tv_sec * 1000 * 1000 * 1000;
return local_cond_timedwait_relative(&cond, &mutex, &ti);
}
#endif
- qt_abstime_for_timeout(&ti, time);
+ qt_abstime_for_timeout(&ti, deadline);
return pthread_cond_timedwait(&cond, &mutex, &ti);
}
- bool wait(unsigned long time)
+ bool wait(QDeadlineTimer deadline)
{
int code;
forever {
- if (time != ULONG_MAX) {
- code = wait_relative(time);
+ if (!deadline.isForever()) {
+ code = wait_relative(deadline);
} else {
code = pthread_cond_wait(&cond, &mutex);
}
@@ -201,6 +204,13 @@ void QWaitCondition::wakeAll()
bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
{
+ if (quint64(time) > quint64(std::numeric_limits<qint64>::max()))
+ return wait(mutex, QDeadlineTimer(QDeadlineTimer::Forever));
+ return wait(mutex, QDeadlineTimer(time));
+}
+
+bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+{
if (! mutex)
return false;
if (mutex->isRecursive()) {
@@ -212,7 +222,7 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
++d->waiters;
mutex->unlock();
- bool returnValue = d->wait(time);
+ bool returnValue = d->wait(deadline);
mutex->lock();
@@ -221,6 +231,11 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
+ return wait(readWriteLock, QDeadlineTimer(time));
+}
+
+bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline)
+{
if (!readWriteLock)
return false;
auto previousState = readWriteLock->stateForWaitCondition();
@@ -236,7 +251,7 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
readWriteLock->unlock();
- bool returnValue = d->wait(time);
+ bool returnValue = d->wait(deadline);
if (previousState == QReadWriteLock::LockedForWrite)
readWriteLock->lockForWrite();
@@ -247,5 +262,3 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
}
QT_END_NAMESPACE
-
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index e6610f18c8..a6ad95b397 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -38,14 +38,13 @@
****************************************************************************/
#include "qwaitcondition.h"
+#include "qdeadlinetimer.h"
#include "qnamespace.h"
#include "qmutex.h"
#include "qreadwritelock.h"
#include "qlist.h"
#include "qalgorithms.h"
-#ifndef QT_NO_THREAD
-
#define Q_MUTEX_T void*
#include <private/qmutex_p.h>
#include <private/qreadwritelock_p.h>
@@ -184,6 +183,11 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
return returnValue;
}
+bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+{
+ return wait(mutex, deadline.remainingTime());
+}
+
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
if (!readWriteLock)
@@ -210,12 +214,16 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
return returnValue;
}
+bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline)
+{
+ return wait(readWriteLock, deadline.remainingTime());
+}
+
void QWaitCondition::wakeOne()
{
// wake up the first waiting thread in the queue
QMutexLocker locker(&d->mtx);
- for (int i = 0; i < d->queue.size(); ++i) {
- QWaitConditionEvent *current = d->queue.at(i);
+ for (QWaitConditionEvent *current : qAsConst(d->queue)) {
if (current->wokenUp)
continue;
SetEvent(current->event);
@@ -228,12 +236,10 @@ void QWaitCondition::wakeAll()
{
// wake up the all threads in the queue
QMutexLocker locker(&d->mtx);
- for (int i = 0; i < d->queue.size(); ++i) {
- QWaitConditionEvent *current = d->queue.at(i);
+ for (QWaitConditionEvent *current : qAsConst(d->queue)) {
SetEvent(current->event);
current->wokenUp = true;
}
}
QT_END_NAMESPACE
-#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri
index dae72564b4..22f0de0523 100644
--- a/src/corelib/thread/thread.pri
+++ b/src/corelib/thread/thread.pri
@@ -1,38 +1,66 @@
# Qt core thread module
-# public headers
-HEADERS += thread/qmutex.h \
- thread/qrunnable.h \
- thread/qreadwritelock.h \
- thread/qsemaphore.h \
- thread/qthread.h \
- thread/qthreadpool.h \
- thread/qthreadstorage.h \
- thread/qwaitcondition.h \
- thread/qatomic.h \
- thread/qatomic_bootstrap.h \
- thread/qatomic_cxx11.h \
- thread/qbasicatomic.h \
- thread/qgenericatomic.h
+HEADERS += \
+ thread/qmutex.h \
+ thread/qreadwritelock.h \
+ thread/qrunnable.h \
+ thread/qthread.h \
+ thread/qthreadstorage.h \
+ thread/qwaitcondition.h
-# private headers
-HEADERS += thread/qmutex_p.h \
- thread/qmutexpool_p.h \
- thread/qfutex_p.h \
- thread/qorderedmutexlocker_p.h \
- thread/qreadwritelock_p.h \
- thread/qthread_p.h \
- thread/qthreadpool_p.h
+SOURCES += \
+ thread/qrunnable.cpp \
+ thread/qthread.cpp
-SOURCES += thread/qatomic.cpp \
- thread/qmutex.cpp \
- thread/qreadwritelock.cpp \
- thread/qrunnable.cpp \
- thread/qmutexpool.cpp \
- thread/qsemaphore.cpp \
- thread/qthread.cpp \
- thread/qthreadpool.cpp \
- thread/qthreadstorage.cpp
+win32 {
+ HEADERS += thread/qatomic_msvc.h
+
+ SOURCES += thread/qthread_win.cpp
+} else {
+ SOURCES += thread/qthread_unix.cpp
+}
+
+qtConfig(thread) {
+ HEADERS += \
+ thread/qatomic.h \
+ thread/qatomic_bootstrap.h \
+ thread/qatomic_cxx11.h \
+ thread/qbasicatomic.h \
+ thread/qfutex_p.h \
+ thread/qgenericatomic.h \
+ thread/qmutexpool_p.h \
+ thread/qmutex_p.h \
+ thread/qorderedmutexlocker_p.h \
+ thread/qreadwritelock_p.h \
+ thread/qsemaphore.h \
+ thread/qthreadpool.h \
+ thread/qthreadpool_p.h \
+ thread/qthread_p.h
+
+ SOURCES += \
+ thread/qatomic.cpp \
+ thread/qmutex.cpp \
+ thread/qmutexpool.cpp \
+ thread/qreadwritelock.cpp \
+ thread/qsemaphore.cpp \
+ thread/qthreadpool.cpp \
+ thread/qthreadstorage.cpp
+
+ win32 {
+ SOURCES += \
+ thread/qmutex_win.cpp \
+ thread/qwaitcondition_win.cpp
+ } else {
+ darwin {
+ SOURCES += thread/qmutex_mac.cpp
+ } else: linux {
+ SOURCES += thread/qmutex_linux.cpp
+ } else {
+ SOURCES += thread/qmutex_unix.cpp
+ }
+ SOURCES += thread/qwaitcondition_unix.cpp
+ }
+}
qtConfig(future) {
HEADERS += \
@@ -52,24 +80,4 @@ qtConfig(future) {
thread/qresultstore.cpp
}
-win32 {
- HEADERS += thread/qatomic_msvc.h
-
- SOURCES += \
- thread/qmutex_win.cpp \
- thread/qthread_win.cpp \
- thread/qwaitcondition_win.cpp
-} else {
- darwin {
- SOURCES += thread/qmutex_mac.cpp
- } else: linux {
- SOURCES += thread/qmutex_linux.cpp
- } else {
- SOURCES += thread/qmutex_unix.cpp
- }
- SOURCES += \
- thread/qthread_unix.cpp \
- thread/qwaitcondition_unix.cpp
-}
-
qtConfig(std-atomic64): QMAKE_USE += libatomic
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index f0ac2701e7..a73ec1e22a 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -29,6 +29,7 @@
\headerfile <QtAlgorithms>
\title Generic Algorithms
\ingroup funclists
+ \keyword generic algorithms
\brief The <QtAlgorithms> header includes the generic, template-based algorithms.
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index f0cc56e899..a642fb9b39 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -159,6 +159,7 @@ struct QTypedArrayData
inline iterator &operator-=(int j) { i-=j; return *this; }
inline iterator operator+(int j) const { return iterator(i+j); }
inline iterator operator-(int j) const { return iterator(i-j); }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
inline int operator-(iterator j) const { return i - j.i; }
inline operator T*() const { return i; }
};
@@ -194,6 +195,7 @@ struct QTypedArrayData
inline const_iterator &operator-=(int j) { i-=j; return *this; }
inline const_iterator operator+(int j) const { return const_iterator(i+j); }
inline const_iterator operator-(int j) const { return const_iterator(i-j); }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
inline int operator-(const_iterator j) const { return i - j.i; }
inline operator const T*() const { return i; }
};
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 424420204a..b53a60b9bf 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -47,6 +47,7 @@
#include "qlocale_p.h"
#include "qlocale_tools_p.h"
#include "private/qnumeric_p.h"
+#include "private/qsimd_p.h"
#include "qstringalgorithms_p.h"
#include "qscopedpointer.h"
#include "qbytearray_p.h"
@@ -356,7 +357,8 @@ char *qstrncpy(char *dst, const char *src, uint len)
Special case 2: Returns an arbitrary non-zero value if \a str1 is
nullptr or \a str2 is nullptr (but not both).
- \sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}
+ \sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons},
+ QByteArray::compare()
*/
int qstrcmp(const char *str1, const char *str2)
{
@@ -381,7 +383,8 @@ int qstrcmp(const char *str1, const char *str2)
Special case 2: Returns a random non-zero value if \a str1 is nullptr
or \a str2 is nullptr (but not both).
- \sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}
+ \sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons},
+ QByteArray::compare()
*/
/*! \relates QByteArray
@@ -400,21 +403,80 @@ int qstrcmp(const char *str1, const char *str2)
Special case 2: Returns a random non-zero value if \a str1 is nullptr
or \a str2 is nullptr (but not both).
- \sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons}
+ \sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons},
+ QByteArray::compare()
*/
int qstricmp(const char *str1, const char *str2)
{
const uchar *s1 = reinterpret_cast<const uchar *>(str1);
const uchar *s2 = reinterpret_cast<const uchar *>(str2);
- int res;
- uchar c;
- if (!s1 || !s2)
- return s1 ? 1 : (s2 ? -1 : 0);
- for (; !(res = (c = latin1_lowercased[*s1]) - latin1_lowercased[*s2]); s1++, s2++)
- if (!c) // strings are equal
- break;
- return res;
+ if (!s1)
+ return s2 ? -1 : 0;
+ if (!s2)
+ return 1;
+
+ enum { Incomplete = 256 };
+ qptrdiff offset = 0;
+ auto innerCompare = [=, &offset](qptrdiff max, bool unlimited) {
+ max += offset;
+ do {
+ uchar c = latin1_lowercased[s1[offset]];
+ int res = c - latin1_lowercased[s2[offset]];
+ if (Q_UNLIKELY(res))
+ return res;
+ if (Q_UNLIKELY(!c))
+ return 0;
+ ++offset;
+ } while (unlimited || offset < max);
+ return int(Incomplete);
+ };
+
+#if defined(__SSE4_1__) && !(defined(__SANITIZE_ADDRESS__) || QT_HAS_FEATURE(address_sanitizer))
+ enum { PageSize = 4096, PageMask = PageSize - 1 };
+ const __m128i zero = _mm_setzero_si128();
+ forever {
+ // Calculate how many bytes we can load until we cross a page boundary
+ // for either source. This isn't an exact calculation, just something
+ // very quick.
+ quintptr u1 = quintptr(s1 + offset);
+ quintptr u2 = quintptr(s2 + offset);
+ uint n = PageSize - ((u1 | u2) & PageMask);
+
+ qptrdiff maxoffset = offset + n;
+ for ( ; offset + 16 <= maxoffset; offset += sizeof(__m128i)) {
+ // load 16 bytes from either source
+ __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s1 + offset));
+ __m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s2 + offset));
+
+ // compare the two against each oher
+ __m128i cmp = _mm_cmpeq_epi8(a, b);
+
+ // find NUL terminators too
+ cmp = _mm_min_epu8(cmp, a);
+ cmp = _mm_cmpeq_epi8(cmp, zero);
+
+ // was there any difference or a NUL?
+ uint mask = _mm_movemask_epi8(cmp);
+ if (mask) {
+ // yes, find out where
+ uint start = qCountTrailingZeroBits(mask);
+ uint end = sizeof(mask) * 8 - qCountLeadingZeroBits(mask);
+ Q_ASSUME(end >= start);
+ offset += start;
+ n = end - start;
+ break;
+ }
+ }
+
+ // using SIMD could cause a page fault, so iterate byte by byte
+ int res = innerCompare(n, false);
+ if (res != Incomplete)
+ return res;
+ }
+#endif
+
+ return innerCompare(-1, true);
}
/*! \relates QByteArray
@@ -434,7 +496,8 @@ int qstricmp(const char *str1, const char *str2)
Special case 2: Returns a random non-zero value if \a str1 is nullptr
or \a str2 is nullptr (but not both).
- \sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons}
+ \sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons},
+ QByteArray::compare()
*/
int qstrnicmp(const char *str1, const char *str2, uint len)
@@ -456,6 +519,55 @@ int qstrnicmp(const char *str1, const char *str2, uint len)
/*!
\internal
+ \since 5.12
+
+ A helper for QByteArray::compare. Compares \a len1 bytes from \a str1 to \a
+ len2 bytes from \a str2. If \a len2 is -1, then \a str2 is expected to be
+ null-terminated.
+ */
+int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
+{
+ Q_ASSERT(str1);
+ Q_ASSERT(len1 >= 0);
+ Q_ASSERT(len2 >= -1);
+ const uchar *s1 = reinterpret_cast<const uchar *>(str1);
+ const uchar *s2 = reinterpret_cast<const uchar *>(str2);
+ if (!s2)
+ return len1 == 0 ? 0 : 1;
+
+ int res;
+ uchar c;
+ if (len2 == -1) {
+ // null-terminated str2
+ qsizetype i;
+ for (i = 0; i < len1; ++i) {
+ c = latin1_lowercased[s2[i]];
+ if (!c)
+ return 1;
+
+ res = latin1_lowercased[s1[i]] - c;
+ if (res)
+ return res;
+ }
+ c = latin1_lowercased[s2[i]];
+ return c ? -1 : 0;
+ } else {
+ // not null-terminated
+ for (qsizetype i = 0; i < qMin(len1, len2); ++i) {
+ c = latin1_lowercased[s2[i]];
+ res = latin1_lowercased[s1[i]] - c;
+ if (res)
+ return res;
+ }
+ if (len1 == len2)
+ return 0;
+ return len1 < len2 ? -1 : 1;
+ }
+}
+
+/*!
+ \internal
+ ### Qt6: replace the QByteArray parameter with [pointer,len] pair
*/
int qstrcmp(const QByteArray &str1, const char *str2)
{
@@ -483,6 +595,7 @@ int qstrcmp(const QByteArray &str1, const char *str2)
/*!
\internal
+ ### Qt6: replace the QByteArray parameter with [pointer,len] pair
*/
int qstrcmp(const QByteArray &str1, const QByteArray &str2)
{
@@ -950,7 +1063,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
$LC_CTYPE is set, most Unix systems do "the right thing".)
Functions that this affects include contains(), indexOf(),
lastIndexOf(), operator<(), operator<=(), operator>(),
- operator>=(), toLower() and toUpper().
+ operator>=(), isLower(), isUpper(), toLower() and toUpper().
This issue does not apply to \l{QString}s since they represent
characters using Unicode.
@@ -2864,6 +2977,31 @@ int QByteArray::count(char ch) const
*/
/*!
+ \fn int QByteArray::compare(const char *c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \since 5.12
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether this QByteArray sorts before, at the same position, or after the
+ string pointed to by \a c. The comparison is performed according to case
+ sensitivity \a cs.
+
+ \sa operator==
+*/
+
+/*!
+ \fn int QByteArray::compare(const QByteArray &a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \overload
+ \since 5.12
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether this QByteArray sorts before, at the same position, or after the
+ QByteArray \a a. The comparison is performed according to case sensitivity
+ \a cs.
+
+ \sa operator==
+*/
+
+/*!
Returns \c true if this byte array starts with byte array \a ba;
otherwise returns \c false.
@@ -2941,6 +3079,78 @@ bool QByteArray::endsWith(const char *str) const
return qstrncmp(d->data() + d->size - len, str, len) == 0;
}
+/*!
+ Returns true if \a c is an uppercase Latin1 letter.
+ \note The multiplication sign 0xD7 and the sz ligature 0xDF are not
+ treated as uppercase Latin1.
+ */
+static inline bool isUpperCaseLatin1(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return true;
+
+ return (uchar(c) >= 0xC0 && uchar(c) <= 0xDE && uchar(c) != 0xD7);
+}
+
+/*!
+ Returns \c true if this byte array contains only uppercase letters,
+ otherwise returns \c false. The byte array is interpreted as a Latin-1
+ encoded string.
+ \since 5.12
+
+ \sa isLower(), toUpper()
+*/
+bool QByteArray::isUpper() const
+{
+ if (isEmpty())
+ return false;
+
+ const char *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!isUpperCaseLatin1(d[i]))
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ Returns true if \a c is an lowercase Latin1 letter.
+ \note The division sign 0xF7 is not treated as lowercase Latin1,
+ but the small y dieresis 0xFF is.
+ */
+static inline bool isLowerCaseLatin1(char c)
+{
+ if (c >= 'a' && c <= 'z')
+ return true;
+
+ return (uchar(c) >= 0xD0 && uchar(c) != 0xF7);
+}
+
+/*!
+ Returns \c true if this byte array contains only lowercase letters,
+ otherwise returns \c false. The byte array is interpreted as a Latin-1
+ encoded string.
+ \since 5.12
+
+ \sa isUpper(), toLower()
+ */
+bool QByteArray::isLower() const
+{
+ if (isEmpty())
+ return false;
+
+ const char *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!isLowerCaseLatin1(d[i]))
+ return false;
+ }
+
+ return true;
+}
+
/*! \overload
Returns \c true if this byte array ends with character \a ch;
@@ -3052,7 +3262,7 @@ QByteArray QByteArray::mid(int pos, int len) const
Example:
\snippet code/src_corelib_tools_qbytearray.cpp 30
- \sa toUpper(), {8-bit Character Comparisons}
+ \sa isLower(), toUpper(), {8-bit Character Comparisons}
*/
// prevent the compiler from inlining the function in each of
@@ -3106,7 +3316,7 @@ QByteArray QByteArray::toLower_helper(QByteArray &a)
Example:
\snippet code/src_corelib_tools_qbytearray.cpp 31
- \sa toLower(), {8-bit Character Comparisons}
+ \sa isUpper(), toLower(), {8-bit Character Comparisons}
*/
QByteArray QByteArray::toUpper_helper(const QByteArray &a)
@@ -3295,6 +3505,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is equal to byte array \a a2;
otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator==(const QByteArray &a1, const char *a2)
@@ -3304,6 +3516,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is equal to string \a a2;
otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator==(const char *a1, const QByteArray &a2)
@@ -3313,6 +3527,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is equal to byte array \a a2;
otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator!=(const QByteArray &a1, const QByteArray &a2)
@@ -3322,6 +3538,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is not equal to byte array \a a2;
otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator!=(const QByteArray &a1, const char *a2)
@@ -3331,6 +3549,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is not equal to string \a a2;
otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator!=(const char *a1, const QByteArray &a2)
@@ -3340,6 +3560,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is not equal to byte array \a a2;
otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator<(const QByteArray &a1, const QByteArray &a2)
@@ -3349,6 +3571,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically less than byte array
\a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn inline bool operator<(const QByteArray &a1, const char *a2)
@@ -3358,6 +3582,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically less than string
\a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator<(const char *a1, const QByteArray &a2)
@@ -3367,6 +3593,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is lexically less than byte array
\a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator<=(const QByteArray &a1, const QByteArray &a2)
@@ -3376,6 +3604,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically less than or equal
to byte array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator<=(const QByteArray &a1, const char *a2)
@@ -3385,6 +3615,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically less than or equal
to string \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator<=(const char *a1, const QByteArray &a2)
@@ -3394,6 +3626,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is lexically less than or equal
to byte array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator>(const QByteArray &a1, const QByteArray &a2)
@@ -3403,6 +3637,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically greater than byte
array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator>(const QByteArray &a1, const char *a2)
@@ -3412,6 +3648,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically greater than string
\a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator>(const char *a1, const QByteArray &a2)
@@ -3421,6 +3659,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is lexically greater than byte array
\a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator>=(const QByteArray &a1, const QByteArray &a2)
@@ -3430,6 +3670,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically greater than or
equal to byte array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator>=(const QByteArray &a1, const char *a2)
@@ -3439,6 +3681,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if byte array \a a1 is lexically greater than or
equal to string \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn bool operator>=(const char *a1, const QByteArray &a2)
@@ -3448,6 +3692,8 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba)
Returns \c true if string \a a1 is lexically greater than or
equal to byte array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
*/
/*! \fn const QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
@@ -3878,9 +4124,16 @@ ushort QByteArray::toUShort(bool *ok, int base) const
\snippet code/src_corelib_tools_qbytearray.cpp 38
+ \warning The QByteArray content may only contain valid numerical characters
+ which includes the plus/minus sign, the character e used in scientific
+ notation, and the decimal point. Including the unit or additional characters
+ leads to a conversion error.
+
\note The conversion of the number is performed in the default C locale,
irrespective of the user's locale.
+ This function ignores leading and trailing whitespace.
+
\sa number()
*/
@@ -3889,7 +4142,8 @@ double QByteArray::toDouble(bool *ok) const
QByteArray nulled = nulTerminated();
bool nonNullOk = false;
int processed = 0;
- double d = asciiToDouble(nulled.constData(), nulled.length(), nonNullOk, processed);
+ double d = qt_asciiToDouble(nulled.constData(), nulled.length(),
+ nonNullOk, processed, WhitespacesAllowed);
if (ok)
*ok = nonNullOk;
return d;
@@ -3903,9 +4157,18 @@ double QByteArray::toDouble(bool *ok) const
If \a ok is not \c nullptr, failure is reported by setting *\a{ok}
to \c false, and success by setting *\a{ok} to \c true.
+ \snippet code/src_corelib_tools_qbytearray.cpp 38float
+
+ \warning The QByteArray content may only contain valid numerical characters
+ which includes the plus/minus sign, the character e used in scientific
+ notation, and the decimal point. Including the unit or additional characters
+ leads to a conversion error.
+
\note The conversion of the number is performed in the default C locale,
irrespective of the user's locale.
+ This function ignores leading and trailing whitespace.
+
\sa number()
*/
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index 300f795469..8ee3a29ecc 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -99,6 +99,7 @@ inline int qstrncmp(const char *str1, const char *str2, uint len)
}
Q_CORE_EXPORT int qstricmp(const char *, const char *);
Q_CORE_EXPORT int qstrnicmp(const char *, const char *, uint len);
+Q_CORE_EXPORT int qstrnicmp(const char *, qsizetype, const char *, qsizetype = -1);
// implemented in qvsnprintf.cpp
Q_CORE_EXPORT int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap);
@@ -231,6 +232,9 @@ public:
int count(const char *a) const;
int count(const QByteArray &a) const;
+ inline int compare(const char *c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline int compare(const QByteArray &a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
Q_REQUIRED_RESULT QByteArray left(int len) const;
Q_REQUIRED_RESULT QByteArray right(int len) const;
Q_REQUIRED_RESULT QByteArray mid(int index, int len = -1) const;
@@ -245,6 +249,9 @@ public:
bool endsWith(char c) const;
bool endsWith(const char *c) const;
+ bool isUpper() const;
+ bool isLower() const;
+
void truncate(int pos);
void chop(int n);
@@ -600,6 +607,16 @@ inline bool QByteArray::contains(const QByteArray &a) const
{ return indexOf(a) != -1; }
inline bool QByteArray::contains(char c) const
{ return indexOf(c) != -1; }
+inline int QByteArray::compare(const char *c, Qt::CaseSensitivity cs) const
+{
+ return cs == Qt::CaseSensitive ? qstrcmp(*this, c) :
+ qstrnicmp(data(), size(), c, -1);
+}
+inline int QByteArray::compare(const QByteArray &a, Qt::CaseSensitivity cs) const
+{
+ return cs == Qt::CaseSensitive ? qstrcmp(*this, a) :
+ qstrnicmp(data(), size(), a.data(), a.size());
+}
inline bool operator==(const QByteArray &a1, const QByteArray &a2) Q_DECL_NOTHROW
{ return (a1.size() == a2.size()) && (memcmp(a1.constData(), a2.constData(), a1.size())==0); }
inline bool operator==(const QByteArray &a1, const char *a2) Q_DECL_NOTHROW
diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp
index 5155badcf8..1cf223aae6 100644
--- a/src/corelib/tools/qcollator.cpp
+++ b/src/corelib/tools/qcollator.cpp
@@ -77,9 +77,8 @@ QT_BEGIN_NAMESPACE
\sa setLocale()
*/
QCollator::QCollator(const QLocale &locale)
- : d(new QCollatorPrivate)
+ : d(new QCollatorPrivate(locale))
{
- d->locale = locale;
d->init();
}
@@ -158,15 +157,13 @@ QCollator &QCollator::operator=(const QCollator &other)
void QCollator::detach()
{
if (d->ref.load() != 1) {
- QCollatorPrivate *x = new QCollatorPrivate;
- x->ref.store(1);
- x->locale = d->locale;
- x->collator = 0;
+ QCollatorPrivate *x = new QCollatorPrivate(d->locale);
if (!d->ref.deref())
delete d;
d = x;
- d->init();
}
+ // All callers need this, because about to modify the object:
+ d->dirty = true;
}
/*!
@@ -179,7 +176,6 @@ void QCollator::setLocale(const QLocale &locale)
detach();
d->locale = locale;
- d->dirty = true;
}
/*!
@@ -204,7 +200,6 @@ void QCollator::setCaseSensitivity(Qt::CaseSensitivity cs)
detach();
d->caseSensitivity = cs;
- d->dirty = true;
}
/*!
@@ -242,7 +237,6 @@ void QCollator::setNumericMode(bool on)
detach();
d->numericMode = on;
- d->dirty = true;
}
/*!
@@ -275,7 +269,6 @@ void QCollator::setIgnorePunctuation(bool on)
detach();
d->ignorePunctuation = on;
- d->dirty = true;
}
/*!
diff --git a/src/corelib/tools/qcollator_icu.cpp b/src/corelib/tools/qcollator_icu.cpp
index 43bbe0ea79..fd621983d3 100644
--- a/src/corelib/tools/qcollator_icu.cpp
+++ b/src/corelib/tools/qcollator_icu.cpp
@@ -61,7 +61,7 @@ void QCollatorPrivate::init()
collator = ucol_open(name.constData(), &status);
if (U_FAILURE(status)) {
qWarning("Could not create collator: %d", status);
- collator = 0;
+ collator = nullptr;
dirty = false;
return;
}
@@ -100,7 +100,7 @@ void QCollatorPrivate::cleanup()
{
if (collator)
ucol_close(collator);
- collator = 0;
+ collator = nullptr;
}
int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
diff --git a/src/corelib/tools/qcollator_p.h b/src/corelib/tools/qcollator_p.h
index c03a3431db..e89c08447c 100644
--- a/src/corelib/tools/qcollator_p.h
+++ b/src/corelib/tools/qcollator_p.h
@@ -68,27 +68,31 @@ QT_BEGIN_NAMESPACE
#if QT_CONFIG(icu)
typedef UCollator *CollatorType;
typedef QByteArray CollatorKeyType;
+const CollatorType NoCollator = nullptr;
#elif defined(Q_OS_OSX)
typedef CollatorRef CollatorType;
typedef QVector<UCCollationValue> CollatorKeyType;
+const CollatorType NoCollator = 0;
#elif defined(Q_OS_WIN)
typedef QString CollatorKeyType;
typedef int CollatorType;
+const CollatorType NoCollator = 0;
# ifdef Q_OS_WINRT
# define USE_COMPARESTRINGEX
# endif
-#else //posix
+#else // posix - ignores CollatorType collator, only handles system locale
typedef QVector<wchar_t> CollatorKeyType;
-typedef int CollatorType;
+typedef bool CollatorType;
+const CollatorType NoCollator = false;
#endif
class QCollatorPrivate
{
public:
- QAtomicInt ref;
+ QAtomicInt ref = 1;
QLocale locale;
#if defined(Q_OS_WIN) && !QT_CONFIG(icu)
#ifdef USE_COMPARESTRINGEX
@@ -97,32 +101,25 @@ public:
LCID localeID;
#endif
#endif
- Qt::CaseSensitivity caseSensitivity;
- bool numericMode;
- bool ignorePunctuation;
- bool dirty;
+ Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
+ bool numericMode = false;
+ bool ignorePunctuation = false;
+ bool dirty = true;
+
+ CollatorType collator = NoCollator;
- CollatorType collator;
+ QCollatorPrivate(const QLocale &locale) : locale(locale) {}
+ ~QCollatorPrivate() { cleanup(); }
void clear() {
cleanup();
- collator = 0;
+ collator = NoCollator;
}
+ // Implemented by each back-end, in its own way:
void init();
void cleanup();
- QCollatorPrivate()
- : ref(1),
- caseSensitivity(Qt::CaseSensitive),
- numericMode(false),
- ignorePunctuation(false),
- dirty(true),
- collator(0)
- { cleanup(); }
-
- ~QCollatorPrivate() { cleanup(); }
-
private:
Q_DISABLE_COPY(QCollatorPrivate)
};
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index 18facf7e42..faa7263d6b 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -211,6 +211,7 @@ void QContiguousCache<T>::detach_helper()
template <typename T>
void QContiguousCache<T>::setCapacity(int asize)
{
+ Q_ASSERT(asize >= 0);
if (asize == d->alloc)
return;
detach();
@@ -285,6 +286,7 @@ inline QContiguousCacheData *QContiguousCache<T>::allocateData(int aalloc)
template <typename T>
QContiguousCache<T>::QContiguousCache(int cap)
{
+ Q_ASSERT(cap >= 0);
d = allocateData(cap);
d->ref.store(1);
d->alloc = cap;
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index a1b121f1ee..3c79bb797d 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -544,6 +544,46 @@ QByteArray QCryptographicHash::hash(const QByteArray &data, Algorithm method)
return hash.result();
}
+/*!
+ Returns the size of the output of the selected hash \a method in bytes.
+
+ \since 5.12
+*/
+int QCryptographicHash::hashLength(QCryptographicHash::Algorithm method)
+{
+ switch (method) {
+ case QCryptographicHash::Sha1:
+ return 20;
+#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ case QCryptographicHash::Md4:
+ return 16;
+ case QCryptographicHash::Md5:
+ return 16;
+ case QCryptographicHash::Sha224:
+ return SHA224HashSize;
+ case QCryptographicHash::Sha256:
+ return SHA256HashSize;
+ case QCryptographicHash::Sha384:
+ return SHA384HashSize;
+ case QCryptographicHash::Sha512:
+ return SHA512HashSize;
+ case QCryptographicHash::RealSha3_224:
+ case QCryptographicHash::Keccak_224:
+ return 224 / 8;
+ case QCryptographicHash::RealSha3_256:
+ case QCryptographicHash::Keccak_256:
+ return 256 / 8;
+ case QCryptographicHash::RealSha3_384:
+ case QCryptographicHash::Keccak_384:
+ return 384 / 8;
+ case QCryptographicHash::RealSha3_512:
+ case QCryptographicHash::Keccak_512:
+ return 512 / 8;
+#endif
+ }
+ return 0;
+}
+
QT_END_NAMESPACE
#ifndef QT_NO_QOBJECT
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
index 2f74d42405..ad1de7c756 100644
--- a/src/corelib/tools/qcryptographichash.h
+++ b/src/corelib/tools/qcryptographichash.h
@@ -101,6 +101,7 @@ public:
QByteArray result() const;
static QByteArray hash(const QByteArray &data, Algorithm method);
+ static int hashLength(Algorithm method);
private:
Q_DISABLE_COPY(QCryptographicHash)
QCryptographicHashPrivate *d;
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index f5e264798e..816bd974eb 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -326,20 +326,19 @@ static int fromOffsetString(const QStringRef &offsetString, bool *valid) Q_DECL_
\brief The QDate class provides date functions.
- A QDate object contains a calendar date, i.e. year, month, and day
- numbers, in the Gregorian calendar. It can read the current date
- from the system clock. It provides functions for comparing dates,
- and for manipulating dates. For example, it is possible to add
- and subtract days, months, and years to dates.
-
- A QDate object is typically created by giving the year,
- month, and day numbers explicitly. Note that QDate interprets two
- digit years as is, i.e., years 0 - 99. A QDate can also be
- constructed with the static function currentDate(), which creates
- a QDate object containing the system clock's date. An explicit
- date can also be set using setDate(). The fromString() function
- returns a QDate given a string and a date format which is used to
- interpret the date within the string.
+ A QDate object encodes a calendar date, i.e. year, month, and day numbers,
+ in the proleptic Gregorian calendar by default. It can read the current date
+ from the system clock. It provides functions for comparing dates, and for
+ manipulating dates. For example, it is possible to add and subtract days,
+ months, and years to dates.
+
+ A QDate object is typically created by giving the year, month, and day
+ numbers explicitly. Note that QDate interprets two digit years as presented,
+ i.e., as years 0 through 99, without adding any offset. A QDate can also be
+ constructed with the static function currentDate(), which creates a QDate
+ object containing the system clock's date. An explicit date can also be set
+ using setDate(). The fromString() function returns a QDate given a string
+ and a date format which is used to interpret the date within the string.
The year(), month(), and day() functions provide access to the
year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
@@ -363,9 +362,9 @@ static int fromOffsetString(const QStringRef &offsetString, bool *valid) Q_DECL_
\section2 No Year 0
- There is no year 0. Dates in that year are considered invalid. The
- year -1 is the year "1 before Christ" or "1 before current era."
- The day before 1 January 1 CE is 31 December 1 BCE.
+ There is no year 0. Dates in that year are considered invalid. The year -1
+ is the year "1 before Christ" or "1 before current era." The day before 1
+ January 1 CE, QDate(1, 1, 1), is 31 December 1 BCE, QDate(-1, 12, 31).
\section2 Range of Valid Dates
@@ -1418,11 +1417,12 @@ bool QDate::isLeapYear(int y)
\brief The QTime class provides clock time functions.
- A QTime object contains a clock time, i.e. the number of hours,
- minutes, seconds, and milliseconds since midnight. It can read the
- current time from the system clock and measure a span of elapsed
- time. It provides functions for comparing times and for
- manipulating a time by adding a number of milliseconds.
+ A QTime object contains a clock time, which it can express as the
+ numbers of hours, minutes, seconds, and milliseconds since
+ midnight. It can read the current time from the system clock and
+ measure a span of elapsed time. It provides functions for
+ comparing times and for manipulating a time by adding a number of
+ milliseconds.
QTime uses the 24-hour clock format; it has no concept of AM/PM.
Unlike QDateTime, QTime knows nothing about time zones or
@@ -1440,15 +1440,15 @@ bool QDate::isLeapYear(int y)
of the time. The same information is provided in textual format by
the toString() function.
- QTime provides a full set of operators to compare two QTime
- objects. QTime A is considered smaller than QTime B if A is
- earlier than B.
-
The addSecs() and addMSecs() functions provide the time a given
number of seconds or milliseconds later than a given time.
Correspondingly, the number of seconds or milliseconds
between two times can be found using secsTo() or msecsTo().
+ QTime provides a full set of operators to compare two QTime
+ objects; an earlier time is considered smaller than a later one;
+ if A.msecsTo(B) is positive, then A < B.
+
QTime can be used to measure a span of elapsed time using the
start(), restart(), and elapsed() functions.
@@ -2341,7 +2341,7 @@ static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localT
// localtime_r() does not have this requirement, so make an explicit call.
// The explicit call should also request the timezone info be re-parsed.
qt_tzset();
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
// Use the reentrant version of localtime() where available
// as is thread-safe and doesn't use a shared static data area
tm *res = 0;
@@ -2981,18 +2981,18 @@ inline QDateTime::Data QDateTimePrivate::create(const QDate &toDate, const QTime
// DST transitions are disambiguated by hint.
inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone &zone,
DaylightStatus hint,
- QDate *localDate, QTime *localTime)
+ QDate *zoneDate, QTime *zoneTime)
{
// Get the effective data from QTimeZone
QTimeZonePrivate::Data data = zone.d->dataForLocalTime(zoneMSecs, int(hint));
- // Docs state any LocalTime before 1970-01-01 will *not* have any DST applied
+ // Docs state any time before 1970-01-01 will *not* have any DST applied
// but all affected times afterwards will have DST applied.
- if (data.atMSecsSinceEpoch >= 0) {
- msecsToTime(data.atMSecsSinceEpoch + (data.offsetFromUtc * 1000), localDate, localTime);
- return data.atMSecsSinceEpoch;
+ if (data.atMSecsSinceEpoch < 0) {
+ msecsToTime(zoneMSecs, zoneDate, zoneTime);
+ return zoneMSecs - data.standardTimeOffset * 1000;
} else {
- msecsToTime(zoneMSecs, localDate, localTime);
- return zoneMSecs - (data.standardTimeOffset * 1000);
+ msecsToTime(data.atMSecsSinceEpoch + data.offsetFromUtc * 1000, zoneDate, zoneTime);
+ return data.atMSecsSinceEpoch;
}
}
#endif // timezone
@@ -3009,8 +3009,8 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
\brief The QDateTime class provides date and time functions.
- A QDateTime object contains a calendar date and a clock time (a
- "datetime"). It is a combination of the QDate and QTime classes.
+ A QDateTime object encodes a calendar date and a clock time (a
+ "datetime"). It combines features of the QDate and QTime classes.
It can read the current datetime from the system clock. It
provides functions for comparing datetimes and for manipulating a
datetime by adding a number of seconds, days, months, or years.
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index 235ca625c1..f82048db0f 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -292,7 +292,7 @@
This is a typedef for a pointer to a function with the following
signature:
- \snippet code/src_corelib_tools_qeasingcurve.cpp 0
+ \snippet code/src_corelib_tools_qeasingcurve.cpp typedef
*/
#include "qeasingcurve.h"
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 5f0b131342..8d2616865e 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1100,9 +1100,8 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
To avoid this problem, replace \c hash[i] with \c hash.value(i)
in the code above.
- Internally, QHash uses a hash table to perform lookups. Unlike Qt
- 3's \c QDict class, which needed to be initialized with a prime
- number, QHash's hash table automatically grows and shrinks to
+ Internally, QHash uses a hash table to perform lookups. This
+ hash table automatically grows and shrinks to
provide fast lookups without wasting too much memory. You can
still control the size of the hash table by calling reserve() if
you already know approximately how many items the QHash will
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index ce663ce2ca..a586ca5671 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -348,6 +348,7 @@ public:
inline iterator operator-(int j) const { return operator+(-j); }
inline iterator &operator+=(int j) { return *this = *this + j; }
inline iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
#ifndef QT_STRICT_ITERATORS
public:
@@ -413,6 +414,7 @@ public:
inline const_iterator operator-(int j) const { return operator+(-j); }
inline const_iterator &operator+=(int j) { return *this = *this + j; }
inline const_iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
// ### Qt 5: not sure this is necessary anymore
#ifdef QT_STRICT_ITERATORS
diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h
index e6ae7a0b85..d013c26d66 100644
--- a/src/corelib/tools/qhashfunctions.h
+++ b/src/corelib/tools/qhashfunctions.h
@@ -104,6 +104,11 @@ Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed =
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(QStringView key, uint chained = 0) Q_DECL_NOTHROW;
+Q_DECL_CONST_FUNCTION inline uint qHash(std::nullptr_t, uint seed = 0) Q_DECL_NOTHROW
+{
+ return qHash(reinterpret_cast<quintptr>(nullptr), seed);
+}
+
template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
{
return qHash(reinterpret_cast<quintptr>(key), seed);
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index c8f3f4c8c3..1e6d4df474 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -159,6 +159,7 @@ public:
inline iterator operator-(int j) const { return operator+(-j); }
inline iterator &operator+=(int j) { return *this = *this + j; }
inline iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
};
friend class iterator;
@@ -193,6 +194,7 @@ public:
inline const_iterator operator-(int j) const { return operator+(-j); }
inline const_iterator &operator+=(int j) { return *this = *this + j; }
inline const_iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
};
friend class const_iterator;
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index af7659e995..c00220ad3a 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -269,6 +269,7 @@ public:
inline iterator &operator-=(difference_type j) { i-=j; return *this; }
inline iterator operator+(difference_type j) const { return iterator(i+j); }
inline iterator operator-(difference_type j) const { return iterator(i-j); }
+ friend inline iterator operator+(difference_type j, iterator k) { return k + j; }
inline int operator-(iterator j) const { return int(i - j.i); }
};
friend class iterator;
@@ -312,6 +313,7 @@ public:
inline const_iterator &operator-=(difference_type j) { i-=j; return *this; }
inline const_iterator operator+(difference_type j) const { return const_iterator(i+j); }
inline const_iterator operator-(difference_type j) const { return const_iterator(i-j); }
+ friend inline const_iterator operator+(difference_type j, const_iterator k) { return k + j; }
inline int operator-(const_iterator j) const { return int(i - j.i); }
};
friend class const_iterator;
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 6361280bc7..ddc973cb37 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -83,7 +83,6 @@ public:
};
Q_GLOBAL_STATIC(QSystemLocaleSingleton, QSystemLocale_globalSystemLocale)
-static QLocaleData *system_data = 0;
static QLocaleData globalLocaleData;
#endif
@@ -233,14 +232,6 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
if (addLikelySubtags(id))
return id;
}
- // language_script
- if (country_id) {
- QLocaleId id = QLocaleId::fromIds(language_id, script_id, 0);
- if (addLikelySubtags(id)) {
- id.country_id = country_id;
- return id;
- }
- }
// language_region
if (script_id) {
QLocaleId id = QLocaleId::fromIds(language_id, 0, country_id);
@@ -249,6 +240,14 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
return id;
}
}
+ // language_script
+ if (country_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, script_id, 0);
+ if (addLikelySubtags(id)) {
+ id.country_id = country_id;
+ return id;
+ }
+ }
// language
if (script_id && country_id) {
QLocaleId id = QLocaleId::fromIds(language_id, 0, 0);
@@ -258,6 +257,14 @@ QLocaleId QLocaleId::withLikelySubtagsAdded() const
return id;
}
}
+ // und_script
+ if (language_id) {
+ QLocaleId id = QLocaleId::fromIds(0, script_id, 0);
+ if (addLikelySubtags(id)) {
+ id.language_id = language_id;
+ return id;
+ }
+ }
return *this;
}
@@ -382,6 +389,13 @@ const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLoca
QList<QLocaleId> tried;
tried.push_back(likelyId);
+ // No match; try again with raw data:
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+
// No match; try again with likely country
if (country != QLocale::AnyCountry
&& (language != QLocale::AnyLanguage || script != QLocale::AnyScript)) {
@@ -614,8 +628,7 @@ QSystemLocale::QSystemLocale()
{
_systemLocale = this;
- if (system_data)
- system_data->m_language_id = 0;
+ globalLocaleData.m_language_id = 0;
}
/*!
@@ -632,8 +645,7 @@ QSystemLocale::~QSystemLocale()
if (_systemLocale == this) {
_systemLocale = 0;
- if (system_data)
- system_data->m_language_id = 0;
+ globalLocaleData.m_language_id = 0;
}
}
@@ -646,48 +658,47 @@ static const QSystemLocale *systemLocale()
void QLocalePrivate::updateSystemPrivate()
{
+ // this function is NOT thread-safe!
const QSystemLocale *sys_locale = systemLocale();
- if (!system_data)
- system_data = &globalLocaleData;
// tell the object that the system locale has changed.
sys_locale->query(QSystemLocale::LocaleChanged, QVariant());
- *system_data = *sys_locale->fallbackUiLocale().d->m_data;
+ globalLocaleData = *sys_locale->fallbackUiLocale().d->m_data;
QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
if (!res.isNull()) {
- system_data->m_language_id = res.toInt();
- system_data->m_script_id = QLocale::AnyScript; // default for compatibility
+ globalLocaleData.m_language_id = res.toInt();
+ globalLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
}
res = sys_locale->query(QSystemLocale::CountryId, QVariant());
if (!res.isNull()) {
- system_data->m_country_id = res.toInt();
- system_data->m_script_id = QLocale::AnyScript; // default for compatibility
+ globalLocaleData.m_country_id = res.toInt();
+ globalLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
}
res = sys_locale->query(QSystemLocale::ScriptId, QVariant());
if (!res.isNull())
- system_data->m_script_id = res.toInt();
+ globalLocaleData.m_script_id = res.toInt();
res = sys_locale->query(QSystemLocale::DecimalPoint, QVariant());
if (!res.isNull())
- system_data->m_decimal = res.toString().at(0).unicode();
+ globalLocaleData.m_decimal = res.toString().at(0).unicode();
res = sys_locale->query(QSystemLocale::GroupSeparator, QVariant());
if (!res.isNull())
- system_data->m_group = res.toString().at(0).unicode();
+ globalLocaleData.m_group = res.toString().at(0).unicode();
res = sys_locale->query(QSystemLocale::ZeroDigit, QVariant());
if (!res.isNull())
- system_data->m_zero = res.toString().at(0).unicode();
+ globalLocaleData.m_zero = res.toString().at(0).unicode();
res = sys_locale->query(QSystemLocale::NegativeSign, QVariant());
if (!res.isNull())
- system_data->m_minus = res.toString().at(0).unicode();
+ globalLocaleData.m_minus = res.toString().at(0).unicode();
res = sys_locale->query(QSystemLocale::PositiveSign, QVariant());
if (!res.isNull())
- system_data->m_plus = res.toString().at(0).unicode();
+ globalLocaleData.m_plus = res.toString().at(0).unicode();
}
#endif // !QT_NO_SYSTEMLOCALE
@@ -703,12 +714,12 @@ static const QLocaleData *systemData()
{
static QBasicMutex systemDataMutex;
systemDataMutex.lock();
- if (!system_data || system_data->m_language_id == 0)
+ if (globalLocaleData.m_language_id == 0)
QLocalePrivate::updateSystemPrivate();
systemDataMutex.unlock();
}
- return system_data;
+ return &globalLocaleData;
#else
return locale_data;
#endif
@@ -770,6 +781,8 @@ static const int locale_data_size = sizeof(locale_data)/sizeof(QLocaleData) - 1;
Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, defaultLocalePrivate,
(QLocalePrivate::create(defaultData(), default_number_options)))
+Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, systemLocalePrivate,
+ (QLocalePrivate::create(systemData())))
static QLocalePrivate *localePrivateByName(const QString &name)
{
@@ -1174,7 +1187,7 @@ T toIntegral_helper(const QLocalePrivate *d, QStringView str, bool *ok)
// we select the right overload by the last, unused parameter
Int64 val = toIntegral_helper(d->m_data, str, ok, d->m_numberOptions, Int64());
if (T(val) != val) {
- if (ok)
+ if (ok != nullptr)
*ok = false;
val = 0;
}
@@ -2340,7 +2353,9 @@ QString QLocale::toString(double i, char f, int prec) const
QLocale QLocale::system()
{
- return QLocale(*QLocalePrivate::create(systemData()));
+ // this function is NOT thread-safe!
+ QT_PREPEND_NAMESPACE(systemData)(); // trigger updating of the system data if necessary
+ return QLocale(*systemLocalePrivate->data());
}
@@ -3069,7 +3084,7 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q
QVarLengthArray<char> buf(bufSize);
int length;
- doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
+ qt_doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
if (qstrncmp(buf.data(), "inf", 3) == 0 || qstrncmp(buf.data(), "nan", 3) == 0) {
num_str = QString::fromLatin1(buf.data(), length);
@@ -3573,14 +3588,14 @@ double QLocaleData::stringToDouble(QStringView str, bool *ok,
{
CharBuff buff;
if (!numberToCLocale(str, number_options, &buff)) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0.0;
}
int processed = 0;
bool nonNullOk = false;
- double d = asciiToDouble(buff.constData(), buff.length() - 1, nonNullOk, processed);
- if (ok)
+ double d = qt_asciiToDouble(buff.constData(), buff.length() - 1, nonNullOk, processed);
+ if (ok != nullptr)
*ok = nonNullOk;
return d;
}
@@ -3590,7 +3605,7 @@ qlonglong QLocaleData::stringToLongLong(QStringView str, int base, bool *ok,
{
CharBuff buff;
if (!numberToCLocale(str, number_options, &buff)) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
@@ -3603,7 +3618,7 @@ qulonglong QLocaleData::stringToUnsLongLong(QStringView str, int base, bool *ok,
{
CharBuff buff;
if (!numberToCLocale(str, number_options, &buff)) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
@@ -3617,8 +3632,8 @@ double QLocaleData::bytearrayToDouble(const char *num, bool *ok)
int len = static_cast<int>(strlen(num));
Q_ASSERT(len >= 0);
int processed = 0;
- double d = asciiToDouble(num, len, nonNullOk, processed);
- if (ok)
+ double d = qt_asciiToDouble(num, len, nonNullOk, processed);
+ if (ok != nullptr)
*ok = nonNullOk;
return d;
}
@@ -3629,7 +3644,7 @@ qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
const char *endptr;
if (*num == '\0') {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
@@ -3637,19 +3652,24 @@ qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
qlonglong l = qstrtoll(num, &endptr, base, &_ok);
if (!_ok) {
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
if (*endptr != '\0') {
+ while (ascii_isspace(*endptr))
+ ++endptr;
+ }
+
+ if (*endptr != '\0') {
// we stopped at a non-digit character after converting some digits
- if (ok != 0)
+ if (ok != nullptr)
*ok = false;
return 0;
}
- if (ok != 0)
+ if (ok != nullptr)
*ok = true;
return l;
}
@@ -3660,13 +3680,24 @@ qulonglong QLocaleData::bytearrayToUnsLongLong(const char *num, int base, bool *
const char *endptr;
qulonglong l = qstrtoull(num, &endptr, base, &_ok);
- if (!_ok || *endptr != '\0') {
- if (ok != 0)
+ if (!_ok) {
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ if (*endptr != '\0') {
+ while (ascii_isspace(*endptr))
+ ++endptr;
+ }
+
+ if (*endptr != '\0') {
+ if (ok != nullptr)
*ok = false;
return 0;
}
- if (ok != 0)
+ if (ok != nullptr)
*ok = true;
return l;
}
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 681867d14a..f3afb8c406 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -437,19 +437,19 @@ public:
Osage = 358,
Tangut = 359,
- Norwegian = NorwegianBokmal,
- Moldavian = Romanian,
- SerboCroatian = Serbian,
- Tagalog = Filipino,
- Twi = Akan,
Afan = Oromo,
- Byelorussian = Belarusian,
Bhutani = Dzongkha,
+ Byelorussian = Belarusian,
Cambodian = Khmer,
- Kurundi = Rundi,
- RhaetoRomance = Romansh,
Chewa = Nyanja,
Frisian = WesternFrisian,
+ Kurundi = Rundi,
+ Moldavian = Romanian,
+ Norwegian = NorwegianBokmal,
+ RhaetoRomance = Romansh,
+ SerboCroatian = Serbian,
+ Tagalog = Filipino,
+ Twi = Akan,
Uigur = Uighur,
LastLanguage = Tangut
@@ -851,7 +851,7 @@ public:
Serbia = 243,
SaintBarthelemy = 244,
SaintMartin = 245,
- LatinAmericaAndTheCaribbean = 246,
+ LatinAmerica = 246,
AscensionIsland = 247,
AlandIslands = 248,
DiegoGarcia = 249,
@@ -865,17 +865,20 @@ public:
Kosovo = 257,
EuropeanUnion = 258,
OutlyingOceania = 259,
+ World = 260,
+ Europe = 261,
- Tokelau = TokelauCountry,
- Tuvalu = TuvaluCountry,
DemocraticRepublicOfCongo = CongoKinshasa,
- PeoplesRepublicOfCongo = CongoBrazzaville,
DemocraticRepublicOfKorea = NorthKorea,
+ LatinAmericaAndTheCaribbean = LatinAmerica,
+ PeoplesRepublicOfCongo = CongoBrazzaville,
RepublicOfKorea = SouthKorea,
RussianFederation = Russia,
SyrianArabRepublic = Syria,
+ Tokelau = TokelauCountry,
+ Tuvalu = TuvaluCountry,
- LastCountry = OutlyingOceania
+ LastCountry = Europe
};
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index c23e4e3439..5c0a9b63e5 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -92,7 +92,7 @@
\note For the current keyboard input locale take a look at
QInputMethod::locale().
- QLocale's data is based on Common Locale Data Repository v31.0.1.
+ QLocale's data is based on Common Locale Data Repository v33.1.
\sa QString::arg(), QString::toInt(), QString::toDouble(),
QInputMethod::locale()
@@ -568,6 +568,7 @@
\value Estonia
\value Ethiopia
\value EuropeanUnion Since Qt 5.7
+ \value Europe Since Qt 5.12
\value FalklandIslands
\value FaroeIslands
\value Fiji
@@ -619,6 +620,8 @@
\value Kuwait
\value Kyrgyzstan
\value Laos
+ \value LatinAmerica
+ \value LatinAmericaAndTheCaribbean Obsolete, please use LatinAmerica
\value Latvia
\value Lebanon
\value Lesotho
@@ -742,6 +745,7 @@
\value UnitedStatesVirginIslands
\value WallisAndFutunaIslands
\value WesternSahara
+ \value World Since Qt 5.12
\value Yemen
\value Zambia
\value Zimbabwe
@@ -749,7 +753,6 @@
\value Serbia
\value SaintBarthelemy
\value SaintMartin
- \value LatinAmericaAndTheCaribbean
\value AscensionIsland
\value AlandIslands
\value DiegoGarcia
diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h
index cf210454d4..aeeec2b085 100644
--- a/src/corelib/tools/qlocale_data_p.h
+++ b/src/corelib/tools/qlocale_data_p.h
@@ -77,8 +77,8 @@ static const int ImperialMeasurementSystemsCount =
// GENERATED PART STARTS HERE
/*
- This part of the file was generated on 2017-06-07 from the
- Common Locale Data Repository v31.0.1
+ This part of the file was generated on 2018-08-13 from the
+ Common Locale Data Repository v33.1
http://www.unicode.org/cldr/
@@ -171,6 +171,7 @@ static const QLocaleId likely_subtags[] = {
{ 43, 0, 0 }, { 43, 16, 85 }, // el -> el_Grek_GR
{ 31, 0, 0 }, { 31, 7, 225 }, // en -> en_Latn_US
{ 31, 92, 0 }, { 31, 92, 224 }, // en_Shaw -> en_Shaw_GB
+ { 32, 0, 0 }, { 32, 7, 260 }, // eo -> eo_Latn_001
{ 111, 0, 0 }, { 111, 7, 197 }, // es -> es_Latn_ES
{ 33, 0, 0 }, { 33, 7, 68 }, // et -> et_Latn_EE
{ 278, 0, 0 }, { 278, 79, 106 }, // ett -> ett_Ital_IT
@@ -258,6 +259,7 @@ static const QLocaleId likely_subtags[] = {
{ 66, 0, 0 }, { 66, 22, 114 }, // ko -> ko_Kore_KR
{ 147, 0, 0 }, { 147, 13, 100 }, // kok -> kok_Deva_IN
{ 169, 0, 0 }, { 169, 7, 121 }, // kpe -> kpe_Latn_LR
+ { 225, 0, 0 }, { 225, 7, 0 }, // kr -> kr_Latn
{ 62, 0, 0 }, { 62, 1, 100 }, // ks -> ks_Arab_IN
{ 214, 0, 0 }, { 214, 7, 210 }, // ksb -> ksb_Latn_TZ
{ 243, 0, 0 }, { 243, 7, 37 }, // ksf -> ksf_Latn_CM
@@ -363,6 +365,7 @@ static const QLocaleId likely_subtags[] = {
{ 342, 0, 0 }, { 342, 41, 100 }, // pka -> pka_Brah_IN
{ 90, 0, 0 }, { 90, 7, 172 }, // pl -> pl_Latn_PL
{ 300, 0, 0 }, { 300, 64, 163 }, // pra -> pra_Khar_PK
+ { 322, 0, 0 }, { 322, 7, 260 }, // prg -> prg_Latn_001
{ 88, 0, 0 }, { 88, 1, 1 }, // ps -> ps_Arab_AF
{ 91, 0, 0 }, { 91, 7, 30 }, // pt -> pt_Latn_BR
{ 93, 0, 0 }, { 93, 7, 169 }, // qu -> qu_Latn_PE
@@ -460,6 +463,7 @@ static const QLocaleId likely_subtags[] = {
{ 252, 0, 0 }, { 252, 35, 121 }, // vai -> vai_Vaii_LR
{ 160, 0, 0 }, { 160, 7, 195 }, // ve -> ve_Latn_ZA
{ 132, 0, 0 }, { 132, 7, 232 }, // vi -> vi_Latn_VN
+ { 133, 0, 0 }, { 133, 7, 260 }, // vo -> vo_Latn_001
{ 187, 0, 0 }, { 187, 7, 210 }, // vun -> vun_Latn_TZ
{ 236, 0, 0 }, { 236, 7, 21 }, // wa -> wa_Latn_BE
{ 253, 0, 0 }, { 253, 7, 206 }, // wae -> wae_Latn_CH
@@ -477,6 +481,7 @@ static const QLocaleId likely_subtags[] = {
{ 298, 0, 0 }, { 298, 59, 102 }, // xpr -> xpr_Prti_IR
{ 302, 0, 0 }, { 302, 81, 237 }, // xsa -> xsa_Sarb_YE
{ 254, 0, 0 }, { 254, 7, 37 }, // yav -> yav_Latn_CM
+ { 137, 0, 0 }, { 137, 18, 260 }, // yi -> yi_Hebr_001
{ 138, 0, 0 }, { 138, 7, 157 }, // yo -> yo_Latn_NG
{ 357, 0, 0 }, { 357, 6, 97 }, // yue -> yue_Hant_HK
{ 357, 0, 44 }, { 357, 5, 44 }, // yue_CN -> yue_Hans_CN
@@ -504,6 +509,7 @@ static const QLocaleId likely_subtags[] = {
{ 25, 140, 0 }, { 25, 140, 208 }, // zh_Hanb -> zh_Hanb_TW
{ 25, 6, 0 }, { 25, 6, 208 }, // zh_Hant -> zh_Hant_TW
{ 140, 0, 0 }, { 140, 7, 195 }, // zu -> zu_Latn_ZA
+ { 0, 0, 261 }, { 96, 2, 178 }, // und_150 -> ru_Cyrl_RU
{ 0, 0, 246 }, { 111, 7, 246 }, // und_419 -> es_Latn_419
{ 0, 0, 5 }, { 24, 7, 5 }, // und_AD -> ca_Latn_AD
{ 0, 0, 223 }, { 8, 1, 223 }, // und_AE -> ar_Arab_AE
@@ -653,7 +659,7 @@ static const QLocaleId likely_subtags[] = {
{ 0, 0, 164 }, { 350, 7, 164 }, // und_PW -> pau_Latn_PW
{ 0, 0, 168 }, { 45, 7, 168 }, // und_PY -> gn_Latn_PY
{ 0, 0, 175 }, { 8, 1, 175 }, // und_QA -> ar_Arab_QA
- { 0, 0, 259 }, { 31, 7, 31 }, // und_QO -> en_Latn_IO
+ { 0, 0, 259 }, { 31, 7, 249 }, // und_QO -> en_Latn_DG
{ 0, 0, 176 }, { 37, 7, 176 }, // und_RE -> fr_Latn_RE
{ 0, 0, 177 }, { 95, 7, 177 }, // und_RO -> ro_Latn_RO
{ 0, 0, 243 }, { 100, 2, 243 }, // und_RS -> sr_Cyrl_RS
@@ -766,7 +772,6 @@ static const QLocaleId likely_subtags[] = {
{ 0, 56, 0 }, { 280, 56, 170 }, // und_Hano -> hnn_Hano_PH
{ 0, 5, 0 }, { 25, 5, 44 }, // und_Hans -> zh_Hans_CN
{ 0, 6, 0 }, { 25, 6, 208 }, // und_Hant -> zh_Hant_TW
- { 0, 6, 44 }, { 357, 6, 44 }, // und_Hant_CN -> yue_Hant_CN
{ 0, 130, 0 }, { 356, 130, 103 }, // und_Hatr -> mis_Hatr_IQ
{ 0, 18, 0 }, { 48, 18, 105 }, // und_Hebr -> he_Hebr_IL
{ 0, 18, 38 }, { 137, 18, 38 }, // und_Hebr_CA -> yi_Hebr_CA
@@ -896,218 +901,218 @@ static const quint16 locale_index[] = {
6, // Albanian
9, // Amharic
10, // Arabic
- 37, // Armenian
- 38, // Assamese
+ 38, // Armenian
+ 39, // Assamese
0, // Aymara
- 39, // Azerbaijani
- 42, // Bashkir
- 43, // Basque
- 44, // Bengali
- 46, // Dzongkha
+ 40, // Azerbaijani
+ 43, // Bashkir
+ 44, // Basque
+ 45, // Bengali
+ 47, // Dzongkha
0, // Bihari
0, // Bislama
- 47, // Breton
- 48, // Bulgarian
- 49, // Burmese
- 50, // Belarusian
- 51, // Khmer
- 52, // Catalan
- 56, // Chinese
- 63, // Corsican
- 64, // Croatian
- 66, // Czech
- 67, // Danish
- 69, // Dutch
- 76, // English
- 0, // Esperanto
- 179, // Estonian
- 180, // Faroese
+ 48, // Breton
+ 49, // Bulgarian
+ 50, // Burmese
+ 51, // Belarusian
+ 52, // Khmer
+ 53, // Catalan
+ 57, // Chinese
+ 64, // Corsican
+ 65, // Croatian
+ 67, // Czech
+ 68, // Danish
+ 70, // Dutch
+ 77, // English
+ 182, // Esperanto
+ 183, // Estonian
+ 184, // Faroese
0, // Fijian
- 182, // Finnish
- 183, // French
- 229, // Western Frisian
- 230, // Gaelic
- 231, // Galician
- 232, // Georgian
- 233, // German
- 240, // Greek
- 242, // Greenlandic
- 243, // Guarani
- 244, // Gujarati
- 245, // Hausa
- 249, // Hebrew
- 250, // Hindi
- 251, // Hungarian
- 252, // Icelandic
- 253, // Indonesian
- 254, // Interlingua
+ 186, // Finnish
+ 187, // French
+ 233, // Western Frisian
+ 234, // Gaelic
+ 235, // Galician
+ 236, // Georgian
+ 237, // German
+ 244, // Greek
+ 246, // Greenlandic
+ 247, // Guarani
+ 248, // Gujarati
+ 249, // Hausa
+ 253, // Hebrew
+ 254, // Hindi
+ 255, // Hungarian
+ 256, // Icelandic
+ 257, // Indonesian
+ 258, // Interlingua
0, // Interlingue
- 255, // Inuktitut
+ 259, // Inuktitut
0, // Inupiak
- 257, // Irish
- 258, // Italian
- 262, // Japanese
- 263, // Javanese
- 264, // Kannada
- 265, // Kashmiri
- 266, // Kazakh
- 267, // Kinyarwanda
- 268, // Kirghiz
- 269, // Korean
- 271, // Kurdish
- 272, // Rundi
- 273, // Lao
+ 261, // Irish
+ 262, // Italian
+ 266, // Japanese
+ 267, // Javanese
+ 268, // Kannada
+ 269, // Kashmiri
+ 270, // Kazakh
+ 271, // Kinyarwanda
+ 272, // Kirghiz
+ 273, // Korean
+ 275, // Kurdish
+ 276, // Rundi
+ 277, // Lao
0, // Latin
- 274, // Latvian
- 275, // Lingala
- 279, // Lithuanian
- 280, // Macedonian
- 281, // Malagasy
- 282, // Malay
- 286, // Malayalam
- 287, // Maltese
- 288, // Maori
- 289, // Marathi
+ 278, // Latvian
+ 279, // Lingala
+ 283, // Lithuanian
+ 284, // Macedonian
+ 285, // Malagasy
+ 286, // Malay
+ 290, // Malayalam
+ 291, // Maltese
+ 292, // Maori
+ 293, // Marathi
0, // Marshallese
- 290, // Mongolian
+ 294, // Mongolian
0, // Nauru
- 292, // Nepali
- 294, // NorwegianBokmal
- 296, // Occitan
- 297, // Oriya
- 298, // Pashto
- 299, // Persian
- 301, // Polish
- 302, // Portuguese
- 314, // Punjabi
- 316, // Quechua
- 319, // Romansh
- 320, // Romanian
- 322, // Russian
+ 296, // Nepali
+ 298, // Norwegian Bokmal
+ 300, // Occitan
+ 301, // Oriya
+ 302, // Pashto
+ 303, // Persian
+ 305, // Polish
+ 306, // Portuguese
+ 318, // Punjabi
+ 320, // Quechua
+ 323, // Romansh
+ 324, // Romanian
+ 326, // Russian
0, // Samoan
- 328, // Sango
- 329, // Sanskrit
- 330, // Serbian
- 338, // Ossetic
- 340, // Southern Sotho
- 341, // Tswana
- 342, // Shona
- 343, // Sindhi
- 344, // Sinhala
- 345, // Swati
- 346, // Slovak
- 347, // Slovenian
- 348, // Somali
- 352, // Spanish
+ 332, // Sango
+ 333, // Sanskrit
+ 334, // Serbian
+ 342, // Ossetic
+ 344, // Southern Sotho
+ 345, // Tswana
+ 346, // Shona
+ 347, // Sindhi
+ 348, // Sinhala
+ 349, // Swati
+ 350, // Slovak
+ 351, // Slovenian
+ 352, // Somali
+ 356, // Spanish
0, // Sundanese
- 380, // Swahili
- 384, // Swedish
+ 384, // Swahili
+ 388, // Swedish
0, // Sardinian
- 387, // Tajik
- 388, // Tamil
- 392, // Tatar
- 393, // Telugu
- 394, // Thai
- 395, // Tibetan
- 397, // Tigrinya
- 399, // Tongan
- 400, // Tsonga
- 401, // Turkish
- 403, // Turkmen
+ 391, // Tajik
+ 392, // Tamil
+ 396, // Tatar
+ 397, // Telugu
+ 398, // Thai
+ 399, // Tibetan
+ 401, // Tigrinya
+ 403, // Tongan
+ 404, // Tsonga
+ 405, // Turkish
+ 407, // Turkmen
0, // Tahitian
- 404, // Uighur
- 405, // Ukrainian
- 406, // Urdu
- 408, // Uzbek
- 411, // Vietnamese
- 0, // Volapuk
- 412, // Welsh
- 413, // Wolof
- 414, // Xhosa
- 0, // Yiddish
- 415, // Yoruba
+ 408, // Uighur
+ 409, // Ukrainian
+ 410, // Urdu
+ 412, // Uzbek
+ 415, // Vietnamese
+ 416, // Volapuk
+ 417, // Welsh
+ 418, // Wolof
+ 419, // Xhosa
+ 420, // Yiddish
+ 421, // Yoruba
0, // Zhuang
- 417, // Zulu
- 418, // NorwegianNynorsk
- 419, // Bosnian
- 421, // Divehi
- 422, // Manx
- 423, // Cornish
- 424, // Akan
- 425, // Konkani
- 426, // Ga
- 427, // Igbo
- 428, // Kamba
- 429, // Syriac
- 430, // Blin
- 431, // Geez
+ 423, // Zulu
+ 424, // Norwegian Nynorsk
+ 425, // Bosnian
+ 427, // Divehi
+ 428, // Manx
+ 429, // Cornish
+ 430, // Akan
+ 431, // Konkani
+ 432, // Ga
+ 433, // Igbo
+ 434, // Kamba
+ 435, // Syriac
+ 436, // Blin
+ 437, // Geez
0, // Koro
- 432, // Sidamo
- 433, // Atsam
- 434, // Tigre
- 435, // Jju
- 436, // Friulian
- 437, // Venda
- 438, // Ewe
- 440, // Walamo
- 441, // Hawaiian
- 442, // Tyap
- 443, // Nyanja
- 444, // Filipino
- 445, // Swiss German
- 448, // Sichuan Yi
- 449, // Kpelle
- 450, // Low German
- 452, // South Ndebele
- 453, // Northern Sotho
- 454, // Northern Sami
- 457, // Taroko
- 458, // Gusii
- 459, // Taita
- 460, // Fulah
- 464, // Kikuyu
- 465, // Samburu
- 466, // Sena
- 467, // North Ndebele
- 468, // Rombo
- 469, // Tachelhit
- 471, // Kabyle
- 472, // Nyankole
- 473, // Bena
- 474, // Vunjo
- 475, // Bambara
- 477, // Embu
- 478, // Cherokee
- 479, // Morisyen
- 480, // Makonde
- 481, // Langi
- 482, // Ganda
- 483, // Bemba
- 484, // Kabuverdianu
- 485, // Meru
- 486, // Kalenjin
- 487, // Nama
- 488, // Machame
- 489, // Colognian
- 490, // Masai
- 492, // Soga
- 493, // Luyia
- 494, // Asu
- 495, // Teso
- 497, // Saho
- 498, // Koyra Chiini
- 499, // Rwa
- 500, // Luo
- 501, // Chiga
- 502, // Central Morocco Tamazight
- 503, // Koyraboro Senni
- 504, // Shambala
- 505, // Bodo
+ 438, // Sidamo
+ 439, // Atsam
+ 440, // Tigre
+ 441, // Jju
+ 442, // Friulian
+ 443, // Venda
+ 444, // Ewe
+ 446, // Walamo
+ 447, // Hawaiian
+ 448, // Tyap
+ 449, // Nyanja
+ 450, // Filipino
+ 451, // Swiss German
+ 454, // Sichuan Yi
+ 455, // Kpelle
+ 456, // Low German
+ 458, // South Ndebele
+ 459, // Northern Sotho
+ 460, // Northern Sami
+ 463, // Taroko
+ 464, // Gusii
+ 465, // Taita
+ 466, // Fulah
+ 470, // Kikuyu
+ 471, // Samburu
+ 472, // Sena
+ 473, // North Ndebele
+ 474, // Rombo
+ 475, // Tachelhit
+ 477, // Kabyle
+ 478, // Nyankole
+ 479, // Bena
+ 480, // Vunjo
+ 481, // Bambara
+ 483, // Embu
+ 484, // Cherokee
+ 485, // Morisyen
+ 486, // Makonde
+ 487, // Langi
+ 488, // Ganda
+ 489, // Bemba
+ 490, // Kabuverdianu
+ 491, // Meru
+ 492, // Kalenjin
+ 493, // Nama
+ 494, // Machame
+ 495, // Colognian
+ 496, // Masai
+ 498, // Soga
+ 499, // Luyia
+ 500, // Asu
+ 501, // Teso
+ 503, // Saho
+ 504, // Koyra Chiini
+ 505, // Rwa
+ 506, // Luo
+ 507, // Chiga
+ 508, // Central Morocco Tamazight
+ 509, // Koyraboro Senni
+ 510, // Shambala
+ 511, // Bodo
0, // Avaric
0, // Chamorro
- 506, // Chechen
- 507, // Church
- 508, // Chuvash
+ 512, // Chechen
+ 513, // Church
+ 514, // Chuvash
0, // Cree
0, // Haitian
0, // Herero
@@ -1117,59 +1122,59 @@ static const quint16 locale_index[] = {
0, // Kongo
0, // Kwanyama
0, // Limburgish
- 509, // LubaKatanga
- 510, // Luxembourgish
+ 515, // Luba Katanga
+ 516, // Luxembourgish
0, // Navaho
0, // Ndonga
0, // Ojibwa
0, // Pali
- 511, // Walloon
- 512, // Aghem
- 513, // Basaa
- 514, // Zarma
- 515, // Duala
- 516, // JolaFonyi
- 517, // Ewondo
- 518, // Bafia
- 519, // MakhuwaMeetto
- 520, // Mundang
- 521, // Kwasio
- 522, // Nuer
- 523, // Sakha
- 524, // Sangu
+ 517, // Walloon
+ 518, // Aghem
+ 519, // Basaa
+ 520, // Zarma
+ 521, // Duala
+ 522, // Jola Fonyi
+ 523, // Ewondo
+ 524, // Bafia
+ 525, // Makhuwa Meetto
+ 526, // Mundang
+ 527, // Kwasio
+ 528, // Nuer
+ 529, // Sakha
+ 530, // Sangu
0, // Congo Swahili
- 525, // Tasawaq
- 526, // Vai
- 528, // Walser
- 529, // Yangben
+ 531, // Tasawaq
+ 532, // Vai
+ 534, // Walser
+ 535, // Yangben
0, // Avestan
- 530, // Asturian
- 531, // Ngomba
- 532, // Kako
- 533, // Meta
- 534, // Ngiemboon
+ 536, // Asturian
+ 537, // Ngomba
+ 538, // Kako
+ 539, // Meta
+ 540, // Ngiemboon
0, // Aragonese
0, // Akkadian
- 0, // AncientEgyptian
- 0, // AncientGreek
+ 0, // Ancient Egyptian
+ 0, // Ancient Greek
0, // Aramaic
0, // Balinese
0, // Bamun
- 0, // BatakToba
+ 0, // Batak Toba
0, // Buginese
0, // Buhid
0, // Carian
- 535, // Chakma
- 0, // ClassicalMandaic
+ 0, // Chakma
+ 0, // Classical Mandaic
0, // Coptic
0, // Dogri
- 0, // EasternCham
- 0, // EasternKayah
+ 0, // Eastern Cham
+ 0, // Eastern Kayah
0, // Etruscan
0, // Gothic
0, // Hanunoo
0, // Ingush
- 0, // LargeFloweryMiao
+ 0, // Large Flowery Miao
0, // Lepcha
0, // Limbu
0, // Lisu
@@ -1177,17 +1182,17 @@ static const quint16 locale_index[] = {
0, // Lycian
0, // Lydian
0, // Mandingo
- 536, // Manipuri
+ 541, // Manipuri
0, // Meroitic
- 0, // NorthernThai
- 0, // OldIrish
- 0, // OldNorse
- 0, // OldPersian
- 0, // OldTurkish
+ 0, // Northern Thai
+ 0, // Old Irish
+ 0, // Old Norse
+ 0, // Old Persian
+ 0, // Old Turkish
0, // Pahlavi
0, // Parthian
0, // Phoenician
- 0, // PrakritLanguage
+ 0, // Prakrit Language
0, // Rejang
0, // Sabaean
0, // Samaritan
@@ -1196,26 +1201,26 @@ static const quint16 locale_index[] = {
0, // Sora
0, // Sylheti
0, // Tagbanwa
- 537, // TaiDam
- 0, // TaiNua
+ 542, // Tai Dam
+ 0, // Tai Nua
0, // Ugaritic
- 538, // Akoose
- 539, // Lakota
- 540, // Standard Moroccan Tamazight
- 541, // Mapuche
- 542, // Central Kurdish
- 544, // LowerSorbian
- 545, // UpperSorbian
- 546, // Kenyang
- 547, // Mohawk
- 548, // Nko
- 0, // Prussian
- 549, // Kiche
- 550, // Southern Sami
- 551, // Lule Sami
- 552, // Inari Sami
- 553, // Skolt Sami
- 554, // Warlpiri
+ 543, // Akoose
+ 544, // Lakota
+ 545, // Standard Moroccan Tamazight
+ 546, // Mapuche
+ 547, // Central Kurdish
+ 549, // Lower Sorbian
+ 550, // Upper Sorbian
+ 551, // Kenyang
+ 552, // Mohawk
+ 553, // Nko
+ 554, // Prussian
+ 555, // Kiche
+ 556, // Southern Sami
+ 557, // Lule Sami
+ 558, // Inari Sami
+ 559, // Skolt Sami
+ 560, // Warlpiri
0, // Manichaean Middle Persian
0, // Mende
0, // Ancient North Arabian
@@ -1233,18 +1238,18 @@ static const quint16 locale_index[] = {
0, // Bhojpuri
0, // Hieroglyphic Luwian
0, // Literary Chinese
- 555, // Mazanderani
+ 561, // Mazanderani
0, // Mru
0, // Newari
- 556, // Northern Luri
+ 562, // Northern Luri
0, // Palauan
0, // Papiamento
0, // Saraiki
0, // Tokelau
0, // Tok Pisin
0, // Tuvalu
- 0, // UncodedLanguages
- 558, // Cantonese
+ 0, // Uncoded Languages
+ 564, // Cantonese
0, // Osage
0, // Tangut
0 // trailing 0
@@ -1256,561 +1261,568 @@ static const QLocaleData locale_data[] = {
{ 3, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 35,18 , 18,7 , 25,12 , 185,48 , 233,111 , 134,24 , 185,48 , 233,111 , 134,24 , 113,28 , 141,55 , 85,14 , 113,28 , 141,55 , 85,14 , 2,2 , 2,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 7,24 , 4,4 , 4,0 , 0,6 , 6,10 , 2, 1, 7, 6, 7 }, // Oromo/Latin/Ethiopia
{ 3, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 35,18 , 37,5 , 8,10 , 185,48 , 233,111 , 344,24 , 185,48 , 233,111 , 134,24 , 113,28 , 141,55 , 196,14 , 113,28 , 141,55 , 196,14 , 2,2 , 2,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 0,6 , 16,8 , 2, 1, 7, 6, 7 }, // Oromo/Latin/Kenya
{ 4, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Afar/Latin/Ethiopia
- { 5, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 53,10 , 80,18 , 37,5 , 8,10 , 416,59 , 475,92 , 134,24 , 416,59 , 475,92 , 134,24 , 210,28 , 238,58 , 296,14 , 210,28 , 238,58 , 296,14 , 4,3 , 4,3 , 49,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 31,67 , 4,4 , 4,0 , 24,9 , 33,11 , 2, 1, 7, 6, 7 }, // Afrikaans/Latin/SouthAfrica
+ { 5, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 53,10 , 80,18 , 37,5 , 8,10 , 416,59 , 475,92 , 134,24 , 416,59 , 475,92 , 134,24 , 210,28 , 238,58 , 296,14 , 210,28 , 238,58 , 296,14 , 4,3 , 4,3 , 49,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 31,67 , 4,4 , 4,0 , 24,9 , 33,11 , 2, 1, 7, 6, 7 }, // Afrikaans/Latin/South Africa
{ 5, 7, 148, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 53,10 , 98,16 , 37,5 , 8,10 , 416,59 , 475,92 , 134,24 , 416,59 , 475,92 , 134,24 , 210,28 , 238,58 , 296,14 , 210,28 , 238,58 , 296,14 , 4,3 , 4,3 , 49,5 , 5,17 , 22,23 , {78,65,68}, 6,1 , 98,55 , 4,4 , 4,0 , 24,9 , 44,7 , 2, 1, 1, 6, 7 }, // Afrikaans/Latin/Namibia
- { 6, 7, 2, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 18,7 , 42,13 , 567,48 , 615,78 , 693,24 , 717,48 , 765,78 , 843,24 , 310,28 , 338,58 , 396,14 , 310,28 , 410,58 , 396,14 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {65,76,76}, 7,4 , 153,45 , 13,5 , 4,0 , 51,5 , 56,8 , 0, 0, 1, 6, 7 }, // Albanian/Latin/Albania
- { 6, 7, 127, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 37,5 , 8,10 , 567,48 , 615,78 , 693,24 , 717,48 , 765,78 , 843,24 , 310,28 , 338,58 , 396,14 , 310,28 , 410,58 , 396,14 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {77,75,68}, 11,3 , 198,54 , 13,5 , 4,0 , 51,5 , 64,8 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Macedonia
- { 6, 7, 257, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 37,5 , 8,10 , 567,48 , 615,78 , 693,24 , 717,48 , 765,78 , 843,24 , 310,28 , 338,58 , 396,14 , 310,28 , 410,58 , 396,14 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 252,21 , 13,5 , 4,0 , 51,5 , 72,6 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Kosovo
- { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 23,6 , 23,6 , 29,9 , 38,8 , 120,10 , 130,17 , 18,7 , 25,12 , 867,46 , 913,61 , 974,24 , 867,46 , 913,61 , 974,24 , 468,27 , 495,28 , 523,14 , 468,27 , 495,28 , 523,14 , 18,3 , 17,4 , 58,3 , 61,23 , 22,23 , {69,84,66}, 15,2 , 273,34 , 4,4 , 4,0 , 78,4 , 82,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia
- { 8, 1, 64, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {69,71,80}, 17,5 , 307,81 , 13,5 , 4,0 , 87,7 , 94,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt
- { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 1097,71 , 1097,71 , 1168,24 , 1097,71 , 1097,71 , 1168,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {68,90,68}, 22,5 , 388,102 , 13,5 , 4,0 , 87,7 , 97,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Algeria
- { 8, 1, 17, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {66,72,68}, 27,5 , 490,91 , 13,5 , 4,0 , 87,7 , 104,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain
- { 8, 1, 42, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {88,65,70}, 32,4 , 581,112 , 13,5 , 4,0 , 87,7 , 111,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad
- { 8, 1, 48, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 37,5 , 8,10 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {75,77,70}, 36,7 , 693,105 , 13,5 , 4,0 , 87,7 , 115,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros
- { 8, 1, 59, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {68,74,70}, 43,3 , 798,84 , 13,5 , 4,0 , 87,7 , 124,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti
- { 8, 1, 67, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {69,82,78}, 46,3 , 882,91 , 13,5 , 4,0 , 87,7 , 130,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea
- { 8, 1, 103, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 1192,92 , 1192,92 , 1284,24 , 1308,92 , 1192,92 , 1284,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,81,68}, 49,5 , 973,84 , 13,5 , 4,0 , 87,7 , 137,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq
- { 8, 1, 105, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 55,4 , 59,9 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,76,83}, 54,1 , 1057,133 , 13,5 , 4,0 , 87,7 , 143,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel
- { 8, 1, 109, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 1192,92 , 1192,92 , 1284,24 , 1192,92 , 1192,92 , 1284,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {74,79,68}, 55,5 , 1190,84 , 13,5 , 4,0 , 87,7 , 150,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan
- { 8, 1, 115, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {75,87,68}, 60,5 , 1274,84 , 13,5 , 4,0 , 87,7 , 156,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait
- { 8, 1, 119, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 1192,92 , 1192,92 , 1284,24 , 1192,92 , 1192,92 , 1284,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {76,66,80}, 65,5 , 1358,84 , 13,5 , 4,0 , 87,7 , 162,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon
- { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {76,89,68}, 70,5 , 1442,88 , 13,5 , 4,0 , 87,7 , 167,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya
- { 8, 1, 136, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 1400,72 , 1400,72 , 1472,24 , 1400,72 , 1400,72 , 1472,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,82,79}, 75,5 , 1530,112 , 13,5 , 4,0 , 87,7 , 172,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Mauritania
- { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 37,5 , 8,10 , 1496,70 , 1496,70 , 1566,24 , 1496,70 , 1496,70 , 1566,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,65,68}, 80,5 , 1642,87 , 13,5 , 4,0 , 87,7 , 181,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco
- { 8, 1, 162, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {79,77,82}, 85,5 , 1729,77 , 13,5 , 4,0 , 87,7 , 187,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Oman
- { 8, 1, 165, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 1192,92 , 1192,92 , 1284,24 , 1192,92 , 1192,92 , 1284,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,76,83}, 54,1 , 1057,133 , 13,5 , 4,0 , 87,7 , 192,18 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/PalestinianTerritories
- { 8, 1, 175, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {81,65,82}, 90,5 , 1806,70 , 13,5 , 4,0 , 87,7 , 210,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar
- { 8, 1, 186, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,65,82}, 95,5 , 1876,77 , 13,5 , 4,0 , 87,7 , 213,24 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/SaudiArabia
- { 8, 1, 194, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,79,83}, 100,1 , 1953,77 , 13,5 , 4,0 , 87,7 , 237,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia
- { 8, 1, 201, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,68,71}, 101,4 , 2030,91 , 13,5 , 4,0 , 87,7 , 244,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan
- { 8, 1, 207, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 1192,92 , 1192,92 , 1284,24 , 1192,92 , 1192,92 , 1284,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,89,80}, 105,5 , 2121,77 , 13,5 , 4,0 , 87,7 , 251,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria
- { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 1097,71 , 1097,71 , 1168,24 , 1097,71 , 1097,71 , 1168,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {84,78,68}, 110,5 , 2198,95 , 13,5 , 4,0 , 87,7 , 256,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia
- { 8, 1, 223, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {65,69,68}, 115,5 , 2293,91 , 13,5 , 4,0 , 87,7 , 260,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/UnitedArabEmirates
- { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,65,68}, 80,5 , 1642,87 , 13,5 , 4,0 , 87,7 , 284,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/WesternSahara
- { 8, 1, 237, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {89,69,82}, 120,5 , 2384,70 , 13,5 , 4,0 , 87,7 , 299,5 , 0, 0, 7, 5, 6 }, // Arabic/Arabic/Yemen
- { 8, 1, 254, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,18 , 18,7 , 25,12 , 998,75 , 998,75 , 1073,24 , 998,75 , 998,75 , 1073,24 , 537,52 , 537,52 , 589,14 , 537,52 , 537,52 , 589,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,83,80}, 125,1 , 2454,132 , 13,5 , 4,0 , 87,7 , 304,12 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/SouthSudan
- { 9, 10, 11, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 65,7 , 65,7 , 175,8 , 183,20 , 37,5 , 8,10 , 1590,48 , 1638,94 , 1732,24 , 1590,48 , 1756,106 , 1732,24 , 603,28 , 631,62 , 693,14 , 603,28 , 631,62 , 693,14 , 0,2 , 0,2 , 129,6 , 135,17 , 22,23 , {65,77,68}, 126,1 , 2586,46 , 8,5 , 4,0 , 316,7 , 323,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia
- { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 203,8 , 211,18 , 68,8 , 76,12 , 1862,62 , 1924,88 , 158,27 , 1862,62 , 1924,88 , 158,27 , 707,37 , 744,58 , 85,14 , 707,37 , 744,58 , 85,14 , 22,9 , 22,7 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 0,7 , 8,5 , 4,0 , 331,7 , 338,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India
- { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 72,8 , 72,8 , 175,8 , 229,17 , 37,5 , 8,10 , 2012,48 , 2060,77 , 158,27 , 2012,48 , 2137,77 , 158,27 , 802,27 , 829,67 , 99,14 , 802,27 , 829,67 , 99,14 , 0,2 , 0,2 , 152,4 , 5,17 , 22,23 , {65,90,78}, 128,1 , 2632,58 , 8,5 , 4,0 , 342,10 , 352,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan
+ { 6, 7, 2, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 18,7 , 42,13 , 567,50 , 617,78 , 695,27 , 722,50 , 772,78 , 850,27 , 310,28 , 338,58 , 396,15 , 310,28 , 411,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {65,76,76}, 7,4 , 153,45 , 13,5 , 4,0 , 51,5 , 56,8 , 0, 0, 1, 6, 7 }, // Albanian/Latin/Albania
+ { 6, 7, 127, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 37,5 , 8,10 , 567,50 , 617,78 , 695,27 , 722,50 , 772,78 , 850,27 , 310,28 , 338,58 , 396,15 , 310,28 , 411,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {77,75,68}, 11,3 , 198,54 , 13,5 , 4,0 , 51,5 , 64,8 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Macedonia
+ { 6, 7, 257, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 37,5 , 8,10 , 567,50 , 617,78 , 695,27 , 722,50 , 772,78 , 850,27 , 310,28 , 338,58 , 396,15 , 310,28 , 411,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 252,21 , 13,5 , 4,0 , 51,5 , 72,6 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Kosovo
+ { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 23,6 , 23,6 , 29,9 , 38,8 , 120,10 , 130,17 , 18,7 , 25,12 , 877,46 , 923,61 , 984,24 , 877,46 , 923,61 , 984,24 , 469,27 , 496,28 , 524,14 , 469,27 , 496,28 , 524,14 , 18,3 , 17,4 , 58,3 , 61,23 , 22,23 , {69,84,66}, 15,2 , 273,34 , 4,4 , 4,0 , 78,4 , 82,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia
+ { 8, 1, 64, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {69,71,80}, 17,5 , 307,81 , 13,5 , 4,0 , 87,7 , 94,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt
+ { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1107,71 , 1107,71 , 1178,24 , 1107,71 , 1107,71 , 1178,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {68,90,68}, 22,5 , 388,102 , 13,5 , 4,0 , 87,7 , 97,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Algeria
+ { 8, 1, 17, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {66,72,68}, 27,5 , 490,91 , 13,5 , 4,0 , 87,7 , 104,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain
+ { 8, 1, 42, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {88,65,70}, 32,4 , 581,112 , 13,5 , 4,0 , 87,7 , 111,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad
+ { 8, 1, 48, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 37,5 , 8,10 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {75,77,70}, 36,2 , 693,105 , 13,5 , 4,0 , 87,7 , 115,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros
+ { 8, 1, 59, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {68,74,70}, 38,3 , 798,84 , 13,5 , 4,0 , 87,7 , 124,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti
+ { 8, 1, 67, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {69,82,78}, 41,3 , 882,91 , 13,5 , 4,0 , 87,7 , 130,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea
+ { 8, 1, 103, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1318,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,81,68}, 44,5 , 973,84 , 13,5 , 4,0 , 87,7 , 137,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq
+ { 8, 1, 105, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 55,4 , 59,9 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,76,83}, 49,1 , 1057,133 , 13,5 , 4,0 , 87,7 , 143,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel
+ { 8, 1, 109, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1202,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {74,79,68}, 50,5 , 1190,84 , 13,5 , 4,0 , 87,7 , 150,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan
+ { 8, 1, 115, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {75,87,68}, 55,5 , 1274,84 , 13,5 , 4,0 , 87,7 , 156,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait
+ { 8, 1, 119, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1202,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {76,66,80}, 60,5 , 1358,84 , 13,5 , 4,0 , 87,7 , 162,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon
+ { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {76,89,68}, 65,5 , 1442,88 , 13,5 , 4,0 , 87,7 , 167,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya
+ { 8, 1, 136, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1410,72 , 1410,72 , 1482,24 , 1410,72 , 1410,72 , 1482,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,82,85}, 0,0 , 1530,112 , 13,5 , 4,0 , 87,7 , 172,9 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Mauritania
+ { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 37,5 , 8,10 , 1506,70 , 1506,70 , 1576,24 , 1506,70 , 1506,70 , 1576,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,65,68}, 70,5 , 1642,87 , 13,5 , 4,0 , 87,7 , 181,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco
+ { 8, 1, 162, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {79,77,82}, 75,5 , 1729,77 , 13,5 , 4,0 , 87,7 , 187,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Oman
+ { 8, 1, 165, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1202,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,76,83}, 49,1 , 1057,133 , 13,5 , 4,0 , 87,7 , 192,18 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Palestinian Territories
+ { 8, 1, 175, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {81,65,82}, 80,5 , 1806,70 , 13,5 , 4,0 , 87,7 , 210,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar
+ { 8, 1, 186, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,65,82}, 85,5 , 1876,77 , 13,5 , 4,0 , 87,7 , 213,24 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Saudi Arabia
+ { 8, 1, 194, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,79,83}, 90,1 , 1953,77 , 13,5 , 4,0 , 87,7 , 237,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia
+ { 8, 1, 201, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,68,71}, 91,4 , 2030,91 , 13,5 , 4,0 , 87,7 , 244,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan
+ { 8, 1, 207, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1202,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,89,80}, 95,5 , 2121,77 , 13,5 , 4,0 , 87,7 , 251,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria
+ { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1107,71 , 1107,71 , 1178,24 , 1107,71 , 1107,71 , 1178,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {84,78,68}, 100,5 , 2198,95 , 13,5 , 4,0 , 87,7 , 256,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia
+ { 8, 1, 223, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {65,69,68}, 105,5 , 2293,91 , 13,5 , 4,0 , 87,7 , 260,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/United Arab Emirates
+ { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,65,68}, 70,5 , 1642,87 , 13,5 , 4,0 , 87,7 , 284,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Western Sahara
+ { 8, 1, 237, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {89,69,82}, 110,5 , 2384,70 , 13,5 , 4,0 , 87,7 , 299,5 , 0, 0, 7, 5, 6 }, // Arabic/Arabic/Yemen
+ { 8, 1, 254, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,83,80}, 115,1 , 2454,132 , 13,5 , 4,0 , 87,7 , 304,12 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/South Sudan
+ { 8, 1, 260, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 316,23 , 339,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/World
+ { 9, 10, 11, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 65,7 , 65,7 , 174,8 , 182,20 , 37,5 , 8,10 , 1600,48 , 1648,94 , 1742,24 , 1600,48 , 1766,106 , 1742,24 , 604,28 , 632,62 , 694,14 , 604,28 , 632,62 , 694,14 , 22,2 , 22,2 , 129,6 , 135,17 , 22,23 , {65,77,68}, 116,1 , 2586,46 , 13,5 , 4,0 , 345,7 , 352,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia
+ { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 72,9 , 72,9 , 202,8 , 210,18 , 68,7 , 75,12 , 1872,64 , 1936,89 , 2025,24 , 1872,64 , 1936,89 , 2025,24 , 708,32 , 740,58 , 798,14 , 708,32 , 740,58 , 798,14 , 24,9 , 24,7 , 152,4 , 156,37 , 22,23 , {73,78,82}, 117,1 , 2632,43 , 8,5 , 4,0 , 360,7 , 367,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India
+ { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 81,8 , 81,8 , 174,8 , 228,17 , 37,5 , 8,10 , 2049,48 , 2097,77 , 158,27 , 2049,48 , 2174,77 , 158,27 , 812,27 , 839,67 , 99,14 , 812,27 , 839,67 , 99,14 , 0,2 , 0,2 , 193,4 , 5,17 , 22,23 , {65,90,78}, 118,1 , 2675,58 , 8,5 , 4,0 , 371,10 , 381,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan
{ 12, 1, 102, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 6, 5, 5 }, // Azerbaijani/Arabic/Iran
- { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 175,8 , 229,17 , 37,5 , 8,10 , 2214,48 , 2262,77 , 158,27 , 2214,48 , 2339,77 , 158,27 , 896,27 , 923,67 , 99,14 , 896,27 , 923,67 , 99,14 , 31,2 , 29,2 , 45,4 , 5,17 , 22,23 , {65,90,78}, 128,1 , 2690,12 , 8,5 , 4,0 , 362,10 , 372,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan
- { 13, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 129,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Bashkir/Cyrillic/Russia
- { 14, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8220, 8221, 0,6 , 0,6 , 80,9 , 80,9 , 246,6 , 252,26 , 37,5 , 88,12 , 2416,60 , 2476,93 , 2569,24 , 2416,60 , 2593,93 , 2569,24 , 990,28 , 1018,68 , 1086,14 , 990,28 , 1100,68 , 1086,14 , 0,2 , 0,2 , 156,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 2702,20 , 13,5 , 4,0 , 382,7 , 389,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain
- { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 89,9 , 89,9 , 278,6 , 211,18 , 18,7 , 25,12 , 2686,90 , 2686,90 , 2776,33 , 2809,77 , 2686,90 , 2776,33 , 1168,37 , 1205,58 , 1263,18 , 1168,37 , 1281,58 , 1263,18 , 0,2 , 0,2 , 163,4 , 5,17 , 22,23 , {66,68,84}, 130,1 , 2722,49 , 0,4 , 4,0 , 397,5 , 402,8 , 2, 1, 5, 6, 7 }, // Bengali/Bengali/Bangladesh
- { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 89,9 , 89,9 , 278,6 , 211,18 , 18,7 , 25,12 , 2686,90 , 2686,90 , 2776,33 , 2809,77 , 2686,90 , 2776,33 , 1168,37 , 1205,58 , 1263,18 , 1168,37 , 1281,58 , 1263,18 , 0,2 , 0,2 , 163,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 2771,43 , 0,4 , 4,0 , 397,5 , 410,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India
- { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 98,9 , 98,9 , 98,9 , 98,9 , 53,10 , 284,30 , 100,22 , 122,27 , 2886,63 , 2949,191 , 3140,27 , 3167,27 , 3194,132 , 3326,27 , 1339,34 , 1373,79 , 1452,27 , 1339,34 , 1373,79 , 1452,27 , 33,5 , 31,6 , 45,4 , 5,17 , 22,23 , {66,84,78}, 131,3 , 2814,15 , 4,4 , 4,0 , 414,6 , 420,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan
- { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 3353,63 , 3416,78 , 3494,36 , 3530,63 , 3416,78 , 3494,36 , 1479,33 , 1512,43 , 1555,18 , 1479,33 , 1512,43 , 1555,18 , 38,4 , 37,4 , 167,7 , 174,17 , 191,23 , {69,85,82}, 14,1 , 2829,36 , 13,5 , 4,0 , 425,9 , 434,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France
- { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 107,7 , 107,7 , 314,12 , 326,22 , 55,4 , 59,9 , 3593,49 , 3642,82 , 3724,24 , 3593,49 , 3642,82 , 3724,24 , 1573,21 , 1594,55 , 1649,14 , 1573,21 , 1594,55 , 1649,14 , 42,6 , 41,6 , 214,7 , 5,17 , 22,23 , {66,71,78}, 134,3 , 2865,47 , 13,5 , 4,0 , 439,9 , 448,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria
- { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 114,5 , 114,5 , 119,10 , 119,10 , 348,8 , 98,16 , 37,5 , 149,10 , 3748,43 , 3791,88 , 3879,24 , 3748,43 , 3791,88 , 3879,24 , 1663,54 , 1663,54 , 1717,14 , 1663,54 , 1663,54 , 1717,14 , 48,5 , 47,3 , 221,5 , 5,17 , 22,23 , {77,77,75}, 137,1 , 2912,27 , 13,5 , 4,0 , 456,6 , 456,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar
- { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 129,7 , 129,7 , 356,7 , 326,22 , 37,5 , 159,11 , 3903,48 , 3951,95 , 4046,24 , 4070,48 , 4118,98 , 4046,24 , 1731,21 , 1752,56 , 1808,14 , 1731,21 , 1752,56 , 1808,14 , 0,2 , 0,2 , 226,5 , 231,17 , 22,23 , {66,89,78}, 0,2 , 2939,89 , 13,5 , 4,0 , 462,10 , 472,8 , 2, 0, 1, 6, 7 }, // Belarusian/Cyrillic/Belarus
- { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 136,9 , 145,9 , 278,6 , 98,16 , 18,7 , 25,12 , 4216,71 , 4216,71 , 4287,24 , 4216,71 , 4216,71 , 4287,24 , 1822,47 , 1822,47 , 1869,14 , 1822,47 , 1822,47 , 1869,14 , 0,2 , 0,2 , 248,2 , 5,17 , 22,23 , {75,72,82}, 138,1 , 3028,29 , 0,4 , 4,0 , 480,5 , 485,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia
- { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 154,7 , 154,7 , 278,6 , 363,22 , 55,4 , 59,9 , 4311,60 , 4371,82 , 4453,36 , 4489,93 , 4582,115 , 4453,36 , 1883,28 , 1911,60 , 1971,21 , 1883,28 , 1911,60 , 1971,21 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 492,6 , 498,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain
- { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 154,7 , 154,7 , 278,6 , 363,22 , 55,4 , 59,9 , 4311,60 , 4371,82 , 4453,36 , 4489,93 , 4582,115 , 4453,36 , 1883,28 , 1911,60 , 1971,21 , 1883,28 , 1911,60 , 1971,21 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 492,6 , 505,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra
- { 24, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 154,7 , 154,7 , 278,6 , 363,22 , 55,4 , 59,9 , 4311,60 , 4371,82 , 4453,36 , 4489,93 , 4582,115 , 4453,36 , 1883,28 , 1911,60 , 1971,21 , 1883,28 , 1911,60 , 1971,21 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 492,6 , 512,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/France
- { 24, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 154,7 , 154,7 , 278,6 , 363,22 , 55,4 , 59,9 , 4311,60 , 4371,82 , 4453,36 , 4489,93 , 4582,115 , 4453,36 , 1883,28 , 1911,60 , 1971,21 , 1883,28 , 1911,60 , 1971,21 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 492,6 , 518,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Italy
- { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 161,5 , 161,5 , 166,5 , 166,5 , 385,8 , 393,13 , 170,6 , 176,11 , 4697,39 , 4736,38 , 158,27 , 4697,39 , 4736,38 , 158,27 , 1992,21 , 2013,28 , 2041,14 , 1992,21 , 2013,28 , 2041,14 , 58,2 , 55,2 , 250,2 , 252,21 , 22,23 , {67,78,89}, 139,1 , 3077,13 , 4,4 , 4,0 , 524,4 , 528,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China
- { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 161,5 , 161,5 , 166,5 , 166,5 , 278,6 , 393,13 , 170,6 , 176,11 , 4697,39 , 4736,38 , 158,27 , 4697,39 , 4736,38 , 158,27 , 1992,21 , 2013,28 , 2041,14 , 1992,21 , 2013,28 , 2041,14 , 58,2 , 55,2 , 250,2 , 252,21 , 22,23 , {72,75,68}, 140,3 , 3090,11 , 4,4 , 4,0 , 524,4 , 530,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/HongKong
- { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 161,5 , 161,5 , 166,5 , 166,5 , 278,6 , 393,13 , 170,6 , 176,11 , 4697,39 , 4736,38 , 158,27 , 4697,39 , 4736,38 , 158,27 , 1992,21 , 2013,28 , 2041,14 , 1992,21 , 2013,28 , 2041,14 , 58,2 , 55,2 , 250,2 , 252,21 , 22,23 , {77,79,80}, 143,4 , 3101,13 , 4,4 , 4,0 , 524,4 , 539,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau
- { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 161,5 , 161,5 , 166,5 , 166,5 , 27,8 , 393,13 , 170,6 , 176,11 , 4697,39 , 4736,38 , 158,27 , 4697,39 , 4736,38 , 158,27 , 1992,21 , 2013,28 , 2041,14 , 1992,21 , 2013,28 , 2041,14 , 58,2 , 55,2 , 250,2 , 252,21 , 22,23 , {83,71,68}, 6,1 , 3114,15 , 4,4 , 4,0 , 524,4 , 548,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore
- { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 161,5 , 161,5 , 171,5 , 171,5 , 406,8 , 393,13 , 170,6 , 187,13 , 4697,39 , 4697,39 , 158,27 , 4697,39 , 4697,39 , 158,27 , 2055,21 , 2013,28 , 2041,14 , 2055,21 , 2013,28 , 2041,14 , 58,2 , 55,2 , 273,3 , 5,17 , 22,23 , {72,75,68}, 140,3 , 3090,11 , 18,5 , 4,0 , 551,4 , 555,9 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/HongKong
- { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 161,5 , 161,5 , 171,5 , 171,5 , 406,8 , 393,13 , 170,6 , 187,13 , 4697,39 , 4697,39 , 158,27 , 4697,39 , 4697,39 , 158,27 , 2055,21 , 2013,28 , 2041,14 , 2055,21 , 2013,28 , 2041,14 , 58,2 , 55,2 , 273,3 , 5,17 , 22,23 , {77,79,80}, 143,4 , 3129,13 , 18,5 , 4,0 , 551,4 , 564,9 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau
- { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 161,5 , 161,5 , 166,5 , 166,5 , 385,8 , 414,14 , 170,6 , 187,13 , 4697,39 , 4697,39 , 158,27 , 4697,39 , 4697,39 , 158,27 , 2055,21 , 2013,28 , 2041,14 , 2055,21 , 2013,28 , 2041,14 , 58,2 , 55,2 , 45,4 , 5,17 , 22,23 , {84,87,68}, 6,1 , 3142,13 , 4,4 , 4,0 , 551,4 , 573,2 , 2, 0, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan
+ { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 174,8 , 228,17 , 37,5 , 8,10 , 2251,48 , 2299,77 , 158,27 , 2251,48 , 2376,77 , 158,27 , 906,27 , 933,67 , 99,14 , 906,27 , 933,67 , 99,14 , 33,2 , 31,2 , 45,4 , 5,17 , 22,23 , {65,90,78}, 118,1 , 2733,12 , 8,5 , 4,0 , 391,10 , 401,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan
+ { 13, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Bashkir/Cyrillic/Russia
+ { 14, 7, 197, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8220, 8221, 0,6 , 0,6 , 89,9 , 89,9 , 245,6 , 251,36 , 37,5 , 87,12 , 2453,60 , 2513,93 , 2606,24 , 2453,60 , 2630,93 , 2606,24 , 1000,28 , 1028,68 , 1096,14 , 1000,28 , 1110,68 , 1096,14 , 0,2 , 0,2 , 197,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 2745,20 , 13,5 , 4,0 , 411,7 , 418,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain
+ { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 98,9 , 98,9 , 287,6 , 210,18 , 18,7 , 25,12 , 2723,90 , 2723,90 , 2813,33 , 2846,77 , 2723,90 , 2813,33 , 1178,37 , 1215,58 , 1273,18 , 1178,37 , 1291,58 , 1273,18 , 0,2 , 0,2 , 152,4 , 5,17 , 22,23 , {66,68,84}, 120,1 , 2765,49 , 0,4 , 4,0 , 426,5 , 431,8 , 2, 1, 7, 6, 7 }, // Bengali/Bengali/Bangladesh
+ { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 98,9 , 98,9 , 287,6 , 210,18 , 18,7 , 25,12 , 2723,90 , 2723,90 , 2813,33 , 2846,77 , 2723,90 , 2813,33 , 1178,37 , 1215,58 , 1273,18 , 1178,37 , 1291,58 , 1273,18 , 0,2 , 0,2 , 152,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 2814,43 , 0,4 , 4,0 , 426,5 , 439,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India
+ { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 107,9 , 107,9 , 107,9 , 107,9 , 53,10 , 293,30 , 99,22 , 121,27 , 2923,63 , 2986,191 , 3177,27 , 3204,27 , 3231,132 , 3363,27 , 1349,34 , 1383,79 , 1462,27 , 1349,34 , 1383,79 , 1462,27 , 35,5 , 33,6 , 45,4 , 5,17 , 22,23 , {66,84,78}, 121,3 , 2857,15 , 4,4 , 4,0 , 443,6 , 449,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan
+ { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 98,16 , 37,5 , 8,10 , 3390,63 , 3453,78 , 3531,36 , 3390,63 , 3453,78 , 3531,36 , 1489,33 , 1522,43 , 1565,18 , 1489,33 , 1522,43 , 1565,18 , 40,4 , 39,4 , 204,7 , 211,17 , 228,23 , {69,85,82}, 14,1 , 2872,36 , 13,5 , 4,0 , 454,9 , 463,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France
+ { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 323,12 , 335,22 , 148,9 , 157,14 , 3567,49 , 3616,82 , 3698,24 , 3567,49 , 3616,82 , 3698,24 , 1583,21 , 1604,55 , 1659,14 , 1583,21 , 1604,55 , 1659,14 , 44,6 , 43,6 , 251,7 , 5,17 , 22,23 , {66,71,78}, 124,3 , 2908,47 , 13,5 , 4,0 , 468,9 , 477,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria
+ { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 123,5 , 123,5 , 128,10 , 128,10 , 357,8 , 365,18 , 171,6 , 177,10 , 3722,43 , 3765,88 , 3853,24 , 3722,43 , 3765,88 , 3853,24 , 1673,54 , 1673,54 , 1727,14 , 1673,54 , 1673,54 , 1727,14 , 50,5 , 49,3 , 258,5 , 5,17 , 22,23 , {77,77,75}, 127,1 , 2955,29 , 13,5 , 4,0 , 485,6 , 485,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar
+ { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 138,7 , 138,7 , 383,7 , 335,22 , 37,5 , 187,11 , 3877,48 , 3925,95 , 4020,24 , 4044,48 , 4092,98 , 4020,24 , 1741,21 , 1762,56 , 1818,14 , 1741,21 , 1762,56 , 1818,14 , 0,2 , 0,2 , 263,5 , 268,17 , 22,23 , {66,89,78}, 0,2 , 2984,89 , 13,5 , 4,0 , 491,10 , 501,8 , 2, 0, 1, 6, 7 }, // Belarusian/Cyrillic/Belarus
+ { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 145,9 , 154,9 , 287,6 , 98,16 , 18,7 , 25,12 , 4190,71 , 4190,71 , 4261,24 , 4190,71 , 4190,71 , 4261,24 , 1832,47 , 1832,47 , 1879,14 , 1832,47 , 1832,47 , 1879,14 , 0,2 , 0,2 , 285,2 , 5,17 , 22,23 , {75,72,82}, 128,1 , 3073,29 , 0,4 , 4,0 , 509,5 , 514,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia
+ { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 287,6 , 390,22 , 55,4 , 59,9 , 4285,60 , 4345,82 , 4427,36 , 4463,93 , 4556,115 , 4427,36 , 1893,28 , 1921,60 , 1981,21 , 1893,28 , 1921,60 , 1981,21 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 527,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain
+ { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 287,6 , 390,22 , 55,4 , 59,9 , 4285,60 , 4345,82 , 4427,36 , 4463,93 , 4556,115 , 4427,36 , 1893,28 , 1921,60 , 1981,21 , 1893,28 , 1921,60 , 1981,21 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 534,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra
+ { 24, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 287,6 , 390,22 , 55,4 , 59,9 , 4285,60 , 4345,82 , 4427,36 , 4463,93 , 4556,115 , 4427,36 , 1893,28 , 1921,60 , 1981,21 , 1893,28 , 1921,60 , 1981,21 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 541,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/France
+ { 24, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 287,6 , 390,22 , 55,4 , 59,9 , 4285,60 , 4345,82 , 4427,36 , 4463,93 , 4556,115 , 4427,36 , 1893,28 , 1921,60 , 1981,21 , 1893,28 , 1921,60 , 1981,21 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 547,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Italy
+ { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 412,8 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 287,2 , 289,21 , 22,23 , {67,78,89}, 129,1 , 3122,13 , 4,4 , 4,0 , 553,4 , 557,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China
+ { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 287,6 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 287,2 , 289,21 , 22,23 , {72,75,68}, 130,3 , 3135,11 , 4,4 , 4,0 , 553,4 , 559,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Hong Kong
+ { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 287,6 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 287,2 , 289,21 , 22,23 , {77,79,80}, 133,4 , 3146,13 , 4,4 , 4,0 , 553,4 , 568,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau
+ { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 27,8 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 287,2 , 289,21 , 22,23 , {83,71,68}, 6,1 , 3159,15 , 4,4 , 4,0 , 553,4 , 577,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore
+ { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 180,5 , 180,5 , 433,8 , 420,13 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2065,21 , 2023,28 , 2051,14 , 2065,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 310,3 , 5,17 , 22,23 , {72,75,68}, 130,3 , 3135,11 , 18,5 , 4,0 , 580,4 , 584,9 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Hong Kong
+ { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 180,5 , 180,5 , 433,8 , 420,13 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2065,21 , 2023,28 , 2051,14 , 2065,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 310,3 , 5,17 , 22,23 , {77,79,80}, 133,4 , 3174,13 , 18,5 , 4,0 , 580,4 , 593,9 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau
+ { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 175,5 , 175,5 , 412,8 , 441,14 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2065,21 , 2023,28 , 2051,14 , 2065,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 45,4 , 5,17 , 22,23 , {84,87,68}, 6,1 , 3187,13 , 4,4 , 4,0 , 580,4 , 602,2 , 2, 0, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan
{ 26, 7, 74, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Corsican/Latin/France
- { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 154,7 , 154,7 , 428,13 , 441,19 , 37,5 , 88,12 , 4774,49 , 4823,94 , 4917,39 , 4774,49 , 4956,98 , 4917,39 , 2076,28 , 2104,58 , 2162,14 , 2076,28 , 2104,58 , 2176,14 , 0,2 , 0,2 , 276,7 , 5,17 , 22,23 , {72,82,75}, 147,3 , 3155,60 , 13,5 , 4,0 , 575,8 , 583,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia
- { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 154,7 , 154,7 , 460,9 , 441,19 , 37,5 , 88,12 , 4774,49 , 4823,94 , 4917,39 , 4774,49 , 4956,98 , 4917,39 , 2076,28 , 2104,58 , 2176,14 , 2076,28 , 2104,58 , 2176,14 , 0,2 , 0,2 , 276,7 , 5,17 , 22,23 , {66,65,77}, 150,2 , 3215,85 , 13,5 , 4,0 , 575,8 , 591,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/BosniaAndHerzegowina
- { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 176,7 , 176,7 , 175,8 , 469,17 , 55,4 , 59,9 , 5054,48 , 5102,82 , 158,27 , 5054,48 , 5184,84 , 158,27 , 2190,21 , 2211,49 , 2260,14 , 2190,21 , 2211,49 , 2260,14 , 60,4 , 57,4 , 283,5 , 5,17 , 22,23 , {67,90,75}, 152,2 , 3300,68 , 13,5 , 4,0 , 610,7 , 617,5 , 2, 0, 1, 6, 7 }, // Czech/Latin/CzechRepublic
- { 29, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 183,8 , 183,8 , 120,10 , 486,23 , 200,5 , 205,10 , 5268,59 , 5327,84 , 134,24 , 5268,59 , 5327,84 , 134,24 , 2274,28 , 2302,51 , 2353,14 , 2367,35 , 2302,51 , 2353,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 154,3 , 3368,42 , 13,5 , 4,0 , 622,5 , 627,7 , 2, 1, 1, 6, 7 }, // Danish/Latin/Denmark
- { 29, 7, 86, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 183,8 , 183,8 , 120,10 , 486,23 , 215,7 , 76,12 , 5268,59 , 5327,84 , 134,24 , 5268,59 , 5327,84 , 134,24 , 2274,28 , 2302,51 , 2353,14 , 2367,35 , 2302,51 , 2353,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 154,3 , 3368,42 , 13,5 , 4,0 , 622,5 , 634,8 , 2, 1, 1, 6, 7 }, // Danish/Latin/Greenland
- { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 348,8 , 98,16 , 37,5 , 8,10 , 5411,59 , 5470,88 , 134,24 , 5411,59 , 5470,88 , 134,24 , 2402,21 , 2423,59 , 2482,14 , 2402,21 , 2423,59 , 2482,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3410,19 , 13,5 , 4,0 , 642,10 , 652,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands
- { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 348,8 , 98,16 , 37,5 , 8,10 , 5411,59 , 5470,88 , 134,24 , 5411,59 , 5470,88 , 134,24 , 2402,21 , 2423,59 , 2482,14 , 2402,21 , 2423,59 , 2482,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {65,87,71}, 157,4 , 3429,55 , 13,5 , 4,0 , 642,10 , 661,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba
- { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 509,7 , 98,16 , 37,5 , 8,10 , 5411,59 , 5470,88 , 134,24 , 5411,59 , 5470,88 , 134,24 , 2402,21 , 2423,59 , 2482,14 , 2402,21 , 2423,59 , 2482,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3410,19 , 13,5 , 4,0 , 642,10 , 666,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium
- { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 348,8 , 98,16 , 37,5 , 8,10 , 5411,59 , 5470,88 , 134,24 , 5411,59 , 5470,88 , 134,24 , 2402,21 , 2423,59 , 2482,14 , 2402,21 , 2423,59 , 2482,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {65,78,71}, 161,4 , 3484,97 , 13,5 , 4,0 , 642,10 , 672,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/CuraSao
- { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 348,8 , 98,16 , 37,5 , 8,10 , 5411,59 , 5470,88 , 134,24 , 5411,59 , 5470,88 , 134,24 , 2402,21 , 2423,59 , 2482,14 , 2402,21 , 2423,59 , 2482,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {83,82,68}, 6,1 , 3581,58 , 13,5 , 4,0 , 642,10 , 679,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname
- { 30, 7, 255, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 348,8 , 98,16 , 37,5 , 8,10 , 5411,59 , 5470,88 , 134,24 , 5411,59 , 5470,88 , 134,24 , 2402,21 , 2423,59 , 2482,14 , 2402,21 , 2423,59 , 2482,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3639,61 , 13,5 , 4,0 , 642,10 , 687,19 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Bonaire
- { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 348,8 , 98,16 , 37,5 , 8,10 , 5411,59 , 5470,88 , 134,24 , 5411,59 , 5470,88 , 134,24 , 2402,21 , 2423,59 , 2482,14 , 2402,21 , 2423,59 , 2482,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {65,78,71}, 161,4 , 3484,97 , 13,5 , 4,0 , 642,10 , 706,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/SintMaarten
- { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3700,35 , 4,4 , 4,0 , 718,16 , 734,13 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStates
- { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 165,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // English/Deseret/UnitedStates
- { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3700,35 , 4,4 , 4,0 , 747,7 , 754,14 , 2, 1, 7, 6, 7 }, // English/Latin/AmericanSamoa
- { 31, 7, 7, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3735,71 , 4,4 , 4,0 , 747,7 , 768,8 , 2, 1, 1, 6, 7 }, // English/Latin/Anguilla
- { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3735,71 , 4,4 , 4,0 , 747,7 , 776,17 , 2, 1, 7, 6, 7 }, // English/Latin/AntiguaAndBarbuda
- { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 201,9 , 201,9 , 278,6 , 10,17 , 18,7 , 25,12 , 5558,59 , 48,86 , 134,24 , 5558,59 , 48,86 , 134,24 , 2496,35 , 28,57 , 2531,25 , 2496,35 , 28,57 , 2531,25 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3806,59 , 4,4 , 4,0 , 793,18 , 811,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia
- { 31, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 8,5 , 4,0 , 747,7 , 820,7 , 2, 1, 1, 6, 7 }, // English/Latin/Austria
- { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,83,68}, 6,1 , 3885,53 , 4,4 , 4,0 , 747,7 , 827,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas
- { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,66,68}, 6,1 , 3938,56 , 4,4 , 4,0 , 747,7 , 834,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados
- { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 27,8 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 13,5 , 4,0 , 747,7 , 842,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium
- { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 27,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,90,68}, 6,1 , 3994,47 , 4,4 , 4,0 , 747,7 , 849,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize
- { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,77,68}, 6,1 , 4041,53 , 4,4 , 4,0 , 747,7 , 855,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda
- { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 27,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,87,80}, 168,1 , 4094,50 , 4,4 , 4,0 , 747,7 , 862,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana
- { 31, 7, 31, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 165,3 , 3700,35 , 4,4 , 4,0 , 747,7 , 870,30 , 2, 1, 1, 6, 7 }, // English/Latin/BritishIndianOceanTerritory
- { 31, 7, 35, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,73,70}, 169,3 , 4144,53 , 4,4 , 4,0 , 747,7 , 900,7 , 0, 0, 1, 6, 7 }, // English/Latin/Burundi
- { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 4197,83 , 4,4 , 4,0 , 747,7 , 907,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon
- { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 53,10 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {67,65,68}, 6,1 , 4280,53 , 4,4 , 4,0 , 915,16 , 931,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada
- { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {75,89,68}, 6,1 , 4333,71 , 4,4 , 4,0 , 747,7 , 937,14 , 2, 1, 1, 6, 7 }, // English/Latin/CaymanIslands
- { 31, 7, 45, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3806,59 , 4,4 , 4,0 , 747,7 , 951,16 , 2, 1, 1, 6, 7 }, // English/Latin/ChristmasIsland
- { 31, 7, 46, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3806,59 , 4,4 , 4,0 , 747,7 , 967,23 , 2, 1, 1, 6, 7 }, // English/Latin/CocosIslands
- { 31, 7, 51, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4404,62 , 4,4 , 4,0 , 747,7 , 990,12 , 2, 1, 1, 6, 7 }, // English/Latin/CookIslands
- { 31, 7, 56, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 4,4 , 4,0 , 747,7 , 1002,6 , 2, 1, 1, 6, 7 }, // English/Latin/Cyprus
- { 31, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 200,5 , 205,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {68,75,75}, 154,3 , 4466,44 , 13,5 , 4,0 , 747,7 , 1008,7 , 2, 1, 1, 6, 7 }, // English/Latin/Denmark
- { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3735,71 , 4,4 , 4,0 , 747,7 , 1015,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica
- { 31, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,82,78}, 46,3 , 4510,50 , 4,4 , 4,0 , 747,7 , 1023,7 , 2, 1, 1, 6, 7 }, // English/Latin/Eritrea
- { 31, 7, 70, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {70,75,80}, 125,1 , 4560,74 , 4,4 , 4,0 , 747,7 , 1030,16 , 2, 1, 1, 6, 7 }, // English/Latin/FalklandIslands
- { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {70,74,68}, 6,1 , 4634,47 , 4,4 , 4,0 , 747,7 , 1046,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji
- { 31, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 222,4 , 226,9 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 13,5 , 4,0 , 747,7 , 1050,7 , 2, 1, 1, 6, 7 }, // English/Latin/Finland
- { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 125,1 , 4681,32 , 4,4 , 4,0 , 747,7 , 1057,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey
- { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,77,68}, 172,1 , 4713,50 , 4,4 , 4,0 , 747,7 , 1065,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia
- { 31, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 13,5 , 4,0 , 747,7 , 1071,7 , 2, 1, 1, 6, 7 }, // English/Latin/Germany
- { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,72,83}, 173,3 , 4763,47 , 4,4 , 4,0 , 747,7 , 1078,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana
- { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,73,80}, 125,1 , 4810,53 , 4,4 , 4,0 , 747,7 , 1083,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar
- { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3735,71 , 4,4 , 4,0 , 747,7 , 1092,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada
- { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3700,35 , 4,4 , 4,0 , 747,7 , 1099,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam
- { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,89,68}, 6,1 , 4863,56 , 4,4 , 4,0 , 747,7 , 1103,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana
- { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 406,8 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {72,75,68}, 140,3 , 4919,56 , 4,4 , 4,0 , 747,7 , 1109,19 , 2, 1, 7, 6, 7 }, // English/Latin/HongKong
- { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 27,8 , 98,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {73,78,82}, 127,1 , 4975,44 , 8,5 , 4,0 , 747,7 , 1128,5 , 2, 1, 7, 7, 7 }, // English/Latin/India
- { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 98,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 4,4 , 4,0 , 747,7 , 1133,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland
- { 31, 7, 105, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 55,4 , 59,9 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {73,76,83}, 54,1 , 5019,62 , 4,4 , 4,0 , 747,7 , 1140,6 , 2, 1, 7, 5, 6 }, // English/Latin/Israel
- { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 278,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {74,77,68}, 6,1 , 5081,53 , 4,4 , 4,0 , 747,7 , 1146,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica
- { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {75,69,83}, 2,3 , 5134,53 , 4,4 , 4,0 , 747,7 , 1153,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya
- { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3806,59 , 4,4 , 4,0 , 747,7 , 1158,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati
- { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 5187,61 , 4,4 , 4,0 , 747,7 , 1166,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho
- { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {76,82,68}, 6,1 , 5248,53 , 4,4 , 4,0 , 747,7 , 1173,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia
- { 31, 7, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,79,80}, 143,4 , 5301,53 , 4,4 , 4,0 , 747,7 , 1180,15 , 2, 1, 7, 6, 7 }, // English/Latin/Macau
- { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,71,65}, 176,2 , 5354,54 , 4,4 , 4,0 , 747,7 , 1195,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar
- { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,87,75}, 178,2 , 5408,53 , 4,4 , 4,0 , 747,7 , 1205,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi
- { 31, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,89,82}, 180,2 , 5461,59 , 4,4 , 4,0 , 747,7 , 1211,8 , 2, 1, 1, 6, 7 }, // English/Latin/Malaysia
- { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 4,4 , 4,0 , 747,7 , 1219,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta
- { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3700,35 , 4,4 , 4,0 , 747,7 , 1224,16 , 2, 1, 7, 6, 7 }, // English/Latin/MarshallIslands
- { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,85,82}, 182,2 , 5520,53 , 4,4 , 4,0 , 747,7 , 1240,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius
- { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 165,3 , 3700,35 , 4,4 , 4,0 , 747,7 , 1249,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia
- { 31, 7, 144, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3735,71 , 4,4 , 4,0 , 747,7 , 1259,10 , 2, 1, 1, 6, 7 }, // English/Latin/Montserrat
- { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,65,68}, 6,1 , 5573,53 , 4,4 , 4,0 , 747,7 , 1269,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia
- { 31, 7, 149, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3806,59 , 4,4 , 4,0 , 747,7 , 1276,5 , 2, 1, 1, 6, 7 }, // English/Latin/Nauru
- { 31, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 8,5 , 23,6 , 747,7 , 1281,11 , 2, 1, 1, 6, 7 }, // English/Latin/Netherlands
- { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 509,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4404,62 , 4,4 , 4,0 , 747,7 , 1292,11 , 2, 1, 7, 6, 7 }, // English/Latin/NewZealand
- { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,71,78}, 184,1 , 5626,50 , 4,4 , 4,0 , 747,7 , 1303,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria
- { 31, 7, 158, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4404,62 , 4,4 , 4,0 , 747,7 , 1310,4 , 2, 1, 1, 6, 7 }, // English/Latin/Niue
- { 31, 7, 159, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3806,59 , 4,4 , 4,0 , 747,7 , 1314,14 , 2, 1, 1, 6, 7 }, // English/Latin/NorfolkIsland
- { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3700,35 , 4,4 , 4,0 , 747,7 , 1328,24 , 2, 1, 1, 6, 7 }, // English/Latin/NorthernMarianaIslands
- { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,75,82}, 182,2 , 5676,53 , 4,4 , 4,0 , 747,7 , 1352,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan
- { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 165,3 , 3700,35 , 4,4 , 4,0 , 747,7 , 1360,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau
- { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,71,75}, 137,1 , 5729,73 , 4,4 , 4,0 , 747,7 , 1365,16 , 2, 1, 1, 6, 7 }, // English/Latin/PapuaNewGuinea
- { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,72,80}, 185,1 , 5802,53 , 4,4 , 4,0 , 747,7 , 1381,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines
- { 31, 7, 171, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4404,62 , 4,4 , 4,0 , 747,7 , 1392,16 , 2, 1, 1, 6, 7 }, // English/Latin/Pitcairn
- { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3700,35 , 4,4 , 4,0 , 747,7 , 1408,11 , 2, 1, 7, 6, 7 }, // English/Latin/PuertoRico
- { 31, 7, 179, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {82,87,70}, 186,2 , 5855,47 , 4,4 , 4,0 , 747,7 , 1419,6 , 0, 0, 1, 6, 7 }, // English/Latin/Rwanda
- { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3735,71 , 4,4 , 4,0 , 747,7 , 1425,17 , 2, 1, 1, 6, 7 }, // English/Latin/SaintKittsAndNevis
- { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3735,71 , 4,4 , 4,0 , 747,7 , 1442,9 , 2, 1, 1, 6, 7 }, // English/Latin/SaintLucia
- { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3735,71 , 4,4 , 4,0 , 747,7 , 1451,24 , 2, 1, 1, 6, 7 }, // English/Latin/SaintVincentAndTheGrenadines
- { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {87,83,84}, 188,3 , 5902,40 , 4,4 , 4,0 , 747,7 , 1475,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa
- { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,67,82}, 191,2 , 5942,59 , 4,4 , 4,0 , 747,7 , 1480,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles
- { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,76,76}, 193,2 , 6001,68 , 4,4 , 4,0 , 747,7 , 1490,12 , 0, 0, 1, 6, 7 }, // English/Latin/SierraLeone
- { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 278,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,71,68}, 6,1 , 6069,56 , 4,4 , 4,0 , 747,7 , 1502,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore
- { 31, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 13,5 , 29,7 , 747,7 , 1511,8 , 2, 1, 1, 6, 7 }, // English/Latin/Slovenia
- { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,66,68}, 6,1 , 6125,74 , 4,4 , 4,0 , 747,7 , 1519,15 , 2, 1, 1, 6, 7 }, // English/Latin/SolomonIslands
- { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 522,10 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 5187,61 , 4,4 , 4,0 , 747,7 , 1534,12 , 2, 1, 7, 6, 7 }, // English/Latin/SouthAfrica
- { 31, 7, 199, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,72,80}, 125,1 , 6199,56 , 4,4 , 4,0 , 747,7 , 1546,10 , 2, 1, 1, 6, 7 }, // English/Latin/SaintHelena
- { 31, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,68,71}, 0,0 , 6255,50 , 4,4 , 4,0 , 747,7 , 1556,5 , 2, 1, 6, 5, 6 }, // English/Latin/Sudan
- { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,90,76}, 195,1 , 6305,53 , 4,4 , 4,0 , 747,7 , 1561,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland
- { 31, 7, 205, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 53,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,69,75}, 196,2 , 6358,47 , 13,5 , 4,0 , 747,7 , 1570,6 , 2, 1, 1, 6, 7 }, // English/Latin/Sweden
- { 31, 7, 206, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {67,72,70}, 0,0 , 6405,41 , 8,5 , 36,5 , 747,7 , 1576,11 , 2, 0, 1, 6, 7 }, // English/Latin/Switzerland
- { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,90,83}, 198,3 , 6446,62 , 4,4 , 4,0 , 747,7 , 1587,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania
- { 31, 7, 213, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4404,62 , 4,4 , 4,0 , 747,7 , 1595,7 , 2, 1, 1, 6, 7 }, // English/Latin/Tokelau
- { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,79,80}, 201,2 , 6508,49 , 4,4 , 4,0 , 747,7 , 1602,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga
- { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,84,68}, 6,1 , 6557,80 , 4,4 , 4,0 , 747,7 , 1607,17 , 2, 1, 7, 6, 7 }, // English/Latin/TrinidadAndTobago
- { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 165,3 , 3700,35 , 4,4 , 4,0 , 747,7 , 1624,22 , 2, 1, 1, 6, 7 }, // English/Latin/TurksAndCaicosIslands
- { 31, 7, 220, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3806,59 , 4,4 , 4,0 , 747,7 , 1646,6 , 2, 1, 1, 6, 7 }, // English/Latin/Tuvalu
- { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,71,88}, 203,3 , 6637,56 , 4,4 , 4,0 , 747,7 , 1652,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda
- { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 201,9 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 125,1 , 6693,47 , 4,4 , 4,0 , 1658,15 , 1673,14 , 2, 1, 1, 6, 7 }, // English/Latin/UnitedKingdom
- { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3700,35 , 4,4 , 4,0 , 747,7 , 1687,21 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesMinorOutlyingIslands
- { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {86,85,86}, 206,2 , 6740,44 , 4,4 , 4,0 , 747,7 , 1708,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu
- { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 165,3 , 3700,35 , 4,4 , 4,0 , 747,7 , 1715,22 , 2, 1, 1, 6, 7 }, // English/Latin/BritishVirginIslands
- { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 516,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3700,35 , 4,4 , 4,0 , 747,7 , 1737,19 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesVirginIslands
- { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,77,87}, 137,1 , 6784,50 , 4,4 , 4,0 , 747,7 , 1756,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia
- { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 406,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 165,3 , 3700,35 , 4,4 , 4,0 , 747,7 , 1762,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe
- { 31, 7, 249, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 165,3 , 3700,35 , 4,4 , 4,0 , 747,7 , 1770,12 , 2, 1, 1, 6, 7 }, // English/Latin/DiegoGarcia
- { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 125,1 , 4681,32 , 4,4 , 4,0 , 747,7 , 1782,11 , 2, 1, 1, 6, 7 }, // English/Latin/IsleOfMan
- { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 125,1 , 4681,32 , 4,4 , 4,0 , 747,7 , 1793,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey
- { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,83,80}, 125,1 , 6834,68 , 4,4 , 4,0 , 747,7 , 1799,11 , 2, 1, 1, 6, 7 }, // English/Latin/SouthSudan
- { 31, 7, 256, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 191,10 , 201,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,78,71}, 161,4 , 6902,95 , 4,4 , 4,0 , 747,7 , 1810,12 , 2, 1, 1, 6, 7 }, // English/Latin/SintMaarten
- { 33, 7, 68, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 210,8 , 210,8 , 175,8 , 532,18 , 37,5 , 8,10 , 5617,59 , 5676,91 , 5767,24 , 5617,59 , 5676,91 , 5767,24 , 2556,14 , 2570,63 , 2556,14 , 2556,14 , 2570,63 , 2556,14 , 0,2 , 0,2 , 288,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 6997,20 , 13,5 , 4,0 , 1822,5 , 1827,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia
- { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 183,8 , 183,8 , 175,8 , 532,18 , 37,5 , 8,10 , 5791,48 , 5839,83 , 134,24 , 5922,59 , 5839,83 , 134,24 , 2633,28 , 2661,74 , 2735,14 , 2749,35 , 2661,74 , 2735,14 , 0,2 , 0,2 , 294,3 , 297,17 , 22,23 , {68,75,75}, 196,2 , 7017,43 , 13,5 , 4,0 , 1832,8 , 1840,7 , 2, 1, 1, 6, 7 }, // Faroese/Latin/FaroeIslands
- { 34, 7, 58, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 183,8 , 183,8 , 175,8 , 532,18 , 37,5 , 8,10 , 5791,48 , 5839,83 , 134,24 , 5922,59 , 5839,83 , 134,24 , 2633,28 , 2661,74 , 2735,14 , 2749,35 , 2661,74 , 2735,14 , 0,2 , 0,2 , 294,3 , 297,17 , 22,23 , {68,75,75}, 154,3 , 7017,43 , 13,5 , 4,0 , 1832,8 , 627,7 , 2, 1, 1, 6, 7 }, // Faroese/Latin/Denmark
- { 36, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 210,8 , 210,8 , 550,8 , 469,17 , 222,4 , 226,9 , 5981,69 , 6050,105 , 6155,24 , 6179,93 , 6272,129 , 6155,24 , 2784,21 , 2805,67 , 2872,14 , 2784,21 , 2886,81 , 2872,14 , 70,3 , 67,3 , 314,5 , 319,17 , 336,23 , {69,85,82}, 14,1 , 7060,20 , 13,5 , 4,0 , 1847,5 , 1852,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland
- { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 1865,6 , 2, 1, 1, 6, 7 }, // French/Latin/France
- { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {68,90,68}, 208,2 , 7080,51 , 13,5 , 4,0 , 1857,8 , 1871,7 , 2, 1, 6, 5, 6 }, // French/Latin/Algeria
- { 37, 7, 21, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 509,7 , 98,16 , 37,5 , 235,23 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 1878,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium
- { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,79,70}, 210,3 , 7131,59 , 13,5 , 4,0 , 1857,8 , 1886,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin
- { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,79,70}, 210,3 , 7131,59 , 13,5 , 4,0 , 1857,8 , 1891,12 , 0, 0, 1, 6, 7 }, // French/Latin/BurkinaFaso
- { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {66,73,70}, 169,3 , 7190,53 , 13,5 , 4,0 , 1857,8 , 900,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi
- { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 73,5 , 70,4 , 359,6 , 174,17 , 191,23 , {88,65,70}, 32,4 , 7243,56 , 13,5 , 4,0 , 1857,8 , 1903,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon
- { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8221, 8220, 0,6 , 0,6 , 218,8 , 218,8 , 558,8 , 98,16 , 258,9 , 8,10 , 6549,64 , 6464,85 , 134,24 , 6549,64 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 64,4 , 61,4 , 359,6 , 174,17 , 191,23 , {67,65,68}, 6,1 , 7299,54 , 41,8 , 4,0 , 1911,17 , 931,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada
- { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,65,70}, 32,4 , 7243,56 , 13,5 , 4,0 , 1857,8 , 1928,25 , 0, 0, 1, 6, 7 }, // French/Latin/CentralAfricanRepublic
- { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,65,70}, 32,4 , 7243,56 , 13,5 , 4,0 , 1857,8 , 1953,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad
- { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {75,77,70}, 213,2 , 7353,51 , 13,5 , 4,0 , 1857,8 , 1958,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros
- { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {67,68,70}, 215,2 , 7404,53 , 13,5 , 4,0 , 1857,8 , 1965,14 , 2, 1, 1, 6, 7 }, // French/Latin/CongoKinshasa
- { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,65,70}, 32,4 , 7243,56 , 13,5 , 4,0 , 1857,8 , 1979,17 , 0, 0, 1, 6, 7 }, // French/Latin/CongoBrazzaville
- { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,79,70}, 210,3 , 7131,59 , 13,5 , 4,0 , 1857,8 , 1996,13 , 0, 0, 1, 6, 7 }, // French/Latin/IvoryCoast
- { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {68,74,70}, 43,3 , 7457,57 , 13,5 , 4,0 , 1857,8 , 2009,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti
- { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,65,70}, 32,4 , 7243,56 , 13,5 , 4,0 , 1857,8 , 2017,18 , 0, 0, 1, 6, 7 }, // French/Latin/EquatorialGuinea
- { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2035,16 , 2, 1, 1, 6, 7 }, // French/Latin/FrenchGuiana
- { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,80,70}, 217,4 , 7514,35 , 13,5 , 4,0 , 1857,8 , 2051,19 , 0, 0, 1, 6, 7 }, // French/Latin/FrenchPolynesia
- { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,65,70}, 32,4 , 7243,56 , 13,5 , 4,0 , 1857,8 , 2070,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon
- { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2075,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe
- { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {71,78,70}, 221,2 , 7549,48 , 13,5 , 4,0 , 1857,8 , 2085,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea
- { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {72,84,71}, 223,1 , 7597,57 , 13,5 , 4,0 , 1857,8 , 2091,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti
- { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2096,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg
- { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {77,71,65}, 176,2 , 7654,54 , 13,5 , 4,0 , 1857,8 , 1195,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar
- { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,79,70}, 210,3 , 7131,59 , 13,5 , 4,0 , 1857,8 , 2106,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali
- { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2110,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique
- { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {77,82,79}, 224,2 , 7708,66 , 13,5 , 4,0 , 1857,8 , 2120,10 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritania
- { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {77,85,82}, 182,2 , 7774,63 , 13,5 , 4,0 , 1857,8 , 2130,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius
- { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2137,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte
- { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2144,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco
- { 37, 7, 145, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6613,61 , 6464,85 , 134,24 , 6613,61 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 64,4 , 61,4 , 359,6 , 174,17 , 191,23 , {77,65,68}, 226,3 , 7837,54 , 13,5 , 4,0 , 1857,8 , 2150,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco
- { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,80,70}, 217,4 , 7514,35 , 13,5 , 4,0 , 1857,8 , 2155,18 , 0, 0, 1, 6, 7 }, // French/Latin/NewCaledonia
- { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,79,70}, 210,3 , 7131,59 , 13,5 , 4,0 , 1857,8 , 2173,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger
- { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2178,10 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion
- { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {82,87,70}, 186,2 , 7891,50 , 13,5 , 4,0 , 1857,8 , 1419,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda
- { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,79,70}, 210,3 , 7131,59 , 13,5 , 4,0 , 1857,8 , 2188,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal
- { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {83,67,82}, 191,2 , 7941,71 , 13,5 , 4,0 , 1857,8 , 1480,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles
- { 37, 7, 200, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2195,24 , 2, 1, 1, 6, 7 }, // French/Latin/SaintPierreAndMiquelon
- { 37, 7, 206, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 218,8 , 218,8 , 175,8 , 10,17 , 37,5 , 267,14 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {67,72,70}, 229,3 , 8012,45 , 13,5 , 4,0 , 2219,15 , 2234,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland
- { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {83,89,80}, 232,2 , 8057,51 , 13,5 , 4,0 , 1857,8 , 2240,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria
- { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,79,70}, 210,3 , 7131,59 , 13,5 , 4,0 , 1857,8 , 2245,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo
- { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {84,78,68}, 234,2 , 8108,51 , 13,5 , 4,0 , 1857,8 , 2249,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia
- { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {86,85,86}, 206,2 , 8159,51 , 13,5 , 4,0 , 1857,8 , 1708,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu
- { 37, 7, 235, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {88,80,70}, 217,4 , 7514,35 , 13,5 , 4,0 , 1857,8 , 2256,16 , 0, 0, 1, 6, 7 }, // French/Latin/WallisAndFutunaIslands
- { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2272,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy
- { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 218,8 , 218,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6401,63 , 6464,85 , 134,24 , 6401,63 , 6464,85 , 134,24 , 2967,35 , 3002,52 , 3054,14 , 2967,35 , 3002,52 , 3054,14 , 0,2 , 0,2 , 359,6 , 174,17 , 191,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 1857,8 , 2288,12 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin
- { 38, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 348,8 , 98,16 , 37,5 , 8,10 , 6674,48 , 6722,95 , 134,24 , 6674,48 , 6722,95 , 134,24 , 3068,21 , 3089,54 , 85,14 , 3068,21 , 3089,54 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3410,19 , 8,5 , 49,6 , 2300,10 , 2310,8 , 2, 1, 1, 6, 7 }, // Western Frisian/Latin/Netherlands
- { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 226,10 , 226,10 , 120,10 , 566,21 , 37,5 , 8,10 , 6817,61 , 6878,142 , 7020,24 , 6817,61 , 7044,167 , 7020,24 , 3143,28 , 3171,69 , 3240,14 , 3143,28 , 3171,69 , 3240,14 , 78,1 , 74,1 , 365,6 , 5,17 , 22,23 , {71,66,80}, 125,1 , 8210,86 , 4,4 , 4,0 , 2318,8 , 2326,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/UnitedKingdom
- { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 7211,60 , 7271,87 , 7358,24 , 7382,60 , 7442,87 , 7529,36 , 3254,35 , 3289,49 , 3338,14 , 3352,35 , 3387,49 , 3436,21 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3865,20 , 13,5 , 4,0 , 2348,6 , 2354,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain
- { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 171, 187, 0,6 , 0,6 , 243,8 , 243,8 , 175,8 , 614,19 , 37,5 , 8,10 , 7565,48 , 7613,99 , 7712,24 , 7565,48 , 7613,99 , 7712,24 , 3457,28 , 3485,62 , 3547,14 , 3457,28 , 3485,62 , 3547,14 , 0,2 , 0,2 , 371,5 , 376,33 , 22,23 , {71,69,76}, 236,1 , 8296,43 , 13,5 , 4,0 , 2360,7 , 2367,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia
- { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7736,48 , 7784,83 , 134,24 , 7867,59 , 7784,83 , 134,24 , 3561,21 , 3582,60 , 3642,14 , 3656,28 , 3582,60 , 3642,14 , 79,5 , 75,6 , 409,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8339,19 , 13,5 , 4,0 , 2377,7 , 2384,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany
- { 42, 7, 14, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7926,48 , 7974,83 , 134,24 , 8057,59 , 7974,83 , 134,24 , 3561,21 , 3582,60 , 3642,14 , 3656,28 , 3582,60 , 3642,14 , 79,5 , 75,6 , 409,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8339,19 , 8,5 , 4,0 , 2395,24 , 2419,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria
- { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7736,48 , 7784,83 , 134,24 , 7867,59 , 7784,83 , 134,24 , 3561,21 , 3582,60 , 3642,14 , 3656,28 , 3582,60 , 3642,14 , 79,5 , 75,6 , 409,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8339,19 , 13,5 , 4,0 , 2377,7 , 2429,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium
- { 42, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7926,48 , 7974,83 , 134,24 , 8057,59 , 7974,83 , 134,24 , 3561,21 , 3582,60 , 3642,14 , 3656,28 , 3582,60 , 3642,14 , 79,5 , 75,6 , 409,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8339,19 , 13,5 , 4,0 , 2377,7 , 2436,7 , 2, 1, 1, 6, 7 }, // German/Latin/Italy
- { 42, 7, 123, 46, 8217, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7736,48 , 7784,83 , 134,24 , 7867,59 , 7784,83 , 134,24 , 3561,21 , 3582,60 , 3642,14 , 3656,28 , 3582,60 , 3642,14 , 79,5 , 75,6 , 409,5 , 5,17 , 22,23 , {67,72,70}, 229,3 , 8358,58 , 8,5 , 4,0 , 2377,7 , 2443,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein
- { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7736,48 , 7784,83 , 134,24 , 7867,59 , 7784,83 , 134,24 , 3561,21 , 3582,60 , 3642,14 , 3656,28 , 3582,60 , 3642,14 , 79,5 , 75,6 , 409,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8339,19 , 13,5 , 4,0 , 2377,7 , 2456,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg
- { 42, 7, 206, 46, 8217, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7736,48 , 7784,83 , 134,24 , 7867,59 , 7784,83 , 134,24 , 3561,21 , 3582,60 , 3642,14 , 3656,28 , 3582,60 , 3642,14 , 79,5 , 75,6 , 409,5 , 5,17 , 22,23 , {67,72,70}, 229,3 , 8358,58 , 8,5 , 36,5 , 2465,21 , 2486,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland
- { 43, 16, 85, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 260,9 , 260,9 , 278,6 , 10,17 , 18,7 , 25,12 , 8116,50 , 8166,115 , 8281,24 , 8305,50 , 8355,115 , 8281,24 , 3684,28 , 3712,55 , 3767,14 , 3684,28 , 3712,55 , 3767,14 , 84,4 , 81,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8416,19 , 13,5 , 4,0 , 2493,8 , 2501,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece
- { 43, 16, 56, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 260,9 , 260,9 , 278,6 , 10,17 , 18,7 , 25,12 , 8116,50 , 8166,115 , 8281,24 , 8305,50 , 8355,115 , 8281,24 , 3684,28 , 3712,55 , 3767,14 , 3684,28 , 3712,55 , 3767,14 , 84,4 , 81,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8416,19 , 13,5 , 4,0 , 2493,8 , 2507,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus
- { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 269,11 , 269,11 , 53,10 , 633,17 , 18,7 , 25,12 , 8470,48 , 8518,96 , 134,24 , 8470,48 , 8518,96 , 134,24 , 3781,28 , 3809,98 , 3907,14 , 3781,28 , 3809,98 , 3907,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 154,3 , 8435,62 , 4,4 , 55,5 , 2513,11 , 2524,16 , 2, 1, 1, 6, 7 }, // Greenlandic/Latin/Greenland
- { 45, 7, 168, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,89,71}, 237,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 7, 6, 7 }, // Guarani/Latin/Paraguay
- { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 280,9 , 280,9 , 278,6 , 211,18 , 281,8 , 289,13 , 8614,67 , 8681,87 , 8768,31 , 8614,67 , 8681,87 , 8768,31 , 3921,32 , 3953,53 , 4006,19 , 3921,32 , 3953,53 , 4006,19 , 0,2 , 0,2 , 414,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 8497,46 , 4,4 , 4,0 , 2540,7 , 2547,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India
- { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 278,6 , 211,18 , 37,5 , 8,10 , 8799,48 , 8847,85 , 8932,24 , 8799,48 , 8847,85 , 8932,24 , 4025,28 , 4053,52 , 4105,14 , 4025,28 , 4053,52 , 4105,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 184,1 , 8543,12 , 8,5 , 4,0 , 2551,5 , 2556,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria
- { 47, 1, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 184,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Hausa/Arabic/Nigeria
- { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 278,6 , 211,18 , 37,5 , 8,10 , 8799,48 , 8847,85 , 8932,24 , 8799,48 , 8847,85 , 8932,24 , 4025,28 , 4053,52 , 4105,14 , 4025,28 , 4053,52 , 4105,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 173,3 , 0,7 , 8,5 , 4,0 , 2551,5 , 2564,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana
- { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 278,6 , 211,18 , 37,5 , 8,10 , 8799,48 , 8847,85 , 8932,24 , 8799,48 , 8847,85 , 8932,24 , 4025,28 , 4053,52 , 4105,14 , 4025,28 , 4053,52 , 4105,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 8555,36 , 8,5 , 4,0 , 2551,5 , 2568,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger
- { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 289,6 , 289,6 , 550,8 , 650,18 , 55,4 , 59,9 , 8956,58 , 9014,72 , 158,27 , 8956,58 , 9014,72 , 158,27 , 4119,46 , 4165,65 , 4230,21 , 4119,46 , 4165,65 , 4230,21 , 88,6 , 85,5 , 418,4 , 5,17 , 22,23 , {73,76,83}, 54,1 , 8591,54 , 60,6 , 66,8 , 2573,5 , 2578,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel
- { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 295,9 , 304,8 , 278,6 , 10,17 , 18,7 , 25,12 , 9086,59 , 9145,73 , 9218,30 , 9086,59 , 9145,73 , 9218,30 , 4251,32 , 4283,53 , 4336,19 , 4251,32 , 4283,53 , 4336,19 , 94,9 , 90,7 , 422,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 8645,42 , 4,4 , 4,0 , 2583,6 , 2589,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India
- { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 312,8 , 312,8 , 668,13 , 681,19 , 55,4 , 59,9 , 9248,64 , 9312,98 , 9410,25 , 9248,64 , 9312,98 , 9410,25 , 4355,19 , 4374,52 , 4426,17 , 4355,19 , 4374,52 , 4426,17 , 103,3 , 97,3 , 426,4 , 5,17 , 22,23 , {72,85,70}, 238,2 , 8687,46 , 13,5 , 4,0 , 2593,6 , 2599,12 , 2, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary
- { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 183,8 , 183,8 , 550,8 , 532,18 , 37,5 , 8,10 , 9435,59 , 9494,82 , 9576,24 , 9435,59 , 9494,82 , 9576,24 , 4443,35 , 4478,81 , 4559,14 , 4443,35 , 4478,81 , 4559,14 , 106,4 , 100,4 , 430,4 , 5,17 , 22,23 , {73,83,75}, 240,3 , 8733,49 , 13,5 , 4,0 , 2611,8 , 2619,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland
- { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 320,10 , 330,9 , 27,8 , 80,18 , 200,5 , 205,10 , 9600,48 , 9648,87 , 134,24 , 9600,48 , 9648,87 , 134,24 , 4573,28 , 4601,43 , 4644,14 , 4573,28 , 4601,43 , 4644,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,68,82}, 243,2 , 8782,39 , 4,4 , 4,0 , 2625,9 , 2625,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia
+ { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 455,13 , 468,19 , 37,5 , 87,12 , 4748,49 , 4797,94 , 4891,39 , 4748,49 , 4930,98 , 4891,39 , 2086,28 , 2114,58 , 2172,14 , 2086,28 , 2114,58 , 2186,14 , 0,2 , 0,2 , 313,7 , 5,17 , 22,23 , {72,82,75}, 137,3 , 3200,60 , 13,5 , 4,0 , 604,8 , 612,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia
+ { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 487,9 , 468,19 , 37,5 , 87,12 , 4748,49 , 4797,94 , 4891,39 , 4748,49 , 4930,98 , 4891,39 , 2086,28 , 2114,58 , 2186,14 , 2086,28 , 2114,58 , 2186,14 , 0,2 , 0,2 , 313,7 , 5,17 , 22,23 , {66,65,77}, 140,2 , 3260,85 , 13,5 , 4,0 , 604,8 , 620,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Bosnia And Herzegowina
+ { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 174,8 , 496,17 , 55,4 , 59,9 , 5028,48 , 5076,82 , 158,27 , 5028,48 , 5158,84 , 158,27 , 2200,21 , 2221,49 , 2270,14 , 2200,21 , 2221,49 , 2270,14 , 62,4 , 59,4 , 320,5 , 5,17 , 22,23 , {67,90,75}, 142,2 , 3345,68 , 13,5 , 4,0 , 639,7 , 646,5 , 2, 0, 1, 6, 7 }, // Czech/Latin/Czech Republic
+ { 29, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 120,10 , 513,23 , 228,5 , 233,10 , 5242,59 , 5301,84 , 134,24 , 5242,59 , 5301,84 , 134,24 , 2284,28 , 2312,51 , 2363,14 , 2377,35 , 2312,51 , 2363,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 144,3 , 3413,42 , 13,5 , 4,0 , 651,5 , 656,7 , 2, 0, 1, 6, 7 }, // Danish/Latin/Denmark
+ { 29, 7, 86, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 120,10 , 513,23 , 228,5 , 233,10 , 5242,59 , 5301,84 , 134,24 , 5242,59 , 5301,84 , 134,24 , 2284,28 , 2312,51 , 2363,14 , 2377,35 , 2312,51 , 2363,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 144,3 , 3413,42 , 13,5 , 4,0 , 651,5 , 663,8 , 2, 0, 1, 6, 7 }, // Danish/Latin/Greenland
+ { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 13,5 , 4,0 , 671,10 , 681,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands
+ { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {65,87,71}, 147,4 , 3474,55 , 13,5 , 4,0 , 671,10 , 690,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba
+ { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 536,7 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 13,5 , 4,0 , 671,10 , 695,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium
+ { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {65,78,71}, 151,4 , 3529,97 , 13,5 , 4,0 , 671,10 , 701,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Cura Sao
+ { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {83,82,68}, 6,1 , 3626,58 , 13,5 , 4,0 , 671,10 , 708,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname
+ { 30, 7, 255, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3684,61 , 13,5 , 4,0 , 671,10 , 716,19 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Bonaire
+ { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {65,78,71}, 151,4 , 3529,97 , 13,5 , 4,0 , 671,10 , 735,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Sint Maarten
+ { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 747,16 , 763,13 , 2, 1, 7, 6, 7 }, // English/Latin/United States
+ { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 155,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // English/Deseret/United States
+ { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 783,14 , 2, 1, 7, 6, 7 }, // English/Latin/American Samoa
+ { 31, 7, 7, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 797,8 , 2, 1, 1, 6, 7 }, // English/Latin/Anguilla
+ { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 805,17 , 2, 1, 7, 6, 7 }, // English/Latin/Antigua And Barbuda
+ { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 210,9 , 210,9 , 287,6 , 10,17 , 18,7 , 25,12 , 5532,59 , 48,86 , 134,24 , 5532,59 , 48,86 , 134,24 , 2506,35 , 28,57 , 2541,25 , 2506,35 , 28,57 , 2541,25 , 70,2 , 67,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 822,18 , 840,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia
+ { 31, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 8,5 , 4,0 , 776,7 , 849,7 , 2, 1, 1, 6, 7 }, // English/Latin/Austria
+ { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,83,68}, 6,1 , 3930,53 , 4,4 , 4,0 , 776,7 , 856,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas
+ { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,66,68}, 6,1 , 3983,56 , 4,4 , 4,0 , 776,7 , 863,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados
+ { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 871,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium
+ { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,90,68}, 6,1 , 4039,47 , 4,4 , 4,0 , 776,7 , 878,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize
+ { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,77,68}, 6,1 , 4086,53 , 4,4 , 4,0 , 776,7 , 884,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda
+ { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,87,80}, 158,1 , 4139,50 , 4,4 , 4,0 , 776,7 , 891,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana
+ { 31, 7, 31, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 899,30 , 2, 1, 1, 6, 7 }, // English/Latin/British Indian Ocean Territory
+ { 31, 7, 35, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,73,70}, 159,3 , 4189,53 , 4,4 , 4,0 , 776,7 , 929,7 , 0, 0, 1, 6, 7 }, // English/Latin/Burundi
+ { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 4242,83 , 4,4 , 4,0 , 776,7 , 936,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon
+ { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 5532,59 , 48,86 , 134,24 , 2506,35 , 28,57 , 85,14 , 2506,35 , 28,57 , 85,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {67,65,68}, 6,1 , 4325,53 , 4,4 , 4,0 , 944,16 , 960,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada
+ { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {75,89,68}, 6,1 , 4378,71 , 4,4 , 4,0 , 776,7 , 966,14 , 2, 1, 1, 6, 7 }, // English/Latin/Cayman Islands
+ { 31, 7, 45, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 980,16 , 2, 1, 1, 6, 7 }, // English/Latin/Christmas Island
+ { 31, 7, 46, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 996,23 , 2, 1, 1, 6, 7 }, // English/Latin/Cocos Islands
+ { 31, 7, 51, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1019,12 , 2, 1, 1, 6, 7 }, // English/Latin/Cook Islands
+ { 31, 7, 56, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1031,6 , 2, 1, 1, 6, 7 }, // English/Latin/Cyprus
+ { 31, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 228,5 , 233,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {68,75,75}, 144,3 , 4511,44 , 13,5 , 4,0 , 776,7 , 1037,7 , 2, 0, 1, 6, 7 }, // English/Latin/Denmark
+ { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1044,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica
+ { 31, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,82,78}, 41,3 , 4555,50 , 4,4 , 4,0 , 776,7 , 1052,7 , 2, 1, 1, 6, 7 }, // English/Latin/Eritrea
+ { 31, 7, 70, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {70,75,80}, 115,1 , 4605,74 , 4,4 , 4,0 , 776,7 , 1059,16 , 2, 1, 1, 6, 7 }, // English/Latin/Falkland Islands
+ { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {70,74,68}, 6,1 , 4679,47 , 4,4 , 4,0 , 776,7 , 1075,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji
+ { 31, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 243,4 , 247,9 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 1079,7 , 2, 1, 1, 6, 7 }, // English/Latin/Finland
+ { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 115,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1086,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey
+ { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,77,68}, 162,1 , 4758,50 , 4,4 , 4,0 , 776,7 , 1094,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia
+ { 31, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 1100,7 , 2, 1, 1, 6, 7 }, // English/Latin/Germany
+ { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,72,83}, 163,3 , 4808,47 , 4,4 , 4,0 , 776,7 , 1107,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana
+ { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,73,80}, 115,1 , 4855,53 , 4,4 , 4,0 , 776,7 , 1112,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar
+ { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1121,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada
+ { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1128,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam
+ { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,89,68}, 6,1 , 4908,56 , 4,4 , 4,0 , 776,7 , 1132,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana
+ { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 433,8 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {72,75,68}, 130,3 , 4964,56 , 4,4 , 4,0 , 776,7 , 1138,19 , 2, 1, 7, 6, 7 }, // English/Latin/Hong Kong
+ { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 210,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {73,78,82}, 117,1 , 5020,44 , 8,5 , 4,0 , 776,7 , 1157,5 , 2, 1, 7, 7, 7 }, // English/Latin/India
+ { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 98,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1162,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland
+ { 31, 7, 105, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 55,4 , 59,9 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {73,76,83}, 49,1 , 5064,62 , 4,4 , 4,0 , 776,7 , 1169,6 , 2, 1, 7, 5, 6 }, // English/Latin/Israel
+ { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 287,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {74,77,68}, 6,1 , 5126,53 , 4,4 , 4,0 , 776,7 , 1175,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica
+ { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {75,69,83}, 2,3 , 5179,53 , 4,4 , 4,0 , 776,7 , 1182,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya
+ { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1187,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati
+ { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 5232,61 , 4,4 , 4,0 , 776,7 , 1195,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho
+ { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {76,82,68}, 6,1 , 5293,53 , 4,4 , 4,0 , 776,7 , 1202,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia
+ { 31, 7, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,79,80}, 133,4 , 5346,53 , 4,4 , 4,0 , 776,7 , 1209,15 , 2, 1, 7, 6, 7 }, // English/Latin/Macau
+ { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,71,65}, 166,2 , 5399,54 , 4,4 , 4,0 , 776,7 , 1224,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar
+ { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,87,75}, 168,2 , 5453,53 , 4,4 , 4,0 , 776,7 , 1234,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi
+ { 31, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,89,82}, 170,2 , 5506,59 , 4,4 , 4,0 , 776,7 , 1240,8 , 2, 1, 1, 6, 7 }, // English/Latin/Malaysia
+ { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1248,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta
+ { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1253,16 , 2, 1, 7, 6, 7 }, // English/Latin/Marshall Islands
+ { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,85,82}, 172,2 , 5565,53 , 4,4 , 4,0 , 776,7 , 1269,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius
+ { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1278,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia
+ { 31, 7, 144, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1288,10 , 2, 1, 1, 6, 7 }, // English/Latin/Montserrat
+ { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,65,68}, 6,1 , 5618,53 , 4,4 , 4,0 , 776,7 , 1298,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia
+ { 31, 7, 149, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1305,5 , 2, 1, 1, 6, 7 }, // English/Latin/Nauru
+ { 31, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 8,5 , 23,6 , 776,7 , 1310,11 , 2, 1, 1, 6, 7 }, // English/Latin/Netherlands
+ { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 536,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1321,11 , 2, 1, 1, 6, 7 }, // English/Latin/New Zealand
+ { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,71,78}, 174,1 , 5671,50 , 4,4 , 4,0 , 776,7 , 1332,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria
+ { 31, 7, 158, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1339,4 , 2, 1, 1, 6, 7 }, // English/Latin/Niue
+ { 31, 7, 159, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1343,14 , 2, 1, 1, 6, 7 }, // English/Latin/Norfolk Island
+ { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1357,24 , 2, 1, 1, 6, 7 }, // English/Latin/Northern Mariana Islands
+ { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,75,82}, 172,2 , 5721,53 , 4,4 , 4,0 , 776,7 , 1381,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan
+ { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1389,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau
+ { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,71,75}, 127,1 , 5774,73 , 4,4 , 4,0 , 776,7 , 1394,16 , 2, 1, 1, 6, 7 }, // English/Latin/Papua New Guinea
+ { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,72,80}, 175,1 , 5847,53 , 4,4 , 4,0 , 776,7 , 1410,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines
+ { 31, 7, 171, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1421,16 , 2, 1, 1, 6, 7 }, // English/Latin/Pitcairn
+ { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1437,11 , 2, 1, 7, 6, 7 }, // English/Latin/Puerto Rico
+ { 31, 7, 179, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {82,87,70}, 176,2 , 5900,47 , 4,4 , 4,0 , 776,7 , 1448,6 , 0, 0, 1, 6, 7 }, // English/Latin/Rwanda
+ { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1454,17 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Kitts And Nevis
+ { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1471,9 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Lucia
+ { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1480,24 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Vincent And The Grenadines
+ { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {87,83,84}, 178,3 , 5947,40 , 4,4 , 4,0 , 776,7 , 1504,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa
+ { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,67,82}, 181,2 , 5987,59 , 4,4 , 4,0 , 776,7 , 1509,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles
+ { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,76,76}, 183,2 , 6046,68 , 4,4 , 4,0 , 776,7 , 1519,12 , 0, 0, 1, 6, 7 }, // English/Latin/Sierra Leone
+ { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 287,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,71,68}, 6,1 , 6114,56 , 4,4 , 4,0 , 776,7 , 1531,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore
+ { 31, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 29,7 , 776,7 , 1540,8 , 2, 1, 1, 6, 7 }, // English/Latin/Slovenia
+ { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,66,68}, 6,1 , 6170,74 , 4,4 , 4,0 , 776,7 , 1548,15 , 2, 1, 1, 6, 7 }, // English/Latin/Solomon Islands
+ { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 549,10 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 5232,61 , 4,4 , 4,0 , 776,7 , 1563,12 , 2, 1, 7, 6, 7 }, // English/Latin/South Africa
+ { 31, 7, 199, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,72,80}, 115,1 , 6244,56 , 4,4 , 4,0 , 776,7 , 1575,10 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Helena
+ { 31, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,68,71}, 0,0 , 6300,50 , 4,4 , 4,0 , 776,7 , 1585,5 , 2, 1, 6, 5, 6 }, // English/Latin/Sudan
+ { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,90,76}, 185,1 , 6350,53 , 4,4 , 4,0 , 776,7 , 1590,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland
+ { 31, 7, 205, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,69,75}, 186,2 , 6403,47 , 13,5 , 4,0 , 776,7 , 1599,6 , 2, 0, 1, 6, 7 }, // English/Latin/Sweden
+ { 31, 7, 206, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {67,72,70}, 0,0 , 6450,41 , 8,5 , 36,5 , 776,7 , 1605,11 , 2, 0, 1, 6, 7 }, // English/Latin/Switzerland
+ { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,90,83}, 188,3 , 6491,62 , 4,4 , 4,0 , 776,7 , 1616,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania
+ { 31, 7, 213, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1624,7 , 2, 1, 1, 6, 7 }, // English/Latin/Tokelau
+ { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,79,80}, 191,2 , 6553,49 , 4,4 , 4,0 , 776,7 , 1631,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga
+ { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,84,68}, 6,1 , 6602,80 , 4,4 , 4,0 , 776,7 , 1636,17 , 2, 1, 7, 6, 7 }, // English/Latin/Trinidad And Tobago
+ { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1653,22 , 2, 1, 1, 6, 7 }, // English/Latin/Turks And Caicos Islands
+ { 31, 7, 220, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1675,6 , 2, 1, 1, 6, 7 }, // English/Latin/Tuvalu
+ { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,71,88}, 193,3 , 6682,56 , 4,4 , 4,0 , 776,7 , 1681,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda
+ { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 210,9 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 70,2 , 67,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 115,1 , 6738,47 , 4,4 , 4,0 , 1687,15 , 1702,14 , 2, 1, 1, 6, 7 }, // English/Latin/United Kingdom
+ { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1716,21 , 2, 1, 7, 6, 7 }, // English/Latin/United States Minor Outlying Islands
+ { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {86,85,86}, 196,2 , 6785,44 , 4,4 , 4,0 , 776,7 , 1737,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu
+ { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1744,22 , 2, 1, 1, 6, 7 }, // English/Latin/British Virgin Islands
+ { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1766,19 , 2, 1, 7, 6, 7 }, // English/Latin/United States Virgin Islands
+ { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,77,87}, 127,1 , 6829,50 , 4,4 , 4,0 , 776,7 , 1785,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia
+ { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 433,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1791,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe
+ { 31, 7, 249, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1799,12 , 2, 1, 1, 6, 7 }, // English/Latin/Diego Garcia
+ { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 115,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1811,11 , 2, 1, 1, 6, 7 }, // English/Latin/Isle Of Man
+ { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 115,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1822,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey
+ { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,83,80}, 115,1 , 6879,68 , 4,4 , 4,0 , 776,7 , 1828,11 , 2, 1, 1, 6, 7 }, // English/Latin/South Sudan
+ { 31, 7, 256, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,78,71}, 151,4 , 6947,95 , 4,4 , 4,0 , 776,7 , 1839,12 , 2, 1, 1, 6, 7 }, // English/Latin/Sint Maarten
+ { 31, 7, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 4,4 , 4,0 , 776,7 , 1851,5 , 2, 1, 1, 6, 7 }, // English/Latin/World
+ { 31, 7, 261, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 776,7 , 1856,6 , 2, 1, 1, 6, 7 }, // English/Latin/Europe
+ { 32, 7, 260, 44, 160, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 219,9 , 219,9 , 559,8 , 567,26 , 37,5 , 256,25 , 5591,48 , 5639,91 , 134,24 , 5591,48 , 5639,91 , 134,24 , 2566,21 , 2587,51 , 2638,14 , 2566,21 , 2587,51 , 2638,14 , 72,3 , 69,3 , 325,6 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 41,6 , 4,0 , 1862,9 , 0,0 , 2, 1, 1, 6, 7 }, // Esperanto/Latin/World
+ { 33, 7, 68, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 228,8 , 228,8 , 174,8 , 593,18 , 37,5 , 8,10 , 5730,59 , 5789,91 , 5880,24 , 5730,59 , 5789,91 , 5880,24 , 2652,14 , 2666,63 , 2652,14 , 2652,14 , 2666,63 , 2652,14 , 0,2 , 0,2 , 331,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 7042,20 , 13,5 , 4,0 , 1871,5 , 1876,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia
+ { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 174,8 , 593,18 , 37,5 , 8,10 , 5904,48 , 5952,83 , 134,24 , 6035,59 , 5952,83 , 134,24 , 2729,28 , 2757,74 , 2831,14 , 2845,35 , 2757,74 , 2831,14 , 0,2 , 0,2 , 337,3 , 340,17 , 22,23 , {68,75,75}, 186,2 , 7062,43 , 13,5 , 4,0 , 1881,8 , 1889,7 , 2, 0, 1, 6, 7 }, // Faroese/Latin/Faroe Islands
+ { 34, 7, 58, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 174,8 , 593,18 , 37,5 , 8,10 , 5904,48 , 5952,83 , 134,24 , 6035,59 , 5952,83 , 134,24 , 2729,28 , 2757,74 , 2831,14 , 2845,35 , 2757,74 , 2831,14 , 0,2 , 0,2 , 337,3 , 340,17 , 22,23 , {68,75,75}, 144,3 , 7062,43 , 13,5 , 4,0 , 1881,8 , 656,7 , 2, 0, 1, 6, 7 }, // Faroese/Latin/Denmark
+ { 36, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 611,8 , 496,17 , 243,4 , 247,9 , 6094,69 , 6163,105 , 6268,24 , 6292,93 , 6385,129 , 6268,24 , 2880,21 , 2901,67 , 2968,14 , 2880,21 , 2982,81 , 2968,14 , 75,3 , 72,3 , 357,5 , 362,17 , 379,23 , {69,85,82}, 14,1 , 7105,20 , 13,5 , 4,0 , 1896,5 , 1901,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland
+ { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 1914,6 , 2, 1, 1, 6, 7 }, // French/Latin/France
+ { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {68,90,68}, 198,2 , 7125,51 , 13,5 , 4,0 , 1906,8 , 1920,7 , 2, 1, 6, 5, 6 }, // French/Latin/Algeria
+ { 37, 7, 21, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 536,7 , 98,16 , 37,5 , 281,23 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 1927,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium
+ { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 1935,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin
+ { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 1940,12 , 0, 0, 1, 6, 7 }, // French/Latin/Burkina Faso
+ { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {66,73,70}, 159,3 , 7235,53 , 13,5 , 4,0 , 1906,8 , 929,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi
+ { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 78,5 , 75,4 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 1952,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon
+ { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8221, 8220, 0,6 , 0,6 , 236,8 , 236,8 , 559,8 , 98,16 , 304,9 , 313,24 , 6662,64 , 6577,85 , 134,24 , 6662,64 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 66,4 , 63,4 , 402,6 , 211,17 , 228,23 , {67,65,68}, 6,1 , 7344,54 , 47,6 , 4,0 , 1960,17 , 960,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada
+ { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 1977,25 , 0, 0, 1, 6, 7 }, // French/Latin/Central African Republic
+ { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2002,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad
+ { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {75,77,70}, 36,2 , 7398,51 , 13,5 , 4,0 , 1906,8 , 2007,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros
+ { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {67,68,70}, 203,2 , 7449,53 , 13,5 , 4,0 , 1906,8 , 2014,14 , 2, 1, 1, 6, 7 }, // French/Latin/Congo Kinshasa
+ { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2028,17 , 0, 0, 1, 6, 7 }, // French/Latin/Congo Brazzaville
+ { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2045,13 , 0, 0, 1, 6, 7 }, // French/Latin/Ivory Coast
+ { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {68,74,70}, 38,3 , 7502,57 , 13,5 , 4,0 , 1906,8 , 2058,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti
+ { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2066,18 , 0, 0, 1, 6, 7 }, // French/Latin/Equatorial Guinea
+ { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2084,16 , 2, 1, 1, 6, 7 }, // French/Latin/French Guiana
+ { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,80,70}, 205,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2100,19 , 0, 0, 1, 6, 7 }, // French/Latin/French Polynesia
+ { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2119,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon
+ { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2124,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe
+ { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {71,78,70}, 209,2 , 7594,48 , 13,5 , 4,0 , 1906,8 , 2134,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea
+ { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {72,84,71}, 211,1 , 7642,57 , 13,5 , 4,0 , 1906,8 , 2140,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti
+ { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2145,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg
+ { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {77,71,65}, 166,2 , 7699,54 , 13,5 , 4,0 , 1906,8 , 1224,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar
+ { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2155,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali
+ { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2159,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique
+ { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {77,82,85}, 212,2 , 7753,66 , 13,5 , 4,0 , 1906,8 , 2169,10 , 2, 1, 1, 6, 7 }, // French/Latin/Mauritania
+ { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {77,85,82}, 172,2 , 7819,63 , 13,5 , 4,0 , 1906,8 , 2179,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius
+ { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2186,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte
+ { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2193,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco
+ { 37, 7, 145, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6726,61 , 6577,85 , 134,24 , 6726,61 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 66,4 , 63,4 , 402,6 , 211,17 , 228,23 , {77,65,68}, 214,3 , 7882,54 , 13,5 , 4,0 , 1906,8 , 2199,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco
+ { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,80,70}, 205,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2204,18 , 0, 0, 1, 6, 7 }, // French/Latin/New Caledonia
+ { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2222,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger
+ { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2227,10 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion
+ { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {82,87,70}, 176,2 , 7936,50 , 13,5 , 4,0 , 1906,8 , 1448,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda
+ { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2237,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal
+ { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {83,67,82}, 181,2 , 7986,71 , 13,5 , 4,0 , 1906,8 , 1509,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles
+ { 37, 7, 200, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2244,24 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Pierre And Miquelon
+ { 37, 7, 206, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 236,8 , 236,8 , 174,8 , 10,17 , 37,5 , 337,14 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {67,72,70}, 217,3 , 8057,45 , 13,5 , 53,6 , 2268,15 , 2283,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland
+ { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {83,89,80}, 220,2 , 8102,51 , 13,5 , 4,0 , 1906,8 , 2289,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria
+ { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2294,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo
+ { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {84,78,68}, 222,2 , 8153,51 , 13,5 , 4,0 , 1906,8 , 2298,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia
+ { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {86,85,86}, 196,2 , 8204,51 , 13,5 , 4,0 , 1906,8 , 1737,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu
+ { 37, 7, 235, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,80,70}, 205,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2305,16 , 0, 0, 1, 6, 7 }, // French/Latin/Wallis And Futuna Islands
+ { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2321,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy
+ { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2337,12 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin
+ { 38, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 6787,48 , 6835,95 , 134,24 , 6787,48 , 6835,95 , 134,24 , 3164,21 , 3185,54 , 85,14 , 3164,21 , 3185,54 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 8,5 , 59,6 , 2349,5 , 2354,8 , 2, 1, 1, 6, 7 }, // Western Frisian/Latin/Netherlands
+ { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 244,10 , 244,10 , 120,10 , 619,21 , 37,5 , 8,10 , 6930,61 , 6991,142 , 7133,24 , 6930,61 , 7157,167 , 7133,24 , 3239,28 , 3267,69 , 3336,14 , 3239,28 , 3267,69 , 3336,14 , 83,1 , 79,1 , 408,6 , 5,17 , 22,23 , {71,66,80}, 115,1 , 8255,86 , 4,4 , 4,0 , 2362,8 , 2370,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/United Kingdom
+ { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 7324,60 , 7384,87 , 7471,24 , 7495,60 , 7555,87 , 7642,36 , 3350,35 , 3385,49 , 3434,14 , 3448,35 , 3483,49 , 3532,21 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 2392,6 , 2398,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain
+ { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 171, 187, 0,6 , 0,6 , 261,8 , 261,8 , 174,8 , 667,19 , 37,5 , 8,10 , 7678,48 , 7726,99 , 7825,24 , 7678,48 , 7726,99 , 7825,24 , 3553,28 , 3581,62 , 3643,14 , 3553,28 , 3581,62 , 3643,14 , 0,2 , 0,2 , 414,5 , 419,33 , 22,23 , {71,69,76}, 224,1 , 8341,43 , 13,5 , 4,0 , 2404,7 , 2411,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia
+ { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2428,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany
+ { 42, 7, 14, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 8039,48 , 8087,83 , 134,24 , 8170,59 , 8087,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 8,5 , 4,0 , 2439,24 , 2463,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria
+ { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2473,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium
+ { 42, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 8039,48 , 8087,83 , 134,24 , 8170,59 , 8087,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2480,7 , 2, 1, 1, 6, 7 }, // German/Latin/Italy
+ { 42, 7, 123, 46, 8217, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {67,72,70}, 217,3 , 8403,58 , 8,5 , 4,0 , 2421,7 , 2487,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein
+ { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2500,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg
+ { 42, 7, 206, 46, 8217, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {67,72,70}, 217,3 , 8403,58 , 8,5 , 36,5 , 2509,21 , 2530,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland
+ { 43, 16, 85, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 278,9 , 278,9 , 287,6 , 10,17 , 18,7 , 25,12 , 8229,50 , 8279,115 , 8394,24 , 8418,50 , 8468,115 , 8394,24 , 3780,28 , 3808,55 , 3863,14 , 3780,28 , 3808,55 , 3863,14 , 84,4 , 80,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8461,19 , 13,5 , 4,0 , 2537,8 , 2545,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece
+ { 43, 16, 56, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 278,9 , 278,9 , 287,6 , 10,17 , 18,7 , 25,12 , 8229,50 , 8279,115 , 8394,24 , 8418,50 , 8468,115 , 8394,24 , 3780,28 , 3808,55 , 3863,14 , 3780,28 , 3808,55 , 3863,14 , 84,4 , 80,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8461,19 , 13,5 , 4,0 , 2537,8 , 2551,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus
+ { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 287,11 , 287,11 , 53,10 , 686,17 , 228,5 , 233,10 , 8583,48 , 8631,96 , 134,24 , 8583,48 , 8631,96 , 134,24 , 3877,28 , 3905,98 , 4003,14 , 3877,28 , 3905,98 , 4003,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 144,3 , 8480,62 , 4,4 , 65,5 , 2557,11 , 2568,16 , 2, 0, 1, 6, 7 }, // Greenlandic/Latin/Greenland
+ { 45, 7, 168, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,89,71}, 225,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 7, 6, 7 }, // Guarani/Latin/Paraguay
+ { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 298,9 , 298,9 , 287,6 , 210,18 , 351,8 , 359,13 , 8727,67 , 8794,87 , 8881,31 , 8727,67 , 8794,87 , 8881,31 , 4017,32 , 4049,53 , 4102,19 , 4017,32 , 4049,53 , 4102,19 , 0,2 , 0,2 , 457,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 8542,46 , 4,4 , 4,0 , 2584,7 , 2591,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India
+ { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 210,18 , 37,5 , 8,10 , 8912,48 , 8960,85 , 9045,24 , 8912,48 , 8960,85 , 9045,24 , 4121,28 , 4149,52 , 4201,14 , 4121,28 , 4149,52 , 4201,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 8588,12 , 8,5 , 4,0 , 2595,5 , 2600,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria
+ { 47, 1, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Hausa/Arabic/Nigeria
+ { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 210,18 , 37,5 , 8,10 , 8912,48 , 8960,85 , 9045,24 , 8912,48 , 8960,85 , 9045,24 , 4121,28 , 4149,52 , 4201,14 , 4121,28 , 4149,52 , 4201,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 163,3 , 0,7 , 8,5 , 4,0 , 2595,5 , 2608,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana
+ { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 210,18 , 37,5 , 8,10 , 8912,48 , 8960,85 , 9045,24 , 8912,48 , 8960,85 , 9045,24 , 4121,28 , 4149,52 , 4201,14 , 4121,28 , 4149,52 , 4201,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 8600,36 , 8,5 , 4,0 , 2595,5 , 2612,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger
+ { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 307,6 , 307,6 , 611,8 , 703,18 , 55,4 , 59,9 , 9069,58 , 9127,72 , 158,27 , 9069,58 , 9127,72 , 158,27 , 4215,46 , 4261,65 , 4326,21 , 4215,46 , 4261,65 , 4326,21 , 88,6 , 84,5 , 461,4 , 5,17 , 22,23 , {73,76,83}, 49,1 , 8636,54 , 70,6 , 76,8 , 2617,5 , 2622,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel
+ { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 313,9 , 322,8 , 287,6 , 10,17 , 18,7 , 25,12 , 9199,59 , 9258,73 , 9331,30 , 9199,59 , 9258,73 , 9331,30 , 4347,32 , 4379,53 , 4432,19 , 4347,32 , 4379,53 , 4432,19 , 94,9 , 89,7 , 465,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 8690,42 , 4,4 , 4,0 , 2627,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India
+ { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 330,8 , 330,8 , 721,13 , 734,19 , 55,4 , 59,9 , 9361,64 , 9425,98 , 9523,25 , 9361,64 , 9425,98 , 9523,25 , 4451,19 , 4470,52 , 4522,17 , 4451,19 , 4470,52 , 4522,17 , 103,3 , 96,3 , 469,4 , 5,17 , 22,23 , {72,85,70}, 226,2 , 8732,46 , 13,5 , 4,0 , 2637,6 , 2643,12 , 2, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary
+ { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 192,8 , 192,8 , 611,8 , 593,18 , 37,5 , 8,10 , 9548,59 , 9607,82 , 9689,24 , 9548,59 , 9607,82 , 9689,24 , 4539,35 , 4574,81 , 4655,14 , 4539,35 , 4574,81 , 4655,14 , 106,4 , 99,4 , 473,4 , 5,17 , 22,23 , {73,83,75}, 228,3 , 8778,49 , 13,5 , 4,0 , 2655,8 , 2663,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland
+ { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 338,10 , 348,9 , 27,8 , 80,18 , 228,5 , 233,10 , 9713,48 , 9761,87 , 134,24 , 9713,48 , 9761,87 , 134,24 , 4669,28 , 4697,43 , 4740,14 , 4669,28 , 4697,43 , 4740,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,68,82}, 231,2 , 8827,39 , 4,4 , 4,0 , 2669,9 , 2669,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia
{ 53, 7, 74, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/France
- { 55, 44, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 245,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Inuktitut/CanadianAboriginal/Canada
- { 55, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 245,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Inuktitut/Latin/Canada
- { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 339,11 , 226,10 , 120,10 , 98,16 , 37,5 , 8,10 , 9735,62 , 9797,107 , 9904,24 , 9735,62 , 9797,107 , 9904,24 , 4658,37 , 4695,75 , 4770,14 , 4658,37 , 4695,75 , 4770,14 , 64,4 , 61,4 , 434,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8821,31 , 4,4 , 4,0 , 2634,7 , 2641,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland
- { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 98,16 , 37,5 , 8,10 , 9928,48 , 9976,94 , 10070,24 , 9928,48 , 9976,94 , 10070,24 , 4784,28 , 4812,57 , 4869,14 , 4784,28 , 4812,57 , 4869,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8852,19 , 13,5 , 4,0 , 2645,8 , 2653,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy
- { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 98,16 , 37,5 , 8,10 , 9928,48 , 9976,94 , 10070,24 , 9928,48 , 9976,94 , 10070,24 , 4784,28 , 4812,57 , 4869,14 , 4784,28 , 4812,57 , 4869,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8852,19 , 13,5 , 4,0 , 2645,8 , 2659,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/SanMarino
- { 58, 7, 206, 46, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 236,7 , 236,7 , 175,8 , 10,17 , 37,5 , 8,10 , 9928,48 , 9976,94 , 10070,24 , 9928,48 , 9976,94 , 10070,24 , 4784,28 , 4812,57 , 4869,14 , 4784,28 , 4812,57 , 4869,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 229,3 , 8871,53 , 8,5 , 36,5 , 2645,8 , 2669,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland
- { 58, 7, 230, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 98,16 , 37,5 , 8,10 , 9928,48 , 9976,94 , 10070,24 , 9928,48 , 9976,94 , 10070,24 , 4784,28 , 4812,57 , 4869,14 , 4784,28 , 4812,57 , 4869,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8852,19 , 13,5 , 4,0 , 2645,8 , 2677,18 , 2, 1, 1, 6, 7 }, // Italian/Latin/VaticanCityState
- { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 161,5 , 161,5 , 161,5 , 161,5 , 522,10 , 393,13 , 55,4 , 302,10 , 4697,39 , 4697,39 , 158,27 , 4697,39 , 4697,39 , 158,27 , 4883,14 , 4897,28 , 4883,14 , 4883,14 , 4897,28 , 4883,14 , 110,2 , 104,2 , 440,3 , 297,17 , 22,23 , {74,80,89}, 139,1 , 8924,11 , 4,4 , 4,0 , 2695,3 , 2698,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan
- { 60, 7, 101, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,68,82}, 243,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 7, 6, 7 }, // Javanese/Latin/Indonesia
- { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 350,12 , 362,11 , 278,6 , 35,18 , 281,8 , 289,13 , 10094,63 , 10157,87 , 10244,31 , 10094,63 , 10157,87 , 10244,31 , 4925,33 , 4958,54 , 5012,20 , 4925,33 , 4958,54 , 5012,20 , 112,9 , 106,7 , 443,8 , 451,33 , 22,23 , {73,78,82}, 127,1 , 8935,49 , 4,4 , 4,0 , 2700,5 , 2705,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India
- { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 516,6 , 35,18 , 18,7 , 25,12 , 10275,72 , 10275,72 , 10347,24 , 10275,72 , 10275,72 , 10347,24 , 5032,54 , 5086,56 , 5142,14 , 5032,54 , 5086,56 , 5142,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 8984,23 , 8,5 , 4,0 , 2709,5 , 2714,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India
- { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 373,10 , 175,8 , 700,22 , 37,5 , 8,10 , 10371,60 , 10431,83 , 10514,24 , 10538,60 , 10598,83 , 10514,24 , 5156,21 , 5177,56 , 5233,14 , 5156,21 , 5247,56 , 5233,14 , 0,2 , 0,2 , 484,4 , 488,17 , 505,23 , {75,90,84}, 248,1 , 9007,58 , 13,5 , 4,0 , 2724,10 , 2734,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan
- { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 10681,60 , 10741,101 , 158,27 , 10681,60 , 10741,101 , 158,27 , 5303,35 , 5338,84 , 85,14 , 5303,35 , 5338,84 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,87,70}, 186,2 , 0,7 , 8,5 , 4,0 , 2743,11 , 1419,6 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda
- { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 383,10 , 383,10 , 278,6 , 722,23 , 37,5 , 8,10 , 10842,48 , 10890,80 , 10970,24 , 10994,59 , 11053,80 , 10970,24 , 5422,38 , 5460,57 , 5517,14 , 5422,38 , 5460,57 , 5517,14 , 121,5 , 113,14 , 484,4 , 528,17 , 22,23 , {75,71,83}, 249,3 , 9065,52 , 13,5 , 4,0 , 2754,8 , 2762,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan
- { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 393,7 , 393,7 , 745,9 , 754,16 , 312,7 , 319,13 , 11133,39 , 11133,39 , 11133,39 , 11133,39 , 11133,39 , 11133,39 , 5531,14 , 5545,28 , 5531,14 , 5531,14 , 5545,28 , 5531,14 , 126,2 , 127,2 , 545,3 , 5,17 , 22,23 , {75,82,87}, 252,1 , 9117,19 , 4,4 , 4,0 , 2772,3 , 2775,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/SouthKorea
- { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 393,7 , 393,7 , 745,9 , 754,16 , 312,7 , 319,13 , 11133,39 , 11133,39 , 11133,39 , 11133,39 , 11133,39 , 11133,39 , 5531,14 , 5545,28 , 5531,14 , 5531,14 , 5545,28 , 5531,14 , 126,2 , 127,2 , 545,3 , 5,17 , 22,23 , {75,80,87}, 253,3 , 9136,39 , 4,4 , 4,0 , 2772,3 , 2779,11 , 0, 0, 1, 6, 7 }, // Korean/Korean/NorthKorea
- { 67, 7, 217, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {84,82,89}, 256,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Kurdish/Latin/Turkey
- { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 11172,60 , 11232,106 , 158,27 , 11172,60 , 11232,106 , 158,27 , 5573,34 , 5607,89 , 85,14 , 5573,34 , 5607,89 , 85,14 , 128,5 , 129,5 , 45,4 , 5,17 , 22,23 , {66,73,70}, 169,3 , 9175,27 , 0,4 , 4,0 , 2790,8 , 2798,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi
- { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 400,9 , 406,8 , 770,19 , 55,4 , 332,24 , 11338,61 , 11399,75 , 158,27 , 11338,61 , 11399,75 , 158,27 , 5696,36 , 5732,57 , 5789,17 , 5696,36 , 5732,57 , 5789,17 , 133,8 , 134,8 , 45,4 , 5,17 , 22,23 , {76,65,75}, 257,1 , 9202,21 , 4,4 , 36,5 , 2806,3 , 2806,3 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos
- { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 409,8 , 409,8 , 175,8 , 789,26 , 37,5 , 8,10 , 11474,65 , 11539,101 , 134,24 , 11474,65 , 11539,101 , 134,24 , 5806,51 , 5857,72 , 5929,14 , 5943,51 , 5994,72 , 5929,14 , 141,14 , 142,11 , 548,5 , 297,17 , 22,23 , {69,85,82}, 14,1 , 9223,23 , 13,5 , 4,0 , 2809,8 , 2817,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia
- { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 417,9 , 417,9 , 406,8 , 98,16 , 37,5 , 8,10 , 11640,48 , 11688,203 , 11891,24 , 11640,48 , 11688,203 , 11891,24 , 6066,28 , 6094,100 , 6194,14 , 6066,28 , 6094,100 , 6194,14 , 155,8 , 153,6 , 45,4 , 5,17 , 22,23 , {67,68,70}, 215,2 , 9246,23 , 13,5 , 4,0 , 2824,7 , 2831,30 , 2, 1, 1, 6, 7 }, // Lingala/Latin/CongoKinshasa
- { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 417,9 , 417,9 , 406,8 , 98,16 , 37,5 , 8,10 , 11640,48 , 11688,203 , 11891,24 , 11640,48 , 11688,203 , 11891,24 , 6066,28 , 6094,100 , 6194,14 , 6066,28 , 6094,100 , 6194,14 , 155,8 , 153,6 , 45,4 , 5,17 , 22,23 , {65,79,65}, 258,2 , 9269,23 , 13,5 , 4,0 , 2824,7 , 2861,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola
- { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 417,9 , 417,9 , 406,8 , 98,16 , 37,5 , 8,10 , 11640,48 , 11688,203 , 11891,24 , 11640,48 , 11688,203 , 11891,24 , 6066,28 , 6094,100 , 6194,14 , 6066,28 , 6094,100 , 6194,14 , 155,8 , 153,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 9292,23 , 13,5 , 4,0 , 2824,7 , 2867,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CentralAfricanRepublic
- { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 417,9 , 417,9 , 406,8 , 98,16 , 37,5 , 8,10 , 11640,48 , 11688,203 , 11891,24 , 11640,48 , 11688,203 , 11891,24 , 6066,28 , 6094,100 , 6194,14 , 6066,28 , 6094,100 , 6194,14 , 155,8 , 153,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 9292,23 , 13,5 , 4,0 , 2824,7 , 2893,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CongoBrazzaville
- { 73, 7, 124, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 426,8 , 426,8 , 53,10 , 815,27 , 37,5 , 8,10 , 11915,70 , 11985,96 , 12081,24 , 11915,70 , 12105,98 , 12081,24 , 6208,21 , 6229,89 , 6318,14 , 6208,21 , 6229,89 , 6318,14 , 163,9 , 159,6 , 553,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 9315,30 , 13,5 , 4,0 , 2898,8 , 2906,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania
- { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 107,7 , 107,7 , 842,7 , 80,18 , 37,5 , 8,10 , 12203,61 , 12264,85 , 12349,24 , 12203,61 , 12264,85 , 12349,24 , 6332,35 , 6367,54 , 1649,14 , 6421,34 , 6367,54 , 1649,14 , 172,10 , 165,8 , 559,5 , 5,17 , 22,23 , {77,75,68}, 260,3 , 9345,56 , 13,5 , 4,0 , 2913,10 , 2923,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia
- { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 98,16 , 37,5 , 8,10 , 12373,48 , 12421,92 , 134,24 , 12373,48 , 12421,92 , 134,24 , 6455,34 , 6489,60 , 6549,14 , 6455,34 , 6489,60 , 6549,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,71,65}, 176,2 , 9401,13 , 8,5 , 4,0 , 2933,8 , 2941,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar
- { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 330,9 , 330,9 , 509,7 , 10,17 , 18,7 , 25,12 , 12513,48 , 12561,82 , 12643,24 , 12513,48 , 12561,82 , 12643,24 , 6563,28 , 6591,43 , 6634,14 , 6563,28 , 6591,43 , 6634,14 , 182,2 , 173,3 , 564,4 , 5,17 , 22,23 , {77,89,82}, 180,2 , 9414,39 , 4,4 , 4,0 , 2953,13 , 1211,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia
- { 76, 1, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,89,82}, 180,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Malay/Arabic/Malaysia
- { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 330,9 , 330,9 , 509,7 , 849,12 , 18,7 , 25,12 , 12513,48 , 12561,82 , 12643,24 , 12513,48 , 12561,82 , 12643,24 , 6563,28 , 6591,43 , 6634,14 , 6563,28 , 6591,43 , 6634,14 , 182,2 , 173,3 , 564,4 , 5,17 , 22,23 , {66,78,68}, 6,1 , 9453,31 , 8,5 , 4,0 , 2953,13 , 2966,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei
- { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 330,9 , 330,9 , 509,7 , 10,17 , 18,7 , 25,12 , 12513,48 , 12561,82 , 12643,24 , 12513,48 , 12561,82 , 12643,24 , 6563,28 , 6591,43 , 6634,14 , 6563,28 , 6591,43 , 6634,14 , 182,2 , 173,3 , 564,4 , 5,17 , 22,23 , {83,71,68}, 6,1 , 9484,37 , 4,4 , 4,0 , 2953,13 , 2972,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore
- { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 434,13 , 447,12 , 278,6 , 861,18 , 18,7 , 25,12 , 12667,62 , 12729,88 , 12817,32 , 12667,62 , 12729,88 , 12849,31 , 6648,41 , 6689,77 , 6766,22 , 6648,41 , 6788,76 , 6864,21 , 0,2 , 0,2 , 568,6 , 574,31 , 22,23 , {73,78,82}, 127,1 , 9521,40 , 4,4 , 4,0 , 2981,6 , 2987,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India
- { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 459,8 , 467,7 , 120,10 , 879,23 , 37,5 , 8,10 , 12880,48 , 12928,86 , 13014,36 , 12880,48 , 12928,86 , 13050,24 , 6885,28 , 6913,63 , 6976,21 , 6885,28 , 6913,63 , 6997,20 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 9561,27 , 4,4 , 4,0 , 2993,5 , 1219,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta
- { 79, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,90,68}, 263,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Maori/Latin/NewZealand
- { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 474,9 , 474,9 , 278,6 , 211,18 , 18,7 , 25,12 , 13074,66 , 13140,86 , 13226,32 , 13074,66 , 13140,86 , 13226,32 , 7017,32 , 7049,53 , 4336,19 , 7017,32 , 7049,53 , 4336,19 , 184,5 , 176,4 , 422,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 9588,43 , 4,4 , 4,0 , 2998,5 , 2589,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India
- { 82, 2, 143, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 902,29 , 37,5 , 8,10 , 13258,99 , 13357,189 , 158,27 , 13258,99 , 13357,189 , 158,27 , 7102,21 , 7123,43 , 7102,21 , 7102,21 , 7123,43 , 7102,21 , 189,3 , 180,3 , 484,4 , 528,17 , 22,23 , {77,78,84}, 266,1 , 9631,25 , 8,5 , 4,0 , 3003,6 , 3009,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia
- { 82, 8, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 267,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Mongolian/Mongolian/China
- { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 483,5 , 0,6 , 488,7 , 488,7 , 53,10 , 63,17 , 37,5 , 8,10 , 13546,85 , 13546,85 , 13631,27 , 13546,85 , 13658,85 , 13631,27 , 7166,33 , 7199,54 , 7253,18 , 7166,33 , 7199,54 , 7253,18 , 94,9 , 90,7 , 422,4 , 5,17 , 22,23 , {78,80,82}, 270,4 , 9656,49 , 8,5 , 4,0 , 3015,6 , 3021,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal
- { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 483,5 , 0,6 , 488,7 , 488,7 , 53,10 , 63,17 , 18,7 , 25,12 , 13546,85 , 13546,85 , 13631,27 , 13546,85 , 13658,85 , 13631,27 , 7166,33 , 7199,54 , 7253,18 , 7166,33 , 7199,54 , 7253,18 , 94,9 , 90,7 , 422,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 9705,49 , 8,5 , 4,0 , 3015,6 , 2589,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India
- { 85, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 183,8 , 183,8 , 931,10 , 469,17 , 37,5 , 8,10 , 5791,48 , 13743,83 , 134,24 , 5922,59 , 13743,83 , 134,24 , 2367,35 , 2302,51 , 2353,14 , 2367,35 , 2302,51 , 2353,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {78,79,75}, 196,2 , 9754,44 , 8,5 , 4,0 , 3026,12 , 3038,5 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/Norway
- { 85, 7, 203, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 183,8 , 183,8 , 931,10 , 469,17 , 37,5 , 8,10 , 5791,48 , 13743,83 , 134,24 , 5922,59 , 13743,83 , 134,24 , 2367,35 , 2302,51 , 2353,14 , 2367,35 , 2302,51 , 2353,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {78,79,75}, 196,2 , 9754,44 , 8,5 , 4,0 , 3026,12 , 3043,21 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/SvalbardAndJanMayenIslands
+ { 55, 44, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 233,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Inuktitut/Canadian Aboriginal/Canada
+ { 55, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 233,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Inuktitut/Latin/Canada
+ { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 357,11 , 244,10 , 120,10 , 98,16 , 37,5 , 8,10 , 9848,62 , 9910,107 , 10017,24 , 9848,62 , 9910,107 , 10017,24 , 4754,37 , 4791,75 , 4866,14 , 4754,37 , 4791,75 , 4866,14 , 110,4 , 103,4 , 477,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8866,31 , 4,4 , 4,0 , 2678,7 , 2685,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland
+ { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 98,16 , 37,5 , 8,10 , 10041,48 , 10089,94 , 10183,24 , 10041,48 , 10089,94 , 10183,24 , 4880,28 , 4908,57 , 4965,14 , 4880,28 , 4908,57 , 4965,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2689,8 , 2697,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy
+ { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 98,16 , 37,5 , 8,10 , 10041,48 , 10089,94 , 10183,24 , 10041,48 , 10089,94 , 10183,24 , 4880,28 , 4908,57 , 4965,14 , 4880,28 , 4908,57 , 4965,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2689,8 , 2703,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/San Marino
+ { 58, 7, 206, 46, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 254,7 , 254,7 , 174,8 , 10,17 , 37,5 , 8,10 , 10041,48 , 10089,94 , 10183,24 , 10041,48 , 10089,94 , 10183,24 , 4880,28 , 4908,57 , 4965,14 , 4880,28 , 4908,57 , 4965,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 217,3 , 8916,53 , 8,5 , 36,5 , 2689,8 , 2713,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland
+ { 58, 7, 230, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 98,16 , 37,5 , 8,10 , 10041,48 , 10089,94 , 10183,24 , 10041,48 , 10089,94 , 10183,24 , 4880,28 , 4908,57 , 4965,14 , 4880,28 , 4908,57 , 4965,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2689,8 , 2721,18 , 2, 1, 1, 6, 7 }, // Italian/Latin/Vatican City State
+ { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 170,5 , 170,5 , 549,10 , 420,13 , 55,4 , 372,10 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 4979,14 , 4993,28 , 4979,14 , 4979,14 , 4993,28 , 4979,14 , 114,2 , 107,2 , 483,3 , 340,17 , 22,23 , {74,80,89}, 129,1 , 8969,11 , 4,4 , 4,0 , 2739,3 , 2742,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan
+ { 60, 7, 101, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,68,82}, 231,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 7, 6, 7 }, // Javanese/Latin/Indonesia
+ { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 368,12 , 380,11 , 287,6 , 35,18 , 351,8 , 359,13 , 10207,63 , 10270,87 , 10357,31 , 10388,69 , 10270,87 , 10357,31 , 5021,33 , 5054,54 , 5108,20 , 5021,33 , 5054,54 , 5108,20 , 116,9 , 109,7 , 486,8 , 494,33 , 22,23 , {73,78,82}, 117,1 , 8980,49 , 4,4 , 4,0 , 2744,5 , 2749,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India
+ { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 543,6 , 35,18 , 18,7 , 25,12 , 10457,72 , 10457,72 , 10529,24 , 10457,72 , 10457,72 , 10529,24 , 5128,54 , 5182,56 , 5238,14 , 5128,54 , 5182,56 , 5238,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 9029,23 , 8,5 , 4,0 , 2753,5 , 2758,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India
+ { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 391,10 , 174,8 , 753,22 , 37,5 , 8,10 , 10553,60 , 10613,83 , 10696,24 , 10720,60 , 10780,83 , 10696,24 , 5252,21 , 5273,56 , 5329,14 , 5252,21 , 5343,56 , 5329,14 , 0,2 , 0,2 , 527,4 , 531,17 , 548,23 , {75,90,84}, 236,1 , 9052,58 , 13,5 , 4,0 , 2768,10 , 2778,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan
+ { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 10863,60 , 10923,101 , 158,27 , 10863,60 , 10923,101 , 158,27 , 5399,35 , 5434,84 , 85,14 , 5399,35 , 5434,84 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,87,70}, 176,2 , 0,7 , 8,5 , 4,0 , 2787,11 , 2798,8 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda
+ { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 401,10 , 401,10 , 287,6 , 775,23 , 37,5 , 8,10 , 11024,48 , 11072,80 , 11152,24 , 11176,59 , 11235,80 , 11152,24 , 5518,38 , 5556,57 , 5613,14 , 5518,38 , 5556,57 , 5613,14 , 125,5 , 116,14 , 527,4 , 571,17 , 22,23 , {75,71,83}, 237,3 , 9110,52 , 13,5 , 4,0 , 2806,8 , 2814,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan
+ { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 411,7 , 411,7 , 798,9 , 807,16 , 382,7 , 389,13 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 5627,14 , 5641,28 , 5627,14 , 5627,14 , 5641,28 , 5627,14 , 130,2 , 130,2 , 588,3 , 5,17 , 22,23 , {75,82,87}, 240,1 , 9162,19 , 4,4 , 4,0 , 2824,3 , 2827,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/South Korea
+ { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 411,7 , 411,7 , 798,9 , 807,16 , 382,7 , 389,13 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 5627,14 , 5641,28 , 5627,14 , 5627,14 , 5641,28 , 5627,14 , 130,2 , 130,2 , 588,3 , 5,17 , 22,23 , {75,80,87}, 241,3 , 9181,39 , 4,4 , 4,0 , 2824,3 , 2831,11 , 0, 0, 1, 6, 7 }, // Korean/Korean/North Korea
+ { 67, 7, 217, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {84,82,89}, 244,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Kurdish/Latin/Turkey
+ { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 11354,60 , 11414,106 , 158,27 , 11354,60 , 11414,106 , 158,27 , 5669,34 , 5703,89 , 85,14 , 5669,34 , 5703,89 , 85,14 , 132,5 , 132,5 , 45,4 , 5,17 , 22,23 , {66,73,70}, 159,3 , 9220,27 , 0,4 , 4,0 , 2842,8 , 2850,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi
+ { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 418,9 , 433,8 , 823,19 , 55,4 , 402,24 , 11520,61 , 11581,75 , 158,27 , 11520,61 , 11581,75 , 158,27 , 5792,36 , 5828,57 , 5885,17 , 5792,36 , 5828,57 , 5885,17 , 137,8 , 137,8 , 45,4 , 5,17 , 22,23 , {76,65,75}, 245,1 , 9247,21 , 4,4 , 36,5 , 2858,3 , 2858,3 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos
+ { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 427,8 , 427,8 , 174,8 , 842,26 , 37,5 , 8,10 , 11656,65 , 11721,101 , 134,24 , 11656,65 , 11721,101 , 134,24 , 5902,51 , 5953,72 , 6025,14 , 6039,51 , 6090,72 , 6025,14 , 145,14 , 145,11 , 591,5 , 340,17 , 22,23 , {69,85,82}, 14,1 , 9268,23 , 13,5 , 4,0 , 2861,8 , 2869,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia
+ { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 435,9 , 435,9 , 433,8 , 98,16 , 37,5 , 8,10 , 11822,48 , 11870,203 , 12073,24 , 11822,48 , 11870,203 , 12073,24 , 6162,28 , 6190,100 , 6290,14 , 6162,28 , 6190,100 , 6290,14 , 159,8 , 156,6 , 45,4 , 5,17 , 22,23 , {67,68,70}, 203,2 , 9291,23 , 13,5 , 4,0 , 2876,7 , 2883,30 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Congo Kinshasa
+ { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 435,9 , 435,9 , 433,8 , 98,16 , 37,5 , 8,10 , 11822,48 , 11870,203 , 12073,24 , 11822,48 , 11870,203 , 12073,24 , 6162,28 , 6190,100 , 6290,14 , 6162,28 , 6190,100 , 6290,14 , 159,8 , 156,6 , 45,4 , 5,17 , 22,23 , {65,79,65}, 246,2 , 9314,23 , 13,5 , 4,0 , 2876,7 , 2913,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola
+ { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 435,9 , 435,9 , 433,8 , 98,16 , 37,5 , 8,10 , 11822,48 , 11870,203 , 12073,24 , 11822,48 , 11870,203 , 12073,24 , 6162,28 , 6190,100 , 6290,14 , 6162,28 , 6190,100 , 6290,14 , 159,8 , 156,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 9337,23 , 13,5 , 4,0 , 2876,7 , 2919,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/Central African Republic
+ { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 435,9 , 435,9 , 433,8 , 98,16 , 37,5 , 8,10 , 11822,48 , 11870,203 , 12073,24 , 11822,48 , 11870,203 , 12073,24 , 6162,28 , 6190,100 , 6290,14 , 6162,28 , 6190,100 , 6290,14 , 159,8 , 156,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 9337,23 , 13,5 , 4,0 , 2876,7 , 2945,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/Congo Brazzaville
+ { 73, 7, 124, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 444,8 , 444,8 , 53,10 , 868,27 , 37,5 , 8,10 , 12097,70 , 12167,96 , 12263,24 , 12097,70 , 12287,98 , 12263,24 , 6304,21 , 6325,89 , 6414,14 , 6304,21 , 6325,89 , 6414,14 , 167,9 , 162,6 , 596,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 9360,30 , 13,5 , 4,0 , 2950,8 , 2958,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania
+ { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 895,7 , 80,18 , 37,5 , 8,10 , 12385,61 , 12446,85 , 12531,24 , 12385,61 , 12446,85 , 12531,24 , 6428,35 , 6463,54 , 1659,14 , 6517,34 , 6463,54 , 1659,14 , 176,10 , 168,8 , 602,5 , 5,17 , 22,23 , {77,75,68}, 248,3 , 9390,56 , 13,5 , 4,0 , 2965,10 , 2975,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia
+ { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 98,16 , 37,5 , 8,10 , 12555,48 , 12603,92 , 134,24 , 12555,48 , 12603,92 , 134,24 , 6551,34 , 6585,60 , 6645,14 , 6551,34 , 6585,60 , 6645,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,71,65}, 166,2 , 9446,13 , 8,5 , 4,0 , 2985,8 , 2993,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar
+ { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 536,7 , 10,17 , 18,7 , 25,12 , 12695,48 , 12743,82 , 12825,24 , 12695,48 , 12743,82 , 12825,24 , 6659,28 , 6687,43 , 6730,14 , 6659,28 , 6687,43 , 6730,14 , 186,2 , 176,3 , 607,4 , 5,17 , 22,23 , {77,89,82}, 170,2 , 9459,39 , 4,4 , 4,0 , 3005,6 , 1240,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia
+ { 76, 1, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,89,82}, 170,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Malay/Arabic/Malaysia
+ { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 536,7 , 902,12 , 18,7 , 25,12 , 12695,48 , 12743,82 , 12825,24 , 12695,48 , 12743,82 , 12825,24 , 6659,28 , 6687,43 , 6730,14 , 6659,28 , 6687,43 , 6730,14 , 186,2 , 176,3 , 607,4 , 5,17 , 22,23 , {66,78,68}, 6,1 , 9498,31 , 8,5 , 4,0 , 3005,6 , 3011,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei
+ { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 536,7 , 10,17 , 18,7 , 25,12 , 12695,48 , 12743,82 , 12825,24 , 12695,48 , 12743,82 , 12825,24 , 6659,28 , 6687,43 , 6730,14 , 6659,28 , 6687,43 , 6730,14 , 186,2 , 176,3 , 607,4 , 5,17 , 22,23 , {83,71,68}, 6,1 , 9529,37 , 4,4 , 4,0 , 3005,6 , 3017,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore
+ { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 452,13 , 465,12 , 287,6 , 914,18 , 18,7 , 25,12 , 12849,62 , 12911,88 , 12999,32 , 12849,62 , 12911,88 , 12999,32 , 6744,41 , 6785,77 , 6862,22 , 6744,41 , 6884,76 , 6960,21 , 0,2 , 0,2 , 611,6 , 617,31 , 22,23 , {73,78,82}, 117,1 , 9566,40 , 4,4 , 4,0 , 3026,6 , 3032,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India
+ { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 477,8 , 485,7 , 120,10 , 932,23 , 37,5 , 8,10 , 13031,48 , 13079,86 , 13165,36 , 13031,48 , 13079,86 , 13201,24 , 6981,28 , 7009,63 , 7072,21 , 6981,28 , 7009,63 , 7093,20 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 9606,27 , 4,4 , 4,0 , 3038,5 , 1248,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta
+ { 79, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,90,68}, 251,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Maori/Latin/New Zealand
+ { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 492,9 , 492,9 , 287,6 , 210,18 , 18,7 , 25,12 , 13225,66 , 13291,86 , 13377,32 , 13225,66 , 13291,86 , 13377,32 , 7113,32 , 7145,53 , 4432,19 , 7113,32 , 7145,53 , 4432,19 , 188,5 , 179,4 , 465,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 9633,43 , 4,4 , 4,0 , 3043,5 , 2633,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India
+ { 82, 2, 143, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 955,10 , 965,16 , 37,5 , 87,12 , 13409,99 , 13508,190 , 13698,38 , 13409,99 , 13508,190 , 13698,38 , 7198,21 , 7219,43 , 7198,21 , 7198,21 , 7219,43 , 7198,21 , 193,3 , 183,3 , 527,4 , 571,17 , 22,23 , {77,78,84}, 254,1 , 9676,25 , 8,5 , 4,0 , 3048,6 , 3054,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia
+ { 82, 8, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 255,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Mongolian/Mongolian/China
+ { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 501,5 , 0,6 , 506,7 , 506,7 , 245,6 , 63,17 , 37,5 , 8,10 , 13736,85 , 13736,85 , 13821,53 , 13736,85 , 13736,85 , 13874,52 , 7262,33 , 7295,54 , 7349,18 , 7262,33 , 7295,54 , 7349,18 , 94,9 , 89,7 , 465,4 , 5,17 , 22,23 , {78,80,82}, 258,4 , 9701,49 , 8,5 , 4,0 , 3060,6 , 3066,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal
+ { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 501,5 , 0,6 , 506,7 , 506,7 , 245,6 , 63,17 , 18,7 , 25,12 , 13736,85 , 13736,85 , 13821,53 , 13736,85 , 13736,85 , 13874,52 , 7262,33 , 7295,54 , 7349,18 , 7262,33 , 7295,54 , 7349,18 , 94,9 , 89,7 , 465,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 9750,49 , 8,5 , 4,0 , 3060,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India
+ { 85, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 981,10 , 496,17 , 37,5 , 8,10 , 5904,48 , 13926,83 , 134,24 , 6035,59 , 13926,83 , 134,24 , 2377,35 , 2312,51 , 2363,14 , 2377,35 , 2312,51 , 2363,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {78,79,75}, 186,2 , 9799,44 , 8,5 , 4,0 , 3071,12 , 3083,5 , 2, 0, 1, 6, 7 }, // Norwegian Bokmal/Latin/Norway
+ { 85, 7, 203, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 981,10 , 496,17 , 37,5 , 8,10 , 5904,48 , 13926,83 , 134,24 , 6035,59 , 13926,83 , 134,24 , 2377,35 , 2312,51 , 2363,14 , 2377,35 , 2312,51 , 2363,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {78,79,75}, 186,2 , 9799,44 , 8,5 , 4,0 , 3071,12 , 3088,21 , 2, 0, 1, 6, 7 }, // Norwegian Bokmal/Latin/Svalbard And Jan Mayen Islands
{ 86, 7, 74, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Occitan/Latin/France
- { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 941,6 , 10,17 , 18,7 , 25,12 , 13826,86 , 13826,86 , 13912,32 , 13826,86 , 13826,86 , 13912,32 , 7271,33 , 7304,54 , 7358,18 , 7271,33 , 7304,54 , 7358,18 , 68,2 , 65,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 9798,11 , 8,5 , 4,0 , 3064,5 , 3069,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India
- { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 385,8 , 947,20 , 55,4 , 356,11 , 13944,68 , 13944,68 , 158,27 , 13944,68 , 13944,68 , 158,27 , 7376,49 , 7376,49 , 85,14 , 7376,49 , 7376,49 , 85,14 , 192,4 , 183,4 , 45,4 , 5,17 , 22,23 , {65,70,78}, 274,1 , 9809,25 , 13,5 , 4,0 , 3073,4 , 3077,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan
- { 89, 1, 102, 1643, 1644, 1563, 37, 1776, 45, 43, 101, 171, 187, 8249, 8250, 495,7 , 495,7 , 502,8 , 510,7 , 385,8 , 98,16 , 55,4 , 356,11 , 14012,70 , 14012,70 , 14082,24 , 14106,74 , 14106,74 , 14082,24 , 7376,49 , 7376,49 , 7425,14 , 7376,49 , 7376,49 , 7425,14 , 196,9 , 187,8 , 605,4 , 609,39 , 22,23 , {73,82,82}, 275,4 , 9834,37 , 74,5 , 4,0 , 3086,5 , 3091,5 , 0, 0, 6, 5, 5 }, // Persian/Arabic/Iran
- { 89, 1, 1, 1643, 1644, 1563, 37, 1776, 45, 43, 101, 171, 187, 8249, 8250, 495,7 , 495,7 , 502,8 , 510,7 , 385,8 , 98,16 , 55,4 , 356,11 , 14180,68 , 14180,68 , 14248,24 , 14272,62 , 14180,68 , 14248,24 , 7376,49 , 7376,49 , 7425,14 , 7376,49 , 7376,49 , 7425,14 , 196,9 , 187,8 , 605,4 , 609,39 , 22,23 , {65,70,78}, 274,1 , 9871,55 , 8,5 , 4,0 , 3096,3 , 3077,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan
- { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 154,7 , 154,7 , 931,10 , 10,17 , 37,5 , 8,10 , 14334,48 , 14382,97 , 14479,24 , 14334,48 , 14503,99 , 14602,24 , 7439,34 , 7473,59 , 7532,14 , 7439,34 , 7473,59 , 7546,14 , 0,2 , 0,2 , 283,5 , 5,17 , 22,23 , {80,76,78}, 279,2 , 9926,77 , 13,5 , 4,0 , 3099,6 , 3105,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland
- { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 236,7 , 236,7 , 120,10 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7560,28 , 7588,79 , 7667,14 , 7560,28 , 7588,79 , 7667,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,82,76}, 281,2 , 10003,54 , 4,4 , 4,0 , 3111,9 , 3120,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil
- { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {65,79,65}, 258,2 , 10057,54 , 13,5 , 4,0 , 3111,9 , 3126,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola
- { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {67,86,69}, 283,1 , 10111,69 , 13,5 , 4,0 , 3111,9 , 3132,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/CapeVerde
- { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {85,83,68}, 165,3 , 10180,81 , 13,5 , 4,0 , 3111,9 , 3142,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/EastTimor
- { 91, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 10261,59 , 13,5 , 4,0 , 3111,9 , 3153,16 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/EquatorialGuinea
- { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {88,79,70}, 210,3 , 10320,62 , 13,5 , 4,0 , 3111,9 , 3169,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/GuineaBissau
- { 91, 7, 125, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 10382,20 , 13,5 , 4,0 , 3111,9 , 3181,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Luxembourg
- { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 18,7 , 25,12 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {77,79,80}, 143,4 , 10402,53 , 13,5 , 4,0 , 3111,9 , 3191,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau
- { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {77,90,78}, 284,3 , 10455,72 , 13,5 , 4,0 , 3111,9 , 3210,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique
- { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 10382,20 , 13,5 , 4,0 , 3220,17 , 3237,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal
- { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {83,84,68}, 287,2 , 10527,92 , 13,5 , 4,0 , 3111,9 , 3245,19 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/SaoTomeAndPrincipe
- { 91, 7, 206, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 587,27 , 37,5 , 8,10 , 14626,48 , 14674,89 , 134,24 , 14626,48 , 14674,89 , 134,24 , 7681,49 , 7588,79 , 7667,14 , 7681,49 , 7588,79 , 7667,14 , 205,8 , 195,8 , 0,5 , 5,17 , 22,23 , {67,72,70}, 229,3 , 10619,45 , 13,5 , 4,0 , 3111,9 , 3264,5 , 2, 0, 1, 6, 7 }, // Portuguese/Latin/Switzerland
- { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 517,9 , 517,9 , 278,6 , 10,17 , 18,7 , 25,12 , 14763,50 , 14813,68 , 14881,28 , 14763,50 , 14813,68 , 14881,28 , 7730,36 , 7766,57 , 7823,23 , 7730,36 , 7766,57 , 7823,23 , 213,6 , 203,6 , 648,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 10664,39 , 4,4 , 4,0 , 3269,6 , 3275,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India
- { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 80,18 , 18,7 , 25,12 , 14909,67 , 14909,67 , 158,27 , 14909,67 , 14909,67 , 158,27 , 7846,37 , 7846,37 , 85,14 , 7846,37 , 7846,37 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,75,82}, 289,1 , 10703,13 , 79,6 , 4,0 , 3279,6 , 3285,7 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan
- { 93, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 211,18 , 37,5 , 8,10 , 14976,48 , 15024,128 , 158,27 , 14976,48 , 15024,128 , 158,27 , 7883,28 , 7911,53 , 7964,14 , 7883,28 , 7911,53 , 7964,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {80,69,78}, 290,2 , 0,7 , 8,5 , 4,0 , 3292,8 , 3300,4 , 2, 1, 7, 6, 7 }, // Quechua/Latin/Peru
- { 93, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 211,18 , 37,5 , 8,10 , 14976,48 , 15024,128 , 158,27 , 14976,48 , 15024,128 , 158,27 , 7883,28 , 7911,53 , 7964,14 , 7883,28 , 7911,53 , 7964,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {66,79,66}, 292,2 , 0,7 , 8,5 , 4,0 , 3292,8 , 3304,7 , 2, 1, 1, 6, 7 }, // Quechua/Latin/Bolivia
- { 93, 7, 63, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 211,18 , 37,5 , 8,10 , 14976,48 , 15024,128 , 158,27 , 14976,48 , 15024,128 , 158,27 , 7883,28 , 7911,53 , 7964,14 , 7883,28 , 7911,53 , 7964,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 8,5 , 4,0 , 3292,8 , 3311,7 , 2, 1, 1, 6, 7 }, // Quechua/Latin/Ecuador
- { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 348,8 , 967,28 , 37,5 , 8,10 , 15152,67 , 15219,92 , 15311,24 , 15152,67 , 15219,92 , 15311,24 , 7978,23 , 8001,56 , 8057,14 , 7978,23 , 8001,56 , 8057,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 229,3 , 10716,46 , 13,5 , 4,0 , 3318,9 , 3327,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland
- { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 526,8 , 526,8 , 931,10 , 10,17 , 37,5 , 8,10 , 15335,60 , 15395,98 , 15493,24 , 15335,60 , 15395,98 , 15493,24 , 8071,34 , 8105,48 , 3054,14 , 8071,34 , 8105,48 , 3054,14 , 64,4 , 61,4 , 652,4 , 5,17 , 22,23 , {82,79,78}, 294,3 , 10762,57 , 13,5 , 4,0 , 3333,6 , 3339,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania
- { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 526,8 , 526,8 , 931,10 , 10,17 , 37,5 , 8,10 , 15335,60 , 15395,98 , 15493,24 , 15335,60 , 15395,98 , 15493,24 , 8153,28 , 8105,48 , 8181,16 , 8153,28 , 8105,48 , 8181,16 , 64,4 , 61,4 , 652,4 , 5,17 , 22,23 , {77,68,76}, 297,1 , 10819,69 , 13,5 , 4,0 , 3346,13 , 3359,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova
- { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 107,7 , 107,7 , 931,10 , 326,22 , 55,4 , 59,9 , 15517,62 , 11053,80 , 10970,24 , 15579,62 , 15641,82 , 10970,24 , 8197,21 , 8218,62 , 8280,14 , 8197,21 , 8218,62 , 8197,21 , 219,2 , 209,2 , 226,5 , 528,17 , 22,23 , {82,85,66}, 129,1 , 10888,89 , 13,5 , 4,0 , 3376,7 , 3383,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia
- { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 107,7 , 107,7 , 931,10 , 326,22 , 55,4 , 59,9 , 15517,62 , 11053,80 , 10970,24 , 15579,62 , 15641,82 , 10970,24 , 8197,21 , 8218,62 , 8280,14 , 8197,21 , 8218,62 , 8197,21 , 219,2 , 209,2 , 226,5 , 528,17 , 22,23 , {66,89,78}, 0,2 , 10977,94 , 13,5 , 4,0 , 3376,7 , 472,8 , 2, 0, 1, 6, 7 }, // Russian/Cyrillic/Belarus
- { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 107,7 , 107,7 , 931,10 , 326,22 , 55,4 , 59,9 , 15517,62 , 11053,80 , 10970,24 , 15579,62 , 15641,82 , 10970,24 , 8197,21 , 8218,62 , 8280,14 , 8197,21 , 8218,62 , 8197,21 , 219,2 , 209,2 , 226,5 , 528,17 , 22,23 , {75,90,84}, 248,1 , 11071,83 , 13,5 , 4,0 , 3376,7 , 3389,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan
- { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 107,7 , 107,7 , 931,10 , 326,22 , 55,4 , 59,9 , 15517,62 , 11053,80 , 10970,24 , 15579,62 , 15641,82 , 10970,24 , 8197,21 , 8218,62 , 8280,14 , 8197,21 , 8218,62 , 8197,21 , 219,2 , 209,2 , 226,5 , 528,17 , 22,23 , {75,71,83}, 249,3 , 11154,82 , 13,5 , 4,0 , 3376,7 , 3398,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan
- { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 107,7 , 107,7 , 931,10 , 326,22 , 55,4 , 59,9 , 15517,62 , 11053,80 , 10970,24 , 15579,62 , 15641,82 , 10970,24 , 8197,21 , 8218,62 , 8280,14 , 8197,21 , 8218,62 , 8197,21 , 219,2 , 209,2 , 226,5 , 528,17 , 22,23 , {77,68,76}, 297,1 , 11236,79 , 13,5 , 4,0 , 3376,7 , 3406,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova
- { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 107,7 , 107,7 , 931,10 , 326,22 , 37,5 , 8,10 , 15517,62 , 11053,80 , 10970,24 , 15579,62 , 15641,82 , 10970,24 , 8197,21 , 8218,62 , 8280,14 , 8197,21 , 8218,62 , 8197,21 , 0,2 , 0,2 , 226,5 , 528,17 , 22,23 , {85,65,72}, 298,1 , 11315,92 , 13,5 , 4,0 , 3376,7 , 3413,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine
- { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 15723,48 , 15771,91 , 15862,24 , 15723,48 , 15771,91 , 15862,24 , 8294,28 , 8322,66 , 8388,14 , 8294,28 , 8322,66 , 8388,14 , 221,2 , 211,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 11407,25 , 4,4 , 36,5 , 3420,5 , 3425,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/CentralAfricanRepublic
- { 99, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Sanskrit/Devanagari/India
- { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 107,7 , 107,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 15886,48 , 15934,81 , 12349,24 , 15886,48 , 15934,81 , 12349,24 , 8402,28 , 8430,52 , 8482,14 , 8402,28 , 8430,52 , 8482,14 , 223,9 , 213,8 , 656,7 , 5,17 , 22,23 , {82,83,68}, 299,3 , 11432,58 , 13,5 , 4,0 , 3447,6 , 3453,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
- { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 107,7 , 107,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 16015,58 , 15934,81 , 12349,24 , 16015,58 , 15934,81 , 12349,24 , 8496,33 , 8529,55 , 8482,14 , 8496,33 , 8529,55 , 8482,14 , 232,11 , 213,8 , 656,7 , 5,17 , 22,23 , {66,65,77}, 302,2 , 11490,174 , 13,5 , 4,0 , 3447,6 , 3459,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/BosniaAndHerzegowina
- { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 107,7 , 107,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 16015,58 , 15934,81 , 12349,24 , 16015,58 , 15934,81 , 12349,24 , 8496,33 , 8529,55 , 8482,14 , 8496,33 , 8529,55 , 8482,14 , 232,11 , 213,8 , 656,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11664,23 , 13,5 , 4,0 , 3447,6 , 3478,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
- { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 107,7 , 107,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 16015,58 , 15934,81 , 12349,24 , 16015,58 , 15934,81 , 12349,24 , 8496,33 , 8430,52 , 8482,14 , 8496,33 , 8430,52 , 8482,14 , 223,9 , 213,8 , 656,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11664,23 , 13,5 , 4,0 , 3447,6 , 3487,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo
- { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 154,7 , 154,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 16073,58 , 16131,81 , 16212,24 , 16073,58 , 16131,81 , 16212,24 , 8584,33 , 8617,57 , 2162,14 , 8584,33 , 8617,57 , 2162,14 , 243,11 , 221,8 , 276,7 , 5,17 , 22,23 , {66,65,77}, 150,2 , 11687,174 , 13,5 , 4,0 , 3493,6 , 591,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/BosniaAndHerzegowina
- { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 154,7 , 154,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 16073,58 , 16131,81 , 16212,24 , 16073,58 , 16131,81 , 16212,24 , 8584,33 , 8617,57 , 2162,14 , 8584,33 , 8617,57 , 2162,14 , 243,11 , 221,8 , 276,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11861,23 , 13,5 , 4,0 , 3493,6 , 3499,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
- { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 154,7 , 154,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 16236,48 , 16131,81 , 16212,24 , 16236,48 , 16131,81 , 16212,24 , 8674,28 , 8702,54 , 2162,14 , 8674,28 , 8702,54 , 2162,14 , 254,9 , 221,8 , 276,7 , 5,17 , 22,23 , {82,83,68}, 299,3 , 11884,58 , 13,5 , 4,0 , 3493,6 , 3508,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
- { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 154,7 , 154,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 16073,58 , 16131,81 , 16212,24 , 16073,58 , 16131,81 , 16212,24 , 8584,33 , 8702,54 , 2162,14 , 8584,33 , 8702,54 , 2162,14 , 254,9 , 221,8 , 276,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11861,23 , 13,5 , 4,0 , 3493,6 , 3514,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo
- { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 534,9 , 534,9 , 175,8 , 1022,23 , 37,5 , 8,10 , 16284,63 , 16347,82 , 10970,24 , 16429,60 , 16489,86 , 10970,24 , 8756,28 , 8784,61 , 8845,14 , 8859,28 , 8887,61 , 8845,14 , 263,15 , 229,15 , 45,4 , 5,17 , 22,23 , {71,69,76}, 236,1 , 11942,17 , 8,5 , 4,0 , 3520,4 , 3524,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia
- { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 534,9 , 534,9 , 175,8 , 1022,23 , 37,5 , 8,10 , 16284,63 , 16347,82 , 10970,24 , 16429,60 , 16489,86 , 10970,24 , 8756,28 , 8784,61 , 8845,14 , 8859,28 , 8887,61 , 8845,14 , 263,15 , 229,15 , 45,4 , 5,17 , 22,23 , {82,85,66}, 129,1 , 11959,17 , 8,5 , 4,0 , 3520,4 , 3535,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
- { 102, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/SouthAfrica
- { 103, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/SouthAfrica
- { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 16575,48 , 16623,100 , 16723,24 , 16575,48 , 16623,100 , 16723,24 , 8948,28 , 8976,55 , 9031,14 , 8948,28 , 8976,55 , 9031,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 165,3 , 11976,22 , 4,4 , 4,0 , 3541,8 , 1762,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe
- { 105, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,75,82}, 182,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 7, 6, 7 }, // Sindhi/Arabic/Pakistan
- { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 543,9 , 552,8 , 53,10 , 63,17 , 200,5 , 205,10 , 16747,59 , 16806,96 , 16902,32 , 16934,61 , 16806,96 , 16902,32 , 9045,39 , 9084,62 , 9146,19 , 9045,39 , 9084,62 , 9146,19 , 278,5 , 244,4 , 663,5 , 668,37 , 22,23 , {76,75,82}, 304,3 , 11998,58 , 4,4 , 4,0 , 3549,5 , 3554,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/SriLanka
- { 107, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/SouthAfrica
- { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 176,7 , 560,7 , 1045,10 , 532,18 , 55,4 , 59,9 , 16995,48 , 17043,82 , 16212,24 , 16995,48 , 17125,89 , 16212,24 , 9165,21 , 9186,52 , 9238,14 , 9165,21 , 9186,52 , 9238,14 , 0,2 , 0,2 , 283,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12056,26 , 13,5 , 4,0 , 3565,10 , 3575,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia
- { 109, 7, 192, 44, 46, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 567,8 , 567,8 , 1055,9 , 1064,19 , 37,5 , 8,10 , 17214,59 , 17273,86 , 16212,24 , 17214,59 , 17273,86 , 16212,24 , 9252,35 , 9287,52 , 9339,14 , 9252,35 , 9287,52 , 9339,14 , 60,4 , 248,4 , 54,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12082,28 , 13,5 , 4,0 , 3584,11 , 3595,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia
- { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1083,19 , 18,7 , 25,12 , 17359,48 , 17407,189 , 17596,24 , 17359,48 , 17407,189 , 17596,24 , 9353,28 , 9381,47 , 9428,15 , 9353,28 , 9381,47 , 9428,15 , 283,3 , 252,3 , 45,4 , 5,17 , 22,23 , {83,79,83}, 100,1 , 12110,22 , 4,4 , 4,0 , 3604,8 , 3612,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia
- { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1083,19 , 18,7 , 25,12 , 17359,48 , 17407,189 , 17596,24 , 17359,48 , 17407,189 , 17596,24 , 9353,28 , 9381,47 , 9428,15 , 9353,28 , 9381,47 , 9428,15 , 283,3 , 252,3 , 45,4 , 5,17 , 22,23 , {68,74,70}, 43,3 , 12132,21 , 4,4 , 4,0 , 3604,8 , 3622,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti
- { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1083,19 , 18,7 , 25,12 , 17359,48 , 17407,189 , 17596,24 , 17359,48 , 17407,189 , 17596,24 , 9353,28 , 9381,47 , 9428,15 , 9353,28 , 9381,47 , 9428,15 , 283,3 , 252,3 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 12153,22 , 4,4 , 4,0 , 3604,8 , 3629,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia
- { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1083,19 , 37,5 , 8,10 , 17359,48 , 17407,189 , 17596,24 , 17359,48 , 17407,189 , 17596,24 , 9353,28 , 9381,47 , 9428,15 , 9353,28 , 9381,47 , 9428,15 , 283,3 , 252,3 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3604,8 , 3637,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya
- { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 55,4 , 356,11 , 17620,61 , 17681,89 , 17770,24 , 17620,61 , 17681,89 , 17770,24 , 9443,35 , 9478,53 , 7964,14 , 9443,35 , 9478,53 , 7964,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 3644,17 , 2354,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain
- { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 3054,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {65,82,83}, 6,1 , 12175,51 , 8,5 , 4,0 , 3661,7 , 3668,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina
- { 111, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {66,90,68}, 6,1 , 12226,52 , 4,4 , 4,0 , 3661,7 , 3677,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Belize
- { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17770,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {66,79,66}, 292,2 , 12278,35 , 4,4 , 4,0 , 3661,7 , 3304,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia
- { 111, 7, 30, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {66,82,76}, 281,2 , 12313,52 , 4,4 , 4,0 , 3661,7 , 3120,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Brazil
- { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 348,8 , 587,27 , 37,5 , 8,10 , 17620,61 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {67,76,80}, 6,1 , 12365,45 , 4,4 , 36,5 , 3661,7 , 3683,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile
- { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 509,7 , 587,27 , 18,7 , 25,12 , 17620,61 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 9531,14 , 9443,35 , 9478,53 , 3054,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {67,79,80}, 6,1 , 12410,54 , 8,5 , 4,0 , 3661,7 , 3688,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia
- { 111, 7, 52, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {67,82,67}, 307,1 , 12464,67 , 4,4 , 4,0 , 3661,7 , 3696,10 , 2, 0, 1, 6, 7 }, // Spanish/Latin/CostaRica
- { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {67,85,80}, 6,1 , 12531,42 , 4,4 , 4,0 , 3661,7 , 3706,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba
- { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 18,7 , 25,12 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 3054,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {68,79,80}, 308,3 , 12573,54 , 4,4 , 85,6 , 3661,7 , 3710,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/DominicanRepublic
- { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12627,70 , 4,4 , 36,5 , 3661,7 , 3311,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador
- { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12627,70 , 4,4 , 4,0 , 3661,7 , 3730,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/ElSalvador
- { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 55,4 , 356,11 , 17620,61 , 17681,89 , 17770,24 , 17620,61 , 17681,89 , 17770,24 , 9443,35 , 9478,53 , 7964,14 , 9443,35 , 9478,53 , 7964,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 12697,53 , 4,4 , 4,0 , 3661,7 , 3741,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/EquatorialGuinea
- { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 509,7 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {71,84,81}, 311,1 , 12750,30 , 18,5 , 4,0 , 3661,7 , 3758,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala
- { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 1102,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {72,78,76}, 297,1 , 12780,60 , 4,4 , 4,0 , 3661,7 , 3767,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras
- { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 27,8 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17878,48 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 3054,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {77,88,78}, 6,1 , 12840,48 , 4,4 , 4,0 , 3775,17 , 3792,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico
- { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {78,73,79}, 312,2 , 12888,69 , 4,4 , 4,0 , 3661,7 , 3798,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua
- { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 1129,8 , 587,27 , 18,7 , 25,12 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17770,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {80,65,66}, 314,3 , 12957,54 , 4,4 , 4,0 , 3661,7 , 3807,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama
- { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17620,61 , 17681,89 , 17770,24 , 17620,61 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {80,89,71}, 317,3 , 13011,61 , 8,5 , 23,6 , 3661,7 , 3813,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay
- { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 509,7 , 587,27 , 37,5 , 8,10 , 17926,60 , 17986,88 , 17770,24 , 18074,60 , 18134,88 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {80,69,78}, 290,2 , 13072,43 , 4,4 , 4,0 , 3661,7 , 3300,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru
- { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 18,7 , 25,12 , 17620,61 , 17681,89 , 17770,24 , 17620,61 , 17681,89 , 17770,24 , 9443,35 , 9478,53 , 7964,14 , 9443,35 , 9478,53 , 7964,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {80,72,80}, 185,1 , 13115,48 , 13,5 , 4,0 , 3661,7 , 3821,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines
- { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 1129,8 , 587,27 , 18,7 , 25,12 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12627,70 , 4,4 , 4,0 , 3661,7 , 1408,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/PuertoRico
- { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 18,7 , 25,12 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12627,70 , 4,4 , 4,0 , 3661,7 , 3830,7 , 2, 1, 7, 6, 7 }, // Spanish/Latin/UnitedStates
- { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17926,60 , 17986,88 , 17770,24 , 18074,60 , 18134,88 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,89,85}, 6,1 , 13163,48 , 8,5 , 4,0 , 3661,7 , 3837,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay
- { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 18,7 , 25,12 , 17620,61 , 17681,89 , 17770,24 , 17620,61 , 17681,89 , 17770,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {86,69,70}, 320,3 , 13211,64 , 4,4 , 36,5 , 3661,7 , 3844,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Venezuela
- { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 55,4 , 356,11 , 17620,61 , 17681,89 , 17770,24 , 17620,61 , 17681,89 , 17770,24 , 9443,35 , 9478,53 , 7964,14 , 9443,35 , 9478,53 , 7964,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 3661,7 , 3853,8 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CanaryIslands
- { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 37,5 , 8,10 , 17794,60 , 17681,89 , 17770,24 , 17794,60 , 17681,89 , 17854,24 , 9443,35 , 9478,53 , 3054,14 , 9443,35 , 9478,53 , 9531,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 13275,0 , 4,4 , 4,0 , 3861,23 , 3884,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/LatinAmericaAndTheCaribbean
- { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 587,27 , 55,4 , 356,11 , 17620,61 , 17681,89 , 17770,24 , 17620,61 , 17681,89 , 17770,24 , 9443,35 , 9478,53 , 7964,14 , 9443,35 , 9478,53 , 7964,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 3661,7 , 3897,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CeutaAndMelilla
- { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 582,8 , 582,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 18270,84 , 134,24 , 18222,48 , 18270,84 , 134,24 , 9545,60 , 9545,60 , 85,14 , 9545,60 , 9545,60 , 85,14 , 286,7 , 255,6 , 548,5 , 705,47 , 22,23 , {84,90,83}, 198,3 , 13275,67 , 4,4 , 4,0 , 3912,9 , 1587,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania
- { 113, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 582,8 , 582,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 18270,84 , 134,24 , 18222,48 , 18270,84 , 134,24 , 9545,60 , 9545,60 , 85,14 , 9545,60 , 9545,60 , 85,14 , 286,7 , 255,6 , 548,5 , 705,47 , 22,23 , {67,68,70}, 215,2 , 13342,55 , 4,4 , 4,0 , 3921,8 , 3929,32 , 2, 1, 1, 6, 7 }, // Swahili/Latin/CongoKinshasa
- { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 582,8 , 582,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 18270,84 , 134,24 , 18222,48 , 18270,84 , 134,24 , 9545,60 , 9545,60 , 85,14 , 9545,60 , 9545,60 , 85,14 , 0,2 , 0,2 , 548,5 , 705,47 , 22,23 , {75,69,83}, 2,3 , 13397,58 , 4,4 , 4,0 , 3912,9 , 1153,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya
- { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 582,8 , 582,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 18270,84 , 134,24 , 18222,48 , 18270,84 , 134,24 , 9545,60 , 9545,60 , 85,14 , 9545,60 , 9545,60 , 85,14 , 286,7 , 255,6 , 548,5 , 705,47 , 22,23 , {85,71,88}, 203,3 , 13455,61 , 4,4 , 4,0 , 3912,9 , 1652,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda
- { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 590,9 , 590,9 , 53,10 , 98,16 , 37,5 , 367,16 , 18354,59 , 18413,86 , 134,24 , 18354,59 , 18413,86 , 134,24 , 9605,29 , 9634,50 , 2353,14 , 9605,29 , 9634,50 , 2353,14 , 293,2 , 261,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 196,2 , 13516,45 , 13,5 , 4,0 , 3961,7 , 3968,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Sweden
- { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 590,9 , 590,9 , 1137,10 , 98,16 , 37,5 , 367,16 , 18354,59 , 18413,86 , 134,24 , 18354,59 , 18413,86 , 134,24 , 9605,29 , 9634,50 , 2353,14 , 9605,29 , 9634,50 , 2353,14 , 293,2 , 261,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8852,19 , 13,5 , 4,0 , 3961,7 , 1050,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland
- { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 590,9 , 590,9 , 53,10 , 98,16 , 37,5 , 367,16 , 18354,59 , 18413,86 , 134,24 , 18354,59 , 18413,86 , 134,24 , 9605,29 , 9634,50 , 2353,14 , 9605,29 , 9634,50 , 2353,14 , 293,2 , 261,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8852,19 , 13,5 , 4,0 , 3961,7 , 3975,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/AlandIslands
- { 116, 2, 209, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {84,74,83}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan
- { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 599,13 , 599,13 , 278,6 , 211,18 , 312,7 , 383,12 , 18499,58 , 18557,86 , 18643,31 , 18499,58 , 18557,86 , 18643,31 , 9684,39 , 9723,49 , 9772,20 , 9684,39 , 9723,49 , 9772,20 , 295,8 , 263,8 , 752,7 , 5,17 , 22,23 , {73,78,82}, 127,1 , 13561,49 , 8,5 , 4,0 , 3980,5 , 3985,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India
- { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 599,13 , 599,13 , 278,6 , 211,18 , 312,7 , 383,12 , 18499,58 , 18557,86 , 18643,31 , 18499,58 , 18557,86 , 18643,31 , 9684,39 , 9723,49 , 9772,20 , 9684,39 , 9723,49 , 9772,20 , 295,8 , 263,8 , 752,7 , 5,17 , 22,23 , {77,89,82}, 180,2 , 13610,61 , 8,5 , 4,0 , 3980,5 , 3992,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia
- { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 599,13 , 599,13 , 278,6 , 211,18 , 312,7 , 383,12 , 18499,58 , 18557,86 , 18643,31 , 18499,58 , 18557,86 , 18643,31 , 9684,39 , 9723,49 , 9772,20 , 9684,39 , 9723,49 , 9772,20 , 295,8 , 263,8 , 752,7 , 5,17 , 22,23 , {83,71,68}, 6,1 , 13671,61 , 8,5 , 4,0 , 3980,5 , 3999,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore
- { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 599,13 , 599,13 , 278,6 , 211,18 , 37,5 , 8,10 , 18499,58 , 18557,86 , 18643,31 , 18499,58 , 18557,86 , 18643,31 , 9684,39 , 9723,49 , 9772,20 , 9684,39 , 9723,49 , 9772,20 , 295,8 , 263,8 , 752,7 , 5,17 , 22,23 , {76,75,82}, 323,3 , 13732,49 , 8,5 , 4,0 , 3980,5 , 4010,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/SriLanka
- { 118, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 129,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Tatar/Cyrillic/Russia
- { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 612,11 , 612,11 , 348,8 , 1147,18 , 18,7 , 25,12 , 18674,66 , 18740,86 , 18826,31 , 18857,62 , 18740,86 , 18826,31 , 9792,32 , 9824,60 , 9884,18 , 9792,32 , 9824,60 , 9884,18 , 0,2 , 0,2 , 759,7 , 766,27 , 22,23 , {73,78,82}, 127,1 , 13781,26 , 4,4 , 4,0 , 4016,6 , 4022,9 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India
- { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 114,5 , 114,5 , 623,8 , 631,7 , 278,6 , 1165,19 , 37,5 , 395,28 , 18919,63 , 18982,98 , 18919,63 , 18919,63 , 18982,98 , 18919,63 , 9902,23 , 9925,68 , 9993,16 , 9902,23 , 9925,68 , 9993,16 , 303,10 , 271,10 , 793,4 , 5,17 , 22,23 , {84,72,66}, 326,3 , 13807,19 , 4,4 , 4,0 , 4031,3 , 4031,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand
- { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1184,23 , 18,7 , 25,12 , 2886,63 , 19080,159 , 158,27 , 2886,63 , 19239,147 , 158,27 , 10009,51 , 10060,79 , 10139,27 , 10009,51 , 10060,79 , 10139,27 , 313,7 , 281,8 , 45,4 , 5,17 , 22,23 , {67,78,89}, 329,1 , 13826,13 , 8,5 , 4,0 , 4034,8 , 4042,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China
- { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1184,23 , 18,7 , 25,12 , 2886,63 , 19080,159 , 158,27 , 2886,63 , 19239,147 , 158,27 , 10009,51 , 10060,79 , 10139,27 , 10009,51 , 10060,79 , 10139,27 , 313,7 , 281,8 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 13839,19 , 8,5 , 4,0 , 4034,8 , 4048,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India
- { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1207,23 , 18,7 , 25,12 , 19386,36 , 19422,54 , 19476,24 , 19386,36 , 19422,54 , 19476,24 , 10166,21 , 10187,29 , 10216,14 , 10166,21 , 10230,29 , 10259,14 , 320,7 , 289,7 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 13858,16 , 4,4 , 4,0 , 4055,4 , 82,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia
- { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1207,23 , 18,7 , 25,12 , 19386,36 , 19422,54 , 19476,24 , 19386,36 , 19422,54 , 19476,24 , 10166,21 , 10187,29 , 10259,14 , 10166,21 , 10230,29 , 10259,14 , 320,7 , 289,7 , 45,4 , 5,17 , 22,23 , {69,82,78}, 46,3 , 0,7 , 4,4 , 4,0 , 4055,4 , 4059,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea
- { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 638,8 , 638,8 , 638,8 , 638,8 , 278,6 , 98,16 , 18,7 , 25,12 , 19500,51 , 19551,87 , 19638,24 , 19500,51 , 19551,87 , 19638,24 , 10273,29 , 10302,60 , 10362,14 , 10273,29 , 10302,60 , 10362,14 , 327,10 , 296,6 , 797,5 , 802,59 , 861,65 , {84,79,80}, 201,2 , 13874,41 , 8,5 , 4,0 , 4063,13 , 1602,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga
- { 124, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/SouthAfrica
- { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 646,8 , 646,8 , 1230,9 , 1239,16 , 37,5 , 8,10 , 19662,48 , 19710,75 , 19785,24 , 19662,48 , 19710,75 , 19785,24 , 10376,28 , 10404,54 , 10458,14 , 10376,28 , 10404,54 , 10458,14 , 337,2 , 302,2 , 152,4 , 5,17 , 22,23 , {84,82,89}, 256,1 , 13915,40 , 4,4 , 4,0 , 4076,6 , 4082,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey
- { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 646,8 , 646,8 , 1230,9 , 1239,16 , 18,7 , 25,12 , 19662,48 , 19710,75 , 19785,24 , 19662,48 , 19710,75 , 19785,24 , 10376,28 , 10404,54 , 10458,14 , 10376,28 , 10404,54 , 10458,14 , 337,2 , 302,2 , 152,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8339,19 , 4,4 , 4,0 , 4076,6 , 4089,6 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus
- { 126, 7, 218, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8220, 8221, 0,6 , 0,6 , 654,8 , 654,8 , 931,10 , 1239,16 , 37,5 , 8,10 , 19809,51 , 19860,77 , 19937,24 , 19809,51 , 19860,77 , 19937,24 , 10472,21 , 10493,54 , 10547,14 , 10472,21 , 10493,54 , 10547,14 , 0,2 , 0,2 , 926,4 , 5,17 , 22,23 , {84,77,84}, 330,3 , 13955,49 , 13,5 , 4,0 , 4095,9 , 4104,12 , 2, 1, 1, 6, 7 }, // Turkmen/Latin/Turkmenistan
- { 128, 1, 44, 46, 44, 59, 37, 48, 45, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 191,10 , 201,9 , 53,10 , 1255,17 , 18,7 , 25,12 , 19961,84 , 19961,84 , 158,27 , 19961,84 , 19961,84 , 158,27 , 10561,21 , 10582,55 , 10637,14 , 10561,21 , 10582,55 , 10637,14 , 339,12 , 304,12 , 45,4 , 5,17 , 22,23 , {67,78,89}, 139,1 , 14004,40 , 4,4 , 4,0 , 4116,8 , 4124,5 , 2, 1, 7, 6, 7 }, // Uighur/Arabic/China
- { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 129,7 , 129,7 , 175,8 , 1272,22 , 37,5 , 8,10 , 20045,48 , 20093,95 , 20188,24 , 20212,67 , 20279,87 , 20366,24 , 1573,21 , 10651,56 , 10707,14 , 1573,21 , 10651,56 , 10707,14 , 351,2 , 316,2 , 930,5 , 528,17 , 22,23 , {85,65,72}, 298,1 , 14044,49 , 13,5 , 4,0 , 4129,10 , 4139,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine
- { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 662,10 , 672,9 , 278,6 , 157,18 , 18,7 , 25,12 , 20390,68 , 20390,68 , 134,24 , 20390,68 , 20390,68 , 134,24 , 10721,39 , 10721,39 , 85,14 , 10721,39 , 10721,39 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,75,82}, 182,2 , 14093,49 , 4,4 , 4,0 , 4146,4 , 3285,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan
- { 130, 1, 100, 46, 44, 59, 37, 1776, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 681,6 , 681,6 , 278,6 , 157,18 , 18,7 , 25,12 , 20390,68 , 20390,68 , 134,24 , 20390,68 , 20390,68 , 134,24 , 10760,36 , 10760,36 , 85,14 , 10760,36 , 10760,36 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 14142,42 , 8,5 , 4,0 , 4146,4 , 4150,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India
- { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8217, 8216, 0,6 , 0,6 , 687,8 , 687,8 , 27,8 , 1294,18 , 37,5 , 356,11 , 20458,48 , 20506,75 , 20581,24 , 20605,48 , 20653,75 , 20581,24 , 10796,32 , 10828,61 , 10889,14 , 10796,32 , 10828,61 , 10889,14 , 353,2 , 318,2 , 152,4 , 297,17 , 22,23 , {85,90,83}, 333,4 , 14184,58 , 13,5 , 4,0 , 4155,6 , 4161,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan
- { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 385,8 , 1312,33 , 55,4 , 356,11 , 20728,47 , 14180,68 , 158,27 , 20728,47 , 14180,68 , 158,27 , 10903,21 , 7376,49 , 85,14 , 10903,21 , 7376,49 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {65,70,78}, 274,1 , 14242,13 , 13,5 , 4,0 , 4172,6 , 3077,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan
- { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 614,19 , 37,5 , 88,12 , 10842,48 , 20775,71 , 10970,24 , 20846,48 , 20894,71 , 10970,24 , 10924,28 , 10952,53 , 11005,14 , 11019,28 , 11047,53 , 11005,14 , 355,2 , 320,2 , 45,4 , 5,17 , 22,23 , {85,90,83}, 337,3 , 14255,49 , 13,5 , 4,0 , 4178,7 , 4185,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan
- { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 695,8 , 695,8 , 120,10 , 211,18 , 37,5 , 8,10 , 20965,75 , 21040,99 , 158,27 , 21139,75 , 21214,99 , 158,27 , 11100,33 , 11133,55 , 11188,21 , 11100,33 , 11133,55 , 11188,21 , 357,2 , 322,2 , 45,4 , 5,17 , 22,23 , {86,78,68}, 340,1 , 14304,33 , 8,5 , 4,0 , 4195,10 , 4205,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam
- { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 10,17 , 37,5 , 8,10 , 21313,52 , 21365,87 , 21452,26 , 21478,59 , 21365,87 , 21452,26 , 11209,29 , 11238,77 , 11315,15 , 11330,30 , 11238,77 , 11315,15 , 359,2 , 324,2 , 935,7 , 5,17 , 22,23 , {71,66,80}, 125,1 , 14337,92 , 4,4 , 4,0 , 4213,7 , 4220,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/UnitedKingdom
- { 135, 7, 187, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Wolof/Latin/Senegal
- { 136, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/SouthAfrica
- { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 21537,73 , 21610,121 , 158,27 , 21537,73 , 21610,121 , 158,27 , 11360,44 , 11404,69 , 85,14 , 11360,44 , 11404,69 , 85,14 , 361,5 , 326,5 , 45,4 , 5,17 , 22,23 , {78,71,78}, 184,1 , 14429,34 , 4,4 , 4,0 , 4236,10 , 4246,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria
- { 138, 7, 23, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 21731,74 , 21805,134 , 158,27 , 21731,74 , 21805,134 , 158,27 , 11473,44 , 11517,69 , 85,14 , 11473,44 , 11517,69 , 85,14 , 366,5 , 331,5 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 14463,34 , 4,4 , 4,0 , 4236,10 , 4264,16 , 0, 0, 1, 6, 7 }, // Yoruba/Latin/Benin
- { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 703,9 , 712,8 , 516,6 , 35,18 , 37,5 , 8,10 , 21939,48 , 21987,91 , 134,24 , 21939,48 , 22078,93 , 22171,24 , 11586,28 , 11614,74 , 11688,14 , 11586,28 , 11614,74 , 11688,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 14497,67 , 4,4 , 4,0 , 4280,7 , 4287,14 , 2, 1, 7, 6, 7 }, // Zulu/Latin/SouthAfrica
- { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 183,8 , 183,8 , 931,10 , 469,17 , 37,5 , 367,16 , 5791,48 , 13743,83 , 134,24 , 22195,59 , 13743,83 , 134,24 , 11702,28 , 11730,51 , 2353,14 , 11781,28 , 11730,51 , 2353,14 , 371,9 , 336,11 , 45,4 , 5,17 , 22,23 , {78,79,75}, 196,2 , 14564,42 , 13,5 , 4,0 , 4301,7 , 4308,5 , 2, 1, 1, 6, 7 }, // NorwegianNynorsk/Latin/Norway
- { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 8216, 8217, 0,6 , 0,6 , 154,7 , 154,7 , 995,7 , 441,19 , 37,5 , 8,10 , 16236,48 , 22254,83 , 16212,24 , 16236,48 , 22254,83 , 16212,24 , 2076,28 , 2104,58 , 2162,14 , 2076,28 , 2104,58 , 2176,14 , 380,10 , 347,7 , 276,7 , 5,17 , 22,23 , {66,65,77}, 150,2 , 14606,170 , 13,5 , 4,0 , 4313,8 , 591,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/BosniaAndHerzegowina
- { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 107,7 , 107,7 , 995,7 , 1002,20 , 37,5 , 8,10 , 15886,48 , 22337,83 , 12349,24 , 15886,48 , 22337,83 , 12349,24 , 11809,28 , 11837,54 , 8482,14 , 11809,28 , 11837,54 , 8482,14 , 223,9 , 354,7 , 45,4 , 5,17 , 22,23 , {66,65,77}, 302,2 , 14776,151 , 13,5 , 4,0 , 4321,8 , 3459,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/BosniaAndHerzegowina
+ { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 513,8 , 521,7 , 543,6 , 35,18 , 18,7 , 25,12 , 14009,86 , 14009,86 , 14095,32 , 14009,86 , 14009,86 , 14095,32 , 7367,33 , 7400,54 , 7454,18 , 7367,33 , 7400,54 , 7454,18 , 0,2 , 0,2 , 648,5 , 5,17 , 22,23 , {73,78,82}, 117,1 , 9843,43 , 8,5 , 4,0 , 3109,5 , 3114,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India
+ { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 46,6 , 46,6 , 528,9 , 537,8 , 412,8 , 991,20 , 55,4 , 426,11 , 14127,68 , 14195,69 , 158,27 , 14264,69 , 14264,69 , 14333,24 , 7472,39 , 7472,39 , 85,14 , 7472,39 , 7472,39 , 85,14 , 196,4 , 186,4 , 0,5 , 5,17 , 22,23 , {65,70,78}, 262,1 , 9886,25 , 13,5 , 4,0 , 3118,4 , 3122,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan
+ { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 545,7 , 545,7 , 552,8 , 560,7 , 412,8 , 98,16 , 55,4 , 426,11 , 14357,70 , 14357,70 , 14427,24 , 14451,74 , 14451,74 , 14427,24 , 7511,49 , 7511,49 , 7560,14 , 7511,49 , 7511,49 , 7560,14 , 200,9 , 190,8 , 653,4 , 657,39 , 22,23 , {73,82,82}, 263,4 , 9911,37 , 84,5 , 4,0 , 3131,5 , 3136,5 , 0, 0, 6, 5, 5 }, // Persian/Arabic/Iran
+ { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 545,7 , 545,7 , 552,8 , 560,7 , 412,8 , 98,16 , 55,4 , 426,11 , 14525,68 , 14525,68 , 14333,24 , 14593,62 , 14525,68 , 14333,24 , 7511,49 , 7511,49 , 7560,14 , 7511,49 , 7511,49 , 7560,14 , 200,9 , 190,8 , 653,4 , 657,39 , 22,23 , {65,70,78}, 262,1 , 9948,55 , 8,5 , 4,0 , 3141,3 , 3122,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan
+ { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 163,7 , 163,7 , 981,10 , 10,17 , 37,5 , 8,10 , 14655,48 , 14703,97 , 14800,24 , 14655,48 , 14824,99 , 14923,24 , 7574,34 , 7608,59 , 7667,14 , 7574,34 , 7608,59 , 7681,14 , 0,2 , 0,2 , 320,5 , 5,17 , 22,23 , {80,76,78}, 267,2 , 10003,77 , 13,5 , 4,0 , 3144,6 , 3150,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland
+ { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 254,7 , 254,7 , 120,10 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7695,28 , 7723,79 , 7802,14 , 7695,28 , 7723,79 , 7802,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,82,76}, 269,2 , 10080,54 , 8,5 , 4,0 , 3156,9 , 3165,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil
+ { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {65,79,65}, 246,2 , 10134,54 , 13,5 , 4,0 , 3156,9 , 3171,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola
+ { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {67,86,69}, 271,1 , 10188,69 , 13,5 , 4,0 , 3156,9 , 3177,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Cape Verde
+ { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 10257,81 , 13,5 , 4,0 , 3156,9 , 3187,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/East Timor
+ { 91, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 10338,59 , 13,5 , 4,0 , 3156,9 , 3198,16 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/Equatorial Guinea
+ { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {88,79,70}, 200,3 , 10397,62 , 13,5 , 4,0 , 3156,9 , 3214,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/Guinea Bissau
+ { 91, 7, 125, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3156,9 , 3226,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Luxembourg
+ { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 18,7 , 25,12 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {77,79,80}, 133,4 , 10459,53 , 13,5 , 4,0 , 3156,9 , 3236,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau
+ { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {77,90,78}, 272,3 , 10512,72 , 13,5 , 4,0 , 3156,9 , 3255,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique
+ { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3265,17 , 3282,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal
+ { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {83,84,78}, 275,2 , 10584,104 , 13,5 , 4,0 , 3156,9 , 3290,19 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Sao Tome And Principe
+ { 91, 7, 206, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {67,72,70}, 217,3 , 10688,45 , 13,5 , 4,0 , 3156,9 , 3309,5 , 2, 0, 1, 6, 7 }, // Portuguese/Latin/Switzerland
+ { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 567,9 , 567,9 , 287,6 , 10,17 , 18,7 , 25,12 , 15084,50 , 15134,68 , 15202,28 , 15084,50 , 15134,68 , 15202,28 , 7865,36 , 7901,57 , 7958,23 , 7865,36 , 7901,57 , 7958,23 , 217,6 , 206,6 , 696,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 10733,39 , 4,4 , 4,0 , 3314,6 , 3320,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India
+ { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 80,18 , 18,7 , 25,12 , 15230,67 , 15230,67 , 158,27 , 15230,67 , 15230,67 , 158,27 , 7981,37 , 7981,37 , 85,14 , 7981,37 , 7981,37 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,75,82}, 277,1 , 10772,13 , 41,6 , 4,0 , 3324,6 , 3330,7 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan
+ { 93, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 210,18 , 37,5 , 8,10 , 15297,48 , 15345,88 , 158,27 , 15297,48 , 15345,88 , 158,27 , 8018,28 , 8046,53 , 8099,14 , 8018,28 , 8046,53 , 8099,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {80,69,78}, 278,2 , 0,7 , 8,5 , 4,0 , 3337,8 , 3345,4 , 2, 1, 7, 6, 7 }, // Quechua/Latin/Peru
+ { 93, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 210,18 , 37,5 , 8,10 , 15297,48 , 15345,88 , 158,27 , 15297,48 , 15345,88 , 158,27 , 8018,28 , 8046,53 , 8099,14 , 8018,28 , 8046,53 , 8099,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {66,79,66}, 280,2 , 0,7 , 8,5 , 4,0 , 3337,8 , 3349,7 , 2, 1, 1, 6, 7 }, // Quechua/Latin/Bolivia
+ { 93, 7, 63, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 210,18 , 37,5 , 8,10 , 15297,48 , 15345,88 , 158,27 , 15297,48 , 15345,88 , 158,27 , 8018,28 , 8046,53 , 8099,14 , 8018,28 , 8046,53 , 8099,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 8,5 , 4,0 , 3337,8 , 3356,7 , 2, 1, 1, 6, 7 }, // Quechua/Latin/Ecuador
+ { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 357,8 , 1011,28 , 37,5 , 8,10 , 15433,67 , 15500,92 , 15592,24 , 15433,67 , 15500,92 , 15592,24 , 8113,23 , 8136,56 , 8192,14 , 8113,23 , 8136,56 , 8192,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 217,3 , 10785,46 , 13,5 , 4,0 , 3363,9 , 3372,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland
+ { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 576,8 , 576,8 , 981,10 , 10,17 , 37,5 , 8,10 , 15616,60 , 15676,98 , 15774,24 , 15616,60 , 15676,98 , 15774,24 , 8206,34 , 8240,48 , 3150,14 , 8206,34 , 8240,48 , 3150,14 , 66,4 , 63,4 , 700,4 , 5,17 , 22,23 , {82,79,78}, 282,3 , 10831,57 , 13,5 , 4,0 , 3378,6 , 3384,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania
+ { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 576,8 , 576,8 , 981,10 , 10,17 , 37,5 , 8,10 , 15616,60 , 15676,98 , 15774,24 , 15616,60 , 15676,98 , 15774,24 , 8288,28 , 8240,48 , 8316,16 , 8288,28 , 8240,48 , 8316,16 , 66,4 , 63,4 , 700,4 , 5,17 , 22,23 , {77,68,76}, 285,1 , 10888,69 , 13,5 , 4,0 , 3378,6 , 3391,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova
+ { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {82,85,66}, 119,1 , 10957,89 , 13,5 , 4,0 , 3408,7 , 3415,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia
+ { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {66,89,78}, 0,2 , 11046,94 , 13,5 , 4,0 , 3408,7 , 501,8 , 2, 0, 1, 6, 7 }, // Russian/Cyrillic/Belarus
+ { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {75,90,84}, 236,1 , 11140,83 , 13,5 , 4,0 , 3408,7 , 3421,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan
+ { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {75,71,83}, 237,3 , 11223,82 , 13,5 , 4,0 , 3408,7 , 3430,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan
+ { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {77,68,76}, 285,1 , 11305,79 , 13,5 , 4,0 , 3408,7 , 3438,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova
+ { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 37,5 , 8,10 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {85,65,72}, 286,1 , 11384,92 , 13,5 , 4,0 , 3408,7 , 3445,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine
+ { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 16004,48 , 16052,91 , 16143,24 , 16004,48 , 16052,91 , 16143,24 , 8429,28 , 8457,66 , 8523,14 , 8429,28 , 8457,66 , 8523,14 , 223,2 , 212,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 11476,25 , 4,4 , 36,5 , 3452,5 , 3457,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/Central African Republic
+ { 99, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Sanskrit/Devanagari/India
+ { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16167,48 , 16215,81 , 12531,24 , 16167,48 , 16215,81 , 12531,24 , 8537,28 , 8565,52 , 8617,14 , 8537,28 , 8565,52 , 8617,14 , 225,9 , 214,8 , 704,7 , 5,17 , 22,23 , {82,83,68}, 287,3 , 11501,58 , 13,5 , 4,0 , 3479,6 , 3485,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
+ { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16296,58 , 16354,81 , 16435,24 , 16296,58 , 16354,81 , 16435,24 , 8631,33 , 8664,57 , 2172,14 , 8631,33 , 8664,57 , 2172,14 , 234,11 , 222,8 , 313,7 , 5,17 , 22,23 , {66,65,77}, 140,2 , 11559,174 , 13,5 , 4,0 , 3491,6 , 620,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Bosnia And Herzegowina
+ { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16296,58 , 16354,81 , 16435,24 , 16296,58 , 16354,81 , 16435,24 , 8631,33 , 8664,57 , 2172,14 , 8631,33 , 8664,57 , 2172,14 , 234,11 , 222,8 , 313,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11733,23 , 13,5 , 4,0 , 3491,6 , 3497,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
+ { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16459,48 , 16354,81 , 16435,24 , 16459,48 , 16354,81 , 16435,24 , 8721,28 , 8749,54 , 2172,14 , 8721,28 , 8749,54 , 2172,14 , 245,9 , 222,8 , 313,7 , 5,17 , 22,23 , {82,83,68}, 287,3 , 11756,58 , 13,5 , 4,0 , 3491,6 , 3506,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
+ { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16507,58 , 16215,81 , 12531,24 , 16507,58 , 16215,81 , 12531,24 , 8803,33 , 8836,55 , 8617,14 , 8803,33 , 8836,55 , 8617,14 , 254,11 , 214,8 , 704,7 , 5,17 , 22,23 , {66,65,77}, 290,2 , 11814,174 , 13,5 , 4,0 , 3479,6 , 3512,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Bosnia And Herzegowina
+ { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16507,58 , 16215,81 , 12531,24 , 16507,58 , 16215,81 , 12531,24 , 8803,33 , 8836,55 , 8617,14 , 8803,33 , 8836,55 , 8617,14 , 254,11 , 214,8 , 704,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11988,23 , 13,5 , 4,0 , 3479,6 , 3531,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
+ { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16507,58 , 16215,81 , 12531,24 , 16507,58 , 16215,81 , 12531,24 , 8803,33 , 8565,52 , 8617,14 , 8803,33 , 8565,52 , 8617,14 , 225,9 , 214,8 , 704,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11988,23 , 13,5 , 4,0 , 3479,6 , 3540,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo
+ { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16296,58 , 16354,81 , 16435,24 , 16296,58 , 16354,81 , 16435,24 , 8631,33 , 8749,54 , 2172,14 , 8631,33 , 8749,54 , 2172,14 , 245,9 , 222,8 , 313,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11733,23 , 13,5 , 4,0 , 3491,6 , 3546,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo
+ { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 584,9 , 584,9 , 174,8 , 1066,23 , 37,5 , 8,10 , 16565,63 , 16628,82 , 11152,24 , 16710,60 , 16770,86 , 11152,24 , 8891,28 , 8919,61 , 8980,14 , 8994,28 , 9022,61 , 8980,14 , 265,15 , 230,15 , 45,4 , 5,17 , 22,23 , {71,69,76}, 224,1 , 12011,17 , 8,5 , 4,0 , 3552,4 , 3556,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia
+ { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 584,9 , 584,9 , 174,8 , 1066,23 , 37,5 , 8,10 , 16565,63 , 16628,82 , 11152,24 , 16710,60 , 16770,86 , 11152,24 , 8891,28 , 8919,61 , 8980,14 , 8994,28 , 9022,61 , 8980,14 , 265,15 , 230,15 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 12028,17 , 8,5 , 4,0 , 3552,4 , 3567,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
+ { 102, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/South Africa
+ { 103, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/South Africa
+ { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 16856,48 , 16904,100 , 17004,24 , 16856,48 , 16904,100 , 17004,24 , 9083,28 , 9111,55 , 9166,14 , 9083,28 , 9111,55 , 9166,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 155,3 , 12045,22 , 4,4 , 4,0 , 3573,8 , 1791,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe
+ { 105, 1, 163, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 17028,72 , 17028,72 , 158,27 , 17028,72 , 17028,72 , 158,27 , 9180,35 , 9180,35 , 9215,21 , 9180,35 , 9180,35 , 9236,31 , 280,11 , 245,11 , 711,6 , 717,52 , 22,23 , {80,75,82}, 172,2 , 12067,43 , 8,5 , 4,0 , 3581,4 , 3585,7 , 0, 0, 7, 6, 7 }, // Sindhi/Arabic/Pakistan
+ { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 593,9 , 602,8 , 53,10 , 63,17 , 228,5 , 233,10 , 17100,59 , 17159,96 , 17255,32 , 17287,61 , 17159,96 , 17255,32 , 9267,39 , 9306,62 , 9368,19 , 9267,39 , 9306,62 , 9368,19 , 291,5 , 256,4 , 769,5 , 774,37 , 22,23 , {76,75,82}, 292,3 , 12110,58 , 4,4 , 4,0 , 3592,5 , 3597,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/Sri Lanka
+ { 107, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/South Africa
+ { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 610,7 , 1089,10 , 496,17 , 55,4 , 59,9 , 17348,48 , 17396,82 , 16435,24 , 17348,48 , 17478,89 , 16435,24 , 9387,21 , 9408,52 , 9460,14 , 9387,21 , 9408,52 , 9460,14 , 0,2 , 0,2 , 320,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12168,26 , 13,5 , 4,0 , 3608,10 , 3618,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia
+ { 109, 7, 192, 44, 46, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 617,8 , 617,8 , 1099,9 , 1108,19 , 37,5 , 8,10 , 17567,59 , 17626,86 , 16435,24 , 17567,59 , 17626,86 , 16435,24 , 9474,35 , 9509,52 , 9561,14 , 9474,35 , 9509,52 , 9561,14 , 62,4 , 260,4 , 54,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12194,28 , 13,5 , 4,0 , 3627,11 , 3638,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia
+ { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1127,19 , 18,7 , 25,12 , 17712,48 , 17760,189 , 17949,24 , 17712,48 , 17760,189 , 17949,24 , 9575,28 , 9603,47 , 9650,15 , 9575,28 , 9603,47 , 9650,15 , 296,3 , 264,3 , 45,4 , 5,17 , 22,23 , {83,79,83}, 90,1 , 12222,22 , 4,4 , 4,0 , 3647,8 , 3655,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia
+ { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1127,19 , 18,7 , 25,12 , 17712,48 , 17760,189 , 17949,24 , 17712,48 , 17760,189 , 17949,24 , 9575,28 , 9603,47 , 9650,15 , 9575,28 , 9603,47 , 9650,15 , 296,3 , 264,3 , 45,4 , 5,17 , 22,23 , {68,74,70}, 38,3 , 12244,21 , 4,4 , 4,0 , 3647,8 , 3665,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti
+ { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1127,19 , 18,7 , 25,12 , 17712,48 , 17760,189 , 17949,24 , 17712,48 , 17760,189 , 17949,24 , 9575,28 , 9603,47 , 9650,15 , 9575,28 , 9603,47 , 9650,15 , 296,3 , 264,3 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 12265,22 , 4,4 , 4,0 , 3647,8 , 3672,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia
+ { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1127,19 , 37,5 , 8,10 , 17712,48 , 17760,189 , 17949,24 , 17712,48 , 17760,189 , 17949,24 , 9575,28 , 9603,47 , 9650,15 , 9575,28 , 9603,47 , 9650,15 , 296,3 , 264,3 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3647,8 , 3680,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya
+ { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 55,4 , 426,11 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3687,17 , 2398,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain
+ { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {65,82,83}, 6,1 , 12287,51 , 8,5 , 4,0 , 3704,7 , 3711,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina
+ { 111, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {66,90,68}, 6,1 , 12338,52 , 4,4 , 4,0 , 3704,7 , 3720,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Belize
+ { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {66,79,66}, 280,2 , 12390,35 , 4,4 , 4,0 , 3704,7 , 3349,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia
+ { 111, 7, 30, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {66,82,76}, 269,2 , 12425,52 , 4,4 , 4,0 , 3704,7 , 3165,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Brazil
+ { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 357,8 , 640,27 , 37,5 , 8,10 , 17973,61 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {67,76,80}, 6,1 , 12477,45 , 4,4 , 36,5 , 3704,7 , 3726,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile
+ { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 536,7 , 640,27 , 18,7 , 25,12 , 17973,61 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 9753,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {67,79,80}, 6,1 , 12522,54 , 8,5 , 4,0 , 3704,7 , 3731,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia
+ { 111, 7, 52, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {67,82,67}, 295,1 , 12576,67 , 4,4 , 4,0 , 3704,7 , 3739,10 , 2, 0, 1, 6, 7 }, // Spanish/Latin/Costa Rica
+ { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {67,85,80}, 6,1 , 12643,42 , 4,4 , 4,0 , 3704,7 , 3749,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba
+ { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 18,7 , 25,12 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {68,79,80}, 296,3 , 12685,54 , 4,4 , 89,6 , 3704,7 , 3753,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Dominican Republic
+ { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12739,70 , 4,4 , 36,5 , 3704,7 , 3356,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador
+ { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12739,70 , 4,4 , 4,0 , 3704,7 , 3773,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/El Salvador
+ { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 55,4 , 426,11 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 12809,92 , 4,4 , 4,0 , 3704,7 , 3784,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Equatorial Guinea
+ { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 536,7 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {71,84,81}, 299,1 , 12901,30 , 18,5 , 4,0 , 3704,7 , 3801,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala
+ { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 1146,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {72,78,76}, 285,1 , 12931,60 , 4,4 , 4,0 , 3704,7 , 3810,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras
+ { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 27,8 , 640,27 , 55,4 , 59,9 , 18147,60 , 18034,89 , 18123,24 , 18207,48 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {77,88,78}, 6,1 , 12991,48 , 47,6 , 4,0 , 3818,17 , 3835,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico
+ { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {78,73,79}, 300,2 , 13039,69 , 4,4 , 4,0 , 3704,7 , 3841,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua
+ { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 1173,8 , 640,27 , 18,7 , 25,12 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {80,65,66}, 302,3 , 13108,54 , 4,4 , 4,0 , 3704,7 , 3850,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama
+ { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {80,89,71}, 305,3 , 13162,61 , 8,5 , 23,6 , 3704,7 , 3856,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay
+ { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 536,7 , 640,27 , 37,5 , 8,10 , 18255,60 , 15345,88 , 18123,24 , 18315,60 , 18375,88 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {80,69,78}, 278,2 , 13223,43 , 4,4 , 4,0 , 3704,7 , 3345,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru
+ { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 18,7 , 25,12 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {80,72,80}, 175,1 , 13266,48 , 13,5 , 4,0 , 3704,7 , 3864,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines
+ { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 1173,8 , 640,27 , 18,7 , 25,12 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12739,70 , 4,4 , 4,0 , 3704,7 , 1437,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Puerto Rico
+ { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 433,8 , 640,27 , 18,7 , 25,12 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12739,70 , 95,7 , 4,0 , 3704,7 , 3873,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/United States
+ { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18255,60 , 15345,88 , 18123,24 , 18315,60 , 18375,88 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,89,85}, 6,1 , 13314,48 , 8,5 , 4,0 , 3704,7 , 3887,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay
+ { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 18,7 , 25,12 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {86,69,70}, 308,3 , 13362,64 , 4,4 , 36,5 , 3704,7 , 3894,9 , 2, 0, 7, 6, 7 }, // Spanish/Latin/Venezuela
+ { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 55,4 , 426,11 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3704,7 , 3903,8 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Canary Islands
+ { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 4,4 , 4,0 , 3911,23 , 3934,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Latin America
+ { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 55,4 , 426,11 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3704,7 , 3947,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ceuta And Melilla
+ { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 632,8 , 632,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 18511,84 , 134,24 , 18463,48 , 18511,84 , 134,24 , 9767,60 , 9767,60 , 85,14 , 9767,60 , 9767,60 , 85,14 , 0,2 , 0,2 , 591,5 , 811,47 , 22,23 , {84,90,83}, 188,3 , 13426,67 , 4,4 , 4,0 , 3962,9 , 1616,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania
+ { 113, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 632,8 , 632,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 18511,84 , 134,24 , 18463,48 , 18511,84 , 134,24 , 9767,60 , 9767,60 , 85,14 , 9767,60 , 9767,60 , 85,14 , 0,2 , 0,2 , 591,5 , 811,47 , 22,23 , {67,68,70}, 203,2 , 13493,55 , 4,4 , 4,0 , 3971,8 , 3979,32 , 2, 1, 1, 6, 7 }, // Swahili/Latin/Congo Kinshasa
+ { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 632,8 , 632,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 18511,84 , 134,24 , 18463,48 , 18511,84 , 134,24 , 9767,60 , 9767,60 , 85,14 , 9767,60 , 9767,60 , 85,14 , 0,2 , 0,2 , 591,5 , 811,47 , 22,23 , {75,69,83}, 2,3 , 13548,58 , 4,4 , 4,0 , 3962,9 , 1182,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya
+ { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 632,8 , 632,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 18511,84 , 134,24 , 18463,48 , 18511,84 , 134,24 , 9767,60 , 9767,60 , 85,14 , 9767,60 , 9767,60 , 85,14 , 0,2 , 0,2 , 591,5 , 811,47 , 22,23 , {85,71,88}, 193,3 , 13606,61 , 4,4 , 4,0 , 3962,9 , 1681,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda
+ { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 640,9 , 640,9 , 53,10 , 98,16 , 37,5 , 437,16 , 18595,59 , 18654,86 , 134,24 , 18595,59 , 18654,86 , 134,24 , 9827,29 , 9856,50 , 2363,14 , 9827,29 , 9856,50 , 2363,14 , 299,2 , 267,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 186,2 , 13667,45 , 13,5 , 4,0 , 4011,7 , 4018,7 , 2, 0, 1, 6, 7 }, // Swedish/Latin/Sweden
+ { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 640,9 , 640,9 , 1181,10 , 98,16 , 37,5 , 437,16 , 18595,59 , 18654,86 , 134,24 , 18595,59 , 18654,86 , 134,24 , 9827,29 , 9856,50 , 2363,14 , 9827,29 , 9856,50 , 2363,14 , 299,2 , 267,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 4011,7 , 1079,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland
+ { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 640,9 , 640,9 , 53,10 , 98,16 , 37,5 , 437,16 , 18595,59 , 18654,86 , 134,24 , 18595,59 , 18654,86 , 134,24 , 9827,29 , 9856,50 , 2363,14 , 9827,29 , 9856,50 , 2363,14 , 299,2 , 267,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 4011,7 , 4025,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Aland Islands
+ { 116, 2, 209, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 80,18 , 37,5 , 8,10 , 11024,48 , 18740,71 , 11152,24 , 11024,48 , 18740,71 , 11152,24 , 9906,28 , 9934,55 , 9989,14 , 9906,28 , 9934,55 , 9989,14 , 301,7 , 269,7 , 45,4 , 5,17 , 22,23 , {84,74,83}, 311,4 , 13712,19 , 13,5 , 4,0 , 4030,6 , 4036,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan
+ { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 649,13 , 649,13 , 287,6 , 210,18 , 382,7 , 453,12 , 18811,58 , 18869,86 , 18955,31 , 18811,58 , 18869,86 , 18955,31 , 10003,39 , 10042,49 , 10091,20 , 10003,39 , 10042,49 , 10091,20 , 308,8 , 276,8 , 858,7 , 5,17 , 22,23 , {73,78,82}, 117,1 , 13731,49 , 8,5 , 4,0 , 4046,5 , 4051,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India
+ { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 649,13 , 649,13 , 287,6 , 210,18 , 382,7 , 453,12 , 18811,58 , 18869,86 , 18955,31 , 18811,58 , 18869,86 , 18955,31 , 10003,39 , 10042,49 , 10091,20 , 10003,39 , 10042,49 , 10091,20 , 308,8 , 276,8 , 858,7 , 5,17 , 22,23 , {77,89,82}, 170,2 , 13780,61 , 8,5 , 4,0 , 4046,5 , 4058,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia
+ { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 649,13 , 649,13 , 287,6 , 210,18 , 382,7 , 453,12 , 18811,58 , 18869,86 , 18955,31 , 18811,58 , 18869,86 , 18955,31 , 10003,39 , 10042,49 , 10091,20 , 10003,39 , 10042,49 , 10091,20 , 308,8 , 276,8 , 858,7 , 5,17 , 22,23 , {83,71,68}, 6,1 , 13841,61 , 8,5 , 4,0 , 4046,5 , 4065,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore
+ { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 649,13 , 649,13 , 287,6 , 210,18 , 37,5 , 8,10 , 18811,58 , 18869,86 , 18955,31 , 18811,58 , 18869,86 , 18955,31 , 10003,39 , 10042,49 , 10091,20 , 10003,39 , 10042,49 , 10091,20 , 308,8 , 276,8 , 858,7 , 5,17 , 22,23 , {76,75,82}, 315,3 , 13902,49 , 8,5 , 4,0 , 4046,5 , 4076,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Sri Lanka
+ { 118, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 662,9 , 662,9 , 981,10 , 1191,23 , 55,4 , 59,9 , 18986,62 , 19048,81 , 158,27 , 18986,62 , 19048,81 , 158,27 , 10111,36 , 10147,56 , 10203,14 , 10111,36 , 10147,56 , 10203,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 13951,21 , 0,4 , 4,0 , 4082,5 , 3415,6 , 2, 1, 1, 6, 7 }, // Tatar/Cyrillic/Russia
+ { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 671,11 , 671,11 , 357,8 , 1214,18 , 18,7 , 25,12 , 19129,62 , 19191,86 , 19277,31 , 19129,62 , 19191,86 , 19277,31 , 10217,32 , 10249,60 , 10309,18 , 10217,32 , 10249,60 , 10309,18 , 0,2 , 0,2 , 865,7 , 872,27 , 22,23 , {73,78,82}, 117,1 , 13972,26 , 4,4 , 4,0 , 4087,6 , 4093,8 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India
+ { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 123,5 , 123,5 , 682,8 , 690,7 , 287,6 , 1232,19 , 37,5 , 465,28 , 19308,63 , 19371,98 , 19308,63 , 19308,63 , 19371,98 , 19308,63 , 10327,23 , 10350,68 , 10418,16 , 10327,23 , 10350,68 , 10418,16 , 316,10 , 284,10 , 899,4 , 5,17 , 22,23 , {84,72,66}, 318,3 , 13998,16 , 4,4 , 4,0 , 4101,3 , 4101,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand
+ { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1251,23 , 18,7 , 25,12 , 2923,63 , 19469,159 , 158,27 , 2923,63 , 19628,147 , 158,27 , 10434,51 , 10485,79 , 10564,27 , 10434,51 , 10485,79 , 10564,27 , 326,7 , 294,8 , 45,4 , 5,17 , 22,23 , {67,78,89}, 321,1 , 14014,13 , 8,5 , 4,0 , 4104,8 , 4112,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China
+ { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1251,23 , 18,7 , 25,12 , 2923,63 , 19469,159 , 158,27 , 2923,63 , 19628,147 , 158,27 , 10434,51 , 10485,79 , 10564,27 , 10434,51 , 10485,79 , 10564,27 , 326,7 , 294,8 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 14027,19 , 8,5 , 4,0 , 4104,8 , 4118,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India
+ { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1274,23 , 18,7 , 25,12 , 19775,36 , 19811,54 , 19865,24 , 19775,36 , 19811,54 , 19865,24 , 10591,21 , 10612,29 , 10641,14 , 10591,21 , 10655,29 , 10684,14 , 333,7 , 302,7 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 14046,16 , 4,4 , 4,0 , 4125,4 , 82,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia
+ { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1274,23 , 18,7 , 25,12 , 19775,36 , 19811,54 , 19865,24 , 19775,36 , 19811,54 , 19865,24 , 10591,21 , 10612,29 , 10684,14 , 10591,21 , 10655,29 , 10684,14 , 333,7 , 302,7 , 45,4 , 5,17 , 22,23 , {69,82,78}, 41,3 , 0,7 , 4,4 , 4,0 , 4125,4 , 4129,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea
+ { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 697,8 , 697,8 , 697,8 , 697,8 , 287,6 , 98,16 , 18,7 , 25,12 , 19889,51 , 19940,87 , 20027,24 , 19889,51 , 19940,87 , 20027,24 , 10698,29 , 10727,60 , 10787,14 , 10698,29 , 10727,60 , 10787,14 , 340,10 , 309,6 , 903,5 , 908,59 , 967,65 , {84,79,80}, 191,2 , 14062,41 , 13,5 , 4,0 , 4133,13 , 1631,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga
+ { 124, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/South Africa
+ { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 705,8 , 705,8 , 1297,9 , 1306,16 , 37,5 , 8,10 , 20051,48 , 20099,75 , 20174,24 , 20051,48 , 20099,75 , 20174,24 , 10801,28 , 10829,54 , 10883,14 , 10801,28 , 10829,54 , 10883,14 , 350,2 , 315,2 , 193,4 , 5,17 , 22,23 , {84,82,89}, 244,1 , 14103,40 , 4,4 , 4,0 , 4146,6 , 4152,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey
+ { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 705,8 , 705,8 , 1297,9 , 1306,16 , 18,7 , 25,12 , 20051,48 , 20099,75 , 20174,24 , 20051,48 , 20099,75 , 20174,24 , 10801,28 , 10829,54 , 10883,14 , 10801,28 , 10829,54 , 10883,14 , 350,2 , 315,2 , 193,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 4,4 , 4,0 , 4146,6 , 4159,6 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus
+ { 126, 7, 218, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8220, 8221, 0,6 , 0,6 , 713,8 , 713,8 , 981,10 , 1306,16 , 37,5 , 8,10 , 20198,51 , 20249,77 , 20326,24 , 20350,51 , 20401,77 , 20326,24 , 10897,28 , 10925,54 , 10979,14 , 10993,28 , 11021,54 , 10979,14 , 352,13 , 317,14 , 1032,4 , 5,17 , 22,23 , {84,77,84}, 322,3 , 14143,49 , 13,5 , 4,0 , 4165,12 , 4177,12 , 2, 1, 1, 6, 7 }, // Turkmen/Latin/Turkmenistan
+ { 128, 1, 44, 46, 44, 59, 37, 48, 45, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 1322,17 , 18,7 , 25,12 , 20478,84 , 20478,84 , 158,27 , 20478,84 , 20478,84 , 158,27 , 11075,21 , 11096,55 , 11151,14 , 11075,21 , 11096,55 , 11151,14 , 365,12 , 331,12 , 45,4 , 5,17 , 22,23 , {67,78,89}, 129,1 , 14192,40 , 4,4 , 4,0 , 4189,8 , 4197,5 , 2, 1, 7, 6, 7 }, // Uighur/Arabic/China
+ { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 138,7 , 138,7 , 174,8 , 1339,22 , 37,5 , 8,10 , 20562,48 , 20610,95 , 20705,24 , 20729,67 , 20796,87 , 20883,24 , 1583,21 , 11165,56 , 11221,14 , 1583,21 , 11165,56 , 11221,14 , 377,2 , 343,2 , 1036,5 , 571,17 , 22,23 , {85,65,72}, 286,1 , 14232,49 , 13,5 , 4,0 , 4202,10 , 4212,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine
+ { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 721,10 , 731,9 , 287,6 , 1361,18 , 18,7 , 25,12 , 20907,68 , 20907,68 , 134,24 , 20907,68 , 20907,68 , 134,24 , 11235,36 , 11235,36 , 85,14 , 11235,36 , 11235,36 , 85,14 , 0,2 , 0,2 , 1041,4 , 5,17 , 22,23 , {80,75,82}, 172,2 , 14281,49 , 4,4 , 4,0 , 4219,4 , 3330,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan
+ { 130, 1, 100, 1643, 1644, 59, 37, 1776, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 740,6 , 740,6 , 287,6 , 1361,18 , 18,7 , 25,12 , 20907,68 , 20907,68 , 134,24 , 20907,68 , 20907,68 , 134,24 , 11235,36 , 11235,36 , 85,14 , 11235,36 , 11235,36 , 85,14 , 0,2 , 0,2 , 1041,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 14330,42 , 8,5 , 4,0 , 4219,4 , 4223,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India
+ { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8217, 8216, 0,6 , 0,6 , 746,8 , 746,8 , 27,8 , 1379,18 , 37,5 , 426,11 , 20975,48 , 21023,75 , 21098,24 , 21122,48 , 21170,75 , 21098,24 , 11271,32 , 11303,61 , 11364,14 , 11271,32 , 11303,61 , 11364,14 , 379,2 , 345,2 , 193,4 , 340,17 , 22,23 , {85,90,83}, 325,4 , 14372,58 , 13,5 , 4,0 , 4228,6 , 4234,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan
+ { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 412,8 , 1397,33 , 55,4 , 426,11 , 21245,47 , 14525,68 , 158,27 , 21245,47 , 14525,68 , 158,27 , 11378,21 , 7511,49 , 85,14 , 11378,21 , 7511,49 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {65,70,78}, 262,1 , 14430,13 , 13,5 , 4,0 , 4245,6 , 3122,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan
+ { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 667,19 , 37,5 , 87,12 , 11024,48 , 18740,71 , 11152,24 , 21292,48 , 21340,71 , 11152,24 , 11399,28 , 11427,53 , 11480,14 , 11494,28 , 11522,53 , 11480,14 , 381,2 , 347,2 , 45,4 , 5,17 , 22,23 , {85,90,83}, 329,3 , 14443,49 , 13,5 , 4,0 , 4251,7 , 4258,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan
+ { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 754,8 , 754,8 , 120,10 , 210,18 , 37,5 , 8,10 , 21411,75 , 21486,99 , 158,27 , 21585,75 , 21660,99 , 158,27 , 11575,33 , 11608,55 , 11663,21 , 11575,33 , 11608,55 , 11663,21 , 383,2 , 349,2 , 45,4 , 5,17 , 22,23 , {86,78,68}, 332,1 , 14492,33 , 13,5 , 4,0 , 4268,10 , 4278,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam
+ { 133, 7, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1430,23 , 37,5 , 8,10 , 21759,48 , 21807,74 , 21881,24 , 21905,48 , 21807,74 , 21881,24 , 11684,21 , 11705,43 , 11748,14 , 11762,28 , 11705,43 , 11748,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 8,5 , 4,0 , 4286,7 , 0,0 , 2, 1, 1, 6, 7 }, // Volapuk/Latin/World
+ { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 762,11 , 773,10 , 27,8 , 10,17 , 37,5 , 8,10 , 21953,52 , 22005,87 , 22092,26 , 22118,59 , 22005,87 , 22092,26 , 11790,29 , 11819,77 , 11896,15 , 11911,30 , 11819,77 , 11896,15 , 385,2 , 351,2 , 1045,7 , 5,17 , 22,23 , {71,66,80}, 115,1 , 14525,92 , 4,4 , 4,0 , 4293,7 , 4300,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/United Kingdom
+ { 135, 7, 187, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1181,10 , 1453,17 , 37,5 , 8,10 , 22177,47 , 22224,84 , 158,27 , 22177,47 , 22224,84 , 158,27 , 11941,28 , 11969,50 , 11941,28 , 11941,28 , 11969,50 , 11941,28 , 387,3 , 353,3 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 14617,65 , 8,5 , 4,0 , 4316,5 , 4321,8 , 0, 0, 1, 6, 7 }, // Wolof/Latin/Senegal
+ { 136, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/South Africa
+ { 137, 18, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 783,9 , 783,9 , 27,8 , 1470,19 , 37,5 , 8,10 , 22308,58 , 22366,92 , 158,27 , 22366,92 , 22366,92 , 158,27 , 12019,54 , 12019,54 , 85,14 , 12019,54 , 12019,54 , 85,14 , 390,11 , 356,10 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 41,6 , 4,0 , 4329,6 , 4335,5 , 2, 1, 1, 6, 7 }, // Yiddish/Hebrew/World
+ { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 22458,73 , 22531,121 , 158,27 , 22458,73 , 22531,121 , 158,27 , 12073,44 , 12117,69 , 85,14 , 12073,44 , 12117,69 , 85,14 , 401,5 , 366,5 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 14682,34 , 4,4 , 4,0 , 4340,10 , 4350,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria
+ { 138, 7, 23, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 22652,74 , 22726,134 , 158,27 , 22652,74 , 22726,134 , 158,27 , 12186,44 , 12230,69 , 85,14 , 12186,44 , 12230,69 , 85,14 , 406,5 , 371,5 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 14716,34 , 4,4 , 4,0 , 4340,10 , 4368,16 , 0, 0, 1, 6, 7 }, // Yoruba/Latin/Benin
+ { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 792,9 , 801,8 , 543,6 , 35,18 , 37,5 , 8,10 , 22860,48 , 22908,91 , 134,24 , 22860,48 , 22908,91 , 22999,24 , 12299,28 , 12327,74 , 12401,14 , 12299,28 , 12327,74 , 12401,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 14750,67 , 4,4 , 4,0 , 4384,7 , 4391,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/South Africa
+ { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 981,10 , 496,17 , 37,5 , 437,16 , 5904,48 , 13926,83 , 134,24 , 23023,59 , 13926,83 , 134,24 , 12415,28 , 12443,51 , 2363,14 , 12494,28 , 12443,51 , 2363,14 , 411,9 , 376,11 , 45,4 , 5,17 , 22,23 , {78,79,75}, 186,2 , 9799,44 , 13,5 , 4,0 , 4408,7 , 4415,5 , 2, 0, 1, 6, 7 }, // Norwegian Nynorsk/Latin/Norway
+ { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 8216, 8217, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 468,19 , 37,5 , 8,10 , 16459,48 , 23082,83 , 16435,24 , 16459,48 , 23082,83 , 16435,24 , 2086,28 , 2114,58 , 2172,14 , 2086,28 , 2114,58 , 2186,14 , 420,10 , 387,7 , 313,7 , 5,17 , 22,23 , {66,65,77}, 140,2 , 14817,170 , 13,5 , 4,0 , 4420,8 , 620,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/Bosnia And Herzegowina
+ { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 23165,48 , 23213,83 , 12531,24 , 23165,48 , 23213,83 , 12531,24 , 12522,28 , 12550,56 , 8617,14 , 12522,28 , 12550,56 , 8617,14 , 225,9 , 394,7 , 45,4 , 5,17 , 22,23 , {66,65,77}, 290,2 , 14987,151 , 13,5 , 4,0 , 4428,8 , 3512,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/Bosnia And Herzegowina
{ 143, 29, 131, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,86,82}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 5, 6, 7 }, // Divehi/Thaana/Maldives
- { 144, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 633,17 , 37,5 , 8,10 , 22420,102 , 22522,140 , 158,27 , 22420,102 , 22522,140 , 158,27 , 11891,30 , 11921,57 , 85,14 , 11891,30 , 11921,57 , 85,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 125,1 , 0,7 , 4,4 , 4,0 , 4329,5 , 4334,12 , 2, 1, 1, 6, 7 }, // Manx/Latin/IsleOfMan
- { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 98,16 , 37,5 , 8,10 , 22662,46 , 22708,130 , 158,27 , 22662,46 , 22708,130 , 158,27 , 11978,28 , 12006,61 , 85,14 , 11978,28 , 12006,61 , 85,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 125,1 , 0,7 , 4,4 , 4,0 , 4346,8 , 4354,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/UnitedKingdom
- { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1345,8 , 1353,18 , 18,7 , 25,12 , 22838,48 , 22886,192 , 158,27 , 22838,48 , 22886,192 , 158,27 , 12067,28 , 12095,49 , 12144,14 , 12067,28 , 12095,49 , 12144,14 , 390,2 , 361,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 173,3 , 14927,17 , 4,4 , 4,0 , 4368,4 , 4372,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana
- { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 941,6 , 98,16 , 18,7 , 25,12 , 23078,87 , 23078,87 , 158,27 , 23078,87 , 23078,87 , 158,27 , 7017,32 , 12158,55 , 85,14 , 7017,32 , 12158,55 , 85,14 , 184,5 , 363,5 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 0,7 , 8,5 , 4,0 , 4377,6 , 2589,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India
+ { 144, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 686,17 , 37,5 , 8,10 , 23296,102 , 23398,140 , 158,27 , 23296,102 , 23398,140 , 158,27 , 12606,30 , 12636,57 , 85,14 , 12606,30 , 12636,57 , 85,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 115,1 , 0,7 , 4,4 , 4,0 , 4436,5 , 4441,12 , 2, 1, 1, 6, 7 }, // Manx/Latin/Isle Of Man
+ { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 98,16 , 37,5 , 8,10 , 23538,46 , 23584,130 , 158,27 , 23538,46 , 23584,130 , 158,27 , 12693,28 , 12721,61 , 85,14 , 12693,28 , 12721,61 , 85,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 115,1 , 0,7 , 4,4 , 4,0 , 4453,8 , 4461,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/United Kingdom
+ { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1489,8 , 1497,18 , 18,7 , 25,12 , 23714,48 , 23762,192 , 158,27 , 23714,48 , 23762,192 , 158,27 , 12782,28 , 12810,49 , 12859,14 , 12782,28 , 12810,49 , 12859,14 , 430,2 , 401,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 163,3 , 15138,17 , 4,4 , 4,0 , 4475,4 , 4479,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana
+ { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1515,6 , 98,16 , 18,7 , 25,12 , 23954,88 , 23954,88 , 158,27 , 23954,88 , 23954,88 , 158,27 , 12873,49 , 12873,49 , 12922,20 , 12873,49 , 12873,49 , 12922,20 , 188,5 , 403,5 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 15155,13 , 8,5 , 4,0 , 4484,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India
{ 148, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Ga/Latin/Ghana
- { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 23165,48 , 23213,86 , 158,27 , 23165,48 , 23213,86 , 158,27 , 12213,29 , 12242,57 , 85,14 , 12213,29 , 12242,57 , 85,14 , 38,4 , 368,4 , 45,4 , 5,17 , 22,23 , {78,71,78}, 184,1 , 14944,12 , 4,4 , 4,0 , 4383,4 , 1303,7 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria
- { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 23299,48 , 23347,189 , 23536,24 , 23299,48 , 23347,189 , 23536,24 , 12299,28 , 12327,74 , 12401,14 , 12299,28 , 12327,74 , 12401,14 , 392,9 , 372,7 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 14956,23 , 4,4 , 4,0 , 4387,7 , 1153,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya
+ { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 24042,48 , 24090,86 , 158,27 , 24042,48 , 24090,86 , 158,27 , 12942,29 , 12971,57 , 85,14 , 12942,29 , 12971,57 , 85,14 , 40,4 , 408,4 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 15168,12 , 4,4 , 4,0 , 4490,4 , 4494,8 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria
+ { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 24176,48 , 24224,189 , 24413,24 , 24176,48 , 24224,189 , 24413,24 , 13028,28 , 13056,74 , 13130,14 , 13028,28 , 13056,74 , 13130,14 , 432,9 , 412,7 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15180,23 , 4,4 , 4,0 , 4502,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya
{ 151, 33, 103, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,81,68}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 6, 5, 6 }, // Syriac/Syriac/Iraq
{ 152, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,82,78}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Blin/Ethiopic/Eritrea
{ 153, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Geez/Ethiopic/Ethiopia
{ 155, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Sidamo/Latin/Ethiopia
- { 156, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 184,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Atsam/Latin/Nigeria
+ { 156, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Atsam/Latin/Nigeria
{ 157, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,82,78}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Tigre/Ethiopic/Eritrea
- { 158, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 184,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Jju/Latin/Nigeria
- { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 236,7 , 236,7 , 27,8 , 1371,27 , 37,5 , 8,10 , 23560,48 , 23608,77 , 23685,24 , 23560,48 , 23608,77 , 23685,24 , 12415,28 , 12443,50 , 3054,14 , 12415,28 , 12443,50 , 3054,14 , 401,2 , 379,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 8,5 , 4,0 , 4394,6 , 4400,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy
- { 160, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/SouthAfrica
- { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 720,11 , 731,10 , 516,6 , 1398,23 , 423,12 , 435,17 , 23709,48 , 23757,87 , 23844,24 , 23709,48 , 23757,87 , 23844,24 , 12493,28 , 12521,44 , 12565,14 , 12493,28 , 12521,44 , 12565,14 , 403,3 , 381,5 , 45,4 , 5,17 , 22,23 , {71,72,83}, 173,3 , 14979,37 , 4,4 , 4,0 , 4406,6 , 4412,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana
- { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 720,11 , 731,10 , 516,6 , 1398,23 , 37,5 , 8,10 , 23709,48 , 23757,87 , 23844,24 , 23709,48 , 23757,87 , 23844,24 , 12493,28 , 12521,44 , 12565,14 , 12493,28 , 12521,44 , 12565,14 , 403,3 , 381,5 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 15016,106 , 4,4 , 4,0 , 4406,6 , 4424,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo
+ { 158, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Jju/Latin/Nigeria
+ { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 1521,27 , 37,5 , 8,10 , 24437,48 , 24485,77 , 24562,24 , 24437,48 , 24485,77 , 24562,24 , 13144,28 , 13172,50 , 3150,14 , 13144,28 , 13172,50 , 3150,14 , 441,2 , 419,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 8,5 , 4,0 , 4509,6 , 4515,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy
+ { 160, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/South Africa
+ { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 809,11 , 820,10 , 543,6 , 1548,23 , 493,12 , 505,17 , 24586,48 , 24634,87 , 24721,24 , 24586,48 , 24634,87 , 24721,24 , 13222,28 , 13250,44 , 13294,14 , 13222,28 , 13250,44 , 13294,14 , 443,3 , 421,5 , 45,4 , 5,17 , 22,23 , {71,72,83}, 163,3 , 15203,37 , 4,4 , 4,0 , 4521,6 , 4527,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana
+ { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 809,11 , 820,10 , 543,6 , 1548,23 , 37,5 , 8,10 , 24586,48 , 24634,87 , 24721,24 , 24586,48 , 24634,87 , 24721,24 , 13222,28 , 13250,44 , 13294,14 , 13222,28 , 13250,44 , 13294,14 , 443,3 , 421,5 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 15240,106 , 4,4 , 4,0 , 4521,6 , 4539,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo
{ 162, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Walamo/Ethiopic/Ethiopia
- { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 278,6 , 10,17 , 18,7 , 25,12 , 23868,59 , 23927,95 , 158,27 , 23868,59 , 23927,95 , 158,27 , 12579,21 , 12600,57 , 85,14 , 12579,21 , 12600,57 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 4,4 , 4,0 , 4435,14 , 4449,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/UnitedStates
- { 164, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 184,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Tyap/Latin/Nigeria
+ { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 10,17 , 18,7 , 25,12 , 24745,59 , 24804,95 , 158,27 , 24745,59 , 24804,95 , 158,27 , 13308,21 , 13329,57 , 85,14 , 13308,21 , 13329,57 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 4,4 , 4,0 , 4550,14 , 4564,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/United States
+ { 164, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Tyap/Latin/Nigeria
{ 165, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,87,75}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Nyanja/Latin/Malawi
- { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 741,9 , 750,8 , 516,6 , 35,18 , 18,7 , 25,12 , 24022,48 , 24070,88 , 24158,38 , 24022,48 , 24070,88 , 24022,48 , 12657,28 , 12685,55 , 12657,28 , 12657,28 , 12685,55 , 12657,28 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,72,80}, 185,1 , 15122,58 , 4,4 , 4,0 , 4468,8 , 4476,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines
- { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7736,48 , 24196,86 , 134,24 , 7736,48 , 24196,86 , 134,24 , 12740,28 , 12768,63 , 3642,14 , 12740,28 , 12768,63 , 3642,14 , 406,12 , 386,11 , 45,4 , 5,17 , 22,23 , {67,72,70}, 229,3 , 15180,55 , 13,5 , 4,0 , 4485,16 , 4501,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland
- { 167, 7, 74, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7736,48 , 24196,86 , 134,24 , 7736,48 , 24196,86 , 134,24 , 12740,28 , 12768,63 , 3642,14 , 12740,28 , 12768,63 , 3642,14 , 406,12 , 386,11 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8339,19 , 13,5 , 4,0 , 4485,16 , 4508,10 , 2, 1, 1, 6, 7 }, // Swiss German/Latin/France
- { 167, 7, 123, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 251,9 , 251,9 , 175,8 , 532,18 , 37,5 , 8,10 , 7736,48 , 24196,86 , 134,24 , 7736,48 , 24196,86 , 134,24 , 12740,28 , 12768,63 , 3642,14 , 12740,28 , 12768,63 , 3642,14 , 406,12 , 386,11 , 45,4 , 5,17 , 22,23 , {67,72,70}, 229,3 , 15180,55 , 13,5 , 4,0 , 4485,16 , 4518,13 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Liechtenstein
- { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 24282,38 , 24282,38 , 158,27 , 24282,38 , 24282,38 , 158,27 , 12831,21 , 12852,28 , 12880,14 , 12831,21 , 12852,28 , 12880,14 , 418,2 , 397,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 329,1 , 0,7 , 8,5 , 4,0 , 4531,3 , 4534,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China
+ { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 830,9 , 839,8 , 543,6 , 35,18 , 18,7 , 25,12 , 24899,48 , 24947,88 , 25035,38 , 24899,48 , 24947,88 , 24899,48 , 13386,28 , 13414,55 , 13386,28 , 13386,28 , 13414,55 , 13386,28 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,72,80}, 175,1 , 15346,58 , 4,4 , 4,0 , 4583,8 , 4591,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines
+ { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 25073,86 , 134,24 , 7849,48 , 25073,86 , 134,24 , 13469,28 , 13497,63 , 3738,14 , 13469,28 , 13497,63 , 3738,14 , 446,12 , 426,11 , 45,4 , 5,17 , 22,23 , {67,72,70}, 217,3 , 15404,55 , 13,5 , 4,0 , 4600,16 , 4616,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland
+ { 167, 7, 74, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 25073,86 , 134,24 , 7849,48 , 25073,86 , 134,24 , 13469,28 , 13497,63 , 3738,14 , 13469,28 , 13497,63 , 3738,14 , 446,12 , 426,11 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 4600,16 , 4623,10 , 2, 1, 1, 6, 7 }, // Swiss German/Latin/France
+ { 167, 7, 123, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 25073,86 , 134,24 , 7849,48 , 25073,86 , 134,24 , 13469,28 , 13497,63 , 3738,14 , 13469,28 , 13497,63 , 3738,14 , 446,12 , 426,11 , 45,4 , 5,17 , 22,23 , {67,72,70}, 217,3 , 15404,55 , 13,5 , 4,0 , 4600,16 , 4633,13 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Liechtenstein
+ { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 25159,38 , 25159,38 , 158,27 , 25159,38 , 25159,38 , 158,27 , 13560,21 , 13581,28 , 13609,14 , 13560,21 , 13581,28 , 13609,14 , 458,2 , 437,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 321,1 , 0,7 , 8,5 , 4,0 , 4646,3 , 4649,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China
{ 169, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Kpelle/Latin/Liberia
- { 170, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 409,8 , 409,8 , 356,7 , 1421,23 , 452,10 , 462,19 , 7867,59 , 24320,85 , 134,24 , 7867,59 , 24320,85 , 134,24 , 12894,28 , 12922,65 , 3642,14 , 12894,28 , 12922,65 , 3642,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15235,15 , 13,5 , 4,0 , 4536,14 , 4550,11 , 2, 1, 1, 6, 7 }, // Low German/Latin/Germany
- { 170, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 409,8 , 409,8 , 356,7 , 1421,23 , 452,10 , 462,19 , 7867,59 , 24320,85 , 134,24 , 7867,59 , 24320,85 , 134,24 , 12894,28 , 12922,65 , 3642,14 , 12894,28 , 12922,65 , 3642,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15235,15 , 13,5 , 4,0 , 4536,14 , 4561,12 , 2, 1, 1, 6, 7 }, // Low German/Latin/Netherlands
- { 171, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/SouthAfrica
- { 172, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/SouthAfrica
- { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 210,8 , 210,8 , 53,10 , 63,17 , 37,5 , 8,10 , 24405,59 , 24464,145 , 24609,24 , 24405,59 , 24464,145 , 24609,24 , 12987,33 , 13020,75 , 13095,14 , 12987,33 , 13020,75 , 13095,14 , 420,11 , 399,13 , 45,4 , 5,17 , 22,23 , {78,79,75}, 196,2 , 15250,63 , 13,5 , 4,0 , 4573,15 , 4588,5 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Norway
- { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 210,8 , 210,8 , 53,10 , 63,17 , 37,5 , 8,10 , 24405,59 , 24464,145 , 24609,24 , 24405,59 , 24464,145 , 24609,24 , 12987,33 , 13020,75 , 13109,14 , 12987,33 , 13123,79 , 13109,14 , 420,11 , 399,13 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15313,23 , 13,5 , 4,0 , 4573,15 , 4593,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland
- { 173, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 210,8 , 210,8 , 53,10 , 63,17 , 37,5 , 8,10 , 24405,59 , 24464,145 , 24609,24 , 24405,59 , 24464,145 , 24609,24 , 12987,33 , 13020,75 , 13095,14 , 12987,33 , 13020,75 , 13095,14 , 420,11 , 399,13 , 45,4 , 5,17 , 22,23 , {83,69,75}, 196,2 , 15336,63 , 13,5 , 4,0 , 4573,15 , 4599,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Sweden
- { 174, 7, 208, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {84,87,68}, 341,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Taroko/Latin/Taiwan
- { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 24633,48 , 24681,88 , 24769,24 , 24633,48 , 24681,88 , 24769,24 , 13202,28 , 13230,62 , 13292,14 , 13202,28 , 13230,62 , 13292,14 , 431,6 , 412,3 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15399,24 , 4,4 , 4,0 , 4605,8 , 1153,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya
- { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 24793,48 , 24841,221 , 25062,24 , 24793,48 , 24841,221 , 25062,24 , 13306,28 , 13334,105 , 13439,14 , 13306,28 , 13334,105 , 13439,14 , 437,10 , 415,10 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15399,24 , 4,4 , 4,0 , 4613,7 , 1153,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya
- { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 25086,48 , 25134,77 , 25211,24 , 25086,48 , 25134,77 , 25211,24 , 13453,28 , 13481,59 , 13540,14 , 13453,28 , 13481,59 , 13540,14 , 447,6 , 425,7 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 15423,26 , 13,5 , 4,0 , 4620,6 , 4626,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal
- { 177, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 25086,48 , 25134,77 , 25211,24 , 25086,48 , 25134,77 , 25211,24 , 13453,28 , 13481,59 , 13540,14 , 13453,28 , 13481,59 , 13540,14 , 447,6 , 425,7 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 15449,25 , 13,5 , 4,0 , 4620,6 , 4634,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Cameroon
- { 177, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 25086,48 , 25134,77 , 25211,24 , 25086,48 , 25134,77 , 25211,24 , 13453,28 , 13481,59 , 13540,14 , 13453,28 , 13481,59 , 13540,14 , 447,6 , 425,7 , 45,4 , 5,17 , 22,23 , {71,78,70}, 221,2 , 0,7 , 13,5 , 4,0 , 4620,6 , 4642,4 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Guinea
- { 177, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 18,7 , 25,12 , 25086,48 , 25134,77 , 25211,24 , 25086,48 , 25134,77 , 25211,24 , 13453,28 , 13481,59 , 13540,14 , 13453,28 , 13481,59 , 13540,14 , 447,6 , 425,7 , 45,4 , 5,17 , 22,23 , {77,82,79}, 224,2 , 15474,22 , 13,5 , 4,0 , 4620,6 , 4646,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Mauritania
- { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 25235,48 , 25283,185 , 25468,24 , 25235,48 , 25283,185 , 25468,24 , 13554,28 , 13582,63 , 13645,14 , 13554,28 , 13582,63 , 13645,14 , 453,6 , 432,8 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15496,23 , 4,4 , 4,0 , 4654,6 , 1153,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya
- { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 25492,48 , 25540,173 , 25713,24 , 25492,48 , 25540,173 , 25713,24 , 13659,28 , 13687,105 , 13792,14 , 13659,28 , 13687,105 , 13792,14 , 459,7 , 440,5 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15519,25 , 4,4 , 4,0 , 4660,8 , 1153,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya
- { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 587,27 , 37,5 , 8,10 , 25737,48 , 25785,88 , 134,24 , 25737,48 , 25785,88 , 134,24 , 13806,28 , 13834,55 , 13889,14 , 13806,28 , 13834,55 , 13889,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,90,78}, 284,3 , 15544,28 , 0,4 , 4,0 , 4668,4 , 3210,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique
- { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 25873,52 , 25925,112 , 26037,24 , 25873,52 , 25925,112 , 26037,24 , 13903,28 , 13931,50 , 13981,14 , 13903,28 , 13931,50 , 13981,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 165,3 , 15572,24 , 4,4 , 4,0 , 4672,10 , 1762,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe
- { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26061,39 , 26100,194 , 26294,24 , 26061,39 , 26100,194 , 26294,24 , 13995,29 , 14024,65 , 14089,14 , 13995,29 , 14024,65 , 14089,14 , 466,8 , 445,7 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 15596,25 , 4,4 , 4,0 , 4682,9 , 1587,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania
- { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 26318,48 , 26366,81 , 26447,24 , 26318,48 , 26366,81 , 26447,24 , 14103,30 , 14133,47 , 85,14 , 14103,30 , 14133,47 , 85,14 , 474,6 , 452,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15621,21 , 0,4 , 4,0 , 4691,7 , 4698,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco
- { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 26471,48 , 26519,81 , 26600,24 , 26471,48 , 26519,81 , 26600,24 , 14180,30 , 14210,48 , 85,14 , 14180,30 , 14210,48 , 85,14 , 480,6 , 460,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15642,21 , 0,4 , 4,0 , 4704,10 , 4714,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco
- { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 18,7 , 25,12 , 26624,48 , 26672,84 , 26756,24 , 26624,48 , 26672,84 , 26756,24 , 14258,30 , 14288,51 , 14339,14 , 14258,30 , 14288,51 , 14339,14 , 486,7 , 468,9 , 45,4 , 5,17 , 22,23 , {68,90,68}, 208,2 , 15663,21 , 0,4 , 4,0 , 4720,9 , 4729,8 , 2, 1, 6, 5, 6 }, // Kabyle/Latin/Algeria
- { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26780,48 , 26828,152 , 134,24 , 26780,48 , 26828,152 , 134,24 , 14353,28 , 14381,74 , 14455,14 , 14353,28 , 14381,74 , 14455,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 203,3 , 15684,26 , 4,4 , 4,0 , 4737,10 , 1652,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda
- { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26980,48 , 27028,254 , 27282,24 , 26980,48 , 27028,254 , 27282,24 , 14469,28 , 14497,82 , 14579,14 , 14469,28 , 14497,82 , 14579,14 , 493,7 , 477,7 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 15710,29 , 0,4 , 4,0 , 4747,6 , 4753,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania
- { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 27306,87 , 134,24 , 18222,48 , 27306,87 , 134,24 , 14593,28 , 14621,62 , 14683,14 , 14593,28 , 14621,62 , 14683,14 , 500,5 , 484,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 15739,27 , 4,4 , 4,0 , 4763,8 , 1587,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania
- { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 27393,47 , 27440,92 , 27532,24 , 27393,47 , 27440,92 , 27532,24 , 14697,28 , 14725,44 , 14769,14 , 14697,28 , 14725,44 , 14769,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 15766,24 , 4,4 , 4,0 , 4771,9 , 2106,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali
- { 188, 75, 132, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Bambara/Nko/Mali
- { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 27556,48 , 27604,207 , 27811,24 , 27556,48 , 27604,207 , 27811,24 , 14783,28 , 14811,64 , 14875,14 , 14783,28 , 14811,64 , 14875,14 , 505,2 , 493,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15399,24 , 4,4 , 4,0 , 4780,6 , 1153,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya
- { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 758,8 , 758,8 , 516,6 , 35,18 , 18,7 , 25,12 , 27835,36 , 27871,58 , 27929,24 , 27835,36 , 27871,58 , 27929,24 , 14889,28 , 14917,49 , 14966,14 , 14889,28 , 14917,49 , 14966,14 , 507,3 , 495,6 , 942,6 , 5,17 , 22,23 , {85,83,68}, 6,1 , 15790,25 , 4,4 , 4,0 , 4786,3 , 4789,15 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/UnitedStates
- { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 27953,47 , 28000,68 , 28068,24 , 27953,47 , 28000,68 , 28068,24 , 14980,27 , 15007,48 , 15055,14 , 14980,27 , 15007,48 , 15055,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,85,82}, 182,2 , 15815,21 , 79,6 , 4,0 , 4804,14 , 4818,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius
- { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 28092,264 , 134,24 , 18222,48 , 28092,264 , 134,24 , 15069,28 , 15097,133 , 14089,14 , 15069,28 , 15097,133 , 14089,14 , 510,4 , 501,5 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 15739,27 , 4,4 , 4,0 , 4823,10 , 1587,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania
- { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 28356,83 , 28439,111 , 28550,24 , 28356,83 , 28439,111 , 28550,24 , 15230,36 , 15266,63 , 15329,14 , 15230,36 , 15266,63 , 15329,14 , 514,3 , 506,3 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 15836,29 , 79,6 , 4,0 , 4833,8 , 4841,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania
- { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 28574,48 , 28622,97 , 134,24 , 28574,48 , 28622,97 , 134,24 , 15343,28 , 15371,66 , 15437,14 , 15343,28 , 15371,66 , 15437,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 203,3 , 15865,26 , 0,4 , 4,0 , 4850,7 , 4857,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda
- { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 28719,48 , 28767,83 , 28850,24 , 28719,48 , 28767,83 , 28850,24 , 15451,80 , 15451,80 , 85,14 , 15451,80 , 15451,80 , 85,14 , 517,8 , 509,7 , 45,4 , 5,17 , 22,23 , {90,77,87}, 137,1 , 0,7 , 4,4 , 4,0 , 4864,9 , 1756,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia
- { 196, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 154,7 , 154,7 , 406,8 , 1444,27 , 37,5 , 8,10 , 28874,48 , 28922,85 , 134,24 , 28874,48 , 28922,85 , 134,24 , 15531,28 , 15559,73 , 15632,14 , 15531,28 , 15646,73 , 15632,14 , 68,2 , 65,2 , 45,4 , 297,17 , 22,23 , {67,86,69}, 283,1 , 15891,43 , 13,5 , 4,0 , 4873,12 , 4885,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/CapeVerde
- { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29007,48 , 29055,86 , 29141,24 , 29007,48 , 29055,86 , 29141,24 , 15719,28 , 15747,51 , 15798,14 , 15719,28 , 15747,51 , 15798,14 , 525,2 , 516,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15399,24 , 4,4 , 4,0 , 4895,6 , 1153,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya
- { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29165,49 , 29214,121 , 29335,24 , 29165,49 , 29214,121 , 29335,24 , 15812,28 , 15840,53 , 15893,14 , 15812,28 , 15840,53 , 15893,14 , 527,6 , 518,10 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15934,26 , 4,4 , 4,0 , 4901,8 , 4909,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya
- { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 29359,136 , 134,24 , 0,48 , 29359,136 , 134,24 , 15907,23 , 15930,92 , 16022,14 , 15907,23 , 15930,92 , 16022,14 , 533,7 , 528,5 , 45,4 , 5,17 , 22,23 , {78,65,68}, 6,1 , 15960,22 , 4,4 , 4,0 , 4921,13 , 4934,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia
- { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 27306,87 , 134,24 , 18222,48 , 27306,87 , 134,24 , 14593,28 , 14621,62 , 14683,14 , 14593,28 , 14621,62 , 14683,14 , 500,5 , 484,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 15739,27 , 4,4 , 4,0 , 4942,9 , 1587,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania
- { 201, 7, 82, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 409,8 , 409,8 , 1045,10 , 1471,23 , 37,5 , 8,10 , 29495,59 , 29554,87 , 12643,24 , 29641,48 , 29554,87 , 12643,24 , 16036,28 , 16064,72 , 3642,14 , 16036,28 , 16064,72 , 3642,14 , 540,16 , 533,16 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15982,11 , 13,5 , 4,0 , 4951,6 , 4957,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany
- { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29689,51 , 29740,132 , 158,27 , 29689,51 , 29740,132 , 158,27 , 14593,28 , 16136,58 , 14089,14 , 14593,28 , 16136,58 , 14089,14 , 556,9 , 549,6 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15993,25 , 4,4 , 4,0 , 4968,3 , 1153,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya
- { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29689,51 , 29740,132 , 158,27 , 29689,51 , 29740,132 , 158,27 , 14593,28 , 16136,58 , 14089,14 , 14593,28 , 16136,58 , 14089,14 , 556,9 , 549,6 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 16018,28 , 4,4 , 4,0 , 4968,3 , 4971,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania
- { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 28574,48 , 28622,97 , 134,24 , 28574,48 , 28622,97 , 134,24 , 16194,35 , 16229,65 , 16294,14 , 16194,35 , 16229,65 , 16294,14 , 565,6 , 555,6 , 45,4 , 5,17 , 22,23 , {85,71,88}, 203,3 , 15865,26 , 13,5 , 4,0 , 4979,7 , 4857,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda
- { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29872,48 , 18270,84 , 134,24 , 29872,48 , 18270,84 , 134,24 , 16308,21 , 16329,75 , 85,14 , 16308,21 , 16329,75 , 85,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16046,23 , 4,4 , 91,6 , 4986,7 , 1153,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya
- { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29920,48 , 18270,84 , 134,24 , 29920,48 , 18270,84 , 134,24 , 16404,28 , 9545,60 , 14683,14 , 16404,28 , 9545,60 , 14683,14 , 571,9 , 561,8 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 16069,28 , 13,5 , 4,0 , 4993,6 , 4999,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania
- { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29968,48 , 30016,94 , 30110,24 , 29968,48 , 30016,94 , 30110,24 , 16432,28 , 16460,69 , 16529,14 , 16432,28 , 16460,69 , 16529,14 , 580,9 , 569,6 , 45,4 , 5,17 , 22,23 , {85,71,88}, 203,3 , 16097,28 , 4,4 , 4,0 , 5007,6 , 1652,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda
- { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29968,48 , 30016,94 , 30110,24 , 29968,48 , 30016,94 , 30110,24 , 16432,28 , 16460,69 , 16529,14 , 16432,28 , 16460,69 , 16529,14 , 580,9 , 569,6 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16125,27 , 4,4 , 4,0 , 5007,6 , 5013,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya
+ { 170, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 427,8 , 427,8 , 383,7 , 1571,23 , 522,10 , 532,19 , 7980,59 , 25197,85 , 134,24 , 7980,59 , 25197,85 , 134,24 , 13623,28 , 13651,65 , 3738,14 , 13623,28 , 13651,65 , 3738,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15459,15 , 13,5 , 4,0 , 4651,14 , 4665,11 , 2, 1, 1, 6, 7 }, // Low German/Latin/Germany
+ { 170, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 427,8 , 427,8 , 383,7 , 1571,23 , 522,10 , 532,19 , 7980,59 , 25197,85 , 134,24 , 7980,59 , 25197,85 , 134,24 , 13623,28 , 13651,65 , 3738,14 , 13623,28 , 13651,65 , 3738,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15459,15 , 13,5 , 4,0 , 4651,14 , 4676,12 , 2, 1, 1, 6, 7 }, // Low German/Latin/Netherlands
+ { 171, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/South Africa
+ { 172, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/South Africa
+ { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 53,10 , 63,17 , 37,5 , 8,10 , 25282,59 , 25341,145 , 25486,24 , 25282,59 , 25341,145 , 25486,24 , 13716,33 , 13749,75 , 13824,14 , 13716,33 , 13749,75 , 13824,14 , 460,11 , 439,13 , 45,4 , 5,17 , 22,23 , {78,79,75}, 186,2 , 15474,63 , 13,5 , 4,0 , 4688,15 , 4703,5 , 2, 0, 1, 6, 7 }, // Northern Sami/Latin/Norway
+ { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 981,10 , 98,16 , 37,5 , 8,10 , 25510,60 , 25341,145 , 25486,24 , 25510,60 , 25341,145 , 25486,24 , 13838,21 , 13859,70 , 13929,14 , 13838,21 , 13859,70 , 13929,14 , 471,2 , 452,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15537,23 , 13,5 , 4,0 , 4688,15 , 4708,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland
+ { 173, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 53,10 , 63,17 , 37,5 , 8,10 , 25282,59 , 25341,145 , 25486,24 , 25282,59 , 25341,145 , 25486,24 , 13716,33 , 13749,75 , 13824,14 , 13716,33 , 13749,75 , 13824,14 , 460,11 , 439,13 , 45,4 , 5,17 , 22,23 , {83,69,75}, 186,2 , 15560,63 , 13,5 , 4,0 , 4688,15 , 4714,6 , 2, 0, 1, 6, 7 }, // Northern Sami/Latin/Sweden
+ { 174, 7, 208, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {84,87,68}, 333,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Taroko/Latin/Taiwan
+ { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 25570,48 , 25618,88 , 25706,24 , 25570,48 , 25618,88 , 25706,24 , 13943,28 , 13971,62 , 14033,14 , 13943,28 , 13971,62 , 14033,14 , 473,6 , 454,3 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15623,24 , 4,4 , 4,0 , 4720,8 , 1182,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya
+ { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 25730,48 , 25778,221 , 25999,24 , 25730,48 , 25778,221 , 25999,24 , 14047,28 , 14075,105 , 14180,14 , 14047,28 , 14075,105 , 14180,14 , 479,10 , 457,10 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15623,24 , 4,4 , 4,0 , 4728,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya
+ { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 26023,48 , 26071,77 , 26148,24 , 26023,48 , 26071,77 , 26148,24 , 14194,28 , 14222,59 , 14281,14 , 14194,28 , 14222,59 , 14281,14 , 489,6 , 467,7 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 15647,26 , 13,5 , 4,0 , 4735,6 , 4321,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal
+ { 177, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 26023,48 , 26071,77 , 26148,24 , 26023,48 , 26071,77 , 26148,24 , 14194,28 , 14222,59 , 14281,14 , 14194,28 , 14222,59 , 14281,14 , 489,6 , 467,7 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 15673,25 , 13,5 , 4,0 , 4735,6 , 4741,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Cameroon
+ { 177, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 26023,48 , 26071,77 , 26148,24 , 26023,48 , 26071,77 , 26148,24 , 14194,28 , 14222,59 , 14281,14 , 14194,28 , 14222,59 , 14281,14 , 489,6 , 467,7 , 45,4 , 5,17 , 22,23 , {71,78,70}, 209,2 , 0,7 , 13,5 , 4,0 , 4735,6 , 4749,4 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Guinea
+ { 177, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 18,7 , 25,12 , 26023,48 , 26071,77 , 26148,24 , 26023,48 , 26071,77 , 26148,24 , 14194,28 , 14222,59 , 14281,14 , 14194,28 , 14222,59 , 14281,14 , 489,6 , 467,7 , 45,4 , 5,17 , 22,23 , {77,82,85}, 212,2 , 15698,22 , 13,5 , 4,0 , 4735,6 , 4753,8 , 2, 1, 1, 6, 7 }, // Fulah/Latin/Mauritania
+ { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26172,48 , 26220,185 , 26405,24 , 26172,48 , 26220,185 , 26405,24 , 14295,28 , 14323,63 , 14386,14 , 14295,28 , 14323,63 , 14386,14 , 495,6 , 474,8 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15720,23 , 4,4 , 4,0 , 4761,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya
+ { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26429,48 , 26477,173 , 26650,24 , 26429,48 , 26477,173 , 26650,24 , 14400,28 , 14428,105 , 14533,14 , 14400,28 , 14428,105 , 14533,14 , 501,7 , 482,5 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15743,25 , 4,4 , 4,0 , 4767,8 , 1182,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya
+ { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 640,27 , 37,5 , 8,10 , 26674,48 , 26722,88 , 134,24 , 26674,48 , 26722,88 , 134,24 , 14547,28 , 14575,55 , 14630,14 , 14547,28 , 14575,55 , 14630,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,90,78}, 272,3 , 15768,28 , 0,4 , 4,0 , 4775,4 , 3255,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique
+ { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26810,52 , 26862,112 , 26974,24 , 26810,52 , 26862,112 , 26974,24 , 14644,28 , 14672,50 , 14722,14 , 14644,28 , 14672,50 , 14722,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 155,3 , 15796,24 , 4,4 , 4,0 , 4779,10 , 1791,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe
+ { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26998,39 , 27037,194 , 27231,24 , 26998,39 , 27037,194 , 27231,24 , 14736,29 , 14765,65 , 14830,14 , 14736,29 , 14765,65 , 14830,14 , 508,8 , 487,7 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15820,25 , 4,4 , 4,0 , 4789,9 , 1616,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania
+ { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 27255,48 , 27303,81 , 27384,24 , 27255,48 , 27303,81 , 27384,24 , 14844,30 , 14874,47 , 85,14 , 14844,30 , 14874,47 , 85,14 , 516,6 , 494,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15845,21 , 0,4 , 4,0 , 4798,7 , 4805,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco
+ { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 27408,48 , 27456,81 , 27537,24 , 27408,48 , 27456,81 , 27537,24 , 14921,30 , 14951,48 , 85,14 , 14921,30 , 14951,48 , 85,14 , 522,6 , 502,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15866,21 , 0,4 , 4,0 , 4811,10 , 4821,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco
+ { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 122, 171, 187, 8220, 8221, 0,6 , 0,6 , 847,12 , 859,11 , 433,8 , 98,16 , 18,7 , 25,12 , 27561,48 , 27609,82 , 27691,24 , 27715,48 , 27763,84 , 27847,24 , 14999,28 , 15027,34 , 15061,14 , 15075,30 , 15105,51 , 15156,14 , 528,7 , 510,9 , 1052,7 , 1059,23 , 1082,29 , {68,90,68}, 198,2 , 15887,53 , 0,4 , 4,0 , 4827,9 , 4836,8 , 2, 1, 6, 5, 6 }, // Kabyle/Latin/Algeria
+ { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 27871,48 , 27919,152 , 134,24 , 27871,48 , 27919,152 , 134,24 , 15170,28 , 15198,74 , 15272,14 , 15170,28 , 15198,74 , 15272,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 15940,26 , 4,4 , 4,0 , 4844,10 , 1681,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda
+ { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 28071,48 , 28119,254 , 28373,24 , 28071,48 , 28119,254 , 28373,24 , 15286,28 , 15314,82 , 15396,14 , 15286,28 , 15314,82 , 15396,14 , 535,7 , 519,7 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15966,29 , 0,4 , 4,0 , 4854,6 , 4860,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania
+ { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 28397,87 , 134,24 , 18463,48 , 28397,87 , 134,24 , 15410,28 , 15438,62 , 15500,14 , 15410,28 , 15438,62 , 15500,14 , 542,5 , 526,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15995,27 , 4,4 , 4,0 , 4870,8 , 1616,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania
+ { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 28484,47 , 28531,92 , 28623,24 , 28484,47 , 28531,92 , 28623,24 , 15514,28 , 15542,44 , 15586,14 , 15514,28 , 15542,44 , 15586,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16022,24 , 4,4 , 4,0 , 4878,9 , 2155,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali
+ { 188, 75, 132, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Bambara/Nko/Mali
+ { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 28647,48 , 28695,207 , 28902,24 , 28647,48 , 28695,207 , 28902,24 , 15600,28 , 15628,64 , 15692,14 , 15600,28 , 15628,64 , 15692,14 , 547,2 , 535,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15623,24 , 4,4 , 4,0 , 4887,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya
+ { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 870,8 , 870,8 , 543,6 , 35,18 , 18,7 , 25,12 , 28926,36 , 28962,58 , 29020,24 , 28926,36 , 28962,58 , 29020,24 , 15706,28 , 15734,49 , 15783,14 , 15706,28 , 15734,49 , 15783,14 , 549,3 , 537,6 , 1111,6 , 5,17 , 22,23 , {85,83,68}, 6,1 , 16046,25 , 4,4 , 4,0 , 4893,3 , 4896,15 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/United States
+ { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 29044,47 , 29091,68 , 29159,24 , 29044,47 , 29091,68 , 29159,24 , 15797,27 , 15824,48 , 15872,14 , 15797,27 , 15824,48 , 15872,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,85,82}, 172,2 , 16071,21 , 41,6 , 4,0 , 4911,14 , 4925,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius
+ { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 29183,264 , 134,24 , 18463,48 , 29183,264 , 134,24 , 15886,28 , 15914,133 , 14830,14 , 15886,28 , 15914,133 , 14830,14 , 552,4 , 543,5 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15995,27 , 4,4 , 4,0 , 4930,10 , 1616,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania
+ { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29447,83 , 29530,111 , 29641,24 , 29447,83 , 29530,111 , 29641,24 , 16047,36 , 16083,63 , 16146,14 , 16047,36 , 16083,63 , 16146,14 , 556,3 , 548,3 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16092,29 , 41,6 , 4,0 , 4940,8 , 4948,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania
+ { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29665,48 , 29713,97 , 134,24 , 29665,48 , 29713,97 , 134,24 , 16160,28 , 16188,66 , 16254,14 , 16160,28 , 16188,66 , 16254,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 16121,26 , 0,4 , 4,0 , 4957,7 , 4964,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda
+ { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 29810,48 , 29858,83 , 29941,24 , 29810,48 , 29858,83 , 29941,24 , 16268,80 , 16268,80 , 85,14 , 16268,80 , 16268,80 , 85,14 , 559,8 , 551,7 , 45,4 , 5,17 , 22,23 , {90,77,87}, 127,1 , 0,7 , 4,4 , 4,0 , 4971,9 , 1785,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia
+ { 196, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 163,7 , 163,7 , 433,8 , 1594,27 , 37,5 , 8,10 , 29965,48 , 30013,85 , 134,24 , 29965,48 , 30013,85 , 134,24 , 16348,28 , 16376,73 , 16449,14 , 16348,28 , 16463,73 , 16449,14 , 70,2 , 67,2 , 45,4 , 340,17 , 22,23 , {67,86,69}, 271,1 , 16147,43 , 13,5 , 4,0 , 4980,12 , 4992,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/Cape Verde
+ { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30098,48 , 30146,86 , 30232,24 , 30098,48 , 30146,86 , 30232,24 , 16536,28 , 16564,51 , 16615,14 , 16536,28 , 16564,51 , 16615,14 , 567,2 , 558,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15623,24 , 4,4 , 4,0 , 5002,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya
+ { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30256,49 , 30305,121 , 30426,24 , 30256,49 , 30305,121 , 30426,24 , 16629,28 , 16657,53 , 16710,14 , 16629,28 , 16657,53 , 16710,14 , 569,6 , 560,10 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16190,26 , 4,4 , 4,0 , 5008,8 , 5016,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya
+ { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 30450,136 , 134,24 , 0,48 , 30450,136 , 134,24 , 16724,23 , 16747,92 , 16839,14 , 16724,23 , 16747,92 , 16839,14 , 575,7 , 570,5 , 45,4 , 5,17 , 22,23 , {78,65,68}, 6,1 , 16216,22 , 4,4 , 4,0 , 5028,13 , 5041,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia
+ { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 28397,87 , 134,24 , 18463,48 , 28397,87 , 134,24 , 15410,28 , 15438,62 , 15500,14 , 15410,28 , 15438,62 , 15500,14 , 542,5 , 526,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15995,27 , 4,4 , 4,0 , 5049,9 , 1616,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania
+ { 201, 7, 82, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 427,8 , 427,8 , 1089,10 , 1621,23 , 37,5 , 8,10 , 30586,59 , 30645,87 , 12825,24 , 30732,48 , 30645,87 , 12825,24 , 16853,28 , 16881,72 , 3738,14 , 16853,28 , 16881,72 , 3738,14 , 582,16 , 575,16 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16238,11 , 13,5 , 4,0 , 5058,6 , 5064,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany
+ { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30780,51 , 30831,132 , 158,27 , 30780,51 , 30831,132 , 158,27 , 15410,28 , 16953,58 , 14830,14 , 15410,28 , 16953,58 , 14830,14 , 598,9 , 591,6 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16249,25 , 4,4 , 4,0 , 5075,3 , 1182,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya
+ { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30780,51 , 30831,132 , 158,27 , 30780,51 , 30831,132 , 158,27 , 15410,28 , 16953,58 , 14830,14 , 15410,28 , 16953,58 , 14830,14 , 598,9 , 591,6 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16274,28 , 4,4 , 4,0 , 5075,3 , 5078,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania
+ { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29665,48 , 29713,97 , 134,24 , 29665,48 , 29713,97 , 134,24 , 17011,35 , 17046,65 , 17111,14 , 17011,35 , 17046,65 , 17111,14 , 607,6 , 597,6 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 16121,26 , 13,5 , 4,0 , 5086,7 , 4964,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda
+ { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30963,48 , 18511,84 , 134,24 , 30963,48 , 18511,84 , 134,24 , 17125,21 , 17146,75 , 85,14 , 17125,21 , 17146,75 , 85,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16302,23 , 4,4 , 102,6 , 5093,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya
+ { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31011,48 , 18511,84 , 134,24 , 31011,48 , 18511,84 , 134,24 , 17221,28 , 9767,60 , 15500,14 , 17221,28 , 9767,60 , 15500,14 , 613,9 , 603,8 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16325,28 , 13,5 , 4,0 , 5100,6 , 5106,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania
+ { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31059,48 , 31107,94 , 31201,24 , 31059,48 , 31107,94 , 31201,24 , 17249,28 , 17277,69 , 17346,14 , 17249,28 , 17277,69 , 17346,14 , 622,9 , 611,6 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 16353,28 , 4,4 , 4,0 , 5114,6 , 1681,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda
+ { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31059,48 , 31107,94 , 31201,24 , 31059,48 , 31107,94 , 31201,24 , 17249,28 , 17277,69 , 17346,14 , 17249,28 , 17277,69 , 17346,14 , 622,9 , 611,6 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16381,27 , 4,4 , 4,0 , 5114,6 , 5120,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya
{ 207, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,82,78}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Saho/Latin/Eritrea
- { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 30134,46 , 30180,88 , 30268,24 , 30134,46 , 30180,88 , 30268,24 , 16543,28 , 16571,53 , 16624,14 , 16543,28 , 16571,53 , 16624,14 , 589,6 , 575,6 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 16152,23 , 0,4 , 4,0 , 5018,11 , 5029,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali
- { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 27306,87 , 134,24 , 18222,48 , 27306,87 , 134,24 , 14593,28 , 14621,62 , 14683,14 , 14593,28 , 14621,62 , 14683,14 , 500,5 , 484,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 15739,27 , 0,4 , 4,0 , 5034,6 , 1587,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania
- { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30292,48 , 30340,186 , 30526,24 , 30292,48 , 30340,186 , 30526,24 , 16638,28 , 16666,69 , 16735,14 , 16638,28 , 16666,69 , 16735,14 , 595,2 , 581,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16175,23 , 0,4 , 4,0 , 5040,6 , 1153,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya
- { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26780,48 , 26828,152 , 134,24 , 26780,48 , 26828,152 , 134,24 , 14353,28 , 14381,74 , 14455,14 , 14353,28 , 14381,74 , 14455,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 203,3 , 15684,26 , 4,4 , 4,0 , 5046,6 , 1652,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda
- { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30550,48 , 30598,86 , 30684,24 , 30550,48 , 30598,86 , 30684,24 , 16749,28 , 16777,48 , 16825,14 , 16749,28 , 16777,48 , 16825,14 , 597,9 , 583,10 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 16198,22 , 13,5 , 4,0 , 5052,17 , 5069,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco
- { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 30134,46 , 30180,88 , 30268,24 , 30134,46 , 30180,88 , 30268,24 , 16839,28 , 16867,54 , 16624,14 , 16839,28 , 16867,54 , 16624,14 , 589,6 , 575,6 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 16152,23 , 0,4 , 4,0 , 5075,15 , 5029,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali
- { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18222,48 , 30708,84 , 134,24 , 18222,48 , 30708,84 , 134,24 , 16921,28 , 16949,63 , 17012,14 , 16921,28 , 16949,63 , 17012,14 , 606,5 , 593,8 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 16220,27 , 0,4 , 4,0 , 5090,9 , 1587,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania
- { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 516,6 , 35,18 , 18,7 , 25,12 , 30792,88 , 30792,88 , 30880,31 , 30792,88 , 30792,88 , 30880,31 , 17026,33 , 17059,54 , 17113,19 , 17026,33 , 17059,54 , 17113,19 , 611,3 , 601,6 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 16247,10 , 8,5 , 4,0 , 5099,4 , 2589,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India
- { 218, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 20846,48 , 11053,80 , 158,27 , 20846,48 , 11053,80 , 158,27 , 17132,74 , 17132,74 , 85,14 , 17132,74 , 17132,74 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 129,1 , 16257,43 , 13,5 , 4,0 , 5103,7 , 5110,5 , 2, 1, 1, 6, 7 }, // Chechen/Cyrillic/Russia
- { 219, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 766,8 , 766,8 , 1494,10 , 1504,23 , 37,5 , 8,10 , 30911,65 , 30976,117 , 31093,30 , 30911,65 , 31123,117 , 31093,30 , 17206,37 , 17243,68 , 10707,14 , 17206,37 , 17243,68 , 10707,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 129,1 , 16300,44 , 13,5 , 4,0 , 5115,19 , 5134,7 , 2, 1, 1, 6, 7 }, // Church/Cyrillic/Russia
- { 220, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 129,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Chuvash/Cyrillic/Russia
- { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 31240,49 , 31289,99 , 31388,24 , 31240,49 , 31289,99 , 31388,24 , 17311,28 , 17339,50 , 17389,14 , 17311,28 , 17339,50 , 17389,14 , 614,5 , 607,6 , 45,4 , 5,17 , 22,23 , {67,68,70}, 215,2 , 16344,24 , 0,4 , 4,0 , 5141,8 , 5149,16 , 2, 1, 1, 6, 7 }, // LubaKatanga/Latin/CongoKinshasa
- { 231, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 774,10 , 774,10 , 175,8 , 532,18 , 37,5 , 8,10 , 31412,48 , 31460,85 , 134,24 , 31545,59 , 31460,85 , 134,24 , 17403,28 , 17431,65 , 3642,14 , 17496,35 , 17431,65 , 3642,14 , 619,5 , 613,8 , 409,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8339,19 , 13,5 , 4,0 , 5165,14 , 5179,10 , 2, 1, 1, 6, 7 }, // Luxembourgish/Latin/Luxembourg
+ { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 31225,46 , 31271,88 , 31359,24 , 31225,46 , 31271,88 , 31359,24 , 17360,28 , 17388,53 , 17441,14 , 17360,28 , 17388,53 , 17441,14 , 631,6 , 617,6 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16408,23 , 0,4 , 4,0 , 5125,11 , 5136,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali
+ { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 28397,87 , 134,24 , 18463,48 , 28397,87 , 134,24 , 15410,28 , 15438,62 , 15500,14 , 15410,28 , 15438,62 , 15500,14 , 542,5 , 526,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15995,27 , 0,4 , 4,0 , 5141,6 , 1616,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania
+ { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31383,48 , 31431,186 , 31617,24 , 31383,48 , 31431,186 , 31617,24 , 17455,28 , 17483,69 , 17552,14 , 17455,28 , 17483,69 , 17552,14 , 637,2 , 623,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16431,23 , 0,4 , 4,0 , 5147,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya
+ { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 27871,48 , 27919,152 , 134,24 , 27871,48 , 27919,152 , 134,24 , 15170,28 , 15198,74 , 15272,14 , 15170,28 , 15198,74 , 15272,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 15940,26 , 4,4 , 4,0 , 5153,6 , 1681,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda
+ { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31641,48 , 31689,86 , 31775,24 , 31641,48 , 31689,86 , 31775,24 , 17566,28 , 17594,48 , 17642,14 , 17566,28 , 17594,48 , 17642,14 , 639,9 , 625,10 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 16454,22 , 13,5 , 4,0 , 5159,17 , 5176,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco
+ { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 31225,46 , 31271,88 , 31359,24 , 31225,46 , 31271,88 , 31359,24 , 17656,28 , 17684,54 , 17441,14 , 17656,28 , 17684,54 , 17441,14 , 631,6 , 617,6 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16408,23 , 0,4 , 4,0 , 5182,15 , 5136,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali
+ { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 31799,84 , 134,24 , 18463,48 , 31799,84 , 134,24 , 17738,28 , 17766,63 , 17829,14 , 17738,28 , 17766,63 , 17829,14 , 648,5 , 635,8 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16476,27 , 0,4 , 4,0 , 5197,9 , 1616,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania
+ { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 543,6 , 35,18 , 18,7 , 25,12 , 31883,88 , 31883,88 , 31971,31 , 31883,88 , 31883,88 , 31971,31 , 17843,33 , 17876,54 , 17930,19 , 17843,33 , 17876,54 , 17930,19 , 653,3 , 643,6 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 16503,10 , 8,5 , 4,0 , 5206,4 , 2633,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India
+ { 218, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 21292,48 , 11235,80 , 11152,24 , 21292,48 , 11235,80 , 11152,24 , 17949,25 , 17974,45 , 18019,17 , 17949,25 , 17974,45 , 17949,25 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 16513,43 , 13,5 , 4,0 , 5210,7 , 5217,5 , 2, 1, 1, 6, 7 }, // Chechen/Cyrillic/Russia
+ { 219, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 878,8 , 878,8 , 955,10 , 1644,23 , 37,5 , 8,10 , 32002,65 , 32067,117 , 32184,30 , 32002,65 , 32214,117 , 32184,30 , 18036,37 , 18073,68 , 11221,14 , 18036,37 , 18073,68 , 11221,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 16556,44 , 13,5 , 4,0 , 5222,19 , 5241,7 , 2, 1, 1, 6, 7 }, // Church/Cyrillic/Russia
+ { 220, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Chuvash/Cyrillic/Russia
+ { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 32331,49 , 32380,99 , 32479,24 , 32331,49 , 32380,99 , 32479,24 , 18141,28 , 18169,50 , 18219,14 , 18141,28 , 18169,50 , 18219,14 , 656,5 , 649,6 , 45,4 , 5,17 , 22,23 , {67,68,70}, 203,2 , 16600,24 , 0,4 , 4,0 , 5248,8 , 5256,16 , 2, 1, 1, 6, 7 }, // Luba Katanga/Latin/Congo Kinshasa
+ { 231, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 886,10 , 886,10 , 174,8 , 593,18 , 37,5 , 8,10 , 32503,48 , 32551,85 , 134,24 , 32636,59 , 32551,85 , 134,24 , 18233,28 , 18261,65 , 3738,14 , 18326,35 , 18261,65 , 3738,14 , 661,5 , 655,8 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 5272,14 , 5286,10 , 2, 1, 1, 6, 7 }, // Luxembourgish/Latin/Luxembourg
{ 236, 7, 21, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Walloon/Latin/Belgium
- { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 31604,48 , 31652,195 , 31847,24 , 31604,48 , 31652,195 , 31847,24 , 17531,28 , 17559,72 , 17631,14 , 17531,28 , 17559,72 , 17631,14 , 624,3 , 621,3 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16368,21 , 0,4 , 4,0 , 5189,5 , 5194,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon
- { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 31871,48 , 31919,90 , 32009,24 , 31871,48 , 31919,90 , 32009,24 , 17645,28 , 17673,70 , 17743,14 , 17645,28 , 17673,70 , 17743,14 , 627,10 , 624,9 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16389,22 , 13,5 , 4,0 , 5201,5 , 5206,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon
- { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 30134,46 , 30180,88 , 30268,24 , 30134,46 , 30180,88 , 30268,24 , 16839,28 , 17757,53 , 17810,14 , 16839,28 , 17757,53 , 17810,14 , 637,8 , 633,10 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 16152,23 , 0,4 , 4,0 , 5214,10 , 5224,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger
- { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 32033,49 , 32082,99 , 32181,24 , 32033,49 , 32082,99 , 32181,24 , 17824,28 , 17852,45 , 17897,14 , 17824,28 , 17852,45 , 17897,14 , 645,5 , 643,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 13,5 , 4,0 , 5229,5 , 1903,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon
- { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 32205,36 , 32241,82 , 32323,24 , 32205,36 , 32241,82 , 32323,24 , 17911,28 , 17939,50 , 17989,14 , 17911,28 , 17939,50 , 17989,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 16411,23 , 13,5 , 4,0 , 5234,5 , 5239,7 , 0, 0, 1, 6, 7 }, // JolaFonyi/Latin/Senegal
- { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 32347,50 , 32397,141 , 32538,24 , 32347,50 , 32397,141 , 32538,24 , 18003,30 , 18033,85 , 18118,14 , 18003,30 , 18033,85 , 18118,14 , 650,7 , 649,9 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16434,23 , 13,5 , 4,0 , 5246,6 , 5252,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon
- { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 32562,39 , 32601,191 , 158,27 , 32562,39 , 32601,191 , 158,27 , 18132,29 , 18161,45 , 18206,14 , 18132,29 , 18161,45 , 18206,14 , 657,6 , 658,7 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16457,11 , 13,5 , 4,0 , 5259,5 , 5264,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon
- { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 32792,48 , 32840,213 , 33053,24 , 32792,48 , 32840,213 , 33053,24 , 18220,28 , 18248,59 , 18307,14 , 18220,28 , 18248,59 , 18307,14 , 663,8 , 665,10 , 45,4 , 5,17 , 22,23 , {77,90,78}, 284,3 , 0,7 , 79,6 , 4,0 , 5271,5 , 5276,10 , 2, 1, 7, 6, 7 }, // MakhuwaMeetto/Latin/Mozambique
- { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 33077,48 , 33125,139 , 33264,24 , 33077,48 , 33125,139 , 33264,24 , 18321,28 , 18349,74 , 18423,14 , 18321,28 , 18349,74 , 18423,14 , 671,5 , 675,5 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16468,17 , 4,4 , 4,0 , 5286,6 , 5292,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon
- { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 33288,51 , 33339,143 , 158,27 , 33288,51 , 33339,143 , 158,27 , 18437,30 , 18467,89 , 18556,14 , 18437,30 , 18467,89 , 18556,14 , 676,4 , 680,4 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16485,20 , 13,5 , 4,0 , 5299,6 , 5305,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon
- { 247, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1527,9 , 98,16 , 18,7 , 481,12 , 33482,54 , 33536,96 , 33632,24 , 33482,54 , 33536,96 , 33632,24 , 18570,38 , 18608,79 , 18687,14 , 18570,38 , 18608,79 , 18687,14 , 680,2 , 684,2 , 45,4 , 5,17 , 22,23 , {83,83,80}, 125,1 , 0,7 , 4,4 , 4,0 , 5312,9 , 0,0 , 2, 1, 1, 6, 7 }, // Nuer/Latin/SouthSudan
- { 248, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 784,11 , 784,11 , 246,6 , 1536,30 , 37,5 , 8,10 , 33656,50 , 33706,116 , 33822,24 , 33656,50 , 33846,121 , 33822,24 , 18701,21 , 18722,71 , 18793,14 , 18701,21 , 18722,71 , 18793,14 , 682,2 , 686,2 , 948,5 , 953,17 , 22,23 , {82,85,66}, 129,1 , 16505,47 , 13,5 , 4,0 , 5321,9 , 5330,9 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia
- { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 33967,48 , 34015,117 , 158,27 , 33967,48 , 34015,117 , 158,27 , 18807,28 , 18835,60 , 18895,14 , 18807,28 , 18835,60 , 18895,14 , 684,9 , 688,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 198,3 , 16552,25 , 0,4 , 4,0 , 5339,9 , 5348,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania
- { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 30134,46 , 30180,88 , 30268,24 , 30134,46 , 30180,88 , 30268,24 , 16839,28 , 16867,54 , 16624,14 , 16839,28 , 16867,54 , 16624,14 , 637,8 , 633,10 , 45,4 , 5,17 , 22,23 , {88,79,70}, 210,3 , 16152,23 , 0,4 , 4,0 , 5357,13 , 5224,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger
- { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 34132,50 , 34132,50 , 158,27 , 34132,50 , 34132,50 , 158,27 , 18909,30 , 18909,30 , 85,14 , 18909,30 , 18909,30 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 16577,15 , 4,4 , 4,0 , 5370,2 , 5372,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia
- { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 34182,81 , 34182,81 , 158,27 , 34182,81 , 34182,81 , 158,27 , 18939,48 , 18939,48 , 85,14 , 18939,48 , 18939,48 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 16592,20 , 4,4 , 4,0 , 5376,3 , 5379,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia
- { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 251,9 , 251,9 , 53,10 , 532,18 , 37,5 , 8,10 , 34263,48 , 34311,99 , 34410,24 , 34263,48 , 34311,99 , 34410,24 , 18987,28 , 19015,53 , 19068,14 , 18987,28 , 19015,53 , 19068,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 0,0 , 0,7 , 79,6 , 4,0 , 5387,6 , 5393,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland
- { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 34434,51 , 34485,191 , 158,27 , 34434,51 , 34485,191 , 158,27 , 19082,21 , 19103,71 , 19174,14 , 19082,21 , 19103,71 , 19174,14 , 693,8 , 697,8 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 13,5 , 4,0 , 5399,6 , 5405,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon
- { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 575,7 , 575,7 , 278,6 , 363,22 , 37,5 , 8,10 , 34676,48 , 34724,85 , 34809,24 , 34833,48 , 34881,117 , 34809,24 , 19188,28 , 19216,54 , 3338,14 , 19188,28 , 19216,54 , 3338,14 , 701,12 , 705,11 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3057,20 , 13,5 , 4,0 , 5412,9 , 2354,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain
- { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 795,11 , 795,11 , 806,16 , 822,9 , 53,10 , 1353,18 , 37,5 , 8,10 , 34998,174 , 34998,174 , 158,27 , 34998,174 , 34998,174 , 158,27 , 19270,60 , 19270,60 , 19330,25 , 19270,60 , 19270,60 , 19330,25 , 713,8 , 716,13 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16612,12 , 8,5 , 4,0 , 5421,5 , 5426,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon
- { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1566,10 , 633,17 , 37,5 , 8,10 , 35172,102 , 35172,102 , 158,27 , 35172,102 , 35172,102 , 158,27 , 19355,54 , 19355,54 , 19409,21 , 19355,54 , 19355,54 , 19409,21 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16624,16 , 79,6 , 4,0 , 5433,4 , 5437,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon
- { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1353,18 , 37,5 , 8,10 , 35274,137 , 35411,142 , 35553,36 , 35274,137 , 35411,142 , 35553,36 , 19430,49 , 19430,49 , 19479,21 , 19430,49 , 19430,49 , 19479,21 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16640,12 , 8,5 , 4,0 , 5444,5 , 5449,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon
- { 260, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1576,32 , 37,5 , 8,10 , 35589,165 , 35589,165 , 158,27 , 35589,165 , 35589,165 , 158,27 , 19500,111 , 19500,111 , 85,14 , 19500,111 , 19500,111 , 85,14 , 721,9 , 729,8 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16652,16 , 8,5 , 4,0 , 5456,16 , 5472,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon
- { 272, 46, 18, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {66,68,84}, 130,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 5, 6, 7 }, // Chakma/Chakma/Bangladesh
- { 290, 11, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 127,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Manipuri/Bengali/India
- { 309, 100, 232, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {86,78,68}, 340,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // TaiDam/Tai Viet/Vietnam
+ { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 32695,48 , 32743,195 , 32938,24 , 32695,48 , 32743,195 , 32938,24 , 18361,28 , 18389,72 , 18461,14 , 18361,28 , 18389,72 , 18461,14 , 666,3 , 663,3 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16624,21 , 0,4 , 4,0 , 5296,5 , 5301,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon
+ { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 32962,48 , 33010,90 , 33100,24 , 32962,48 , 33010,90 , 33100,24 , 18475,28 , 18503,70 , 18573,14 , 18475,28 , 18503,70 , 18573,14 , 669,10 , 666,9 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16645,22 , 13,5 , 4,0 , 5308,5 , 5313,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon
+ { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 31225,46 , 31271,88 , 31359,24 , 31225,46 , 31271,88 , 31359,24 , 17656,28 , 18587,53 , 18640,14 , 17656,28 , 18587,53 , 18640,14 , 679,8 , 675,10 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16408,23 , 0,4 , 4,0 , 5321,10 , 5331,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger
+ { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 33124,49 , 33173,99 , 33272,24 , 33124,49 , 33173,99 , 33272,24 , 18654,28 , 18682,45 , 18727,14 , 18654,28 , 18682,45 , 18727,14 , 687,5 , 685,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 13,5 , 4,0 , 5336,5 , 1952,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon
+ { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 33296,36 , 33332,82 , 33414,24 , 33296,36 , 33332,82 , 33414,24 , 18741,28 , 18769,50 , 18819,14 , 18741,28 , 18769,50 , 18819,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16667,23 , 13,5 , 4,0 , 5341,5 , 5346,7 , 0, 0, 1, 6, 7 }, // Jola Fonyi/Latin/Senegal
+ { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 33438,50 , 33488,141 , 33629,24 , 33438,50 , 33488,141 , 33629,24 , 18833,30 , 18863,85 , 18948,14 , 18833,30 , 18863,85 , 18948,14 , 692,7 , 691,9 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16690,23 , 13,5 , 4,0 , 5353,6 , 5359,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon
+ { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 33653,39 , 33692,191 , 158,27 , 33653,39 , 33692,191 , 158,27 , 18962,29 , 18991,45 , 19036,14 , 18962,29 , 18991,45 , 19036,14 , 699,6 , 700,7 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16713,11 , 13,5 , 4,0 , 5366,5 , 5371,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon
+ { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 33883,48 , 33931,213 , 34144,24 , 33883,48 , 33931,213 , 34144,24 , 19050,28 , 19078,59 , 19137,14 , 19050,28 , 19078,59 , 19137,14 , 705,8 , 707,10 , 45,4 , 5,17 , 22,23 , {77,90,78}, 272,3 , 0,7 , 41,6 , 4,0 , 5378,5 , 5383,10 , 2, 1, 7, 6, 7 }, // Makhuwa Meetto/Latin/Mozambique
+ { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 34168,48 , 34216,139 , 34355,24 , 34168,48 , 34216,139 , 34355,24 , 19151,28 , 19179,74 , 19253,14 , 19151,28 , 19179,74 , 19253,14 , 713,5 , 717,5 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16724,17 , 4,4 , 4,0 , 5393,6 , 5399,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon
+ { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 34379,51 , 34430,143 , 158,27 , 34379,51 , 34430,143 , 158,27 , 19267,30 , 19297,89 , 19386,14 , 19267,30 , 19297,89 , 19386,14 , 718,4 , 722,4 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16741,20 , 13,5 , 4,0 , 5406,6 , 5412,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon
+ { 247, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1667,9 , 98,16 , 18,7 , 551,12 , 34573,54 , 34627,96 , 34723,24 , 34573,54 , 34627,96 , 34723,24 , 19400,38 , 19438,79 , 19517,14 , 19400,38 , 19438,79 , 19517,14 , 722,2 , 726,2 , 45,4 , 5,17 , 22,23 , {83,83,80}, 115,1 , 0,7 , 4,4 , 4,0 , 5419,9 , 0,0 , 2, 1, 1, 6, 7 }, // Nuer/Latin/South Sudan
+ { 248, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 896,11 , 896,11 , 245,6 , 1676,30 , 37,5 , 8,10 , 34747,50 , 34797,116 , 34913,24 , 34747,50 , 34937,121 , 34913,24 , 19531,21 , 19552,71 , 19623,14 , 19531,21 , 19552,71 , 19623,14 , 724,2 , 728,2 , 1117,5 , 1122,17 , 22,23 , {82,85,66}, 119,1 , 16761,47 , 13,5 , 4,0 , 5428,9 , 5437,9 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia
+ { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 35058,48 , 35106,117 , 158,27 , 35058,48 , 35106,117 , 158,27 , 19637,28 , 19665,60 , 19725,14 , 19637,28 , 19665,60 , 19725,14 , 726,9 , 730,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16808,25 , 0,4 , 4,0 , 5446,9 , 5455,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania
+ { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 31225,46 , 31271,88 , 31359,24 , 31225,46 , 31271,88 , 31359,24 , 17656,28 , 17684,54 , 17441,14 , 17656,28 , 17684,54 , 17441,14 , 679,8 , 675,10 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16408,23 , 0,4 , 4,0 , 5464,13 , 5331,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger
+ { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 35223,38 , 35261,61 , 158,27 , 35223,38 , 35261,61 , 158,27 , 19739,30 , 19739,30 , 85,14 , 19739,30 , 19739,30 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 16833,15 , 4,4 , 4,0 , 5477,2 , 5479,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia
+ { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 35322,81 , 35322,81 , 158,27 , 35322,81 , 35322,81 , 158,27 , 19769,48 , 19769,48 , 85,14 , 19769,48 , 19769,48 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 16848,20 , 4,4 , 4,0 , 5483,3 , 5486,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia
+ { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 53,10 , 593,18 , 37,5 , 8,10 , 35403,48 , 35451,99 , 35550,24 , 35403,48 , 35451,99 , 35550,24 , 19817,28 , 19845,53 , 19898,14 , 19817,28 , 19845,53 , 19898,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 0,0 , 0,7 , 41,6 , 4,0 , 5494,6 , 5500,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland
+ { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 35574,51 , 35625,191 , 158,27 , 35574,51 , 35625,191 , 158,27 , 19912,21 , 19933,71 , 20004,14 , 19912,21 , 19933,71 , 20004,14 , 735,8 , 739,8 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 13,5 , 4,0 , 5506,6 , 5512,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon
+ { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 390,22 , 37,5 , 8,10 , 35816,48 , 35864,85 , 35949,24 , 35973,48 , 36021,117 , 35949,24 , 20018,28 , 20046,54 , 3434,14 , 20018,28 , 20046,54 , 3434,14 , 743,12 , 747,11 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 5519,9 , 2398,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain
+ { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 907,11 , 907,11 , 918,16 , 934,9 , 53,10 , 1497,18 , 37,5 , 8,10 , 36138,174 , 36138,174 , 158,27 , 36138,174 , 36138,174 , 158,27 , 20100,60 , 20100,60 , 20160,25 , 20100,60 , 20100,60 , 20160,25 , 755,8 , 758,13 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16868,12 , 8,5 , 4,0 , 5528,5 , 5533,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon
+ { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1706,10 , 686,17 , 37,5 , 8,10 , 36312,102 , 36312,102 , 158,27 , 36312,102 , 36312,102 , 158,27 , 20185,54 , 20185,54 , 20239,21 , 20185,54 , 20185,54 , 20239,21 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16880,16 , 41,6 , 4,0 , 5540,4 , 5544,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon
+ { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1497,18 , 37,5 , 8,10 , 36414,137 , 36551,142 , 36693,36 , 36414,137 , 36551,142 , 36693,36 , 20260,49 , 20260,49 , 20309,21 , 20260,49 , 20260,49 , 20309,21 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16896,12 , 8,5 , 4,0 , 5551,5 , 5556,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon
+ { 260, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1716,32 , 37,5 , 8,10 , 36729,165 , 36729,165 , 158,27 , 36729,165 , 36729,165 , 158,27 , 20330,111 , 20330,111 , 85,14 , 20330,111 , 20330,111 , 85,14 , 763,9 , 771,8 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16908,16 , 8,5 , 4,0 , 5563,16 , 5579,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon
+ { 290, 11, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Manipuri/Bengali/India
+ { 309, 100, 232, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {86,78,68}, 332,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Tai Dam/Tai Viet/Vietnam
{ 312, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Akoose/Latin/Cameroon
- { 313, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 516,6 , 35,18 , 18,7 , 25,12 , 35754,180 , 35754,180 , 158,27 , 35754,180 , 35754,180 , 158,27 , 19611,87 , 19611,87 , 85,14 , 19611,87 , 19611,87 , 19698,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 79,6 , 4,0 , 5479,12 , 5491,22 , 2, 1, 7, 6, 7 }, // Lakota/Latin/UnitedStates
- { 314, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 406,8 , 98,16 , 37,5 , 8,10 , 26318,48 , 26366,81 , 26447,24 , 26318,48 , 26366,81 , 26447,24 , 14103,30 , 19712,48 , 85,14 , 14103,30 , 19712,48 , 85,14 , 474,6 , 452,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15621,21 , 0,4 , 4,0 , 5513,8 , 4698,6 , 2, 1, 6, 5, 6 }, // Standard Moroccan Tamazight/Tifinagh/Morocco
+ { 313, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 543,6 , 35,18 , 18,7 , 25,12 , 36894,180 , 36894,180 , 158,27 , 36894,180 , 36894,180 , 158,27 , 20441,87 , 20441,87 , 85,14 , 20441,87 , 20441,87 , 20528,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 41,6 , 4,0 , 5586,12 , 5598,22 , 2, 1, 7, 6, 7 }, // Lakota/Latin/United States
+ { 314, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 27255,48 , 27303,81 , 27384,24 , 27255,48 , 27303,81 , 27384,24 , 14844,30 , 20542,48 , 85,14 , 14844,30 , 20542,48 , 85,14 , 516,6 , 494,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15845,21 , 0,4 , 4,0 , 5620,8 , 4805,6 , 2, 1, 6, 5, 6 }, // Standard Moroccan Tamazight/Tifinagh/Morocco
{ 315, 7, 43, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,76,80}, 6,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Mapuche/Latin/Chile
- { 316, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 35934,105 , 35934,105 , 36039,24 , 35934,105 , 35934,105 , 36039,24 , 19760,58 , 19760,58 , 19818,14 , 19760,58 , 19760,58 , 19818,14 , 730,3 , 737,3 , 45,4 , 5,17 , 22,23 , {73,81,68}, 0,0 , 16668,20 , 13,5 , 4,0 , 5521,14 , 5535,5 , 0, 0, 6, 5, 6 }, // Central Kurdish/Arabic/Iraq
- { 316, 1, 102, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 35934,105 , 35934,105 , 36039,24 , 35934,105 , 35934,105 , 36039,24 , 19760,58 , 19760,58 , 19818,14 , 19760,58 , 19760,58 , 19818,14 , 730,3 , 737,3 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 16688,19 , 13,5 , 4,0 , 5521,14 , 5540,5 , 0, 0, 6, 5, 5 }, // Central Kurdish/Arabic/Iran
- { 317, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 176,7 , 176,7 , 114,6 , 532,18 , 55,4 , 59,9 , 36063,48 , 36111,85 , 16212,24 , 36196,60 , 36256,93 , 16212,24 , 19832,28 , 19860,53 , 19913,14 , 19832,28 , 19860,53 , 19913,14 , 733,9 , 740,10 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16707,27 , 13,5 , 4,0 , 5545,14 , 5559,6 , 2, 1, 1, 6, 7 }, // LowerSorbian/Latin/Germany
- { 318, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 176,7 , 176,7 , 114,6 , 532,18 , 493,12 , 59,9 , 36349,48 , 36397,86 , 16212,24 , 36483,60 , 36543,93 , 16212,24 , 19927,28 , 19955,53 , 20008,14 , 19927,28 , 19955,53 , 20008,14 , 733,9 , 750,9 , 970,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16734,29 , 13,5 , 4,0 , 5565,15 , 5580,6 , 2, 1, 1, 6, 7 }, // UpperSorbian/Latin/Germany
+ { 316, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 37074,105 , 37074,105 , 37179,24 , 37074,105 , 37074,105 , 37179,24 , 20590,58 , 20590,58 , 20648,14 , 20590,58 , 20590,58 , 20648,14 , 772,3 , 779,3 , 45,4 , 5,17 , 22,23 , {73,81,68}, 44,5 , 16924,20 , 13,5 , 4,0 , 5628,14 , 5642,5 , 0, 0, 6, 5, 6 }, // Central Kurdish/Arabic/Iraq
+ { 316, 1, 102, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 37074,105 , 37074,105 , 37179,24 , 37074,105 , 37074,105 , 37179,24 , 20590,58 , 20590,58 , 20648,14 , 20590,58 , 20590,58 , 20648,14 , 772,3 , 779,3 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 16944,19 , 13,5 , 4,0 , 5628,14 , 5647,5 , 0, 0, 6, 5, 5 }, // Central Kurdish/Arabic/Iran
+ { 317, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 114,6 , 593,18 , 55,4 , 59,9 , 37203,48 , 37251,85 , 16435,24 , 37336,60 , 37396,93 , 16435,24 , 20662,28 , 20690,53 , 20743,14 , 20662,28 , 20690,53 , 20743,14 , 775,9 , 782,10 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16963,27 , 13,5 , 4,0 , 5652,14 , 5666,6 , 2, 1, 1, 6, 7 }, // Lower Sorbian/Latin/Germany
+ { 318, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 114,6 , 593,18 , 563,12 , 59,9 , 37489,48 , 37537,86 , 16435,24 , 37623,60 , 37683,93 , 16435,24 , 20757,28 , 20785,53 , 20838,14 , 20757,28 , 20785,53 , 20838,14 , 775,9 , 792,9 , 1139,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16990,29 , 13,5 , 4,0 , 5672,15 , 5687,6 , 2, 1, 1, 6, 7 }, // Upper Sorbian/Latin/Germany
{ 319, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Kenyang/Latin/Cameroon
- { 320, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 245,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Mohawk/Latin/Canada
- { 321, 75, 91, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,78,70}, 221,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Nko/Nko/Guinea
- { 323, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,84,81}, 311,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Kiche/Latin/Guatemala
- { 324, 7, 205, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 196,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Southern Sami/Latin/Sweden
- { 325, 7, 205, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 196,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Lule Sami/Latin/Sweden
- { 326, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 550,8 , 1608,18 , 222,4 , 226,9 , 36636,77 , 36713,140 , 36853,25 , 36636,77 , 36713,140 , 36853,25 , 20022,28 , 20050,70 , 85,14 , 20022,28 , 20120,73 , 20193,14 , 742,3 , 759,3 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16763,11 , 13,5 , 4,0 , 5586,11 , 5597,5 , 2, 1, 1, 6, 7 }, // Inari Sami/Latin/Finland
+ { 320, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 233,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Mohawk/Latin/Canada
+ { 321, 75, 91, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,78,70}, 209,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Nko/Nko/Guinea
+ { 322, 7, 260, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 943,8 , 943,8 , 174,8 , 1748,27 , 37,5 , 8,10 , 37776,48 , 37824,91 , 37915,24 , 37776,48 , 37824,91 , 37915,24 , 20852,28 , 20880,69 , 20949,14 , 20852,28 , 20880,69 , 20949,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 5693,9 , 5702,6 , 2, 1, 1, 6, 7 }, // Prussian/Latin/World
+ { 323, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,84,81}, 299,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Kiche/Latin/Guatemala
+ { 324, 7, 205, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 186,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 1, 6, 7 }, // Southern Sami/Latin/Sweden
+ { 325, 7, 205, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 186,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 1, 6, 7 }, // Lule Sami/Latin/Sweden
+ { 326, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 611,8 , 1775,18 , 243,4 , 247,9 , 37939,77 , 38016,140 , 38156,25 , 37939,77 , 38016,140 , 38156,25 , 20963,28 , 20991,70 , 85,14 , 20963,28 , 21061,73 , 21134,14 , 784,3 , 801,3 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 17019,11 , 13,5 , 4,0 , 5708,11 , 5719,5 , 2, 1, 1, 6, 7 }, // Inari Sami/Latin/Finland
{ 327, 7, 73, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Skolt Sami/Latin/Finland
- { 328, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {65,85,68}, 344,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Warlpiri/Latin/Australia
- { 346, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 14012,70 , 14012,70 , 158,27 , 14012,70 , 14012,70 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 605,4 , 609,39 , 22,23 , {73,82,82}, 346,3 , 16774,27 , 8,5 , 4,0 , 5602,7 , 3091,5 , 0, 0, 6, 5, 5 }, // Mazanderani/Arabic/Iran
- { 349, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 36878,77 , 36878,77 , 158,27 , 36878,77 , 36878,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 0,7 , 8,5 , 4,0 , 5609,11 , 0,0 , 0, 0, 6, 5, 5 }, // Northern Luri/Arabic/Iran
- { 349, 1, 103, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 36878,77 , 36878,77 , 158,27 , 36878,77 , 36878,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,81,68}, 0,0 , 0,7 , 8,5 , 4,0 , 5609,11 , 0,0 , 0, 0, 6, 5, 6 }, // Northern Luri/Arabic/Iraq
- { 357, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 161,5 , 161,5 , 831,5 , 831,5 , 385,8 , 414,14 , 170,6 , 187,13 , 4697,39 , 4697,39 , 158,27 , 4697,39 , 4697,39 , 158,27 , 2055,21 , 2013,28 , 2041,14 , 2055,21 , 2013,28 , 2041,14 , 58,2 , 55,2 , 45,4 , 5,17 , 22,23 , {72,75,68}, 140,3 , 16801,11 , 4,4 , 4,0 , 5620,2 , 5622,14 , 2, 1, 7, 6, 7 }, // Cantonese/Traditional Han/HongKong
+ { 328, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {65,85,68}, 336,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Warlpiri/Latin/Australia
+ { 346, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 14357,70 , 14357,70 , 158,27 , 14357,70 , 14357,70 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 653,4 , 657,39 , 22,23 , {73,82,82}, 338,3 , 17030,27 , 8,5 , 4,0 , 5724,7 , 3136,5 , 0, 0, 6, 5, 5 }, // Mazanderani/Arabic/Iran
+ { 349, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 38181,77 , 38181,77 , 158,27 , 38181,77 , 38181,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 0,7 , 8,5 , 4,0 , 5731,11 , 0,0 , 0, 0, 6, 5, 5 }, // Northern Luri/Arabic/Iran
+ { 349, 1, 103, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 38181,77 , 38181,77 , 158,27 , 38181,77 , 38181,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,81,68}, 44,5 , 0,7 , 8,5 , 4,0 , 5731,11 , 0,0 , 0, 0, 6, 5, 6 }, // Northern Luri/Arabic/Iraq
+ { 357, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 951,5 , 951,5 , 412,8 , 441,14 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2023,28 , 2023,28 , 2051,14 , 2023,28 , 2023,28 , 2051,14 , 60,2 , 57,2 , 45,4 , 5,17 , 22,23 , {72,75,68}, 130,3 , 17057,11 , 4,4 , 4,0 , 5742,2 , 5744,14 , 2, 1, 7, 6, 7 }, // Cantonese/Traditional Han/Hong Kong
+ { 357, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 951,5 , 951,5 , 412,8 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 129,1 , 3122,13 , 4,4 , 4,0 , 5758,2 , 5760,7 , 2, 1, 7, 6, 7 }, // Cantonese/Simplified Han/China
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, {0,0,0}, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0, 0, 0, 0, 0 } // trailing 0s
};
@@ -1818,45 +1830,51 @@ static const ushort list_pattern_part_data[] = {
0x25, 0x31, 0x2c, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x64, 0x68, 0x65,
0x20, 0x25, 0x32, 0x25, 0x31, 0x1363, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x12a5, 0x1293, 0x20, 0x25, 0x32, 0x25, 0x31,
0x20, 0x12a5, 0x1293, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x648, 0x25, 0x32, 0x25,
-0x31, 0x20, 0x648, 0x25, 0x32, 0x25, 0x31, 0x20, 0x587, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0x259, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x20, 0x65, 0x74, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x98f, 0x9ac, 0x982, 0x20, 0x25, 0x32, 0x25, 0x31,
-0x20, 0xf51, 0xf44, 0xf0b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x438, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x25, 0x32, 0x25,
-0x31, 0x1014, 0x103e, 0x1004, 0x1037, 0x103a, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x456, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x1793,
-0x17b7, 0x1784, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x1793, 0x17b7, 0x1784, 0x200b, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x20, 0x25,
-0x32, 0x25, 0x31, 0x3001, 0x25, 0x32, 0x25, 0x31, 0x548c, 0x25, 0x32, 0x25, 0x31, 0x53ca, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61,
-0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6f, 0x67, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x25,
-0x32, 0x25, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6a, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31,
-0x20, 0x65, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65,
-0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x10d3, 0x10d0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x64, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x20, 0x3ba, 0x3b1, 0x3b9, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x61, 0x6d, 0x6d, 0x61, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x20, 0xa85, 0xaa8, 0xac7, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x5d5, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x914,
-0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x914, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xe9, 0x73, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x2c, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25,
-0x31, 0x2c, 0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20,
-0x25, 0x32, 0x25, 0x31, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x436, 0x4d9, 0x43d, 0x435,
-0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x436, 0x430, 0x43d, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xbc0f, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x20, 0xec1, 0xea5, 0xeb0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20,
-0x6d, 0x70, 0xe9, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x72, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x25, 0x32,
-0x20, 0xd0e, 0xd28, 0xd4d, 0xd28, 0xd3f, 0xd35, 0x25, 0x31, 0x20, 0xd15, 0xd42, 0xd1f, 0xd3e, 0xd24, 0xd46, 0x20, 0x25, 0x32, 0x25,
-0x31, 0x2c, 0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x906, 0x923, 0x93f,
-0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x25, 0x32, 0x25, 0x31, 0x20, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x200f, 0x20,
-0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20,
-0xa05, 0xa24, 0xa47, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x219, 0x69, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x4d5, 0x43c, 0x4d5,
-0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xdc3, 0xdc4, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xdc3, 0xdc4, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x20, 0x61, 0xa0, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x79, 0x20,
-0x25, 0x32, 0x25, 0x31, 0x20, 0x6e, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6f, 0x63, 0x68, 0x20, 0x25, 0x32, 0x25,
-0x31, 0x20, 0xbae, 0xbb1, 0xbcd, 0xbb1, 0xbc1, 0xbae, 0xbcd, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xc2e, 0xc30, 0xc3f, 0xc2f, 0xc41,
-0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31,
-0x20, 0x6d, 0x6f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x77, 0x65, 0x20,
-0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25,
-0x32, 0x25, 0x32, 0x60c, 0x20, 0x25, 0x31, 0x25, 0x31, 0x20, 0x76, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0xe0,
-0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6e, 0x65, 0x2d, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6e, 0x65, 0x2d, 0x25, 0x32,
-0x25, 0x31, 0x2c, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25,
-0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31,
-0x20, 0x13a0, 0x13b4, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x438, 0x486, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x28, 0x6e,
-0x29, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x443, 0x43e, 0x43d, 0x43d, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x14b,
-0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x1e3f, 0x62, 0x25b, 0x6e, 0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20,
-0x25, 0x32, 0x25, 0x31, 0x20, 0x70, 0x254, 0x70, 0x20, 0x25, 0x32, 0x25, 0x31, 0x540c, 0x25, 0x32
+0x31, 0x20, 0x648, 0x25, 0x32, 0x25, 0x31, 0x20, 0x587, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x986, 0x9f0, 0x9c1, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x20, 0x76, 0x259, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x74, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x20, 0x98f, 0x9ac, 0x982, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xf51, 0xf44, 0xf0b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x438,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x25, 0x32, 0x25, 0x31, 0x1014, 0x103e, 0x1004, 0x1037, 0x103a, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x20, 0x456, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x1793, 0x17b7, 0x1784, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x1793, 0x17b7, 0x1784,
+0x200b, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x20, 0x25, 0x32, 0x25, 0x31, 0x3001, 0x25, 0x32, 0x25, 0x31, 0x548c, 0x25, 0x32,
+0x25, 0x31, 0x53ca, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6f, 0x67, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x25, 0x32, 0x25,
+0x31, 0x20, 0x6b, 0x61, 0x6a, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6a, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65,
+0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x20, 0x10d3, 0x10d0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x20, 0x3ba, 0x3b1, 0x3b9, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x61, 0x6d, 0x6d, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x20, 0xa85, 0xaa8, 0xac7, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x5d5, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x914, 0x930, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x20, 0x914, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xe9, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x2c, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c,
+0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x436, 0x4d9, 0x43d, 0x435, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x20, 0x436, 0x430, 0x43d, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xbc0f, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x20, 0xec1, 0xea5, 0xeb0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6d, 0x70,
+0xe9, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x72, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x25, 0x32, 0x20, 0xd0e,
+0xd28, 0xd4d, 0xd28, 0xd3f, 0xd35, 0x25, 0x31, 0x20, 0xd15, 0xd42, 0xd1f, 0xd3e, 0xd24, 0xd46, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c,
+0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x906, 0x923, 0x93f, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x2c, 0x25, 0x32, 0x25, 0x31, 0x20, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xb13, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x20, 0xb13, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x627, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20,
+0x627, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x200f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x648, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xa05, 0xa24, 0xa47, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x219,
+0x69, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x4d5, 0x43c, 0x4d5, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xdc3, 0xdc4, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x20, 0xdc3, 0xdc4, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0xa0, 0x25, 0x32, 0x25, 0x31, 0x20,
+0x69, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x79, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6e, 0x61, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x20, 0x6f, 0x63, 0x68, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xbae, 0xbb1, 0xbcd, 0xbb1, 0xbc1, 0xbae, 0xbcd, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x20, 0x4bb, 0x4d9, 0x43c, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xc2e, 0xc30, 0xc3f, 0xc2f, 0xc41, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x20, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0x20,
+0x6d, 0x6f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x77, 0x65, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x60c, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32,
+0x25, 0x32, 0x60c, 0x20, 0x25, 0x31, 0x25, 0x31, 0x20, 0x76, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0xe0, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x28, 0x63, 0x29, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x28, 0x63, 0x29,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x5d0, 0x5d5, 0x5df, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6e, 0x65, 0x2d, 0x25,
+0x32, 0x25, 0x31, 0x20, 0x6e, 0x65, 0x2d, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25,
+0x31, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x6b, 0x6b, 0x65, 0x64, 0x20, 0x25, 0x32, 0x25,
+0x31, 0x20, 0x61, 0x6b, 0x6b, 0x65, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x13a0, 0x13b4, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x20, 0x438, 0x486, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x28, 0x6e, 0x29, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x443,
+0x43e, 0x43d, 0x43d, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x2c, 0x20, 0x1e3f, 0x62, 0x25b, 0x6e, 0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x70, 0x254, 0x70,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x62, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x540c, 0x25, 0x32
};
static const ushort date_format_data[] = {
@@ -1868,109 +1886,120 @@ static const ushort date_format_data[] = {
0x64, 0x64, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79,
0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x1363, 0x64, 0x20, 0x4d, 0x4d,
0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x200f, 0x2f, 0x4d, 0x200f, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64,
-0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2e, 0x4d, 0x4d,
-0x2e, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x569, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64,
-0x64, 0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d,
-0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79,
-0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x79, 0x79, 0x79, 0x79, 0x28, 0x27, 0x65, 0x27,
-0x29, 0x27, 0x6b, 0x6f, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f,
-0x4d, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf63, 0xf7c, 0xf0b, 0x79, 0x79,
-0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0xf5a, 0xf7a, 0xf66, 0xf0b, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79,
-0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
-0x79, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x4d,
-0x2e, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27,
-0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708,
-0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d,
-0x6708, 0x64, 0x65e5, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79,
-0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e,
-0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d,
-0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x2e, 0x20,
-0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x4d, 0x2f, 0x64, 0x2f,
-0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e,
-0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-0x2d, 0x4d, 0x4d, 0x2d, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x27, 0x6d, 0x68, 0x27, 0x20, 0x4d, 0x4d,
-0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20,
-0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20,
-0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64,
-0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x5d1, 0x4d,
-0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x64, 0x64,
-0x2e, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64,
-0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x436, 0x27, 0x2e, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x64, 0x64,
-0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x27, 0x436, 0x27, 0x2e, 0x2c, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c,
-0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0xb144, 0x20,
-0x4d, 0xc6d4, 0x20, 0x64, 0xc77c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0xe97, 0xeb5, 0x20, 0x64, 0x20,
-0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e,
-0x20, 0x27, 0x67, 0x61, 0x64, 0x61, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x79, 0x79, 0x79, 0x79, 0x20,
-0x27, 0x6d, 0x27, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x64, 0x27, 0x2e, 0x2c, 0x20, 0x64, 0x64,
-0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79,
-0x79, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64,
-0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x74, 0x61, 0x27, 0x2019, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79,
-0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x43e, 0x43d, 0x44b, 0x27, 0x20, 0x4d,
-0x4d, 0x20, 0x27, 0x441, 0x430, 0x440, 0x44b, 0x43d, 0x27, 0x20, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79,
-0x79, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x62f, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x62f,
-0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x69, 0x6c, 0x73, 0x27, 0x20, 0x64,
-0x20, 0x27, 0x64, 0x61, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79,
-0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79,
-0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79,
-0x20, 0x27, 0x430, 0x437, 0x27, 0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x20, 0x4d, 0x4d,
-0x2e, 0x20, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
-0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79,
-0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
-0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x2d,
-0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2c,
-0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0xe17, 0xe35, 0xe48, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
-0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0xf60, 0xf72, 0xf0b, 0xf5a, 0xf7a, 0xf66, 0xf0b,
-0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x1363, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
-0x20, 0x1218, 0x12d3, 0x120d, 0x1272, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64,
-0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20,
-0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20,
-0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x440, 0x27, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20,
-0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x646, 0x686, 0x6cc,
-0x20, 0x6cc, 0x6cc, 0x644, 0x20, 0x64, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x64,
-0x20, 0x6a9, 0x648, 0x646, 0x6cc, 0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79,
-0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x27, 0x64,
-0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x61, 0x6c, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64,
-0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x6c, 0x69, 0x61, 0x27, 0x20, 0x79, 0x79, 0x79,
-0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
-0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d,
-0x4d, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0xe4,
-0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x4d,
-0x4d, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x43b, 0x27,
+0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e,
+0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x569, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2c,
+0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x79, 0x79, 0x79, 0x79, 0x28, 0x27, 0x65, 0x27, 0x29,
+0x27, 0x6b, 0x6f, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x27, 0x72, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x28, 0x27, 0x61, 0x27,
+0x29, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0xf66,
+0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf63, 0xf7c, 0xf0b, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0xf5a, 0xf7a, 0xf66,
+0xf0b, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c,
+0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x64, 0x2d,
+0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x104a, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x104a, 0x20, 0x64,
+0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64,
+0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x79,
+0x79, 0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x20, 0x4d,
+0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d,
+0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64,
+0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x64,
+0x65, 0x6e, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d,
+0x2f, 0x79, 0x79, 0x4d, 0x2f, 0x64, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x79,
+0x79, 0x2d, 0x4d, 0x4d, 0x2d, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2d, 0x27, 0x61, 0x27, 0x20, 0x27,
+0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64,
+0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64,
+0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x27, 0x6d, 0x68, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79,
+0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64,
+0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
+0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x5d1, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79,
+0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x64, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x436,
+0x27, 0x2e, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x2d,
+0x27, 0x436, 0x27, 0x2e, 0x2c, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79,
+0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0xb144, 0x20, 0x4d, 0xc6d4, 0x20, 0x64, 0xc77c, 0x20, 0x64,
+0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0xe97, 0xeb5, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x27, 0x67, 0x61, 0x64, 0x61, 0x27,
+0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x6d, 0x27, 0x2e, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x64, 0x27, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e,
+0x79, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20,
+0x27, 0x74, 0x61, 0x27, 0x2019, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e,
+0x4d, 0x4d, 0x2e, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x4d, 0x4d, 0x2e, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x62f, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x20, 0x62f, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x69, 0x6c,
+0x73, 0x27, 0x20, 0x64, 0x20, 0x27, 0x64, 0x61, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64,
+0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20,
+0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x430, 0x437, 0x27, 0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64,
+0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64,
+0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d,
+0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x2f, 0x79,
+0x79, 0x64, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79,
+0x79, 0x79, 0x79, 0x20, 0x27, 0x435, 0x43b, 0x27, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d,
+0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0xe17, 0xe35, 0xe48, 0x20,
+0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0xf60, 0xf72, 0xf0b, 0xf5a, 0xf7a, 0xf66, 0xf0b, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x1363, 0x20,
+0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1218, 0x12d3, 0x120d, 0x1272, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d,
+0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x64, 0x64,
+0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x440, 0x27,
+0x2e, 0x64, 0x64, 0x64, 0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64,
+0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+0x79, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x6cc, 0x6cc, 0x644, 0x20, 0x64, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x64, 0x64, 0x64, 0x64, 0x20, 0x6a9, 0x648, 0x646, 0x6cc, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x27,
+0x61, 0x27, 0x20, 0x27, 0x64, 0x27, 0x2e, 0x20, 0x64, 0x27, 0x69, 0x64, 0x27, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64,
+0x20, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x5d8, 0x5df, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64,
+0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d, 0x79,
+0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64,
+0x61, 0x6c, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64,
+0x20, 0x27, 0x6c, 0x69, 0x61, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0x65,
+0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20,
+0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x79, 0x79, 0x79,
+0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0xe4, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x43b, 0x27,
0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
0x20, 0x27, 0x441, 0x44b, 0x43b, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x43a, 0x4af, 0x43d, 0x44d, 0x27,
0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64,
0x20, 0x2c, 0x20, 0x27, 0x6c, 0x79, 0x25b, 0x27, 0x30c, 0x2bc, 0x20, 0x64, 0x20, 0x27, 0x6e, 0x61, 0x27, 0x20, 0x4d, 0x4d,
-0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64,
-0x2e, 0x20, 0x79, 0x79, 0x79, 0x79
+0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27,
+0x6d, 0x65, 0x74, 0x74, 0x61, 0x73, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x64, 0x64, 0x64, 0x64, 0x2c,
+0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79
};
static const ushort time_format_data[] = {
0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x68, 0x3a,
0x6d, 0x6d, 0x20, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x48, 0x48, 0x3a,
0x6d, 0x6d, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x2c, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x48,
-0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x68, 0x2e, 0x6d, 0x6d, 0x2e, 0x20, 0x41, 0x50, 0x68, 0x2e, 0x6d, 0x6d,
-0x2e, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29,
-0xf46, 0xf74, 0xf0b, 0xf5a, 0xf7c, 0xf51, 0xf0b, 0x20, 0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d, 0x20,
-0x41, 0x50, 0xf46, 0xf74, 0xf0b, 0xf5a, 0xf7c, 0xf51, 0xf0b, 0x20, 0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d,
-0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x74, 0x20, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x48,
-0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x74, 0x20, 0x41, 0x50,
-0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x5b, 0x74, 0x5d,
-0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x74, 0x68, 0x2e, 0x6d, 0x6d, 0x20,
-0x41, 0x50, 0x48, 0x2e, 0x6d, 0x6d, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x74, 0x48, 0x20, 0x27, 0x68, 0x27,
-0x20, 0x6d, 0x6d, 0x20, 0x27, 0x6d, 0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20, 0x27, 0x73, 0x27, 0x20, 0x74, 0x48, 0x48,
-0x20, 0x27, 0x68, 0x27, 0x20, 0x6d, 0x6d, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x27, 0x68, 0x27, 0x20,
-0x74, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x20, 0x41, 0x50, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50,
-0x20, 0x74, 0x48, 0x6642, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41,
-0x50, 0x20, 0x68, 0xc2dc, 0x20, 0x6d, 0xbd84, 0x20, 0x73, 0xcd08, 0x20, 0x74, 0x48, 0x20, 0xec2, 0xea1, 0xe87, 0x20, 0x6d, 0x20,
-0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x73, 0x73, 0x20, 0xea7, 0xeb4, 0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d,
-0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29, 0x27, 0x6b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73,
-0x73, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x48, 0x20, 0xe19, 0xe32, 0xe2c,
-0xe34, 0xe01, 0xe32, 0x20, 0x6d, 0x6d, 0x20, 0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x73, 0x73, 0x20, 0xe27, 0xe34, 0xe19, 0xe32, 0xe17,
-0xe35, 0x20, 0x74, 0x41, 0x50, 0x20, 0x27, 0x67, 0x61, 0x27, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x27, 0x67,
-0x61, 0x27, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x27, 0x4b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x2e,
-0x6d, 0x6d, 0x27, 0x4b, 0x6c, 0x6f, 0x63, 0x6b, 0x27, 0x20, 0x48, 0x2e, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74,
-0x29, 0x74, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x48, 0x3a, 0x6d, 0x6d, 0x20, 0x27, 0x68,
-0x6f, 0x64, 0x17a, 0x27, 0x2e
+0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x2e, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68, 0x2e,
+0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x74, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29, 0xf46,
+0xf74, 0xf0b, 0xf5a, 0xf7c, 0xf51, 0xf0b, 0x20, 0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d, 0x20, 0x41,
+0x50, 0xf46, 0xf74, 0xf0b, 0xf5a, 0xf7c, 0xf51, 0xf0b, 0x20, 0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d,
+0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x20, 0x27, 0x447, 0x27, 0x2e, 0x48, 0x3a, 0x6d,
+0x6d, 0x3a, 0x73, 0x73, 0x20, 0x27, 0x447, 0x27, 0x2e, 0x20, 0x74, 0x42, 0x20, 0x48, 0x3a, 0x6d, 0x6d, 0x74, 0x20, 0x48,
+0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x41, 0x50,
+0x68, 0x3a, 0x6d, 0x6d, 0x74, 0x20, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x41, 0x50, 0x68, 0x3a, 0x6d,
+0x6d, 0x3a, 0x73, 0x73, 0x20, 0x5b, 0x74, 0x5d, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73,
+0x73, 0x20, 0x74, 0x48, 0x2e, 0x6d, 0x6d, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x74, 0x48, 0x2d, 0x27, 0x61,
+0x27, 0x20, 0x27, 0x68, 0x6f, 0x72, 0x6f, 0x27, 0x20, 0x27, 0x6b, 0x61, 0x6a, 0x27, 0x20, 0x6d, 0x3a, 0x73, 0x73, 0x20,
+0x74, 0x48, 0x20, 0x27, 0x68, 0x27, 0x20, 0x6d, 0x6d, 0x20, 0x27, 0x6d, 0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20, 0x27,
+0x73, 0x27, 0x20, 0x74, 0x48, 0x48, 0x20, 0x27, 0x68, 0x27, 0x20, 0x6d, 0x6d, 0x48, 0x48, 0x20, 0x27, 0x68, 0x27, 0x20,
+0x6d, 0x6d, 0x20, 0x27, 0x6d, 0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20, 0x27, 0x73, 0x27, 0x20, 0x74, 0x48, 0x48, 0x2e,
+0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x27, 0x68, 0x27, 0x20, 0x74, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x20, 0x41, 0x50, 0x68,
+0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x48, 0x6642, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2,
+0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68, 0xc2dc, 0x20, 0x6d, 0xbd84, 0x20, 0x73, 0xcd08,
+0x20, 0x74, 0x48, 0x20, 0xec2, 0xea1, 0xe87, 0x20, 0x6d, 0x20, 0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x73, 0x73, 0x20, 0xea7, 0xeb4,
+0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29, 0x27, 0x6b, 0x6c,
+0x27, 0x2e, 0x20, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d,
+0x3a, 0x73, 0x73, 0x20, 0x74, 0x48, 0x20, 0xe19, 0xe32, 0xe2c, 0xe34, 0xe01, 0xe32, 0x20, 0x6d, 0x6d, 0x20, 0xe19, 0xe32, 0xe17,
+0xe35, 0x20, 0x73, 0x73, 0x20, 0xe27, 0xe34, 0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x74, 0x41, 0x50, 0x20, 0x27, 0x67, 0x61, 0x27,
+0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x27, 0x67, 0x61, 0x27, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73,
+0x20, 0x74, 0x27, 0x4b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x2e, 0x6d, 0x6d, 0x27, 0x4b, 0x6c, 0x6f, 0x63, 0x6b, 0x27, 0x20,
+0x48, 0x2e, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29, 0x74, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73,
+0x20, 0x41, 0x50, 0x48, 0x3a, 0x6d, 0x6d, 0x20, 0x27, 0x68, 0x6f, 0x64, 0x17a, 0x27, 0x2e
};
static const ushort months_data[] = {
@@ -2003,1043 +2032,1075 @@ static const ushort months_data[] = {
0x65, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72,
0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65,
0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x53, 0x68, 0x6b, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x50,
-0x72, 0x69, 0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x51, 0x65, 0x72, 0x3b, 0x4b, 0x6f, 0x72, 0x3b, 0x47, 0x73, 0x68, 0x3b, 0x53,
-0x68, 0x74, 0x3b, 0x54, 0x65, 0x74, 0x3b, 0x4e, 0xeb, 0x6e, 0x3b, 0x44, 0x68, 0x6a, 0x3b, 0x4a, 0x61, 0x6e, 0x61, 0x72,
-0x3b, 0x53, 0x68, 0x6b, 0x75, 0x72, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x50, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x4d,
-0x61, 0x6a, 0x3b, 0x51, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x3b, 0x4b, 0x6f, 0x72, 0x72, 0x69, 0x6b, 0x3b, 0x47, 0x75,
-0x73, 0x68, 0x74, 0x3b, 0x53, 0x68, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x3b, 0x54, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x4e, 0xeb,
-0x6e, 0x74, 0x6f, 0x72, 0x3b, 0x44, 0x68, 0x6a, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x50,
-0x3b, 0x4d, 0x3b, 0x51, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e,
-0x3b, 0x73, 0x68, 0x6b, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x71, 0x65, 0x72,
-0x3b, 0x6b, 0x6f, 0x72, 0x3b, 0x67, 0x73, 0x68, 0x3b, 0x73, 0x68, 0x74, 0x3b, 0x74, 0x65, 0x74, 0x3b, 0x6e, 0xeb, 0x6e,
-0x3b, 0x64, 0x68, 0x6a, 0x3b, 0x6a, 0x61, 0x6e, 0x61, 0x72, 0x3b, 0x73, 0x68, 0x6b, 0x75, 0x72, 0x74, 0x3b, 0x6d, 0x61,
-0x72, 0x73, 0x3b, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x71, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72,
-0x3b, 0x6b, 0x6f, 0x72, 0x72, 0x69, 0x6b, 0x3b, 0x67, 0x75, 0x73, 0x68, 0x74, 0x3b, 0x73, 0x68, 0x74, 0x61, 0x74, 0x6f,
-0x72, 0x3b, 0x74, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x6e, 0xeb, 0x6e, 0x74, 0x6f, 0x72, 0x3b, 0x64, 0x68, 0x6a, 0x65, 0x74,
-0x6f, 0x72, 0x3b, 0x6a, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x70, 0x3b, 0x6d, 0x3b, 0x71, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x73,
-0x3b, 0x74, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x1303, 0x1295, 0x12e9, 0x3b, 0x134c, 0x1265, 0x1229, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4,
-0x1355, 0x122a, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x3b, 0x1234, 0x1355, 0x1274,
-0x3b, 0x12a6, 0x12ad, 0x1276, 0x3b, 0x1296, 0x126c, 0x121d, 0x3b, 0x12f2, 0x1234, 0x121d, 0x3b, 0x1303, 0x1295, 0x12e9, 0x12c8, 0x122a, 0x3b, 0x134c,
-0x1265, 0x1229, 0x12c8, 0x122a, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x122a, 0x120d, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b,
-0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x1275, 0x3b, 0x1234, 0x1355, 0x1274, 0x121d, 0x1260, 0x122d, 0x3b, 0x12a6, 0x12ad, 0x1276, 0x1260,
-0x122d, 0x3b, 0x1296, 0x126c, 0x121d, 0x1260, 0x122d, 0x3b, 0x12f2, 0x1234, 0x121d, 0x1260, 0x122d, 0x3b, 0x1303, 0x3b, 0x134c, 0x3b, 0x121b, 0x3b,
-0x12a4, 0x3b, 0x121c, 0x3b, 0x1301, 0x3b, 0x1301, 0x3b, 0x12a6, 0x3b, 0x1234, 0x3b, 0x12a6, 0x3b, 0x1296, 0x3b, 0x12f2, 0x3b, 0x64a, 0x646,
-0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a,
-0x644, 0x3b, 0x645, 0x627, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x623,
-0x63a, 0x633, 0x637, 0x633, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646,
-0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x64a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623,
-0x3b, 0x648, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x633, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x62c, 0x627, 0x646,
-0x641, 0x64a, 0x3b, 0x641, 0x64a, 0x641, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x641, 0x631, 0x64a, 0x644, 0x3b,
-0x645, 0x627, 0x64a, 0x3b, 0x62c, 0x648, 0x627, 0x646, 0x3b, 0x62c, 0x648, 0x64a, 0x644, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x62a, 0x3b,
-0x633, 0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631,
-0x3b, 0x62f, 0x64a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b, 0x62c, 0x3b,
-0x62c, 0x3b, 0x623, 0x3b, 0x633, 0x3b, 0x623, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644,
-0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x634, 0x628, 0x627, 0x637, 0x3b, 0x622, 0x630, 0x627, 0x631, 0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646,
-0x3b, 0x623, 0x64a, 0x627, 0x631, 0x3b, 0x62d, 0x632, 0x64a, 0x631, 0x627, 0x646, 0x3b, 0x62a, 0x645, 0x648, 0x632, 0x3b, 0x622, 0x628,
-0x3b, 0x623, 0x64a, 0x644, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a,
-0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644,
-0x623, 0x648, 0x644, 0x3b, 0x643, 0x3b, 0x634, 0x3b, 0x622, 0x3b, 0x646, 0x3b, 0x623, 0x3b, 0x62d, 0x3b, 0x62a, 0x3b, 0x622, 0x3b,
-0x623, 0x3b, 0x62a, 0x3b, 0x62a, 0x3b, 0x643, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a,
-0x3b, 0x634, 0x628, 0x627, 0x637, 0x3b, 0x622, 0x630, 0x627, 0x631, 0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646, 0x3b, 0x623, 0x64a, 0x627,
-0x631, 0x3b, 0x62d, 0x632, 0x64a, 0x631, 0x627, 0x646, 0x3b, 0x62a, 0x645, 0x648, 0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644,
-0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x6cc, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646,
-0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b,
-0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x625, 0x628,
-0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648,
-0x3b, 0x623, 0x63a, 0x634, 0x62a, 0x3b, 0x634, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646,
-0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x62c, 0x645, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x625, 0x3b,
-0x648, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x634, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x64a, 0x646, 0x627, 0x64a,
-0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a, 0x644, 0x3b,
-0x645, 0x627, 0x64a, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x632, 0x3b, 0x63a, 0x634, 0x62a,
-0x3b, 0x634, 0x62a, 0x646, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x646, 0x628, 0x631, 0x3b,
-0x62f, 0x62c, 0x646, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b, 0x646, 0x3b, 0x644, 0x3b,
-0x63a, 0x3b, 0x634, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x570, 0x576, 0x57e, 0x3b, 0x583, 0x57f, 0x57e, 0x3b, 0x574, 0x580,
-0x57f, 0x3b, 0x561, 0x57a, 0x580, 0x3b, 0x574, 0x575, 0x57d, 0x3b, 0x570, 0x576, 0x57d, 0x3b, 0x570, 0x56c, 0x57d, 0x3b, 0x585, 0x563,
-0x57d, 0x3b, 0x57d, 0x565, 0x57a, 0x3b, 0x570, 0x578, 0x56f, 0x3b, 0x576, 0x578, 0x575, 0x3b, 0x564, 0x565, 0x56f, 0x3b, 0x570, 0x578,
-0x582, 0x576, 0x57e, 0x561, 0x580, 0x3b, 0x583, 0x565, 0x57f, 0x580, 0x57e, 0x561, 0x580, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x3b, 0x561,
-0x57a, 0x580, 0x56b, 0x56c, 0x3b, 0x574, 0x561, 0x575, 0x56b, 0x57d, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x3b, 0x570, 0x578,
-0x582, 0x56c, 0x56b, 0x57d, 0x3b, 0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578, 0x57d, 0x3b, 0x57d, 0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562,
-0x565, 0x580, 0x3b, 0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x576, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565,
-0x580, 0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x540, 0x3b, 0x553, 0x3b, 0x544, 0x3b, 0x531, 0x3b,
-0x544, 0x3b, 0x540, 0x3b, 0x540, 0x3b, 0x555, 0x3b, 0x54d, 0x3b, 0x540, 0x3b, 0x546, 0x3b, 0x534, 0x3b, 0x570, 0x578, 0x582, 0x576,
-0x57e, 0x561, 0x580, 0x56b, 0x3b, 0x583, 0x565, 0x57f, 0x580, 0x57e, 0x561, 0x580, 0x56b, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x56b, 0x3b,
-0x561, 0x57a, 0x580, 0x56b, 0x56c, 0x56b, 0x3b, 0x574, 0x561, 0x575, 0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d,
-0x56b, 0x3b, 0x570, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x56b, 0x3b, 0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578, 0x57d, 0x56b, 0x3b, 0x57d,
-0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b,
-0x3b, 0x576, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580,
-0x56b, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b,
-0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b,
-0x986, 0x997, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x3b, 0x9a1,
-0x9bf, 0x9b8, 0x9c7, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x9f1,
-0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b,
-0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b7, 0x9cd, 0x99f, 0x3b, 0x99b, 0x9c7, 0x9aa, 0x9cd,
-0x9a4, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9f0, 0x3b, 0x9a8, 0x9f1, 0x9c7, 0x9ae, 0x9cd,
-0x9ac, 0x9f0, 0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b,
-0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b, 0x69, 0x79, 0x6c, 0x3b,
-0x61, 0x76, 0x71, 0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b, 0x64, 0x65, 0x6b, 0x3b,
-0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41,
-0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x130, 0x79, 0x75, 0x6e, 0x3b, 0x130, 0x79, 0x75, 0x6c, 0x3b, 0x41,
-0x76, 0x71, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x79, 0x61,
-0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x79, 0x61, 0x6e,
-0x76, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x65,
-0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x75, 0x6e, 0x3b, 0x69, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x71, 0x75,
-0x73, 0x74, 0x3b, 0x73, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b,
-0x6e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x64, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435,
-0x432, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x43d, 0x3b, 0x438, 0x458,
-0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43d, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x458, 0x3b, 0x434, 0x435,
-0x43a, 0x3b, 0x408, 0x430, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, 0x440, 0x442,
-0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x458, 0x443, 0x43d, 0x3b, 0x418, 0x458, 0x443, 0x43b,
-0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442,
-0x458, 0x430, 0x431, 0x440, 0x3b, 0x41d, 0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x458,
-0x430, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f,
-0x440, 0x435, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x443, 0x43d, 0x3b, 0x438, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432,
-0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x458, 0x430, 0x431,
-0x440, 0x3b, 0x43d, 0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x75, 0x72, 0x74, 0x2e,
-0x3b, 0x6f, 0x74, 0x73, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x69, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x2e,
-0x3b, 0x65, 0x6b, 0x61, 0x2e, 0x3b, 0x75, 0x7a, 0x74, 0x2e, 0x3b, 0x61, 0x62, 0x75, 0x2e, 0x3b, 0x69, 0x72, 0x61, 0x2e,
-0x3b, 0x75, 0x72, 0x72, 0x2e, 0x3b, 0x61, 0x7a, 0x61, 0x2e, 0x3b, 0x61, 0x62, 0x65, 0x2e, 0x3b, 0x75, 0x72, 0x74, 0x61,
-0x72, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x4f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x78, 0x6f,
-0x61, 0x3b, 0x41, 0x70, 0x69, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, 0x45, 0x6b,
-0x61, 0x69, 0x6e, 0x61, 0x3b, 0x55, 0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x41, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61,
-0x3b, 0x49, 0x72, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x55, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x41, 0x7a, 0x61, 0x72, 0x6f, 0x61,
-0x3b, 0x41, 0x62, 0x65, 0x6e, 0x64, 0x75, 0x61, 0x3b, 0x55, 0x3b, 0x4f, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x45,
-0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72, 0x72, 0x69,
-0x6c, 0x61, 0x3b, 0x6f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61, 0x3b, 0x61,
-0x70, 0x69, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, 0x65, 0x6b, 0x61, 0x69, 0x6e,
-0x61, 0x3b, 0x75, 0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x61, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61, 0x3b, 0x69, 0x72,
-0x61, 0x69, 0x6c, 0x61, 0x3b, 0x75, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x61, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x61, 0x62,
-0x65, 0x6e, 0x64, 0x75, 0x61, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd,
-0x9b0, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9b0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2,
-0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b,
-0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8,
-0x9ad, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x99c, 0x9be, 0x3b, 0x9ab,
-0x9c7, 0x3b, 0x9ae, 0x9be, 0x3b, 0x98f, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x3b, 0x986, 0x3b, 0x9b8,
-0x9c7, 0x3b, 0x985, 0x3b, 0x9a8, 0x3b, 0x9a1, 0x9bf, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x3b, 0x9ae, 0x9be,
-0x9b0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1,
-0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0,
-0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8,
-0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf22, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf23,
-0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf24, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf25, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf26, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf27,
-0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf28, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf29, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf20, 0x3b, 0xf5f, 0xfb3, 0xf0b,
-0xf21, 0xf21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf22, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54,
-0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4,
-0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f,
-0xfb3, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54,
-0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1,
-0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3,
-0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42,
-0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b,
-0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b,
-0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b,
-0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21, 0xf20,
-0x3b, 0xf21, 0xf21, 0x3b, 0xf21, 0xf22, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27,
-0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0x31, 0x32, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54,
-0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58,
-0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b,
-0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53,
-0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51,
-0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56,
-0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49,
-0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0x34, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b,
-0xf28, 0x3b, 0x39, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0xf21, 0xf22, 0x3b, 0x47, 0x65, 0x6e, 0x2e, 0x3b, 0x43, 0x2bc,
-0x68, 0x77, 0x65, 0x2e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x2e, 0x3b, 0x45, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x65, 0x3b,
-0x4d, 0x65, 0x7a, 0x68, 0x2e, 0x3b, 0x47, 0x6f, 0x75, 0x65, 0x2e, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65,
-0x6e, 0x2e, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x72, 0x2e, 0x3b, 0x47, 0x65, 0x6e, 0x76,
-0x65, 0x72, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b,
-0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x47,
-0x6f, 0x75, 0x65, 0x72, 0x65, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b,
-0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x72, 0x7a, 0x75, 0x3b, 0x30, 0x31, 0x3b, 0x30, 0x32, 0x3b,
-0x30, 0x33, 0x3b, 0x30, 0x34, 0x3b, 0x30, 0x35, 0x3b, 0x30, 0x36, 0x3b, 0x30, 0x37, 0x3b, 0x30, 0x38, 0x3b, 0x30, 0x39,
-0x3b, 0x31, 0x30, 0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32, 0x3b, 0x47, 0x65, 0x6e, 0x2e, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65,
+0x72, 0x69, 0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x51, 0x65, 0x72, 0x3b, 0x4b, 0x6f, 0x72, 0x72, 0x3b, 0x47, 0x75, 0x73, 0x68,
+0x3b, 0x53, 0x68, 0x74, 0x3b, 0x54, 0x65, 0x74, 0x3b, 0x4e, 0xeb, 0x6e, 0x3b, 0x44, 0x68, 0x6a, 0x3b, 0x4a, 0x61, 0x6e,
+0x61, 0x72, 0x3b, 0x53, 0x68, 0x6b, 0x75, 0x72, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x50, 0x72, 0x69, 0x6c, 0x6c,
+0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x51, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x3b, 0x4b, 0x6f, 0x72, 0x72, 0x69, 0x6b, 0x3b,
+0x47, 0x75, 0x73, 0x68, 0x74, 0x3b, 0x53, 0x68, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x3b, 0x54, 0x65, 0x74, 0x6f, 0x72, 0x3b,
+0x4e, 0xeb, 0x6e, 0x74, 0x6f, 0x72, 0x3b, 0x44, 0x68, 0x6a, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x4a, 0x3b, 0x53, 0x68, 0x3b,
+0x4d, 0x3b, 0x50, 0x3b, 0x4d, 0x3b, 0x51, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x53, 0x68, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44,
+0x68, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x73, 0x68, 0x6b, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, 0x72, 0x69, 0x3b, 0x6d, 0x61,
+0x6a, 0x3b, 0x71, 0x65, 0x72, 0x3b, 0x6b, 0x6f, 0x72, 0x72, 0x3b, 0x67, 0x75, 0x73, 0x68, 0x3b, 0x73, 0x68, 0x74, 0x3b,
+0x74, 0x65, 0x74, 0x3b, 0x6e, 0xeb, 0x6e, 0x3b, 0x64, 0x68, 0x6a, 0x3b, 0x6a, 0x61, 0x6e, 0x61, 0x72, 0x3b, 0x73, 0x68,
+0x6b, 0x75, 0x72, 0x74, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b,
+0x71, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x3b, 0x6b, 0x6f, 0x72, 0x72, 0x69, 0x6b, 0x3b, 0x67, 0x75, 0x73, 0x68, 0x74,
+0x3b, 0x73, 0x68, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x3b, 0x74, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x6e, 0xeb, 0x6e, 0x74, 0x6f,
+0x72, 0x3b, 0x64, 0x68, 0x6a, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x6a, 0x3b, 0x73, 0x68, 0x3b, 0x6d, 0x3b, 0x70, 0x3b, 0x6d,
+0x3b, 0x71, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x73, 0x68, 0x3b, 0x74, 0x3b, 0x6e, 0x3b, 0x64, 0x68, 0x3b, 0x1303, 0x1295, 0x12e9,
+0x3b, 0x134c, 0x1265, 0x1229, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x122a, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301,
+0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x3b, 0x1234, 0x1355, 0x1274, 0x3b, 0x12a6, 0x12ad, 0x1276, 0x3b, 0x1296, 0x126c, 0x121d, 0x3b, 0x12f2,
+0x1234, 0x121d, 0x3b, 0x1303, 0x1295, 0x12e9, 0x12c8, 0x122a, 0x3b, 0x134c, 0x1265, 0x1229, 0x12c8, 0x122a, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4,
+0x1355, 0x122a, 0x120d, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x1275, 0x3b, 0x1234,
+0x1355, 0x1274, 0x121d, 0x1260, 0x122d, 0x3b, 0x12a6, 0x12ad, 0x1276, 0x1260, 0x122d, 0x3b, 0x1296, 0x126c, 0x121d, 0x1260, 0x122d, 0x3b, 0x12f2, 0x1234,
+0x121d, 0x1260, 0x122d, 0x3b, 0x1303, 0x3b, 0x134c, 0x3b, 0x121b, 0x3b, 0x12a4, 0x3b, 0x121c, 0x3b, 0x1301, 0x3b, 0x1301, 0x3b, 0x12a6, 0x3b,
+0x1234, 0x3b, 0x12a6, 0x3b, 0x1296, 0x3b, 0x12f2, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631,
+0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x646,
+0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x623, 0x63a, 0x633, 0x637, 0x633, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628,
+0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x64a, 0x633, 0x645,
+0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x648, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x633,
+0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x62c, 0x627, 0x646, 0x641, 0x64a, 0x3b, 0x641, 0x64a, 0x641, 0x631, 0x64a, 0x3b, 0x645,
+0x627, 0x631, 0x633, 0x3b, 0x623, 0x641, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x62c, 0x648, 0x627, 0x646, 0x3b, 0x62c,
+0x648, 0x64a, 0x644, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x62a, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a,
+0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x64a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b,
+0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x623, 0x3b, 0x633, 0x3b, 0x623, 0x3b, 0x646, 0x3b,
+0x62f, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x634, 0x628, 0x627, 0x637, 0x3b,
+0x622, 0x630, 0x627, 0x631, 0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646, 0x3b, 0x623, 0x64a, 0x627, 0x631, 0x3b, 0x62d, 0x632, 0x64a, 0x631,
+0x627, 0x646, 0x3b, 0x62a, 0x645, 0x648, 0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631,
+0x64a, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646,
+0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x643, 0x3b, 0x634, 0x3b, 0x622, 0x3b,
+0x646, 0x3b, 0x623, 0x3b, 0x62d, 0x3b, 0x62a, 0x3b, 0x622, 0x3b, 0x623, 0x3b, 0x62a, 0x3b, 0x62a, 0x3b, 0x643, 0x3b, 0x643, 0x627,
+0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x634, 0x628, 0x627, 0x637, 0x3b, 0x622, 0x630, 0x627, 0x631,
+0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646, 0x3b, 0x623, 0x64a, 0x627, 0x631, 0x3b, 0x62d, 0x632, 0x64a, 0x631, 0x627, 0x646, 0x3b, 0x62a,
+0x645, 0x648, 0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0xa0, 0x627,
+0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x643, 0x627,
+0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627,
+0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x625, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x648, 0x3b, 0x64a,
+0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x623, 0x63a, 0x634, 0x62a, 0x3b, 0x634, 0x62a, 0x645, 0x628,
+0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x62c, 0x645, 0x628,
+0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x625, 0x3b, 0x648, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x634, 0x3b,
+0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645,
+0x627, 0x631, 0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b,
+0x64a, 0x648, 0x644, 0x64a, 0x648, 0x632, 0x3b, 0x63a, 0x634, 0x62a, 0x3b, 0x634, 0x62a, 0x646, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a,
+0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x646, 0x628, 0x631, 0x3b, 0x62f, 0x62c, 0x646, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b,
+0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x634, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b,
+0x570, 0x576, 0x57e, 0x3b, 0x583, 0x57f, 0x57e, 0x3b, 0x574, 0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580, 0x3b, 0x574, 0x575, 0x57d, 0x3b,
+0x570, 0x576, 0x57d, 0x3b, 0x570, 0x56c, 0x57d, 0x3b, 0x585, 0x563, 0x57d, 0x3b, 0x57d, 0x565, 0x57a, 0x3b, 0x570, 0x578, 0x56f, 0x3b,
+0x576, 0x578, 0x575, 0x3b, 0x564, 0x565, 0x56f, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580, 0x3b, 0x583, 0x565, 0x57f, 0x580,
+0x57e, 0x561, 0x580, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580, 0x56b, 0x56c, 0x3b, 0x574, 0x561, 0x575, 0x56b, 0x57d,
+0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x3b, 0x570, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x3b, 0x585, 0x563, 0x578, 0x57d, 0x57f,
+0x578, 0x57d, 0x3b, 0x57d, 0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562,
+0x565, 0x580, 0x3b, 0x576, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565,
+0x580, 0x3b, 0x540, 0x3b, 0x553, 0x3b, 0x544, 0x3b, 0x531, 0x3b, 0x544, 0x3b, 0x540, 0x3b, 0x540, 0x3b, 0x555, 0x3b, 0x54d, 0x3b,
+0x540, 0x3b, 0x546, 0x3b, 0x534, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580, 0x56b, 0x3b, 0x583, 0x565, 0x57f, 0x580, 0x57e,
+0x561, 0x580, 0x56b, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x56b, 0x3b, 0x561, 0x57a, 0x580, 0x56b, 0x56c, 0x56b, 0x3b, 0x574, 0x561, 0x575,
+0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x56b, 0x3b,
+0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578, 0x57d, 0x56b, 0x3b, 0x57d, 0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b,
+0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x576, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b,
+0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac,
+0x9cd, 0x9f0, 0x9c1, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x2019,
+0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x3b, 0x99b, 0x9c7, 0x9aa, 0x9cd, 0x9a4, 0x9c7,
+0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x3b, 0x9a8, 0x9f1, 0x9c7, 0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1,
+0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd,
+0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x2019, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2,
+0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b7, 0x9cd, 0x99f, 0x3b, 0x99b, 0x9c7, 0x9aa, 0x9cd, 0x9a4, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b,
+0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9f0, 0x3b, 0x9a8, 0x9f1, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7,
+0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x99c, 0x3b, 0x9ab, 0x3b, 0x9ae, 0x3b, 0x98f, 0x3b, 0x9ae, 0x3b, 0x99c, 0x3b, 0x99c, 0x3b, 0x986,
+0x3b, 0x99b, 0x3b, 0x985, 0x3b, 0x9a8, 0x3b, 0x9a1, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72,
+0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b, 0x69, 0x79, 0x6c, 0x3b, 0x61, 0x76, 0x71,
+0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b, 0x64, 0x65, 0x6b, 0x3b, 0x59, 0x61, 0x6e,
+0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65,
+0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x130, 0x79, 0x75, 0x6e, 0x3b, 0x130, 0x79, 0x75, 0x6c, 0x3b, 0x41, 0x76, 0x71, 0x75,
+0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b,
+0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x79, 0x61, 0x6e, 0x76, 0x61, 0x72,
+0x3b, 0x66, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x6d,
+0x61, 0x79, 0x3b, 0x69, 0x79, 0x75, 0x6e, 0x3b, 0x69, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x71, 0x75, 0x73, 0x74, 0x3b,
+0x73, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x6e, 0x6f, 0x79,
+0x61, 0x62, 0x72, 0x3b, 0x64, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x432, 0x3b, 0x43c,
+0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x43d, 0x3b, 0x438, 0x458, 0x43b, 0x3b, 0x430,
+0x432, 0x433, 0x3b, 0x441, 0x435, 0x43d, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x458, 0x3b, 0x434, 0x435, 0x43a, 0x3b, 0x408,
+0x430, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f,
+0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x458, 0x443, 0x43d, 0x3b, 0x418, 0x458, 0x443, 0x43b, 0x3b, 0x410, 0x432,
+0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442, 0x458, 0x430, 0x431,
+0x440, 0x3b, 0x41d, 0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x458, 0x430, 0x43d, 0x432,
+0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b,
+0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x443, 0x43d, 0x3b, 0x438, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441,
+0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x43d,
+0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x75, 0x72, 0x74, 0x2e, 0x3b, 0x6f, 0x74,
+0x73, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x69, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x2e, 0x3b, 0x65, 0x6b,
+0x61, 0x2e, 0x3b, 0x75, 0x7a, 0x74, 0x2e, 0x3b, 0x61, 0x62, 0x75, 0x2e, 0x3b, 0x69, 0x72, 0x61, 0x2e, 0x3b, 0x75, 0x72,
+0x72, 0x2e, 0x3b, 0x61, 0x7a, 0x61, 0x2e, 0x3b, 0x61, 0x62, 0x65, 0x2e, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72, 0x72, 0x69,
+0x6c, 0x61, 0x3b, 0x4f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61, 0x3b, 0x41,
+0x70, 0x69, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, 0x45, 0x6b, 0x61, 0x69, 0x6e,
+0x61, 0x3b, 0x55, 0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x41, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61, 0x3b, 0x49, 0x72,
+0x61, 0x69, 0x6c, 0x61, 0x3b, 0x55, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x41, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x41, 0x62,
+0x65, 0x6e, 0x64, 0x75, 0x61, 0x3b, 0x55, 0x3b, 0x4f, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x55, 0x3b,
+0x41, 0x3b, 0x49, 0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72, 0x72, 0x69, 0x6c, 0x61, 0x3b,
+0x6f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61, 0x3b, 0x61, 0x70, 0x69, 0x72,
+0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, 0x65, 0x6b, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x75,
+0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x61, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61, 0x3b, 0x69, 0x72, 0x61, 0x69, 0x6c,
+0x61, 0x3b, 0x75, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x61, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x61, 0x62, 0x65, 0x6e, 0x64,
+0x75, 0x61, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9b0, 0x9c1, 0x9af,
+0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9b0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7,
+0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa,
+0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae,
+0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x99c, 0x9be, 0x3b, 0x9ab, 0x9c7, 0x3b, 0x9ae,
+0x9be, 0x3b, 0x98f, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x3b, 0x986, 0x3b, 0x9b8, 0x9c7, 0x3b, 0x985,
+0x3b, 0x9a8, 0x3b, 0x9a1, 0x9bf, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x3b, 0x9ae, 0x9be, 0x9b0, 0x9cd, 0x99a,
+0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987,
+0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x985, 0x995,
+0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd,
+0x9ac, 0x9b0, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf22, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf23, 0x3b, 0xf5f, 0xfb3,
+0xf0b, 0xf24, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf25, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf26, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf27, 0x3b, 0xf5f, 0xfb3,
+0xf0b, 0xf28, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf29, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf20, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf21, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf22, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf66,
+0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b,
+0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56,
+0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66,
+0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62,
+0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54,
+0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1,
+0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1,
+0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22,
+0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21,
+0x3b, 0xf21, 0xf22, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b,
+0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0x31, 0x32, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf5f,
+0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b,
+0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b,
+0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b,
+0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b,
+0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b,
+0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0x34, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0x39,
+0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0xf21, 0xf22, 0x3b, 0x47, 0x65, 0x6e, 0x2e, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65,
0x2e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x2e, 0x3b, 0x45, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a,
0x68, 0x2e, 0x3b, 0x47, 0x6f, 0x75, 0x65, 0x2e, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x2e, 0x3b,
-0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x7a, 0x75, 0x2e, 0x3b, 0x44f, 0x43d, 0x443, 0x3b, 0x444, 0x435, 0x432,
-0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b,
-0x438, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x435, 0x3b, 0x434, 0x435,
-0x43a, 0x3b, 0x44f, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430,
-0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438,
-0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a,
-0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c,
-0x432, 0x440, 0x438, 0x3b, 0x44f, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x44e, 0x3b, 0x44e, 0x3b, 0x430, 0x3b,
-0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x1007, 0x1014, 0x103a, 0x3b, 0x1016, 0x1031, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027,
-0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x3b, 0x1029, 0x3b, 0x1005, 0x1000, 0x103a, 0x3b, 0x1021, 0x1031,
-0x102c, 0x1000, 0x103a, 0x3b, 0x1014, 0x102d, 0x102f, 0x3b, 0x1012, 0x102e, 0x3b, 0x1007, 0x1014, 0x103a, 0x1014, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b,
-0x1016, 0x1031, 0x1016, 0x1031, 0x102c, 0x103a, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x1015, 0x103c, 0x102e, 0x3b,
-0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x101c, 0x102d, 0x102f, 0x1004, 0x103a, 0x3b, 0x1029, 0x1002, 0x102f, 0x1010,
-0x103a, 0x3b, 0x1005, 0x1000, 0x103a, 0x1010, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x1010, 0x102d, 0x102f, 0x1018,
-0x102c, 0x3b, 0x1014, 0x102d, 0x102f, 0x101d, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1012, 0x102e, 0x1007, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1007,
-0x3b, 0x1016, 0x3b, 0x1019, 0x3b, 0x1027, 0x3b, 0x1019, 0x3b, 0x1007, 0x3b, 0x1007, 0x3b, 0x1029, 0x3b, 0x1005, 0x3b, 0x1021, 0x3b, 0x1014,
-0x3b, 0x1012, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x43c,
-0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a,
-0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44c, 0x3b,
-0x43b, 0x44e, 0x442, 0x44b, 0x3b, 0x441, 0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432, 0x456,
-0x43a, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x456, 0x43f, 0x435, 0x43d, 0x44c,
-0x3b, 0x436, 0x43d, 0x456, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x435, 0x43d, 0x44c, 0x3b, 0x43a, 0x430,
-0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, 0x434, 0x3b, 0x441, 0x43d,
-0x435, 0x436, 0x430, 0x43d, 0x44c, 0x3b, 0x441, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x43a, 0x3b, 0x43c, 0x3b, 0x447, 0x3b, 0x43b, 0x3b,
-0x436, 0x3b, 0x432, 0x3b, 0x43a, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430,
-0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d,
-0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442,
-0x443, 0x434, 0x437, 0x435, 0x43d, 0x44f, 0x3b, 0x43b, 0x44e, 0x442, 0x430, 0x433, 0x430, 0x3b, 0x441, 0x430, 0x43a, 0x430, 0x432, 0x456,
-0x43a, 0x430, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440,
-0x432, 0x435, 0x43d, 0x44f, 0x3b, 0x43b, 0x456, 0x43f, 0x435, 0x43d, 0x44f, 0x3b, 0x436, 0x43d, 0x456, 0x45e, 0x43d, 0x44f, 0x3b, 0x432,
-0x435, 0x440, 0x430, 0x441, 0x43d, 0x44f, 0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x430, 0x3b, 0x43b,
-0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, 0x434, 0x430, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x43d, 0x44f, 0x3b, 0x1798, 0x1780, 0x179a, 0x17b6,
-0x3b, 0x1780, 0x17bb, 0x1798, 0x17d2, 0x1797, 0x17c8, 0x3b, 0x1798, 0x17b8, 0x1793, 0x17b6, 0x3b, 0x1798, 0x17c1, 0x179f, 0x17b6, 0x3b, 0x17a7, 0x179f,
-0x1797, 0x17b6, 0x3b, 0x1798, 0x17b7, 0x1790, 0x17bb, 0x1793, 0x17b6, 0x3b, 0x1780, 0x1780, 0x17d2, 0x1780, 0x178a, 0x17b6, 0x3b, 0x179f, 0x17b8, 0x17a0,
-0x17b6, 0x3b, 0x1780, 0x1789, 0x17d2, 0x1789, 0x17b6, 0x3b, 0x178f, 0x17bb, 0x179b, 0x17b6, 0x3b, 0x179c, 0x17b7, 0x1785, 0x17d2, 0x1786, 0x17b7, 0x1780,
-0x17b6, 0x3b, 0x1792, 0x17d2, 0x1793, 0x17bc, 0x3b, 0x1798, 0x3b, 0x1780, 0x3b, 0x1798, 0x3b, 0x1798, 0x3b, 0x17a7, 0x3b, 0x1798, 0x3b, 0x1780,
-0x3b, 0x179f, 0x3b, 0x1780, 0x3b, 0x178f, 0x3b, 0x179c, 0x3b, 0x1792, 0x3b, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72,
-0x2e, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e,
-0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e,
-0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x65, 0x62,
-0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b,
-0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x3b, 0x73, 0x65,
-0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d,
-0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x47, 0x4e, 0x3b, 0x46, 0x42, 0x3b, 0x4d,
-0xc7, 0x3b, 0x41, 0x42, 0x3b, 0x4d, 0x47, 0x3b, 0x4a, 0x4e, 0x3b, 0x4a, 0x4c, 0x3b, 0x41, 0x47, 0x3b, 0x53, 0x54, 0x3b,
-0x4f, 0x43, 0x3b, 0x4e, 0x56, 0x3b, 0x44, 0x53, 0x3b, 0x64, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x64, 0x65, 0x20,
-0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x2e,
-0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x64, 0x65, 0x20,
-0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x64, 0x2019, 0x61, 0x67, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x64,
-0x2019, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x64, 0x65, 0x73,
-0x2e, 0x3b, 0x64, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72,
-0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x64, 0x65, 0x20,
-0x6d, 0x61, 0x69, 0x67, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6c, 0x69,
-0x6f, 0x6c, 0x3b, 0x64, 0x2019, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62,
-0x72, 0x65, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x6e, 0x6f, 0x76, 0x65,
-0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x31, 0x6708, 0x3b,
-0x32, 0x6708, 0x3b, 0x33, 0x6708, 0x3b, 0x34, 0x6708, 0x3b, 0x35, 0x6708, 0x3b, 0x36, 0x6708, 0x3b, 0x37, 0x6708, 0x3b, 0x38, 0x6708,
-0x3b, 0x39, 0x6708, 0x3b, 0x31, 0x30, 0x6708, 0x3b, 0x31, 0x31, 0x6708, 0x3b, 0x31, 0x32, 0x6708, 0x3b, 0x4e00, 0x6708, 0x3b, 0x4e8c,
-0x6708, 0x3b, 0x4e09, 0x6708, 0x3b, 0x56db, 0x6708, 0x3b, 0x4e94, 0x6708, 0x3b, 0x516d, 0x6708, 0x3b, 0x4e03, 0x6708, 0x3b, 0x516b, 0x6708, 0x3b,
-0x4e5d, 0x6708, 0x3b, 0x5341, 0x6708, 0x3b, 0x5341, 0x4e00, 0x6708, 0x3b, 0x5341, 0x4e8c, 0x6708, 0x3b, 0x73, 0x69, 0x6a, 0x3b, 0x76, 0x65,
-0x6c, 0x6a, 0x3b, 0x6f, 0x17e, 0x75, 0x3b, 0x74, 0x72, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x3b, 0x6c, 0x69, 0x70, 0x3b, 0x73,
-0x72, 0x70, 0x3b, 0x6b, 0x6f, 0x6c, 0x3b, 0x72, 0x75, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x73, 0x74, 0x75, 0x3b, 0x70,
-0x72, 0x6f, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x61, 0x6e, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x61, 0x3b,
-0x6f, 0x17e, 0x75, 0x6a, 0x61, 0x6b, 0x3b, 0x74, 0x72, 0x61, 0x76, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x61,
-0x6e, 0x6a, 0x3b, 0x6c, 0x69, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x72, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x6b, 0x6f, 0x6c,
-0x6f, 0x76, 0x6f, 0x7a, 0x3b, 0x72, 0x75, 0x6a, 0x61, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b,
-0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x69, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x61, 0x63, 0x3b, 0x31, 0x2e, 0x3b,
-0x32, 0x2e, 0x3b, 0x33, 0x2e, 0x3b, 0x34, 0x2e, 0x3b, 0x35, 0x2e, 0x3b, 0x36, 0x2e, 0x3b, 0x37, 0x2e, 0x3b, 0x38, 0x2e,
-0x3b, 0x39, 0x2e, 0x3b, 0x31, 0x30, 0x2e, 0x3b, 0x31, 0x31, 0x2e, 0x3b, 0x31, 0x32, 0x2e, 0x3b, 0x73, 0x69, 0x6a, 0x65,
-0x10d, 0x6e, 0x6a, 0x61, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x65, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x6b, 0x61, 0x3b,
-0x74, 0x72, 0x61, 0x76, 0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x6e, 0x6a, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x6e,
-0x6a, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x6a, 0x61, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x61, 0x3b, 0x72,
-0x75, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65,
-0x6e, 0x6f, 0x67, 0x61, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x61, 0x3b, 0x6c, 0x65, 0x64, 0x3b, 0xfa, 0x6e,
-0x6f, 0x3b, 0x62, 0x159, 0x65, 0x3b, 0x64, 0x75, 0x62, 0x3b, 0x6b, 0x76, 0x11b, 0x3b, 0x10d, 0x76, 0x6e, 0x3b, 0x10d, 0x76,
-0x63, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x7a, 0xe1, 0x159, 0x3b, 0x159, 0xed, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x70, 0x72,
-0x6f, 0x3b, 0x6c, 0x65, 0x64, 0x65, 0x6e, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x65, 0x6e, 0x3b,
-0x64, 0x75, 0x62, 0x65, 0x6e, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x3b,
-0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x65, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x65, 0x6e, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b,
-0x159, 0xed, 0x6a, 0x65, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69,
-0x6e, 0x65, 0x63, 0x3b, 0x6c, 0x65, 0x64, 0x6e, 0x61, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x61, 0x3b, 0x62, 0x159, 0x65, 0x7a,
-0x6e, 0x61, 0x3b, 0x64, 0x75, 0x62, 0x6e, 0x61, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76,
-0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x63, 0x65, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x61, 0x3b, 0x7a, 0xe1,
-0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x75, 0x3b, 0x70,
-0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61,
-0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c,
-0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76,
-0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61,
-0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75,
-0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65,
-0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65,
-0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e,
-0x3b, 0x6d, 0x72, 0x74, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b,
-0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b,
-0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65,
-0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d,
-0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75,
-0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b,
-0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61,
-0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61,
-0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70,
-0x2e, 0x3b, 0x4f, 0x63, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x61,
-0x6e, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61,
-0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65,
-0x70, 0x74, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x3b, 0x6a, 0x61, 0x61, 0x6e,
-0x75, 0x61, 0x72, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61,
-0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c,
+0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x7a, 0x75, 0x2e, 0x3b, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b,
+0x43, 0x2bc, 0x68, 0x77, 0x65, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x45, 0x62, 0x72,
+0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x47, 0x6f, 0x75, 0x65,
+0x72, 0x65, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x48, 0x65, 0x72,
+0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x72, 0x7a, 0x75, 0x3b, 0x30, 0x31, 0x3b, 0x30, 0x32, 0x3b, 0x30, 0x33, 0x3b,
+0x30, 0x34, 0x3b, 0x30, 0x35, 0x3b, 0x30, 0x36, 0x3b, 0x30, 0x37, 0x3b, 0x30, 0x38, 0x3b, 0x30, 0x39, 0x3b, 0x31, 0x30,
+0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32, 0x3b, 0x44f, 0x43d, 0x443, 0x3b, 0x444, 0x435, 0x432, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b,
+0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x3b,
+0x441, 0x435, 0x43f, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x435, 0x3b, 0x434, 0x435, 0x43a, 0x3b, 0x44f, 0x43d, 0x443, 0x430,
+0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440,
+0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441,
+0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438,
+0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x44f, 0x3b,
+0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x44e, 0x3b, 0x44e, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b,
+0x434, 0x3b, 0x1007, 0x1014, 0x103a, 0x3b, 0x1016, 0x1031, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d,
+0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x3b, 0x1029, 0x3b, 0x1005, 0x1000, 0x103a, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x3b, 0x1014, 0x102d,
+0x102f, 0x3b, 0x1012, 0x102e, 0x3b, 0x1007, 0x1014, 0x103a, 0x1014, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1016, 0x1031, 0x1016, 0x1031, 0x102c, 0x103a,
+0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x1015, 0x103c, 0x102e, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014,
+0x103a, 0x3b, 0x1007, 0x1030, 0x101c, 0x102d, 0x102f, 0x1004, 0x103a, 0x3b, 0x1029, 0x1002, 0x102f, 0x1010, 0x103a, 0x3b, 0x1005, 0x1000, 0x103a, 0x1010,
+0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x1010, 0x102d, 0x102f, 0x1018, 0x102c, 0x3b, 0x1014, 0x102d, 0x102f, 0x101d,
+0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1012, 0x102e, 0x1007, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1007, 0x3b, 0x1016, 0x3b, 0x1019, 0x3b, 0x1027,
+0x3b, 0x1019, 0x3b, 0x1007, 0x3b, 0x1007, 0x3b, 0x1029, 0x3b, 0x1005, 0x3b, 0x1021, 0x3b, 0x1014, 0x3b, 0x1012, 0x3b, 0x441, 0x442, 0x443,
+0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440,
+0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441,
+0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x44e, 0x442, 0x44b, 0x3b, 0x441,
+0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43c, 0x430, 0x439, 0x3b,
+0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x456, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x436, 0x43d, 0x456, 0x432, 0x435,
+0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x435, 0x43d, 0x44c, 0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d,
+0x456, 0x43a, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, 0x434, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x430, 0x43d, 0x44c, 0x3b,
+0x441, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x43a, 0x3b, 0x43c, 0x3b, 0x447, 0x3b, 0x43b, 0x3b, 0x436, 0x3b, 0x432, 0x3b, 0x43a, 0x3b,
+0x43b, 0x3b, 0x441, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b,
+0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b,
+0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44f,
+0x3b, 0x43b, 0x44e, 0x442, 0x430, 0x433, 0x430, 0x3b, 0x441, 0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43a, 0x440, 0x430,
+0x441, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44f, 0x3b, 0x43b,
+0x456, 0x43f, 0x435, 0x43d, 0x44f, 0x3b, 0x436, 0x43d, 0x456, 0x45e, 0x43d, 0x44f, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x43d, 0x44f,
+0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x430, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430,
+0x434, 0x430, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x43d, 0x44f, 0x3b, 0x1798, 0x1780, 0x179a, 0x17b6, 0x3b, 0x1780, 0x17bb, 0x1798, 0x17d2, 0x1797,
+0x17c8, 0x3b, 0x1798, 0x17b8, 0x1793, 0x17b6, 0x3b, 0x1798, 0x17c1, 0x179f, 0x17b6, 0x3b, 0x17a7, 0x179f, 0x1797, 0x17b6, 0x3b, 0x1798, 0x17b7, 0x1790,
+0x17bb, 0x1793, 0x17b6, 0x3b, 0x1780, 0x1780, 0x17d2, 0x1780, 0x178a, 0x17b6, 0x3b, 0x179f, 0x17b8, 0x17a0, 0x17b6, 0x3b, 0x1780, 0x1789, 0x17d2, 0x1789,
+0x17b6, 0x3b, 0x178f, 0x17bb, 0x179b, 0x17b6, 0x3b, 0x179c, 0x17b7, 0x1785, 0x17d2, 0x1786, 0x17b7, 0x1780, 0x17b6, 0x3b, 0x1792, 0x17d2, 0x1793, 0x17bc,
+0x3b, 0x1798, 0x3b, 0x1780, 0x3b, 0x1798, 0x3b, 0x1798, 0x3b, 0x17a7, 0x3b, 0x1798, 0x3b, 0x1780, 0x3b, 0x179f, 0x3b, 0x1780, 0x3b, 0x178f,
+0x3b, 0x179c, 0x3b, 0x1792, 0x3b, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0xe7,
+0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x2e,
+0x3b, 0x61, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b,
+0x64, 0x65, 0x73, 0x2e, 0x3b, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61,
+0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a,
+0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65,
+0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65,
+0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x47, 0x4e, 0x3b, 0x46, 0x42, 0x3b, 0x4d, 0xc7, 0x3b, 0x41, 0x42, 0x3b, 0x4d,
+0x47, 0x3b, 0x4a, 0x4e, 0x3b, 0x4a, 0x4c, 0x3b, 0x41, 0x47, 0x3b, 0x53, 0x54, 0x3b, 0x4f, 0x43, 0x3b, 0x4e, 0x56, 0x3b,
+0x44, 0x53, 0x3b, 0x64, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b,
+0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61,
+0x69, 0x67, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x64,
+0x2019, 0x61, 0x67, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x74, 0x2e, 0x3b,
+0x64, 0x65, 0x20, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x67,
+0x65, 0x6e, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61,
+0x72, 0xe7, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x64,
+0x65, 0x20, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x64, 0x2019, 0x61,
+0x67, 0x6f, 0x73, 0x74, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x2019, 0x6f,
+0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64,
+0x65, 0x20, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x31, 0x6708, 0x3b, 0x32, 0x6708, 0x3b, 0x33, 0x6708, 0x3b,
+0x34, 0x6708, 0x3b, 0x35, 0x6708, 0x3b, 0x36, 0x6708, 0x3b, 0x37, 0x6708, 0x3b, 0x38, 0x6708, 0x3b, 0x39, 0x6708, 0x3b, 0x31, 0x30,
+0x6708, 0x3b, 0x31, 0x31, 0x6708, 0x3b, 0x31, 0x32, 0x6708, 0x3b, 0x4e00, 0x6708, 0x3b, 0x4e8c, 0x6708, 0x3b, 0x4e09, 0x6708, 0x3b, 0x56db,
+0x6708, 0x3b, 0x4e94, 0x6708, 0x3b, 0x516d, 0x6708, 0x3b, 0x4e03, 0x6708, 0x3b, 0x516b, 0x6708, 0x3b, 0x4e5d, 0x6708, 0x3b, 0x5341, 0x6708, 0x3b,
+0x5341, 0x4e00, 0x6708, 0x3b, 0x5341, 0x4e8c, 0x6708, 0x3b, 0x73, 0x69, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x3b, 0x6f, 0x17e, 0x75,
+0x3b, 0x74, 0x72, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x3b, 0x6c, 0x69, 0x70, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x6b, 0x6f, 0x6c,
+0x3b, 0x72, 0x75, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x73, 0x74, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x73, 0x69, 0x6a,
+0x65, 0x10d, 0x61, 0x6e, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x61, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x61, 0x6b,
+0x3b, 0x74, 0x72, 0x61, 0x76, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x61, 0x6e, 0x6a, 0x3b, 0x6c, 0x69, 0x70,
+0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x72, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x3b, 0x72,
+0x75, 0x6a, 0x61, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e,
+0x69, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x61, 0x63, 0x3b, 0x31, 0x2e, 0x3b, 0x32, 0x2e, 0x3b, 0x33, 0x2e, 0x3b,
+0x34, 0x2e, 0x3b, 0x35, 0x2e, 0x3b, 0x36, 0x2e, 0x3b, 0x37, 0x2e, 0x3b, 0x38, 0x2e, 0x3b, 0x39, 0x2e, 0x3b, 0x31, 0x30,
+0x2e, 0x3b, 0x31, 0x31, 0x2e, 0x3b, 0x31, 0x32, 0x2e, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x6e, 0x6a, 0x61, 0x3b, 0x76,
+0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x65, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x6b, 0x61, 0x3b, 0x74, 0x72, 0x61, 0x76, 0x6e, 0x6a,
+0x61, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x6e, 0x6a, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x72, 0x70,
+0x6e, 0x6a, 0x61, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x61, 0x3b, 0x72, 0x75, 0x6a, 0x6e, 0x61, 0x3b, 0x6c,
+0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x6f, 0x67, 0x61, 0x3b, 0x70,
+0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x61, 0x3b, 0x6c, 0x65, 0x64, 0x3b, 0xfa, 0x6e, 0x6f, 0x3b, 0x62, 0x159, 0x65, 0x3b,
+0x64, 0x75, 0x62, 0x3b, 0x6b, 0x76, 0x11b, 0x3b, 0x10d, 0x76, 0x6e, 0x3b, 0x10d, 0x76, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x3b,
+0x7a, 0xe1, 0x159, 0x3b, 0x159, 0xed, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x6c, 0x65, 0x64, 0x65,
+0x6e, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x65, 0x6e, 0x3b, 0x64, 0x75, 0x62, 0x65, 0x6e, 0x3b,
+0x6b, 0x76, 0x11b, 0x74, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e,
+0x65, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x65, 0x6e, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x65, 0x6e, 0x3b,
+0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x65, 0x63, 0x3b, 0x6c, 0x65,
+0x64, 0x6e, 0x61, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x61, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x6e, 0x61, 0x3b, 0x64, 0x75, 0x62,
+0x6e, 0x61, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72,
+0x76, 0x65, 0x6e, 0x63, 0x65, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x61, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a,
+0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63,
+0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72,
+0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e,
+0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e,
+0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74,
+0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c,
0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f,
-0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x74,
-0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a,
-0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d,
-0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61,
-0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x6a,
-0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61,
-0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61,
-0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f,
-0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65,
-0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72,
-0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e,
-0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e,
-0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x3b,
-0x68, 0x75, 0x68, 0x74, 0x69, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x3b, 0x68, 0x65, 0x69,
-0x6e, 0xe4, 0x3b, 0x65, 0x6c, 0x6f, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x3b, 0x6d, 0x61, 0x72,
-0x72, 0x61, 0x73, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x68,
-0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x75,
-0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x6b, 0x65, 0x73, 0xe4,
-0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x3b,
-0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x72,
-0x61, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x3b, 0x54, 0x3b, 0x48, 0x3b, 0x4d,
-0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x48, 0x3b, 0x45, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x74,
-0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69,
-0x73, 0x6b, 0x2e, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x2e, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x2e, 0x3b,
-0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x2e, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x2e, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x2e,
-0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x2e, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61,
-0x73, 0x6b, 0x2e, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x2e, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75,
-0x74, 0x61, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73,
-0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x74, 0x6f, 0x75,
-0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65,
-0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x73, 0x79,
-0x79, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61,
-0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x74, 0x61,
-0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76,
-0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, 0x3b, 0x61, 0x6f,
-0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64,
-0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x72, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x69, 0x65, 0x72, 0x3b,
-0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b,
-0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x65, 0x74, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
-0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b,
-0x64, 0xe9, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x2e,
-0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b,
-0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63,
-0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0xe9,
-0x76, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69,
-0x2e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f,
-0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65,
-0x62, 0x3b, 0x4d, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75,
-0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65,
-0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65, 0x77, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x77, 0x61,
-0x72, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x61, 0x69,
-0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x3b, 0x4a, 0x75, 0x6c, 0x79, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73,
-0x3b, 0x53, 0x65, 0x70, 0x74, 0x69, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e,
-0x6f, 0x76, 0x69, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x73, 0x69, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x46, 0x61, 0x6f,
-0x69, 0x3b, 0x47, 0x65, 0x61, 0x72, 0x72, 0x3b, 0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x47, 0x69, 0x62, 0x6c, 0x3b, 0x43, 0xe8,
-0x69, 0x74, 0x3b, 0xd2, 0x67, 0x6d, 0x68, 0x3b, 0x49, 0x75, 0x63, 0x68, 0x3b, 0x4c, 0xf9, 0x6e, 0x61, 0x3b, 0x53, 0x75,
-0x6c, 0x74, 0x3b, 0x44, 0xe0, 0x6d, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x3b, 0x44, 0xf9, 0x62, 0x68, 0x3b, 0x41, 0x6d,
-0x20, 0x46, 0x61, 0x6f, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x63, 0x68, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x65, 0x61, 0x72, 0x72,
-0x61, 0x6e, 0x3b, 0x41, 0x6d, 0x20, 0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x69, 0x62, 0x6c, 0x65, 0x61,
-0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x43, 0xe8, 0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0xd2, 0x67,
-0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x49, 0x75, 0x63, 0x68, 0x61, 0x72, 0x3b, 0x41, 0x6e,
-0x20, 0x4c, 0xf9, 0x6e, 0x61, 0x73, 0x74, 0x61, 0x6c, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x75, 0x6c, 0x74, 0x61,
-0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44, 0xe0, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53,
-0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61, 0x63, 0x68, 0x64, 0x3b,
-0x46, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x43, 0x3b, 0xd2, 0x3b, 0x49, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x44, 0x3b,
-0x53, 0x3b, 0x44, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x46, 0x68, 0x61, 0x6f, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x63, 0x68,
-0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x47, 0x68, 0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20,
-0x4d, 0x68, 0xe0, 0x72, 0x74, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x47, 0x68, 0x69, 0x62, 0x6c, 0x65, 0x61, 0x6e, 0x3b,
-0x64, 0x68, 0x65, 0x6e, 0x20, 0x43, 0x68, 0xe8, 0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0xd2,
-0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x49, 0x75, 0x63, 0x68, 0x61, 0x72, 0x3b, 0x64,
-0x68, 0x65, 0x6e, 0x20, 0x4c, 0xf9, 0x6e, 0x61, 0x73, 0x74, 0x61, 0x6c, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x2d,
-0x53, 0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x44, 0xe0, 0x6d, 0x68, 0x61, 0x69, 0x72,
-0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e,
-0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61, 0x63, 0x68, 0x64, 0x3b, 0x58, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e,
-0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75, 0xf1, 0x6f,
-0x3b, 0x58, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x74, 0x2e, 0x3b, 0x4f, 0x75, 0x74, 0x2e,
-0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x63, 0x2e, 0x3b, 0x58, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46,
-0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b,
-0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75, 0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x6c, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73,
-0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b,
-0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x58, 0x3b,
-0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b,
-0x44, 0x3b, 0x78, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72,
-0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x78, 0x75, 0xf1, 0x6f, 0x3b, 0x78, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f,
-0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f, 0x75, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63,
-0x2e, 0x3b, 0x78, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d,
-0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x78, 0x75, 0xf1, 0x6f,
-0x3b, 0x78, 0x75, 0x6c, 0x6c, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62,
-0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b,
-0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x78, 0x2e, 0x3b, 0x66, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x61, 0x2e,
-0x3b, 0x6d, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, 0x61, 0x2e, 0x3b, 0x73, 0x2e, 0x3b, 0x6f, 0x2e, 0x3b, 0x6e,
-0x2e, 0x3b, 0x64, 0x2e, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x3b, 0x10d0, 0x10de, 0x10e0,
-0x3b, 0x10db, 0x10d0, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x3b, 0x10d0, 0x10d2, 0x10d5, 0x3b, 0x10e1, 0x10d4, 0x10e5,
-0x3b, 0x10dd, 0x10e5, 0x10e2, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x10d5, 0x10d0, 0x10e0, 0x10d8,
-0x3b, 0x10d7, 0x10d4, 0x10d1, 0x10d4, 0x10e0, 0x10d5, 0x10d0, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x10e2, 0x10d8, 0x3b, 0x10d0, 0x10de, 0x10e0,
-0x10d8, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10da,
-0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d0, 0x10d2, 0x10d5, 0x10d8, 0x10e1, 0x10e2, 0x10dd, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x10e2, 0x10d4, 0x10db, 0x10d1, 0x10d4,
-0x10e0, 0x10d8, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x10dd, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0,
-0x10d8, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d7, 0x3b, 0x10db, 0x3b, 0x10d0, 0x3b,
-0x10db, 0x3b, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d0, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10dc, 0x3b, 0x10d3, 0x3b, 0x4a, 0x61, 0x6e, 0x3b,
-0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b,
-0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b,
-0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d,
-0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a,
-0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72,
-0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65,
-0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72,
-0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69,
-0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e,
-0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, 0xe4, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70,
-0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65,
-0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0xe4, 0x6e, 0x6e, 0x65, 0x72,
-0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b,
-0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74,
-0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e,
-0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0xe4, 0x6e,
-0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69,
-0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e,
-0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b,
-0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3ac, 0x3b9, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd,
-0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b, 0x391, 0x3cd, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf,
-0x3ad, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x3a6, 0x3b5, 0x3b2,
-0x3c1, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3c4, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3c0, 0x3c1,
-0x3af, 0x3bb, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c, 0x3ac, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b9, 0x3bf, 0x3c2, 0x3b,
-0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3cd, 0x3b3, 0x3bf, 0x3c5, 0x3c3, 0x3c4, 0x3bf, 0x3c2, 0x3b, 0x3a3, 0x3b5,
-0x3c0, 0x3c4, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3ce, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b,
-0x39d, 0x3bf, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2,
-0x3b, 0x399, 0x3b, 0x3a6, 0x3b, 0x39c, 0x3b, 0x391, 0x3b, 0x39c, 0x3b, 0x399, 0x3b, 0x399, 0x3b, 0x391, 0x3b, 0x3a3, 0x3b, 0x39f,
-0x3b, 0x39d, 0x3b, 0x394, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1,
-0x3b, 0x39c, 0x3b1, 0x390, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3b, 0x3a3,
-0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5,
-0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1,
-0x3c1, 0x3c4, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b9, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x390, 0x3bf, 0x3c5,
-0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c5, 0x3b3,
-0x3bf, 0x3cd, 0x3c3, 0x3c4, 0x3bf, 0x3c5, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39f,
-0x3ba, 0x3c4, 0x3c9, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x394,
-0x3b5, 0x3ba, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61,
-0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75,
-0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61,
-0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73,
-0x69, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a,
-0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d,
-0x62, 0x65, 0x72, 0x69, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
-0x65, 0x72, 0x69, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1,
-0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2,
-0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b,
-0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0x3b, 0xaa8, 0xab5, 0xac7, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7,
-0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0xa86, 0xab0, 0xac0,
+0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x72, 0x74, 0x2e, 0x3b,
+0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61,
+0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64,
+0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69,
+0x3b, 0x6d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e,
+0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62,
+0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x2e,
+0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x63, 0x74, 0x2e,
+0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d,
+0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61,
+0x16d, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a,
+0x61, 0x6e, 0x75, 0x61, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x74,
+0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x6f, 0x3b, 0x6d, 0x61, 0x6a, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b,
+0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x16d, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d,
+0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f,
+0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72,
+0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69,
+0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x3b, 0x6f, 0x6b, 0x74, 0x3b,
+0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x76, 0x65, 0x65,
+0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d,
+0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73,
+0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72,
+0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x4a, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b,
+0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b,
+0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b,
+0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66,
+0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61,
+0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73,
+0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b,
+0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a,
+0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f,
+0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x3b,
+0x68, 0x65, 0x6c, 0x6d, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x3b, 0x74,
+0x6f, 0x75, 0x6b, 0x6f, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x3b, 0x65, 0x6c, 0x6f, 0x3b,
+0x73, 0x79, 0x79, 0x73, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x3b, 0x6a, 0x6f, 0x75,
+0x6c, 0x75, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75,
+0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x3b,
+0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x69,
+0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75,
+0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6a,
+0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x3b, 0x54, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x4b, 0x3b,
+0x48, 0x3b, 0x45, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x2e, 0x3b,
+0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x2e, 0x3b, 0x68, 0x75, 0x68,
+0x74, 0x69, 0x6b, 0x2e, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x2e, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x2e, 0x3b,
+0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x2e, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x2e, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x2e,
+0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x2e, 0x3b, 0x6a, 0x6f, 0x75,
+0x6c, 0x75, 0x6b, 0x2e, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65, 0x6c, 0x6d,
+0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68,
+0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61,
+0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x74,
+0x61, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61,
+0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75,
+0x74, 0x61, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b,
+0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b,
+0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74,
+0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e,
+0x76, 0x69, 0x65, 0x72, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x69, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76,
+0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x65, 0x74,
+0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f,
+0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0xe9, 0x63, 0x65, 0x6d, 0x62, 0x72,
+0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61,
+0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x2e, 0x3b,
+0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e,
+0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e,
+0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x2e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e,
+0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76,
+0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x72, 0x74, 0x3b, 0x41,
+0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53,
+0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65,
+0x77, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x77, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x61,
+0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x61, 0x69, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x3b,
+0x4a, 0x75, 0x6c, 0x79, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x69, 0x6d,
+0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x69, 0x6d, 0x62, 0x65, 0x72,
+0x3b, 0x44, 0x65, 0x73, 0x69, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x46, 0x61, 0x6f, 0x69, 0x3b, 0x47, 0x65, 0x61, 0x72, 0x72,
+0x3b, 0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x47, 0x69, 0x62, 0x6c, 0x3b, 0x43, 0xe8, 0x69, 0x74, 0x3b, 0xd2, 0x67, 0x6d, 0x68,
+0x3b, 0x49, 0x75, 0x63, 0x68, 0x3b, 0x4c, 0xf9, 0x6e, 0x61, 0x3b, 0x53, 0x75, 0x6c, 0x74, 0x3b, 0x44, 0xe0, 0x6d, 0x68,
+0x3b, 0x53, 0x61, 0x6d, 0x68, 0x3b, 0x44, 0xf9, 0x62, 0x68, 0x3b, 0x41, 0x6d, 0x20, 0x46, 0x61, 0x6f, 0x69, 0x6c, 0x6c,
+0x65, 0x61, 0x63, 0x68, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, 0x41, 0x6d, 0x20, 0x4d,
+0xe0, 0x72, 0x74, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x69, 0x62, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x43, 0xe8,
+0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0xd2, 0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, 0x41,
+0x6e, 0x20, 0x74, 0x2d, 0x49, 0x75, 0x63, 0x68, 0x61, 0x72, 0x3b, 0x41, 0x6e, 0x20, 0x4c, 0xf9, 0x6e, 0x61, 0x73, 0x74,
+0x61, 0x6c, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44,
+0xe0, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b,
+0x41, 0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61, 0x63, 0x68, 0x64, 0x3b, 0x46, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x47,
+0x3b, 0x43, 0x3b, 0xd2, 0x3b, 0x49, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x64, 0x68, 0x65,
+0x6e, 0x20, 0x46, 0x68, 0x61, 0x6f, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x63, 0x68, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x47,
+0x68, 0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x4d, 0x68, 0xe0, 0x72, 0x74, 0x3b, 0x64,
+0x68, 0x65, 0x6e, 0x20, 0x47, 0x68, 0x69, 0x62, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x43, 0x68,
+0xe8, 0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0xd2, 0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b,
+0x64, 0x68, 0x65, 0x6e, 0x20, 0x49, 0x75, 0x63, 0x68, 0x61, 0x72, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x4c, 0xf9, 0x6e,
+0x61, 0x73, 0x74, 0x61, 0x6c, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e,
+0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x44, 0xe0, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x74,
+0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61,
+0x63, 0x68, 0x64, 0x3b, 0x58, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41,
+0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75, 0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x2e, 0x3b, 0x41,
+0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x74, 0x2e, 0x3b, 0x4f, 0x75, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44,
+0x65, 0x63, 0x2e, 0x3b, 0x58, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f,
+0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75,
+0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x6c, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65,
+0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72,
+0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x58, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d,
+0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x78, 0x61, 0x6e, 0x2e, 0x3b,
+0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b,
+0x78, 0x75, 0xf1, 0x6f, 0x3b, 0x78, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b,
+0x6f, 0x75, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x78, 0x61, 0x6e, 0x65, 0x69,
+0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62,
+0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x78, 0x75, 0xf1, 0x6f, 0x3b, 0x78, 0x75, 0x6c, 0x6c, 0x6f, 0x3b,
+0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74, 0x75,
+0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72,
+0x6f, 0x3b, 0x78, 0x2e, 0x3b, 0x66, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x61, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x78, 0x2e, 0x3b,
+0x78, 0x2e, 0x3b, 0x61, 0x2e, 0x3b, 0x73, 0x2e, 0x3b, 0x6f, 0x2e, 0x3b, 0x6e, 0x2e, 0x3b, 0x64, 0x2e, 0x3b, 0x10d8, 0x10d0,
+0x10dc, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x3b, 0x10db, 0x10d0, 0x10d8, 0x3b, 0x10d8, 0x10d5,
+0x10dc, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x3b, 0x10d0, 0x10d2, 0x10d5, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x3b, 0x10dc, 0x10dd,
+0x10d4, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x10d5, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x10d4, 0x10e0, 0x10d5,
+0x10d0, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x10e2, 0x10d8, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x10d8, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10d8,
+0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d0, 0x10d2, 0x10d5,
+0x10d8, 0x10e1, 0x10e2, 0x10dd, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x10e2, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x10dd,
+0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x10d4, 0x10db,
+0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d7, 0x3b, 0x10db, 0x3b, 0x10d0, 0x3b, 0x10db, 0x3b, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d0,
+0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10dc, 0x3b, 0x10d3, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72,
+0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67,
+0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e,
+0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72,
+0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67,
+0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65,
+0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b,
+0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53,
+0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a,
+0xe4, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a,
+0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e,
+0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0xe4, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61,
+0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e,
+0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d,
+0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72,
+0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0xe4, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b,
+0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a,
+0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e,
+0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3ac, 0x3c1,
+0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3ac, 0x3b9, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b, 0x391,
+0x3cd, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399,
+0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf,
+0x3c2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3c4, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3af, 0x3bb, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c,
+0x3ac, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b9, 0x3bf, 0x3c2,
+0x3b, 0x391, 0x3cd, 0x3b3, 0x3bf, 0x3c5, 0x3c3, 0x3c4, 0x3bf, 0x3c2, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9,
+0x3bf, 0x3c2, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3ce, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9,
+0x3bf, 0x3c2, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3b, 0x3a6, 0x3b, 0x39c, 0x3b,
+0x391, 0x3b, 0x39c, 0x3b, 0x399, 0x3b, 0x399, 0x3b, 0x391, 0x3b, 0x3a3, 0x3b, 0x39f, 0x3b, 0x39d, 0x3b, 0x394, 0x3b, 0x399, 0x3b1,
+0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3b1, 0x390, 0x3b, 0x399, 0x3bf,
+0x3c5, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b,
+0x39d, 0x3bf, 0x3b5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x3a6,
+0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3c4, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391,
+0x3c0, 0x3c1, 0x3b9, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x390, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3af, 0x3bf,
+0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3bf, 0x3cd, 0x3c3, 0x3c4, 0x3bf, 0x3c5, 0x3b,
+0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3c9, 0x3b2, 0x3c1, 0x3af, 0x3bf,
+0x3c5, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af,
+0x3bf, 0x3c5, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d,
+0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f,
+0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66,
+0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c,
+0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67,
+0x75, 0x73, 0x74, 0x75, 0x73, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6f, 0x6b,
+0x74, 0x6f, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x64, 0x65, 0x63,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1,
0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8,
-0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0xaae, 0xacd,
-0xaac, 0xab0, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0xaac, 0xab0, 0x3b, 0xaa8, 0xab5, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xaa1,
-0xabf, 0xab8, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa9c, 0xabe, 0x3b, 0xaab, 0xac7, 0x3b, 0xaae, 0xabe, 0x3b, 0xa8f, 0x3b, 0xaae,
-0xac7, 0x3b, 0xa9c, 0xac2, 0x3b, 0xa9c, 0xac1, 0x3b, 0xa91, 0x3b, 0xab8, 0x3b, 0xa91, 0x3b, 0xaa8, 0x3b, 0xaa1, 0xabf, 0x3b, 0x4a,
-0x61, 0x6e, 0x3b, 0x46, 0x61, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x66, 0x69, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59,
-0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e,
-0x75, 0x77, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x46, 0x61, 0x62, 0x75, 0x72,
-0x61, 0x69, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x41, 0x66, 0x69, 0x72, 0x69, 0x6c, 0x75, 0x3b, 0x4d,
-0x61, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x69, 0x3b, 0x59, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x61,
-0x3b, 0x53, 0x61, 0x74, 0x75, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x75, 0x77, 0x61,
-0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b,
-0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5f3,
-0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5f3, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5f3, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9,
-0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5f3, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5f3, 0x3b, 0x5d0,
-0x5d5, 0x5e7, 0x5f3, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x5f3, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5f3, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5d0, 0x5e8, 0x3b,
-0x5e4, 0x5d1, 0x5e8, 0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d0, 0x5d9,
-0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b, 0x5e1, 0x5e4,
-0x5d8, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5d8, 0x5d5, 0x5d1, 0x5e8, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x5de, 0x5d1, 0x5e8, 0x3b,
-0x5d3, 0x5e6, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x91c, 0x928, 0x970, 0x3b, 0x92b, 0x93c, 0x930, 0x970, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a,
-0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x970, 0x3b,
-0x905, 0x917, 0x970, 0x3b, 0x938, 0x93f, 0x924, 0x970, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942, 0x970, 0x3b, 0x928, 0x935, 0x970, 0x3b,
-0x926, 0x93f, 0x938, 0x970, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x93c, 0x930, 0x935, 0x930, 0x940, 0x3b, 0x92e, 0x93e,
-0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941,
-0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x93f, 0x924, 0x902, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d,
-0x924, 0x942, 0x92c, 0x930, 0x3b, 0x928, 0x935, 0x902, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x3b,
-0x92b, 0x93c, 0x3b, 0x92e, 0x93e, 0x3b, 0x905, 0x3b, 0x92e, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, 0x905, 0x3b, 0x938, 0x93f,
-0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d,
-0xe1, 0x72, 0x63, 0x2e, 0x3b, 0xe1, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x6a, 0x2e, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b,
-0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74,
-0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66,
-0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x69, 0x75, 0x73, 0x3b, 0xe1, 0x70, 0x72, 0x69, 0x6c,
-0x69, 0x73, 0x3b, 0x6d, 0xe1, 0x6a, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6e, 0x69, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6c, 0x69,
-0x75, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x7a, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x65, 0x6d,
-0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72,
-0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0xc1, 0x3b, 0x4d, 0x3b,
-0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x7a, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b,
-0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a,
-0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0xe1, 0x67, 0xfa, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f,
-0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0xf3, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0xfa, 0x61, 0x72,
-0x3b, 0x66, 0x65, 0x62, 0x72, 0xfa, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b,
-0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, 0xed, 0x3b, 0x6a, 0xfa, 0x6c, 0xed, 0x3b, 0xe1, 0x67, 0xfa, 0x73, 0x74, 0x3b,
-0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0xf3,
-0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b,
-0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0xc1, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b,
-0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b,
-0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72,
-0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x72, 0x65, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69,
-0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53,
-0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76,
-0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x45, 0x61, 0x6e, 0x3b, 0x46,
-0x65, 0x61, 0x62, 0x68, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x3b,
-0x4d, 0x65, 0x69, 0x74, 0x68, 0x3b, 0x49, 0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x3b, 0x4d, 0x46, 0xf3, 0x6d, 0x68,
-0x3b, 0x44, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x3b, 0x45, 0x61, 0x6e,
-0xe1, 0x69, 0x72, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x72, 0x61, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69,
-0x62, 0x72, 0x65, 0xe1, 0x6e, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x74,
-0x68, 0x65, 0x61, 0x6d, 0x68, 0x3b, 0x49, 0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x61, 0x73, 0x61, 0x3b, 0x4d, 0x65,
-0xe1, 0x6e, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x44, 0x65, 0x69, 0x72, 0x65, 0x61, 0x64, 0x68, 0x20,
-0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c,
-0x61, 0x69, 0x67, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x4c, 0x3b,
-0x4d, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x67, 0x65, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b,
-0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x67, 0x3b, 0x67, 0x69, 0x75, 0x3b, 0x6c, 0x75, 0x67, 0x3b, 0x61, 0x67, 0x6f, 0x3b,
-0x73, 0x65, 0x74, 0x3b, 0x6f, 0x74, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x67, 0x65, 0x6e, 0x6e,
-0x61, 0x69, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61,
-0x70, 0x72, 0x69, 0x6c, 0x65, 0x3b, 0x6d, 0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x67, 0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b,
-0x6c, 0x75, 0x67, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x65, 0x6d,
-0x62, 0x72, 0x65, 0x3b, 0x6f, 0x74, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65,
-0x3b, 0x64, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x47, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b,
-0x47, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xc9c, 0xca8, 0x3b, 0xcab, 0xcc6, 0xcac,
-0xccd, 0xcb0, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c,
+0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91,
+0xa95, 0xacd, 0xa9f, 0xacb, 0x3b, 0xaa8, 0xab5, 0xac7, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1,
+0xa86, 0xab0, 0xac0, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b,
+0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b,
+0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f,
+0xacb, 0xaac, 0xab0, 0x3b, 0xaa8, 0xab5, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0,
+0x3b, 0xa9c, 0xabe, 0x3b, 0xaab, 0xac7, 0x3b, 0xaae, 0xabe, 0x3b, 0xa8f, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0x3b, 0xa9c, 0xac1,
+0x3b, 0xa91, 0x3b, 0xab8, 0x3b, 0xa91, 0x3b, 0xaa8, 0x3b, 0xaa1, 0xabf, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x61, 0x62, 0x3b,
+0x4d, 0x61, 0x72, 0x3b, 0x41, 0x66, 0x69, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b,
+0x41, 0x67, 0x75, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x75, 0x77, 0x3b, 0x44, 0x69, 0x73, 0x3b,
+0x4a, 0x61, 0x6e, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x46, 0x61, 0x62, 0x75, 0x72, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x4d, 0x61,
+0x72, 0x69, 0x73, 0x3b, 0x41, 0x66, 0x69, 0x72, 0x69, 0x6c, 0x75, 0x3b, 0x4d, 0x61, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e,
+0x69, 0x3b, 0x59, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x53, 0x61, 0x74, 0x75, 0x6d, 0x62,
+0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x75, 0x77, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73,
+0x61, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x41,
+0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5f3, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5f3, 0x3b, 0x5de,
+0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5f3, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc,
+0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5f3, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5f3, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5f3, 0x3b, 0x5e0, 0x5d5, 0x5d1,
+0x5f3, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5f3, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5d5, 0x5d0, 0x5e8, 0x3b,
+0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9,
+0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d0, 0x5d5,
+0x5e7, 0x5d8, 0x5d5, 0x5d1, 0x5e8, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x91c,
+0x928, 0x970, 0x3b, 0x92b, 0x93c, 0x930, 0x970, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932,
+0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x970, 0x3b, 0x905, 0x917, 0x970, 0x3b, 0x938, 0x93f, 0x924,
+0x970, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942, 0x970, 0x3b, 0x928, 0x935, 0x970, 0x3b, 0x926, 0x93f, 0x938, 0x970, 0x3b, 0x91c, 0x928,
+0x935, 0x930, 0x940, 0x3b, 0x92b, 0x93c, 0x930, 0x935, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d,
+0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938,
+0x94d, 0x924, 0x3b, 0x938, 0x93f, 0x924, 0x902, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942, 0x92c, 0x930, 0x3b, 0x928, 0x935,
+0x902, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x93c, 0x3b, 0x92e, 0x93e, 0x3b, 0x905,
+0x3b, 0x92e, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, 0x905, 0x3b, 0x938, 0x93f, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f,
+0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x2e, 0x3b, 0xe1, 0x70,
+0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x6a, 0x2e, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0x61, 0x75,
+0x67, 0x2e, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b,
+0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b,
+0x6d, 0xe1, 0x72, 0x63, 0x69, 0x75, 0x73, 0x3b, 0xe1, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0xe1, 0x6a, 0x75,
+0x73, 0x3b, 0x6a, 0xfa, 0x6e, 0x69, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6c, 0x69, 0x75, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75,
+0x73, 0x7a, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74,
+0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0xc1, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53,
+0x7a, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61,
+0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c,
+0x2e, 0x3b, 0xe1, 0x67, 0xfa, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0xf3, 0x76,
+0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0xfa, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0xfa, 0x61,
+0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e,
+0xed, 0x3b, 0x6a, 0xfa, 0x6c, 0xed, 0x3b, 0xe1, 0x67, 0xfa, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0xf3, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a,
+0x3b, 0x4a, 0x3b, 0xc1, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62,
+0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c,
+0x3b, 0x41, 0x67, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73,
+0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61,
+0x72, 0x65, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a,
+0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65,
+0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44,
+0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x45, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x3b, 0x4d, 0xe1,
+0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x3b, 0x49,
+0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x3b, 0x4d, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x44, 0x46, 0xf3, 0x6d, 0x68, 0x3b,
+0x53, 0x61, 0x6d, 0x68, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x3b, 0x45, 0x61, 0x6e, 0xe1, 0x69, 0x72, 0x3b, 0x46, 0x65, 0x61,
+0x62, 0x68, 0x72, 0x61, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x72, 0x65, 0xe1, 0x6e, 0x3b, 0x42,
+0x65, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x65, 0x61, 0x6d, 0x68, 0x3b, 0x49,
+0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x61, 0x73, 0x61, 0x3b, 0x4d, 0x65, 0xe1, 0x6e, 0x20, 0x46, 0xf3, 0x6d, 0x68,
+0x61, 0x69, 0x72, 0x3b, 0x44, 0x65, 0x69, 0x72, 0x65, 0x61, 0x64, 0x68, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72,
+0x3b, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x61, 0x69, 0x67, 0x3b, 0x45, 0x3b, 0x46,
+0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x4e,
+0x3b, 0x67, 0x65, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x67,
+0x3b, 0x67, 0x69, 0x75, 0x3b, 0x6c, 0x75, 0x67, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x74, 0x74,
+0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x67, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f, 0x3b, 0x66, 0x65, 0x62,
+0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x65, 0x3b, 0x6d,
+0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x67, 0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b, 0x6c, 0x75, 0x67, 0x6c, 0x69, 0x6f, 0x3b,
+0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x74, 0x74,
+0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x65, 0x6d, 0x62,
+0x72, 0x65, 0x3b, 0x47, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53,
+0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xc9c, 0xca8, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd,
+0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2,
+0xcc8, 0x3b, 0xc86, 0xc97, 0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0x3b, 0xca8,
+0xcb5, 0xcc6, 0xc82, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd,
+0xcb0, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0xcb2, 0xccd, 0x3b,
+0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, 0xc97, 0xcb8, 0xccd, 0xc9f, 0xccd, 0x3b,
+0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0xcac, 0xcb0, 0xccd, 0x3b,
+0xca8, 0xcb5, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc9c, 0x3b, 0xcab,
+0xcc6, 0x3b, 0xcae, 0xcbe, 0x3b, 0xc8f, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0x3b, 0xc9c, 0xcc1, 0x3b, 0xc86, 0x3b, 0xcb8, 0xcc6,
+0x3b, 0xc85, 0x3b, 0xca8, 0x3b, 0xca1, 0xcbf, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcb5,
+0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c,
0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, 0xc97, 0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0x3b,
-0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0x3b, 0xc9c, 0xca8, 0xcb5,
-0xcb0, 0xcbf, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f,
-0xcaa, 0xccd, 0xcb0, 0xcbf, 0xcb2, 0xccd, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b,
-0xc86, 0xc97, 0xcb8, 0xccd, 0xc9f, 0xccd, 0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc85, 0xc95,
-0xccd, 0xc9f, 0xccb, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82,
-0xcac, 0xcb0, 0xccd, 0x3b, 0xc9c, 0x3b, 0xcab, 0xcc6, 0x3b, 0xcae, 0xcbe, 0x3b, 0xc8f, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0x3b,
-0xc9c, 0xcc1, 0x3b, 0xc86, 0x3b, 0xcb8, 0xcc6, 0x3b, 0xc85, 0x3b, 0xca8, 0x3b, 0xca1, 0xcbf, 0x3b, 0x62c, 0x646, 0x624, 0x631, 0x6cc,
-0x3b, 0x641, 0x631, 0x624, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x655, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645,
-0x6cc, 0x654, 0x3b, 0x62c, 0x648, 0x657, 0x646, 0x3b, 0x62c, 0x648, 0x657, 0x644, 0x627, 0x6cc, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a,
-0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x657, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631,
-0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c,
-0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x49a, 0x430, 0x4a3, 0x2e, 0x3b, 0x410, 0x49b, 0x43f, 0x2e,
-0x3b, 0x41d, 0x430, 0x443, 0x2e, 0x3b, 0x421, 0x4d9, 0x443, 0x2e, 0x3b, 0x41c, 0x430, 0x43c, 0x2e, 0x3b, 0x41c, 0x430, 0x443, 0x2e,
-0x3b, 0x428, 0x456, 0x43b, 0x2e, 0x3b, 0x422, 0x430, 0x43c, 0x2e, 0x3b, 0x49a, 0x44b, 0x440, 0x2e, 0x3b, 0x49a, 0x430, 0x437, 0x2e,
-0x3b, 0x49a, 0x430, 0x440, 0x2e, 0x3b, 0x416, 0x435, 0x43b, 0x2e, 0x3b, 0x49a, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x410, 0x49b,
-0x43f, 0x430, 0x43d, 0x3b, 0x41d, 0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b, 0x421, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x41c, 0x430, 0x43c,
-0x44b, 0x440, 0x3b, 0x41c, 0x430, 0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x428, 0x456, 0x43b, 0x434, 0x435, 0x3b, 0x422, 0x430, 0x43c, 0x44b,
-0x437, 0x3b, 0x49a, 0x44b, 0x440, 0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49a, 0x430, 0x440,
-0x430, 0x448, 0x430, 0x3b, 0x416, 0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441, 0x430, 0x43d, 0x3b, 0x49a, 0x3b, 0x410, 0x3b, 0x41d, 0x3b,
-0x421, 0x3b, 0x41c, 0x3b, 0x41c, 0x3b, 0x428, 0x3b, 0x422, 0x3b, 0x49a, 0x3b, 0x49a, 0x3b, 0x49a, 0x3b, 0x416, 0x3b, 0x49b, 0x430,
-0x4a3, 0x2e, 0x3b, 0x430, 0x49b, 0x43f, 0x2e, 0x3b, 0x43d, 0x430, 0x443, 0x2e, 0x3b, 0x441, 0x4d9, 0x443, 0x2e, 0x3b, 0x43c, 0x430,
-0x43c, 0x2e, 0x3b, 0x43c, 0x430, 0x443, 0x2e, 0x3b, 0x448, 0x456, 0x43b, 0x2e, 0x3b, 0x442, 0x430, 0x43c, 0x2e, 0x3b, 0x49b, 0x44b,
-0x440, 0x2e, 0x3b, 0x49b, 0x430, 0x437, 0x2e, 0x3b, 0x49b, 0x430, 0x440, 0x2e, 0x3b, 0x436, 0x435, 0x43b, 0x2e, 0x3b, 0x49b, 0x430,
-0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x430, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x43d, 0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b, 0x441, 0x4d9,
-0x443, 0x456, 0x440, 0x3b, 0x43c, 0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x43c, 0x430, 0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x448, 0x456, 0x43b,
-0x434, 0x435, 0x3b, 0x442, 0x430, 0x43c, 0x44b, 0x437, 0x3b, 0x49b, 0x44b, 0x440, 0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b, 0x49b, 0x430,
-0x437, 0x430, 0x43d, 0x3b, 0x49b, 0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x436, 0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441, 0x430, 0x43d,
-0x3b, 0x6d, 0x75, 0x74, 0x2e, 0x3b, 0x67, 0x61, 0x73, 0x2e, 0x3b, 0x77, 0x65, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x2e,
-0x3b, 0x67, 0x69, 0x63, 0x2e, 0x3b, 0x6b, 0x61, 0x6d, 0x2e, 0x3b, 0x6e, 0x79, 0x61, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e,
-0x3b, 0x6e, 0x7a, 0x65, 0x2e, 0x3b, 0x75, 0x6b, 0x77, 0x2e, 0x3b, 0x75, 0x67, 0x75, 0x2e, 0x3b, 0x75, 0x6b, 0x75, 0x2e,
-0x3b, 0x4d, 0x75, 0x74, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0x47, 0x61, 0x73, 0x68, 0x79, 0x61, 0x6e, 0x74, 0x61, 0x72,
-0x65, 0x3b, 0x57, 0x65, 0x72, 0x75, 0x72, 0x77, 0x65, 0x3b, 0x4d, 0x61, 0x74, 0x61, 0x3b, 0x47, 0x69, 0x63, 0x75, 0x72,
-0x61, 0x6e, 0x73, 0x69, 0x3b, 0x4b, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61,
-0x3b, 0x4b, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x3b, 0x4e, 0x7a, 0x65, 0x6c, 0x69, 0x3b, 0x55, 0x6b, 0x77, 0x61, 0x6b, 0x69,
-0x72, 0x61, 0x3b, 0x55, 0x67, 0x75, 0x73, 0x68, 0x79, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x55, 0x6b, 0x75, 0x62, 0x6f, 0x7a,
-0x61, 0x3b, 0x42f, 0x43d, 0x432, 0x3b, 0x424, 0x435, 0x432, 0x3b, 0x41c, 0x430, 0x440, 0x3b, 0x410, 0x43f, 0x440, 0x3b, 0x41c, 0x430,
-0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x3b, 0x421, 0x435, 0x43d, 0x3b, 0x41e, 0x43a,
-0x442, 0x3b, 0x41d, 0x43e, 0x44f, 0x3b, 0x414, 0x435, 0x43a, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432,
-0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439,
+0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0x3b, 0x62c, 0x646, 0x624,
+0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x624, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x655, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644,
+0x3b, 0x645, 0x6cc, 0x654, 0x3b, 0x62c, 0x648, 0x657, 0x646, 0x3b, 0x62c, 0x648, 0x657, 0x644, 0x627, 0x6cc, 0x6cc, 0x3b, 0x627, 0x6af,
+0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x657, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645,
+0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c,
+0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x49a, 0x430, 0x4a3, 0x2e, 0x3b, 0x410, 0x49b,
+0x43f, 0x2e, 0x3b, 0x41d, 0x430, 0x443, 0x2e, 0x3b, 0x421, 0x4d9, 0x443, 0x2e, 0x3b, 0x41c, 0x430, 0x43c, 0x2e, 0x3b, 0x41c, 0x430,
+0x443, 0x2e, 0x3b, 0x428, 0x456, 0x43b, 0x2e, 0x3b, 0x422, 0x430, 0x43c, 0x2e, 0x3b, 0x49a, 0x44b, 0x440, 0x2e, 0x3b, 0x49a, 0x430,
+0x437, 0x2e, 0x3b, 0x49a, 0x430, 0x440, 0x2e, 0x3b, 0x416, 0x435, 0x43b, 0x2e, 0x3b, 0x49a, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b,
+0x410, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x41d, 0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b, 0x421, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x41c,
+0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x41c, 0x430, 0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x428, 0x456, 0x43b, 0x434, 0x435, 0x3b, 0x422, 0x430,
+0x43c, 0x44b, 0x437, 0x3b, 0x49a, 0x44b, 0x440, 0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49a,
+0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x416, 0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441, 0x430, 0x43d, 0x3b, 0x49a, 0x3b, 0x410, 0x3b,
+0x41d, 0x3b, 0x421, 0x3b, 0x41c, 0x3b, 0x41c, 0x3b, 0x428, 0x3b, 0x422, 0x3b, 0x49a, 0x3b, 0x49a, 0x3b, 0x49a, 0x3b, 0x416, 0x3b,
+0x49b, 0x430, 0x4a3, 0x2e, 0x3b, 0x430, 0x49b, 0x43f, 0x2e, 0x3b, 0x43d, 0x430, 0x443, 0x2e, 0x3b, 0x441, 0x4d9, 0x443, 0x2e, 0x3b,
+0x43c, 0x430, 0x43c, 0x2e, 0x3b, 0x43c, 0x430, 0x443, 0x2e, 0x3b, 0x448, 0x456, 0x43b, 0x2e, 0x3b, 0x442, 0x430, 0x43c, 0x2e, 0x3b,
+0x49b, 0x44b, 0x440, 0x2e, 0x3b, 0x49b, 0x430, 0x437, 0x2e, 0x3b, 0x49b, 0x430, 0x440, 0x2e, 0x3b, 0x436, 0x435, 0x43b, 0x2e, 0x3b,
+0x49b, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x430, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x43d, 0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b,
+0x441, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x43c, 0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x43c, 0x430, 0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x448,
+0x456, 0x43b, 0x434, 0x435, 0x3b, 0x442, 0x430, 0x43c, 0x44b, 0x437, 0x3b, 0x49b, 0x44b, 0x440, 0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b,
+0x49b, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49b, 0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x436, 0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441,
+0x430, 0x43d, 0x3b, 0x6d, 0x75, 0x74, 0x2e, 0x3b, 0x67, 0x61, 0x73, 0x2e, 0x3b, 0x77, 0x65, 0x72, 0x2e, 0x3b, 0x6d, 0x61,
+0x74, 0x2e, 0x3b, 0x67, 0x69, 0x63, 0x2e, 0x3b, 0x6b, 0x61, 0x6d, 0x2e, 0x3b, 0x6e, 0x79, 0x61, 0x2e, 0x3b, 0x6b, 0x61,
+0x6e, 0x2e, 0x3b, 0x6e, 0x7a, 0x65, 0x2e, 0x3b, 0x75, 0x6b, 0x77, 0x2e, 0x3b, 0x75, 0x67, 0x75, 0x2e, 0x3b, 0x75, 0x6b,
+0x75, 0x2e, 0x3b, 0x4d, 0x75, 0x74, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0x47, 0x61, 0x73, 0x68, 0x79, 0x61, 0x6e, 0x74,
+0x61, 0x72, 0x65, 0x3b, 0x57, 0x65, 0x72, 0x75, 0x72, 0x77, 0x65, 0x3b, 0x4d, 0x61, 0x74, 0x61, 0x3b, 0x47, 0x69, 0x63,
+0x75, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x3b, 0x4b, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e,
+0x67, 0x61, 0x3b, 0x4b, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x3b, 0x4e, 0x7a, 0x65, 0x6c, 0x69, 0x3b, 0x55, 0x6b, 0x77, 0x61,
+0x6b, 0x69, 0x72, 0x61, 0x3b, 0x55, 0x67, 0x75, 0x73, 0x68, 0x79, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x55, 0x6b, 0x75, 0x62,
+0x6f, 0x7a, 0x61, 0x3b, 0x42f, 0x43d, 0x432, 0x3b, 0x424, 0x435, 0x432, 0x3b, 0x41c, 0x430, 0x440, 0x3b, 0x410, 0x43f, 0x440, 0x3b,
+0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x3b, 0x421, 0x435, 0x43d, 0x3b,
+0x41e, 0x43a, 0x442, 0x3b, 0x41d, 0x43e, 0x44f, 0x3b, 0x414, 0x435, 0x43a, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424,
+0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c,
+0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b,
+0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f,
+0x431, 0x440, 0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x42f, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x3b,
+0x41c, 0x3b, 0x418, 0x3b, 0x418, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x41e, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x44f, 0x43d, 0x432, 0x2e,
+0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b,
+0x438, 0x44e, 0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b,
+0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440,
+0x44c, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b,
+0x44c, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443,
+0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b,
+0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x31, 0xc6d4, 0x3b, 0x32, 0xc6d4,
+0x3b, 0x33, 0xc6d4, 0x3b, 0x34, 0xc6d4, 0x3b, 0x35, 0xc6d4, 0x3b, 0x36, 0xc6d4, 0x3b, 0x37, 0xc6d4, 0x3b, 0x38, 0xc6d4, 0x3b, 0x39,
+0xc6d4, 0x3b, 0x31, 0x30, 0xc6d4, 0x3b, 0x31, 0x31, 0xc6d4, 0x3b, 0x31, 0x32, 0xc6d4, 0x3b, 0x4d, 0x75, 0x74, 0x2e, 0x3b, 0x47,
+0x61, 0x73, 0x2e, 0x3b, 0x57, 0x65, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x74, 0x2e, 0x3b, 0x47, 0x69, 0x63, 0x2e, 0x3b, 0x4b,
+0x61, 0x6d, 0x2e, 0x3b, 0x4e, 0x79, 0x61, 0x2e, 0x3b, 0x4b, 0x61, 0x6e, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x2e, 0x3b, 0x55,
+0x6b, 0x77, 0x2e, 0x3b, 0x55, 0x67, 0x75, 0x2e, 0x3b, 0x55, 0x6b, 0x75, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x72, 0x6f, 0x3b,
+0x52, 0x75, 0x68, 0x75, 0x68, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x74, 0x77, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x3b, 0x4e,
+0x64, 0x61, 0x6d, 0x75, 0x6b, 0x69, 0x7a, 0x61, 0x3b, 0x52, 0x75, 0x73, 0x61, 0x6d, 0x61, 0x3b, 0x52, 0x75, 0x68, 0x65,
+0x73, 0x68, 0x69, 0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x6b, 0x61, 0x72, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6e, 0x64, 0x61, 0x67,
+0x61, 0x72, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x47, 0x69, 0x74, 0x75, 0x67, 0x75, 0x74,
+0x75, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x6f, 0x6e, 0x79, 0x6f, 0x3b, 0x4b, 0x69, 0x67, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b,
+0xea1, 0x2e, 0xe81, 0x2e, 0x3b, 0xe81, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0x2e, 0xe99, 0x2e, 0x3b, 0xea1, 0x2e, 0xeaa, 0x2e, 0x3b,
+0xe9e, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0xeb4, 0x2e, 0xe96, 0x2e, 0x3b, 0xe81, 0x2e, 0xea5, 0x2e, 0x3b, 0xeaa, 0x2e, 0xeab, 0x2e,
+0x3b, 0xe81, 0x2e, 0xe8d, 0x2e, 0x3b, 0xe95, 0x2e, 0xea5, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe88, 0x2e, 0x3b, 0xe97, 0x2e, 0xea7, 0x2e,
+0x3b, 0xea1, 0xeb1, 0xe87, 0xe81, 0xead, 0xe99, 0x3b, 0xe81, 0xeb8, 0xea1, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb5, 0xe99, 0xeb2, 0x3b, 0xec0,
+0xea1, 0xeaa, 0xeb2, 0x3b, 0xe9e, 0xeb6, 0xe94, 0xeaa, 0xeb0, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb4, 0xe96, 0xeb8, 0xe99, 0xeb2, 0x3b, 0xe81,
+0xecd, 0xea5, 0xeb0, 0xe81, 0xebb, 0xe94, 0x3b, 0xeaa, 0xeb4, 0xe87, 0xeab, 0xeb2, 0x3b, 0xe81, 0xeb1, 0xe99, 0xe8d, 0xeb2, 0x3b, 0xe95,
+0xeb8, 0xea5, 0xeb2, 0x3b, 0xe9e, 0xeb0, 0xe88, 0xeb4, 0xe81, 0x3b, 0xe97, 0xeb1, 0xe99, 0xea7, 0xeb2, 0x3b, 0x6a, 0x61, 0x6e, 0x76,
+0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d,
+0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x2e, 0x3b, 0x6a, 0x16b, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b,
+0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e,
+0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x101, 0x72, 0x69, 0x73, 0x3b,
+0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x12b, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b,
+0x6a, 0x16b, 0x6e, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6c, 0x69, 0x6a, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74,
+0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x69,
+0x73, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69,
+0x73, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x6c, 0x3b, 0x6d, 0x61,
+0x69, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x74, 0x3b, 0x73, 0x74, 0x62, 0x3b, 0x254, 0x74,
+0x62, 0x3b, 0x6e, 0x76, 0x62, 0x3b, 0x64, 0x73, 0x62, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x79,
+0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9,
+0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x73, 0xe1, 0x6e,
+0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0x65, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61,
+0x20, 0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x6f, 0x74,
+0xf3, 0x62, 0xe1, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6e, 0x73, 0x61, 0x6d, 0x62, 0x6f, 0x3b,
+0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x77, 0x61, 0x6d, 0x62, 0x65, 0x3b, 0x73, 0xe1, 0x6e, 0x7a,
+0xe1, 0x20, 0x79, 0x61, 0x20, 0x6c, 0x69, 0x62, 0x77, 0x61, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20,
+0x7a, 0xf3, 0x6d, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e,
+0x61, 0x20, 0x6d, 0x254, 0x30c, 0x6b, 0x254, 0x301, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3,
+0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x79, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61,
+0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x254, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x73, 0x61, 0x75,
+0x73, 0x2e, 0x3b, 0x76, 0x61, 0x73, 0x2e, 0x3b, 0x6b, 0x6f, 0x76, 0x2e, 0x3b, 0x62, 0x61, 0x6c, 0x2e, 0x3b, 0x67, 0x65,
+0x67, 0x2e, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x2e, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x2e, 0x3b, 0x72, 0x75, 0x67, 0x70, 0x2e,
+0x3b, 0x72, 0x75, 0x67, 0x73, 0x2e, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x2e, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x2e, 0x3b,
+0x67, 0x72, 0x75, 0x6f, 0x64, 0x2e, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x73, 0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69,
+0x73, 0x3b, 0x6b, 0x6f, 0x76, 0x61, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x3b, 0x67, 0x65, 0x67,
+0x75, 0x17e, 0x117, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x61, 0x3b, 0x72,
+0x75, 0x67, 0x70, 0x6a, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x69, 0x73, 0x3b, 0x73, 0x70,
+0x61, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x74, 0x69, 0x73, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64,
+0x69, 0x73, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x47, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x52, 0x3b, 0x52,
+0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x47, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69,
+0x6f, 0x3b, 0x6b, 0x6f, 0x76, 0x6f, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x17e, 0x69, 0x6f, 0x3b, 0x67, 0x65, 0x67,
+0x75, 0x17e, 0x117, 0x73, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x6f, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x6f, 0x73,
+0x3b, 0x72, 0x75, 0x67, 0x70, 0x6a, 0x16b, 0x10d, 0x69, 0x6f, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x6f, 0x3b, 0x73,
+0x70, 0x61, 0x6c, 0x69, 0x6f, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x10d, 0x69, 0x6f, 0x3b, 0x67, 0x72, 0x75, 0x6f,
+0x64, 0x17e, 0x69, 0x6f, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b,
+0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x2e, 0x3b, 0x458, 0x443, 0x43b, 0x2e, 0x3b, 0x430,
+0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x2e,
+0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430,
+0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443,
+0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435,
+0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440,
+0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x458, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c,
+0x3b, 0x458, 0x3b, 0x458, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46,
+0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x3b, 0x4a,
+0x6f, 0x6c, 0x3b, 0x41, 0x6f, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44,
+0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6f, 0x61, 0x72, 0x79, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x6f, 0x61, 0x72, 0x79, 0x3b,
+0x4d, 0x61, 0x72, 0x74, 0x73, 0x61, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f,
+0x6e, 0x61, 0x3b, 0x4a, 0x6f, 0x6c, 0x61, 0x79, 0x3b, 0x41, 0x6f, 0x67, 0x6f, 0x73, 0x69, 0x74, 0x72, 0x61, 0x3b, 0x53,
+0x65, 0x70, 0x74, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x4e, 0x6f, 0x76,
+0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46,
+0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a,
+0x75, 0x6c, 0x3b, 0x4f, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44,
+0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b,
+0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75,
+0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f,
+0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f,
+0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xd1c, 0xd28, 0xd41, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0x3b,
+0xd2e, 0xd3e, 0xd7c, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c,
+0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0x3b, 0xd12, 0xd15, 0xd4d, 0xd1f,
+0xd4b, 0x3b, 0xd28, 0xd35, 0xd02, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0x3b, 0xd1c, 0xd28, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2b, 0xd46,
+0xd2c, 0xd4d, 0xd30, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd3e, 0xd7c, 0xd1a, 0xd4d, 0xd1a, 0xd4d, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30,
+0xd3f, 0xd7d, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0xd38,
+0xd4d, 0xd31, 0xd4d, 0xd31, 0xd4d, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd12, 0xd15, 0xd4d,
+0x200c, 0xd1f, 0xd4b, 0xd2c, 0xd7c, 0x3b, 0xd28, 0xd35, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd1c,
+0x3b, 0xd2b, 0xd46, 0x3b, 0xd2e, 0xd3e, 0x3b, 0xd0f, 0x3b, 0xd2e, 0xd46, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd13,
+0x3b, 0xd38, 0xd46, 0x3b, 0xd12, 0x3b, 0xd28, 0x3b, 0xd21, 0xd3f, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x72, 0x61, 0x3b, 0x4d,
+0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x6a, 0x3b, 0x120, 0x75, 0x6e, 0x3b, 0x4c, 0x75, 0x6c, 0x3b, 0x41,
+0x77, 0x77, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x10b, 0x3b, 0x4a,
+0x61, 0x6e, 0x6e, 0x61, 0x72, 0x3b, 0x46, 0x72, 0x61, 0x72, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x41, 0x70, 0x72,
+0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x6a, 0x6a, 0x75, 0x3b, 0x120, 0x75, 0x6e, 0x6a, 0x75, 0x3b, 0x4c, 0x75, 0x6c, 0x6a, 0x75,
+0x3b, 0x41, 0x77, 0x77, 0x69, 0x73, 0x73, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4f,
+0x74, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x10b, 0x65,
+0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x6e, 0x3b, 0x46, 0x72, 0x3b, 0x4d, 0x7a, 0x3b, 0x41, 0x70, 0x3b, 0x4d, 0x6a, 0x3b,
+0x120, 0x6e, 0x3b, 0x4c, 0x6a, 0x3b, 0x41, 0x77, 0x3b, 0x53, 0x74, 0x3b, 0x4f, 0x62, 0x3b, 0x4e, 0x76, 0x3b, 0x44, 0x10b,
+0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x120, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f,
+0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x3b, 0x92e, 0x93e, 0x930,
+0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948,
+0x3b, 0x911, 0x917, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x935,
+0x94d, 0x939, 0x947, 0x902, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b,
+0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d,
+0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x911, 0x917, 0x938, 0x94d,
+0x91f, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928,
+0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x93e, 0x3b,
+0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, 0x911, 0x3b, 0x938,
+0x3b, 0x911, 0x3b, 0x928, 0x94b, 0x3b, 0x921, 0x93f, 0x3b, 0x31, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x32, 0x2d, 0x440,
+0x20, 0x441, 0x430, 0x440, 0x3b, 0x33, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x34, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440,
+0x3b, 0x35, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x36, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x37, 0x2d, 0x440,
+0x20, 0x441, 0x430, 0x440, 0x3b, 0x38, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x39, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440,
+0x3b, 0x31, 0x30, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, 0x31, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31,
+0x32, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x41d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430,
+0x440, 0x3b, 0x425, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x413, 0x443, 0x440,
+0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x414, 0x4e9, 0x440, 0x4e9, 0x432, 0x434, 0x4af,
+0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x422, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441,
+0x430, 0x440, 0x3b, 0x417, 0x443, 0x440, 0x433, 0x430, 0x430, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b,
+0x414, 0x43e, 0x43b, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x41d, 0x430, 0x439, 0x43c, 0x434, 0x443,
+0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x415, 0x441, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430,
+0x440, 0x3b, 0x410, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x432,
+0x430, 0x43d, 0x20, 0x43d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x432,
+0x430, 0x43d, 0x20, 0x445, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x49, 0x3b,
+0x49, 0x49, 0x3b, 0x49, 0x49, 0x49, 0x3b, 0x49, 0x56, 0x3b, 0x56, 0x3b, 0x56, 0x49, 0x3b, 0x56, 0x49, 0x49, 0x3b, 0x56,
+0x49, 0x49, 0x49, 0x3b, 0x49, 0x58, 0x3b, 0x58, 0x3b, 0x58, 0x49, 0x3b, 0x58, 0x49, 0x49, 0x3b, 0x91c, 0x928, 0x935, 0x930,
+0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x905, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a,
+0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917,
+0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b,
+0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x92e, 0x94d, 0x92c, 0x930,
+0x3b, 0x91c, 0x928, 0x3b, 0x92b, 0x947, 0x947, 0x92c, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x3b,
+0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x3b, 0x905, 0x917, 0x3b, 0x938, 0x947, 0x92a, 0x3b, 0x905, 0x915,
+0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x3b, 0x91c, 0x928, 0x3b, 0x92b, 0x947, 0x92c,
+0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c,
+0x941, 0x932, 0x3b, 0x905, 0x917, 0x3b, 0x938, 0x947, 0x92a, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x92d, 0x947,
+0x3b, 0x921, 0x93f, 0x938, 0x947, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72,
+0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69,
+0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xb1c, 0xb3e, 0xb28, 0xb41, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2b, 0xb47, 0xb2c,
+0xb43, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2e, 0xb3e, 0xb30, 0xb4d, 0xb1a, 0xb4d, 0xb1a, 0x3b, 0xb05, 0xb2a, 0xb4d, 0xb30, 0xb47, 0xb32, 0x3b,
+0xb2e, 0xb07, 0x3b, 0xb1c, 0xb41, 0xb28, 0x3b, 0xb1c, 0xb41, 0xb32, 0xb3e, 0xb07, 0x3b, 0xb05, 0xb17, 0xb37, 0xb4d, 0xb1f, 0x3b, 0xb38,
+0xb47, 0xb2a, 0xb4d, 0xb1f, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb05, 0xb15, 0xb4d, 0xb1f, 0xb4b, 0xb2c, 0xb30, 0x3b, 0xb28, 0xb2d,
+0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb21, 0xb3f, 0xb38, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb1c, 0xb3e, 0x3b, 0xb2b, 0xb47,
+0x3b, 0xb2e, 0xb3e, 0x3b, 0xb05, 0x3b, 0xb2e, 0xb07, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb05, 0x3b, 0xb38, 0xb47, 0x3b,
+0xb05, 0x3b, 0xb28, 0x3b, 0xb21, 0xb3f, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b,
+0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cd, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648,
+0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648,
+0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a,
+0x3b, 0x641, 0x6d0, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b,
+0x645, 0x6cd, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e,
+0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633,
+0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631,
+0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cd, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc,
+0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x6d0, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631,
+0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627,
+0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x698, 0x627, 0x646,
+0x648, 0x6cc, 0x647, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644,
+0x3b, 0x645, 0x647, 0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633,
+0x67e, 0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b,
+0x62f, 0x633, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x622, 0x3b, 0x645, 0x3b, 0x698, 0x3b, 0x698,
+0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x654, 0x3b, 0x641,
+0x648, 0x631, 0x6cc, 0x647, 0x654, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x654,
+0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x654, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a,
+0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633,
+0x627, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627,
+0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627,
+0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631,
+0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x628, 0x631,
+0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648,
+0x646, 0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9,
+0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x73, 0x74, 0x79, 0x3b, 0x6c,
+0x75, 0x74, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6b, 0x77, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x3b, 0x6c,
+0x69, 0x70, 0x3b, 0x73, 0x69, 0x65, 0x3b, 0x77, 0x72, 0x7a, 0x3b, 0x70, 0x61, 0x17a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x67,
+0x72, 0x75, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x65, 0x144, 0x3b, 0x6c, 0x75, 0x74, 0x79, 0x3b, 0x6d, 0x61, 0x72, 0x7a,
+0x65, 0x63, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x63, 0x69, 0x65, 0x144, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x72,
+0x77, 0x69, 0x65, 0x63, 0x3b, 0x6c, 0x69, 0x70, 0x69, 0x65, 0x63, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x69, 0x65, 0x144,
+0x3b, 0x77, 0x72, 0x7a, 0x65, 0x73, 0x69, 0x65, 0x144, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69,
+0x6b, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x7a, 0x69, 0x65, 0x144, 0x3b,
+0x53, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x57, 0x3b, 0x50, 0x3b,
+0x4c, 0x3b, 0x47, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x6e, 0x69, 0x61, 0x3b, 0x6c, 0x75, 0x74, 0x65, 0x67, 0x6f, 0x3b,
+0x6d, 0x61, 0x72, 0x63, 0x61, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x74, 0x6e, 0x69, 0x61, 0x3b, 0x6d, 0x61, 0x6a, 0x61, 0x3b,
+0x63, 0x7a, 0x65, 0x72, 0x77, 0x63, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x63, 0x61, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x6e,
+0x69, 0x61, 0x3b, 0x77, 0x72, 0x7a, 0x65, 0x15b, 0x6e, 0x69, 0x61, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72,
+0x6e, 0x69, 0x6b, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x6e,
+0x69, 0x61, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x63, 0x3b, 0x6c, 0x3b, 0x73, 0x3b, 0x77,
+0x3b, 0x70, 0x3b, 0x6c, 0x3b, 0x67, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61,
+0x62, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73,
+0x65, 0x74, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x7a, 0x3b, 0x6a, 0x61, 0x6e, 0x65, 0x69,
+0x72, 0x6f, 0x3b, 0x66, 0x65, 0x76, 0x65, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x61,
+0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x68,
+0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75,
+0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x7a, 0x65, 0x6d,
+0x62, 0x72, 0x6f, 0x3b, 0xa1c, 0xa28, 0x3b, 0xa2b, 0xa3c, 0xa30, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30,
+0xa48, 0x3b, 0xa2e, 0xa08, 0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0x3b, 0xa05, 0xa17, 0x3b, 0xa38, 0xa24, 0xa70,
+0x3b, 0xa05, 0xa15, 0xa24, 0xa42, 0x3b, 0xa28, 0xa35, 0xa70, 0x3b, 0xa26, 0xa38, 0xa70, 0x3b, 0xa1c, 0xa28, 0xa35, 0xa30, 0xa40, 0x3b,
+0xa2b, 0xa3c, 0xa30, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, 0xa48, 0xa32, 0x3b, 0xa2e,
+0xa08, 0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0xa08, 0x3b, 0xa05, 0xa17, 0xa38, 0xa24, 0x3b, 0xa38, 0xa24, 0xa70,
+0xa2c, 0xa30, 0x3b, 0xa05, 0xa15, 0xa24, 0xa42, 0xa2c, 0xa30, 0x3b, 0xa28, 0xa35, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa26, 0xa38, 0xa70, 0xa2c,
+0xa30, 0x3b, 0xa1c, 0x3b, 0xa2b, 0xa3c, 0x3b, 0xa2e, 0xa3e, 0x3b, 0xa05, 0x3b, 0xa2e, 0x3b, 0xa1c, 0xa42, 0x3b, 0xa1c, 0xa41, 0x3b,
+0xa05, 0x3b, 0xa38, 0x3b, 0xa05, 0x3b, 0xa28, 0x3b, 0xa26, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631,
+0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x3b, 0x62c, 0x648, 0x646, 0x3b,
+0x62c, 0x648, 0x644, 0x627, 0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9,
+0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x45, 0x6e, 0x65,
+0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6e,
+0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x63, 0x74, 0x3b, 0x4e, 0x6f, 0x76,
+0x3b, 0x44, 0x69, 0x63, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x4d,
+0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x69,
+0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x69, 0x65,
+0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62,
+0x72, 0x65, 0x3b, 0x44, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x2e, 0x3b,
+0x66, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x67,
+0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x2e, 0x3b, 0x66, 0x61, 0x6e, 0x2e, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73,
+0x65, 0x74, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b,
+0x73, 0x63, 0x68, 0x61, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x61, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b,
+0x61, 0x76, 0x72, 0x69, 0x67, 0x6c, 0x3b, 0x6d, 0x61, 0x74, 0x67, 0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x61, 0x64, 0x75,
+0x72, 0x3b, 0x66, 0x61, 0x6e, 0x61, 0x64, 0x75, 0x72, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x74,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b,
+0x4d, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x69, 0x61, 0x6e, 0x2e,
+0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b,
+0x69, 0x75, 0x6e, 0x2e, 0x3b, 0x69, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e,
+0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x69, 0x61, 0x6e, 0x75,
+0x61, 0x72, 0x69, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x69,
+0x65, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, 0x69, 0x65, 0x3b,
+0x69, 0x75, 0x6c, 0x69, 0x65, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x72, 0x69, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6e, 0x6f, 0x69, 0x65, 0x6d, 0x62,
+0x72, 0x69, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x4d, 0x3b,
+0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44f, 0x43d,
+0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c,
+0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435,
+0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b,
+0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e,
+0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b,
+0x441, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a,
+0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44f, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x440,
+0x442, 0x430, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438,
+0x44e, 0x43b, 0x44f, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44f,
+0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x434, 0x435, 0x43a, 0x430,
+0x431, 0x440, 0x44f, 0x3b, 0x4e, 0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x3b, 0x4d, 0x62, 0xe4, 0x3b, 0x4e, 0x67, 0x75, 0x3b,
+0x42, 0xea, 0x6c, 0x3b, 0x46, 0xf6, 0x6e, 0x3b, 0x4c, 0x65, 0x6e, 0x3b, 0x4b, 0xfc, 0x6b, 0x3b, 0x4d, 0x76, 0x75, 0x3b,
+0x4e, 0x67, 0x62, 0x3b, 0x4e, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6b, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x65, 0x3b, 0x46,
+0x75, 0x6c, 0x75, 0x6e, 0x64, 0xef, 0x67, 0x69, 0x3b, 0x4d, 0x62, 0xe4, 0x6e, 0x67, 0xfc, 0x3b, 0x4e, 0x67, 0x75, 0x62,
+0xf9, 0x65, 0x3b, 0x42, 0xea, 0x6c, 0xe4, 0x77, 0xfc, 0x3b, 0x46, 0xf6, 0x6e, 0x64, 0x6f, 0x3b, 0x4c, 0x65, 0x6e, 0x67,
+0x75, 0x61, 0x3b, 0x4b, 0xfc, 0x6b, 0xfc, 0x72, 0xfc, 0x3b, 0x4d, 0x76, 0x75, 0x6b, 0x61, 0x3b, 0x4e, 0x67, 0x62, 0x65,
+0x72, 0x65, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x62, 0xe4, 0x6e, 0x64, 0xfc, 0x72, 0x75, 0x3b, 0x4b, 0x61, 0x6b, 0x61, 0x75,
+0x6b, 0x61, 0x3b, 0x4e, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4d,
+0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430,
+0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441,
+0x435, 0x43f, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430,
+0x440, 0x3b, 0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b,
+0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b,
+0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e,
+0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x2e,
+0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b,
+0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f,
+0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72,
+0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b,
+0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73,
+0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76,
+0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d,
+0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x6a,
+0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a,
+0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e,
+0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x431, 0x2e, 0x3b, 0x43c, 0x430, 0x440,
+0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430,
+0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x432, 0x2e, 0x3b,
+0x434, 0x435, 0x446, 0x2e, 0x3b, 0x42f, 0x43d, 0x432, 0x2e, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x440, 0x442,
+0x2e, 0x3b, 0x410, 0x43f, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c,
+0x3b, 0x410, 0x432, 0x433, 0x2e, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x41e, 0x43a, 0x442, 0x2e, 0x3b, 0x41d, 0x43e, 0x44f,
+0x431, 0x2e, 0x3b, 0x414, 0x435, 0x43a, 0x2e, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430,
+0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439,
0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435,
0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440,
-0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x42f, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x3b, 0x41c, 0x3b,
-0x418, 0x3b, 0x418, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x41e, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444,
-0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e,
-0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a,
-0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b,
-0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b,
-0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442,
-0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43d, 0x43e,
-0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x31, 0xc6d4, 0x3b, 0x32, 0xc6d4, 0x3b, 0x33,
-0xc6d4, 0x3b, 0x34, 0xc6d4, 0x3b, 0x35, 0xc6d4, 0x3b, 0x36, 0xc6d4, 0x3b, 0x37, 0xc6d4, 0x3b, 0x38, 0xc6d4, 0x3b, 0x39, 0xc6d4, 0x3b,
-0x31, 0x30, 0xc6d4, 0x3b, 0x31, 0x31, 0xc6d4, 0x3b, 0x31, 0x32, 0xc6d4, 0x3b, 0x4d, 0x75, 0x74, 0x2e, 0x3b, 0x47, 0x61, 0x73,
-0x2e, 0x3b, 0x57, 0x65, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x74, 0x2e, 0x3b, 0x47, 0x69, 0x63, 0x2e, 0x3b, 0x4b, 0x61, 0x6d,
-0x2e, 0x3b, 0x4e, 0x79, 0x61, 0x2e, 0x3b, 0x4b, 0x61, 0x6e, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x2e, 0x3b, 0x55, 0x6b, 0x77,
-0x2e, 0x3b, 0x55, 0x67, 0x75, 0x2e, 0x3b, 0x55, 0x6b, 0x75, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x52, 0x75,
-0x68, 0x75, 0x68, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x74, 0x77, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x3b, 0x4e, 0x64, 0x61,
-0x6d, 0x75, 0x6b, 0x69, 0x7a, 0x61, 0x3b, 0x52, 0x75, 0x73, 0x61, 0x6d, 0x61, 0x3b, 0x52, 0x75, 0x68, 0x65, 0x73, 0x68,
-0x69, 0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x6b, 0x61, 0x72, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x61, 0x72,
-0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x47, 0x69, 0x74, 0x75, 0x67, 0x75, 0x74, 0x75, 0x3b,
-0x4d, 0x75, 0x6e, 0x79, 0x6f, 0x6e, 0x79, 0x6f, 0x3b, 0x4b, 0x69, 0x67, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0xea1, 0x2e,
-0xe81, 0x2e, 0x3b, 0xe81, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0x2e, 0xe99, 0x2e, 0x3b, 0xea1, 0x2e, 0xeaa, 0x2e, 0x3b, 0xe9e, 0x2e,
-0xe9e, 0x2e, 0x3b, 0xea1, 0xeb4, 0x2e, 0xe96, 0x2e, 0x3b, 0xe81, 0x2e, 0xea5, 0x2e, 0x3b, 0xeaa, 0x2e, 0xeab, 0x2e, 0x3b, 0xe81,
-0x2e, 0xe8d, 0x2e, 0x3b, 0xe95, 0x2e, 0xea5, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe88, 0x2e, 0x3b, 0xe97, 0x2e, 0xea7, 0x2e, 0x3b, 0xea1,
-0xeb1, 0xe87, 0xe81, 0xead, 0xe99, 0x3b, 0xe81, 0xeb8, 0xea1, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb5, 0xe99, 0xeb2, 0x3b, 0xec0, 0xea1, 0xeaa,
-0xeb2, 0x3b, 0xe9e, 0xeb6, 0xe94, 0xeaa, 0xeb0, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb4, 0xe96, 0xeb8, 0xe99, 0xeb2, 0x3b, 0xe81, 0xecd, 0xea5,
-0xeb0, 0xe81, 0xebb, 0xe94, 0x3b, 0xeaa, 0xeb4, 0xe87, 0xeab, 0xeb2, 0x3b, 0xe81, 0xeb1, 0xe99, 0xe8d, 0xeb2, 0x3b, 0xe95, 0xeb8, 0xea5,
-0xeb2, 0x3b, 0xe9e, 0xeb0, 0xe88, 0xeb4, 0xe81, 0x3b, 0xe97, 0xeb1, 0xe99, 0xea7, 0xeb2, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b,
-0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69,
-0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x2e, 0x3b, 0x6a, 0x16b, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65,
-0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a,
-0x61, 0x6e, 0x76, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x6d, 0x61,
-0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x12b, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b,
-0x6e, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6c, 0x69, 0x6a, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x73, 0x3b,
-0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x69, 0x73, 0x3b,
-0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b,
-0x79, 0x61, 0x6e, 0x3b, 0x66, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b,
-0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x74, 0x3b, 0x73, 0x74, 0x62, 0x3b, 0x254, 0x74, 0x62, 0x3b,
-0x6e, 0x76, 0x62, 0x3b, 0x64, 0x73, 0x62, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x79, 0x61, 0x6d,
-0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x73,
-0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1,
-0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0x65, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d,
-0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x6f, 0x74, 0xf3, 0x62,
-0xe1, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6e, 0x73, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1,
-0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x77, 0x61, 0x6d, 0x62, 0x65, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20,
-0x79, 0x61, 0x20, 0x6c, 0x69, 0x62, 0x77, 0x61, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3,
-0x6d, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20,
-0x6d, 0x254, 0x30c, 0x6b, 0x254, 0x301, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69,
-0x20, 0x6e, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x79, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d,
-0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x254, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x2e,
-0x3b, 0x76, 0x61, 0x73, 0x2e, 0x3b, 0x6b, 0x6f, 0x76, 0x2e, 0x3b, 0x62, 0x61, 0x6c, 0x2e, 0x3b, 0x67, 0x65, 0x67, 0x2e,
-0x3b, 0x62, 0x69, 0x72, 0x17e, 0x2e, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x2e, 0x3b, 0x72, 0x75, 0x67, 0x70, 0x2e, 0x3b, 0x72,
-0x75, 0x67, 0x73, 0x2e, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x2e, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x2e, 0x3b, 0x67, 0x72,
-0x75, 0x6f, 0x64, 0x2e, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x73, 0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69, 0x73, 0x3b,
-0x6b, 0x6f, 0x76, 0x61, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x3b, 0x67, 0x65, 0x67, 0x75, 0x17e,
-0x117, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x61, 0x3b, 0x72, 0x75, 0x67,
-0x70, 0x6a, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x69, 0x73, 0x3b, 0x73, 0x70, 0x61, 0x6c,
-0x69, 0x73, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x74, 0x69, 0x73, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x69, 0x73,
-0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x47, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x52, 0x3b, 0x52, 0x3b, 0x53,
-0x3b, 0x4c, 0x3b, 0x47, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69, 0x6f, 0x3b,
-0x6b, 0x6f, 0x76, 0x6f, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x17e, 0x69, 0x6f, 0x3b, 0x67, 0x65, 0x67, 0x75, 0x17e,
-0x117, 0x73, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x6f, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x6f, 0x73, 0x3b, 0x72,
-0x75, 0x67, 0x70, 0x6a, 0x16b, 0x10d, 0x69, 0x6f, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x6f, 0x3b, 0x73, 0x70, 0x61,
-0x6c, 0x69, 0x6f, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x10d, 0x69, 0x6f, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x17e,
-0x69, 0x6f, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f,
-0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x2e, 0x3b, 0x458, 0x443, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433,
-0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x2e, 0x3b, 0x434,
-0x435, 0x43a, 0x2e, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438,
-0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438,
-0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432,
-0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b,
-0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x458, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x458,
-0x3b, 0x458, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62,
-0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x3b, 0x4a, 0x6f, 0x6c,
-0x3b, 0x41, 0x6f, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73,
-0x3b, 0x4a, 0x61, 0x6e, 0x6f, 0x61, 0x72, 0x79, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x6f, 0x61, 0x72, 0x79, 0x3b, 0x4d, 0x61,
-0x72, 0x74, 0x73, 0x61, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x61,
-0x3b, 0x4a, 0x6f, 0x6c, 0x61, 0x79, 0x3b, 0x41, 0x6f, 0x67, 0x6f, 0x73, 0x69, 0x74, 0x72, 0x61, 0x3b, 0x53, 0x65, 0x70,
-0x74, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x61, 0x6d,
-0x62, 0x72, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62,
-0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c,
-0x3b, 0x4f, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73,
-0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61,
-0x63, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61,
-0x69, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74,
-0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62,
-0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53,
-0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xd1c, 0xd28, 0xd41, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0x3b, 0xd2e, 0xd3e,
-0xd7c, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32,
-0xd48, 0x3b, 0xd13, 0xd17, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0x3b, 0xd12, 0xd15, 0xd4d, 0xd1f, 0xd4b, 0x3b,
-0xd28, 0xd35, 0xd02, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0x3b, 0xd1c, 0xd28, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d,
-0xd30, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd3e, 0xd7c, 0xd1a, 0xd4d, 0xd1a, 0xd4d, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0xd7d,
-0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0xd38, 0xd4d, 0xd31,
-0xd4d, 0xd31, 0xd4d, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd12, 0xd15, 0xd4d, 0x200c, 0xd1f,
-0xd4b, 0xd2c, 0xd7c, 0x3b, 0xd28, 0xd35, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd1c, 0x3b, 0xd2b,
-0xd46, 0x3b, 0xd2e, 0xd3e, 0x3b, 0xd0f, 0x3b, 0xd2e, 0xd46, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd13, 0x3b, 0xd38,
-0xd46, 0x3b, 0xd12, 0x3b, 0xd28, 0x3b, 0xd21, 0xd3f, 0x3b, 0xd1c, 0x3b, 0xd2b, 0x3b, 0xd2e, 0xd3e, 0x3b, 0xd0f, 0x3b, 0xd2e, 0xd46,
-0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd13, 0x3b, 0xd38, 0xd46, 0x3b, 0xd12, 0x3b, 0xd28, 0x3b, 0xd21, 0xd3f, 0x3b,
-0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x72, 0x61, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x6a, 0x3b,
-0x120, 0x75, 0x6e, 0x3b, 0x4c, 0x75, 0x6c, 0x3b, 0x41, 0x77, 0x77, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x74, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x10b, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x61, 0x72, 0x3b, 0x46, 0x72, 0x61, 0x72, 0x3b,
-0x4d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x6a, 0x6a, 0x75, 0x3b, 0x120, 0x75,
-0x6e, 0x6a, 0x75, 0x3b, 0x4c, 0x75, 0x6c, 0x6a, 0x75, 0x3b, 0x41, 0x77, 0x77, 0x69, 0x73, 0x73, 0x75, 0x3b, 0x53, 0x65,
-0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
-0x6d, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x10b, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x6e, 0x3b, 0x46, 0x72, 0x3b,
-0x4d, 0x7a, 0x3b, 0x41, 0x70, 0x3b, 0x4d, 0x6a, 0x3b, 0x120, 0x6e, 0x3b, 0x4c, 0x6a, 0x3b, 0x41, 0x77, 0x3b, 0x53, 0x74,
-0x3b, 0x4f, 0x62, 0x3b, 0x4e, 0x76, 0x3b, 0x44, 0x10b, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b,
-0x120, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x3b, 0x92b,
-0x947, 0x92c, 0x94d, 0x930, 0x941, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x3b, 0x92e, 0x947,
-0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x911, 0x917, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x3b,
-0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x3b,
-0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b,
-0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b,
-0x91c, 0x941, 0x932, 0x948, 0x3b, 0x911, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b,
-0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f,
-0x938, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x93e, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, 0x947, 0x3b,
-0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, 0x911, 0x3b, 0x938, 0x3b, 0x911, 0x3b, 0x928, 0x94b, 0x3b, 0x921, 0x93f, 0x3b, 0x31, 0x2d,
-0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x32, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x33, 0x2d, 0x440, 0x20, 0x441, 0x430,
-0x440, 0x3b, 0x34, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x35, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x36, 0x2d,
-0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x37, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x38, 0x2d, 0x440, 0x20, 0x441, 0x430,
-0x440, 0x3b, 0x39, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, 0x30, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31,
-0x31, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, 0x32, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x41d, 0x44d, 0x433,
-0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x425, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430,
-0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x413, 0x443, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430,
-0x440, 0x3b, 0x414, 0x4e9, 0x440, 0x4e9, 0x432, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x422, 0x430,
-0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x417, 0x443, 0x440, 0x433, 0x430, 0x434, 0x443, 0x433,
-0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x414, 0x43e, 0x43b, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430,
-0x440, 0x3b, 0x41d, 0x430, 0x439, 0x43c, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x415, 0x441, 0x434,
-0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440,
-0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x432, 0x430, 0x43d, 0x20, 0x43d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440,
-0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x432, 0x430, 0x43d, 0x20, 0x445, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430,
-0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x905, 0x930,
-0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941,
-0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947,
-0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c,
-0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x967, 0x3b, 0x968, 0x3b, 0x969, 0x3b, 0x96a, 0x3b, 0x96b,
-0x3b, 0x96c, 0x3b, 0x96d, 0x3b, 0x96e, 0x3b, 0x96f, 0x3b, 0x967, 0x966, 0x3b, 0x967, 0x967, 0x3b, 0x967, 0x968, 0x3b, 0x91c, 0x928,
-0x935, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x905, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b,
-0x905, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b,
-0x905, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d,
-0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x92e, 0x94d,
-0x92c, 0x930, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61,
-0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75,
-0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
-0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73,
-0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xb1c, 0xb3e, 0xb28, 0xb41, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2b, 0xb47, 0xb2c, 0xb43, 0xb06, 0xb30,
-0xb40, 0x3b, 0xb2e, 0xb3e, 0xb30, 0xb4d, 0xb1a, 0xb4d, 0xb1a, 0x3b, 0xb05, 0xb2a, 0xb4d, 0xb30, 0xb47, 0xb32, 0x3b, 0xb2e, 0xb07, 0x3b,
-0xb1c, 0xb41, 0xb28, 0x3b, 0xb1c, 0xb41, 0xb32, 0xb3e, 0xb07, 0x3b, 0xb05, 0xb17, 0xb37, 0xb4d, 0xb1f, 0x3b, 0xb38, 0xb47, 0xb2a, 0xb4d,
-0xb1f, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb05, 0xb15, 0xb4d, 0xb1f, 0xb4b, 0xb2c, 0xb30, 0x3b, 0xb28, 0xb2d, 0xb47, 0xb2e, 0xb4d,
-0xb2c, 0xb30, 0x3b, 0xb21, 0xb3f, 0xb38, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb1c, 0xb3e, 0x3b, 0xb2b, 0xb47, 0x3b, 0xb2e, 0xb3e,
-0x3b, 0xb05, 0x3b, 0xb2e, 0xb07, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb05, 0x3b, 0xb38, 0xb47, 0x3b, 0xb05, 0x3b, 0xb28,
-0x3b, 0xb21, 0xb3f, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631,
-0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cd, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc,
-0x3b, 0x627, 0x6ab, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b,
-0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x3b, 0x641,
-0x648, 0x631, 0x6cc, 0x647, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x3b, 0x698,
-0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, 0x645, 0x628,
-0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x627, 0x645, 0x628,
-0x631, 0x3b, 0x698, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x622, 0x3b, 0x645, 0x3b, 0x698, 0x3b, 0x698, 0x3b, 0x627, 0x3b, 0x633, 0x3b,
-0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x654, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x654,
-0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x654, 0x3b, 0x698, 0x648, 0x626, 0x646,
-0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x654, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b,
-0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x627, 0x645, 0x628, 0x631, 0x3b,
-0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e,
-0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6af, 0x633,
-0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628,
-0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c, 0x3b,
-0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x628, 0x631, 0x648,
-0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646,
-0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a,
-0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x73, 0x74, 0x79, 0x3b, 0x6c, 0x75,
-0x74, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6b, 0x77, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x3b, 0x6c, 0x69,
-0x70, 0x3b, 0x73, 0x69, 0x65, 0x3b, 0x77, 0x72, 0x7a, 0x3b, 0x70, 0x61, 0x17a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x67, 0x72,
-0x75, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x65, 0x144, 0x3b, 0x6c, 0x75, 0x74, 0x79, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x65,
-0x63, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x63, 0x69, 0x65, 0x144, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x72, 0x77,
-0x69, 0x65, 0x63, 0x3b, 0x6c, 0x69, 0x70, 0x69, 0x65, 0x63, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x69, 0x65, 0x144, 0x3b,
-0x77, 0x72, 0x7a, 0x65, 0x73, 0x69, 0x65, 0x144, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, 0x6b,
-0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x7a, 0x69, 0x65, 0x144, 0x3b, 0x53,
-0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x57, 0x3b, 0x50, 0x3b, 0x4c,
-0x3b, 0x47, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x6e, 0x69, 0x61, 0x3b, 0x6c, 0x75, 0x74, 0x65, 0x67, 0x6f, 0x3b, 0x6d,
-0x61, 0x72, 0x63, 0x61, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x74, 0x6e, 0x69, 0x61, 0x3b, 0x6d, 0x61, 0x6a, 0x61, 0x3b, 0x63,
-0x7a, 0x65, 0x72, 0x77, 0x63, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x63, 0x61, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x6e, 0x69,
-0x61, 0x3b, 0x77, 0x72, 0x7a, 0x65, 0x15b, 0x6e, 0x69, 0x61, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e,
-0x69, 0x6b, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x6e, 0x69,
-0x61, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x63, 0x3b, 0x6c, 0x3b, 0x73, 0x3b, 0x77, 0x3b,
-0x70, 0x3b, 0x6c, 0x3b, 0x67, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62,
-0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65,
-0x74, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x7a, 0x3b, 0x6a, 0x61, 0x6e, 0x65, 0x69, 0x72,
-0x6f, 0x3b, 0x66, 0x65, 0x76, 0x65, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x61, 0x62,
-0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x68, 0x6f,
-0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74,
-0x75, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x7a, 0x65, 0x6d, 0x62,
-0x72, 0x6f, 0x3b, 0xa1c, 0xa28, 0x3b, 0xa2b, 0xa3c, 0xa30, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, 0xa48,
-0x3b, 0xa2e, 0xa08, 0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0x3b, 0xa05, 0xa17, 0x3b, 0xa38, 0xa24, 0xa70, 0x3b,
-0xa05, 0xa15, 0xa24, 0xa42, 0x3b, 0xa28, 0xa35, 0xa70, 0x3b, 0xa26, 0xa38, 0xa70, 0x3b, 0xa1c, 0xa28, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2b,
-0xa3c, 0xa30, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, 0xa48, 0xa32, 0x3b, 0xa2e, 0xa08,
-0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0xa08, 0x3b, 0xa05, 0xa17, 0xa38, 0xa24, 0x3b, 0xa38, 0xa24, 0xa70, 0xa2c,
-0xa30, 0x3b, 0xa05, 0xa15, 0xa24, 0xa42, 0xa2c, 0xa30, 0x3b, 0xa28, 0xa35, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa26, 0xa38, 0xa70, 0xa2c, 0xa30,
-0x3b, 0xa1c, 0x3b, 0xa2b, 0xa3c, 0x3b, 0xa2e, 0xa3e, 0x3b, 0xa05, 0x3b, 0xa2e, 0x3b, 0xa1c, 0xa42, 0x3b, 0xa1c, 0xa41, 0x3b, 0xa05,
-0x3b, 0xa38, 0x3b, 0xa05, 0x3b, 0xa28, 0x3b, 0xa26, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631, 0x6cc,
-0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c,
-0x648, 0x644, 0x627, 0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a,
-0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x51, 0x75, 0x6c, 0x3b,
-0x48, 0x61, 0x74, 0x3b, 0x50, 0x61, 0x75, 0x3b, 0x41, 0x79, 0x72, 0x3b, 0x41, 0x79, 0x6d, 0x3b, 0x49, 0x6e, 0x74, 0x3b,
-0x41, 0x6e, 0x74, 0x3b, 0x51, 0x68, 0x61, 0x3b, 0x55, 0x6d, 0x61, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x41, 0x79, 0x61, 0x3b,
-0x4b, 0x61, 0x70, 0x3b, 0x51, 0x75, 0x6c, 0x6c, 0x61, 0x20, 0x70, 0x75, 0x71, 0x75, 0x79, 0x3b, 0x48, 0x61, 0x74, 0x75,
-0x6e, 0x20, 0x70, 0x75, 0x71, 0x75, 0x79, 0x3b, 0x50, 0x61, 0x75, 0x71, 0x61, 0x72, 0x20, 0x77, 0x61, 0x72, 0x61, 0x79,
-0x3b, 0x41, 0x79, 0x72, 0x69, 0x77, 0x61, 0x3b, 0x41, 0x79, 0x6d, 0x75, 0x72, 0x61, 0x79, 0x3b, 0x49, 0x6e, 0x74, 0x69,
-0x20, 0x72, 0x61, 0x79, 0x6d, 0x69, 0x3b, 0x41, 0x6e, 0x74, 0x61, 0x20, 0x53, 0x69, 0x74, 0x77, 0x61, 0x3b, 0x51, 0x68,
-0x61, 0x70, 0x61, 0x71, 0x20, 0x53, 0x69, 0x74, 0x77, 0x61, 0x3b, 0x55, 0x6d, 0x61, 0x20, 0x72, 0x61, 0x79, 0x6d, 0x69,
-0x3b, 0x4b, 0x61, 0x6e, 0x74, 0x61, 0x72, 0x61, 0x79, 0x3b, 0x41, 0x79, 0x61, 0x6d, 0x61, 0x72, 0x71, 0x2bc, 0x61, 0x3b,
-0x4b, 0x61, 0x70, 0x61, 0x71, 0x20, 0x52, 0x61, 0x79, 0x6d, 0x69, 0x3b, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x2e, 0x3b, 0x66,
-0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x67, 0x3b,
-0x7a, 0x65, 0x72, 0x63, 0x6c, 0x2e, 0x3b, 0x66, 0x61, 0x6e, 0x2e, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65,
-0x74, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x73,
-0x63, 0x68, 0x61, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x61, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61,
-0x76, 0x72, 0x69, 0x67, 0x6c, 0x3b, 0x6d, 0x61, 0x74, 0x67, 0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x61, 0x64, 0x75, 0x72,
-0x3b, 0x66, 0x61, 0x6e, 0x61, 0x64, 0x75, 0x72, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x65,
-0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65,
-0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d,
-0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x69, 0x61, 0x6e, 0x2e, 0x3b,
-0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69,
-0x75, 0x6e, 0x2e, 0x3b, 0x69, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b,
-0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x69, 0x61, 0x6e, 0x75, 0x61,
-0x72, 0x69, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x69, 0x65,
-0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, 0x69, 0x65, 0x3b, 0x69,
-0x75, 0x6c, 0x69, 0x65, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72,
-0x69, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6e, 0x6f, 0x69, 0x65, 0x6d, 0x62, 0x72,
-0x69, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41,
-0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44f, 0x43d, 0x432,
-0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430,
-0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d,
-0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f,
-0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b,
-0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441,
-0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e,
-0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44f, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x440, 0x442,
-0x430, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438, 0x44e,
-0x43b, 0x44f, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b,
-0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431,
-0x440, 0x44f, 0x3b, 0x4e, 0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x3b, 0x4d, 0x62, 0xe4, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x42,
-0xea, 0x6c, 0x3b, 0x46, 0xf6, 0x6e, 0x3b, 0x4c, 0x65, 0x6e, 0x3b, 0x4b, 0xfc, 0x6b, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x4e,
-0x67, 0x62, 0x3b, 0x4e, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6b, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x65, 0x3b, 0x46, 0x75,
-0x6c, 0x75, 0x6e, 0x64, 0xef, 0x67, 0x69, 0x3b, 0x4d, 0x62, 0xe4, 0x6e, 0x67, 0xfc, 0x3b, 0x4e, 0x67, 0x75, 0x62, 0xf9,
-0x65, 0x3b, 0x42, 0xea, 0x6c, 0xe4, 0x77, 0xfc, 0x3b, 0x46, 0xf6, 0x6e, 0x64, 0x6f, 0x3b, 0x4c, 0x65, 0x6e, 0x67, 0x75,
-0x61, 0x3b, 0x4b, 0xfc, 0x6b, 0xfc, 0x72, 0xfc, 0x3b, 0x4d, 0x76, 0x75, 0x6b, 0x61, 0x3b, 0x4e, 0x67, 0x62, 0x65, 0x72,
-0x65, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x62, 0xe4, 0x6e, 0x64, 0xfc, 0x72, 0x75, 0x3b, 0x4b, 0x61, 0x6b, 0x61, 0x75, 0x6b,
-0x61, 0x3b, 0x4e, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b,
-0x4e, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f,
-0x440, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435,
-0x43f, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440,
-0x3b, 0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b,
-0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441,
-0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432,
-0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b,
-0x444, 0x435, 0x431, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458,
-0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a,
-0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x432, 0x2e, 0x3b, 0x434, 0x435, 0x446, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65,
-0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e,
-0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e,
-0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65,
-0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a,
-0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74,
-0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
-0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b,
-0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x6a, 0x61, 0x6e, 0x3b,
-0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b,
-0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b,
-0x64, 0x65, 0x63, 0x3b, 0x42f, 0x43d, 0x432, 0x2e, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x2e,
-0x3b, 0x410, 0x43f, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b,
-0x410, 0x432, 0x433, 0x2e, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x41e, 0x43a, 0x442, 0x2e, 0x3b, 0x41d, 0x43e, 0x44f, 0x431,
-0x2e, 0x3b, 0x414, 0x435, 0x43a, 0x2e, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b,
-0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b,
-0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d,
-0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c,
-0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c,
-0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438,
-0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d,
-0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44b, 0x3b, 0x444, 0x435, 0x432, 0x440,
-0x430, 0x43b, 0x44b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x439, 0x44b, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44b, 0x3b,
-0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441,
-0x442, 0x44b, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b,
-0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44b, 0x3b, 0x4e, 0x64, 0x69, 0x3b, 0x4b,
-0x75, 0x6b, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x4b, 0x75, 0x62, 0x3b, 0x43, 0x68, 0x76, 0x3b, 0x43, 0x68, 0x6b, 0x3b, 0x43,
-0x68, 0x67, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x47, 0x75, 0x6e, 0x3b, 0x47, 0x75, 0x6d, 0x3b, 0x4d, 0x62, 0x75, 0x3b, 0x5a,
-0x76, 0x69, 0x3b, 0x4e, 0x64, 0x69, 0x72, 0x61, 0x3b, 0x4b, 0x75, 0x6b, 0x61, 0x64, 0x7a, 0x69, 0x3b, 0x4b, 0x75, 0x72,
-0x75, 0x6d, 0x65, 0x3b, 0x4b, 0x75, 0x62, 0x76, 0x75, 0x6d, 0x62, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x76, 0x61, 0x62, 0x76,
-0x75, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6e, 0x67, 0x75, 0x72, 0x75,
-0x3b, 0x4e, 0x79, 0x61, 0x6d, 0x61, 0x76, 0x68, 0x75, 0x76, 0x68, 0x75, 0x3b, 0x47, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x61,
-0x3b, 0x47, 0x75, 0x6d, 0x69, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x4d, 0x62, 0x75, 0x64, 0x7a, 0x69, 0x3b, 0x5a, 0x76, 0x69,
-0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4e, 0x3b, 0x47,
-0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0x3b, 0xd85,
-0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6,
-0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0,
-0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0xda2, 0xdb1, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0xdbb, 0xdc0, 0xdcf, 0xdbb,
-0xdd2, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0,
-0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0xdc3, 0xdca, 0xdad, 0xdd4,
-0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0xdad, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0xdad, 0xddd, 0xdb6, 0xdbb,
-0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb,
-0xdca, 0x3b, 0xda2, 0x3b, 0xdb4, 0xdd9, 0x3b, 0xdb8, 0xdcf, 0x3b, 0xd85, 0x3b, 0xdb8, 0xdd0, 0x3b, 0xda2, 0xdd6, 0x3b, 0xda2, 0xdd6,
-0x3b, 0xd85, 0x3b, 0xdc3, 0xdd0, 0x3b, 0xd94, 0x3b, 0xdb1, 0xdd9, 0x3b, 0xdaf, 0xdd9, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6,
-0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba,
-0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca,
-0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66,
-0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a,
-0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64,
-0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0x61,
-0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa,
-0x6c, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f,
-0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65,
-0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72,
-0x61, 0x3b, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x61, 0x3b, 0x6d, 0xe1, 0x6a, 0x61, 0x3b,
-0x6a, 0xfa, 0x6e, 0x61, 0x3b, 0x6a, 0xfa, 0x6c, 0x61, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x73, 0x65,
-0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f, 0x76, 0x65,
-0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66,
-0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75,
-0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b,
-0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b,
-0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b,
-0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x3b, 0x61, 0x76, 0x67, 0x75,
-0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72,
-0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4b,
-0x6f, 0x62, 0x3b, 0x4c, 0x61, 0x62, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x41, 0x66, 0x72, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x4c,
-0x69, 0x78, 0x3b, 0x54, 0x6f, 0x64, 0x3b, 0x53, 0x69, 0x64, 0x3b, 0x53, 0x61, 0x67, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x4b,
-0x49, 0x54, 0x3b, 0x4c, 0x49, 0x54, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x6f, 0x62, 0x61, 0x61, 0x64,
-0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20,
-0x53, 0x61, 0x64, 0x64, 0x65, 0x78, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x41, 0x66, 0x72, 0x61,
-0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x68, 0x61, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73,
-0x68, 0x61, 0x20, 0x4c, 0x69, 0x78, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x64, 0x6f,
-0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x69, 0x64, 0x65, 0x65, 0x64, 0x61, 0x61, 0x64,
-0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x67, 0x61, 0x61, 0x6c, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73,
-0x68, 0x61, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x77,
-0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c,
-0x61, 0x62, 0x61, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b,
-0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b,
-0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b,
-0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b,
-0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e,
-0x3b, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f,
-0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75,
-0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72,
-0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b,
-0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b,
-0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66,
-0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a,
-0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f,
-0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x3b, 0x66, 0x3b, 0x6d, 0x3b,
-0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x65, 0x6e,
-0x65, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6a, 0x75,
-0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, 0x3b, 0x6e, 0x6f,
-0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x45, 0x6e, 0x65, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e,
-0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x79, 0x2e, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e,
-0x3b, 0x41, 0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x74, 0x2e, 0x3b, 0x4f, 0x63, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e,
-0x3b, 0x44, 0x69, 0x63, 0x2e, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b,
-0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x4a, 0x75, 0x6e,
-0x69, 0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x69,
-0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x76, 0x69, 0x65, 0x6d,
-0x62, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66,
-0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a,
-0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f,
+0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b,
+0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b,
+0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b,
+0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44b, 0x3b, 0x444, 0x435, 0x432,
+0x440, 0x430, 0x43b, 0x44b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x439, 0x44b, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44b,
+0x3b, 0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x443,
+0x441, 0x442, 0x44b, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44b,
+0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44b, 0x3b, 0x4e, 0x64, 0x69, 0x3b,
+0x4b, 0x75, 0x6b, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x4b, 0x75, 0x62, 0x3b, 0x43, 0x68, 0x76, 0x3b, 0x43, 0x68, 0x6b, 0x3b,
+0x43, 0x68, 0x67, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x47, 0x75, 0x6e, 0x3b, 0x47, 0x75, 0x6d, 0x3b, 0x4d, 0x62, 0x75, 0x3b,
+0x5a, 0x76, 0x69, 0x3b, 0x4e, 0x64, 0x69, 0x72, 0x61, 0x3b, 0x4b, 0x75, 0x6b, 0x61, 0x64, 0x7a, 0x69, 0x3b, 0x4b, 0x75,
+0x72, 0x75, 0x6d, 0x65, 0x3b, 0x4b, 0x75, 0x62, 0x76, 0x75, 0x6d, 0x62, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x76, 0x61, 0x62,
+0x76, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6e, 0x67, 0x75, 0x72,
+0x75, 0x3b, 0x4e, 0x79, 0x61, 0x6d, 0x61, 0x76, 0x68, 0x75, 0x76, 0x68, 0x75, 0x3b, 0x47, 0x75, 0x6e, 0x79, 0x61, 0x6e,
+0x61, 0x3b, 0x47, 0x75, 0x6d, 0x69, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x4d, 0x62, 0x75, 0x64, 0x7a, 0x69, 0x3b, 0x5a, 0x76,
+0x69, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4e, 0x3b,
+0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x64a, 0x628, 0x631, 0x648, 0x631,
+0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x626, 0x64a, 0x3b, 0x62c, 0x648, 0x646,
+0x3b, 0x62c, 0x648, 0x644, 0x627, 0x621, 0x650, 0x3b, 0x622, 0x6af, 0x633, 0x67d, 0x3b, 0x633, 0x64a, 0x67e, 0x67d, 0x645, 0x628, 0x631,
+0x3b, 0x622, 0x6aa, 0x67d, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x68a, 0x633, 0x645, 0x628, 0x631, 0x3b,
+0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca,
+0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b,
+0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0xda2,
+0xdb1, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0xdbb, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad,
+0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2,
+0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0xdc3, 0xdca, 0xdad, 0xdd4, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0xdad, 0xdd0,
+0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0xdad, 0xddd, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0xdb8,
+0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xda2, 0x3b, 0xdb4, 0xdd9, 0x3b,
+0xdb8, 0xdcf, 0x3b, 0xd85, 0x3b, 0xdb8, 0xdd0, 0x3b, 0xda2, 0xdd6, 0x3b, 0xda2, 0xdd6, 0x3b, 0xd85, 0x3b, 0xdc3, 0xdd0, 0x3b, 0xd94,
+0x3b, 0xdb1, 0xdd9, 0x3b, 0xdaf, 0xdd9, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0xdd4,
+0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b,
+0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc,
+0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b,
+0x61, 0x70, 0x72, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b,
+0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75,
+0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72,
+0xed, 0x6c, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73,
+0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b,
+0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61,
+0x6e, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x63, 0x61,
+0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x61, 0x3b, 0x6d, 0xe1, 0x6a, 0x61, 0x3b, 0x6a, 0xfa, 0x6e, 0x61, 0x3b, 0x6a, 0xfa,
+0x6c, 0x61, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61,
+0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65,
+0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72,
+0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e,
+0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e,
+0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72,
+0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e,
+0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4b, 0x6f, 0x62, 0x3b, 0x4c, 0x61, 0x62, 0x3b,
+0x53, 0x61, 0x64, 0x3b, 0x41, 0x66, 0x72, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x4c, 0x69, 0x78, 0x3b, 0x54, 0x6f, 0x64, 0x3b,
+0x53, 0x69, 0x64, 0x3b, 0x53, 0x61, 0x67, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x4b, 0x49, 0x54, 0x3b, 0x4c, 0x49, 0x54, 0x3b,
+0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20,
+0x4c, 0x61, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x64, 0x64, 0x65, 0x78, 0x61,
+0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x41, 0x66, 0x72, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68,
+0x61, 0x20, 0x53, 0x68, 0x61, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x69, 0x78, 0x61,
+0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x64, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69,
+0x73, 0x68, 0x61, 0x20, 0x53, 0x69, 0x64, 0x65, 0x65, 0x64, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20,
+0x53, 0x61, 0x67, 0x61, 0x61, 0x6c, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x62, 0x6e,
+0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x77, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f,
+0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x20, 0x69, 0x79, 0x6f,
+0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4c,
+0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66, 0x65,
+0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a, 0x75,
+0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f,
0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x3b,
0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b,
0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f,
-0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72,
-0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72,
-0x65, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65,
-0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b,
-0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65,
-0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b,
-0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74,
-0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f,
-0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66,
-0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75,
-0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b,
-0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69,
-0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c,
-0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73,
-0x74, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72,
-0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xb9c,
-0xba9, 0x2e, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0x2e, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0x2e, 0x3b,
-0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbaa,
-0xbcd, 0x2e, 0x3b, 0xb85, 0xb95, 0xbcd, 0x2e, 0x3b, 0xba8, 0xbb5, 0x2e, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0x2e, 0x3b, 0xb9c, 0xba9, 0xbb5,
-0xbb0, 0xbbf, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0xbb0, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0xb9a, 0xbcd, 0x3b, 0xb8f,
-0xbaa, 0xbcd, 0xbb0, 0xbb2, 0xbcd, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86,
-0xb95, 0xbb8, 0xbcd, 0xb9f, 0xbcd, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb85, 0xb95, 0xbcd,
-0xb9f, 0xbcb, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xba8, 0xbb5, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0xbae, 0xbcd, 0xbaa,
-0xbb0, 0xbcd, 0x3b, 0xb9c, 0x3b, 0xbaa, 0xbbf, 0x3b, 0xbae, 0xbbe, 0x3b, 0xb8f, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb9c,
-0xbc2, 0x3b, 0xb86, 0x3b, 0xb9a, 0xbc6, 0x3b, 0xb85, 0x3b, 0xba8, 0x3b, 0xb9f, 0xbbf, 0x3b, 0xc1c, 0xc28, 0x3b, 0xc2b, 0xc3f, 0xc2c,
-0xc4d, 0xc30, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c,
-0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f, 0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d,
-0xc1f, 0xc46, 0xc02, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0x3b, 0xc28, 0xc35, 0xc02, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0x3b,
-0xc1c, 0xc28, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a,
-0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0xc32, 0xc4d, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc41,
-0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f, 0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d,
-0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc28, 0xc35, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f, 0xc38,
-0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc1c, 0x3b, 0xc2b, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0x3b, 0xc0f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c,
-0xc42, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc06, 0x3b, 0xc38, 0xc46, 0x3b, 0xc05, 0x3b, 0xc28, 0x3b, 0xc21, 0xc3f, 0x3b, 0xc1c, 0xc28, 0x3b,
-0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0x3b, 0xc2e,
-0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f,
-0xc46, 0xc02, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0x3b, 0xc28, 0xc35, 0xc02, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0x3b, 0xe21,
-0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe1e, 0x2e, 0x3b, 0xe21, 0xe35, 0x2e, 0xe04, 0x2e, 0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e,
-0x3b, 0xe1e, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe34, 0x2e, 0xe22, 0x2e, 0x3b, 0xe01, 0x2e, 0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04,
-0x2e, 0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b, 0xe15, 0x2e, 0xe04, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04,
-0x2e, 0x3b, 0xe21, 0xe01, 0xe23, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe38, 0xe21, 0xe20, 0xe32, 0xe1e, 0xe31, 0xe19, 0xe18, 0xe4c, 0x3b,
-0xe21, 0xe35, 0xe19, 0xe32, 0xe04, 0xe21, 0x3b, 0xe40, 0xe21, 0xe29, 0xe32, 0xe22, 0xe19, 0x3b, 0xe1e, 0xe24, 0xe29, 0xe20, 0xe32, 0xe04,
-0xe21, 0x3b, 0xe21, 0xe34, 0xe16, 0xe38, 0xe19, 0xe32, 0xe22, 0xe19, 0x3b, 0xe01, 0xe23, 0xe01, 0xe0e, 0xe32, 0xe04, 0xe21, 0x3b, 0xe2a,
-0xe34, 0xe07, 0xe2b, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe31, 0xe19, 0xe22, 0xe32, 0xe22, 0xe19, 0x3b, 0xe15, 0xe38, 0xe25, 0xe32, 0xe04,
-0xe21, 0x3b, 0xe1e, 0xe24, 0xe28, 0xe08, 0xe34, 0xe01, 0xe32, 0xe22, 0xe19, 0x3b, 0xe18, 0xe31, 0xe19, 0xe27, 0xe32, 0xe04, 0xe21, 0x3b,
-0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72,
-0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3,
-0xf0b, 0xf56, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b,
-0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56,
-0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b,
-0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45,
-0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54,
-0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f,
-0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b,
-0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56,
-0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b,
-0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0x3b, 0xf5f,
-0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74,
-0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56,
-0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42,
-0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x3b, 0x1218, 0x130b, 0x3b, 0x121a, 0x12eb, 0x3b, 0x130d, 0x1295,
-0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x3b, 0x1290, 0x1213, 0x3b, 0x1218, 0x1235, 0x3b, 0x1325, 0x1245, 0x3b, 0x1215, 0x12f3, 0x3b, 0x1273,
-0x1215, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x1275, 0x3b, 0x1218, 0x130b, 0x1262, 0x1275, 0x3b, 0x121a, 0x12eb, 0x12dd, 0x12eb, 0x3b,
-0x130d, 0x1295, 0x1266, 0x1275, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x1208, 0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235, 0x12a8, 0x1228,
-0x121d, 0x3b, 0x1325, 0x1245, 0x121d, 0x1272, 0x3b, 0x1215, 0x12f3, 0x122d, 0x3b, 0x1273, 0x1215, 0x1233, 0x1235, 0x3b, 0x1325, 0x3b, 0x1208, 0x3b,
-0x1218, 0x3b, 0x121a, 0x3b, 0x130d, 0x3b, 0x1230, 0x3b, 0x1213, 0x3b, 0x1290, 0x3b, 0x1218, 0x3b, 0x1325, 0x3b, 0x1215, 0x3b, 0x1273, 0x3b,
-0x53, 0x101, 0x6e, 0x3b, 0x46, 0x113, 0x70, 0x3b, 0x4d, 0x61, 0x2bb, 0x61, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x3b, 0x4d, 0x113,
-0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x53, 0x69, 0x75, 0x3b, 0x2bb, 0x41, 0x6f, 0x6b, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x2bb, 0x4f,
-0x6b, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x3b, 0x54, 0x12b, 0x73, 0x3b, 0x53, 0x101, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46,
-0x113, 0x70, 0x75, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x2bb, 0x61, 0x73, 0x69, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x6c, 0x65,
-0x6c, 0x69, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x65, 0x3b, 0x53, 0x69, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41,
-0x6f, 0x6b, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x69, 0x74, 0x65, 0x6d, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x74,
-0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x65, 0x6d, 0x61, 0x3b, 0x54, 0x12b, 0x73, 0x65, 0x6d, 0x61, 0x3b, 0x53, 0x3b,
-0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b,
-0x54, 0x3b, 0x4f, 0x63, 0x61, 0x3b, 0x15e, 0x75, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4e, 0x69, 0x73, 0x3b, 0x4d, 0x61,
-0x79, 0x3b, 0x48, 0x61, 0x7a, 0x3b, 0x54, 0x65, 0x6d, 0x3b, 0x41, 0x11f, 0x75, 0x3b, 0x45, 0x79, 0x6c, 0x3b, 0x45, 0x6b,
-0x69, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x4f, 0x63, 0x61, 0x6b, 0x3b, 0x15e, 0x75, 0x62, 0x61, 0x74,
-0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x4e, 0x69, 0x73, 0x61, 0x6e, 0x3b, 0x4d, 0x61, 0x79, 0x131, 0x73, 0x3b, 0x48, 0x61,
-0x7a, 0x69, 0x72, 0x61, 0x6e, 0x3b, 0x54, 0x65, 0x6d, 0x6d, 0x75, 0x7a, 0x3b, 0x41, 0x11f, 0x75, 0x73, 0x74, 0x6f, 0x73,
-0x3b, 0x45, 0x79, 0x6c, 0xfc, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x73, 0x131, 0x6d, 0x3b, 0x41, 0x72,
-0x61, 0x6c, 0x131, 0x6b, 0x3b, 0x4f, 0x3b, 0x15e, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x41,
-0x3b, 0x45, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x41, 0x3b, 0xfd, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x77, 0x3b, 0x6d, 0x61, 0x72,
-0x74, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0xfd, 0x3b, 0x69, 0xfd, 0x75, 0x6e, 0x3b, 0x69, 0xfd, 0x75, 0x6c, 0x3b,
-0x61, 0x77, 0x67, 0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0xfd, 0x3b, 0x64, 0x65, 0x6b, 0x3b,
-0xfd, 0x61, 0x6e, 0x77, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x77, 0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61,
-0x70, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x61, 0xfd, 0x3b, 0x69, 0xfd, 0x75, 0x6e, 0x3b, 0x69, 0xfd, 0x75, 0x6c, 0x3b, 0x61,
-0x77, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x6e, 0x74, 0xfd, 0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xfd, 0x61,
-0x62, 0x72, 0x3b, 0x6e, 0x6f, 0xfd, 0x61, 0x62, 0x72, 0x3b, 0x64, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0xdd, 0x3b, 0x46,
-0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44,
-0x3b, 0x64a, 0x627, 0x646, 0x6cb, 0x627, 0x631, 0x3b, 0x641, 0x6d0, 0x6cb, 0x631, 0x627, 0x644, 0x3b, 0x645, 0x627, 0x631, 0x62a, 0x3b,
-0x626, 0x627, 0x67e, 0x631, 0x6d0, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x626, 0x649, 0x64a, 0x6c7, 0x646, 0x3b, 0x626, 0x649, 0x64a,
-0x6c7, 0x644, 0x3b, 0x626, 0x627, 0x6cb, 0x63a, 0x6c7, 0x633, 0x62a, 0x3b, 0x633, 0x6d0, 0x646, 0x62a, 0x6d5, 0x628, 0x649, 0x631, 0x3b,
-0x626, 0x6c6, 0x643, 0x62a, 0x6d5, 0x628, 0x649, 0x631, 0x3b, 0x646, 0x648, 0x64a, 0x627, 0x628, 0x649, 0x631, 0x3b, 0x62f, 0x6d0, 0x643,
-0x627, 0x628, 0x649, 0x631, 0x3b, 0x441, 0x456, 0x447, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x431, 0x435, 0x440, 0x3b, 0x43a, 0x432, 0x456,
-0x3b, 0x442, 0x440, 0x430, 0x3b, 0x447, 0x435, 0x440, 0x3b, 0x43b, 0x438, 0x43f, 0x3b, 0x441, 0x435, 0x440, 0x3b, 0x432, 0x435, 0x440,
-0x3b, 0x436, 0x43e, 0x432, 0x3b, 0x43b, 0x438, 0x441, 0x3b, 0x433, 0x440, 0x443, 0x3b, 0x441, 0x456, 0x447, 0x435, 0x43d, 0x44c, 0x3b,
-0x43b, 0x44e, 0x442, 0x438, 0x439, 0x3b, 0x431, 0x435, 0x440, 0x435, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x435,
-0x43d, 0x44c, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x447, 0x435, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b,
-0x438, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x435, 0x441, 0x435,
-0x43d, 0x44c, 0x3b, 0x436, 0x43e, 0x432, 0x442, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x3b,
-0x433, 0x440, 0x443, 0x434, 0x435, 0x43d, 0x44c, 0x3b, 0x421, 0x3b, 0x41b, 0x3b, 0x411, 0x3b, 0x41a, 0x3b, 0x422, 0x3b, 0x427, 0x3b,
-0x41b, 0x3b, 0x421, 0x3b, 0x412, 0x3b, 0x416, 0x3b, 0x41b, 0x3b, 0x413, 0x3b, 0x441, 0x456, 0x447, 0x2e, 0x3b, 0x43b, 0x44e, 0x442,
-0x2e, 0x3b, 0x431, 0x435, 0x440, 0x2e, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x2e, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x2e, 0x3b, 0x447,
-0x435, 0x440, 0x432, 0x2e, 0x3b, 0x43b, 0x438, 0x43f, 0x2e, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x2e, 0x3b, 0x432, 0x435, 0x440, 0x2e,
-0x3b, 0x436, 0x43e, 0x432, 0x442, 0x2e, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x2e, 0x3b, 0x433, 0x440, 0x443, 0x434, 0x2e, 0x3b, 0x441,
-0x456, 0x447, 0x43d, 0x44f, 0x3b, 0x43b, 0x44e, 0x442, 0x43e, 0x433, 0x43e, 0x3b, 0x431, 0x435, 0x440, 0x435, 0x437, 0x43d, 0x44f, 0x3b,
-0x43a, 0x432, 0x456, 0x442, 0x43d, 0x44f, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x43d, 0x44f, 0x3b, 0x447, 0x435, 0x440, 0x432, 0x43d, 0x44f,
-0x3b, 0x43b, 0x438, 0x43f, 0x43d, 0x44f, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x43d, 0x44f, 0x3b, 0x432, 0x435, 0x440, 0x435, 0x441, 0x43d,
-0x44f, 0x3b, 0x436, 0x43e, 0x432, 0x442, 0x43d, 0x44f, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x430, 0x3b, 0x433,
-0x440, 0x443, 0x434, 0x43d, 0x44f, 0x3b, 0x441, 0x3b, 0x43b, 0x3b, 0x431, 0x3b, 0x43a, 0x3b, 0x442, 0x3b, 0x447, 0x3b, 0x43b, 0x3b,
-0x441, 0x3b, 0x432, 0x3b, 0x436, 0x3b, 0x43b, 0x3b, 0x433, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631,
-0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x6cc, 0x3b, 0x62c, 0x648, 0x646,
-0x3b, 0x62c, 0x648, 0x644, 0x627, 0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627,
-0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x59, 0x61,
-0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x49, 0x79,
-0x6e, 0x3b, 0x49, 0x79, 0x6c, 0x3b, 0x41, 0x76, 0x67, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f,
-0x79, 0x3b, 0x44, 0x65, 0x6b, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b,
-0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x49, 0x79, 0x75, 0x6e, 0x3b,
-0x49, 0x79, 0x75, 0x6c, 0x3b, 0x41, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x61, 0x62, 0x72, 0x3b,
-0x4f, 0x6b, 0x74, 0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72,
-0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f,
-0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72,
-0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b, 0x69, 0x79, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x6e,
-0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b, 0x64, 0x65, 0x6b, 0x3b, 0x79, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b,
-0x66, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x61,
-0x79, 0x3b, 0x69, 0x79, 0x75, 0x6e, 0x3b, 0x69, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73,
-0x65, 0x6e, 0x74, 0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x61, 0x62, 0x72, 0x3b, 0x6e, 0x6f, 0x79, 0x61, 0x62, 0x72,
-0x3b, 0x64, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x628, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x3b,
-0x627, 0x67e, 0x631, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x6af, 0x633, 0x3b, 0x633,
-0x67e, 0x62a, 0x3b, 0x627, 0x6a9, 0x62a, 0x3b, 0x646, 0x648, 0x645, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440,
-0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x41c,
-0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435,
-0x43d, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x3b, 0x414,
-0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x44f, 0x43d, 0x432, 0x3b, 0x444, 0x435, 0x432, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f,
-0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x3b, 0x438, 0x44e, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435,
-0x43d, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x44f, 0x3b, 0x434, 0x435, 0x43a, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x3b,
-0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x43c, 0x430,
-0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x3b, 0x438, 0x44e, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d,
-0x442, 0x44f, 0x431, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x3b, 0x434, 0x435,
-0x43a, 0x430, 0x431, 0x440, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x32, 0x3b, 0x54, 0x68, 0x67,
-0x20, 0x33, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x34, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x35, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x36,
-0x3b, 0x54, 0x68, 0x67, 0x20, 0x37, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x38, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x39, 0x3b, 0x54,
-0x68, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x32, 0x3b,
-0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x32, 0x3b, 0x54, 0x68, 0xe1, 0x6e,
-0x67, 0x20, 0x33, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x34, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x35, 0x3b,
-0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x36, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x37, 0x3b, 0x54, 0x68, 0xe1, 0x6e,
-0x67, 0x20, 0x38, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x39, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x30,
-0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x32, 0x3b, 0x74,
-0x68, 0x67, 0x20, 0x31, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x32, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x33, 0x3b, 0x74, 0x68, 0x67,
-0x20, 0x34, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x35, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x36, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x37,
-0x3b, 0x74, 0x68, 0x67, 0x20, 0x38, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x39, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x30, 0x3b,
-0x74, 0x68, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x32, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20,
-0x31, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x32, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x33, 0x3b, 0x74, 0x68,
-0xe1, 0x6e, 0x67, 0x20, 0x34, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x35, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20,
-0x36, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x37, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x38, 0x3b, 0x74, 0x68,
-0xe1, 0x6e, 0x67, 0x20, 0x39, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67,
-0x20, 0x31, 0x31, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x32, 0x3b, 0x49, 0x6f, 0x6e, 0x3b, 0x43, 0x68, 0x77,
+0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62,
+0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62,
+0x72, 0x65, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53,
+0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72,
+0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c,
+0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76,
+0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61,
+0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73,
+0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x45, 0x6e, 0x65, 0x2e, 0x3b,
+0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x79, 0x2e, 0x3b,
+0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x74, 0x2e, 0x3b,
+0x4f, 0x63, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b,
+0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b,
+0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b,
+0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x72, 0x6f,
+0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c,
+0x3b, 0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67,
+0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62,
+0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62,
+0x72, 0x65, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d,
+0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f,
+0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46,
+0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x69,
+0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73,
+0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e,
+0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b,
+0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a,
+0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f,
+0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72,
+0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69,
+0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75,
+0x73, 0x74, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65,
+0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x42f, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f,
+0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x443,
+0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41d, 0x43e,
+0x44f, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0xb9c, 0xba9, 0x2e, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0x2e,
+0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0x2e, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b,
+0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xb85, 0xb95, 0xbcd, 0x2e, 0x3b,
+0xba8, 0xbb5, 0x2e, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0x2e, 0x3b, 0xb9c, 0xba9, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0xbb0,
+0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0xb9a, 0xbcd, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0xbb0, 0xbb2, 0xbcd, 0x3b, 0xbae, 0xbc7,
+0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0xbb8, 0xbcd, 0xb9f, 0xbcd, 0x3b, 0xb9a, 0xbc6,
+0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb85, 0xb95, 0xbcd, 0xb9f, 0xbcb, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xba8, 0xbb5,
+0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9c, 0x3b, 0xbaa, 0xbbf, 0x3b,
+0xbae, 0xbbe, 0x3b, 0xb8f, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb86, 0x3b, 0xb9a, 0xbc6, 0x3b, 0xb85,
+0x3b, 0xba8, 0x3b, 0xb9f, 0xbbf, 0x3b, 0x433, 0x44b, 0x439, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440,
+0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c,
+0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f,
+0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x433, 0x44b, 0x439, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, 0x440,
+0x430, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x439, 0x3b,
+0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d,
+0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44c,
+0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0xc1c, 0xc28, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0x3b, 0xc2e, 0xc3e,
+0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c,
+0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b,
+0x3b, 0xc28, 0xc35, 0xc02, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0x3b, 0xc1c, 0xc28, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2b, 0xc3f, 0xc2c,
+0xc4d, 0xc30, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0xc32, 0xc4d,
+0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f, 0xc41,
+0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0xc2c, 0xc30, 0xc4d,
+0x3b, 0xc28, 0xc35, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc1c, 0x3b, 0xc2b,
+0xc3f, 0x3b, 0xc2e, 0xc3e, 0x3b, 0xc0f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc06, 0x3b, 0xc38, 0xc46,
+0x3b, 0xc05, 0x3b, 0xc28, 0x3b, 0xc21, 0xc3f, 0x3b, 0xe21, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe1e, 0x2e, 0x3b, 0xe21, 0xe35,
+0x2e, 0xe04, 0x2e, 0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe34, 0x2e, 0xe22, 0x2e,
+0x3b, 0xe01, 0x2e, 0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b, 0xe15, 0x2e, 0xe04, 0x2e,
+0x3b, 0xe1e, 0x2e, 0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe01, 0xe23, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe38,
+0xe21, 0xe20, 0xe32, 0xe1e, 0xe31, 0xe19, 0xe18, 0xe4c, 0x3b, 0xe21, 0xe35, 0xe19, 0xe32, 0xe04, 0xe21, 0x3b, 0xe40, 0xe21, 0xe29, 0xe32,
+0xe22, 0xe19, 0x3b, 0xe1e, 0xe24, 0xe29, 0xe20, 0xe32, 0xe04, 0xe21, 0x3b, 0xe21, 0xe34, 0xe16, 0xe38, 0xe19, 0xe32, 0xe22, 0xe19, 0x3b,
+0xe01, 0xe23, 0xe01, 0xe0e, 0xe32, 0xe04, 0xe21, 0x3b, 0xe2a, 0xe34, 0xe07, 0xe2b, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe31, 0xe19, 0xe22,
+0xe32, 0xe22, 0xe19, 0x3b, 0xe15, 0xe38, 0xe25, 0xe32, 0xe04, 0xe21, 0x3b, 0xe1e, 0xe24, 0xe28, 0xe08, 0xe34, 0xe01, 0xe32, 0xe22, 0xe19,
+0x3b, 0xe18, 0xe31, 0xe19, 0xe27, 0xe32, 0xe04, 0xe21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0xf0b,
+0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42,
+0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b,
+0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56,
+0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54,
+0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56,
+0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b,
+0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0x3b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58,
+0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63,
+0xf94, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56,
+0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54,
+0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74,
+0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab,
+0x3b, 0x1218, 0x130b, 0x3b, 0x121a, 0x12eb, 0x3b, 0x130d, 0x1295, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x3b, 0x1290, 0x1213, 0x3b, 0x1218,
+0x1235, 0x3b, 0x1325, 0x1245, 0x3b, 0x1215, 0x12f3, 0x3b, 0x1273, 0x1215, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x1275, 0x3b, 0x1218,
+0x130b, 0x1262, 0x1275, 0x3b, 0x121a, 0x12eb, 0x12dd, 0x12eb, 0x3b, 0x130d, 0x1295, 0x1266, 0x1275, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x1208,
+0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235, 0x12a8, 0x1228, 0x121d, 0x3b, 0x1325, 0x1245, 0x121d, 0x1272, 0x3b, 0x1215, 0x12f3, 0x122d, 0x3b,
+0x1273, 0x1215, 0x1233, 0x1235, 0x3b, 0x1325, 0x3b, 0x1208, 0x3b, 0x1218, 0x3b, 0x121a, 0x3b, 0x130d, 0x3b, 0x1230, 0x3b, 0x1213, 0x3b, 0x1290,
+0x3b, 0x1218, 0x3b, 0x1325, 0x3b, 0x1215, 0x3b, 0x1273, 0x3b, 0x53, 0x101, 0x6e, 0x3b, 0x46, 0x113, 0x70, 0x3b, 0x4d, 0x61, 0x2bb,
+0x61, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x53, 0x69, 0x75, 0x3b, 0x2bb, 0x41,
+0x6f, 0x6b, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x3b, 0x54, 0x12b, 0x73, 0x3b,
+0x53, 0x101, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x113, 0x70, 0x75, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x2bb, 0x61,
+0x73, 0x69, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x6c, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x65, 0x3b,
+0x53, 0x69, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x6f, 0x6b, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x69, 0x74,
+0x65, 0x6d, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x74, 0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x65, 0x6d, 0x61, 0x3b,
+0x54, 0x12b, 0x73, 0x65, 0x6d, 0x61, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53,
+0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4f, 0x63, 0x61, 0x3b, 0x15e, 0x75, 0x62, 0x3b, 0x4d,
+0x61, 0x72, 0x3b, 0x4e, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, 0x61, 0x7a, 0x3b, 0x54, 0x65, 0x6d, 0x3b, 0x41,
+0x11f, 0x75, 0x3b, 0x45, 0x79, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x4f,
+0x63, 0x61, 0x6b, 0x3b, 0x15e, 0x75, 0x62, 0x61, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x4e, 0x69, 0x73, 0x61, 0x6e,
+0x3b, 0x4d, 0x61, 0x79, 0x131, 0x73, 0x3b, 0x48, 0x61, 0x7a, 0x69, 0x72, 0x61, 0x6e, 0x3b, 0x54, 0x65, 0x6d, 0x6d, 0x75,
+0x7a, 0x3b, 0x41, 0x11f, 0x75, 0x73, 0x74, 0x6f, 0x73, 0x3b, 0x45, 0x79, 0x6c, 0xfc, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x6d,
+0x3b, 0x4b, 0x61, 0x73, 0x131, 0x6d, 0x3b, 0x41, 0x72, 0x61, 0x6c, 0x131, 0x6b, 0x3b, 0x4f, 0x3b, 0x15e, 0x3b, 0x4d, 0x3b,
+0x4e, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x45, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x41, 0x3b, 0xdd, 0x61,
+0x6e, 0x3b, 0x46, 0x65, 0x77, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0xfd, 0x3b, 0x49,
+0xfd, 0x75, 0x6e, 0x3b, 0x49, 0xfd, 0x75, 0x6c, 0x3b, 0x41, 0x77, 0x67, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x4f, 0x6b, 0x74,
+0x3b, 0x4e, 0x6f, 0xfd, 0x3b, 0x44, 0x65, 0x6b, 0x3b, 0xdd, 0x61, 0x6e, 0x77, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x77, 0x72,
+0x61, 0x6c, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0xfd, 0x3b, 0x49, 0xfd,
+0x75, 0x6e, 0x3b, 0x49, 0xfd, 0x75, 0x6c, 0x3b, 0x41, 0x77, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0xfd,
+0x61, 0x62, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0xfd, 0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0xfd, 0x61, 0x62, 0x72, 0x3b, 0x44,
+0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0xdd, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b,
+0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xfd, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x77, 0x3b, 0x6d, 0x61,
+0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0xfd, 0x3b, 0x69, 0xfd, 0x75, 0x6e, 0x3b, 0x69, 0xfd, 0x75, 0x6c,
+0x3b, 0x61, 0x77, 0x67, 0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0xfd, 0x3b, 0x64, 0x65, 0x6b,
+0x3b, 0xfd, 0x61, 0x6e, 0x77, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x77, 0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b,
+0x61, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x61, 0xfd, 0x3b, 0x69, 0xfd, 0x75, 0x6e, 0x3b, 0x69, 0xfd, 0x75, 0x6c, 0x3b,
+0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x6e, 0x74, 0xfd, 0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xfd,
+0x61, 0x62, 0x72, 0x3b, 0x6e, 0x6f, 0xfd, 0x61, 0x62, 0x72, 0x3b, 0x64, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x64a, 0x627,
+0x646, 0x6cb, 0x627, 0x631, 0x3b, 0x641, 0x6d0, 0x6cb, 0x631, 0x627, 0x644, 0x3b, 0x645, 0x627, 0x631, 0x62a, 0x3b, 0x626, 0x627, 0x67e,
+0x631, 0x6d0, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x626, 0x649, 0x64a, 0x6c7, 0x646, 0x3b, 0x626, 0x649, 0x64a, 0x6c7, 0x644, 0x3b,
+0x626, 0x627, 0x6cb, 0x63a, 0x6c7, 0x633, 0x62a, 0x3b, 0x633, 0x6d0, 0x646, 0x62a, 0x6d5, 0x628, 0x649, 0x631, 0x3b, 0x626, 0x6c6, 0x643,
+0x62a, 0x6d5, 0x628, 0x649, 0x631, 0x3b, 0x646, 0x648, 0x64a, 0x627, 0x628, 0x649, 0x631, 0x3b, 0x62f, 0x6d0, 0x643, 0x627, 0x628, 0x649,
+0x631, 0x3b, 0x441, 0x456, 0x447, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x431, 0x435, 0x440, 0x3b, 0x43a, 0x432, 0x456, 0x3b, 0x442, 0x440,
+0x430, 0x3b, 0x447, 0x435, 0x440, 0x3b, 0x43b, 0x438, 0x43f, 0x3b, 0x441, 0x435, 0x440, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x436, 0x43e,
+0x432, 0x3b, 0x43b, 0x438, 0x441, 0x3b, 0x433, 0x440, 0x443, 0x3b, 0x441, 0x456, 0x447, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x44e, 0x442,
+0x438, 0x439, 0x3b, 0x431, 0x435, 0x440, 0x435, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x435, 0x43d, 0x44c, 0x3b,
+0x442, 0x440, 0x430, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x447, 0x435, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x438, 0x43f, 0x435,
+0x43d, 0x44c, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x3b,
+0x436, 0x43e, 0x432, 0x442, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x3b, 0x433, 0x440, 0x443,
+0x434, 0x435, 0x43d, 0x44c, 0x3b, 0x421, 0x3b, 0x41b, 0x3b, 0x411, 0x3b, 0x41a, 0x3b, 0x422, 0x3b, 0x427, 0x3b, 0x41b, 0x3b, 0x421,
+0x3b, 0x412, 0x3b, 0x416, 0x3b, 0x41b, 0x3b, 0x413, 0x3b, 0x441, 0x456, 0x447, 0x2e, 0x3b, 0x43b, 0x44e, 0x442, 0x2e, 0x3b, 0x431,
+0x435, 0x440, 0x2e, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x2e, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x2e, 0x3b, 0x447, 0x435, 0x440, 0x432,
+0x2e, 0x3b, 0x43b, 0x438, 0x43f, 0x2e, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x2e, 0x3b, 0x432, 0x435, 0x440, 0x2e, 0x3b, 0x436, 0x43e,
+0x432, 0x442, 0x2e, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x2e, 0x3b, 0x433, 0x440, 0x443, 0x434, 0x2e, 0x3b, 0x441, 0x456, 0x447, 0x43d,
+0x44f, 0x3b, 0x43b, 0x44e, 0x442, 0x43e, 0x433, 0x43e, 0x3b, 0x431, 0x435, 0x440, 0x435, 0x437, 0x43d, 0x44f, 0x3b, 0x43a, 0x432, 0x456,
+0x442, 0x43d, 0x44f, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x43d, 0x44f, 0x3b, 0x447, 0x435, 0x440, 0x432, 0x43d, 0x44f, 0x3b, 0x43b, 0x438,
+0x43f, 0x43d, 0x44f, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x43d, 0x44f, 0x3b, 0x432, 0x435, 0x440, 0x435, 0x441, 0x43d, 0x44f, 0x3b, 0x436,
+0x43e, 0x432, 0x442, 0x43d, 0x44f, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x430, 0x3b, 0x433, 0x440, 0x443, 0x434,
+0x43d, 0x44f, 0x3b, 0x441, 0x3b, 0x43b, 0x3b, 0x431, 0x3b, 0x43a, 0x3b, 0x442, 0x3b, 0x447, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x432,
+0x3b, 0x436, 0x3b, 0x43b, 0x3b, 0x433, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645,
+0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648,
+0x644, 0x627, 0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648,
+0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x59, 0x61, 0x6e, 0x3b, 0x46,
+0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x49, 0x79, 0x6e, 0x3b, 0x49,
+0x79, 0x6c, 0x3b, 0x41, 0x76, 0x67, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x79, 0x3b, 0x44,
+0x65, 0x6b, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61, 0x72,
+0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x49, 0x79, 0x75, 0x6e, 0x3b, 0x49, 0x79, 0x75,
+0x6c, 0x3b, 0x41, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x61, 0x62, 0x72, 0x3b, 0x4f, 0x6b, 0x74,
+0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x59, 0x3b,
+0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b,
+0x44, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61,
+0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b, 0x69, 0x79, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b,
+0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b, 0x64, 0x65, 0x6b, 0x3b, 0x79, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x76,
+0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69,
+0x79, 0x75, 0x6e, 0x3b, 0x69, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x6e, 0x74,
+0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x61, 0x62, 0x72, 0x3b, 0x6e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x64, 0x65,
+0x6b, 0x61, 0x62, 0x72, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x628, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x3b, 0x627, 0x67e, 0x631,
+0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x6af, 0x633, 0x3b, 0x633, 0x67e, 0x62a, 0x3b,
+0x627, 0x6a9, 0x62a, 0x3b, 0x646, 0x648, 0x645, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x44f, 0x43d, 0x432, 0x3b, 0x444, 0x435, 0x432, 0x3b,
+0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x3b, 0x438, 0x44e, 0x43b, 0x3b,
+0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43d, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x44f, 0x3b, 0x434, 0x435, 0x43a, 0x3b,
+0x44f, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f,
+0x440, 0x435, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x3b, 0x438, 0x44e, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443,
+0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x43d, 0x43e,
+0x44f, 0x431, 0x440, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x3b, 0x54, 0x68, 0x67,
+0x20, 0x32, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x33, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x34, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x35,
+0x3b, 0x54, 0x68, 0x67, 0x20, 0x36, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x37, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x38, 0x3b, 0x54,
+0x68, 0x67, 0x20, 0x39, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x54,
+0x68, 0x67, 0x20, 0x31, 0x32, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20,
+0x32, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x33, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x34, 0x3b, 0x54, 0x68,
+0xe1, 0x6e, 0x67, 0x20, 0x35, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x36, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20,
+0x37, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x38, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x39, 0x3b, 0x54, 0x68,
+0xe1, 0x6e, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x54, 0x68, 0xe1, 0x6e,
+0x67, 0x20, 0x31, 0x32, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x32, 0x3b, 0x74, 0x68, 0x67,
+0x20, 0x33, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x34, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x35, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x36,
+0x3b, 0x74, 0x68, 0x67, 0x20, 0x37, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x38, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x39, 0x3b, 0x74,
+0x68, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x32, 0x3b,
+0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x32, 0x3b, 0x74, 0x68, 0xe1, 0x6e,
+0x67, 0x20, 0x33, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x34, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x35, 0x3b,
+0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x36, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x37, 0x3b, 0x74, 0x68, 0xe1, 0x6e,
+0x67, 0x20, 0x38, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x39, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x30,
+0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x32, 0x3b, 0x79,
+0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0xe4, 0x7a, 0x3b, 0x70, 0x72, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x79,
+0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x67, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x74, 0x6f, 0x62, 0x3b, 0x6e,
+0x6f, 0x76, 0x3b, 0x64, 0x65, 0x6b, 0x3b, 0x79, 0x61, 0x6e, 0x75, 0x6c, 0x3b, 0x66, 0x65, 0x62, 0x75, 0x6c, 0x3b, 0x6d,
+0xe4, 0x7a, 0x75, 0x6c, 0x3b, 0x70, 0x72, 0x69, 0x6c, 0x75, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x75, 0x6c, 0x3b, 0x79, 0x75,
+0x6e, 0x75, 0x6c, 0x3b, 0x79, 0x75, 0x6c, 0x75, 0x6c, 0x3b, 0x67, 0x75, 0x73, 0x74, 0x75, 0x6c, 0x3b, 0x73, 0x65, 0x74,
+0x75, 0x6c, 0x3b, 0x74, 0x6f, 0x62, 0x75, 0x6c, 0x3b, 0x6e, 0x6f, 0x76, 0x75, 0x6c, 0x3b, 0x64, 0x65, 0x6b, 0x75, 0x6c,
+0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x54,
+0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0xe4, 0x7a, 0x3b, 0x70, 0x72, 0x6c,
+0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x67, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74,
+0x3b, 0x74, 0x6f, 0x6e, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x6b, 0x3b, 0x49, 0x6f, 0x6e, 0x3b, 0x43, 0x68, 0x77,
0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4d, 0x65, 0x68, 0x3b, 0x47, 0x6f, 0x72,
0x3b, 0x41, 0x77, 0x73, 0x74, 0x3b, 0x4d, 0x65, 0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x3b,
0x52, 0x68, 0x61, 0x67, 0x3b, 0x49, 0x6f, 0x6e, 0x61, 0x77, 0x72, 0x3b, 0x43, 0x68, 0x77, 0x65, 0x66, 0x72, 0x6f, 0x72,
@@ -3050,640 +3111,665 @@ static const ushort months_data[] = {
0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x52, 0x68, 0x3b, 0x49, 0x6f,
0x6e, 0x3b, 0x43, 0x68, 0x77, 0x65, 0x66, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x45, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x4d,
0x61, 0x69, 0x3b, 0x4d, 0x65, 0x68, 0x3b, 0x47, 0x6f, 0x72, 0x66, 0x66, 0x3b, 0x41, 0x77, 0x73, 0x74, 0x3b, 0x4d, 0x65,
-0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x3b, 0x52, 0x68, 0x61, 0x67, 0x3b, 0x1e62, 0x1eb9, 0x301,
-0x72, 0x1eb9, 0x301, 0x3b, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62,
-0xe9, 0x3b, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x1eb9, 0x6d, 0x1ecd,
-0x3b, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42,
-0xe9, 0x6c, 0xfa, 0x3b, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1e62, 0x1eb9, 0x301, 0x72, 0x1eb9, 0x301,
-0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e,
-0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x300, 0x62, 0x69, 0x62,
-0x69, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x41, 0x67, 0x1eb9, 0x6d,
-0x1ecd, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x4f, 0x77, 0x65, 0x77, 0x65,
-0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa,
-0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, 0xc8,
-0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x190, 0x72, 0x25b, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x190, 0x300, 0x62,
-0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x25b, 0x6d, 0x254, 0x3b, 0xd2, 0x67, 0xfa, 0x6e,
-0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x186,
-0x300, 0x70, 0x25b, 0x300, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, 0x4f, 0x73,
-0x68, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x72, 0x25b, 0x300, 0x6e, 0xe0,
-0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x300, 0x62, 0x69,
-0x62, 0x69, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x41,
-0x67, 0x25b, 0x6d, 0x254, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20,
-0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, 0x73,
-0x68, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x70, 0x25b, 0x300, 0x3b, 0x4a,
-0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x73, 0x3b, 0x45, 0x70, 0x68, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a,
-0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e,
-0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72,
-0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x68, 0x72, 0x65, 0x6c, 0x69, 0x3b,
-0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x61,
-0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62,
-0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x55, 0x4d,
-0x61, 0x73, 0x69, 0x6e, 0x67, 0x61, 0x6e, 0x61, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d,
-0x61, 0x73, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x68, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75,
-0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70,
-0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d,
-0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d,
-0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b,
-0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a,
-0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f,
-0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72,
-0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b,
-0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74,
-0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e,
-0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x458, 0x430, 0x43d,
-0x443, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440,
-0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433,
-0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430,
-0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b,
-0x4a, 0x2d, 0x67, 0x75, 0x65, 0x72, 0x3b, 0x54, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e,
-0x74, 0x3b, 0x41, 0x76, 0x72, 0x72, 0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x73,
-0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4a, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69,
-0x73, 0x74, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x2d, 0x66, 0x6f, 0x75, 0x79,
-0x69, 0x72, 0x3b, 0x4d, 0x2d, 0x48, 0x6f, 0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x2d, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63,
-0x6b, 0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x67, 0x65, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x54, 0x6f, 0x73, 0x68,
-0x69, 0x61, 0x67, 0x68, 0x74, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41,
-0x76, 0x65, 0x72, 0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x73,
-0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b,
-0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69,
-0x72, 0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x20,
-0x48, 0x6f, 0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x6e, 0x79, 0x20, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63,
-0x6b, 0x3b, 0x47, 0x65, 0x6e, 0x3b, 0x48, 0x77, 0x65, 0x3b, 0x4d, 0x65, 0x75, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x65,
-0x3b, 0x4d, 0x65, 0x74, 0x3b, 0x47, 0x6f, 0x72, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x6e, 0x3b, 0x48, 0x65, 0x64,
-0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x76, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x6d,
-0x69, 0x73, 0x20, 0x48, 0x77, 0x65, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, 0x75, 0x72, 0x74,
-0x68, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, 0x3b, 0x6d,
-0x69, 0x73, 0x20, 0x4d, 0x65, 0x74, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x6f, 0x72, 0x74,
-0x68, 0x65, 0x72, 0x65, 0x6e, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x45, 0x73, 0x74, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x77,
-0x79, 0x6e, 0x6e, 0x67, 0x61, 0x6c, 0x61, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x48, 0x65, 0x64, 0x72, 0x61, 0x3b, 0x6d, 0x69,
-0x73, 0x20, 0x44, 0x75, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4b, 0x65, 0x76, 0x61, 0x72, 0x64, 0x68, 0x75, 0x3b, 0x53, 0x2d,
-0x186, 0x3b, 0x4b, 0x2d, 0x186, 0x3b, 0x45, 0x2d, 0x186, 0x3b, 0x45, 0x2d, 0x4f, 0x3b, 0x45, 0x2d, 0x4b, 0x3b, 0x4f, 0x2d,
-0x41, 0x3b, 0x41, 0x2d, 0x4b, 0x3b, 0x44, 0x2d, 0x186, 0x3b, 0x46, 0x2d, 0x190, 0x3b, 0x186, 0x2d, 0x41, 0x3b, 0x186, 0x2d,
-0x4f, 0x3b, 0x4d, 0x2d, 0x186, 0x3b, 0x53, 0x61, 0x6e, 0x64, 0x61, 0x2d, 0x186, 0x70, 0x25b, 0x70, 0x254, 0x6e, 0x3b, 0x4b,
-0x77, 0x61, 0x6b, 0x77, 0x61, 0x72, 0x2d, 0x186, 0x67, 0x79, 0x65, 0x66, 0x75, 0x6f, 0x3b, 0x45, 0x62, 0x254, 0x77, 0x2d,
-0x186, 0x62, 0x65, 0x6e, 0x65, 0x6d, 0x3b, 0x45, 0x62, 0x254, 0x62, 0x69, 0x72, 0x61, 0x2d, 0x4f, 0x66, 0x6f, 0x72, 0x69,
-0x73, 0x75, 0x6f, 0x3b, 0x45, 0x73, 0x75, 0x73, 0x6f, 0x77, 0x20, 0x41, 0x6b, 0x65, 0x74, 0x73, 0x65, 0x61, 0x62, 0x61,
-0x2d, 0x4b, 0x254, 0x74, 0x254, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x62, 0x69, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x41,
-0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x6d, 0x75, 0x6d, 0x75, 0x3b, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x2d, 0x4b,
-0x69, 0x74, 0x61, 0x77, 0x6f, 0x6e, 0x73, 0x61, 0x3b, 0x44, 0x69, 0x66, 0x75, 0x75, 0x2d, 0x186, 0x73, 0x61, 0x6e, 0x64,
-0x61, 0x61, 0x3b, 0x46, 0x61, 0x6e, 0x6b, 0x77, 0x61, 0x2d, 0x190, 0x62, 0x254, 0x3b, 0x186, 0x62, 0x25b, 0x73, 0x25b, 0x2d,
-0x41, 0x68, 0x69, 0x6e, 0x69, 0x6d, 0x65, 0x3b, 0x186, 0x62, 0x65, 0x72, 0x25b, 0x66, 0x25b, 0x77, 0x2d, 0x4f, 0x62, 0x75,
-0x62, 0x75, 0x6f, 0x3b, 0x4d, 0x75, 0x6d, 0x75, 0x2d, 0x186, 0x70, 0x25b, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e,
-0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e,
-0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941,
-0x932, 0x948, 0x3b, 0x913, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x913,
-0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938,
-0x947, 0x902, 0x92c, 0x930, 0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x45, 0x70, 0x72,
-0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x3b, 0x53, 0x65, 0x70,
-0x3b, 0x1ecc, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x65, 0x6e, 0x1ee5, 0x77, 0x61, 0x72,
-0x1ecb, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x4d, 0x61, 0x61, 0x63, 0x68, 0x1ecb, 0x3b, 0x45,
-0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x1ecb, 0x3b,
-0x1ecc, 0x67, 0x1ecd, 0x1ecd, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x1ecc, 0x6b, 0x74, 0x6f,
-0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4d,
-0x62, 0x65, 0x3b, 0x4b, 0x65, 0x6c, 0x3b, 0x4b, 0x74, 0x169, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x74, 0x6e, 0x3b, 0x54,
-0x68, 0x61, 0x3b, 0x4d, 0x6f, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x4b, 0x6e, 0x64, 0x3b, 0x128, 0x6b, 0x75, 0x3b, 0x128,
-0x6b, 0x6d, 0x3b, 0x128, 0x6b, 0x6c, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x65, 0x3b,
-0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61,
-0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61,
-0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x61, 0x69,
-0x20, 0x77, 0x61, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77,
-0x61, 0x20, 0x6d, 0x75, 0x6f, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x79, 0x61,
-0x61, 0x6e, 0x79, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d,
-0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61,
-0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x129, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20,
-0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6c, 0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b,
-0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x128, 0x3b,
-0x5a, 0x65, 0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x76, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b,
-0x4a, 0x75, 0x67, 0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x63, 0x3b, 0x5a, 0x65, 0x6e, 0xe2, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0xe2, 0x72,
-0x3b, 0x4d, 0x61, 0x72, 0xe7, 0x3b, 0x41, 0x76, 0x72, 0xee, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x6e,
-0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b,
-0x4f, 0x74, 0x75, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x63, 0x65,
-0x6d, 0x62, 0x61, 0x72, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4c, 0x3b, 0x41,
-0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x64, 0x7a, 0x76, 0x3b, 0x64, 0x7a, 0x64, 0x3b, 0x74, 0x65, 0x64,
-0x3b, 0x61, 0x66, 0x254, 0x3b, 0x64, 0x61, 0x6d, 0x3b, 0x6d, 0x61, 0x73, 0x3b, 0x73, 0x69, 0x61, 0x3b, 0x64, 0x65, 0x61,
-0x3b, 0x61, 0x6e, 0x79, 0x3b, 0x6b, 0x65, 0x6c, 0x3b, 0x61, 0x64, 0x65, 0x3b, 0x64, 0x7a, 0x6d, 0x3b, 0x64, 0x7a, 0x6f,
-0x76, 0x65, 0x3b, 0x64, 0x7a, 0x6f, 0x64, 0x7a, 0x65, 0x3b, 0x74, 0x65, 0x64, 0x6f, 0x78, 0x65, 0x3b, 0x61, 0x66, 0x254,
-0x66, 0x129, 0x65, 0x3b, 0x64, 0x61, 0x6d, 0x61, 0x3b, 0x6d, 0x61, 0x73, 0x61, 0x3b, 0x73, 0x69, 0x61, 0x6d, 0x6c, 0x254,
-0x6d, 0x3b, 0x64, 0x65, 0x61, 0x73, 0x69, 0x61, 0x6d, 0x69, 0x6d, 0x65, 0x3b, 0x61, 0x6e, 0x79, 0x254, 0x6e, 0x79, 0x254,
-0x3b, 0x6b, 0x65, 0x6c, 0x65, 0x3b, 0x61, 0x64, 0x65, 0x25b, 0x6d, 0x65, 0x6b, 0x70, 0x254, 0x78, 0x65, 0x3b, 0x64, 0x7a,
-0x6f, 0x6d, 0x65, 0x3b, 0x64, 0x3b, 0x64, 0x3b, 0x74, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b,
-0x61, 0x3b, 0x6b, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x49, 0x61, 0x6e, 0x2e, 0x3b, 0x50, 0x65, 0x70, 0x2e, 0x3b, 0x4d, 0x61,
-0x6c, 0x2e, 0x3b, 0x2bb, 0x41, 0x70, 0x2e, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x2e, 0x3b, 0x49, 0x75, 0x6c,
-0x2e, 0x3b, 0x2bb, 0x41, 0x75, 0x2e, 0x3b, 0x4b, 0x65, 0x70, 0x2e, 0x3b, 0x2bb, 0x4f, 0x6b, 0x2e, 0x3b, 0x4e, 0x6f, 0x77,
-0x2e, 0x3b, 0x4b, 0x65, 0x6b, 0x2e, 0x3b, 0x49, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x50, 0x65, 0x70, 0x65, 0x6c,
-0x75, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x6b, 0x69, 0x3b, 0x2bb, 0x41, 0x70, 0x65, 0x6c, 0x69, 0x6c, 0x61,
-0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x65, 0x3b, 0x49, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x75, 0x6b,
-0x61, 0x6b, 0x65, 0x3b, 0x4b, 0x65, 0x70, 0x61, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x6b,
-0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x6f, 0x77, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x4b, 0x65, 0x6b, 0x65, 0x6d, 0x61, 0x70,
-0x61, 0x3b, 0x45, 0x6e, 0x65, 0x3b, 0x50, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61,
-0x79, 0x3b, 0x48, 0x75, 0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b,
-0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x50, 0x65, 0x62, 0x72,
-0x65, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f,
-0x3b, 0x48, 0x75, 0x6e, 0x79, 0x6f, 0x3b, 0x48, 0x75, 0x6c, 0x79, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b,
-0x53, 0x65, 0x74, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f,
-0x62, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x73, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b,
-0x50, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x48, 0x75, 0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b,
-0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75,
-0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69,
-0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75,
-0x73, 0x63, 0x68, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f,
-0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65,
-0x72, 0x3b, 0xa2cd, 0xa1aa, 0x3b, 0xa44d, 0xa1aa, 0x3b, 0xa315, 0xa1aa, 0x3b, 0xa1d6, 0xa1aa, 0x3b, 0xa26c, 0xa1aa, 0x3b, 0xa0d8, 0xa1aa, 0x3b,
-0xa3c3, 0xa1aa, 0x3b, 0xa246, 0xa1aa, 0x3b, 0xa22c, 0xa1aa, 0x3b, 0xa2b0, 0xa1aa, 0x3b, 0xa2b0, 0xa2aa, 0xa1aa, 0x3b, 0xa2b0, 0xa44b, 0xa1aa, 0x3b,
-0x4a, 0x61, 0x6e, 0x75, 0x61, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72,
-0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c,
-0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f,
-0x6b, 0x74, 0x6f, 0x76, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65,
-0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x111, 0x111, 0x6a, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x3b,
-0x63, 0x75, 0x6f, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x3b, 0x62,
-0x6f, 0x72, 0x67, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x3b, 0x6a,
-0x75, 0x6f, 0x76, 0x3b, 0x6f, 0x111, 0x111, 0x61, 0x6a, 0x61, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x75,
-0x6f, 0x76, 0x76, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e,
-0x75, 0x3b, 0x63, 0x75, 0x6f, 0x14b, 0x6f, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x73, 0x65, 0x6d,
-0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x73, 0x75, 0x6f,
-0x69, 0x64, 0x6e, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75,
-0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x67, 0x6f, 0x74, 0x6d,
-0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x6d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6a, 0x75, 0x6f,
-0x76, 0x6c, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x4f, 0x3b, 0x47, 0x3b, 0x4e, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0x47,
-0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x10c, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x43, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62,
-0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x43, 0x75, 0x6c,
-0x3b, 0x41, 0x67, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73,
-0x3b, 0x43, 0x68, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x61, 0x72, 0x69, 0x3b, 0x4d,
-0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x69, 0x72, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e,
-0x69, 0x3b, 0x43, 0x68, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74,
-0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x62, 0x65, 0x6d, 0x62, 0x61,
-0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x43, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a,
-0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x49, 0x6d, 0x62, 0x3b, 0x4b, 0x61, 0x77,
-0x3b, 0x4b, 0x61, 0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4b, 0x61, 0x72, 0x3b, 0x4d, 0x66, 0x75,
-0x3b, 0x57, 0x75, 0x6e, 0x3b, 0x49, 0x6b, 0x65, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x77, 0x69,
-0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6d, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x6f,
-0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68,
-0x77, 0x61, 0x20, 0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20,
-0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x73, 0x61, 0x6e,
-0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x72, 0x61, 0x6e, 0x64, 0x61, 0x64,
-0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6d, 0x66, 0x75, 0x6e, 0x67, 0x61, 0x64, 0x65,
-0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x77, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x79, 0x61, 0x3b,
-0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x6f, 0x72,
-0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68,
-0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4d,
-0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x77,
-0x69, 0x3b, 0x49, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, 0x49, 0x3b,
-0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x73, 0x69, 0x69, 0x3b, 0x63, 0x6f, 0x6c, 0x3b, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0x65,
-0x65, 0x3b, 0x64, 0x75, 0x75, 0x3b, 0x6b, 0x6f, 0x72, 0x3b, 0x6d, 0x6f, 0x72, 0x3b, 0x6a, 0x75, 0x6b, 0x3b, 0x73, 0x6c,
-0x74, 0x3b, 0x79, 0x61, 0x72, 0x3b, 0x6a, 0x6f, 0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x3b, 0x73, 0x69, 0x69, 0x6c, 0x6f, 0x3b,
-0x63, 0x6f, 0x6c, 0x74, 0x65, 0x3b, 0x6d, 0x62, 0x6f, 0x6f, 0x79, 0x3b, 0x73, 0x65, 0x65, 0x257, 0x74, 0x6f, 0x3b, 0x64,
-0x75, 0x75, 0x6a, 0x61, 0x6c, 0x3b, 0x6b, 0x6f, 0x72, 0x73, 0x65, 0x3b, 0x6d, 0x6f, 0x72, 0x73, 0x6f, 0x3b, 0x6a, 0x75,
-0x6b, 0x6f, 0x3b, 0x73, 0x69, 0x69, 0x6c, 0x74, 0x6f, 0x3b, 0x79, 0x61, 0x72, 0x6b, 0x6f, 0x6d, 0x61, 0x61, 0x3b, 0x6a,
-0x6f, 0x6c, 0x61, 0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x74, 0x65, 0x3b, 0x73, 0x3b, 0x63, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64,
-0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x73, 0x3b, 0x79, 0x3b, 0x6a, 0x3b, 0x62, 0x3b, 0x4a, 0x45, 0x4e, 0x3b, 0x57,
-0x4b, 0x52, 0x3b, 0x57, 0x47, 0x54, 0x3b, 0x57, 0x4b, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x57, 0x54, 0x44, 0x3b, 0x57,
-0x4d, 0x4a, 0x3b, 0x57, 0x4e, 0x4e, 0x3b, 0x57, 0x4b, 0x44, 0x3b, 0x57, 0x49, 0x4b, 0x3b, 0x57, 0x4d, 0x57, 0x3b, 0x44,
-0x49, 0x54, 0x3b, 0x4e, 0x6a, 0x65, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61,
-0x20, 0x6b, 0x65, 0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74,
-0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72,
-0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61,
-0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20,
-0x6d, 0x169, 0x67, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61,
-0x6e, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b,
-0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65,
-0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4e, 0x64,
-0x69, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b,
-0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x44, 0x3b, 0x4f, 0x62, 0x6f, 0x3b, 0x57, 0x61, 0x61, 0x3b,
-0x4f, 0x6b, 0x75, 0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6d, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53, 0x61, 0x70, 0x3b,
-0x49, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x61, 0x3b, 0x54, 0x6f, 0x6d, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x54, 0x6f, 0x77, 0x3b,
-0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20,
-0x77, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6b, 0x75, 0x6e, 0x69, 0x3b,
-0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61,
-0x20, 0x6c, 0x65, 0x20, 0x69, 0x6d, 0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x6c, 0x65,
-0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c,
-0x65, 0x20, 0x69, 0x73, 0x69, 0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x61, 0x6c,
-0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20,
-0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65,
-0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x77, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4f, 0x3b, 0x57, 0x3b, 0x4f, 0x3b, 0x4f,
-0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4a, 0x61, 0x6e,
-0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e,
-0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76,
-0x3b, 0x44, 0x65, 0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x65, 0x69, 0x72,
-0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x63, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x4a,
-0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x53,
-0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d,
-0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x5a, 0x69, 0x62, 0x3b, 0x4e, 0x68, 0x6c,
-0x6f, 0x3b, 0x4d, 0x62, 0x69, 0x3b, 0x4d, 0x61, 0x62, 0x3b, 0x4e, 0x6b, 0x77, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x3b, 0x4e,
-0x74, 0x75, 0x3b, 0x4e, 0x63, 0x77, 0x3b, 0x4d, 0x70, 0x61, 0x6e, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x3b,
-0x4d, 0x70, 0x61, 0x6c, 0x3b, 0x5a, 0x69, 0x62, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x6c, 0x61, 0x3b, 0x4e, 0x68, 0x6c, 0x6f,
-0x6c, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x62, 0x69, 0x6d, 0x62, 0x69, 0x74, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x62, 0x61,
-0x73, 0x61, 0x3b, 0x4e, 0x6b, 0x77, 0x65, 0x6e, 0x6b, 0x77, 0x65, 0x7a, 0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67,
-0x75, 0x6c, 0x61, 0x3b, 0x4e, 0x74, 0x75, 0x6c, 0x69, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x4e, 0x63, 0x77, 0x61, 0x62, 0x61,
-0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6e, 0x64, 0x75, 0x6c, 0x61, 0x3b, 0x4d, 0x66, 0x75, 0x6d, 0x66, 0x75,
-0x3b, 0x4c, 0x77, 0x65, 0x7a, 0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6c, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x5a, 0x3b, 0x4e,
-0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4d,
-0x3b, 0x4d, 0x31, 0x3b, 0x4d, 0x32, 0x3b, 0x4d, 0x33, 0x3b, 0x4d, 0x34, 0x3b, 0x4d, 0x35, 0x3b, 0x4d, 0x36, 0x3b, 0x4d,
-0x37, 0x3b, 0x4d, 0x38, 0x3b, 0x4d, 0x39, 0x3b, 0x4d, 0x31, 0x30, 0x3b, 0x4d, 0x31, 0x31, 0x3b, 0x4d, 0x31, 0x32, 0x3b,
-0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72,
-0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20,
-0x6b, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x61, 0x6e,
-0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72,
-0x69, 0x20, 0x77, 0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x73,
-0x61, 0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77,
-0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61,
-0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d,
-0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69,
-0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b,
-0x4b, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x2d49, 0x2d4f,
-0x2d4f, 0x3b, 0x2d31, 0x2d55, 0x2d30, 0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x3b, 0x2d49, 0x2d31, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x3b, 0x2d62, 0x2d53,
-0x2d4f, 0x3b, 0x2d62, 0x2d53, 0x2d4d, 0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x3b, 0x2d3d, 0x2d5c, 0x2d53, 0x3b, 0x2d4f, 0x2d53,
-0x2d61, 0x3b, 0x2d37, 0x2d53, 0x2d4a, 0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x2d30, 0x2d62, 0x2d54, 0x3b, 0x2d31, 0x2d55, 0x2d30, 0x2d62, 0x2d55, 0x3b, 0x2d4e,
-0x2d30, 0x2d55, 0x2d5a, 0x3b, 0x2d49, 0x2d31, 0x2d54, 0x2d49, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x2d62,
-0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4d, 0x2d62, 0x2d53, 0x2d63, 0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x2d5c, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x2d30, 0x2d4f, 0x2d31,
-0x2d49, 0x2d54, 0x3b, 0x2d3d, 0x2d5c, 0x2d53, 0x2d31, 0x2d54, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d37, 0x2d53,
-0x2d4a, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d49, 0x3b, 0x2d31, 0x3b, 0x2d4e, 0x3b, 0x2d49, 0x3b, 0x2d4e, 0x3b, 0x2d62, 0x3b, 0x2d62,
-0x3b, 0x2d56, 0x3b, 0x2d5b, 0x3b, 0x2d3d, 0x3b, 0x2d4f, 0x3b, 0x2d37, 0x3b, 0x69, 0x6e, 0x6e, 0x3b, 0x62, 0x1e5b, 0x61, 0x3b, 0x6d,
-0x61, 0x1e5b, 0x3b, 0x69, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x263,
-0x75, 0x63, 0x3b, 0x63, 0x75, 0x74, 0x3b, 0x6b, 0x74, 0x75, 0x3b, 0x6e, 0x75, 0x77, 0x3b, 0x64, 0x75, 0x6a, 0x3b, 0x69,
-0x6e, 0x6e, 0x61, 0x79, 0x72, 0x3b, 0x62, 0x1e5b, 0x61, 0x79, 0x1e5b, 0x3b, 0x6d, 0x61, 0x1e5b, 0x1e63, 0x3b, 0x69, 0x62, 0x72,
-0x69, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6c, 0x79, 0x75,
-0x7a, 0x3b, 0x263, 0x75, 0x63, 0x74, 0x3b, 0x63, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x6b, 0x74, 0x75, 0x62,
-0x72, 0x3b, 0x6e, 0x75, 0x77, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x64, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b,
-0x69, 0x3b, 0x62, 0x3b, 0x6d, 0x3b, 0x69, 0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x263, 0x3b, 0x63, 0x3b, 0x6b, 0x3b,
-0x6e, 0x3b, 0x64, 0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x46, 0x75, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b,
-0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b,
-0x54, 0x75, 0x62, 0x3b, 0x4e, 0x75, 0x6e, 0x3b, 0x44, 0x75, 0x1e7, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72,
-0x3b, 0x46, 0x75, 0x1e5b, 0x61, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x72, 0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72,
-0x3b, 0x4d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194,
-0x75, 0x63, 0x74, 0x3b, 0x43, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x4e, 0x75,
-0x6e, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x44, 0x75, 0x1e7, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b,
-0x4d, 0x3b, 0x59, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44, 0x3b,
-0x4b, 0x42, 0x5a, 0x3b, 0x4b, 0x42, 0x52, 0x3b, 0x4b, 0x53, 0x54, 0x3b, 0x4b, 0x4b, 0x4e, 0x3b, 0x4b, 0x54, 0x4e, 0x3b,
-0x4b, 0x4d, 0x4b, 0x3b, 0x4b, 0x4d, 0x53, 0x3b, 0x4b, 0x4d, 0x4e, 0x3b, 0x4b, 0x4d, 0x57, 0x3b, 0x4b, 0x4b, 0x4d, 0x3b,
-0x4b, 0x4e, 0x4b, 0x3b, 0x4b, 0x4e, 0x42, 0x3b, 0x4f, 0x6b, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b,
-0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61,
-0x74, 0x75, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61,
-0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61,
-0x6d, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x6a, 0x75, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x6e, 0x61, 0x61, 0x6e, 0x61,
-0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x77, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d,
-0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x77, 0x65,
-0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x62, 0x69, 0x72, 0x69, 0x3b,
-0x48, 0x75, 0x74, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x44, 0x61, 0x74, 0x3b, 0x54, 0x61, 0x69, 0x3b, 0x48, 0x61, 0x6e, 0x3b,
-0x53, 0x69, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b,
-0x4b, 0x6d, 0x6a, 0x3b, 0x4b, 0x6d, 0x62, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77,
-0x61, 0x20, 0x68, 0x75, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67,
-0x77, 0x61, 0x20, 0x77, 0x75, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20,
-0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x64, 0x61, 0x74, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69,
-0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x74, 0x61, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69,
-0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a,
-0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69,
-0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20,
-0x67, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67,
-0x77, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77,
-0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61,
-0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65,
-0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c,
-0x69, 0x3b, 0x48, 0x3b, 0x56, 0x3b, 0x44, 0x3b, 0x54, 0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b,
-0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61,
-0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4d, 0x65, 0x69,
-0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x79, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x69,
-0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76,
-0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62,
-0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x77, 0x69, 0x3b, 0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x3b, 0x7a, 0x75, 0x6c, 0x3b,
-0x75, 0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x3b, 0x254, 0x6b, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x73, 0x3b,
-0x7a, 0x61, 0x6e, 0x77, 0x75, 0x79, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x75, 0x72, 0x75, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72,
-0x69, 0x73, 0x69, 0x3b, 0x61, 0x77, 0x69, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x25b, 0x6e,
-0x3b, 0x7a, 0x75, 0x6c, 0x75, 0x79, 0x65, 0x3b, 0x75, 0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72,
-0x75, 0x3b, 0x254, 0x6b, 0x75, 0x74, 0x254, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72,
-0x75, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b,
-0x4d, 0x3b, 0x5a, 0x3b, 0x5a, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x186, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x62, 0x65, 0x3b,
-0x4b, 0x61, 0x69, 0x3b, 0x4b, 0x61, 0x74, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x47, 0x61, 0x74, 0x3b, 0x47, 0x61, 0x6e, 0x3b,
-0x4d, 0x75, 0x67, 0x3b, 0x4b, 0x6e, 0x6e, 0x3b, 0x4b, 0x65, 0x6e, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b,
-0x49, 0x67, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4d,
-0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x129, 0x72, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20,
-0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20,
-0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f,
-0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x74, 0x61, 0x74, 0x169, 0x3b,
-0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x169, 0x67, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77,
-0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20,
-0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b,
-0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e,
-0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d,
-0x69, 0x20, 0x6e, 0x61, 0x20, 0x4b, 0x61, 0x129, 0x72, 0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x47,
-0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x13a4, 0x13c3, 0x3b, 0x13a7, 0x13a6,
-0x3b, 0x13a0, 0x13c5, 0x3b, 0x13a7, 0x13ec, 0x3b, 0x13a0, 0x13c2, 0x3b, 0x13d5, 0x13ad, 0x3b, 0x13ab, 0x13f0, 0x3b, 0x13a6, 0x13b6, 0x3b, 0x13da,
-0x13b5, 0x3b, 0x13da, 0x13c2, 0x3b, 0x13c5, 0x13d3, 0x3b, 0x13a5, 0x13cd, 0x3b, 0x13a4, 0x13c3, 0x13b8, 0x13d4, 0x13c5, 0x3b, 0x13a7, 0x13a6, 0x13b5,
-0x3b, 0x13a0, 0x13c5, 0x13f1, 0x3b, 0x13a7, 0x13ec, 0x13c2, 0x3b, 0x13a0, 0x13c2, 0x13cd, 0x13ac, 0x13d8, 0x3b, 0x13d5, 0x13ad, 0x13b7, 0x13f1, 0x3b,
-0x13ab, 0x13f0, 0x13c9, 0x13c2, 0x3b, 0x13a6, 0x13b6, 0x13c2, 0x3b, 0x13da, 0x13b5, 0x13cd, 0x13d7, 0x3b, 0x13da, 0x13c2, 0x13c5, 0x13d7, 0x3b, 0x13c5,
-0x13d3, 0x13d5, 0x13c6, 0x3b, 0x13a5, 0x13cd, 0x13a9, 0x13f1, 0x3b, 0x13a4, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13d5,
-0x3b, 0x13ab, 0x3b, 0x13a6, 0x3b, 0x13da, 0x3b, 0x13da, 0x3b, 0x13c5, 0x3b, 0x13a5, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76,
-0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x76, 0x72, 0x3b, 0x6d, 0x65, 0x3b, 0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x3b,
-0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b,
-0x7a, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x66, 0x65, 0x76, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b,
-0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x3b, 0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x79, 0x65, 0x3b, 0x6f,
-0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x61, 0x6d, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x3b, 0x6e, 0x6f, 0x76, 0x61,
-0x6d, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6d, 0x3b, 0x7a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x7a, 0x3b,
-0x7a, 0x3b, 0x6f, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x4e, 0x74,
-0x61, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x3b, 0x4d,
-0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x54, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77,
-0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e,
-0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e,
-0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x6d, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e,
-0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69,
-0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x69, 0x74, 0x61, 0x74, 0x75,
-0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20,
-0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79,
-0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20,
-0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20,
-0x6e, 0x61, 0x20, 0x55, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f,
-0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x3b, 0x46, 0xfa, 0x6e, 0x67,
-0x61, 0x74, 0x268, 0x3b, 0x4e, 0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x49, 0x6b, 0xfa,
-0x6d, 0x69, 0x3b, 0x49, 0x6e, 0x79, 0x61, 0x6d, 0x62, 0x61, 0x6c, 0x61, 0x3b, 0x49, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61,
-0x3b, 0x4d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b, 0x56, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x53, 0x61, 0x61, 0x74, 0x289,
-0x3b, 0x49, 0x6e, 0x79, 0x69, 0x3b, 0x53, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x53, 0x61, 0x73, 0x61, 0x74, 0x289, 0x3b, 0x4b,
-0x289, 0x66, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b, 0x4b, 0x289, 0x6e, 0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, 0x289, 0x6b,
-0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6e,
-0x79, 0x61, 0x6d, 0x62, 0xe1, 0x6c, 0x61, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4b,
-0x289, 0x6d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b, 0x4b, 0x289, 0x76, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x4b, 0x289, 0x73,
-0x61, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6e, 0x79, 0x69, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x6e, 0x6f,
-0x3b, 0x4b, 0x289, 0x73, 0x61, 0x73, 0x61, 0x74, 0x289, 0x3b, 0x46, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b,
-0x49, 0x3b, 0x4d, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65,
-0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x75, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75,
-0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x62, 0x3b, 0x4f, 0x6b, 0x69, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65,
-0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x77, 0x61, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x77, 0x61, 0x6c, 0x69, 0x79,
-0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b, 0x41, 0x70, 0x75, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x61, 0x79, 0x69,
-0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x69,
-0x74, 0x6f, 0x3b, 0x53, 0x65, 0x62, 0x75, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62,
-0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a,
-0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a,
-0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e,
-0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75,
-0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b,
-0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65,
-0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
-0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b,
-0x4a, 0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65,
-0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75,
-0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x75, 0x76, 0x3b, 0x44, 0x69,
-0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x72, 0x75, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72,
-0x73, 0x75, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x75, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x75, 0x3b,
-0x4a, 0x75, 0x6c, 0x68, 0x75, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6e, 0x62, 0x72,
-0x75, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x75, 0x76, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69,
-0x7a, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x41, 0x4e, 0x3b, 0x46, 0x45, 0x42, 0x3b, 0x4d, 0x41, 0x43, 0x3b, 0x128,
-0x50, 0x55, 0x3b, 0x4d, 0x128, 0x128, 0x3b, 0x4e, 0x4a, 0x55, 0x3b, 0x4e, 0x4a, 0x52, 0x3b, 0x41, 0x47, 0x41, 0x3b, 0x53,
-0x50, 0x54, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4e, 0x4f, 0x56, 0x3b, 0x44, 0x45, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61,
-0x72, 0x129, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x128,
-0x70, 0x75, 0x72, 0x169, 0x3b, 0x4d, 0x129, 0x129, 0x3b, 0x4e, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x72, 0x61,
-0x129, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b,
-0x74, 0x169, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61,
-0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x128, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f,
-0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x4e, 0x67, 0x61, 0x74, 0x3b, 0x54, 0x61, 0x61, 0x3b, 0x49, 0x77,
-0x6f, 0x3b, 0x4d, 0x61, 0x6d, 0x3b, 0x50, 0x61, 0x61, 0x3b, 0x4e, 0x67, 0x65, 0x3b, 0x52, 0x6f, 0x6f, 0x3b, 0x42, 0x75,
-0x72, 0x3b, 0x45, 0x70, 0x65, 0x3b, 0x4b, 0x70, 0x74, 0x3b, 0x4b, 0x70, 0x61, 0x3b, 0x4d, 0x75, 0x6c, 0x67, 0x75, 0x6c,
-0x3b, 0x4e, 0x67, 0x2019, 0x61, 0x74, 0x79, 0x61, 0x61, 0x74, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x74, 0x61, 0x61, 0x6d, 0x6f,
-0x3b, 0x49, 0x77, 0x6f, 0x6f, 0x74, 0x6b, 0x75, 0x75, 0x74, 0x3b, 0x4d, 0x61, 0x6d, 0x75, 0x75, 0x74, 0x3b, 0x50, 0x61,
-0x61, 0x67, 0x69, 0x3b, 0x4e, 0x67, 0x2019, 0x65, 0x69, 0x79, 0x65, 0x65, 0x74, 0x3b, 0x52, 0x6f, 0x6f, 0x70, 0x74, 0x75,
-0x69, 0x3b, 0x42, 0x75, 0x72, 0x65, 0x65, 0x74, 0x3b, 0x45, 0x70, 0x65, 0x65, 0x73, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x73,
-0x75, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x20, 0x74, 0x61, 0x61, 0x69, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x75,
-0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x62, 0x6f, 0x20, 0x61, 0x65, 0x6e, 0x67, 0x2019, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x54,
-0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x4e, 0x3b, 0x52, 0x3b, 0x42, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x1c3,
-0x4b, 0x68, 0x61, 0x6e, 0x6e, 0x69, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x6e, 0x1c0, 0x67, 0xf4, 0x61, 0x62, 0x3b, 0x1c0, 0x4b,
-0x68, 0x75, 0x75, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x1c3, 0x48, 0xf4, 0x61, 0x1c2, 0x6b, 0x68, 0x61, 0x69, 0x62, 0x3b,
-0x1c3, 0x4b, 0x68, 0x61, 0x69, 0x74, 0x73, 0xe2, 0x62, 0x3b, 0x47, 0x61, 0x6d, 0x61, 0x1c0, 0x61, 0x65, 0x62, 0x3b, 0x1c2,
-0x4b, 0x68, 0x6f, 0x65, 0x73, 0x61, 0x6f, 0x62, 0x3b, 0x41, 0x6f, 0x1c1, 0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b,
-0x68, 0xe2, 0x62, 0x3b, 0x54, 0x61, 0x72, 0x61, 0x1c0, 0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2, 0x62,
-0x3b, 0x1c2, 0x4e, 0xfb, 0x1c1, 0x6e, 0xe2, 0x69, 0x73, 0x65, 0x62, 0x3b, 0x1c0, 0x48, 0x6f, 0x6f, 0x1c2, 0x67, 0x61, 0x65,
-0x62, 0x3b, 0x48, 0xf4, 0x61, 0x73, 0x6f, 0x72, 0x65, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b,
-0x46, 0xe4, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x7a, 0x2e, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a,
-0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x4f, 0x75, 0x6a, 0x2e, 0x3b, 0x53, 0xe4, 0x70, 0x2e, 0x3b, 0x4f,
-0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65, 0x77,
-0x61, 0x3b, 0x46, 0xe4, 0x62, 0x72, 0x6f, 0x77, 0x61, 0x3b, 0x4d, 0xe4, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c,
-0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x4f, 0x75,
-0x6a, 0x6f, 0xdf, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x68, 0x62,
-0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65, 0x72,
-0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0xe4, 0x62, 0x3b, 0x4d, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69,
-0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x75, 0x6a, 0x3b, 0x53, 0xe4, 0x70, 0x3b, 0x4f, 0x6b, 0x74,
-0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x44, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0xe1, 0x3b, 0x186, 0x25b, 0x6e,
-0x3b, 0x44, 0x6f, 0x79, 0x3b, 0x4c, 0xe9, 0x70, 0x3b, 0x52, 0x6f, 0x6b, 0x3b, 0x53, 0xe1, 0x73, 0x3b, 0x42, 0x254, 0x301,
-0x72, 0x3b, 0x4b, 0xfa, 0x73, 0x3b, 0x47, 0xed, 0x73, 0x3b, 0x53, 0x68, 0x289, 0x301, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x3b,
-0x4f, 0x6c, 0x61, 0x64, 0x61, 0x6c, 0x289, 0x301, 0x3b, 0x41, 0x72, 0xe1, 0x74, 0x3b, 0x186, 0x25b, 0x6e, 0x268, 0x301, 0x254,
-0x268, 0x14b, 0x254, 0x6b, 0x3b, 0x4f, 0x6c, 0x6f, 0x64, 0x6f, 0x79, 0xed, 0xf3, 0x72, 0xed, 0xea, 0x20, 0x69, 0x6e, 0x6b,
-0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4f, 0x6c, 0x6f, 0x69, 0x6c, 0xe9, 0x70, 0x16b, 0x6e, 0x79, 0x12b, 0x113, 0x20, 0x69, 0x6e,
-0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4b, 0xfa, 0x6a, 0xfa, 0x254, 0x72, 0x254, 0x6b, 0x3b, 0x4d, 0xf3, 0x72, 0x75, 0x73,
-0xe1, 0x73, 0x69, 0x6e, 0x3b, 0x186, 0x6c, 0x254, 0x301, 0x268, 0x301, 0x62, 0x254, 0x301, 0x72, 0xe1, 0x72, 0x25b, 0x3b, 0x4b,
-0xfa, 0x73, 0x68, 0xee, 0x6e, 0x3b, 0x4f, 0x6c, 0x67, 0xed, 0x73, 0x61, 0x6e, 0x3b, 0x50, 0x289, 0x73, 0x68, 0x289, 0x301,
-0x6b, 0x61, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x14b, 0x289, 0x301, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b,
-0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b,
-0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b,
-0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b,
-0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4d, 0x75, 0x6b, 0x3b, 0x4b, 0x77, 0x61, 0x3b,
-0x44, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x6f, 0x64, 0x3b, 0x4a, 0x6f, 0x6c, 0x3b, 0x50, 0x65, 0x64, 0x3b,
-0x53, 0x6f, 0x6b, 0x3b, 0x54, 0x69, 0x62, 0x3b, 0x4c, 0x61, 0x62, 0x3b, 0x50, 0x6f, 0x6f, 0x3b, 0x4f, 0x72, 0x61, 0x72,
-0x61, 0x3b, 0x4f, 0x6d, 0x75, 0x6b, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x67, 0x2019, 0x3b, 0x4f, 0x64, 0x75, 0x6e, 0x67,
-0x2019, 0x65, 0x6c, 0x3b, 0x4f, 0x6d, 0x61, 0x72, 0x75, 0x6b, 0x3b, 0x4f, 0x6d, 0x6f, 0x64, 0x6f, 0x6b, 0x2019, 0x6b, 0x69,
-0x6e, 0x67, 0x2019, 0x6f, 0x6c, 0x3b, 0x4f, 0x6a, 0x6f, 0x6c, 0x61, 0x3b, 0x4f, 0x70, 0x65, 0x64, 0x65, 0x6c, 0x3b, 0x4f,
-0x73, 0x6f, 0x6b, 0x6f, 0x73, 0x6f, 0x6b, 0x6f, 0x6d, 0x61, 0x3b, 0x4f, 0x74, 0x69, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6c,
-0x61, 0x62, 0x6f, 0x72, 0x3b, 0x4f, 0x70, 0x6f, 0x6f, 0x3b, 0x52, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x44, 0x3b, 0x4d, 0x3b,
-0x4d, 0x3b, 0x4a, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x50, 0x3b, 0x17d, 0x61, 0x6e, 0x3b, 0x46, 0x65,
-0x65, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x77, 0x69, 0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x3b, 0x17d, 0x75, 0x79,
-0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x6f, 0x3b, 0x44, 0x65, 0x65, 0x3b,
-0x17d, 0x61, 0x6e, 0x77, 0x69, 0x79, 0x65, 0x3b, 0x46, 0x65, 0x65, 0x77, 0x69, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x4d, 0x61,
-0x72, 0x73, 0x69, 0x3b, 0x41, 0x77, 0x69, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x65, 0x14b, 0x3b,
-0x17d, 0x75, 0x79, 0x79, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x4f,
-0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x75, 0x72, 0x3b, 0x4e, 0x6f, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x44, 0x65,
-0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x17d, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x17d, 0x3b,
-0x17d, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44, 0x41, 0x43, 0x3b, 0x44, 0x41, 0x52, 0x3b,
-0x44, 0x41, 0x44, 0x3b, 0x44, 0x41, 0x4e, 0x3b, 0x44, 0x41, 0x48, 0x3b, 0x44, 0x41, 0x55, 0x3b, 0x44, 0x41, 0x4f, 0x3b,
-0x44, 0x41, 0x42, 0x3b, 0x44, 0x4f, 0x43, 0x3b, 0x44, 0x41, 0x50, 0x3b, 0x44, 0x47, 0x49, 0x3b, 0x44, 0x41, 0x47, 0x3b,
-0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d,
-0x61, 0x72, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x64, 0x65,
-0x6b, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x6e, 0x67, 0x2019, 0x77, 0x65, 0x6e, 0x3b, 0x44, 0x77,
-0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, 0x63, 0x68, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20,
-0x41, 0x75, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, 0x72,
-0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x6f, 0x72, 0x6f, 0x3b, 0x44, 0x77,
-0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4f, 0x63, 0x68, 0x69, 0x6b, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72,
-0x20, 0x41, 0x70, 0x61, 0x72, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x63, 0x68,
-0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x20, 0x67, 0x69, 0x20,
-0x61, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x43, 0x3b, 0x52, 0x3b, 0x44, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x55, 0x3b, 0x42, 0x3b,
-0x42, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61,
-0x72, 0x3b, 0x49, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75,
-0x63, 0x3b, 0x43, 0x75, 0x74, 0x3b, 0x4b, 0x1e6d, 0x75, 0x3b, 0x4e, 0x77, 0x61, 0x3b, 0x44, 0x75, 0x6a, 0x3b, 0x59, 0x65,
-0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x4d, 0x61, 0x72, 0x73,
-0x3b, 0x49, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59,
-0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b,
-0x4b, 0x1e6d, 0x75, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x77, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x44, 0x75, 0x6a, 0x61, 0x6e,
-0x62, 0x69, 0x72, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194, 0x3b,
-0x43, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x6c,
-0x75, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x6c, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x65,
-0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b,
-0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
-0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x941, 0x935, 0x93e, 0x930, 0x940,
-0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x938, 0x3b, 0x90f, 0x92b,
-0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x907, 0x3b, 0x906, 0x917,
-0x938, 0x94d, 0x925, 0x3b, 0x938, 0x947, 0x92c, 0x925, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x905, 0x916, 0x925, 0x92c, 0x930,
-0x3b, 0x928, 0x92c, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b,
-0x91c, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x3b, 0x91c, 0x941, 0x3b, 0x906,
-0x3b, 0x938, 0x947, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f, 0x3b, 0x456, 0x486, 0x430, 0x2de9, 0x487, 0x3b, 0x444, 0x435, 0x2de1,
-0x487, 0x3b, 0x43c, 0x430, 0x2dec, 0x487, 0x3b, 0x430, 0x486, 0x43f, 0x2dec, 0x487, 0x3b, 0x43c, 0x430, 0xa675, 0x3b, 0x456, 0x486, 0xa64b,
-0x2de9, 0x487, 0x3b, 0x456, 0x486, 0xa64b, 0x2de7, 0x487, 0x3b, 0x430, 0x486, 0x301, 0x475, 0x2de2, 0x487, 0x3b, 0x441, 0x435, 0x2deb, 0x487,
-0x3b, 0x47b, 0x486, 0x43a, 0x2dee, 0x3b, 0x43d, 0x43e, 0x435, 0x2de8, 0x3b, 0x434, 0x435, 0x2de6, 0x487, 0x3b, 0x456, 0x486, 0x430, 0x43d,
-0x43d, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x439, 0x3b, 0x444, 0x435, 0x432, 0x440, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x439, 0x3b, 0x43c,
-0x430, 0x301, 0x440, 0x442, 0x44a, 0x3b, 0x430, 0x486, 0x43f, 0x440, 0x456, 0x301, 0x43b, 0x43b, 0x457, 0x439, 0x3b, 0x43c, 0x430, 0x301,
-0x457, 0x439, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43d, 0x457, 0x439, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43b, 0x457, 0x439, 0x3b, 0x430,
-0x486, 0x301, 0x475, 0x433, 0xa64b, 0x441, 0x442, 0x44a, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x439,
-0x3b, 0x47b, 0x486, 0x43a, 0x442, 0x461, 0x301, 0x432, 0x440, 0x457, 0x439, 0x3b, 0x43d, 0x43e, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457,
-0x439, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x439, 0x3b, 0x406, 0x486, 0x3b, 0x424, 0x3b, 0x41c, 0x3b,
-0x410, 0x486, 0x3b, 0x41c, 0x3b, 0x406, 0x486, 0x3b, 0x406, 0x486, 0x3b, 0x410, 0x486, 0x3b, 0x421, 0x3b, 0x47a, 0x486, 0x3b, 0x41d,
-0x3b, 0x414, 0x3b, 0x456, 0x486, 0x430, 0x43d, 0x43d, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x430, 0x3b, 0x444, 0x435, 0x432, 0x440, 0xa64b,
-0x430, 0x301, 0x440, 0x457, 0x430, 0x3b, 0x43c, 0x430, 0x301, 0x440, 0x442, 0x430, 0x3b, 0x430, 0x486, 0x43f, 0x440, 0x456, 0x301, 0x43b,
-0x43b, 0x457, 0x430, 0x3b, 0x43c, 0x430, 0x301, 0x457, 0x430, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43d, 0x457, 0x430, 0x3b, 0x456, 0x486,
-0xa64b, 0x301, 0x43b, 0x457, 0x430, 0x3b, 0x430, 0x486, 0x301, 0x475, 0x433, 0xa64b, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43f, 0x442,
-0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x47b, 0x486, 0x43a, 0x442, 0x461, 0x301, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x43d,
-0x43e, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b,
-0x43, 0x69, 0x6f, 0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x4c, 0x75, 0x73, 0x3b, 0x4d, 0x75, 0x75, 0x3b, 0x4c, 0x75, 0x6d, 0x3b,
-0x4c, 0x75, 0x66, 0x3b, 0x4b, 0x61, 0x62, 0x3b, 0x4c, 0x75, 0x73, 0x68, 0x3b, 0x4c, 0x75, 0x74, 0x3b, 0x4c, 0x75, 0x6e,
-0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x43, 0x69, 0x73, 0x3b, 0x43, 0x69, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0xf9, 0x69, 0x73,
-0x68, 0x69, 0x3b, 0x4c, 0x75, 0x73, 0xf2, 0x6c, 0x6f, 0x3b, 0x4d, 0xf9, 0x75, 0x79, 0xe0, 0x3b, 0x4c, 0x75, 0x6d, 0xf9,
-0x6e, 0x67, 0xf9, 0x6c, 0xf9, 0x3b, 0x4c, 0x75, 0x66, 0x75, 0x69, 0x6d, 0x69, 0x3b, 0x4b, 0x61, 0x62, 0xe0, 0x6c, 0xe0,
-0x73, 0x68, 0xec, 0x70, 0xf9, 0x3b, 0x4c, 0xf9, 0x73, 0x68, 0xec, 0x6b, 0xe0, 0x3b, 0x4c, 0x75, 0x74, 0x6f, 0x6e, 0x67,
-0x6f, 0x6c, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x67, 0xf9, 0x64, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x77, 0xe8, 0x6b, 0xe8, 0x73,
-0xe8, 0x3b, 0x43, 0x69, 0x73, 0x77, 0xe0, 0x3b, 0x43, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b,
-0x4b, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b,
-0x4d, 0xe4, 0x65, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b,
-0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b,
-0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x65, 0x72, 0x7a,
-0x3b, 0x41, 0x62, 0x72, 0xeb, 0x6c, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c,
-0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f,
-0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65,
-0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x65, 0x2e, 0x3b,
-0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41,
-0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44,
-0x65, 0x7a, 0x2e, 0x3b, 0x6e, 0xf9, 0x6d, 0x3b, 0x6b, 0x268, 0x7a, 0x3b, 0x74, 0x268, 0x64, 0x3b, 0x74, 0x61, 0x61, 0x3b,
-0x73, 0x65, 0x65, 0x3b, 0x6e, 0x7a, 0x75, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x66, 0x254, 0x65, 0x3b, 0x64, 0x7a, 0x75, 0x3b,
-0x6c, 0x254, 0x6d, 0x3b, 0x6b, 0x61, 0x61, 0x3b, 0x66, 0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300,
-0x6e, 0xf9, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6b, 0x197, 0x300, 0x7a, 0xf9, 0x294, 0x3b, 0x6e,
-0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197, 0x300, 0x64, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x3b, 0x6e, 0x64, 0x7a,
-0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x1ce, 0x61, 0x66, 0x289, 0x304, 0x67, 0x68, 0x101, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
-0x14b, 0xe8, 0x73, 0xe8, 0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6e, 0x7a, 0xf9, 0x67, 0x68, 0xf2,
-0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x64, 0xf9, 0x6d, 0x6c, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
-0x14b, 0x254, 0x300, 0x6b, 0x77, 0xee, 0x66, 0x254, 0x300, 0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74,
-0x197, 0x300, 0x66, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x64, 0x7a, 0x75, 0x67, 0x68, 0xf9, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
-0x14b, 0x254, 0x300, 0x67, 0x68, 0x1d4, 0x75, 0x77, 0x65, 0x6c, 0x254, 0x300, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b,
-0x254, 0x300, 0x63, 0x68, 0x77, 0x61, 0x294, 0xe0, 0x6b, 0x61, 0x61, 0x20, 0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
-0x14b, 0xe8, 0x66, 0x77, 0xf2, 0x6f, 0x3b, 0x6e, 0x3b, 0x6b, 0x3b, 0x74, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x6b,
-0x3b, 0x66, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x63, 0x3b, 0x66, 0x3b, 0x6b, 0x254, 0x6e, 0x3b, 0x6d, 0x61, 0x63, 0x3b, 0x6d,
-0x61, 0x74, 0x3b, 0x6d, 0x74, 0x6f, 0x3b, 0x6d, 0x70, 0x75, 0x3b, 0x68, 0x69, 0x6c, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x68,
-0x69, 0x6b, 0x3b, 0x64, 0x69, 0x70, 0x3b, 0x62, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6c, 0x69, 0x253, 0x3b, 0x4b,
-0x254, 0x6e, 0x64, 0x254, 0x14b, 0x3b, 0x4d, 0xe0, 0x63, 0x25b, 0x302, 0x6c, 0x3b, 0x4d, 0xe0, 0x74, 0xf9, 0x6d, 0x62, 0x3b,
-0x4d, 0xe0, 0x74, 0x6f, 0x70, 0x3b, 0x4d, 0x300, 0x70, 0x75, 0x79, 0x25b, 0x3b, 0x48, 0xec, 0x6c, 0xf2, 0x6e, 0x64, 0x25b,
-0x300, 0x3b, 0x4e, 0x6a, 0xe8, 0x62, 0xe0, 0x3b, 0x48, 0xec, 0x6b, 0x61, 0x14b, 0x3b, 0x44, 0xec, 0x70, 0x254, 0x300, 0x73,
-0x3b, 0x42, 0xec, 0xf2, 0xf4, 0x6d, 0x3b, 0x4d, 0xe0, 0x79, 0x25b, 0x73, 0xe8, 0x70, 0x3b, 0x4c, 0xec, 0x62, 0x75, 0x79,
-0x20, 0x6c, 0x69, 0x20, 0x144, 0x79, 0xe8, 0x65, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x68,
-0x3b, 0x6e, 0x3b, 0x68, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x6d, 0x3b, 0x6c, 0x3b, 0x64, 0x69, 0x3b, 0x14b, 0x67, 0x254, 0x6e,
-0x3b, 0x73, 0x254, 0x14b, 0x3b, 0x64, 0x69, 0x253, 0x3b, 0x65, 0x6d, 0x69, 0x3b, 0x65, 0x73, 0x254, 0x3b, 0x6d, 0x61, 0x64,
-0x3b, 0x64, 0x69, 0x14b, 0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x74, 0x69, 0x6e, 0x3b, 0x65, 0x6c,
-0xe1, 0x3b, 0x64, 0x69, 0x6d, 0x254, 0x301, 0x64, 0x69, 0x3b, 0x14b, 0x67, 0x254, 0x6e, 0x64, 0x25b, 0x3b, 0x73, 0x254, 0x14b,
-0x25b, 0x3b, 0x64, 0x69, 0x253, 0xe1, 0x253, 0xe1, 0x3b, 0x65, 0x6d, 0x69, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x3b, 0x65, 0x73,
-0x254, 0x70, 0x25b, 0x73, 0x254, 0x70, 0x25b, 0x3b, 0x6d, 0x61, 0x64, 0x69, 0x253, 0x25b, 0x301, 0x64, 0xed, 0x253, 0x25b, 0x301,
-0x3b, 0x64, 0x69, 0x14b, 0x67, 0x69, 0x6e, 0x64, 0x69, 0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x25b, 0x6b, 0x69, 0x3b, 0x6d, 0x61,
-0x79, 0xe9, 0x73, 0x25b, 0x301, 0x3b, 0x74, 0x69, 0x6e, 0xed, 0x6e, 0xed, 0x3b, 0x65, 0x6c, 0xe1, 0x14b, 0x67, 0x25b, 0x301,
-0x3b, 0x64, 0x3b, 0x14b, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x65, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x64, 0x3b, 0x6e, 0x3b, 0x6d,
-0x3b, 0x74, 0x3b, 0x65, 0x3b, 0x53, 0x61, 0x3b, 0x46, 0x65, 0x3b, 0x4d, 0x61, 0x3b, 0x41, 0x62, 0x3b, 0x4d, 0x65, 0x3b,
-0x53, 0x75, 0x3b, 0x53, 0xfa, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x3b, 0x4f, 0x6b, 0x3b, 0x4e, 0x6f, 0x3b, 0x44, 0x65,
-0x3b, 0x53, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x46, 0xe9, 0x62, 0x69, 0x72, 0x69, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73,
-0x3b, 0x41, 0x62, 0x75, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x53, 0x75, 0x65, 0x14b, 0x3b, 0x53, 0xfa, 0x75,
-0x79, 0x65, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6b, 0x74,
-0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x61, 0x6d, 0x62,
-0x61, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x55, 0x3b, 0x53,
-0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6e, 0x67, 0x6f, 0x3b, 0x6e, 0x67, 0x62, 0x3b, 0x6e, 0x67, 0x6c, 0x3b, 0x6e,
-0x67, 0x6e, 0x3b, 0x6e, 0x67, 0x74, 0x3b, 0x6e, 0x67, 0x73, 0x3b, 0x6e, 0x67, 0x7a, 0x3b, 0x6e, 0x67, 0x6d, 0x3b, 0x6e,
-0x67, 0x65, 0x3b, 0x6e, 0x67, 0x61, 0x3b, 0x6e, 0x67, 0x61, 0x64, 0x3b, 0x6e, 0x67, 0x61, 0x62, 0x3b, 0x6e, 0x67, 0x254,
-0x6e, 0x20, 0x6f, 0x73, 0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20,
-0x6c, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6e, 0x79, 0x69, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e,
-0x20, 0x74, 0xe1, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x73, 0x61, 0x6d, 0x259, 0x6e, 0x61, 0x3b, 0x6e, 0x67,
-0x254, 0x6e, 0x20, 0x7a, 0x61, 0x6d, 0x67, 0x62, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6d, 0x77, 0x6f,
-0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x65, 0x62, 0x75, 0x6c, 0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77,
-0xf3, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x20, 0x61, 0x69, 0x20, 0x64, 0x7a, 0x69, 0xe1,
-0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x20, 0x61, 0x69, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6f, 0x3b,
-0x62, 0x3b, 0x6c, 0x3b, 0x6e, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x61, 0x3b, 0x64, 0x3b,
-0x62, 0x3b, 0x14b, 0x31, 0x3b, 0x14b, 0x32, 0x3b, 0x14b, 0x33, 0x3b, 0x14b, 0x34, 0x3b, 0x14b, 0x35, 0x3b, 0x14b, 0x36, 0x3b,
-0x14b, 0x37, 0x3b, 0x14b, 0x38, 0x3b, 0x14b, 0x39, 0x3b, 0x14b, 0x31, 0x30, 0x3b, 0x14b, 0x31, 0x31, 0x3b, 0x14b, 0x31, 0x32,
-0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x20, 0x6e, 0x74, 0x254, 0x301, 0x6e, 0x74, 0x254, 0x3b, 0x14b, 0x77, 0xed, 0xed,
-0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x62, 0x25b, 0x301, 0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x72,
-0xe1, 0xe1, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed,
-0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74,
-0xe1, 0x61, 0x66, 0x254, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x62, 0x25b,
-0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x72, 0x61, 0x61, 0x3b, 0x14b, 0x77,
-0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61,
-0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b,
-0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x254, 0x301, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e,
-0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x25b, 0x301, 0x25b, 0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x55, 0x6e, 0x61, 0x3b,
-0x52, 0x61, 0x72, 0x3b, 0x43, 0x68, 0x65, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x4d, 0x6f, 0x63, 0x3b, 0x53, 0x61, 0x62, 0x3b,
-0x4e, 0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b, 0x4d, 0x6f, 0x6a, 0x3b, 0x59, 0x65, 0x6c, 0x3b,
-0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72,
-0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x61, 0x79, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
-0x6f, 0x20, 0x75, 0x6e, 0x65, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75,
-0x6e, 0x65, 0x63, 0x68, 0x65, 0x73, 0x68, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e,
-0x65, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x6e,
-0x75, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x63, 0x68, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20,
-0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d,
-0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
-0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69,
-0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75,
-0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x79, 0x65, 0x6c, 0x2019, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x55, 0x3b, 0x52, 0x3b, 0x43,
-0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x46, 0x4c, 0x4f,
-0x3b, 0x43, 0x4c, 0x41, 0x3b, 0x43, 0x4b, 0x49, 0x3b, 0x46, 0x4d, 0x46, 0x3b, 0x4d, 0x41, 0x44, 0x3b, 0x4d, 0x42, 0x49,
-0x3b, 0x4d, 0x4c, 0x49, 0x3b, 0x4d, 0x41, 0x4d, 0x3b, 0x46, 0x44, 0x45, 0x3b, 0x46, 0x4d, 0x55, 0x3b, 0x46, 0x47, 0x57,
-0x3b, 0x46, 0x59, 0x55, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4c, 0x6f, 0x6f, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, 0x61, 0x6b,
-0x6c, 0x61, 0x14b, 0x6e, 0x65, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, 0x61, 0x6b, 0x6c, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69,
-0x20, 0x4d, 0x61, 0x72, 0x66, 0x6f, 0x6f, 0x3b, 0x4d, 0x61, 0x64, 0x1dd, 0x1dd, 0x75, 0x75, 0x74, 0x1dd, 0x62, 0x69, 0x6a,
-0x61, 0x14b, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x66, 0x61, 0x68, 0x62, 0x69, 0x69, 0x3b, 0x4d,
-0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x6c, 0x69, 0x69, 0x3b, 0x4d, 0x61, 0x64, 0x1dd, 0x6d, 0x62, 0x69, 0x69,
-0x3b, 0x46, 0x129, 0x69, 0x20, 0x44, 0x1dd, 0x253, 0x6c, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x75, 0x6e, 0x64,
-0x61, 0x14b, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x47, 0x77, 0x61, 0x68, 0x6c, 0x6c, 0x65, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x59,
-0x75, 0x72, 0x75, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b,
-0x45, 0x3b, 0x55, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x6e, 0x67, 0x31, 0x3b, 0x6e, 0x67, 0x32, 0x3b, 0x6e, 0x67, 0x33, 0x3b,
-0x6e, 0x67, 0x34, 0x3b, 0x6e, 0x67, 0x35, 0x3b, 0x6e, 0x67, 0x36, 0x3b, 0x6e, 0x67, 0x37, 0x3b, 0x6e, 0x67, 0x38, 0x3b,
-0x6e, 0x67, 0x39, 0x3b, 0x6e, 0x67, 0x31, 0x30, 0x3b, 0x6e, 0x67, 0x31, 0x31, 0x3b, 0x6b, 0x72, 0x69, 0x73, 0x3b, 0x6e,
-0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0xe1, 0x68, 0x72, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144,
-0x6d, 0x62, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6c, 0x61, 0x6c, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e,
-0x20, 0x144, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x74, 0x61, 0x6e, 0x3b, 0x6e, 0x67, 0x77, 0x25b,
-0x6e, 0x20, 0x144, 0x74, 0x75, 0xf3, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x68, 0x25b, 0x6d, 0x62, 0x75, 0x25b, 0x72,
-0xed, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6c, 0x254, 0x6d, 0x62, 0x69, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20,
-0x72, 0x25b, 0x62, 0x76, 0x75, 0xe2, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x3b, 0x6e, 0x67, 0x77,
-0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x20, 0x6e, 0x61, 0x76, 0x1d4, 0x72, 0x3b, 0x6b, 0x72, 0xed, 0x73, 0x69, 0x6d, 0x69,
-0x6e, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x3b, 0x50, 0x25b, 0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331, 0x3b, 0x47, 0x75,
-0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x3b, 0x4b, 0x6f, 0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x54, 0x68, 0x6f, 0x6f, 0x3b,
-0x54, 0x25b, 0x25b, 0x3b, 0x4c, 0x61, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x54, 0x69, 0x64, 0x3b, 0x54, 0x69, 0x6f, 0x70,
-0x20, 0x74, 0x68, 0x61, 0x72, 0x20, 0x70, 0x25b, 0x74, 0x3b, 0x50, 0x25b, 0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331,
-0x14b, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x74, 0x3b, 0x4b, 0x6f, 0x72, 0x6e, 0x79, 0x6f, 0x6f, 0x74,
-0x3b, 0x50, 0x61, 0x79, 0x20, 0x79, 0x69, 0x65, 0x331, 0x74, 0x6e, 0x69, 0x3b, 0x54, 0x68, 0x6f, 0x331, 0x6f, 0x331, 0x72,
-0x3b, 0x54, 0x25b, 0x25b, 0x72, 0x3b, 0x4c, 0x61, 0x61, 0x74, 0x68, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x54, 0x69, 0x6f, 0x331,
-0x70, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x331, 0x69, 0x331, 0x74, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x44, 0x3b, 0x47, 0x3b,
-0x44, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x422, 0x43e, 0x445, 0x441,
-0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x3b, 0x41a, 0x43b, 0x43d, 0x3b, 0x41c, 0x441, 0x443, 0x3b, 0x42b, 0x430, 0x43c, 0x3b, 0x411, 0x44d,
-0x441, 0x3b, 0x41e, 0x442, 0x439, 0x3b, 0x410, 0x442, 0x440, 0x3b, 0x411, 0x43b, 0x495, 0x3b, 0x410, 0x43b, 0x442, 0x3b, 0x421, 0x44d,
-0x442, 0x3b, 0x410, 0x445, 0x441, 0x3b, 0x442, 0x43e, 0x445, 0x441, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x43e, 0x43b, 0x443, 0x43d,
-0x43d, 0x44c, 0x443, 0x3b, 0x43a, 0x443, 0x43b, 0x443, 0x43d, 0x20, 0x442, 0x443, 0x442, 0x430, 0x440, 0x3b, 0x43c, 0x443, 0x443, 0x441,
-0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x44b, 0x430, 0x43c, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x431, 0x44d, 0x441, 0x20, 0x44b,
-0x439, 0x430, 0x3b, 0x43e, 0x442, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x430, 0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b,
-0x439, 0x430, 0x3b, 0x431, 0x430, 0x43b, 0x430, 0x495, 0x430, 0x43d, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x430, 0x43b, 0x442, 0x44b, 0x43d,
-0x43d, 0x44c, 0x44b, 0x3b, 0x441, 0x44d, 0x442, 0x438, 0x43d, 0x43d, 0x44c, 0x438, 0x3b, 0x430, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c,
-0x44b, 0x3b, 0x422, 0x3b, 0x41e, 0x3b, 0x41a, 0x3b, 0x41c, 0x3b, 0x42b, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x410, 0x3b, 0x411, 0x3b,
-0x410, 0x3b, 0x421, 0x3b, 0x410, 0x3b, 0x422, 0x43e, 0x445, 0x441, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41e, 0x43b, 0x443, 0x43d,
-0x43d, 0x44c, 0x443, 0x3b, 0x41a, 0x443, 0x43b, 0x443, 0x43d, 0x20, 0x442, 0x443, 0x442, 0x430, 0x440, 0x3b, 0x41c, 0x443, 0x443, 0x441,
-0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x42b, 0x430, 0x43c, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x44d, 0x441, 0x20,
-0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x41e, 0x442, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b,
-0x445, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x430, 0x43b, 0x430, 0x495, 0x430, 0x43d, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b,
-0x410, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x421, 0x44d, 0x442, 0x438, 0x43d, 0x43d, 0x44c, 0x438, 0x3b, 0x430, 0x445,
-0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x4d, 0x75, 0x70, 0x3b, 0x4d, 0x77, 0x69, 0x3b, 0x4d, 0x73, 0x68, 0x3b, 0x4d,
-0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x67, 0x3b, 0x4d, 0x75, 0x6a, 0x3b, 0x4d, 0x73, 0x70, 0x3b, 0x4d, 0x70, 0x67, 0x3b, 0x4d,
-0x79, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x3b, 0x4d, 0x75, 0x73, 0x3b, 0x4d, 0x75, 0x68, 0x3b, 0x4d, 0x75, 0x70, 0x61, 0x6c,
-0x61, 0x6e, 0x67, 0x75, 0x6c, 0x77, 0x61, 0x3b, 0x4d, 0x77, 0x69, 0x74, 0x6f, 0x70, 0x65, 0x3b, 0x4d, 0x75, 0x73, 0x68,
-0x65, 0x6e, 0x64, 0x65, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x20,
-0x4d, 0x61, 0x67, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x75, 0x6a, 0x69, 0x6d, 0x62, 0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x69,
-0x70, 0x65, 0x70, 0x6f, 0x3b, 0x4d, 0x75, 0x70, 0x75, 0x67, 0x75, 0x74, 0x6f, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x65, 0x6e,
-0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x68, 0x75, 0x3b, 0x4d, 0x75, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x6d,
-0x62, 0x77, 0x65, 0x3b, 0x4d, 0x75, 0x68, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0xa5a8, 0xa56a, 0xa583, 0x20, 0xa51e, 0xa56e, 0x3b, 0xa552,
-0xa561, 0xa59d, 0xa595, 0x3b, 0xa57e, 0xa5ba, 0x3b, 0xa5a2, 0xa595, 0x3b, 0xa591, 0xa571, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0xa5db, 0xa515, 0x3b,
-0xa562, 0xa54c, 0x3b, 0xa56d, 0xa583, 0x3b, 0xa51e, 0xa60b, 0xa554, 0xa57f, 0x20, 0xa578, 0xa583, 0xa5cf, 0x3b, 0xa5a8, 0xa56a, 0xa571, 0x20, 0xa5cf,
-0xa56e, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6b, 0x65, 0x6d, 0xe3, 0x3b, 0x253, 0x61, 0x6e, 0x64, 0x61, 0x253,
+0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x3b, 0x52, 0x68, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d,
+0x3b, 0x46, 0x65, 0x77, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x77, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x53, 0x75, 0x77,
+0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0xe0, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x77, 0x3b,
+0x44, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x77, 0x69, 0x79, 0x65, 0x65, 0x3b, 0x46, 0x65, 0x77, 0x72, 0x69, 0x79, 0x65,
+0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x77, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x53, 0x75, 0x77,
+0x65, 0x3b, 0x53, 0x75, 0x6c, 0x65, 0x74, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0xe0, 0x74, 0x74, 0x75, 0x6d, 0x62, 0x61, 0x72,
+0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x77, 0xe0, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44,
+0x65, 0x73, 0xe0, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x5d9, 0x5d0, 0x5b7, 0x5e0, 0x3b, 0x5e4, 0x5bf, 0x5e2, 0x5d1, 0x3b, 0x5de, 0x5e2,
+0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5b7, 0x5e4, 0x5bc, 0x5e8, 0x3b, 0x5de, 0x5d9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5,
+0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d9, 0x5d2, 0x3b, 0x5e1, 0x5e2, 0x5e4, 0x5bc, 0x3b, 0x5d0, 0x5e7, 0x5d8, 0x3b, 0x5e0, 0x5d0, 0x5d5,
+0x5d5, 0x3b, 0x5d3, 0x5e2, 0x5e6, 0x3b, 0x5d9, 0x5d0, 0x5b7, 0x5e0, 0x5d5, 0x5d0, 0x5b7, 0x5e8, 0x3b, 0x5e4, 0x5bf, 0x5e2, 0x5d1, 0x5e8,
+0x5d5, 0x5d0, 0x5b7, 0x5e8, 0x3b, 0x5de, 0x5e2, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5b7, 0x5e4, 0x5bc, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d9,
+0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d9, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b,
+0x5e1, 0x5e2, 0x5e4, 0x5bc, 0x5d8, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5d0, 0x5e7, 0x5d8, 0x5d0, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5e0,
+0x5d0, 0x5d5, 0x5d5, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5d3, 0x5e2, 0x5e6, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x1e62, 0x1eb9,
+0x301, 0x72, 0x1eb9, 0x301, 0x3b, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67,
+0x62, 0xe9, 0x3b, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x1eb9, 0x6d,
+0x1ecd, 0x3b, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b,
+0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1e62, 0x1eb9, 0x301, 0x72, 0x1eb9,
+0x301, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x72, 0x1eb9, 0x300,
+0x6e, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x300, 0x62, 0x69,
+0x62, 0x69, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x41, 0x67, 0x1eb9,
+0x6d, 0x1ecd, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x4f, 0x77, 0x65, 0x77,
+0x65, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x42, 0xe9, 0x6c,
+0xfa, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b,
+0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x190, 0x72, 0x25b, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x190, 0x300,
+0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x25b, 0x6d, 0x254, 0x3b, 0xd2, 0x67, 0xfa,
+0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42, 0xe9, 0x6c, 0xfa, 0x3b,
+0x186, 0x300, 0x70, 0x25b, 0x300, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, 0x4f,
+0x73, 0x68, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x72, 0x25b, 0x300, 0x6e,
+0xe0, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x300, 0x62,
+0x69, 0x62, 0x69, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20,
+0x41, 0x67, 0x25b, 0x6d, 0x254, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x73, 0x68, 0xf9,
+0x20, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f,
+0x73, 0x68, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x70, 0x25b, 0x300, 0x3b,
+0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x73, 0x3b, 0x45, 0x70, 0x68, 0x3b, 0x4d, 0x65, 0x79, 0x3b,
+0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b,
+0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62,
+0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x68, 0x72, 0x65, 0x6c, 0x69,
+0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67,
+0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f,
+0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a,
+0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e,
+0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70,
+0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67,
+0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73,
+0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72,
+0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c,
+0x69, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f,
+0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65,
+0x6d, 0x62, 0x61, 0x72, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440,
+0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x443, 0x433, 0x3b, 0x441, 0x435, 0x43f,
+0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b,
+0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c,
+0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x443, 0x433, 0x443, 0x441, 0x442, 0x3b,
+0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e,
+0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x4a, 0x2d, 0x67, 0x75,
+0x65, 0x72, 0x3b, 0x54, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76,
+0x72, 0x72, 0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65,
+0x65, 0x3b, 0x4a, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x79, 0x6e,
+0x3b, 0x4d, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d,
+0x2d, 0x48, 0x6f, 0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x2d, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x4a, 0x65,
+0x72, 0x72, 0x65, 0x79, 0x2d, 0x67, 0x65, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x54, 0x6f, 0x73, 0x68, 0x69, 0x61, 0x67, 0x68,
+0x74, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x65, 0x72, 0x69,
+0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65,
+0x65, 0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e,
+0x69, 0x73, 0x74, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x65,
+0x72, 0x72, 0x65, 0x79, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x48, 0x6f, 0x75, 0x6e,
+0x65, 0x79, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x6e, 0x79, 0x20, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x47, 0x65,
+0x6e, 0x3b, 0x48, 0x77, 0x65, 0x3b, 0x4d, 0x65, 0x75, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x3b, 0x4d, 0x65, 0x74,
+0x3b, 0x47, 0x6f, 0x72, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x6e, 0x3b, 0x48, 0x65, 0x64, 0x3b, 0x44, 0x75, 0x3b,
+0x4b, 0x65, 0x76, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x48,
+0x77, 0x65, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, 0x75, 0x72, 0x74, 0x68, 0x3b, 0x6d, 0x69,
+0x73, 0x20, 0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d,
+0x65, 0x74, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x65,
+0x6e, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x45, 0x73, 0x74, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x77, 0x79, 0x6e, 0x6e, 0x67,
+0x61, 0x6c, 0x61, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x48, 0x65, 0x64, 0x72, 0x61, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x44, 0x75,
+0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4b, 0x65, 0x76, 0x61, 0x72, 0x64, 0x68, 0x75, 0x3b, 0x53, 0x2d, 0x186, 0x3b, 0x4b, 0x2d,
+0x186, 0x3b, 0x45, 0x2d, 0x186, 0x3b, 0x45, 0x2d, 0x4f, 0x3b, 0x45, 0x2d, 0x4b, 0x3b, 0x4f, 0x2d, 0x41, 0x3b, 0x41, 0x2d,
+0x4b, 0x3b, 0x44, 0x2d, 0x186, 0x3b, 0x46, 0x2d, 0x190, 0x3b, 0x186, 0x2d, 0x41, 0x3b, 0x186, 0x2d, 0x4f, 0x3b, 0x4d, 0x2d,
+0x186, 0x3b, 0x53, 0x61, 0x6e, 0x64, 0x61, 0x2d, 0x186, 0x70, 0x25b, 0x70, 0x254, 0x6e, 0x3b, 0x4b, 0x77, 0x61, 0x6b, 0x77,
+0x61, 0x72, 0x2d, 0x186, 0x67, 0x79, 0x65, 0x66, 0x75, 0x6f, 0x3b, 0x45, 0x62, 0x254, 0x77, 0x2d, 0x186, 0x62, 0x65, 0x6e,
+0x65, 0x6d, 0x3b, 0x45, 0x62, 0x254, 0x62, 0x69, 0x72, 0x61, 0x2d, 0x4f, 0x66, 0x6f, 0x72, 0x69, 0x73, 0x75, 0x6f, 0x3b,
+0x45, 0x73, 0x75, 0x73, 0x6f, 0x77, 0x20, 0x41, 0x6b, 0x65, 0x74, 0x73, 0x65, 0x61, 0x62, 0x61, 0x2d, 0x4b, 0x254, 0x74,
+0x254, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x62, 0x69, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x41, 0x79, 0x25b, 0x77, 0x6f,
+0x68, 0x6f, 0x6d, 0x75, 0x6d, 0x75, 0x3b, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x2d, 0x4b, 0x69, 0x74, 0x61, 0x77,
+0x6f, 0x6e, 0x73, 0x61, 0x3b, 0x44, 0x69, 0x66, 0x75, 0x75, 0x2d, 0x186, 0x73, 0x61, 0x6e, 0x64, 0x61, 0x61, 0x3b, 0x46,
+0x61, 0x6e, 0x6b, 0x77, 0x61, 0x2d, 0x190, 0x62, 0x254, 0x3b, 0x186, 0x62, 0x25b, 0x73, 0x25b, 0x2d, 0x41, 0x68, 0x69, 0x6e,
+0x69, 0x6d, 0x65, 0x3b, 0x186, 0x62, 0x65, 0x72, 0x25b, 0x66, 0x25b, 0x77, 0x2d, 0x4f, 0x62, 0x75, 0x62, 0x75, 0x6f, 0x3b,
+0x4d, 0x75, 0x6d, 0x75, 0x2d, 0x186, 0x70, 0x25b, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e,
+0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b,
+0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x92f, 0x3b,
+0x906, 0x917, 0x94b, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x911, 0x915, 0x94d, 0x91f,
+0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c,
+0x930, 0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65,
+0x65, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x1ecc, 0x6b,
+0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x65, 0x6e, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x46,
+0x65, 0x62, 0x72, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x4d, 0x61, 0x61, 0x63, 0x68, 0x1ecb, 0x3b, 0x45, 0x70, 0x72, 0x65,
+0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x1ecb, 0x3b, 0x1ecc, 0x67, 0x1ecd,
+0x1ecd, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x1ecc, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b,
+0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4d, 0x62, 0x65, 0x3b,
+0x4b, 0x65, 0x6c, 0x3b, 0x4b, 0x74, 0x169, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x74, 0x6e, 0x3b, 0x54, 0x68, 0x61, 0x3b,
+0x4d, 0x6f, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x4b, 0x6e, 0x64, 0x3b, 0x128, 0x6b, 0x75, 0x3b, 0x128, 0x6b, 0x6d, 0x3b,
+0x128, 0x6b, 0x6c, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x65, 0x3b, 0x4d, 0x77, 0x61,
+0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61,
+0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77,
+0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61,
+0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d,
+0x75, 0x6f, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x79, 0x61, 0x61, 0x6e, 0x79,
+0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b,
+0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x129, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20,
+0x129, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6c, 0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b,
+0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x5a, 0x65, 0x6e,
+0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x76, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67,
+0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76,
+0x3b, 0x44, 0x69, 0x63, 0x3b, 0x5a, 0x65, 0x6e, 0xe2, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0xe2, 0x72, 0x3b, 0x4d, 0x61,
+0x72, 0xe7, 0x3b, 0x41, 0x76, 0x72, 0xee, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x6e, 0x3b, 0x4c, 0x75,
+0x69, 0x3b, 0x41, 0x76, 0x6f, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x74, 0x75,
+0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61,
+0x72, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b,
+0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x64, 0x7a, 0x76, 0x3b, 0x64, 0x7a, 0x64, 0x3b, 0x74, 0x65, 0x64, 0x3b, 0x61, 0x66,
+0x254, 0x3b, 0x64, 0x61, 0x6d, 0x3b, 0x6d, 0x61, 0x73, 0x3b, 0x73, 0x69, 0x61, 0x3b, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x6e,
+0x79, 0x3b, 0x6b, 0x65, 0x6c, 0x3b, 0x61, 0x64, 0x65, 0x3b, 0x64, 0x7a, 0x6d, 0x3b, 0x64, 0x7a, 0x6f, 0x76, 0x65, 0x3b,
+0x64, 0x7a, 0x6f, 0x64, 0x7a, 0x65, 0x3b, 0x74, 0x65, 0x64, 0x6f, 0x78, 0x65, 0x3b, 0x61, 0x66, 0x254, 0x66, 0x129, 0x65,
+0x3b, 0x64, 0x61, 0x6d, 0x61, 0x3b, 0x6d, 0x61, 0x73, 0x61, 0x3b, 0x73, 0x69, 0x61, 0x6d, 0x6c, 0x254, 0x6d, 0x3b, 0x64,
+0x65, 0x61, 0x73, 0x69, 0x61, 0x6d, 0x69, 0x6d, 0x65, 0x3b, 0x61, 0x6e, 0x79, 0x254, 0x6e, 0x79, 0x254, 0x3b, 0x6b, 0x65,
+0x6c, 0x65, 0x3b, 0x61, 0x64, 0x65, 0x25b, 0x6d, 0x65, 0x6b, 0x70, 0x254, 0x78, 0x65, 0x3b, 0x64, 0x7a, 0x6f, 0x6d, 0x65,
+0x3b, 0x64, 0x3b, 0x64, 0x3b, 0x74, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x61, 0x3b, 0x6b,
+0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x49, 0x61, 0x6e, 0x2e, 0x3b, 0x50, 0x65, 0x70, 0x2e, 0x3b, 0x4d, 0x61, 0x6c, 0x2e, 0x3b,
+0x2bb, 0x41, 0x70, 0x2e, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x2e, 0x3b, 0x49, 0x75, 0x6c, 0x2e, 0x3b, 0x2bb,
+0x41, 0x75, 0x2e, 0x3b, 0x4b, 0x65, 0x70, 0x2e, 0x3b, 0x2bb, 0x4f, 0x6b, 0x2e, 0x3b, 0x4e, 0x6f, 0x77, 0x2e, 0x3b, 0x4b,
+0x65, 0x6b, 0x2e, 0x3b, 0x49, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x50, 0x65, 0x70, 0x65, 0x6c, 0x75, 0x61, 0x6c,
+0x69, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x6b, 0x69, 0x3b, 0x2bb, 0x41, 0x70, 0x65, 0x6c, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x65,
+0x69, 0x3b, 0x49, 0x75, 0x6e, 0x65, 0x3b, 0x49, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x75, 0x6b, 0x61, 0x6b, 0x65,
+0x3b, 0x4b, 0x65, 0x70, 0x61, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x6b, 0x6f, 0x70, 0x61,
+0x3b, 0x4e, 0x6f, 0x77, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x4b, 0x65, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x45,
+0x6e, 0x65, 0x3b, 0x50, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48,
+0x75, 0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e,
+0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x50, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f,
+0x3b, 0x4d, 0x61, 0x72, 0x73, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x48, 0x75,
+0x6e, 0x79, 0x6f, 0x3b, 0x48, 0x75, 0x6c, 0x79, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74,
+0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x62, 0x79, 0x65,
+0x6d, 0x62, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x73, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x50, 0x3b, 0x4d,
+0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x48, 0x75, 0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74,
+0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b,
+0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d,
+0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x63, 0x68,
+0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72,
+0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xa2cd,
+0xa1aa, 0x3b, 0xa44d, 0xa1aa, 0x3b, 0xa315, 0xa1aa, 0x3b, 0xa1d6, 0xa1aa, 0x3b, 0xa26c, 0xa1aa, 0x3b, 0xa0d8, 0xa1aa, 0x3b, 0xa3c3, 0xa1aa, 0x3b,
+0xa246, 0xa1aa, 0x3b, 0xa22c, 0xa1aa, 0x3b, 0xa2b0, 0xa1aa, 0x3b, 0xa2b0, 0xa2aa, 0xa1aa, 0x3b, 0xa2b0, 0xa44b, 0xa1aa, 0x3b, 0x4a, 0x61, 0x6e,
+0x75, 0x61, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41,
+0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41,
+0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f,
+0x76, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65,
+0x72, 0x3b, 0x6f, 0x111, 0x111, 0x6a, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x3b, 0x63, 0x75, 0x6f,
+0x3b, 0x6d, 0x69, 0x65, 0x73, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x3b, 0x62, 0x6f, 0x72, 0x67,
+0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x3b, 0x6a, 0x75, 0x6f, 0x76,
+0x3b, 0x6f, 0x111, 0x111, 0x61, 0x6a, 0x61, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x76,
+0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x63,
+0x75, 0x6f, 0x14b, 0x6f, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e,
+0x75, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x64, 0x6e,
+0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x10d, 0x61,
+0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x67, 0x6f, 0x74, 0x6d, 0xe1, 0x6e, 0x6e,
+0x75, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x6d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0x61,
+0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x4f, 0x3b, 0x47, 0x3b, 0x4e, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x53, 0x3b,
+0x42, 0x3b, 0x10c, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x6f, 0x111, 0x111, 0x6a, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x3b,
+0x6e, 0x6a, 0x75, 0x6b, 0x3b, 0x63, 0x75, 0x6f, 0x14b, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x3b,
+0x73, 0x75, 0x6f, 0x69, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x3b,
+0x73, 0x6b, 0xe1, 0x62, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x3b, 0x43, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61,
+0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x43, 0x75, 0x6c, 0x3b, 0x41, 0x67,
+0x74, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x43, 0x68,
+0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68,
+0x69, 0x3b, 0x41, 0x70, 0x69, 0x72, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x43,
+0x68, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69,
+0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x43, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x43, 0x3b,
+0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x49, 0x6d, 0x62, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, 0x61,
+0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4b, 0x61, 0x72, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x57, 0x75,
+0x6e, 0x3b, 0x49, 0x6b, 0x65, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x77, 0x69, 0x3b, 0x4d, 0x6f,
+0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6d, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20,
+0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20,
+0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e,
+0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4d,
+0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x72, 0x61, 0x6e, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d,
+0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6d, 0x66, 0x75, 0x6e, 0x67, 0x61, 0x64, 0x65, 0x3b, 0x4d, 0x6f,
+0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x77, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x79, 0x61, 0x3b, 0x4d, 0x6f, 0x72,
+0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67,
+0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20,
+0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69,
+0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x77, 0x69, 0x3b, 0x49,
+0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49,
+0x3b, 0x49, 0x3b, 0x73, 0x69, 0x69, 0x3b, 0x63, 0x6f, 0x6c, 0x3b, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x64,
+0x75, 0x75, 0x3b, 0x6b, 0x6f, 0x72, 0x3b, 0x6d, 0x6f, 0x72, 0x3b, 0x6a, 0x75, 0x6b, 0x3b, 0x73, 0x6c, 0x74, 0x3b, 0x79,
+0x61, 0x72, 0x3b, 0x6a, 0x6f, 0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x3b, 0x73, 0x69, 0x69, 0x6c, 0x6f, 0x3b, 0x63, 0x6f, 0x6c,
+0x74, 0x65, 0x3b, 0x6d, 0x62, 0x6f, 0x6f, 0x79, 0x3b, 0x73, 0x65, 0x65, 0x257, 0x74, 0x6f, 0x3b, 0x64, 0x75, 0x75, 0x6a,
+0x61, 0x6c, 0x3b, 0x6b, 0x6f, 0x72, 0x73, 0x65, 0x3b, 0x6d, 0x6f, 0x72, 0x73, 0x6f, 0x3b, 0x6a, 0x75, 0x6b, 0x6f, 0x3b,
+0x73, 0x69, 0x69, 0x6c, 0x74, 0x6f, 0x3b, 0x79, 0x61, 0x72, 0x6b, 0x6f, 0x6d, 0x61, 0x61, 0x3b, 0x6a, 0x6f, 0x6c, 0x61,
+0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x74, 0x65, 0x3b, 0x73, 0x3b, 0x63, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x6b, 0x3b,
+0x6d, 0x3b, 0x6a, 0x3b, 0x73, 0x3b, 0x79, 0x3b, 0x6a, 0x3b, 0x62, 0x3b, 0x4a, 0x45, 0x4e, 0x3b, 0x57, 0x4b, 0x52, 0x3b,
+0x57, 0x47, 0x54, 0x3b, 0x57, 0x4b, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x57, 0x54, 0x44, 0x3b, 0x57, 0x4d, 0x4a, 0x3b,
+0x57, 0x4e, 0x4e, 0x3b, 0x57, 0x4b, 0x44, 0x3b, 0x57, 0x49, 0x4b, 0x3b, 0x57, 0x4d, 0x57, 0x3b, 0x44, 0x49, 0x54, 0x3b,
+0x4e, 0x6a, 0x65, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65,
+0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d,
+0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77,
+0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61,
+0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x169, 0x67,
+0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x6e,
+0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x65,
+0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61,
+0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4e, 0x64, 0x69, 0x74, 0x68,
+0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b,
+0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x44, 0x3b, 0x4f, 0x62, 0x6f, 0x3b, 0x57, 0x61, 0x61, 0x3b, 0x4f, 0x6b, 0x75,
+0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6d, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53, 0x61, 0x70, 0x3b, 0x49, 0x73, 0x69,
+0x3b, 0x53, 0x61, 0x61, 0x3b, 0x54, 0x6f, 0x6d, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x54, 0x6f, 0x77, 0x3b, 0x4c, 0x61, 0x70,
+0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x61,
+0x72, 0x65, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4c, 0x61, 0x70,
+0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65,
+0x20, 0x69, 0x6d, 0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x6c, 0x65, 0x3b, 0x4c, 0x61,
+0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69,
+0x73, 0x69, 0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x61, 0x6c, 0x3b, 0x4c, 0x61,
+0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20,
+0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f,
+0x6d, 0x6f, 0x6e, 0x20, 0x77, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4f, 0x3b, 0x57, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x49, 0x3b,
+0x49, 0x3b, 0x53, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65,
+0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75,
+0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65,
+0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d,
+0x61, 0x72, 0x63, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x68,
+0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65,
+0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f,
+0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x5a, 0x69, 0x62, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x3b, 0x4d,
+0x62, 0x69, 0x3b, 0x4d, 0x61, 0x62, 0x3b, 0x4e, 0x6b, 0x77, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x3b, 0x4e, 0x74, 0x75, 0x3b,
+0x4e, 0x63, 0x77, 0x3b, 0x4d, 0x70, 0x61, 0x6e, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x4d, 0x70, 0x61,
+0x6c, 0x3b, 0x5a, 0x69, 0x62, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x6c, 0x61, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x6c, 0x61, 0x6e,
+0x6a, 0x61, 0x3b, 0x4d, 0x62, 0x69, 0x6d, 0x62, 0x69, 0x74, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x62, 0x61, 0x73, 0x61, 0x3b,
+0x4e, 0x6b, 0x77, 0x65, 0x6e, 0x6b, 0x77, 0x65, 0x7a, 0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61,
+0x3b, 0x4e, 0x74, 0x75, 0x6c, 0x69, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x4e, 0x63, 0x77, 0x61, 0x62, 0x61, 0x6b, 0x61, 0x7a,
+0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6e, 0x64, 0x75, 0x6c, 0x61, 0x3b, 0x4d, 0x66, 0x75, 0x6d, 0x66, 0x75, 0x3b, 0x4c, 0x77,
+0x65, 0x7a, 0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6c, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x5a, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b,
+0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x31,
+0x3b, 0x4d, 0x32, 0x3b, 0x4d, 0x33, 0x3b, 0x4d, 0x34, 0x3b, 0x4d, 0x35, 0x3b, 0x4d, 0x36, 0x3b, 0x4d, 0x37, 0x3b, 0x4d,
+0x38, 0x3b, 0x4d, 0x39, 0x3b, 0x4d, 0x31, 0x30, 0x3b, 0x4d, 0x31, 0x31, 0x3b, 0x4d, 0x31, 0x32, 0x3b, 0x4d, 0x77, 0x65,
+0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
+0x61, 0x20, 0x6b, 0x61, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74,
+0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4d,
+0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
+0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61,
+0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b,
+0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e,
+0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d,
+0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x54,
+0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x3b, 0x2d31,
+0x2d55, 0x2d30, 0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x3b, 0x2d49, 0x2d31, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x3b, 0x2d62,
+0x2d53, 0x2d4d, 0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x3b, 0x2d3d, 0x2d5c, 0x2d53, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x3b, 0x2d37,
+0x2d53, 0x2d4a, 0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x2d30, 0x2d62, 0x2d54, 0x3b, 0x2d31, 0x2d55, 0x2d30, 0x2d62, 0x2d55, 0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x2d5a,
+0x3b, 0x2d49, 0x2d31, 0x2d54, 0x2d49, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x2d62, 0x2d53, 0x3b, 0x2d62,
+0x2d53, 0x2d4d, 0x2d62, 0x2d53, 0x2d63, 0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x2d5c, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b,
+0x2d3d, 0x2d5c, 0x2d53, 0x2d31, 0x2d54, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d37, 0x2d53, 0x2d4a, 0x2d30, 0x2d4f,
+0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d49, 0x3b, 0x2d31, 0x3b, 0x2d4e, 0x3b, 0x2d49, 0x3b, 0x2d4e, 0x3b, 0x2d62, 0x3b, 0x2d62, 0x3b, 0x2d56, 0x3b,
+0x2d5b, 0x3b, 0x2d3d, 0x3b, 0x2d4f, 0x3b, 0x2d37, 0x3b, 0x69, 0x6e, 0x6e, 0x3b, 0x62, 0x1e5b, 0x61, 0x3b, 0x6d, 0x61, 0x1e5b, 0x3b,
+0x69, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x263, 0x75, 0x63, 0x3b,
+0x63, 0x75, 0x74, 0x3b, 0x6b, 0x74, 0x75, 0x3b, 0x6e, 0x75, 0x77, 0x3b, 0x64, 0x75, 0x6a, 0x3b, 0x69, 0x6e, 0x6e, 0x61,
+0x79, 0x72, 0x3b, 0x62, 0x1e5b, 0x61, 0x79, 0x1e5b, 0x3b, 0x6d, 0x61, 0x1e5b, 0x1e63, 0x3b, 0x69, 0x62, 0x72, 0x69, 0x72, 0x3b,
+0x6d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x263,
+0x75, 0x63, 0x74, 0x3b, 0x63, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x3b, 0x6e,
+0x75, 0x77, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x64, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x69, 0x3b, 0x62,
+0x3b, 0x6d, 0x3b, 0x69, 0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x263, 0x3b, 0x63, 0x3b, 0x6b, 0x3b, 0x6e, 0x3b, 0x64,
+0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x46, 0x75, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x79,
+0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x62,
+0x3b, 0x57, 0x61, 0x6d, 0x3b, 0x44, 0x75, 0x6a, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x46, 0x75,
+0x1e5b, 0x61, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x72, 0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61,
+0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194, 0x75, 0x63, 0x74,
+0x3b, 0x43, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x57, 0x61, 0x6d, 0x62, 0x65,
+0x1e5b, 0x3b, 0x44, 0x75, 0x6a, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x4d,
+0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x46,
+0x75, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59,
+0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x62, 0x3b, 0x4e, 0x75, 0x6e, 0x3b, 0x44,
+0x75, 0x1e7, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x46, 0x75, 0x1e5b, 0x61, 0x72, 0x3b, 0x4d, 0x65,
+0x263, 0x72, 0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x59, 0x75,
+0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43, 0x74, 0x65, 0x6d, 0x62,
+0x65, 0x1e5b, 0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x4e, 0x75, 0x6e, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x44, 0x75,
+0x1e7, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x194, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4c,
+0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x52, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x4b, 0x42, 0x5a, 0x3b, 0x4b, 0x42, 0x52, 0x3b, 0x4b,
+0x53, 0x54, 0x3b, 0x4b, 0x4b, 0x4e, 0x3b, 0x4b, 0x54, 0x4e, 0x3b, 0x4b, 0x4d, 0x4b, 0x3b, 0x4b, 0x4d, 0x53, 0x3b, 0x4b,
+0x4d, 0x4e, 0x3b, 0x4b, 0x4d, 0x57, 0x3b, 0x4b, 0x4b, 0x4d, 0x3b, 0x4b, 0x4e, 0x4b, 0x3b, 0x4b, 0x4e, 0x42, 0x3b, 0x4f,
+0x6b, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x62, 0x69, 0x72,
+0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61,
+0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d,
+0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x6a, 0x75, 0x3b,
+0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x6e, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x77, 0x65, 0x6e,
+0x64, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75,
+0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x77, 0x65, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d,
+0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x48, 0x75, 0x74, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x44,
+0x61, 0x74, 0x3b, 0x54, 0x61, 0x69, 0x3b, 0x48, 0x61, 0x6e, 0x3b, 0x53, 0x69, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e,
+0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b, 0x4b, 0x6d, 0x6a, 0x3b, 0x4b, 0x6d, 0x62, 0x3b, 0x70,
+0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x68, 0x75, 0x74, 0x61, 0x6c, 0x61, 0x3b,
+0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x76, 0x69, 0x6c, 0x69,
+0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x64, 0x61, 0x74,
+0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x74, 0x61,
+0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x68, 0x61,
+0x6e, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x69, 0x74,
+0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61,
+0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b,
+0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x70,
+0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x70, 0x61,
+0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20,
+0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b,
+0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x48, 0x3b, 0x56, 0x3b, 0x44, 0x3b, 0x54,
+0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4a, 0x61, 0x6e,
+0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b,
+0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x69, 0x3b, 0x4a, 0x75,
+0x6c, 0x79, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61,
+0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65,
+0x6d, 0x62, 0x61, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x77, 0x69, 0x3b,
+0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x3b, 0x7a, 0x75, 0x6c, 0x3b, 0x75, 0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x3b, 0x254,
+0x6b, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x77, 0x75, 0x79, 0x65, 0x3b, 0x66,
+0x65, 0x62, 0x75, 0x72, 0x75, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b, 0x61, 0x77, 0x69, 0x72, 0x69,
+0x6c, 0x69, 0x3b, 0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x25b, 0x6e, 0x3b, 0x7a, 0x75, 0x6c, 0x75, 0x79, 0x65, 0x3b, 0x75,
+0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x254, 0x6b, 0x75, 0x74, 0x254, 0x62, 0x75,
+0x72, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75,
+0x72, 0x75, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x5a, 0x3b, 0x55, 0x3b, 0x53,
+0x3b, 0x186, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x62, 0x65, 0x3b, 0x4b, 0x61, 0x69, 0x3b, 0x4b, 0x61, 0x74, 0x3b, 0x4b,
+0x61, 0x6e, 0x3b, 0x47, 0x61, 0x74, 0x3b, 0x47, 0x61, 0x6e, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x4b, 0x6e, 0x6e, 0x3b, 0x4b,
+0x65, 0x6e, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x67, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b,
+0x61, 0x129, 0x72, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x68, 0x61, 0x74,
+0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72,
+0x69, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61,
+0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20,
+0x6d, 0x169, 0x67, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61,
+0x6e, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b,
+0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77,
+0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x4b, 0x61, 0x129, 0x72,
+0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b,
+0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x13a4, 0x13c3, 0x3b, 0x13a7, 0x13a6, 0x3b, 0x13a0, 0x13c5, 0x3b, 0x13a7, 0x13ec, 0x3b, 0x13a0, 0x13c2,
+0x3b, 0x13d5, 0x13ad, 0x3b, 0x13ab, 0x13f0, 0x3b, 0x13a6, 0x13b6, 0x3b, 0x13da, 0x13b5, 0x3b, 0x13da, 0x13c2, 0x3b, 0x13c5, 0x13d3, 0x3b, 0x13a5,
+0x13cd, 0x3b, 0x13a4, 0x13c3, 0x13b8, 0x13d4, 0x13c5, 0x3b, 0x13a7, 0x13a6, 0x13b5, 0x3b, 0x13a0, 0x13c5, 0x13f1, 0x3b, 0x13a7, 0x13ec, 0x13c2, 0x3b,
+0x13a0, 0x13c2, 0x13cd, 0x13ac, 0x13d8, 0x3b, 0x13d5, 0x13ad, 0x13b7, 0x13f1, 0x3b, 0x13ab, 0x13f0, 0x13c9, 0x13c2, 0x3b, 0x13a6, 0x13b6, 0x13c2, 0x3b,
+0x13da, 0x13b5, 0x13cd, 0x13d7, 0x3b, 0x13da, 0x13c2, 0x13c5, 0x13d7, 0x3b, 0x13c5, 0x13d3, 0x13d5, 0x13c6, 0x3b, 0x13a5, 0x13cd, 0x13a9, 0x13f1, 0x3b,
+0x13a4, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13d5, 0x3b, 0x13ab, 0x3b, 0x13a6, 0x3b, 0x13da, 0x3b, 0x13da, 0x3b,
+0x13c5, 0x3b, 0x13a5, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x76, 0x72, 0x3b,
+0x6d, 0x65, 0x3b, 0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f,
+0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x66, 0x65,
+0x76, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x3b,
+0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x79, 0x65, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x61, 0x6d,
+0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x3b, 0x6e, 0x6f, 0x76, 0x61, 0x6d, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6d, 0x3b, 0x7a,
+0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x7a, 0x3b, 0x7a, 0x3b, 0x6f, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e,
+0x3b, 0x64, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x4e, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64,
+0x69, 0x20, 0x77, 0x61, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x54,
+0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69,
+0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65,
+0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x6d, 0x6f, 0x3b,
+0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d,
+0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e,
+0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61,
+0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, 0x3b, 0x4d,
+0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e,
+0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f,
+0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x3b, 0x4d, 0x77, 0x65, 0x64,
+0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e,
+0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x3b, 0x46, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b, 0x4e, 0x61, 0x61, 0x6e, 0x268,
+0x3b, 0x4b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x49, 0x6b, 0xfa, 0x6d, 0x69, 0x3b, 0x49, 0x6e, 0x79, 0x61, 0x6d, 0x62,
+0x61, 0x6c, 0x61, 0x3b, 0x49, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b,
+0x56, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x53, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x49, 0x6e, 0x79, 0x69, 0x3b, 0x53, 0x61, 0x61,
+0x6e, 0x6f, 0x3b, 0x53, 0x61, 0x73, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x289, 0x66, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b,
+0x4b, 0x289, 0x6e, 0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, 0x289, 0x6b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4b, 0x77, 0x69,
+0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6e, 0x79, 0x61, 0x6d, 0x62, 0xe1, 0x6c, 0x61, 0x3b, 0x4b,
+0x77, 0x69, 0x69, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4b, 0x289, 0x6d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b,
+0x4b, 0x289, 0x76, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x77, 0x69, 0x69,
+0x6e, 0x79, 0x69, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x73, 0x61, 0x74, 0x289,
+0x3b, 0x46, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x49,
+0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x75,
+0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x62,
+0x3b, 0x4f, 0x6b, 0x69, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x77, 0x61, 0x6c, 0x69,
+0x79, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x77, 0x61, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b,
+0x41, 0x70, 0x75, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75,
+0x6c, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x69, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x62, 0x75, 0x74, 0x74,
+0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
+0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61,
+0x63, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67,
+0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61,
+0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69,
+0x3b, 0x45, 0x70, 0x72, 0x65, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61,
+0x69, 0x3b, 0x4f, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b,
+0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61,
+0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f,
+0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72,
+0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74,
+0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x75, 0x76, 0x3b, 0x44, 0x69, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x72, 0x75, 0x3b,
+0x46, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x75, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b,
+0x4d, 0x61, 0x69, 0x75, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x75, 0x3b, 0x41, 0x67, 0x6f,
+0x73, 0x74, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b,
+0x4e, 0x75, 0x76, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x7a, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x41,
+0x4e, 0x3b, 0x46, 0x45, 0x42, 0x3b, 0x4d, 0x41, 0x43, 0x3b, 0x128, 0x50, 0x55, 0x3b, 0x4d, 0x128, 0x128, 0x3b, 0x4e, 0x4a,
+0x55, 0x3b, 0x4e, 0x4a, 0x52, 0x3b, 0x41, 0x47, 0x41, 0x3b, 0x53, 0x50, 0x54, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4e, 0x4f,
+0x56, 0x3b, 0x44, 0x45, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x75,
+0x61, 0x72, 0x129, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x128, 0x70, 0x75, 0x72, 0x169, 0x3b, 0x4d, 0x129, 0x129, 0x3b,
+0x4e, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x72, 0x61, 0x129, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b,
+0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x169, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x128, 0x3b,
+0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x75, 0x6c, 0x3b,
+0x4e, 0x67, 0x61, 0x74, 0x3b, 0x54, 0x61, 0x61, 0x3b, 0x49, 0x77, 0x6f, 0x3b, 0x4d, 0x61, 0x6d, 0x3b, 0x50, 0x61, 0x61,
+0x3b, 0x4e, 0x67, 0x65, 0x3b, 0x52, 0x6f, 0x6f, 0x3b, 0x42, 0x75, 0x72, 0x3b, 0x45, 0x70, 0x65, 0x3b, 0x4b, 0x70, 0x74,
+0x3b, 0x4b, 0x70, 0x61, 0x3b, 0x4d, 0x75, 0x6c, 0x67, 0x75, 0x6c, 0x3b, 0x4e, 0x67, 0x2019, 0x61, 0x74, 0x79, 0x61, 0x61,
+0x74, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x74, 0x61, 0x61, 0x6d, 0x6f, 0x3b, 0x49, 0x77, 0x6f, 0x6f, 0x74, 0x6b, 0x75, 0x75,
+0x74, 0x3b, 0x4d, 0x61, 0x6d, 0x75, 0x75, 0x74, 0x3b, 0x50, 0x61, 0x61, 0x67, 0x69, 0x3b, 0x4e, 0x67, 0x2019, 0x65, 0x69,
+0x79, 0x65, 0x65, 0x74, 0x3b, 0x52, 0x6f, 0x6f, 0x70, 0x74, 0x75, 0x69, 0x3b, 0x42, 0x75, 0x72, 0x65, 0x65, 0x74, 0x3b,
+0x45, 0x70, 0x65, 0x65, 0x73, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x20,
+0x74, 0x61, 0x61, 0x69, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x62, 0x6f, 0x20,
+0x61, 0x65, 0x6e, 0x67, 0x2019, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x4e, 0x3b,
+0x52, 0x3b, 0x42, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x6e, 0x6e, 0x69, 0x3b, 0x1c3, 0x4b,
+0x68, 0x61, 0x6e, 0x1c0, 0x67, 0xf4, 0x61, 0x62, 0x3b, 0x1c0, 0x4b, 0x68, 0x75, 0x75, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b,
+0x1c3, 0x48, 0xf4, 0x61, 0x1c2, 0x6b, 0x68, 0x61, 0x69, 0x62, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x69, 0x74, 0x73, 0xe2, 0x62,
+0x3b, 0x47, 0x61, 0x6d, 0x61, 0x1c0, 0x61, 0x65, 0x62, 0x3b, 0x1c2, 0x4b, 0x68, 0x6f, 0x65, 0x73, 0x61, 0x6f, 0x62, 0x3b,
+0x41, 0x6f, 0x1c1, 0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x54, 0x61, 0x72, 0x61, 0x1c0,
+0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x1c2, 0x4e, 0xfb, 0x1c1, 0x6e, 0xe2, 0x69, 0x73,
+0x65, 0x62, 0x3b, 0x1c0, 0x48, 0x6f, 0x6f, 0x1c2, 0x67, 0x61, 0x65, 0x62, 0x3b, 0x48, 0xf4, 0x61, 0x73, 0x6f, 0x72, 0x65,
+0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0xe4, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x7a, 0x2e,
+0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b,
+0x4f, 0x75, 0x6a, 0x2e, 0x3b, 0x53, 0xe4, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b,
+0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65, 0x77, 0x61, 0x3b, 0x46, 0xe4, 0x62, 0x72, 0x6f, 0x77, 0x61,
+0x3b, 0x4d, 0xe4, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x75,
+0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x4f, 0x75, 0x6a, 0x6f, 0xdf, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x68, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0xe4, 0x62, 0x3b,
+0x4d, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b,
+0x4f, 0x75, 0x6a, 0x3b, 0x53, 0xe4, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b,
+0x44, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0xe1, 0x3b, 0x186, 0x25b, 0x6e, 0x3b, 0x44, 0x6f, 0x79, 0x3b, 0x4c, 0xe9, 0x70, 0x3b,
+0x52, 0x6f, 0x6b, 0x3b, 0x53, 0xe1, 0x73, 0x3b, 0x42, 0x254, 0x301, 0x72, 0x3b, 0x4b, 0xfa, 0x73, 0x3b, 0x47, 0xed, 0x73,
+0x3b, 0x53, 0x68, 0x289, 0x301, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x3b, 0x4f, 0x6c, 0x61, 0x64, 0x61, 0x6c, 0x289, 0x301, 0x3b,
+0x41, 0x72, 0xe1, 0x74, 0x3b, 0x186, 0x25b, 0x6e, 0x268, 0x301, 0x254, 0x268, 0x14b, 0x254, 0x6b, 0x3b, 0x4f, 0x6c, 0x6f, 0x64,
+0x6f, 0x79, 0xed, 0xf3, 0x72, 0xed, 0xea, 0x20, 0x69, 0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4f, 0x6c, 0x6f, 0x69,
+0x6c, 0xe9, 0x70, 0x16b, 0x6e, 0x79, 0x12b, 0x113, 0x20, 0x69, 0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4b, 0xfa, 0x6a,
+0xfa, 0x254, 0x72, 0x254, 0x6b, 0x3b, 0x4d, 0xf3, 0x72, 0x75, 0x73, 0xe1, 0x73, 0x69, 0x6e, 0x3b, 0x186, 0x6c, 0x254, 0x301,
+0x268, 0x301, 0x62, 0x254, 0x301, 0x72, 0xe1, 0x72, 0x25b, 0x3b, 0x4b, 0xfa, 0x73, 0x68, 0xee, 0x6e, 0x3b, 0x4f, 0x6c, 0x67,
+0xed, 0x73, 0x61, 0x6e, 0x3b, 0x50, 0x289, 0x73, 0x68, 0x289, 0x301, 0x6b, 0x61, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x14b, 0x289,
+0x301, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d,
+0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f,
+0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d,
+0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41,
+0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x52,
+0x61, 0x72, 0x3b, 0x4d, 0x75, 0x6b, 0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x44, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d,
+0x6f, 0x64, 0x3b, 0x4a, 0x6f, 0x6c, 0x3b, 0x50, 0x65, 0x64, 0x3b, 0x53, 0x6f, 0x6b, 0x3b, 0x54, 0x69, 0x62, 0x3b, 0x4c,
+0x61, 0x62, 0x3b, 0x50, 0x6f, 0x6f, 0x3b, 0x4f, 0x72, 0x61, 0x72, 0x61, 0x3b, 0x4f, 0x6d, 0x75, 0x6b, 0x3b, 0x4f, 0x6b,
+0x77, 0x61, 0x6d, 0x67, 0x2019, 0x3b, 0x4f, 0x64, 0x75, 0x6e, 0x67, 0x2019, 0x65, 0x6c, 0x3b, 0x4f, 0x6d, 0x61, 0x72, 0x75,
+0x6b, 0x3b, 0x4f, 0x6d, 0x6f, 0x64, 0x6f, 0x6b, 0x2019, 0x6b, 0x69, 0x6e, 0x67, 0x2019, 0x6f, 0x6c, 0x3b, 0x4f, 0x6a, 0x6f,
+0x6c, 0x61, 0x3b, 0x4f, 0x70, 0x65, 0x64, 0x65, 0x6c, 0x3b, 0x4f, 0x73, 0x6f, 0x6b, 0x6f, 0x73, 0x6f, 0x6b, 0x6f, 0x6d,
+0x61, 0x3b, 0x4f, 0x74, 0x69, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x3b, 0x4f, 0x70, 0x6f, 0x6f,
+0x3b, 0x52, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54,
+0x3b, 0x4c, 0x3b, 0x50, 0x3b, 0x17d, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x77, 0x69,
+0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x3b, 0x17d, 0x75, 0x79, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x3b, 0x4f,
+0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x6f, 0x3b, 0x44, 0x65, 0x65, 0x3b, 0x17d, 0x61, 0x6e, 0x77, 0x69, 0x79, 0x65, 0x3b, 0x46,
+0x65, 0x65, 0x77, 0x69, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x69, 0x3b, 0x41, 0x77, 0x69, 0x72, 0x69,
+0x6c, 0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x65, 0x14b, 0x3b, 0x17d, 0x75, 0x79, 0x79, 0x65, 0x3b, 0x55, 0x74, 0x3b,
+0x53, 0x65, 0x6b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x75, 0x72, 0x3b, 0x4e,
+0x6f, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x44, 0x65, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x17d,
+0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x17d, 0x3b, 0x17d, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e,
+0x3b, 0x44, 0x3b, 0x44, 0x41, 0x43, 0x3b, 0x44, 0x41, 0x52, 0x3b, 0x44, 0x41, 0x44, 0x3b, 0x44, 0x41, 0x4e, 0x3b, 0x44,
+0x41, 0x48, 0x3b, 0x44, 0x41, 0x55, 0x3b, 0x44, 0x41, 0x4f, 0x3b, 0x44, 0x41, 0x42, 0x3b, 0x44, 0x4f, 0x43, 0x3b, 0x44,
+0x41, 0x50, 0x3b, 0x44, 0x47, 0x49, 0x3b, 0x44, 0x41, 0x47, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41,
+0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b,
+0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x64, 0x65, 0x6b, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72,
+0x20, 0x41, 0x6e, 0x67, 0x2019, 0x77, 0x65, 0x6e, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69,
+0x63, 0x68, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x75, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44,
+0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d,
+0x61, 0x72, 0x20, 0x41, 0x62, 0x6f, 0x72, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4f, 0x63, 0x68,
+0x69, 0x6b, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x3b, 0x44, 0x77, 0x65,
+0x20, 0x6d, 0x61, 0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d,
+0x61, 0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x43, 0x3b, 0x52,
+0x3b, 0x44, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x55, 0x3b, 0x42, 0x3b, 0x42, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x50,
+0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x49, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79,
+0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x75, 0x74, 0x3b, 0x4b, 0x1e6d, 0x75,
+0x3b, 0x4e, 0x77, 0x61, 0x3b, 0x44, 0x75, 0x6a, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x59, 0x65,
+0x62, 0x72, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61,
+0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x194, 0x75, 0x63,
+0x74, 0x3b, 0x43, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x4b, 0x1e6d, 0x75, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x77,
+0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x44, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x4d,
+0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a,
+0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x6c, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68,
+0x69, 0x3b, 0x41, 0x70, 0x6c, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75,
+0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b,
+0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d,
+0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e,
+0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x938, 0x3b, 0x90f, 0x92b, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c,
+0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x907, 0x3b, 0x906, 0x917, 0x938, 0x94d, 0x925, 0x3b, 0x938, 0x947, 0x92c, 0x925, 0x947,
+0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x905, 0x916, 0x925, 0x92c, 0x930, 0x3b, 0x928, 0x92c, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930,
+0x3b, 0x926, 0x93f, 0x938, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f,
+0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x3b, 0x91c, 0x941, 0x3b, 0x906, 0x3b, 0x938, 0x947, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926,
+0x93f, 0x3b, 0x456, 0x486, 0x430, 0x2de9, 0x487, 0x3b, 0x444, 0x435, 0x2de1, 0x487, 0x3b, 0x43c, 0x430, 0x2dec, 0x487, 0x3b, 0x430, 0x486,
+0x43f, 0x2dec, 0x487, 0x3b, 0x43c, 0x430, 0xa675, 0x3b, 0x456, 0x486, 0xa64b, 0x2de9, 0x487, 0x3b, 0x456, 0x486, 0xa64b, 0x2de7, 0x487, 0x3b,
+0x430, 0x486, 0x301, 0x475, 0x2de2, 0x487, 0x3b, 0x441, 0x435, 0x2deb, 0x487, 0x3b, 0x47b, 0x486, 0x43a, 0x2dee, 0x3b, 0x43d, 0x43e, 0x435,
+0x2de8, 0x3b, 0x434, 0x435, 0x2de6, 0x487, 0x3b, 0x456, 0x486, 0x430, 0x43d, 0x43d, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x439, 0x3b, 0x444,
+0x435, 0x432, 0x440, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x439, 0x3b, 0x43c, 0x430, 0x301, 0x440, 0x442, 0x44a, 0x3b, 0x430, 0x486, 0x43f,
+0x440, 0x456, 0x301, 0x43b, 0x43b, 0x457, 0x439, 0x3b, 0x43c, 0x430, 0x301, 0x457, 0x439, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43d, 0x457,
+0x439, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43b, 0x457, 0x439, 0x3b, 0x430, 0x486, 0x301, 0x475, 0x433, 0xa64b, 0x441, 0x442, 0x44a, 0x3b,
+0x441, 0x435, 0x43f, 0x442, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x439, 0x3b, 0x47b, 0x486, 0x43a, 0x442, 0x461, 0x301, 0x432, 0x440,
+0x457, 0x439, 0x3b, 0x43d, 0x43e, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x439, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x301, 0x43c, 0x432,
+0x440, 0x457, 0x439, 0x3b, 0x406, 0x486, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x486, 0x3b, 0x41c, 0x3b, 0x406, 0x486, 0x3b, 0x406,
+0x486, 0x3b, 0x410, 0x486, 0x3b, 0x421, 0x3b, 0x47a, 0x486, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x456, 0x486, 0x430, 0x43d, 0x43d, 0xa64b,
+0x430, 0x301, 0x440, 0x457, 0x430, 0x3b, 0x444, 0x435, 0x432, 0x440, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x430, 0x3b, 0x43c, 0x430, 0x301,
+0x440, 0x442, 0x430, 0x3b, 0x430, 0x486, 0x43f, 0x440, 0x456, 0x301, 0x43b, 0x43b, 0x457, 0x430, 0x3b, 0x43c, 0x430, 0x301, 0x457, 0x430,
+0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43d, 0x457, 0x430, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43b, 0x457, 0x430, 0x3b, 0x430, 0x486, 0x301,
+0x475, 0x433, 0xa64b, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x47b,
+0x486, 0x43a, 0x442, 0x461, 0x301, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x43d, 0x43e, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b,
+0x434, 0x435, 0x43a, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x43, 0x69, 0x6f, 0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x4c,
+0x75, 0x73, 0x3b, 0x4d, 0x75, 0x75, 0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x66, 0x3b, 0x4b, 0x61, 0x62, 0x3b, 0x4c,
+0x75, 0x73, 0x68, 0x3b, 0x4c, 0x75, 0x74, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x43, 0x69, 0x73, 0x3b,
+0x43, 0x69, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0xf9, 0x69, 0x73, 0x68, 0x69, 0x3b, 0x4c, 0x75, 0x73, 0xf2, 0x6c, 0x6f,
+0x3b, 0x4d, 0xf9, 0x75, 0x79, 0xe0, 0x3b, 0x4c, 0x75, 0x6d, 0xf9, 0x6e, 0x67, 0xf9, 0x6c, 0xf9, 0x3b, 0x4c, 0x75, 0x66,
+0x75, 0x69, 0x6d, 0x69, 0x3b, 0x4b, 0x61, 0x62, 0xe0, 0x6c, 0xe0, 0x73, 0x68, 0xec, 0x70, 0xf9, 0x3b, 0x4c, 0xf9, 0x73,
+0x68, 0xec, 0x6b, 0xe0, 0x3b, 0x4c, 0x75, 0x74, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x67, 0xf9,
+0x64, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x77, 0xe8, 0x6b, 0xe8, 0x73, 0xe8, 0x3b, 0x43, 0x69, 0x73, 0x77, 0xe0, 0x3b, 0x43,
+0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b,
+0x3b, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x65, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d,
+0x65, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f,
+0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65,
+0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x65, 0x72, 0x7a, 0x3b, 0x41, 0x62, 0x72, 0xeb, 0x6c, 0x6c, 0x3b, 0x4d,
+0x65, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b,
+0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f,
+0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e,
+0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x65, 0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x65, 0x65, 0x3b,
+0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b,
+0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x6e, 0xf9, 0x6d, 0x3b, 0x6b,
+0x268, 0x7a, 0x3b, 0x74, 0x268, 0x64, 0x3b, 0x74, 0x61, 0x61, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x6e, 0x7a, 0x75, 0x3b, 0x64,
+0x75, 0x6d, 0x3b, 0x66, 0x254, 0x65, 0x3b, 0x64, 0x7a, 0x75, 0x3b, 0x6c, 0x254, 0x6d, 0x3b, 0x6b, 0x61, 0x61, 0x3b, 0x66,
+0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6e, 0xf9, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
+0x14b, 0x254, 0x300, 0x6b, 0x197, 0x300, 0x7a, 0xf9, 0x294, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197,
+0x300, 0x64, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x1ce, 0x61, 0x66,
+0x289, 0x304, 0x67, 0x68, 0x101, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0xe8, 0x73, 0xe8, 0x65, 0x3b, 0x6e, 0x64, 0x7a,
+0x254, 0x300, 0x14b, 0x254, 0x300, 0x6e, 0x7a, 0xf9, 0x67, 0x68, 0xf2, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300,
+0x64, 0xf9, 0x6d, 0x6c, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6b, 0x77, 0xee, 0x66, 0x254, 0x300,
+0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197, 0x300, 0x66, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x64,
+0x7a, 0x75, 0x67, 0x68, 0xf9, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x67, 0x68, 0x1d4, 0x75, 0x77, 0x65,
+0x6c, 0x254, 0x300, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x63, 0x68, 0x77, 0x61, 0x294, 0xe0, 0x6b,
+0x61, 0x61, 0x20, 0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0xe8, 0x66, 0x77, 0xf2, 0x6f, 0x3b, 0x6e, 0x3b,
+0x6b, 0x3b, 0x74, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x63, 0x3b,
+0x66, 0x3b, 0x6b, 0x254, 0x6e, 0x3b, 0x6d, 0x61, 0x63, 0x3b, 0x6d, 0x61, 0x74, 0x3b, 0x6d, 0x74, 0x6f, 0x3b, 0x6d, 0x70,
+0x75, 0x3b, 0x68, 0x69, 0x6c, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x68, 0x69, 0x6b, 0x3b, 0x64, 0x69, 0x70, 0x3b, 0x62, 0x69,
+0x6f, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6c, 0x69, 0x253, 0x3b, 0x4b, 0x254, 0x6e, 0x64, 0x254, 0x14b, 0x3b, 0x4d, 0xe0, 0x63,
+0x25b, 0x302, 0x6c, 0x3b, 0x4d, 0xe0, 0x74, 0xf9, 0x6d, 0x62, 0x3b, 0x4d, 0xe0, 0x74, 0x6f, 0x70, 0x3b, 0x4d, 0x300, 0x70,
+0x75, 0x79, 0x25b, 0x3b, 0x48, 0xec, 0x6c, 0xf2, 0x6e, 0x64, 0x25b, 0x300, 0x3b, 0x4e, 0x6a, 0xe8, 0x62, 0xe0, 0x3b, 0x48,
+0xec, 0x6b, 0x61, 0x14b, 0x3b, 0x44, 0xec, 0x70, 0x254, 0x300, 0x73, 0x3b, 0x42, 0xec, 0xf2, 0xf4, 0x6d, 0x3b, 0x4d, 0xe0,
+0x79, 0x25b, 0x73, 0xe8, 0x70, 0x3b, 0x4c, 0xec, 0x62, 0x75, 0x79, 0x20, 0x6c, 0x69, 0x20, 0x144, 0x79, 0xe8, 0x65, 0x3b,
+0x6b, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x6e, 0x3b, 0x68, 0x3b, 0x64, 0x3b, 0x62, 0x3b,
+0x6d, 0x3b, 0x6c, 0x3b, 0x64, 0x69, 0x3b, 0x14b, 0x67, 0x254, 0x6e, 0x3b, 0x73, 0x254, 0x14b, 0x3b, 0x64, 0x69, 0x253, 0x3b,
+0x65, 0x6d, 0x69, 0x3b, 0x65, 0x73, 0x254, 0x3b, 0x6d, 0x61, 0x64, 0x3b, 0x64, 0x69, 0x14b, 0x3b, 0x6e, 0x79, 0x25b, 0x74,
+0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x74, 0x69, 0x6e, 0x3b, 0x65, 0x6c, 0xe1, 0x3b, 0x64, 0x69, 0x6d, 0x254, 0x301, 0x64, 0x69,
+0x3b, 0x14b, 0x67, 0x254, 0x6e, 0x64, 0x25b, 0x3b, 0x73, 0x254, 0x14b, 0x25b, 0x3b, 0x64, 0x69, 0x253, 0xe1, 0x253, 0xe1, 0x3b,
+0x65, 0x6d, 0x69, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x3b, 0x65, 0x73, 0x254, 0x70, 0x25b, 0x73, 0x254, 0x70, 0x25b, 0x3b, 0x6d,
+0x61, 0x64, 0x69, 0x253, 0x25b, 0x301, 0x64, 0xed, 0x253, 0x25b, 0x301, 0x3b, 0x64, 0x69, 0x14b, 0x67, 0x69, 0x6e, 0x64, 0x69,
+0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x25b, 0x6b, 0x69, 0x3b, 0x6d, 0x61, 0x79, 0xe9, 0x73, 0x25b, 0x301, 0x3b, 0x74, 0x69, 0x6e,
+0xed, 0x6e, 0xed, 0x3b, 0x65, 0x6c, 0xe1, 0x14b, 0x67, 0x25b, 0x301, 0x3b, 0x64, 0x3b, 0x14b, 0x3b, 0x73, 0x3b, 0x64, 0x3b,
+0x65, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x64, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x74, 0x3b, 0x65, 0x3b, 0x53, 0x61, 0x3b, 0x46,
+0x65, 0x3b, 0x4d, 0x61, 0x3b, 0x41, 0x62, 0x3b, 0x4d, 0x65, 0x3b, 0x53, 0x75, 0x3b, 0x53, 0xfa, 0x3b, 0x55, 0x74, 0x3b,
+0x53, 0x65, 0x3b, 0x4f, 0x6b, 0x3b, 0x4e, 0x6f, 0x3b, 0x44, 0x65, 0x3b, 0x53, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x46,
+0xe9, 0x62, 0x69, 0x72, 0x69, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x62, 0x75, 0x72, 0x69, 0x6c, 0x3b, 0x4d,
+0x65, 0x65, 0x3b, 0x53, 0x75, 0x65, 0x14b, 0x3b, 0x53, 0xfa, 0x75, 0x79, 0x65, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65,
+0x74, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x61, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b,
+0x41, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6e, 0x67,
+0x6f, 0x3b, 0x6e, 0x67, 0x62, 0x3b, 0x6e, 0x67, 0x6c, 0x3b, 0x6e, 0x67, 0x6e, 0x3b, 0x6e, 0x67, 0x74, 0x3b, 0x6e, 0x67,
+0x73, 0x3b, 0x6e, 0x67, 0x7a, 0x3b, 0x6e, 0x67, 0x6d, 0x3b, 0x6e, 0x67, 0x65, 0x3b, 0x6e, 0x67, 0x61, 0x3b, 0x6e, 0x67,
+0x61, 0x64, 0x3b, 0x6e, 0x67, 0x61, 0x62, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6f, 0x73, 0xfa, 0x3b, 0x6e, 0x67, 0x254,
+0x6e, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6c, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e,
+0x20, 0x6e, 0x79, 0x69, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x74, 0xe1, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254,
+0x6e, 0x20, 0x73, 0x61, 0x6d, 0x259, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x7a, 0x61, 0x6d, 0x67, 0x62, 0xe1,
+0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6d, 0x77, 0x6f, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x65, 0x62,
+0x75, 0x6c, 0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61,
+0x77, 0xf3, 0x6d, 0x20, 0x61, 0x69, 0x20, 0x64, 0x7a, 0x69, 0xe1, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3,
+0x6d, 0x20, 0x61, 0x69, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6f, 0x3b, 0x62, 0x3b, 0x6c, 0x3b, 0x6e, 0x3b, 0x74, 0x3b, 0x73,
+0x3b, 0x7a, 0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x14b, 0x31, 0x3b, 0x14b, 0x32, 0x3b, 0x14b,
+0x33, 0x3b, 0x14b, 0x34, 0x3b, 0x14b, 0x35, 0x3b, 0x14b, 0x36, 0x3b, 0x14b, 0x37, 0x3b, 0x14b, 0x38, 0x3b, 0x14b, 0x39, 0x3b,
+0x14b, 0x31, 0x30, 0x3b, 0x14b, 0x31, 0x31, 0x3b, 0x14b, 0x31, 0x32, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x20, 0x6e,
+0x74, 0x254, 0x301, 0x6e, 0x74, 0x254, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x62, 0x25b, 0x301, 0x25b,
+0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x72, 0xe1, 0xe1, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61,
+0x6b, 0x1dd, 0x20, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e,
+0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x66, 0x254, 0x6b, 0x3b, 0x14b, 0x77, 0xed,
+0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x62, 0x25b, 0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b,
+0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x72, 0x61, 0x61, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1,
+0x61, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x3b, 0x14b,
+0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x254, 0x301, 0x6b,
+0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x25b,
+0x301, 0x25b, 0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x55, 0x6e, 0x61, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x43, 0x68, 0x65, 0x3b, 0x54,
+0x68, 0x61, 0x3b, 0x4d, 0x6f, 0x63, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b,
+0x75, 0x6d, 0x3b, 0x4d, 0x6f, 0x6a, 0x3b, 0x59, 0x65, 0x6c, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20,
+0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x61, 0x79,
+0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x72, 0x61, 0x72, 0x75,
+0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x63, 0x68, 0x65, 0x73, 0x68, 0x65, 0x3b,
+0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77,
+0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x63, 0x68,
+0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72,
+0x69, 0x20, 0x77, 0x6f, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74,
+0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77,
+0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b,
+0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x79, 0x65, 0x6c,
+0x2019, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x55, 0x3b, 0x52, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x4e, 0x3b,
+0x54, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x46, 0x4c, 0x4f, 0x3b, 0x43, 0x4c, 0x41, 0x3b, 0x43, 0x4b, 0x49, 0x3b,
+0x46, 0x4d, 0x46, 0x3b, 0x4d, 0x41, 0x44, 0x3b, 0x4d, 0x42, 0x49, 0x3b, 0x4d, 0x4c, 0x49, 0x3b, 0x4d, 0x41, 0x4d, 0x3b,
+0x46, 0x44, 0x45, 0x3b, 0x46, 0x4d, 0x55, 0x3b, 0x46, 0x47, 0x57, 0x3b, 0x46, 0x59, 0x55, 0x3b, 0x46, 0x129, 0x69, 0x20,
+0x4c, 0x6f, 0x6f, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, 0x61, 0x6b, 0x6c, 0x61, 0x14b, 0x6e, 0x65, 0x3b, 0x43, 0x6f, 0x6b,
+0x63, 0x77, 0x61, 0x6b, 0x6c, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x61, 0x72, 0x66, 0x6f, 0x6f, 0x3b, 0x4d,
+0x61, 0x64, 0x1dd, 0x1dd, 0x75, 0x75, 0x74, 0x1dd, 0x62, 0x69, 0x6a, 0x61, 0x14b, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67,
+0x77, 0xe3, 0x61, 0x66, 0x61, 0x68, 0x62, 0x69, 0x69, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x6c,
+0x69, 0x69, 0x3b, 0x4d, 0x61, 0x64, 0x1dd, 0x6d, 0x62, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x44, 0x1dd, 0x253, 0x6c,
+0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x75, 0x6e, 0x64, 0x61, 0x14b, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x47, 0x77,
+0x61, 0x68, 0x6c, 0x6c, 0x65, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x59, 0x75, 0x72, 0x75, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49,
+0x3b, 0x46, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x55, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x6e,
+0x67, 0x31, 0x3b, 0x6e, 0x67, 0x32, 0x3b, 0x6e, 0x67, 0x33, 0x3b, 0x6e, 0x67, 0x34, 0x3b, 0x6e, 0x67, 0x35, 0x3b, 0x6e,
+0x67, 0x36, 0x3b, 0x6e, 0x67, 0x37, 0x3b, 0x6e, 0x67, 0x38, 0x3b, 0x6e, 0x67, 0x39, 0x3b, 0x6e, 0x67, 0x31, 0x30, 0x3b,
+0x6e, 0x67, 0x31, 0x31, 0x3b, 0x6b, 0x72, 0x69, 0x73, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0xe1,
+0x68, 0x72, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6d, 0x62, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e,
+0x20, 0x144, 0x6c, 0x61, 0x6c, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b,
+0x6e, 0x20, 0x144, 0x74, 0x61, 0x6e, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x74, 0x75, 0xf3, 0x3b, 0x6e, 0x67,
+0x77, 0x25b, 0x6e, 0x20, 0x68, 0x25b, 0x6d, 0x62, 0x75, 0x25b, 0x72, 0xed, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6c,
+0x254, 0x6d, 0x62, 0x69, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x72, 0x25b, 0x62, 0x76, 0x75, 0xe2, 0x3b, 0x6e, 0x67,
+0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x20, 0x6e, 0x61,
+0x76, 0x1d4, 0x72, 0x3b, 0x6b, 0x72, 0xed, 0x73, 0x69, 0x6d, 0x69, 0x6e, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x3b, 0x50, 0x25b,
+0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x3b, 0x4b, 0x6f,
+0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x54, 0x68, 0x6f, 0x6f, 0x3b, 0x54, 0x25b, 0x25b, 0x3b, 0x4c, 0x61, 0x61, 0x3b, 0x4b,
+0x75, 0x72, 0x3b, 0x54, 0x69, 0x64, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x61, 0x72, 0x20, 0x70, 0x25b, 0x74,
+0x3b, 0x50, 0x25b, 0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331, 0x14b, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75,
+0xe4, 0x74, 0x3b, 0x4b, 0x6f, 0x72, 0x6e, 0x79, 0x6f, 0x6f, 0x74, 0x3b, 0x50, 0x61, 0x79, 0x20, 0x79, 0x69, 0x65, 0x331,
+0x74, 0x6e, 0x69, 0x3b, 0x54, 0x68, 0x6f, 0x331, 0x6f, 0x331, 0x72, 0x3b, 0x54, 0x25b, 0x25b, 0x72, 0x3b, 0x4c, 0x61, 0x61,
+0x74, 0x68, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x54, 0x69, 0x6f, 0x331, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x331, 0x69,
+0x331, 0x74, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x54,
+0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x422, 0x43e, 0x445, 0x441, 0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x3b, 0x41a, 0x43b, 0x43d,
+0x3b, 0x41c, 0x441, 0x443, 0x3b, 0x42b, 0x430, 0x43c, 0x3b, 0x411, 0x44d, 0x441, 0x3b, 0x41e, 0x442, 0x439, 0x3b, 0x410, 0x442, 0x440,
+0x3b, 0x411, 0x43b, 0x495, 0x3b, 0x410, 0x43b, 0x442, 0x3b, 0x421, 0x44d, 0x442, 0x3b, 0x410, 0x445, 0x441, 0x3b, 0x442, 0x43e, 0x445,
+0x441, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x43e, 0x43b, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x43a, 0x443, 0x43b, 0x443, 0x43d,
+0x20, 0x442, 0x443, 0x442, 0x430, 0x440, 0x3b, 0x43c, 0x443, 0x443, 0x441, 0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x44b, 0x430,
+0x43c, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x431, 0x44d, 0x441, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x43e, 0x442, 0x20, 0x44b, 0x439, 0x430,
+0x3b, 0x430, 0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x431, 0x430, 0x43b, 0x430, 0x495, 0x430,
+0x43d, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x430, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x441, 0x44d, 0x442, 0x438, 0x43d,
+0x43d, 0x44c, 0x438, 0x3b, 0x430, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x422, 0x3b, 0x41e, 0x3b, 0x41a, 0x3b, 0x41c,
+0x3b, 0x42b, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x410, 0x3b, 0x411, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x410, 0x3b, 0x422, 0x43e, 0x445,
+0x441, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41a, 0x443, 0x43b, 0x443, 0x43d,
+0x20, 0x442, 0x443, 0x442, 0x430, 0x440, 0x3b, 0x41c, 0x443, 0x443, 0x441, 0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x42b, 0x430,
+0x43c, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x44d, 0x441, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x41e, 0x442, 0x20, 0x44b,
+0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x430,
+0x43b, 0x430, 0x495, 0x430, 0x43d, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b,
+0x421, 0x44d, 0x442, 0x438, 0x43d, 0x43d, 0x44c, 0x438, 0x3b, 0x430, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x4d, 0x75,
+0x70, 0x3b, 0x4d, 0x77, 0x69, 0x3b, 0x4d, 0x73, 0x68, 0x3b, 0x4d, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x67, 0x3b, 0x4d, 0x75,
+0x6a, 0x3b, 0x4d, 0x73, 0x70, 0x3b, 0x4d, 0x70, 0x67, 0x3b, 0x4d, 0x79, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x3b, 0x4d, 0x75,
+0x73, 0x3b, 0x4d, 0x75, 0x68, 0x3b, 0x4d, 0x75, 0x70, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x77, 0x61, 0x3b, 0x4d,
+0x77, 0x69, 0x74, 0x6f, 0x70, 0x65, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x3b, 0x4d, 0x75, 0x6e, 0x79,
+0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x67, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x75,
+0x6a, 0x69, 0x6d, 0x62, 0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x69, 0x70, 0x65, 0x70, 0x6f, 0x3b, 0x4d, 0x75, 0x70, 0x75,
+0x67, 0x75, 0x74, 0x6f, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x68, 0x75, 0x3b,
+0x4d, 0x75, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x6d, 0x62, 0x77, 0x65, 0x3b, 0x4d, 0x75, 0x68, 0x61, 0x61,
+0x6e, 0x6f, 0x3b, 0xa5a8, 0xa595, 0xa51e, 0x3b, 0xa552, 0xa561, 0x3b, 0xa57e, 0xa5ba, 0x3b, 0xa5a2, 0xa595, 0x3b, 0xa591, 0xa571, 0x3b, 0xa5b1,
+0xa60b, 0x3b, 0xa5b1, 0xa55e, 0x3b, 0xa5db, 0xa515, 0x3b, 0xa562, 0xa54c, 0x3b, 0xa56d, 0xa583, 0x3b, 0xa51e, 0xa60b, 0x3b, 0xa5a8, 0xa595, 0xa5cf,
+0x3b, 0xa5a8, 0xa595, 0x20, 0xa56a, 0xa574, 0x20, 0xa51e, 0xa500, 0xa56e, 0xa54a, 0x3b, 0xa552, 0xa561, 0xa59d, 0xa595, 0x3b, 0xa57e, 0xa5ba, 0x3b,
+0xa5a2, 0xa595, 0x3b, 0xa591, 0xa571, 0x3b, 0xa5b1, 0xa60b, 0x3b, 0xa5b1, 0xa55e, 0xa524, 0x3b, 0xa5db, 0xa515, 0x3b, 0xa562, 0xa54c, 0x3b, 0xa56d,
+0xa583, 0x3b, 0xa51e, 0xa60b, 0xa554, 0xa57f, 0x20, 0xa578, 0xa583, 0xa5cf, 0x3b, 0xa5a8, 0xa595, 0x20, 0xa56a, 0xa574, 0x20, 0xa5cf, 0xa5ba, 0xa56e,
+0xa54a, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6b, 0x65, 0x6d, 0xe3, 0x3b, 0x253, 0x61, 0x6e, 0x64, 0x61, 0x253,
0x75, 0x3b, 0x76, 0x254, 0x254, 0x3b, 0x66, 0x75, 0x6c, 0x75, 0x3b, 0x67, 0x6f, 0x6f, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x6b,
0x254, 0x6e, 0x64, 0x65, 0x3b, 0x73, 0x61, 0x61, 0x68, 0x3b, 0x67, 0x61, 0x6c, 0x6f, 0x3b, 0x6b, 0x65, 0x6e, 0x70, 0x6b,
0x61, 0x74, 0x6f, 0x20, 0x253, 0x6f, 0x6c, 0x6f, 0x6c, 0x254, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6c, 0x254,
@@ -3805,23 +3891,31 @@ static const ushort months_data[] = {
0x6d, 0x11b, 0x72, 0x63, 0x61, 0x3b, 0x61, 0x70, 0x72, 0x79, 0x6c, 0x61, 0x3b, 0x6d, 0x65, 0x6a, 0x65, 0x3b, 0x6a, 0x75,
0x6e, 0x69, 0x6a, 0x61, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x61, 0x3b, 0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b,
0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f,
-0x77, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x75, 0x111, 0x69, 0x76,
-0x3b, 0x6b, 0x75, 0x6f, 0x76, 0xe2, 0x3b, 0x6e, 0x6a, 0x75, 0x68, 0x10d, 0xe2, 0x3b, 0x63, 0x75, 0xe1, 0x14b, 0x75, 0x69,
-0x3b, 0x76, 0x79, 0x65, 0x73, 0x69, 0x3b, 0x6b, 0x65, 0x73, 0x69, 0x3b, 0x73, 0x79, 0x65, 0x69, 0x6e, 0x69, 0x3b, 0x70,
-0x6f, 0x72, 0x67, 0x65, 0x3b, 0x10d, 0x6f, 0x68, 0x10d, 0xe2, 0x3b, 0x72, 0x6f, 0x6f, 0x76, 0x76, 0xe2, 0x64, 0x3b, 0x73,
-0x6b, 0x61, 0x6d, 0x6d, 0xe2, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0xe2, 0x3b, 0x75, 0x111, 0x111, 0xe2, 0x69, 0x76, 0x65,
-0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6b, 0x75, 0x6f, 0x76, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6e, 0x6a, 0x75,
-0x68, 0x10d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x63, 0x75, 0xe1, 0x14b, 0x75, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75,
-0x3b, 0x76, 0x79, 0x65, 0x73, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6b, 0x65, 0x73, 0x69, 0x6d, 0xe1, 0xe1, 0x6e,
-0x75, 0x3b, 0x73, 0x79, 0x65, 0x69, 0x6e, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x70, 0x6f, 0x72, 0x67, 0x65, 0x6d,
-0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x10d, 0x6f, 0x68, 0x10d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x72, 0x6f, 0x6f, 0x76,
-0x76, 0xe2, 0x64, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x73, 0x6b, 0x61, 0x6d, 0x6d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75,
-0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x55, 0x3b, 0x4b, 0x3b, 0x4e, 0x4a, 0x3b,
-0x43, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x10c, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x62c, 0x627,
-0x646, 0x6a4, 0x6cc, 0x6d5, 0x3b, 0x641, 0x626, 0x6a4, 0x631, 0x6cc, 0x6d5, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x6a4, 0x631,
-0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x6cc, 0x3b, 0x62c, 0x648, 0x659, 0x623, 0x646, 0x3b, 0x62c, 0x648, 0x659, 0x644, 0x627, 0x3b, 0x622,
-0x6af, 0x648, 0x633, 0x62a, 0x3b, 0x633, 0x626, 0x67e, 0x62a, 0x627, 0x645, 0x631, 0x3b, 0x626, 0x648, 0x6a9, 0x62a, 0x648, 0x6a4, 0x631,
-0x3b, 0x646, 0x648, 0x6a4, 0x627, 0x645, 0x631, 0x3b, 0x62f, 0x626, 0x633, 0x627, 0x645, 0x631, 0x3b
+0x77, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x72, 0x61, 0x67, 0x3b,
+0x77, 0x61, 0x73, 0x3b, 0x70, 0x16b, 0x6c, 0x3b, 0x73, 0x61, 0x6b, 0x3b, 0x7a, 0x61, 0x6c, 0x3b, 0x73, 0x12b, 0x6d, 0x3b,
+0x6c, 0x12b, 0x70, 0x3b, 0x64, 0x61, 0x67, 0x3b, 0x73, 0x69, 0x6c, 0x3b, 0x73, 0x70, 0x61, 0x3b, 0x6c, 0x61, 0x70, 0x3b,
+0x73, 0x61, 0x6c, 0x3b, 0x72, 0x61, 0x67, 0x73, 0x3b, 0x77, 0x61, 0x73, 0x73, 0x61, 0x72, 0x69, 0x6e, 0x73, 0x3b, 0x70,
+0x16b, 0x6c, 0x69, 0x73, 0x3b, 0x73, 0x61, 0x6b, 0x6b, 0x69, 0x73, 0x3b, 0x7a, 0x61, 0x6c, 0x6c, 0x61, 0x77, 0x73, 0x3b,
+0x73, 0x12b, 0x6d, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6c, 0x12b, 0x70, 0x61, 0x3b, 0x64, 0x61, 0x67, 0x67, 0x69, 0x73, 0x3b,
+0x73, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x73, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x73, 0x3b, 0x6c, 0x61, 0x70,
+0x6b, 0x72, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x73, 0x61, 0x6c, 0x6c, 0x61, 0x77, 0x73, 0x3b, 0x52, 0x3b, 0x57, 0x3b, 0x50,
+0x3b, 0x53, 0x3b, 0x5a, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x75,
+0x111, 0x69, 0x76, 0x3b, 0x6b, 0x75, 0x6f, 0x76, 0xe2, 0x3b, 0x6e, 0x6a, 0x75, 0x68, 0x10d, 0xe2, 0x3b, 0x63, 0x75, 0xe1,
+0x14b, 0x75, 0x69, 0x3b, 0x76, 0x79, 0x65, 0x73, 0x69, 0x3b, 0x6b, 0x65, 0x73, 0x69, 0x3b, 0x73, 0x79, 0x65, 0x69, 0x6e,
+0x69, 0x3b, 0x70, 0x6f, 0x72, 0x67, 0x65, 0x3b, 0x10d, 0x6f, 0x68, 0x10d, 0xe2, 0x3b, 0x72, 0x6f, 0x6f, 0x76, 0x76, 0xe2,
+0x64, 0x3b, 0x73, 0x6b, 0x61, 0x6d, 0x6d, 0xe2, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0xe2, 0x3b, 0x75, 0x111, 0x111, 0xe2,
+0x69, 0x76, 0x65, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6b, 0x75, 0x6f, 0x76, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b,
+0x6e, 0x6a, 0x75, 0x68, 0x10d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x63, 0x75, 0xe1, 0x14b, 0x75, 0x69, 0x6d, 0xe1,
+0xe1, 0x6e, 0x75, 0x3b, 0x76, 0x79, 0x65, 0x73, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6b, 0x65, 0x73, 0x69, 0x6d,
+0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x73, 0x79, 0x65, 0x69, 0x6e, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x70, 0x6f, 0x72,
+0x67, 0x65, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x10d, 0x6f, 0x68, 0x10d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x72,
+0x6f, 0x6f, 0x76, 0x76, 0xe2, 0x64, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x73, 0x6b, 0x61, 0x6d, 0x6d, 0xe2, 0x6d, 0xe1,
+0xe1, 0x6e, 0x75, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x55, 0x3b, 0x4b, 0x3b,
+0x4e, 0x4a, 0x3b, 0x43, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x10c, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4a,
+0x3b, 0x62c, 0x627, 0x646, 0x6a4, 0x6cc, 0x6d5, 0x3b, 0x641, 0x626, 0x6a4, 0x631, 0x6cc, 0x6d5, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b,
+0x622, 0x6a4, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x6cc, 0x3b, 0x62c, 0x648, 0x659, 0x623, 0x646, 0x3b, 0x62c, 0x648, 0x659, 0x644,
+0x627, 0x3b, 0x622, 0x6af, 0x648, 0x633, 0x62a, 0x3b, 0x633, 0x626, 0x67e, 0x62a, 0x627, 0x645, 0x631, 0x3b, 0x626, 0x648, 0x6a9, 0x62a,
+0x648, 0x6a4, 0x631, 0x3b, 0x646, 0x648, 0x6a4, 0x627, 0x645, 0x631, 0x3b, 0x62f, 0x626, 0x633, 0x627, 0x645, 0x631, 0x3b
};
static const ushort days_data[] = {
@@ -3845,997 +3939,1044 @@ static const ushort days_data[] = {
0x64, 0x69, 0x65, 0x6c, 0x3b, 0x45, 0x20, 0x68, 0xeb, 0x6e, 0xeb, 0x3b, 0x45, 0x20, 0x6d, 0x61, 0x72, 0x74, 0xeb, 0x3b,
0x45, 0x20, 0x6d, 0xeb, 0x72, 0x6b, 0x75, 0x72, 0xeb, 0x3b, 0x45, 0x20, 0x65, 0x6e, 0x6a, 0x74, 0x65, 0x3b, 0x45, 0x20,
0x70, 0x72, 0x65, 0x6d, 0x74, 0x65, 0x3b, 0x45, 0x20, 0x73, 0x68, 0x74, 0x75, 0x6e, 0xeb, 0x3b, 0x44, 0x3b, 0x48, 0x3b,
-0x4d, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x65, 0x20, 0x64, 0x69, 0x65, 0x6c, 0x3b, 0x65, 0x20, 0x68,
-0xeb, 0x6e, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x74, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0xeb, 0x72, 0x6b, 0x75, 0x72,
-0xeb, 0x3b, 0x65, 0x20, 0x65, 0x6e, 0x6a, 0x74, 0x65, 0x3b, 0x65, 0x20, 0x70, 0x72, 0x65, 0x6d, 0x74, 0x65, 0x3b, 0x65,
-0x20, 0x73, 0x68, 0x74, 0x75, 0x6e, 0xeb, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b, 0x1230, 0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x3b, 0x1228,
-0x1261, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b, 0x1245, 0x12f3, 0x121c, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b, 0x1230,
-0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x129e, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b, 0x1245,
-0x12f3, 0x121c, 0x3b, 0x12a5, 0x3b, 0x1230, 0x3b, 0x121b, 0x3b, 0x1228, 0x3b, 0x1210, 0x3b, 0x12d3, 0x3b, 0x1245, 0x3b, 0x627, 0x644, 0x623,
-0x62d, 0x62f, 0x3b, 0x627, 0x644, 0x627, 0x62b, 0x646, 0x64a, 0x646, 0x3b, 0x627, 0x644, 0x62b, 0x644, 0x627, 0x62b, 0x627, 0x621, 0x3b,
-0x627, 0x644, 0x623, 0x631, 0x628, 0x639, 0x627, 0x621, 0x3b, 0x627, 0x644, 0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x627, 0x644, 0x62c, 0x645,
-0x639, 0x629, 0x3b, 0x627, 0x644, 0x633, 0x628, 0x62a, 0x3b, 0x62d, 0x3b, 0x646, 0x3b, 0x62b, 0x3b, 0x631, 0x3b, 0x62e, 0x3b, 0x62c,
-0x3b, 0x633, 0x3b, 0x56f, 0x56b, 0x580, 0x3b, 0x565, 0x580, 0x56f, 0x3b, 0x565, 0x580, 0x584, 0x3b, 0x579, 0x580, 0x584, 0x3b, 0x570,
-0x576, 0x563, 0x3b, 0x578, 0x582, 0x580, 0x3b, 0x577, 0x562, 0x569, 0x3b, 0x56f, 0x56b, 0x580, 0x561, 0x56f, 0x56b, 0x3b, 0x565, 0x580,
-0x56f, 0x578, 0x582, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x565, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x579,
-0x578, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x570, 0x56b, 0x576, 0x563, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b,
-0x578, 0x582, 0x580, 0x562, 0x561, 0x569, 0x3b, 0x577, 0x561, 0x562, 0x561, 0x569, 0x3b, 0x53f, 0x3b, 0x535, 0x3b, 0x535, 0x3b, 0x549,
-0x3b, 0x540, 0x3b, 0x548, 0x3b, 0x547, 0x3b, 0x9f0, 0x9ac, 0x9bf, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2,
-0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x3b,
-0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9a6, 0x9c7, 0x993, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ae, 0x999,
-0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd, 0x9aa,
-0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be,
-0x9f0, 0x3b, 0x42, 0x2e, 0x3b, 0x42, 0x2e, 0x45, 0x2e, 0x3b, 0xc7, 0x2e, 0x41, 0x2e, 0x3b, 0xc7, 0x2e, 0x3b, 0x43, 0x2e,
-0x41, 0x2e, 0x3b, 0x43, 0x2e, 0x3b, 0x15e, 0x2e, 0x3b, 0x62, 0x61, 0x7a, 0x61, 0x72, 0x3b, 0x62, 0x61, 0x7a, 0x61, 0x72,
-0x20, 0x65, 0x72, 0x74, 0x259, 0x73, 0x69, 0x3b, 0xe7, 0x259, 0x72, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x20, 0x61, 0x78, 0x15f,
-0x61, 0x6d, 0x131, 0x3b, 0xe7, 0x259, 0x72, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x20, 0x61, 0x78,
-0x15f, 0x61, 0x6d, 0x131, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x3b, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x3b, 0x411, 0x2e, 0x3b, 0x411,
-0x2e, 0x415, 0x2e, 0x3b, 0x427, 0x2e, 0x410, 0x2e, 0x3b, 0x427, 0x2e, 0x3b, 0x4b8, 0x2e, 0x410, 0x2e, 0x3b, 0x4b8, 0x2e, 0x3b,
-0x428, 0x2e, 0x3b, 0x431, 0x430, 0x437, 0x430, 0x440, 0x3b, 0x431, 0x430, 0x437, 0x430, 0x440, 0x20, 0x435, 0x440, 0x442, 0x4d9, 0x441,
-0x438, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x20, 0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x447, 0x4d9,
-0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, 0x4b9, 0x4af, 0x43c, 0x4d9, 0x20, 0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x4b9,
-0x4af, 0x43c, 0x4d9, 0x3b, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, 0x69, 0x67, 0x2e, 0x3b, 0x61, 0x6c, 0x2e, 0x3b, 0x61, 0x72,
-0x2e, 0x3b, 0x61, 0x7a, 0x2e, 0x3b, 0x6f, 0x67, 0x2e, 0x3b, 0x6f, 0x72, 0x2e, 0x3b, 0x6c, 0x72, 0x2e, 0x3b, 0x49, 0x67,
-0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x41, 0x73, 0x74, 0x65, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61, 0x3b, 0x41, 0x73, 0x74,
-0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x41, 0x73, 0x74, 0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x73,
-0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x4f, 0x73, 0x74, 0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b, 0x4c, 0x61, 0x72, 0x75,
-0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x4c, 0x3b,
-0x69, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61, 0x3b, 0x61,
-0x73, 0x74, 0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b,
-0x6f, 0x73, 0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x6f, 0x73, 0x74, 0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b, 0x6c, 0x61,
-0x72, 0x75, 0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997,
-0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0,
-0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae,
-0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd,
-0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac,
-0x9be, 0x9b0, 0x3b, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x3b, 0x9ae, 0x3b, 0x9ac, 0x9c1, 0x3b, 0x9ac, 0x9c3, 0x3b, 0x9b6, 0x9c1, 0x3b, 0x9b6,
-0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2,
-0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac,
-0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0xf5f,
-0xfb3, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf62, 0xf0b, 0x3b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0x3b, 0xf66, 0xf44,
-0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0x3b, 0xf49, 0xf72, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f, 0xfb3, 0xf0b,
-0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b,
-0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf42,
-0xf5f, 0xf60, 0xf0b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54,
-0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf62, 0x3b, 0xf63,
-0xfb7, 0xf42, 0x3b, 0xf55, 0xf74, 0xf62, 0x3b, 0xf66, 0xf44, 0xfb6, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0xf49, 0xf72, 0x3b, 0x53,
-0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x65, 0x75, 0x2e, 0x3b, 0x4d, 0x65, 0x72, 0x2e, 0x3b, 0x59, 0x61, 0x6f,
-0x75, 0x3b, 0x47, 0x77, 0x65, 0x2e, 0x3b, 0x53, 0x61, 0x64, 0x2e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b,
-0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x4d, 0x65, 0x72, 0x63, 0x2bc, 0x68, 0x65, 0x72, 0x3b, 0x59, 0x61, 0x6f, 0x75,
-0x3b, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x53, 0x61, 0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x53, 0x75, 0x3b, 0x4c, 0x3b,
-0x4d, 0x7a, 0x3b, 0x4d, 0x63, 0x3b, 0x59, 0x3b, 0x47, 0x3b, 0x53, 0x61, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x432,
-0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44f,
-0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b,
-0x441, 0x440, 0x44f, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x44a, 0x440, 0x442, 0x44a, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x44a,
-0x43a, 0x3b, 0x441, 0x44a, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x432, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f,
-0x3b, 0x441, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x1002, 0x1014, 0x103d, 0x1031, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x101c, 0x102c,
-0x3b, 0x1021, 0x1004, 0x103a, 0x1039, 0x1002, 0x102b, 0x3b, 0x1017, 0x102f, 0x1012, 0x1039, 0x1013, 0x101f, 0x1030, 0x1038, 0x3b, 0x1000, 0x103c, 0x102c,
-0x101e, 0x1015, 0x1010, 0x1031, 0x1038, 0x3b, 0x101e, 0x1031, 0x102c, 0x1000, 0x103c, 0x102c, 0x3b, 0x1005, 0x1014, 0x1031, 0x3b, 0x1010, 0x3b, 0x1010,
-0x3b, 0x1021, 0x3b, 0x1017, 0x3b, 0x1000, 0x3b, 0x101e, 0x3b, 0x1005, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x430, 0x45e, 0x3b,
-0x441, 0x440, 0x3b, 0x447, 0x446, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x44f, 0x3b,
-0x43f, 0x430, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x430, 0x43a, 0x3b, 0x430, 0x45e, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441,
-0x435, 0x440, 0x430, 0x434, 0x430, 0x3b, 0x447, 0x430, 0x446, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x456, 0x446, 0x430,
-0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b,
-0x441, 0x3b, 0x17a2, 0x17b6, 0x1791, 0x17b7, 0x178f, 0x17d2, 0x1799, 0x3b, 0x1785, 0x17d0, 0x1793, 0x17d2, 0x1791, 0x3b, 0x17a2, 0x1784, 0x17d2, 0x1782,
-0x17b6, 0x179a, 0x3b, 0x1796, 0x17bb, 0x1792, 0x3b, 0x1796, 0x17d2, 0x179a, 0x17a0, 0x179f, 0x17d2, 0x1794, 0x178f, 0x17b7, 0x17cd, 0x3b, 0x179f, 0x17bb,
-0x1780, 0x17d2, 0x179a, 0x3b, 0x179f, 0x17c5, 0x179a, 0x17cd, 0x3b, 0x17a2, 0x3b, 0x1785, 0x3b, 0x17a2, 0x3b, 0x1796, 0x3b, 0x1796, 0x3b, 0x179f,
-0x3b, 0x179f, 0x3b, 0x64, 0x67, 0x2e, 0x3b, 0x64, 0x6c, 0x2e, 0x3b, 0x64, 0x74, 0x2e, 0x3b, 0x64, 0x63, 0x2e, 0x3b, 0x64,
-0x6a, 0x2e, 0x3b, 0x64, 0x76, 0x2e, 0x3b, 0x64, 0x73, 0x2e, 0x3b, 0x64, 0x69, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x65, 0x3b,
-0x64, 0x69, 0x6c, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x65,
-0x63, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6a, 0x6f, 0x75, 0x73, 0x3b, 0x64, 0x69, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65,
-0x73, 0x3b, 0x64, 0x69, 0x73, 0x73, 0x61, 0x62, 0x74, 0x65, 0x3b, 0x64, 0x67, 0x3b, 0x64, 0x6c, 0x3b, 0x64, 0x74, 0x3b,
-0x64, 0x63, 0x3b, 0x64, 0x6a, 0x3b, 0x64, 0x76, 0x3b, 0x64, 0x73, 0x3b, 0x5468, 0x65e5, 0x3b, 0x5468, 0x4e00, 0x3b, 0x5468, 0x4e8c,
-0x3b, 0x5468, 0x4e09, 0x3b, 0x5468, 0x56db, 0x3b, 0x5468, 0x4e94, 0x3b, 0x5468, 0x516d, 0x3b, 0x661f, 0x671f, 0x65e5, 0x3b, 0x661f, 0x671f, 0x4e00,
-0x3b, 0x661f, 0x671f, 0x4e8c, 0x3b, 0x661f, 0x671f, 0x4e09, 0x3b, 0x661f, 0x671f, 0x56db, 0x3b, 0x661f, 0x671f, 0x4e94, 0x3b, 0x661f, 0x671f, 0x516d,
-0x3b, 0x65e5, 0x3b, 0x4e00, 0x3b, 0x4e8c, 0x3b, 0x4e09, 0x3b, 0x56db, 0x3b, 0x4e94, 0x3b, 0x516d, 0x3b, 0x9031, 0x65e5, 0x3b, 0x9031, 0x4e00,
-0x3b, 0x9031, 0x4e8c, 0x3b, 0x9031, 0x4e09, 0x3b, 0x9031, 0x56db, 0x3b, 0x9031, 0x4e94, 0x3b, 0x9031, 0x516d, 0x3b, 0x6e, 0x65, 0x64, 0x3b,
-0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x69, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b,
-0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x6a, 0x65,
-0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b,
-0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74,
-0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x4e, 0x3b, 0x50, 0x3b,
-0x55, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0xfa, 0x74, 0x3b, 0x73,
-0x74, 0x3b, 0x10d, 0x74, 0x3b, 0x70, 0xe1, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x11b, 0x6c, 0x65, 0x3b, 0x70, 0x6f,
-0x6e, 0x64, 0x11b, 0x6c, 0xed, 0x3b, 0xfa, 0x74, 0x65, 0x72, 0xfd, 0x3b, 0x73, 0x74, 0x159, 0x65, 0x64, 0x61, 0x3b, 0x10d,
-0x74, 0x76, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0xe1, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b,
-0x4e, 0x3b, 0x50, 0x3b, 0xda, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0x61,
-0x6e, 0x3b, 0x74, 0x69, 0x72, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf8,
-0x72, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x72, 0x73,
-0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66,
-0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0xf8, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4f,
-0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0xf8, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x6e, 0x2e, 0x3b, 0x74, 0x69, 0x72,
-0x2e, 0x3b, 0x6f, 0x6e, 0x73, 0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x66, 0x72, 0x65, 0x2e, 0x3b, 0x6c, 0xf8, 0x72,
-0x2e, 0x3b, 0x7a, 0x6f, 0x3b, 0x6d, 0x61, 0x3b, 0x64, 0x69, 0x3b, 0x77, 0x6f, 0x3b, 0x64, 0x6f, 0x3b, 0x76, 0x72, 0x3b,
-0x7a, 0x61, 0x3b, 0x7a, 0x6f, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x69,
-0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x77, 0x6f, 0x65, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x6f, 0x6e, 0x64, 0x65,
-0x72, 0x64, 0x61, 0x67, 0x3b, 0x76, 0x72, 0x69, 0x6a, 0x64, 0x61, 0x67, 0x3b, 0x7a, 0x61, 0x74, 0x65, 0x72, 0x64, 0x61,
-0x67, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x56, 0x3b, 0x5a, 0x3b, 0x53, 0x75, 0x6e, 0x2e,
-0x3b, 0x4d, 0x6f, 0x6e, 0x2e, 0x3b, 0x54, 0x75, 0x65, 0x2e, 0x3b, 0x57, 0x65, 0x64, 0x2e, 0x3b, 0x54, 0x68, 0x75, 0x2e,
-0x3b, 0x46, 0x72, 0x69, 0x2e, 0x3b, 0x53, 0x61, 0x74, 0x2e, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0x2e, 0x3b, 0x54, 0x75,
-0x2e, 0x3b, 0x57, 0x2e, 0x3b, 0x54, 0x68, 0x2e, 0x3b, 0x46, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x50, 0x3b, 0x45, 0x3b,
-0x54, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x52, 0x3b, 0x4c, 0x3b, 0x70, 0xfc, 0x68, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x65,
-0x73, 0x6d, 0x61, 0x73, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x74, 0x65, 0x69, 0x73, 0x69, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6b,
-0x6f, 0x6c, 0x6d, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6e, 0x65, 0x6c, 0x6a, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x72,
-0x65, 0x65, 0x64, 0x65, 0x3b, 0x6c, 0x61, 0x75, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x73, 0x75, 0x6e, 0x3b, 0x6d, 0xe1, 0x6e,
-0x3b, 0x74, 0xfd, 0x73, 0x3b, 0x6d, 0x69, 0x6b, 0x3b, 0x68, 0xf3, 0x73, 0x3b, 0x66, 0x72, 0xed, 0x3b, 0x6c, 0x65, 0x79,
-0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x61, 0x64, 0x61, 0x67, 0x75,
-0x72, 0x3b, 0x74, 0xfd, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72,
-0x3b, 0x68, 0xf3, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x72, 0xed, 0x67, 0x67, 0x6a, 0x61, 0x64, 0x61, 0x67,
-0x75, 0x72, 0x3b, 0x6c, 0x65, 0x79, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54,
-0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0xe1, 0x6e, 0x2e, 0x3b, 0x74,
-0xfd, 0x73, 0x2e, 0x3b, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x68, 0xf3, 0x73, 0x2e, 0x3b, 0x66, 0x72, 0xed, 0x2e, 0x3b, 0x6c,
-0x65, 0x79, 0x2e, 0x3b, 0x73, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x74, 0x69, 0x3b, 0x6b, 0x65, 0x3b, 0x74, 0x6f, 0x3b, 0x70,
-0x65, 0x3b, 0x6c, 0x61, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61,
-0x6e, 0x74, 0x61, 0x69, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x6b, 0x65, 0x73, 0x6b, 0x69, 0x76, 0x69,
-0x69, 0x6b, 0x6b, 0x6f, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74,
-0x61, 0x69, 0x3b, 0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4b, 0x3b,
-0x54, 0x3b, 0x50, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6d, 0x61,
-0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b,
-0x6b, 0x65, 0x73, 0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, 0x6e, 0x61, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61,
-0x69, 0x6e, 0x61, 0x3b, 0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6c, 0x61, 0x75, 0x61,
-0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x64, 0x69, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72,
-0x2e, 0x3b, 0x6d, 0x65, 0x72, 0x2e, 0x3b, 0x6a, 0x65, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e, 0x3b, 0x73, 0x61, 0x6d,
-0x2e, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72,
-0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x6a, 0x65, 0x75, 0x64, 0x69, 0x3b, 0x76, 0x65,
-0x6e, 0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x69, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b,
-0x4d, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x73, 0x69, 0x3b, 0x6d, 0x6f, 0x3b, 0x74, 0x69, 0x3b, 0x77, 0x6f, 0x3b,
-0x74, 0x6f, 0x3b, 0x66, 0x72, 0x3b, 0x73, 0x6f, 0x3b, 0x73, 0x6e, 0x65, 0x69, 0x6e, 0x3b, 0x6d, 0x6f, 0x61, 0x6e, 0x64,
-0x65, 0x69, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x77, 0x6f, 0x61, 0x6e, 0x73, 0x64, 0x65, 0x69, 0x3b,
-0x74, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x66, 0x72, 0x65, 0x65, 0x64, 0x3b, 0x73, 0x6e, 0x65,
-0x6f, 0x6e, 0x3b, 0x44, 0x69, 0x44, 0x3b, 0x44, 0x69, 0x4c, 0x3b, 0x44, 0x69, 0x4d, 0x3b, 0x44, 0x69, 0x43, 0x3b, 0x44,
-0x69, 0x61, 0x3b, 0x44, 0x69, 0x68, 0x3b, 0x44, 0x69, 0x53, 0x3b, 0x44, 0x69, 0x44, 0xf2, 0x6d, 0x68, 0x6e, 0x61, 0x69,
-0x63, 0x68, 0x3b, 0x44, 0x69, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x4d, 0xe0, 0x69, 0x72, 0x74, 0x3b, 0x44,
-0x69, 0x43, 0x69, 0x61, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x61, 0x72, 0x44, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44,
-0x69, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0x69, 0x53, 0x61, 0x74, 0x68, 0x61, 0x69, 0x72, 0x6e, 0x65, 0x3b,
-0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x2e, 0x3b, 0x4c,
-0x75, 0x6e, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x4d, 0xe9, 0x72, 0x2e, 0x3b, 0x58, 0x6f, 0x76, 0x2e, 0x3b, 0x56,
-0x65, 0x6e, 0x2e, 0x3b, 0x53, 0xe1, 0x62, 0x2e, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e,
-0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x58, 0x6f,
-0x76, 0x65, 0x73, 0x3b, 0x56, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b,
-0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e,
-0x73, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0xe9, 0x72, 0x2e, 0x3b, 0x78, 0x6f, 0x76, 0x2e, 0x3b, 0x76, 0x65, 0x6e,
-0x2e, 0x3b, 0x73, 0xe1, 0x62, 0x2e, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x73, 0x3b,
-0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x78, 0x6f, 0x76, 0x65,
-0x73, 0x3b, 0x76, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x64, 0x2e, 0x3b, 0x6c,
-0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, 0x76, 0x2e, 0x3b, 0x73, 0x2e, 0x3b, 0x10d9, 0x10d5, 0x10d8,
-0x3b, 0x10dd, 0x10e0, 0x10e8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x3b, 0x10de, 0x10d0, 0x10e0,
-0x3b, 0x10e8, 0x10d0, 0x10d1, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x10e0, 0x10d0, 0x3b, 0x10dd, 0x10e0, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b,
-0x10e1, 0x10d0, 0x10db, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b,
-0x10ee, 0x10e3, 0x10d7, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x10d0, 0x10e1, 0x10d9, 0x10d4, 0x10d5, 0x10d8, 0x3b,
-0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10d9, 0x3b, 0x10dd, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10ee, 0x3b, 0x10de, 0x3b, 0x10e8,
-0x3b, 0x53, 0x6f, 0x3b, 0x4d, 0x6f, 0x3b, 0x44, 0x69, 0x3b, 0x4d, 0x69, 0x3b, 0x44, 0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53,
-0x61, 0x3b, 0x53, 0x6f, 0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x65,
-0x6e, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65,
-0x72, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x65, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x74, 0x61,
-0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x2e, 0x3b,
-0x4d, 0x6f, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x6f, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b,
-0x53, 0x61, 0x2e, 0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3b,
-0x3a0, 0x3ad, 0x3bc, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b9, 0x3b1, 0x3ba, 0x3ae, 0x3b,
-0x394, 0x3b5, 0x3c5, 0x3c4, 0x3ad, 0x3c1, 0x3b1, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3c4, 0x3b7, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3ac, 0x3c1, 0x3c4,
-0x3b7, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3c0, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b1, 0x3c3, 0x3ba, 0x3b5, 0x3c5, 0x3ae, 0x3b, 0x3a3,
-0x3ac, 0x3b2, 0x3b2, 0x3b1, 0x3c4, 0x3bf, 0x3b, 0x39a, 0x3b, 0x394, 0x3b, 0x3a4, 0x3b, 0x3a4, 0x3b, 0x3a0, 0x3b, 0x3a0, 0x3b, 0x3a3,
-0x3b, 0x73, 0x61, 0x62, 0x3b, 0x61, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, 0x69, 0x6e, 0x3b, 0x73, 0x69, 0x73,
-0x3b, 0x74, 0x61, 0x6c, 0x3b, 0x61, 0x72, 0x66, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x61, 0x74, 0x3b, 0x61, 0x74, 0x61, 0x61,
-0x73, 0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x6d, 0x61, 0x72, 0x6c, 0x75, 0x6e, 0x6e, 0x67, 0x6f,
-0x72, 0x6e, 0x65, 0x71, 0x3b, 0x70, 0x69, 0x6e, 0x67, 0x61, 0x73, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71,
-0x3b, 0x73, 0x69, 0x73, 0x61, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x74, 0x61, 0x6c, 0x6c,
-0x69, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x6e, 0x6e,
-0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x41,
-0x3b, 0xab0, 0xab5, 0xabf, 0x3b, 0xab8, 0xacb, 0xaae, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0x3b, 0xaac, 0xac1, 0xaa7, 0x3b, 0xa97, 0xac1,
-0xab0, 0xac1, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0x3b, 0xab0, 0xab5, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b,
-0xab8, 0xacb, 0xaae, 0xab5, 0xabe, 0xab0, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0xab5, 0xabe, 0xab0, 0x3b, 0xaac, 0xac1, 0xaa7, 0xab5, 0xabe,
-0xab0, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6,
-0xaa8, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab0, 0x3b, 0xab8, 0xacb, 0x3b, 0xaae, 0xa82, 0x3b, 0xaac, 0xac1, 0x3b, 0xa97, 0xac1, 0x3b,
-0xab6, 0xac1, 0x3b, 0xab6, 0x3b, 0x4c, 0x61, 0x68, 0x3b, 0x4c, 0x69, 0x74, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x72,
-0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x4c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b,
-0x4c, 0x69, 0x74, 0x69, 0x6e, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x4c, 0x61, 0x72, 0x61, 0x62,
-0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x6d, 0x61, 0x2bc, 0x61, 0x3b, 0x41, 0x73,
-0x61, 0x62, 0x61, 0x72, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x5d9,
-0x5d5, 0x5dd, 0x20, 0x5d0, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d1, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d2, 0x5f3, 0x3b,
-0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d3, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d4, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d5, 0x5f3,
-0x3b, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d0, 0x5e9, 0x5d5, 0x5df, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9,
-0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5dc, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d1, 0x5d9,
-0x5e2, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d7, 0x5de, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d9, 0x5e9,
-0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d0, 0x5f3, 0x3b, 0x5d1, 0x5f3, 0x3b, 0x5d2, 0x5f3, 0x3b, 0x5d3,
-0x5f3, 0x3b, 0x5d4, 0x5f3, 0x3b, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5f3, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e,
-0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936,
-0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917,
-0x932, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b,
-0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x94b,
-0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x917, 0x941, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b,
-0x3b, 0x53, 0x7a, 0x65, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0xe1, 0x72, 0x6e,
-0x61, 0x70, 0x3b, 0x68, 0xe9, 0x74, 0x66, 0x151, 0x3b, 0x6b, 0x65, 0x64, 0x64, 0x3b, 0x73, 0x7a, 0x65, 0x72, 0x64, 0x61,
-0x3b, 0x63, 0x73, 0xfc, 0x74, 0xf6, 0x72, 0x74, 0xf6, 0x6b, 0x3b, 0x70, 0xe9, 0x6e, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x7a,
-0x6f, 0x6d, 0x62, 0x61, 0x74, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b,
-0x53, 0x7a, 0x3b, 0x73, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0xe1, 0x6e, 0x2e, 0x3b, 0xfe, 0x72, 0x69, 0x2e, 0x3b, 0x6d, 0x69,
-0xf0, 0x2e, 0x3b, 0x66, 0x69, 0x6d, 0x2e, 0x3b, 0x66, 0xf6, 0x73, 0x2e, 0x3b, 0x6c, 0x61, 0x75, 0x2e, 0x3b, 0x73, 0x75,
-0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0xfe,
-0x72, 0x69, 0xf0, 0x6a, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0xf0, 0x76, 0x69, 0x6b, 0x75, 0x64, 0x61,
-0x67, 0x75, 0x72, 0x3b, 0x66, 0x69, 0x6d, 0x6d, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0xf6, 0x73, 0x74,
-0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, 0x61, 0x75, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53,
-0x3b, 0x4d, 0x3b, 0xde, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4d, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6e,
-0x3b, 0x53, 0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62,
-0x3b, 0x4d, 0x69, 0x6e, 0x67, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61,
-0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x3b, 0x53, 0x61,
-0x62, 0x74, 0x75, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x44, 0x6f,
-0x6d, 0x68, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x3b, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x43, 0xe9, 0x61, 0x64, 0x3b, 0x44,
-0xe9, 0x61, 0x72, 0x3b, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x44, 0x6f,
-0x6d, 0x68, 0x6e, 0x61, 0x69, 0x67, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20,
-0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x44, 0xe9, 0x20, 0x43, 0xe9, 0x61, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9,
-0x61, 0x72, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0xe9,
-0x20, 0x53, 0x61, 0x74, 0x68, 0x61, 0x69, 0x72, 0x6e, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x44, 0x3b,
-0x41, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b,
-0x67, 0x69, 0x6f, 0x3b, 0x76, 0x65, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x63, 0x61,
-0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x64, 0xec, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x6d, 0x65, 0x72, 0x63,
-0x6f, 0x6c, 0x65, 0x64, 0xec, 0x3b, 0x67, 0x69, 0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x76, 0x65, 0x6e, 0x65, 0x72, 0x64,
-0xec, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x56,
-0x3b, 0x53, 0x3b, 0x65e5, 0x3b, 0x6708, 0x3b, 0x706b, 0x3b, 0x6c34, 0x3b, 0x6728, 0x3b, 0x91d1, 0x3b, 0x571f, 0x3b, 0x65e5, 0x66dc, 0x65e5,
-0x3b, 0x6708, 0x66dc, 0x65e5, 0x3b, 0x706b, 0x66dc, 0x65e5, 0x3b, 0x6c34, 0x66dc, 0x65e5, 0x3b, 0x6728, 0x66dc, 0x65e5, 0x3b, 0x91d1, 0x66dc, 0x65e5,
-0x3b, 0x571f, 0x66dc, 0x65e5, 0x3b, 0xcad, 0xcbe, 0xca8, 0xcc1, 0x3b, 0xcb8, 0xccb, 0xcae, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0x3b, 0xcac,
-0xcc1, 0xca7, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf, 0x3b, 0xcad, 0xcbe,
-0xca8, 0xcc1, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb8, 0xccb, 0xcae, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0xcb5, 0xcbe, 0xcb0,
-0x3b, 0xcac, 0xcc1, 0xca7, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd,
-0xcb0, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcad, 0xcbe, 0x3b, 0xcb8, 0xccb, 0x3b, 0xcae, 0xc82,
-0x3b, 0xcac, 0xcc1, 0x3b, 0xc97, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0x3b, 0xcb6, 0x3b, 0x622, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698,
-0x654, 0x646, 0x65b, 0x62f, 0x655, 0x631, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648,
-0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x631, 0x65b, 0x66e, 0x6ea, 0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b,
-0x628, 0x679, 0x648, 0x627, 0x631, 0x3b, 0x627, 0x64e, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x631,
+0x4d, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x50, 0x3b, 0x53, 0x68, 0x3b, 0x65, 0x20, 0x64, 0x69, 0x65, 0x6c, 0x3b, 0x65, 0x20,
+0x68, 0xeb, 0x6e, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x74, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0xeb, 0x72, 0x6b, 0x75,
+0x72, 0xeb, 0x3b, 0x65, 0x20, 0x65, 0x6e, 0x6a, 0x74, 0x65, 0x3b, 0x65, 0x20, 0x70, 0x72, 0x65, 0x6d, 0x74, 0x65, 0x3b,
+0x65, 0x20, 0x73, 0x68, 0x74, 0x75, 0x6e, 0xeb, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b, 0x1230, 0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x3b,
+0x1228, 0x1261, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b, 0x1245, 0x12f3, 0x121c, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b,
+0x1230, 0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x129e, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b,
+0x1245, 0x12f3, 0x121c, 0x3b, 0x12a5, 0x3b, 0x1230, 0x3b, 0x121b, 0x3b, 0x1228, 0x3b, 0x1210, 0x3b, 0x12d3, 0x3b, 0x1245, 0x3b, 0x627, 0x644,
+0x623, 0x62d, 0x62f, 0x3b, 0x627, 0x644, 0x627, 0x62b, 0x646, 0x64a, 0x646, 0x3b, 0x627, 0x644, 0x62b, 0x644, 0x627, 0x62b, 0x627, 0x621,
+0x3b, 0x627, 0x644, 0x623, 0x631, 0x628, 0x639, 0x627, 0x621, 0x3b, 0x627, 0x644, 0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x627, 0x644, 0x62c,
+0x645, 0x639, 0x629, 0x3b, 0x627, 0x644, 0x633, 0x628, 0x62a, 0x3b, 0x62d, 0x3b, 0x646, 0x3b, 0x62b, 0x3b, 0x631, 0x3b, 0x62e, 0x3b,
+0x62c, 0x3b, 0x633, 0x3b, 0x56f, 0x56b, 0x580, 0x3b, 0x565, 0x580, 0x56f, 0x3b, 0x565, 0x580, 0x584, 0x3b, 0x579, 0x580, 0x584, 0x3b,
+0x570, 0x576, 0x563, 0x3b, 0x578, 0x582, 0x580, 0x3b, 0x577, 0x562, 0x569, 0x3b, 0x56f, 0x56b, 0x580, 0x561, 0x56f, 0x56b, 0x3b, 0x565,
+0x580, 0x56f, 0x578, 0x582, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x565, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b,
+0x579, 0x578, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x570, 0x56b, 0x576, 0x563, 0x577, 0x561, 0x562, 0x569, 0x56b,
+0x3b, 0x578, 0x582, 0x580, 0x562, 0x561, 0x569, 0x3b, 0x577, 0x561, 0x562, 0x561, 0x569, 0x3b, 0x53f, 0x3b, 0x535, 0x3b, 0x535, 0x3b,
+0x549, 0x3b, 0x540, 0x3b, 0x548, 0x3b, 0x547, 0x3b, 0x9a6, 0x9c7, 0x993, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997,
+0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b,
+0x9a6, 0x9c7, 0x993, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac,
+0x9be, 0x9f0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be,
+0x9f0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9a6, 0x3b,
+0x9b8, 0x3b, 0x9ae, 0x3b, 0x9ac, 0x3b, 0x9ac, 0x3b, 0x9b6, 0x3b, 0x9b6, 0x3b, 0x42, 0x2e, 0x3b, 0x42, 0x2e, 0x45, 0x2e, 0x3b,
+0xc7, 0x2e, 0x41, 0x2e, 0x3b, 0xc7, 0x2e, 0x3b, 0x43, 0x2e, 0x41, 0x2e, 0x3b, 0x43, 0x2e, 0x3b, 0x15e, 0x2e, 0x3b, 0x62,
+0x61, 0x7a, 0x61, 0x72, 0x3b, 0x62, 0x61, 0x7a, 0x61, 0x72, 0x20, 0x65, 0x72, 0x74, 0x259, 0x73, 0x69, 0x3b, 0xe7, 0x259,
+0x72, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x20, 0x61, 0x78, 0x15f, 0x61, 0x6d, 0x131, 0x3b, 0xe7, 0x259, 0x72, 0x15f, 0x259, 0x6e,
+0x62, 0x259, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x20, 0x61, 0x78, 0x15f, 0x61, 0x6d, 0x131, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x3b,
+0x15f, 0x259, 0x6e, 0x62, 0x259, 0x3b, 0x411, 0x2e, 0x3b, 0x411, 0x2e, 0x415, 0x2e, 0x3b, 0x427, 0x2e, 0x410, 0x2e, 0x3b, 0x427,
+0x2e, 0x3b, 0x4b8, 0x2e, 0x410, 0x2e, 0x3b, 0x4b8, 0x2e, 0x3b, 0x428, 0x2e, 0x3b, 0x431, 0x430, 0x437, 0x430, 0x440, 0x3b, 0x431,
+0x430, 0x437, 0x430, 0x440, 0x20, 0x435, 0x440, 0x442, 0x4d9, 0x441, 0x438, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9,
+0x20, 0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, 0x4b9, 0x4af, 0x43c,
+0x4d9, 0x20, 0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x4b9, 0x4af, 0x43c, 0x4d9, 0x3b, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b,
+0x69, 0x67, 0x2e, 0x3b, 0x61, 0x6c, 0x2e, 0x3b, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x7a, 0x2e, 0x3b, 0x6f, 0x67, 0x2e, 0x3b,
+0x6f, 0x72, 0x2e, 0x3b, 0x6c, 0x72, 0x2e, 0x3b, 0x49, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x41, 0x73, 0x74, 0x65,
+0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61, 0x3b, 0x41, 0x73, 0x74, 0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x41, 0x73, 0x74,
+0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x73, 0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x4f, 0x73, 0x74,
+0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b, 0x4c, 0x61, 0x72, 0x75, 0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x49, 0x3b, 0x41, 0x3b,
+0x41, 0x3b, 0x41, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x4c, 0x3b, 0x69, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x73,
+0x74, 0x65, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x61,
+0x73, 0x74, 0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x73, 0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x6f,
+0x73, 0x74, 0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b, 0x6c, 0x61, 0x72, 0x75, 0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x9b0, 0x9ac,
+0x9bf, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8,
+0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be,
+0x9b0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1,
+0x9a7, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995,
+0x9cd, 0x9b0, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x3b, 0x9ae, 0x3b,
+0x9ac, 0x9c1, 0x3b, 0x9ac, 0x9c3, 0x3b, 0x9b6, 0x9c1, 0x3b, 0x9b6, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b8, 0x9cb,
+0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9b0,
+0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x9ac, 0x9be,
+0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf62, 0xf0b, 0x3b, 0xf63, 0xfb7,
+0xf42, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0x3b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0x3b, 0xf49,
+0xf72, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42,
+0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60,
+0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b,
+0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58,
+0xf0b, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf62, 0x3b, 0xf63, 0xfb7, 0xf42, 0x3b, 0xf55, 0xf74, 0xf62, 0x3b, 0xf66, 0xf44, 0xfb6,
+0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0xf49, 0xf72, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x65, 0x75,
+0x2e, 0x3b, 0x4d, 0x65, 0x72, 0x2e, 0x3b, 0x59, 0x61, 0x6f, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x2e, 0x3b, 0x53, 0x61, 0x64,
+0x2e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x4d, 0x65, 0x72,
+0x63, 0x2bc, 0x68, 0x65, 0x72, 0x3b, 0x59, 0x61, 0x6f, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x53, 0x61,
+0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x53, 0x75, 0x3b, 0x4c, 0x3b, 0x4d, 0x7a, 0x3b, 0x4d, 0x63, 0x3b, 0x59, 0x3b, 0x47, 0x3b,
+0x53, 0x61, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442,
+0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d, 0x438,
+0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x44f, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432,
+0x44a, 0x440, 0x442, 0x44a, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x44a, 0x43a, 0x3b, 0x441, 0x44a, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d,
+0x3b, 0x43f, 0x3b, 0x432, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x1002, 0x1014,
+0x103d, 0x1031, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x101c, 0x102c, 0x3b, 0x1021, 0x1004, 0x103a, 0x1039, 0x1002, 0x102b, 0x3b, 0x1017, 0x102f,
+0x1012, 0x1039, 0x1013, 0x101f, 0x1030, 0x1038, 0x3b, 0x1000, 0x103c, 0x102c, 0x101e, 0x1015, 0x1010, 0x1031, 0x1038, 0x3b, 0x101e, 0x1031, 0x102c, 0x1000,
+0x103c, 0x102c, 0x3b, 0x1005, 0x1014, 0x1031, 0x3b, 0x1010, 0x3b, 0x1010, 0x3b, 0x1021, 0x3b, 0x1017, 0x3b, 0x1000, 0x3b, 0x101e, 0x3b, 0x1005,
+0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x430, 0x45e, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x446, 0x3b, 0x43f, 0x442, 0x3b, 0x441,
+0x431, 0x3b, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x430, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x430, 0x43a,
+0x3b, 0x430, 0x45e, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x435, 0x440, 0x430, 0x434, 0x430, 0x3b, 0x447, 0x430, 0x446, 0x432,
+0x435, 0x440, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x456, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b,
+0x43f, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x17a2, 0x17b6, 0x1791, 0x17b7, 0x178f, 0x17d2, 0x1799, 0x3b,
+0x1785, 0x17d0, 0x1793, 0x17d2, 0x1791, 0x3b, 0x17a2, 0x1784, 0x17d2, 0x1782, 0x17b6, 0x179a, 0x3b, 0x1796, 0x17bb, 0x1792, 0x3b, 0x1796, 0x17d2, 0x179a,
+0x17a0, 0x179f, 0x17d2, 0x1794, 0x178f, 0x17b7, 0x17cd, 0x3b, 0x179f, 0x17bb, 0x1780, 0x17d2, 0x179a, 0x3b, 0x179f, 0x17c5, 0x179a, 0x17cd, 0x3b, 0x17a2,
+0x3b, 0x1785, 0x3b, 0x17a2, 0x3b, 0x1796, 0x3b, 0x1796, 0x3b, 0x179f, 0x3b, 0x179f, 0x3b, 0x64, 0x67, 0x2e, 0x3b, 0x64, 0x6c, 0x2e,
+0x3b, 0x64, 0x74, 0x2e, 0x3b, 0x64, 0x63, 0x2e, 0x3b, 0x64, 0x6a, 0x2e, 0x3b, 0x64, 0x76, 0x2e, 0x3b, 0x64, 0x73, 0x2e,
+0x3b, 0x64, 0x69, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x65, 0x3b, 0x64, 0x69, 0x6c, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x64, 0x69,
+0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x65, 0x63, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6a, 0x6f, 0x75,
+0x73, 0x3b, 0x64, 0x69, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x73, 0x73, 0x61, 0x62, 0x74, 0x65,
+0x3b, 0x64, 0x67, 0x3b, 0x64, 0x6c, 0x3b, 0x64, 0x74, 0x3b, 0x64, 0x63, 0x3b, 0x64, 0x6a, 0x3b, 0x64, 0x76, 0x3b, 0x64,
+0x73, 0x3b, 0x5468, 0x65e5, 0x3b, 0x5468, 0x4e00, 0x3b, 0x5468, 0x4e8c, 0x3b, 0x5468, 0x4e09, 0x3b, 0x5468, 0x56db, 0x3b, 0x5468, 0x4e94, 0x3b,
+0x5468, 0x516d, 0x3b, 0x661f, 0x671f, 0x65e5, 0x3b, 0x661f, 0x671f, 0x4e00, 0x3b, 0x661f, 0x671f, 0x4e8c, 0x3b, 0x661f, 0x671f, 0x4e09, 0x3b, 0x661f,
+0x671f, 0x56db, 0x3b, 0x661f, 0x671f, 0x4e94, 0x3b, 0x661f, 0x671f, 0x516d, 0x3b, 0x65e5, 0x3b, 0x4e00, 0x3b, 0x4e8c, 0x3b, 0x4e09, 0x3b, 0x56db,
+0x3b, 0x4e94, 0x3b, 0x516d, 0x3b, 0x9031, 0x65e5, 0x3b, 0x9031, 0x4e00, 0x3b, 0x9031, 0x4e8c, 0x3b, 0x9031, 0x4e09, 0x3b, 0x9031, 0x56db, 0x3b,
+0x9031, 0x4e94, 0x3b, 0x9031, 0x516d, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72,
+0x69, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c,
+0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61,
+0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70,
+0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b,
+0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b,
+0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0xfa, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x10d, 0x74, 0x3b, 0x70, 0xe1, 0x3b, 0x73, 0x6f,
+0x3b, 0x6e, 0x65, 0x64, 0x11b, 0x6c, 0x65, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x11b, 0x6c, 0xed, 0x3b, 0xfa, 0x74, 0x65, 0x72,
+0xfd, 0x3b, 0x73, 0x74, 0x159, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x74, 0x76, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0xe1, 0x74,
+0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0xda, 0x3b, 0x53, 0x3b, 0x10c, 0x3b,
+0x50, 0x3b, 0x53, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0x61, 0x6e, 0x3b, 0x74, 0x69, 0x72, 0x3b, 0x6f, 0x6e, 0x73, 0x3b,
+0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf8, 0x72, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d,
+0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67,
+0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0xf8, 0x72, 0x64,
+0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0xf8, 0x6e,
+0x2e, 0x3b, 0x6d, 0x61, 0x6e, 0x2e, 0x3b, 0x74, 0x69, 0x72, 0x2e, 0x3b, 0x6f, 0x6e, 0x73, 0x2e, 0x3b, 0x74, 0x6f, 0x72,
+0x2e, 0x3b, 0x66, 0x72, 0x65, 0x2e, 0x3b, 0x6c, 0xf8, 0x72, 0x2e, 0x3b, 0x7a, 0x6f, 0x3b, 0x6d, 0x61, 0x3b, 0x64, 0x69,
+0x3b, 0x77, 0x6f, 0x3b, 0x64, 0x6f, 0x3b, 0x76, 0x72, 0x3b, 0x7a, 0x61, 0x3b, 0x7a, 0x6f, 0x6e, 0x64, 0x61, 0x67, 0x3b,
+0x6d, 0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x69, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x77, 0x6f, 0x65, 0x6e,
+0x73, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x76, 0x72, 0x69, 0x6a, 0x64,
+0x61, 0x67, 0x3b, 0x7a, 0x61, 0x74, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x57, 0x3b,
+0x44, 0x3b, 0x56, 0x3b, 0x5a, 0x3b, 0x53, 0x75, 0x6e, 0x2e, 0x3b, 0x4d, 0x6f, 0x6e, 0x2e, 0x3b, 0x54, 0x75, 0x65, 0x2e,
+0x3b, 0x57, 0x65, 0x64, 0x2e, 0x3b, 0x54, 0x68, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x69, 0x2e, 0x3b, 0x53, 0x61, 0x74, 0x2e,
+0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0x2e, 0x3b, 0x54, 0x75, 0x2e, 0x3b, 0x57, 0x2e, 0x3b, 0x54, 0x68, 0x2e, 0x3b, 0x46,
+0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x64, 0x69, 0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x65, 0x3b, 0x135, 0x61,
+0x3b, 0x76, 0x65, 0x3b, 0x73, 0x61, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x109, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x6f,
+0x3b, 0x6d, 0x61, 0x72, 0x64, 0x6f, 0x3b, 0x6d, 0x65, 0x72, 0x6b, 0x72, 0x65, 0x64, 0x6f, 0x3b, 0x135, 0x61, 0x16d, 0x64,
+0x6f, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x6f, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x3b,
+0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x134, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x45, 0x3b, 0x54, 0x3b, 0x4b, 0x3b,
+0x4e, 0x3b, 0x52, 0x3b, 0x4c, 0x3b, 0x70, 0xfc, 0x68, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x65, 0x73, 0x6d, 0x61, 0x73,
+0x70, 0xe4, 0x65, 0x76, 0x3b, 0x74, 0x65, 0x69, 0x73, 0x69, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6b, 0x6f, 0x6c, 0x6d, 0x61,
+0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6e, 0x65, 0x6c, 0x6a, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x72, 0x65, 0x65, 0x64, 0x65,
+0x3b, 0x6c, 0x61, 0x75, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x73, 0x75, 0x6e, 0x3b, 0x6d, 0xe1, 0x6e, 0x3b, 0x74, 0xfd, 0x73,
+0x3b, 0x6d, 0x69, 0x6b, 0x3b, 0x68, 0xf3, 0x73, 0x3b, 0x66, 0x72, 0xed, 0x3b, 0x6c, 0x65, 0x79, 0x3b, 0x73, 0x75, 0x6e,
+0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x74, 0xfd,
+0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x68, 0xf3, 0x73,
+0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x72, 0xed, 0x67, 0x67, 0x6a, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c,
+0x65, 0x79, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x48,
+0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0xe1, 0x6e, 0x2e, 0x3b, 0x74, 0xfd, 0x73, 0x2e, 0x3b,
+0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x68, 0xf3, 0x73, 0x2e, 0x3b, 0x66, 0x72, 0xed, 0x2e, 0x3b, 0x6c, 0x65, 0x79, 0x2e, 0x3b,
+0x73, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x74, 0x69, 0x3b, 0x6b, 0x65, 0x3b, 0x74, 0x6f, 0x3b, 0x70, 0x65, 0x3b, 0x6c, 0x61,
+0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69,
+0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x6b, 0x65, 0x73, 0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f,
+0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6c,
+0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x50, 0x3b,
+0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e,
+0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0x6b,
+0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, 0x6e, 0x61, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b,
+0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69,
+0x6e, 0x61, 0x3b, 0x64, 0x69, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x65,
+0x72, 0x2e, 0x3b, 0x6a, 0x65, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e, 0x3b, 0x73, 0x61, 0x6d, 0x2e, 0x3b, 0x64, 0x69,
+0x6d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d,
+0x65, 0x72, 0x63, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x6a, 0x65, 0x75, 0x64, 0x69, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65,
+0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x69, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b,
+0x56, 0x3b, 0x53, 0x3b, 0x73, 0x69, 0x3b, 0x6d, 0x6f, 0x3b, 0x74, 0x69, 0x3b, 0x77, 0x6f, 0x3b, 0x74, 0x6f, 0x3b, 0x66,
+0x72, 0x3b, 0x73, 0x6f, 0x3b, 0x73, 0x6e, 0x65, 0x69, 0x6e, 0x3b, 0x6d, 0x6f, 0x61, 0x6e, 0x64, 0x65, 0x69, 0x3b, 0x74,
+0x69, 0x69, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x77, 0x6f, 0x61, 0x6e, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x74, 0x6f, 0x6e, 0x67,
+0x65, 0x72, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x66, 0x72, 0x65, 0x65, 0x64, 0x3b, 0x73, 0x6e, 0x65, 0x6f, 0x6e, 0x3b, 0x44,
+0x69, 0x44, 0x3b, 0x44, 0x69, 0x4c, 0x3b, 0x44, 0x69, 0x4d, 0x3b, 0x44, 0x69, 0x43, 0x3b, 0x44, 0x69, 0x61, 0x3b, 0x44,
+0x69, 0x68, 0x3b, 0x44, 0x69, 0x53, 0x3b, 0x44, 0x69, 0x44, 0xf2, 0x6d, 0x68, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x3b, 0x44,
+0x69, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x4d, 0xe0, 0x69, 0x72, 0x74, 0x3b, 0x44, 0x69, 0x43, 0x69, 0x61,
+0x64, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x61, 0x72, 0x44, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x68, 0x41, 0x6f,
+0x69, 0x6e, 0x65, 0x3b, 0x44, 0x69, 0x53, 0x61, 0x74, 0x68, 0x61, 0x69, 0x72, 0x6e, 0x65, 0x3b, 0x44, 0x3b, 0x4c, 0x3b,
+0x4d, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x2e, 0x3b, 0x4c, 0x75, 0x6e, 0x73, 0x3b,
+0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x4d, 0xe9, 0x72, 0x2e, 0x3b, 0x58, 0x6f, 0x76, 0x2e, 0x3b, 0x56, 0x65, 0x6e, 0x2e, 0x3b,
+0x53, 0xe1, 0x62, 0x2e, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x73, 0x3b, 0x4d, 0x61,
+0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x58, 0x6f, 0x76, 0x65, 0x73, 0x3b,
+0x56, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b,
+0x4d, 0x3b, 0x58, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x6d, 0x61,
+0x72, 0x2e, 0x3b, 0x6d, 0xe9, 0x72, 0x2e, 0x3b, 0x78, 0x6f, 0x76, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e, 0x3b, 0x73, 0xe1,
+0x62, 0x2e, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74,
+0x65, 0x73, 0x3b, 0x6d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x78, 0x6f, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x65,
+0x6e, 0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x64, 0x2e, 0x3b, 0x6c, 0x2e, 0x3b, 0x6d, 0x2e,
+0x3b, 0x6d, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, 0x76, 0x2e, 0x3b, 0x73, 0x2e, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x3b, 0x10dd, 0x10e0, 0x10e8,
+0x3b, 0x10e1, 0x10d0, 0x10db, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x3b, 0x10e8, 0x10d0, 0x10d1,
+0x3b, 0x10d9, 0x10d5, 0x10d8, 0x10e0, 0x10d0, 0x3b, 0x10dd, 0x10e0, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x10e8,
+0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x10e8,
+0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x10d0, 0x10e1, 0x10d9, 0x10d4, 0x10d5, 0x10d8, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x10d0,
+0x10d7, 0x10d8, 0x3b, 0x10d9, 0x3b, 0x10dd, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10ee, 0x3b, 0x10de, 0x3b, 0x10e8, 0x3b, 0x53, 0x6f, 0x3b,
+0x4d, 0x6f, 0x3b, 0x44, 0x69, 0x3b, 0x4d, 0x69, 0x3b, 0x44, 0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53, 0x61, 0x3b, 0x53, 0x6f,
+0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x65, 0x6e, 0x73, 0x74, 0x61,
+0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x61,
+0x67, 0x3b, 0x46, 0x72, 0x65, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b,
+0x4d, 0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b,
+0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x6f, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b,
+0x39a, 0x3c5, 0x3c1, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3b,
+0x3a0, 0x3b1, 0x3c1, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b9, 0x3b1, 0x3ba, 0x3ae, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3c4,
+0x3ad, 0x3c1, 0x3b1, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3c4, 0x3b7, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3ac, 0x3c1, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3ad,
+0x3bc, 0x3c0, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b1, 0x3c3, 0x3ba, 0x3b5, 0x3c5, 0x3ae, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b2, 0x3b1,
+0x3c4, 0x3bf, 0x3b, 0x39a, 0x3b, 0x394, 0x3b, 0x3a4, 0x3b, 0x3a4, 0x3b, 0x3a0, 0x3b, 0x3a0, 0x3b, 0x3a3, 0x3b, 0x73, 0x61, 0x62,
+0x3b, 0x61, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, 0x69, 0x6e, 0x3b, 0x73, 0x69, 0x73, 0x3b, 0x74, 0x61, 0x6c,
+0x3b, 0x61, 0x72, 0x66, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x61, 0x74, 0x3b, 0x61, 0x74, 0x61, 0x61, 0x73, 0x69, 0x6e, 0x6e,
+0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x6d, 0x61, 0x72, 0x6c, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71,
+0x3b, 0x70, 0x69, 0x6e, 0x67, 0x61, 0x73, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x73, 0x69, 0x73,
+0x61, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x74, 0x61, 0x6c, 0x6c, 0x69, 0x6d, 0x61, 0x6e,
+0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e,
+0x65, 0x71, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0xab0, 0xab5, 0xabf,
+0x3b, 0xab8, 0xacb, 0xaae, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0x3b, 0xaac, 0xac1, 0xaa7, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0x3b, 0xab6,
+0xac1, 0xa95, 0xacd, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0x3b, 0xab0, 0xab5, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab8, 0xacb, 0xaae, 0xab5,
+0xabe, 0xab0, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0xab5, 0xabe, 0xab0, 0x3b, 0xaac, 0xac1, 0xaa7, 0xab5, 0xabe, 0xab0, 0x3b, 0xa97, 0xac1,
+0xab0, 0xac1, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0xab5, 0xabe,
+0xab0, 0x3b, 0xab0, 0x3b, 0xab8, 0xacb, 0x3b, 0xaae, 0xa82, 0x3b, 0xaac, 0xac1, 0x3b, 0xa97, 0xac1, 0x3b, 0xab6, 0xac1, 0x3b, 0xab6,
+0x3b, 0x4c, 0x61, 0x68, 0x3b, 0x4c, 0x69, 0x74, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x72, 0x3b, 0x41, 0x6c, 0x68,
+0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x4c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x4c, 0x69, 0x74, 0x69,
+0x6e, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x4c, 0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x41, 0x6c,
+0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x6d, 0x61, 0x2bc, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x61, 0x72,
+0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d0,
+0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d1, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d2, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20,
+0x5d3, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d4, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5d1, 0x5ea,
+0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d0, 0x5e9, 0x5d5, 0x5df, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5e0, 0x5d9, 0x3b, 0x5d9,
+0x5d5, 0x5dd, 0x20, 0x5e9, 0x5dc, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d1, 0x5d9, 0x5e2, 0x5d9, 0x3b, 0x5d9,
+0x5d5, 0x5dd, 0x20, 0x5d7, 0x5de, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5,
+0x5dd, 0x20, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d0, 0x5f3, 0x3b, 0x5d1, 0x5f3, 0x3b, 0x5d2, 0x5f3, 0x3b, 0x5d3, 0x5f3, 0x3b, 0x5d4, 0x5f3,
+0x3b, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5f3, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b,
+0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930,
+0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x935, 0x93e, 0x930,
+0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d,
+0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x902, 0x3b,
+0x92c, 0x941, 0x3b, 0x917, 0x941, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x65,
+0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0xe1, 0x72, 0x6e, 0x61, 0x70, 0x3b, 0x68,
+0xe9, 0x74, 0x66, 0x151, 0x3b, 0x6b, 0x65, 0x64, 0x64, 0x3b, 0x73, 0x7a, 0x65, 0x72, 0x64, 0x61, 0x3b, 0x63, 0x73, 0xfc,
+0x74, 0xf6, 0x72, 0x74, 0xf6, 0x6b, 0x3b, 0x70, 0xe9, 0x6e, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x7a, 0x6f, 0x6d, 0x62, 0x61,
+0x74, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x3b, 0x73,
+0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0xe1, 0x6e, 0x2e, 0x3b, 0xfe, 0x72, 0x69, 0x2e, 0x3b, 0x6d, 0x69, 0xf0, 0x2e, 0x3b, 0x66,
+0x69, 0x6d, 0x2e, 0x3b, 0x66, 0xf6, 0x73, 0x2e, 0x3b, 0x6c, 0x61, 0x75, 0x2e, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64,
+0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0xfe, 0x72, 0x69, 0xf0, 0x6a,
+0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0xf0, 0x76, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b,
+0x66, 0x69, 0x6d, 0x6d, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0xf6, 0x73, 0x74, 0x75, 0x64, 0x61, 0x67,
+0x75, 0x72, 0x3b, 0x6c, 0x61, 0x75, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0xde,
+0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4d, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x53, 0x65, 0x6c,
+0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4d, 0x69, 0x6e,
+0x67, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62,
+0x75, 0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b,
+0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x68, 0x3b, 0x4c,
+0x75, 0x61, 0x6e, 0x3b, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x43, 0xe9, 0x61, 0x64, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x3b,
+0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x44, 0x6f, 0x6d, 0x68, 0x6e, 0x61,
+0x69, 0x67, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x4d, 0xe1, 0x69, 0x72,
+0x74, 0x3b, 0x44, 0xe9, 0x20, 0x43, 0xe9, 0x61, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x64, 0x61,
+0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0xe9, 0x20, 0x53, 0x61, 0x74,
+0x68, 0x61, 0x69, 0x72, 0x6e, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x44, 0x3b, 0x41, 0x3b, 0x53, 0x3b,
+0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x67, 0x69, 0x6f, 0x3b,
+0x76, 0x65, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x63, 0x61, 0x3b, 0x6c, 0x75, 0x6e,
+0x65, 0x64, 0xec, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64,
+0xec, 0x3b, 0x67, 0x69, 0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x76, 0x65, 0x6e, 0x65, 0x72, 0x64, 0xec, 0x3b, 0x73, 0x61,
+0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x65e5,
+0x3b, 0x6708, 0x3b, 0x706b, 0x3b, 0x6c34, 0x3b, 0x6728, 0x3b, 0x91d1, 0x3b, 0x571f, 0x3b, 0x65e5, 0x66dc, 0x65e5, 0x3b, 0x6708, 0x66dc, 0x65e5,
+0x3b, 0x706b, 0x66dc, 0x65e5, 0x3b, 0x6c34, 0x66dc, 0x65e5, 0x3b, 0x6728, 0x66dc, 0x65e5, 0x3b, 0x91d1, 0x66dc, 0x65e5, 0x3b, 0x571f, 0x66dc, 0x65e5,
+0x3b, 0xcad, 0xcbe, 0xca8, 0xcc1, 0x3b, 0xcb8, 0xccb, 0xcae, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0x3b, 0xcac, 0xcc1, 0xca7, 0x3b, 0xc97,
+0xcc1, 0xcb0, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf, 0x3b, 0xcad, 0xcbe, 0xca8, 0xcc1, 0xcb5, 0xcbe,
+0xcb0, 0x3b, 0xcb8, 0xccb, 0xcae, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcac, 0xcc1, 0xca7,
+0xcb5, 0xcbe, 0xcb0, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0xcb5, 0xcbe, 0xcb0,
+0x3b, 0xcb6, 0xca8, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcad, 0xcbe, 0x3b, 0xcb8, 0xccb, 0x3b, 0xcae, 0xc82, 0x3b, 0xcac, 0xcc1, 0x3b,
+0xc97, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0x3b, 0xcb6, 0x3b, 0x622, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f,
0x655, 0x631, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631,
0x3b, 0x628, 0x631, 0x65b, 0x66e, 0x6ea, 0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627,
-0x631, 0x3b, 0x627, 0x3b, 0x698, 0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x62c, 0x3b, 0x628, 0x3b, 0x416, 0x441, 0x3b, 0x414,
-0x441, 0x3b, 0x421, 0x441, 0x3b, 0x421, 0x440, 0x3b, 0x411, 0x441, 0x3b, 0x416, 0x43c, 0x3b, 0x421, 0x431, 0x3b, 0x416, 0x435, 0x43a,
-0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x414, 0x4af, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x421, 0x435, 0x439, 0x441, 0x435,
-0x43d, 0x431, 0x456, 0x3b, 0x421, 0x4d9, 0x440, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x411, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431,
-0x456, 0x3b, 0x416, 0x4b1, 0x43c, 0x430, 0x3b, 0x421, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x421,
-0x3b, 0x411, 0x3b, 0x416, 0x3b, 0x421, 0x3b, 0x436, 0x435, 0x43a, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x434, 0x4af, 0x439, 0x441,
-0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x4d9, 0x440, 0x441, 0x435, 0x43d,
-0x431, 0x456, 0x3b, 0x431, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x436, 0x4b1, 0x43c, 0x430, 0x3b, 0x441, 0x435, 0x43d,
-0x431, 0x456, 0x3b, 0x63, 0x79, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62, 0x2e, 0x3b, 0x67, 0x74,
-0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64, 0x2e, 0x3b, 0x4b, 0x75,
-0x20, 0x63, 0x79, 0x75, 0x6d, 0x77, 0x65, 0x72, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65,
-0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61,
-0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20,
-0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74,
-0x75, 0x3b, 0x436, 0x435, 0x43a, 0x2e, 0x3b, 0x434, 0x4af, 0x439, 0x2e, 0x3b, 0x448, 0x435, 0x439, 0x448, 0x2e, 0x3b, 0x448, 0x430,
-0x440, 0x448, 0x2e, 0x3b, 0x431, 0x435, 0x439, 0x448, 0x2e, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x438, 0x448, 0x43c, 0x2e, 0x3b,
-0x436, 0x435, 0x43a, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x434, 0x4af, 0x439, 0x448, 0x4e9, 0x43c, 0x431, 0x4af, 0x3b, 0x448, 0x435,
-0x439, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x448, 0x430, 0x440, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x431, 0x435, 0x439, 0x448,
-0x435, 0x43c, 0x431, 0x438, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x438, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x416, 0x3b, 0x414,
-0x3b, 0x428, 0x3b, 0x428, 0x3b, 0x411, 0x3b, 0x416, 0x3b, 0x418, 0x3b, 0xc77c, 0x3b, 0xc6d4, 0x3b, 0xd654, 0x3b, 0xc218, 0x3b, 0xbaa9,
-0x3b, 0xae08, 0x3b, 0xd1a0, 0x3b, 0xc77c, 0xc694, 0xc77c, 0x3b, 0xc6d4, 0xc694, 0xc77c, 0x3b, 0xd654, 0xc694, 0xc77c, 0x3b, 0xc218, 0xc694, 0xc77c,
-0x3b, 0xbaa9, 0xc694, 0xc77c, 0x3b, 0xae08, 0xc694, 0xc77c, 0x3b, 0xd1a0, 0xc694, 0xc77c, 0x3b, 0x63, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65,
-0x2e, 0x3b, 0x6b, 0x61, 0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75,
-0x2e, 0x3b, 0x67, 0x6e, 0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x2019, 0x69, 0x6e, 0x64, 0x77, 0x69, 0x3b, 0x4b, 0x75,
-0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69,
-0x72, 0x69, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77,
-0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b,
-0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0xead, 0xeb2, 0xe97, 0xeb4,
-0xe94, 0x3b, 0xe88, 0xeb1, 0xe99, 0x3b, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xe9e, 0xeb8, 0xe94, 0x3b, 0xe9e, 0xeb0, 0xeab,
-0xeb1, 0xe94, 0x3b, 0xeaa, 0xeb8, 0xe81, 0x3b, 0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94,
-0x3b, 0xea7, 0xeb1, 0xe99, 0xe88, 0xeb1, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xea7, 0xeb1,
-0xe99, 0xe9e, 0xeb8, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xeaa, 0xeb8, 0xe81,
-0x3b, 0xea7, 0xeb1, 0xe99, 0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xead, 0xeb2, 0x3b, 0xe88, 0x3b, 0xead, 0x3b, 0xe9e, 0x3b, 0xe9e, 0xeab,
-0x3b, 0xeaa, 0xeb8, 0x3b, 0xeaa, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x2e, 0x3b, 0x50, 0x69, 0x72, 0x6d, 0x64, 0x2e, 0x3b,
-0x4f, 0x74, 0x72, 0x64, 0x2e, 0x3b, 0x54, 0x72, 0x65, 0x161, 0x64, 0x2e, 0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64,
-0x2e, 0x3b, 0x50, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x2e, 0x3b, 0x53, 0x65, 0x73, 0x74, 0x64, 0x2e, 0x3b, 0x53, 0x76, 0x113,
-0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x74, 0x72,
-0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x54, 0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x43, 0x65, 0x74, 0x75,
-0x72, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53,
-0x65, 0x73, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x43, 0x3b, 0x50,
-0x3b, 0x53, 0x3b, 0x73, 0x76, 0x113, 0x74, 0x64, 0x2e, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x64, 0x2e, 0x3b, 0x6f, 0x74, 0x72,
-0x64, 0x2e, 0x3b, 0x74, 0x72, 0x65, 0x161, 0x64, 0x2e, 0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x2e, 0x3b, 0x70,
-0x69, 0x65, 0x6b, 0x74, 0x64, 0x2e, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x64, 0x2e, 0x3b, 0x73, 0x76, 0x113, 0x74, 0x64, 0x69,
-0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x69, 0x65,
-0x6e, 0x61, 0x3b, 0x74, 0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64,
-0x69, 0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74,
-0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x65, 0x79, 0x65, 0x3b, 0x79, 0x62, 0x6f, 0x3b, 0x6d, 0x62, 0x6c, 0x3b, 0x6d, 0x73,
-0x74, 0x3b, 0x6d, 0x69, 0x6e, 0x3b, 0x6d, 0x74, 0x6e, 0x3b, 0x6d, 0x70, 0x73, 0x3b, 0x65, 0x79, 0x65, 0x6e, 0x67, 0x61,
-0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x6d, 0x6f,
-0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x6d, 0x6f, 0x6b, 0x254,
-0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254,
-0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0xe9, 0x69, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20,
-0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x6d, 0x70, 0x254, 0x301, 0x73, 0x254, 0x3b, 0x65, 0x3b, 0x79, 0x3b, 0x6d, 0x3b,
-0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x70, 0x3b, 0x73, 0x6b, 0x3b, 0x70, 0x72, 0x3b, 0x61, 0x6e, 0x3b, 0x74, 0x72, 0x3b,
-0x6b, 0x74, 0x3b, 0x70, 0x6e, 0x3b, 0x161, 0x74, 0x3b, 0x73, 0x65, 0x6b, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73,
-0x3b, 0x70, 0x69, 0x72, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x64, 0x69,
-0x65, 0x6e, 0x69, 0x73, 0x3b, 0x74, 0x72, 0x65, 0x10d, 0x69, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6b, 0x65,
-0x74, 0x76, 0x69, 0x72, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x65, 0x6e, 0x6b, 0x74, 0x61, 0x64,
-0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x161, 0x65, 0x161, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x53, 0x3b,
-0x50, 0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x160, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d,
-0x2e, 0x3b, 0x432, 0x442, 0x43e, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442,
-0x2e, 0x3b, 0x441, 0x430, 0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435,
-0x43b, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447,
-0x435, 0x442, 0x432, 0x440, 0x442, 0x43e, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x43e, 0x43a, 0x3b, 0x441, 0x430, 0x431, 0x43e, 0x442, 0x430,
-0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x432, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b,
-0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x430, 0x431, 0x2e, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x3b,
-0x41, 0x6c, 0x61, 0x74, 0x73, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x3b,
-0x5a, 0x6f, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x61, 0x64, 0x79, 0x3b, 0x41, 0x6c, 0x61,
-0x74, 0x73, 0x69, 0x6e, 0x61, 0x69, 0x6e, 0x79, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72,
-0x6f, 0x62, 0x69, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x61, 0x6d, 0x69, 0x73, 0x79, 0x3b, 0x5a, 0x6f, 0x6d, 0x61, 0x3b,
-0x41, 0x73, 0x61, 0x62, 0x6f, 0x74, 0x73, 0x79, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x5a,
-0x3b, 0x41, 0x3b, 0x41, 0x68, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b,
-0x68, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x68, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69,
-0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x73,
-0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x53, 0x3b,
-0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd7c, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd7e, 0x3b,
-0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd7b, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd02, 0x3b, 0xd35, 0xd46,
-0xd33, 0xd4d, 0xd33, 0xd3f, 0x3b, 0xd36, 0xd28, 0xd3f, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd24,
-0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e, 0xd34, 0xd4d, 0x200c,
-0xd1a, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34, 0xd4d,
-0x200c, 0xd1a, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f,
-0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1e, 0xd3e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d,
-0xd2f, 0xd3e, 0x3b, 0xd35, 0xd46, 0x3b, 0xd36, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd24, 0xd3f,
-0xd19, 0xd4d, 0xd15, 0xd33, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e, 0xd34, 0xd4d, 0xd1a, 0x3b,
-0xd2c, 0xd41, 0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a,
-0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e, 0xd34,
-0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0x3b,
-0xd35, 0xd46, 0x3b, 0xd36, 0x3b, 0x126, 0x61, 0x64, 0x3b, 0x54, 0x6e, 0x65, 0x3b, 0x54, 0x6c, 0x69, 0x3b, 0x45, 0x72, 0x62,
-0x3b, 0x126, 0x61, 0x6d, 0x3b, 0x120, 0x69, 0x6d, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x64, 0x64,
-0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6e, 0x65, 0x6a, 0x6e, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6c, 0x69, 0x65, 0x74, 0x61, 0x3b,
-0x4c, 0x2d, 0x45, 0x72, 0x62, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x49, 0x6c,
-0x2d, 0x120, 0x69, 0x6d, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x73, 0x2d, 0x53, 0x69, 0x62, 0x74, 0x3b, 0x126, 0x64, 0x3b, 0x54,
-0x6e, 0x3b, 0x54, 0x6c, 0x3b, 0x45, 0x72, 0x3b, 0x126, 0x6d, 0x3b, 0x120, 0x6d, 0x3b, 0x53, 0x62, 0x3b, 0x126, 0x64, 0x3b,
-0x54, 0x3b, 0x54, 0x6c, 0x3b, 0x45, 0x72, 0x3b, 0x126, 0x6d, 0x3b, 0x120, 0x6d, 0x3b, 0x53, 0x62, 0x3b, 0x930, 0x935, 0x93f,
-0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936,
-0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935,
-0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941,
-0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e,
-0x930, 0x3b, 0x41d, 0x44f, 0x3b, 0x414, 0x430, 0x3b, 0x41c, 0x44f, 0x3b, 0x41b, 0x445, 0x3b, 0x41f, 0x4af, 0x3b, 0x411, 0x430, 0x3b,
-0x411, 0x44f, 0x3b, 0x43d, 0x44f, 0x43c, 0x3b, 0x434, 0x430, 0x432, 0x430, 0x430, 0x3b, 0x43c, 0x44f, 0x433, 0x43c, 0x430, 0x440, 0x3b,
-0x43b, 0x445, 0x430, 0x433, 0x432, 0x430, 0x3b, 0x43f, 0x4af, 0x440, 0x44d, 0x432, 0x3b, 0x431, 0x430, 0x430, 0x441, 0x430, 0x43d, 0x3b,
-0x431, 0x44f, 0x43c, 0x431, 0x430, 0x3b, 0x906, 0x907, 0x924, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x3b,
-0x92c, 0x941, 0x927, 0x3b, 0x92c, 0x93f, 0x939, 0x93f, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x906,
-0x907, 0x924, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x92c, 0x93e,
-0x930, 0x3b, 0x92c, 0x941, 0x927, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915,
-0x94d, 0x930, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x906, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x3b,
-0x92c, 0x941, 0x3b, 0x92c, 0x93f, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0xb30, 0xb2c, 0xb3f, 0x3b, 0xb38, 0xb4b, 0xb2e, 0x3b, 0xb2e,
-0xb19, 0xb4d, 0xb17, 0xb33, 0x3b, 0xb2c, 0xb41, 0xb27, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0x3b,
-0xb36, 0xb28, 0xb3f, 0x3b, 0xb30, 0xb2c, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb38, 0xb4b, 0xb2e, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2e, 0xb19,
-0xb4d, 0xb17, 0xb33, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2c, 0xb41, 0xb27, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0xb2c, 0xb3e,
-0xb30, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb30, 0x3b,
-0xb38, 0xb4b, 0x3b, 0xb2e, 0x3b, 0xb2c, 0xb41, 0x3b, 0xb17, 0xb41, 0x3b, 0xb36, 0xb41, 0x3b, 0xb36, 0x3b, 0x6cc, 0x6a9, 0x634, 0x646,
-0x628, 0x647, 0x3b, 0x62f, 0x648, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x633, 0x647, 0x200c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x686, 0x647,
-0x627, 0x631, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x67e, 0x646, 0x62c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b,
-0x634, 0x646, 0x628, 0x647, 0x3b, 0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x6e,
-0x69, 0x65, 0x64, 0x7a, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x77, 0x74, 0x2e, 0x3b, 0x15b, 0x72, 0x2e, 0x3b, 0x63,
-0x7a, 0x77, 0x2e, 0x3b, 0x70, 0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x65,
-0x6c, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x61, 0x142, 0x65, 0x6b, 0x3b, 0x77, 0x74, 0x6f, 0x72,
-0x65, 0x6b, 0x3b, 0x15b, 0x72, 0x6f, 0x64, 0x61, 0x3b, 0x63, 0x7a, 0x77, 0x61, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x69,
-0x105, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x15a, 0x3b,
-0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x15b, 0x3b, 0x63, 0x3b, 0x70, 0x3b, 0x73, 0x3b,
-0x64, 0x6f, 0x6d, 0x3b, 0x73, 0x65, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, 0x71, 0x75, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x3b,
-0x73, 0x65, 0x78, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75,
-0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72,
-0x61, 0x3b, 0x71, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74,
-0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b,
-0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x53, 0x3b, 0x53,
-0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x3b, 0x74, 0x65, 0x72,
-0xe7, 0x61, 0x3b, 0x71, 0x75, 0x61, 0x72, 0x74, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x78,
-0x74, 0x61, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0xa10, 0xa24, 0x3b, 0xa38, 0xa4b, 0xa2e, 0x3b, 0xa2e, 0xa70, 0xa17,
-0xa32, 0x3b, 0xa2c, 0xa41, 0xa71, 0xa27, 0x3b, 0xa35, 0xa40, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0x3b, 0xa38, 0xa3c,
-0xa28, 0xa3f, 0xa71, 0xa1a, 0xa30, 0x3b, 0xa10, 0xa24, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa4b, 0xa2e, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2e,
-0xa70, 0xa17, 0xa32, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2c, 0xa41, 0xa71, 0xa27, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa35, 0xa40, 0xa30, 0xa35, 0xa3e,
-0xa30, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa3f, 0xa71, 0xa1a, 0xa30, 0xa35,
-0xa3e, 0xa30, 0x3b, 0xa10, 0x3b, 0xa38, 0xa4b, 0x3b, 0xa2e, 0xa70, 0x3b, 0xa2c, 0xa41, 0xa71, 0x3b, 0xa35, 0xa40, 0x3b, 0xa38, 0xa3c,
-0xa41, 0xa71, 0x3b, 0xa38, 0xa3c, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644,
-0x3b, 0x628, 0x64f, 0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641,
-0x62a, 0x6c1, 0x3b, 0x44, 0x6f, 0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0xe9, 0x3b, 0x4a,
-0x75, 0x65, 0x3b, 0x56, 0x69, 0x65, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c,
-0x75, 0x6e, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65,
-0x73, 0x3b, 0x4a, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x56, 0x69, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62,
-0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75,
-0x3b, 0x67, 0x6c, 0x69, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x65, 0x3b, 0x67, 0x69, 0x65, 0x3b, 0x76, 0x65, 0x3b, 0x73, 0x6f,
-0x3b, 0x64, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x69, 0x61, 0x3b, 0x67, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x73, 0x64, 0x69, 0x3b,
-0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x73, 0x65, 0x6d, 0x6e, 0x61, 0x3b, 0x67, 0x69, 0x65, 0x76, 0x67, 0x69,
-0x61, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x6e, 0x64, 0x61, 0x3b, 0x44, 0x3b, 0x47,
-0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e,
-0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x69, 0x65, 0x2e, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x2e, 0x3b,
-0x73, 0xe2, 0x6d, 0x2e, 0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x103, 0x3b, 0x6c, 0x75, 0x6e, 0x69, 0x3b, 0x6d,
-0x61, 0x72, 0x21b, 0x69, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x72, 0x69, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69,
-0x6e, 0x65, 0x72, 0x69, 0x3b, 0x73, 0xe2, 0x6d, 0x62, 0x103, 0x74, 0x103, 0x3b, 0x44, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x6e,
-0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0x65, 0x3b, 0x4a, 0x6f, 0x69, 0x3b, 0x56, 0x69, 0x6e, 0x3b, 0x53, 0xe2, 0x6d,
-0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x61, 0x3b, 0x4d, 0x69, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x432, 0x441, 0x3b,
-0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x432, 0x43e,
-0x441, 0x43a, 0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438,
-0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432,
-0x435, 0x440, 0x433, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b,
-0x412, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x42, 0x6b, 0x31, 0x3b, 0x42, 0x6b,
-0x32, 0x3b, 0x42, 0x6b, 0x33, 0x3b, 0x42, 0x6b, 0x34, 0x3b, 0x42, 0x6b, 0x35, 0x3b, 0x4c, 0xe2, 0x70, 0x3b, 0x4c, 0xe2,
-0x79, 0x3b, 0x42, 0x69, 0x6b, 0x75, 0x61, 0x2d, 0xf4, 0x6b, 0x6f, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0xfb, 0x73,
-0x65, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x70, 0x74, 0xe2, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x75, 0x73,
-0xef, 0xf6, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x6f, 0x6b, 0xfc, 0x3b, 0x4c, 0xe2, 0x70, 0xf4, 0x73, 0xf6, 0x3b,
-0x4c, 0xe2, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x50, 0x3b,
-0x59, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x435, 0x3b, 0x447, 0x435,
-0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d,
-0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b,
-0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442,
-0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x43d, 0x435, 0x434, 0x2e,
-0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x443, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f,
-0x435, 0x442, 0x2e, 0x3b, 0x441, 0x443, 0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x458, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d,
-0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434,
-0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431,
-0x43e, 0x442, 0x430, 0x3b, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x75, 0x74, 0x2e, 0x3b, 0x73, 0x72,
-0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70, 0x65, 0x74, 0x2e, 0x3b, 0x73, 0x75, 0x62, 0x2e, 0x3b, 0x6e, 0x65, 0x64,
-0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f,
-0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b,
-0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f,
-0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75,
-0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x6b,
-0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74,
-0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x425, 0x446, 0x431, 0x3b,
-0x41a, 0x440, 0x441, 0x3b, 0x414, 0x446, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x3b, 0x426, 0x43f, 0x440, 0x3b, 0x41c, 0x440, 0x431, 0x3b,
-0x421, 0x431, 0x442, 0x3b, 0x425, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x41a, 0x44a, 0x443, 0x44b, 0x440, 0x438,
-0x441, 0x4d5, 0x440, 0x3b, 0x414, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b,
-0x426, 0x44b, 0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x41c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x421,
-0x430, 0x431, 0x430, 0x442, 0x3b, 0x425, 0x3b, 0x41a, 0x3b, 0x414, 0x3b, 0x4d4, 0x3b, 0x426, 0x3b, 0x41c, 0x3b, 0x421, 0x3b, 0x445,
-0x446, 0x431, 0x3b, 0x43a, 0x440, 0x441, 0x3b, 0x434, 0x446, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x3b, 0x446, 0x43f, 0x440, 0x3b, 0x43c,
-0x440, 0x431, 0x3b, 0x441, 0x431, 0x442, 0x3b, 0x445, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x43a, 0x44a, 0x443,
-0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x434, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x44b, 0x446, 0x446,
-0x4d5, 0x433, 0x3b, 0x446, 0x44b, 0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x43c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e,
-0x43d, 0x3b, 0x441, 0x430, 0x431, 0x430, 0x442, 0x3b, 0x53, 0x76, 0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x3b, 0x43, 0x68, 0x70, 0x3b,
-0x43, 0x68, 0x74, 0x3b, 0x43, 0x68, 0x6e, 0x3b, 0x43, 0x68, 0x73, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x76, 0x6f, 0x6e,
-0x64, 0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x68, 0x75, 0x72, 0x6f, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43,
-0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, 0x6e,
-0x75, 0x3b, 0x4d, 0x75, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43,
-0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f, 0xdc4,
-0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0x3b,
-0xdc3, 0xdd9, 0xdb1, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f, 0xdc4, 0xdbb,
-0xdd4, 0xdc0, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0xdb4,
-0xdad, 0xdd2, 0xdb1, 0xdca, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd9, 0xdb1, 0xdc3,
-0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xd89, 0x3b, 0xdc3, 0x3b, 0xd85, 0x3b, 0xdb6, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0x3b, 0xdc3,
-0xdd2, 0x3b, 0xdc3, 0xdd9, 0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0x75, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x161, 0x74, 0x3b,
-0x70, 0x69, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x13e, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x6c, 0x6f,
-0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6b, 0x3b, 0x73, 0x74, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, 0x76, 0x72,
-0x74, 0x6f, 0x6b, 0x3b, 0x70, 0x69, 0x61, 0x74, 0x6f, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b,
-0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, 0x161, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e,
-0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x73, 0x72, 0x65, 0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70, 0x65, 0x74,
-0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64,
-0x65, 0x6c, 0x6a, 0x65, 0x6b, 0x3b, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65,
-0x74, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e,
-0x3b, 0x70, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x41, 0x78, 0x64, 0x3b, 0x49, 0x73, 0x6e,
-0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x53, 0x61, 0x62,
-0x3b, 0x41, 0x78, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61, 0x64, 0x6f,
-0x3b, 0x41, 0x72, 0x62, 0x61, 0x63, 0x6f, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x3b, 0x4a, 0x69, 0x6d, 0x63,
-0x6f, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x69, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x4b, 0x68, 0x3b, 0x4a,
-0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x69,
-0xe9, 0x2e, 0x3b, 0x6a, 0x75, 0x65, 0x2e, 0x3b, 0x76, 0x69, 0x65, 0x2e, 0x3b, 0x73, 0xe1, 0x62, 0x2e, 0x3b, 0x64, 0x6f,
-0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d,
-0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x6a, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x72,
-0x6e, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6a,
-0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61,
-0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b,
-0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
-0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x73, 0xf6, 0x6e, 0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74, 0x69, 0x73, 0x3b, 0x6f, 0x6e, 0x73,
-0x3b, 0x74, 0x6f, 0x72, 0x73, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf6, 0x72, 0x3b, 0x73, 0xf6, 0x6e, 0x64, 0x61, 0x67,
-0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61,
-0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0xf6, 0x72,
-0x64, 0x61, 0x67, 0x3b, 0xb9e, 0xbbe, 0xbaf, 0xbbf, 0x2e, 0x3b, 0xba4, 0xbbf, 0xb99, 0xbcd, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbb5, 0xbcd,
-0x2e, 0x3b, 0xbaa, 0xbc1, 0xba4, 0x2e, 0x3b, 0xbb5, 0xbbf, 0xbaf, 0xbbe, 0x2e, 0x3b, 0xbb5, 0xbc6, 0xbb3, 0xbcd, 0x2e, 0x3b, 0xb9a,
-0xba9, 0xbbf, 0x3b, 0xb9e, 0xbbe, 0xbaf, 0xbbf, 0xbb1, 0xbc1, 0x3b, 0xba4, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b, 0xb9a, 0xbc6,
-0xbb5, 0xbcd, 0xbb5, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0xbaa, 0xbc1, 0xba4, 0xba9, 0xbcd, 0x3b, 0xbb5, 0xbbf, 0xbaf, 0xbbe, 0xbb4, 0xba9, 0xbcd,
-0x3b, 0xbb5, 0xbc6, 0xbb3, 0xbcd, 0xbb3, 0xbbf, 0x3b, 0xb9a, 0xba9, 0xbbf, 0x3b, 0xb9e, 0xbbe, 0x3b, 0xba4, 0xbbf, 0x3b, 0xb9a, 0xbc6,
-0x3b, 0xbaa, 0xbc1, 0x3b, 0xbb5, 0xbbf, 0x3b, 0xbb5, 0xbc6, 0x3b, 0xb9a, 0x3b, 0xc06, 0xc26, 0xc3f, 0x3b, 0xc38, 0xc4b, 0xc2e, 0x3b,
-0xc2e, 0xc02, 0xc17, 0xc33, 0x3b, 0xc2c, 0xc41, 0xc27, 0x3b, 0xc17, 0xc41, 0xc30, 0xc41, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d, 0xc30, 0x3b,
-0xc36, 0xc28, 0xc3f, 0x3b, 0xc06, 0xc26, 0xc3f, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc38, 0xc4b, 0xc2e, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b,
-0xc2e, 0xc02, 0xc17, 0xc33, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc2c, 0xc41, 0xc27, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc17, 0xc41, 0xc30,
-0xc41, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d, 0xc30, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc36, 0xc28, 0xc3f, 0xc35,
-0xc3e, 0xc30, 0xc02, 0x3b, 0xc06, 0x3b, 0xc38, 0xc4b, 0x3b, 0xc2e, 0x3b, 0xc2c, 0xc41, 0x3b, 0xc17, 0xc41, 0x3b, 0xc36, 0xc41, 0x3b,
-0xc36, 0x3b, 0xe2d, 0xe32, 0x2e, 0x3b, 0xe08, 0x2e, 0x3b, 0xe2d, 0x2e, 0x3b, 0xe1e, 0x2e, 0x3b, 0xe1e, 0xe24, 0x2e, 0x3b, 0xe28,
-0x2e, 0x3b, 0xe2a, 0x2e, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe32, 0xe17, 0xe34, 0xe15, 0xe22, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe08,
-0xe31, 0xe19, 0xe17, 0xe23, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe31, 0xe07, 0xe04, 0xe32, 0xe23, 0x3b, 0xe27, 0xe31, 0xe19, 0xe1e,
-0xe38, 0xe18, 0x3b, 0xe27, 0xe31, 0xe19, 0xe1e, 0xe24, 0xe2b, 0xe31, 0xe2a, 0xe1a, 0xe14, 0xe35, 0x3b, 0xe27, 0xe31, 0xe19, 0xe28, 0xe38,
-0xe01, 0xe23, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe40, 0xe2a, 0xe32, 0xe23, 0xe4c, 0x3b, 0xe2d, 0xe32, 0x3b, 0xe08, 0x3b, 0xe2d, 0x3b,
-0xe1e, 0x3b, 0xe1e, 0xe24, 0x3b, 0xe28, 0x3b, 0xe2a, 0x3b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b,
-0x3b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62,
-0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b,
-0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b,
-0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf63, 0xfb7, 0xf42,
-0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b,
-0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf49,
-0xf72, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf42, 0x3b, 0xf63, 0xfb7, 0xf42, 0x3b, 0xf55, 0xf74, 0xf62, 0x3b, 0xf66, 0xf44, 0xf66,
-0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0x1230, 0x1295, 0x3b, 0x1230, 0x1291, 0x3b, 0x1230, 0x1209, 0x3b, 0x1228, 0x1261, 0x3b, 0x1213, 0x1219,
-0x3b, 0x12d3, 0x122d, 0x3b, 0x1240, 0x12f3, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b, 0x1230, 0x1291, 0x12ed, 0x3b, 0x1230, 0x1209, 0x1235, 0x3b,
-0x1228, 0x1261, 0x12d5, 0x3b, 0x1213, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b,
-0x1220, 0x3b, 0x1228, 0x3b, 0x1213, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b, 0x1230, 0x1291, 0x12ed, 0x3b, 0x1220,
-0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1283, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d, 0x3b, 0x1230,
-0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1228, 0x3b, 0x1213, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x53, 0x101, 0x70, 0x3b, 0x4d, 0x14d, 0x6e,
-0x3b, 0x54, 0x16b, 0x73, 0x3b, 0x50, 0x75, 0x6c, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x3b, 0x46, 0x61, 0x6c, 0x3b, 0x54, 0x6f,
-0x6b, 0x3b, 0x53, 0x101, 0x70, 0x61, 0x74, 0x65, 0x3b, 0x4d, 0x14d, 0x6e, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x16b, 0x73, 0x69,
-0x74, 0x65, 0x3b, 0x50, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x70, 0x75, 0x6c, 0x65,
-0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x46, 0x61, 0x6c, 0x61, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x6f, 0x6b, 0x6f, 0x6e, 0x61, 0x6b,
-0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x54, 0x3b, 0x50, 0x61, 0x7a, 0x3b,
-0x50, 0x7a, 0x74, 0x3b, 0x53, 0x61, 0x6c, 0x3b, 0xc7, 0x61, 0x72, 0x3b, 0x50, 0x65, 0x72, 0x3b, 0x43, 0x75, 0x6d, 0x3b,
-0x43, 0x6d, 0x74, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b,
-0x53, 0x61, 0x6c, 0x131, 0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x50, 0x65, 0x72, 0x15f, 0x65, 0x6d,
-0x62, 0x65, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x50, 0x3b,
-0x50, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0xfd, 0x62, 0x3b, 0x64, 0x62, 0x3b, 0x73, 0x62,
-0x3b, 0xe7, 0x62, 0x3b, 0x70, 0x62, 0x3b, 0x61, 0x6e, 0x3b, 0x15f, 0x62, 0x3b, 0xfd, 0x65, 0x6b, 0x15f, 0x65, 0x6e, 0x62,
-0x65, 0x3b, 0x64, 0x75, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x73, 0x69, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xe7, 0x61,
-0x72, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x70, 0x65, 0x6e, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x61, 0x6e, 0x6e, 0x61,
-0x3b, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xdd, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, 0x41, 0x3b, 0x15e,
-0x3b, 0x64a, 0x6d5, 0x3b, 0x62f, 0x6c8, 0x3b, 0x633, 0x6d5, 0x3b, 0x686, 0x627, 0x3b, 0x67e, 0x6d5, 0x3b, 0x62c, 0x6c8, 0x3b, 0x634,
-0x6d5, 0x3b, 0x64a, 0x6d5, 0x643, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x62f, 0x6c8, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x633,
-0x6d5, 0x64a, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x686, 0x627, 0x631, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x67e, 0x6d5, 0x64a,
-0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x62c, 0x6c8, 0x645, 0x6d5, 0x3b, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x64a, 0x3b, 0x62f,
-0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e,
-0x43d, 0x435, 0x434, 0x456, 0x43b, 0x43e, 0x43a, 0x3b, 0x432, 0x456, 0x432, 0x442, 0x43e, 0x440, 0x43e, 0x43a, 0x3b, 0x441, 0x435, 0x440,
-0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x2bc, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x44f, 0x3b,
-0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x41d, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421,
-0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x633, 0x648, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628,
-0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b,
-0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x62f, 0x6be, 0x3b, 0x62c,
-0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x59, 0x61, 0x6b, 0x3b,
-0x44, 0x75, 0x73, 0x68, 0x3b, 0x53, 0x65, 0x73, 0x68, 0x3b, 0x43, 0x68, 0x6f, 0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x4a,
-0x75, 0x6d, 0x3b, 0x53, 0x68, 0x61, 0x6e, 0x3b, 0x79, 0x61, 0x6b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x64, 0x75,
-0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x63, 0x68, 0x6f, 0x72,
-0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x70, 0x61, 0x79, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x6a, 0x75, 0x6d,
-0x61, 0x3b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x59, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x4a,
-0x3b, 0x53, 0x3b, 0x6cc, 0x2e, 0x3b, 0x62f, 0x2e, 0x3b, 0x633, 0x2e, 0x3b, 0x686, 0x2e, 0x3b, 0x67e, 0x2e, 0x3b, 0x62c, 0x2e,
-0x3b, 0x634, 0x2e, 0x3b, 0x42f, 0x43a, 0x448, 0x3b, 0x414, 0x443, 0x448, 0x3b, 0x421, 0x435, 0x448, 0x3b, 0x427, 0x43e, 0x440, 0x3b,
-0x41f, 0x430, 0x439, 0x3b, 0x416, 0x443, 0x43c, 0x3b, 0x428, 0x430, 0x43d, 0x3b, 0x42f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b,
-0x414, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x421, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x427, 0x43e, 0x440, 0x448,
-0x430, 0x43d, 0x431, 0x430, 0x3b, 0x41f, 0x430, 0x439, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x416, 0x443, 0x43c, 0x430, 0x3b, 0x428,
-0x430, 0x43d, 0x431, 0x430, 0x3b, 0x42f, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x416, 0x3b, 0x428, 0x3b, 0x44f,
-0x43a, 0x448, 0x3b, 0x434, 0x443, 0x448, 0x3b, 0x441, 0x435, 0x448, 0x3b, 0x447, 0x43e, 0x440, 0x3b, 0x43f, 0x430, 0x439, 0x3b, 0x436,
-0x443, 0x43c, 0x3b, 0x448, 0x430, 0x43d, 0x3b, 0x44f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x434, 0x443, 0x448, 0x430, 0x43d,
-0x431, 0x430, 0x3b, 0x441, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x447, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b,
-0x43f, 0x430, 0x439, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b,
-0x43, 0x4e, 0x3b, 0x54, 0x68, 0x20, 0x32, 0x3b, 0x54, 0x68, 0x20, 0x33, 0x3b, 0x54, 0x68, 0x20, 0x34, 0x3b, 0x54, 0x68,
-0x20, 0x35, 0x3b, 0x54, 0x68, 0x20, 0x36, 0x3b, 0x54, 0x68, 0x20, 0x37, 0x3b, 0x43, 0x68, 0x1ee7, 0x20, 0x4e, 0x68, 0x1ead,
-0x74, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x48, 0x61, 0x69, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42, 0x61, 0x3b, 0x54, 0x68, 0x1ee9,
-0x20, 0x54, 0x1b0, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x4e, 0x103, 0x6d, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x53, 0xe1, 0x75, 0x3b,
-0x54, 0x68, 0x1ee9, 0x20, 0x42, 0x1ea3, 0x79, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x32, 0x3b, 0x54, 0x33, 0x3b, 0x54, 0x34, 0x3b,
-0x54, 0x35, 0x3b, 0x54, 0x36, 0x3b, 0x54, 0x37, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d, 0x61,
-0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, 0x79,
-0x64, 0x64, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x44, 0x79, 0x64,
-0x64, 0x20, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x65, 0x72, 0x63, 0x68, 0x65,
-0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x49, 0x61, 0x75, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x47, 0x77, 0x65, 0x6e,
-0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, 0x61, 0x64, 0x77, 0x72, 0x6e, 0x3b, 0x53, 0x3b, 0x4c, 0x6c, 0x3b,
-0x4d, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d,
-0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b, 0x53, 0x61, 0x64, 0x3b,
-0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, 0xe9, 0x3b, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd,
-0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x62, 0x1ecd, 0x3b, 0x1eb8, 0x74, 0xec, 0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9,
-0x301, 0x74, 0x61, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x41,
-0x6a, 0xe9, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301,
-0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x62, 0x1ecd, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x1eb8, 0x74, 0xec, 0x3b, 0x1ecc,
-0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a,
-0xe9, 0x3b, 0xcc, 0x73, 0x25b, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254,
-0x301, 0x62, 0x254, 0x3b, 0x190, 0x74, 0xec, 0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x186, 0x6a, 0x254,
-0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x186, 0x6a, 0x254, 0x301,
-0x20, 0xcc, 0x73, 0x25b, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301,
-0x62, 0x254, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0x190, 0x74, 0xec, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xc0, 0x62, 0xe1,
-0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x73, 0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68,
-0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x49, 0x53, 0x6f, 0x6e, 0x74, 0x6f,
-0x3b, 0x55, 0x4d, 0x73, 0x6f, 0x6d, 0x62, 0x75, 0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62,
-0x69, 0x6c, 0x69, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x55, 0x4c, 0x77,
-0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x55, 0x4d,
-0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x48, 0x3b,
-0x4d, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74, 0x79, 0x73, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f,
-0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0x61, 0x75, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e,
-0x64, 0x61, 0x67, 0x3b, 0x74, 0x79, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f,
-0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0x61, 0x75, 0x72, 0x64, 0x61, 0x67,
-0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d, 0xe5, 0x2e, 0x3b, 0x74, 0x79, 0x2e, 0x3b, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x2e,
-0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x6c, 0x61, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e,
-0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434,
+0x631, 0x3b, 0x627, 0x64e, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x631, 0x655, 0x631, 0x648, 0x627,
+0x631, 0x3b, 0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x631, 0x65b,
+0x66e, 0x6ea, 0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, 0x631, 0x3b, 0x627, 0x3b,
+0x698, 0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x62c, 0x3b, 0x628, 0x3b, 0x416, 0x441, 0x3b, 0x414, 0x441, 0x3b, 0x421, 0x441,
+0x3b, 0x421, 0x440, 0x3b, 0x411, 0x441, 0x3b, 0x416, 0x43c, 0x3b, 0x421, 0x431, 0x3b, 0x416, 0x435, 0x43a, 0x441, 0x435, 0x43d, 0x431,
+0x456, 0x3b, 0x414, 0x4af, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x421, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b,
+0x421, 0x4d9, 0x440, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x411, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x416, 0x4b1,
+0x43c, 0x430, 0x3b, 0x421, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x421, 0x3b, 0x411, 0x3b, 0x416,
+0x3b, 0x421, 0x3b, 0x436, 0x435, 0x43a, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x434, 0x4af, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456,
+0x3b, 0x441, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x4d9, 0x440, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x431,
+0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x436, 0x4b1, 0x43c, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x63,
+0x79, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b,
+0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x63, 0x79, 0x75,
+0x6d, 0x77, 0x65, 0x72, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x77,
+0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75,
+0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61,
+0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0x436, 0x435,
+0x43a, 0x2e, 0x3b, 0x434, 0x4af, 0x439, 0x2e, 0x3b, 0x448, 0x435, 0x439, 0x448, 0x2e, 0x3b, 0x448, 0x430, 0x440, 0x448, 0x2e, 0x3b,
+0x431, 0x435, 0x439, 0x448, 0x2e, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x438, 0x448, 0x43c, 0x2e, 0x3b, 0x436, 0x435, 0x43a, 0x448,
+0x435, 0x43c, 0x431, 0x438, 0x3b, 0x434, 0x4af, 0x439, 0x448, 0x4e9, 0x43c, 0x431, 0x4af, 0x3b, 0x448, 0x435, 0x439, 0x448, 0x435, 0x43c,
+0x431, 0x438, 0x3b, 0x448, 0x430, 0x440, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x431, 0x435, 0x439, 0x448, 0x435, 0x43c, 0x431, 0x438,
+0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x438, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x428, 0x3b, 0x428,
+0x3b, 0x411, 0x3b, 0x416, 0x3b, 0x418, 0x3b, 0xc77c, 0x3b, 0xc6d4, 0x3b, 0xd654, 0x3b, 0xc218, 0x3b, 0xbaa9, 0x3b, 0xae08, 0x3b, 0xd1a0,
+0x3b, 0xc77c, 0xc694, 0xc77c, 0x3b, 0xc6d4, 0xc694, 0xc77c, 0x3b, 0xd654, 0xc694, 0xc77c, 0x3b, 0xc218, 0xc694, 0xc77c, 0x3b, 0xbaa9, 0xc694, 0xc77c,
+0x3b, 0xae08, 0xc694, 0xc77c, 0x3b, 0xd1a0, 0xc694, 0xc77c, 0x3b, 0x63, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61,
+0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e,
+0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x2019, 0x69, 0x6e, 0x64, 0x77, 0x69, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20,
+0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b,
+0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61,
+0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77,
+0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b, 0xe88, 0xeb1,
+0xe99, 0x3b, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xe9e, 0xeb8, 0xe94, 0x3b, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xeaa,
+0xeb8, 0xe81, 0x3b, 0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99,
+0xe88, 0xeb1, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb8, 0xe94,
+0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xeaa, 0xeb8, 0xe81, 0x3b, 0xea7, 0xeb1, 0xe99,
+0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xead, 0xeb2, 0x3b, 0xe88, 0x3b, 0xead, 0x3b, 0xe9e, 0x3b, 0xe9e, 0xeab, 0x3b, 0xeaa, 0xeb8, 0x3b,
+0xeaa, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x2e, 0x3b, 0x50, 0x69, 0x72, 0x6d, 0x64, 0x2e, 0x3b, 0x4f, 0x74, 0x72, 0x64,
+0x2e, 0x3b, 0x54, 0x72, 0x65, 0x161, 0x64, 0x2e, 0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x2e, 0x3b, 0x50, 0x69,
+0x65, 0x6b, 0x74, 0x64, 0x2e, 0x3b, 0x53, 0x65, 0x73, 0x74, 0x64, 0x2e, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65,
+0x6e, 0x61, 0x3b, 0x50, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e,
+0x61, 0x3b, 0x54, 0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69,
+0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x65, 0x73, 0x74, 0x64,
+0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73,
+0x76, 0x113, 0x74, 0x64, 0x2e, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x64, 0x2e, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x2e, 0x3b, 0x74,
+0x72, 0x65, 0x161, 0x64, 0x2e, 0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x2e, 0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74,
+0x64, 0x2e, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x64, 0x2e, 0x3b, 0x73, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b,
+0x70, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x74,
+0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61,
+0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x64, 0x69, 0x65, 0x6e,
+0x61, 0x3b, 0x65, 0x79, 0x65, 0x3b, 0x79, 0x62, 0x6f, 0x3b, 0x6d, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x74, 0x3b, 0x6d, 0x69,
+0x6e, 0x3b, 0x6d, 0x74, 0x6e, 0x3b, 0x6d, 0x70, 0x73, 0x3b, 0x65, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x6d, 0x6f, 0x6b,
+0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254,
+0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d,
+0x77, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20,
+0x6d, 0xed, 0x6e, 0xe9, 0x69, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x74, 0xe1,
+0x6e, 0x6f, 0x3b, 0x6d, 0x70, 0x254, 0x301, 0x73, 0x254, 0x3b, 0x65, 0x3b, 0x79, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b,
+0x6d, 0x3b, 0x70, 0x3b, 0x73, 0x6b, 0x3b, 0x70, 0x72, 0x3b, 0x61, 0x6e, 0x3b, 0x74, 0x72, 0x3b, 0x6b, 0x74, 0x3b, 0x70,
+0x6e, 0x3b, 0x161, 0x74, 0x3b, 0x73, 0x65, 0x6b, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x69, 0x72,
+0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73,
+0x3b, 0x74, 0x72, 0x65, 0x10d, 0x69, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6b, 0x65, 0x74, 0x76, 0x69, 0x72,
+0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x65, 0x6e, 0x6b, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69,
+0x73, 0x3b, 0x161, 0x65, 0x161, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x41, 0x3b,
+0x54, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x160, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x432, 0x442,
+0x43e, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x430,
+0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d, 0x438, 0x43a,
+0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440,
+0x442, 0x43e, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x43e, 0x43a, 0x3b, 0x441, 0x430, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x435, 0x434,
+0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x432, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e,
+0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x430, 0x431, 0x2e, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x3b, 0x41, 0x6c, 0x61, 0x74,
+0x73, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x3b, 0x5a, 0x6f, 0x6d, 0x3b,
+0x41, 0x73, 0x61, 0x62, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x61, 0x64, 0x79, 0x3b, 0x41, 0x6c, 0x61, 0x74, 0x73, 0x69, 0x6e,
+0x61, 0x69, 0x6e, 0x79, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x6f, 0x62, 0x69, 0x61,
+0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x61, 0x6d, 0x69, 0x73, 0x79, 0x3b, 0x5a, 0x6f, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62,
+0x6f, 0x74, 0x73, 0x79, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x5a, 0x3b, 0x41, 0x3b, 0x41,
+0x68, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a,
+0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x68, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65,
+0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d,
+0x61, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b,
+0x4a, 0x3b, 0x53, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd7c, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd7e, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d,
+0xd35, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd7b, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd02, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f,
+0x3b, 0xd36, 0xd28, 0xd3f, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15,
+0xd33, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd2c, 0xd41,
+0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35,
+0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c,
+0xd1a, 0x3b, 0xd1e, 0xd3e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0x3b, 0xd35,
+0xd46, 0x3b, 0xd36, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33,
+0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e, 0xd34, 0xd4d, 0xd1a, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28,
+0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd46, 0xd33,
+0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b,
+0xd1e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0x3b, 0xd35, 0xd46, 0x3b, 0xd36,
+0x3b, 0x126, 0x61, 0x64, 0x3b, 0x54, 0x6e, 0x65, 0x3b, 0x54, 0x6c, 0x69, 0x3b, 0x45, 0x72, 0x62, 0x3b, 0x126, 0x61, 0x6d,
+0x3b, 0x120, 0x69, 0x6d, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x64, 0x64, 0x3b, 0x49, 0x74, 0x2d,
+0x54, 0x6e, 0x65, 0x6a, 0x6e, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6c, 0x69, 0x65, 0x74, 0x61, 0x3b, 0x4c, 0x2d, 0x45, 0x72,
+0x62, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x49, 0x6c, 0x2d, 0x120, 0x69, 0x6d,
+0x67, 0x127, 0x61, 0x3b, 0x49, 0x73, 0x2d, 0x53, 0x69, 0x62, 0x74, 0x3b, 0x126, 0x64, 0x3b, 0x54, 0x6e, 0x3b, 0x54, 0x6c,
+0x3b, 0x45, 0x72, 0x3b, 0x126, 0x6d, 0x3b, 0x120, 0x6d, 0x3b, 0x53, 0x62, 0x3b, 0x126, 0x64, 0x3b, 0x54, 0x3b, 0x54, 0x6c,
+0x3b, 0x45, 0x72, 0x3b, 0x126, 0x6d, 0x3b, 0x120, 0x6d, 0x3b, 0x53, 0x62, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e,
+0x3b, 0x92e, 0x902, 0x917, 0x933, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930,
+0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e,
+0x902, 0x917, 0x933, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e,
+0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x41d, 0x44f,
+0x3b, 0x414, 0x430, 0x3b, 0x41c, 0x44f, 0x3b, 0x41b, 0x445, 0x3b, 0x41f, 0x4af, 0x3b, 0x411, 0x430, 0x3b, 0x411, 0x44f, 0x3b, 0x43d,
+0x44f, 0x43c, 0x3b, 0x434, 0x430, 0x432, 0x430, 0x430, 0x3b, 0x43c, 0x44f, 0x433, 0x43c, 0x430, 0x440, 0x3b, 0x43b, 0x445, 0x430, 0x433,
+0x432, 0x430, 0x3b, 0x43f, 0x4af, 0x440, 0x44d, 0x432, 0x3b, 0x431, 0x430, 0x430, 0x441, 0x430, 0x43d, 0x3b, 0x431, 0x44f, 0x43c, 0x431,
+0x430, 0x3b, 0x906, 0x907, 0x924, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b,
+0x92c, 0x93f, 0x939, 0x93f, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x906, 0x907, 0x924, 0x92c, 0x93e,
+0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941,
+0x927, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x92c, 0x93e,
+0x930, 0x3b, 0x936, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x906, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x3b, 0x92c, 0x941, 0x3b, 0x92c,
+0x93f, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0xb30, 0xb2c, 0xb3f, 0x3b, 0xb38, 0xb4b, 0xb2e, 0x3b, 0xb2e, 0xb19, 0xb4d, 0xb17, 0xb33,
+0x3b, 0xb2c, 0xb41, 0xb27, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0x3b,
+0xb30, 0xb2c, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb38, 0xb4b, 0xb2e, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2e, 0xb19, 0xb4d, 0xb17, 0xb33, 0xb2c,
+0xb3e, 0xb30, 0x3b, 0xb2c, 0xb41, 0xb27, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb41,
+0xb15, 0xb4d, 0xb30, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb30, 0x3b, 0xb38, 0xb4b, 0x3b, 0xb2e,
+0x3b, 0xb2c, 0xb41, 0x3b, 0xb17, 0xb41, 0x3b, 0xb36, 0xb41, 0x3b, 0xb36, 0x3b, 0x64a, 0x648, 0x646, 0x6cd, 0x3b, 0x62f, 0x648, 0x646,
+0x6cd, 0x3b, 0x62f, 0x631, 0x6d0, 0x646, 0x6cd, 0x3b, 0x685, 0x644, 0x631, 0x646, 0x6cd, 0x3b, 0x67e, 0x64a, 0x646, 0x681, 0x646, 0x6cd,
+0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b, 0x627, 0x648, 0x646, 0x6cd, 0x3b, 0x6cc, 0x6a9, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62f, 0x648,
+0x634, 0x646, 0x628, 0x647, 0x3b, 0x633, 0x647, 0x200c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x686, 0x647, 0x627, 0x631, 0x634, 0x646, 0x628,
+0x647, 0x3b, 0x67e, 0x646, 0x62c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b, 0x634, 0x646, 0x628, 0x647, 0x3b,
+0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x2e,
+0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x77, 0x74, 0x2e, 0x3b, 0x15b, 0x72, 0x2e, 0x3b, 0x63, 0x7a, 0x77, 0x2e, 0x3b, 0x70,
+0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0x6f,
+0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x61, 0x142, 0x65, 0x6b, 0x3b, 0x77, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x15b, 0x72,
+0x6f, 0x64, 0x61, 0x3b, 0x63, 0x7a, 0x77, 0x61, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x69, 0x105, 0x74, 0x65, 0x6b, 0x3b,
+0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x15a, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53,
+0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x15b, 0x3b, 0x63, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x73,
+0x65, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, 0x71, 0x75, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x3b, 0x73, 0x65, 0x78, 0x3b, 0x73,
+0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66,
+0x65, 0x69, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x61,
+0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69,
+0x72, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64,
+0x6f, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x69,
+0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x3b, 0x71, 0x75,
+0x61, 0x72, 0x74, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x3b, 0x73, 0xe1,
+0x62, 0x61, 0x64, 0x6f, 0x3b, 0xa10, 0xa24, 0x3b, 0xa38, 0xa4b, 0xa2e, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0x3b, 0xa2c, 0xa41, 0xa71,
+0xa27, 0x3b, 0xa35, 0xa40, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa3f, 0xa71, 0xa1a, 0xa30,
+0x3b, 0xa10, 0xa24, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa4b, 0xa2e, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0xa35, 0xa3e,
+0xa30, 0x3b, 0xa2c, 0xa41, 0xa71, 0xa27, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa35, 0xa40, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa41,
+0xa71, 0xa15, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa3f, 0xa71, 0xa1a, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa10, 0x3b,
+0xa38, 0xa4b, 0x3b, 0xa2e, 0xa70, 0x3b, 0xa2c, 0xa41, 0xa71, 0x3b, 0xa35, 0xa40, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0x3b, 0xa38, 0xa3c,
+0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x64f, 0x62f, 0x6be,
+0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x44, 0x6f,
+0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0xe9, 0x3b, 0x4a, 0x75, 0x65, 0x3b, 0x56, 0x69,
+0x65, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x73, 0x3b,
+0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x4a, 0x75, 0x65,
+0x76, 0x65, 0x73, 0x3b, 0x56, 0x69, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44,
+0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x3b, 0x67, 0x6c, 0x69, 0x3b,
+0x6d, 0x61, 0x3b, 0x6d, 0x65, 0x3b, 0x67, 0x69, 0x65, 0x3b, 0x76, 0x65, 0x3b, 0x73, 0x6f, 0x3b, 0x64, 0x75, 0x6d, 0x65,
+0x6e, 0x67, 0x69, 0x61, 0x3b, 0x67, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x73, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69,
+0x3b, 0x6d, 0x65, 0x73, 0x65, 0x6d, 0x6e, 0x61, 0x3b, 0x67, 0x69, 0x65, 0x76, 0x67, 0x69, 0x61, 0x3b, 0x76, 0x65, 0x6e,
+0x64, 0x65, 0x72, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x6e, 0x64, 0x61, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b,
+0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e,
+0x3b, 0x6d, 0x69, 0x65, 0x2e, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x2e, 0x3b, 0x73, 0xe2, 0x6d, 0x2e, 0x3b,
+0x64, 0x75, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x103, 0x3b, 0x6c, 0x75, 0x6e, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x21b, 0x69, 0x3b,
+0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x72, 0x69, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x65, 0x72, 0x69, 0x3b,
+0x73, 0xe2, 0x6d, 0x62, 0x103, 0x74, 0x103, 0x3b, 0x44, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b,
+0x4d, 0x69, 0x65, 0x3b, 0x4a, 0x6f, 0x69, 0x3b, 0x56, 0x69, 0x6e, 0x3b, 0x53, 0xe2, 0x6d, 0x3b, 0x44, 0x3b, 0x4c, 0x3b,
+0x4d, 0x61, 0x3b, 0x4d, 0x69, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x432, 0x441, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442,
+0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x432, 0x43e, 0x441, 0x43a, 0x440, 0x435, 0x441,
+0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e,
+0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x433, 0x3b, 0x43f,
+0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x412, 0x3b, 0x41f, 0x3b, 0x412,
+0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x42, 0x6b, 0x31, 0x3b, 0x42, 0x6b, 0x32, 0x3b, 0x42, 0x6b, 0x33,
+0x3b, 0x42, 0x6b, 0x34, 0x3b, 0x42, 0x6b, 0x35, 0x3b, 0x4c, 0xe2, 0x70, 0x3b, 0x4c, 0xe2, 0x79, 0x3b, 0x42, 0x69, 0x6b,
+0x75, 0x61, 0x2d, 0xf4, 0x6b, 0x6f, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0xfb, 0x73, 0x65, 0x3b, 0x42, 0xef, 0x6b,
+0x75, 0x61, 0x2d, 0x70, 0x74, 0xe2, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x75, 0x73, 0xef, 0xf6, 0x3b, 0x42, 0xef,
+0x6b, 0x75, 0x61, 0x2d, 0x6f, 0x6b, 0xfc, 0x3b, 0x4c, 0xe2, 0x70, 0xf4, 0x73, 0xf6, 0x3b, 0x4c, 0xe2, 0x79, 0x65, 0x6e,
+0x67, 0x61, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x59, 0x3b, 0x43d, 0x435, 0x434,
+0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x435, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442,
+0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430,
+0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440,
+0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f,
+0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e,
+0x3b, 0x75, 0x74, 0x2e, 0x3b, 0x73, 0x72, 0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70, 0x65, 0x74, 0x2e, 0x3b, 0x73,
+0x75, 0x62, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c,
+0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x10d,
+0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61,
+0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74,
+0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e,
+0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61,
+0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f,
+0x74, 0x61, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x443, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x2e,
+0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x443, 0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x458,
0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a,
0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435,
-0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x4a, 0x65, 0x64, 0x3b, 0x4a, 0x65, 0x6c, 0x3b, 0x4a,
-0x65, 0x6d, 0x3b, 0x4a, 0x65, 0x72, 0x63, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x3b, 0x4a, 0x65, 0x68, 0x3b, 0x4a, 0x65, 0x73,
-0x3b, 0x4a, 0x65, 0x64, 0x6f, 0x6f, 0x6e, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x6c, 0x68, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65,
-0x6d, 0x61, 0x79, 0x72, 0x74, 0x3b, 0x4a, 0x65, 0x72, 0x63, 0x65, 0x61, 0x6e, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x65, 0x69,
-0x6e, 0x3b, 0x4a, 0x65, 0x68, 0x65, 0x69, 0x6e, 0x65, 0x79, 0x3b, 0x4a, 0x65, 0x73, 0x61, 0x72, 0x6e, 0x3b, 0x53, 0x75,
-0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x74, 0x68, 0x3b, 0x4d, 0x68, 0x72, 0x3b, 0x59, 0x6f, 0x77, 0x3b, 0x47, 0x77,
-0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x64, 0x79, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x64, 0x79, 0x20, 0x4c, 0x75, 0x6e, 0x3b,
-0x64, 0x79, 0x20, 0x4d, 0x65, 0x75, 0x72, 0x74, 0x68, 0x3b, 0x64, 0x79, 0x20, 0x4d, 0x65, 0x72, 0x68, 0x65, 0x72, 0x3b,
-0x64, 0x79, 0x20, 0x59, 0x6f, 0x77, 0x3b, 0x64, 0x79, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x64, 0x79, 0x20,
-0x53, 0x61, 0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x44, 0x77, 0x6f, 0x3b, 0x42, 0x65, 0x6e, 0x3b, 0x57,
-0x75, 0x6b, 0x3b, 0x59, 0x61, 0x77, 0x3b, 0x46, 0x69, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x3b, 0x4b, 0x77, 0x65, 0x73, 0x69,
-0x64, 0x61, 0x3b, 0x44, 0x77, 0x6f, 0x77, 0x64, 0x61, 0x3b, 0x42, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x3b, 0x57, 0x75, 0x6b,
-0x75, 0x64, 0x61, 0x3b, 0x59, 0x61, 0x77, 0x64, 0x61, 0x3b, 0x46, 0x69, 0x64, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x65, 0x6e,
-0x65, 0x64, 0x61, 0x3b, 0x4b, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x906, 0x926,
-0x93f, 0x924, 0x94d, 0x92f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x93e,
-0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915,
-0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd, 0x6e,
-0x3b, 0x54, 0x69, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x3b, 0x53, 0x61,
-0x74, 0x3b, 0x4d, 0x62, 0x1ecd, 0x73, 0x1ecb, 0x20, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd, 0x6e, 0x64, 0x65, 0x3b, 0x54, 0x69,
-0x75, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x65, 0x6e, 0x65, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x7a, 0x64,
-0x65, 0x65, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x64, 0x65, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x1ecd, 0x64, 0x65, 0x65, 0x3b, 0x57,
-0x6b, 0x79, 0x3b, 0x57, 0x6b, 0x77, 0x3b, 0x57, 0x6b, 0x6c, 0x3b, 0x57, 0x74, 0x169, 0x3b, 0x57, 0x6b, 0x6e, 0x3b, 0x57,
-0x74, 0x6e, 0x3b, 0x57, 0x74, 0x68, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x79, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x57, 0x61, 0x20,
-0x6b, 0x77, 0x61, 0x6d, 0x62, 0x129, 0x6c, 0x129, 0x6c, 0x79, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129, 0x3b,
-0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x57, 0x61,
-0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x57, 0x61, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x169,
-0x3b, 0x59, 0x3b, 0x57, 0x3b, 0x45, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c,
-0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0x65, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x3b, 0x73,
-0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x65, 0x3b, 0x6c, 0x75, 0x6e, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72,
-0x74, 0x61, 0x72, 0x73, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x73, 0x3b, 0x6a, 0x6f, 0x69, 0x62, 0x65, 0x3b, 0x76,
-0x69, 0x6e, 0x61, 0x72, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x69, 0x64, 0x65, 0x3b, 0x6b, 0x254, 0x73, 0x3b, 0x64, 0x7a, 0x6f,
-0x3b, 0x62, 0x6c, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x3b, 0x79, 0x61, 0x77, 0x3b, 0x66, 0x69, 0x256, 0x3b, 0x6d, 0x65, 0x6d,
-0x3b, 0x6b, 0x254, 0x73, 0x69, 0x256, 0x61, 0x3b, 0x64, 0x7a, 0x6f, 0x256, 0x61, 0x3b, 0x62, 0x6c, 0x61, 0x256, 0x61, 0x3b,
-0x6b, 0x75, 0x256, 0x61, 0x3b, 0x79, 0x61, 0x77, 0x6f, 0x256, 0x61, 0x3b, 0x66, 0x69, 0x256, 0x61, 0x3b, 0x6d, 0x65, 0x6d,
-0x6c, 0x65, 0x256, 0x61, 0x3b, 0x6b, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x6b, 0x3b, 0x79, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x4c,
-0x50, 0x3b, 0x50, 0x31, 0x3b, 0x50, 0x32, 0x3b, 0x50, 0x33, 0x3b, 0x50, 0x34, 0x3b, 0x50, 0x35, 0x3b, 0x50, 0x36, 0x3b,
-0x4c, 0x101, 0x70, 0x75, 0x6c, 0x65, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x61, 0x68, 0x69, 0x3b, 0x50, 0x6f, 0x2bb, 0x61,
-0x6c, 0x75, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x6f, 0x6c, 0x75, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x68, 0x101, 0x3b,
-0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x69, 0x6d, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6f, 0x6e, 0x6f, 0x3b, 0x4c, 0x69, 0x6e,
-0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0x79, 0x3b, 0x48, 0x75, 0x77, 0x3b, 0x42, 0x69, 0x79,
-0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4c, 0x69, 0x6e, 0x67, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x4d, 0x61,
-0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0x79, 0x65, 0x72, 0x6b, 0x75, 0x6c, 0x65, 0x73, 0x3b, 0x48, 0x75, 0x77, 0x65,
-0x62, 0x65, 0x73, 0x3b, 0x42, 0x69, 0x79, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x64, 0x6f, 0x3b,
-0x53, 0x75, 0x2e, 0x3b, 0x4d, 0xe4, 0x2e, 0x3b, 0x5a, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b,
-0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x74, 0x69, 0x67, 0x3b, 0x4d, 0xe4, 0xe4, 0x6e,
-0x74, 0x69, 0x67, 0x3b, 0x5a, 0x69, 0x69, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x75,
-0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0x46, 0x72, 0x69, 0x69, 0x74, 0x69, 0x67,
-0x3b, 0x53, 0x61, 0x6d, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0xa46d, 0xa18f, 0x3b, 0xa18f, 0xa2cd, 0x3b, 0xa18f, 0xa44d, 0x3b,
-0xa18f, 0xa315, 0x3b, 0xa18f, 0xa1d6, 0x3b, 0xa18f, 0xa26c, 0x3b, 0xa18f, 0xa0d8, 0x3b, 0xa46d, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa2cd, 0x3b,
-0xa18f, 0xa282, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa315, 0x3b, 0xa18f, 0xa282, 0xa1d6, 0x3b, 0xa18f, 0xa282, 0xa26c, 0x3b, 0xa18f, 0xa282, 0xa0d8, 0x3b,
-0xa18f, 0x3b, 0xa2cd, 0x3b, 0xa44d, 0x3b, 0xa315, 0x3b, 0xa1d6, 0x3b, 0xa26c, 0x3b, 0xa0d8, 0x3b, 0x53, 0xfc, 0x2e, 0x3b, 0x4d, 0x61,
-0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61,
-0x2e, 0x3b, 0x53, 0xfc, 0x6e, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x44, 0x69,
-0x6e, 0x67, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x64, 0x64, 0x65, 0x77, 0x65, 0x6b, 0x65, 0x6e, 0x3b, 0x44, 0x75,
-0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x65, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x53, 0xfc, 0x6e,
-0x6e, 0x61, 0x76, 0x65, 0x6e, 0x64, 0x3b, 0x73, 0x6f, 0x74, 0x6e, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x3b, 0x6d, 0x61, 0x14b,
-0x3b, 0x67, 0x61, 0x73, 0x6b, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x3b, 0x6c, 0xe1, 0x76, 0x3b,
-0x73, 0x6f, 0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0xe1, 0x72, 0x67,
-0x61, 0x3b, 0x6d, 0x61, 0x14b, 0x14b, 0x65, 0x62, 0xe1, 0x72, 0x67, 0x61, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61,
-0x68, 0x6b, 0x6b, 0x75, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x61, 0x73, 0x64, 0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a,
-0x61, 0x64, 0x61, 0x74, 0x3b, 0x6c, 0xe1, 0x76, 0x76, 0x61, 0x72, 0x64, 0x61, 0x74, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4d,
-0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42,
-0x3b, 0x4c, 0x3b, 0x73, 0x6f, 0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73,
-0xe1, 0x72, 0x67, 0x67, 0x61, 0x3b, 0x6d, 0x61, 0x14b, 0x14b, 0x65, 0x62, 0xe1, 0x72, 0x67, 0x67, 0x61, 0x3b, 0x67, 0x61,
-0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x75, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x61, 0x73, 0x74, 0x61, 0x67, 0x61, 0x3b,
-0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x67, 0x61, 0x3b, 0x6c, 0xe1, 0x76, 0x76, 0x61, 0x72, 0x64, 0x61, 0x67,
-0x61, 0x3b, 0x43, 0x70, 0x72, 0x3b, 0x43, 0x74, 0x74, 0x3b, 0x43, 0x6d, 0x6e, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x41, 0x72,
-0x73, 0x3b, 0x49, 0x63, 0x6d, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, 0x3b,
-0x43, 0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x43,
-0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x63, 0x68,
-0x75, 0x6d, 0x61, 0x3b, 0x45, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b,
-0x41, 0x3b, 0x49, 0x3b, 0x45, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, 0x61,
-0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x49, 0x74, 0x75, 0x6b, 0x75, 0x20,
-0x6a, 0x61, 0x20, 0x6a, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6a, 0x69,
-0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, 0x3b,
-0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x75, 0x72, 0x61,
-0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b,
-0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x69, 0x66, 0x75, 0x6c, 0x61, 0x20, 0x6e, 0x67, 0x75, 0x77, 0x6f, 0x3b, 0x4a,
-0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x64, 0x65, 0x77, 0x3b, 0x61, 0x61, 0x253,
-0x3b, 0x6d, 0x61, 0x77, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x3b, 0x6d, 0x77, 0x64, 0x3b, 0x68, 0x62, 0x69,
-0x3b, 0x64, 0x65, 0x77, 0x6f, 0x3b, 0x61, 0x61, 0x253, 0x6e, 0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x62, 0x61, 0x61, 0x72,
-0x65, 0x3b, 0x6e, 0x6a, 0x65, 0x73, 0x6c, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x73, 0x61, 0x61, 0x6e, 0x64,
-0x65, 0x3b, 0x6d, 0x61, 0x77, 0x6e, 0x64, 0x65, 0x3b, 0x68, 0x6f, 0x6f, 0x72, 0x65, 0x2d, 0x62, 0x69, 0x69, 0x72, 0x3b,
-0x64, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x4b, 0x4d, 0x41, 0x3b, 0x4e, 0x54,
-0x54, 0x3b, 0x4e, 0x4d, 0x4e, 0x3b, 0x4e, 0x4d, 0x54, 0x3b, 0x41, 0x52, 0x54, 0x3b, 0x4e, 0x4d, 0x41, 0x3b, 0x4e, 0x4d,
-0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4e,
-0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x61, 0x3b, 0x41, 0x72,
-0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x6d,
-0x6f, 0x74, 0x68, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41,
-0x72, 0x65, 0x3b, 0x4b, 0x75, 0x6e, 0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53,
-0x61, 0x70, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x61, 0x72, 0x65,
-0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4d, 0x64, 0x65, 0x72,
-0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74,
-0x20, 0x65, 0x65, 0x20, 0x69, 0x6e, 0x65, 0x74, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x69,
-0x6c, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4d, 0x64,
-0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x77, 0x65, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x4f, 0x3b, 0x49, 0x3b,
-0x49, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x50, 0x6f, 0x73, 0x3b, 0x50, 0x69, 0x72, 0x3b, 0x54, 0x61,
-0x74, 0x3b, 0x4e, 0x61, 0x69, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x69, 0x6e, 0x67,
-0x75, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x6f, 0x73, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68,
-0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, 0x6e,
-0x75, 0x3b, 0x53, 0x61, 0x62, 0x75, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x53,
-0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x53, 0x69, 0x74, 0x3b, 0x53,
-0x69, 0x6e, 0x3b, 0x53, 0x69, 0x68, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x4d, 0x76, 0x75,
-0x6c, 0x6f, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x53, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x53,
-0x69, 0x6e, 0x65, 0x3b, 0x53, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f,
-0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x49, 0x6a, 0x70, 0x3b, 0x49,
-0x6a, 0x74, 0x3b, 0x49, 0x6a, 0x6e, 0x3b, 0x49, 0x6a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b,
-0x49, 0x6a, 0x6d, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x74,
-0x61, 0x74, 0x75, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61,
-0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x49,
-0x6a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37,
-0x3b, 0x31, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x3b, 0x2d30,
-0x2d3d, 0x2d61, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, 0x3b,
-0x2d30, 0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, 0x2d30,
-0x2d3d, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, 0x3b,
-0x61, 0x73, 0x61, 0x3b, 0x61, 0x79, 0x6e, 0x3b, 0x61, 0x73, 0x69, 0x3b, 0x61, 0x6b, 0x1e5b, 0x3b, 0x61, 0x6b, 0x77, 0x3b,
-0x61, 0x73, 0x69, 0x6d, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x3b, 0x61, 0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, 0x61, 0x79, 0x6e,
-0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x1e5b, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x77, 0x61,
-0x73, 0x3b, 0x61, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, 0x3b, 0x59, 0x61,
-0x6e, 0x3b, 0x53, 0x61, 0x6e, 0x3b, 0x4b, 0x72, 0x61, 0x1e0d, 0x3b, 0x4b, 0x75, 0x1e93, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53,
-0x1e0d, 0x69, 0x73, 0x3b, 0x53, 0x61, 0x79, 0x3b, 0x59, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6e, 0x61, 0x73,
-0x73, 0x3b, 0x4b, 0x72, 0x61, 0x1e0d, 0x61, 0x73, 0x73, 0x3b, 0x4b, 0x75, 0x1e93, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6d,
-0x61, 0x73, 0x73, 0x3b, 0x53, 0x1e0d, 0x69, 0x73, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x79, 0x61, 0x73, 0x73, 0x3b, 0x59,
-0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x41, 0x4e, 0x3b, 0x4f, 0x52, 0x4b,
-0x3b, 0x4f, 0x4b, 0x42, 0x3b, 0x4f, 0x4b, 0x53, 0x3b, 0x4f, 0x4b, 0x4e, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4f, 0x4d, 0x4b,
-0x3b, 0x53, 0x61, 0x6e, 0x64, 0x65, 0x3b, 0x4f, 0x72, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f,
-0x72, 0x77, 0x61, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74,
-0x75, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61,
-0x6e, 0x6f, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x52,
-0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x48, 0x69, 0x76,
-0x3b, 0x48, 0x69, 0x64, 0x3b, 0x48, 0x69, 0x74, 0x3b, 0x48, 0x69, 0x68, 0x3b, 0x4c, 0x65, 0x6d, 0x3b, 0x70, 0x61, 0x20,
-0x6d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x76, 0x69, 0x6c, 0x75,
-0x68, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x64, 0x61,
-0x74, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x74, 0x61, 0x79, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x68, 0x61,
-0x6e, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x6c, 0x65, 0x6d, 0x62, 0x65, 0x6c, 0x61, 0x3b, 0x4d,
-0x3b, 0x4a, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74,
-0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f,
-0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x75,
-0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x41, 0x6c,
-0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f,
-0x73, 0x69, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x6b, 0x61, 0x72,
-0x3b, 0x6e, 0x74, 0x25b, 0x3b, 0x74, 0x61, 0x72, 0x3b, 0x61, 0x72, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x3b, 0x6a, 0x75, 0x6d,
-0x3b, 0x73, 0x69, 0x62, 0x3b, 0x6b, 0x61, 0x72, 0x69, 0x3b, 0x6e, 0x74, 0x25b, 0x6e, 0x25b, 0x3b, 0x74, 0x61, 0x72, 0x61,
-0x74, 0x61, 0x3b, 0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x6a, 0x75, 0x6d,
-0x61, 0x3b, 0x73, 0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x4a,
-0x3b, 0x53, 0x3b, 0x4b, 0x6d, 0x61, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6e, 0x3b, 0x41,
-0x72, 0x6d, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x4e, 0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a,
-0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75,
-0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d,
-0x61, 0x61, 0x3b, 0x4e, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x74, 0x68, 0x69, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e,
-0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x13c6, 0x13cd, 0x13ac, 0x3b, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1,
-0x3b, 0x13e6, 0x13a2, 0x13c1, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x3b, 0x13c8, 0x13d5, 0x13be, 0x3b, 0x13a4, 0x13be, 0x13d9,
-0x13d3, 0x13c6, 0x13cd, 0x13ac, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e6,
-0x13a2, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x13b6, 0x13cd, 0x13d7, 0x3b, 0x13a4, 0x13be,
-0x13d9, 0x13d3, 0x13c8, 0x13d5, 0x13be, 0x3b, 0x13c6, 0x3b, 0x13c9, 0x3b, 0x13d4, 0x3b, 0x13e6, 0x3b, 0x13c5, 0x3b, 0x13e7, 0x3b, 0x13a4, 0x3b,
-0x64, 0x69, 0x6d, 0x3b, 0x6c, 0x69, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x7a, 0x65, 0x3b, 0x76,
-0x61, 0x6e, 0x3b, 0x73, 0x61, 0x6d, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x73, 0x3b, 0x6c, 0x69, 0x6e, 0x64, 0x69, 0x3b,
-0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x6b, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x7a, 0x65, 0x64, 0x69, 0x3b,
-0x76, 0x61, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0x69, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d,
-0x3b, 0x6d, 0x3b, 0x7a, 0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4c, 0x6c, 0x32, 0x3b, 0x4c, 0x6c, 0x33, 0x3b, 0x4c, 0x6c, 0x34,
-0x3b, 0x4c, 0x6c, 0x35, 0x3b, 0x4c, 0x6c, 0x36, 0x3b, 0x4c, 0x6c, 0x37, 0x3b, 0x4c, 0x6c, 0x31, 0x3b, 0x4c, 0x69, 0x64,
-0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c,
-0x79, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x63, 0x68,
-0x65, 0x63, 0x68, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e,
-0x6f, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e,
-0x61, 0x20, 0x6c, 0x69, 0x6e, 0x6a, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e,
-0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76,
-0x61, 0x20, 0x6c, 0x69, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x50, 0xed, 0x69, 0x6c, 0x69, 0x3b, 0x54, 0xe1, 0x61, 0x74,
-0x75, 0x3b, 0xcd, 0x6e, 0x65, 0x3b, 0x54, 0xe1, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b,
-0x4d, 0xf3, 0x6f, 0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
-0x74, 0xe1, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0xed, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x61,
-0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x61, 0x6d, 0xed, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0xe1, 0x61, 0x3b, 0x4a,
-0x75, 0x6d, 0x61, 0x6d, 0xf3, 0x6f, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49,
-0x3b, 0x4d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x42, 0x61, 0x6c, 0x3b, 0x4c, 0x77, 0x32, 0x3b, 0x4c, 0x77, 0x33, 0x3b, 0x4c,
-0x77, 0x34, 0x3b, 0x4c, 0x77, 0x35, 0x3b, 0x4c, 0x77, 0x36, 0x3b, 0x53, 0x61, 0x62, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b,
-0x42, 0x61, 0x6c, 0x61, 0x7a, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4c, 0x77, 0x61,
-0x6b, 0x75, 0x73, 0x61, 0x74, 0x75, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75,
-0x74, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4c, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42,
-0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x50, 0x61, 0x20, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67,
-0x75, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x6d, 0x6f, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x62,
-0x75, 0x6c, 0x69, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x50, 0x61, 0x6c, 0x69,
-0x63, 0x68, 0x69, 0x6e, 0x65, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x6f, 0x3b, 0x50, 0x61,
-0x63, 0x68, 0x69, 0x62, 0x65, 0x6c, 0x75, 0x73, 0x68, 0x69, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x73, 0x69, 0x67, 0x3b, 0x74,
-0x65, 0x72, 0x3b, 0x6b, 0x75, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x3b, 0x73, 0x65, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64,
-0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b,
-0x74, 0x65, 0x72, 0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65,
-0x72, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x61, 0x2d,
-0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b,
-0x4b, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64,
-0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75,
-0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61,
-0x3b, 0x73, 0x65, 0x73, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x4b,
-0x49, 0x55, 0x3b, 0x4d, 0x52, 0x41, 0x3b, 0x57, 0x41, 0x49, 0x3b, 0x57, 0x45, 0x54, 0x3b, 0x57, 0x45, 0x4e, 0x3b, 0x57,
-0x54, 0x4e, 0x3b, 0x4a, 0x55, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4d, 0x75, 0x72, 0x61, 0x6d, 0x75,
-0x6b, 0x6f, 0x3b, 0x57, 0x61, 0x69, 0x72, 0x69, 0x3b, 0x57, 0x65, 0x74, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x57, 0x65, 0x6e,
-0x61, 0x3b, 0x57, 0x65, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4b, 0x3b,
-0x4d, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4b, 0x74, 0x73, 0x3b, 0x4b, 0x6f, 0x74, 0x3b,
-0x4b, 0x6f, 0x6f, 0x3b, 0x4b, 0x6f, 0x73, 0x3b, 0x4b, 0x6f, 0x61, 0x3b, 0x4b, 0x6f, 0x6d, 0x3b, 0x4b, 0x6f, 0x6c, 0x3b,
-0x4b, 0x6f, 0x74, 0x69, 0x73, 0x61, 0x70, 0x3b, 0x4b, 0x6f, 0x74, 0x61, 0x61, 0x69, 0x3b, 0x4b, 0x6f, 0x61, 0x65, 0x6e,
-0x67, 0x2019, 0x3b, 0x4b, 0x6f, 0x73, 0x6f, 0x6d, 0x6f, 0x6b, 0x3b, 0x4b, 0x6f, 0x61, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e,
-0x3b, 0x4b, 0x6f, 0x6d, 0x75, 0x75, 0x74, 0x3b, 0x4b, 0x6f, 0x6c, 0x6f, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x53,
-0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x61, 0x3b, 0x44, 0x65, 0x3b, 0x57, 0x75, 0x3b,
-0x44, 0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65,
-0x73, 0x3b, 0x4d, 0x61, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x65, 0x6e, 0x73, 0x74, 0x61,
-0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x57, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b,
-0x44, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x46, 0x72, 0x61, 0x69, 0x74,
-0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x74, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65,
-0x73, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x75, 0x2e, 0x3b,
-0x4d, 0x6f, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x65, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b,
-0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x6f, 0x68, 0x6e, 0x64, 0x61,
-0x61, 0x63, 0x68, 0x3b, 0x44, 0x69, 0x6e, 0x6e, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x65, 0x74, 0x77, 0x6f,
-0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x46, 0x72, 0x69, 0x69,
-0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
-0x70, 0xed, 0x6c, 0xed, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x65,
-0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x6e, 0x254, 0x3b, 0x41, 0x6c, 0x61, 0xe1, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x4a,
-0x75, 0x6d, 0xe1, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0xf3, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x3b, 0x42,
-0x61, 0x6c, 0x61, 0x3b, 0x4b, 0x75, 0x62, 0x69, 0x3b, 0x4b, 0x75, 0x73, 0x61, 0x3b, 0x4b, 0x75, 0x6e, 0x61, 0x3b, 0x4b,
-0x75, 0x74, 0x61, 0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c,
-0x61, 0x7a, 0x61, 0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x73,
-0x61, 0x74, 0x75, 0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x74, 0x61, 0x61,
-0x6e, 0x75, 0x3b, 0x4f, 0x6c, 0x6f, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x42, 0x3b,
-0x53, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x4a, 0x32, 0x3b, 0x4a, 0x33, 0x3b, 0x4a, 0x34, 0x3b, 0x4a, 0x35, 0x3b,
-0x41, 0x6c, 0x3b, 0x49, 0x6a, 0x3b, 0x4a, 0x31, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75,
-0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74,
-0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x75, 0x72, 0x77, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4d,
-0x75, 0x72, 0x77, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d,
-0x6f, 0x73, 0x69, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b,
-0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x42, 0x61, 0x72, 0x3b,
-0x41, 0x61, 0x72, 0x3b, 0x55, 0x6e, 0x69, 0x3b, 0x55, 0x6e, 0x67, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x53, 0x61, 0x62, 0x3b,
-0x4e, 0x61, 0x6b, 0x61, 0x65, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x65, 0x62, 0x61, 0x72, 0x61, 0x73,
-0x61, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x61,
-0x6b, 0x61, 0x75, 0x6e, 0x67, 0x2019, 0x6f, 0x6e, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x6b, 0x61, 0x6e, 0x79, 0x3b, 0x4e, 0x61,
-0x6b, 0x61, 0x73, 0x61, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x4a, 0x3b, 0x42, 0x3b, 0x41, 0x3b, 0x55, 0x3b, 0x55, 0x3b, 0x4b,
-0x3b, 0x53, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41,
-0x6c, 0x6d, 0x3b, 0x41, 0x6c, 0x6a, 0x3b, 0x41, 0x73, 0x73, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74,
-0x69, 0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41,
-0x6c, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x73, 0x61,
-0x62, 0x64, 0x75, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x4a, 0x4d,
-0x50, 0x3b, 0x57, 0x55, 0x54, 0x3b, 0x54, 0x41, 0x52, 0x3b, 0x54, 0x41, 0x44, 0x3b, 0x54, 0x41, 0x4e, 0x3b, 0x54, 0x41,
-0x42, 0x3b, 0x4e, 0x47, 0x53, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x3b, 0x57, 0x75, 0x6f, 0x6b, 0x20, 0x54,
-0x69, 0x63, 0x68, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20,
-0x41, 0x64, 0x65, 0x6b, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x6e, 0x67, 0x2019, 0x77, 0x65, 0x6e, 0x3b, 0x54, 0x69,
-0x63, 0x68, 0x20, 0x41, 0x62, 0x69, 0x63, 0x68, 0x3b, 0x4e, 0x67, 0x65, 0x73, 0x6f, 0x3b, 0x4a, 0x3b, 0x57, 0x3b, 0x54,
-0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x41, 0x79, 0x6e, 0x3b, 0x41, 0x73, 0x6e,
-0x3b, 0x41, 0x6b, 0x72, 0x3b, 0x41, 0x6b, 0x77, 0x3b, 0x41, 0x73, 0x6d, 0x3b, 0x41, 0x73, 0x1e0d, 0x3b, 0x41, 0x73, 0x61,
-0x6d, 0x61, 0x73, 0x3b, 0x41, 0x79, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x6b, 0x72,
-0x61, 0x73, 0x3b, 0x41, 0x6b, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69,
-0x1e0d, 0x79, 0x61, 0x73, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41,
-0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b, 0x41,
-0x6c, 0x7a, 0x3b, 0x41, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69,
-0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68,
-0x61, 0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69,
-0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6d, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68,
-0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x70, 0x69, 0x69, 0x3b, 0x4a, 0x75,
-0x6d, 0x61, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
-0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61,
-0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b,
-0x41, 0x3b, 0x49, 0x3b, 0x31, 0x3b, 0x930, 0x92c, 0x93f, 0x3b, 0x938, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941,
-0x926, 0x3b, 0x92c, 0x93f, 0x938, 0x925, 0x93f, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x3b, 0x930,
-0x92c, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b,
-0x92c, 0x941, 0x926, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x938, 0x925, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941, 0x916, 0x941,
-0x930, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x3b, 0x92e, 0x902, 0x3b,
-0x92c, 0x941, 0x3b, 0x92c, 0x93f, 0x3b, 0x938, 0x941, 0x3b, 0x938, 0x941, 0x3b, 0x43a, 0x4c0, 0x438, 0x440, 0x430, 0x43d, 0x430, 0x43d,
-0x20, 0x434, 0x435, 0x3b, 0x43e, 0x440, 0x448, 0x43e, 0x442, 0x430, 0x43d, 0x20, 0x434, 0x435, 0x3b, 0x448, 0x438, 0x43d, 0x430, 0x440,
-0x438, 0x43d, 0x20, 0x434, 0x435, 0x3b, 0x43a, 0x445, 0x430, 0x430, 0x440, 0x438, 0x43d, 0x20, 0x434, 0x435, 0x3b, 0x435, 0x430, 0x440,
-0x438, 0x43d, 0x20, 0x434, 0x435, 0x3b, 0x43f, 0x4c0, 0x435, 0x440, 0x430, 0x441, 0x43a, 0x430, 0x43d, 0x20, 0x434, 0x435, 0x3b, 0x448,
-0x43e, 0x442, 0x20, 0x434, 0x435, 0x3b, 0x43d, 0x434, 0x2de7, 0x487, 0x467, 0x3b, 0x43f, 0x43d, 0x2de3, 0x435, 0x3b, 0x432, 0x442, 0x43e,
-0x2dec, 0x487, 0x3b, 0x441, 0x440, 0x2de3, 0x435, 0x3b, 0x447, 0x435, 0x2de6, 0x487, 0x3b, 0x43f, 0x467, 0x2de6, 0x487, 0x3b, 0x441, 0xa64b,
-0x2de0, 0x487, 0x3b, 0x43d, 0x435, 0x434, 0x463, 0x301, 0x43b, 0x467, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x463, 0x301, 0x43b, 0x44c,
-0x43d, 0x438, 0x43a, 0x44a, 0x3b, 0x432, 0x442, 0x43e, 0x301, 0x440, 0x43d, 0x438, 0x43a, 0x44a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430,
-0x300, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x442, 0x43e, 0x301, 0x43a, 0x44a, 0x3b, 0x43f, 0x467, 0x442, 0x43e, 0x301, 0x43a,
-0x44a, 0x3b, 0x441, 0xa64b, 0x431, 0x431, 0x461, 0x301, 0x442, 0x430, 0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4e, 0x6b, 0x6f, 0x3b, 0x4e,
-0x64, 0x79, 0x3b, 0x4e, 0x64, 0x67, 0x3b, 0x4e, 0x6a, 0x77, 0x3b, 0x4e, 0x67, 0x76, 0x3b, 0x4c, 0x75, 0x62, 0x3b, 0x4c,
-0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4e, 0x6b, 0x6f, 0x64, 0x79, 0x61, 0x3b, 0x4e, 0x64, 0xe0, 0x61, 0x79, 0xe0,
-0x3b, 0x4e, 0x64, 0x61, 0x6e, 0x67, 0xf9, 0x3b, 0x4e, 0x6a, 0xf2, 0x77, 0x61, 0x3b, 0x4e, 0x67, 0xf2, 0x76, 0x79, 0x61,
-0x3b, 0x4c, 0x75, 0x62, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4c, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e,
-0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0xe9, 0x69, 0x3b, 0x44, 0xeb, 0x6e, 0x3b, 0x4d, 0xeb, 0x74, 0x3b, 0x44,
-0x6f, 0x6e, 0x3b, 0x46, 0x72, 0x65, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x6f, 0x6e, 0x6e, 0x64, 0x65, 0x67, 0x3b, 0x4d,
-0xe9, 0x69, 0x6e, 0x64, 0x65, 0x67, 0x3b, 0x44, 0xeb, 0x6e, 0x73, 0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x4d, 0xeb, 0x74,
-0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65, 0x73, 0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x46, 0x72,
-0x65, 0x69, 0x64, 0x65, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x53, 0x6f, 0x6e, 0x2e,
-0x3b, 0x4d, 0xe9, 0x69, 0x2e, 0x3b, 0x44, 0xeb, 0x6e, 0x2e, 0x3b, 0x4d, 0xeb, 0x74, 0x2e, 0x3b, 0x44, 0x6f, 0x6e, 0x2e,
-0x3b, 0x46, 0x72, 0x65, 0x2e, 0x3b, 0x53, 0x61, 0x6d, 0x2e, 0x3b, 0x6e, 0x74, 0x73, 0x3b, 0x6b, 0x70, 0x61, 0x3b, 0x67,
-0x68, 0x254, 0x3b, 0x74, 0x254, 0x6d, 0x3b, 0x75, 0x6d, 0x65, 0x3b, 0x67, 0x68, 0x268, 0x3b, 0x64, 0x7a, 0x6b, 0x3b, 0x74,
-0x73, 0x75, 0x294, 0x6e, 0x74, 0x73, 0x268, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x6b, 0x70, 0xe0, 0x3b, 0x74, 0x73, 0x75,
-0x294, 0x75, 0x67, 0x68, 0x254, 0x65, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x74, 0x254, 0x300, 0x6d, 0x6c, 0xf2, 0x3b, 0x74,
-0x73, 0x75, 0x294, 0x75, 0x6d, 0xe8, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x67, 0x68, 0x268, 0x302, 0x6d, 0x3b, 0x74, 0x73,
-0x75, 0x294, 0x6e, 0x64, 0x7a, 0x268, 0x6b, 0x254, 0x294, 0x254, 0x3b, 0x6e, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x74, 0x3b, 0x75,
-0x3b, 0x67, 0x3b, 0x64, 0x3b, 0x6e, 0x254, 0x79, 0x3b, 0x6e, 0x6a, 0x61, 0x3b, 0x75, 0x75, 0x6d, 0x3b, 0x14b, 0x67, 0x65,
-0x3b, 0x6d, 0x62, 0x254, 0x3b, 0x6b, 0x254, 0x254, 0x3b, 0x6a, 0x6f, 0x6e, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x254,
-0x302, 0x79, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x6a, 0x61, 0x14b, 0x67, 0x75, 0x6d, 0x62, 0x61, 0x3b, 0x14b, 0x67,
-0x77, 0xe0, 0x20, 0xfb, 0x6d, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x14b, 0x67, 0xea, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20,
-0x6d, 0x62, 0x254, 0x6b, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6b, 0x254, 0x254, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6a,
-0xf4, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x75, 0x3b, 0x14b, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6a, 0x3b, 0x41, 0x6c, 0x68,
-0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b,
-0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x7a, 0x75,
-0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b,
-0x5a, 0x3b, 0x53, 0x3b, 0xe9, 0x74, 0x3b, 0x6d, 0x254, 0x301, 0x73, 0x3b, 0x6b, 0x77, 0x61, 0x3b, 0x6d, 0x75, 0x6b, 0x3b,
-0x14b, 0x67, 0x69, 0x3b, 0x257, 0xf3, 0x6e, 0x3b, 0x65, 0x73, 0x61, 0x3b, 0xe9, 0x74, 0x69, 0x3b, 0x6d, 0x254, 0x301, 0x73,
-0xfa, 0x3b, 0x6b, 0x77, 0x61, 0x73, 0xfa, 0x3b, 0x6d, 0x75, 0x6b, 0x254, 0x301, 0x73, 0xfa, 0x3b, 0x14b, 0x67, 0x69, 0x73,
-0xfa, 0x3b, 0x257, 0xf3, 0x6e, 0x25b, 0x73, 0xfa, 0x3b, 0x65, 0x73, 0x61, 0x253, 0x61, 0x73, 0xfa, 0x3b, 0x65, 0x3b, 0x6d,
-0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x14b, 0x3b, 0x257, 0x3b, 0x65, 0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x54, 0x65, 0x6e, 0x3b, 0x54,
-0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x41, 0x72, 0x6a, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x44,
-0x69, 0x6d, 0x61, 0x73, 0x3b, 0x54, 0x65, 0x6e, 0x65, 0x14b, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c,
-0x61, 0x72, 0x62, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x6a, 0x75, 0x6d,
-0x61, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x44, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41,
-0x3b, 0x53, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, 0x73, 0x6d, 0x6c,
-0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x66, 0xfa, 0x6c, 0x3b, 0x73, 0xe9, 0x72, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b,
-0x6d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d,
-0x259, 0x301, 0x62, 0x25b, 0x30c, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259,
-0x301, 0x6c, 0x25b, 0x301, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301,
-0x6e, 0x79, 0x69, 0x3b, 0x66, 0xfa, 0x6c, 0x61, 0x64, 0xe9, 0x3b, 0x73, 0xe9, 0x72, 0x61, 0x64, 0xe9, 0x3b, 0x73, 0x3b,
-0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6c, 0x1dd, 0x6e,
-0x3b, 0x6d, 0x61, 0x61, 0x3b, 0x6d, 0x25b, 0x6b, 0x3b, 0x6a, 0x1dd, 0x1dd, 0x3b, 0x6a, 0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x6d,
-0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x1dd, 0x3b, 0x6c, 0x1dd, 0x6e, 0x64, 0xed, 0x3b, 0x6d, 0x61, 0x61, 0x64, 0xed, 0x3b,
-0x6d, 0x25b, 0x6b, 0x72, 0x25b, 0x64, 0xed, 0x3b, 0x6a, 0x1dd, 0x1dd, 0x64, 0xed, 0x3b, 0x6a, 0xfa, 0x6d, 0x62, 0xe1, 0x3b,
-0x73, 0x61, 0x6d, 0x64, 0xed, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x73, 0x3b,
-0x53, 0x61, 0x62, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x72, 0x61, 0x3b,
-0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74,
+0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x425, 0x446, 0x431, 0x3b, 0x41a, 0x440, 0x441, 0x3b, 0x414,
+0x446, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x3b, 0x426, 0x43f, 0x440, 0x3b, 0x41c, 0x440, 0x431, 0x3b, 0x421, 0x431, 0x442, 0x3b, 0x425,
+0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x41a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x414,
+0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x426, 0x44b, 0x43f, 0x43f, 0x4d5,
+0x440, 0x4d5, 0x43c, 0x3b, 0x41c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x421, 0x430, 0x431, 0x430, 0x442, 0x3b,
+0x425, 0x3b, 0x41a, 0x3b, 0x414, 0x3b, 0x4d4, 0x3b, 0x426, 0x3b, 0x41c, 0x3b, 0x421, 0x3b, 0x445, 0x446, 0x431, 0x3b, 0x43a, 0x440,
+0x441, 0x3b, 0x434, 0x446, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x3b, 0x446, 0x43f, 0x440, 0x3b, 0x43c, 0x440, 0x431, 0x3b, 0x441, 0x431,
+0x442, 0x3b, 0x445, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x43a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441, 0x4d5,
+0x440, 0x3b, 0x434, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x446, 0x44b,
+0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x43c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x441, 0x430, 0x431,
+0x430, 0x442, 0x3b, 0x53, 0x76, 0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x3b, 0x43, 0x68, 0x70, 0x3b, 0x43, 0x68, 0x74, 0x3b, 0x43,
+0x68, 0x6e, 0x3b, 0x43, 0x68, 0x73, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x76, 0x6f, 0x6e, 0x64, 0x6f, 0x3b, 0x4d, 0x75,
+0x76, 0x68, 0x75, 0x72, 0x6f, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x74, 0x61, 0x74,
+0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75, 0x67,
+0x6f, 0x76, 0x65, 0x72, 0x61, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4d, 0x3b,
+0x622, 0x686, 0x631, 0x3b, 0x633, 0x648, 0x645, 0x631, 0x3b, 0x627, 0x6b1, 0x627, 0x631, 0x648, 0x3b, 0x627, 0x631, 0x628, 0x639, 0x3b,
+0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x62c, 0x645, 0x639, 0x648, 0x3b, 0x687, 0x646, 0x687, 0x631, 0x3b, 0x622, 0x686, 0x3b, 0x633, 0x648,
+0x3b, 0x627, 0x6b1, 0x3b, 0x627, 0x631, 0x3b, 0x62e, 0x645, 0x3b, 0x62c, 0x645, 0x3b, 0x687, 0x646, 0x3b, 0x622, 0x686, 0x631, 0x3b,
+0x633, 0x648, 0x3b, 0x627, 0x6b1, 0x627, 0x631, 0x648, 0x3b, 0x627, 0x631, 0x628, 0x639, 0x3b, 0x62e, 0x645, 0x3b, 0x62c, 0x645, 0x639,
+0x648, 0x3b, 0x687, 0x646, 0x687, 0x631, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85,
+0xd9f, 0xdc4, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0x3b, 0xdc3, 0xdd2, 0xd9a,
+0xdd4, 0x3b, 0xdc3, 0xdd9, 0xdb1, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f,
+0xdc4, 0xdbb, 0xdd4, 0xdc0, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3,
+0xdca, 0xdb4, 0xdad, 0xdd2, 0xdb1, 0xdca, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd9,
+0xdb1, 0xdc3, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xd89, 0x3b, 0xdc3, 0x3b, 0xd85, 0x3b, 0xdb6, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb,
+0x3b, 0xdc3, 0xdd2, 0x3b, 0xdc3, 0xdd9, 0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0x75, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x161,
+0x74, 0x3b, 0x70, 0x69, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x13e, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x65,
+0x6c, 0x6f, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6b, 0x3b, 0x73, 0x74, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74,
+0x76, 0x72, 0x74, 0x6f, 0x6b, 0x3b, 0x70, 0x69, 0x61, 0x74, 0x6f, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b,
+0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, 0x161, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70,
+0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x73, 0x72, 0x65, 0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70,
+0x65, 0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e,
+0x65, 0x64, 0x65, 0x6c, 0x6a, 0x65, 0x6b, 0x3b, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b,
+0x10d, 0x65, 0x74, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61,
+0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x41, 0x78, 0x64, 0x3b, 0x49,
+0x73, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x53,
+0x61, 0x62, 0x3b, 0x41, 0x78, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61,
+0x64, 0x6f, 0x3b, 0x41, 0x72, 0x62, 0x61, 0x63, 0x6f, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x3b, 0x4a, 0x69,
+0x6d, 0x63, 0x6f, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x69, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x4b, 0x68,
+0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b,
+0x6d, 0x69, 0xe9, 0x2e, 0x3b, 0x6a, 0x75, 0x65, 0x2e, 0x3b, 0x76, 0x69, 0x65, 0x2e, 0x3b, 0x73, 0xe1, 0x62, 0x2e, 0x3b,
+0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73,
+0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x6a, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69,
+0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d,
+0x3b, 0x6a, 0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
+0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e,
+0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75,
+0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x73, 0xf6, 0x6e, 0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74, 0x69, 0x73, 0x3b, 0x6f,
+0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf6, 0x72, 0x3b, 0x73, 0xf6, 0x6e, 0x64,
+0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73,
+0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c,
+0xf6, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x42f, 0x448, 0x431, 0x3b, 0x414, 0x448, 0x431, 0x3b, 0x421, 0x448, 0x431, 0x3b, 0x427, 0x448,
+0x431, 0x3b, 0x41f, 0x448, 0x431, 0x3b, 0x4b6, 0x43c, 0x44a, 0x3b, 0x428, 0x43d, 0x431, 0x3b, 0x42f, 0x43a, 0x448, 0x430, 0x43d, 0x431,
+0x435, 0x3b, 0x414, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x421, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x427, 0x43e,
+0x440, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x41f, 0x430, 0x43d, 0x4b7, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x4b6, 0x443, 0x43c,
+0x44a, 0x430, 0x3b, 0x428, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x42f, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x4b6,
+0x3b, 0x428, 0x3b, 0xb9e, 0xbbe, 0xbaf, 0xbbf, 0x2e, 0x3b, 0xba4, 0xbbf, 0xb99, 0xbcd, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbb5, 0xbcd, 0x2e,
+0x3b, 0xbaa, 0xbc1, 0xba4, 0x2e, 0x3b, 0xbb5, 0xbbf, 0xbaf, 0xbbe, 0x2e, 0x3b, 0xbb5, 0xbc6, 0xbb3, 0xbcd, 0x2e, 0x3b, 0xb9a, 0xba9,
+0xbbf, 0x3b, 0xb9e, 0xbbe, 0xbaf, 0xbbf, 0xbb1, 0xbc1, 0x3b, 0xba4, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b, 0xb9a, 0xbc6, 0xbb5,
+0xbcd, 0xbb5, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0xbaa, 0xbc1, 0xba4, 0xba9, 0xbcd, 0x3b, 0xbb5, 0xbbf, 0xbaf, 0xbbe, 0xbb4, 0xba9, 0xbcd, 0x3b,
+0xbb5, 0xbc6, 0xbb3, 0xbcd, 0xbb3, 0xbbf, 0x3b, 0xb9a, 0xba9, 0xbbf, 0x3b, 0xb9e, 0xbbe, 0x3b, 0xba4, 0xbbf, 0x3b, 0xb9a, 0xbc6, 0x3b,
+0xbaa, 0xbc1, 0x3b, 0xbb5, 0xbbf, 0x3b, 0xbb5, 0xbc6, 0x3b, 0xb9a, 0x3b, 0x44f, 0x43a, 0x448, 0x2e, 0x3b, 0x434, 0x4af, 0x448, 0x2e,
+0x3b, 0x441, 0x438, 0x448, 0x2e, 0x3b, 0x447, 0x4d9, 0x440, 0x2e, 0x3b, 0x43f, 0x4d9, 0x43d, 0x497, 0x2e, 0x3b, 0x497, 0x43e, 0x43c,
+0x2e, 0x3b, 0x448, 0x438, 0x43c, 0x2e, 0x3b, 0x44f, 0x43a, 0x448, 0x4d9, 0x43c, 0x431, 0x435, 0x3b, 0x434, 0x4af, 0x448, 0x4d9, 0x43c,
+0x431, 0x435, 0x3b, 0x441, 0x438, 0x448, 0x4d9, 0x43c, 0x431, 0x435, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43c, 0x431, 0x435, 0x3b,
+0x43f, 0x4d9, 0x43d, 0x497, 0x435, 0x448, 0x4d9, 0x43c, 0x431, 0x435, 0x3b, 0x497, 0x43e, 0x43c, 0x433, 0x430, 0x3b, 0x448, 0x438, 0x43c,
+0x431, 0x4d9, 0x3b, 0x42f, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x496, 0x3b, 0x428, 0x3b, 0xc06, 0xc26, 0xc3f,
+0x3b, 0xc38, 0xc4b, 0xc2e, 0x3b, 0xc2e, 0xc02, 0xc17, 0xc33, 0x3b, 0xc2c, 0xc41, 0xc27, 0x3b, 0xc17, 0xc41, 0xc30, 0xc41, 0x3b, 0xc36,
+0xc41, 0xc15, 0xc4d, 0xc30, 0x3b, 0xc36, 0xc28, 0xc3f, 0x3b, 0xc06, 0xc26, 0xc3f, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc38, 0xc4b, 0xc2e,
+0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc2e, 0xc02, 0xc17, 0xc33, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc2c, 0xc41, 0xc27, 0xc35, 0xc3e, 0xc30,
+0xc02, 0x3b, 0xc17, 0xc41, 0xc30, 0xc41, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d, 0xc30, 0xc35, 0xc3e, 0xc30, 0xc02,
+0x3b, 0xc36, 0xc28, 0xc3f, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc06, 0x3b, 0xc38, 0xc4b, 0x3b, 0xc2e, 0x3b, 0xc2c, 0xc41, 0x3b, 0xc17,
+0xc41, 0x3b, 0xc36, 0xc41, 0x3b, 0xc36, 0x3b, 0xe2d, 0xe32, 0x2e, 0x3b, 0xe08, 0x2e, 0x3b, 0xe2d, 0x2e, 0x3b, 0xe1e, 0x2e, 0x3b,
+0xe1e, 0xe24, 0x2e, 0x3b, 0xe28, 0x2e, 0x3b, 0xe2a, 0x2e, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe32, 0xe17, 0xe34, 0xe15, 0xe22, 0xe4c,
+0x3b, 0xe27, 0xe31, 0xe19, 0xe08, 0xe31, 0xe19, 0xe17, 0xe23, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe31, 0xe07, 0xe04, 0xe32, 0xe23,
+0x3b, 0xe27, 0xe31, 0xe19, 0xe1e, 0xe38, 0xe18, 0x3b, 0xe27, 0xe31, 0xe19, 0xe1e, 0xe24, 0xe2b, 0xe31, 0xe2a, 0xe1a, 0xe14, 0xe35, 0x3b,
+0xe27, 0xe31, 0xe19, 0xe28, 0xe38, 0xe01, 0xe23, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe40, 0xe2a, 0xe32, 0xe23, 0xe4c, 0x3b, 0xe2d, 0xe32,
+0x3b, 0xe08, 0x3b, 0xe2d, 0x3b, 0xe1e, 0x3b, 0xe1e, 0xe24, 0x3b, 0xe28, 0x3b, 0xe2a, 0x3b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54,
+0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a,
+0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f,
+0xf60, 0xf0b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b,
+0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53,
+0xf0b, 0xf54, 0xf0b, 0x3b, 0xf49, 0xf72, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf42, 0x3b, 0xf63, 0xfb7, 0xf42, 0x3b, 0xf55, 0xf74,
+0xf62, 0x3b, 0xf66, 0xf44, 0xf66, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0x1230, 0x1295, 0x3b, 0x1230, 0x1291, 0x3b, 0x1230, 0x1209, 0x3b,
+0x1228, 0x1261, 0x3b, 0x1213, 0x1219, 0x3b, 0x12d3, 0x122d, 0x3b, 0x1240, 0x12f3, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b, 0x1230, 0x1291, 0x12ed,
+0x3b, 0x1230, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1213, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d,
+0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1220, 0x3b, 0x1228, 0x3b, 0x1213, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b,
+0x1230, 0x1291, 0x12ed, 0x3b, 0x1220, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1283, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b,
+0x1240, 0x12f3, 0x121d, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1228, 0x3b, 0x1213, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x53, 0x101,
+0x70, 0x3b, 0x4d, 0x14d, 0x6e, 0x3b, 0x54, 0x16b, 0x73, 0x3b, 0x50, 0x75, 0x6c, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x3b, 0x46,
+0x61, 0x6c, 0x3b, 0x54, 0x6f, 0x6b, 0x3b, 0x53, 0x101, 0x70, 0x61, 0x74, 0x65, 0x3b, 0x4d, 0x14d, 0x6e, 0x69, 0x74, 0x65,
+0x3b, 0x54, 0x16b, 0x73, 0x69, 0x74, 0x65, 0x3b, 0x50, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x54, 0x75, 0x2bb,
+0x61, 0x70, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x46, 0x61, 0x6c, 0x61, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x6f,
+0x6b, 0x6f, 0x6e, 0x61, 0x6b, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x54,
+0x3b, 0x50, 0x61, 0x7a, 0x3b, 0x50, 0x7a, 0x74, 0x3b, 0x53, 0x61, 0x6c, 0x3b, 0xc7, 0x61, 0x72, 0x3b, 0x50, 0x65, 0x72,
+0x3b, 0x43, 0x75, 0x6d, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72,
+0x74, 0x65, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x6c, 0x131, 0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x50,
+0x65, 0x72, 0x15f, 0x65, 0x6d, 0x62, 0x65, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x72, 0x74, 0x65,
+0x73, 0x69, 0x3b, 0x50, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0xdd, 0x65, 0x6b,
+0x3b, 0x44, 0x75, 0x15f, 0x3b, 0x53, 0x69, 0x15f, 0x3b, 0xc7, 0x61, 0x72, 0x3b, 0x50, 0x65, 0x6e, 0x3b, 0x41, 0x6e, 0x6e,
+0x3b, 0x15e, 0x65, 0x6e, 0x3b, 0xdd, 0x65, 0x6b, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x44, 0x75, 0x15f, 0x65, 0x6e, 0x62,
+0x65, 0x3b, 0x53, 0x69, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x50,
+0x65, 0x6e, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x41, 0x6e, 0x6e, 0x61, 0x3b, 0x15e, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xdd,
+0x3b, 0x44, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, 0x41, 0x3b, 0x15e, 0x3b, 0xfd, 0x65, 0x6b, 0x3b, 0x64, 0x75, 0x15f,
+0x3b, 0x73, 0x69, 0x15f, 0x3b, 0xe7, 0x61, 0x72, 0x3b, 0x70, 0x65, 0x6e, 0x3b, 0x61, 0x6e, 0x6e, 0x3b, 0x15f, 0x65, 0x6e,
+0x3b, 0xfd, 0x65, 0x6b, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x64, 0x75, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x73, 0x69,
+0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xe7, 0x61, 0x72, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x70, 0x65, 0x6e, 0x15f, 0x65,
+0x6e, 0x62, 0x65, 0x3b, 0x61, 0x6e, 0x6e, 0x61, 0x3b, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x64a, 0x6d5, 0x3b, 0x62f, 0x6c8,
+0x3b, 0x633, 0x6d5, 0x3b, 0x686, 0x627, 0x3b, 0x67e, 0x6d5, 0x3b, 0x62c, 0x6c8, 0x3b, 0x634, 0x6d5, 0x3b, 0x64a, 0x6d5, 0x643, 0x634,
+0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x62f, 0x6c8, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x633, 0x6d5, 0x64a, 0x634, 0x6d5, 0x646, 0x628,
+0x6d5, 0x3b, 0x686, 0x627, 0x631, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x67e, 0x6d5, 0x64a, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b,
+0x62c, 0x6c8, 0x645, 0x6d5, 0x3b, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x64a, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e,
+0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x43e,
+0x43a, 0x3b, 0x432, 0x456, 0x432, 0x442, 0x43e, 0x440, 0x43e, 0x43a, 0x3b, 0x441, 0x435, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435,
+0x442, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x2bc, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x44f, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430,
+0x3b, 0x41d, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631,
+0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a,
+0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x59, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0x73, 0x68, 0x3b,
+0x53, 0x65, 0x73, 0x68, 0x3b, 0x43, 0x68, 0x6f, 0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x68,
+0x61, 0x6e, 0x3b, 0x79, 0x61, 0x6b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x64, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x62,
+0x61, 0x3b, 0x73, 0x65, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x63, 0x68, 0x6f, 0x72, 0x73, 0x68, 0x61, 0x6e, 0x62,
+0x61, 0x3b, 0x70, 0x61, 0x79, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x73, 0x68, 0x61,
+0x6e, 0x62, 0x61, 0x3b, 0x59, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x6cc, 0x2e,
+0x3b, 0x62f, 0x2e, 0x3b, 0x633, 0x2e, 0x3b, 0x686, 0x2e, 0x3b, 0x67e, 0x2e, 0x3b, 0x62c, 0x2e, 0x3b, 0x634, 0x2e, 0x3b, 0x42f,
+0x43a, 0x448, 0x3b, 0x414, 0x443, 0x448, 0x3b, 0x421, 0x435, 0x448, 0x3b, 0x427, 0x43e, 0x440, 0x3b, 0x41f, 0x430, 0x439, 0x3b, 0x416,
+0x443, 0x43c, 0x3b, 0x428, 0x430, 0x43d, 0x3b, 0x42f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x414, 0x443, 0x448, 0x430, 0x43d,
+0x431, 0x430, 0x3b, 0x421, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x427, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b,
+0x41f, 0x430, 0x439, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x416, 0x443, 0x43c, 0x430, 0x3b, 0x428, 0x430, 0x43d, 0x431, 0x430, 0x3b,
+0x42f, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x416, 0x3b, 0x428, 0x3b, 0x44f, 0x43a, 0x448, 0x3b, 0x434, 0x443,
+0x448, 0x3b, 0x441, 0x435, 0x448, 0x3b, 0x447, 0x43e, 0x440, 0x3b, 0x43f, 0x430, 0x439, 0x3b, 0x436, 0x443, 0x43c, 0x3b, 0x448, 0x430,
+0x43d, 0x3b, 0x44f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x434, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x441, 0x435,
+0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x447, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x43f, 0x430, 0x439, 0x448, 0x430,
+0x43d, 0x431, 0x430, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x68,
+0x20, 0x32, 0x3b, 0x54, 0x68, 0x20, 0x33, 0x3b, 0x54, 0x68, 0x20, 0x34, 0x3b, 0x54, 0x68, 0x20, 0x35, 0x3b, 0x54, 0x68,
+0x20, 0x36, 0x3b, 0x54, 0x68, 0x20, 0x37, 0x3b, 0x43, 0x68, 0x1ee7, 0x20, 0x4e, 0x68, 0x1ead, 0x74, 0x3b, 0x54, 0x68, 0x1ee9,
+0x20, 0x48, 0x61, 0x69, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42, 0x61, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x54, 0x1b0, 0x3b, 0x54,
+0x68, 0x1ee9, 0x20, 0x4e, 0x103, 0x6d, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x53, 0xe1, 0x75, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42,
+0x1ea3, 0x79, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x32, 0x3b, 0x54, 0x33, 0x3b, 0x54, 0x34, 0x3b, 0x54, 0x35, 0x3b, 0x54, 0x36,
+0x3b, 0x54, 0x37, 0x3b, 0x53, 0x75, 0x3b, 0x4d, 0x75, 0x3b, 0x54, 0x75, 0x3b, 0x56, 0x65, 0x3b, 0x44, 0xf6, 0x3b, 0x46,
+0x72, 0x3b, 0x5a, 0xe4, 0x3b, 0x73, 0x75, 0x64, 0x65, 0x6c, 0x3b, 0x6d, 0x75, 0x64, 0x65, 0x6c, 0x3b, 0x74, 0x75, 0x64,
+0x65, 0x6c, 0x3b, 0x76, 0x65, 0x64, 0x65, 0x6c, 0x3b, 0x64, 0xf6, 0x64, 0x65, 0x6c, 0x3b, 0x66, 0x72, 0x69, 0x64, 0x65,
+0x6c, 0x3b, 0x7a, 0xe4, 0x64, 0x65, 0x6c, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x56, 0x3b, 0x44, 0x3b, 0x46, 0x3b,
+0x5a, 0x3b, 0x73, 0x75, 0x2e, 0x3b, 0x6d, 0x75, 0x2e, 0x3b, 0x74, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x2e, 0x3b, 0x64, 0xf6,
+0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x7a, 0xe4, 0x2e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d,
+0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44,
+0x79, 0x64, 0x64, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x44, 0x79,
+0x64, 0x64, 0x20, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x65, 0x72, 0x63, 0x68,
+0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x49, 0x61, 0x75, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x47, 0x77, 0x65,
+0x6e, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, 0x61, 0x64, 0x77, 0x72, 0x6e, 0x3b, 0x53, 0x3b, 0x4c, 0x6c,
+0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b,
+0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b, 0x53, 0x61, 0x64,
+0x3b, 0x44, 0x69, 0x62, 0x3b, 0x41, 0x6c, 0x74, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0xc0, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x78,
+0x3b, 0xc0, 0x6a, 0x6a, 0x3b, 0x41, 0x73, 0x65, 0x3b, 0x44, 0x69, 0x62, 0xe9, 0x65, 0x72, 0x3b, 0x41, 0x6c, 0x74, 0x69,
+0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0xc0, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c,
+0x78, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0xc0, 0x6a, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x65, 0x65, 0x72, 0x3b, 0x5d6,
+0x5d5, 0x5e0, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5de, 0x5d0, 0x5b8, 0x5e0, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5d3, 0x5d9, 0x5e0, 0x5e1, 0x5d8, 0x5d9,
+0x5e7, 0x3b, 0x5de, 0x5d9, 0x5d8, 0x5d5, 0x5d5, 0x5d0, 0x5da, 0x3b, 0x5d3, 0x5d0, 0x5e0, 0x5e2, 0x5e8, 0x5e9, 0x5d8, 0x5d9, 0x5e7, 0x3b,
+0x5e4, 0x5bf, 0x5e8, 0x5f2, 0x5b7, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a,
+0xe9, 0x3b, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd,
+0x301, 0x62, 0x1ecd, 0x3b, 0x1eb8, 0x74, 0xec, 0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0x1ecc, 0x6a, 0x1ecd,
+0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301,
+0x20, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301,
+0x62, 0x1ecd, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x1eb8, 0x74, 0xec, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0x62, 0xe1,
+0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, 0xe9, 0x3b, 0xcc, 0x73, 0x25b, 0x301, 0x67,
+0x75, 0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x62, 0x254, 0x3b, 0x190, 0x74, 0xec,
+0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b,
+0x186, 0x6a, 0x254, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xcc, 0x73, 0x25b, 0x301, 0x67, 0x75,
+0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x62, 0x254, 0x3b, 0x186, 0x6a, 0x254, 0x301,
+0x20, 0x190, 0x74, 0xec, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xc0, 0x62, 0xe1, 0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x53,
+0x6f, 0x6e, 0x3b, 0x4d, 0x73, 0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48,
+0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x49, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x55, 0x4d, 0x73, 0x6f, 0x6d, 0x62,
+0x75, 0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x55, 0x4c, 0x77,
+0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x55,
+0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x55, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f,
+0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d,
+0xe5, 0x6e, 0x3b, 0x74, 0x79, 0x73, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c,
+0x61, 0x75, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x79, 0x73,
+0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66,
+0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0x61, 0x75, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d, 0xe5,
+0x2e, 0x3b, 0x74, 0x79, 0x2e, 0x3b, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x6c, 0x61,
+0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435,
+0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x458, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e,
+0x43d, 0x435, 0x434, 0x458, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458,
+0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441,
+0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x4a, 0x65, 0x64, 0x3b, 0x4a, 0x65, 0x6c, 0x3b, 0x4a, 0x65, 0x6d, 0x3b, 0x4a, 0x65,
+0x72, 0x63, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x3b, 0x4a, 0x65, 0x68, 0x3b, 0x4a, 0x65, 0x73, 0x3b, 0x4a, 0x65, 0x64, 0x6f,
+0x6f, 0x6e, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x6c, 0x68, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x6d, 0x61, 0x79, 0x72, 0x74,
+0x3b, 0x4a, 0x65, 0x72, 0x63, 0x65, 0x61, 0x6e, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x68,
+0x65, 0x69, 0x6e, 0x65, 0x79, 0x3b, 0x4a, 0x65, 0x73, 0x61, 0x72, 0x6e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e,
+0x3b, 0x4d, 0x74, 0x68, 0x3b, 0x4d, 0x68, 0x72, 0x3b, 0x59, 0x6f, 0x77, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64,
+0x3b, 0x64, 0x79, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x64, 0x79, 0x20, 0x4c, 0x75, 0x6e, 0x3b, 0x64, 0x79, 0x20, 0x4d, 0x65,
+0x75, 0x72, 0x74, 0x68, 0x3b, 0x64, 0x79, 0x20, 0x4d, 0x65, 0x72, 0x68, 0x65, 0x72, 0x3b, 0x64, 0x79, 0x20, 0x59, 0x6f,
+0x77, 0x3b, 0x64, 0x79, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x64, 0x79, 0x20, 0x53, 0x61, 0x64, 0x6f, 0x72,
+0x6e, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x44, 0x77, 0x6f, 0x3b, 0x42, 0x65, 0x6e, 0x3b, 0x57, 0x75, 0x6b, 0x3b, 0x59, 0x61,
+0x77, 0x3b, 0x46, 0x69, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x3b, 0x4b, 0x77, 0x65, 0x73, 0x69, 0x64, 0x61, 0x3b, 0x44, 0x77,
+0x6f, 0x77, 0x64, 0x61, 0x3b, 0x42, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x3b, 0x57, 0x75, 0x6b, 0x75, 0x64, 0x61, 0x3b, 0x59,
+0x61, 0x77, 0x64, 0x61, 0x3b, 0x46, 0x69, 0x64, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x65, 0x6e, 0x65, 0x64, 0x61, 0x3b, 0x4b,
+0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x906, 0x92f, 0x924, 0x93e, 0x930, 0x3b, 0x938,
+0x94b, 0x92e, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917,
+0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x93e, 0x930, 0x3b, 0x936, 0x947, 0x928, 0x935, 0x93e,
+0x930, 0x3b, 0x906, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x917, 0x941, 0x3b, 0x936, 0x941, 0x3b, 0x936,
+0x947, 0x3b, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd, 0x6e, 0x3b, 0x54, 0x69, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x3b, 0x54, 0x1ecd,
+0x1ecd, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4d, 0x62, 0x1ecd, 0x73, 0x1ecb, 0x20, 0x1ee4, 0x6b, 0x61,
+0x3b, 0x4d, 0x1ecd, 0x6e, 0x64, 0x65, 0x3b, 0x54, 0x69, 0x75, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x65, 0x6e, 0x65, 0x7a,
+0x64, 0x65, 0x65, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x64, 0x65, 0x65, 0x3b,
+0x53, 0x61, 0x74, 0x1ecd, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x6b, 0x79, 0x3b, 0x57, 0x6b, 0x77, 0x3b, 0x57, 0x6b, 0x6c, 0x3b,
+0x57, 0x74, 0x169, 0x3b, 0x57, 0x6b, 0x6e, 0x3b, 0x57, 0x74, 0x6e, 0x3b, 0x57, 0x74, 0x68, 0x3b, 0x57, 0x61, 0x20, 0x6b,
+0x79, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6d, 0x62, 0x129, 0x6c, 0x129, 0x6c, 0x79, 0x61,
+0x3b, 0x57, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x57,
+0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x57, 0x61, 0x20,
+0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x59, 0x3b, 0x57, 0x3b, 0x45, 0x3b, 0x41, 0x3b, 0x41, 0x3b,
+0x41, 0x3b, 0x41, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0x65, 0x3b,
+0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x65, 0x3b,
+0x6c, 0x75, 0x6e, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x61, 0x72, 0x73, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75,
+0x73, 0x3b, 0x6a, 0x6f, 0x69, 0x62, 0x65, 0x3b, 0x76, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x69, 0x64,
+0x65, 0x3b, 0x6b, 0x254, 0x73, 0x3b, 0x64, 0x7a, 0x6f, 0x3b, 0x62, 0x6c, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x3b, 0x79, 0x61,
+0x77, 0x3b, 0x66, 0x69, 0x256, 0x3b, 0x6d, 0x65, 0x6d, 0x3b, 0x6b, 0x254, 0x73, 0x69, 0x256, 0x61, 0x3b, 0x64, 0x7a, 0x6f,
+0x256, 0x61, 0x3b, 0x62, 0x6c, 0x61, 0x256, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x61, 0x3b, 0x79, 0x61, 0x77, 0x6f, 0x256, 0x61,
+0x3b, 0x66, 0x69, 0x256, 0x61, 0x3b, 0x6d, 0x65, 0x6d, 0x6c, 0x65, 0x256, 0x61, 0x3b, 0x6b, 0x3b, 0x64, 0x3b, 0x62, 0x3b,
+0x6b, 0x3b, 0x79, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x4c, 0x50, 0x3b, 0x50, 0x31, 0x3b, 0x50, 0x32, 0x3b, 0x50, 0x33, 0x3b,
+0x50, 0x34, 0x3b, 0x50, 0x35, 0x3b, 0x50, 0x36, 0x3b, 0x4c, 0x101, 0x70, 0x75, 0x6c, 0x65, 0x3b, 0x50, 0x6f, 0x2bb, 0x61,
+0x6b, 0x61, 0x68, 0x69, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x75, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x6f, 0x6c,
+0x75, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x68, 0x101, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x69, 0x6d, 0x61, 0x3b, 0x50, 0x6f,
+0x2bb, 0x61, 0x6f, 0x6e, 0x6f, 0x3b, 0x4c, 0x69, 0x6e, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69,
+0x79, 0x3b, 0x48, 0x75, 0x77, 0x3b, 0x42, 0x69, 0x79, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4c, 0x69, 0x6e, 0x67, 0x67, 0x6f,
+0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0x79, 0x65, 0x72, 0x6b,
+0x75, 0x6c, 0x65, 0x73, 0x3b, 0x48, 0x75, 0x77, 0x65, 0x62, 0x65, 0x73, 0x3b, 0x42, 0x69, 0x79, 0x65, 0x72, 0x6e, 0x65,
+0x73, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0xe4, 0x2e, 0x3b, 0x5a, 0x69, 0x2e,
+0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e,
+0x6e, 0x74, 0x69, 0x67, 0x3b, 0x4d, 0xe4, 0xe4, 0x6e, 0x74, 0x69, 0x67, 0x3b, 0x5a, 0x69, 0x69, 0x73, 0x63, 0x68, 0x74,
+0x69, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x75, 0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x73, 0x63, 0x68, 0x74, 0x69,
+0x67, 0x3b, 0x46, 0x72, 0x69, 0x69, 0x74, 0x69, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b,
+0xa46d, 0xa18f, 0x3b, 0xa18f, 0xa2cd, 0x3b, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa315, 0x3b, 0xa18f, 0xa1d6, 0x3b, 0xa18f, 0xa26c, 0x3b, 0xa18f, 0xa0d8,
+0x3b, 0xa46d, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa2cd, 0x3b, 0xa18f, 0xa282, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa315, 0x3b, 0xa18f, 0xa282, 0xa1d6,
+0x3b, 0xa18f, 0xa282, 0xa26c, 0x3b, 0xa18f, 0xa282, 0xa0d8, 0x3b, 0xa18f, 0x3b, 0xa2cd, 0x3b, 0xa44d, 0x3b, 0xa315, 0x3b, 0xa1d6, 0x3b, 0xa26c,
+0x3b, 0xa0d8, 0x3b, 0x53, 0xfc, 0x2e, 0x3b, 0x4d, 0x61, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44,
+0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0xfc, 0x6e, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x4d,
+0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x6e, 0x67, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x64, 0x64,
+0x65, 0x77, 0x65, 0x6b, 0x65, 0x6e, 0x3b, 0x44, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x46, 0x72,
+0x65, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x53, 0xfc, 0x6e, 0x6e, 0x61, 0x76, 0x65, 0x6e, 0x64, 0x3b, 0x73, 0x6f, 0x74, 0x6e,
+0x3b, 0x76, 0x75, 0x6f, 0x73, 0x3b, 0x6d, 0x61, 0x14b, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x3b,
+0x62, 0x65, 0x61, 0x72, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x73, 0x6f, 0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69,
+0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0xe1, 0x72, 0x67, 0x61, 0x3b, 0x6d, 0x61, 0x14b, 0x14b, 0x65, 0x62, 0xe1, 0x72, 0x67,
+0x61, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x6b, 0x75, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x61, 0x73,
+0x64, 0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x74, 0x3b, 0x6c, 0xe1, 0x76, 0x76, 0x61, 0x72,
+0x64, 0x61, 0x74, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x73, 0x6f,
+0x3b, 0x6d, 0xe1, 0x3b, 0x64, 0x69, 0x3b, 0x67, 0x61, 0x3b, 0x64, 0x75, 0x3b, 0x62, 0x65, 0x3b, 0x6c, 0xe1, 0x3b, 0x73,
+0x6f, 0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69, 0x3b, 0x6d, 0xe1, 0x6e, 0x6e, 0x6f, 0x64, 0x61, 0x74, 0x3b,
+0x64, 0x69, 0x73, 0x64, 0x61, 0x74, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x6b, 0x75, 0x3b, 0x64,
+0x75, 0x6f, 0x72, 0x61, 0x73, 0x74, 0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x74, 0x3b, 0x6c,
+0xe1, 0x76, 0x76, 0x6f, 0x72, 0x64, 0x61, 0x74, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42,
+0x3b, 0x4c, 0x3b, 0x43, 0x70, 0x72, 0x3b, 0x43, 0x74, 0x74, 0x3b, 0x43, 0x6d, 0x6e, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x41,
+0x72, 0x73, 0x3b, 0x49, 0x63, 0x6d, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69,
+0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b,
+0x43, 0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x63,
+0x68, 0x75, 0x6d, 0x61, 0x3b, 0x45, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43,
+0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x45, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b,
+0x61, 0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x49, 0x74, 0x75, 0x6b, 0x75,
+0x20, 0x6a, 0x61, 0x20, 0x6a, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6a,
+0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69,
+0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x75, 0x72,
+0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20,
+0x6b, 0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x69, 0x66, 0x75, 0x6c, 0x61, 0x20, 0x6e, 0x67, 0x75, 0x77, 0x6f, 0x3b,
+0x4a, 0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x64, 0x65, 0x77, 0x3b, 0x61, 0x61,
+0x253, 0x3b, 0x6d, 0x61, 0x77, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x3b, 0x6d, 0x77, 0x64, 0x3b, 0x68, 0x62,
+0x69, 0x3b, 0x64, 0x65, 0x77, 0x6f, 0x3b, 0x61, 0x61, 0x253, 0x6e, 0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x62, 0x61, 0x61,
+0x72, 0x65, 0x3b, 0x6e, 0x6a, 0x65, 0x73, 0x6c, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x73, 0x61, 0x61, 0x6e,
+0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x6e, 0x64, 0x65, 0x3b, 0x68, 0x6f, 0x6f, 0x72, 0x65, 0x2d, 0x62, 0x69, 0x69, 0x72,
+0x3b, 0x64, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x4b, 0x4d, 0x41, 0x3b, 0x4e,
+0x54, 0x54, 0x3b, 0x4e, 0x4d, 0x4e, 0x3b, 0x4e, 0x4d, 0x54, 0x3b, 0x41, 0x52, 0x54, 0x3b, 0x4e, 0x4d, 0x41, 0x3b, 0x4e,
+0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b,
+0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x61, 0x3b, 0x41,
+0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61,
+0x6d, 0x6f, 0x74, 0x68, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b,
+0x41, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x6e, 0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b,
+0x53, 0x61, 0x70, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x61, 0x72,
+0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4d, 0x64, 0x65,
+0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f,
+0x74, 0x20, 0x65, 0x65, 0x20, 0x69, 0x6e, 0x65, 0x74, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20,
+0x69, 0x6c, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4d,
+0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x77, 0x65, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x4f, 0x3b, 0x49,
+0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x50, 0x6f, 0x73, 0x3b, 0x50, 0x69, 0x72, 0x3b, 0x54,
+0x61, 0x74, 0x3b, 0x4e, 0x61, 0x69, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x69, 0x6e,
+0x67, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x6f, 0x73, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43,
+0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61,
+0x6e, 0x75, 0x3b, 0x53, 0x61, 0x62, 0x75, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b,
+0x53, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x53, 0x69, 0x74, 0x3b,
+0x53, 0x69, 0x6e, 0x3b, 0x53, 0x69, 0x68, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x4d, 0x76,
+0x75, 0x6c, 0x6f, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x53, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b,
+0x53, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c,
+0x6f, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x49, 0x6a, 0x70, 0x3b,
+0x49, 0x6a, 0x74, 0x3b, 0x49, 0x6a, 0x6e, 0x3b, 0x49, 0x6a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75,
+0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61,
+0x74, 0x61, 0x74, 0x75, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x74,
+0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b,
+0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b,
+0x37, 0x3b, 0x31, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x3b,
+0x2d30, 0x2d3d, 0x2d61, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59,
+0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b,
+0x2d30, 0x2d3d, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59,
+0x3b, 0x61, 0x73, 0x61, 0x3b, 0x61, 0x79, 0x6e, 0x3b, 0x61, 0x73, 0x69, 0x3b, 0x61, 0x6b, 0x1e5b, 0x3b, 0x61, 0x6b, 0x77,
+0x3b, 0x61, 0x73, 0x69, 0x6d, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x3b, 0x61, 0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, 0x61, 0x79,
+0x6e, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x1e5b, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x77,
+0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, 0x3b, 0x41,
+0x63, 0x65, 0x3b, 0x41, 0x72, 0x69, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x41, 0x68, 0x61, 0x3b, 0x41, 0x6d, 0x68, 0x3b, 0x53,
+0x65, 0x6d, 0x3b, 0x53, 0x65, 0x64, 0x3b, 0x41, 0x63, 0x65, 0x72, 0x3b, 0x41, 0x72, 0x69, 0x6d, 0x3b, 0x41, 0x72, 0x61,
+0x6d, 0x3b, 0x41, 0x68, 0x61, 0x64, 0x3b, 0x41, 0x6d, 0x68, 0x61, 0x64, 0x3b, 0x53, 0x65, 0x6d, 0x3b, 0x53, 0x65, 0x64,
+0x3b, 0x59, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x59, 0x61, 0x6e, 0x3b, 0x53,
+0x61, 0x6e, 0x3b, 0x4b, 0x72, 0x61, 0x1e0d, 0x3b, 0x4b, 0x75, 0x1e93, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x1e0d, 0x69, 0x73,
+0x3b, 0x53, 0x61, 0x79, 0x3b, 0x59, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x4b,
+0x72, 0x61, 0x1e0d, 0x61, 0x73, 0x73, 0x3b, 0x4b, 0x75, 0x1e93, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x61, 0x73, 0x73,
+0x3b, 0x53, 0x1e0d, 0x69, 0x73, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x79, 0x61, 0x73, 0x73, 0x3b, 0x43, 0x3b, 0x52, 0x3b,
+0x41, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x53, 0x41, 0x4e, 0x3b, 0x4f, 0x52, 0x4b, 0x3b, 0x4f, 0x4b,
+0x42, 0x3b, 0x4f, 0x4b, 0x53, 0x3b, 0x4f, 0x4b, 0x4e, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4f, 0x4d, 0x4b, 0x3b, 0x53, 0x61,
+0x6e, 0x64, 0x65, 0x3b, 0x4f, 0x72, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61,
+0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f,
+0x72, 0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x6f, 0x3b,
+0x4f, 0x72, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x52, 0x3b, 0x53, 0x3b,
+0x4e, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x48, 0x69, 0x76, 0x3b, 0x48, 0x69,
+0x64, 0x3b, 0x48, 0x69, 0x74, 0x3b, 0x48, 0x69, 0x68, 0x3b, 0x4c, 0x65, 0x6d, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x75, 0x6c,
+0x75, 0x6e, 0x67, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x76, 0x69, 0x6c, 0x75, 0x68, 0x61, 0x3b,
+0x70, 0x61, 0x20, 0x68, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x64, 0x61, 0x74, 0x75, 0x3b,
+0x70, 0x61, 0x20, 0x68, 0x69, 0x74, 0x61, 0x79, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x68, 0x61, 0x6e, 0x75, 0x3b,
+0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x6c, 0x65, 0x6d, 0x62, 0x65, 0x6c, 0x61, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b,
+0x48, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e,
+0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75,
+0x6d, 0x61, 0x70, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x75, 0x3b, 0x4a, 0x75,
+0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d,
+0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b,
+0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x6b, 0x61, 0x72, 0x3b, 0x6e, 0x74,
+0x25b, 0x3b, 0x74, 0x61, 0x72, 0x3b, 0x61, 0x72, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x3b, 0x73, 0x69,
+0x62, 0x3b, 0x6b, 0x61, 0x72, 0x69, 0x3b, 0x6e, 0x74, 0x25b, 0x6e, 0x25b, 0x3b, 0x74, 0x61, 0x72, 0x61, 0x74, 0x61, 0x3b,
+0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x73,
+0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x4a, 0x3b, 0x53, 0x3b,
+0x4b, 0x6d, 0x61, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6e, 0x3b, 0x41, 0x72, 0x6d, 0x3b,
+0x4d, 0x61, 0x61, 0x3b, 0x4e, 0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61,
+0x74, 0x61, 0x74, 0x75, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74,
+0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b,
+0x4e, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x74, 0x68, 0x69, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b,
+0x41, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x13c6, 0x13cd, 0x13ac, 0x3b, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x3b, 0x13e6, 0x13a2,
+0x13c1, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x3b, 0x13c8, 0x13d5, 0x13be, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c6, 0x13cd,
+0x13ac, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e6, 0x13a2, 0x13c1, 0x13a2,
+0x13a6, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x13b6, 0x13cd, 0x13d7, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c8,
+0x13d5, 0x13be, 0x3b, 0x13c6, 0x3b, 0x13c9, 0x3b, 0x13d4, 0x3b, 0x13e6, 0x3b, 0x13c5, 0x3b, 0x13e7, 0x3b, 0x13a4, 0x3b, 0x64, 0x69, 0x6d,
+0x3b, 0x6c, 0x69, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x7a, 0x65, 0x3b, 0x76, 0x61, 0x6e, 0x3b,
+0x73, 0x61, 0x6d, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x73, 0x3b, 0x6c, 0x69, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72,
+0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x6b, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x7a, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, 0x6e,
+0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0x69, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b,
+0x7a, 0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4c, 0x6c, 0x32, 0x3b, 0x4c, 0x6c, 0x33, 0x3b, 0x4c, 0x6c, 0x34, 0x3b, 0x4c, 0x6c,
+0x35, 0x3b, 0x4c, 0x6c, 0x36, 0x3b, 0x4c, 0x6c, 0x37, 0x3b, 0x4c, 0x6c, 0x31, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61,
+0x20, 0x6c, 0x79, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x74,
+0x61, 0x74, 0x75, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x63, 0x68,
+0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4c,
+0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6c,
+0x69, 0x6e, 0x6a, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e,
+0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c,
+0x69, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x50, 0xed, 0x69, 0x6c, 0x69, 0x3b, 0x54, 0xe1, 0x61, 0x74, 0x75, 0x3b, 0xcd,
+0x6e, 0x65, 0x3b, 0x54, 0xe1, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4d, 0xf3, 0x6f,
+0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74,
+0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0xed, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x61, 0x6e, 0x6f, 0x3b,
+0x41, 0x6c, 0x61, 0x6d, 0xed, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0xe1, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
+0x6d, 0xf3, 0x6f, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4d, 0x3b,
+0x53, 0x61, 0x62, 0x3b, 0x42, 0x61, 0x6c, 0x3b, 0x4c, 0x77, 0x32, 0x3b, 0x4c, 0x77, 0x33, 0x3b, 0x4c, 0x77, 0x34, 0x3b,
+0x4c, 0x77, 0x35, 0x3b, 0x4c, 0x77, 0x36, 0x3b, 0x53, 0x61, 0x62, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c,
+0x61, 0x7a, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x73,
+0x61, 0x74, 0x75, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x74, 0x61, 0x61,
+0x6e, 0x6f, 0x3b, 0x4c, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x4c, 0x3b,
+0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x50, 0x61, 0x20, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x50,
+0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x6d, 0x6f, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x62, 0x75, 0x6c, 0x69,
+0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69,
+0x6e, 0x65, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x6f, 0x3b, 0x50, 0x61, 0x63, 0x68, 0x69,
+0x62, 0x65, 0x6c, 0x75, 0x73, 0x68, 0x69, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x73, 0x69, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b,
+0x6b, 0x75, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x3b, 0x73, 0x65, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x75, 0x6d, 0x69,
+0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72,
+0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b,
+0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72,
+0x61, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x53,
+0x3b, 0x53, 0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66,
+0x65, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74,
+0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65,
+0x73, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x49, 0x55, 0x3b,
+0x4d, 0x52, 0x41, 0x3b, 0x57, 0x41, 0x49, 0x3b, 0x57, 0x45, 0x54, 0x3b, 0x57, 0x45, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b,
+0x4a, 0x55, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4d, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x6f, 0x3b,
+0x57, 0x61, 0x69, 0x72, 0x69, 0x3b, 0x57, 0x65, 0x74, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x61, 0x3b, 0x57,
+0x65, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57,
+0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4b, 0x74, 0x73, 0x3b, 0x4b, 0x6f, 0x74, 0x3b, 0x4b, 0x6f, 0x6f,
+0x3b, 0x4b, 0x6f, 0x73, 0x3b, 0x4b, 0x6f, 0x61, 0x3b, 0x4b, 0x6f, 0x6d, 0x3b, 0x4b, 0x6f, 0x6c, 0x3b, 0x4b, 0x6f, 0x74,
+0x69, 0x73, 0x61, 0x70, 0x3b, 0x4b, 0x6f, 0x74, 0x61, 0x61, 0x69, 0x3b, 0x4b, 0x6f, 0x61, 0x65, 0x6e, 0x67, 0x2019, 0x3b,
+0x4b, 0x6f, 0x73, 0x6f, 0x6d, 0x6f, 0x6b, 0x3b, 0x4b, 0x6f, 0x61, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4b, 0x6f,
+0x6d, 0x75, 0x75, 0x74, 0x3b, 0x4b, 0x6f, 0x6c, 0x6f, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x41, 0x3b,
+0x4d, 0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x61, 0x3b, 0x44, 0x65, 0x3b, 0x57, 0x75, 0x3b, 0x44, 0x6f, 0x3b,
+0x46, 0x72, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x4d,
+0x61, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x65, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73,
+0x65, 0x65, 0x73, 0x3b, 0x57, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x6f, 0x6e,
+0x64, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x46, 0x72, 0x61, 0x69, 0x74, 0x61, 0x78, 0x74,
+0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x74, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x53,
+0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e,
+0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x65, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e,
+0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x6f, 0x68, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68,
+0x3b, 0x44, 0x69, 0x6e, 0x6e, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x65, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b,
+0x44, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x46, 0x72, 0x69, 0x69, 0x64, 0x61, 0x61,
+0x63, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x6c,
+0xed, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75,
+0x6d, 0x61, 0x74, 0xe1, 0x6e, 0x254, 0x3b, 0x41, 0x6c, 0x61, 0xe1, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0xe1,
+0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0xf3, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61,
+0x3b, 0x4b, 0x75, 0x62, 0x69, 0x3b, 0x4b, 0x75, 0x73, 0x61, 0x3b, 0x4b, 0x75, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x74, 0x61,
+0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x7a, 0x61,
+0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x73, 0x61, 0x74, 0x75,
+0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x74, 0x61, 0x61, 0x6e, 0x75, 0x3b,
+0x4f, 0x6c, 0x6f, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x42, 0x3b, 0x53, 0x3b, 0x4b,
+0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x4a, 0x32, 0x3b, 0x4a, 0x33, 0x3b, 0x4a, 0x34, 0x3b, 0x4a, 0x35, 0x3b, 0x41, 0x6c, 0x3b,
+0x49, 0x6a, 0x3b, 0x4a, 0x31, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74,
0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f,
-0x3b, 0x41, 0x72, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75,
-0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a,
-0x3b, 0x43, 0x79, 0x61, 0x3b, 0x43, 0x6c, 0x61, 0x3b, 0x43, 0x7a, 0x69, 0x3b, 0x43, 0x6b, 0x6f, 0x3b, 0x43, 0x6b, 0x61,
-0x3b, 0x43, 0x67, 0x61, 0x3b, 0x43, 0x7a, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x2019, 0x79, 0x61, 0x6b, 0x6b, 0x65, 0x3b, 0x43,
-0x6f, 0x6d, 0x6c, 0x61, 0x61, 0x257, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x7a, 0x79, 0x69, 0x69, 0x257, 0x69, 0x69, 0x3b,
-0x43, 0x6f, 0x6d, 0x6b, 0x6f, 0x6c, 0x6c, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x6b, 0x61, 0x6c, 0x64, 0x1dd, 0x253, 0x6c, 0x69,
-0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x67, 0x61, 0x69, 0x73, 0x75, 0x75, 0x3b, 0x43, 0x6f, 0x6d, 0x7a, 0x79, 0x65, 0x253, 0x73,
-0x75, 0x75, 0x3b, 0x59, 0x3b, 0x4c, 0x3b, 0x5a, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x47, 0x3b, 0x45, 0x3b, 0x73, 0x254, 0x301,
-0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, 0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x6d,
-0x62, 0x73, 0x3b, 0x73, 0x61, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x254,
-0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x62, 0x61, 0x3b, 0x73, 0x254,
-0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x6c, 0x61, 0x6c, 0x3b, 0x73, 0x254, 0x301, 0x6e,
-0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x62, 0xe1, 0x67, 0xe1, 0x20,
-0x6d, 0xe1, 0x20, 0x73, 0x75, 0x6b, 0x75, 0x6c, 0x3b, 0x73, 0xe1, 0x73, 0x61, 0x64, 0x69, 0x3b, 0x73, 0x3b, 0x6d, 0x3b,
-0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x43, 0xe4, 0x14b, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x3b, 0x52,
-0x25b, 0x77, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x3b, 0x14a, 0x75, 0x61, 0x61, 0x6e, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65,
-0x63, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x3b, 0x43, 0xe4, 0x14b, 0x20, 0x6b, 0x75, 0x254, 0x74, 0x68, 0x3b, 0x4a, 0x69,
-0x65, 0x63, 0x20, 0x6c, 0x61, 0x331, 0x74, 0x3b, 0x52, 0x25b, 0x77, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44, 0x69,
-0x254, 0x331, 0x6b, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x14a, 0x75, 0x61, 0x61, 0x6e, 0x20, 0x6c, 0xe4, 0x74, 0x6e,
-0x69, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c,
-0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x43, 0x3b, 0x4a, 0x3b, 0x52, 0x3b, 0x44, 0x3b, 0x14a, 0x3b, 0x44, 0x3b, 0x42,
-0x3b, 0x431, 0x441, 0x3b, 0x431, 0x43d, 0x3b, 0x43e, 0x43f, 0x3b, 0x441, 0x44d, 0x3b, 0x447, 0x43f, 0x3b, 0x431, 0x44d, 0x3b, 0x441,
-0x431, 0x3b, 0x431, 0x430, 0x441, 0x43a, 0x44b, 0x4bb, 0x44b, 0x430, 0x43d, 0x43d, 0x44c, 0x430, 0x3b, 0x431, 0x44d, 0x43d, 0x438, 0x434,
-0x438, 0x44d, 0x43d, 0x43d, 0x44c, 0x438, 0x43a, 0x3b, 0x43e, 0x43f, 0x442, 0x443, 0x43e, 0x440, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x43a,
-0x3b, 0x441, 0x44d, 0x440, 0x44d, 0x434, 0x44d, 0x3b, 0x447, 0x44d, 0x43f, 0x43f, 0x438, 0x44d, 0x440, 0x3b, 0x411, 0x44d, 0x44d, 0x442,
-0x438, 0x4a5, 0x441, 0x44d, 0x3b, 0x441, 0x443, 0x431, 0x443, 0x43e, 0x442, 0x430, 0x3b, 0x411, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x421,
-0x3b, 0x427, 0x3b, 0x411, 0x3b, 0x421, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a,
-0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4d, 0x75, 0x6c, 0x75, 0x6e,
-0x67, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b,
-0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49,
-0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a,
-0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0xa55e, 0xa54c, 0xa535, 0x3b, 0xa5f3, 0xa5e1, 0xa609, 0x3b, 0xa55a, 0xa55e, 0xa55a,
-0x3b, 0xa549, 0xa55e, 0xa552, 0x3b, 0xa549, 0xa524, 0xa546, 0xa562, 0x3b, 0xa549, 0xa524, 0xa540, 0xa56e, 0x3b, 0xa53b, 0xa52c, 0xa533, 0x3b, 0x6c,
-0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x74, 0x25b, 0x25b, 0x6e, 0x25b, 0x25b, 0x3b, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b,
-0x61, 0x6c, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x69, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x61, 0x69, 0x6a, 0x69, 0x6d, 0x61, 0x3b,
-0x73, 0x69, 0x253, 0x69, 0x74, 0x69, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x4d, 0xe4, 0x6e, 0x3b, 0x5a, 0x69, 0x161, 0x3b, 0x4d,
-0x69, 0x74, 0x3b, 0x46, 0x72, 0xf3, 0x3b, 0x46, 0x72, 0x69, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x74,
-0x61, 0x67, 0x3b, 0x4d, 0xe4, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x5a, 0x69, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x74,
-0x74, 0x77, 0x75, 0x10d, 0x3b, 0x46, 0x72, 0xf3, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x69, 0x74, 0x61, 0x67, 0x3b,
-0x53, 0x61, 0x6d, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b,
-0x53, 0x3b, 0x73, 0x64, 0x3b, 0x6d, 0x64, 0x3b, 0x6d, 0x77, 0x3b, 0x65, 0x74, 0x3b, 0x6b, 0x6c, 0x3b, 0x66, 0x6c, 0x3b,
-0x73, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x25b, 0x3b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, 0x3b, 0x6d, 0x75,
-0xe1, 0x6e, 0x79, 0xe1, 0x14b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, 0x3b, 0x6d, 0x65, 0x74, 0xfa, 0x6b, 0x70, 0xed, 0xe1,
-0x70, 0x25b, 0x3b, 0x6b, 0xfa, 0x70, 0xe9, 0x6c, 0x69, 0x6d, 0x65, 0x74, 0xfa, 0x6b, 0x70, 0x69, 0x61, 0x70, 0x25b, 0x3b,
-0x66, 0x65, 0x6c, 0xe9, 0x74, 0x65, 0x3b, 0x73, 0xe9, 0x73, 0x65, 0x6c, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b,
-0x65, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x3b,
-0x6d, 0x69, 0xe9, 0x3b, 0x78, 0x75, 0x65, 0x3b, 0x76, 0x69, 0x65, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69,
-0x6e, 0x67, 0x75, 0x3b, 0x6c, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69,
-0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x78, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x6e, 0x72,
-0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x53, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x254, 0x301,
-0x6e, 0x64, 0x69, 0x3b, 0xc1, 0x70, 0x74, 0x61, 0x20, 0x4d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x57, 0x25b, 0x301, 0x6e,
-0x25b, 0x73, 0x25b, 0x64, 0x25b, 0x3b, 0x54, 0x254, 0x301, 0x73, 0x25b, 0x64, 0x25b, 0x3b, 0x46, 0x25b, 0x6c, 0xe2, 0x79, 0x25b,
-0x64, 0x25b, 0x3b, 0x53, 0xe1, 0x73, 0x69, 0x64, 0x25b, 0x3b, 0x53, 0x254, 0x301, 0x3b, 0x4d, 0x254, 0x301, 0x3b, 0xc1, 0x4d,
-0x3b, 0x57, 0x25b, 0x301, 0x3b, 0x54, 0x254, 0x301, 0x3b, 0x46, 0x25b, 0x3b, 0x53, 0xe1, 0x3b, 0x73, 0x254, 0x6e, 0x64, 0x69,
-0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x25b, 0x72, 0x6b, 0x25b, 0x72, 0x25b,
-0x64, 0x69, 0x3b, 0x79, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, 0x14b, 0x64, 0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x6d, 0x254,
-0x6e, 0x254, 0x20, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x25b,
-0x3b, 0x79, 0x65, 0x3b, 0x76, 0x61, 0x3b, 0x6d, 0x73, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x31, 0x3b, 0x41, 0x6e, 0x65,
-0x67, 0x20, 0x32, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x33, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x34, 0x3b, 0x41, 0x6e,
-0x65, 0x67, 0x20, 0x35, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x36, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x37, 0x3b, 0x41,
-0x31, 0x3b, 0x41, 0x32, 0x3b, 0x41, 0x33, 0x3b, 0x41, 0x34, 0x3b, 0x41, 0x35, 0x3b, 0x41, 0x36, 0x3b, 0x41, 0x37, 0x3b,
-0x6c, 0x79, 0x25b, 0x2bc, 0x25b, 0x301, 0x20, 0x73, 0x1e85, 0xed, 0x14b, 0x74, 0xe8, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c,
-0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c,
-0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x74, 0x73, 0xe8, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b,
-0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79,
-0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6d, 0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b,
-0x6d, 0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x77, 0x61, 0x6b,
-0x21f, 0x61, 0x14b, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x77, 0x61, 0x14b, 0x17e, 0x69, 0x3b, 0x41, 0x14b, 0x70, 0xe9,
-0x74, 0x75, 0x6e, 0x75, 0x14b, 0x70, 0x61, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x79, 0x61, 0x6d, 0x6e, 0x69, 0x3b,
-0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x74, 0x6f, 0x70, 0x61, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x7a, 0x61, 0x70,
-0x74, 0x61, 0x14b, 0x3b, 0x4f, 0x77, 0xe1, 0x14b, 0x67, 0x79, 0x75, 0x17e, 0x61, 0x17e, 0x61, 0x70, 0x69, 0x3b, 0x41, 0x3b,
-0x57, 0x3b, 0x4e, 0x3b, 0x59, 0x3b, 0x54, 0x3b, 0x5a, 0x3b, 0x4f, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, 0x3b, 0x2d30,
-0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d,
-0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, 0x3b,
-0x6cc, 0x6d5, 0x6a9, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x62f, 0x648, 0x648, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x633, 0x6ce,
-0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x686, 0x648, 0x627, 0x631, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x67e, 0x6ce, 0x646, 0x62c,
-0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x6be, 0x6d5, 0x6cc, 0x646, 0x6cc, 0x3b, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x6cc, 0x3b,
-0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x6be, 0x3b, 0x634, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x70, 0xf3, 0x6e, 0x3b,
-0x77, 0x61, 0x142, 0x3b, 0x73, 0x72, 0x6a, 0x3b, 0x73, 0x74, 0x77, 0x3b, 0x70, 0x11b, 0x74, 0x3b, 0x73, 0x6f, 0x62, 0x3b,
-0x6e, 0x6a, 0x65, 0x17a, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0xf3, 0x6e, 0x6a, 0x65, 0x17a, 0x65, 0x6c, 0x65, 0x3b, 0x77, 0x61,
-0x142, 0x74, 0x6f, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x6a, 0x6f, 0x64, 0x61, 0x3b, 0x73, 0x74, 0x77, 0xf3, 0x72, 0x74, 0x6b,
-0x3b, 0x70, 0x11b, 0x74, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x73,
-0x3b, 0x73, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x70, 0xf3, 0x6e, 0x3b, 0x77, 0x75, 0x74, 0x3b, 0x73,
-0x72, 0x6a, 0x3b, 0x161, 0x74, 0x77, 0x3b, 0x70, 0x6a, 0x61, 0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x6a, 0x65, 0x64, 0x17a,
-0x65, 0x6c, 0x61, 0x3b, 0x70, 0xf3, 0x6e, 0x64, 0x17a, 0x65, 0x6c, 0x61, 0x3b, 0x77, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x3b,
-0x73, 0x72, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, 0x77, 0xf3, 0x72, 0x74, 0x6b, 0x3b, 0x70, 0x6a, 0x61, 0x74, 0x6b,
-0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x73, 0x3b, 0x161, 0x3b, 0x70, 0x3b,
-0x73, 0x3b, 0x70, 0x61, 0x73, 0x3b, 0x76, 0x75, 0x6f, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6b, 0x6f, 0x73, 0x3b, 0x74, 0x75,
-0x6f, 0x3b, 0x76, 0xe1, 0x73, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x70, 0x61, 0x73, 0x65, 0x70, 0x65, 0x69, 0x76, 0x69, 0x3b,
-0x76, 0x75, 0x6f, 0x73, 0x73, 0x61, 0x72, 0x67, 0xe2, 0x3b, 0x6d, 0x61, 0x6a, 0x65, 0x62, 0x61, 0x72, 0x67, 0xe2, 0x3b,
-0x6b, 0x6f, 0x73, 0x6b, 0x6f, 0x6b, 0x6b, 0x6f, 0x3b, 0x74, 0x75, 0x6f, 0x72, 0xe2, 0x73, 0x74, 0xe2, 0x68, 0x3b, 0x76,
-0xe1, 0x73, 0x74, 0x75, 0x70, 0x70, 0x65, 0x69, 0x76, 0x69, 0x3b, 0x6c, 0xe1, 0x76, 0x75, 0x72, 0x64, 0xe2, 0x68, 0x3b,
-0x70, 0x61, 0x73, 0x65, 0x70, 0x65, 0x65, 0x69, 0x76, 0x69, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0x61, 0x61, 0x72, 0x67,
-0xe2, 0x3b, 0x6d, 0x61, 0x6a, 0x65, 0x62, 0x61, 0x61, 0x72, 0x67, 0xe2, 0x3b, 0x6b, 0x6f, 0x73, 0x6b, 0x6f, 0x68, 0x6f,
-0x3b, 0x74, 0x75, 0x6f, 0x72, 0xe2, 0x73, 0x74, 0x75, 0x76, 0x3b, 0x76, 0xe1, 0x73, 0x74, 0x75, 0x70, 0x70, 0x65, 0x65,
-0x69, 0x76, 0x69, 0x3b, 0x6c, 0xe1, 0x76, 0x75, 0x72, 0x64, 0x75, 0x76, 0x3b, 0x70, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x4b,
-0x3b, 0x54, 0x3b, 0x56, 0x3b, 0x4c, 0x3b
+0x3b, 0x4d, 0x75, 0x72, 0x77, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4d, 0x75, 0x72, 0x77,
+0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69,
+0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68,
+0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x42, 0x61, 0x72, 0x3b, 0x41, 0x61, 0x72,
+0x3b, 0x55, 0x6e, 0x69, 0x3b, 0x55, 0x6e, 0x67, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6b,
+0x61, 0x65, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x65, 0x62, 0x61, 0x72, 0x61, 0x73, 0x61, 0x3b, 0x4e,
+0x61, 0x6b, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75,
+0x6e, 0x67, 0x2019, 0x6f, 0x6e, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x6b, 0x61, 0x6e, 0x79, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x73,
+0x61, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x4a, 0x3b, 0x42, 0x3b, 0x41, 0x3b, 0x55, 0x3b, 0x55, 0x3b, 0x4b, 0x3b, 0x53, 0x3b,
+0x41, 0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b,
+0x41, 0x6c, 0x6a, 0x3b, 0x41, 0x73, 0x73, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x69,
+0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61,
+0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x73, 0x61, 0x62, 0x64, 0x75,
+0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x4a, 0x4d, 0x50, 0x3b, 0x57,
+0x55, 0x54, 0x3b, 0x54, 0x41, 0x52, 0x3b, 0x54, 0x41, 0x44, 0x3b, 0x54, 0x41, 0x4e, 0x3b, 0x54, 0x41, 0x42, 0x3b, 0x4e,
+0x47, 0x53, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x3b, 0x57, 0x75, 0x6f, 0x6b, 0x20, 0x54, 0x69, 0x63, 0x68,
+0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x64, 0x65,
+0x6b, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x6e, 0x67, 0x2019, 0x77, 0x65, 0x6e, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20,
+0x41, 0x62, 0x69, 0x63, 0x68, 0x3b, 0x4e, 0x67, 0x65, 0x73, 0x6f, 0x3b, 0x4a, 0x3b, 0x57, 0x3b, 0x54, 0x3b, 0x54, 0x3b,
+0x54, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x41, 0x79, 0x6e, 0x3b, 0x41, 0x73, 0x6e, 0x3b, 0x41, 0x6b,
+0x72, 0x3b, 0x41, 0x6b, 0x77, 0x3b, 0x41, 0x73, 0x6d, 0x3b, 0x41, 0x73, 0x1e0d, 0x3b, 0x41, 0x73, 0x61, 0x6d, 0x61, 0x73,
+0x3b, 0x41, 0x79, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x6b, 0x72, 0x61, 0x73, 0x3b,
+0x41, 0x6b, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x1e0d, 0x79, 0x61,
+0x73, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x6c, 0x68, 0x3b,
+0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b, 0x41, 0x6c, 0x7a, 0x3b,
+0x41, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, 0x3b, 0x41, 0x74,
+0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69,
+0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, 0x4a, 0x70,
+0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6d, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a,
+0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x70, 0x69, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61,
+0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x61,
+0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a,
+0x75, 0x6d, 0x61, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x41, 0x3b, 0x49,
+0x3b, 0x31, 0x3b, 0x930, 0x92c, 0x93f, 0x3b, 0x938, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x926, 0x3b, 0x92c,
+0x93f, 0x938, 0x925, 0x93f, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x3b, 0x930, 0x92c, 0x93f, 0x92c,
+0x93e, 0x930, 0x3b, 0x938, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x926,
+0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x938, 0x925, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x92c, 0x93e,
+0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b,
+0x92c, 0x93f, 0x3b, 0x938, 0x941, 0x3b, 0x938, 0x941, 0x3b, 0x43a, 0x4c0, 0x438, 0x3b, 0x43e, 0x440, 0x3b, 0x448, 0x438, 0x3b, 0x43a,
+0x445, 0x430, 0x3b, 0x435, 0x430, 0x3b, 0x43f, 0x4c0, 0x435, 0x3b, 0x448, 0x443, 0x43e, 0x3b, 0x43a, 0x4c0, 0x438, 0x440, 0x430, 0x3b,
+0x43e, 0x440, 0x448, 0x43e, 0x442, 0x3b, 0x448, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x43a, 0x445, 0x430, 0x430, 0x440, 0x430, 0x3b,
+0x435, 0x430, 0x440, 0x430, 0x3b, 0x43f, 0x4c0, 0x435, 0x440, 0x430, 0x441, 0x43a, 0x430, 0x3b, 0x448, 0x443, 0x43e, 0x442, 0x3b, 0x43a,
+0x4c0, 0x3b, 0x43e, 0x3b, 0x448, 0x3b, 0x43a, 0x445, 0x3b, 0x435, 0x3b, 0x43f, 0x4c0, 0x3b, 0x448, 0x3b, 0x43d, 0x434, 0x2de7, 0x487,
+0x467, 0x3b, 0x43f, 0x43d, 0x2de3, 0x435, 0x3b, 0x432, 0x442, 0x43e, 0x2dec, 0x487, 0x3b, 0x441, 0x440, 0x2de3, 0x435, 0x3b, 0x447, 0x435,
+0x2de6, 0x487, 0x3b, 0x43f, 0x467, 0x2de6, 0x487, 0x3b, 0x441, 0xa64b, 0x2de0, 0x487, 0x3b, 0x43d, 0x435, 0x434, 0x463, 0x301, 0x43b, 0x467,
+0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x463, 0x301, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x44a, 0x3b, 0x432, 0x442, 0x43e, 0x301, 0x440,
+0x43d, 0x438, 0x43a, 0x44a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x300, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x442, 0x43e,
+0x301, 0x43a, 0x44a, 0x3b, 0x43f, 0x467, 0x442, 0x43e, 0x301, 0x43a, 0x44a, 0x3b, 0x441, 0xa64b, 0x431, 0x431, 0x461, 0x301, 0x442, 0x430,
+0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4e, 0x6b, 0x6f, 0x3b, 0x4e, 0x64, 0x79, 0x3b, 0x4e, 0x64, 0x67, 0x3b, 0x4e, 0x6a, 0x77,
+0x3b, 0x4e, 0x67, 0x76, 0x3b, 0x4c, 0x75, 0x62, 0x3b, 0x4c, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4e, 0x6b, 0x6f,
+0x64, 0x79, 0x61, 0x3b, 0x4e, 0x64, 0xe0, 0x61, 0x79, 0xe0, 0x3b, 0x4e, 0x64, 0x61, 0x6e, 0x67, 0xf9, 0x3b, 0x4e, 0x6a,
+0xf2, 0x77, 0x61, 0x3b, 0x4e, 0x67, 0xf2, 0x76, 0x79, 0x61, 0x3b, 0x4c, 0x75, 0x62, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4c,
+0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0xe9, 0x69,
+0x3b, 0x44, 0xeb, 0x6e, 0x3b, 0x4d, 0xeb, 0x74, 0x3b, 0x44, 0x6f, 0x6e, 0x3b, 0x46, 0x72, 0x65, 0x3b, 0x53, 0x61, 0x6d,
+0x3b, 0x53, 0x6f, 0x6e, 0x6e, 0x64, 0x65, 0x67, 0x3b, 0x4d, 0xe9, 0x69, 0x6e, 0x64, 0x65, 0x67, 0x3b, 0x44, 0xeb, 0x6e,
+0x73, 0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x4d, 0xeb, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e,
+0x65, 0x73, 0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x46, 0x72, 0x65, 0x69, 0x64, 0x65, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73,
+0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x53, 0x6f, 0x6e, 0x2e, 0x3b, 0x4d, 0xe9, 0x69, 0x2e, 0x3b, 0x44, 0xeb, 0x6e, 0x2e,
+0x3b, 0x4d, 0xeb, 0x74, 0x2e, 0x3b, 0x44, 0x6f, 0x6e, 0x2e, 0x3b, 0x46, 0x72, 0x65, 0x2e, 0x3b, 0x53, 0x61, 0x6d, 0x2e,
+0x3b, 0x6e, 0x74, 0x73, 0x3b, 0x6b, 0x70, 0x61, 0x3b, 0x67, 0x68, 0x254, 0x3b, 0x74, 0x254, 0x6d, 0x3b, 0x75, 0x6d, 0x65,
+0x3b, 0x67, 0x68, 0x268, 0x3b, 0x64, 0x7a, 0x6b, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x6e, 0x74, 0x73, 0x268, 0x3b, 0x74, 0x73,
+0x75, 0x294, 0x75, 0x6b, 0x70, 0xe0, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x67, 0x68, 0x254, 0x65, 0x3b, 0x74, 0x73, 0x75,
+0x294, 0x75, 0x74, 0x254, 0x300, 0x6d, 0x6c, 0xf2, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x6d, 0xe8, 0x3b, 0x74, 0x73, 0x75,
+0x294, 0x75, 0x67, 0x68, 0x268, 0x302, 0x6d, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x6e, 0x64, 0x7a, 0x268, 0x6b, 0x254, 0x294, 0x254,
+0x3b, 0x6e, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x74, 0x3b, 0x75, 0x3b, 0x67, 0x3b, 0x64, 0x3b, 0x6e, 0x254, 0x79, 0x3b, 0x6e,
+0x6a, 0x61, 0x3b, 0x75, 0x75, 0x6d, 0x3b, 0x14b, 0x67, 0x65, 0x3b, 0x6d, 0x62, 0x254, 0x3b, 0x6b, 0x254, 0x254, 0x3b, 0x6a,
+0x6f, 0x6e, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x254, 0x302, 0x79, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x6a,
+0x61, 0x14b, 0x67, 0x75, 0x6d, 0x62, 0x61, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0xfb, 0x6d, 0x3b, 0x14b, 0x67, 0x77, 0xe0,
+0x20, 0x14b, 0x67, 0xea, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6d, 0x62, 0x254, 0x6b, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20,
+0x6b, 0x254, 0x254, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6a, 0xf4, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x75, 0x3b, 0x14b,
+0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6a, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69,
+0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68,
+0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b,
+0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x53, 0x3b, 0xe9, 0x74, 0x3b, 0x6d, 0x254, 0x301,
+0x73, 0x3b, 0x6b, 0x77, 0x61, 0x3b, 0x6d, 0x75, 0x6b, 0x3b, 0x14b, 0x67, 0x69, 0x3b, 0x257, 0xf3, 0x6e, 0x3b, 0x65, 0x73,
+0x61, 0x3b, 0xe9, 0x74, 0x69, 0x3b, 0x6d, 0x254, 0x301, 0x73, 0xfa, 0x3b, 0x6b, 0x77, 0x61, 0x73, 0xfa, 0x3b, 0x6d, 0x75,
+0x6b, 0x254, 0x301, 0x73, 0xfa, 0x3b, 0x14b, 0x67, 0x69, 0x73, 0xfa, 0x3b, 0x257, 0xf3, 0x6e, 0x25b, 0x73, 0xfa, 0x3b, 0x65,
+0x73, 0x61, 0x253, 0x61, 0x73, 0xfa, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x14b, 0x3b, 0x257, 0x3b, 0x65,
+0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x54, 0x65, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x72, 0x61,
+0x3b, 0x41, 0x72, 0x6a, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x61, 0x73, 0x3b, 0x54, 0x65, 0x6e, 0x65, 0x14b,
+0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x61, 0x6d,
+0x69, 0x73, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x44,
+0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254,
+0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, 0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x66, 0xfa, 0x6c, 0x3b, 0x73,
+0xe9, 0x72, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x254, 0x301,
+0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x62, 0x25b, 0x30c, 0x3b, 0x73, 0x254, 0x301, 0x6e,
+0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x6c, 0x25b, 0x301, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64,
+0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x6e, 0x79, 0x69, 0x3b, 0x66, 0xfa, 0x6c, 0x61, 0x64, 0xe9,
+0x3b, 0x73, 0xe9, 0x72, 0x61, 0x64, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x66, 0x3b,
+0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6c, 0x1dd, 0x6e, 0x3b, 0x6d, 0x61, 0x61, 0x3b, 0x6d, 0x25b, 0x6b, 0x3b, 0x6a,
+0x1dd, 0x1dd, 0x3b, 0x6a, 0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x6d, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x1dd, 0x3b, 0x6c, 0x1dd,
+0x6e, 0x64, 0xed, 0x3b, 0x6d, 0x61, 0x61, 0x64, 0xed, 0x3b, 0x6d, 0x25b, 0x6b, 0x72, 0x25b, 0x64, 0xed, 0x3b, 0x6a, 0x1dd,
+0x1dd, 0x64, 0xed, 0x3b, 0x6a, 0xfa, 0x6d, 0x62, 0xe1, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0xed, 0x3b, 0x73, 0x3b, 0x6c, 0x3b,
+0x6d, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x73, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e,
+0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x53, 0x61,
+0x62, 0x61, 0x74, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e,
+0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69,
+0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x3b, 0x4a,
+0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x43, 0x79, 0x61, 0x3b, 0x43, 0x6c, 0x61, 0x3b, 0x43,
+0x7a, 0x69, 0x3b, 0x43, 0x6b, 0x6f, 0x3b, 0x43, 0x6b, 0x61, 0x3b, 0x43, 0x67, 0x61, 0x3b, 0x43, 0x7a, 0x65, 0x3b, 0x43,
+0x6f, 0x6d, 0x2019, 0x79, 0x61, 0x6b, 0x6b, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x6c, 0x61, 0x61, 0x257, 0x69, 0x69, 0x3b, 0x43,
+0x6f, 0x6d, 0x7a, 0x79, 0x69, 0x69, 0x257, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x6b, 0x6f, 0x6c, 0x6c, 0x65, 0x3b, 0x43,
+0x6f, 0x6d, 0x6b, 0x61, 0x6c, 0x64, 0x1dd, 0x253, 0x6c, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x67, 0x61, 0x69, 0x73, 0x75,
+0x75, 0x3b, 0x43, 0x6f, 0x6d, 0x7a, 0x79, 0x65, 0x253, 0x73, 0x75, 0x75, 0x3b, 0x59, 0x3b, 0x4c, 0x3b, 0x5a, 0x3b, 0x4f,
+0x3b, 0x41, 0x3b, 0x47, 0x3b, 0x45, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62,
+0x3b, 0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x6d, 0x62, 0x73, 0x3b, 0x73, 0x61, 0x73, 0x3b, 0x73, 0x254, 0x301,
+0x6e, 0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61,
+0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x62, 0x61, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20,
+0x6d, 0xe1, 0x6c, 0x61, 0x6c, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1,
+0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x62, 0xe1, 0x67, 0xe1, 0x20, 0x6d, 0xe1, 0x20, 0x73, 0x75, 0x6b, 0x75, 0x6c, 0x3b, 0x73,
+0xe1, 0x73, 0x61, 0x64, 0x69, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b,
+0x43, 0xe4, 0x14b, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x3b, 0x52, 0x25b, 0x77, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x3b, 0x14a,
+0x75, 0x61, 0x61, 0x6e, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x3b, 0x43, 0xe4,
+0x14b, 0x20, 0x6b, 0x75, 0x254, 0x74, 0x68, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x20, 0x6c, 0x61, 0x331, 0x74, 0x3b, 0x52, 0x25b,
+0x77, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b,
+0x14a, 0x75, 0x61, 0x61, 0x6e, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x20, 0x6c,
+0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x43, 0x3b, 0x4a,
+0x3b, 0x52, 0x3b, 0x44, 0x3b, 0x14a, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x431, 0x441, 0x3b, 0x431, 0x43d, 0x3b, 0x43e, 0x43f, 0x3b,
+0x441, 0x44d, 0x3b, 0x447, 0x43f, 0x3b, 0x431, 0x44d, 0x3b, 0x441, 0x431, 0x3b, 0x431, 0x430, 0x441, 0x43a, 0x44b, 0x4bb, 0x44b, 0x430,
+0x43d, 0x43d, 0x44c, 0x430, 0x3b, 0x431, 0x44d, 0x43d, 0x438, 0x434, 0x438, 0x44d, 0x43d, 0x43d, 0x44c, 0x438, 0x43a, 0x3b, 0x43e, 0x43f,
+0x442, 0x443, 0x43e, 0x440, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x43a, 0x3b, 0x441, 0x44d, 0x440, 0x44d, 0x434, 0x44d, 0x3b, 0x447, 0x44d,
+0x43f, 0x43f, 0x438, 0x44d, 0x440, 0x3b, 0x411, 0x44d, 0x44d, 0x442, 0x438, 0x4a5, 0x441, 0x44d, 0x3b, 0x441, 0x443, 0x431, 0x443, 0x43e,
+0x442, 0x430, 0x3b, 0x411, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x411, 0x3b, 0x421, 0x3b, 0x4d, 0x75, 0x6c,
+0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75,
+0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74,
+0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41,
+0x6c, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
+0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0xa55e,
+0xa54c, 0xa535, 0x3b, 0xa5f3, 0xa5e1, 0xa609, 0x3b, 0xa55a, 0xa55e, 0xa55a, 0x3b, 0xa549, 0xa55e, 0xa552, 0x3b, 0xa549, 0xa524, 0xa546, 0xa562, 0x3b,
+0xa549, 0xa524, 0xa540, 0xa56e, 0x3b, 0xa53b, 0xa52c, 0xa533, 0x3b, 0x6c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x74, 0x25b, 0x25b, 0x6e,
+0x25b, 0x25b, 0x3b, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x69, 0x6d, 0x69,
+0x73, 0x61, 0x3b, 0x61, 0x69, 0x6a, 0x69, 0x6d, 0x61, 0x3b, 0x73, 0x69, 0x253, 0x69, 0x74, 0x69, 0x3b, 0x53, 0x75, 0x6e,
+0x3b, 0x4d, 0xe4, 0x6e, 0x3b, 0x5a, 0x69, 0x161, 0x3b, 0x4d, 0x69, 0x74, 0x3b, 0x46, 0x72, 0xf3, 0x3b, 0x46, 0x72, 0x69,
+0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0xe4, 0x6e, 0x74, 0x61, 0x67, 0x3b,
+0x5a, 0x69, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x75, 0x10d, 0x3b, 0x46, 0x72, 0xf3, 0x6e, 0x74,
+0x61, 0x67, 0x3b, 0x46, 0x72, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b,
+0x4d, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x73, 0x64, 0x3b, 0x6d, 0x64, 0x3b, 0x6d, 0x77,
+0x3b, 0x65, 0x74, 0x3b, 0x6b, 0x6c, 0x3b, 0x66, 0x6c, 0x3b, 0x73, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x25b,
+0x3b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, 0x3b, 0x6d, 0x75, 0xe1, 0x6e, 0x79, 0xe1, 0x14b, 0x6d, 0xf3, 0x6e, 0x64, 0x69,
+0x65, 0x3b, 0x6d, 0x65, 0x74, 0xfa, 0x6b, 0x70, 0xed, 0xe1, 0x70, 0x25b, 0x3b, 0x6b, 0xfa, 0x70, 0xe9, 0x6c, 0x69, 0x6d,
+0x65, 0x74, 0xfa, 0x6b, 0x70, 0x69, 0x61, 0x70, 0x25b, 0x3b, 0x66, 0x65, 0x6c, 0xe9, 0x74, 0x65, 0x3b, 0x73, 0xe9, 0x73,
+0x65, 0x6c, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x64, 0x6f,
+0x6d, 0x3b, 0x6c, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0xe9, 0x3b, 0x78, 0x75, 0x65, 0x3b, 0x76, 0x69,
+0x65, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x6c, 0x6c, 0x75, 0x6e, 0x65, 0x73,
+0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x78, 0x75,
+0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b,
+0x53, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0xc1, 0x70, 0x74, 0x61, 0x20, 0x4d,
+0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x57, 0x25b, 0x301, 0x6e, 0x25b, 0x73, 0x25b, 0x64, 0x25b, 0x3b, 0x54, 0x254, 0x301, 0x73,
+0x25b, 0x64, 0x25b, 0x3b, 0x46, 0x25b, 0x6c, 0xe2, 0x79, 0x25b, 0x64, 0x25b, 0x3b, 0x53, 0xe1, 0x73, 0x69, 0x64, 0x25b, 0x3b,
+0x53, 0x254, 0x301, 0x3b, 0x4d, 0x254, 0x301, 0x3b, 0xc1, 0x4d, 0x3b, 0x57, 0x25b, 0x301, 0x3b, 0x54, 0x254, 0x301, 0x3b, 0x46,
+0x25b, 0x3b, 0x53, 0xe1, 0x3b, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72,
+0x64, 0x69, 0x3b, 0x6d, 0x25b, 0x72, 0x6b, 0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x79, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61,
+0x14b, 0x64, 0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x6d, 0x254, 0x6e, 0x254, 0x20, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x73,
+0x6f, 0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x25b, 0x3b, 0x79, 0x65, 0x3b, 0x76, 0x61, 0x3b, 0x6d, 0x73, 0x3b,
+0x41, 0x6e, 0x65, 0x67, 0x20, 0x31, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x32, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x33,
+0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x34, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x35, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20,
+0x36, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x37, 0x3b, 0x41, 0x31, 0x3b, 0x41, 0x32, 0x3b, 0x41, 0x33, 0x3b, 0x41, 0x34,
+0x3b, 0x41, 0x35, 0x3b, 0x41, 0x36, 0x3b, 0x41, 0x37, 0x3b, 0x6c, 0x79, 0x25b, 0x2bc, 0x25b, 0x301, 0x20, 0x73, 0x1e85, 0xed,
+0x14b, 0x74, 0xe8, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254,
+0x6e, 0x74, 0xe8, 0x20, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x74, 0x73, 0xe8, 0x74, 0x73,
+0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x74,
+0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6d,
+0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc,
+0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x77, 0x61, 0x6b, 0x21f, 0x61, 0x14b, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75,
+0x77, 0x61, 0x14b, 0x17e, 0x69, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x6e, 0x75, 0x14b, 0x70, 0x61, 0x3b, 0x41, 0x14b,
+0x70, 0xe9, 0x74, 0x75, 0x79, 0x61, 0x6d, 0x6e, 0x69, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x74, 0x6f, 0x70, 0x61,
+0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x7a, 0x61, 0x70, 0x74, 0x61, 0x14b, 0x3b, 0x4f, 0x77, 0xe1, 0x14b, 0x67, 0x79,
+0x75, 0x17e, 0x61, 0x17e, 0x61, 0x70, 0x69, 0x3b, 0x41, 0x3b, 0x57, 0x3b, 0x4e, 0x3b, 0x59, 0x3b, 0x54, 0x3b, 0x5a, 0x3b,
+0x4f, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30,
+0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30,
+0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, 0x3b, 0x6cc, 0x6d5, 0x6a9, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x62f,
+0x648, 0x648, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x633, 0x6ce, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x686, 0x648, 0x627, 0x631,
+0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x67e, 0x6ce, 0x646, 0x62c, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x6be, 0x6d5, 0x6cc, 0x646,
+0x6cc, 0x3b, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x6be, 0x3b,
+0x634, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x70, 0xf3, 0x6e, 0x3b, 0x77, 0x61, 0x142, 0x3b, 0x73, 0x72, 0x6a, 0x3b, 0x73, 0x74,
+0x77, 0x3b, 0x70, 0x11b, 0x74, 0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x6a, 0x65, 0x17a, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0xf3,
+0x6e, 0x6a, 0x65, 0x17a, 0x65, 0x6c, 0x65, 0x3b, 0x77, 0x61, 0x142, 0x74, 0x6f, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x6a, 0x6f,
+0x64, 0x61, 0x3b, 0x73, 0x74, 0x77, 0xf3, 0x72, 0x74, 0x6b, 0x3b, 0x70, 0x11b, 0x74, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f,
+0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x6a, 0x65,
+0x3b, 0x70, 0xf3, 0x6e, 0x3b, 0x77, 0x75, 0x74, 0x3b, 0x73, 0x72, 0x6a, 0x3b, 0x161, 0x74, 0x77, 0x3b, 0x70, 0x6a, 0x61,
+0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x6a, 0x65, 0x64, 0x17a, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0xf3, 0x6e, 0x64, 0x17a, 0x65,
+0x6c, 0x61, 0x3b, 0x77, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, 0x77,
+0xf3, 0x72, 0x74, 0x6b, 0x3b, 0x70, 0x6a, 0x61, 0x74, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b,
+0x70, 0x3b, 0x77, 0x3b, 0x73, 0x3b, 0x161, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x61, 0x64, 0x3b, 0x70, 0x61, 0x6e, 0x3b,
+0x77, 0x69, 0x73, 0x3b, 0x70, 0x75, 0x73, 0x3b, 0x6b, 0x65, 0x74, 0x3b, 0x70, 0x113, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b,
+0x6e, 0x61, 0x64, 0x12b, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x6e, 0x61, 0x64, 0x12b, 0x6c, 0x69, 0x3b, 0x77, 0x69, 0x73, 0x61,
+0x73, 0x12b, 0x64, 0x69, 0x73, 0x3b, 0x70, 0x75, 0x73, 0x73, 0x69, 0x73, 0x61, 0x77, 0x61, 0x69, 0x74, 0x69, 0x3b, 0x6b,
+0x65, 0x74, 0x77, 0x69, 0x72, 0x74, 0x69, 0x6b, 0x73, 0x3b, 0x70, 0x113, 0x6e, 0x74, 0x6e, 0x69, 0x6b, 0x73, 0x3b, 0x73,
+0x61, 0x62, 0x61, 0x74, 0x74, 0x69, 0x6b, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x50, 0x3b, 0x4b, 0x3b, 0x50,
+0x3b, 0x53, 0x3b, 0x70, 0x61, 0x73, 0x3b, 0x76, 0x75, 0x6f, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6b, 0x6f, 0x73, 0x3b, 0x74,
+0x75, 0x6f, 0x3b, 0x76, 0xe1, 0x73, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x70, 0x61, 0x73, 0x65, 0x70, 0x65, 0x69, 0x76, 0x69,
+0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0x61, 0x72, 0x67, 0xe2, 0x3b, 0x6d, 0x61, 0x6a, 0x65, 0x62, 0x61, 0x72, 0x67, 0xe2,
+0x3b, 0x6b, 0x6f, 0x73, 0x6b, 0x6f, 0x6b, 0x6b, 0x6f, 0x3b, 0x74, 0x75, 0x6f, 0x72, 0xe2, 0x73, 0x74, 0xe2, 0x68, 0x3b,
+0x76, 0xe1, 0x73, 0x74, 0x75, 0x70, 0x70, 0x65, 0x69, 0x76, 0x69, 0x3b, 0x6c, 0xe1, 0x76, 0x75, 0x72, 0x64, 0xe2, 0x68,
+0x3b, 0x70, 0x61, 0x73, 0x65, 0x70, 0x65, 0x65, 0x69, 0x76, 0x69, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0x61, 0x61, 0x72,
+0x67, 0xe2, 0x3b, 0x6d, 0x61, 0x6a, 0x65, 0x62, 0x61, 0x61, 0x72, 0x67, 0xe2, 0x3b, 0x6b, 0x6f, 0x73, 0x6b, 0x6f, 0x68,
+0x6f, 0x3b, 0x74, 0x75, 0x6f, 0x72, 0xe2, 0x73, 0x74, 0x75, 0x76, 0x3b, 0x76, 0xe1, 0x73, 0x74, 0x75, 0x70, 0x70, 0x65,
+0x65, 0x69, 0x76, 0x69, 0x3b, 0x6c, 0xe1, 0x76, 0x75, 0x72, 0x64, 0x75, 0x76, 0x3b, 0x70, 0x3b, 0x56, 0x3b, 0x4d, 0x3b,
+0x4b, 0x3b, 0x54, 0x3b, 0x56, 0x3b, 0x4c, 0x3b
};
static const ushort byte_unit_data[] = {
@@ -4846,152 +4987,165 @@ static const ushort byte_unit_data[] = {
0x42, 0x3b, 0x45, 0x42, 0x628, 0x627, 0x64a, 0x62a, 0x643, 0x64a, 0x644, 0x648, 0x628, 0x627, 0x64a, 0x62a, 0x3b, 0x645, 0x64a, 0x63a,
0x627, 0x628, 0x627, 0x64a, 0x62a, 0x3b, 0x63a, 0x64a, 0x63a, 0x627, 0x628, 0x627, 0x64a, 0x62a, 0x3b, 0x62a, 0x64a, 0x631, 0x627, 0x628,
0x627, 0x64a, 0x62a, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x562, 0x561, 0x575, 0x569, 0x565, 0x580, 0x56f, 0x532, 0x3b, 0x544, 0x532,
-0x3b, 0x533, 0x532, 0x3b, 0x54f, 0x532, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x62, 0x61, 0x79, 0x74, 0x62, 0x79, 0x74, 0x65,
-0x2d, 0x61, 0x6b, 0x9ac, 0x9be, 0x987, 0x99f, 0x6f, 0x6b, 0x74, 0x65, 0x64, 0x6f, 0xf9, 0x6b, 0x6f, 0x3b, 0x4d, 0x6f, 0x3b,
-0x47, 0x6f, 0x3b, 0x54, 0x6f, 0x3b, 0x50, 0x6f, 0x3b, 0x45, 0x6f, 0x4b, 0x69, 0x6f, 0x3b, 0x4d, 0x69, 0x6f, 0x3b, 0x47,
-0x69, 0x6f, 0x3b, 0x54, 0x69, 0x6f, 0x3b, 0x50, 0x69, 0x6f, 0x3b, 0x45, 0x69, 0x6f, 0x431, 0x430, 0x439, 0x442, 0x43e, 0x432,
-0x435, 0x1018, 0x102d, 0x102f, 0x1000, 0x103a, 0x431, 0x430, 0x439, 0x442, 0x44b, 0x41a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b,
-0x422, 0x411, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x1794, 0x17c3, 0x5b57, 0x8282, 0x5343, 0x5b57, 0x8282, 0x3b, 0x5146, 0x5b57, 0x8282, 0x3b,
-0x5409, 0x5b57, 0x8282, 0x3b, 0x592a, 0x5b57, 0x8282, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x4f4d, 0x5143, 0x7d44, 0x62, 0x61, 0x6a, 0x74,
-0x6f, 0x76, 0x69, 0x62, 0x61, 0x6a, 0x74, 0x79, 0x62, 0x61, 0x69, 0x64, 0x69, 0x64, 0x62, 0xfd, 0x74, 0x4b, 0x42, 0x3b,
-0x4d, 0x42, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x74, 0x61, 0x76, 0x75, 0x74, 0x6b,
-0x74, 0x3b, 0x4d, 0x74, 0x3b, 0x47, 0x74, 0x3b, 0x54, 0x74, 0x3b, 0x50, 0x74, 0x3b, 0x45, 0x74, 0x4b, 0x69, 0x74, 0x3b,
-0x4d, 0x69, 0x74, 0x3b, 0x47, 0x69, 0x74, 0x3b, 0x54, 0x69, 0x74, 0x3b, 0x50, 0x69, 0x74, 0x3b, 0x45, 0x69, 0x74, 0x6f,
-0x63, 0x74, 0x65, 0x74, 0x73, 0x62, 0x61, 0x69, 0x64, 0x68, 0x74, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x10d9, 0x10d1, 0x10d0, 0x10d8,
-0x10e2, 0x10d8, 0x3b, 0x10db, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10d2, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10e2, 0x10d1, 0x10d0,
-0x10d8, 0x10e2, 0x10d8, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x42, 0x79, 0x74, 0x65, 0x73, 0xaac, 0xabe, 0xa87, 0xa9f, 0x5d1, 0x5ea,
-0x5d9, 0x5dd, 0x92c, 0x93e, 0x907, 0x91f, 0x62, 0xe1, 0x6a, 0x74, 0x62, 0xe6, 0x74, 0x69, 0x62, 0x65, 0x61, 0x72, 0x74, 0x61,
-0x30d0, 0x30a4, 0x30c8, 0xcac, 0xcc8, 0xc9f, 0xccd, 0x200c, 0xc97, 0xcb3, 0xcc1, 0xc95, 0xcbf, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xcae, 0xcc6,
-0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xc97, 0xcbf, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xc9f, 0xcc6, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0x50,
-0x42, 0x3b, 0x45, 0x42, 0x431, 0x430, 0x439, 0x442, 0x43a, 0x411, 0x3b, 0x4d, 0x411, 0x3b, 0x413, 0x411, 0x3b, 0x54, 0x411, 0x3b,
-0x50, 0x411, 0x3b, 0x45, 0x411, 0x4b, 0x69, 0x411, 0x3b, 0x4d, 0x69, 0x411, 0x3b, 0x47, 0x69, 0x411, 0x3b, 0x54, 0x69, 0x411,
-0x3b, 0x50, 0x69, 0x411, 0x3b, 0x45, 0x69, 0x411, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b, 0x422, 0x411, 0x3b,
-0x50, 0x42, 0x3b, 0x45, 0x42, 0xbc14, 0xc774, 0xd2b8, 0x62, 0x61, 0x69, 0x74, 0x69, 0x62, 0x61, 0x69, 0x74, 0x61, 0x69, 0x431,
-0x430, 0x458, 0x442, 0x438, 0x62, 0x61, 0x69, 0x74, 0xd2c, 0xd48, 0xd31, 0xd4d, 0xd31, 0xd4d, 0xd15, 0xd3f, 0x2e, 0xd2c, 0xd3f, 0x2e,
-0x3b, 0xd2e, 0xd46, 0x2e, 0xd2c, 0xd48, 0x2e, 0x3b, 0xd1c, 0xd3f, 0x2e, 0xd2c, 0xd48, 0x2e, 0x3b, 0xd1f, 0xd3f, 0xd2c, 0xd3f, 0x3b,
-0x50, 0x42, 0x3b, 0x45, 0x42, 0x628, 0x627, 0x6cc, 0x62a, 0x6a9, 0x6cc, 0x644, 0x648, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x645, 0x6af,
-0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x6af, 0x6cc, 0x6af, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x62a, 0x631, 0x627, 0x628, 0x627,
-0x6cc, 0x62a, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xa2c, 0xa3e, 0xa07, 0xa1f, 0x62, 0x79, 0x21b, 0x69, 0x431, 0x430, 0x458, 0x442,
-0x43e, 0x432, 0x438, 0xdb6, 0xdba, 0xdd2, 0xda7, 0xdca, 0xd9a, 0xdd2, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xdb8, 0xdd9, 0xdb6, 0x20,
-0x7b, 0x30, 0x7d, 0x3b, 0xd9c, 0xdd2, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xda7, 0xdd9, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b,
-0x50, 0x42, 0x3b, 0x45, 0x42, 0x6b, 0x69, 0x6c, 0x6f, 0x62, 0x61, 0x69, 0x74, 0x69, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d,
-0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x74, 0x65, 0x72, 0x61, 0x62, 0x61, 0x69,
-0x74, 0x69, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xbaa, 0xbc8, 0xb9f, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0xc2c,
-0xc48, 0xc1f, 0xc4d, 0x200c, 0xc32, 0xc41, 0xc15, 0xc47, 0xc2c, 0xc40, 0x3b, 0xc0e, 0xc2e, 0xc4d, 0x200c, 0xc2c, 0xc3f, 0x3b, 0xc1c, 0xc40,
-0xc2c, 0xc40, 0x3b, 0xc1f, 0xc40, 0xc2c, 0xc40, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xe44, 0xe1a, 0xe15, 0xe4c, 0x70, 0x61, 0x69,
-0x74, 0x69, 0x6b, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30,
-0x7d, 0x3b, 0x47, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x54, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30,
-0x7d, 0x3b, 0x50, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x45, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30,
-0x7d, 0x4b, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b,
-0x30, 0x7d, 0x3b, 0x47, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x54, 0x69, 0x42, 0x20, 0x2bb, 0x65,
-0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x45, 0x69, 0x42, 0x20,
-0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x62, 0x61, 0xfd, 0x74, 0x431, 0x430, 0x439, 0x442, 0x438, 0x62, 0x65, 0x69, 0x74, 0x69,
-0x61, 0x75, 0x13d7, 0x13d3, 0x13cd, 0x13a6, 0x13b5, 0x13a9, 0x431, 0x430, 0x430, 0x439, 0x442, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x47,
-0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x62, 0x79, 0x74, 0x65, 0x79
+0x3b, 0x533, 0x532, 0x3b, 0x54f, 0x532, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x9ac, 0x9be, 0x987, 0x99f, 0x995, 0x9bf, 0x983, 0x20,
+0x9ac, 0x9be, 0x983, 0x3b, 0x9ae, 0x9c7, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, 0x997, 0x9bf, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b,
+0x99f, 0x9c7, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x62, 0x61, 0x79, 0x74, 0x62, 0x79, 0x74,
+0x65, 0x2d, 0x61, 0x6b, 0x6f, 0x6b, 0x74, 0x65, 0x64, 0x6f, 0xf9, 0x6b, 0x6f, 0x3b, 0x4d, 0x6f, 0x3b, 0x47, 0x6f, 0x3b,
+0x54, 0x6f, 0x3b, 0x50, 0x6f, 0x3b, 0x45, 0x6f, 0x4b, 0x69, 0x6f, 0x3b, 0x4d, 0x69, 0x6f, 0x3b, 0x47, 0x69, 0x6f, 0x3b,
+0x54, 0x69, 0x6f, 0x3b, 0x50, 0x69, 0x6f, 0x3b, 0x45, 0x69, 0x6f, 0x431, 0x430, 0x439, 0x442, 0x43e, 0x432, 0x435, 0x1018, 0x102d,
+0x102f, 0x1000, 0x103a, 0x431, 0x430, 0x439, 0x442, 0x44b, 0x41a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b, 0x422, 0x411, 0x3b,
+0x50, 0x42, 0x3b, 0x45, 0x42, 0x1794, 0x17c3, 0x5b57, 0x8282, 0x5343, 0x5b57, 0x8282, 0x3b, 0x5146, 0x5b57, 0x8282, 0x3b, 0x5409, 0x5b57, 0x8282,
+0x3b, 0x592a, 0x5b57, 0x8282, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x4f4d, 0x5143, 0x7d44, 0x62, 0x61, 0x6a, 0x74, 0x6f, 0x76, 0x69,
+0x62, 0x61, 0x6a, 0x74, 0x79, 0x62, 0x61, 0x6a, 0x74, 0x6f, 0x6a, 0x62, 0x61, 0x69, 0x64, 0x69, 0x64, 0x62, 0xfd, 0x74,
+0x4b, 0x42, 0x3b, 0x4d, 0x42, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x74, 0x61, 0x76,
+0x75, 0x74, 0x6b, 0x74, 0x3b, 0x4d, 0x74, 0x3b, 0x47, 0x74, 0x3b, 0x54, 0x74, 0x3b, 0x50, 0x74, 0x3b, 0x45, 0x74, 0x4b,
+0x69, 0x74, 0x3b, 0x4d, 0x69, 0x74, 0x3b, 0x47, 0x69, 0x74, 0x3b, 0x54, 0x69, 0x74, 0x3b, 0x50, 0x69, 0x74, 0x3b, 0x45,
+0x69, 0x74, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x62, 0x61, 0x69, 0x64, 0x68, 0x74, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x10d9,
+0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10db, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10d2, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b,
+0x10e2, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x42, 0x79, 0x74, 0x65, 0x73, 0xaac, 0xabe, 0xa87,
+0xa9f, 0x5d1, 0x5d9, 0x5d9, 0x5d8, 0x92c, 0x93e, 0x907, 0x91f, 0x62, 0xe1, 0x6a, 0x74, 0x62, 0xe6, 0x74, 0x69, 0x62, 0x65, 0x61,
+0x72, 0x74, 0x61, 0x30d0, 0x30a4, 0x30c8, 0xcac, 0xcc8, 0xc9f, 0xccd, 0x200c, 0xc97, 0xcb3, 0xcc1, 0xc95, 0xcbf, 0x2e, 0xcac, 0xcc8, 0x2e,
+0x3b, 0xcae, 0xcc6, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xc97, 0xcbf, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xc9f, 0xcc6, 0x2e, 0xcac, 0xcc8,
+0x2e, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x431, 0x430, 0x439, 0x442, 0x43a, 0x411, 0x3b, 0x4d, 0x411, 0x3b, 0x413, 0x411, 0x3b,
+0x54, 0x411, 0x3b, 0x50, 0x411, 0x3b, 0x45, 0x411, 0x4b, 0x69, 0x411, 0x3b, 0x4d, 0x69, 0x411, 0x3b, 0x47, 0x69, 0x411, 0x3b,
+0x54, 0x69, 0x411, 0x3b, 0x50, 0x69, 0x411, 0x3b, 0x45, 0x69, 0x411, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b,
+0x422, 0x411, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xbc14, 0xc774, 0xd2b8, 0x62, 0x61, 0x69, 0x74, 0x69, 0x62, 0x61, 0x69, 0x74,
+0x61, 0x69, 0x431, 0x430, 0x458, 0x442, 0x438, 0x62, 0x61, 0x69, 0x74, 0xd2c, 0xd48, 0xd31, 0xd4d, 0xd31, 0xd4d, 0xd15, 0xd3f, 0x2e,
+0xd2c, 0xd3f, 0x2e, 0x3b, 0xd2e, 0xd46, 0x2e, 0xd2c, 0xd48, 0x2e, 0x3b, 0xd1c, 0xd3f, 0x2e, 0xd2c, 0xd48, 0x2e, 0x3b, 0xd1f, 0xd3f,
+0xd2c, 0xd3f, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xb2c, 0xb3e, 0xb07, 0xb1f, 0xb4d, 0x628, 0x627, 0x6cc, 0x62a, 0x6a9, 0x6cc, 0x644,
+0x648, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x645, 0x6af, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x6af, 0x6cc, 0x6af, 0x627, 0x628, 0x627,
+0x6cc, 0x62a, 0x3b, 0x62a, 0x631, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xa2c, 0xa3e, 0xa07, 0xa1f,
+0x62, 0x79, 0x21b, 0x69, 0x431, 0x430, 0x458, 0x442, 0x43e, 0x432, 0x438, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x6aa, 0x644, 0x648,
+0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b, 0x645, 0x64a, 0x6af, 0x627, 0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b,
+0x6af, 0x64a, 0x6af, 0x627, 0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b, 0x67d, 0x64a, 0x631, 0x627, 0x20, 0x628, 0x627, 0x626,
+0x64a, 0x67d, 0x632, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xdb6, 0xdba, 0xdd2, 0xda7, 0xdca, 0xd9a, 0xdd2, 0xdb6, 0x20, 0x7b, 0x30,
+0x7d, 0x3b, 0xdb8, 0xdd9, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xd9c, 0xdd2, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xda7, 0xdd9,
+0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x6b, 0x69, 0x6c, 0x6f, 0x62, 0x61, 0x69, 0x74, 0x69,
+0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d, 0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x74,
+0x65, 0x72, 0x61, 0x62, 0x61, 0x69, 0x74, 0x69, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xbaa, 0xbc8,
+0xb9f, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0xc2c, 0xc48, 0xc1f, 0xc4d, 0x200c, 0xc32, 0xc41, 0xc15, 0xc47, 0xc2c, 0xc40, 0x3b, 0xc0e, 0xc2e, 0xc4d,
+0x200c, 0xc2c, 0xc3f, 0x3b, 0xc1c, 0xc40, 0xc2c, 0xc40, 0x3b, 0xc1f, 0xc40, 0xc2c, 0xc40, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xe44,
+0xe1a, 0xe15, 0xe4c, 0x70, 0x61, 0x69, 0x74, 0x69, 0x6b, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d, 0x42,
+0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x54, 0x42,
+0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x45, 0x42,
+0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x4b, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d, 0x69,
+0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b,
+0x54, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30,
+0x7d, 0x3b, 0x45, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x62, 0x61, 0xfd, 0x74, 0x431, 0x430, 0x439, 0x442,
+0x438, 0x628, 0x627, 0x626, 0x679, 0x62, 0x65, 0x69, 0x74, 0x69, 0x61, 0x75, 0x61, 0x1e6d, 0x61, 0x6d, 0x1e0d, 0x61, 0x6e, 0x6b,
+0x41, 0x1e6c, 0x3b, 0x4d, 0x41, 0x1e6c, 0x3b, 0x47, 0x41, 0x1e6c, 0x3b, 0x54, 0x41, 0x1e6c, 0x3b, 0x50, 0x41, 0x1e6c, 0x3b, 0x45,
+0x41, 0x1e6c, 0x4b, 0x69, 0x41, 0x1e6c, 0x3b, 0x4d, 0x69, 0x41, 0x1e6c, 0x3b, 0x47, 0x69, 0x41, 0x1e6c, 0x3b, 0x54, 0x69, 0x41,
+0x1e6c, 0x3b, 0x50, 0x69, 0x41, 0x1e6c, 0x3b, 0x45, 0x69, 0x41, 0x1e6c, 0x13d7, 0x13d3, 0x13cd, 0x13a6, 0x13b5, 0x13a9, 0x431, 0x430, 0x430,
+0x439, 0x442, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x62,
+0x79, 0x74, 0x65, 0x79
};
static const ushort am_data[] = {
0x41, 0x4d, 0x57, 0x44, 0x76, 0x6d, 0x2e, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x64, 0x69, 0x74, 0x65, 0x73, 0x1325, 0x12cb,
-0x1275, 0x635, 0x9aa, 0x9c2, 0x9f0, 0x9cd, 0x9ac, 0x9be, 0x9b9, 0x9cd, 0x9a3, 0x410, 0x41c, 0xf66, 0xf94, 0xf0b, 0xf46, 0xf0b, 0x41, 0x2e,
-0x4d, 0x2e, 0x43f, 0x440, 0x2e, 0x43e, 0x431, 0x2e, 0x1014, 0x1036, 0x1014, 0x1000, 0x103a, 0x61, 0x2e, 0x20, 0x6d, 0x2e, 0x4e0a, 0x5348,
-0x64, 0x6f, 0x70, 0x2e, 0x61, 0x2e, 0x6d, 0x2e, 0x61, 0x6d, 0x61, 0x70, 0x2e, 0x6d, 0x61, 0x74, 0x69, 0x6e, 0x6d, 0x76,
-0x6f, 0x72, 0x6d, 0x2e, 0x3c0, 0x2e, 0x3bc, 0x2e, 0x5dc, 0x5e4, 0x5e0, 0x5d4, 0x5f4, 0x5e6, 0x92a, 0x942, 0x930, 0x94d, 0x935, 0x93e,
-0x939, 0x94d, 0x928, 0x64, 0x65, 0x2e, 0x66, 0x2e, 0x68, 0x2e, 0x5348, 0x524d, 0xcaa, 0xcc2, 0xcb0, 0xccd, 0xcb5, 0xcbe, 0xcb9, 0xccd,
-0xca8, 0x442, 0x430, 0x4a3, 0x43a, 0x44b, 0xc624, 0xc804, 0x5a, 0x2e, 0x4d, 0x55, 0x2e, 0xe81, 0xec8, 0xead, 0xe99, 0xe97, 0xec8, 0xebd,
-0xe87, 0x70, 0x72, 0x69, 0x65, 0x6b, 0x161, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6e, 0x74, 0x254, 0x301, 0x6e,
-0x67, 0x254, 0x301, 0x70, 0x72, 0x69, 0x65, 0x161, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x440, 0x435, 0x442, 0x43f, 0x43b, 0x430, 0x434,
-0x43d, 0x435, 0x50, 0x47, 0x92e, 0x2e, 0x92a, 0x942, 0x2e, 0x4af, 0x2e, 0x4e9, 0x63a, 0x2e, 0x645, 0x2e, 0x642, 0x628, 0x644, 0x200c,
-0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, 0x20, 0x6d, 0x61, 0x6e, 0x68, 0xe3, 0xa2a, 0xa42, 0x2e, 0xa26, 0xa41, 0x2e, 0x414,
-0x41f, 0x4e, 0x44, 0x43f, 0x440, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x43f, 0x440, 0x438, 0x458, 0x435, 0x20, 0x43f, 0x43e,
-0x434, 0x43d, 0x435, 0x70, 0x72, 0x69, 0x6a, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x70, 0x72, 0x65, 0x20, 0x70, 0x6f,
-0x64, 0x6e, 0x65, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20, 0x440, 0x430, 0x437, 0x43c, 0x4d5, 0xdb4, 0xdd9,
-0x2e, 0xdc0, 0x2e, 0x73, 0x6e, 0x2e, 0x41, 0x73, 0x75, 0x62, 0x75, 0x68, 0x69, 0x66, 0x6d, 0xbae, 0xbc1, 0xbb1, 0xbcd, 0xbaa,
-0xb95, 0xbb2, 0xbcd, 0xe01, 0xe48, 0xe2d, 0xe19, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf66, 0xf94, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b,
-0x1295, 0x1309, 0x1206, 0x20, 0x1230, 0x12d3, 0x1270, 0x68, 0x65, 0x6e, 0x67, 0x69, 0x68, 0x65, 0x6e, 0x67, 0x69, 0xd6, 0xd6, 0x686,
-0x6c8, 0x634, 0x62a, 0x649, 0x646, 0x20, 0x628, 0x6c7, 0x631, 0x6c7, 0x646, 0x434, 0x43f, 0x54, 0x4f, 0x422, 0x41e, 0x53, 0x41, 0x79,
-0x62, 0xc0, 0xe1, 0x72, 0x1ecd, 0x300, 0xc0, 0xe1, 0x72, 0x254, 0x300, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67,
+0x1275, 0x635, 0x53f, 0x531, 0x9aa, 0x9c2, 0x9f0, 0x9cd, 0x9ac, 0x9be, 0x9b9, 0x9cd, 0x9a8, 0x410, 0x41c, 0xf66, 0xf94, 0xf0b, 0xf46, 0xf0b,
+0x41, 0x2e, 0x4d, 0x2e, 0x43f, 0x440, 0x2e, 0x43e, 0x431, 0x2e, 0x1014, 0x1036, 0x1014, 0x1000, 0x103a, 0x61, 0x2e, 0x20, 0x6d, 0x2e,
+0x4e0a, 0x5348, 0x64, 0x6f, 0x70, 0x2e, 0x61, 0x2e, 0x6d, 0x2e, 0x61, 0x6d, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x2e, 0x6d, 0x61,
+0x74, 0x69, 0x6e, 0x6d, 0x3c0, 0x2e, 0x3bc, 0x2e, 0x5dc, 0x5e4, 0x5e0, 0x5d4, 0x5f4, 0x5e6, 0x92a, 0x942, 0x930, 0x94d, 0x935, 0x93e,
+0x939, 0x94d, 0x928, 0x64, 0x65, 0x2e, 0x66, 0x2e, 0x68, 0x2e, 0x72, 0x2e, 0x6e, 0x2e, 0x5348, 0x524d, 0xcaa, 0xcc2, 0xcb0, 0xccd,
+0xcb5, 0xcbe, 0xcb9, 0xccd, 0xca8, 0x442, 0x430, 0x4a3, 0x43a, 0x44b, 0xc624, 0xc804, 0x5a, 0x2e, 0x4d, 0x55, 0x2e, 0xe81, 0xec8, 0xead,
+0xe99, 0xe97, 0xec8, 0xebd, 0xe87, 0x70, 0x72, 0x69, 0x65, 0x6b, 0x161, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6e,
+0x74, 0x254, 0x301, 0x6e, 0x67, 0x254, 0x301, 0x70, 0x72, 0x69, 0x65, 0x161, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x440, 0x435, 0x442,
+0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x47, 0x92e, 0x2e, 0x92a, 0x942, 0x2e, 0x4af, 0x2e, 0x4e9, 0x63a, 0x2e, 0x645, 0x2e,
+0x642, 0x628, 0x644, 0x200c, 0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, 0x20, 0x6d, 0x61, 0x6e, 0x68, 0xe3, 0xa2a, 0xa42, 0x2e,
+0xa26, 0xa41, 0x2e, 0x4e, 0x44, 0x43f, 0x440, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x72, 0x69, 0x6a, 0x65, 0x20,
+0x70, 0x6f, 0x64, 0x6e, 0x65, 0x70, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x43f, 0x440, 0x438, 0x458, 0x435, 0x20,
+0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20, 0x440, 0x430, 0x437, 0x43c, 0x4d5,
+0x635, 0x628, 0x62d, 0x60c, 0x20, 0x645, 0x646, 0x62c, 0x647, 0x646, 0x62f, 0xdb4, 0xdd9, 0x2e, 0xdc0, 0x2e, 0x73, 0x6e, 0x2e, 0x66,
+0x6d, 0x43f, 0x435, 0x2e, 0x20, 0x447, 0x43e, 0x2e, 0xbae, 0xbc1, 0xbb1, 0xbcd, 0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe01, 0xe48, 0xe2d, 0xe19,
+0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf66, 0xf94, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b, 0x1295, 0x1309, 0x1206, 0x20, 0x1230, 0x12d3, 0x1270,
+0x68, 0x65, 0x6e, 0x67, 0x69, 0x68, 0x65, 0x6e, 0x67, 0x69, 0xd6, 0xd6, 0x67, 0xfc, 0x6e, 0x6f, 0x72, 0x74, 0x61, 0x64,
+0x61, 0x6e, 0x20, 0xf6, 0x148, 0x686, 0x6c8, 0x634, 0x62a, 0x649, 0x646, 0x20, 0x628, 0x6c7, 0x631, 0x6c7, 0x646, 0x434, 0x43f, 0x54,
+0x4f, 0x422, 0x41e, 0x53, 0x41, 0x79, 0x62, 0x53, 0x75, 0x62, 0x5e4, 0x5bf, 0x5d0, 0x5b7, 0x5e8, 0x5de, 0x5d9, 0x5d8, 0x5d0, 0x5b8,
+0x5d2, 0xc0, 0xe1, 0x72, 0x1ecd, 0x300, 0xc0, 0xe1, 0x72, 0x254, 0x300, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67,
0x70, 0x72, 0x69, 0x6a, 0x65, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x41, 0x4e, 0x128, 0x79, 0x61, 0x6b, 0x77, 0x61, 0x6b, 0x79,
0x61, 0x61, 0x2e, 0x14b, 0x64, 0x69, 0x61, 0x6d, 0x20, 0x56, 0x6f, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x61, 0x67, 0xa3b8, 0xa111,
-0x69, 0x111, 0x69, 0x74, 0x62, 0x65, 0x61, 0x69, 0x76, 0x65, 0x74, 0x4d, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x4c, 0x75, 0x6d,
-0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x4b, 0x73, 0x75, 0x62, 0x61, 0x6b, 0x61, 0x4b, 0x69, 0x72, 0x6f, 0x6b, 0x6f, 0x54,
-0x65, 0x73, 0x69, 0x72, 0x61, 0x6e, 0x6b, 0x61, 0x6e, 0x67, 0x2019, 0x61, 0x6d, 0x61, 0x2d5c, 0x2d49, 0x2d3c, 0x2d30, 0x2d61, 0x2d5c,
-0x74, 0x69, 0x66, 0x61, 0x77, 0x74, 0x6e, 0x20, 0x74, 0x75, 0x66, 0x61, 0x74, 0x70, 0x61, 0x6d, 0x69, 0x6c, 0x61, 0x75,
-0x75, 0x74, 0x75, 0x6b, 0x6f, 0x4b, 0x49, 0x13cc, 0x13be, 0x13b4, 0x4d, 0x75, 0x68, 0x69, 0x54, 0x4f, 0x4f, 0x75, 0x6c, 0x75,
-0x63, 0x68, 0x65, 0x6c, 0x6f, 0x52, 0x168, 0x6b, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x1c1, 0x67, 0x6f, 0x61, 0x67, 0x61, 0x73,
-0x55, 0x68, 0x72, 0x20, 0x76, 0xf6, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x61, 0x63, 0x68, 0x73, 0x190, 0x6e, 0x6b, 0x61,
-0x6b, 0x25b, 0x6e, 0x79, 0xe1, 0x4d, 0x75, 0x6e, 0x6b, 0x79, 0x6f, 0x69, 0x63, 0x68, 0x65, 0x68, 0x65, 0x61, 0x76, 0x6f,
-0x54, 0x61, 0x70, 0x61, 0x72, 0x61, 0x63, 0x68, 0x75, 0x41, 0x64, 0x64, 0x75, 0x68, 0x61, 0x4f, 0x44, 0x5a, 0x64, 0x61,
-0x74, 0x20, 0x61, 0x7a, 0x61, 0x6c, 0x6d, 0x61, 0x6b, 0x65, 0x6f, 0x92b, 0x941, 0x902, 0x44, 0x69, 0x6e, 0x64, 0x61, 0x6d,
-0x6f, 0x69, 0x65, 0x73, 0x61, 0x2e, 0x67, 0x49, 0x20, 0x62, 0x69, 0x6b, 0x25b, 0x302, 0x67, 0x6c, 0xe0, 0x53, 0x75, 0x62,
-0x62, 0x61, 0x61, 0x68, 0x69, 0x69, 0x64, 0x69, 0x253, 0x61, 0x6b, 0xed, 0x6b, 0xed, 0x72, 0xed, 0x67, 0x73, 0xe1, 0x72,
-0xfa, 0x77, 0xe1, 0x77, 0x69, 0x63, 0x68, 0x69, 0x73, 0x68, 0x75, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6d, 0x61, 0x6e, 0xe1,
-0x52, 0x57, 0x42d, 0x418, 0x4c, 0x77, 0x61, 0x6d, 0x69, 0x6c, 0x61, 0x77, 0x75, 0x6b, 0x69, 0x25b, 0x6d, 0x25b, 0x301, 0x25b,
-0x6d, 0x64, 0x65, 0x20, 0x6c, 0x61, 0x20, 0x6d, 0x61, 0xf1, 0x61, 0x6e, 0x61, 0x6d, 0x62, 0x61, 0xa78c, 0x6d, 0x62, 0x61,
-0xa78c, 0x6d, 0x62, 0x61, 0x2bc, 0xe1, 0x6d, 0x62, 0x61, 0x2bc, 0x628, 0x2e, 0x646, 0x64, 0x6f, 0x70, 0x6f, 0x142, 0x64, 0x6e,
-0x6a, 0x61, 0x69, 0x70, 0x2e
+0x69, 0x111, 0x69, 0x74, 0x62, 0x65, 0x61, 0x69, 0x76, 0x65, 0x74, 0x69, 0x62, 0x4d, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x4c,
+0x75, 0x6d, 0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x4b, 0x73, 0x75, 0x62, 0x61, 0x6b, 0x61, 0x4b, 0x69, 0x72, 0x6f, 0x6b,
+0x6f, 0x54, 0x65, 0x73, 0x69, 0x72, 0x61, 0x6e, 0x6b, 0x61, 0x6e, 0x67, 0x2019, 0x61, 0x6d, 0x61, 0x2d5c, 0x2d49, 0x2d3c, 0x2d30,
+0x2d61, 0x2d5c, 0x74, 0x69, 0x66, 0x61, 0x77, 0x74, 0x6e, 0x20, 0x74, 0x75, 0x66, 0x61, 0x74, 0x70, 0x61, 0x6d, 0x69, 0x6c,
+0x61, 0x75, 0x75, 0x74, 0x75, 0x6b, 0x6f, 0x4b, 0x49, 0x13cc, 0x13be, 0x13b4, 0x4d, 0x75, 0x68, 0x69, 0x54, 0x4f, 0x4f, 0x75,
+0x6c, 0x75, 0x63, 0x68, 0x65, 0x6c, 0x6f, 0x52, 0x168, 0x6b, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x1c1, 0x67, 0x6f, 0x61, 0x67,
+0x61, 0x73, 0x55, 0x68, 0x72, 0x20, 0x76, 0xf6, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x61, 0x63, 0x68, 0x73, 0x190, 0x6e,
+0x6b, 0x61, 0x6b, 0x25b, 0x6e, 0x79, 0xe1, 0x4d, 0x75, 0x6e, 0x6b, 0x79, 0x6f, 0x69, 0x63, 0x68, 0x65, 0x68, 0x65, 0x61,
+0x76, 0x6f, 0x54, 0x61, 0x70, 0x61, 0x72, 0x61, 0x63, 0x68, 0x75, 0x41, 0x64, 0x64, 0x75, 0x68, 0x61, 0x4f, 0x44, 0x5a,
+0x64, 0x61, 0x74, 0x20, 0x61, 0x7a, 0x61, 0x6c, 0x6d, 0x61, 0x6b, 0x65, 0x6f, 0x92b, 0x941, 0x902, 0x44, 0x69, 0x6e, 0x64,
+0x61, 0x6d, 0x6f, 0x69, 0x65, 0x73, 0x61, 0x2e, 0x67, 0x49, 0x20, 0x62, 0x69, 0x6b, 0x25b, 0x302, 0x67, 0x6c, 0xe0, 0x53,
+0x75, 0x62, 0x62, 0x61, 0x61, 0x68, 0x69, 0x69, 0x64, 0x69, 0x253, 0x61, 0x6b, 0xed, 0x6b, 0xed, 0x72, 0xed, 0x67, 0x73,
+0xe1, 0x72, 0xfa, 0x77, 0xe1, 0x77, 0x69, 0x63, 0x68, 0x69, 0x73, 0x68, 0x75, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6d, 0x61,
+0x6e, 0xe1, 0x52, 0x57, 0x42d, 0x418, 0x4c, 0x77, 0x61, 0x6d, 0x69, 0x6c, 0x61, 0x77, 0x75, 0x6b, 0x69, 0x25b, 0x6d, 0x25b,
+0x301, 0x25b, 0x6d, 0x64, 0x65, 0x20, 0x6c, 0x61, 0x20, 0x6d, 0x61, 0xf1, 0x61, 0x6e, 0x61, 0x6d, 0x62, 0x61, 0xa78c, 0x6d,
+0x62, 0x61, 0xa78c, 0x6d, 0x62, 0x61, 0x2bc, 0xe1, 0x6d, 0x62, 0x61, 0x2bc, 0x628, 0x2e, 0x646, 0x64, 0x6f, 0x70, 0x6f, 0x142,
+0x64, 0x6e, 0x6a, 0x61, 0x69, 0x70, 0x2e
};
static const ushort pm_data[] = {
0x50, 0x4d, 0x57, 0x42, 0x6e, 0x6d, 0x2e, 0x65, 0x20, 0x70, 0x61, 0x73, 0x64, 0x69, 0x74, 0x65, 0x73, 0x12a8, 0x1230, 0x12d3,
-0x1275, 0x645, 0x985, 0x9aa, 0x9f0, 0x9be, 0x9b9, 0x9cd, 0x9a3, 0x41f, 0x41c, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf46, 0xf0b, 0x47, 0x2e, 0x4d,
-0x2e, 0x441, 0x43b, 0x2e, 0x43e, 0x431, 0x2e, 0x100a, 0x1014, 0x1031, 0x70, 0x2e, 0x20, 0x6d, 0x2e, 0x4e0b, 0x5348, 0x6f, 0x64, 0x70,
-0x2e, 0x70, 0x2e, 0x6d, 0x2e, 0x70, 0x6d, 0x69, 0x70, 0x2e, 0x73, 0x6f, 0x69, 0x72, 0x66, 0x6e, 0x61, 0x63, 0x68, 0x6d,
-0x2e, 0x3bc, 0x2e, 0x3bc, 0x2e, 0x5d0, 0x5d7, 0x5d4, 0x5f4, 0x5e6, 0x905, 0x92a, 0x930, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x75, 0x2e,
-0x65, 0x2e, 0x68, 0x2e, 0x5348, 0x5f8c, 0xc85, 0xcaa, 0xcb0, 0xcbe, 0xcb9, 0xccd, 0xca8, 0x442, 0x4af, 0x448, 0x442, 0x4e9, 0x43d, 0x20,
-0x43a, 0x438, 0x439, 0x438, 0x43d, 0x43a, 0x438, 0xc624, 0xd6c4, 0x5a, 0x2e, 0x4d, 0x57, 0x2e, 0xeab, 0xebc, 0xeb1, 0xe87, 0xe97, 0xec8,
-0xebd, 0xe87, 0x70, 0x113, 0x63, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6d, 0x70, 0xf3, 0x6b, 0x77, 0x61, 0x70,
-0x6f, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x43e, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x54, 0x47, 0x92e, 0x2e, 0x909, 0x2e,
-0x4af, 0x2e, 0x445, 0x63a, 0x2e, 0x648, 0x2e, 0x628, 0x639, 0x62f, 0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, 0x20, 0x74, 0x61,
-0x72, 0x64, 0x65, 0xa2c, 0xa3e, 0x2e, 0xa26, 0xa41, 0x2e, 0x41f, 0x41f, 0x4c, 0x4b, 0x43f, 0x43e, 0x20, 0x43f, 0x43e, 0x434, 0x43d,
-0x435, 0x70, 0x6f, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20, 0x444,
-0x4d5, 0x441, 0x442, 0x4d5, 0xdb4, 0x2e, 0xdc0, 0x2e, 0x70, 0x6f, 0x70, 0x2e, 0x67, 0x6e, 0x2e, 0x4d, 0x63, 0x68, 0x61, 0x6e,
-0x61, 0x65, 0x6d, 0xbaa, 0xbbf, 0xbb1, 0xbcd, 0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe2b, 0xe25, 0xe31, 0xe07, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22,
-0xe07, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b, 0x12f5, 0x1215, 0x122d, 0x20, 0x1230, 0x12d3, 0x1275, 0x65, 0x66, 0x69, 0x61,
-0x66, 0x69, 0xd6, 0x53, 0x686, 0x6c8, 0x634, 0x62a, 0x649, 0x646, 0x20, 0x643, 0x6d0, 0x64a, 0x649, 0x646, 0x43f, 0x43f, 0x54, 0x4b,
-0x422, 0x41a, 0x43, 0x48, 0x79, 0x68, 0x1ecc, 0x300, 0x73, 0xe1, 0x6e, 0x186, 0x300, 0x73, 0xe1, 0x6e, 0x65, 0x74, 0x74, 0x65,
+0x1275, 0x645, 0x53f, 0x540, 0x985, 0x9aa, 0x9f0, 0x9be, 0x9b9, 0x9cd, 0x9a8, 0x41f, 0x41c, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf46, 0xf0b, 0x47,
+0x2e, 0x4d, 0x2e, 0x441, 0x43b, 0x2e, 0x43e, 0x431, 0x2e, 0x100a, 0x1014, 0x1031, 0x70, 0x2e, 0x20, 0x6d, 0x2e, 0x4e0b, 0x5348, 0x6f,
+0x64, 0x70, 0x2e, 0x70, 0x2e, 0x6d, 0x2e, 0x70, 0x6d, 0x70, 0x74, 0x6d, 0x69, 0x70, 0x2e, 0x73, 0x6f, 0x69, 0x72, 0x66,
+0x3bc, 0x2e, 0x3bc, 0x2e, 0x5d0, 0x5d7, 0x5d4, 0x5f4, 0x5e6, 0x905, 0x92a, 0x930, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x75, 0x2e, 0x65,
+0x2e, 0x68, 0x2e, 0x69, 0x2e, 0x6e, 0x2e, 0x5348, 0x5f8c, 0xc85, 0xcaa, 0xcb0, 0xcbe, 0xcb9, 0xccd, 0xca8, 0x442, 0x4af, 0x448, 0x442,
+0x4e9, 0x43d, 0x20, 0x43a, 0x438, 0x439, 0x438, 0x43d, 0x43a, 0x438, 0xc624, 0xd6c4, 0x5a, 0x2e, 0x4d, 0x57, 0x2e, 0xeab, 0xebc, 0xeb1,
+0xe87, 0xe97, 0xec8, 0xebd, 0xe87, 0x70, 0x113, 0x63, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6d, 0x70, 0xf3, 0x6b,
+0x77, 0x61, 0x70, 0x6f, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x43e, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x54, 0x47, 0x92e,
+0x2e, 0x909, 0x2e, 0x4af, 0x2e, 0x445, 0x63a, 0x2e, 0x648, 0x2e, 0x628, 0x639, 0x62f, 0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61,
+0x20, 0x74, 0x61, 0x72, 0x64, 0x65, 0xa2c, 0xa3e, 0x2e, 0xa26, 0xa41, 0x2e, 0x4c, 0x4b, 0x43f, 0x43e, 0x20, 0x43f, 0x43e, 0x434,
+0x43d, 0x435, 0x70, 0x6f, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20,
+0x444, 0x4d5, 0x441, 0x442, 0x4d5, 0x645, 0x646, 0x62c, 0x647, 0x646, 0x62f, 0x60c, 0x20, 0x634, 0x627, 0x645, 0xdb4, 0x2e, 0xdc0, 0x2e,
+0x70, 0x6f, 0x70, 0x2e, 0x67, 0x6e, 0x2e, 0x65, 0x6d, 0x43f, 0x430, 0x2e, 0x20, 0x447, 0x43e, 0x2e, 0xbaa, 0xbbf, 0xbb1, 0xbcd,
+0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe2b, 0xe25, 0xe31, 0xe07, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf51, 0xfb2,
+0xf7c, 0xf0b, 0x12f5, 0x1215, 0x122d, 0x20, 0x1230, 0x12d3, 0x1275, 0x65, 0x66, 0x69, 0x61, 0x66, 0x69, 0xd6, 0x53, 0x67, 0xfc, 0x6e,
+0x6f, 0x72, 0x74, 0x61, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x6f, 0x148, 0x686, 0x6c8, 0x634, 0x62a, 0x649, 0x646, 0x20, 0x643, 0x6d0,
+0x64a, 0x649, 0x646, 0x43f, 0x43f, 0x54, 0x4b, 0x422, 0x41a, 0x43, 0x48, 0x79, 0x68, 0x4e, 0x67, 0x6f, 0x5e0, 0x5d0, 0x5b8, 0x5db,
+0x5de, 0x5d9, 0x5d8, 0x5d0, 0x5b8, 0x5d2, 0x1ecc, 0x300, 0x73, 0xe1, 0x6e, 0x186, 0x300, 0x73, 0xe1, 0x6e, 0x65, 0x74, 0x74, 0x65,
0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67, 0x70, 0x6f, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x43f, 0x43e, 0x43f, 0x43e, 0x434, 0x43d,
0x435, 0x45, 0x57, 0x92e, 0x2e, 0x928, 0x902, 0x2e, 0x50, 0x2e, 0x4d, 0x2e, 0x128, 0x79, 0x61, 0x77, 0x129, 0x6f, 0x6f, 0x70,
0x2e, 0x263, 0x65, 0x74, 0x72, 0x254, 0x61, 0x6d, 0x20, 0x4e, 0x61, 0x6d, 0x69, 0x74, 0x74, 0x61, 0x67, 0xa06f, 0xa2d2, 0x65,
-0x61, 0x68, 0x6b, 0x65, 0x74, 0x62, 0x65, 0x61, 0x69, 0x76, 0x65, 0x74, 0x4d, 0x6f, 0x67, 0x6c, 0x75, 0x6d, 0x61, 0x20,
-0x6c, 0x77, 0x61, 0x20, 0x70, 0x6b, 0x69, 0x6b, 0x69, 0x69, 0x257, 0x65, 0x48, 0x77, 0x61, 0x129, 0x2d, 0x69, 0x6e, 0x129,
-0x54, 0x65, 0x69, 0x70, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6f, 0x74, 0x6f, 0x2d5c, 0x2d30, 0x2d37, 0x2d33, 0x2d33, 0x2d6f, 0x2d30, 0x2d5c,
-0x74, 0x61, 0x64, 0x67, 0x67, 0x2b7, 0x61, 0x74, 0x6e, 0x20, 0x74, 0x6d, 0x65, 0x64, 0x64, 0x69, 0x74, 0x70, 0x61, 0x6d,
-0x75, 0x6e, 0x79, 0x69, 0x6b, 0x79, 0x69, 0x75, 0x6b, 0x6f, 0x6e, 0x79, 0x69, 0x55, 0x54, 0x13d2, 0x13af, 0x13f1, 0x13a2, 0x13d7,
-0x13e2, 0x43, 0x68, 0x69, 0x6c, 0x6f, 0x4d, 0x55, 0x55, 0x61, 0x6b, 0x61, 0x73, 0x75, 0x62, 0x61, 0x168, 0x47, 0x6b, 0x6f,
-0x6f, 0x73, 0x6b, 0x6f, 0x6c, 0x69, 0x6e, 0x79, 0x1c3, 0x75, 0x69, 0x61, 0x73, 0x55, 0x68, 0x72, 0x20, 0x6e, 0x6f, 0x6d,
-0x6d, 0x65, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x73, 0x190, 0x6e, 0x64, 0xe1, 0x6d, 0xe2, 0x45, 0x69, 0x67, 0x75, 0x6c,
-0x6f, 0x69, 0x63, 0x68, 0x61, 0x6d, 0x74, 0x68, 0x69, 0x45, 0x62, 0x6f, 0x6e, 0x67, 0x69, 0x41, 0x6c, 0x75, 0x75, 0x6c,
-0x61, 0x4f, 0x54, 0x1e0c, 0x65, 0x66, 0x66, 0x69, 0x72, 0x20, 0x61, 0x7a, 0x61, 0x6e, 0x79, 0x69, 0x61, 0x67, 0x68, 0x75,
-0x6f, 0x92c, 0x947, 0x932, 0x93e, 0x938, 0x947, 0x44, 0x69, 0x6c, 0x6f, 0x6c, 0x6f, 0x6e, 0x6f, 0x6d, 0xeb, 0x74, 0x74, 0x65,
-0x73, 0x61, 0x2e, 0x6b, 0x49, 0x20, 0x253, 0x75, 0x67, 0x61, 0x6a, 0x254, 0x70, 0x5a, 0x61, 0x61, 0x72, 0x69, 0x6b, 0x61,
-0x79, 0x20, 0x62, 0x65, 0x62, 0x79, 0xe1, 0x6d, 0x75, 0x6e, 0x67, 0x259, 0x67, 0xf3, 0x67, 0x259, 0x6c, 0x65, 0x63, 0x25b,
-0x25b, 0x301, 0x6e, 0x6b, 0x6f, 0x6d, 0x63, 0x68, 0x6f, 0x63, 0x68, 0x69, 0x6c, 0x2019, 0x6c, 0x6c, 0x69, 0x6c, 0x6c, 0x69,
-0x6b, 0x75, 0x67, 0xfa, 0x54, 0x14a, 0x42d, 0x41a, 0x50, 0x61, 0x73, 0x68, 0x61, 0x6d, 0x69, 0x68, 0x65, 0x6b, 0x69, 0x73,
-0x25b, 0x301, 0x6e, 0x64, 0x25b, 0x64, 0x65, 0x20, 0x6c, 0x61, 0x20, 0x74, 0x61, 0x72, 0x64, 0x65, 0x14b, 0x6b, 0x61, 0x20,
-0x6d, 0x62, 0x254, 0x301, 0x74, 0x20, 0x6e, 0x6a, 0x69, 0x6e, 0x63, 0x77, 0xf2, 0x6e, 0x7a, 0xe9, 0x6d, 0x62f, 0x2e, 0x646,
-0x77, 0xf3, 0x74, 0x70, 0x6f, 0x142, 0x64, 0x6e, 0x6a, 0x61, 0x70, 0x6f, 0x70, 0x6f, 0x142, 0x64, 0x6e, 0x6a, 0x75, 0x65,
-0x70, 0x2e
+0x61, 0x68, 0x6b, 0x65, 0x74, 0x62, 0x65, 0x61, 0x69, 0x76, 0x65, 0x74, 0x65, 0x62, 0x4d, 0x6f, 0x67, 0x6c, 0x75, 0x6d,
+0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x70, 0x6b, 0x69, 0x6b, 0x69, 0x69, 0x257, 0x65, 0x48, 0x77, 0x61, 0x129, 0x2d, 0x69,
+0x6e, 0x129, 0x54, 0x65, 0x69, 0x70, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6f, 0x74, 0x6f, 0x2d5c, 0x2d30, 0x2d37, 0x2d33, 0x2d33, 0x2d6f,
+0x2d30, 0x2d5c, 0x74, 0x61, 0x64, 0x67, 0x67, 0x2b7, 0x61, 0x74, 0x6e, 0x20, 0x74, 0x6d, 0x65, 0x64, 0x64, 0x69, 0x74, 0x70,
+0x61, 0x6d, 0x75, 0x6e, 0x79, 0x69, 0x6b, 0x79, 0x69, 0x75, 0x6b, 0x6f, 0x6e, 0x79, 0x69, 0x55, 0x54, 0x13d2, 0x13af, 0x13f1,
+0x13a2, 0x13d7, 0x13e2, 0x43, 0x68, 0x69, 0x6c, 0x6f, 0x4d, 0x55, 0x55, 0x61, 0x6b, 0x61, 0x73, 0x75, 0x62, 0x61, 0x168, 0x47,
+0x6b, 0x6f, 0x6f, 0x73, 0x6b, 0x6f, 0x6c, 0x69, 0x6e, 0x79, 0x1c3, 0x75, 0x69, 0x61, 0x73, 0x55, 0x68, 0x72, 0x20, 0x6e,
+0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x73, 0x190, 0x6e, 0x64, 0xe1, 0x6d, 0xe2, 0x45, 0x69, 0x67,
+0x75, 0x6c, 0x6f, 0x69, 0x63, 0x68, 0x61, 0x6d, 0x74, 0x68, 0x69, 0x45, 0x62, 0x6f, 0x6e, 0x67, 0x69, 0x41, 0x6c, 0x75,
+0x75, 0x6c, 0x61, 0x4f, 0x54, 0x1e0c, 0x65, 0x66, 0x66, 0x69, 0x72, 0x20, 0x61, 0x7a, 0x61, 0x6e, 0x79, 0x69, 0x61, 0x67,
+0x68, 0x75, 0x6f, 0x92c, 0x947, 0x932, 0x93e, 0x938, 0x947, 0x44, 0x69, 0x6c, 0x6f, 0x6c, 0x6f, 0x6e, 0x6f, 0x6d, 0xeb, 0x74,
+0x74, 0x65, 0x73, 0x61, 0x2e, 0x6b, 0x49, 0x20, 0x253, 0x75, 0x67, 0x61, 0x6a, 0x254, 0x70, 0x5a, 0x61, 0x61, 0x72, 0x69,
+0x6b, 0x61, 0x79, 0x20, 0x62, 0x65, 0x62, 0x79, 0xe1, 0x6d, 0x75, 0x6e, 0x67, 0x259, 0x67, 0xf3, 0x67, 0x259, 0x6c, 0x65,
+0x63, 0x25b, 0x25b, 0x301, 0x6e, 0x6b, 0x6f, 0x6d, 0x63, 0x68, 0x6f, 0x63, 0x68, 0x69, 0x6c, 0x2019, 0x6c, 0x6c, 0x69, 0x6c,
+0x6c, 0x69, 0x6b, 0x75, 0x67, 0xfa, 0x54, 0x14a, 0x42d, 0x41a, 0x50, 0x61, 0x73, 0x68, 0x61, 0x6d, 0x69, 0x68, 0x65, 0x6b,
+0x69, 0x73, 0x25b, 0x301, 0x6e, 0x64, 0x25b, 0x64, 0x65, 0x20, 0x6c, 0x61, 0x20, 0x74, 0x61, 0x72, 0x64, 0x65, 0x14b, 0x6b,
+0x61, 0x20, 0x6d, 0x62, 0x254, 0x301, 0x74, 0x20, 0x6e, 0x6a, 0x69, 0x6e, 0x63, 0x77, 0xf2, 0x6e, 0x7a, 0xe9, 0x6d, 0x62f,
+0x2e, 0x646, 0x77, 0xf3, 0x74, 0x70, 0x6f, 0x142, 0x64, 0x6e, 0x6a, 0x61, 0x70, 0x6f, 0x70, 0x6f, 0x142, 0x64, 0x6e, 0x6a,
+0x75, 0x65, 0x70, 0x2e
};
static const ushort currency_symbol_data[] = {
0x42, 0x72, 0x4b, 0x73, 0x68, 0x52, 0x24, 0x4c, 0x65, 0x6b, 0xeb, 0x64, 0x65, 0x6e, 0x20ac, 0x1265, 0x122d, 0x62c, 0x2e, 0x645,
-0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43, 0x46, 0x41, 0x641, 0x2e, 0x62c, 0x2e,
-0x642, 0x2e, 0x200f, 0x46, 0x64, 0x6a, 0x4e, 0x66, 0x6b, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f,
-0x62f, 0x2e, 0x643, 0x2e, 0x200f, 0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x623, 0x2e, 0x645, 0x2e, 0x200f,
-0x62f, 0x2e, 0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f, 0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f,
-0x53, 0x62c, 0x2e, 0x633, 0x2e, 0x644, 0x2e, 0x633, 0x2e, 0x200f, 0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f,
-0x631, 0x2e, 0x64a, 0x2e, 0x200f, 0xa3, 0x58f, 0x20b9, 0x20bc, 0x20bd, 0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b, 0x17db, 0xffe5,
-0x48, 0x4b, 0x24, 0x4d, 0x4f, 0x50, 0x24, 0x48, 0x52, 0x4b, 0x4b, 0x4d, 0x4b, 0x10d, 0x6b, 0x72, 0x2e, 0x41, 0x66, 0x6c,
-0x2e, 0x4e, 0x41, 0x66, 0x2e, 0x55, 0x53, 0x24, 0x50, 0x46, 0x42, 0x75, 0x44, 0x47, 0x48, 0x20b5, 0x41, 0x72, 0x4d, 0x4b,
-0x52, 0x4d, 0x52, 0x73, 0x20a6, 0x20b1, 0x52, 0x46, 0x57, 0x53, 0x24, 0x53, 0x52, 0x4c, 0x65, 0x45, 0x6b, 0x72, 0x54, 0x53,
-0x68, 0x54, 0x24, 0x55, 0x53, 0x68, 0x56, 0x54, 0x44, 0x41, 0x43, 0x46, 0x41, 0x43, 0x46, 0x46, 0x43, 0x46, 0x43, 0x46,
-0x50, 0x46, 0x47, 0x47, 0x55, 0x4d, 0x4d, 0x41, 0x44, 0x43, 0x48, 0x46, 0x4c, 0x53, 0x44, 0x54, 0x20be, 0x20b2, 0x46, 0x74,
-0x49, 0x53, 0x4b, 0x52, 0x70, 0x43, 0x41, 0x24, 0x20b8, 0x441, 0x43e, 0x43c, 0x20a9, 0x4b, 0x50, 0x57, 0x20ba, 0x20ad, 0x4b, 0x7a,
-0x434, 0x435, 0x43d, 0x4e, 0x5a, 0x24, 0x20ae, 0x43, 0x4e, 0xa5, 0x928, 0x947, 0x930, 0x942, 0x60b, 0x631, 0x6cc, 0x627, 0x644, 0x7a,
-0x142, 0x52, 0x24, 0x200b, 0x4d, 0x54, 0x6e, 0x44, 0x62, 0x631, 0x53, 0x2f, 0x42, 0x73, 0x52, 0x4f, 0x4e, 0x4c, 0x20b4, 0x52,
-0x53, 0x44, 0x41a, 0x41c, 0xdbb, 0xdd4, 0x2e, 0x20a1, 0x52, 0x44, 0x24, 0x51, 0x43, 0x24, 0x42, 0x2f, 0x2e, 0x47, 0x73, 0x2e,
-0x42, 0x73, 0x2e, 0x52, 0x73, 0x2e, 0x54, 0x48, 0x42, 0xa5, 0x54, 0x4d, 0x54, 0x73, 0x6f, 0x2bb, 0x6d, 0x441, 0x45e, 0x43c,
-0x20ab, 0x4e, 0x54, 0x24, 0x41, 0x24, 0x49, 0x52, 0x52
+0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43, 0x46, 0x41, 0x43, 0x46, 0x46, 0x64,
+0x6a, 0x4e, 0x66, 0x6b, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f, 0x62f, 0x2e, 0x643, 0x2e, 0x200f,
+0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f,
+0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f, 0x53, 0x62c, 0x2e, 0x633, 0x2e, 0x644, 0x2e, 0x633, 0x2e, 0x200f,
+0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f, 0x631, 0x2e, 0x64a, 0x2e, 0x200f, 0xa3, 0x58f, 0x20b9, 0x20bc, 0x20bd,
+0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b, 0x17db, 0xffe5, 0x48, 0x4b, 0x24, 0x4d, 0x4f, 0x50, 0x24, 0x48, 0x52, 0x4b,
+0x4b, 0x4d, 0x4b, 0x10d, 0x6b, 0x72, 0x2e, 0x41, 0x66, 0x6c, 0x2e, 0x4e, 0x41, 0x66, 0x2e, 0x55, 0x53, 0x24, 0x50, 0x46,
+0x42, 0x75, 0x44, 0x47, 0x48, 0x20b5, 0x41, 0x72, 0x4d, 0x4b, 0x52, 0x4d, 0x52, 0x73, 0x20a6, 0x20b1, 0x52, 0x46, 0x57, 0x53,
+0x24, 0x53, 0x52, 0x4c, 0x65, 0x45, 0x6b, 0x72, 0x54, 0x53, 0x68, 0x54, 0x24, 0x55, 0x53, 0x68, 0x56, 0x54, 0x44, 0x41,
+0x43, 0x46, 0x41, 0x46, 0x43, 0x46, 0x43, 0x46, 0x50, 0x46, 0x47, 0x47, 0x55, 0x4d, 0x4d, 0x41, 0x44, 0x43, 0x48, 0x46,
+0x4c, 0x53, 0x44, 0x54, 0x20be, 0x20b2, 0x46, 0x74, 0x49, 0x53, 0x4b, 0x52, 0x70, 0x43, 0x41, 0x24, 0x20b8, 0x441, 0x43e, 0x43c,
+0x20a9, 0x4b, 0x50, 0x57, 0x20ba, 0x20ad, 0x4b, 0x7a, 0x434, 0x435, 0x43d, 0x4e, 0x5a, 0x24, 0x20ae, 0x43, 0x4e, 0xa5, 0x928, 0x947,
+0x930, 0x942, 0x60b, 0x631, 0x6cc, 0x627, 0x644, 0x7a, 0x142, 0x52, 0x24, 0x200b, 0x4d, 0x54, 0x6e, 0x44, 0x62, 0x631, 0x53, 0x2f,
+0x42, 0x73, 0x52, 0x4f, 0x4e, 0x4c, 0x20b4, 0x52, 0x53, 0x44, 0x41a, 0x41c, 0xdbb, 0xdd4, 0x2e, 0x20a1, 0x52, 0x44, 0x24, 0x51,
+0x43, 0x24, 0x42, 0x2f, 0x2e, 0x47, 0x73, 0x2e, 0x42, 0x73, 0x2e, 0x441, 0x43e, 0x43c, 0x2e, 0x52, 0x73, 0x2e, 0x54, 0x48,
+0x42, 0xa5, 0x54, 0x4d, 0x54, 0x73, 0x6f, 0x2bb, 0x6d, 0x441, 0x45e, 0x43c, 0x20ab, 0x4e, 0x54, 0x24, 0x41, 0x24, 0x49, 0x52,
+0x52
};
static const ushort currency_display_name_data[] = {
@@ -5124,726 +5278,740 @@ static const ushort currency_display_name_data[] = {
0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x627, 0x62a, 0x20, 0x62c, 0x646, 0x648, 0x628, 0x20,
0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x64b, 0x627, 0x20, 0x62c, 0x646, 0x648, 0x628, 0x20,
0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644,
-0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b,
+0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x570, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b,
0x3b, 0x570, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x3b, 0x3b, 0x570, 0x561,
-0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63,
-0x61, 0x6e, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61,
-0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63,
-0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x43c, 0x430, 0x43d, 0x430, 0x442, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72,
-0x6f, 0x3b, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x3b, 0x9ac, 0x9be,
-0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ac, 0x9be, 0x982, 0x9b2,
-0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0,
-0x9c1, 0x9aa, 0x9bf, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf, 0x3b, 0x3b, 0x3b,
-0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf, 0x3b, 0xf51, 0xf44, 0xf74, 0xf63, 0xf0b, 0xf40,
-0xfb2, 0xf58, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b,
-0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x61, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x69, 0x6f, 0xf9, 0x3b,
-0x65, 0x75, 0x72, 0x6f, 0x3b, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b,
-0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x44a, 0x43b,
-0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x430, 0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x1000, 0x103b,
-0x1015, 0x103a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x1000, 0x103b, 0x1015, 0x103a, 0x3b, 0x431,
-0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443, 0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b,
-0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443, 0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x430, 0x440,
-0x443, 0x441, 0x43a, 0x456, 0x44f, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x456, 0x3b, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a,
-0x456, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x451, 0x45e, 0x3b, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x430, 0x433,
-0x430, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x179a, 0x17c0, 0x179b, 0x200b, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x179a, 0x17c0, 0x179b, 0x200b, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x3b, 0x65, 0x75, 0x72,
-0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x4eba, 0x6c11, 0x5e01,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4eba, 0x6c11, 0x5e01, 0x3b, 0x6e2f, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5143,
-0x3b, 0x6fb3, 0x95e8, 0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x95e8, 0x5143, 0x3b, 0x65b0, 0x52a0, 0x5761, 0x5143, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x52a0, 0x5761, 0x5143, 0x3b, 0x6fb3, 0x9580, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x9580,
-0x5143, 0x3b, 0x65b0, 0x53f0, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x53f0, 0x5e63, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74,
-0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b,
-0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x65, 0x3b, 0x3b,
-0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65,
-0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76,
-0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e,
-0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x3b, 0x6b, 0x6f,
-0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b,
-0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20,
-0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79,
-0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xfd, 0x63,
-0x68, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b,
-0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73,
-0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f,
-0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67,
-0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c,
-0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c,
-0x64, 0x65, 0x6e, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c,
-0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65,
-0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20,
-0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73,
-0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e,
-0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
-0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b,
-0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b,
-0x3b, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x55, 0x53, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
-0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20,
-0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x45, 0x61,
-0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x3b, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c,
-0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c,
-0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65,
-0x75, 0x72, 0x6f, 0x73, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
-0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b,
-0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x61,
-0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x72, 0x62,
-0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x72, 0x62,
-0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65,
-0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73,
-0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x65,
-0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x65, 0x72,
-0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61,
-0x6e, 0x61, 0x6e, 0x20, 0x50, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20,
-0x70, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x70, 0x75,
-0x6c, 0x61, 0x73, 0x3b, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x3b,
-0x3b, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x3b, 0x3b,
-0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x3b, 0x43, 0x65, 0x6e,
-0x74, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x43, 0x46, 0x41, 0x20, 0x46, 0x72, 0x61,
-0x6e, 0x63, 0x3b, 0x3b, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20,
-0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c,
-0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x3b,
-0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x43, 0x61, 0x6e,
-0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61,
-0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20,
-0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d,
-0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b,
+0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20,
+0x9f0, 0x9c1, 0x9aa, 0x9c0, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9f0, 0x9c1, 0x9aa, 0x9c0, 0x3b, 0x3b,
+0x3b, 0x3b, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9f0, 0x9c1, 0x9aa, 0x9c0, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62,
+0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61,
+0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62,
+0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x43c, 0x430, 0x43d, 0x430, 0x442, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
+0x65, 0x75, 0x72, 0x6f, 0x3b, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b,
+0x3b, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ac,
+0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af,
+0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf,
+0x3b, 0x3b, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf, 0x3b, 0xf51, 0xf44, 0xf74,
+0xf63, 0xf0b, 0xf40, 0xfb2, 0xf58, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75,
+0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x61, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x69,
+0x6f, 0xf9, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435,
+0x432, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x3b, 0x3b,
+0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x430, 0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019,
+0x102c, 0x20, 0x1000, 0x103b, 0x1015, 0x103a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x20, 0x1000,
+0x103b, 0x1015, 0x103a, 0x3b, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443, 0x431, 0x435, 0x43b, 0x44c,
+0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443, 0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b,
+0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x44f, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x456, 0x3b, 0x431, 0x435, 0x43b,
+0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x451, 0x45e, 0x3b, 0x431, 0x435, 0x43b, 0x430, 0x440,
+0x443, 0x441, 0x43a, 0x430, 0x433, 0x430, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x179a, 0x17c0, 0x179b, 0x200b, 0x1780, 0x1798, 0x17d2,
+0x1796, 0x17bb, 0x1787, 0x17b6, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x179a, 0x17c0, 0x179b, 0x200b, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787,
+0x17b6, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f,
+0x73, 0x3b, 0x4eba, 0x6c11, 0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4eba, 0x6c11, 0x5e01, 0x3b, 0x6e2f, 0x5143, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x6e2f, 0x5143, 0x3b, 0x6fb3, 0x95e8, 0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x95e8, 0x5143, 0x3b, 0x65b0,
+0x52a0, 0x5761, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x52a0, 0x5761, 0x5143, 0x3b, 0x6fb3, 0x9580, 0x5143, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x6fb3, 0x9580, 0x5143, 0x3b, 0x65b0, 0x53f0, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x53f0, 0x5e63, 0x3b,
+0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74,
+0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x65, 0x20, 0x6b,
+0x75, 0x6e, 0x65, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b,
+0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b,
+0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61,
+0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b,
+0x65, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61,
+0x72, 0x61, 0x6b, 0x61, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d,
+0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b,
+0x6f, 0x72, 0x75, 0x6e, 0x79, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79, 0x3b, 0x10d,
+0x65, 0x73, 0x6b, 0xfd, 0x63, 0x68, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b,
+0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b,
+0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b,
+0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61,
+0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73,
+0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73,
+0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d,
+0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b,
+0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61,
+0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72,
+0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67,
+0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c,
+0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c,
+0x6c, 0x61, 0x72, 0x3b, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x55, 0x53, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
+0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61,
+0x72, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65, 0x61, 0x6e, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65,
+0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61,
+0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e,
+0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61,
+0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f,
+0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x44,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
+0x72, 0x73, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
+0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b,
+0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42,
+0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65,
+0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61,
+0x72, 0x3b, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
+0x3b, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42,
+0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x6e, 0x20, 0x50, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77,
+0x61, 0x6e, 0x61, 0x6e, 0x20, 0x70, 0x75, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e,
+0x61, 0x6e, 0x20, 0x70, 0x75, 0x6c, 0x61, 0x73, 0x3b, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x46,
+0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x73, 0x3b, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x43, 0x46,
+0x41, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x66, 0x72,
+0x69, 0x63, 0x61, 0x6e, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x65,
+0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x73, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
+0x3b, 0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b,
+0x3b, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x43, 0x61,
+0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x73, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x44, 0x61, 0x6e, 0x69, 0x73, 0x68, 0x20, 0x4b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b,
-0x44, 0x61, 0x6e, 0x69, 0x73, 0x68, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x69,
-0x73, 0x68, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x6e, 0x20, 0x4e,
-0x61, 0x6b, 0x66, 0x61, 0x3b, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x6b, 0x66, 0x61,
-0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x6b, 0x66, 0x61, 0x73, 0x3b,
-0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x50, 0x6f, 0x75,
-0x6e, 0x64, 0x3b, 0x3b, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73,
-0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e,
-0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73,
-0x3b, 0x55, 0x4b, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x55, 0x4b, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b,
-0x3b, 0x3b, 0x3b, 0x55, 0x4b, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e,
-0x20, 0x44, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c,
-0x61, 0x73, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73,
-0x69, 0x73, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x43, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x47, 0x68,
-0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61,
-0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x73, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20,
-0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75,
-0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e,
-0x64, 0x73, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b,
-0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x48,
-0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x48, 0x6f, 0x6e,
-0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x48, 0x6f, 0x6e,
-0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61,
-0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65,
-0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x49,
-0x73, 0x72, 0x61, 0x65, 0x6c, 0x69, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x53, 0x68, 0x65, 0x6b, 0x65, 0x6c, 0x3b, 0x3b, 0x49,
-0x73, 0x72, 0x61, 0x65, 0x6c, 0x69, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x73, 0x68, 0x65, 0x6b, 0x65, 0x6c, 0x3b, 0x3b, 0x3b,
-0x3b, 0x49, 0x73, 0x72, 0x61, 0x65, 0x6c, 0x69, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x73, 0x68, 0x65, 0x6b, 0x65, 0x6c, 0x73,
-0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4a, 0x61,
-0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a, 0x61, 0x6d,
-0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e,
-0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68,
-0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
-0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e,
-0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e,
-0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c,
-0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
-0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73,
-0x3b, 0x4d, 0x61, 0x63, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x61, 0x74, 0x61, 0x63, 0x61, 0x3b, 0x3b, 0x4d, 0x61,
-0x63, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x61, 0x74, 0x61, 0x63, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x63,
-0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x61, 0x74, 0x61, 0x63, 0x61, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61,
-0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20,
-0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x61,
-0x72, 0x69, 0x61, 0x72, 0x69, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61,
-0x63, 0x68, 0x61, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61,
-0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73,
-0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x69, 0x6e, 0x67, 0x67, 0x69, 0x74, 0x3b, 0x3b,
-0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x69, 0x6e, 0x67, 0x67, 0x69, 0x74, 0x3b, 0x3b, 0x3b,
-0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x69, 0x6e, 0x67, 0x67, 0x69, 0x74, 0x73, 0x3b,
-0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x4d, 0x61, 0x75,
-0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72,
-0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61,
-0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x4e, 0x61, 0x69, 0x72, 0x61,
-0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
-0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x73, 0x3b, 0x50, 0x61, 0x6b, 0x69,
-0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61,
-0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e,
-0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47,
-0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e,
-0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x50,
-0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e,
-0x61, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x50, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x50,
-0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x68,
-0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x3b, 0x52, 0x77, 0x61, 0x6e, 0x64,
-0x61, 0x6e, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x73, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x54, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61,
-0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c,
-0x61, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b,
-0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b,
-0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73,
-0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4c, 0x65, 0x6f, 0x6e,
-0x65, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65,
-0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61,
-0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x44,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c,
-0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c,
-0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73,
-0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c,
-0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d,
-0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53,
-0x74, 0x2e, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x74, 0x2e,
-0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x74, 0x2e,
-0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x53, 0x75, 0x64, 0x61, 0x6e,
-0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20,
-0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f,
-0x75, 0x6e, 0x64, 0x73, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x4c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69,
-0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x6c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x3b,
-0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x53, 0x77,
-0x65, 0x64, 0x69, 0x73, 0x68, 0x20, 0x4b, 0x72, 0x6f, 0x6e, 0x61, 0x3b, 0x3b, 0x53, 0x77, 0x65, 0x64, 0x69, 0x73, 0x68,
-0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x65, 0x64, 0x69, 0x73, 0x68, 0x20, 0x6b, 0x72,
-0x6f, 0x6e, 0x6f, 0x72, 0x3b, 0x53, 0x77, 0x69, 0x73, 0x73, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x53, 0x77,
-0x69, 0x73, 0x73, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x69, 0x73, 0x73, 0x20, 0x66,
-0x72, 0x61, 0x6e, 0x63, 0x73, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c,
-0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c,
-0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68,
-0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x50, 0x61, 0x2bb, 0x61, 0x6e,
-0x67, 0x61, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b,
-0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0x72, 0x69,
-0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x26, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61,
-0x72, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x26, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f,
-0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20,
-0x26, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x55, 0x67, 0x61,
-0x6e, 0x64, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64,
-0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64,
-0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
-0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f, 0x75, 0x6e,
-0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b,
-0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x56, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74,
-0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61,
-0x74, 0x75, 0x73, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b,
-0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x5a, 0x61,
-0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20,
-0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74,
-0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b,
-0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64,
-0x73, 0x3b, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c,
-0x65, 0x61, 0x6e, 0x20, 0x47, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c,
-0x61, 0x6e, 0x64, 0x73, 0x20, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x6e, 0x20, 0x67, 0x75, 0x69, 0x6c, 0x64,
-0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x41, 0x6e,
-0x74, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x6e, 0x20, 0x67, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x3b, 0x65, 0x75, 0x72,
-0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x74, 0x3b, 0x64, 0x6f, 0x6e,
-0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e,
-0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b,
-0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b,
-0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61,
-0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73,
-0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41,
-0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20,
-0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46,
-0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75,
-0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61,
-0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61,
-0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
-0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63,
-0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72,
-0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69,
-0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b,
-0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61,
-0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x73, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
-0x43, 0x46, 0x50, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9,
-0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x73, 0x3b, 0x67, 0x6f, 0x75,
-0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64,
-0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64,
-0x65, 0x73, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79,
-0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61,
-0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x73, 0x20, 0x6d, 0x61,
-0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72,
-0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75,
-0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x73,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65,
-0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70,
-0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x72,
-0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d,
-0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x73,
-0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61,
-0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69,
-0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73,
-0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c,
-0x65, 0x73, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68,
-0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x73,
-0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75,
-0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b,
-0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x73, 0x3b, 0x6c, 0x69, 0x76,
-0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73,
-0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x73, 0x20, 0x73, 0x79,
-0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69,
-0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
-0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x76,
-0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20,
-0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x73, 0x20, 0x76,
-0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x73, 0x3b, 0x50, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61,
-0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b, 0x70, 0x68, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e,
-0x61, 0x63, 0x68, 0x3b, 0x70, 0x68, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68,
-0x3b, 0x70, 0x75, 0x69, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x68, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b,
-0x70, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7,
-0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0,
-0x10e0, 0x10d8, 0x3b, 0x3b, 0x3b, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x45,
-0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x53, 0x63,
-0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x53, 0x63, 0x68,
-0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x63,
-0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x395, 0x3c5, 0x3c1, 0x3ce,
-0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x64, 0x61, 0x6e, 0x6d, 0x61,
-0x72, 0x6b, 0x69, 0x6d, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73,
-0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x61, 0x6e,
-0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6d, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0xaad, 0xabe, 0xab0,
-0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xabf, 0xaaf, 0xabe, 0x3b, 0x3b, 0xaad, 0xabe, 0xab0, 0xaa4, 0xac0, 0xaaf, 0x20, 0xab0,
-0xac2, 0xaaa, 0xabf, 0xaaf, 0xabe, 0x3b, 0x3b, 0x3b, 0x3b, 0xaad, 0xabe, 0xab0, 0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xabf,
-0xaaf, 0xabe, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x75, 0x257, 0x69, 0x6e,
-0x20, 0x53, 0x65, 0x66, 0x61, 0x20, 0x6e, 0x61, 0x20, 0x41, 0x66, 0x69, 0x72, 0x6b, 0x61, 0x20, 0x54, 0x61, 0x20, 0x59,
-0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x3b, 0x3b,
-0x5e9, 0x5e7, 0x5dc, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b,
-0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7,
-0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x92d,
-0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940,
-0x92f, 0x20, 0x930, 0x942, 0x92a, 0x90f, 0x3b, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74,
-0x3b, 0x3b, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74, 0x3b, 0x3b, 0x3b, 0x3b, 0x6d,
-0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b,
-0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e,
-0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75,
-0x72, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61,
-0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72,
-0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75,
-0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x76,
-0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a,
-0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x69, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a,
-0x65, 0x72, 0x69, 0x3b, 0x65e5, 0x672c, 0x5186, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5186, 0x3b, 0xcad, 0xcbe, 0xcb0, 0xca4, 0xcc0,
-0xcaf, 0x20, 0xcb0, 0xcc2, 0xcaa, 0xcbe, 0xcaf, 0xcbf, 0x3b, 0x3b, 0xcad, 0xcbe, 0xcb0, 0xca4, 0xcc0, 0xcaf, 0x20, 0xcb0, 0xcc2, 0xcaa,
-0xcbe, 0xcaf, 0xcbf, 0x3b, 0x3b, 0x3b, 0x3b, 0xcad, 0xcbe, 0xcb0, 0xca4, 0xcc0, 0xcaf, 0x20, 0xcb0, 0xcc2, 0xcaa, 0xcbe, 0xcaf, 0xcbf,
-0xc97, 0xcb3, 0xcc1, 0x3b, 0x6c1, 0x650, 0x646, 0x62f, 0x64f, 0x633, 0x62a, 0x672, 0x646, 0x6cd, 0x20, 0x631, 0x6c4, 0x67e, 0x64e, 0x6d2,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x442, 0x435, 0x4a3,
-0x433, 0x435, 0x441, 0x456, 0x3b, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x442, 0x435, 0x4a3, 0x433,
-0x435, 0x441, 0x456, 0x3b, 0x3b, 0x3b, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x442, 0x435, 0x4a3,
-0x433, 0x435, 0x441, 0x456, 0x3b, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x443,
-0x3b, 0x3b, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x443, 0x3b, 0x3b, 0x3b,
-0x3b, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x443, 0x3b, 0xb300, 0xd55c, 0xbbfc,
-0xad6d, 0x20, 0xc6d0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0x20, 0xc6d0, 0x3b, 0xc870, 0xc120, 0x20, 0xbbfc,
-0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d, 0x20, 0xc6d0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xc870, 0xc120,
-0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d, 0x20, 0xc6d0, 0x3b, 0x49, 0x66, 0x61, 0x72, 0x61,
-0x6e, 0x67, 0x61, 0x20, 0x72, 0x79, 0x2019, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0xea5, 0xeb2, 0xea7, 0x20, 0xe81, 0xeb5, 0xe9a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xea5, 0xeb2, 0xea7, 0x20, 0xe81,
-0xeb5, 0xe9a, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x3b,
-0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x61, 0x6c, 0xe1, 0x6e, 0x67, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e,
-0x67, 0xf3, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x79, 0x61, 0x20, 0x41,
-0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x6c, 0xe1, 0x6e, 0x67, 0x61, 0x20,
-0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x61, 0x73,
-0x3b, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x73, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x69, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b,
-0x65, 0x75, 0x72, 0x173, 0x3b, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x435, 0x43d, 0x430,
-0x440, 0x3b, 0x3b, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x435, 0x43d, 0x430, 0x440, 0x3b,
-0x3b, 0x3b, 0x3b, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x435, 0x43d, 0x430, 0x440, 0x438,
-0x3b, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x69, 0x6e, 0x67, 0x67, 0x69,
-0x74, 0x20, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x69, 0x6e, 0x67,
-0x67, 0x69, 0x74, 0x20, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x42,
-0x72, 0x75, 0x6e, 0x65, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x42, 0x72, 0x75,
-0x6e, 0x65, 0x69, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61,
-0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f,
-0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a,
-0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x65, 0x77,
-0x72, 0x6f, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e,
-0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e,
-0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x947, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x442,
-0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x3b, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x928, 0x947, 0x92a, 0x93e,
-0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x20, 0x930,
-0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x3b, 0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a,
-0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, 0x93e, 0x3b,
-0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x92d,
-0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, 0x93e, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65,
-0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65,
-0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0xb1f, 0xb19,
-0xb15, 0xb3e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x3b, 0x627, 0x641, 0x63a,
-0x627, 0x646, 0x6cd, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627,
-0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b,
-0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641,
-0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627,
-0x646, 0x633, 0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627,
-0x646, 0x633, 0x62a, 0x627, 0x646, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b,
-0x7a, 0x142, 0x6f, 0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x20,
-0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x65, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x63, 0x68, 0x20, 0x70, 0x6f, 0x6c, 0x73,
-0x6b, 0x69, 0x63, 0x68, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x67, 0x6f, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x65,
-0x67, 0x6f, 0x3b, 0x52, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b,
-0x52, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x52,
-0x65, 0x61, 0x69, 0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x73, 0x3b, 0x4b, 0x77, 0x61,
-0x6e, 0x7a, 0x61, 0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61,
-0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x73,
-0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x45, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61,
-0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x45, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20,
-0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x73, 0x63,
-0x75, 0x64, 0x6f, 0x73, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b,
-0x44, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e,
-0x69, 0x64, 0x6f, 0x73, 0x3b, 0x3b, 0x44, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61,
-0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0xf3, 0x6c, 0x61, 0x72, 0x65,
-0x73, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73,
-0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b,
-0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b,
-0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b,
-0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b,
-0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b,
-0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f,
-0x29, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f,
-0x73, 0x3b, 0x50, 0x61, 0x74, 0x61, 0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x50,
-0x61, 0x74, 0x61, 0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61,
-0x74, 0x61, 0x63, 0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63,
-0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x4d, 0x65,
-0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b,
-0x3b, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61,
-0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x44, 0x6f, 0x62, 0x72, 0x61, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f, 0x20,
-0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x3b, 0x44, 0x6f, 0x62,
-0x72, 0x61, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed,
-0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x62, 0x72, 0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x53,
-0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x46,
-0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20,
-0x73, 0x75, 0xed, 0xe7, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x73, 0x75, 0xed,
-0xe7, 0x6f, 0x73, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa07, 0xa06, 0x3b, 0x3b, 0xa2d, 0xa3e, 0xa30,
-0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa07, 0xa06, 0x3b, 0x3b, 0x3b, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41,
-0xa2a, 0xa0f, 0x3b, 0x631, 0x648, 0x67e, 0x626, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
-0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69,
-0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65,
-0x72, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20,
-0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65,
-0x219, 0x74, 0x69, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x6c,
-0x65, 0x75, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20,
-0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c,
-0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f,
-0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440,
-0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431,
-0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f,
-0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, 0x3b, 0x440,
-0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x411, 0x435, 0x43b,
-0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e,
-0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440,
-0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441,
-0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441,
-0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x439,
-0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435,
-0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435,
-0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437,
-0x430, 0x445, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437,
-0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439,
-0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c,
-0x430, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c, 0x43e, 0x432, 0x3b, 0x43a,
-0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x41c, 0x43e, 0x43b, 0x434,
-0x430, 0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a,
-0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b,
-0x435, 0x44f, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b, 0x435, 0x435, 0x432, 0x3b, 0x43c,
-0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x43b, 0x435, 0x44f, 0x3b, 0x423, 0x43a, 0x440, 0x430, 0x438,
-0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d,
-0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441,
-0x43a, 0x438, 0x435, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x438,
-0x445, 0x20, 0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x43e, 0x439, 0x20,
-0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, 0x66, 0x61, 0x72, 0xe2, 0x6e, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28,
-0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x421, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434,
-0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b,
-0x441, 0x440, 0x43f, 0x441, 0x43a, 0x430, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a,
-0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x411, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445,
-0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438,
-0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a,
-0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435,
-0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430,
-0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e,
-0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x65, 0x3b, 0x3b, 0x431,
-0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438,
-0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440,
-0x430, 0x43a, 0x430, 0x3b, 0x415, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430,
-0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x42, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63,
-0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c,
-0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68,
-0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69,
-0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b,
-0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65,
-0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61,
-0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b,
-0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61,
-0x3b, 0x45, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x3b, 0x65,
-0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72,
-0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x61, 0x20, 0x64,
-0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72,
-0x61, 0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x44b, 0x3b, 0x421,
-0x43e, 0x43c, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x44b, 0x3b, 0x44, 0x6f, 0x72, 0x61,
-0x20, 0x72, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xdc1, 0xdca,
-0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0xdc1, 0xdca, 0x200d,
-0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0x3b, 0x3b, 0xdc1, 0xdca,
-0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x65, 0x75, 0x72, 0x6f,
-0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0xe1, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x3b, 0x65, 0x75,
-0x72, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65, 0x76,
-0x72, 0x69, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x76, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6f,
-0x6d, 0x61, 0x61, 0x6c, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x20, 0x4a, 0x61,
-0x62, 0x62, 0x75, 0x75, 0x74, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x69, 0x72, 0x74, 0x61, 0x20, 0x49,
-0x74, 0x6f, 0x6f, 0x62, 0x62, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20,
-0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x65,
-0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e,
-0x74, 0x69, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f,
-0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
-0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x62, 0x6f,
-0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b,
-0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72,
-0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c,
-0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x65, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c,
-0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x50, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x70,
-0x65, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73,
-0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d,
-0x62, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61,
-0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61,
-0x6e, 0x6f, 0x73, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65,
-0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63,
-0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x73, 0x74,
-0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61,
-0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70,
-0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f,
-0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e,
-0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e,
-0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75,
-0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64,
-0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73,
-0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61,
-0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f,
-0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73,
-0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x3b, 0x3b, 0x71,
-0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x3b, 0x3b, 0x3b, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x65, 0x73, 0x3b,
-0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x6c,
-0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
-0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x73, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x73, 0x3b,
-0x70, 0x65, 0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20,
-0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x6d, 0x65,
-0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61,
-0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69,
-0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62,
-0x61, 0x73, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x62, 0x61, 0x6c,
-0x62, 0x6f, 0x61, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61,
-0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x73,
-0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70,
-0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61,
-0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x65, 0x73,
-0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x73, 0x3b, 0x73, 0x6f, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x75,
-0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
-0x73, 0x6f, 0x6c, 0x65, 0x73, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20,
-0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70,
-0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e,
-0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x70, 0x65,
-0x73, 0x6f, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73,
-0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x76,
-0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x76,
-0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72,
-0x65, 0x73, 0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69,
-0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x73, 0x68, 0x69,
-0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b,
-0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x7a, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69,
-0x61, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x3b,
-0x66, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
-0x66, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x7a, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x53, 0x68, 0x69,
-0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c,
-0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69,
-0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x7a, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69,
-0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69,
-0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69,
-0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x7a, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x73, 0x76, 0x65, 0x6e,
-0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x61, 0x3b, 0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f,
-0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x6f, 0x72,
-0x3b, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0xb87, 0xba8, 0xbcd, 0xba4,
-0xbbf, 0xbaf, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0x20,
-0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xba9, 0xbcd, 0x20, 0xbb0,
-0xbbf, 0xb99, 0xbcd, 0xb95, 0xbbf, 0xb9f, 0xbcd, 0x3b, 0x3b, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xba9, 0xbcd, 0x20, 0xbb0, 0xbbf,
-0xb99, 0xbcd, 0xb95, 0xbbf, 0xb9f, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xba9, 0xbcd, 0x20, 0xbb0,
-0xbbf, 0xb99, 0xbcd, 0xb95, 0xbbf, 0xb9f, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2,
-0xbb0, 0xbcd, 0x20, 0xb9f, 0xbbe, 0xbb2, 0xbb0, 0xbcd, 0x3b, 0x3b, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0,
-0xbcd, 0x20, 0xb9f, 0xbbe, 0xbb2, 0xbb0, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2,
-0xbb0, 0xbcd, 0x20, 0xb9f, 0xbbe, 0xbb2, 0xbb0, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0x20, 0xbb0,
-0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd,
-0x3b, 0x3b, 0x3b, 0x3b, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0xb95, 0xbb3, 0xbcd,
-0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc3f, 0x3b, 0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc3f, 0x3b, 0x3b, 0x3b, 0x3b, 0xc30,
-0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc32, 0xc41, 0x3b, 0xe1a, 0xe32, 0xe17, 0xe44, 0xe17, 0xe22, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xe1a,
-0xe32, 0xe17, 0xe44, 0xe17, 0xe22, 0x3b, 0xf61, 0xf74, 0xf0b, 0xf68, 0xf53, 0xf0b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf62,
-0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0xf66, 0xf92, 0xf7c, 0xf62, 0xf0b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2,
-0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67,
-0x61, 0x20, 0x66, 0x61, 0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x2bb,
-0x61, 0x6e, 0x67, 0x61, 0x20, 0x66, 0x61, 0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x20,
-0x4c, 0x69, 0x72, 0x61, 0x73, 0x131, 0x3b, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x20, 0x6c, 0x69, 0x72, 0x61, 0x73, 0x131, 0x3b,
-0x3b, 0x3b, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x20, 0x6c, 0x69, 0x72, 0x61, 0x73, 0x131, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x6d,
-0x65, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x79, 0x3b, 0x3b, 0x74, 0xfc, 0x72, 0x6b, 0x6d, 0x65, 0x6e, 0x20, 0x6d,
-0x61, 0x6e, 0x61, 0x74, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x74, 0xfc, 0x72, 0x6b, 0x6d, 0x65, 0x6e, 0x20, 0x6d, 0x61, 0x6e,
-0x61, 0x74, 0x79, 0x3b, 0x62c, 0x6c7, 0x6ad, 0x6af, 0x648, 0x20, 0x64a, 0x6c8, 0x6d5, 0x646, 0x649, 0x3b, 0x3b, 0x62c, 0x6c7, 0x6ad,
-0x6af, 0x648, 0x20, 0x64a, 0x6c8, 0x6d5, 0x646, 0x649, 0x3b, 0x3b, 0x3b, 0x3b, 0x62c, 0x6c7, 0x6ad, 0x6af, 0x648, 0x20, 0x64a, 0x6c8,
-0x6d5, 0x646, 0x649, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a, 0x430, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d,
-0x44f, 0x3b, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44f, 0x3b, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x456, 0x3b, 0x433, 0x440,
-0x438, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x456, 0x3b, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646,
-0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x6cc, 0x20, 0x631, 0x648,
-0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc,
-0x6c1, 0x3b, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x628, 0x6be, 0x627, 0x631,
-0x62a, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6cc, 0x20, 0x631,
-0x648, 0x67e, 0x6d2, 0x3b, 0x4f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2018, 0x6d,
-0x69, 0x3b, 0x3b, 0x4f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2018, 0x6d, 0x69,
-0x3b, 0x3b, 0x3b, 0x3b, 0x4f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2018, 0x6d,
-0x69, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x40e, 0x437, 0x431, 0x435, 0x43a,
-0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x3b, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e,
-0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20,
-0x441, 0x45e, 0x43c, 0x3b, 0x110, 0x1ed3, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x110, 0x1ed3, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x3b, 0x50, 0x75, 0x6e,
-0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x70, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61,
-0x69, 0x6e, 0x3b, 0x62, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x62, 0x75, 0x6e, 0x74,
-0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x70, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69,
-0x6e, 0x3b, 0x70, 0x68, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x70, 0x75, 0x6e, 0x74,
-0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72,
-0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301,
-0xe8, 0x64, 0x65, 0x20, 0x42, 0x49, 0x4b, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53,
-0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x69,
-0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b,
-0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52,
-0x61, 0x6e, 0x64, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x6e, 0x6f, 0x72,
-0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b,
-0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x42, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67,
-0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61,
-0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63,
-0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c,
-0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65,
-0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62,
-0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f,
-0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72,
-0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x41a, 0x43e, 0x43d, 0x432,
+0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73,
+0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64,
+0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64,
+0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61,
+0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x44, 0x61, 0x6e, 0x69, 0x73, 0x68, 0x20, 0x4b, 0x72,
+0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x69, 0x73, 0x68, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b,
+0x3b, 0x44, 0x61, 0x6e, 0x69, 0x73, 0x68, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72,
+0x65, 0x61, 0x6e, 0x20, 0x4e, 0x61, 0x6b, 0x66, 0x61, 0x3b, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x6e, 0x20,
+0x6e, 0x61, 0x6b, 0x66, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x6e, 0x20, 0x6e, 0x61,
+0x6b, 0x66, 0x61, 0x73, 0x3b, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64,
+0x73, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x73,
+0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x6c, 0x6b, 0x6c,
+0x61, 0x6e, 0x64, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x46,
+0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e,
+0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x55, 0x4b, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x55, 0x4b, 0x20, 0x70,
+0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x4b, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x61,
+0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61,
+0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20,
+0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x73, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x43, 0x65, 0x64,
+0x69, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b,
+0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x73, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61,
+0x6c, 0x74, 0x61, 0x72, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61,
+0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72,
+0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x44, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x73, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
+0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
+0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b,
+0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e,
+0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70,
+0x65, 0x65, 0x73, 0x3b, 0x49, 0x73, 0x72, 0x61, 0x65, 0x6c, 0x69, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x53, 0x68, 0x65, 0x6b,
+0x65, 0x6c, 0x3b, 0x3b, 0x49, 0x73, 0x72, 0x61, 0x65, 0x6c, 0x69, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x73, 0x68, 0x65, 0x6b,
+0x65, 0x6c, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x73, 0x72, 0x61, 0x65, 0x6c, 0x69, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x73, 0x68,
+0x65, 0x6b, 0x65, 0x6c, 0x73, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61,
+0x72, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
+0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4b,
+0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79,
+0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61,
+0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66,
+0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66,
+0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20,
+0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61,
+0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4d, 0x61, 0x63, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x61, 0x74, 0x61, 0x63,
+0x61, 0x3b, 0x3b, 0x4d, 0x61, 0x63, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x61, 0x74, 0x61, 0x63, 0x61, 0x3b, 0x3b,
+0x3b, 0x3b, 0x4d, 0x61, 0x63, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x61, 0x74, 0x61, 0x63, 0x61, 0x73, 0x3b, 0x4d,
+0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61,
+0x67, 0x61, 0x73, 0x79, 0x20, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67,
+0x61, 0x73, 0x79, 0x20, 0x61, 0x72, 0x69, 0x61, 0x72, 0x69, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61,
+0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x6b,
+0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77,
+0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x69, 0x6e, 0x67,
+0x67, 0x69, 0x74, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x69, 0x6e, 0x67, 0x67,
+0x69, 0x74, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x69, 0x6e, 0x67,
+0x67, 0x69, 0x74, 0x73, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65,
+0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b,
+0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4e, 0x61,
+0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62,
+0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69,
+0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20,
+0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x73,
+0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x50, 0x61,
+0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x6b,
+0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20,
+0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x50, 0x61,
+0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61,
+0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61,
+0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x50, 0x69,
+0x73, 0x6f, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x69, 0x73, 0x6f, 0x3b,
+0x3b, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x69, 0x73, 0x6f, 0x73, 0x3b,
+0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x52, 0x77, 0x61, 0x6e, 0x64,
+0x61, 0x6e, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x54, 0x61, 0x6c, 0x61, 0x3b, 0x3b,
+0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61,
+0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x52,
+0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75,
+0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72,
+0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e,
+0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65,
+0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c,
+0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70,
+0x6f, 0x72, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72,
+0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72,
+0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73,
+0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f,
+0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b,
+0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x73, 0x3b, 0x53, 0x74, 0x2e, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64,
+0x3b, 0x3b, 0x53, 0x74, 0x2e, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b,
+0x3b, 0x3b, 0x53, 0x74, 0x2e, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b,
+0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x75, 0x64, 0x61,
+0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65,
+0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x4c, 0x69, 0x6c, 0x61,
+0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x6c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65,
+0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x65,
+0x6e, 0x69, 0x3b, 0x53, 0x77, 0x65, 0x64, 0x69, 0x73, 0x68, 0x20, 0x4b, 0x72, 0x6f, 0x6e, 0x61, 0x3b, 0x3b, 0x53, 0x77,
+0x65, 0x64, 0x69, 0x73, 0x68, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x65, 0x64, 0x69,
+0x73, 0x68, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x6f, 0x72, 0x3b, 0x53, 0x77, 0x69, 0x73, 0x73, 0x20, 0x46, 0x72, 0x61, 0x6e,
+0x63, 0x3b, 0x3b, 0x53, 0x77, 0x69, 0x73, 0x73, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77,
+0x69, 0x73, 0x73, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e,
+0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e,
+0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69,
+0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20,
+0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61,
+0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67,
+0x61, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x26, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20,
+0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x26, 0x20, 0x54,
+0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e,
+0x69, 0x64, 0x61, 0x64, 0x20, 0x26, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
+0x73, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b,
+0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b,
+0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x42, 0x72,
+0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
+0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f,
+0x75, 0x6e, 0x64, 0x73, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x56, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x56,
+0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61,
+0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x73, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61,
+0x63, 0x68, 0x61, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b,
+0x3b, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x53,
+0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b,
+0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e,
+0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20,
+0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x41,
+0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x6e, 0x20, 0x47, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x3b, 0x3b, 0x4e, 0x65,
+0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x6e, 0x20,
+0x67, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e,
+0x64, 0x73, 0x20, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x6e, 0x20, 0x67, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72,
+0x73, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f,
+0x74, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b,
+0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20, 0x6b, 0x72,
+0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65,
+0x75, 0x72, 0x6f, 0x61, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b,
+0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64,
+0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75,
+0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x62, 0x75,
+0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42,
+0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41,
+0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45,
+0x41, 0x43, 0x29, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b,
+0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b,
+0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
+0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63,
+0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f,
+0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69,
+0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69,
+0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66,
+0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b,
+0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
+0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9,
+0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e,
+0x73, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b,
+0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b,
+0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x73, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x61,
+0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61,
+0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72,
+0x79, 0x73, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61,
+0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79,
+0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x6f, 0x75, 0x67,
+0x75, 0x69, 0x79, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x72,
+0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x72,
+0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b,
+0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65,
+0x73, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x64,
+0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69,
+0x72, 0x68, 0x61, 0x6d, 0x73, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77,
+0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x72, 0x77, 0x61,
+0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79,
+0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20,
+0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65,
+0x73, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69,
+0x73, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65,
+0x73, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x6c, 0x69,
+0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72,
+0x65, 0x73, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74,
+0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73,
+0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69,
+0x65, 0x6e, 0x73, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b,
+0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x76, 0x61,
+0x74, 0x75, 0x73, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x73, 0x3b, 0x50, 0x75, 0x6e, 0x6e, 0x64,
+0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b, 0x70, 0x68, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53,
+0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x70, 0x68, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61,
+0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x70, 0x75, 0x69, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x68, 0x61, 0x73, 0x61, 0x6e, 0x6e,
+0x61, 0x63, 0x68, 0x3b, 0x3b, 0x70, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68,
+0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3,
+0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x3b, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da,
+0x10d0, 0x10e0, 0x10d8, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75,
+0x72, 0x6f, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e,
+0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b,
+0x3b, 0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e,
+0x3b, 0x395, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b,
+0x64, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6d, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b,
+0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b,
+0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6d, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e,
+0x69, 0x3b, 0xaad, 0xabe, 0xab0, 0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xabf, 0xaaf, 0xabe, 0x3b, 0x3b, 0xaad, 0xabe, 0xab0,
+0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xabf, 0xaaf, 0xabe, 0x3b, 0x3b, 0x3b, 0x3b, 0xaad, 0xabe, 0xab0, 0xaa4, 0xac0, 0xaaf,
+0x20, 0xab0, 0xac2, 0xaaa, 0xabf, 0xaaf, 0xabe, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4b, 0x75, 0x257, 0x69, 0x6e, 0x20, 0x53, 0x65, 0x66, 0x61, 0x20, 0x6e, 0x61, 0x20, 0x41, 0x66, 0x69, 0x72, 0x6b, 0x61,
+0x20, 0x54, 0x61, 0x20, 0x59, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x20,
+0x5d7, 0x5d3, 0x5e9, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7,
+0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7,
+0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a,
+0x92f, 0x93e, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b,
+0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x90f, 0x3b, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66,
+0x6f, 0x72, 0x69, 0x6e, 0x74, 0x3b, 0x3b, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74,
+0x3b, 0x3b, 0x3b, 0x3b, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74, 0x3b, 0xed, 0x73,
+0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b,
+0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20,
+0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65,
+0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f,
+0x6e, 0x65, 0x73, 0x69, 0x61, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72,
+0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72,
+0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x6f, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20,
+0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x69, 0x20,
+0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x69, 0x3b, 0x65e5, 0x672c, 0x5186, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5186, 0x3b,
+0xcad, 0xcbe, 0xcb0, 0xca4, 0xcc0, 0xcaf, 0x20, 0xcb0, 0xcc2, 0xcaa, 0xcbe, 0xcaf, 0xcbf, 0x3b, 0x3b, 0xcad, 0xcbe, 0xcb0, 0xca4, 0xcc0,
+0xcaf, 0x20, 0xcb0, 0xcc2, 0xcaa, 0xcbe, 0xcaf, 0xcbf, 0x3b, 0x3b, 0x3b, 0x3b, 0xcad, 0xcbe, 0xcb0, 0xca4, 0xcc0, 0xcaf, 0x20, 0xcb0,
+0xcc2, 0xcaa, 0xcbe, 0xcaf, 0xcbf, 0xc97, 0xcb3, 0xcc1, 0x3b, 0x6c1, 0x650, 0x646, 0x62f, 0x64f, 0x633, 0x62a, 0x672, 0x646, 0x6cd, 0x20,
+0x631, 0x6c4, 0x67e, 0x64e, 0x6d2, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430,
+0x43d, 0x20, 0x442, 0x435, 0x4a3, 0x433, 0x435, 0x441, 0x456, 0x3b, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d,
+0x20, 0x442, 0x435, 0x4a3, 0x433, 0x435, 0x441, 0x456, 0x3b, 0x3b, 0x3b, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430,
+0x43d, 0x20, 0x442, 0x435, 0x4a3, 0x433, 0x435, 0x441, 0x456, 0x3b, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d,
+0x20, 0x441, 0x43e, 0x43c, 0x443, 0x3b, 0x3b, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x441, 0x43e,
+0x43c, 0x443, 0x3b, 0x3b, 0x3b, 0x3b, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x441, 0x43e, 0x43c,
+0x443, 0x3b, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0x20, 0xc6d0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0x20, 0xc6d0,
+0x3b, 0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d, 0x20, 0xc6d0, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d, 0x20, 0xc6d0, 0x3b,
+0x49, 0x66, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x72, 0x79, 0x2019, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xea5, 0xeb2, 0xea7, 0x20, 0xe81, 0xeb5, 0xe9a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0xea5, 0xeb2, 0xea7, 0x20, 0xe81, 0xeb5, 0xe9a, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x65, 0x69,
+0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x61, 0x6c, 0xe1, 0x6e, 0x67, 0x61, 0x20, 0x79,
+0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61,
+0x20, 0x79, 0x61, 0x20, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x6c,
+0xe1, 0x6e, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x45, 0x75, 0x72, 0x61, 0x73, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x73, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x69, 0x3b,
+0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x173, 0x3b, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438,
+0x20, 0x434, 0x435, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434,
+0x435, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434,
+0x435, 0x43d, 0x430, 0x440, 0x438, 0x3b, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x52,
+0x69, 0x6e, 0x67, 0x67, 0x69, 0x74, 0x20, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x52, 0x69, 0x6e, 0x67, 0x67, 0x69, 0x74, 0x20, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x3b, 0x44, 0x6f,
+0x6c, 0x61, 0x72, 0x20, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61,
+0x72, 0x20, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x53, 0x69, 0x6e, 0x67, 0x61,
+0x70, 0x75, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x53, 0x69, 0x6e, 0x67,
+0x61, 0x70, 0x75, 0x72, 0x61, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0xd07,
+0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f,
+0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x77,
+0x72, 0x6f, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20,
+0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b,
+0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x947, 0x3b, 0x442, 0x4e9, 0x433, 0x440,
+0x4e9, 0x433, 0x3b, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x3b, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, 0x433,
+0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x928, 0x947, 0x92a,
+0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x3b, 0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932,
+0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a,
+0x93f, 0x901, 0x92f, 0x93e, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, 0x93e,
+0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, 0x93e, 0x3b, 0x6e,
+0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20,
+0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e,
+0x65, 0x72, 0x3b, 0xb2d, 0xb3e, 0xb30, 0xb24, 0xb40, 0xb5f, 0x20, 0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x3b, 0xb2d, 0xb3e, 0xb30,
+0xb24, 0xb40, 0xb5f, 0x20, 0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x3b, 0x3b, 0x3b, 0xb2d, 0xb3e, 0xb30, 0xb24, 0xb40, 0xb5f, 0x20,
+0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd,
+0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627,
+0x646, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x631, 0x6cc, 0x627,
+0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646,
+0x633, 0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a,
+0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a,
+0x627, 0x646, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f,
+0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c,
+0x73, 0x6b, 0x69, 0x65, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x63, 0x68, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x63,
+0x68, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x67, 0x6f, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x65, 0x67, 0x6f, 0x3b,
+0x52, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x52, 0x65, 0x61,
+0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x65, 0x61, 0x69,
+0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x73, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61,
+0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x61, 0x6e,
+0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x73, 0x20, 0x61, 0x6e,
+0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d,
+0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62,
+0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, 0x6f,
+0x73, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, 0x6c,
+0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f,
+0x73, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73,
+0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x64,
+0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x46, 0x72,
+0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x46, 0x72, 0x61,
+0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72,
+0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66,
+0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x50,
+0x61, 0x74, 0x61, 0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x50, 0x61, 0x74, 0x61,
+0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x74, 0x61, 0x63,
+0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20,
+0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63,
+0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69,
+0x71, 0x75, 0x65, 0x3b, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x26, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63,
+0x69, 0x70, 0x65, 0x20, 0x44, 0x6f, 0x62, 0x72, 0x61, 0x20, 0x28, 0x32, 0x30, 0x31, 0x38, 0x29, 0x3b, 0x3b, 0x53, 0xe3,
+0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x26, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x20, 0x64, 0x6f,
+0x62, 0x72, 0x61, 0x20, 0x28, 0x32, 0x30, 0x31, 0x38, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f,
+0x6d, 0xe9, 0x20, 0x26, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x20, 0x64, 0x6f, 0x62, 0x72, 0x61, 0x73,
+0x20, 0x28, 0x32, 0x30, 0x31, 0x38, 0x29, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f,
+0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f, 0x73, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30,
+0xa41, 0xa2a, 0xa07, 0xa06, 0x3b, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa07, 0xa06, 0x3b, 0x3b, 0x3b,
+0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa0f, 0x3b, 0x631, 0x648, 0x67e, 0x626, 0x6cc, 0x6c1, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e,
+0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c,
+0x65, 0x69, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x72, 0x6f,
+0x6d, 0xe2, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e,
+0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x63,
+0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x3b,
+0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x440, 0x43e, 0x441,
+0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438,
+0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441,
+0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x445,
+0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20,
+0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443,
+0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431,
+0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b,
+0x44f, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439,
+0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b,
+0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437,
+0x430, 0x445, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441,
+0x43a, 0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x445, 0x20,
+0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x442, 0x435, 0x43d,
+0x433, 0x435, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a,
+0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438,
+0x437, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438,
+0x445, 0x20, 0x441, 0x43e, 0x43c, 0x43e, 0x432, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20,
+0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b,
+0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b,
+0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b, 0x435, 0x44f, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a,
+0x438, 0x445, 0x20, 0x43b, 0x435, 0x435, 0x432, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20,
+0x43b, 0x435, 0x44f, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d,
+0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x430,
+0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x438, 0x435, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b,
+0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, 0x3b, 0x443, 0x43a,
+0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x43e, 0x439, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, 0x66, 0x61, 0x72, 0xe2,
+0x6e, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x421, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a,
+0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x430, 0x20, 0x434, 0x438, 0x43d, 0x430,
+0x440, 0x430, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x42,
+0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61,
+0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61,
+0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61,
+0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61,
+0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67,
+0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65,
+0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72,
+0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62,
+0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x45, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65,
+0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73,
+0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e,
+0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x61, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x3b, 0x73,
+0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x411, 0x43e, 0x441, 0x430, 0x43d, 0x441,
+0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432,
0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441,
0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a,
0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b,
0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a,
0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a,
-0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430,
-0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20,
-0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x53, 0x69, 0x64, 0x69, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x1ecb, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69,
-0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x67,
-0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256,
-0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x263, 0x65, 0x74, 0x6f,
-0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20,
-0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42,
-0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72,
-0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41,
-0x4f, 0x3b, 0x50, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x3b,
-0x3b, 0x70, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x3b,
-0x3b, 0x3b, 0x70, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x3b,
-0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x3b, 0x53, 0x63,
-0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x63,
-0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75,
-0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f,
-0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f,
-0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65,
-0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x72, 0x75, 0x6f, 0x167,
-0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b,
-0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e,
-0x6f, 0x3b, 0x3b, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x53,
-0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x75, 0x20, 0x53, 0x65, 0x65, 0x66, 0x61, 0x61, 0x20, 0x42, 0x43, 0x45,
-0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x69, 0x20, 0x53, 0x65, 0x65, 0x66,
-0x61, 0x61, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67, 0x69, 0x79, 0x79, 0x61,
-0x20, 0x4d, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x69, 0x72, 0x69,
-0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e,
-0x6a, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x65, 0x6c, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d,
-0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x20, 0x79, 0x61, 0x73,
-0x65, 0x20, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x68, 0x65, 0x6c, 0x65,
-0x72, 0x69, 0x20, 0x73, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x2d30, 0x2d37, 0x2d54, 0x2d49, 0x2d4e, 0x20, 0x2d4f, 0x20, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x61, 0x64, 0x72, 0x69, 0x6d, 0x20, 0x6e, 0x20, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x41, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x41, 0x7a, 0x7a, 0x61, 0x79, 0x72, 0x69, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x73, 0x68, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67, 0x61,
-0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79,
-0x61, 0x20, 0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53,
-0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x65, 0x66, 0x61, 0x20, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, 0x45,
-0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, 0x3b, 0x3b, 0x55, 0x53,
-0x20, 0x13a0, 0x13d5, 0x13b3, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69,
-0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c,
-0xed, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x79, 0x61, 0x20, 0x59, 0x75, 0x67,
-0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75, 0x20, 0x4b, 0x61, 0x62,
-0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75,
-0x20, 0x4b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67,
-0x69, 0x74, 0x61, 0x62, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72, 0x6f, 0x70, 0x69, 0x79, 0x69,
-0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72,
-0x6f, 0x70, 0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x72, 0x69, 0x6e, 0x6a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e,
-0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61,
-0x20, 0x54, 0x61, 0x6e, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6e, 0x67,
-0x6f, 0x2019, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x2019, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x2019, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x2019, 0x20,
-0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0x72, 0x61, 0x14b,
-0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e,
-0x67, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x65,
-0x72, 0x68, 0x65, 0x6d, 0x20, 0x55, 0x6d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x930, 0x93e, 0x902, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x420, 0x43e, 0x441,
-0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e,
-0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e, 0x44c, 0x43c, 0x430, 0x448, 0x3b,
-0x440, 0x461, 0x441, 0x441, 0x456, 0x301, 0x439, 0x441, 0x43a, 0x457, 0x439, 0x20, 0x440, 0xa64b, 0x301, 0x431, 0x43b, 0x44c, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x440, 0x461, 0x441, 0x441, 0x456, 0x301, 0x439, 0x441, 0x43a, 0x430, 0x433, 0x461, 0x20, 0x440, 0xa64b, 0x431,
-0x43b, 0x467, 0x300, 0x3b, 0x4e, 0x66, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67,
-0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0xe0, 0x6c, 0xe2, 0x14b, 0x20, 0x42, 0x45,
-0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x1ce, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42,
-0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x65, 0x65, 0x66, 0x61, 0x20, 0x79, 0x61, 0x74,
-0x69, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x259, 0x6c, 0xe1, 0x14b, 0x20,
-0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0xe1,
-0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x61, 0x69, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x20, 0x441, 0x43e, 0x43b, 0x43a, 0x443,
-0x43e, 0x431, 0x430, 0x439, 0x430, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430,
-0x20, 0x441, 0x43e, 0x43b, 0x43a, 0x443, 0x43e, 0x431, 0x430, 0x439, 0x430, 0x3b, 0x49, 0x68, 0x65, 0x6c, 0x61, 0x20, 0x79, 0x61,
-0x20, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xa55e, 0xa524, 0xa52b,
-0xa569, 0x20, 0xa55c, 0xa55e, 0xa54c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61,
-0x20, 0x44, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x25b, 0x6c, 0xe2, 0x14b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x73, 0x68, 0x69, 0x72, 0xe8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x65, 0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46,
-0x41, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x62f, 0x6cc, 0x646, 0x627, 0x631, 0x6cc, 0x20, 0x639, 0x6ce, 0x631, 0x627, 0x642,
-0x6cc, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x695, 0x6cc, 0x627, 0x6b5, 0x6cc, 0x20, 0x626, 0x6ce, 0x631, 0x627, 0x646, 0x6cc,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75,
-0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b,
-0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x6a, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x3b, 0x3b, 0x65, 0x75, 0x72,
-0x6f, 0x77, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x20,
-0x631, 0x6cc, 0x627, 0x644, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x20, 0x631, 0x6cc, 0x627, 0x644,
-0x3b, 0x6e2f, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5e63, 0x3b
+0x65, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432,
+0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445,
+0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x415, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b,
+0x435, 0x432, 0x440, 0x430, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x3b,
+0x3b, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x44b, 0x3b, 0x421, 0x43e, 0x43c, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b,
+0x441, 0x43e, 0x43c, 0x44b, 0x3b, 0x44, 0x6f, 0x72, 0x61, 0x20, 0x72, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, 0x67e, 0x64a, 0x3b,
+0x3b, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, 0x67e, 0x64a, 0x3b, 0x3b, 0x3b, 0x3b, 0x67e, 0x627, 0x6aa,
+0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, 0x67e, 0x64a, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf,
+0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0x20,
+0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0x3b, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf,
+0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b,
+0x65, 0x75, 0x72, 0xe1, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x3b, 0x65, 0x75, 0x72, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b,
+0x65, 0x76, 0x72, 0x6f, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x69, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f,
+0x76, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x20, 0x4a, 0x61, 0x62, 0x62, 0x75, 0x75, 0x74, 0x69, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x69, 0x72, 0x74, 0x61, 0x20, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x62, 0x69, 0x79, 0x61,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e,
+0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b,
+0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3,
+0x6c, 0x61, 0x72, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20,
+0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20,
+0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b,
+0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69,
+0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, 0x6f, 0x3b,
+0x3b, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x72,
+0x65, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x50, 0x65, 0x73,
+0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c,
+0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f,
+0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70,
+0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65,
+0x73, 0x6f, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63, 0x6f, 0x6c, 0xf3,
+0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x63, 0x6f, 0x6c,
+0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b,
+0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73,
+0x65, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f,
+0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x75, 0x62,
+0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f,
+0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b,
+0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64,
+0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b,
+0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73,
+0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75,
+0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20,
+0x64, 0x65, 0x20, 0xc1, 0x66, 0x72, 0x69, 0x63, 0x61, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x3b, 0x3b, 0x66,
+0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0xc1, 0x66, 0x72, 0x69, 0x63, 0x61, 0x20,
+0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43,
+0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0xc1, 0x66, 0x72, 0x69, 0x63, 0x61, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c,
+0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x3b, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x3b, 0x3b, 0x3b,
+0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x65, 0x73, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68,
+0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f,
+0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x73, 0x20,
+0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69,
+0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b,
+0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63,
+0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b,
+0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73,
+0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x73, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61,
+0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d,
+0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f,
+0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x73, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f,
+0x73, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b,
+0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b,
+0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x65, 0x73, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79,
+0x6f, 0x73, 0x3b, 0x73, 0x6f, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x20,
+0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x65, 0x73, 0x20, 0x70, 0x65, 0x72,
+0x75, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b,
+0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65,
+0x73, 0x6f, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x75,
+0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61,
+0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f,
+0x73, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f,
+0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f,
+0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x65, 0x73, 0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f,
+0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61,
+0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20,
+0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69,
+0x20, 0x7a, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61,
+0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x3b, 0x66, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x79,
+0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x7a,
+0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20,
+0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b,
+0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x7a, 0x61, 0x20,
+0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67,
+0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67,
+0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x7a, 0x61, 0x20,
+0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x61, 0x3b,
+0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x76, 0x65,
+0x6e, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x6f, 0x72, 0x3b, 0x421, 0x43e, 0x43c, 0x43e, 0x43d, 0x4e3, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x421, 0x43e, 0x43c, 0x43e, 0x43d, 0x4e3, 0x3b, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0x20, 0xbb0, 0xbc2,
+0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b,
+0x3b, 0x3b, 0x3b, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b,
+0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xba9, 0xbcd, 0x20, 0xbb0, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbbf, 0xb9f, 0xbcd, 0x3b, 0x3b, 0xbae,
+0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xba9, 0xbcd, 0x20, 0xbb0, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbbf, 0xb9f, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b,
+0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xba9, 0xbcd, 0x20, 0xbb0, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbbf, 0xb9f, 0xbcd, 0xb95, 0xbb3, 0xbcd,
+0x3b, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0x20, 0xb9f, 0xbbe, 0xbb2, 0xbb0, 0xbcd, 0x3b, 0x3b,
+0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0x20, 0xb9f, 0xbbe, 0xbb2, 0xbb0, 0xbcd, 0x3b, 0x3b, 0x3b,
+0x3b, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0x20, 0xb9f, 0xbbe, 0xbb2, 0xbb0, 0xbcd, 0xb95, 0xbb3,
+0xbcd, 0x3b, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0xb87, 0xbb2, 0xb99,
+0xbcd, 0xb95, 0xbc8, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8,
+0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x44f, 0x20, 0x441, 0x443,
+0x43c, 0x44b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x441, 0x443, 0x43c, 0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc3f, 0x3b, 0x3b,
+0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc3f, 0x3b, 0x3b, 0x3b, 0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc32, 0xc41, 0x3b, 0xe1a, 0xe32,
+0xe17, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xe1a, 0xe32, 0xe17, 0xe44, 0xe17, 0xe22, 0x3b, 0xf61, 0xf74, 0xf0b, 0xf68, 0xf53, 0xf0b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0xf66, 0xf92, 0xf7c, 0xf62, 0xf0b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x66, 0x61, 0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x66, 0x61, 0x6b, 0x61, 0x74, 0x6f, 0x6e,
+0x67, 0x61, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x20, 0x4c, 0x69, 0x72, 0x61, 0x73, 0x131, 0x3b, 0x3b, 0x54, 0xfc, 0x72, 0x6b,
+0x20, 0x6c, 0x69, 0x72, 0x61, 0x73, 0x131, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x20, 0x6c, 0x69, 0x72, 0x61,
+0x73, 0x131, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x6d, 0x65, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x64, 0x79, 0x3b, 0x3b, 0x74,
+0xfc, 0x72, 0x6b, 0x6d, 0x65, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x64, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x74, 0xfc, 0x72,
+0x6b, 0x6d, 0x65, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x64, 0x79, 0x3b, 0x62c, 0x6c7, 0x6ad, 0x6af, 0x648, 0x20, 0x64a, 0x6c8,
+0x6d5, 0x646, 0x649, 0x3b, 0x3b, 0x62c, 0x6c7, 0x6ad, 0x6af, 0x648, 0x20, 0x64a, 0x6c8, 0x6d5, 0x646, 0x649, 0x3b, 0x3b, 0x3b, 0x3b,
+0x62c, 0x6c7, 0x6ad, 0x6af, 0x648, 0x20, 0x64a, 0x6c8, 0x6d5, 0x646, 0x649, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c,
+0x43a, 0x430, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44f, 0x3b, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44f, 0x3b, 0x3b, 0x433,
+0x440, 0x438, 0x432, 0x43d, 0x456, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x456,
+0x3b, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x67e, 0x627, 0x6a9,
+0x633, 0x62a, 0x627, 0x646, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x67e, 0x627, 0x6a9, 0x633, 0x62a,
+0x627, 0x646, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6cc, 0x20, 0x631, 0x648, 0x67e,
+0x6cc, 0x6c1, 0x3b, 0x3b, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b,
+0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6d2, 0x3b, 0x4f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73,
+0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2018, 0x6d, 0x69, 0x3b, 0x3b, 0x4f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73, 0x74,
+0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2018, 0x6d, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x4f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73,
+0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2018, 0x6d, 0x69, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x3b, 0x40e,
+0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x40e, 0x437, 0x431,
+0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x110, 0x1ed3, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7,
+0x74, 0x20, 0x4e, 0x61, 0x6d, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x110, 0x1ed3, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74,
+0x20, 0x4e, 0x61, 0x6d, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x70, 0x75,
+0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x62, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64,
+0x61, 0x69, 0x6e, 0x3b, 0x62, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x70, 0x75, 0x6e,
+0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x70, 0x68, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64,
+0x61, 0x69, 0x6e, 0x3b, 0x70, 0x75, 0x6e, 0x74, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x46, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x62, 0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x20, 0x53, 0x6f, 0x77, 0x77,
+0x75, 0x2d, 0x6a, 0x61, 0x6e, 0x74, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46,
+0x41, 0x20, 0x79, 0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x20, 0x53, 0x6f, 0x77, 0x77, 0x75, 0x2d, 0x6a, 0x61, 0x6e,
+0x74, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65,
+0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61,
+0x6e, 0x73, 0x69, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x42, 0x49, 0x4b,
+0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66,
+0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20,
+0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f,
+0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x42, 0x6f, 0x73,
+0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f,
+0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62,
+0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20,
+0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b,
+0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b,
+0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b,
+0x65, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61,
+0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20,
+0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x41a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430,
+0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440,
+0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438,
+0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d,
+0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442,
+0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a,
+0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432,
+0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x47, 0x68,
+0x61, 0x6e, 0x61, 0x20, 0x53, 0x69, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x4e, 0x52, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x4e, 0x52, 0x3b, 0x4e, 0x61, 0x1ecb, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61,
+0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b,
+0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46,
+0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256,
+0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65,
+0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
+0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x50, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69,
+0x6e, 0x61, 0x73, 0x3b, 0x3b, 0x70, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e,
+0x61, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69,
+0x6e, 0x61, 0x73, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65,
+0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x3b,
+0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x45,
+0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61,
+0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75,
+0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b,
+0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x65, 0x75, 0x72,
+0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b,
+0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x72, 0x75, 0x6f, 0x167,
+0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72,
+0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64,
+0x6e, 0x6f, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x75, 0x20, 0x53, 0x65, 0x65, 0x66, 0x61, 0x61,
+0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x69, 0x20,
+0x53, 0x65, 0x65, 0x66, 0x61, 0x61, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67,
+0x69, 0x79, 0x79, 0x61, 0x20, 0x4d, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x43, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x4e, 0x6a, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x65, 0x6c, 0x20, 0x4b, 0x65, 0x6e, 0x79,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d,
+0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61,
+0x20, 0x79, 0x61, 0x73, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x68, 0x65, 0x6c, 0x65, 0x72, 0x69, 0x20, 0x73, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x2d30, 0x2d37, 0x2d54, 0x2d49, 0x2d4e, 0x20, 0x2d4f, 0x20, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x61, 0x64, 0x72, 0x69, 0x6d, 0x20, 0x6e, 0x20, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x41, 0x7a, 0x7a, 0x61, 0x79, 0x72,
+0x69, 0x3b, 0x3b, 0x41, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x6e, 0x20, 0x5a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x3b,
+0x3b, 0x3b, 0x49, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x65, 0x6e, 0x20, 0x6e, 0x20, 0x5a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x3b,
+0x45, 0x73, 0x68, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x48, 0x75,
+0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69,
+0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x73, 0x65, 0x66, 0x61, 0x20, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3,
+0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x20, 0x6d, 0x6f, 0x72,
+0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0xed, 0x69, 0x6e, 0x67,
+0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x79, 0x61, 0x20, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75, 0x20, 0x4b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72,
+0x64, 0x69, 0x61, 0x6e, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75, 0x20, 0x4b, 0x61, 0x62,
+0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x74, 0x61, 0x62,
+0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69,
+0x62, 0x69, 0x61, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75,
+0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72, 0x6f, 0x70, 0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20,
+0x65, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72, 0x6f, 0x70, 0x69, 0x79,
+0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x53, 0x69, 0x72, 0x69, 0x6e, 0x6a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e,
+0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x2019, 0x6f, 0x74,
+0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x2019, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x2019, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x2019, 0x20, 0x4b, 0x65, 0x6e, 0x79,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43,
+0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61,
+0x72, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x65, 0x72, 0x68, 0x65, 0x6d,
+0x20, 0x55, 0x6d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c,
+0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x930, 0x93e, 0x902, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d,
+0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b,
+0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e, 0x44c, 0x43c, 0x430, 0x448, 0x3b, 0x440, 0x461, 0x441, 0x441,
+0x456, 0x301, 0x439, 0x441, 0x43a, 0x457, 0x439, 0x20, 0x440, 0xa64b, 0x301, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x440, 0x461, 0x441, 0x441, 0x456, 0x301, 0x439, 0x441, 0x43a, 0x430, 0x433, 0x461, 0x20, 0x440, 0xa64b, 0x431, 0x43b, 0x467, 0x300, 0x3b,
+0x4e, 0x66, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0xe0, 0x6c, 0xe2, 0x14b, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x1ce, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x65, 0x65, 0x66, 0x61, 0x20, 0x79, 0x61, 0x74, 0x69, 0x20, 0x42, 0x43,
+0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x259, 0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20,
+0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0xe1, 0x14b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x61, 0x69, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x20, 0x441, 0x43e, 0x43b, 0x43a, 0x443, 0x43e, 0x431, 0x430, 0x439,
+0x430, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x20, 0x441, 0x43e, 0x43b,
+0x43a, 0x443, 0x43e, 0x431, 0x430, 0x439, 0x430, 0x3b, 0x49, 0x68, 0x65, 0x6c, 0x61, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e,
+0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x20, 0xa55c, 0xa55e,
+0xa54c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x20, 0x44, 0x61, 0x6c,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x25b, 0x6c, 0xe2, 0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x72,
+0xe8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x65, 0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x62f, 0x6cc, 0x646, 0x627, 0x631, 0x6cc, 0x20, 0x639, 0x6ce, 0x631, 0x627, 0x642, 0x6cc, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x695, 0x6cc, 0x627, 0x6b5, 0x6cc, 0x20, 0x626, 0x6ce, 0x631, 0x627, 0x646, 0x6cc, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65,
+0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f,
+0x3b, 0x65, 0x75, 0x72, 0x61, 0x6a, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x77, 0x3b, 0x65,
+0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x20, 0x631, 0x6cc, 0x627, 0x644,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x20, 0x631, 0x6cc, 0x627, 0x644, 0x3b, 0x6e2f, 0x5e63, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5e63, 0x3b
};
static const ushort currency_format_data[] = {
0x25, 0x31, 0x25, 0x32, 0x25, 0x32, 0x25, 0x31, 0x25, 0x32, 0xa0, 0x25, 0x31, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x25, 0x32,
0x25, 0x31, 0x4b, 0x25, 0x32, 0xa0, 0x2d, 0x25, 0x31, 0x28, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x29, 0x25, 0x32, 0x2d, 0x25,
-0x31, 0x25, 0x31, 0xa0, 0x6d, 0x6e, 0xa0, 0x25, 0x32, 0x25, 0x32, 0xa0, 0x25, 0x31, 0x2d, 0x25, 0x32, 0x2212, 0x25, 0x31,
-0x200f, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x200f, 0x200e, 0x2d, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x200e, 0x25, 0x32, 0x25, 0x31, 0x25,
-0x32, 0xa0, 0x25, 0x31, 0x4b, 0x28, 0x25, 0x32, 0x25, 0x31, 0x29, 0x25, 0x32, 0x2d, 0xa0, 0x25, 0x31
+0x31, 0x25, 0x32, 0xa0, 0x25, 0x31, 0x4b, 0x25, 0x31, 0xa0, 0x6b, 0x25, 0x32, 0x2d, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x25,
+0x32, 0xa0, 0x25, 0x31, 0x2d, 0x25, 0x32, 0x2212, 0x25, 0x31, 0x200f, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x200f, 0x200e, 0x2d, 0x25,
+0x31, 0xa0, 0x25, 0x32, 0x200e, 0x25, 0x32, 0x25, 0x31, 0x28, 0x25, 0x32, 0x25, 0x31, 0x29, 0x25, 0x31, 0xa0, 0x4b, 0xa0,
+0x25, 0x32, 0x25, 0x32, 0x2d, 0xa0, 0x25, 0x31
};
static const ushort endonyms_data[] = {
@@ -5862,273 +6030,280 @@ static const ushort endonyms_data[] = {
0x648, 0x645, 0x627, 0x644, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x633, 0x648, 0x631, 0x64a, 0x627, 0x62a, 0x648, 0x646, 0x633,
0x627, 0x644, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x645,
0x62a, 0x62d, 0x62f, 0x629, 0x627, 0x644, 0x635, 0x62d, 0x631, 0x627, 0x621, 0x20, 0x627, 0x644, 0x63a, 0x631, 0x628, 0x64a, 0x629, 0x627,
-0x644, 0x64a, 0x645, 0x646, 0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x570, 0x561, 0x575, 0x565,
-0x580, 0x565, 0x576, 0x540, 0x561, 0x575, 0x561, 0x57d, 0x57f, 0x561, 0x576, 0x985, 0x9b8, 0x9ae, 0x9c0, 0x9af, 0x9bc, 0x9be, 0x9ad, 0x9be,
-0x9f0, 0x9a4, 0x61, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63,
-0x61, 0x6e, 0x430, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430, 0x43d, 0x410, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9,
-0x430, 0x43d, 0x65, 0x75, 0x73, 0x6b, 0x61, 0x72, 0x61, 0x45, 0x73, 0x70, 0x61, 0x69, 0x6e, 0x69, 0x61, 0x9ac, 0x9be, 0x982,
-0x9b2, 0x9be, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0xf62, 0xfab, 0xf7c, 0xf44, 0xf0b, 0xf41,
-0xf60, 0xf56, 0xfb2, 0xf74, 0xf42, 0x62, 0x72, 0x65, 0x7a, 0x68, 0x6f, 0x6e, 0x65, 0x67, 0x46, 0x72, 0x61, 0xf1, 0x73, 0x431,
-0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x438, 0x44f, 0x1019, 0x103c, 0x1014, 0x103a,
-0x1019, 0x102c, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x430, 0x44f, 0x411, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x44c,
-0x1781, 0x17d2, 0x1798, 0x17c2, 0x179a, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x63, 0x61, 0x74, 0x61, 0x6c, 0xe0, 0x45, 0x73,
-0x70, 0x61, 0x6e, 0x79, 0x61, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72, 0x61, 0x46, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x49, 0x74,
-0xe0, 0x6c, 0x69, 0x61, 0x7b80, 0x4f53, 0x4e2d, 0x6587, 0x4e2d, 0x56fd, 0x4e2d, 0x56fd, 0x9999, 0x6e2f, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x4e2d,
-0x56fd, 0x6fb3, 0x95e8, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x65b0, 0x52a0, 0x5761, 0x7e41, 0x9ad4, 0x4e2d, 0x6587, 0x4e2d, 0x570b, 0x9999, 0x6e2f, 0x7279,
-0x5225, 0x884c, 0x653f, 0x5340, 0x4e2d, 0x570b, 0x6fb3, 0x9580, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x53f0, 0x7063, 0x68, 0x72, 0x76, 0x61, 0x74,
-0x73, 0x6b, 0x69, 0x48, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x42, 0x6f, 0x73, 0x6e, 0x61, 0x20, 0x69, 0x20, 0x48,
-0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x69, 0x6e, 0x61, 0x10d, 0x65, 0x161, 0x74, 0x69, 0x6e, 0x61, 0x10c, 0x65, 0x73,
-0x6b, 0x6f, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x47, 0x72, 0xf8, 0x6e, 0x6c, 0x61,
-0x6e, 0x64, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e,
-0x64, 0x41, 0x72, 0x75, 0x62, 0x61, 0x42, 0x65, 0x6c, 0x67, 0x69, 0xeb, 0x43, 0x75, 0x72, 0x61, 0xe7, 0x61, 0x6f, 0x53,
-0x75, 0x72, 0x69, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x61, 0x72, 0x69, 0x62, 0x69, 0x73, 0x63, 0x68, 0x20, 0x4e, 0x65, 0x64,
-0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x61, 0x72, 0x74, 0x65, 0x6e, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64,
-0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x6e, 0x20, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x41, 0x6e, 0x67, 0x75, 0x69, 0x6c, 0x6c, 0x61, 0x41, 0x6e, 0x74, 0x69,
-0x67, 0x75, 0x61, 0x20, 0x26, 0x20, 0x42, 0x61, 0x72, 0x62, 0x75, 0x64, 0x61, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c,
-0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61,
-0x41, 0x75, 0x73, 0x74, 0x72, 0x69, 0x61, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x61, 0x73, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64,
-0x6f, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x75, 0x6d, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x65, 0x72, 0x6d, 0x75,
-0x64, 0x61, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x49, 0x6e,
-0x64, 0x69, 0x61, 0x6e, 0x20, 0x4f, 0x63, 0x65, 0x61, 0x6e, 0x20, 0x54, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6f, 0x72, 0x79,
-0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x61, 0x64,
-0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x43, 0x61, 0x79,
-0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x6d, 0x61, 0x73,
-0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x43, 0x6f, 0x63, 0x6f, 0x73, 0x20, 0x28, 0x4b, 0x65, 0x65, 0x6c, 0x69, 0x6e,
-0x67, 0x29, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x43, 0x6f, 0x6f, 0x6b, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e,
-0x64, 0x73, 0x43, 0x79, 0x70, 0x72, 0x75, 0x73, 0x44, 0x65, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x44, 0x6f, 0x6d, 0x69, 0x6e,
-0x69, 0x63, 0x61, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x46, 0x69, 0x6a, 0x69, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x47, 0x75, 0x65,
-0x72, 0x6e, 0x73, 0x65, 0x79, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x79, 0x47, 0x68,
-0x61, 0x6e, 0x61, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x47,
-0x75, 0x61, 0x6d, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x53,
-0x41, 0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x49, 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x64,
-0x49, 0x73, 0x72, 0x61, 0x65, 0x6c, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x69,
-0x72, 0x69, 0x62, 0x61, 0x74, 0x69, 0x4c, 0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61,
-0x4d, 0x61, 0x63, 0x61, 0x75, 0x20, 0x53, 0x41, 0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x61, 0x64, 0x61, 0x67,
-0x61, 0x73, 0x63, 0x61, 0x72, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x4d,
-0x61, 0x6c, 0x74, 0x61, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73,
-0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x4d,
-0x6f, 0x6e, 0x74, 0x73, 0x65, 0x72, 0x72, 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x4e, 0x61, 0x75, 0x72,
-0x75, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c,
-0x61, 0x6e, 0x64, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x4e, 0x69, 0x75, 0x65, 0x4e, 0x6f, 0x72, 0x66, 0x6f, 0x6c,
-0x6b, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x72,
-0x69, 0x61, 0x6e, 0x61, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e,
-0x50, 0x61, 0x6c, 0x61, 0x75, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65,
-0x61, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x73, 0x50, 0x69, 0x74, 0x63, 0x61, 0x69, 0x72, 0x6e,
-0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x50, 0x75, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x52, 0x69, 0x63, 0x6f, 0x52,
-0x77, 0x61, 0x6e, 0x64, 0x61, 0x53, 0x74, 0x2e, 0x20, 0x4b, 0x69, 0x74, 0x74, 0x73, 0x20, 0x26, 0x20, 0x4e, 0x65, 0x76,
-0x69, 0x73, 0x53, 0x74, 0x2e, 0x20, 0x4c, 0x75, 0x63, 0x69, 0x61, 0x53, 0x74, 0x2e, 0x20, 0x56, 0x69, 0x6e, 0x63, 0x65,
-0x6e, 0x74, 0x20, 0x26, 0x20, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x53, 0x61, 0x6d, 0x6f, 0x61,
-0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f,
-0x6e, 0x65, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x53, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x69, 0x61, 0x53,
-0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20,
-0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x53, 0x74, 0x2e, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x53, 0x75, 0x64, 0x61,
-0x6e, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x6c, 0x61, 0x6e, 0x64, 0x53, 0x77, 0x65, 0x64, 0x65, 0x6e, 0x53, 0x77, 0x69, 0x74,
-0x7a, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x54, 0x6f, 0x6b, 0x65, 0x6c,
-0x61, 0x75, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x26, 0x20, 0x54, 0x6f,
-0x62, 0x61, 0x67, 0x6f, 0x54, 0x75, 0x72, 0x6b, 0x73, 0x20, 0x26, 0x20, 0x43, 0x61, 0x69, 0x63, 0x6f, 0x73, 0x20, 0x49,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x54, 0x75, 0x76, 0x61, 0x6c, 0x75, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x42, 0x72,
-0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20,
-0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x4f, 0x75, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x67,
-0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x42, 0x72, 0x69, 0x74, 0x69,
-0x73, 0x68, 0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x2e, 0x53,
-0x2e, 0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x5a, 0x61, 0x6d, 0x62,
-0x69, 0x61, 0x5a, 0x69, 0x6d, 0x62, 0x61, 0x62, 0x77, 0x65, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x20, 0x47, 0x61, 0x72, 0x63,
-0x69, 0x61, 0x49, 0x73, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x61, 0x6e, 0x4a, 0x65, 0x72, 0x73, 0x65, 0x79, 0x53,
-0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x53, 0x69, 0x6e, 0x74, 0x20, 0x4d, 0x61, 0x61, 0x72, 0x74,
-0x65, 0x6e, 0x65, 0x65, 0x73, 0x74, 0x69, 0x45, 0x65, 0x73, 0x74, 0x69, 0x66, 0xf8, 0x72, 0x6f, 0x79, 0x73, 0x6b, 0x74,
-0x46, 0xf8, 0x72, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x75, 0x6f, 0x6d, 0x69, 0x53, 0x75, 0x6f, 0x6d, 0x69, 0x66, 0x72, 0x61,
-0x6e, 0xe7, 0x61, 0x69, 0x73, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x42, 0x65,
-0x6c, 0x67, 0x69, 0x71, 0x75, 0x65, 0x42, 0xe9, 0x6e, 0x69, 0x6e, 0x42, 0x75, 0x72, 0x6b, 0x69, 0x6e, 0x61, 0x20, 0x46,
-0x61, 0x73, 0x6f, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x75, 0x6e, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20,
-0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x63,
-0x65, 0x6e, 0x74, 0x72, 0x61, 0x66, 0x72, 0x69, 0x63, 0x61, 0x69, 0x6e, 0x65, 0x54, 0x63, 0x68, 0x61, 0x64, 0x43, 0x6f,
-0x6d, 0x6f, 0x72, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x2d, 0x4b, 0x69, 0x6e, 0x73, 0x68, 0x61, 0x73, 0x61, 0x43,
-0x6f, 0x6e, 0x67, 0x6f, 0x2d, 0x42, 0x72, 0x61, 0x7a, 0x7a, 0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x43, 0xf4, 0x74, 0x65,
-0x20, 0x64, 0x2019, 0x49, 0x76, 0x6f, 0x69, 0x72, 0x65, 0x44, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x47, 0x75, 0x69,
-0x6e, 0xe9, 0x65, 0x20, 0xe9, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x65, 0x47, 0x75, 0x79, 0x61, 0x6e,
-0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x50, 0x6f, 0x6c, 0x79, 0x6e, 0xe9, 0x73, 0x69, 0x65,
-0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x47, 0x61, 0x62, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x64, 0x65,
-0x6c, 0x6f, 0x75, 0x70, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x48, 0x61, 0xef, 0x74, 0x69, 0x4c, 0x75, 0x78, 0x65,
-0x6d, 0x62, 0x6f, 0x75, 0x72, 0x67, 0x4d, 0x61, 0x6c, 0x69, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71, 0x75, 0x65,
-0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x79,
-0x6f, 0x74, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x4d, 0x61, 0x72, 0x6f, 0x63, 0x4e, 0x6f, 0x75, 0x76, 0x65,
-0x6c, 0x6c, 0x65, 0x2d, 0x43, 0x61, 0x6c, 0xe9, 0x64, 0x6f, 0x6e, 0x69, 0x65, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x4c, 0x61,
-0x20, 0x52, 0xe9, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x53, 0xe9, 0x6e, 0xe9, 0x67, 0x61, 0x6c, 0x53, 0x61, 0x69, 0x6e, 0x74,
-0x2d, 0x50, 0x69, 0x65, 0x72, 0x72, 0x65, 0x2d, 0x65, 0x74, 0x2d, 0x4d, 0x69, 0x71, 0x75, 0x65, 0x6c, 0x6f, 0x6e, 0x66,
-0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x75, 0x69, 0x73, 0x73, 0x65,
-0x53, 0x79, 0x72, 0x69, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x54, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x57, 0x61, 0x6c, 0x6c,
-0x69, 0x73, 0x2d, 0x65, 0x74, 0x2d, 0x46, 0x75, 0x74, 0x75, 0x6e, 0x61, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x42, 0x61,
-0x72, 0x74, 0x68, 0xe9, 0x6c, 0x65, 0x6d, 0x79, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e,
-0x57, 0x65, 0x73, 0x74, 0x2d, 0x46, 0x72, 0x79, 0x73, 0x6b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0xe2, 0x6e, 0x47, 0xe0,
-0x69, 0x64, 0x68, 0x6c, 0x69, 0x67, 0x41, 0x6e, 0x20, 0x52, 0xec, 0x6f, 0x67, 0x68, 0x61, 0x63, 0x68, 0x64, 0x20, 0x41,
-0x6f, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x74, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x45, 0x73, 0x70, 0x61, 0xf1, 0x61,
-0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x10e1, 0x10d0, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10d5, 0x10d4, 0x10da, 0x10dd, 0x44, 0x65, 0x75,
-0x74, 0x73, 0x63, 0x68, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0xd6, 0x73, 0x74, 0x65, 0x72,
-0x72, 0x65, 0x69, 0x63, 0x68, 0x69, 0x73, 0x63, 0x68, 0x65, 0x73, 0x20, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0xd6,
-0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x65, 0x6e, 0x49, 0x74, 0x61, 0x6c,
-0x69, 0x65, 0x6e, 0x4c, 0x69, 0x65, 0x63, 0x68, 0x74, 0x65, 0x6e, 0x73, 0x74, 0x65, 0x69, 0x6e, 0x4c, 0x75, 0x78, 0x65,
-0x6d, 0x62, 0x75, 0x72, 0x67, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x48, 0x6f, 0x63, 0x68, 0x64,
-0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x395, 0x3bb, 0x3bb, 0x3b7, 0x3bd, 0x3b9, 0x3ba,
-0x3ac, 0x395, 0x3bb, 0x3bb, 0x3ac, 0x3b4, 0x3b1, 0x39a, 0x3cd, 0x3c0, 0x3c1, 0x3bf, 0x3c2, 0x6b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c,
-0x69, 0x73, 0x75, 0x74, 0x4b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x74, 0x20, 0x4e, 0x75, 0x6e, 0x61, 0x61, 0x74,
-0xa97, 0xac1, 0xa9c, 0xab0, 0xabe, 0xaa4, 0xac0, 0xaad, 0xabe, 0xab0, 0xaa4, 0x48, 0x61, 0x75, 0x73, 0x61, 0x4e, 0x61, 0x6a, 0x65,
-0x72, 0x69, 0x79, 0x61, 0x47, 0x61, 0x6e, 0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72, 0x5e2, 0x5d1, 0x5e8, 0x5d9, 0x5ea, 0x5d9, 0x5e9,
-0x5e8, 0x5d0, 0x5dc, 0x939, 0x93f, 0x928, 0x94d, 0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x4d,
-0x61, 0x67, 0x79, 0x61, 0x72, 0x6f, 0x72, 0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0xcd,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x47, 0x61, 0x65, 0x69, 0x6c, 0x67,
-0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x53,
-0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x61, 0x43, 0x69, 0x74,
-0x74, 0xe0, 0x20, 0x64, 0x65, 0x6c, 0x20, 0x56, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x65e5, 0x672c, 0x8a9e, 0x65e5, 0x672c,
-0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672, 0x634, 0x64f, 0x631, 0x6c1, 0x650, 0x646, 0x65b, 0x62f, 0x648,
-0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, 0x430, 0x49b, 0x20, 0x442, 0x456, 0x43b, 0x456, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441,
-0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, 0x61, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x43a, 0x44b, 0x440, 0x433, 0x44b, 0x437,
-0x447, 0x430, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0xd55c, 0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0xc870,
-0xc120, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0xc778, 0xbbfc, 0xacf5, 0xd654, 0xad6d, 0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x55, 0x62,
-0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, 0xeb2, 0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74,
-0x76, 0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0xed, 0x6b, 0x69,
-0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x20, 0x44, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0xed, 0x6b,
-0x69, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41,
-0x66, 0x72, 0xed, 0x6b, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69,
-0x65, 0x74, 0x75, 0x76, 0x69, 0x173, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d,
-0x441, 0x43a, 0x438, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73,
-0x79, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x69, 0x6b, 0x61, 0x72, 0x61, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20,
-0x4d, 0x65, 0x6c, 0x61, 0x79, 0x75, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x75, 0x72,
-0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d, 0x61, 0x6c, 0x74, 0x69, 0x92e, 0x930,
-0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x928, 0x947, 0x92a, 0x93e, 0x932,
-0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, 0x6b, 0x6d, 0xe5, 0x6c, 0x4e, 0x6f,
-0x72, 0x67, 0x65, 0x53, 0x76, 0x61, 0x6c, 0x62, 0x61, 0x72, 0x64, 0x20, 0x6f, 0x67, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x4d,
-0x61, 0x79, 0x65, 0x6e, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a, 0x62a, 0x648, 0x627, 0x641, 0x63a,
-0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x62f, 0x631, 0x6cc, 0x70,
-0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73,
-0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, 0x6f, 0x20, 0x56, 0x65, 0x72,
-0x64, 0x65, 0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x20, 0x45,
-0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x2d, 0x42, 0x69, 0x73, 0x73, 0x61,
-0x75, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x6f, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x2c, 0x20, 0x52, 0x41,
-0x45, 0x20, 0x64, 0x61, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65,
-0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x50, 0x6f, 0x72,
-0x74, 0x75, 0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e,
-0x63, 0x69, 0x70, 0x65, 0x53, 0x75, 0xed, 0xe7, 0x61, 0xa2a, 0xa70, 0xa1c, 0xa3e, 0xa2c, 0xa40, 0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e,
-0x646, 0x62c, 0x627, 0x628, 0x6cc, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x52, 0x75, 0x6e, 0x61, 0x73, 0x69, 0x6d, 0x69,
-0x50, 0x65, 0x72, 0xfa, 0x42, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x45, 0x63, 0x75, 0x61, 0x64, 0x6f, 0x72, 0x72, 0x75,
-0x6d, 0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x103, 0x52,
-0x6f, 0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x61, 0x73, 0x63, 0x103, 0x52,
-0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x61, 0x440, 0x443, 0x441, 0x441,
-0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438,
-0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e, 0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430,
-0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64, 0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73, 0x65, 0x20, 0x74, 0xee, 0x20, 0x42,
-0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421, 0x440, 0x431, 0x438, 0x458, 0x430, 0x411,
-0x43e, 0x441, 0x43d, 0x430, 0x20, 0x438, 0x20, 0x425, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440,
-0x43d, 0x430, 0x20, 0x413, 0x43e, 0x440, 0x430, 0x41a, 0x43e, 0x441, 0x43e, 0x432, 0x43e, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x43,
-0x72, 0x6e, 0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, 0x4b, 0x6f, 0x73, 0x6f, 0x76, 0x6f,
-0x438, 0x440, 0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440, 0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441,
-0x435, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f, 0x6e, 0x61, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20,
-0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65,
-0x6e, 0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65,
-0x6e, 0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69,
-0x79, 0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x69,
-0x6e, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, 0x70, 0x61, 0xf1,
-0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x42, 0x65, 0x6c,
-0x69, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43, 0x6f, 0x73, 0x74,
-0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x20,
-0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x6c, 0x20, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f,
-0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75,
-0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1,
-0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4e, 0x69,
-0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x50, 0x61, 0x6e, 0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61,
-0x79, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x45, 0x45, 0x2e, 0x20, 0x55, 0x55, 0x2e, 0x55, 0x72, 0x75,
-0x67, 0x75, 0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61,
-0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x6e, 0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75,
-0x74, 0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c, 0x6c, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c,
-0x69, 0x4b, 0x69, 0x6e, 0x67, 0x77, 0x61, 0x6e, 0x61, 0x4a, 0x61, 0x6d, 0x68, 0x75, 0x72, 0x69, 0x20, 0x79, 0x61, 0x20,
-0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, 0x69, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67,
-0x6f, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76, 0x65, 0x72, 0x69, 0x67, 0x65, 0xc5, 0x6c, 0x61, 0x6e, 0x64,
-0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, 0xbc7, 0xb9a, 0xbbf, 0xbaf, 0xbbe, 0xb9a,
-0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0xc24, 0xc46, 0xc32, 0xc41,
-0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0x20, 0xc26, 0xc47, 0xc36, 0xc02, 0xe44, 0xe17, 0xe22, 0xf56, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90,
-0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53, 0xf42, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4,
-0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20, 0x66, 0x61, 0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72, 0x6b,
-0xe7, 0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x4b, 0x131, 0x62, 0x72, 0x131, 0x73, 0x74, 0xfc, 0x72, 0x6b, 0x6d,
-0x65, 0x6e, 0xe7, 0x65, 0x54, 0xfc, 0x72, 0x6b, 0x6d, 0x65, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x626, 0x6c7, 0x64a, 0x63a,
-0x6c7, 0x631, 0x686, 0x6d5, 0x62c, 0x6c7, 0x6ad, 0x6af, 0x648, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a, 0x430, 0x423,
-0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627, 0x631, 0x62f, 0x648, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6f, 0x2018, 0x7a, 0x62, 0x65,
-0x6b, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x627, 0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x45e, 0x437,
-0x431, 0x435, 0x43a, 0x447, 0x430, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x54, 0x69, 0x1ebf, 0x6e, 0x67,
-0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, 0x1ec7, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67,
-0x59, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61, 0x73, 0x20, 0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0xc8, 0x64, 0xe8, 0x20,
-0x59, 0x6f, 0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a,
-0xed, 0x72, 0xed, 0xe0, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x42, 0x25b, 0x300, 0x6e, 0x25b, 0x300,
-0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, 0x65, 0x67, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b,
-0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, 0x65, 0x6c, 0x67, 0x45, 0x6c, 0x6c, 0x61, 0x6e, 0x20,
-0x56, 0x61, 0x6e, 0x6e, 0x69, 0x6e, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x77, 0x65, 0x6b, 0x52, 0x79, 0x77, 0x76, 0x61, 0x6e,
-0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x41, 0x6b, 0x61, 0x6e, 0x47, 0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902,
-0x915, 0x923, 0x940, 0x49, 0x67, 0x62, 0x6f, 0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x66, 0x75, 0x72, 0x6c, 0x61, 0x6e,
-0x49, 0x74, 0x61, 0x6c, 0x69, 0x65, 0x45, 0x28b, 0x65, 0x67, 0x62, 0x65, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75,
-0x74, 0x6f, 0x6d, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c,
-0x6f, 0x20, 0x48, 0x61, 0x77, 0x61, 0x69, 0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75,
-0x69, 0x20, 0x50, 0x16b, 0x20, 0x2bb, 0x49, 0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69,
-0x70, 0x69, 0x6e, 0x61, 0x73, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63,
-0x68, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x72, 0x69, 0x69, 0x63, 0x68, 0x4c, 0x69,
-0xe4, 0x63, 0x68, 0x74, 0x65, 0x73, 0x63, 0x68, 0x74, 0xe4, 0x69, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x4e, 0x65, 0x64, 0x64,
-0x65, 0x72, 0x73, 0x61, 0x73, 0x73, 0x2019, 0x73, 0x63, 0x68, 0x44, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e,
-0x64, 0x4e, 0x65, 0x64, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x6e, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73, 0xe1,
-0x6d, 0x65, 0x67, 0x69, 0x65, 0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61, 0x52,
-0x75, 0x6f, 0x167, 0x167, 0x61, 0x45, 0x6b, 0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61,
-0x50, 0x75, 0x6c, 0x61, 0x61, 0x72, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75,
-0x75, 0x6e, 0x47, 0x69, 0x6e, 0x65, 0x4d, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x47, 0x69, 0x6b, 0x75, 0x79, 0x75,
-0x4b, 0x69, 0x73, 0x61, 0x6d, 0x70, 0x75, 0x72, 0x73, 0x65, 0x6e, 0x61, 0x69, 0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, 0x65,
-0x6c, 0x65, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, 0x2d5b, 0x2d4d, 0x2d43, 0x2d49, 0x2d5c, 0x2d4d, 0x2d4e,
-0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x54, 0x61, 0x73, 0x68, 0x65, 0x6c, 0x1e25, 0x69, 0x79, 0x74, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62,
-0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x52, 0x75, 0x6e,
-0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61, 0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, 0x61,
-0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61, 0x6d, 0x61, 0x6e, 0x61, 0x6b, 0x61, 0x6e,
-0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13cc, 0x13ca, 0x20, 0x13a2, 0x13f3, 0x13be, 0x13b5, 0x13cd, 0x13d4, 0x13c5, 0x20,
-0x13cd, 0x13a6, 0x13da, 0x13a9, 0x6b, 0x72, 0x65, 0x6f, 0x6c, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, 0x6f,
-0x72, 0x69, 0x73, 0x43, 0x68, 0x69, 0x6d, 0x61, 0x6b, 0x6f, 0x6e, 0x64, 0x65, 0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, 0x67,
-0x69, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x4c, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, 0x67,
-0x61, 0x6e, 0x64, 0x61, 0x49, 0x63, 0x68, 0x69, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72,
-0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b, 0x61, 0x62, 0x75, 0x20, 0x56, 0x65, 0x72, 0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, 0x72,
-0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e, 0x6a, 0x69, 0x6e, 0x45, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, 0x79,
-0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b, 0x68, 0x6f, 0x65, 0x67, 0x6f, 0x77, 0x61, 0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69,
-0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61, 0x63, 0x68, 0x61, 0x6d, 0x65, 0x4b, 0xf6, 0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, 0xfc,
-0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x61, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, 0x4f,
-0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61, 0x4c, 0x75, 0x6c, 0x75, 0x68, 0x69, 0x61, 0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, 0x54,
-0x61, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x69, 0x74, 0x65, 0x73, 0x6f, 0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, 0x6f,
-0x79, 0x72, 0x61, 0x20, 0x63, 0x69, 0x69, 0x6e, 0x69, 0x4d, 0x61, 0x61, 0x6c, 0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, 0x61,
-0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f, 0x52, 0x75, 0x6b, 0x69, 0x67, 0x61, 0x54, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, 0x74,
-0x20, 0x6e, 0x20, 0x6c, 0x61, 0x1e6d, 0x6c, 0x61, 0x1e63, 0x4d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x4b, 0x6f, 0x79, 0x72, 0x61,
-0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73, 0x68, 0x61, 0x6d, 0x62, 0x61, 0x61, 0x92c,
-0x921, 0x93c, 0x94b, 0x43d, 0x43e, 0x445, 0x447, 0x438, 0x439, 0x43d, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x446, 0x435, 0x440, 0x43a, 0x43e,
-0x432, 0x43d, 0x43e, 0x441, 0x43b, 0x43e, 0x432, 0x435, 0x301, 0x43d, 0x441, 0x43a, 0x457, 0x439, 0x440, 0x461, 0x441, 0x441, 0x456, 0x301,
-0x430, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75, 0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20,
-0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x4c, 0xeb, 0x74, 0x7a, 0x65, 0x62, 0x75, 0x65, 0x72, 0x67, 0x65, 0x73, 0x63, 0x68, 0x4c,
-0xeb, 0x74, 0x7a, 0x65, 0x62, 0x75, 0x65, 0x72, 0x67, 0x41, 0x67, 0x68, 0x65, 0x6d, 0x4b, 0xe0, 0x6d, 0xe0, 0x6c, 0xfb,
-0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb, 0x6e, 0x5a, 0x61, 0x72, 0x6d, 0x61, 0x63,
-0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c, 0xe1, 0x6a, 0x6f, 0x6f, 0x6c, 0x61, 0x53,
-0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b, 0x61, 0x6d, 0x259, 0x72, 0xfa, 0x6e, 0x72,
-0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61, 0x6b, 0x75, 0x61, 0x55, 0x6d, 0x6f, 0x7a,
-0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x14b, 0x4b,
-0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54, 0x68, 0x6f, 0x6b, 0x20, 0x4e, 0x61, 0x74,
-0x68, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x49,
-0x73, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x54, 0x61, 0x73,
-0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559, 0xa524, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c,
-0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e,
-0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa, 0x6e, 0x61, 0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e,
-0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c, 0xfb, 0x6e, 0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d,
-0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61, 0x6d, 0x61, 0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3,
-0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254, 0x6e, 0x4b, 0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d, 0x4c,
-0x61, 0x6b, 0x21f, 0xf3, 0x6c, 0x2bc, 0x69, 0x79, 0x61, 0x70, 0x69, 0x4d, 0xed, 0x6c, 0x61, 0x68, 0x61, 0x14b, 0x73, 0x6b,
-0x61, 0x20, 0x54, 0x21f, 0x61, 0x6d, 0xe1, 0x6b, 0x21f, 0x6f, 0x10d, 0x68, 0x65, 0x2d5c, 0x2d30, 0x2d4e, 0x2d30, 0x2d63, 0x2d49, 0x2d56,
-0x2d5c, 0x6a9, 0x648, 0x631, 0x62f, 0x6cc, 0x6cc, 0x20, 0x646, 0x627, 0x648, 0x6d5, 0x646, 0x62f, 0x6cc, 0x639, 0x6ce, 0x631, 0x627, 0x642,
-0x626, 0x6ce, 0x631, 0x627, 0x646, 0x64, 0x6f, 0x6c, 0x6e, 0x6f, 0x73, 0x65, 0x72, 0x62, 0x161, 0x107, 0x69, 0x6e, 0x61, 0x4e,
-0x69, 0x6d, 0x73, 0x6b, 0x61, 0x68, 0x6f, 0x72, 0x6e, 0x6a, 0x6f, 0x73, 0x65, 0x72, 0x62, 0x161, 0x107, 0x69, 0x6e, 0x61,
-0x4e, 0x11b, 0x6d, 0x73, 0x6b, 0x61, 0x61, 0x6e, 0x61, 0x72, 0xe2, 0x161, 0x6b, 0x69, 0x65, 0x6c, 0xe2, 0x53, 0x75, 0x6f,
-0x6d, 0xe2, 0x645, 0x627, 0x632, 0x631, 0x648, 0x646, 0x6cc, 0x644, 0x6ca, 0x631, 0x6cc, 0x20, 0x634, 0x648, 0x645, 0x627, 0x644, 0x6cc,
-0x7cb5, 0x8a9e, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340
+0x644, 0x64a, 0x645, 0x646, 0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x627, 0x644, 0x639, 0x631,
+0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x631, 0x633, 0x645, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x62d, 0x62f, 0x64a, 0x62b, 0x629, 0x627,
+0x644, 0x639, 0x627, 0x644, 0x645, 0x570, 0x561, 0x575, 0x565, 0x580, 0x565, 0x576, 0x540, 0x561, 0x575, 0x561, 0x57d, 0x57f, 0x561, 0x576,
+0x985, 0x9b8, 0x9ae, 0x9c0, 0x9af, 0x9bc, 0x9be, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x61, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61,
+0x6e, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x430, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430,
+0x43d, 0x410, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430, 0x43d, 0x65, 0x75, 0x73, 0x6b, 0x61, 0x72, 0x61, 0x45, 0x73,
+0x70, 0x61, 0x69, 0x6e, 0x69, 0x61, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9ad,
+0x9be, 0x9b0, 0x9a4, 0xf62, 0xfab, 0xf7c, 0xf44, 0xf0b, 0xf41, 0xf60, 0xf56, 0xfb2, 0xf74, 0xf42, 0x62, 0x72, 0x65, 0x7a, 0x68, 0x6f,
+0x6e, 0x65, 0x67, 0x46, 0x72, 0x61, 0xf1, 0x73, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x411, 0x44a, 0x43b,
+0x433, 0x430, 0x440, 0x438, 0x44f, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x430,
+0x44f, 0x411, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x44c, 0x1781, 0x17d2, 0x1798, 0x17c2, 0x179a, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787,
+0x17b6, 0x63, 0x61, 0x74, 0x61, 0x6c, 0xe0, 0x45, 0x73, 0x70, 0x61, 0x6e, 0x79, 0x61, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72,
+0x61, 0x46, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x49, 0x74, 0xe0, 0x6c, 0x69, 0x61, 0x7b80, 0x4f53, 0x4e2d, 0x6587, 0x4e2d, 0x56fd, 0x4e2d,
+0x56fd, 0x9999, 0x6e2f, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x4e2d, 0x56fd, 0x6fb3, 0x95e8, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x65b0, 0x52a0, 0x5761,
+0x7e41, 0x9ad4, 0x4e2d, 0x6587, 0x4e2d, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x4e2d, 0x570b, 0x6fb3, 0x9580, 0x7279, 0x5225, 0x884c,
+0x653f, 0x5340, 0x53f0, 0x7063, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x48, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61,
+0x42, 0x6f, 0x73, 0x6e, 0x61, 0x20, 0x69, 0x20, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x69, 0x6e, 0x61, 0x10d,
+0x65, 0x161, 0x74, 0x69, 0x6e, 0x61, 0x10c, 0x65, 0x73, 0x6b, 0x6f, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x44, 0x61, 0x6e, 0x6d,
+0x61, 0x72, 0x6b, 0x47, 0x72, 0xf8, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64,
+0x73, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x41, 0x72, 0x75, 0x62, 0x61, 0x42, 0x65, 0x6c, 0x67, 0x69,
+0xeb, 0x43, 0x75, 0x72, 0x61, 0xe7, 0x61, 0x6f, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x61, 0x72, 0x69,
+0x62, 0x69, 0x73, 0x63, 0x68, 0x20, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x2d,
+0x4d, 0x61, 0x61, 0x72, 0x74, 0x65, 0x6e, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c,
+0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x67, 0x6c,
+0x69, 0x73, 0x68, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x41, 0x6e, 0x67,
+0x75, 0x69, 0x6c, 0x6c, 0x61, 0x41, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x61, 0x20, 0x26, 0x20, 0x42, 0x61, 0x72, 0x62, 0x75,
+0x64, 0x61, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68,
+0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x41, 0x75, 0x73, 0x74, 0x72, 0x69, 0x61, 0x42, 0x61, 0x68, 0x61,
+0x6d, 0x61, 0x73, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x6f, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x75, 0x6d, 0x42, 0x65,
+0x6c, 0x69, 0x7a, 0x65, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x42,
+0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x4f, 0x63, 0x65, 0x61, 0x6e, 0x20,
+0x54, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x43, 0x61, 0x6d, 0x65,
+0x72, 0x6f, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68,
+0x43, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73,
+0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x6d, 0x61, 0x73, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x43, 0x6f, 0x63, 0x6f,
+0x73, 0x20, 0x28, 0x4b, 0x65, 0x65, 0x6c, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x43,
+0x6f, 0x6f, 0x6b, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x43, 0x79, 0x70, 0x72, 0x75, 0x73, 0x44, 0x65, 0x6e,
+0x6d, 0x61, 0x72, 0x6b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x46,
+0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x46, 0x69, 0x6a, 0x69, 0x46,
+0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x47, 0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61,
+0x47, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x79, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61,
+0x72, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x47, 0x75, 0x61, 0x6d, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x48, 0x6f,
+0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x53, 0x41, 0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x49, 0x6e, 0x64,
+0x69, 0x61, 0x49, 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x64, 0x49, 0x73, 0x72, 0x61, 0x65, 0x6c, 0x4a, 0x61, 0x6d, 0x61, 0x69,
+0x63, 0x61, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x69, 0x72, 0x69, 0x62, 0x61, 0x74, 0x69, 0x4c, 0x65, 0x73, 0x6f, 0x74,
+0x68, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x20, 0x53, 0x41, 0x52, 0x20, 0x43,
+0x68, 0x69, 0x6e, 0x61, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x63, 0x61, 0x72, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69,
+0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x4d, 0x61, 0x6c, 0x74, 0x61, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c,
+0x6c, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x4d, 0x69,
+0x63, 0x72, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x4d, 0x6f, 0x6e, 0x74, 0x73, 0x65, 0x72, 0x72, 0x61, 0x74, 0x4e, 0x61,
+0x6d, 0x69, 0x62, 0x69, 0x61, 0x4e, 0x61, 0x75, 0x72, 0x75, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64,
+0x73, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x4e,
+0x69, 0x75, 0x65, 0x4e, 0x6f, 0x72, 0x66, 0x6f, 0x6c, 0x6b, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x6f, 0x72,
+0x74, 0x68, 0x65, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x61, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64,
+0x73, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20,
+0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65,
+0x73, 0x50, 0x69, 0x74, 0x63, 0x61, 0x69, 0x72, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x50, 0x75, 0x65,
+0x72, 0x74, 0x6f, 0x20, 0x52, 0x69, 0x63, 0x6f, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x53, 0x74, 0x2e, 0x20, 0x4b, 0x69,
+0x74, 0x74, 0x73, 0x20, 0x26, 0x20, 0x4e, 0x65, 0x76, 0x69, 0x73, 0x53, 0x74, 0x2e, 0x20, 0x4c, 0x75, 0x63, 0x69, 0x61,
+0x53, 0x74, 0x2e, 0x20, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x26, 0x20, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64,
+0x69, 0x6e, 0x65, 0x73, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x53,
+0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65,
+0x53, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x69, 0x61, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61,
+0x6e, 0x64, 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x53, 0x74, 0x2e, 0x20, 0x48,
+0x65, 0x6c, 0x65, 0x6e, 0x61, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x6c, 0x61, 0x6e, 0x64, 0x53,
+0x77, 0x65, 0x64, 0x65, 0x6e, 0x53, 0x77, 0x69, 0x74, 0x7a, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x54, 0x61, 0x6e, 0x7a,
+0x61, 0x6e, 0x69, 0x61, 0x54, 0x6f, 0x6b, 0x65, 0x6c, 0x61, 0x75, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0x72, 0x69, 0x6e,
+0x69, 0x64, 0x61, 0x64, 0x20, 0x26, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x54, 0x75, 0x72, 0x6b, 0x73, 0x20, 0x26,
+0x20, 0x43, 0x61, 0x69, 0x63, 0x6f, 0x73, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x54, 0x75, 0x76, 0x61, 0x6c,
+0x75, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69,
+0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x55, 0x2e, 0x53, 0x2e,
+0x20, 0x4f, 0x75, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x56, 0x61, 0x6e,
+0x75, 0x61, 0x74, 0x75, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49,
+0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73,
+0x6c, 0x61, 0x6e, 0x64, 0x73, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x5a, 0x69, 0x6d, 0x62, 0x61, 0x62, 0x77, 0x65, 0x44,
+0x69, 0x65, 0x67, 0x6f, 0x20, 0x47, 0x61, 0x72, 0x63, 0x69, 0x61, 0x49, 0x73, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d,
+0x61, 0x6e, 0x4a, 0x65, 0x72, 0x73, 0x65, 0x79, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x53,
+0x69, 0x6e, 0x74, 0x20, 0x4d, 0x61, 0x61, 0x72, 0x74, 0x65, 0x6e, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x45, 0x75, 0x72, 0x6f,
+0x70, 0x65, 0x65, 0x73, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x74, 0x6f, 0x65, 0x65, 0x73, 0x74, 0x69, 0x45, 0x65, 0x73, 0x74,
+0x69, 0x66, 0xf8, 0x72, 0x6f, 0x79, 0x73, 0x6b, 0x74, 0x46, 0xf8, 0x72, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x75, 0x6f, 0x6d,
+0x69, 0x53, 0x75, 0x6f, 0x6d, 0x69, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x65,
+0x41, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x71, 0x75, 0x65, 0x42, 0xe9, 0x6e, 0x69, 0x6e,
+0x42, 0x75, 0x72, 0x6b, 0x69, 0x6e, 0x61, 0x20, 0x46, 0x61, 0x73, 0x6f, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x75, 0x6e,
+0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x52, 0xe9, 0x70,
+0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x66, 0x72, 0x69, 0x63, 0x61, 0x69,
+0x6e, 0x65, 0x54, 0x63, 0x68, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6f, 0x72, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x2d,
+0x4b, 0x69, 0x6e, 0x73, 0x68, 0x61, 0x73, 0x61, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x2d, 0x42, 0x72, 0x61, 0x7a, 0x7a, 0x61,
+0x76, 0x69, 0x6c, 0x6c, 0x65, 0x43, 0xf4, 0x74, 0x65, 0x20, 0x64, 0x2019, 0x49, 0x76, 0x6f, 0x69, 0x72, 0x65, 0x44, 0x6a,
+0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x20, 0xe9, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72,
+0x69, 0x61, 0x6c, 0x65, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65,
+0x50, 0x6f, 0x6c, 0x79, 0x6e, 0xe9, 0x73, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x47,
+0x61, 0x62, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f, 0x75, 0x70, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65,
+0x48, 0x61, 0xef, 0x74, 0x69, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75, 0x72, 0x67, 0x4d, 0x61, 0x6c, 0x69, 0x4d,
+0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x4d,
+0x61, 0x75, 0x72, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x4d,
+0x61, 0x72, 0x6f, 0x63, 0x4e, 0x6f, 0x75, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x2d, 0x43, 0x61, 0x6c, 0xe9, 0x64, 0x6f, 0x6e,
+0x69, 0x65, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x4c, 0x61, 0x20, 0x52, 0xe9, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x53, 0xe9, 0x6e,
+0xe9, 0x67, 0x61, 0x6c, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x50, 0x69, 0x65, 0x72, 0x72, 0x65, 0x2d, 0x65, 0x74, 0x2d,
+0x4d, 0x69, 0x71, 0x75, 0x65, 0x6c, 0x6f, 0x6e, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x73, 0x75, 0x69,
+0x73, 0x73, 0x65, 0x53, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x79, 0x72, 0x69, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x54, 0x75,
+0x6e, 0x69, 0x73, 0x69, 0x65, 0x57, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x2d, 0x65, 0x74, 0x2d, 0x46, 0x75, 0x74, 0x75, 0x6e,
+0x61, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x42, 0x61, 0x72, 0x74, 0x68, 0xe9, 0x6c, 0x65, 0x6d, 0x79, 0x53, 0x61, 0x69,
+0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x46, 0x72, 0x79, 0x73, 0x6b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c,
+0xe2, 0x6e, 0x47, 0xe0, 0x69, 0x64, 0x68, 0x6c, 0x69, 0x67, 0x41, 0x6e, 0x20, 0x52, 0xec, 0x6f, 0x67, 0x68, 0x61, 0x63,
+0x68, 0x64, 0x20, 0x41, 0x6f, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x74, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x45, 0x73,
+0x70, 0x61, 0xf1, 0x61, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x10e1, 0x10d0, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10d5, 0x10d4, 0x10da,
+0x10dd, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0xd6,
+0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x69, 0x73, 0x63, 0x68, 0x65, 0x73, 0x20, 0x44, 0x65, 0x75, 0x74,
+0x73, 0x63, 0x68, 0xd6, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x65, 0x6e,
+0x49, 0x74, 0x61, 0x6c, 0x69, 0x65, 0x6e, 0x4c, 0x69, 0x65, 0x63, 0x68, 0x74, 0x65, 0x6e, 0x73, 0x74, 0x65, 0x69, 0x6e,
+0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x48,
+0x6f, 0x63, 0x68, 0x64, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x395, 0x3bb, 0x3bb,
+0x3b7, 0x3bd, 0x3b9, 0x3ba, 0x3ac, 0x395, 0x3bb, 0x3bb, 0x3ac, 0x3b4, 0x3b1, 0x39a, 0x3cd, 0x3c0, 0x3c1, 0x3bf, 0x3c2, 0x6b, 0x61, 0x6c,
+0x61, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x75, 0x74, 0x4b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x74, 0x20, 0x4e, 0x75,
+0x6e, 0x61, 0x61, 0x74, 0xa97, 0xac1, 0xa9c, 0xab0, 0xabe, 0xaa4, 0xac0, 0xaad, 0xabe, 0xab0, 0xaa4, 0x48, 0x61, 0x75, 0x73, 0x61,
+0x4e, 0x61, 0x6a, 0x65, 0x72, 0x69, 0x79, 0x61, 0x47, 0x61, 0x6e, 0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72, 0x5e2, 0x5d1, 0x5e8,
+0x5d9, 0x5ea, 0x5d9, 0x5e9, 0x5e8, 0x5d0, 0x5dc, 0x939, 0x93f, 0x928, 0x94d, 0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924, 0x6d, 0x61, 0x67,
+0x79, 0x61, 0x72, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x6f, 0x72, 0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73, 0x6c, 0x65, 0x6e,
+0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x47, 0x61,
+0x65, 0x69, 0x6c, 0x67, 0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x49, 0x74, 0x61,
+0x6c, 0x69, 0x61, 0x53, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72,
+0x61, 0x43, 0x69, 0x74, 0x74, 0xe0, 0x20, 0x64, 0x65, 0x6c, 0x20, 0x56, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x65e5,
+0x672c, 0x8a9e, 0x65e5, 0x672c, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672, 0x634, 0x64f, 0x631, 0x6c1, 0x650,
+0x646, 0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, 0x430, 0x49b, 0x20, 0x442, 0x456, 0x43b, 0x456, 0x49a, 0x430,
+0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, 0x61, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x55, 0x20,
+0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x43a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x447, 0x430, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437,
+0x441, 0x442, 0x430, 0x43d, 0xd55c, 0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0xc870, 0xc120, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0xc778, 0xbbfc, 0xacf5,
+0xd654, 0xad6d, 0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, 0xeb2,
+0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e, 0x67,
+0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0xed, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67,
+0xf3, 0x20, 0x44, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0xed, 0x6b, 0x69, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x52,
+0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72, 0xed, 0x6b, 0x61, 0x20, 0x79, 0x61,
+0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x69, 0x173, 0x4c, 0x69,
+0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x41c, 0x430, 0x43a, 0x435, 0x434,
+0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73,
+0x69, 0x6b, 0x61, 0x72, 0x61, 0x4d, 0x65, 0x6c, 0x61, 0x79, 0x75, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69, 0x6e,
+0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d, 0x61,
+0x6c, 0x74, 0x69, 0x92e, 0x930, 0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b,
+0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, 0x6b,
+0x6d, 0xe5, 0x6c, 0x4e, 0x6f, 0x72, 0x67, 0x65, 0x53, 0x76, 0x61, 0x6c, 0x62, 0x61, 0x72, 0x64, 0x20, 0x6f, 0x67, 0x20,
+0x4a, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x79, 0x65, 0x6e, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a,
+0x62a, 0x648, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627,
+0x646, 0x62f, 0x631, 0x6cc, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74,
+0x75, 0x67, 0x75, 0xea, 0x73, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62,
+0x6f, 0x20, 0x56, 0x65, 0x72, 0x64, 0x65, 0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75,
+0x69, 0x6e, 0xe9, 0x20, 0x45, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x2d,
+0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x6f, 0x4d, 0x61, 0x63, 0x61,
+0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, 0x20, 0x64, 0x61, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d,
+0x62, 0x69, 0x71, 0x75, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70,
+0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65,
+0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x53, 0x75, 0xed, 0xe7, 0x61, 0xa2a, 0xa70, 0xa1c, 0xa3e, 0xa2c, 0xa40,
+0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, 0x62c, 0x627, 0x628, 0x6cc, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x52, 0x75, 0x6e,
+0x61, 0x73, 0x69, 0x6d, 0x69, 0x50, 0x65, 0x72, 0xfa, 0x42, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x45, 0x63, 0x75, 0x61,
+0x64, 0x6f, 0x72, 0x72, 0x75, 0x6d, 0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f,
+0x6d, 0xe2, 0x6e, 0x103, 0x52, 0x6f, 0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61,
+0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438,
+0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e,
+0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64,
+0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73, 0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x441,
+0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421, 0x440, 0x431, 0x438, 0x458, 0x430, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e,
+0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, 0x411, 0x43e, 0x441, 0x43d, 0x430, 0x20, 0x438, 0x20,
+0x425, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d, 0x430, 0x20, 0x413, 0x43e, 0x440, 0x430,
+0x41a, 0x43e, 0x441, 0x43e, 0x432, 0x43e, 0x4b, 0x6f, 0x73, 0x6f, 0x76, 0x6f, 0x438, 0x440, 0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440,
+0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441, 0x435, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f, 0x6e,
+0x61, 0x633, 0x646, 0x68c, 0x64a, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d,
+0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c,
+0x6f, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c,
+0x6f, 0x76, 0x65, 0x6e, 0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61,
+0x61, 0x6c, 0x69, 0x79, 0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61,
+0x4b, 0x69, 0x69, 0x6e, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73,
+0x70, 0x61, 0xf1, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61,
+0x42, 0x65, 0x6c, 0x69, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43,
+0x6f, 0x73, 0x74, 0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69,
+0x63, 0x61, 0x20, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x6c, 0x20, 0x53, 0x61, 0x6c, 0x76,
+0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61,
+0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x61, 0x73, 0x65, 0x73,
+0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4d, 0xe9, 0x78, 0x69, 0x63,
+0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x50, 0x61, 0x6e, 0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61,
+0x67, 0x75, 0x61, 0x79, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73,
+0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x55, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75,
+0x65, 0x6c, 0x61, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c,
+0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f,
+0x61, 0x6d, 0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c,
+0x6c, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x4b, 0x69, 0x6e, 0x67, 0x77, 0x61, 0x6e, 0x61, 0x4a,
+0x61, 0x6d, 0x68, 0x75, 0x72, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73,
+0x69, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76,
+0x65, 0x72, 0x69, 0x67, 0x65, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x442, 0x43e, 0x4b7, 0x438, 0x43a, 0x4e3, 0x422, 0x43e, 0x4b7, 0x438,
+0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2,
+0xbc7, 0xb9a, 0xbbf, 0xbaf, 0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd,
+0xb95, 0xbc8, 0x442, 0x430, 0x442, 0x430, 0x440, 0xc24, 0xc46, 0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0xc26, 0xc47, 0xc36,
+0xc02, 0xe44, 0xe17, 0xe22, 0xf56, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53, 0xf42, 0xf62, 0xf92,
+0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20, 0x66, 0x61, 0x6b,
+0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72, 0x6b, 0xe7, 0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x4b,
+0x131, 0x62, 0x72, 0x131, 0x73, 0x74, 0xfc, 0x72, 0x6b, 0x6d, 0x65, 0x6e, 0x20, 0x64, 0x69, 0x6c, 0x69, 0x54, 0xfc, 0x72,
+0x6b, 0x6d, 0x65, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x626, 0x6c7, 0x64a, 0x63a, 0x6c7, 0x631, 0x686, 0x6d5, 0x62c, 0x6c7, 0x6ad,
+0x6af, 0x648, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627,
+0x631, 0x62f, 0x648, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b,
+0x69, 0x73, 0x74, 0x6f, 0x6e, 0x627, 0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x45e, 0x437, 0x431, 0x435, 0x43a, 0x447, 0x430, 0x40e, 0x437,
+0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x54, 0x69, 0x1ebf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69,
+0x1ec7, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x56, 0x6f, 0x6c, 0x61, 0x70, 0xfc, 0x6b, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67,
+0x59, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61, 0x73, 0x20, 0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x57, 0x6f, 0x6c, 0x6f,
+0x66, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x5d9, 0x5d9, 0x5b4, 0x5d3, 0x5d9, 0x5e9, 0x5d5, 0x5d5, 0x5e2, 0x5dc, 0x5d8,
+0xc8, 0x64, 0xe8, 0x20, 0x59, 0x6f, 0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20,
+0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x42, 0x25b,
+0x300, 0x6e, 0x25b, 0x300, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x4e, 0x69, 0x6e, 0x67, 0x69, 0x7a, 0x69, 0x6d,
+0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, 0x65, 0x67,
+0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, 0x65, 0x6c,
+0x67, 0x45, 0x6c, 0x6c, 0x61, 0x6e, 0x20, 0x56, 0x61, 0x6e, 0x6e, 0x69, 0x6e, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x77, 0x65,
+0x6b, 0x52, 0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x41, 0x6b, 0x61, 0x6e, 0x47,
+0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67, 0x62, 0x6f, 0x4e, 0x61, 0x1ecb, 0x6a, 0x1ecb, 0x72,
+0x1ecb, 0x61, 0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x66, 0x75, 0x72, 0x6c, 0x61, 0x6e, 0x49, 0x74, 0x61, 0x6c, 0x69,
+0x65, 0x45, 0x28b, 0x65, 0x67, 0x62, 0x65, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x54,
+0x6f, 0x67, 0x6f, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, 0x61, 0x77,
+0x61, 0x69, 0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, 0x16b, 0x20,
+0x2bb, 0x49, 0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73,
+0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77,
+0x69, 0x69, 0x7a, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x72, 0x69, 0x69, 0x63, 0x68, 0x4c, 0x69, 0xe4, 0x63, 0x68, 0x74, 0x65,
+0x73, 0x63, 0x68, 0x74, 0xe4, 0x69, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x4e, 0x65, 0x64, 0x64, 0x65, 0x72, 0x73, 0x61, 0x73,
+0x73, 0x2019, 0x73, 0x63, 0x68, 0x44, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x65, 0x64, 0x64,
+0x65, 0x72, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x6e, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73, 0xe1, 0x6d, 0x65, 0x67, 0x69, 0x65,
+0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61, 0x52, 0x75, 0x6f, 0x167, 0x167, 0x61,
+0x45, 0x6b, 0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61, 0x50, 0x75, 0x6c, 0x61, 0x61,
+0x72, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x75, 0x6e, 0x47, 0x69, 0x6e, 0x65, 0x4d, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e,
+0x69, 0x47, 0x69, 0x6b, 0x75, 0x79, 0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d, 0x70, 0x75, 0x72, 0x73, 0x65, 0x6e, 0x61, 0x69,
+0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, 0x65, 0x6c, 0x65, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30,
+0x2d5b, 0x2d4d, 0x2d43, 0x2d49, 0x2d5c, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x54, 0x61, 0x73, 0x68, 0x65, 0x6c, 0x1e25, 0x69, 0x79,
+0x74, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a,
+0x61, 0x79, 0x65, 0x72, 0x52, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61,
+0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61,
+0x6d, 0x61, 0x6e, 0x61, 0x6b, 0x61, 0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13cc, 0x13ca, 0x20, 0x13a2,
+0x13f3, 0x13be, 0x13b5, 0x13cd, 0x13d4, 0x13c5, 0x20, 0x13cd, 0x13a6, 0x13da, 0x13a9, 0x6b, 0x72, 0x65, 0x6f, 0x6c, 0x20, 0x6d, 0x6f, 0x72,
+0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, 0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69, 0x6d, 0x61, 0x6b, 0x6f, 0x6e, 0x64, 0x65,
+0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, 0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x4c, 0x75, 0x67,
+0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63, 0x68, 0x69, 0x62, 0x65, 0x6d, 0x62, 0x61,
+0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b, 0x61, 0x62, 0x75, 0x20, 0x56, 0x65, 0x72,
+0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, 0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e, 0x6a, 0x69, 0x6e, 0x45, 0x6d, 0x65, 0x74,
+0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b, 0x68, 0x6f, 0x65, 0x67, 0x6f, 0x77, 0x61,
+0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61, 0x63, 0x68, 0x61, 0x6d, 0x65, 0x4b, 0xf6,
+0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x61, 0x54, 0x61,
+0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, 0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61, 0x4c, 0x75, 0x6c, 0x75, 0x68, 0x69, 0x61,
+0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, 0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x69, 0x74, 0x65, 0x73, 0x6f,
+0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69, 0x69, 0x6e, 0x69, 0x4d, 0x61, 0x61, 0x6c,
+0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, 0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f, 0x52, 0x75, 0x6b, 0x69, 0x67, 0x61, 0x54,
+0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, 0x74, 0x20, 0x6e, 0x20, 0x6c, 0x61, 0x1e6d, 0x6c, 0x61, 0x1e63, 0x4d, 0x65, 0x1e5b, 0x1e5b,
+0x75, 0x6b, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73,
+0x68, 0x61, 0x6d, 0x62, 0x61, 0x61, 0x92c, 0x921, 0x93c, 0x94b, 0x43d, 0x43e, 0x445, 0x447, 0x438, 0x439, 0x43d, 0x420, 0x43e, 0x441,
+0x441, 0x438, 0x446, 0x435, 0x440, 0x43a, 0x43e, 0x432, 0x43d, 0x43e, 0x441, 0x43b, 0x43e, 0x432, 0x435, 0x301, 0x43d, 0x441, 0x43a, 0x457,
+0x439, 0x440, 0x461, 0x441, 0x441, 0x456, 0x301, 0x430, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75,
+0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x4c, 0xeb, 0x74, 0x7a, 0x65, 0x62, 0x75, 0x65,
+0x72, 0x67, 0x65, 0x73, 0x63, 0x68, 0x4c, 0xeb, 0x74, 0x7a, 0x65, 0x62, 0x75, 0x65, 0x72, 0x67, 0x41, 0x67, 0x68, 0x65,
+0x6d, 0x4b, 0xe0, 0x6d, 0xe0, 0x6c, 0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb,
+0x6e, 0x5a, 0x61, 0x72, 0x6d, 0x61, 0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c,
+0xe1, 0x6a, 0x6f, 0x6f, 0x6c, 0x61, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b,
+0x61, 0x6d, 0x259, 0x72, 0xfa, 0x6e, 0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61,
+0x6b, 0x75, 0x61, 0x55, 0x6d, 0x6f, 0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b,
+0x61, 0x6d, 0x65, 0x72, 0x75, 0x14b, 0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54,
+0x68, 0x6f, 0x6b, 0x20, 0x4e, 0x61, 0x74, 0x68, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x410, 0x440, 0x430,
+0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x49, 0x73, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61,
+0x6e, 0x69, 0x79, 0x61, 0x54, 0x61, 0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559, 0xa524, 0xa55e,
+0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73, 0x65, 0x72,
+0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa, 0x6e, 0x61,
+0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c, 0xfb, 0x6e,
+0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61, 0x6d, 0x61,
+0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254, 0x6e, 0x4b,
+0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d, 0x4c, 0x61, 0x6b, 0x21f, 0xf3, 0x6c, 0x2bc, 0x69, 0x79, 0x61, 0x70, 0x69, 0x4d, 0xed,
+0x6c, 0x61, 0x68, 0x61, 0x14b, 0x73, 0x6b, 0x61, 0x20, 0x54, 0x21f, 0x61, 0x6d, 0xe1, 0x6b, 0x21f, 0x6f, 0x10d, 0x68, 0x65,
+0x2d5c, 0x2d30, 0x2d4e, 0x2d30, 0x2d63, 0x2d49, 0x2d56, 0x2d5c, 0x6a9, 0x648, 0x631, 0x62f, 0x6cc, 0x6cc, 0x20, 0x646, 0x627, 0x648, 0x6d5, 0x646,
+0x62f, 0x6cc, 0x639, 0x6ce, 0x631, 0x627, 0x642, 0x626, 0x6ce, 0x631, 0x627, 0x646, 0x64, 0x6f, 0x6c, 0x6e, 0x6f, 0x73, 0x65, 0x72,
+0x62, 0x161, 0x107, 0x69, 0x6e, 0x61, 0x4e, 0x69, 0x6d, 0x73, 0x6b, 0x61, 0x68, 0x6f, 0x72, 0x6e, 0x6a, 0x6f, 0x73, 0x65,
+0x72, 0x62, 0x161, 0x107, 0x69, 0x6e, 0x61, 0x4e, 0x11b, 0x6d, 0x73, 0x6b, 0x61, 0x70, 0x72, 0x16b, 0x73, 0x69, 0x73, 0x6b,
+0x61, 0x6e, 0x73, 0x77, 0x12b, 0x74, 0x61, 0x69, 0x61, 0x6e, 0x61, 0x72, 0xe2, 0x161, 0x6b, 0x69, 0x65, 0x6c, 0xe2, 0x53,
+0x75, 0x6f, 0x6d, 0xe2, 0x645, 0x627, 0x632, 0x631, 0x648, 0x646, 0x6cc, 0x644, 0x6ca, 0x631, 0x6cc, 0x20, 0x634, 0x648, 0x645, 0x627,
+0x644, 0x6cc, 0x7cb5, 0x8a9e, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x7ca4, 0x8bed,
+0x4e2d, 0x534e, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x56fd
};
static const char language_name_list[] =
@@ -6217,7 +6392,7 @@ static const char language_name_list[] =
"Mongolian\0"
"Nauru\0"
"Nepali\0"
-"NorwegianBokmal\0"
+"Norwegian Bokmal\0"
"Occitan\0"
"Oriya\0"
"Pashto\0"
@@ -6273,7 +6448,7 @@ static const char language_name_list[] =
"Yoruba\0"
"Zhuang\0"
"Zulu\0"
-"NorwegianNynorsk\0"
+"Norwegian Nynorsk\0"
"Bosnian\0"
"Divehi\0"
"Manx\0"
@@ -6362,7 +6537,7 @@ static const char language_name_list[] =
"Kongo\0"
"Kwanyama\0"
"Limburgish\0"
-"LubaKatanga\0"
+"Luba Katanga\0"
"Luxembourgish\0"
"Navaho\0"
"Ndonga\0"
@@ -6373,10 +6548,10 @@ static const char language_name_list[] =
"Basaa\0"
"Zarma\0"
"Duala\0"
-"JolaFonyi\0"
+"Jola Fonyi\0"
"Ewondo\0"
"Bafia\0"
-"MakhuwaMeetto\0"
+"Makhuwa Meetto\0"
"Mundang\0"
"Kwasio\0"
"Nuer\0"
@@ -6395,26 +6570,26 @@ static const char language_name_list[] =
"Ngiemboon\0"
"Aragonese\0"
"Akkadian\0"
-"AncientEgyptian\0"
-"AncientGreek\0"
+"Ancient Egyptian\0"
+"Ancient Greek\0"
"Aramaic\0"
"Balinese\0"
"Bamun\0"
-"BatakToba\0"
+"Batak Toba\0"
"Buginese\0"
"Buhid\0"
"Carian\0"
"Chakma\0"
-"ClassicalMandaic\0"
+"Classical Mandaic\0"
"Coptic\0"
"Dogri\0"
-"EasternCham\0"
-"EasternKayah\0"
+"Eastern Cham\0"
+"Eastern Kayah\0"
"Etruscan\0"
"Gothic\0"
"Hanunoo\0"
"Ingush\0"
-"LargeFloweryMiao\0"
+"Large Flowery Miao\0"
"Lepcha\0"
"Limbu\0"
"Lisu\0"
@@ -6424,15 +6599,15 @@ static const char language_name_list[] =
"Mandingo\0"
"Manipuri\0"
"Meroitic\0"
-"NorthernThai\0"
-"OldIrish\0"
-"OldNorse\0"
-"OldPersian\0"
-"OldTurkish\0"
+"Northern Thai\0"
+"Old Irish\0"
+"Old Norse\0"
+"Old Persian\0"
+"Old Turkish\0"
"Pahlavi\0"
"Parthian\0"
"Phoenician\0"
-"PrakritLanguage\0"
+"Prakrit Language\0"
"Rejang\0"
"Sabaean\0"
"Samaritan\0"
@@ -6441,16 +6616,16 @@ static const char language_name_list[] =
"Sora\0"
"Sylheti\0"
"Tagbanwa\0"
-"TaiDam\0"
-"TaiNua\0"
+"Tai Dam\0"
+"Tai Nua\0"
"Ugaritic\0"
"Akoose\0"
"Lakota\0"
"Standard Moroccan Tamazight\0"
"Mapuche\0"
"Central Kurdish\0"
-"LowerSorbian\0"
-"UpperSorbian\0"
+"Lower Sorbian\0"
+"Upper Sorbian\0"
"Kenyang\0"
"Mohawk\0"
"Nko\0"
@@ -6488,7 +6663,7 @@ static const char language_name_list[] =
"Tokelau\0"
"Tok Pisin\0"
"Tuvalu\0"
-"UncodedLanguages\0"
+"Uncoded Languages\0"
"Cantonese\0"
"Osage\0"
"Tangut\0"
@@ -6580,281 +6755,281 @@ static const quint16 language_name_index[] = {
680, // Mongolian
690, // Nauru
696, // Nepali
- 703, // NorwegianBokmal
- 719, // Occitan
- 727, // Oriya
- 733, // Pashto
- 740, // Persian
- 748, // Polish
- 755, // Portuguese
- 766, // Punjabi
- 774, // Quechua
- 782, // Romansh
- 790, // Romanian
- 799, // Russian
- 807, // Samoan
- 814, // Sango
- 820, // Sanskrit
- 829, // Serbian
- 837, // Ossetic
- 845, // Southern Sotho
- 860, // Tswana
- 867, // Shona
- 873, // Sindhi
- 880, // Sinhala
- 888, // Swati
- 894, // Slovak
- 901, // Slovenian
- 911, // Somali
- 918, // Spanish
- 926, // Sundanese
- 936, // Swahili
- 944, // Swedish
- 952, // Sardinian
- 962, // Tajik
- 968, // Tamil
- 974, // Tatar
- 980, // Telugu
- 987, // Thai
- 992, // Tibetan
- 1000, // Tigrinya
- 1009, // Tongan
- 1016, // Tsonga
- 1023, // Turkish
- 1031, // Turkmen
- 1039, // Tahitian
- 1048, // Uighur
- 1055, // Ukrainian
- 1065, // Urdu
- 1070, // Uzbek
- 1076, // Vietnamese
- 1087, // Volapuk
- 1095, // Welsh
- 1101, // Wolof
- 1107, // Xhosa
- 1113, // Yiddish
- 1121, // Yoruba
- 1128, // Zhuang
- 1135, // Zulu
- 1140, // NorwegianNynorsk
- 1157, // Bosnian
- 1165, // Divehi
- 1172, // Manx
- 1177, // Cornish
- 1185, // Akan
- 1190, // Konkani
- 1198, // Ga
- 1201, // Igbo
- 1206, // Kamba
- 1212, // Syriac
- 1219, // Blin
- 1224, // Geez
- 1229, // Koro
- 1234, // Sidamo
- 1241, // Atsam
- 1247, // Tigre
- 1253, // Jju
- 1257, // Friulian
- 1266, // Venda
- 1272, // Ewe
- 1276, // Walamo
- 1283, // Hawaiian
- 1292, // Tyap
- 1297, // Nyanja
- 1304, // Filipino
- 1313, // Swiss German
- 1326, // Sichuan Yi
- 1337, // Kpelle
- 1344, // Low German
- 1355, // South Ndebele
- 1369, // Northern Sotho
- 1384, // Northern Sami
- 1398, // Taroko
- 1405, // Gusii
- 1411, // Taita
- 1417, // Fulah
- 1423, // Kikuyu
- 1430, // Samburu
- 1438, // Sena
- 1443, // North Ndebele
- 1457, // Rombo
- 1463, // Tachelhit
- 1473, // Kabyle
- 1480, // Nyankole
- 1489, // Bena
- 1494, // Vunjo
- 1500, // Bambara
- 1508, // Embu
- 1513, // Cherokee
- 1522, // Morisyen
- 1531, // Makonde
- 1539, // Langi
- 1545, // Ganda
- 1551, // Bemba
- 1557, // Kabuverdianu
- 1570, // Meru
- 1575, // Kalenjin
- 1584, // Nama
- 1589, // Machame
- 1597, // Colognian
- 1607, // Masai
- 1613, // Soga
- 1618, // Luyia
- 1624, // Asu
- 1628, // Teso
- 1633, // Saho
- 1638, // Koyra Chiini
- 1651, // Rwa
- 1655, // Luo
- 1659, // Chiga
- 1665, // Central Morocco Tamazight
- 1691, // Koyraboro Senni
- 1707, // Shambala
- 1716, // Bodo
- 1721, // Avaric
- 1728, // Chamorro
- 1737, // Chechen
- 1745, // Church
- 1752, // Chuvash
- 1760, // Cree
- 1765, // Haitian
- 1773, // Herero
- 1780, // Hiri Motu
- 1790, // Kanuri
- 1797, // Komi
- 1802, // Kongo
- 1808, // Kwanyama
- 1817, // Limburgish
- 1828, // LubaKatanga
- 1840, // Luxembourgish
- 1854, // Navaho
- 1861, // Ndonga
- 1868, // Ojibwa
- 1875, // Pali
- 1880, // Walloon
- 1888, // Aghem
- 1894, // Basaa
- 1900, // Zarma
- 1906, // Duala
- 1912, // JolaFonyi
- 1922, // Ewondo
- 1929, // Bafia
- 1935, // MakhuwaMeetto
- 1949, // Mundang
- 1957, // Kwasio
- 1964, // Nuer
- 1969, // Sakha
- 1975, // Sangu
- 1981, // Congo Swahili
- 1995, // Tasawaq
- 2003, // Vai
- 2007, // Walser
- 2014, // Yangben
- 2022, // Avestan
- 2030, // Asturian
- 2039, // Ngomba
- 2046, // Kako
- 2051, // Meta
- 2056, // Ngiemboon
- 2066, // Aragonese
- 2076, // Akkadian
- 2085, // AncientEgyptian
- 2101, // AncientGreek
- 2114, // Aramaic
- 2122, // Balinese
- 2131, // Bamun
- 2137, // BatakToba
- 2147, // Buginese
- 2156, // Buhid
- 2162, // Carian
- 2169, // Chakma
- 2176, // ClassicalMandaic
- 2193, // Coptic
- 2200, // Dogri
- 2206, // EasternCham
- 2218, // EasternKayah
- 2231, // Etruscan
- 2240, // Gothic
- 2247, // Hanunoo
- 2255, // Ingush
- 2262, // LargeFloweryMiao
- 2279, // Lepcha
- 2286, // Limbu
- 2292, // Lisu
- 2297, // Lu
- 2300, // Lycian
- 2307, // Lydian
- 2314, // Mandingo
- 2323, // Manipuri
- 2332, // Meroitic
- 2341, // NorthernThai
- 2354, // OldIrish
- 2363, // OldNorse
- 2372, // OldPersian
- 2383, // OldTurkish
- 2394, // Pahlavi
- 2402, // Parthian
- 2411, // Phoenician
- 2422, // PrakritLanguage
- 2438, // Rejang
- 2445, // Sabaean
- 2453, // Samaritan
- 2463, // Santali
- 2471, // Saurashtra
- 2482, // Sora
- 2487, // Sylheti
- 2495, // Tagbanwa
- 2504, // TaiDam
- 2511, // TaiNua
- 2518, // Ugaritic
- 2527, // Akoose
- 2534, // Lakota
- 2541, // Standard Moroccan Tamazight
- 2569, // Mapuche
- 2577, // Central Kurdish
- 2593, // LowerSorbian
- 2606, // UpperSorbian
- 2619, // Kenyang
- 2627, // Mohawk
- 2634, // Nko
- 2638, // Prussian
- 2647, // Kiche
- 2653, // Southern Sami
- 2667, // Lule Sami
- 2677, // Inari Sami
- 2688, // Skolt Sami
- 2699, // Warlpiri
- 2708, // Manichaean Middle Persian
- 2734, // Mende
- 2740, // Ancient North Arabian
- 2762, // Linear A
- 2771, // Hmong Njua
- 2782, // Ho
- 2785, // Lezghian
- 2794, // Bassa
- 2800, // Mono
- 2805, // Tedim Chin
- 2816, // Maithili
- 2825, // Ahom
- 2830, // American Sign Language
- 2853, // Ardhamagadhi Prakrit
- 2874, // Bhojpuri
- 2883, // Hieroglyphic Luwian
- 2903, // Literary Chinese
- 2920, // Mazanderani
- 2932, // Mru
- 2936, // Newari
- 2943, // Northern Luri
- 2957, // Palauan
- 2965, // Papiamento
- 2976, // Saraiki
- 2984, // Tokelau
- 2992, // Tok Pisin
- 3002, // Tuvalu
- 3009, // UncodedLanguages
- 3026, // Cantonese
- 3036, // Osage
- 3042, // Tangut
+ 703, // Norwegian Bokmal
+ 720, // Occitan
+ 728, // Oriya
+ 734, // Pashto
+ 741, // Persian
+ 749, // Polish
+ 756, // Portuguese
+ 767, // Punjabi
+ 775, // Quechua
+ 783, // Romansh
+ 791, // Romanian
+ 800, // Russian
+ 808, // Samoan
+ 815, // Sango
+ 821, // Sanskrit
+ 830, // Serbian
+ 838, // Ossetic
+ 846, // Southern Sotho
+ 861, // Tswana
+ 868, // Shona
+ 874, // Sindhi
+ 881, // Sinhala
+ 889, // Swati
+ 895, // Slovak
+ 902, // Slovenian
+ 912, // Somali
+ 919, // Spanish
+ 927, // Sundanese
+ 937, // Swahili
+ 945, // Swedish
+ 953, // Sardinian
+ 963, // Tajik
+ 969, // Tamil
+ 975, // Tatar
+ 981, // Telugu
+ 988, // Thai
+ 993, // Tibetan
+ 1001, // Tigrinya
+ 1010, // Tongan
+ 1017, // Tsonga
+ 1024, // Turkish
+ 1032, // Turkmen
+ 1040, // Tahitian
+ 1049, // Uighur
+ 1056, // Ukrainian
+ 1066, // Urdu
+ 1071, // Uzbek
+ 1077, // Vietnamese
+ 1088, // Volapuk
+ 1096, // Welsh
+ 1102, // Wolof
+ 1108, // Xhosa
+ 1114, // Yiddish
+ 1122, // Yoruba
+ 1129, // Zhuang
+ 1136, // Zulu
+ 1141, // Norwegian Nynorsk
+ 1159, // Bosnian
+ 1167, // Divehi
+ 1174, // Manx
+ 1179, // Cornish
+ 1187, // Akan
+ 1192, // Konkani
+ 1200, // Ga
+ 1203, // Igbo
+ 1208, // Kamba
+ 1214, // Syriac
+ 1221, // Blin
+ 1226, // Geez
+ 1231, // Koro
+ 1236, // Sidamo
+ 1243, // Atsam
+ 1249, // Tigre
+ 1255, // Jju
+ 1259, // Friulian
+ 1268, // Venda
+ 1274, // Ewe
+ 1278, // Walamo
+ 1285, // Hawaiian
+ 1294, // Tyap
+ 1299, // Nyanja
+ 1306, // Filipino
+ 1315, // Swiss German
+ 1328, // Sichuan Yi
+ 1339, // Kpelle
+ 1346, // Low German
+ 1357, // South Ndebele
+ 1371, // Northern Sotho
+ 1386, // Northern Sami
+ 1400, // Taroko
+ 1407, // Gusii
+ 1413, // Taita
+ 1419, // Fulah
+ 1425, // Kikuyu
+ 1432, // Samburu
+ 1440, // Sena
+ 1445, // North Ndebele
+ 1459, // Rombo
+ 1465, // Tachelhit
+ 1475, // Kabyle
+ 1482, // Nyankole
+ 1491, // Bena
+ 1496, // Vunjo
+ 1502, // Bambara
+ 1510, // Embu
+ 1515, // Cherokee
+ 1524, // Morisyen
+ 1533, // Makonde
+ 1541, // Langi
+ 1547, // Ganda
+ 1553, // Bemba
+ 1559, // Kabuverdianu
+ 1572, // Meru
+ 1577, // Kalenjin
+ 1586, // Nama
+ 1591, // Machame
+ 1599, // Colognian
+ 1609, // Masai
+ 1615, // Soga
+ 1620, // Luyia
+ 1626, // Asu
+ 1630, // Teso
+ 1635, // Saho
+ 1640, // Koyra Chiini
+ 1653, // Rwa
+ 1657, // Luo
+ 1661, // Chiga
+ 1667, // Central Morocco Tamazight
+ 1693, // Koyraboro Senni
+ 1709, // Shambala
+ 1718, // Bodo
+ 1723, // Avaric
+ 1730, // Chamorro
+ 1739, // Chechen
+ 1747, // Church
+ 1754, // Chuvash
+ 1762, // Cree
+ 1767, // Haitian
+ 1775, // Herero
+ 1782, // Hiri Motu
+ 1792, // Kanuri
+ 1799, // Komi
+ 1804, // Kongo
+ 1810, // Kwanyama
+ 1819, // Limburgish
+ 1830, // Luba Katanga
+ 1843, // Luxembourgish
+ 1857, // Navaho
+ 1864, // Ndonga
+ 1871, // Ojibwa
+ 1878, // Pali
+ 1883, // Walloon
+ 1891, // Aghem
+ 1897, // Basaa
+ 1903, // Zarma
+ 1909, // Duala
+ 1915, // Jola Fonyi
+ 1926, // Ewondo
+ 1933, // Bafia
+ 1939, // Makhuwa Meetto
+ 1954, // Mundang
+ 1962, // Kwasio
+ 1969, // Nuer
+ 1974, // Sakha
+ 1980, // Sangu
+ 1986, // Congo Swahili
+ 2000, // Tasawaq
+ 2008, // Vai
+ 2012, // Walser
+ 2019, // Yangben
+ 2027, // Avestan
+ 2035, // Asturian
+ 2044, // Ngomba
+ 2051, // Kako
+ 2056, // Meta
+ 2061, // Ngiemboon
+ 2071, // Aragonese
+ 2081, // Akkadian
+ 2090, // Ancient Egyptian
+ 2107, // Ancient Greek
+ 2121, // Aramaic
+ 2129, // Balinese
+ 2138, // Bamun
+ 2144, // Batak Toba
+ 2155, // Buginese
+ 2164, // Buhid
+ 2170, // Carian
+ 2177, // Chakma
+ 2184, // Classical Mandaic
+ 2202, // Coptic
+ 2209, // Dogri
+ 2215, // Eastern Cham
+ 2228, // Eastern Kayah
+ 2242, // Etruscan
+ 2251, // Gothic
+ 2258, // Hanunoo
+ 2266, // Ingush
+ 2273, // Large Flowery Miao
+ 2292, // Lepcha
+ 2299, // Limbu
+ 2305, // Lisu
+ 2310, // Lu
+ 2313, // Lycian
+ 2320, // Lydian
+ 2327, // Mandingo
+ 2336, // Manipuri
+ 2345, // Meroitic
+ 2354, // Northern Thai
+ 2368, // Old Irish
+ 2378, // Old Norse
+ 2388, // Old Persian
+ 2400, // Old Turkish
+ 2412, // Pahlavi
+ 2420, // Parthian
+ 2429, // Phoenician
+ 2440, // Prakrit Language
+ 2457, // Rejang
+ 2464, // Sabaean
+ 2472, // Samaritan
+ 2482, // Santali
+ 2490, // Saurashtra
+ 2501, // Sora
+ 2506, // Sylheti
+ 2514, // Tagbanwa
+ 2523, // Tai Dam
+ 2531, // Tai Nua
+ 2539, // Ugaritic
+ 2548, // Akoose
+ 2555, // Lakota
+ 2562, // Standard Moroccan Tamazight
+ 2590, // Mapuche
+ 2598, // Central Kurdish
+ 2614, // Lower Sorbian
+ 2628, // Upper Sorbian
+ 2642, // Kenyang
+ 2650, // Mohawk
+ 2657, // Nko
+ 2661, // Prussian
+ 2670, // Kiche
+ 2676, // Southern Sami
+ 2690, // Lule Sami
+ 2700, // Inari Sami
+ 2711, // Skolt Sami
+ 2722, // Warlpiri
+ 2731, // Manichaean Middle Persian
+ 2757, // Mende
+ 2763, // Ancient North Arabian
+ 2785, // Linear A
+ 2794, // Hmong Njua
+ 2805, // Ho
+ 2808, // Lezghian
+ 2817, // Bassa
+ 2823, // Mono
+ 2828, // Tedim Chin
+ 2839, // Maithili
+ 2848, // Ahom
+ 2853, // American Sign Language
+ 2876, // Ardhamagadhi Prakrit
+ 2897, // Bhojpuri
+ 2906, // Hieroglyphic Luwian
+ 2926, // Literary Chinese
+ 2943, // Mazanderani
+ 2955, // Mru
+ 2959, // Newari
+ 2966, // Northern Luri
+ 2980, // Palauan
+ 2988, // Papiamento
+ 2999, // Saraiki
+ 3007, // Tokelau
+ 3015, // Tok Pisin
+ 3025, // Tuvalu
+ 3032, // Uncoded Languages
+ 3050, // Cantonese
+ 3060, // Osage
+ 3066, // Tangut
};
static const char script_name_list[] =
@@ -6902,7 +7077,7 @@ static const char script_name_list[] =
"Brahmi\0"
"Buginese\0"
"Buhid\0"
-"CanadianAboriginal\0"
+"Canadian Aboriginal\0"
"Carian\0"
"Chakma\0"
"Cham\0"
@@ -6991,7 +7166,7 @@ static const char script_name_list[] =
"Hatran\0"
"Multani\0"
"Old Hungarian\0"
-"SignWriting\0"
+"Sign Writing\0"
"Adlam\0"
"Bhaiksuki\0"
"Marchen\0"
@@ -7047,104 +7222,104 @@ static const quint16 script_name_index[] = {
325, // Brahmi
332, // Buginese
341, // Buhid
- 347, // CanadianAboriginal
- 366, // Carian
- 373, // Chakma
- 380, // Cham
- 385, // Coptic
- 392, // Cypriot
- 400, // Egyptian Hieroglyphs
- 421, // Fraser
- 428, // Glagolitic
- 439, // Gothic
- 446, // Han
- 450, // Hangul
- 457, // Hanunoo
- 465, // Imperial Aramaic
- 482, // Inscriptional Pahlavi
- 504, // Inscriptional Parthian
- 527, // Javanese
- 536, // Kaithi
- 543, // Katakana
- 552, // Kayah Li
- 561, // Kharoshthi
- 572, // Lanna
- 578, // Lepcha
- 585, // Limbu
- 591, // Linear B
- 600, // Lycian
- 607, // Lydian
- 614, // Mandaean
- 623, // Meitei Mayek
- 636, // Meroitic
- 645, // Meroitic Cursive
- 662, // Nko
- 666, // New Tai Lue
- 678, // Ogham
- 684, // Ol Chiki
- 693, // Old Italic
- 704, // Old Persian
- 716, // Old South Arabian
- 734, // Orkhon
- 741, // Osmanya
- 749, // Phags Pa
- 758, // Phoenician
- 769, // Pollard Phonetic
- 786, // Rejang
- 793, // Runic
- 799, // Samaritan
- 809, // Saurashtra
- 820, // Sharada
- 828, // Shavian
- 836, // Sora Sompeng
- 849, // Cuneiform
- 859, // Sundanese
- 869, // Syloti Nagri
- 882, // Tagalog
- 890, // Tagbanwa
- 899, // Tai Le
- 906, // Tai Viet
- 915, // Takri
- 921, // Ugaritic
- 930, // Braille
- 938, // Hiragana
- 947, // Caucasian Albanian
- 966, // Bassa Vah
- 976, // Duployan
- 985, // Elbasan
- 993, // Grantha
- 1001, // Pahawh Hmong
- 1014, // Khojki
- 1021, // Linear A
- 1030, // Mahajani
- 1039, // Manichaean
- 1050, // Mende Kikakui
- 1064, // Modi
- 1069, // Mro
- 1073, // Old North Arabian
- 1091, // Nabataean
- 1101, // Palmyrene
- 1111, // Pau Cin Hau
- 1123, // Old Permic
- 1134, // Psalter Pahlavi
- 1150, // Siddham
- 1158, // Khudawadi
- 1168, // Tirhuta
- 1176, // Varang Kshiti
- 1190, // Ahom
- 1195, // Anatolian Hieroglyphs
- 1217, // Hatran
- 1224, // Multani
- 1232, // Old Hungarian
- 1246, // SignWriting
- 1258, // Adlam
- 1264, // Bhaiksuki
- 1274, // Marchen
- 1282, // Newa
- 1287, // Osage
- 1293, // Tangut
- 1300, // Han with Bopomofo
- 1318, // Jamo
+ 347, // Canadian Aboriginal
+ 367, // Carian
+ 374, // Chakma
+ 381, // Cham
+ 386, // Coptic
+ 393, // Cypriot
+ 401, // Egyptian Hieroglyphs
+ 422, // Fraser
+ 429, // Glagolitic
+ 440, // Gothic
+ 447, // Han
+ 451, // Hangul
+ 458, // Hanunoo
+ 466, // Imperial Aramaic
+ 483, // Inscriptional Pahlavi
+ 505, // Inscriptional Parthian
+ 528, // Javanese
+ 537, // Kaithi
+ 544, // Katakana
+ 553, // Kayah Li
+ 562, // Kharoshthi
+ 573, // Lanna
+ 579, // Lepcha
+ 586, // Limbu
+ 592, // Linear B
+ 601, // Lycian
+ 608, // Lydian
+ 615, // Mandaean
+ 624, // Meitei Mayek
+ 637, // Meroitic
+ 646, // Meroitic Cursive
+ 663, // Nko
+ 667, // New Tai Lue
+ 679, // Ogham
+ 685, // Ol Chiki
+ 694, // Old Italic
+ 705, // Old Persian
+ 717, // Old South Arabian
+ 735, // Orkhon
+ 742, // Osmanya
+ 750, // Phags Pa
+ 759, // Phoenician
+ 770, // Pollard Phonetic
+ 787, // Rejang
+ 794, // Runic
+ 800, // Samaritan
+ 810, // Saurashtra
+ 821, // Sharada
+ 829, // Shavian
+ 837, // Sora Sompeng
+ 850, // Cuneiform
+ 860, // Sundanese
+ 870, // Syloti Nagri
+ 883, // Tagalog
+ 891, // Tagbanwa
+ 900, // Tai Le
+ 907, // Tai Viet
+ 916, // Takri
+ 922, // Ugaritic
+ 931, // Braille
+ 939, // Hiragana
+ 948, // Caucasian Albanian
+ 967, // Bassa Vah
+ 977, // Duployan
+ 986, // Elbasan
+ 994, // Grantha
+ 1002, // Pahawh Hmong
+ 1015, // Khojki
+ 1022, // Linear A
+ 1031, // Mahajani
+ 1040, // Manichaean
+ 1051, // Mende Kikakui
+ 1065, // Modi
+ 1070, // Mro
+ 1074, // Old North Arabian
+ 1092, // Nabataean
+ 1102, // Palmyrene
+ 1112, // Pau Cin Hau
+ 1124, // Old Permic
+ 1135, // Psalter Pahlavi
+ 1151, // Siddham
+ 1159, // Khudawadi
+ 1169, // Tirhuta
+ 1177, // Varang Kshiti
+ 1191, // Ahom
+ 1196, // Anatolian Hieroglyphs
+ 1218, // Hatran
+ 1225, // Multani
+ 1233, // Old Hungarian
+ 1247, // Sign Writing
+ 1260, // Adlam
+ 1266, // Bhaiksuki
+ 1276, // Marchen
+ 1284, // Newa
+ 1289, // Osage
+ 1295, // Tangut
+ 1302, // Han with Bopomofo
+ 1320, // Jamo
};
static const char country_name_list[] =
@@ -7152,12 +7327,12 @@ static const char country_name_list[] =
"Afghanistan\0"
"Albania\0"
"Algeria\0"
-"AmericanSamoa\0"
+"American Samoa\0"
"Andorra\0"
"Angola\0"
"Anguilla\0"
"Antarctica\0"
-"AntiguaAndBarbuda\0"
+"Antigua And Barbuda\0"
"Argentina\0"
"Armenia\0"
"Aruba\0"
@@ -7175,58 +7350,58 @@ static const char country_name_list[] =
"Bermuda\0"
"Bhutan\0"
"Bolivia\0"
-"BosniaAndHerzegowina\0"
+"Bosnia And Herzegowina\0"
"Botswana\0"
-"BouvetIsland\0"
+"Bouvet Island\0"
"Brazil\0"
-"BritishIndianOceanTerritory\0"
+"British Indian Ocean Territory\0"
"Brunei\0"
"Bulgaria\0"
-"BurkinaFaso\0"
+"Burkina Faso\0"
"Burundi\0"
"Cambodia\0"
"Cameroon\0"
"Canada\0"
-"CapeVerde\0"
-"CaymanIslands\0"
-"CentralAfricanRepublic\0"
+"Cape Verde\0"
+"Cayman Islands\0"
+"Central African Republic\0"
"Chad\0"
"Chile\0"
"China\0"
-"ChristmasIsland\0"
-"CocosIslands\0"
+"Christmas Island\0"
+"Cocos Islands\0"
"Colombia\0"
"Comoros\0"
-"CongoKinshasa\0"
-"CongoBrazzaville\0"
-"CookIslands\0"
-"CostaRica\0"
-"IvoryCoast\0"
+"Congo Kinshasa\0"
+"Congo Brazzaville\0"
+"Cook Islands\0"
+"Costa Rica\0"
+"Ivory Coast\0"
"Croatia\0"
"Cuba\0"
"Cyprus\0"
-"CzechRepublic\0"
+"Czech Republic\0"
"Denmark\0"
"Djibouti\0"
"Dominica\0"
-"DominicanRepublic\0"
-"EastTimor\0"
+"Dominican Republic\0"
+"East Timor\0"
"Ecuador\0"
"Egypt\0"
-"ElSalvador\0"
-"EquatorialGuinea\0"
+"El Salvador\0"
+"Equatorial Guinea\0"
"Eritrea\0"
"Estonia\0"
"Ethiopia\0"
-"FalklandIslands\0"
-"FaroeIslands\0"
+"Falkland Islands\0"
+"Faroe Islands\0"
"Fiji\0"
"Finland\0"
"France\0"
"Guernsey\0"
-"FrenchGuiana\0"
-"FrenchPolynesia\0"
-"FrenchSouthernTerritories\0"
+"French Guiana\0"
+"French Polynesia\0"
+"French Southern Territories\0"
"Gabon\0"
"Gambia\0"
"Georgia\0"
@@ -7240,12 +7415,12 @@ static const char country_name_list[] =
"Guam\0"
"Guatemala\0"
"Guinea\0"
-"GuineaBissau\0"
+"Guinea Bissau\0"
"Guyana\0"
"Haiti\0"
-"HeardAndMcDonaldIslands\0"
+"Heard And McDonald Islands\0"
"Honduras\0"
-"HongKong\0"
+"Hong Kong\0"
"Hungary\0"
"Iceland\0"
"India\0"
@@ -7261,8 +7436,8 @@ static const char country_name_list[] =
"Kazakhstan\0"
"Kenya\0"
"Kiribati\0"
-"NorthKorea\0"
-"SouthKorea\0"
+"North Korea\0"
+"South Korea\0"
"Kuwait\0"
"Kyrgyzstan\0"
"Laos\0"
@@ -7282,7 +7457,7 @@ static const char country_name_list[] =
"Maldives\0"
"Mali\0"
"Malta\0"
-"MarshallIslands\0"
+"Marshall Islands\0"
"Martinique\0"
"Mauritania\0"
"Mauritius\0"
@@ -7300,58 +7475,58 @@ static const char country_name_list[] =
"Nauru\0"
"Nepal\0"
"Netherlands\0"
-"CuraSao\0"
-"NewCaledonia\0"
-"NewZealand\0"
+"Cura Sao\0"
+"New Caledonia\0"
+"New Zealand\0"
"Nicaragua\0"
"Niger\0"
"Nigeria\0"
"Niue\0"
-"NorfolkIsland\0"
-"NorthernMarianaIslands\0"
+"Norfolk Island\0"
+"Northern Mariana Islands\0"
"Norway\0"
"Oman\0"
"Pakistan\0"
"Palau\0"
-"PalestinianTerritories\0"
+"Palestinian Territories\0"
"Panama\0"
-"PapuaNewGuinea\0"
+"Papua New Guinea\0"
"Paraguay\0"
"Peru\0"
"Philippines\0"
"Pitcairn\0"
"Poland\0"
"Portugal\0"
-"PuertoRico\0"
+"Puerto Rico\0"
"Qatar\0"
"Reunion\0"
"Romania\0"
"Russia\0"
"Rwanda\0"
-"SaintKittsAndNevis\0"
-"SaintLucia\0"
-"SaintVincentAndTheGrenadines\0"
+"Saint Kitts And Nevis\0"
+"Saint Lucia\0"
+"Saint Vincent And The Grenadines\0"
"Samoa\0"
-"SanMarino\0"
-"SaoTomeAndPrincipe\0"
-"SaudiArabia\0"
+"San Marino\0"
+"Sao Tome And Principe\0"
+"Saudi Arabia\0"
"Senegal\0"
"Seychelles\0"
-"SierraLeone\0"
+"Sierra Leone\0"
"Singapore\0"
"Slovakia\0"
"Slovenia\0"
-"SolomonIslands\0"
+"Solomon Islands\0"
"Somalia\0"
-"SouthAfrica\0"
-"SouthGeorgiaAndTheSouthSandwichIslands\0"
+"South Africa\0"
+"South Georgia And The South Sandwich Islands\0"
"Spain\0"
-"SriLanka\0"
-"SaintHelena\0"
-"SaintPierreAndMiquelon\0"
+"Sri Lanka\0"
+"Saint Helena\0"
+"Saint Pierre And Miquelon\0"
"Sudan\0"
"Suriname\0"
-"SvalbardAndJanMayenIslands\0"
+"Svalbard And Jan Mayen Islands\0"
"Swaziland\0"
"Sweden\0"
"Switzerland\0"
@@ -7363,51 +7538,53 @@ static const char country_name_list[] =
"Togo\0"
"Tokelau\0"
"Tonga\0"
-"TrinidadAndTobago\0"
+"Trinidad And Tobago\0"
"Tunisia\0"
"Turkey\0"
"Turkmenistan\0"
-"TurksAndCaicosIslands\0"
+"Turks And Caicos Islands\0"
"Tuvalu\0"
"Uganda\0"
"Ukraine\0"
-"UnitedArabEmirates\0"
-"UnitedKingdom\0"
-"UnitedStates\0"
-"UnitedStatesMinorOutlyingIslands\0"
+"United Arab Emirates\0"
+"United Kingdom\0"
+"United States\0"
+"United States Minor Outlying Islands\0"
"Uruguay\0"
"Uzbekistan\0"
"Vanuatu\0"
-"VaticanCityState\0"
+"Vatican City State\0"
"Venezuela\0"
"Vietnam\0"
-"BritishVirginIslands\0"
-"UnitedStatesVirginIslands\0"
-"WallisAndFutunaIslands\0"
-"WesternSahara\0"
+"British Virgin Islands\0"
+"United States Virgin Islands\0"
+"Wallis And Futuna Islands\0"
+"Western Sahara\0"
"Yemen\0"
-"CanaryIslands\0"
+"Canary Islands\0"
"Zambia\0"
"Zimbabwe\0"
-"ClippertonIsland\0"
+"Clipperton Island\0"
"Montenegro\0"
"Serbia\0"
"Saint Barthelemy\0"
"Saint Martin\0"
-"LatinAmericaAndTheCaribbean\0"
-"AscensionIsland\0"
-"AlandIslands\0"
-"DiegoGarcia\0"
-"CeutaAndMelilla\0"
-"IsleOfMan\0"
+"Latin America\0"
+"Ascension Island\0"
+"Aland Islands\0"
+"Diego Garcia\0"
+"Ceuta And Melilla\0"
+"Isle Of Man\0"
"Jersey\0"
-"TristanDaCunha\0"
-"SouthSudan\0"
+"Tristan Da Cunha\0"
+"South Sudan\0"
"Bonaire\0"
-"SintMaarten\0"
+"Sint Maarten\0"
"Kosovo\0"
"European Union\0"
"Outlying Oceania\0"
+"World\0"
+"Europe\0"
;
static const quint16 country_name_index[] = {
@@ -7415,262 +7592,264 @@ static const quint16 country_name_index[] = {
8, // Afghanistan
20, // Albania
28, // Algeria
- 36, // AmericanSamoa
- 50, // Andorra
- 58, // Angola
- 65, // Anguilla
- 74, // Antarctica
- 85, // AntiguaAndBarbuda
- 103, // Argentina
- 113, // Armenia
- 121, // Aruba
- 127, // Australia
- 137, // Austria
- 145, // Azerbaijan
- 156, // Bahamas
- 164, // Bahrain
- 172, // Bangladesh
- 183, // Barbados
- 192, // Belarus
- 200, // Belgium
- 208, // Belize
- 215, // Benin
- 221, // Bermuda
- 229, // Bhutan
- 236, // Bolivia
- 244, // BosniaAndHerzegowina
- 265, // Botswana
- 274, // BouvetIsland
- 287, // Brazil
- 294, // BritishIndianOceanTerritory
- 322, // Brunei
- 329, // Bulgaria
- 338, // BurkinaFaso
- 350, // Burundi
- 358, // Cambodia
- 367, // Cameroon
- 376, // Canada
- 383, // CapeVerde
- 393, // CaymanIslands
- 407, // CentralAfricanRepublic
- 430, // Chad
- 435, // Chile
- 441, // China
- 447, // ChristmasIsland
- 463, // CocosIslands
- 476, // Colombia
- 485, // Comoros
- 493, // CongoKinshasa
- 507, // CongoBrazzaville
- 524, // CookIslands
- 536, // CostaRica
- 546, // IvoryCoast
- 557, // Croatia
- 565, // Cuba
- 570, // Cyprus
- 577, // CzechRepublic
- 591, // Denmark
- 599, // Djibouti
- 608, // Dominica
- 617, // DominicanRepublic
- 635, // EastTimor
- 645, // Ecuador
- 653, // Egypt
- 659, // ElSalvador
- 670, // EquatorialGuinea
- 687, // Eritrea
- 695, // Estonia
- 703, // Ethiopia
- 712, // FalklandIslands
- 728, // FaroeIslands
- 741, // Fiji
- 746, // Finland
- 754, // France
- 761, // Guernsey
- 770, // FrenchGuiana
- 783, // FrenchPolynesia
- 799, // FrenchSouthernTerritories
- 825, // Gabon
- 831, // Gambia
- 838, // Georgia
- 846, // Germany
- 854, // Ghana
- 860, // Gibraltar
- 870, // Greece
- 877, // Greenland
- 887, // Grenada
- 895, // Guadeloupe
- 906, // Guam
- 911, // Guatemala
- 921, // Guinea
- 928, // GuineaBissau
- 941, // Guyana
- 948, // Haiti
- 954, // HeardAndMcDonaldIslands
- 978, // Honduras
- 987, // HongKong
- 996, // Hungary
- 1004, // Iceland
- 1012, // India
- 1018, // Indonesia
- 1028, // Iran
- 1033, // Iraq
- 1038, // Ireland
- 1046, // Israel
- 1053, // Italy
- 1059, // Jamaica
- 1067, // Japan
- 1073, // Jordan
- 1080, // Kazakhstan
- 1091, // Kenya
- 1097, // Kiribati
- 1106, // NorthKorea
- 1117, // SouthKorea
- 1128, // Kuwait
- 1135, // Kyrgyzstan
- 1146, // Laos
- 1151, // Latvia
- 1158, // Lebanon
- 1166, // Lesotho
- 1174, // Liberia
- 1182, // Libya
- 1188, // Liechtenstein
- 1202, // Lithuania
- 1212, // Luxembourg
- 1223, // Macau
- 1229, // Macedonia
- 1239, // Madagascar
- 1250, // Malawi
- 1257, // Malaysia
- 1266, // Maldives
- 1275, // Mali
- 1280, // Malta
- 1286, // MarshallIslands
- 1302, // Martinique
- 1313, // Mauritania
- 1324, // Mauritius
- 1334, // Mayotte
- 1342, // Mexico
- 1349, // Micronesia
- 1360, // Moldova
- 1368, // Monaco
- 1375, // Mongolia
- 1384, // Montserrat
- 1395, // Morocco
- 1403, // Mozambique
- 1414, // Myanmar
- 1422, // Namibia
- 1430, // Nauru
- 1436, // Nepal
- 1442, // Netherlands
- 1454, // CuraSao
- 1462, // NewCaledonia
- 1475, // NewZealand
- 1486, // Nicaragua
- 1496, // Niger
- 1502, // Nigeria
- 1510, // Niue
- 1515, // NorfolkIsland
- 1529, // NorthernMarianaIslands
- 1552, // Norway
- 1559, // Oman
- 1564, // Pakistan
- 1573, // Palau
- 1579, // PalestinianTerritories
- 1602, // Panama
- 1609, // PapuaNewGuinea
- 1624, // Paraguay
- 1633, // Peru
- 1638, // Philippines
- 1650, // Pitcairn
- 1659, // Poland
- 1666, // Portugal
- 1675, // PuertoRico
- 1686, // Qatar
- 1692, // Reunion
- 1700, // Romania
- 1708, // Russia
- 1715, // Rwanda
- 1722, // SaintKittsAndNevis
- 1741, // SaintLucia
- 1752, // SaintVincentAndTheGrenadines
- 1781, // Samoa
- 1787, // SanMarino
- 1797, // SaoTomeAndPrincipe
- 1816, // SaudiArabia
- 1828, // Senegal
- 1836, // Seychelles
- 1847, // SierraLeone
- 1859, // Singapore
- 1869, // Slovakia
- 1878, // Slovenia
- 1887, // SolomonIslands
- 1902, // Somalia
- 1910, // SouthAfrica
- 1922, // SouthGeorgiaAndTheSouthSandwichIslands
- 1961, // Spain
- 1967, // SriLanka
- 1976, // SaintHelena
- 1988, // SaintPierreAndMiquelon
- 2011, // Sudan
- 2017, // Suriname
- 2026, // SvalbardAndJanMayenIslands
- 2053, // Swaziland
- 2063, // Sweden
- 2070, // Switzerland
- 2082, // Syria
- 2088, // Taiwan
- 2095, // Tajikistan
- 2106, // Tanzania
- 2115, // Thailand
- 2124, // Togo
- 2129, // Tokelau
- 2137, // Tonga
- 2143, // TrinidadAndTobago
- 2161, // Tunisia
- 2169, // Turkey
- 2176, // Turkmenistan
- 2189, // TurksAndCaicosIslands
- 2211, // Tuvalu
- 2218, // Uganda
- 2225, // Ukraine
- 2233, // UnitedArabEmirates
- 2252, // UnitedKingdom
- 2266, // UnitedStates
- 2279, // UnitedStatesMinorOutlyingIslands
- 2312, // Uruguay
- 2320, // Uzbekistan
- 2331, // Vanuatu
- 2339, // VaticanCityState
- 2356, // Venezuela
- 2366, // Vietnam
- 2374, // BritishVirginIslands
- 2395, // UnitedStatesVirginIslands
- 2421, // WallisAndFutunaIslands
- 2444, // WesternSahara
- 2458, // Yemen
- 2464, // CanaryIslands
- 2478, // Zambia
- 2485, // Zimbabwe
- 2494, // ClippertonIsland
- 2511, // Montenegro
- 2522, // Serbia
- 2529, // Saint Barthelemy
- 2546, // Saint Martin
- 2559, // LatinAmericaAndTheCaribbean
- 2587, // AscensionIsland
- 2603, // AlandIslands
- 2616, // DiegoGarcia
- 2628, // CeutaAndMelilla
- 2644, // IsleOfMan
- 2654, // Jersey
- 2661, // TristanDaCunha
- 2676, // SouthSudan
- 2687, // Bonaire
- 2695, // SintMaarten
- 2707, // Kosovo
- 2714, // European Union
- 2729, // Outlying Oceania
+ 36, // American Samoa
+ 51, // Andorra
+ 59, // Angola
+ 66, // Anguilla
+ 75, // Antarctica
+ 86, // Antigua And Barbuda
+ 106, // Argentina
+ 116, // Armenia
+ 124, // Aruba
+ 130, // Australia
+ 140, // Austria
+ 148, // Azerbaijan
+ 159, // Bahamas
+ 167, // Bahrain
+ 175, // Bangladesh
+ 186, // Barbados
+ 195, // Belarus
+ 203, // Belgium
+ 211, // Belize
+ 218, // Benin
+ 224, // Bermuda
+ 232, // Bhutan
+ 239, // Bolivia
+ 247, // Bosnia And Herzegowina
+ 270, // Botswana
+ 279, // Bouvet Island
+ 293, // Brazil
+ 300, // British Indian Ocean Territory
+ 331, // Brunei
+ 338, // Bulgaria
+ 347, // Burkina Faso
+ 360, // Burundi
+ 368, // Cambodia
+ 377, // Cameroon
+ 386, // Canada
+ 393, // Cape Verde
+ 404, // Cayman Islands
+ 419, // Central African Republic
+ 444, // Chad
+ 449, // Chile
+ 455, // China
+ 461, // Christmas Island
+ 478, // Cocos Islands
+ 492, // Colombia
+ 501, // Comoros
+ 509, // Congo Kinshasa
+ 524, // Congo Brazzaville
+ 542, // Cook Islands
+ 555, // Costa Rica
+ 566, // Ivory Coast
+ 578, // Croatia
+ 586, // Cuba
+ 591, // Cyprus
+ 598, // Czech Republic
+ 613, // Denmark
+ 621, // Djibouti
+ 630, // Dominica
+ 639, // Dominican Republic
+ 658, // East Timor
+ 669, // Ecuador
+ 677, // Egypt
+ 683, // El Salvador
+ 695, // Equatorial Guinea
+ 713, // Eritrea
+ 721, // Estonia
+ 729, // Ethiopia
+ 738, // Falkland Islands
+ 755, // Faroe Islands
+ 769, // Fiji
+ 774, // Finland
+ 782, // France
+ 789, // Guernsey
+ 798, // French Guiana
+ 812, // French Polynesia
+ 829, // French Southern Territories
+ 857, // Gabon
+ 863, // Gambia
+ 870, // Georgia
+ 878, // Germany
+ 886, // Ghana
+ 892, // Gibraltar
+ 902, // Greece
+ 909, // Greenland
+ 919, // Grenada
+ 927, // Guadeloupe
+ 938, // Guam
+ 943, // Guatemala
+ 953, // Guinea
+ 960, // Guinea Bissau
+ 974, // Guyana
+ 981, // Haiti
+ 987, // Heard And McDonald Islands
+ 1014, // Honduras
+ 1023, // Hong Kong
+ 1033, // Hungary
+ 1041, // Iceland
+ 1049, // India
+ 1055, // Indonesia
+ 1065, // Iran
+ 1070, // Iraq
+ 1075, // Ireland
+ 1083, // Israel
+ 1090, // Italy
+ 1096, // Jamaica
+ 1104, // Japan
+ 1110, // Jordan
+ 1117, // Kazakhstan
+ 1128, // Kenya
+ 1134, // Kiribati
+ 1143, // North Korea
+ 1155, // South Korea
+ 1167, // Kuwait
+ 1174, // Kyrgyzstan
+ 1185, // Laos
+ 1190, // Latvia
+ 1197, // Lebanon
+ 1205, // Lesotho
+ 1213, // Liberia
+ 1221, // Libya
+ 1227, // Liechtenstein
+ 1241, // Lithuania
+ 1251, // Luxembourg
+ 1262, // Macau
+ 1268, // Macedonia
+ 1278, // Madagascar
+ 1289, // Malawi
+ 1296, // Malaysia
+ 1305, // Maldives
+ 1314, // Mali
+ 1319, // Malta
+ 1325, // Marshall Islands
+ 1342, // Martinique
+ 1353, // Mauritania
+ 1364, // Mauritius
+ 1374, // Mayotte
+ 1382, // Mexico
+ 1389, // Micronesia
+ 1400, // Moldova
+ 1408, // Monaco
+ 1415, // Mongolia
+ 1424, // Montserrat
+ 1435, // Morocco
+ 1443, // Mozambique
+ 1454, // Myanmar
+ 1462, // Namibia
+ 1470, // Nauru
+ 1476, // Nepal
+ 1482, // Netherlands
+ 1494, // Cura Sao
+ 1503, // New Caledonia
+ 1517, // New Zealand
+ 1529, // Nicaragua
+ 1539, // Niger
+ 1545, // Nigeria
+ 1553, // Niue
+ 1558, // Norfolk Island
+ 1573, // Northern Mariana Islands
+ 1598, // Norway
+ 1605, // Oman
+ 1610, // Pakistan
+ 1619, // Palau
+ 1625, // Palestinian Territories
+ 1649, // Panama
+ 1656, // Papua New Guinea
+ 1673, // Paraguay
+ 1682, // Peru
+ 1687, // Philippines
+ 1699, // Pitcairn
+ 1708, // Poland
+ 1715, // Portugal
+ 1724, // Puerto Rico
+ 1736, // Qatar
+ 1742, // Reunion
+ 1750, // Romania
+ 1758, // Russia
+ 1765, // Rwanda
+ 1772, // Saint Kitts And Nevis
+ 1794, // Saint Lucia
+ 1806, // Saint Vincent And The Grenadines
+ 1839, // Samoa
+ 1845, // San Marino
+ 1856, // Sao Tome And Principe
+ 1878, // Saudi Arabia
+ 1891, // Senegal
+ 1899, // Seychelles
+ 1910, // Sierra Leone
+ 1923, // Singapore
+ 1933, // Slovakia
+ 1942, // Slovenia
+ 1951, // Solomon Islands
+ 1967, // Somalia
+ 1975, // South Africa
+ 1988, // South Georgia And The South Sandwich Islands
+ 2033, // Spain
+ 2039, // Sri Lanka
+ 2049, // Saint Helena
+ 2062, // Saint Pierre And Miquelon
+ 2088, // Sudan
+ 2094, // Suriname
+ 2103, // Svalbard And Jan Mayen Islands
+ 2134, // Swaziland
+ 2144, // Sweden
+ 2151, // Switzerland
+ 2163, // Syria
+ 2169, // Taiwan
+ 2176, // Tajikistan
+ 2187, // Tanzania
+ 2196, // Thailand
+ 2205, // Togo
+ 2210, // Tokelau
+ 2218, // Tonga
+ 2224, // Trinidad And Tobago
+ 2244, // Tunisia
+ 2252, // Turkey
+ 2259, // Turkmenistan
+ 2272, // Turks And Caicos Islands
+ 2297, // Tuvalu
+ 2304, // Uganda
+ 2311, // Ukraine
+ 2319, // United Arab Emirates
+ 2340, // United Kingdom
+ 2355, // United States
+ 2369, // United States Minor Outlying Islands
+ 2406, // Uruguay
+ 2414, // Uzbekistan
+ 2425, // Vanuatu
+ 2433, // Vatican City State
+ 2452, // Venezuela
+ 2462, // Vietnam
+ 2470, // British Virgin Islands
+ 2493, // United States Virgin Islands
+ 2522, // Wallis And Futuna Islands
+ 2548, // Western Sahara
+ 2563, // Yemen
+ 2569, // Canary Islands
+ 2584, // Zambia
+ 2591, // Zimbabwe
+ 2600, // Clipperton Island
+ 2618, // Montenegro
+ 2629, // Serbia
+ 2636, // Saint Barthelemy
+ 2653, // Saint Martin
+ 2666, // Latin America
+ 2680, // Ascension Island
+ 2697, // Aland Islands
+ 2711, // Diego Garcia
+ 2724, // Ceuta And Melilla
+ 2742, // Isle Of Man
+ 2754, // Jersey
+ 2761, // Tristan Da Cunha
+ 2778, // South Sudan
+ 2790, // Bonaire
+ 2798, // Sint Maarten
+ 2811, // Kosovo
+ 2818, // European Union
+ 2833, // Outlying Oceania
+ 2850, // World
+ 2856, // Europe
};
static const unsigned char language_code_list[] =
@@ -7759,7 +7938,7 @@ static const unsigned char language_code_list[] =
"mn\0" // Mongolian
"na\0" // Nauru
"ne\0" // Nepali
-"nb\0" // NorwegianBokmal
+"nb\0" // Norwegian Bokmal
"oc\0" // Occitan
"or\0" // Oriya
"ps\0" // Pashto
@@ -7815,7 +7994,7 @@ static const unsigned char language_code_list[] =
"yo\0" // Yoruba
"za\0" // Zhuang
"zu\0" // Zulu
-"nn\0" // NorwegianNynorsk
+"nn\0" // Norwegian Nynorsk
"bs\0" // Bosnian
"dv\0" // Divehi
"gv\0" // Manx
@@ -7904,7 +8083,7 @@ static const unsigned char language_code_list[] =
"kg\0" // Kongo
"kj\0" // Kwanyama
"li\0" // Limburgish
-"lu\0" // LubaKatanga
+"lu\0" // Luba Katanga
"lb\0" // Luxembourgish
"nv\0" // Navaho
"ng\0" // Ndonga
@@ -7915,10 +8094,10 @@ static const unsigned char language_code_list[] =
"bas" // Basaa
"dje" // Zarma
"dua" // Duala
-"dyo" // JolaFonyi
+"dyo" // Jola Fonyi
"ewo" // Ewondo
"ksf" // Bafia
-"mgh" // MakhuwaMeetto
+"mgh" // Makhuwa Meetto
"mua" // Mundang
"nmg" // Kwasio
"nus" // Nuer
@@ -7937,26 +8116,26 @@ static const unsigned char language_code_list[] =
"nnh" // Ngiemboon
"an\0" // Aragonese
"akk" // Akkadian
-"egy" // AncientEgyptian
-"grc" // AncientGreek
+"egy" // Ancient Egyptian
+"grc" // Ancient Greek
"arc" // Aramaic
"ban" // Balinese
"bax" // Bamun
-"bbc" // BatakToba
+"bbc" // Batak Toba
"bug" // Buginese
"bku" // Buhid
"xcr" // Carian
"ccp" // Chakma
-"myz" // ClassicalMandaic
+"myz" // Classical Mandaic
"cop" // Coptic
"doi" // Dogri
-"cjm" // EasternCham
-"eky" // EasternKayah
+"cjm" // Eastern Cham
+"eky" // Eastern Kayah
"ett" // Etruscan
"got" // Gothic
"hnn" // Hanunoo
"inh" // Ingush
-"hmd" // LargeFloweryMiao
+"hmd" // Large Flowery Miao
"lep" // Lepcha
"lif" // Limbu
"lis" // Lisu
@@ -7966,15 +8145,15 @@ static const unsigned char language_code_list[] =
"man" // Mandingo
"mni" // Manipuri
"xmr" // Meroitic
-"nod" // NorthernThai
-"sga" // OldIrish
-"non" // OldNorse
-"peo" // OldPersian
-"otk" // OldTurkish
+"nod" // Northern Thai
+"sga" // Old Irish
+"non" // Old Norse
+"peo" // Old Persian
+"otk" // Old Turkish
"pal" // Pahlavi
"xpr" // Parthian
"phn" // Phoenician
-"pra" // PrakritLanguage
+"pra" // Prakrit Language
"rej" // Rejang
"xsa" // Sabaean
"smp" // Samaritan
@@ -7983,16 +8162,16 @@ static const unsigned char language_code_list[] =
"srb" // Sora
"syl" // Sylheti
"tbw" // Tagbanwa
-"blt" // TaiDam
-"tdd" // TaiNua
+"blt" // Tai Dam
+"tdd" // Tai Nua
"uga" // Ugaritic
"bss" // Akoose
"lkt" // Lakota
"zgh" // Standard Moroccan Tamazight
"arn" // Mapuche
"ckb" // Central Kurdish
-"dsb" // LowerSorbian
-"hsb" // UpperSorbian
+"dsb" // Lower Sorbian
+"hsb" // Upper Sorbian
"ken" // Kenyang
"moh" // Mohawk
"nqo" // Nko
@@ -8030,7 +8209,7 @@ static const unsigned char language_code_list[] =
"tkl" // Tokelau
"tpi" // Tok Pisin
"tvl" // Tuvalu
-"mis" // UncodedLanguages
+"mis" // Uncoded Languages
"yue" // Cantonese
"osa" // Osage
"txg" // Tangut
@@ -8081,7 +8260,7 @@ static const unsigned char script_code_list[] =
"Brah" // Brahmi
"Bugi" // Buginese
"Buhd" // Buhid
-"Cans" // CanadianAboriginal
+"Cans" // Canadian Aboriginal
"Cari" // Carian
"Cakm" // Chakma
"Cham" // Cham
@@ -8170,7 +8349,7 @@ static const unsigned char script_code_list[] =
"Hatr" // Hatran
"Mult" // Multani
"Hung" // Old Hungarian
-"Sgnw" // SignWriting
+"Sgnw" // Sign Writing
"Adlm" // Adlam
"Bhks" // Bhaiksuki
"Marc" // Marchen
@@ -8185,12 +8364,12 @@ static const unsigned char country_code_list[] =
"AF\0" // Afghanistan
"AL\0" // Albania
"DZ\0" // Algeria
-"AS\0" // AmericanSamoa
+"AS\0" // American Samoa
"AD\0" // Andorra
"AO\0" // Angola
"AI\0" // Anguilla
"AQ\0" // Antarctica
-"AG\0" // AntiguaAndBarbuda
+"AG\0" // Antigua And Barbuda
"AR\0" // Argentina
"AM\0" // Armenia
"AW\0" // Aruba
@@ -8208,58 +8387,58 @@ static const unsigned char country_code_list[] =
"BM\0" // Bermuda
"BT\0" // Bhutan
"BO\0" // Bolivia
-"BA\0" // BosniaAndHerzegowina
+"BA\0" // Bosnia And Herzegowina
"BW\0" // Botswana
-"BV\0" // BouvetIsland
+"BV\0" // Bouvet Island
"BR\0" // Brazil
-"IO\0" // BritishIndianOceanTerritory
+"IO\0" // British Indian Ocean Territory
"BN\0" // Brunei
"BG\0" // Bulgaria
-"BF\0" // BurkinaFaso
+"BF\0" // Burkina Faso
"BI\0" // Burundi
"KH\0" // Cambodia
"CM\0" // Cameroon
"CA\0" // Canada
-"CV\0" // CapeVerde
-"KY\0" // CaymanIslands
-"CF\0" // CentralAfricanRepublic
+"CV\0" // Cape Verde
+"KY\0" // Cayman Islands
+"CF\0" // Central African Republic
"TD\0" // Chad
"CL\0" // Chile
"CN\0" // China
-"CX\0" // ChristmasIsland
-"CC\0" // CocosIslands
+"CX\0" // Christmas Island
+"CC\0" // Cocos Islands
"CO\0" // Colombia
"KM\0" // Comoros
-"CD\0" // CongoKinshasa
-"CG\0" // CongoBrazzaville
-"CK\0" // CookIslands
-"CR\0" // CostaRica
-"CI\0" // IvoryCoast
+"CD\0" // Congo Kinshasa
+"CG\0" // Congo Brazzaville
+"CK\0" // Cook Islands
+"CR\0" // Costa Rica
+"CI\0" // Ivory Coast
"HR\0" // Croatia
"CU\0" // Cuba
"CY\0" // Cyprus
-"CZ\0" // CzechRepublic
+"CZ\0" // Czech Republic
"DK\0" // Denmark
"DJ\0" // Djibouti
"DM\0" // Dominica
-"DO\0" // DominicanRepublic
-"TL\0" // EastTimor
+"DO\0" // Dominican Republic
+"TL\0" // East Timor
"EC\0" // Ecuador
"EG\0" // Egypt
-"SV\0" // ElSalvador
-"GQ\0" // EquatorialGuinea
+"SV\0" // El Salvador
+"GQ\0" // Equatorial Guinea
"ER\0" // Eritrea
"EE\0" // Estonia
"ET\0" // Ethiopia
-"FK\0" // FalklandIslands
-"FO\0" // FaroeIslands
+"FK\0" // Falkland Islands
+"FO\0" // Faroe Islands
"FJ\0" // Fiji
"FI\0" // Finland
"FR\0" // France
"GG\0" // Guernsey
-"GF\0" // FrenchGuiana
-"PF\0" // FrenchPolynesia
-"TF\0" // FrenchSouthernTerritories
+"GF\0" // French Guiana
+"PF\0" // French Polynesia
+"TF\0" // French Southern Territories
"GA\0" // Gabon
"GM\0" // Gambia
"GE\0" // Georgia
@@ -8273,12 +8452,12 @@ static const unsigned char country_code_list[] =
"GU\0" // Guam
"GT\0" // Guatemala
"GN\0" // Guinea
-"GW\0" // GuineaBissau
+"GW\0" // Guinea Bissau
"GY\0" // Guyana
"HT\0" // Haiti
-"HM\0" // HeardAndMcDonaldIslands
+"HM\0" // Heard And McDonald Islands
"HN\0" // Honduras
-"HK\0" // HongKong
+"HK\0" // Hong Kong
"HU\0" // Hungary
"IS\0" // Iceland
"IN\0" // India
@@ -8294,8 +8473,8 @@ static const unsigned char country_code_list[] =
"KZ\0" // Kazakhstan
"KE\0" // Kenya
"KI\0" // Kiribati
-"KP\0" // NorthKorea
-"KR\0" // SouthKorea
+"KP\0" // North Korea
+"KR\0" // South Korea
"KW\0" // Kuwait
"KG\0" // Kyrgyzstan
"LA\0" // Laos
@@ -8315,7 +8494,7 @@ static const unsigned char country_code_list[] =
"MV\0" // Maldives
"ML\0" // Mali
"MT\0" // Malta
-"MH\0" // MarshallIslands
+"MH\0" // Marshall Islands
"MQ\0" // Martinique
"MR\0" // Mauritania
"MU\0" // Mauritius
@@ -8333,58 +8512,58 @@ static const unsigned char country_code_list[] =
"NR\0" // Nauru
"NP\0" // Nepal
"NL\0" // Netherlands
-"CW\0" // CuraSao
-"NC\0" // NewCaledonia
-"NZ\0" // NewZealand
+"CW\0" // Cura Sao
+"NC\0" // New Caledonia
+"NZ\0" // New Zealand
"NI\0" // Nicaragua
"NE\0" // Niger
"NG\0" // Nigeria
"NU\0" // Niue
-"NF\0" // NorfolkIsland
-"MP\0" // NorthernMarianaIslands
+"NF\0" // Norfolk Island
+"MP\0" // Northern Mariana Islands
"NO\0" // Norway
"OM\0" // Oman
"PK\0" // Pakistan
"PW\0" // Palau
-"PS\0" // PalestinianTerritories
+"PS\0" // Palestinian Territories
"PA\0" // Panama
-"PG\0" // PapuaNewGuinea
+"PG\0" // Papua New Guinea
"PY\0" // Paraguay
"PE\0" // Peru
"PH\0" // Philippines
"PN\0" // Pitcairn
"PL\0" // Poland
"PT\0" // Portugal
-"PR\0" // PuertoRico
+"PR\0" // Puerto Rico
"QA\0" // Qatar
"RE\0" // Reunion
"RO\0" // Romania
"RU\0" // Russia
"RW\0" // Rwanda
-"KN\0" // SaintKittsAndNevis
-"LC\0" // SaintLucia
-"VC\0" // SaintVincentAndTheGrenadines
+"KN\0" // Saint Kitts And Nevis
+"LC\0" // Saint Lucia
+"VC\0" // Saint Vincent And The Grenadines
"WS\0" // Samoa
-"SM\0" // SanMarino
-"ST\0" // SaoTomeAndPrincipe
-"SA\0" // SaudiArabia
+"SM\0" // San Marino
+"ST\0" // Sao Tome And Principe
+"SA\0" // Saudi Arabia
"SN\0" // Senegal
"SC\0" // Seychelles
-"SL\0" // SierraLeone
+"SL\0" // Sierra Leone
"SG\0" // Singapore
"SK\0" // Slovakia
"SI\0" // Slovenia
-"SB\0" // SolomonIslands
+"SB\0" // Solomon Islands
"SO\0" // Somalia
-"ZA\0" // SouthAfrica
-"GS\0" // SouthGeorgiaAndTheSouthSandwichIslands
+"ZA\0" // South Africa
+"GS\0" // South Georgia And The South Sandwich Islands
"ES\0" // Spain
-"LK\0" // SriLanka
-"SH\0" // SaintHelena
-"PM\0" // SaintPierreAndMiquelon
+"LK\0" // Sri Lanka
+"SH\0" // Saint Helena
+"PM\0" // Saint Pierre And Miquelon
"SD\0" // Sudan
"SR\0" // Suriname
-"SJ\0" // SvalbardAndJanMayenIslands
+"SJ\0" // Svalbard And Jan Mayen Islands
"SZ\0" // Swaziland
"SE\0" // Sweden
"CH\0" // Switzerland
@@ -8396,51 +8575,53 @@ static const unsigned char country_code_list[] =
"TG\0" // Togo
"TK\0" // Tokelau
"TO\0" // Tonga
-"TT\0" // TrinidadAndTobago
+"TT\0" // Trinidad And Tobago
"TN\0" // Tunisia
"TR\0" // Turkey
"TM\0" // Turkmenistan
-"TC\0" // TurksAndCaicosIslands
+"TC\0" // Turks And Caicos Islands
"TV\0" // Tuvalu
"UG\0" // Uganda
"UA\0" // Ukraine
-"AE\0" // UnitedArabEmirates
-"GB\0" // UnitedKingdom
-"US\0" // UnitedStates
-"UM\0" // UnitedStatesMinorOutlyingIslands
+"AE\0" // United Arab Emirates
+"GB\0" // United Kingdom
+"US\0" // United States
+"UM\0" // United States Minor Outlying Islands
"UY\0" // Uruguay
"UZ\0" // Uzbekistan
"VU\0" // Vanuatu
-"VA\0" // VaticanCityState
+"VA\0" // Vatican City State
"VE\0" // Venezuela
"VN\0" // Vietnam
-"VG\0" // BritishVirginIslands
-"VI\0" // UnitedStatesVirginIslands
-"WF\0" // WallisAndFutunaIslands
-"EH\0" // WesternSahara
+"VG\0" // British Virgin Islands
+"VI\0" // United States Virgin Islands
+"WF\0" // Wallis And Futuna Islands
+"EH\0" // Western Sahara
"YE\0" // Yemen
-"IC\0" // CanaryIslands
+"IC\0" // Canary Islands
"ZM\0" // Zambia
"ZW\0" // Zimbabwe
-"CP\0" // ClippertonIsland
+"CP\0" // Clipperton Island
"ME\0" // Montenegro
"RS\0" // Serbia
"BL\0" // Saint Barthelemy
"MF\0" // Saint Martin
-"419" // LatinAmericaAndTheCaribbean
-"AC\0" // AscensionIsland
-"AX\0" // AlandIslands
-"DG\0" // DiegoGarcia
-"EA\0" // CeutaAndMelilla
-"IM\0" // IsleOfMan
+"419" // Latin America
+"AC\0" // Ascension Island
+"AX\0" // Aland Islands
+"DG\0" // Diego Garcia
+"EA\0" // Ceuta And Melilla
+"IM\0" // Isle Of Man
"JE\0" // Jersey
-"TA\0" // TristanDaCunha
-"SS\0" // SouthSudan
+"TA\0" // Tristan Da Cunha
+"SS\0" // South Sudan
"BQ\0" // Bonaire
-"SX\0" // SintMaarten
+"SX\0" // Sint Maarten
"XK\0" // Kosovo
"EU\0" // European Union
"QO\0" // Outlying Oceania
+"001" // World
+"150" // Europe
;
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 6669ae7c8b..f2e11499c8 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -274,6 +274,7 @@ public:
public:
quint16 m_language_id, m_script_id, m_country_id;
+ // FIXME QTBUG-69324: not all unicode code-points map to single-token UTF-16 :-(
quint16 m_decimal, m_group, m_list, m_percent, m_zero, m_minus, m_plus, m_exponential;
quint16 m_quotation_start, m_quotation_end;
quint16 m_alternate_quotation_start, m_alternate_quotation_end;
diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp
index 4d969a4723..bde52a20b9 100644
--- a/src/corelib/tools/qlocale_tools.cpp
+++ b/src/corelib/tools/qlocale_tools.cpp
@@ -75,8 +75,8 @@ QT_BEGIN_NAMESPACE
QT_CLOCALE_HOLDER
-void doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, int bufSize,
- bool &sign, int &length, int &decpt)
+void qt_doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, int bufSize,
+ bool &sign, int &length, int &decpt)
{
if (bufSize == 0) {
decpt = 0;
@@ -277,8 +277,8 @@ void doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *
--length;
}
-double asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
- TrailingJunkMode trailingJunkMode)
+double qt_asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
+ StrayCharacterMode strayCharMode)
{
if (*num == '\0') {
ok = false;
@@ -315,9 +315,13 @@ double asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
double d = 0.0;
#if !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
- int conv_flags = (trailingJunkMode == TrailingJunkAllowed) ?
- double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK :
- double_conversion::StringToDoubleConverter::NO_FLAGS;
+ int conv_flags = double_conversion::StringToDoubleConverter::NO_FLAGS;
+ if (strayCharMode == TrailingJunkAllowed) {
+ conv_flags = double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK;
+ } else if (strayCharMode == WhitespacesAllowed) {
+ conv_flags = double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES
+ | double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES;
+ }
double_conversion::StringToDoubleConverter conv(conv_flags, 0.0, qt_snan(), 0, 0);
d = conv.StringToDouble(num, numLen, &processed);
@@ -336,7 +340,7 @@ double asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
if (qDoubleSscanf(num, QT_CLOCALE, "%lf%n", &d, &processed) < 1)
processed = 0;
- if ((trailingJunkMode == TrailingJunkProhibited && processed != numLen) || qIsNaN(d)) {
+ if ((strayCharMode == TrailingJunkProhibited && processed != numLen) || qIsNaN(d)) {
// Implementation defined nan symbol or garbage found. We don't accept it.
processed = 0;
ok = false;
@@ -361,7 +365,7 @@ double asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
#endif // !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
// Otherwise we would have gotten NaN or sorted it out above.
- Q_ASSERT(trailingJunkMode == TrailingJunkAllowed || processed == numLen);
+ Q_ASSERT(strayCharMode == TrailingJunkAllowed || processed == numLen);
// Check if underflow has occurred.
if (isZero(d)) {
@@ -544,7 +548,7 @@ double qstrntod(const char *s00, int len, const char **se, bool *ok)
{
int processed = 0;
bool nonNullOk = false;
- double d = asciiToDouble(s00, len, nonNullOk, processed, TrailingJunkAllowed);
+ double d = qt_asciiToDouble(s00, len, nonNullOk, processed, TrailingJunkAllowed);
if (se)
*se = s00 + processed;
if (ok)
@@ -560,8 +564,8 @@ QString qdtoa(qreal d, int *decpt, int *sign)
// Some versions of libdouble-conversion like an extra digit, probably for '\0'
char result[QLocaleData::DoubleMaxSignificant + 1];
- doubleToAscii(d, QLocaleData::DFSignificantDigits, QLocale::FloatingPointShortest, result,
- QLocaleData::DoubleMaxSignificant + 1, nonNullSign, length, nonNullDecpt);
+ qt_doubleToAscii(d, QLocaleData::DFSignificantDigits, QLocale::FloatingPointShortest, result,
+ QLocaleData::DoubleMaxSignificant + 1, nonNullSign, length, nonNullDecpt);
if (sign)
*sign = nonNullSign ? 1 : 0;
diff --git a/src/corelib/tools/qlocale_tools_p.h b/src/corelib/tools/qlocale_tools_p.h
index 742abb4957..594331ae37 100644
--- a/src/corelib/tools/qlocale_tools_p.h
+++ b/src/corelib/tools/qlocale_tools_p.h
@@ -72,15 +72,16 @@
QT_BEGIN_NAMESPACE
-enum TrailingJunkMode {
+enum StrayCharacterMode {
TrailingJunkProhibited,
- TrailingJunkAllowed
+ TrailingJunkAllowed,
+ WhitespacesAllowed
};
-double asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
- TrailingJunkMode trailingJunkMode = TrailingJunkProhibited);
-void doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, int bufSize,
- bool &sign, int &length, int &decpt);
+double qt_asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
+ StrayCharacterMode strayCharMode = TrailingJunkProhibited);
+void qt_doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, int bufSize,
+ bool &sign, int &length, int &decpt);
QString qulltoa(qulonglong l, int base, const QChar _zero);
Q_CORE_EXPORT QString qdtoa(qreal d, int *decpt, int *sign);
diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp
index 30aefb71c1..ebc4430046 100644
--- a/src/corelib/tools/qlocale_win.cpp
+++ b/src/corelib/tools/qlocale_win.cpp
@@ -274,7 +274,7 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution()
QString &QSystemLocalePrivate::substituteDigits(QString &string)
{
ushort zero = zeroDigit().unicode();
- ushort *qch = (ushort *)string.data();
+ ushort *qch = reinterpret_cast<ushort *>(string.data());
for (ushort *end = qch + string.size(); qch != end; ++qch) {
if (*qch >= '0' && *qch <= '9')
*qch = zero + (*qch - '0');
@@ -365,7 +365,7 @@ QVariant QSystemLocalePrivate::dayName(int day, QLocale::FormatType type)
if (type == QLocale::LongFormat)
return getLocaleInfo(long_day_map[day]);
- else if (type == QLocale::NarrowFormat)
+ if (type == QLocale::NarrowFormat)
return getLocaleInfo(narrow_day_map[day]);
return getLocaleInfo(short_day_map[day]);
}
@@ -386,7 +386,7 @@ QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type)
month -= 1;
if (month < 0 || month > 11)
- return QString();
+ return QString();
LCTYPE lctype = (type == QLocale::ShortFormat || type == QLocale::NarrowFormat)
? short_month_map[month] : long_month_map[month];
@@ -988,7 +988,7 @@ LCID qt_inIsoNametoLCID(const char *name)
// handle norwegian manually, the list above will fail
if (!strncmp(name, "nb", 2))
return 0x0414;
- else if (!strncmp(name, "nn", 2))
+ if (!strncmp(name, "nn", 2))
return 0x0814;
char n[64];
@@ -1001,9 +1001,9 @@ LCID qt_inIsoNametoLCID(const char *name)
++c;
}
- for (int i = 0; i < windows_to_iso_count; ++i) {
- if (!strcmp(n, windows_to_iso_list[i].iso_name))
- return windows_to_iso_list[i].windows_code;
+ for (const WindowsToISOListElt &i : windows_to_iso_list) {
+ if (!strcmp(n, i.iso_name))
+ return i.windows_code;
}
return LOCALE_USER_DEFAULT;
}
@@ -1099,8 +1099,7 @@ static QByteArray getWinLocaleName(LPWSTR id)
id = qstrtoll(result.data(), 0, 0, &ok);
if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX )
return result;
- else
- return winLangCodeToIsoName( (int)id );
+ return winLangCodeToIsoName(int(id));
}
}
diff --git a/src/corelib/tools/qmakearray_p.h b/src/corelib/tools/qmakearray_p.h
new file mode 100644
index 0000000000..ae4d7f07c6
--- /dev/null
+++ b/src/corelib/tools/qmakearray_p.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMAKEARRAY_P_H
+#define QMAKEARRAY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+#include <array>
+#include <type_traits>
+#include <utility>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtPrivate {
+template<typename T>
+constexpr T&& Forward(typename std::remove_reference<T>::type& t) noexcept
+{
+ return static_cast<T&&>(t);
+}
+
+template<typename T>
+constexpr T&& Forward(typename std::remove_reference<T>::type&& t) noexcept
+{
+ static_assert(!std::is_lvalue_reference<T>::value,
+ "template argument substituting T is an lvalue reference type");
+ return static_cast<T&&>(t);
+}
+
+template <typename ManualType, typename ...>
+struct ArrayTypeHelper
+{
+ using type = ManualType;
+};
+
+template <typename ... Types>
+struct ArrayTypeHelper<void, Types...> : std::common_type<Types...> { };
+
+template <typename ManualType, typename... Types>
+using ArrayType = std::array<typename ArrayTypeHelper<ManualType, Types...>::type,
+ sizeof...(Types)>;
+
+template<typename ... Values>
+struct QuickSortData { };
+
+template <template <typename> class Predicate,
+ typename ... Values>
+struct QuickSortFilter;
+
+template <typename ... Right, typename ... Left>
+constexpr QuickSortData<Right..., Left...> quickSortConcat(
+ QuickSortData<Right...>, QuickSortData<Left...>) noexcept;
+
+template<typename ... Right, typename Middle, typename ... Left>
+constexpr QuickSortData<Right..., Middle, Left...> quickSortConcat(
+ QuickSortData<Right...>,
+ QuickSortData<Middle>,
+ QuickSortData<Left...>) noexcept;
+
+template <template <typename> class Predicate,
+ typename Head, typename ... Tail>
+struct QuickSortFilter<Predicate, QuickSortData<Head, Tail...>>
+{
+ using TailFilteredData = typename QuickSortFilter<
+ Predicate, QuickSortData<Tail...>>::Type;
+
+ using Type = typename QConditional<
+ Predicate<Head>::value,
+ decltype(quickSortConcat(QuickSortData<Head> {}, TailFilteredData{})),
+ TailFilteredData>::Type;
+};
+
+template <template <typename> class Predicate>
+struct QuickSortFilter<Predicate, QuickSortData<>>
+{
+ using Type = QuickSortData<>;
+};
+
+template <typename ... Values>
+struct QuickSort;
+
+template <typename Pivot, typename ... Values>
+struct QuickSort<QuickSortData<Pivot, Values...>>
+{
+ template <typename Left>
+ struct LessThan {
+ static constexpr const bool value = Left::data() <= Pivot::data();
+ };
+
+ template <typename Left>
+ struct MoreThan {
+ static constexpr const bool value = !(Left::data() <= Pivot::data());
+ };
+
+ using LeftSide = typename QuickSortFilter<LessThan, QuickSortData<Values...>>::Type;
+ using RightSide = typename QuickSortFilter<MoreThan, QuickSortData<Values...>>::Type;
+
+ using LeftQS = typename QuickSort<LeftSide>::Type;
+ using RightQS = typename QuickSort<RightSide>::Type;
+
+ using Type = decltype(quickSortConcat(LeftQS{}, QuickSortData<Pivot> {}, RightQS{}));
+
+};
+
+template <>
+struct QuickSort<QuickSortData<>>
+{
+ using Type = QuickSortData<>;
+};
+} // namespace QtPrivate
+
+template <typename ManualType = void, typename ... Types>
+constexpr QtPrivate::ArrayType<ManualType, Types...> qMakeArray(Types && ... t) noexcept
+{
+ return {{QtPrivate::Forward<typename QtPrivate::ArrayType<ManualType, Types...>::value_type>(t)...}};
+}
+
+template<typename ... Values>
+struct QSortedData {
+ using Data = typename QtPrivate::QuickSort<typename QtPrivate::QuickSortData<Values...>>::Type;
+};
+
+template<typename ... Values>
+constexpr auto qMakeArray(QtPrivate::QuickSortData<Values...>) noexcept -> decltype(qMakeArray(Values::data()...))
+{
+ return qMakeArray(Values::data() ...);
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QMAKEARRAY_P_H
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index a5b9096835..1cf9299e26 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -449,6 +449,7 @@ public:
inline iterator operator-(int j) const { return operator+(-j); }
inline iterator &operator+=(int j) { return *this = *this + j; }
inline iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
#ifndef QT_STRICT_ITERATORS
public:
@@ -512,6 +513,7 @@ public:
inline const_iterator operator-(int j) const { return operator+(-j); }
inline const_iterator &operator+=(int j) { return *this = *this + j; }
inline const_iterator &operator-=(int j) { return *this = *this - j; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
#ifdef QT_STRICT_ITERATORS
private:
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 96ddca56af..87b30c952e 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -3813,50 +3813,57 @@ struct QRegExpPrivate
};
#if !defined(QT_NO_REGEXP_OPTIM)
-typedef QCache<QRegExpEngineKey, QRegExpEngine> EngineCache;
-Q_GLOBAL_STATIC(EngineCache, globalEngineCache)
-static QBasicMutex globalEngineCacheMutex;
+struct QRECache
+{
+ typedef QHash<QRegExpEngineKey, QRegExpEngine *> EngineCache;
+ typedef QCache<QRegExpEngineKey, QRegExpEngine> UnusedEngineCache;
+ EngineCache usedEngines;
+ UnusedEngineCache unusedEngines;
+};
+Q_GLOBAL_STATIC(QRECache, engineCache)
+static QBasicMutex engineCacheMutex;
#endif // QT_NO_REGEXP_OPTIM
static void derefEngine(QRegExpEngine *eng, const QRegExpEngineKey &key)
{
- if (!eng->ref.deref()) {
#if !defined(QT_NO_REGEXP_OPTIM)
- if (globalEngineCache()) {
- QMutexLocker locker(&globalEngineCacheMutex);
- QT_TRY {
- globalEngineCache()->insert(key, eng, 4 + key.pattern.length() / 4);
- } QT_CATCH(const std::bad_alloc &) {
- // in case of an exception (e.g. oom), just delete the engine
- delete eng;
- }
+ QMutexLocker locker(&engineCacheMutex);
+ if (!eng->ref.deref()) {
+ if (QRECache *c = engineCache()) {
+ c->unusedEngines.insert(key, eng, 4 + key.pattern.length() / 4);
+ c->usedEngines.remove(key);
} else {
delete eng;
}
+ }
#else
- Q_UNUSED(key);
+ Q_UNUSED(key);
+ if (!eng->ref.deref())
delete eng;
#endif
- }
}
static void prepareEngine_helper(QRegExpPrivate *priv)
{
- bool initMatchState = !priv->eng;
+ Q_ASSERT(!priv->eng);
+
#if !defined(QT_NO_REGEXP_OPTIM)
- if (!priv->eng && globalEngineCache()) {
- QMutexLocker locker(&globalEngineCacheMutex);
- priv->eng = globalEngineCache()->take(priv->engineKey);
- if (priv->eng != 0)
+ QMutexLocker locker(&engineCacheMutex);
+ if (QRECache *c = engineCache()) {
+ priv->eng = c->unusedEngines.take(priv->engineKey);
+ if (!priv->eng)
+ priv->eng = c->usedEngines.value(priv->engineKey);
+ if (!priv->eng)
+ priv->eng = new QRegExpEngine(priv->engineKey);
+ else
priv->eng->ref.ref();
+
+ c->usedEngines.insert(priv->engineKey, priv->eng);
+ return;
}
#endif // QT_NO_REGEXP_OPTIM
- if (!priv->eng)
- priv->eng = new QRegExpEngine(priv->engineKey);
-
- if (initMatchState)
- priv->matchState.prepareForMatch(priv->eng);
+ priv->eng = new QRegExpEngine(priv->engineKey);
}
inline static void prepareEngine(QRegExpPrivate *priv)
@@ -3864,6 +3871,7 @@ inline static void prepareEngine(QRegExpPrivate *priv)
if (priv->eng)
return;
prepareEngine_helper(priv);
+ priv->matchState.prepareForMatch(priv->eng);
}
static void prepareEngineForMatch(QRegExpPrivate *priv, const QString &str)
diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp
index 13eff07c04..1026d4ab28 100644
--- a/src/corelib/tools/qregularexpression.cpp
+++ b/src/corelib/tools/qregularexpression.cpp
@@ -43,7 +43,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qhashfunctions.h>
-#include <QtCore/qreadwritelock.h>
+#include <QtCore/qmutex.h>
#include <QtCore/qvector.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>
@@ -483,6 +483,11 @@ QT_BEGIN_NAMESPACE
Note the usage of the non-capturing group in order to preserve the meaning
of the branch operator inside the pattern.
+ The QRegularExpression::anchoredPattern() helper method does exactly that for
+ you.
+
+ \sa anchoredPattern
+
\section3 Porting from QRegExp's Partial Matching
When using QRegExp::exactMatch(), if an exact match was not found, one
@@ -516,10 +521,10 @@ QT_BEGIN_NAMESPACE
\section2 Wildcard matching
- There is no equivalent of wildcard matching in QRegularExpression.
- Nevertheless, rewriting a regular expression in wildcard syntax to a
- Perl-compatible regular expression is a very easy task, given the fact
- that wildcard syntax supported by QRegExp is very simple.
+ There is no direct way to do wildcard matching in QRegularExpression.
+ However, the wildcardToRegularExpression method is provided to translate
+ glob patterns into a Perl-compatible regular expression that can be used
+ for that purpose.
\section2 Other pattern syntaxes
@@ -720,21 +725,14 @@ QT_BEGIN_NAMESPACE
to the \c{/u} modifier in Perl regular expressions.
\value OptimizeOnFirstUsageOption
- The regular expression will be optimized (and possibly
- JIT-compiled) on its first usage, instead of after a certain (undefined)
- number of usages. See also \l{QRegularExpression::}{optimize()}.
- This enum value has been introduced in Qt 5.4.
+ This option is ignored. A regular expression is automatically optimized
+ (including JIT compiling) the first time it is used. This enum value
+ was introduced in Qt 5.4.
\value DontAutomaticallyOptimizeOption
- Regular expressions are automatically optimized after a
- certain number of usages; setting this option prevents such
- optimizations, therefore avoiding possible unpredictable spikes in
- CPU and memory usage. If both this option and the
- \c{OptimizeOnFirstUsageOption} option are set, then this option takes
- precedence. Note: this option will still let the regular expression
- to be optimized by manually calling
- \l{QRegularExpression::}{optimize()}. This enum value has been
- introduced in Qt 5.4.
+ This option is ignored. A regular expression is automatically optimized
+ (including JIT compiling) the first time it is used. This enum value
+ was introduced in Qt 5.4.
*/
/*!
@@ -791,13 +789,6 @@ QT_BEGIN_NAMESPACE
Qt 5.4.
*/
-// after how many usages we optimize the regexp
-#ifdef QT_BUILD_INTERNAL
-Q_AUTOTEST_EXPORT unsigned int qt_qregularexpression_optimize_after_use_count = 10;
-#else
-static const unsigned int qt_qregularexpression_optimize_after_use_count = 10;
-#endif // QT_BUILD_INTERNAL
-
/*!
\internal
*/
@@ -847,13 +838,7 @@ struct QRegularExpressionPrivate : QSharedData
void cleanCompiledPattern();
void compilePattern();
void getPatternInfo();
-
- enum OptimizePatternOption {
- LazyOptimizeOption,
- ImmediateOptimizeOption
- };
-
- void optimizePattern(OptimizePatternOption option);
+ void optimizePattern();
enum CheckSubjectStringOption {
CheckSubjectString,
@@ -878,16 +863,15 @@ struct QRegularExpressionPrivate : QSharedData
// *All* of the following members are managed while holding this mutex,
// except for isDirty which is set to true by QRegularExpression setters
// (right after a detach happened).
- mutable QReadWriteLock mutex;
+ mutable QMutex mutex;
// The PCRE code pointer is reference-counted by the QRegularExpressionPrivate
// objects themselves; when the private is copied (i.e. a detach happened)
- // they are set to 0
+ // it is set to nullptr
pcre2_code_16 *compiledPattern;
int errorCode;
int errorOffset;
int capturingCount;
- unsigned int usedCount;
bool usingCrLfNewlines;
bool isDirty;
};
@@ -952,11 +936,10 @@ QRegularExpressionPrivate::QRegularExpressionPrivate()
patternOptions(0),
pattern(),
mutex(),
- compiledPattern(0),
+ compiledPattern(nullptr),
errorCode(0),
errorOffset(-1),
capturingCount(0),
- usedCount(0),
usingCrLfNewlines(false),
isDirty(true)
{
@@ -974,8 +957,8 @@ QRegularExpressionPrivate::~QRegularExpressionPrivate()
\internal
Copies the private, which means copying only the pattern and the pattern
- options. The compiledPattern and the studyData pointers are NOT copied (we
- do not own them any more), and in general all the members set when
+ options. The compiledPattern pointer is NOT copied (we
+ do not own it any more), and in general all the members set when
compiling a pattern are set to default values. isDirty is set back to true
so that the pattern has to be recompiled again.
*/
@@ -984,11 +967,10 @@ QRegularExpressionPrivate::QRegularExpressionPrivate(const QRegularExpressionPri
patternOptions(other.patternOptions),
pattern(other.pattern),
mutex(),
- compiledPattern(0),
+ compiledPattern(nullptr),
errorCode(0),
errorOffset(-1),
capturingCount(0),
- usedCount(0),
usingCrLfNewlines(false),
isDirty(true)
{
@@ -1000,11 +982,10 @@ QRegularExpressionPrivate::QRegularExpressionPrivate(const QRegularExpressionPri
void QRegularExpressionPrivate::cleanCompiledPattern()
{
pcre2_code_free_16(compiledPattern);
- compiledPattern = 0;
+ compiledPattern = nullptr;
errorCode = 0;
errorOffset = -1;
capturingCount = 0;
- usedCount = 0;
usingCrLfNewlines = false;
}
@@ -1013,7 +994,7 @@ void QRegularExpressionPrivate::cleanCompiledPattern()
*/
void QRegularExpressionPrivate::compilePattern()
{
- const QWriteLocker lock(&mutex);
+ const QMutexLocker lock(&mutex);
if (!isDirty)
return;
@@ -1040,6 +1021,7 @@ void QRegularExpressionPrivate::compilePattern()
errorCode = 0;
}
+ optimizePattern();
getPatternInfo();
}
@@ -1140,15 +1122,10 @@ static bool isJitEnabled()
The purpose of the function is to call pcre2_jit_compile_16, which
JIT-compiles the pattern.
- It gets called by doMatch() every time a match is performed.
-
- As of now, the optimizations on the pattern are performed after a certain
- number of usages (i.e. the qt_qregularexpression_optimize_after_use_count
- constant) unless the DontAutomaticallyOptimizeOption option is set on the
- QRegularExpression object, or anyhow by calling optimize() (which will pass
- ImmediateOptimizeOption).
+ It gets called when a pattern is recompiled by us (in compilePattern()),
+ under mutex protection.
*/
-void QRegularExpressionPrivate::optimizePattern(OptimizePatternOption option)
+void QRegularExpressionPrivate::optimizePattern()
{
Q_ASSERT(compiledPattern);
@@ -1157,11 +1134,6 @@ void QRegularExpressionPrivate::optimizePattern(OptimizePatternOption option)
if (!enableJit)
return;
- const QWriteLocker lock(&mutex);
-
- if ((option == LazyOptimizeOption) && (++usedCount != qt_qregularexpression_optimize_after_use_count))
- return;
-
pcre2_jit_compile_16(compiledPattern, PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD);
}
@@ -1267,22 +1239,12 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString
return priv;
}
- // skip optimizing and doing the actual matching if NoMatch type was requested
+ // skip doing the actual matching if NoMatch type was requested
if (matchType == QRegularExpression::NoMatch) {
priv->isValid = true;
return priv;
}
- if (!(patternOptions & QRegularExpression::DontAutomaticallyOptimizeOption)) {
- const OptimizePatternOption optimizePatternOption =
- (patternOptions & QRegularExpression::OptimizeOnFirstUsageOption)
- ? ImmediateOptimizeOption
- : LazyOptimizeOption;
-
- // this is mutex protected
- const_cast<QRegularExpressionPrivate *>(this)->optimizePattern(optimizePatternOption);
- }
-
int pcreOptions = convertToPcreOptions(matchOptions);
if (matchType == QRegularExpression::PartialPreferCompleteMatch)
@@ -1307,8 +1269,6 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString
int result;
- QReadLocker lock(&mutex);
-
if (!previousMatchWasEmpty) {
result = safe_pcre2_match_16(compiledPattern,
subjectUtf16, subjectLength,
@@ -1340,8 +1300,6 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString
}
}
- lock.unlock();
-
#ifdef QREGULAREXPRESSION_DEBUG
qDebug() << "Matching" << pattern << "against" << subject
<< "starting at" << subjectStart << "len" << subjectLength
@@ -1810,22 +1768,14 @@ QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QStringRef
/*!
\since 5.4
- Forces an immediate optimization of the pattern, including
- JIT-compiling it (if the JIT compiler is enabled).
-
- Patterns are normally optimized only after a certain number of usages.
- If you can predict that this QRegularExpression object is going to be
- used for several matches, it may be convenient to optimize it in
- advance by calling this function.
+ Compiles the pattern immediately, including JIT compiling it (if
+ the JIT is enabled) for optimization.
- \sa QRegularExpression::OptimizeOnFirstUsageOption
+ \sa isValid(), {Debugging Code that Uses QRegularExpression}
*/
void QRegularExpression::optimize() const
{
- if (!isValid()) // will compile the pattern
- return;
-
- d->optimizePattern(QRegularExpressionPrivate::ImmediateOptimizeOption);
+ d.data()->compilePattern();
}
/*!
@@ -1926,6 +1876,141 @@ QString QRegularExpression::escape(const QString &str)
}
/*!
+ \since 5.12
+
+ Returns a regular expression representation of the given glob \a pattern.
+ The transformation is targeting file path globbing, which means in particular
+ that path separators receive special treatment. This implies that it is not
+ just a basic translation from "*" to ".*".
+
+ \snippet code/src_corelib_tools_qregularexpression.cpp 31
+
+ \warning Unlike QRegExp, this implementation follows closely the definition
+ of wildcard for glob patterns:
+ \table
+ \row \li \b{c}
+ \li Any character represents itself apart from those mentioned
+ below. Thus \b{c} matches the character \e c.
+ \row \li \b{?}
+ \li Matches any single character. It is the same as
+ \b{.} in full regexps.
+ \row \li \b{*}
+ \li Matches zero or more of any characters. It is the
+ same as \b{.*} in full regexps.
+ \row \li \b{[abc]}
+ \li Matches one character given in the bracket.
+ \row \li \b{[a-c]}
+ \li Matches one character from the range given in the bracket.
+ \row \li \b{[!abc]}
+ \li Matches one character that is not given in the bracket. It is the
+ same as \b{[^abc]} in full regexp.
+ \row \li \b{[!a-c]}
+ \li Matches one character that is not from the range given in the
+ bracket. It is the same as \b{[^a-c]} in full regexp.
+ \endtable
+
+ \note The backslash (\\) character is \e not an escape char in this context.
+ In order to match one of the special characters, place it in square brackets
+ (for example, "[?]").
+
+ More information about the implementation can be found in:
+ \list
+ \li \l {https://en.wikipedia.org/wiki/Glob_(programming)} {The Wikipedia Glob article}
+ \li \c man 7 glob
+ \endlist
+
+ \sa escape()
+*/
+QString QRegularExpression::wildcardToRegularExpression(const QString &pattern)
+{
+ const int wclen = pattern.length();
+ QString rx;
+ rx.reserve(wclen + wclen / 16);
+ int i = 0;
+ const QChar *wc = pattern.unicode();
+
+#ifdef Q_OS_WIN
+ const QLatin1Char nativePathSeparator('\\');
+ const QLatin1String starEscape("[^/\\\\]*");
+ const QLatin1String questionMarkEscape("[^/\\\\]");
+#else
+ const QLatin1Char nativePathSeparator('/');
+ const QLatin1String starEscape("[^/]*");
+ const QLatin1String questionMarkEscape("[^/]");
+#endif
+
+ while (i < wclen) {
+ const QChar c = wc[i++];
+ switch (c.unicode()) {
+ case '*':
+ rx += starEscape;
+ break;
+ case '?':
+ rx += questionMarkEscape;
+ break;
+ case '\\':
+#ifdef Q_OS_WIN
+ case '/':
+ rx += QLatin1String("[/\\\\]");
+ break;
+#endif
+ case '$':
+ case '(':
+ case ')':
+ case '+':
+ case '.':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ rx += QLatin1Char('\\');
+ rx += c;
+ break;
+ case '[':
+ rx += c;
+ // Support for the [!abc] or [!a-c] syntax
+ if (i < wclen) {
+ if (wc[i] == QLatin1Char('!')) {
+ rx += QLatin1Char('^');
+ ++i;
+ }
+
+ if (i < wclen && wc[i] == QLatin1Char(']'))
+ rx += wc[i++];
+
+ while (i < wclen && wc[i] != QLatin1Char(']')) {
+ // The '/' appearing in a character class invalidates the
+ // regular expression parsing. It also concerns '\\' on
+ // Windows OS types.
+ if (wc[i] == QLatin1Char('/') || wc[i] == nativePathSeparator)
+ return rx;
+ if (wc[i] == QLatin1Char('\\'))
+ rx += QLatin1Char('\\');
+ rx += wc[i++];
+ }
+ }
+ break;
+ default:
+ rx += c;
+ break;
+ }
+ }
+
+ return rx;
+}
+
+/*!
+ \fn QRegularExpression::anchoredPattern(const QString &expression)
+
+ \since 5.12
+
+ Returns the expression wrapped between the \c{\A} and \c{\z} anchors to be
+ used for exact matching.
+
+ \sa {Porting from QRegExp's Exact Matching}
+*/
+
+/*!
\since 5.1
Constructs a valid, empty QRegularExpressionMatch object. The regular
@@ -2657,10 +2742,13 @@ QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOption
flags.append("DontCaptureOption|");
if (patternOptions & QRegularExpression::UseUnicodePropertiesOption)
flags.append("UseUnicodePropertiesOption|");
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
if (patternOptions & QRegularExpression::OptimizeOnFirstUsageOption)
flags.append("OptimizeOnFirstUsageOption|");
if (patternOptions & QRegularExpression::DontAutomaticallyOptimizeOption)
flags.append("DontAutomaticallyOptimizeOption|");
+QT_WARNING_POP
flags.chop(1);
}
diff --git a/src/corelib/tools/qregularexpression.h b/src/corelib/tools/qregularexpression.h
index 398fc9ec9c..f9e7029550 100644
--- a/src/corelib/tools/qregularexpression.h
+++ b/src/corelib/tools/qregularexpression.h
@@ -73,8 +73,8 @@ public:
InvertedGreedinessOption = 0x0010,
DontCaptureOption = 0x0020,
UseUnicodePropertiesOption = 0x0040,
- OptimizeOnFirstUsageOption = 0x0080,
- DontAutomaticallyOptimizeOption = 0x0100
+ OptimizeOnFirstUsageOption Q_DECL_ENUMERATOR_DEPRECATED_X("This option does not have any effect since Qt 5.12") = 0x0080,
+ DontAutomaticallyOptimizeOption Q_DECL_ENUMERATOR_DEPRECATED_X("This option does not have any effect since Qt 5.12") = 0x0100,
};
Q_DECLARE_FLAGS(PatternOptions, PatternOption)
@@ -141,6 +141,13 @@ public:
void optimize() const;
static QString escape(const QString &str);
+ static QString wildcardToRegularExpression(const QString &str);
+ static inline QString anchoredPattern(const QString &expression)
+ {
+ return QLatin1String("\\A(?:")
+ + expression
+ + QLatin1String(")\\z");
+ }
bool operator==(const QRegularExpression &re) const;
inline bool operator!=(const QRegularExpression &re) const { return !operator==(re); }
diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp
index eb7bdfe95c..59650ed2f7 100644
--- a/src/corelib/tools/qringbuffer.cpp
+++ b/src/corelib/tools/qringbuffer.cpp
@@ -312,12 +312,14 @@ qint64 QRingBuffer::peek(char *data, qint64 maxLength, qint64 pos) const
Q_ASSERT(maxLength >= 0 && pos >= 0);
qint64 readSoFar = 0;
- for (int i = 0; readSoFar < maxLength && i < buffers.size(); ++i) {
- qint64 blockLength = buffers[i].size();
+ for (const QRingChunk &chunk : buffers) {
+ if (readSoFar == maxLength)
+ break;
+ qint64 blockLength = chunk.size();
if (pos < blockLength) {
blockLength = qMin(blockLength - pos, maxLength - readSoFar);
- memcpy(data + readSoFar, buffers[i].data() + pos, blockLength);
+ memcpy(data + readSoFar, chunk.data() + pos, blockLength);
readSoFar += blockLength;
pos = 0;
} else {
diff --git a/src/corelib/tools/qscopeguard.h b/src/corelib/tools/qscopeguard.h
new file mode 100644
index 0000000000..31100fcabb
--- /dev/null
+++ b/src/corelib/tools/qscopeguard.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCOPEGUARD_H
+#define QSCOPEGUARD_H
+
+#include <QtCore/qglobal.h>
+
+
+QT_BEGIN_NAMESPACE
+
+
+template <typename F> class QScopeGuard;
+template <typename F> QScopeGuard<F> qScopeGuard(F f);
+
+template <typename F>
+class QScopeGuard
+{
+public:
+ QScopeGuard(QScopeGuard &&other) Q_DECL_NOEXCEPT
+ : m_func(std::move(other.m_func))
+ , m_invoke(other.m_invoke)
+ {
+ other.dismiss();
+ }
+
+ ~QScopeGuard()
+ {
+ if (m_invoke)
+ m_func();
+ }
+
+ void dismiss() Q_DECL_NOEXCEPT
+ {
+ m_invoke = false;
+ }
+
+private:
+ explicit QScopeGuard(F f) Q_DECL_NOEXCEPT
+ : m_func(std::move(f))
+ {
+ }
+
+ Q_DISABLE_COPY(QScopeGuard)
+
+ F m_func;
+ bool m_invoke = true;
+ friend QScopeGuard qScopeGuard<F>(F);
+};
+
+
+template <typename F>
+QScopeGuard<F> qScopeGuard(F f)
+{
+ return QScopeGuard<F>(std::move(f));
+}
+
+QT_END_NAMESPACE
+
+#endif // QSCOPEGUARD_H
diff --git a/src/corelib/tools/qscopeguard.qdoc b/src/corelib/tools/qscopeguard.qdoc
new file mode 100644
index 0000000000..7cbc3e9c7b
--- /dev/null
+++ b/src/corelib/tools/qscopeguard.qdoc
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscopeguard.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \fn const QScopeGuard<F> qScopeGuard(F f)
+ \inmodule QtCore
+ \brief The qScopeGuard function can be used to call a function at the end of the scope.
+ \since 5.12
+ \ingroup misc
+
+ QScopeGuard<F> is a class which sole purpose is to run a function F in its destructor.
+ This is useful for guaranteeing your cleanup code is executed whether the function is exited normally,
+ exited early by a return statement, or exited by an exception.
+
+ If F is a lambda then you cannot instantiate the template directly, therefore the qScopeGuard() helper
+ is provided and QScopeGuard<F> is made a private implementation detail.
+
+ Example usage is as follows:
+
+ \snippet code/src_corelib_tools_qscopeguard.cpp 0
+
+ \note Exceptions are not supported. The callable shouldn't throw when executed, copied or moved.
+
+ \sa QScopedValueRollback
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 7ded120ab7..6640c8486d 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -131,6 +131,7 @@ public:
inline iterator operator--(int) { iterator r = *this; --i; return r; }
inline iterator operator+(int j) const { return i + j; }
inline iterator operator-(int j) const { return i - j; }
+ friend inline iterator operator+(int j, iterator k) { return k + j; }
inline iterator &operator+=(int j) { i += j; return *this; }
inline iterator &operator-=(int j) { i -= j; return *this; }
};
@@ -165,6 +166,7 @@ public:
inline const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
inline const_iterator operator+(int j) const { return i + j; }
inline const_iterator operator-(int j) const { return i - j; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
inline const_iterator &operator+=(int j) { i += j; return *this; }
inline const_iterator &operator-=(int j) { i -= j; return *this; }
};
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index 780f2331a8..6930cb96a5 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -136,6 +136,18 @@ private:
T *d;
};
+template <class T> inline bool operator==(std::nullptr_t p1, const QSharedDataPointer<T> &p2)
+{
+ Q_UNUSED(p1);
+ return !p2;
+}
+
+template <class T> inline bool operator==(const QSharedDataPointer<T> &p1, std::nullptr_t p2)
+{
+ Q_UNUSED(p2);
+ return !p1;
+}
+
template <class T> class QExplicitlySharedDataPointer
{
public:
@@ -147,6 +159,7 @@ public:
inline T *operator->() const { return d; }
inline T *data() const { return d; }
inline const T *constData() const { return d; }
+ inline T *take() { T *x = d; d = nullptr; return x; }
inline void detach() { if (d && d->ref.load() != 1) detach_helper(); }
@@ -271,6 +284,18 @@ Q_INLINE_TEMPLATE QExplicitlySharedDataPointer<T>::QExplicitlySharedDataPointer(
: d(adata)
{ if (d) d->ref.ref(); }
+template <class T> inline bool operator==(std::nullptr_t p1, const QExplicitlySharedDataPointer<T> &p2)
+{
+ Q_UNUSED(p1);
+ return !p2;
+}
+
+template <class T> inline bool operator==(const QExplicitlySharedDataPointer<T> &p1, std::nullptr_t p2)
+{
+ Q_UNUSED(p2);
+ return !p1;
+}
+
template <class T>
Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer<T> &p1, QSharedDataPointer<T> &p2)
{ p1.swap(p2); }
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 25340f2d02..07a8b022bc 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -80,6 +80,43 @@
QT_BEGIN_NAMESPACE
+/*
+ * Use kdesdk/scripts/generate_string_table.pl to update the table below. Note
+ * we remove the terminating -1 that the script adds.
+ */
+
+// begin generated
+#if defined(Q_PROCESSOR_ARM)
+/* Data:
+ neon
+ crc32
+ */
+static const char features_string[] =
+ " neon\0"
+ " crc32\0"
+ "\0";
+static const int features_indices[] = { 0, 6 };
+#elif defined(Q_PROCESSOR_MIPS)
+/* Data:
+ dsp
+ dspr2
+*/
+static const char features_string[] =
+ " dsp\0"
+ " dspr2\0"
+ "\0";
+
+static const int features_indices[] = {
+ 0, 5
+};
+#elif defined(Q_PROCESSOR_X86)
+# include "qsimd_x86.cpp" // generated by util/x86simdgen
+#else
+static const char features_string[] = "";
+static const int features_indices[] = { };
+#endif
+// end generated
+
#if defined (Q_OS_NACL)
static inline uint detectProcessorFeatures()
{
@@ -153,7 +190,9 @@ static inline quint64 detectProcessorFeatures()
static int maxBasicCpuidSupported()
{
-#if defined(Q_CC_GNU)
+#if defined(Q_CC_EMSCRIPTEN)
+ return 6; // All features supported by Emscripten
+#elif defined(Q_CC_GNU)
qregisterint tmp1;
# if Q_PROCESSOR_X86 < 5
@@ -198,7 +237,7 @@ static int maxBasicCpuidSupported()
static void cpuidFeatures01(uint &ecx, uint &edx)
{
-#if defined(Q_CC_GNU)
+#if defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)
qregisterint tmp1;
asm ("xchg " PICreg", %2\n"
"cpuid\n"
@@ -215,6 +254,9 @@ static void cpuidFeatures01(uint &ecx, uint &edx)
__CPUID(1, info);
ecx = info[2];
edx = info[3];
+#else
+ Q_UNUSED(ecx);
+ Q_UNUSED(edx);
#endif
}
@@ -222,29 +264,32 @@ static void cpuidFeatures01(uint &ecx, uint &edx)
inline void __cpuidex(int info[4], int, __int64) { memset(info, 0, 4*sizeof(int));}
#endif
-static void cpuidFeatures07_00(uint &ebx, uint &ecx)
+static void cpuidFeatures07_00(uint &ebx, uint &ecx, uint &edx)
{
-#if defined(Q_CC_GNU)
+#if defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)
qregisteruint rbx; // in case it's 64-bit
qregisteruint rcx = 0;
+ qregisteruint rdx = 0;
asm ("xchg " PICreg", %0\n"
"cpuid\n"
"xchg " PICreg", %0\n"
- : "=&r" (rbx), "+&c" (rcx)
- : "a" (7)
- : "%edx");
+ : "=&r" (rbx), "+&c" (rcx), "+&d" (rdx)
+ : "a" (7));
ebx = rbx;
ecx = rcx;
+ edx = rdx;
#elif defined(Q_OS_WIN)
int info[4];
__cpuidex(info, 7, 0);
ebx = info[1];
ecx = info[2];
+ edx = info[3];
#elif defined(Q_CC_GHS)
unsigned int info[4];
__CPUIDEX(7, 0, info);
ebx = info[1];
ecx = info[2];
+ edx = info[3];
#endif
}
@@ -254,7 +299,7 @@ inline quint64 _xgetbv(__int64) { return 0; }
#endif
static void xgetbv(uint in, uint &eax, uint &edx)
{
-#if defined(Q_CC_GNU) || defined(Q_CC_GHS)
+#if (defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)) || defined(Q_CC_GHS)
asm (".byte 0x0F, 0x01, 0xD0" // xgetbv instruction
: "=a" (eax), "=d" (edx)
: "c" (in));
@@ -262,6 +307,10 @@ static void xgetbv(uint in, uint &eax, uint &edx)
quint64 result = _xgetbv(in);
eax = result;
edx = result >> 32;
+#else
+ Q_UNUSED(in);
+ Q_UNUSED(eax);
+ Q_UNUSED(edx);
#endif
}
@@ -282,13 +331,8 @@ static quint64 detectProcessorFeatures()
AVXState = XMM0_15 | YMM0_15Hi128,
AVX512State = AVXState | OpMask | ZMM0_15Hi256 | ZMM16_31
};
- static const quint64 AllAVX512 = (Q_UINT64_C(1) << CpuFeatureAVX512F) | (Q_UINT64_C(1) << CpuFeatureAVX512CD) |
- (Q_UINT64_C(1) << CpuFeatureAVX512ER) | (Q_UINT64_C(1) << CpuFeatureAVX512PF) |
- (Q_UINT64_C(1) << CpuFeatureAVX512BW) | (Q_UINT64_C(1) << CpuFeatureAVX512DQ) |
- (Q_UINT64_C(1) << CpuFeatureAVX512VL) |
- (Q_UINT64_C(1) << CpuFeatureAVX512IFMA) | (Q_UINT64_C(1) << CpuFeatureAVX512VBMI);
- static const quint64 AllAVX2 = (Q_UINT64_C(1) << CpuFeatureAVX2) | AllAVX512;
- static const quint64 AllAVX = (Q_UINT64_C(1) << CpuFeatureAVX) | AllAVX2;
+ static const quint64 AllAVX2 = CpuFeatureAVX2 | AllAVX512;
+ static const quint64 AllAVX = CpuFeatureAVX | AllAVX2;
quint64 features = 0;
int cpuidLevel = maxBasicCpuidSupported();
@@ -299,52 +343,33 @@ static quint64 detectProcessorFeatures()
Q_ASSERT(cpuidLevel >= 1);
#endif
- uint cpuid01ECX = 0, cpuid01EDX = 0;
- cpuidFeatures01(cpuid01ECX, cpuid01EDX);
-
- // the low 32-bits of features is cpuid01ECX
- // note: we need to check OS support for saving the AVX register state
- features = cpuid01ECX;
-
-#if defined(Q_PROCESSOR_X86_32)
- // x86 might not have SSE2 support
- if (cpuid01EDX & (1u << 26))
- features |= Q_UINT64_C(1) << CpuFeatureSSE2;
- else
- features &= ~(Q_UINT64_C(1) << CpuFeatureSSE2);
- // we should verify that the OS enabled saving of the SSE state...
-#else
- // x86-64 or x32
- features |= Q_UINT64_C(1) << CpuFeatureSSE2;
-#endif
+ uint results[X86CpuidMaxLeaf] = {};
+ cpuidFeatures01(results[Leaf1ECX], results[Leaf1EDX]);
+ if (cpuidLevel >= 7)
+ cpuidFeatures07_00(results[Leaf7_0EBX], results[Leaf7_0ECX], results[Leaf7_0EDX]);
+
+ // populate our feature list
+ for (uint i = 0; i < sizeof(x86_locators) / sizeof(x86_locators[0]); ++i) {
+ uint word = x86_locators[i] / 32;
+ uint bit = 1U << (x86_locators[i] % 32);
+ quint64 feature = Q_UINT64_C(1) << (i + 1);
+ if (results[word] & bit)
+ features |= feature;
+ }
+ // now check the AVX state
uint xgetbvA = 0, xgetbvD = 0;
- if (cpuid01ECX & (1u << 27)) {
+ if (results[Leaf1ECX] & (1u << 27)) {
// XGETBV enabled
xgetbv(0, xgetbvA, xgetbvD);
}
- uint cpuid0700EBX = 0;
- uint cpuid0700ECX = 0;
- if (cpuidLevel >= 7) {
- cpuidFeatures07_00(cpuid0700EBX, cpuid0700ECX);
-
- // the high 32-bits of features is cpuid0700EBX
- features |= quint64(cpuid0700EBX) << 32;
- }
-
if ((xgetbvA & AVXState) != AVXState) {
// support for YMM registers is disabled, disable all AVX
features &= ~AllAVX;
} else if ((xgetbvA & AVX512State) != AVX512State) {
// support for ZMM registers or mask registers is disabled, disable all AVX512
features &= ~AllAVX512;
- } else {
- // this feature is out of order
- if (cpuid0700ECX & (1u << 1))
- features |= Q_UINT64_C(1) << CpuFeatureAVX512VBMI;
- else
- features &= ~(Q_UINT64_C(1) << CpuFeatureAVX512VBMI);
}
return features;
@@ -493,152 +518,6 @@ static inline uint detectProcessorFeatures()
}
#endif
-/*
- * Use kdesdk/scripts/generate_string_table.pl to update the table below. Note
- * that the x86 version has a lot of blanks that must be kept and that the
- * offset table's type is changed to make the table smaller. We also remove the
- * terminating -1 that the script adds.
- */
-
-// begin generated
-#if defined(Q_PROCESSOR_ARM)
-/* Data:
- neon
- crc32
- */
-static const char features_string[] =
- " neon\0"
- " crc32\0"
- "\0";
-static const int features_indices[] = { 0, 6 };
-#elif defined(Q_PROCESSOR_MIPS)
-/* Data:
- dsp
- dspr2
-*/
-static const char features_string[] =
- " dsp\0"
- " dspr2\0"
- "\0";
-
-static const int features_indices[] = {
- 0, 5
-};
-#elif defined(Q_PROCESSOR_X86)
-/* Data:
- sse3
- sse2
- avx512vbmi
-
-
-
-
-
-
- ssse3
-
-
- fma
- cmpxchg16b
-
-
-
-
-
- sse4.1
- sse4.2
-
- movbe
- popcnt
-
- aes
-
-
- avx
- f16c
- rdrand
-
-
-
-
- bmi
- hle
- avx2
-
-
- bmi2
-
-
- rtm
-
-
-
-
- avx512f
- avx512dq
- rdseed
-
-
- avx512ifma
-
-
-
-
- avx512pf
- avx512er
- avx512cd
- sha
- avx512bw
- avx512vl
- */
-static const char features_string[] =
- " sse3\0"
- " sse2\0"
- " avx512vbmi\0"
- " ssse3\0"
- " fma\0"
- " cmpxchg16b\0"
- " sse4.1\0"
- " sse4.2\0"
- " movbe\0"
- " popcnt\0"
- " aes\0"
- " avx\0"
- " f16c\0"
- " rdrand\0"
- " bmi\0"
- " hle\0"
- " avx2\0"
- " bmi2\0"
- " rtm\0"
- " avx512f\0"
- " avx512dq\0"
- " rdseed\0"
- " avx512ifma\0"
- " avx512pf\0"
- " avx512er\0"
- " avx512cd\0"
- " sha\0"
- " avx512bw\0"
- " avx512vl\0"
- "\0";
-
-static const quint8 features_indices[] = {
- 0, 6, 12, 5, 5, 5, 5, 5,
- 5, 24, 5, 5, 31, 36, 5, 5,
- 5, 5, 5, 48, 56, 5, 64, 71,
- 5, 79, 5, 5, 84, 89, 95, 5,
- 5, 5, 5, 103, 108, 113, 5, 5,
- 119, 5, 5, 125, 5, 5, 5, 5,
- 130, 139, 149, 5, 5, 157, 5, 5,
- 5, 5, 169, 179, 189, 199, 204, 214
-};
-#else
-static const char features_string[] = "";
-static const int features_indices[] = { };
-#endif
-// end generated
-
static const int features_count = (sizeof features_indices) / (sizeof features_indices[0]);
// record what CPU features were enabled by default in this Qt build
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 18684caefb..9f1321df94 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -232,32 +232,48 @@
# define __RDRND__ 1
# endif
-#define QT_FUNCTION_TARGET_STRING_SSE2 "sse2"
-#define QT_FUNCTION_TARGET_STRING_SSE3 "sse3"
-#define QT_FUNCTION_TARGET_STRING_SSSE3 "ssse3"
-#define QT_FUNCTION_TARGET_STRING_SSE4_1 "sse4.1"
-#define QT_FUNCTION_TARGET_STRING_SSE4_2 "sse4.2"
-#define QT_FUNCTION_TARGET_STRING_AVX "avx"
-#define QT_FUNCTION_TARGET_STRING_AVX2 "avx2"
-#define QT_FUNCTION_TARGET_STRING_AVX512F "avx512f"
-#define QT_FUNCTION_TARGET_STRING_AVX512CD "avx512cd"
-#define QT_FUNCTION_TARGET_STRING_AVX512ER "avx512er"
-#define QT_FUNCTION_TARGET_STRING_AVX512PF "avx512pf"
-#define QT_FUNCTION_TARGET_STRING_AVX512BW "avx512bw"
-#define QT_FUNCTION_TARGET_STRING_AVX512DQ "avx512dq"
-#define QT_FUNCTION_TARGET_STRING_AVX512VL "avx512vl"
-#define QT_FUNCTION_TARGET_STRING_AVX512IFMA "avx512ifma"
-#define QT_FUNCTION_TARGET_STRING_AVX512VBMI "avx512vbmi"
-
-#define QT_FUNCTION_TARGET_STRING_AES "aes,sse4.2"
-#define QT_FUNCTION_TARGET_STRING_PCLMUL "pclmul,sse4.2"
-#define QT_FUNCTION_TARGET_STRING_POPCNT "popcnt"
-#define QT_FUNCTION_TARGET_STRING_F16C "f16c,avx"
-#define QT_FUNCTION_TARGET_STRING_RDRND "rdrnd"
-#define QT_FUNCTION_TARGET_STRING_BMI "bmi"
-#define QT_FUNCTION_TARGET_STRING_BMI2 "bmi2"
-#define QT_FUNCTION_TARGET_STRING_RDSEED "rdseed"
-#define QT_FUNCTION_TARGET_STRING_SHA "sha"
+# if defined(__BMI__) && !defined(__BMI2__) && defined(Q_CC_INTEL)
+// BMI2 instructions:
+// All processors that support BMI support BMI2 (and AVX2)
+// (but neither MSVC nor the Intel compiler define this macro)
+# define __BMI2__ 1
+# endif
+
+# include "qsimd_x86_p.h"
+
+// Haswell sub-architecture
+//
+// The Intel Core 4th generation was codenamed "Haswell" and introduced AVX2,
+// BMI1, BMI2, FMA, LZCNT, MOVBE, which makes it a good divider for a
+// sub-target for us. The first AMD processor with AVX2 support (Zen) has the
+// same features.
+//
+// macOS's fat binaries support the "x86_64h" sub-architecture and the GNU libc
+// ELF loader also supports a "haswell/" subdir (e.g., /usr/lib/haswell).
+# define QT_FUNCTION_TARGET_STRING_ARCH_HASWELL "arch=haswell"
+# if defined(__AVX2__) && defined(__BMI__) && defined(__BMI2__) && defined(__F16C__) && \
+ defined(__FMA__) && defined(__LZCNT__) && defined(__RDRND__)
+# define __haswell__ 1
+# endif
+
+// This constant does not include all CPU features found in a Haswell, only
+// those that we'd have optimized code for.
+// Note: must use Q_CONSTEXPR here, as this file may be compiled in C mode.
+QT_BEGIN_NAMESPACE
+static const quint64 CpuFeatureArchHaswell = 0
+ | CpuFeatureSSE2
+ | CpuFeatureSSE3
+ | CpuFeatureSSSE3
+ | CpuFeatureSSE4_1
+ | CpuFeatureSSE4_2
+ | CpuFeatureFMA
+ | CpuFeaturePOPCNT
+ | CpuFeatureAVX
+ | CpuFeatureF16C
+ | CpuFeatureAVX2
+ | CpuFeatureBMI
+ | CpuFeatureBMI2;
+QT_END_NAMESPACE
#endif /* Q_PROCESSOR_X86 */
@@ -292,148 +308,36 @@
QT_BEGIN_NAMESPACE
+#ifndef Q_PROCESSOR_X86
enum CPUFeatures {
#if defined(Q_PROCESSOR_ARM)
- CpuFeatureNEON = 0,
+ CpuFeatureNEON = 2,
CpuFeatureARM_NEON = CpuFeatureNEON,
- CpuFeatureCRC32 = 1,
+ CpuFeatureCRC32 = 4,
#elif defined(Q_PROCESSOR_MIPS)
- CpuFeatureDSP = 0,
- CpuFeatureDSPR2 = 1,
-#elif defined(Q_PROCESSOR_X86)
- // The order of the flags is jumbled so it matches most closely the bits in CPUID
- // Out of order:
- CpuFeatureSSE2 = 1, // uses the bit for PCLMULQDQ
- // in level 1, ECX
- CpuFeatureSSE3 = (0 + 0),
- CpuFeatureSSSE3 = (0 + 9),
- CpuFeatureSSE4_1 = (0 + 19),
- CpuFeatureSSE4_2 = (0 + 20),
- CpuFeatureMOVBE = (0 + 22),
- CpuFeaturePOPCNT = (0 + 23),
- CpuFeatureAES = (0 + 25),
- CpuFeatureAVX = (0 + 28),
- CpuFeatureF16C = (0 + 29),
- CpuFeatureRDRND = (0 + 30),
- // 31 is always zero and we've used it for the QSimdInitialized
-
- // in level 7, leaf 0, EBX
- CpuFeatureBMI = (32 + 3),
- CpuFeatureHLE = (32 + 4),
- CpuFeatureAVX2 = (32 + 5),
- CpuFeatureBMI2 = (32 + 8),
- CpuFeatureRTM = (32 + 11),
- CpuFeatureAVX512F = (32 + 16),
- CpuFeatureAVX512DQ = (32 + 17),
- CpuFeatureRDSEED = (32 + 18),
- CpuFeatureAVX512IFMA = (32 + 21),
- CpuFeatureAVX512PF = (32 + 26),
- CpuFeatureAVX512ER = (32 + 27),
- CpuFeatureAVX512CD = (32 + 28),
- CpuFeatureSHA = (32 + 29),
- CpuFeatureAVX512BW = (32 + 30),
- CpuFeatureAVX512VL = (32 + 31),
-
- // in level 7, leaf 0, ECX (out of order, for now)
- CpuFeatureAVX512VBMI = 2, // uses the bit for DTES64
+ CpuFeatureDSP = 2,
+ CpuFeatureDSPR2 = 4,
#endif
// used only to indicate that the CPU detection was initialised
- QSimdInitialized = 0x80000000
+ QSimdInitialized = 1
};
static const quint64 qCompilerCpuFeatures = 0
-#if defined __SHA__
- | (Q_UINT64_C(1) << CpuFeatureSHA)
-#endif
-#if defined __AES__
- | (Q_UINT64_C(1) << CpuFeatureAES)
-#endif
-#if defined __RTM__
- | (Q_UINT64_C(1) << CpuFeatureRTM)
-#endif
-#ifdef __RDRND__
- | (Q_UINT64_C(1) << CpuFeatureRDRND)
-#endif
-#ifdef __RDSEED__
- | (Q_UINT64_C(1) << CpuFeatureRDSEED)
-#endif
-#if defined __BMI__
- | (Q_UINT64_C(1) << CpuFeatureBMI)
-#endif
-#if defined __BMI2__
- | (Q_UINT64_C(1) << CpuFeatureBMI2)
-#endif
-#if defined __F16C__
- | (Q_UINT64_C(1) << CpuFeatureF16C)
-#endif
-#if defined __POPCNT__
- | (Q_UINT64_C(1) << CpuFeaturePOPCNT)
-#endif
-#if defined __MOVBE__ // GCC and Clang don't seem to define this
- | (Q_UINT64_C(1) << CpuFeatureMOVBE)
-#endif
-#if defined __AVX512F__
- | (Q_UINT64_C(1) << CpuFeatureAVX512F)
-#endif
-#if defined __AVX512CD__
- | (Q_UINT64_C(1) << CpuFeatureAVX512CD)
-#endif
-#if defined __AVX512ER__
- | (Q_UINT64_C(1) << CpuFeatureAVX512ER)
-#endif
-#if defined __AVX512PF__
- | (Q_UINT64_C(1) << CpuFeatureAVX512PF)
-#endif
-#if defined __AVX512BW__
- | (Q_UINT64_C(1) << CpuFeatureAVX512BW)
-#endif
-#if defined __AVX512DQ__
- | (Q_UINT64_C(1) << CpuFeatureAVX512DQ)
-#endif
-#if defined __AVX512VL__
- | (Q_UINT64_C(1) << CpuFeatureAVX512VL)
-#endif
-#if defined __AVX512IFMA__
- | (Q_UINT64_C(1) << CpuFeatureAVX512IFMA)
-#endif
-#if defined __AVX512VBMI__
- | (Q_UINT64_C(1) << CpuFeatureAVX512VBMI)
-#endif
-#if defined __AVX2__
- | (Q_UINT64_C(1) << CpuFeatureAVX2)
-#endif
-#if defined __AVX__
- | (Q_UINT64_C(1) << CpuFeatureAVX)
-#endif
-#if defined __SSE4_2__
- | (Q_UINT64_C(1) << CpuFeatureSSE4_2)
-#endif
-#if defined __SSE4_1__
- | (Q_UINT64_C(1) << CpuFeatureSSE4_1)
-#endif
-#if defined __SSSE3__
- | (Q_UINT64_C(1) << CpuFeatureSSSE3)
-#endif
-#if defined __SSE3__
- | (Q_UINT64_C(1) << CpuFeatureSSE3)
-#endif
-#if defined __SSE2__
- | (Q_UINT64_C(1) << CpuFeatureSSE2)
-#endif
#if defined __ARM_NEON__
- | (Q_UINT64_C(1) << CpuFeatureNEON)
+ | CpuFeatureNEON
#endif
#if defined __ARM_FEATURE_CRC32
- | (Q_UINT64_C(1) << CpuFeatureCRC32)
+ | CpuFeatureCRC32
#endif
#if defined __mips_dsp
- | (Q_UINT64_C(1) << CpuFeatureDSP)
+ | CpuFeatureDSP
#endif
#if defined __mips_dspr2
- | (Q_UINT64_C(1) << CpuFeatureDSPR2)
+ | CpuFeatureDSPR2
#endif
;
+#endif
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
extern Q_CORE_EXPORT QBasicAtomicInteger<quint64> qt_cpu_features[1];
@@ -459,8 +363,8 @@ static inline quint64 qCpuFeatures()
return features;
}
-#define qCpuHasFeature(feature) ((qCompilerCpuFeatures & (Q_UINT64_C(1) << CpuFeature ## feature)) \
- || (qCpuFeatures() & (Q_UINT64_C(1) << CpuFeature ## feature)))
+#define qCpuHasFeature(feature) (((qCompilerCpuFeatures & CpuFeature ## feature) == CpuFeature ## feature) \
+ || ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature))
#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \
for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i)
diff --git a/src/corelib/tools/qsimd_x86.cpp b/src/corelib/tools/qsimd_x86.cpp
new file mode 100644
index 0000000000..509af464b2
--- /dev/null
+++ b/src/corelib/tools/qsimd_x86.cpp
@@ -0,0 +1,116 @@
+// This is a generated file. DO NOT EDIT.
+// Please see util/x86simdgen/generate.pl
+#include "qsimd_p.h"
+
+static const char features_string[] =
+ " sse2\0"
+ " sse3\0"
+ " ssse3\0"
+ " fma\0"
+ " sse4.1\0"
+ " sse4.2\0"
+ " movbe\0"
+ " popcnt\0"
+ " aes\0"
+ " avx\0"
+ " f16c\0"
+ " rdrnd\0"
+ " bmi\0"
+ " hle\0"
+ " avx2\0"
+ " bmi2\0"
+ " rtm\0"
+ " avx512f\0"
+ " avx512dq\0"
+ " rdseed\0"
+ " avx512ifma\0"
+ " avx512pf\0"
+ " avx512er\0"
+ " avx512cd\0"
+ " sha\0"
+ " avx512bw\0"
+ " avx512vl\0"
+ " avx512vbmi\0"
+ " avx512vbmi2\0"
+ " gfni\0"
+ " vaes\0"
+ " avx512vnni\0"
+ " avx512bitalg\0"
+ " avx512vpopcntdq\0"
+ " avx5124nniw\0"
+ " avx5124fmaps\0"
+ "\0";
+
+static const quint16 features_indices[] = {
+ 306, 0, 6, 12, 19, 24, 32, 40,
+ 47, 55, 60, 65, 71, 78, 83, 88,
+ 94, 100, 105, 114, 124, 132, 144, 154,
+ 164, 174, 179, 189, 199, 211, 224, 230,
+ 236, 248, 262, 279, 292
+};
+
+enum X86CpuidLeaves {
+ Leaf1ECX,
+ Leaf1EDX,
+ Leaf7_0EBX,
+ Leaf7_0ECX,
+ Leaf7_0EDX,
+ X86CpuidMaxLeaf
+};
+
+static const quint8 x86_locators[] = {
+ Leaf1EDX*32 + 26, // sse2
+ Leaf1ECX*32 + 0, // sse3
+ Leaf1ECX*32 + 9, // ssse3
+ Leaf1ECX*32 + 12, // fma
+ Leaf1ECX*32 + 19, // sse4.1
+ Leaf1ECX*32 + 20, // sse4.2
+ Leaf1ECX*32 + 22, // movbe
+ Leaf1ECX*32 + 23, // popcnt
+ Leaf1ECX*32 + 25, // aes
+ Leaf1ECX*32 + 28, // avx
+ Leaf1ECX*32 + 29, // f16c
+ Leaf1ECX*32 + 30, // rdrnd
+ Leaf7_0EBX*32 + 3, // bmi
+ Leaf7_0EBX*32 + 4, // hle
+ Leaf7_0EBX*32 + 5, // avx2
+ Leaf7_0EBX*32 + 8, // bmi2
+ Leaf7_0EBX*32 + 11, // rtm
+ Leaf7_0EBX*32 + 16, // avx512f
+ Leaf7_0EBX*32 + 17, // avx512dq
+ Leaf7_0EBX*32 + 18, // rdseed
+ Leaf7_0EBX*32 + 21, // avx512ifma
+ Leaf7_0EBX*32 + 26, // avx512pf
+ Leaf7_0EBX*32 + 27, // avx512er
+ Leaf7_0EBX*32 + 28, // avx512cd
+ Leaf7_0EBX*32 + 29, // sha
+ Leaf7_0EBX*32 + 30, // avx512bw
+ Leaf7_0EBX*32 + 31, // avx512vl
+ Leaf7_0ECX*32 + 1, // avx512vbmi
+ Leaf7_0ECX*32 + 6, // avx512vbmi2
+ Leaf7_0ECX*32 + 8, // gfni
+ Leaf7_0ECX*32 + 9, // vaes
+ Leaf7_0ECX*32 + 11, // avx512vnni
+ Leaf7_0ECX*32 + 12, // avx512bitalg
+ Leaf7_0ECX*32 + 14, // avx512vpopcntdq
+ Leaf7_0EDX*32 + 2, // avx5124nniw
+ Leaf7_0EDX*32 + 3 // avx5124fmaps
+};
+
+// List of AVX512 features (see detectProcessorFeatures())
+static const quint64 AllAVX512 = 0
+ | CpuFeatureAVX512F
+ | CpuFeatureAVX512DQ
+ | CpuFeatureAVX512IFMA
+ | CpuFeatureAVX512PF
+ | CpuFeatureAVX512ER
+ | CpuFeatureAVX512CD
+ | CpuFeatureAVX512BW
+ | CpuFeatureAVX512VL
+ | CpuFeatureAVX512VBMI
+ | CpuFeatureAVX512VBMI2
+ | CpuFeatureAVX512VNNI
+ | CpuFeatureAVX512BITALG
+ | CpuFeatureAVX512VPOPCNTDQ
+ | CpuFeatureAVX5124NNIW
+ | CpuFeatureAVX5124FMAPS;
diff --git a/src/corelib/tools/qsimd_x86_p.h b/src/corelib/tools/qsimd_x86_p.h
new file mode 100644
index 0000000000..2434e2b797
--- /dev/null
+++ b/src/corelib/tools/qsimd_x86_p.h
@@ -0,0 +1,222 @@
+// This is a generated file. DO NOT EDIT.
+// Please see util/x86simdgen/generate.pl
+#ifndef QSIMD_P_H
+# error "Please include <private/qsimd_p.h> instead"
+#endif
+#ifndef QSIMD_X86_P_H
+#define QSIMD_X86_P_H
+
+#include "qsimd_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.
+//
+
+QT_BEGIN_NAMESPACE
+
+// used only to indicate that the CPU detection was initialized
+#define QSimdInitialized (Q_UINT64_C(1) << 0)
+
+// in CPUID Leaf 1, EDX:
+#define CpuFeatureSSE2 (Q_UINT64_C(1) << 1)
+#define QT_FUNCTION_TARGET_STRING_SSE2 "sse2"
+
+// in CPUID Leaf 1, ECX:
+#define CpuFeatureSSE3 (Q_UINT64_C(1) << 2)
+#define QT_FUNCTION_TARGET_STRING_SSE3 "sse3"
+#define CpuFeatureSSSE3 (Q_UINT64_C(1) << 3)
+#define QT_FUNCTION_TARGET_STRING_SSSE3 "ssse3"
+#define CpuFeatureFMA (Q_UINT64_C(1) << 4)
+#define QT_FUNCTION_TARGET_STRING_FMA "fma"
+#define CpuFeatureSSE4_1 (Q_UINT64_C(1) << 5)
+#define QT_FUNCTION_TARGET_STRING_SSE4_1 "sse4.1"
+#define CpuFeatureSSE4_2 (Q_UINT64_C(1) << 6)
+#define QT_FUNCTION_TARGET_STRING_SSE4_2 "sse4.2"
+#define CpuFeatureMOVBE (Q_UINT64_C(1) << 7)
+#define QT_FUNCTION_TARGET_STRING_MOVBE "movbe"
+#define CpuFeaturePOPCNT (Q_UINT64_C(1) << 8)
+#define QT_FUNCTION_TARGET_STRING_POPCNT "popcnt"
+#define CpuFeatureAES (Q_UINT64_C(1) << 9)
+#define QT_FUNCTION_TARGET_STRING_AES "aes,sse4.2"
+#define CpuFeatureAVX (Q_UINT64_C(1) << 10)
+#define QT_FUNCTION_TARGET_STRING_AVX "avx"
+#define CpuFeatureF16C (Q_UINT64_C(1) << 11)
+#define QT_FUNCTION_TARGET_STRING_F16C "f16c"
+#define CpuFeatureRDRND (Q_UINT64_C(1) << 12)
+#define QT_FUNCTION_TARGET_STRING_RDRND "rdrnd"
+
+// in CPUID Leaf 7, Sub-leaf 0, EBX:
+#define CpuFeatureBMI (Q_UINT64_C(1) << 13)
+#define QT_FUNCTION_TARGET_STRING_BMI "bmi"
+#define CpuFeatureHLE (Q_UINT64_C(1) << 14)
+#define QT_FUNCTION_TARGET_STRING_HLE "hle"
+#define CpuFeatureAVX2 (Q_UINT64_C(1) << 15)
+#define QT_FUNCTION_TARGET_STRING_AVX2 "avx2"
+#define CpuFeatureBMI2 (Q_UINT64_C(1) << 16)
+#define QT_FUNCTION_TARGET_STRING_BMI2 "bmi2"
+#define CpuFeatureRTM (Q_UINT64_C(1) << 17)
+#define QT_FUNCTION_TARGET_STRING_RTM "rtm"
+#define CpuFeatureAVX512F (Q_UINT64_C(1) << 18)
+#define QT_FUNCTION_TARGET_STRING_AVX512F "avx512f"
+#define CpuFeatureAVX512DQ (Q_UINT64_C(1) << 19)
+#define QT_FUNCTION_TARGET_STRING_AVX512DQ "avx512dq"
+#define CpuFeatureRDSEED (Q_UINT64_C(1) << 20)
+#define QT_FUNCTION_TARGET_STRING_RDSEED "rdseed"
+#define CpuFeatureAVX512IFMA (Q_UINT64_C(1) << 21)
+#define QT_FUNCTION_TARGET_STRING_AVX512IFMA "avx512ifma"
+#define CpuFeatureAVX512PF (Q_UINT64_C(1) << 22)
+#define QT_FUNCTION_TARGET_STRING_AVX512PF "avx512pf"
+#define CpuFeatureAVX512ER (Q_UINT64_C(1) << 23)
+#define QT_FUNCTION_TARGET_STRING_AVX512ER "avx512er"
+#define CpuFeatureAVX512CD (Q_UINT64_C(1) << 24)
+#define QT_FUNCTION_TARGET_STRING_AVX512CD "avx512cd"
+#define CpuFeatureSHA (Q_UINT64_C(1) << 25)
+#define QT_FUNCTION_TARGET_STRING_SHA "sha"
+#define CpuFeatureAVX512BW (Q_UINT64_C(1) << 26)
+#define QT_FUNCTION_TARGET_STRING_AVX512BW "avx512bw"
+#define CpuFeatureAVX512VL (Q_UINT64_C(1) << 27)
+#define QT_FUNCTION_TARGET_STRING_AVX512VL "avx512vl"
+
+// in CPUID Leaf 7, Sub-leaf 0, ECX:
+#define CpuFeatureAVX512VBMI (Q_UINT64_C(1) << 28)
+#define QT_FUNCTION_TARGET_STRING_AVX512VBMI "avx512vbmi"
+#define CpuFeatureAVX512VBMI2 (Q_UINT64_C(1) << 29)
+#define QT_FUNCTION_TARGET_STRING_AVX512VBMI2 "avx512vbmi2"
+#define CpuFeatureGFNI (Q_UINT64_C(1) << 30)
+#define QT_FUNCTION_TARGET_STRING_GFNI "gfni"
+#define CpuFeatureVAES (Q_UINT64_C(1) << 31)
+#define QT_FUNCTION_TARGET_STRING_VAES "vaes"
+#define CpuFeatureAVX512VNNI (Q_UINT64_C(1) << 32)
+#define QT_FUNCTION_TARGET_STRING_AVX512VNNI "avx512vnni"
+#define CpuFeatureAVX512BITALG (Q_UINT64_C(1) << 33)
+#define QT_FUNCTION_TARGET_STRING_AVX512BITALG "avx512bitalg"
+#define CpuFeatureAVX512VPOPCNTDQ (Q_UINT64_C(1) << 34)
+#define QT_FUNCTION_TARGET_STRING_AVX512VPOPCNTDQ "avx512vpopcntdq"
+
+// in CPUID Leaf 7, Sub-leaf 0, EDX:
+#define CpuFeatureAVX5124NNIW (Q_UINT64_C(1) << 35)
+#define QT_FUNCTION_TARGET_STRING_AVX5124NNIW "avx5124nniw"
+#define CpuFeatureAVX5124FMAPS (Q_UINT64_C(1) << 36)
+#define QT_FUNCTION_TARGET_STRING_AVX5124FMAPS "avx5124fmaps"
+
+static const quint64 qCompilerCpuFeatures = 0
+#ifdef __SSE2__
+ | CpuFeatureSSE2
+#endif
+#ifdef __SSE3__
+ | CpuFeatureSSE3
+#endif
+#ifdef __SSSE3__
+ | CpuFeatureSSSE3
+#endif
+#ifdef __FMA__
+ | CpuFeatureFMA
+#endif
+#ifdef __SSE4_1__
+ | CpuFeatureSSE4_1
+#endif
+#ifdef __SSE4_2__
+ | CpuFeatureSSE4_2
+#endif
+#ifdef __MOVBE__
+ | CpuFeatureMOVBE
+#endif
+#ifdef __POPCNT__
+ | CpuFeaturePOPCNT
+#endif
+#ifdef __AES__
+ | CpuFeatureAES
+#endif
+#ifdef __AVX__
+ | CpuFeatureAVX
+#endif
+#ifdef __F16C__
+ | CpuFeatureF16C
+#endif
+#ifdef __RDRND__
+ | CpuFeatureRDRND
+#endif
+#ifdef __BMI__
+ | CpuFeatureBMI
+#endif
+#ifdef __HLE__
+ | CpuFeatureHLE
+#endif
+#ifdef __AVX2__
+ | CpuFeatureAVX2
+#endif
+#ifdef __BMI2__
+ | CpuFeatureBMI2
+#endif
+#ifdef __RTM__
+ | CpuFeatureRTM
+#endif
+#ifdef __AVX512F__
+ | CpuFeatureAVX512F
+#endif
+#ifdef __AVX512DQ__
+ | CpuFeatureAVX512DQ
+#endif
+#ifdef __RDSEED__
+ | CpuFeatureRDSEED
+#endif
+#ifdef __AVX512IFMA__
+ | CpuFeatureAVX512IFMA
+#endif
+#ifdef __AVX512PF__
+ | CpuFeatureAVX512PF
+#endif
+#ifdef __AVX512ER__
+ | CpuFeatureAVX512ER
+#endif
+#ifdef __AVX512CD__
+ | CpuFeatureAVX512CD
+#endif
+#ifdef __SHA__
+ | CpuFeatureSHA
+#endif
+#ifdef __AVX512BW__
+ | CpuFeatureAVX512BW
+#endif
+#ifdef __AVX512VL__
+ | CpuFeatureAVX512VL
+#endif
+#ifdef __AVX512VBMI__
+ | CpuFeatureAVX512VBMI
+#endif
+#ifdef __AVX512VBMI2__
+ | CpuFeatureAVX512VBMI2
+#endif
+#ifdef __GFNI__
+ | CpuFeatureGFNI
+#endif
+#ifdef __VAES__
+ | CpuFeatureVAES
+#endif
+#ifdef __AVX512VNNI__
+ | CpuFeatureAVX512VNNI
+#endif
+#ifdef __AVX512BITALG__
+ | CpuFeatureAVX512BITALG
+#endif
+#ifdef __AVX512VPOPCNTDQ__
+ | CpuFeatureAVX512VPOPCNTDQ
+#endif
+#ifdef __AVX5124NNIW__
+ | CpuFeatureAVX5124NNIW
+#endif
+#ifdef __AVX5124FMAPS__
+ | CpuFeatureAVX5124FMAPS
+#endif
+ ;
+
+QT_END_NAMESPACE
+
+#endif // QSIMD_X86_P_H
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 82a065efc0..b3ed62982e 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -227,10 +227,8 @@ template <uint MaxCount> struct UnrollTailLoop
return returnIfExited;
bool check = loopCheck(i);
- if (check) {
- const RetType &retval = returnIfFailed(i);
- return retval;
- }
+ if (check)
+ return returnIfFailed(i);
return UnrollTailLoop<MaxCount - 1>::exec(count - 1, returnIfExited, loopCheck, returnIfFailed, i + 1);
}
@@ -253,119 +251,265 @@ inline RetType UnrollTailLoop<0>::exec(Number, RetType returnIfExited, Functor1,
}
#endif
+/*!
+ * \internal
+ *
+ * Searches for character \a \c in the string \a str and returns a pointer to
+ * it. Unlike strchr() and wcschr() (but like glibc's strchrnul()), if the
+ * character is not found, this function returns a pointer to the end of the
+ * string -- that is, \c{str.end()}.
+ */
+const ushort *QtPrivate::qustrchr(QStringView str, ushort c) noexcept
+{
+ const ushort *n = reinterpret_cast<const ushort *>(str.begin());
+ const ushort *e = reinterpret_cast<const ushort *>(str.end());
+
+#ifdef __SSE2__
+ __m128i mch = _mm_set1_epi32(c | (c << 16));
+
+ // we're going to read n[0..7] (16 bytes)
+ for (const ushort *next = n + 8; next <= e; n = next, next += 8) {
+ __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(n));
+ __m128i result = _mm_cmpeq_epi16(data, mch);
+ uint mask = _mm_movemask_epi8(result);
+ if (ushort(mask)) {
+ // found a match
+ return n + (qCountTrailingZeroBits(mask) >> 1);
+ }
+ }
+
+# if !defined(__OPTIMIZE_SIZE__)
+ // we're going to read n[0..3] (8 bytes)
+ if (e - n > 3) {
+ __m128i data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(n));
+ __m128i result = _mm_cmpeq_epi16(data, mch);
+ uint mask = _mm_movemask_epi8(result);
+ if (uchar(mask)) {
+ // found a match
+ return n + (qCountTrailingZeroBits(mask) >> 1);
+ }
+
+ n += 4;
+ }
+
+ return UnrollTailLoop<3>::exec(e - n, e,
+ [=](int i) { return n[i] == c; },
+ [=](int i) { return n + i; });
+# endif
+#elif defined(__ARM_NEON__) && defined(Q_PROCESSOR_ARM_64) // vaddv is only available on Aarch64
+ const uint16x8_t vmask = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 };
+ const uint16x8_t ch_vec = vdupq_n_u16(c);
+ for (const ushort *next = n + 8; next <= e; n = next, next += 8) {
+ uint16x8_t data = vld1q_u16(n);
+ uint mask = vaddvq_u16(vandq_u16(vceqq_u16(data, ch_vec), vmask));
+ if (ushort(mask)) {
+ // found a match
+ return n + qCountTrailingZeroBits(mask);
+ }
+ }
+#endif // aarch64
+
+ --n;
+ while (++n != e)
+ if (*n == c)
+ return n;
+
+ return n;
+}
+
#ifdef __SSE2__
+// Scans from \a ptr to \a end until \a maskval is non-zero. Returns true if
+// the no non-zero was found. Returns false and updates \a ptr to point to the
+// first 16-bit word that has any bit set (note: if the input is 8-bit, \a ptr
+// may be updated to one byte short).
static bool simdTestMask(const char *&ptr, const char *end, quint32 maskval)
{
-# if defined(__AVX2__)
+ auto updatePtr = [&](uint result) {
+ // found a character matching the mask
+ uint idx = qCountTrailingZeroBits(~result);
+ ptr += idx;
+ return false;
+ };
+
+# if defined(__SSE4_1__)
+ __m128i mask;
+ auto updatePtrSimd = [&](__m128i data) {
+ __m128i masked = _mm_and_si128(mask, data);
+ __m128i comparison = _mm_cmpeq_epi16(masked, _mm_setzero_si128());
+ uint result = _mm_movemask_epi8(comparison);
+ return updatePtr(result);
+ };
+
+# if defined(__AVX2__)
// AVX2 implementation: test 32 bytes at a time
const __m256i mask256 = _mm256_broadcastd_epi32(_mm_cvtsi32_si128(maskval));
while (ptr + 32 <= end) {
__m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr));
- if (!_mm256_testz_si256(mask256, data))
- return false;
+ if (!_mm256_testz_si256(mask256, data)) {
+ // found a character matching the mask
+ __m256i masked256 = _mm256_and_si256(mask256, data);
+ __m256i comparison256 = _mm256_cmpeq_epi16(masked256, _mm256_setzero_si256());
+ return updatePtr(_mm256_movemask_epi8(comparison256));
+ }
ptr += 32;
}
- const __m128i mask = _mm256_castsi256_si128(mask256);
-# elif defined(__SSE4_1__)
+ mask = _mm256_castsi256_si128(mask256);
+# else
// SSE 4.1 implementation: test 32 bytes at a time (two 16-byte
// comparisons, unrolled)
- const __m128i mask = _mm_set1_epi32(maskval);
+ mask = _mm_set1_epi32(maskval);
while (ptr + 32 <= end) {
__m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
__m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr + 16));
if (!_mm_testz_si128(mask, data1))
- return false;
+ return updatePtrSimd(data1);
+
+ ptr += 16;
if (!_mm_testz_si128(mask, data2))
- return false;
- ptr += 32;
+ return updatePtrSimd(data2);
+ ptr += 16;
}
-# endif
-# if defined(__SSE4_1__)
+# endif
+
// AVX2 and SSE4.1: final 16-byte comparison
if (ptr + 16 <= end) {
__m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
if (!_mm_testz_si128(mask, data1))
- return false;
+ return updatePtrSimd(data1);
ptr += 16;
}
+
+ // and final 8-byte comparison
+ if (ptr + 8 <= end) {
+ __m128i data1 = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(ptr));
+ if (!_mm_testz_si128(mask, data1))
+ return updatePtrSimd(data1);
+ ptr += 8;
+ }
+
# else
// SSE2 implementation: test 16 bytes at a time.
const __m128i mask = _mm_set1_epi32(maskval);
- while (ptr + 16 < end) {
+ while (ptr + 16 <= end) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
- __m128i masked = _mm_andnot_si128(mask, data);
+ __m128i masked = _mm_and_si128(mask, data);
__m128i comparison = _mm_cmpeq_epi16(masked, _mm_setzero_si128());
- if (quint16(_mm_movemask_epi8(comparison)) != 0xffff)
- return false;
+ quint16 result = _mm_movemask_epi8(comparison);
+ if (result != 0xffff)
+ return updatePtr(result);
ptr += 16;
}
+
+ // and one 8-byte comparison
+ if (ptr + 8 <= end) {
+ __m128i data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(ptr));
+ __m128i masked = _mm_and_si128(mask, data);
+ __m128i comparison = _mm_cmpeq_epi16(masked, _mm_setzero_si128());
+ quint8 result = _mm_movemask_epi8(comparison);
+ if (result != 0xff)
+ return updatePtr(result);
+ ptr += 8;
+ }
# endif
return true;
}
#endif
-bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW
+// Note: ptr on output may be off by one and point to a preceding US-ASCII
+// character. Usually harmless.
+bool qt_is_ascii(const char *&ptr, const char *end) Q_DECL_NOTHROW
{
- const char *ptr = s.begin();
- const char *end = s.end();
-
#if defined(__SSE2__)
// Testing for the high bit can be done efficiently with just PMOVMSKB
# if defined(__AVX2__)
while (ptr + 32 <= end) {
__m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr));
quint32 mask = _mm256_movemask_epi8(data);
- if (mask)
+ if (mask) {
+ uint idx = qCountTrailingZeroBits(mask);
+ ptr += idx;
return false;
+ }
ptr += 32;
}
# endif
-
while (ptr + 16 <= end) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
quint32 mask = _mm_movemask_epi8(data);
- if (mask)
+ if (mask) {
+ uint idx = qCountTrailingZeroBits(mask);
+ ptr += idx;
return false;
+ }
ptr += 16;
}
+ if (ptr + 8 <= end) {
+ __m128i data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(ptr));
+ quint8 mask = _mm_movemask_epi8(data);
+ if (mask) {
+ uint idx = qCountTrailingZeroBits(mask);
+ ptr += idx;
+ return false;
+ }
+ ptr += 8;
+ }
#endif
while (ptr + 4 <= end) {
quint32 data = qFromUnaligned<quint32>(ptr);
- if (data & 0x80808080U)
+ if (data &= 0x80808080U) {
+ uint idx = qCountTrailingZeroBits(data);
+ ptr += idx / 8;
return false;
+ }
ptr += 4;
}
while (ptr != end) {
- if (quint8(*ptr++) & 0x80)
+ if (quint8(*ptr) & 0x80)
return false;
+ ++ptr;
}
return true;
}
-bool QtPrivate::isAscii(QStringView s) Q_DECL_NOTHROW
+bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW
{
- const QChar *ptr = s.begin();
- const QChar *end = s.end();
+ const char *ptr = s.begin();
+ const char *end = s.end();
+
+ return qt_is_ascii(ptr, end);
+}
+static bool isAscii(const QChar *&ptr, const QChar *end)
+{
#ifdef __SSE2__
const char *ptr8 = reinterpret_cast<const char *>(ptr);
const char *end8 = reinterpret_cast<const char *>(end);
- if (!simdTestMask(ptr8, end8, 0xff80ff80))
- return false;
+ bool ok = simdTestMask(ptr8, end8, 0xff80ff80);
ptr = reinterpret_cast<const QChar *>(ptr8);
+ if (!ok)
+ return false;
#endif
while (ptr != end) {
- if ((*ptr++).unicode() & 0xff80)
+ if (ptr->unicode() & 0xff80)
return false;
+ ++ptr;
}
return true;
}
+bool QtPrivate::isAscii(QStringView s) Q_DECL_NOTHROW
+{
+ const QChar *ptr = s.begin();
+ const QChar *end = s.end();
+
+ return isAscii(ptr, end);
+}
+
bool QtPrivate::isLatin1(QStringView s) Q_DECL_NOTHROW
{
const QChar *ptr = s.begin();
@@ -439,11 +583,19 @@ void qt_from_latin1(ushort *dst, const char *str, size_t size) Q_DECL_NOTHROW
#endif
}
- size = size % 16;
+ // we're going to read str[offset..offset+7] (8 bytes)
+ if (str + offset + 7 < e) {
+ const __m128i chunk = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(str + offset));
+ const __m128i unpacked = _mm_unpacklo_epi8(chunk, _mm_setzero_si128());
+ _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + offset), unpacked);
+ offset += 8;
+ }
+
+ size = size % 8;
dst += offset;
str += offset;
# if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__)
- return UnrollTailLoop<15>::exec(int(size), [=](int i) { dst[i] = (uchar)str[i]; });
+ return UnrollTailLoop<7>::exec(int(size), [=](int i) { dst[i] = (uchar)str[i]; });
# endif
#endif
#if defined(__mips_dsp)
@@ -457,86 +609,117 @@ void qt_from_latin1(ushort *dst, const char *str, size_t size) Q_DECL_NOTHROW
#endif
}
-#if defined(__SSE2__)
-static inline __m128i mergeQuestionMarks(__m128i chunk)
+template <bool Checked>
+static void qt_to_latin1_internal(uchar *dst, const ushort *src, qsizetype length)
{
+#if defined(__SSE2__)
+ uchar *e = dst + length;
+ qptrdiff offset = 0;
+
+# ifdef __AVX2__
+ const __m256i questionMark256 = _mm256_broadcastw_epi16(_mm_cvtsi32_si128('?'));
+ const __m256i outOfRange256 = _mm256_broadcastw_epi16(_mm_cvtsi32_si128(0x100));
+ const __m128i questionMark = _mm256_castsi256_si128(questionMark256);
+ const __m128i outOfRange = _mm256_castsi256_si128(outOfRange256);
+# else
const __m128i questionMark = _mm_set1_epi16('?');
+ const __m128i outOfRange = _mm_set1_epi16(0x100);
+# endif
-# ifdef __SSE4_2__
- // compare the unsigned shorts for the range 0x0100-0xFFFF
- // note on the use of _mm_cmpestrm:
- // The MSDN documentation online (http://technet.microsoft.com/en-us/library/bb514080.aspx)
- // says for range search the following:
- // For each character c in a, determine whether b0 <= c <= b1 or b2 <= c <= b3
- //
- // However, all examples on the Internet, including from Intel
- // (see http://software.intel.com/en-us/articles/xml-parsing-accelerator-with-intel-streaming-simd-extensions-4-intel-sse4/)
- // put the range to be searched first
- //
- // Disassembly and instruction-level debugging with GCC and ICC show
- // that they are doing the right thing. Inverting the arguments in the
- // instruction does cause a bunch of test failures.
-
- const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100);
- const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8,
- _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK);
-
- // replace the non-Latin 1 characters in the chunk with question marks
- chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
+ auto mergeQuestionMarks = [=](__m128i chunk) {
+ // SSE has no compare instruction for unsigned comparison.
+# ifdef __SSE4_1__
+ // We use an unsigned uc = qMin(uc, 0x100) and then compare for equality.
+ chunk = _mm_min_epu16(chunk, outOfRange);
+ const __m128i offLimitMask = _mm_cmpeq_epi16(chunk, outOfRange);
+ chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
# else
- // SSE has no compare instruction for unsigned comparison.
- // The variables must be shiffted + 0x8000 to be compared
- const __m128i signedBitOffset = _mm_set1_epi16(short(0x8000));
- const __m128i thresholdMask = _mm_set1_epi16(short(0xff + 0x8000));
+ // The variables must be shiffted + 0x8000 to be compared
+ const __m128i signedBitOffset = _mm_set1_epi16(short(0x8000));
+ const __m128i thresholdMask = _mm_set1_epi16(short(0xff + 0x8000));
- const __m128i signedChunk = _mm_add_epi16(chunk, signedBitOffset);
- const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask);
+ const __m128i signedChunk = _mm_add_epi16(chunk, signedBitOffset);
+ const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask);
-# ifdef __SSE4_1__
- // replace the non-Latin 1 characters in the chunk with question marks
- chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
-# else
- // offLimitQuestionMark contains '?' for each 16 bits that was off-limit
- // the 16 bits that were correct contains zeros
- const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark);
+ // offLimitQuestionMark contains '?' for each 16 bits that was off-limit
+ // the 16 bits that were correct contains zeros
+ const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark);
- // correctBytes contains the bytes that were in limit
- // the 16 bits that were off limits contains zeros
- const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk);
+ // correctBytes contains the bytes that were in limit
+ // the 16 bits that were off limits contains zeros
+ const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk);
- // merge offLimitQuestionMark and correctBytes to have the result
- chunk = _mm_or_si128(correctBytes, offLimitQuestionMark);
-# endif
-# endif
- return chunk;
-}
-#endif
+ // merge offLimitQuestionMark and correctBytes to have the result
+ chunk = _mm_or_si128(correctBytes, offLimitQuestionMark);
-static void qt_to_latin1(uchar *dst, const ushort *src, int length)
-{
-#if defined(__SSE2__)
- uchar *e = dst + length;
- qptrdiff offset = 0;
+ Q_UNUSED(outOfRange);
+# endif
+ return chunk;
+ };
// we're going to write to dst[offset..offset+15] (16 bytes)
for ( ; dst + offset + 15 < e; offset += 16) {
+# if defined(__AVX2__)
+ __m256i chunk = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src + offset));
+ if (Checked) {
+ // See mergeQuestionMarks lambda above for details
+ chunk = _mm256_min_epu16(chunk, outOfRange256);
+ const __m256i offLimitMask = _mm256_cmpeq_epi16(chunk, outOfRange256);
+ chunk = _mm256_blendv_epi8(chunk, questionMark256, offLimitMask);
+ }
+
+ const __m128i chunk2 = _mm256_extracti128_si256(chunk, 1);
+ const __m128i chunk1 = _mm256_castsi256_si128(chunk);
+# else
__m128i chunk1 = _mm_loadu_si128((const __m128i*)(src + offset)); // load
- chunk1 = mergeQuestionMarks(chunk1);
+ if (Checked)
+ chunk1 = mergeQuestionMarks(chunk1);
__m128i chunk2 = _mm_loadu_si128((const __m128i*)(src + offset + 8)); // load
- chunk2 = mergeQuestionMarks(chunk2);
+ if (Checked)
+ chunk2 = mergeQuestionMarks(chunk2);
+# endif
// pack the two vector to 16 x 8bits elements
const __m128i result = _mm_packus_epi16(chunk1, chunk2);
_mm_storeu_si128((__m128i*)(dst + offset), result); // store
}
- length = length % 16;
+# if !defined(__OPTIMIZE_SIZE__)
+ // we're going to write to dst[offset..offset+7] (8 bytes)
+ if (dst + offset + 7 < e) {
+ __m128i chunk = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + offset));
+ if (Checked)
+ chunk = mergeQuestionMarks(chunk);
+
+ // pack, where the upper half is ignored
+ const __m128i result = _mm_packus_epi16(chunk, chunk);
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(dst + offset), result);
+ offset += 8;
+ }
+
+ // we're going to write to dst[offset..offset+3] (4 bytes)
+ if (dst + offset + 3 < e) {
+ __m128i chunk = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(src + offset));
+ if (Checked)
+ chunk = mergeQuestionMarks(chunk);
+
+ // pack, we'll the upper three quarters
+ const __m128i result = _mm_packus_epi16(chunk, chunk);
+ qToUnaligned(_mm_cvtsi128_si32(result), dst + offset);
+ offset += 4;
+ }
+
+ length = length % 4;
dst += offset;
src += offset;
-# if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__)
- return UnrollTailLoop<15>::exec(length, [=](int i) { dst[i] = (src[i]>0xff) ? '?' : (uchar) src[i]; });
+ return UnrollTailLoop<3>::exec(length, [=](int i) {
+ if (Checked)
+ dst[i] = (src[i]>0xff) ? '?' : (uchar) src[i];
+ else
+ dst[i] = src[i];
+ });
# endif
#elif defined(__ARM_NEON__)
// Refer to the documentation of the SSE2 implementation
@@ -551,10 +734,12 @@ static void qt_to_latin1(uchar *dst, const ushort *src, int length)
uint16x8_t chunk = vld1q_u16((uint16_t *)src); // load
src += 8;
- const uint16x8_t offLimitMask = vcgtq_u16(chunk, thresholdMask); // chunk > thresholdMask
- const uint16x8_t offLimitQuestionMark = vandq_u16(offLimitMask, questionMark); // offLimitMask & questionMark
- const uint16x8_t correctBytes = vbicq_u16(chunk, offLimitMask); // !offLimitMask & chunk
- chunk = vorrq_u16(correctBytes, offLimitQuestionMark); // correctBytes | offLimitQuestionMark
+ if (Checked) {
+ const uint16x8_t offLimitMask = vcgtq_u16(chunk, thresholdMask); // chunk > thresholdMask
+ const uint16x8_t offLimitQuestionMark = vandq_u16(offLimitMask, questionMark); // offLimitMask & questionMark
+ const uint16x8_t correctBytes = vbicq_u16(chunk, offLimitMask); // !offLimitMask & chunk
+ chunk = vorrq_u16(correctBytes, offLimitQuestionMark); // correctBytes | offLimitQuestionMark
+ }
const uint8x8_t result = vmovn_u16(chunk); // narrowing move->packing
vst1_u8(dst, result); // store
dst += 8;
@@ -566,12 +751,25 @@ static void qt_to_latin1(uchar *dst, const ushort *src, int length)
qt_toLatin1_mips_dsp_asm(dst, src, length);
#else
while (length--) {
- *dst++ = (*src>0xff) ? '?' : (uchar) *src;
+ if (Checked)
+ *dst++ = (*src>0xff) ? '?' : (uchar) *src;
+ else
+ *dst++ = *src;
++src;
}
#endif
}
+static void qt_to_latin1(uchar *dst, const ushort *src, qsizetype length)
+{
+ qt_to_latin1_internal<true>(dst, src, length);
+}
+
+void qt_to_latin1_unchecked(uchar *dst, const ushort *src, qsizetype length)
+{
+ qt_to_latin1_internal<false>(dst, src, length);
+}
+
// Unicode case-insensitive comparison
static int ucstricmp(const QChar *a, const QChar *ae, const QChar *b, const QChar *be)
{
@@ -836,12 +1034,11 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l)
}
}
-# ifdef Q_PROCESSOR_X86_64
- enum { MaxTailLength = 7 };
+# if !defined(__OPTIMIZE_SIZE__)
// we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes)
if (uc + offset + 7 < e) {
// same, but we're using an 8-byte load
- __m128i chunk = _mm_cvtsi64_si128(qFromUnaligned<long long>(c + offset));
+ __m128i chunk = _mm_loadl_epi64((const __m128i*)(c + offset));
__m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask);
__m128i ucdata = _mm_loadu_si128((const __m128i*)(uc + offset));
@@ -856,17 +1053,30 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l)
// still matched
offset += 8;
}
-# else
- // 32-bit, we can't do MOVQ to load 8 bytes
- Q_UNUSED(nullmask);
- enum { MaxTailLength = 15 };
-# endif
+
+ enum { MaxTailLength = 3 };
+ // we'll read uc[offset..offset+3] (8 bytes) and c[offset..offset+3] (4 bytes)
+ if (uc + offset + 3 < e) {
+ __m128i chunk = _mm_cvtsi32_si128(qFromUnaligned<int>(c + offset));
+ __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask);
+
+ __m128i ucdata = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(uc + offset));
+ __m128i result = _mm_cmpeq_epi8(secondHalf, ucdata);
+ uint mask = ~_mm_movemask_epi8(result);
+ if (uchar(mask)) {
+ // found a different character
+ uint idx = qCountTrailingZeroBits(mask);
+ return uc[offset + idx / 2] - c[offset + idx / 2];
+ }
+
+ // still matched
+ offset += 4;
+ }
// reset uc and c
uc += offset;
c += offset;
-# if !defined(__OPTIMIZE_SIZE__)
const auto lambda = [=](size_t i) { return uc[i] - ushort(c[i]); };
return UnrollTailLoop<MaxTailLength>::exec(e - uc, 0, lambda, lambda);
# endif
@@ -930,14 +1140,12 @@ static int qt_compare_strings(QLatin1String lhs, QStringView rhs, Qt::CaseSensit
static int qt_compare_strings(QLatin1String lhs, QLatin1String rhs, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{
+ if (cs == Qt::CaseInsensitive)
+ return qstrnicmp(lhs.data(), lhs.size(), rhs.data(), rhs.size());
if (lhs.isEmpty())
return lencmp(0, rhs.size());
const auto l = std::min(lhs.size(), rhs.size());
- int r;
- if (cs == Qt::CaseSensitive)
- r = qstrncmp(lhs.data(), rhs.data(), l);
- else
- r = qstrnicmp(lhs.data(), rhs.data(), l);
+ int r = qstrncmp(lhs.data(), rhs.data(), l);
return r ? r : lencmp(lhs.size(), rhs.size());
}
@@ -1039,44 +1247,9 @@ static int findChar(const QChar *str, int len, QChar ch, int from,
const ushort *n = s + from;
const ushort *e = s + len;
if (cs == Qt::CaseSensitive) {
-#ifdef __SSE2__
- __m128i mch = _mm_set1_epi32(c | (c << 16));
-
- // we're going to read n[0..7] (16 bytes)
- for (const ushort *next = n + 8; next <= e; n = next, next += 8) {
- __m128i data = _mm_loadu_si128((const __m128i*)n);
- __m128i result = _mm_cmpeq_epi16(data, mch);
- uint mask = _mm_movemask_epi8(result);
- if (ushort(mask)) {
- // found a match
- // same as: return n - s + _bit_scan_forward(mask) / 2
- return (reinterpret_cast<const char *>(n) - reinterpret_cast<const char *>(s)
- + qCountTrailingZeroBits(mask)) >> 1;
- }
- }
-
-# if defined(Q_COMPILER_LAMBDA) && !defined(__OPTIMIZE_SIZE__)
- return UnrollTailLoop<7>::exec(e - n, -1,
- [=](int i) { return n[i] == c; },
- [=](int i) { return n - s + i; });
-# endif
-#endif
-#if defined(__ARM_NEON__) && defined(Q_PROCESSOR_ARM_64) // vaddv is only available on Aarch64
- const uint16x8_t vmask = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 };
- const uint16x8_t ch_vec = vdupq_n_u16(c);
- for (const ushort *next = n + 8; next <= e; n = next, next += 8) {
- uint16x8_t data = vld1q_u16(n);
- uint mask = vaddvq_u16(vandq_u16(vceqq_u16(data, ch_vec), vmask));
- if (ushort(mask)) {
- // found a match
- return n - s + qCountTrailingZeroBits(mask);
- }
- }
-#endif // aarch64
- --n;
- while (++n != e)
- if (*n == c)
- return n - s;
+ n = QtPrivate::qustrchr(QStringView(n, e), c);
+ if (n != e)
+ return n - s;
} else {
c = foldCase(c);
--n;
@@ -4930,16 +5103,55 @@ bool QString::endsWith(QChar c, Qt::CaseSensitivity cs) const
return qt_ends_with(*this, c, cs);
}
-static QByteArray qt_convert_to_latin1(QStringView string);
+/*!
+ Returns \c true if the string only contains uppercase letters,
+ otherwise returns \c false.
+ \since 5.12
-QByteArray QString::toLatin1_helper(const QString &string)
+ \sa QChar::isUpper(), isLower()
+*/
+bool QString::isUpper() const
{
- return qt_convert_to_latin1(string);
+ if (isEmpty())
+ return false;
+
+ const QChar *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!d[i].isUpper())
+ return false;
+ }
+
+ return true;
}
-QByteArray QString::toLatin1_helper(const QChar *data, int length)
+/*!
+ Returns \c true if the string only contains lowercase letters,
+ otherwise returns \c false.
+ \since 5.12
+
+ \sa QChar::isLower(), isUpper()
+ */
+bool QString::isLower() const
+{
+ if (isEmpty())
+ return false;
+
+ const QChar *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!d[i].isLower())
+ return false;
+ }
+
+ return true;
+}
+
+static QByteArray qt_convert_to_latin1(QStringView string);
+
+QByteArray QString::toLatin1_helper(const QString &string)
{
- return qt_convert_to_latin1(QStringView(data, length));
+ return qt_convert_to_latin1(string);
}
/*!
@@ -6013,7 +6225,17 @@ QString& QString::fill(QChar ch, int size)
sensitivity setting \a cs.
*/
+/*!
+ \fn int QString::compare(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+
+ \since 5.12
+ \overload compare()
+
+ Performs a comparison of this with \a s, using the case
+ sensitivity setting \a cs.
+*/
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\overload compare()
\since 4.2
@@ -6029,6 +6251,7 @@ int QString::compare(const QString &other, Qt::CaseSensitivity cs) const Q_DECL_
{
return qt_compare_strings(*this, other, cs);
}
+#endif
/*!
\internal
@@ -6055,6 +6278,7 @@ int QString::compare(QLatin1String other, Qt::CaseSensitivity cs) const Q_DECL_N
return qt_compare_strings(*this, other, cs);
}
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn int QString::compare(const QStringRef &ref, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\overload compare()
@@ -6063,6 +6287,7 @@ int QString::compare(QLatin1String other, Qt::CaseSensitivity cs) const Q_DECL_N
an integer less than, equal to, or greater than zero if the string
is less than, equal to, or greater than \a ref.
*/
+#endif
/*!
\internal
@@ -6173,7 +6398,7 @@ int QString::localeAwareCompare(const QString &other) const
return localeAwareCompare_helper(constData(), length(), other.constData(), other.length());
}
-#if QT_CONFIG(icu) && !defined(Q_OS_WIN32) && !defined(Q_OS_DARWIN)
+#if QT_CONFIG(icu)
Q_GLOBAL_STATIC(QThreadStorage<QCollator>, defaultCollator)
#endif
@@ -6194,12 +6419,15 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
return qt_compare_strings(QStringView(data1, length1), QStringView(data2, length2),
Qt::CaseSensitive);
-#if defined(Q_OS_WIN)
-# ifndef Q_OS_WINRT
- int res = CompareString(GetUserDefaultLCID(), 0, (wchar_t*)data1, length1, (wchar_t*)data2, length2);
-# else
- int res = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, (LPCWSTR)data1, length1, (LPCWSTR)data2, length2, NULL, NULL, 0);
-# endif
+#if QT_CONFIG(icu)
+ if (!defaultCollator()->hasLocalData())
+ defaultCollator()->setLocalData(QCollator());
+ return defaultCollator()->localData().compare(data1, length1, data2, length2);
+#else
+ const QString lhs = QString::fromRawData(data1, length1).normalized(QString::NormalizationForm_C);
+ const QString rhs = QString::fromRawData(data2, length2).normalized(QString::NormalizationForm_C);
+# if defined(Q_OS_WIN)
+ int res = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, (LPWSTR)lhs.constData(), lhs.length(), (LPWSTR)rhs.constData(), rhs.length(), NULL, NULL, 0);
switch (res) {
case CSTR_LESS_THAN:
@@ -6209,37 +6437,33 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
default:
return 0;
}
-#elif defined (Q_OS_MAC)
+# elif defined (Q_OS_DARWIN)
// Use CFStringCompare for comparing strings on Mac. This makes Qt order
// strings the same way as native applications do, and also respects
// the "Order for sorted lists" setting in the International preferences
// panel.
const CFStringRef thisString =
CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
- reinterpret_cast<const UniChar *>(data1), length1, kCFAllocatorNull);
+ reinterpret_cast<const UniChar *>(lhs.constData()), lhs.length(), kCFAllocatorNull);
const CFStringRef otherString =
CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
- reinterpret_cast<const UniChar *>(data2), length2, kCFAllocatorNull);
+ reinterpret_cast<const UniChar *>(rhs.constData()), rhs.length(), kCFAllocatorNull);
const int result = CFStringCompare(thisString, otherString, kCFCompareLocalized);
CFRelease(thisString);
CFRelease(otherString);
return result;
-#elif QT_CONFIG(icu)
- if (!defaultCollator()->hasLocalData())
- defaultCollator()->setLocalData(QCollator());
- return defaultCollator()->localData().compare(data1, length1, data2, length2);
-#elif defined(Q_OS_UNIX)
+# elif defined(Q_OS_UNIX)
// declared in <string.h>
- int delta = strcoll(toLocal8Bit_helper(data1, length1).constData(), toLocal8Bit_helper(data2, length2).constData());
+ int delta = strcoll(lhs.toLocal8Bit().constData(), rhs.toLocal8Bit().constData());
if (delta == 0)
- delta = qt_compare_strings(QStringView(data1, length1), QStringView(data2, length2),
- Qt::CaseSensitive);
+ delta = qt_compare_strings(lhs, rhs, Qt::CaseSensitive);
return delta;
-#else
- return qt_compare_strings(QStringView(data1, length1), QStringView(data2, length2),
- Qt::CaseSensitive);
-#endif
+# else
+# error "This case shouldn't happen"
+ return qt_compare_strings(lhs, rhs, Qt::CaseSensitive);
+# endif
+#endif // !QT_CONFIG(icu)
}
@@ -7784,19 +8008,11 @@ QString QString::repeated(int times) const
void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::UnicodeVersion version, int from)
{
- bool simple = true;
- const QChar *p = data->constData();
- int len = data->length();
- for (int i = from; i < len; ++i) {
- if (p[i].unicode() >= 0x80) {
- simple = false;
- if (i > from)
- from = i - 1;
- break;
- }
- }
- if (simple)
+ const QChar *p = data->constData() + from;
+ if (isAscii(p, p + data->length() - from))
return;
+ if (p > data->constData() + from)
+ from = p - data->constData() - 1; // need one before the non-ASCII to perform NFC
if (version == QChar::Unicode_Unassigned) {
version = QChar::currentUnicodeVersion();
@@ -9757,11 +9973,7 @@ QDataStream &operator<<(QDataStream &out, const QString &str)
out.writeBytes(reinterpret_cast<const char *>(str.unicode()), sizeof(QChar) * str.length());
} else {
QVarLengthArray<ushort> buffer(str.length());
- const ushort *data = reinterpret_cast<const ushort *>(str.constData());
- for (int i = 0; i < str.length(); i++) {
- buffer[i] = qbswap(*data);
- ++data;
- }
+ qbswap<sizeof(ushort)>(str.constData(), str.length(), buffer.data());
out.writeBytes(reinterpret_cast<const char *>(buffer.data()), sizeof(ushort) * buffer.size());
}
} else {
@@ -9818,10 +10030,7 @@ QDataStream &operator>>(QDataStream &in, QString &str)
if ((in.byteOrder() == QDataStream::BigEndian)
!= (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
ushort *data = reinterpret_cast<ushort *>(str.data());
- while (len--) {
- *data = qbswap(*data);
- ++data;
- }
+ qbswap<sizeof(*data)>(data, len, data);
}
} else {
str = QString(QLatin1String(""));
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index f27f7efa2b..6be3dcdbe1 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -409,6 +409,9 @@ public:
bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ bool isUpper() const;
+ bool isLower() const;
+
Q_REQUIRED_RESULT QString leftJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const;
Q_REQUIRED_RESULT QString rightJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const;
@@ -605,8 +608,12 @@ public:
QString &setUnicode(const QChar *unicode, int size);
inline QString &setUtf16(const ushort *utf16, int size);
+#if QT_STRINGVIEW_LEVEL < 2
int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
+ inline int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
+#endif
int compare(QLatin1String other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
+ inline int compare(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
static inline int compare(const QString &s1, const QString &s2,
Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW
@@ -619,7 +626,6 @@ public:
Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW
{ return -s2.compare(s1, cs); }
- inline int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
static int compare(const QString &s1, const QStringRef &s2,
Qt::CaseSensitivity = Qt::CaseSensitive) Q_DECL_NOTHROW;
@@ -875,7 +881,6 @@ private:
static QString fromUtf8_helper(const char *str, int size);
static QString fromLocal8Bit_helper(const char *, int size);
static QByteArray toLatin1_helper(const QString &);
- static QByteArray toLatin1_helper(const QChar *data, int size);
static QByteArray toLatin1_helper_inplace(QString &);
static QByteArray toUtf8_helper(const QString &);
static QByteArray toLocal8Bit_helper(const QChar *data, int size);
@@ -1636,8 +1641,12 @@ inline bool operator> (const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW
inline bool operator<=(const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW { return rhs >= lhs; }
inline bool operator>=(const QStringRef &lhs, const QString &rhs) Q_DECL_NOTHROW { return rhs <= lhs; }
+#if QT_STRINGVIEW_LEVEL < 2
inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
+#endif
+inline int QString::compare(QStringView s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
+{ return -s.compare(*this, cs); }
inline int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
diff --git a/src/corelib/tools/qstringalgorithms.h b/src/corelib/tools/qstringalgorithms.h
index 8446d85239..cc0eda71f3 100644
--- a/src/corelib/tools/qstringalgorithms.h
+++ b/src/corelib/tools/qstringalgorithms.h
@@ -56,6 +56,7 @@ template <typename T> class QVector;
namespace QtPrivate {
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype qustrlen(const ushort *str) Q_DECL_NOTHROW;
+Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION const ushort *qustrchr(QStringView str, ushort ch) noexcept;
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QStringView rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QLatin1String rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index e9b7397a74..cf150c2a1b 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -323,6 +323,7 @@ static bool stringList_contains(const QStringList &stringList, const T &str, Qt:
}
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn bool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const
@@ -332,11 +333,31 @@ static bool stringList_contains(const QStringList &stringList, const T &str, Qt:
\sa indexOf(), lastIndexOf(), QString::contains()
*/
+#endif
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/// Not really needed anymore, but kept for binary compatibility
bool QtPrivate::QStringList_contains(const QStringList *that, const QString &str,
Qt::CaseSensitivity cs)
{
return stringList_contains(*that, str, cs);
}
+#endif
+
+/*!
+ \fn bool QStringList::contains(QStringView str, Qt::CaseSensitivity cs) const
+ \overload
+ \since 5.12
+
+ Returns \c true if the list contains the string \a str; otherwise
+ returns \c false. The search is case insensitive if \a cs is
+ Qt::CaseInsensitive; the search is case sensitive by default.
+ */
+bool QtPrivate::QStringList_contains(const QStringList *that, QStringView str,
+ Qt::CaseSensitivity cs)
+{
+ return stringList_contains(*that, str, cs);
+}
/*!
\fn bool QStringList::contains(QLatin1String str, Qt::CaseSensitivity cs) const
@@ -692,7 +713,7 @@ int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegularExpres
if (from < 0)
from = qMax(from + that->size(), 0);
- QString exactPattern = QLatin1String("\\A(?:") + re.pattern() + QLatin1String(")\\z");
+ QString exactPattern = QRegularExpression::anchoredPattern(re.pattern());
QRegularExpression exactRe(exactPattern, re.patternOptions());
for (int i = from; i < that->size(); ++i) {
@@ -722,7 +743,7 @@ int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegularEx
else if (from >= that->size())
from = that->size() - 1;
- QString exactPattern = QLatin1String("\\A(?:") + re.pattern() + QLatin1String(")\\z");
+ QString exactPattern = QRegularExpression::anchoredPattern(re.pattern());
QRegularExpression exactRe(exactPattern, re.patternOptions());
for (int i = from; i >= 0; --i) {
diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h
index e58445b8c0..10cbad04d6 100644
--- a/src/corelib/tools/qstringlist.h
+++ b/src/corelib/tools/qstringlist.h
@@ -117,8 +117,11 @@ public:
{ QList<QString>::operator=(std::move(other)); return *this; }
#endif
+#if QT_STRINGVIEW_LEVEL < 2
inline bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+#endif
inline bool contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline bool contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline QStringList operator+(const QStringList &other) const
{ QStringList n = *this; n += other; return n; }
@@ -161,7 +164,10 @@ namespace QtPrivate {
QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QString &str,
Qt::CaseSensitivity cs);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, const QString &str, Qt::CaseSensitivity cs);
+#endif
+ bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, QStringView str, Qt::CaseSensitivity cs);
bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, QLatin1String str, Qt::CaseSensitivity cs);
void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QString &before, const QString &after,
Qt::CaseSensitivity cs);
@@ -213,16 +219,23 @@ inline QStringList QListSpecialMethods<QString>::filter(const QString &str, Qt::
return QtPrivate::QStringList_filter(self(), str, cs);
}
+#if QT_STRINGVIEW_LEVEL < 2
inline bool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const
{
return QtPrivate::QStringList_contains(this, str, cs);
}
+#endif
inline bool QStringList::contains(QLatin1String str, Qt::CaseSensitivity cs) const
{
return QtPrivate::QStringList_contains(this, str, cs);
}
+inline bool QStringList::contains(QStringView str, Qt::CaseSensitivity cs) const
+{
+ return QtPrivate::QStringList_contains(this, str, cs);
+}
+
inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
{
QtPrivate::QStringList_replaceInStrings(self(), before, after, cs);
diff --git a/src/corelib/tools/qstringliteral.h b/src/corelib/tools/qstringliteral.h
index 6a1a74a80e..64296b89fc 100644
--- a/src/corelib/tools/qstringliteral.h
+++ b/src/corelib/tools/qstringliteral.h
@@ -51,33 +51,17 @@ QT_BEGIN_NAMESPACE
typedef QTypedArrayData<ushort> QStringData;
-#if defined(Q_OS_WIN) && !defined(Q_COMPILER_UNICODE_STRINGS)
-// fall back to wchar_t if the a Windows compiler does not
-// support Unicode string literals, assuming wchar_t is 2 bytes
-// on that platform (sanity-checked by static_assert further below)
-
-#if defined(Q_CC_MSVC)
-# define QT_UNICODE_LITERAL_II(str) L##str
-#else
-# define QT_UNICODE_LITERAL_II(str) L"" str
-#endif
-typedef wchar_t qunicodechar;
-
-#else
// all our supported compilers support Unicode string literals,
// even if their Q_COMPILER_UNICODE_STRING has been revoked due
// to lacking stdlib support. But QStringLiteral only needs the
// core language feature, so just use u"" here unconditionally:
-#define QT_UNICODE_LITERAL_II(str) u"" str
typedef char16_t qunicodechar;
-#endif
-
Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
"qunicodechar must typedef an integral type of size 2");
-#define QT_UNICODE_LITERAL(str) QT_UNICODE_LITERAL_II(str)
+#define QT_UNICODE_LITERAL(str) u"" str
#define QStringLiteral(str) \
([]() Q_DECL_NOEXCEPT -> QString { \
enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp
index 0e3246c72c..ce8fdacafb 100644
--- a/src/corelib/tools/qstringview.cpp
+++ b/src/corelib/tools/qstringview.cpp
@@ -681,6 +681,20 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn int QStringView::compare(QStringView other, Qt::CaseSensitivity cs) const
+ \since 5.12
+
+ Compares this string-view with the \a other string-view and returns an
+ integer less than, equal to, or greater than zero if this string-view
+ is less than, equal to, or greater than the other string-view.
+
+ If \a cs is Qt::CaseSensitive, the comparison is case sensitive;
+ otherwise the comparison is case insensitive.
+
+ \sa operator==(), operator<(), operator>()
+*/
+
+/*!
\fn bool QStringView::startsWith(QStringView str, Qt::CaseSensitivity cs) const
\fn bool QStringView::startsWith(QLatin1String l1, Qt::CaseSensitivity cs) const
\fn bool QStringView::startsWith(QChar ch) const
diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h
index 4f7d48fe1d..2e95c2b218 100644
--- a/src/corelib/tools/qstringview.h
+++ b/src/corelib/tools/qstringview.h
@@ -250,6 +250,9 @@ public:
Q_REQUIRED_RESULT QStringView trimmed() const Q_DECL_NOTHROW { return QtPrivate::trimmed(*this); }
+ Q_REQUIRED_RESULT int compare(QStringView other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW
+ { return QtPrivate::compareStrings(*this, other, cs); }
+
Q_REQUIRED_RESULT bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW
{ return QtPrivate::startsWith(*this, s, cs); }
Q_REQUIRED_RESULT inline bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
diff --git a/src/corelib/tools/qt_attribution.json b/src/corelib/tools/qt_attribution.json
index 49a76cb8b4..63288be4e3 100644
--- a/src/corelib/tools/qt_attribution.json
+++ b/src/corelib/tools/qt_attribution.json
@@ -26,10 +26,11 @@
world's languages, with the largest and most extensive standard repository of locale data
available.",
"Homepage": "http://cldr.unicode.org/",
- "Version": "v31.0.1",
+ "Version": "v33.1",
+ "License": "// as specified in https://spdx.org/licenses/Unicode-DFS-2016.html",
"License": "Unicode License Agreement - Data Files and Software (2016)",
"LicenseId": "Unicode-DFS-2016",
"LicenseFile": "UNICODE_LICENSE.txt",
- "Copyright": "Copyright (C) 1991-2017 Unicode, Inc."
+ "Copyright": "Copyright (C) 1991-2018 Unicode, Inc."
}
]
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index daa7dc1531..db6be581ec 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -66,11 +66,10 @@ static QTimeZonePrivate *newBackendTimeZone()
return new QAndroidTimeZonePrivate();
#elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED)
return new QTzTimeZonePrivate();
- // Registry based timezone backend not available on WinRT
-#elif defined Q_OS_WIN
- return new QWinTimeZonePrivate();
#elif QT_CONFIG(icu)
return new QIcuTimeZonePrivate();
+#elif defined Q_OS_WIN
+ return new QWinTimeZonePrivate();
#else
return new QUtcTimeZonePrivate();
#endif // System Locales
@@ -93,11 +92,10 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
return new QAndroidTimeZonePrivate(ianaId);
#elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED)
return new QTzTimeZonePrivate(ianaId);
- // Registry based timezone backend not available on WinRT
-#elif defined Q_OS_WIN
- return new QWinTimeZonePrivate(ianaId);
#elif QT_CONFIG(icu)
return new QIcuTimeZonePrivate(ianaId);
+#elif defined Q_OS_WIN
+ return new QWinTimeZonePrivate(ianaId);
#else
return new QUtcTimeZonePrivate(ianaId);
#endif // System Locales
@@ -822,8 +820,8 @@ bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
// IDs as availableTimeZoneIds() may be slow
if (!QTimeZonePrivate::isValidId(ianaId))
return false;
- const QList<QByteArray> tzIds = availableTimeZoneIds();
- return std::binary_search(tzIds.begin(), tzIds.end(), ianaId);
+ return QUtcTimeZonePrivate().isTimeZoneIdAvailable(ianaId) ||
+ global_tz->backend->isTimeZoneIdAvailable(ianaId);
}
static QList<QByteArray> set_union(const QList<QByteArray> &l1, const QList<QByteArray> &l2)
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index 1a5135f103..8bf7336a42 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -260,6 +260,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
const qint64 sixteenHoursInMSecs(16 * 3600 * 1000);
Q_STATIC_ASSERT(-sixteenHoursInMSecs / 1000 < QTimeZone::MinUtcOffsetSecs
&& sixteenHoursInMSecs / 1000 > QTimeZone::MaxUtcOffsetSecs);
+ const qint64 recent = forLocalMSecs - sixteenHoursInMSecs;
+ const qint64 imminent = forLocalMSecs + sixteenHoursInMSecs;
/*
Offsets are Local - UTC, positive to the east of Greenwich, negative to
the west; DST offset always exceeds standard offset, when DST applies.
@@ -327,7 +329,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
// Get a transition definitely before the local MSecs; usually all we need.
// Only around the transition times might we need another.
- Data tran = previousTransition(forLocalMSecs - sixteenHoursInMSecs);
+ Data tran = previousTransition(recent);
Q_ASSERT(forLocalMSecs < 0 || // Pre-epoch TZ info may be unavailable
forLocalMSecs - tran.offsetFromUtc * 1000 >= tran.atMSecsSinceEpoch);
Data nextTran = nextTransition(tran.atMSecsSinceEpoch);
@@ -343,8 +345,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
&& forLocalMSecs > nextTran.atMSecsSinceEpoch + nextTran.offsetFromUtc * 1000) {
Data newTran = nextTransition(nextTran.atMSecsSinceEpoch);
if (newTran.atMSecsSinceEpoch == invalidMSecs()
- || newTran.atMSecsSinceEpoch + newTran.offsetFromUtc * 1000
- > forLocalMSecs + sixteenHoursInMSecs) {
+ || newTran.atMSecsSinceEpoch + newTran.offsetFromUtc * 1000 > imminent) {
// Definitely not a relevant tansition: too far in the future.
break;
}
@@ -357,10 +358,10 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
/*
So now tran is definitely before and nextTran is either after or only
- slightly before. The one with the larger offset is in DST; the other in
- standard time. Our hint tells us which of those to use (defaulting to
- standard if no hint): try it first; if that fails, try the other; if both
- fail life's tricky.
+ slightly before. One is standard time; we interpret the other as DST
+ (although the transition might in fact by a change in standard offset). Our
+ hint tells us which of those to use (defaulting to standard if no hint): try
+ it first; if that fails, try the other; if both fail, life's tricky.
*/
Q_ASSERT(forLocalMSecs < 0
|| forLocalMSecs - tran.offsetFromUtc * 1000 > tran.atMSecsSinceEpoch);
@@ -369,7 +370,9 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
nextTran.atMSecsSinceEpoch = forLocalMSecs - nextTran.offsetFromUtc * 1000;
tran.atMSecsSinceEpoch = forLocalMSecs - tran.offsetFromUtc * 1000;
- const bool nextIsDst = tran.offsetFromUtc < nextTran.offsetFromUtc;
+ // If both or neither have zero DST, treat the one with lower offset as standard:
+ const bool nextIsDst = !nextTran.daylightTimeOffset == !tran.daylightTimeOffset
+ ? tran.offsetFromUtc < nextTran.offsetFromUtc : nextTran.daylightTimeOffset;
// If that agrees with hint > 0, our first guess is to use nextTran; else tran.
const bool nextFirst = nextIsDst == (hint > 0) && nextStart != invalidMSecs();
for (int i = 0; i < 2; i++) {
@@ -399,7 +402,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
0 < tran.atMSecsSinceEpoch - nextTran.atMSecsSinceEpoch
= (nextTran.offsetFromUtc - tran.offsetFromUtc) * 1000
*/
- int dstStep = nextTran.offsetFromUtc - tran.offsetFromUtc;
+ int dstStep = (nextTran.offsetFromUtc - tran.offsetFromUtc) * 1000;
Q_ASSERT(dstStep > 0); // How else could we get here ?
if (nextFirst) { // hint thought we needed nextTran, so use tran
tran.atMSecsSinceEpoch -= dstStep;
@@ -415,8 +418,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
/* Bracket and refine to discover offset. */
qint64 utcEpochMSecs;
- int early = offsetFromUtc(forLocalMSecs - sixteenHoursInMSecs);
- int late = offsetFromUtc(forLocalMSecs + sixteenHoursInMSecs);
+ int early = offsetFromUtc(recent);
+ int late = offsetFromUtc(imminent);
if (Q_LIKELY(early == late)) { // > 99% of the time
utcEpochMSecs = forLocalMSecs - early * 1000;
} else {
@@ -437,9 +440,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
utcEpochMSecs = forStd;
} else {
// Invalid forLocalMSecs: in spring-forward gap.
- const int dstStep = daylightTimeOffset(early < late ?
- forLocalMSecs + sixteenHoursInMSecs :
- forLocalMSecs - sixteenHoursInMSecs);
+ const int dstStep = daylightTimeOffset(early < late ? imminent : recent);
Q_ASSERT(dstStep); // There can't be a transition without it !
utcEpochMSecs = (hint > 0) ? forStd - dstStep : forDst + dstStep;
}
@@ -486,6 +487,13 @@ QByteArray QTimeZonePrivate::systemTimeZoneId() const
return QByteArray();
}
+bool QTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray& ianaId) const
+{
+ // Fall-back implementation, can be made faster in subclasses
+ const QList<QByteArray> tzIds = availableTimeZoneIds();
+ return std::binary_search(tzIds.begin(), tzIds.end(), ianaId);
+}
+
QList<QByteArray> QTimeZonePrivate::availableTimeZoneIds() const
{
return QList<QByteArray>();
@@ -864,6 +872,17 @@ QByteArray QUtcTimeZonePrivate::systemTimeZoneId() const
return utcQByteArray();
}
+bool QUtcTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
+{
+ for (int i = 0; i < utcDataTableSize; ++i) {
+ const QUtcData *data = utcData(i);
+ if (utcId(data) == ianaId) {
+ return true;
+ }
+ }
+ return false;
+}
+
QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const
{
QList<QByteArray> result;
diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h
index 4d357111f2..c9a5726216 100644
--- a/src/corelib/tools/qtimezoneprivate_p.h
+++ b/src/corelib/tools/qtimezoneprivate_p.h
@@ -128,6 +128,7 @@ public:
virtual QByteArray systemTimeZoneId() const;
+ virtual bool isTimeZoneIdAvailable(const QByteArray &ianaId) const;
virtual QList<QByteArray> availableTimeZoneIds() const;
virtual QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const;
virtual QList<QByteArray> availableTimeZoneIds(int utcOffset) const;
@@ -204,6 +205,7 @@ public:
QByteArray systemTimeZoneId() const override;
+ bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override;
QList<QByteArray> availableTimeZoneIds() const override;
QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const override;
QList<QByteArray> availableTimeZoneIds(int utcOffset) const override;
@@ -323,6 +325,7 @@ public:
QByteArray systemTimeZoneId() const override;
+ bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override;
QList<QByteArray> availableTimeZoneIds() const override;
QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const override;
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 6a5df6272a..bed62a02bd 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -535,7 +535,7 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
// See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
QList<QByteArray> parts = posixRule.split(',');
- PosixZone stdZone, dstZone;
+ PosixZone stdZone, dstZone = PosixZone::invalid();
{
const QByteArray &zoneinfo = parts.at(0);
const char *begin = zoneinfo.constBegin();
@@ -878,14 +878,17 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
}
// Otherwise is strange sequence, so work backwards through trans looking for first match, if any
- for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
- if (m_tranTimes.at(i).atMSecsSinceEpoch <= currentMSecs) {
- tran = dataForTzTransition(m_tranTimes.at(i));
- if ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
- || (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0)) {
- return tran.abbreviation;
- }
- }
+ auto it = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(),
+ [currentMSecs](const QTzTransitionTime &at) {
+ return at.atMSecsSinceEpoch <= currentMSecs;
+ });
+
+ while (it != m_tranTimes.cbegin()) {
+ --it;
+ tran = dataForTzTransition(*it);
+ int offset = tran.daylightTimeOffset;
+ if ((timeType == QTimeZone::DaylightTime) != (offset == 0))
+ return tran.abbreviation;
}
// Otherwise if no match use current data
@@ -900,7 +903,7 @@ QString QTzTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
int QTzTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch) const
{
const QTimeZonePrivate::Data tran = data(atMSecsSinceEpoch);
- return tran.standardTimeOffset + tran.daylightTimeOffset;
+ return tran.offsetFromUtc; // == tran.standardTimeOffset + tran.daylightTimeOffset
}
int QTzTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
@@ -942,40 +945,38 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::dataForTzTransition(QTzTransitionTime
QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
{
+ // If we have no rules (so probably an invalid tz), return invalid data:
+ if (!m_tranTimes.size())
+ return invalidData();
+
// If the required time is after the last transition and we have a POSIX rule then use it
- if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch
+ if (m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch
&& !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) {
const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year();
QVector<QTimeZonePrivate::Data> posixTrans =
calculatePosixTransitions(m_posixRule, year - 1, year + 1,
m_tranTimes.last().atMSecsSinceEpoch);
- for (int i = posixTrans.size() - 1; i >= 0; --i) {
- if (posixTrans.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) {
- QTimeZonePrivate::Data data = posixTrans.at(i);
- data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- return data;
- }
- }
- }
-
- // Otherwise if we can find a valid tran then use its rule
- for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
- if (m_tranTimes.at(i).atMSecsSinceEpoch <= forMSecsSinceEpoch) {
- Data data = dataForTzTransition(m_tranTimes.at(i));
+ auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
+ [forMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
+ return at.atMSecsSinceEpoch <= forMSecsSinceEpoch;
+ });
+ if (it > posixTrans.cbegin()) {
+ QTimeZonePrivate::Data data = *--it;
data.atMSecsSinceEpoch = forMSecsSinceEpoch;
return data;
}
}
- // Otherwise use the earliest transition we have
- if (m_tranTimes.size() > 0) {
- Data data = dataForTzTransition(m_tranTimes.at(0));
- data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- return data;
- }
-
- // Otherwise we have no rules, so probably an invalid tz, so return invalid data
- return invalidData();
+ // Otherwise, if we can find a valid tran, then use its rule:
+ auto last = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(),
+ [forMSecsSinceEpoch] (const QTzTransitionTime &at) {
+ return at.atMSecsSinceEpoch <= forMSecsSinceEpoch;
+ });
+ if (last > m_tranTimes.cbegin())
+ --last;
+ Data data = dataForTzTransition(*last);
+ data.atMSecsSinceEpoch = forMSecsSinceEpoch;
+ return data;
}
bool QTzTimeZonePrivate::hasTransitions() const
@@ -992,21 +993,20 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince
QVector<QTimeZonePrivate::Data> posixTrans =
calculatePosixTransitions(m_posixRule, year - 1, year + 1,
m_tranTimes.last().atMSecsSinceEpoch);
- for (int i = 0; i < posixTrans.size(); ++i) {
- if (posixTrans.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch)
- return posixTrans.at(i);
- }
- }
+ auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
+ [afterMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
+ return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch;
+ });
- // Otherwise if we can find a valid tran then use its rule
- for (int i = 0; i < m_tranTimes.size(); ++i) {
- if (m_tranTimes.at(i).atMSecsSinceEpoch > afterMSecsSinceEpoch) {
- return dataForTzTransition(m_tranTimes.at(i));
- }
+ return it == posixTrans.cend() ? invalidData() : *it;
}
- // Otherwise we have no rule, or there is no next transition, so return invalid data
- return invalidData();
+ // Otherwise, if we can find a valid tran, use its rule:
+ auto last = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(),
+ [afterMSecsSinceEpoch] (const QTzTransitionTime &at) {
+ return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch;
+ });
+ return last != m_tranTimes.cend() ? dataForTzTransition(*last) : invalidData();
}
QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
@@ -1018,21 +1018,20 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs
QVector<QTimeZonePrivate::Data> posixTrans =
calculatePosixTransitions(m_posixRule, year - 1, year + 1,
m_tranTimes.last().atMSecsSinceEpoch);
- for (int i = posixTrans.size() - 1; i >= 0; --i) {
- if (posixTrans.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch)
- return posixTrans.at(i);
- }
+ auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
+ [beforeMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
+ return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch;
+ });
+ Q_ASSERT(it > posixTrans.cbegin());
+ return *--it;
}
// Otherwise if we can find a valid tran then use its rule
- for (int i = m_tranTimes.size() - 1; i >= 0; --i) {
- if (m_tranTimes.at(i).atMSecsSinceEpoch < beforeMSecsSinceEpoch) {
- return dataForTzTransition(m_tranTimes.at(i));
- }
- }
-
- // Otherwise we have no rule, so return invalid data
- return invalidData();
+ auto last = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(),
+ [beforeMSecsSinceEpoch] (const QTzTransitionTime &at) {
+ return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch;
+ });
+ return last > m_tranTimes.cbegin() ? dataForTzTransition(*--last) : invalidData();
}
// TODO Could cache the value and monitor the required files for any changes
@@ -1098,6 +1097,11 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
return ianaId;
}
+bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
+{
+ return tzZones->contains(ianaId);
+}
+
QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const
{
QList<QByteArray> result = tzZones->keys();
diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp
index 8bde07c710..1bf2366748 100644
--- a/src/corelib/tools/qtimezoneprivate_win.cpp
+++ b/src/corelib/tools/qtimezoneprivate_win.cpp
@@ -49,6 +49,7 @@
QT_BEGIN_NAMESPACE
#ifndef Q_OS_WINRT
+// The registry-based timezone backend is not available on WinRT, which falls back to equivalent APIs.
#define QT_USE_REGISTRY_TIMEZONE 1
#endif
@@ -139,15 +140,15 @@ bool equalTzi(const TIME_ZONE_INFORMATION &tzi1, const TIME_ZONE_INFORMATION &tz
#ifdef QT_USE_REGISTRY_TIMEZONE
bool openRegistryKey(const QString &keyPath, HKEY *key)
{
- return (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (const wchar_t*)keyPath.utf16(), 0, KEY_READ, key)
- == ERROR_SUCCESS);
+ return RegOpenKeyEx(HKEY_LOCAL_MACHINE, reinterpret_cast<const wchar_t*>(keyPath.utf16()),
+ 0, KEY_READ, key) == ERROR_SUCCESS;
}
QString readRegistryString(const HKEY &key, const wchar_t *value)
{
wchar_t buffer[MAX_PATH] = {0};
DWORD size = sizeof(wchar_t) * MAX_PATH;
- RegQueryValueEx(key, (LPCWSTR)value, NULL, NULL, (LPBYTE)buffer, &size);
+ RegQueryValueEx(key, value, nullptr, nullptr, reinterpret_cast<LPBYTE>(buffer), &size);
return QString::fromWCharArray(buffer);
}
@@ -155,7 +156,7 @@ int readRegistryValue(const HKEY &key, const wchar_t *value)
{
DWORD buffer;
DWORD size = sizeof(buffer);
- RegQueryValueEx(key, (LPCWSTR)value, NULL, NULL, (LPBYTE)&buffer, &size);
+ RegQueryValueEx(key, value, nullptr, nullptr, reinterpret_cast<LPBYTE>(&buffer), &size);
return buffer;
}
@@ -166,7 +167,7 @@ QWinTimeZonePrivate::QWinTransitionRule readRegistryRule(const HKEY &key,
QWinTimeZonePrivate::QWinTransitionRule rule;
REG_TZI_FORMAT tzi;
DWORD tziSize = sizeof(tzi);
- if (RegQueryValueEx(key, (LPCWSTR)value, NULL, NULL, (BYTE *)&tzi, &tziSize)
+ if (RegQueryValueEx(key, value, nullptr, nullptr, reinterpret_cast<BYTE *>(&tzi), &tziSize)
== ERROR_SUCCESS) {
rule.startYear = 0;
rule.standardTimeBias = tzi.Bias + tzi.StandardBias;
@@ -191,12 +192,12 @@ TIME_ZONE_INFORMATION getRegistryTzi(const QByteArray &windowsId, bool *ok)
if (openRegistryKey(tziKeyPath, &key)) {
DWORD size = sizeof(tzi.DaylightName);
- RegQueryValueEx(key, L"Dlt", NULL, NULL, (LPBYTE)tzi.DaylightName, &size);
+ RegQueryValueEx(key, L"Dlt", nullptr, nullptr, reinterpret_cast<LPBYTE>(tzi.DaylightName), &size);
size = sizeof(tzi.StandardName);
- RegQueryValueEx(key, L"Std", NULL, NULL, (LPBYTE)tzi.StandardName, &size);
+ RegQueryValueEx(key, L"Std", nullptr, nullptr, reinterpret_cast<LPBYTE>(tzi.StandardName), &size);
- if (RegQueryValueEx(key, L"TZI", NULL, NULL, (BYTE *) &regTzi, &regTziSize)
+ if (RegQueryValueEx(key, L"TZI", nullptr, nullptr, reinterpret_cast<BYTE *>(&regTzi), &regTziSize)
== ERROR_SUCCESS) {
tzi.Bias = regTzi.Bias;
tzi.StandardBias = regTzi.StandardBias;
@@ -589,7 +590,7 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId)
for (int year = startYear; year <= endYear; ++year) {
bool ruleOk;
QWinTransitionRule rule = readRegistryRule(dynamicKey,
- (LPCWSTR)QString::number(year).utf16(),
+ reinterpret_cast<LPCWSTR>(QString::number(year).utf16()),
&ruleOk);
if (ruleOk
// Don't repeat a recurrent rule:
@@ -687,10 +688,10 @@ QString QWinTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
if (nameType == QTimeZone::OffsetName) {
const QWinTransitionRule &rule =
m_tranRules.at(ruleIndexForYear(m_tranRules, QDate::currentDate().year()));
+ int offset = rule.standardTimeBias;
if (timeType == QTimeZone::DaylightTime)
- return isoOffsetFormat((rule.standardTimeBias + rule.daylightTimeBias) * -60);
- else
- return isoOffsetFormat((rule.standardTimeBias) * -60);
+ offset += rule.daylightTimeBias;
+ return isoOffsetFormat(offset * -60);
}
switch (timeType) {
diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h
index f3fb6ec1b0..3f2e91a9b2 100644
--- a/src/corelib/tools/qunicodetables_p.h
+++ b/src/corelib/tools/qunicodetables_p.h
@@ -72,6 +72,9 @@ struct Properties {
signed short mirrorDiff : 16;
ushort lowerCaseSpecial : 1;
signed short lowerCaseDiff : 15;
+#ifdef Q_OS_WASM
+ unsigned char : 0; //wasm 64 packing trick
+#endif
ushort upperCaseSpecial : 1;
signed short upperCaseDiff : 15;
ushort titleCaseSpecial : 1;
@@ -80,6 +83,9 @@ struct Properties {
signed short caseFoldDiff : 15;
ushort unicodeVersion : 8; /* 5 used */
ushort nfQuickCheck : 8;
+#ifdef Q_OS_WASM
+ unsigned char : 0; //wasm 64 packing trick
+#endif
ushort graphemeBreakClass : 5; /* 5 used */
ushort wordBreakClass : 5; /* 5 used */
ushort sentenceBreakClass : 8; /* 4 used */
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 72224f280d..dc28e0e0a2 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -34,6 +34,7 @@ HEADERS += \
tools/qlocale_p.h \
tools/qlocale_tools_p.h \
tools/qlocale_data_p.h \
+ tools/qmakearray_p.h \
tools/qmap.h \
tools/qmargins.h \
tools/qmessageauthenticationcode.h \
@@ -45,6 +46,7 @@ HEADERS += \
tools/qregexp.h \
tools/qringbuffer_p.h \
tools/qrefcount.h \
+ tools/qscopeguard.h \
tools/qscopedpointer.h \
tools/qscopedpointer_p.h \
tools/qscopedvaluerollback.h \
@@ -126,7 +128,6 @@ else:unix {
}
else:win32 {
SOURCES += tools/qlocale_win.cpp
- winrt-*-msvc2013: LIBS += advapi32.lib
} else:integrity {
SOURCES += tools/qlocale_unix.cpp
}
@@ -159,16 +160,18 @@ qtConfig(timezone) {
SOURCES += \
tools/qtimezone.cpp \
tools/qtimezoneprivate.cpp
- !nacl:darwin: \
+ !nacl:darwin: {
SOURCES += tools/qtimezoneprivate_mac.mm
- else: android:!android-embedded: \
+ } else: android:!android-embedded: {
SOURCES += tools/qtimezoneprivate_android.cpp
- else: unix: \
+ } else: unix: {
SOURCES += tools/qtimezoneprivate_tz.cpp
- else: win32: \
- SOURCES += tools/qtimezoneprivate_win.cpp
- qtConfig(icu): \
+ qtConfig(icu): SOURCES += tools/qtimezoneprivate_icu.cpp
+ } else: qtConfig(icu): {
SOURCES += tools/qtimezoneprivate_icu.cpp
+ } else: win32: {
+ SOURCES += tools/qtimezoneprivate_win.cpp
+ }
}
qtConfig(datetimeparser) {
@@ -179,7 +182,8 @@ qtConfig(datetimeparser) {
qtConfig(regularexpression) {
QMAKE_USE_PRIVATE += pcre2
- HEADERS += tools/qregularexpression.h
+ HEADERS += \
+ tools/qregularexpression.h
SOURCES += tools/qregularexpression.cpp
}
@@ -216,7 +220,7 @@ qtConfig(system-doubleconversion) {
}
# Note: libm should be present by default becaue this is C++
-unix:!macx-icc:!vxworks:!haiku:!integrity: LIBS_PRIVATE += -lm
+unix:!macx-icc:!vxworks:!haiku:!integrity:!wasm: LIBS_PRIVATE += -lm
TR_EXCLUDE += ../3rdparty/*
diff --git a/src/dbus/qdbus_symbols.cpp b/src/dbus/qdbus_symbols.cpp
index 1e93a46c0c..f22696639d 100644
--- a/src/dbus/qdbus_symbols.cpp
+++ b/src/dbus/qdbus_symbols.cpp
@@ -79,10 +79,8 @@ bool qdbus_loadLibDBus()
#endif
static bool triedToLoadLibrary = false;
-#ifndef QT_NO_THREAD
static QBasicMutex mutex;
QMutexLocker locker(&mutex);
-#endif
QLibrary *&lib = qdbus_libdbus;
if (triedToLoadLibrary)
@@ -126,14 +124,16 @@ bool qdbus_loadLibDBus()
#endif
}
-#if QT_CONFIG(library)
void (*qdbus_resolve_conditionally(const char *name))()
{
+#if QT_CONFIG(library)
if (qdbus_loadLibDBus())
return qdbus_libdbus->resolve(name);
+#else
+ Q_UNUSED(name);
+#endif
return 0;
}
-#endif
void (*qdbus_resolve_me(const char *name))()
{
diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h
index 9eaebe6d7e..7cce0d71aa 100644
--- a/src/dbus/qdbus_symbols_p.h
+++ b/src/dbus/qdbus_symbols_p.h
@@ -161,6 +161,19 @@ template <> struct TraceReturn<void> { typedef void Type; };
funcret DEBUGRET(ret) ptr argcall; \
}
+# define DEFINEFUNC_CONDITIONALLY(ret, func, args, argcall, funcret, failret) \
+ typedef ret (* _q_PTR_##func) args; \
+ static inline ret q_##func args \
+ { \
+ static _q_PTR_##func ptr; \
+ DEBUGCALL(#func, argcall); \
+ if (!ptr) \
+ ptr = (_q_PTR_##func) qdbus_resolve_conditionally(#func); \
+ if (!ptr) \
+ failret; \
+ funcret DEBUGRET(ret) ptr argcall; \
+ }
+
#else // defined QT_LINKED_LIBDBUS
inline bool qdbus_loadLibDBus() { return true; }
@@ -300,6 +313,26 @@ DEFINEFUNC(const char* , dbus_message_get_signature, (DBusMessage *message),
(message), return)
DEFINEFUNC(int , dbus_message_get_type, (DBusMessage *message),
(message), return)
+
+#if !defined QT_LINKED_LIBDBUS
+
+DEFINEFUNC_CONDITIONALLY(dbus_bool_t , dbus_message_get_allow_interactive_authorization, (DBusMessage *message),
+ (message), return, return false)
+
+#else // defined QT_LINKED_LIBDBUS
+
+static inline dbus_bool_t q_dbus_message_get_allow_interactive_authorization(DBusMessage *message)
+{
+#ifdef DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION
+ return dbus_message_get_allow_interactive_authorization(message);
+#else
+ Q_UNUSED(message);
+ return false;
+#endif
+}
+
+#endif // defined QT_LINKED_LIBDBUS
+
DEFINEFUNC(dbus_bool_t , dbus_message_iter_append_basic, (DBusMessageIter *iter,
int type,
const void *value),
@@ -378,9 +411,33 @@ DEFINEFUNC(dbus_bool_t , dbus_message_set_sender, (DBusMessage *message,
DEFINEFUNC(void , dbus_message_unref, (DBusMessage *message),
(message), )
+#if !defined QT_LINKED_LIBDBUS
+
+DEFINEFUNC_CONDITIONALLY(void, dbus_message_set_allow_interactive_authorization,
+ (DBusMessage *message, dbus_bool_t allow), (message, allow), return, return)
+
+
+#else // defined QT_LINKED_LIBDBUS
+
+static inline void q_dbus_message_set_allow_interactive_authorization(DBusMessage *message, dbus_bool_t allow)
+{
+#ifdef DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION
+ dbus_message_set_allow_interactive_authorization(message, allow);
+#else
+ Q_UNUSED(message);
+ Q_UNUSED(allow);
+#endif
+}
+
+#endif // defined QT_LINKED_LIBDBUS
+
/* dbus-misc.h */
DEFINEFUNC(char* , dbus_get_local_machine_id , (void), (), return)
+DEFINEFUNC(void , dbus_get_version , (int *major_version, int *minor_version, int *micro_version)
+ , (major_version, minor_version, micro_version)
+ , return)
+
/* dbus-pending-call.h */
DEFINEFUNC(dbus_bool_t , dbus_pending_call_set_notify, (DBusPendingCall *pending,
diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp
index ef827e82b0..3e8f2eaf3f 100644
--- a/src/dbus/qdbusmessage.cpp
+++ b/src/dbus/qdbusmessage.cpp
@@ -70,7 +70,8 @@ static inline const char *data(const QByteArray &arr)
QDBusMessagePrivate::QDBusMessagePrivate()
: msg(0), reply(0), localReply(0), ref(1), type(QDBusMessage::InvalidMessage),
delayedReply(false), localMessage(false),
- parametersValidated(false), autoStartService(true)
+ parametersValidated(false), autoStartService(true),
+ interactiveAuthorizationAllowed(false)
{
}
@@ -138,6 +139,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB
msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(),
data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8());
q_dbus_message_set_auto_start( msg, d_ptr->autoStartService );
+ q_dbus_message_set_allow_interactive_authorization(msg, d_ptr->interactiveAuthorizationAllowed);
+
break;
case QDBusMessage::ReplyMessage:
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
@@ -242,6 +245,7 @@ QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnec
QString::fromUtf8(q_dbus_message_get_member(dmsg));
message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
+ message.d_ptr->interactiveAuthorizationAllowed = q_dbus_message_get_allow_interactive_authorization(dmsg);
message.d_ptr->msg = q_dbus_message_ref(dmsg);
QDBusDemarshaller demarshaller(capabilities);
@@ -725,6 +729,44 @@ bool QDBusMessage::autoStartService() const
}
/*!
+ Sets the interactive authorization flag to \a enable.
+ This flag only makes sense for method call messages, where it
+ tells the D-Bus server that the caller of the method is prepared
+ to wait for interactive authorization to take place (for instance
+ via Polkit) before the actual method is processed.
+
+ By default this flag is false and the other end is expected to
+ make any authorization decisions non-interactively and promptly.
+
+ The \c org.freedesktop.DBus.Error.InteractiveAuthorizationRequired
+ error indicates that authorization failed, but could have succeeded
+ if this flag had been set.
+
+ \sa isInteractiveAuthorizationAllowed()
+
+ \since 5.12
+*/
+void QDBusMessage::setInteractiveAuthorizationAllowed(bool enable)
+{
+ d_ptr->interactiveAuthorizationAllowed = enable;
+}
+
+/*!
+ Returns the interactive authorization allowed flag, as set by
+ setInteractiveAuthorizationAllowed(). By default this flag
+ is false and the other end is expected to make any authorization
+ decisions non-interactively and promptly.
+
+ \sa setInteractiveAuthorizationAllowed()
+
+ \since 5.12
+*/
+bool QDBusMessage::isInteractiveAuthorizationAllowed() const
+{
+ return d_ptr->interactiveAuthorizationAllowed;
+}
+
+/*!
Sets the arguments that are going to be sent over D-Bus to \a arguments. Those
will be the arguments to a method call or the parameters in the signal.
diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h
index 9f4a98b855..23e04045d8 100644
--- a/src/dbus/qdbusmessage.h
+++ b/src/dbus/qdbusmessage.h
@@ -119,6 +119,9 @@ public:
void setAutoStartService(bool enable);
bool autoStartService() const;
+ void setInteractiveAuthorizationAllowed(bool enable);
+ bool isInteractiveAuthorizationAllowed() const;
+
void setArguments(const QList<QVariant> &arguments);
QList<QVariant> arguments() const;
diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h
index 4b84b3f0cc..f921c33832 100644
--- a/src/dbus/qdbusmessage_p.h
+++ b/src/dbus/qdbusmessage_p.h
@@ -87,6 +87,7 @@ public:
uint localMessage : 1;
mutable uint parametersValidated : 1;
uint autoStartService : 1;
+ uint interactiveAuthorizationAllowed : 1;
static void setParametersValidated(QDBusMessage &msg, bool enable)
{ msg.d_ptr->parametersValidated = enable; }
diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index f64e30b49b..c4296f5c55 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -412,7 +412,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
- methods.count(); // ditto
QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data());
- Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QtDBus meta-object generator should generate the same version as moc");
+ Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QtDBus meta-object generator should generate the same version as moc");
header->revision = QMetaObjectPrivate::OutputRevision;
header->className = 0;
header->classInfoCount = 0;
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index d60a21606b..6b48f573b2 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -202,7 +202,7 @@ Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");
This enum type defines accessible event types.
- \omitvalue InvalidEvent Internal: Used when creating subclasses of QAccessibleEvent.
+ \omitvalue InvalidEvent \omit Internal: Used when creating subclasses of QAccessibleEvent. \endomit
\value AcceleratorChanged The keyboard accelerator for an action has been changed.
\value ActionChanged An action has been changed.
\value ActiveDescendantChanged
@@ -273,27 +273,27 @@ Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");
\value SelectionWithin Several changes to a selection has occurred in an item
view.
\value SoundPlayed A sound has been played by an object
- \omitvalue StateChanged The QAccessible::State of an object has changed.
- This value is used internally for the QAccessibleStateChangeEvent.
+ \omitvalue StateChanged \omit The QAccessible::State of an object has changed.
+ This value is used internally for the QAccessibleStateChangeEvent. \endomit
\value TableCaptionChanged A table caption has been changed.
\value TableColumnDescriptionChanged The description of a table column, typically found in
the column's header, has been changed.
\value TableColumnHeaderChanged A table column header has been changed.
- \omitvalue TableModelChanged The model providing data for a table has been changed.
+ \omitvalue TableModelChanged \omit The model providing data for a table has been changed. \endomit
\value TableRowDescriptionChanged The description of a table row, typically found in the
row's header, has been changed.
\value TableRowHeaderChanged A table row header has been changed.
\value TableSummaryChanged The summary of a table has been changed.
\omitvalue TextAttributeChanged
- \omitvalue TextCaretMoved The caret has moved in an editable widget.
+ \omitvalue TextCaretMoved \omit The caret has moved in an editable widget.
The caret represents the cursor position in an editable
- widget with the input focus.
+ widget with the input focus. \endomit
\value TextColumnChanged A text column has been changed.
- \omitvalue TextInserted Text has been inserted into an editable widget.
- \omitvalue TextRemoved Text has been removed from an editable widget.
- \omitvalue TextSelectionChanged The selected text has changed in an editable widget.
- \omitvalue TextUpdated The text has been update in an editable widget.
- \omitvalue ValueChanged The QAccessible::Value of an object has changed.
+ \omitvalue TextInserted \omit Text has been inserted into an editable widget. \endomit
+ \omitvalue TextRemoved \omit Text has been removed from an editable widget. \endomit
+ \omitvalue TextSelectionChanged \omit The selected text has changed in an editable widget. \endomit
+ \omitvalue TextUpdated \omit The text has been update in an editable widget. \endomit
+ \omitvalue ValueChanged \omit The QAccessible::Value of an object has changed. \endomit
\value VisibleDataChanged
The values for this enum are defined to be the same as those defined in the
@@ -441,10 +441,10 @@ Q_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");
\note When subclassing one of these interfaces, \l QAccessibleInterface::interface_cast() needs to be implemented.
\value TextInterface For text that supports selections or is more than one line. Simple labels do not need to implement this interface.
- \omitvalue EditableTextInterface For text that can be edited by the user.
+ \omitvalue EditableTextInterface \omit For text that can be edited by the user. \endomit
\value ValueInterface For objects that are used to manipulate a value, for example slider or scroll bar.
\value ActionInterface For interactive objects that allow the user to trigger an action. Basically everything that allows for example mouse interaction.
- \omitvalue ImageInterface For objects that represent an image. This interface is generally less important.
+ \omitvalue ImageInterface \omit For objects that represent an image. This interface is generally less important. \endomit
\value TableInterface For lists, tables and trees.
\value TableCellInterface For cells in a TableInterface object.
diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp
index f4242036ce..20376a54c4 100644
--- a/src/gui/accessible/qaccessiblecache.cpp
+++ b/src/gui/accessible/qaccessiblecache.cpp
@@ -38,11 +38,15 @@
****************************************************************************/
#include "qaccessiblecache_p.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qloggingcategory.h>
#ifndef QT_NO_ACCESSIBILITY
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcAccessibilityCache, "qt.accessibility.cache");
+
/*!
\class QAccessibleCache
\internal
@@ -57,6 +61,12 @@ static void cleanupAccessibleCache()
accessibleCache = nullptr;
}
+QAccessibleCache::~QAccessibleCache()
+{
+ for (QAccessible::Id id: idToInterface.keys())
+ deleteInterface(id);
+}
+
QAccessibleCache *QAccessibleCache::instance()
{
if (!accessibleCache) {
@@ -116,6 +126,7 @@ QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface *
}
idToInterface.insert(id, iface);
interfaceToId.insert(iface, id);
+ qCDebug(lcAccessibilityCache) << "insert - id:" << id << " iface:" << iface;
return id;
}
@@ -131,6 +142,9 @@ void QAccessibleCache::objectDestroyed(QObject* obj)
void QAccessibleCache::deleteInterface(QAccessible::Id id, QObject *obj)
{
QAccessibleInterface *iface = idToInterface.take(id);
+ qCDebug(lcAccessibilityCache) << "delete - id:" << id << " iface:" << iface;
+ if (!iface) // the interface may be deleted already
+ return;
interfaceToId.take(iface);
if (!obj)
obj = iface->object();
diff --git a/src/gui/accessible/qaccessiblecache_p.h b/src/gui/accessible/qaccessiblecache_p.h
index f054ee9678..a976277c1d 100644
--- a/src/gui/accessible/qaccessiblecache_p.h
+++ b/src/gui/accessible/qaccessiblecache_p.h
@@ -68,6 +68,7 @@ class Q_GUI_EXPORT QAccessibleCache :public QObject
Q_OBJECT
public:
+ ~QAccessibleCache() override;
static QAccessibleCache *instance();
QAccessibleInterface *interfaceForId(QAccessible::Id id) const;
QAccessible::Id idForInterface(QAccessibleInterface *iface) const;
diff --git a/src/gui/configure.json b/src/gui/configure.json
index 219385a108..4741ed345a 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -44,7 +44,7 @@
"xcb": { "type": "enum", "values": [ "no", "yes", "qt", "system" ] },
"xcb-native-painting": "boolean",
"xcb-xlib": "boolean",
- "xinput2": "boolean",
+ "xcb-xinput": "boolean",
"xkb": "boolean",
"xkbcommon": { "type": "enum", "values": [ "no", "qt", "system" ] },
"xkbcommon-evdev": "boolean",
@@ -114,11 +114,16 @@
"drm": {
"label": "KMS",
"test": {
- "include": [ "stdlib.h", "stdint.h" ],
+ "head": [
+ "#include <stdlib.h>",
+ "#include <stdint.h>",
+ "extern \"C\" {"
+ ],
+ "include": [
+ "xf86drmMode.h",
+ "xf86drm.h"
+ ],
"tail": [
- "extern \"C\" {",
- "#include <xf86drmMode.h>",
- "#include <xf86drm.h>",
"}"
],
"main": "(void) drmModeGetCrtc(0, 0);"
@@ -146,8 +151,8 @@
"freetype": {
"label": "FreeType",
"test": {
- "head": [
- "#include <ft2build.h>",
+ "include": "ft2build.h",
+ "tail": [
"#include FT_FREETYPE_H",
"#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) < 20200)",
"# error This version of freetype is too old.",
@@ -159,14 +164,15 @@
},
"sources": [
{ "type": "pkgConfig", "args": "freetype2" },
- { "type": "freetype", "libs": "-lfreetype" }
+ { "type": "freetype", "libs": "-lfreetype", "condition": "!config.wasm" },
+ { "type": "freetype", "libs": "-s USE_FREETYPE=1", "condition": "config.wasm" }
]
},
"fontconfig": {
"label": "Fontconfig",
"test": {
- "head": [
- "#include <fontconfig/fontconfig.h>",
+ "include": "fontconfig/fontconfig.h",
+ "tail": [
"#ifndef FC_RGBA_UNKNOWN",
"# error This version of fontconfig is tool old, it is missing the FC_RGBA_UNKNOWN define",
"#endif"
@@ -184,10 +190,13 @@
"gbm": {
"label": "GBM",
"test": {
- "include": [ "stdlib.h", "stdint.h" ],
+ "head": [
+ "#include <stdlib.h>",
+ "#include <stdint.h>",
+ "extern \"C\" {"
+ ],
+ "include": "gbm.h",
"tail": [
- "extern \"C\" {",
- "#include <gbm.h>",
"}"
],
"main": "gbm_surface *surface = 0;"
@@ -252,7 +261,11 @@
"integrityhid": {
"label": "integrityhid",
"test": {
- "include": [ "stdlib.h", "stdint.h", "device/hiddriver.h" ],
+ "head": [
+ "#include <stdlib.h>",
+ "#include <stdint.h>"
+ ],
+ "include": "device/hiddriver.h",
"main": [
"HIDDriver *driver;",
"uintptr_t devicecontext;",
@@ -267,10 +280,13 @@
"libjpeg": {
"label": "libjpeg",
"test": {
- "include": [ "sys/types.h", "stdio.h" ],
+ "head": [
+ "#include <sys/types.h>",
+ "#include <stdio.h>",
+ "extern \"C\" {"
+ ],
+ "include": "jpeglib.h",
"tail": [
- "extern \"C\" {",
- "#include <jpeglib.h>",
"}",
"",
"j_compress_ptr cinfo;"
@@ -279,7 +295,7 @@
},
"sources": [
{ "libs": "-llibjpeg", "condition": "config.msvc" },
- { "libs": "-ljpeg", "condition": "!config.msvc" }
+ "-ljpeg"
]
},
"libpng": {
@@ -290,8 +306,11 @@
},
"sources": [
{ "type": "pkgConfig", "args": "libpng" },
+ { "libs": "-llibpng16", "condition": "config.msvc" },
{ "libs": "-llibpng", "condition": "config.msvc" },
- { "libs": "-lpng", "condition": "!config.msvc" }
+ { "libs": "-lpng16", "condition": "!config.msvc" },
+ { "libs": "-lpng", "condition": "!config.msvc" },
+ { "libs": "-s USE_LIBPNG=1", "condition": "config.wasm" }
],
"use": [
{ "lib": "zlib", "condition": "features.system-zlib" }
@@ -393,13 +412,15 @@
"v4l2": {
"label": "V4L2",
"test": {
+ "head": [
+ "#include <cstddef>",
+ "extern \"C\" {"
+ ],
"include": [
- "cstddef"
+ "mediactl/mediactl.h",
+ "mediactl/v4l2subdev.h"
],
"tail": [
- "extern \"C\" {",
- "#include <mediactl/mediactl.h>",
- "#include <mediactl/v4l2subdev.h>",
"}"
],
"main": [
@@ -439,18 +460,18 @@
]
},
"xcb": {
- "label": "XCB >= 1.5 (core)",
+ "label": "XCB >= 1.9 (core)",
"test": {
"include": "xcb/xcb.h",
"main": [
"int primaryScreen = 0;",
"(void)xcb_connect(\"\", &primaryScreen);",
- "// This won't compile unless libxcb >= 1.5 which defines XCB_ATOM_PRIMARY.",
- "int xcbAtomPrimary = XCB_ATOM_PRIMARY;"
+ "// This won't compile unless libxcb >= 1.9 which defines XCB_CONN_CLOSED_INVALID_SCREEN.",
+ "int xcbScreenError = XCB_CONN_CLOSED_INVALID_SCREEN;"
]
},
"sources": [
- { "type": "pkgConfig", "args": "xcb >= 1.5" },
+ { "type": "pkgConfig", "args": "xcb >= 1.9" },
"-lxcb"
]
},
@@ -566,33 +587,22 @@
"-lxcb-glx -lxcb"
]
},
- "xinput2": {
- "label": "Xinput2",
+ "xcb_xinput": {
+ "label": "XCB XInput",
"test": {
- "include": [ "X11/Xlib.h", "X11/extensions/XInput2.h", "X11/extensions/Xge.h" ],
- "tail": [
- "#ifndef XInput_2_0",
- "# error Missing XInput_2_0 #define",
- "#endif"
- ],
+ "include": [ "xcb/xcb.h", "xcb/xinput.h" ],
"main": [
- "// need XGenericEventCookie for XInput2 to work",
- "Display *dpy = 0;",
- "XEvent xevent;",
- "XIEvent *xievent = 0;",
- "XIDeviceEvent *xideviceevent = 0;",
- "XIHierarchyEvent *xihierarchyevent = 0;",
- "int deviceid = 0;",
- "int len = 0;",
- "(void) XGetEventData(dpy, &xevent.xcookie);",
- "XFreeEventData(dpy, &xevent.xcookie);",
- "(void) XIListProperties(dpy, deviceid, &len);"
- ],
- "qmake": "CONFIG += x11"
+ "int primaryScreen = 0;",
+ "xcb_connection_t *connection = xcb_connect(\"\", &primaryScreen);",
+ "xcb_generic_error_t *error = 0;",
+ "xcb_input_xi_query_version_cookie_t xinput_query_cookie = xcb_input_xi_query_version(",
+ " connection, XCB_INPUT_MAJOR_VERSION, XCB_INPUT_MINOR_VERSION);",
+ "xcb_input_xi_query_version_reply(connection, xinput_query_cookie, &error);"
+ ]
},
"sources": [
- { "type": "pkgConfig", "args": "xi" },
- "-lXi"
+ { "type": "pkgConfig", "args": "xcb-xinput >= 1.12 xcb" },
+ "-lxcb-xinput -lxcb"
]
},
"xkbcommon": {
@@ -661,6 +671,26 @@
"fxc.exe"
]
},
+ "drm_atomic": {
+ "label": "DRM Atomic API",
+ "type": "compile",
+ "test": {
+ "head": [
+ "#include <stdlib.h>",
+ "#include <stdint.h>",
+ "extern \"C\" {"
+ ],
+ "include": [
+ "xf86drmMode.h",
+ "xf86drm.h"
+ ],
+ "tail": [
+ "}"
+ ],
+ "main": "drmModeAtomicReq *request;"
+ },
+ "use": "drm"
+ },
"egl-x11": {
"label": "EGL on X11",
"type": "compile",
@@ -953,7 +983,7 @@
},
"evdev": {
"label": "evdev",
- "condition": "tests.evdev",
+ "condition": "features.thread && tests.evdev",
"output": [ "privateFeature" ]
},
"freetype": {
@@ -1010,6 +1040,11 @@
"condition": "libs.drm",
"output": [ "publicQtConfig", "privateFeature" ]
},
+ "drm_atomic": {
+ "label": "DRM Atomic API",
+ "condition": "libs.drm && tests.drm_atomic",
+ "output": [ "privateFeature" ]
+ },
"libinput": {
"label": "libinput",
"condition": "features.libudev && libs.libinput",
@@ -1078,7 +1113,7 @@
},
"opengles3": {
"label": "OpenGL ES 3.0",
- "condition": "features.opengles2 && !features.angle && tests.opengles3",
+ "condition": "features.opengles2 && !features.angle && tests.opengles3 && !config.wasm",
"output": [
"publicFeature",
{ "type": "define", "name": "QT_OPENGL_ES_3" }
@@ -1105,7 +1140,7 @@
"enable": "input.opengl == 'desktop'",
"disable": "input.opengl == 'es2' || input.opengl == 'dynamic' || input.opengl == 'no'",
"condition": "(config.win32 && !config.winrt && !features.opengles2 && (config.msvc || libs.opengl))
- || (!config.watchos && !config.win32 && libs.opengl)"
+ || (!config.watchos && !config.win32 && !config.wasm && libs.opengl)"
},
"opengl-dynamic": {
"label": "Dynamic OpenGL",
@@ -1139,7 +1174,7 @@
},
"egl_x11": {
"label": "EGL on X11",
- "condition": "features.egl && tests.egl-x11",
+ "condition": "features.thread && features.egl && tests.egl-x11",
"output": [ "privateFeature" ]
},
"eglfs": {
@@ -1269,7 +1304,7 @@
"section": "Platform plugins",
"autoDetect": "!config.darwin",
"enable": "input.xcb == 'system' || input.xcb == 'qt' || input.xcb == 'yes'",
- "condition": "libs.xcb",
+ "condition": "features.thread && libs.xcb",
"output": [ "privateFeature" ]
},
"system-xcb": {
@@ -1327,10 +1362,10 @@
"condition": "features.sessionmanager && libs.x11sm",
"output": [ "privateFeature" ]
},
- "xinput2": {
- "label": "Xinput2",
+ "xcb-xinput": {
+ "label": "XCB XInput",
"emitIf": "features.xcb",
- "condition": "features.xcb-xlib && libs.xinput2",
+ "condition": "!features.system-xcb || libs.xcb_xinput",
"output": [ "privateFeature" ]
},
"xkbcommon-evdev": {
@@ -1701,7 +1736,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
"section": "X11",
"condition": "features.xcb",
"entries": [
- "system-xcb", "egl_x11", "xinput2", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xlib", "xkbcommon-system", "xcb-native-painting"
+ "system-xcb", "egl_x11", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xinput", "xcb-xlib", "xkbcommon-system", "xcb-native-painting"
]
},
{
diff --git a/src/gui/configure.pri b/src/gui/configure.pri
index fcd2d1f73e..2971fd136e 100644
--- a/src/gui/configure.pri
+++ b/src/gui/configure.pri
@@ -7,7 +7,7 @@ defineTest(qtConfLibrary_freetype) {
for (p, TRY_INCLUDEPATHS) {
includedir = $$p/freetype2
exists($$includedir) {
- $${1}.includedir = "$$val_escape(includedir)"
+ $${1}.includedir = $$includedir
export($${1}.includedir)
return(true)
}
@@ -55,6 +55,7 @@ defineTest(qtConfTest_qpaDefaultPlatform) {
else: qnx: name = qnx
else: integrity: name = integrityfb
else: haiku: name = haiku
+ else: wasm: name = webassembly
else: name = xcb
$${1}.value = $$name
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index e1afa426ed..e546c817a7 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -60,3 +60,6 @@ manifestmeta.highlighted.names = "QtGui/Analog Clock Window Example"
navigation.landingpage = "Qt GUI"
navigation.cppclassespage = "Qt GUI C++ Classes"
+
+# Ignore warnings about undocumented enum values for the QGradient presets
+spurious += "Undocumented enum item '.*' in QGradient::Preset"
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 76aba944b2..70fccbc378 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -9,6 +9,7 @@ HEADERS += \
image/qimage_p.h \
image/qimageiohandler.h \
image/qimagereader.h \
+ image/qimagereaderwriterhelpers_p.h \
image/qimagewriter.h \
image/qpaintengine_pic_p.h \
image/qpicture.h \
@@ -33,6 +34,7 @@ SOURCES += \
image/qimage_conversions.cpp \
image/qimageiohandler.cpp \
image/qimagereader.cpp \
+ image/qimagereaderwriterhelpers.cpp \
image/qimagewriter.cpp \
image/qpaintengine_pic.cpp \
image/qpicture.cpp \
@@ -80,10 +82,7 @@ qtConfig(png) {
}
# SIMD
-SSE2_SOURCES += image/qimage_sse2.cpp
SSSE3_SOURCES += image/qimage_ssse3.cpp
-SSE4_1_SOURCES += image/qimage_sse4.cpp
-AVX2_SOURCES += image/qimage_avx2.cpp
NEON_SOURCES += image/qimage_neon.cpp
MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp
index e8405a6d11..2453242fa8 100644
--- a/src/gui/image/qbitmap.cpp
+++ b/src/gui/image/qbitmap.cpp
@@ -189,9 +189,7 @@ QBitmap &QBitmap::operator=(const QPixmap &pixmap)
} else if (pixmap.depth() == 1) { // 1-bit pixmap
QPixmap::operator=(pixmap); // shallow assignment
} else { // n-bit depth pixmap
- QImage image;
- image = pixmap.toImage(); // convert pixmap to image
- *this = fromImage(image); // will dither image
+ *this = fromImage(pixmap.toImage()); // will dither image
}
return *this;
}
@@ -223,6 +221,24 @@ QBitmap::operator QVariant() const
return QVariant(QVariant::Bitmap, this);
}
+static QBitmap makeBitmap(QImage &&image, Qt::ImageConversionFlags flags)
+{
+ // make sure image.color(0) == Qt::color0 (white)
+ // and image.color(1) == Qt::color1 (black)
+ const QRgb c0 = QColor(Qt::black).rgb();
+ const QRgb c1 = QColor(Qt::white).rgb();
+ if (image.color(0) == c0 && image.color(1) == c1) {
+ image.invertPixels();
+ image.setColor(0, c1);
+ image.setColor(1, c0);
+ }
+
+ QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType));
+
+ data->fromImageInPlace(image, flags | Qt::MonoOnly);
+ return QPixmap(data.take());
+}
+
/*!
Returns a copy of the given \a image converted to a bitmap using
the specified image conversion \a flags.
@@ -234,22 +250,24 @@ QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QBitmap();
- QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags);
+ return makeBitmap(image.convertToFormat(QImage::Format_MonoLSB, flags), flags);
+}
- // make sure image.color(0) == Qt::color0 (white)
- // and image.color(1) == Qt::color1 (black)
- const QRgb c0 = QColor(Qt::black).rgb();
- const QRgb c1 = QColor(Qt::white).rgb();
- if (img.color(0) == c0 && img.color(1) == c1) {
- img.invertPixels();
- img.setColor(0, c1);
- img.setColor(1, c0);
- }
+/*!
+ \since 5.12
+ \overload
- QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType));
+ Returns a copy of the given \a image converted to a bitmap using
+ the specified image conversion \a flags.
- data->fromImage(img, flags | Qt::MonoOnly);
- return QPixmap(data.take());
+ \sa fromData()
+*/
+QBitmap QBitmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
+{
+ if (image.isNull())
+ return QBitmap();
+
+ return makeBitmap(std::move(image).convertToFormat(QImage::Format_MonoLSB, flags), flags);
}
/*!
@@ -277,7 +295,7 @@ QBitmap QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format m
int bytesPerLine = (size.width() + 7) / 8;
for (int y = 0; y < size.height(); ++y)
memcpy(image.scanLine(y), bits + bytesPerLine * y, bytesPerLine);
- return QBitmap::fromImage(image);
+ return QBitmap::fromImage(std::move(image));
}
/*!
diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h
index 6a8c8b3457..188064fccf 100644
--- a/src/gui/image/qbitmap.h
+++ b/src/gui/image/qbitmap.h
@@ -72,6 +72,7 @@ public:
inline void clear() { fill(Qt::color0); }
static QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ static QBitmap fromImage(QImage &&image, Qt::ImageConversionFlags flags = Qt::AutoColor);
static QBitmap fromData(const QSize &size, const uchar *bits,
QImage::Format monoFormat = QImage::Format_MonoLSB);
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index 32fa9e75ac..14a0248600 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -1194,7 +1194,7 @@ void QIcon::setFallbackSearchPaths(const QStringList &paths)
The \a name should correspond to a directory name in the
themeSearchPath() containing an index.theme
- file describing it's contents.
+ file describing its contents.
\sa themeSearchPaths(), themeName()
*/
@@ -1220,6 +1220,37 @@ QString QIcon::themeName()
}
/*!
+ \since 5.12
+
+ Returns the name of the fallback icon theme.
+
+ On X11, if not set, the fallback icon theme depends on your desktop
+ settings. On other platforms it is not set by default.
+
+ \sa setFallbackThemeName(), themeName()
+*/
+QString QIcon::fallbackThemeName()
+{
+ return QIconLoader::instance()->fallbackThemeName();
+}
+
+/*!
+ \since 5.12
+
+ Sets the fallback icon theme to \a name.
+
+ The \a name should correspond to a directory name in the
+ themeSearchPath() containing an index.theme
+ file describing its contents.
+
+ \sa fallbackThemeName(), themeSearchPaths(), themeName()
+*/
+void QIcon::setFallbackThemeName(const QString &name)
+{
+ QIconLoader::instance()->setFallbackThemeName(name);
+}
+
+/*!
\since 4.6
Returns the QIcon corresponding to \a name in the current
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 653ba6fda4..6a4fc8927a 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -124,6 +124,9 @@ public:
static QString themeName();
static void setThemeName(const QString &path);
+ static QString fallbackThemeName();
+ static void setFallbackThemeName(const QString &name);
+
Q_DUMMY_COMPARISON_OPERATOR(QIcon)
private:
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 1ea4f1340b..228de3adc3 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance)
/* Theme to use in last resort, if the theme does not have the icon, neither the parents */
-static QString fallbackTheme()
+static QString systemFallbackThemeName()
{
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
const QVariant themeHint = theme->themeHint(QPlatformTheme::SystemIconFallbackThemeName);
@@ -117,7 +117,7 @@ void QIconLoader::ensureInitialized()
m_systemTheme = systemThemeName();
if (m_systemTheme.isEmpty())
- m_systemTheme = fallbackTheme();
+ m_systemTheme = systemFallbackThemeName();
if (qt_iconEngineFactoryLoader()->keyMap().key(QLatin1String("svg"), -1) != -1)
m_supportsSvg = true;
}
@@ -137,7 +137,7 @@ void QIconLoader::updateSystemTheme()
if (m_userTheme.isEmpty()) {
QString theme = systemThemeName();
if (theme.isEmpty())
- theme = fallbackTheme();
+ theme = fallbackThemeName();
if (theme != m_systemTheme) {
m_systemTheme = theme;
invalidateKey();
@@ -151,6 +151,16 @@ void QIconLoader::setThemeName(const QString &themeName)
invalidateKey();
}
+QString QIconLoader::fallbackThemeName() const
+{
+ return m_userFallbackTheme.isEmpty() ? systemFallbackThemeName() : m_userFallbackTheme;
+}
+
+void QIconLoader::setFallbackThemeName(const QString &themeName)
+{
+ m_userFallbackTheme = themeName;
+}
+
void QIconLoader::setThemeSearchPath(const QStringList &searchPaths)
{
m_iconDirs = searchPaths;
@@ -388,7 +398,7 @@ QIconTheme::QIconTheme(const QString &themeName)
// Ensure a default platform fallback for all themes
if (m_parents.isEmpty()) {
- const QString fallback = fallbackTheme();
+ const QString fallback = QIconLoader::instance()->fallbackThemeName();
if (!fallback.isEmpty())
m_parents.append(fallback);
}
@@ -414,7 +424,7 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName,
if (!theme.isValid()) {
theme = QIconTheme(themeName);
if (!theme.isValid())
- theme = QIconTheme(fallbackTheme());
+ theme = QIconTheme(fallbackThemeName());
}
const QStringList contentDirs = theme.contentDirs();
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
index 746e871fb1..fac18b5d79 100644
--- a/src/gui/image/qiconloader_p.h
+++ b/src/gui/image/qiconloader_p.h
@@ -177,6 +177,8 @@ public:
QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; }
void setThemeName(const QString &themeName);
+ QString fallbackThemeName() const;
+ void setFallbackThemeName(const QString &themeName);
QIconTheme theme() { return themeList.value(themeName()); }
void setThemeSearchPath(const QStringList &searchPaths);
QStringList themeSearchPaths() const;
@@ -200,6 +202,7 @@ private:
bool m_initialized;
mutable QString m_userTheme;
+ mutable QString m_userFallbackTheme;
mutable QString m_systemTheme;
mutable QStringList m_iconDirs;
mutable QHash <QString, QIconTheme> themeList;
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 7fcae12cbd..8a4c6b7fda 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -277,6 +277,16 @@ bool QImageData::checkForAlphaPixels() const
bits += bytes_per_line;
}
} break;
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied: {
+ uchar *bits = data;
+ for (int y=0; y<height && !has_alpha_pixels; ++y) {
+ for (int x=0; x<width; ++x) {
+ has_alpha_pixels |= !(((QRgba64 *)bits)[x].isOpaque());
+ }
+ bits += bytes_per_line;
+ }
+ } break;
case QImage::Format_RGB32:
case QImage::Format_RGB16:
@@ -288,6 +298,7 @@ bool QImageData::checkForAlphaPixels() const
case QImage::Format_BGR30:
case QImage::Format_RGB30:
case QImage::Format_Grayscale8:
+ case QImage::Format_RGBX64:
break;
case QImage::Format_Invalid:
case QImage::NImageFormats:
@@ -651,11 +662,7 @@ bool QImageData::checkForAlphaPixels() const
/*!
\enum QImage::Format
- The following image formats are available in Qt. Values from Format_ARGB8565_Premultiplied
- to Format_ARGB4444_Premultiplied were added in Qt 4.4. Values Format_RGBX8888, Format_RGBA8888
- and Format_RGBA8888_Premultiplied were added in Qt 5.2. Values Format_BGR30, Format_A2BGR30_Premultiplied,
- Format_RGB30, Format_A2RGB30_Premultiplied were added in Qt 5.4. Format_Alpha8 and Format_Grayscale8
- were added in Qt 5.5.
+ The following image formats are available in Qt.
See the notes after the table.
\value Format_Invalid The image is invalid.
@@ -699,29 +706,32 @@ bool QImageData::checkForAlphaPixels() const
\value Format_ARGB4444_Premultiplied The image is stored using a
premultiplied 16-bit ARGB format (4-4-4-4).
\value Format_RGBX8888 The image is stored using a 32-bit byte-ordered RGB(x) format (8-8-8-8).
- This is the same as the Format_RGBA8888 except alpha must always be 255.
+ This is the same as the Format_RGBA8888 except alpha must always be 255. (added in Qt 5.2)
\value Format_RGBA8888 The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8).
Unlike ARGB32 this is a byte-ordered format, which means the 32bit
encoding differs between big endian and little endian architectures,
being respectively (0xRRGGBBAA) and (0xAABBGGRR). The order of the colors
- is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA.
+ is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA. (added in Qt 5.2)
\value Format_RGBA8888_Premultiplied The image is stored using a
- premultiplied 32-bit byte-ordered RGBA format (8-8-8-8).
- \value Format_BGR30 The image is stored using a 32-bit BGR format (x-10-10-10).
- \value Format_A2BGR30_Premultiplied The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10).
- \value Format_RGB30 The image is stored using a 32-bit RGB format (x-10-10-10).
- \value Format_A2RGB30_Premultiplied The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10).
- \value Format_Alpha8 The image is stored using an 8-bit alpha only format.
- \value Format_Grayscale8 The image is stored using an 8-bit grayscale format.
+ premultiplied 32-bit byte-ordered RGBA format (8-8-8-8). (added in Qt 5.2)
+ \value Format_BGR30 The image is stored using a 32-bit BGR format (x-10-10-10). (added in Qt 5.4)
+ \value Format_A2BGR30_Premultiplied The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10). (added in Qt 5.4)
+ \value Format_RGB30 The image is stored using a 32-bit RGB format (x-10-10-10). (added in Qt 5.4)
+ \value Format_A2RGB30_Premultiplied The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10). (added in Qt 5.4)
+ \value Format_Alpha8 The image is stored using an 8-bit alpha only format. (added in Qt 5.5)
+ \value Format_Grayscale8 The image is stored using an 8-bit grayscale format. (added in Qt 5.5)
+ \value Format_RGBX64 The image is stored using a 64-bit halfword-ordered RGB(x) format (16-16-16-16).
+ This is the same as the Format_RGBX64 except alpha must always be 65535. (added in Qt 5.12)
+ \value Format_RGBA64 The image is stored using a 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12)
+ \value Format_RGBA64_Premultiplied The image is stored using a premultiplied 64-bit halfword-ordered
+ RGBA format (16-16-16-16). (added in Qt 5.12)
\note Drawing into a QImage with QImage::Format_Indexed8 is not
supported.
- \note Do not render into ARGB32 images using QPainter. Using
- QImage::Format_ARGB32_Premultiplied is significantly faster.
-
- \note Formats with more than 8 bit per color channel will only be processed by the raster engine using 8 bit
- per color.
+ \note Avoid most rendering directly to most of these formats using QPainter. Rendering
+ is best optimized to the \c Format_RGB32 and \c Format_ARGB32_Premultiplied formats, and secondarily for rendering to the
+ \c Format_RGB16, \c Format_RGBX8888, \c Format_RGBA8888_Premultiplied, \c Format_RGBX64 and \c Format_RGBA64_Premultiplied formats
\sa format(), convertToFormat()
*/
@@ -1708,6 +1718,10 @@ void QImage::fill(uint pixel)
qt_rectfill<quint24>(reinterpret_cast<quint24*>(d->data), pixel,
0, 0, d->width, d->height, d->bytes_per_line);
return;
+ } else if (d->depth == 64) {
+ qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), QRgba64::fromArgb32(pixel),
+ 0, 0, d->width, d->height, d->bytes_per_line);
+ return;
}
if (d->format == Format_RGB32)
@@ -1815,6 +1829,19 @@ void QImage::fill(const QColor &color)
else
fill((uint) 0);
break;
+ case QImage::Format_RGBX64: {
+ QRgba64 c = color.rgba64();
+ c.setAlpha(65535);
+ qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), c,
+ 0, 0, d->width, d->height, d->bytes_per_line);
+ break;
+
+ }
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), color.rgba64(),
+ 0, 0, d->width, d->height, d->bytes_per_line);
+ break;
default: {
QPainter p(this);
p.setCompositionMode(QPainter::CompositionMode_Source);
@@ -1838,7 +1865,8 @@ void QImage::fill(const QColor &color)
changed.
If the image has a premultiplied alpha channel, the image is first
- converted to ARGB32 to be inverted and then converted back.
+ converted to an unpremultiplied image format to be inverted and
+ then converted back.
\sa {QImage#Image Transformations}{Image Transformations}
*/
@@ -1857,8 +1885,13 @@ void QImage::invertPixels(InvertMode mode)
QImage::Format originalFormat = d->format;
// Inverting premultiplied pixels would produce invalid image data.
if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied) {
- if (!d->convertInPlace(QImage::Format_ARGB32, 0))
- *this = convertToFormat(QImage::Format_ARGB32);
+ if (depth() > 32) {
+ if (!d->convertInPlace(QImage::Format_RGBA64, 0))
+ *this = convertToFormat(QImage::Format_RGBA64);
+ } else {
+ if (!d->convertInPlace(QImage::Format_ARGB32, 0))
+ *this = convertToFormat(QImage::Format_ARGB32);
+ }
}
if (depth() < 32) {
@@ -1871,6 +1904,20 @@ void QImage::invertPixels(InvertMode mode)
*sl++ ^= 0xff;
sl += pad;
}
+ }
+ else if (depth() == 64) {
+ quint16 *p = (quint16*)d->data;
+ quint16 *end = (quint16*)(d->data + d->nbytes);
+ quint16 xorbits = 0xffff;
+ while (p < end) {
+ *p++ ^= xorbits;
+ *p++ ^= xorbits;
+ *p++ ^= xorbits;
+ if (mode == InvertRgba)
+ *p++ ^= xorbits;
+ else
+ p++;
+ }
} else {
quint32 *p = (quint32*)d->data;
quint32 *end = (quint32*)(d->data + d->nbytes);
@@ -1987,6 +2034,26 @@ QImage::Format QImage::format() const
\sa {Image Formats}
*/
+static bool highColorPrecision(QImage::Format format)
+{
+ // Formats with higher color precision than ARGB32_Premultiplied.
+ switch (format) {
+ case QImage::Format_ARGB32:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_BGR30:
+ case QImage::Format_RGB30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ case QImage::Format_A2RGB30_Premultiplied:
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
/*!
\internal
*/
@@ -1999,8 +2066,18 @@ QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags fl
return QImage();
Image_Converter converter = qimage_converter_map[d->format][format];
- if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8)
- converter = convert_generic;
+ if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8) {
+ if (highColorPrecision(format) && highColorPrecision(d->format)) {
+ // Convert over RGBA64_Premultiplied
+ if (format == QImage::Format_RGBA64_Premultiplied)
+ converter = convert_generic_to_rgb64;
+ else {
+ Q_ASSERT(d->format != QImage::Format_RGBA64_Premultiplied);
+ return convertToFormat(Format_RGBA64_Premultiplied, flags).convertToFormat(format, flags);
+ }
+ } else
+ converter = convert_generic;
+ }
if (converter) {
QImage image(d->width, d->height, format);
@@ -2298,13 +2375,16 @@ QRgb QImage::pixel(int x, int y) const
return qConvertA2rgb30ToArgb32<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
case Format_RGB16:
return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]);
+ case Format_RGBX64:
+ case Format_RGBA64: // Match ARGB32 behavior.
+ case Format_RGBA64_Premultiplied:
+ return reinterpret_cast<const QRgba64 *>(s)[x].toArgb32();
default:
break;
}
const QPixelLayout *layout = &qPixelLayouts[d->format];
uint result;
- const uint *ptr = qFetchPixels[layout->bpp](&result, s, x, 1);
- return *layout->convertToARGB32PM(&result, ptr, 1, 0, 0);
+ return *layout->fetchToARGB32PM(&result, s, x, 1, nullptr, nullptr);
}
/*!
@@ -2405,9 +2485,7 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
}
const QPixelLayout *layout = &qPixelLayouts[d->format];
- uint result;
- const uint *ptr = layout->convertFromARGB32PM(&result, &index_or_rgb, 1, 0, 0);
- qStorePixels[layout->bpp](s, ptr, x, 1);
+ layout->storeFromARGB32PM(s, &index_or_rgb, x, 1, nullptr, nullptr);
}
/*!
@@ -2450,6 +2528,11 @@ QColor QImage::pixelColor(int x, int y) const
case Format_A2RGB30_Premultiplied:
c = qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
break;
+ case Format_RGBX64:
+ case Format_RGBA64:
+ case Format_RGBA64_Premultiplied:
+ c = reinterpret_cast<const QRgba64 *>(s)[x];
+ break;
default:
c = QRgba64::fromArgb32(pixel(x, y));
break;
@@ -2520,6 +2603,14 @@ void QImage::setPixelColor(int x, int y, const QColor &color)
case Format_A2RGB30_Premultiplied:
((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c);
return;
+ case Format_RGBX64:
+ ((QRgba64 *)s)[x] = color.rgba64();
+ ((QRgba64 *)s)[x].setAlpha(65535);
+ return;
+ case Format_RGBA64:
+ case Format_RGBA64_Premultiplied:
+ ((QRgba64 *)s)[x] = color.rgba64();
+ return;
default:
setPixel(x, y, c.toArgb32());
return;
@@ -2582,17 +2673,15 @@ bool QImage::allGray() const
break;
}
- const int buffer_size = 2048;
- uint buffer[buffer_size];
+ uint buffer[BufferSize];
const QPixelLayout *layout = &qPixelLayouts[d->format];
- FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
+ const auto fetch = layout->fetchToARGB32PM;
for (int j = 0; j < d->height; ++j) {
const uchar *b = constScanLine(j);
int x = 0;
while (x < d->width) {
- int l = qMin(d->width - x, buffer_size);
- const uint *ptr = fetch(buffer, b, x, l);
- ptr = layout->convertToARGB32PM(buffer, ptr, l, 0, 0);
+ int l = qMin(d->width - x, BufferSize);
+ const uint *ptr = fetch(buffer, b, x, l, nullptr, nullptr);
for (int i = 0; i < l; ++i) {
if (!qIsGray(ptr[i]))
return false;
@@ -2780,6 +2869,13 @@ QMatrix QImage::trueMatrix(const QMatrix &matrix, int w, int h)
Returns a copy of the image that is transformed using the given
transformation \a matrix and transformation \a mode.
+ The returned image will normally have the same {Image Formats}{format} as
+ the original image. However, a complex transformation may result in an
+ image where not all pixels are covered by the transformed pixels of the
+ original image. In such cases, those background pixels will be assigned a
+ transparent color value, and the transformed image will be given a format
+ with an alpha channel, even if the orginal image did not have that.
+
The transformation \a matrix is internally adjusted to compensate
for unwanted translation; i.e. the image produced is the smallest
image that contains all the transformed points of the original
@@ -3098,6 +3194,9 @@ inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool ve
}
switch (depth) {
+ case 64:
+ do_mirror_data<quint64>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
+ break;
case 32:
do_mirror_data<quint32>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
break;
@@ -3210,33 +3309,18 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical)
inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
{
- Q_ASSERT(layout->redWidth == layout->blueWidth);
- FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
- StorePixelsFunc store = qStorePixels[layout->bpp];
-
- const uint redBlueMask = (1 << layout->redWidth) - 1;
- const uint alphaGreenMask = (((1 << layout->alphaWidth) - 1) << layout->alphaShift)
- | (((1 << layout->greenWidth) - 1) << layout->greenShift);
+ const RbSwapFunc func = layout->rbSwap;
+ if (!func) {
+ qWarning("Trying to rb-swap an image format where it doesn't make sense");
+ if (src != dst)
+ *dst = *src;
+ return;
+ }
- const int buffer_size = 2048;
- uint buffer[buffer_size];
for (int i = 0; i < height; ++i) {
uchar *q = dst->scanLine(i);
const uchar *p = src->constScanLine(i);
- int x = 0;
- while (x < width) {
- int l = qMin(width - x, buffer_size);
- const uint *ptr = fetch(buffer, p, x, l);
- for (int j = 0; j < l; ++j) {
- uint red = (ptr[j] >> layout->redShift) & redBlueMask;
- uint blue = (ptr[j] >> layout->blueShift) & redBlueMask;
- buffer[j] = (ptr[j] & alphaGreenMask)
- | (red << layout->blueShift)
- | (blue << layout->redShift);
- }
- store(q, buffer, x, l);
- x += l;
- }
+ func(q, p, width);
}
}
@@ -3321,18 +3405,18 @@ QImage QImage::rgbSwapped_helper() const
}
}
break;
- case Format_BGR30:
- case Format_A2BGR30_Premultiplied:
- case Format_RGB30:
- case Format_A2RGB30_Premultiplied:
+ case Format_RGBX64:
+ case Format_RGBA64:
+ case Format_RGBA64_Premultiplied:
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
- uint *q = (uint*)res.scanLine(i);
- const uint *p = (const uint*)constScanLine(i);
- const uint *end = p + d->width;
+ QRgba64 *q = reinterpret_cast<QRgba64 *>(res.scanLine(i));
+ const QRgba64 *p = reinterpret_cast<const QRgba64 *>(constScanLine(i));
+ const QRgba64 *end = p + d->width;
while (p < end) {
- *q = qRgbSwapRgb30(*p);
+ QRgba64 c = *p;
+ *q = QRgba64::fromRgba64(c.blue(), c.green(), c.red(), c.alpha());
p++;
q++;
}
@@ -3430,6 +3514,19 @@ void QImage::rgbSwapped_inplace()
}
}
break;
+ case Format_RGBX64:
+ case Format_RGBA64:
+ case Format_RGBA64_Premultiplied:
+ for (int i = 0; i < d->height; i++) {
+ QRgba64 *p = reinterpret_cast<QRgba64 *>(scanLine(i));
+ QRgba64 *end = p + d->width;
+ while (p < end) {
+ QRgba64 c = *p;
+ *p = QRgba64::fromRgba64(c.blue(), c.green(), c.red(), c.alpha());
+ p++;
+ }
+ }
+ break;
default:
rgbSwapped_generic(d->width, d->height, this, this, &qPixelLayouts[d->format]);
break;
@@ -3457,8 +3554,7 @@ void QImage::rgbSwapped_inplace()
bool QImage::load(const QString &fileName, const char* format)
{
- QImage image = QImageReader(fileName, format).read();
- operator=(image);
+ *this = QImageReader(fileName, format).read();
return !isNull();
}
@@ -3471,8 +3567,7 @@ bool QImage::load(const QString &fileName, const char* format)
bool QImage::load(QIODevice* device, const char* format)
{
- QImage image = QImageReader(device, format).read();
- operator=(image);
+ *this = QImageReader(device, format).read();
return !isNull();
}
@@ -3492,8 +3587,7 @@ bool QImage::load(QIODevice* device, const char* format)
bool QImage::loadFromData(const uchar *data, int len, const char *format)
{
- QImage image = fromData(data, len, format);
- operator=(image);
+ *this = fromData(data, len, format);
return !isNull();
}
@@ -4506,6 +4600,9 @@ int QImage::bitPlaneCount() const
case QImage::Format_RGB444:
bpc = 12;
break;
+ case QImage::Format_RGBX64:
+ bpc = 48;
+ break;
default:
bpc = qt_depthForFormat(d->format);
break;
@@ -4526,6 +4623,11 @@ QImage QImage::smoothScaled(int w, int h) const {
case QImage::Format_RGBX8888:
#endif
case QImage::Format_RGBA8888_Premultiplied:
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64_Premultiplied:
+ break;
+ case QImage::Format_RGBA64:
+ src = src.convertToFormat(QImage::Format_RGBA64_Premultiplied);
break;
default:
if (src.hasAlphaChannel())
@@ -4610,6 +4712,13 @@ static QImage rotated270(const QImage &image)
Returns a copy of the image that is transformed using the given
transformation \a matrix and transformation \a mode.
+ The returned image will normally have the same {Image Formats}{format} as
+ the original image. However, a complex transformation may result in an
+ image where not all pixels are covered by the transformed pixels of the
+ original image. In such cases, those background pixels will be assigned a
+ transparent color value, and the transformed image will be given a format
+ with an alpha channel, even if the orginal image did not have that.
+
The transformation \a matrix is internally adjusted to compensate
for unwanted translation; i.e. the image produced is the smallest
image that contains all the transformed points of the original
@@ -5197,6 +5306,45 @@ static Q_CONSTEXPR QPixelFormat pixelformats[] = {
/*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
/*INTERPRETATION*/ QPixelFormat::UnsignedByte,
/*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
+ //QImage::Format_RGBX64:
+ QPixelFormat(QPixelFormat::RGB,
+ /*RED*/ 16,
+ /*GREEN*/ 16,
+ /*BLUE*/ 16,
+ /*FOURTH*/ 0,
+ /*FIFTH*/ 0,
+ /*ALPHA*/ 16,
+ /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
+ /*ALPHA POSITION*/ QPixelFormat::AtEnd,
+ /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
+ /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
+ /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
+ //QImage::Format_RGBA64:
+ QPixelFormat(QPixelFormat::RGB,
+ /*RED*/ 16,
+ /*GREEN*/ 16,
+ /*BLUE*/ 16,
+ /*FOURTH*/ 0,
+ /*FIFTH*/ 0,
+ /*ALPHA*/ 16,
+ /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
+ /*ALPHA POSITION*/ QPixelFormat::AtEnd,
+ /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
+ /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
+ /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
+ //QImage::Format_RGBA64_Premultiplied:
+ QPixelFormat(QPixelFormat::RGB,
+ /*RED*/ 16,
+ /*GREEN*/ 16,
+ /*BLUE*/ 16,
+ /*FOURTH*/ 0,
+ /*FIFTH*/ 0,
+ /*ALPHA*/ 16,
+ /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
+ /*ALPHA POSITION*/ QPixelFormat::AtEnd,
+ /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
+ /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
+ /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
};
Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats);
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 9b76b62f24..4b7a3b1ead 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -96,6 +96,7 @@ typedef void (*QImageCleanupFunction)(void*);
class Q_GUI_EXPORT QImage : public QPaintDevice
{
+ Q_GADGET
public:
enum InvertMode { InvertRgb, InvertRgba };
enum Format {
@@ -124,6 +125,9 @@ public:
Format_A2RGB30_Premultiplied,
Format_Alpha8,
Format_Grayscale8,
+ Format_RGBX64,
+ Format_RGBA64,
+ Format_RGBA64_Premultiplied,
#if 0
// reserved for future use
Format_Grayscale16,
@@ -132,6 +136,7 @@ public:
NImageFormats
#endif
};
+ Q_ENUM(Format)
QImage() Q_DECL_NOEXCEPT;
QImage(const QSize &size, Format format);
@@ -329,7 +334,7 @@ public:
static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW;
static QImage::Format toImageFormat(QPixelFormat format) Q_DECL_NOTHROW;
- // Platform spesific conversion functions
+ // Platform specific conversion functions
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
CGImageRef toCGImage() const Q_DECL_CF_RETURNS_RETAINED;
#endif
diff --git a/src/gui/image/qimage_avx2.cpp b/src/gui/image/qimage_avx2.cpp
deleted file mode 100644
index 0519f17c5d..0000000000
--- a/src/gui/image/qimage_avx2.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qimage.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qimage_p.h>
-#include <private/qsimd_p.h>
-
-#ifdef QT_COMPILER_SUPPORTS_AVX2
-
-QT_BEGIN_NAMESPACE
-
-void convert_ARGB_to_ARGB_PM_avx2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const uint *src_data = (uint *) src->data;
- uint *dest_data = (uint *) dest->data;
- for (int i = 0; i < src->height; ++i) {
- qt_convertARGB32ToARGB32PM(dest_data, src_data, src->width);
- src_data += src->bytes_per_line >> 2;
- dest_data += dest->bytes_per_line >> 2;
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_COMPILER_SUPPORTS_AVX2
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index d981c43711..e1f66dceee 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -118,26 +118,35 @@ void qGamma_correct_back_to_linear_cs(QImage *image)
Internal routines for converting image depth.
*****************************************************************************/
-// The drawhelper conversions from/to RGB32 are passthroughs which is not always correct for general image conversion.
-static const uint *QT_FASTCALL convertRGB32FromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+// The drawhelper conversions from/to RGB32 are passthroughs which is not always correct for general image conversion
+static void QT_FASTCALL storeRGB32FromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
- buffer[i] = 0xff000000 | qUnpremultiply(src[i]);
- return buffer;
+ d[i] = 0xff000000 | qUnpremultiply(src[i]);
+}
+
+static void QT_FASTCALL storeRGB32FromARGB32(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ for (int i = 0; i < count; ++i)
+ d[i] = 0xff000000 | src[i];
}
-static const uint *QT_FASTCALL maskRGB32(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static const uint *QT_FASTCALL fetchRGB32ToARGB32PM(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
+ const uint *s = reinterpret_cast<const uint *>(src) + index;
for (int i = 0; i < count; ++i)
- buffer[i] = 0xff000000 |src[i];
+ buffer[i] = 0xff000000 | s[i];
return buffer;
}
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
-extern const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *);
+extern void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
#endif
void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
@@ -145,42 +154,39 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
// Cannot be used with indexed formats.
Q_ASSERT(dest->format > QImage::Format_Indexed8);
Q_ASSERT(src->format > QImage::Format_Indexed8);
- const int buffer_size = 2048;
- uint buf[buffer_size];
+ uint buf[BufferSize];
uint *buffer = buf;
const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
const uchar *srcData = src->data;
uchar *destData = dest->data;
- const FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
- const StorePixelsFunc store = qStorePixels[destLayout->bpp];
- ConvertFunc convertToARGB32PM = srcLayout->convertToARGB32PM;
- ConvertFunc convertFromARGB32PM = destLayout->convertFromARGB32PM;
- if (srcLayout->alphaWidth == 0 && destLayout->convertFromRGB32) {
- // If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method.
- convertFromARGB32PM = destLayout->convertFromRGB32;
+ FetchAndConvertPixelsFunc fetch = srcLayout->fetchToARGB32PM;
+ ConvertAndStorePixelsFunc store = destLayout->storeFromARGB32PM;
+ if (!srcLayout->hasAlphaChannel && destLayout->storeFromRGB32) {
+ // If the source doesn't have an alpha channel, we can use the faster storeFromRGB32 method.
+ store = destLayout->storeFromRGB32;
} else {
// The drawhelpers do not mask the alpha value in RGB32, we want to here.
if (src->format == QImage::Format_RGB32)
- convertToARGB32PM = maskRGB32;
+ fetch = fetchRGB32ToARGB32PM;
if (dest->format == QImage::Format_RGB32) {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
- convertFromARGB32PM = convertRGB32FromARGB32PM_sse4;
+ store = storeRGB32FromARGB32PM_sse4;
else
#endif
- convertFromARGB32PM = convertRGB32FromARGB32PM;
+ store = storeRGB32FromARGB32PM;
}
}
- if ((src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888) &&
- destLayout->alphaWidth == 0 && destLayout->convertFromRGB32) {
+ if (srcLayout->hasAlphaChannel && !srcLayout->premultiplied &&
+ !destLayout->hasAlphaChannel && destLayout->storeFromRGB32) {
// Avoid unnecessary premultiply and unpremultiply when converting from unpremultiplied src format.
- convertToARGB32PM = qPixelLayouts[src->format + 1].convertToARGB32PM;
+ fetch = qPixelLayouts[src->format + 1].fetchToARGB32PM;
if (dest->format == QImage::Format_RGB32)
- convertFromARGB32PM = maskRGB32;
+ store = storeRGB32FromARGB32;
else
- convertFromARGB32PM = destLayout->convertFromRGB32;
+ store = destLayout->storeFromRGB32;
}
QDitherInfo dither;
QDitherInfo *ditherPtr = 0;
@@ -196,12 +202,9 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
if (destLayout->bpp == QPixelLayout::BPP32)
buffer = reinterpret_cast<uint *>(destData) + x;
else
- l = qMin(l, buffer_size);
- const uint *ptr = fetch(buffer, srcData, x, l);
- ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr);
- ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr);
- if (ptr != reinterpret_cast<uint *>(destData))
- store(destData, ptr, x, l);
+ l = qMin(l, BufferSize);
+ const uint *ptr = fetch(buffer, srcData, x, l, 0, ditherPtr);
+ store(destData, ptr, x, l, 0, ditherPtr);
x += l;
}
srcData += src->bytes_per_line;
@@ -209,6 +212,26 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
}
}
+void convert_generic_to_rgb64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(dest->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(src->format > QImage::Format_Indexed8);
+ const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
+ const uchar *srcData = src->data;
+ uchar *destData = dest->data;
+
+ const FetchAndConvertPixelsFunc64 fetch = srcLayout->fetchToRGBA64PM;
+
+ for (int y = 0; y < src->height; ++y) {
+ const QRgba64 *ptr = fetch((QRgba64*)destData, srcData, 0, src->width, nullptr, nullptr);
+ if (ptr != (const QRgba64*)destData) {
+ memcpy(destData, ptr, dest->bytes_per_line);
+ }
+ srcData += src->bytes_per_line;
+ destData += dest->bytes_per_line;
+ }
+}
+
bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags flags)
{
// Cannot be used with indexed formats or between formats with different pixel depths.
@@ -217,39 +240,39 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
if (data->depth != qt_depthForFormat(dst_format))
return false;
- const int buffer_size = 2048;
- uint buffer[buffer_size];
+ uint buf[BufferSize];
+ uint *buffer = buf;
const QPixelLayout *srcLayout = &qPixelLayouts[data->format];
const QPixelLayout *destLayout = &qPixelLayouts[dst_format];
uchar *srcData = data->data;
- const FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
- const StorePixelsFunc store = qStorePixels[destLayout->bpp];
- ConvertFunc convertToARGB32PM = srcLayout->convertToARGB32PM;
- ConvertFunc convertFromARGB32PM = destLayout->convertFromARGB32PM;
- if (srcLayout->alphaWidth == 0 && destLayout->convertFromRGB32) {
- // If the source doesn't have an alpha channel, we can use the faster convertFromRGB32 method.
- convertFromARGB32PM = destLayout->convertFromRGB32;
+ Q_ASSERT(srcLayout->bpp == destLayout->bpp);
+ Q_ASSERT(srcLayout->bpp != QPixelLayout::BPP64);
+ FetchAndConvertPixelsFunc fetch = srcLayout->fetchToARGB32PM;
+ ConvertAndStorePixelsFunc store = destLayout->storeFromARGB32PM;
+ if (!srcLayout->hasAlphaChannel && destLayout->storeFromRGB32) {
+ // If the source doesn't have an alpha channel, we can use the faster storeFromRGB32 method.
+ store = destLayout->storeFromRGB32;
} else {
if (data->format == QImage::Format_RGB32)
- convertToARGB32PM = maskRGB32;
+ fetch = fetchRGB32ToARGB32PM;
if (dst_format == QImage::Format_RGB32) {
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
if (qCpuHasFeature(SSE4_1))
- convertFromARGB32PM = convertRGB32FromARGB32PM_sse4;
+ store = storeRGB32FromARGB32PM_sse4;
else
#endif
- convertFromARGB32PM = convertRGB32FromARGB32PM;
+ store = storeRGB32FromARGB32PM;
}
}
- if ((data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888) &&
- destLayout->alphaWidth == 0 && destLayout->convertFromRGB32) {
+ if (srcLayout->hasAlphaChannel && !srcLayout->premultiplied &&
+ !destLayout->hasAlphaChannel && destLayout->storeFromRGB32) {
// Avoid unnecessary premultiply and unpremultiply when converting from unpremultiplied src format.
- convertToARGB32PM = qPixelLayouts[data->format + 1].convertToARGB32PM;
- if (dst_format == QImage::Format_RGB32)
- convertFromARGB32PM = maskRGB32;
+ fetch = qPixelLayouts[data->format + 1].fetchToARGB32PM;
+ if (data->format == QImage::Format_RGB32)
+ store = storeRGB32FromARGB32;
else
- convertFromARGB32PM = destLayout->convertFromRGB32;
+ store = destLayout->storeFromRGB32;
}
QDitherInfo dither;
QDitherInfo *ditherPtr = 0;
@@ -261,13 +284,13 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
int x = 0;
while (x < data->width) {
dither.x = x;
- int l = qMin(data->width - x, buffer_size);
- const uint *ptr = fetch(buffer, srcData, x, l);
- ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr);
- ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr);
- // The conversions might be passthrough and not use the buffer, in that case we are already done.
- if (srcData != (const uchar*)ptr)
- store(srcData, ptr, x, l);
+ int l = data->width - x;
+ if (destLayout->bpp == QPixelLayout::BPP32)
+ buffer = reinterpret_cast<uint *>(srcData) + x;
+ else
+ l = qMin(l, BufferSize);
+ const uint *ptr = fetch(buffer, srcData, x, l, nullptr, ditherPtr);
+ store(srcData, ptr, x, l, nullptr, ditherPtr);
x += l;
}
srcData += data->bytes_per_line;
@@ -281,20 +304,15 @@ static void convert_passthrough(QImageData *dest, const QImageData *src, Qt::Ima
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
+ const int src_bpl = src->bytes_per_line;
+ const int dest_bpl = dest->bytes_per_line;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = *src_data;
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
+ memcpy(dest_data, src_data, src_bpl);
+ src_data += src_bpl;
+ dest_data += dest_bpl;
}
}
@@ -305,30 +323,6 @@ static bool convert_passthrough_inplace(QImageData *data, Qt::ImageConversionFla
return true;
}
-static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = qPremultiply(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dest_data, const uchar *src_data, int len)
{
int pixel = 0;
@@ -431,33 +425,6 @@ static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::I
}
}
-#ifdef __SSE2__
-extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
-#else
-static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data,Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- QRgb *rgb_data = (QRgb *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const QRgb *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = qPremultiply(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
-
- if (data->format == QImage::Format_ARGB32)
- data->format = QImage::Format_ARGB32_Premultiplied;
- else
- data->format = QImage::Format_RGBA8888_Premultiplied;
- return true;
-}
-#endif
-
static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_ARGB32);
@@ -573,11 +540,12 @@ static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFl
return true;
}
-template<QtPixelOrder PixelOrder>
+template<QtPixelOrder PixelOrder, bool RGBA>
static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
- Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32);
+ Q_ASSERT(RGBA || src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32);
+ Q_ASSERT(!RGBA || src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888);
Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_RGB30);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
@@ -590,7 +558,10 @@ static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::Im
for (int i = 0; i < src->height; ++i) {
const quint32 *end = src_data + src->width;
while (src_data < end) {
- *dest_data = qConvertRgb32ToRgb30<PixelOrder>(*src_data);
+ QRgb c = *src_data;
+ if (RGBA)
+ c = RGBA2ARGB(c);
+ *dest_data = qConvertRgb32ToRgb30<PixelOrder>(c);
++src_data;
++dest_data;
}
@@ -599,10 +570,11 @@ static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::Im
}
}
-template<QtPixelOrder PixelOrder>
+template<QtPixelOrder PixelOrder, bool RGBA>
static bool convert_RGB_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags)
{
- Q_ASSERT(data->format == QImage::Format_RGB32 || data->format == QImage::Format_ARGB32);
+ Q_ASSERT(RGBA || (data->format == QImage::Format_RGB32 || data->format == QImage::Format_ARGB32));
+ Q_ASSERT(!RGBA || (data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888));
const int pad = (data->bytes_per_line >> 2) - data->width;
QRgb *rgb_data = (QRgb *) data->data;
@@ -610,7 +582,10 @@ static bool convert_RGB_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFl
for (int i = 0; i < data->height; ++i) {
const QRgb *end = rgb_data + data->width;
while (rgb_data < end) {
- *rgb_data = qConvertRgb32ToRgb30<PixelOrder>(*rgb_data);
+ QRgb c = *rgb_data;
+ if (RGBA)
+ c = RGBA2ARGB(c);
+ *rgb_data = qConvertRgb32ToRgb30<PixelOrder>(c);
++rgb_data;
}
rgb_data += pad;
@@ -771,11 +746,11 @@ static bool convert_BGR30_to_A2RGB30_inplace(QImageData *data, Qt::ImageConversi
return true;
}
-template<QtPixelOrder PixelOrder>
+template<QtPixelOrder PixelOrder, bool RGBA>
static void convert_A2RGB30_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(RGBA ? dest->format == QImage::Format_RGBA8888 : dest->format == QImage::Format_ARGB32);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
@@ -788,6 +763,8 @@ static void convert_A2RGB30_PM_to_ARGB(QImageData *dest, const QImageData *src,
const quint32 *end = src_data + src->width;
while (src_data < end) {
*dest_data = qConvertA2rgb30ToArgb32<PixelOrder>(qUnpremultiplyRgb30(*src_data));
+ if (RGBA)
+ *dest_data = ARGB2RGBA(*dest_data);
++src_data;
++dest_data;
}
@@ -796,7 +773,7 @@ static void convert_A2RGB30_PM_to_ARGB(QImageData *dest, const QImageData *src,
}
}
-template<QtPixelOrder PixelOrder>
+template<QtPixelOrder PixelOrder, bool RGBA>
static bool convert_A2RGB30_PM_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags)
{
Q_ASSERT(data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied);
@@ -808,11 +785,16 @@ static bool convert_A2RGB30_PM_to_ARGB_inplace(QImageData *data, Qt::ImageConver
const uint *end = rgb_data + data->width;
while (rgb_data < end) {
*rgb_data = qConvertA2rgb30ToArgb32<PixelOrder>(qUnpremultiplyRgb30(*rgb_data));
+ if (RGBA)
+ *rgb_data = ARGB2RGBA(*rgb_data);
++rgb_data;
}
rgb_data += pad;
}
- data->format = QImage::Format_ARGB32;
+ if (RGBA)
+ data->format = QImage::Format_RGBA8888;
+ else
+ data->format = QImage::Format_ARGB32;
return true;
}
@@ -1188,6 +1170,270 @@ static bool mask_alpha_converter_rgbx_inplace(QImageData *data, Qt::ImageConvers
#endif
}
+template<bool RGBA>
+static void convert_RGBA64_to_ARGB32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA64);
+ Q_ASSERT(RGBA || dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(!RGBA || dest->format == QImage::Format_RGBA8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const uchar *srcData = src->data;
+ uchar *destData = dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ uint *d = reinterpret_cast<uint *>(destData);
+ const QRgba64 *s = reinterpret_cast<const QRgba64 *>(srcData);
+ qt_convertRGBA64ToARGB32<RGBA>(d, s, src->width);
+ srcData += src->bytes_per_line;
+ destData += dest->bytes_per_line;
+ }
+}
+
+template<bool RGBA>
+static void convert_RGBA64PM_to_ARGB32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(RGBA || dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(!RGBA || dest->format == QImage::Format_RGBA8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 3) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
+ uint *dest_data = reinterpret_cast<uint *>(dest->data);
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgba64 *end = src_data + src->width;
+ while (src_data < end) {
+ QRgba64 s = src_data->unpremultiplied();
+ *dest_data = RGBA ? ARGB2RGBA(s.toArgb32()) : s.toArgb32();
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+template<bool RGBA>
+static void convert_ARGB32_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(RGBA || src->format == QImage::Format_ARGB32);
+ Q_ASSERT(!RGBA || src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_RGBA64);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 3) - dest->width;
+ const uint *src_data = reinterpret_cast<const uint *>(src->data);
+ QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data);
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ if (RGBA)
+ *dest_data = QRgba64::fromArgb32(RGBA2ARGB(*src_data));
+ else
+ *dest_data = QRgba64::fromArgb32(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+template<QtPixelOrder PixelOrder>
+static void convert_RGBA64PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 3) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
+ uint *dest_data = reinterpret_cast<uint *>(dest->data);
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgba64 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xc0000000 | qConvertRgb64ToRgb30<PixelOrder>(src_data->unpremultiplied());
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+template<QtPixelOrder PixelOrder>
+static void convert_RGBA64PM_to_A2RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_A2RGB30_Premultiplied
+ || dest->format == QImage::Format_A2BGR30_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 3) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
+ uint *dest_data = reinterpret_cast<uint *>(dest->data);
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgba64 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qConvertRgb64ToRgb30<PixelOrder>(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA64_to_RGBx64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA64);
+ Q_ASSERT(dest->format == QImage::Format_RGBX64);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 3) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 3) - dest->width;
+ const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
+ QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data);
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgba64 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = *src_data;
+ dest_data->setAlpha(65535);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA64_to_RGBx64_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBA64);
+
+ const int pad = (data->bytes_per_line >> 3) - data->width;
+ QRgba64 *rgb_data = reinterpret_cast<QRgba64 *>(data->data);
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgba64 *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ rgb_data->setAlpha(65535);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_RGBX64;
+ return true;
+}
+
+static void convert_RGBA64_to_RGBA64PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA64);
+ Q_ASSERT(dest->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 3) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 3) - dest->width;
+ const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
+ QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data);
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgba64 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = src_data->premultiplied();
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA64_to_RGBA64PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBA64);
+
+ const int pad = (data->bytes_per_line >> 3) - data->width;
+ QRgba64 *rgb_data = reinterpret_cast<QRgba64 *>(data->data);
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgba64 *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = rgb_data->premultiplied();
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_RGBA64_Premultiplied;
+ return true;
+}
+
+template<bool MaskAlpha>
+static void convert_RGBA64PM_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA64 || dest->format == QImage::Format_RGBX64);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 3) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 3) - dest->width;
+ const QRgba64 *src_data = reinterpret_cast<const QRgba64 *>(src->data);
+ QRgba64 *dest_data = reinterpret_cast<QRgba64 *>(dest->data);
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgba64 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = src_data->unpremultiplied();
+ if (MaskAlpha)
+ dest_data->setAlpha(65535);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+template<bool MaskAlpha>
+static bool convert_RGBA64PM_to_RGBA64_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBA64_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 3) - data->width;
+ QRgba64 *rgb_data = reinterpret_cast<QRgba64 *>(data->data);
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgba64 *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = rgb_data->unpremultiplied();
+ if (MaskAlpha)
+ rgb_data->setAlpha(65535);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = MaskAlpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64;
+ return true;
+}
+
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2032,7 +2278,7 @@ static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageCo
Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
0,
@@ -2053,7 +2299,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
@@ -2075,7 +2321,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
@@ -2100,6 +2346,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0, 0, 0, 0,
convert_Indexed8_to_Alpha8,
convert_Indexed8_to_Grayscale8,
+ 0, 0, 0
}, // Format_Indexed8
{
@@ -2122,11 +2369,12 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_RGB_to_RGB30<PixelOrderBGR>,
+ convert_RGB_to_RGB30<PixelOrderBGR, false>,
0,
- convert_RGB_to_RGB30<PixelOrderRGB>,
+ convert_RGB_to_RGB30<PixelOrderRGB, false>,
0,
- 0, 0
+ 0, 0,
+ 0, 0, 0
}, // Format_RGB32
{
@@ -2136,7 +2384,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_ARGB_to_Indexed8,
mask_alpha_converter,
0,
- convert_ARGB_to_ARGB_PM,
+ 0,
0,
0,
0,
@@ -2149,11 +2397,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_ARGB_to_RGBx,
convert_ARGB_to_RGBA,
0,
- convert_RGB_to_RGB30<PixelOrderBGR>,
+ convert_RGB_to_RGB30<PixelOrderBGR, false>,
0,
- convert_RGB_to_RGB30<PixelOrderRGB>,
+ convert_RGB_to_RGB30<PixelOrderRGB, false>,
0,
- 0, 0
+ 0, 0,
+ 0,
+ convert_ARGB32_to_RGBA64<false>,
+ 0
}, // Format_ARGB32
{
@@ -2176,11 +2427,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
convert_ARGB_to_RGBA,
- 0,
- 0,
- 0,
- 0,
- 0, 0
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0
}, // Format_ARGB32_Premultiplied
{
@@ -2202,7 +2451,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
@@ -2224,7 +2473,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
@@ -2246,7 +2495,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
@@ -2268,7 +2517,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
@@ -2290,7 +2539,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
@@ -2312,7 +2561,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
@@ -2335,7 +2584,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB888
{
@@ -2357,7 +2606,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
@@ -2378,7 +2627,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB4444_Premultiplied
{
0,
@@ -2398,9 +2647,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- mask_alpha_converter_RGBx,
- mask_alpha_converter_RGBx,
- 0, 0, 0, 0, 0, 0
+ convert_passthrough,
+ convert_passthrough,
+ convert_RGB_to_RGB30<PixelOrderBGR, true>,
+ 0,
+ convert_RGB_to_RGB30<PixelOrderRGB, true>,
+ 0,
+ 0, 0,
+ 0, 0, 0
}, // Format_RGBX8888
{
0,
@@ -2420,14 +2674,16 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
mask_alpha_converter_RGBx,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
0,
- convert_ARGB_to_ARGB_PM,
-#else
0,
+ convert_RGB_to_RGB30<PixelOrderBGR, true>,
0,
-#endif
- 0, 0, 0, 0, 0, 0
+ convert_RGB_to_RGB30<PixelOrderRGB, true>,
+ 0,
+ 0, 0,
+ 0,
+ convert_ARGB32_to_RGBA64<true>,
+ 0
}, // Format_RGBA8888
{
@@ -2449,7 +2705,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888_Premultiplied
{
@@ -2476,7 +2732,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_passthrough,
convert_BGR30_to_RGB30,
convert_BGR30_to_RGB30,
- 0, 0
+ 0, 0,
+ 0, 0, 0
}, // Format_BGR30
{
0,
@@ -2484,8 +2741,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_A2RGB30_PM_to_ARGB<PixelOrderBGR>,
- 0,
+ convert_A2RGB30_PM_to_ARGB<PixelOrderBGR, false>,
0,
0,
0,
@@ -2497,12 +2753,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ convert_A2RGB30_PM_to_ARGB<PixelOrderBGR, true>,
0,
convert_A2RGB30_PM_to_RGB30<false>,
0,
convert_A2RGB30_PM_to_RGB30<true>,
convert_BGR30_to_RGB30,
- 0, 0
+ 0, 0,
+ 0, 0, 0
}, // Format_BGR30A2_Premultiplied
{
0,
@@ -2528,7 +2786,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_BGR30_to_RGB30,
0,
convert_passthrough,
- 0, 0
+ 0, 0, 0, 0, 0
}, // Format_RGB30
{
0,
@@ -2536,8 +2794,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_A2RGB30_PM_to_ARGB<PixelOrderRGB>,
- 0,
+ convert_A2RGB30_PM_to_ARGB<PixelOrderRGB, false>,
0,
0,
0,
@@ -2549,12 +2806,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
+ convert_A2RGB30_PM_to_ARGB<PixelOrderRGB, true>,
0,
convert_A2RGB30_PM_to_RGB30<true>,
convert_BGR30_to_RGB30,
convert_A2RGB30_PM_to_RGB30<false>,
0,
- 0, 0
+ 0, 0,
+ 0, 0, 0
}, // Format_RGB30A2_Premultiplied
{
0,
@@ -2574,7 +2833,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Alpha8
{
0,
@@ -2594,20 +2853,81 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0
- } // Format_Grayscale8
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_Grayscale8
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, // self
+ convert_passthrough,
+ convert_passthrough
+ }, // Format_RGBX64
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA64_to_ARGB32<false>,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA64_to_ARGB32<true>,
+ 0,
+ 0, 0, 0, 0,
+ 0, 0,
+ convert_RGBA64_to_RGBx64,
+ 0, // self
+ convert_RGBA64_to_RGBA64PM
+ }, // Format_RGBA64
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA64PM_to_ARGB32<false>,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA64PM_to_ARGB32<true>,
+ 0,
+ convert_RGBA64PM_to_RGB30<PixelOrderBGR>,
+ convert_RGBA64PM_to_A2RGB30<PixelOrderBGR>,
+ convert_RGBA64PM_to_RGB30<PixelOrderRGB>,
+ convert_RGBA64PM_to_A2RGB30<PixelOrderRGB>,
+ 0, 0,
+ convert_RGBA64PM_to_RGBA64<true>,
+ convert_RGBA64PM_to_RGBA64<false>,
+ 0 // self
+ } // Format_RGBA64_Premultiplied
};
InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
0,
@@ -2631,6 +2951,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, 0, 0, 0, 0,
convert_Indexed8_to_Alpha8_inplace,
convert_Indexed8_to_Grayscale8_inplace,
+ 0, 0, 0
}, // Format_Indexed8
{
0,
@@ -2652,11 +2973,12 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- convert_RGB_to_RGB30_inplace<PixelOrderBGR>,
+ convert_RGB_to_RGB30_inplace<PixelOrderBGR, false>,
0,
- convert_RGB_to_RGB30_inplace<PixelOrderRGB>,
+ convert_RGB_to_RGB30_inplace<PixelOrderRGB, false>,
0,
- 0, 0
+ 0, 0,
+ 0, 0, 0
}, // Format_RGB32
{
0,
@@ -2665,11 +2987,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
mask_alpha_converter_inplace<QImage::Format_RGB32>,
0,
-#ifdef __SSE2__
- convert_ARGB_to_ARGB_PM_inplace_sse2,
-#else
- convert_ARGB_to_ARGB_PM_inplace,
-#endif
+ 0,
0,
0,
0,
@@ -2682,11 +3000,12 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_ARGB_to_RGBA_inplace<QImage::Format_RGBX8888>,
convert_ARGB_to_RGBA_inplace<QImage::Format_RGBA8888>,
0,
- convert_RGB_to_RGB30_inplace<PixelOrderBGR>,
+ convert_RGB_to_RGB30_inplace<PixelOrderBGR, false>,
0,
- convert_RGB_to_RGB30_inplace<PixelOrderRGB>,
+ convert_RGB_to_RGB30_inplace<PixelOrderRGB, false>,
0,
- 0, 0
+ 0, 0,
+ 0, 0, 0
}, // Format_ARGB32
{
0,
@@ -2708,38 +3027,36 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
convert_ARGB_to_RGBA_inplace<QImage::Format_RGBA8888_Premultiplied>,
- 0,
- 0,
- 0,
- 0,
- 0, 0
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0
}, // Format_ARGB32_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB888
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB4444_Premultiplied
{
0,
@@ -2761,7 +3078,12 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
convert_passthrough_inplace<QImage::Format_RGBA8888>,
convert_passthrough_inplace<QImage::Format_RGBA8888_Premultiplied>,
- 0, 0, 0, 0, 0, 0
+ convert_RGB_to_RGB30_inplace<PixelOrderBGR, true>,
+ 0,
+ convert_RGB_to_RGB30_inplace<PixelOrderRGB, true>,
+ 0,
+ 0, 0,
+ 0, 0, 0
}, // Format_RGBX8888
{
0,
@@ -2782,14 +3104,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
mask_alpha_converter_rgbx_inplace,
0,
-#ifdef __SSE2__
- convert_ARGB_to_ARGB_PM_inplace_sse2,
-#elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- convert_ARGB_to_ARGB_PM_inplace,
-#else
0,
-#endif
- 0, 0, 0, 0, 0, 0
+ convert_RGB_to_RGB30_inplace<PixelOrderBGR, true>,
+ 0,
+ convert_RGB_to_RGB30_inplace<PixelOrderRGB, true>,
+ 0,
+ 0, 0,
+ 0, 0, 0
}, // Format_RGBA8888
{
0,
@@ -2811,7 +3132,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888_Premultiplied
{
0,
@@ -2837,7 +3158,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>,
convert_BGR30_to_RGB30_inplace,
convert_BGR30_to_A2RGB30_inplace,
- 0, 0
+ 0, 0,
+ 0, 0, 0
}, // Format_BGR30
{
0,
@@ -2845,8 +3167,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderBGR>,
- 0,
+ convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderBGR, false>,
0,
0,
0,
@@ -2858,12 +3179,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
+ convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderBGR, true>,
0,
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
convert_A2RGB30_PM_to_RGB30_inplace<true>,
convert_BGR30_to_RGB30_inplace,
- 0, 0
+ 0, 0, 0, 0, 0
}, // Format_BGR30A2_Premultiplied
{
0,
@@ -2889,7 +3211,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_BGR30_to_A2RGB30_inplace,
0, // self
convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>,
- 0, 0
+ 0, 0, 0, 0, 0
}, // Format_RGB30
{
0,
@@ -2897,8 +3219,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB>,
- 0,
+ convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB, false>,
0,
0,
0,
@@ -2910,12 +3231,14 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
+ convert_A2RGB30_PM_to_ARGB_inplace<PixelOrderRGB, true>,
0,
convert_A2RGB30_PM_to_RGB30_inplace<true>,
convert_BGR30_to_RGB30_inplace,
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
- 0, 0
+ 0, 0,
+ 0, 0, 0
}, // Format_RGB30A2_Premultiplied
{
0,
@@ -2937,11 +3260,10 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
+ 0, 0, 0, 0,
+ 0, // self
0,
- 0,
- 0,
- 0,
- 0, 0
+ 0, 0, 0
}, // Format_Alpha8
{
0,
@@ -2963,12 +3285,29 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
+ 0, 0, 0, 0,
0,
- 0,
- 0,
- 0,
- 0, 0
- } // Format_Grayscale8
+ 0, // self
+ 0, 0, 0
+ }, // Format_Grayscale8
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, // self
+ convert_passthrough_inplace<QImage::Format_RGBA64>,
+ convert_passthrough_inplace<QImage::Format_RGBA64_Premultiplied>,
+ }, // Format_RGBX64
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ convert_RGBA64_to_RGBx64_inplace,
+ 0, // self
+ convert_RGBA64_to_RGBA64PM_inplace
+ }, // Format_RGBA64
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ convert_RGBA64PM_to_RGBA64_inplace<true>,
+ convert_RGBA64PM_to_RGBA64_inplace<false>,
+ 0 // self
+ } // Format_RGBA64_Premultiplied
};
static void qInitImageConversions()
@@ -2982,22 +3321,6 @@ static void qInitImageConversions()
}
#endif
-#if defined(QT_COMPILER_SUPPORTS_SSE4_1) && !defined(__SSE4_1__)
- if (qCpuHasFeature(SSE4_1)) {
- extern void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
- qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4;
- qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_sse4;
- }
-#endif
-
-#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__)
- if (qCpuHasFeature(AVX2)) {
- extern void convert_ARGB_to_ARGB_PM_avx2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
- qimage_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_avx2;
- qimage_converter_map[QImage::Format_RGBA8888][QImage::Format_RGBA8888_Premultiplied] = convert_ARGB_to_ARGB_PM_avx2;
- }
-#endif
-
#if defined(__ARM_NEON__)
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index f5fea2ed00..2fe29a88d3 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -113,6 +113,7 @@ extern Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImag
extern InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats];
void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+void convert_generic_to_rgb64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags);
void dither_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags, bool fromalpha);
@@ -164,6 +165,11 @@ inline int qt_depthForFormat(QImage::Format format)
case QImage::Format_RGB888:
depth = 24;
break;
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ depth = 64;
+ break;
}
return depth;
}
@@ -190,6 +196,9 @@ inline QImage::Format qt_opaqueVersion(QImage::Format format)
return QImage::Format_BGR30;
case QImage::Format_A2RGB30_Premultiplied:
return QImage::Format_RGB30;
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ return QImage::Format_RGBX64;
case QImage::Format_ARGB32_Premultiplied:
case QImage::Format_ARGB32:
default:
@@ -214,6 +223,8 @@ inline QImage::Format qt_alphaVersion(QImage::Format format)
return QImage::Format_A2BGR30_Premultiplied;
case QImage::Format_RGB30:
return QImage::Format_A2RGB30_Premultiplied;
+ case QImage::Format_RGBX64:
+ return QImage::Format_RGBA64_Premultiplied;
default:
break;
}
diff --git a/src/gui/image/qimage_sse2.cpp b/src/gui/image/qimage_sse2.cpp
deleted file mode 100644
index 8f7195e0b5..0000000000
--- a/src/gui/image/qimage_sse2.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qimage.h"
-#include <private/qimage_p.h>
-#include <private/qsimd_p.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qdrawingprimitive_sse2_p.h>
-
-#ifdef QT_COMPILER_SUPPORTS_SSE2
-
-QT_BEGIN_NAMESPACE
-
-bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888);
-
- const int width = data->width;
- const int height = data->height;
- const int bpl = data->bytes_per_line;
-
- const __m128i alphaMask = _mm_set1_epi32(0xff000000);
- const __m128i nullVector = _mm_setzero_si128();
- const __m128i half = _mm_set1_epi16(0x80);
- const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
-
- uchar *d = data->data;
- for (int y = 0; y < height; ++y) {
- int i = 0;
- quint32 *d32 = reinterpret_cast<quint32 *>(d);
- ALIGNMENT_PROLOGUE_16BYTES(d, i, width) {
- const quint32 p = d32[i];
- if (p <= 0x00ffffff)
- d32[i] = 0;
- else if (p < 0xff000000)
- d32[i] = qPremultiply(p);
- }
- __m128i *d128 = reinterpret_cast<__m128i *>(d32 + i);
- for (; i < (width - 3); i += 4) {
- const __m128i srcVector = _mm_load_si128(d128);
-#ifdef __SSE4_1__
- if (_mm_testc_si128(srcVector, alphaMask)) {
- // opaque, data is unchanged
- } else if (_mm_testz_si128(srcVector, alphaMask)) {
- // fully transparent
- _mm_store_si128(d128, nullVector);
- } else {
- const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask);
-#else
- const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask);
- if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) {
- // opaque, data is unchanged
- } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) == 0xffff) {
- // fully transparent
- _mm_store_si128(d128, nullVector);
- } else {
-#endif
- __m128i alphaChannel = _mm_srli_epi32(srcVector, 24);
- alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16));
-
- __m128i result;
- BYTE_MUL_SSE2(result, srcVector, alphaChannel, colorMask, half);
- result = _mm_or_si128(_mm_andnot_si128(alphaMask, result), srcVectorAlpha);
- _mm_store_si128(d128, result);
- }
- d128++;
- }
-
- SIMD_EPILOGUE(i, width, 3) {
- const quint32 p = d32[i];
- if (p <= 0x00ffffff)
- d32[i] = 0;
- else if (p < 0xff000000)
- d32[i] = qPremultiply(p);
- }
-
- d += bpl;
- }
-
- if (data->format == QImage::Format_ARGB32)
- data->format = QImage::Format_ARGB32_Premultiplied;
- else
- data->format = QImage::Format_RGBA8888_Premultiplied;
- return true;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_COMPILER_SUPPORTS_SSE2
diff --git a/src/gui/image/qimage_sse4.cpp b/src/gui/image/qimage_sse4.cpp
deleted file mode 100644
index 0e2c2f492e..0000000000
--- a/src/gui/image/qimage_sse4.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qimage.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qdrawingprimitive_sse2_p.h>
-#include <private/qimage_p.h>
-#include <private/qsimd_p.h>
-
-#ifdef QT_COMPILER_SUPPORTS_SSE4_1
-
-QT_BEGIN_NAMESPACE
-
-const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = 0xff000000 | qUnpremultiply_sse4(src[i]);
- return buffer;
-}
-
-void convert_ARGB_to_ARGB_PM_sse4(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const uint *src_data = (uint *) src->data;
- uint *dest_data = (uint *) dest->data;
- for (int i = 0; i < src->height; ++i) {
- qt_convertARGB32ToARGB32PM(dest_data, src_data, src->width);
- src_data += src->bytes_per_line >> 2;
- dest_data += dest->bytes_per_line >> 2;
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_COMPILER_SUPPORTS_SSE4_1
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 7086e102ea..6d358984d6 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -164,73 +164,13 @@
#include <private/qpnghandler_p.h>
#endif
+#include <private/qimagereaderwriterhelpers_p.h>
+
#include <algorithm>
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
-#endif
-
-enum _qt_BuiltInFormatType {
-#ifndef QT_NO_IMAGEFORMAT_PNG
- _qt_PngFormat,
-#endif
-#ifndef QT_NO_IMAGEFORMAT_BMP
- _qt_BmpFormat,
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PPM
- _qt_PpmFormat,
- _qt_PgmFormat,
- _qt_PbmFormat,
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XBM
- _qt_XbmFormat,
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- _qt_XpmFormat,
-#endif
- _qt_NumFormats,
- _qt_NoFormat = -1
-};
-
-#if !defined(QT_NO_IMAGEFORMAT_PPM)
-# define MAX_MT_SIZE 20
-#elif !defined(QT_NO_IMAGEFORMAT_XBM) || !defined(QT_NO_IMAGEFORMAT_XPM)
-# define MAX_MT_SIZE 10
-#else
-# define MAX_MT_SIZE 4
-#endif
-
-struct _qt_BuiltInFormatStruct
-{
- char extension[4];
- char mimeType[MAX_MT_SIZE];
-};
-
-#undef MAX_MT_SIZE
-
-static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = {
-#ifndef QT_NO_IMAGEFORMAT_PNG
- {"png", "png"},
-#endif
-#ifndef QT_NO_IMAGEFORMAT_BMP
- {"bmp", "bmp"},
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PPM
- {"ppm", "x-portable-pixmap"},
- {"pgm", "x-portable-graymap"},
- {"pbm", "x-portable-bitmap"},
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XBM
- {"xbm", "x-xbitmap"},
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- {"xpm", "x-xpixmap"},
-#endif
-};
-Q_STATIC_ASSERT(_qt_NumFormats == sizeof _qt_BuiltInFormats / sizeof *_qt_BuiltInFormats);
+using namespace QImageReaderWriterHelpers;
static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
const QByteArray &format,
@@ -251,7 +191,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
typedef QMultiMap<int, QString> PluginKeyMap;
// check if we have plugins that support the image format
- QFactoryLoader *l = loader();
+ auto l = QImageReaderWriterHelpers::pluginLoader();
const PluginKeyMap keyMap = l->keyMap();
#ifdef QIMAGEREADER_DEBUG
@@ -1565,16 +1505,6 @@ QByteArray QImageReader::imageFormat(QIODevice *device)
return format;
}
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-void supportedImageHandlerFormats(QFactoryLoader *loader,
- QImageIOPlugin::Capability cap,
- QList<QByteArray> *result);
-
-void supportedImageHandlerMimeTypes(QFactoryLoader *loader,
- QImageIOPlugin::Capability cap,
- QList<QByteArray> *result);
-#endif
-
/*!
Returns the list of image formats supported by QImageReader.
@@ -1605,18 +1535,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader,
QList<QByteArray> QImageReader::supportedImageFormats()
{
- QList<QByteArray> formats;
- formats.reserve(_qt_NumFormats);
- for (int i = 0; i < _qt_NumFormats; ++i)
- formats << _qt_BuiltInFormats[i].extension;
-
-#ifndef QT_NO_IMAGEFORMATPLUGIN
- supportedImageHandlerFormats(loader(), QImageIOPlugin::CanRead, &formats);
-#endif // QT_NO_IMAGEFORMATPLUGIN
-
- std::sort(formats.begin(), formats.end());
- formats.erase(std::unique(formats.begin(), formats.end()), formats.end());
- return formats;
+ return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanRead);
}
/*!
@@ -1630,18 +1549,24 @@ QList<QByteArray> QImageReader::supportedImageFormats()
QList<QByteArray> QImageReader::supportedMimeTypes()
{
- QList<QByteArray> mimeTypes;
- mimeTypes.reserve(_qt_NumFormats);
- for (const auto &fmt : _qt_BuiltInFormats)
- mimeTypes.append(QByteArrayLiteral("image/") + fmt.mimeType);
+ return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanRead);
+}
-#ifndef QT_NO_IMAGEFORMATPLUGIN
- supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanRead, &mimeTypes);
-#endif // QT_NO_IMAGEFORMATPLUGIN
+/*!
+ \since 5.12
- std::sort(mimeTypes.begin(), mimeTypes.end());
- mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end());
- return mimeTypes;
+ Returns the list of image formats corresponding to \a mimeType.
+
+ Note that the QGuiApplication instance must be created before this function is
+ called.
+
+ \sa supportedImageFormats(), supportedMimeTypes()
+*/
+
+QList<QByteArray> QImageReader::imageFormatsForMimeType(const QByteArray &mimeType)
+{
+ return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType,
+ QImageReaderWriterHelpers::CanRead);
}
QT_END_NAMESPACE
diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h
index 9d6c1e0b1e..4e9a08b6e6 100644
--- a/src/gui/image/qimagereader.h
+++ b/src/gui/image/qimagereader.h
@@ -144,6 +144,7 @@ public:
static QByteArray imageFormat(QIODevice *device);
static QList<QByteArray> supportedImageFormats();
static QList<QByteArray> supportedMimeTypes();
+ static QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType);
private:
Q_DISABLE_COPY(QImageReader)
diff --git a/src/gui/image/qimagereaderwriterhelpers.cpp b/src/gui/image/qimagereaderwriterhelpers.cpp
new file mode 100644
index 0000000000..a5b7fb6449
--- /dev/null
+++ b/src/gui/image/qimagereaderwriterhelpers.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qimagereaderwriterhelpers_p.h"
+
+#include <qjsonarray.h>
+#include <qmutex.h>
+#include <private/qfactoryloader_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QImageReaderWriterHelpers {
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
+Q_GLOBAL_STATIC(QMutex, loaderMutex)
+
+static void appendImagePluginFormats(QFactoryLoader *loader,
+ QImageIOPlugin::Capability cap,
+ QList<QByteArray> *result)
+{
+ typedef QMultiMap<int, QString> PluginKeyMap;
+ typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
+
+ const PluginKeyMap keyMap = loader->keyMap();
+ const PluginKeyMapConstIterator cend = keyMap.constEnd();
+ int i = -1;
+ QImageIOPlugin *plugin = 0;
+ result->reserve(result->size() + keyMap.size());
+ for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) {
+ if (it.key() != i) {
+ i = it.key();
+ plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i));
+ }
+ const QByteArray key = it.value().toLatin1();
+ if (plugin && (plugin->capabilities(0, key) & cap) != 0)
+ result->append(key);
+ }
+}
+
+static void appendImagePluginMimeTypes(QFactoryLoader *loader,
+ QImageIOPlugin::Capability cap,
+ QList<QByteArray> *result,
+ QList<QByteArray> *resultKeys = nullptr)
+{
+ QList<QJsonObject> metaDataList = loader->metaData();
+
+ const int pluginCount = metaDataList.size();
+ for (int i = 0; i < pluginCount; ++i) {
+ const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject();
+ const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray();
+ const QJsonArray mimeTypes = metaData.value(QLatin1String("MimeTypes")).toArray();
+ QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i));
+ const int keyCount = keys.size();
+ for (int k = 0; k < keyCount; ++k) {
+ const QByteArray key = keys.at(k).toString().toLatin1();
+ if (plugin && (plugin->capabilities(0, key) & cap) != 0) {
+ result->append(mimeTypes.at(k).toString().toLatin1());
+ if (resultKeys)
+ resultKeys->append(key);
+ }
+ }
+ }
+}
+
+QSharedPointer<QFactoryLoader> pluginLoader()
+{
+ loaderMutex()->lock();
+ return QSharedPointer<QFactoryLoader>(loader(), [](QFactoryLoader *) {
+ loaderMutex()->unlock();
+ });
+}
+
+static inline QImageIOPlugin::Capability pluginCapability(Capability cap)
+{
+ return cap == CanRead ? QImageIOPlugin::CanRead : QImageIOPlugin::CanWrite;
+}
+
+#endif // QT_NO_IMAGEFORMATPLUGIN
+
+QList<QByteArray> supportedImageFormats(Capability cap)
+{
+ QList<QByteArray> formats;
+ formats.reserve(_qt_NumFormats);
+ for (int i = 0; i < _qt_NumFormats; ++i)
+ formats << _qt_BuiltInFormats[i].extension;
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+ appendImagePluginFormats(loader(), pluginCapability(cap), &formats);
+#endif // QT_NO_IMAGEFORMATPLUGIN
+
+ std::sort(formats.begin(), formats.end());
+ formats.erase(std::unique(formats.begin(), formats.end()), formats.end());
+ return formats;
+}
+
+QList<QByteArray> supportedMimeTypes(Capability cap)
+{
+ QList<QByteArray> mimeTypes;
+ mimeTypes.reserve(_qt_NumFormats);
+ for (const auto &fmt : _qt_BuiltInFormats)
+ mimeTypes.append(QByteArrayLiteral("image/") + fmt.mimeType);
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+ appendImagePluginMimeTypes(loader(), pluginCapability(cap), &mimeTypes);
+#endif // QT_NO_IMAGEFORMATPLUGIN
+
+ std::sort(mimeTypes.begin(), mimeTypes.end());
+ mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end());
+ return mimeTypes;
+}
+
+QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType, Capability cap)
+{
+ QList<QByteArray> formats;
+ if (mimeType.startsWith("image/")) {
+ const QByteArray type = mimeType.mid(sizeof("image/") - 1);
+ for (const auto &fmt : _qt_BuiltInFormats) {
+ if (fmt.mimeType == type && !formats.contains(fmt.extension))
+ formats << fmt.extension;
+ }
+ }
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+ QList<QByteArray> mimeTypes;
+ QList<QByteArray> keys;
+ appendImagePluginMimeTypes(loader(), pluginCapability(cap), &mimeTypes, &keys);
+ for (int i = 0; i < mimeTypes.size(); ++i) {
+ if (mimeTypes.at(i) == mimeType) {
+ const auto &key = keys.at(i);
+ if (!formats.contains(key))
+ formats << key;
+ }
+ }
+#endif // QT_NO_IMAGEFORMATPLUGIN
+
+ return formats;
+}
+
+} // QImageReaderWriterHelpers
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qimagereaderwriterhelpers_p.h b/src/gui/image/qimagereaderwriterhelpers_p.h
new file mode 100644
index 0000000000..6fe418a8ab
--- /dev/null
+++ b/src/gui/image/qimagereaderwriterhelpers_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QIMAGEREADERWRITERHELPERS_P_H
+#define QIMAGEREADERWRITERHELPERS_P_H
+
+#include <QtGui/private/qtguiglobal_p.h>
+#include <qsharedpointer.h>
+#include "qimageiohandler.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.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QFactoryLoader;
+
+namespace QImageReaderWriterHelpers {
+
+enum _qt_BuiltInFormatType {
+#ifndef QT_NO_IMAGEFORMAT_PNG
+ _qt_PngFormat,
+#endif
+#ifndef QT_NO_IMAGEFORMAT_BMP
+ _qt_BmpFormat,
+#endif
+#ifndef QT_NO_IMAGEFORMAT_PPM
+ _qt_PpmFormat,
+ _qt_PgmFormat,
+ _qt_PbmFormat,
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XBM
+ _qt_XbmFormat,
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ _qt_XpmFormat,
+#endif
+ _qt_NumFormats,
+ _qt_NoFormat = -1
+};
+
+#if !defined(QT_NO_IMAGEFORMAT_PPM)
+# define MAX_MT_SIZE 20
+#elif !defined(QT_NO_IMAGEFORMAT_XBM) || !defined(QT_NO_IMAGEFORMAT_XPM)
+# define MAX_MT_SIZE 10
+#else
+# define MAX_MT_SIZE 4
+#endif
+
+struct _qt_BuiltInFormatStruct
+{
+ char extension[4];
+ char mimeType[MAX_MT_SIZE];
+};
+
+#undef MAX_MT_SIZE
+
+static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = {
+#ifndef QT_NO_IMAGEFORMAT_PNG
+ {"png", "png"},
+#endif
+#ifndef QT_NO_IMAGEFORMAT_BMP
+ {"bmp", "bmp"},
+#endif
+#ifndef QT_NO_IMAGEFORMAT_PPM
+ {"ppm", "x-portable-pixmap"},
+ {"pgm", "x-portable-graymap"},
+ {"pbm", "x-portable-bitmap"},
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XBM
+ {"xbm", "x-xbitmap"},
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ {"xpm", "x-xpixmap"},
+#endif
+};
+Q_STATIC_ASSERT(_qt_NumFormats == sizeof _qt_BuiltInFormats / sizeof *_qt_BuiltInFormats);
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+QSharedPointer<QFactoryLoader> pluginLoader();
+#endif
+
+enum Capability {
+ CanRead,
+ CanWrite
+};
+QList<QByteArray> supportedImageFormats(Capability cap);
+QList<QByteArray> supportedMimeTypes(Capability cap);
+QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType, Capability cap);
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QIMAGEREADERWRITERHELPERS_P_H
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index a39d204677..5ce7e309bb 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -102,7 +102,6 @@
#include <qfileinfo.h>
#include <qimage.h>
#include <qimageiohandler.h>
-#include <qjsonarray.h>
#include <qset.h>
#include <qvariant.h>
@@ -119,15 +118,12 @@
#include <private/qpnghandler_p.h>
#endif
+#include <private/qimagereaderwriterhelpers_p.h>
+
#include <algorithm>
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
-#endif
-
static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
const QByteArray &format)
{
@@ -139,7 +135,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
typedef QMultiMap<int, QString> PluginKeyMap;
// check if any plugins can write the image
- QFactoryLoader *l = loader();
+ auto l = QImageReaderWriterHelpers::pluginLoader();
const PluginKeyMap keyMap = l->keyMap();
int suffixPluginIndex = -1;
#endif
@@ -268,7 +264,7 @@ QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq)
deleteDevice = false;
handler = 0;
quality = -1;
- compression = 0;
+ compression = -1;
gamma = 0.0;
optimizedWrite = false;
progressiveScanWrite = false;
@@ -824,52 +820,6 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const
return d->handler->supportsOption(option);
}
-
-#ifndef QT_NO_IMAGEFORMATPLUGIN
-void supportedImageHandlerFormats(QFactoryLoader *loader,
- QImageIOPlugin::Capability cap,
- QList<QByteArray> *result)
-{
- typedef QMultiMap<int, QString> PluginKeyMap;
- typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;
-
- const PluginKeyMap keyMap = loader->keyMap();
- const PluginKeyMapConstIterator cend = keyMap.constEnd();
- int i = -1;
- QImageIOPlugin *plugin = 0;
- result->reserve(result->size() + keyMap.size());
- for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) {
- if (it.key() != i) {
- i = it.key();
- plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i));
- }
- const QByteArray key = it.value().toLatin1();
- if (plugin && (plugin->capabilities(0, key) & cap) != 0)
- result->append(key);
- }
-}
-
-void supportedImageHandlerMimeTypes(QFactoryLoader *loader,
- QImageIOPlugin::Capability cap,
- QList<QByteArray> *result)
-{
- QList<QJsonObject> metaDataList = loader->metaData();
-
- const int pluginCount = metaDataList.size();
- for (int i = 0; i < pluginCount; ++i) {
- const QJsonObject metaData = metaDataList.at(i).value(QLatin1String("MetaData")).toObject();
- const QJsonArray keys = metaData.value(QLatin1String("Keys")).toArray();
- const QJsonArray mimeTypes = metaData.value(QLatin1String("MimeTypes")).toArray();
- QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(loader->instance(i));
- const int keyCount = keys.size();
- for (int k = 0; k < keyCount; ++k) {
- if (plugin && (plugin->capabilities(0, keys.at(k).toString().toLatin1()) & cap) != 0)
- result->append(mimeTypes.at(k).toString().toLatin1());
- }
- }
-}
-#endif // QT_NO_IMAGEFORMATPLUGIN
-
/*!
Returns the list of image formats supported by QImageWriter.
@@ -897,30 +847,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader,
*/
QList<QByteArray> QImageWriter::supportedImageFormats()
{
- QList<QByteArray> formats;
-#ifndef QT_NO_IMAGEFORMAT_BMP
- formats << "bmp";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PPM
- formats << "pbm" << "pgm" << "ppm";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XBM
- formats << "xbm";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- formats << "xpm";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PNG
- formats << "png";
-#endif
-
-#ifndef QT_NO_IMAGEFORMATPLUGIN
- supportedImageHandlerFormats(loader(), QImageIOPlugin::CanWrite, &formats);
-#endif // QT_NO_IMAGEFORMATPLUGIN
-
- std::sort(formats.begin(), formats.end());
- formats.erase(std::unique(formats.begin(), formats.end()), formats.end());
- return formats;
+ return QImageReaderWriterHelpers::supportedImageFormats(QImageReaderWriterHelpers::CanWrite);
}
/*!
@@ -933,32 +860,24 @@ QList<QByteArray> QImageWriter::supportedImageFormats()
*/
QList<QByteArray> QImageWriter::supportedMimeTypes()
{
- QList<QByteArray> mimeTypes;
-#ifndef QT_NO_IMAGEFORMAT_BMP
- mimeTypes << "image/bmp";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PPM
- mimeTypes << "image/x-portable-bitmap";
- mimeTypes << "image/x-portable-graymap";
- mimeTypes << "image/x-portable-pixmap";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XBM
- mimeTypes << "image/x-xbitmap";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- mimeTypes << "image/x-xpixmap";
-#endif
-#ifndef QT_NO_IMAGEFORMAT_PNG
- mimeTypes << "image/png";
-#endif
+ return QImageReaderWriterHelpers::supportedMimeTypes(QImageReaderWriterHelpers::CanWrite);
+}
-#ifndef QT_NO_IMAGEFORMATPLUGIN
- supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanWrite, &mimeTypes);
-#endif // QT_NO_IMAGEFORMATPLUGIN
+/*!
+ \since 5.12
- std::sort(mimeTypes.begin(), mimeTypes.end());
- mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end());
- return mimeTypes;
+ Returns the list of image formats corresponding to \a mimeType.
+
+ Note that the QGuiApplication instance must be created before this function is
+ called.
+
+ \sa supportedImageFormats(), supportedMimeTypes()
+*/
+
+QList<QByteArray> QImageWriter::imageFormatsForMimeType(const QByteArray &mimeType)
+{
+ return QImageReaderWriterHelpers::imageFormatsForMimeType(mimeType,
+ QImageReaderWriterHelpers::CanWrite);
}
QT_END_NAMESPACE
diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h
index fd1fdd07e8..29c06ccdd2 100644
--- a/src/gui/image/qimagewriter.h
+++ b/src/gui/image/qimagewriter.h
@@ -116,6 +116,7 @@ public:
static QList<QByteArray> supportedImageFormats();
static QList<QByteArray> supportedMimeTypes();
+ static QList<QByteArray> imageFormatsForMimeType(const QByteArray &mimeType);
private:
Q_DISABLE_COPY(QImageWriter)
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 1ea503a268..4b2334ae52 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -248,9 +248,9 @@ QPixmap::QPixmap(const char * const xpm[])
QImage image(xpm);
if (!image.isNull()) {
if (data && data->pixelType() == QPlatformPixmap::BitmapType)
- *this = QBitmap::fromImage(image);
+ *this = QBitmap::fromImage(std::move(image));
else
- *this = fromImage(image);
+ *this = fromImage(std::move(image));
}
}
#endif
@@ -691,7 +691,7 @@ QBitmap QPixmap::createHeuristicMask(bool clipTight) const
QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
{
QImage image = toImage().convertToFormat(QImage::Format_ARGB32);
- return QBitmap::fromImage(image.createMaskFromColor(maskColor.rgba(), mode));
+ return QBitmap::fromImage(std::move(image).createMaskFromColor(maskColor.rgba(), mode));
}
/*!
@@ -1018,9 +1018,9 @@ QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
if (image.isNull()) {
pixmap = QPixmap();
} else if (image.depth() == 1) {
- pixmap = QBitmap::fromImage(image);
+ pixmap = QBitmap::fromImage(std::move(image));
} else {
- pixmap = QPixmap::fromImage(image);
+ pixmap = QPixmap::fromImage(std::move(image));
}
return stream;
}
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index 646e737afa..649a25250c 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -150,13 +150,7 @@ void QBlittablePlatformPixmap::fill(const QColor &color)
m_alpha = true;
}
- uint pixel = qPremultiply(color.rgba());
- const QPixelLayout *layout = &qPixelLayouts[blittable()->lock()->format()];
- Q_ASSERT(layout->convertFromARGB32PM);
- layout->convertFromARGB32PM(&pixel, &pixel, 1, 0, 0);
-
- //so premultiplied formats are supported and ARGB32 and RGB32
- blittable()->lock()->fill(pixel);
+ blittable()->lock()->fill(color);
}
}
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 431002d032..13c1c29d5b 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -193,17 +193,12 @@ void QRasterPlatformPixmap::fill(const QColor &color)
if (alpha != 255) {
if (!image.hasAlphaChannel()) {
QImage::Format toFormat = qt_alphaVersionForPainting(image.format());
- if (!image.isNull() && qt_depthForFormat(image.format()) == qt_depthForFormat(toFormat)) {
- image.detach();
- image.d->format = toFormat;
- } else {
+ if (!image.reinterpretAsFormat(toFormat))
image = QImage(image.width(), image.height(), toFormat);
- }
}
}
- pixel = qPremultiply(color.rgba());
- const QPixelLayout *layout = &qPixelLayouts[image.format()];
- layout->convertFromARGB32PM(&pixel, &pixel, 1, 0, 0);
+ image.fill(color);
+ return;
} else if (image.format() == QImage::Format_Alpha8) {
pixel = qAlpha(color.rgba());
} else if (image.format() == QImage::Format_Grayscale8) {
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 92f6964783..a9e472f8c4 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -42,39 +42,76 @@
#include <qpa/qplatformpixmap.h>
#include "qpixmap_raster_p.h"
-#include <qglobal.h>
+#include <qdebug.h>
#include <QScopedArrayPointer>
#include <qt_windows.h>
+#include <algorithm>
+#include <iterator>
+
QT_BEGIN_NAMESPACE
-static inline void initBitMapInfoHeader(int width, int height, bool topToBottom, BITMAPINFOHEADER *bih)
+template <typename Int>
+static inline Int pad4(Int v)
+{
+ return (v + Int(3)) & ~Int(3);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const BITMAPINFOHEADER &bih)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << "BITMAPINFOHEADER(" << bih.biWidth << 'x' << qAbs(bih.biHeight)
+ << (bih.biHeight < 0 ? ", top-down" : ", bottom-up")
+ << ", planes=" << bih.biPlanes << ", bitCount=" << bih.biBitCount
+ << ", compression=" << bih.biCompression << ", size="
+ << bih.biSizeImage << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+static inline void initBitMapInfoHeader(int width, int height, bool topToBottom,
+ DWORD compression, DWORD bitCount,
+ BITMAPINFOHEADER *bih)
{
memset(bih, 0, sizeof(BITMAPINFOHEADER));
bih->biSize = sizeof(BITMAPINFOHEADER);
bih->biWidth = width;
bih->biHeight = topToBottom ? -height : height;
bih->biPlanes = 1;
- bih->biBitCount = 32;
- bih->biCompression = BI_RGB;
- bih->biSizeImage = width * height * 4;
+ bih->biBitCount = WORD(bitCount);
+ bih->biCompression = compression;
+ // scan lines are word-aligned (unless RLE)
+ const DWORD bytesPerLine = pad4(DWORD(width) * bitCount / 8);
+ bih->biSizeImage = bytesPerLine * DWORD(height);
}
-static inline void initBitMapInfo(int width, int height, bool topToBottom, BITMAPINFO *bmi)
+enum { Indexed8ColorTableSize = 256 };
+
+struct BITMAPINFO_COLORTABLE256 { // BITMAPINFO with 256 entry color table for Indexed 8 format
+ BITMAPINFOHEADER bmiHeader;
+ RGBQUAD bmiColors[Indexed8ColorTableSize];
+};
+
+template <class BITMAPINFO_T> // BITMAPINFO, BITMAPINFO_COLORTABLE256
+static inline void initBitMapInfo(int width, int height, bool topToBottom,
+ DWORD compression, DWORD bitCount,
+ BITMAPINFO_T *bmi)
{
- initBitMapInfoHeader(width, height, topToBottom, &bmi->bmiHeader);
- memset(bmi->bmiColors, 0, sizeof(RGBQUAD));
+ initBitMapInfoHeader(width, height, topToBottom, compression, bitCount, &bmi->bmiHeader);
+ memset(bmi->bmiColors, 0, sizeof(bmi->bmiColors));
}
static inline uchar *getDiBits(HDC hdc, HBITMAP bitmap, int width, int height, bool topToBottom = true)
{
BITMAPINFO bmi;
- initBitMapInfo(width, height, topToBottom, &bmi);
+ initBitMapInfo(width, height, topToBottom, BI_RGB, 32u, &bmi);
uchar *result = new uchar[bmi.bmiHeader.biSizeImage];
- if (!GetDIBits(hdc, bitmap, 0, height, result, &bmi, DIB_RGB_COLORS)) {
+ if (!GetDIBits(hdc, bitmap, 0, UINT(height), result, &bmi, DIB_RGB_COLORS)) {
delete [] result;
qErrnoWarning("%s: GetDIBits() failed to get bitmap bits.", __FUNCTION__);
- return 0;
+ return nullptr;
}
return result;
}
@@ -98,18 +135,92 @@ static inline void copyImageDataCreateAlpha(const uchar *data, QImage *target)
}
}
-static inline void copyImageData(const uchar *data, QImage *target)
+// Flip RGB triplets from DIB to QImage formats. Scan lines are padded to 32bit
+// both in QImage and DIB.
+static inline void flipRgb3(uchar *p, int width, int height)
{
- const int height = target->height();
- const int bytesPerLine = target->bytesPerLine();
+ const int lineSize = 3 * width;
+ const int linePad = pad4(lineSize) - lineSize;
for (int y = 0; y < height; ++y) {
- void *dest = static_cast<void *>(target->scanLine(y));
- const void *src = data + y * bytesPerLine;
- memcpy(dest, src, bytesPerLine);
+ uchar *end = p + lineSize;
+ for ( ; p < end; p += 3)
+ std::swap(*p, *(p + 2));
+ p += linePad;
+ }
+}
+
+static inline RGBQUAD qRgbToRgbQuad(QRgb qrgb)
+{
+ RGBQUAD result = {BYTE(qBlue(qrgb)), BYTE(qGreen(qrgb)), BYTE(qRed(qrgb)), 0};
+ return result;
+}
+
+static inline QRgb rgbQuadToQRgb(RGBQUAD quad)
+{
+ return QRgb(quad.rgbBlue) + (QRgb(quad.rgbGreen) << 8) + (QRgb(quad.rgbRed) << 16)
+ + 0xff000000;
+}
+
+// Helper for imageFromWinHBITMAP_*(), create image in desired format
+static QImage copyImageData(const BITMAPINFOHEADER &header, const RGBQUAD *colorTableIn,
+ const void *data, QImage::Format format)
+{
+ const QSize size = QSize(header.biWidth, qAbs(header.biHeight));
+ QImage image(size, format);
+
+ int colorTableSize = 0;
+ switch (format) {
+ case QImage::Format_Mono:
+ colorTableSize = 2;
+ break;
+ case QImage::Format_Indexed8:
+ colorTableSize = Indexed8ColorTableSize;
+ break;
+ default:
+ break;
+ }
+ if (colorTableSize) {
+ Q_ASSERT(colorTableIn);
+ QVector<QRgb> colorTable;
+ colorTable.reserve(colorTableSize);
+ std::transform(colorTableIn, colorTableIn + colorTableSize,
+ std::back_inserter(colorTable), rgbQuadToQRgb);
+ image.setColorTable(colorTable);
}
+ switch (header.biBitCount) {
+ case 32:
+ copyImageDataCreateAlpha(static_cast<const uchar *>(data), &image);
+ break;
+ case 1:
+ case 8:
+ case 16:
+ case 24:
+ Q_ASSERT(DWORD(image.sizeInBytes()) == header.biSizeImage);
+ memcpy(image.bits(), data, header.biSizeImage);
+ if (format == QImage::Format_RGB888)
+ image = image.rgbSwapped();
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ return image;
}
+class DisplayHdc
+{
+ Q_DISABLE_COPY(DisplayHdc)
+public:
+ DisplayHdc() : m_displayDc(GetDC(nullptr)) {}
+ ~DisplayHdc() { ReleaseDC(nullptr, m_displayDc); }
+
+ operator HDC() const { return m_displayDc; }
+
+private:
+ const HDC m_displayDc;
+};
+
enum HBitmapFormat
{
HBitmapNoAlpha,
@@ -123,108 +234,229 @@ Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap)
const int w = bm.width();
const int h = bm.height();
const int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment
- QScopedArrayPointer<uchar> bits(new uchar[bpl * h]);
+ QScopedArrayPointer<uchar> bits(new uchar[size_t(bpl * h)]);
bm.invertPixels();
for (int y = 0; y < h; ++y)
- memcpy(bits.data() + y * bpl, bm.constScanLine(y), bpl);
+ memcpy(bits.data() + y * bpl, bm.constScanLine(y), size_t(bpl));
HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits.data());
return hbm;
}
-Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0)
+static inline QImage::Format format32(int hbitmapFormat)
{
- if (p.isNull())
- return 0;
-
- HBITMAP bitmap = 0;
- if (p.handle()->classId() != QPlatformPixmap::RasterClass) {
- QRasterPlatformPixmap *data = new QRasterPlatformPixmap(p.depth() == 1 ?
- QRasterPlatformPixmap::BitmapType : QRasterPlatformPixmap::PixmapType);
- data->fromImage(p.toImage(), Qt::AutoColor);
- return qt_pixmapToWinHBITMAP(QPixmap(data), hbitmapFormat);
+ switch (hbitmapFormat) {
+ case HBitmapNoAlpha:
+ return QImage::Format_RGB32;
+ case HBitmapAlpha:
+ return QImage::Format_ARGB32;
+ default:
+ break;
}
+ return QImage::Format_ARGB32_Premultiplied;
+}
- QRasterPlatformPixmap *d = static_cast<QRasterPlatformPixmap*>(p.handle());
- const QImage *rasterImage = d->buffer();
- const int w = rasterImage->width();
- const int h = rasterImage->height();
-
- HDC display_dc = GetDC(0);
+Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &imageIn, int hbitmapFormat = 0)
+{
+ if (imageIn.isNull())
+ return nullptr;
// Define the header
- BITMAPINFO bmi;
- initBitMapInfo(w, h, true, &bmi);
+ DWORD compression = 0;
+ DWORD bitCount = 0;
+
+ // Copy over the data
+ QImage image = imageIn;
+ switch (image.format()) {
+ case QImage::Format_Mono:
+ bitCount = 1u;
+ break;
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
+ case QImage::Format_ARGB32_Premultiplied: {
+ compression = BI_RGB;
+ bitCount = 32u;
+ const QImage::Format targetFormat = format32(hbitmapFormat);
+ if (targetFormat != image.format())
+ image = image.convertToFormat(targetFormat);
+ }
+ break;
+ case QImage::Format_RGB888:
+ compression = BI_RGB;
+ bitCount = 24u;
+ break;
+ case QImage::Format_Indexed8:
+ bitCount = 8u;
+ break;
+ case QImage::Format_RGB555:
+ bitCount = 16u;
+ break;
+ default: {
+ QImage::Format fallbackFormat = QImage::Format_ARGB32_Premultiplied;
+ switch (image.format()) { // Convert to a suitable format.
+ case QImage::Format_MonoLSB:
+ fallbackFormat = QImage::Format_Mono;
+ break;
+ case QImage::Format_RGB16:
+ fallbackFormat = QImage::Format_RGB555;
+ break;
+ case QImage::Format_Grayscale8:
+ fallbackFormat = QImage::Format_Indexed8;
+ break;
+ default:
+ break;
+ } // switch conversion format
+ return qt_imageToWinHBITMAP(imageIn.convertToFormat(fallbackFormat), hbitmapFormat);
+ }
+ }
+
+ const int w = image.width();
+ const int h = image.height();
+
+ BITMAPINFO_COLORTABLE256 bmiColorTable256;
+ initBitMapInfo(w, h, true, compression, bitCount, &bmiColorTable256);
+ BITMAPINFO &bmi = reinterpret_cast<BITMAPINFO &>(bmiColorTable256);
+ switch (image.format()) {
+ case QImage::Format_Mono: // Color table with 2 entries
+ case QImage::Format_Indexed8:
+ std::transform(image.colorTable().constBegin(), image.colorTable().constEnd(),
+ bmiColorTable256.bmiColors, qRgbToRgbQuad);
+ break;
+ default:
+ break;
+ }
// Create the pixmap
- uchar *pixels = 0;
- bitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (void **) &pixels, 0, 0);
- ReleaseDC(0, display_dc);
+ uchar *pixels = nullptr;
+ const HBITMAP bitmap = CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS,
+ reinterpret_cast<void **>(&pixels), nullptr, 0);
if (!bitmap) {
qErrnoWarning("%s, failed to create dibsection", __FUNCTION__);
- return 0;
+ return nullptr;
}
if (!pixels) {
qErrnoWarning("%s, did not allocate pixel data", __FUNCTION__);
- return 0;
+ return nullptr;
}
-
- // Copy over the data
- QImage::Format imageFormat = QImage::Format_RGB32;
- if (hbitmapFormat == HBitmapAlpha)
- imageFormat = QImage::Format_ARGB32;
- else if (hbitmapFormat == HBitmapPremultipliedAlpha)
- imageFormat = QImage::Format_ARGB32_Premultiplied;
- const QImage image = rasterImage->convertToFormat(imageFormat);
- const int bytes_per_line = w * 4;
- for (int y=0; y < h; ++y)
- memcpy(pixels + y * bytes_per_line, image.scanLine(y), bytes_per_line);
-
+ memcpy(pixels, image.constBits(), bmi.bmiHeader.biSizeImage);
+ if (image.format() == QImage::Format_RGB888)
+ flipRgb3(pixels, w, h);
return bitmap;
}
+Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0)
+{
+ if (p.isNull())
+ return nullptr;
-Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0)
+ QPlatformPixmap *platformPixmap = p.handle();
+ if (platformPixmap->classId() != QPlatformPixmap::RasterClass) {
+ QRasterPlatformPixmap *data = new QRasterPlatformPixmap(p.depth() == 1 ?
+ QRasterPlatformPixmap::BitmapType : QRasterPlatformPixmap::PixmapType);
+ data->fromImage(p.toImage(), Qt::AutoColor);
+ return qt_pixmapToWinHBITMAP(QPixmap(data), hbitmapFormat);
+ }
+
+ return qt_imageToWinHBITMAP(*static_cast<QRasterPlatformPixmap*>(platformPixmap)->buffer(), hbitmapFormat);
+}
+
+static QImage::Format imageFromWinHBITMAP_Format(const BITMAPINFOHEADER &header, int hbitmapFormat)
{
- // Verify size
- BITMAP bitmap_info;
- memset(&bitmap_info, 0, sizeof(BITMAP));
+ QImage::Format result = QImage::Format_Invalid;
+ switch (header.biBitCount) {
+ case 32:
+ result = hbitmapFormat == HBitmapNoAlpha
+ ? QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied;
+ break;
+ case 24:
+ result = QImage::Format_RGB888;
+ break;
+ case 16:
+ result = QImage::Format_RGB555;
+ break;
+ case 8:
+ result = QImage::Format_Indexed8;
+ break;
+ case 1:
+ result = QImage::Format_Mono;
+ break;
+ }
+ return result;
+}
- const int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info);
- if (!res) {
- qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info");
- return QPixmap();
+// Fast path for creating a QImage directly from a HBITMAP created by CreateDIBSection(),
+// not requiring memory allocation.
+static QImage imageFromWinHBITMAP_DibSection(HBITMAP bitmap, int hbitmapFormat)
+{
+ DIBSECTION dibSection;
+ memset(&dibSection, 0, sizeof(dibSection));
+ dibSection.dsBmih.biSize = sizeof(dibSection.dsBmih);
+
+ if (!GetObject(bitmap, sizeof(dibSection), &dibSection)
+ || !dibSection.dsBm.bmBits
+ || dibSection.dsBmih.biBitCount <= 8 // Cannot access the color table for Indexed8, Mono
+ || dibSection.dsBmih.biCompression != BI_RGB) {
+ return QImage();
}
- const int w = bitmap_info.bmWidth;
- const int h = bitmap_info.bmHeight;
-
- // Get bitmap bits
- HDC display_dc = GetDC(0);
- QScopedArrayPointer<uchar> data(getDiBits(display_dc, bitmap, w, h, true));
- if (data.isNull()) {
- ReleaseDC(0, display_dc);
- return QPixmap();
+
+ const QImage::Format imageFormat = imageFromWinHBITMAP_Format(dibSection.dsBmih, hbitmapFormat);
+ if (imageFormat == QImage::Format_Invalid)
+ return QImage();
+
+ return copyImageData(dibSection.dsBmih, nullptr, dibSection.dsBm.bmBits, imageFormat);
+}
+
+// Create QImage from a HBITMAP using GetDIBits(), potentially with conversion.
+static QImage imageFromWinHBITMAP_GetDiBits(HBITMAP bitmap, bool forceQuads, int hbitmapFormat)
+{
+ BITMAPINFO_COLORTABLE256 bmiColorTable256;
+ BITMAPINFO &info = reinterpret_cast<BITMAPINFO &>(bmiColorTable256);
+ memset(&info, 0, sizeof(info));
+ info.bmiHeader.biSize = sizeof(info.bmiHeader);
+
+ DisplayHdc displayDc;
+ if (!GetDIBits(displayDc, bitmap, 0, 1, 0, &info, DIB_RGB_COLORS)) {
+ qErrnoWarning("%s: GetDIBits() failed to query data.", __FUNCTION__);
+ return QImage();
}
- const QImage::Format imageFormat = hbitmapFormat == HBitmapNoAlpha ?
- QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied;
+ if (info.bmiHeader.biHeight > 0) // Force top-down
+ info.bmiHeader.biHeight = -info.bmiHeader.biHeight;
+ info.bmiHeader.biCompression = BI_RGB; // Extract using no compression (can be BI_BITFIELD)
+ if (forceQuads)
+ info.bmiHeader.biBitCount = 32;
- // Create image and copy data into image.
- QImage image(w, h, imageFormat);
- if (image.isNull()) { // failed to alloc?
- ReleaseDC(0, display_dc);
- qWarning("%s, failed create image of %dx%d", __FUNCTION__, w, h);
- return QPixmap();
+ const QImage::Format imageFormat = imageFromWinHBITMAP_Format(info.bmiHeader, hbitmapFormat);
+ if (imageFormat == QImage::Format_Invalid) {
+ qWarning().nospace() << __FUNCTION__ << ": unsupported image format:" << info.bmiHeader;
+ return QImage();
}
- copyImageDataCreateAlpha(data.data(), &image);
- ReleaseDC(0, display_dc);
- return QPixmap::fromImage(image);
+
+ QScopedPointer<uchar> data(new uchar[info.bmiHeader.biSizeImage]);
+ if (!GetDIBits(displayDc, bitmap, 0, qAbs(info.bmiHeader.biHeight), data.data(), &info, DIB_RGB_COLORS)) {
+ qErrnoWarning("%s: GetDIBits() failed to get data.", __FUNCTION__);
+ return QImage();
+ }
+ return copyImageData(info.bmiHeader, bmiColorTable256.bmiColors, data.data(), imageFormat);
}
+Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0)
+{
+ QImage result = imageFromWinHBITMAP_DibSection(bitmap, hbitmapFormat);
+ if (result.isNull())
+ result = imageFromWinHBITMAP_GetDiBits(bitmap, /* forceQuads */ false, hbitmapFormat);
+ return result;
+}
+
+Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0)
+{
+ const QImage image = imageFromWinHBITMAP_GetDiBits(bitmap, /* forceQuads */ true, hbitmapFormat);
+ return QPixmap::fromImage(image);
+}
Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p)
{
if (p.isNull())
- return 0;
+ return nullptr;
QBitmap maskBitmap = p.mask();
if (maskBitmap.isNull()) {
@@ -267,7 +499,7 @@ static QImage qt_imageFromWinIconHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
QScopedArrayPointer<uchar> data(getDiBits(hdc, bitmap, w, h, true));
if (data.isNull())
return QImage();
- copyImageData(data.data(), &image);
+ memcpy(image.bits(), data.data(), size_t(image.sizeInBytes()));
return image;
}
@@ -287,9 +519,9 @@ static inline bool hasAlpha(const QImage &image)
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
{
- HDC screenDevice = GetDC(0);
+ HDC screenDevice = GetDC(nullptr);
HDC hdc = CreateCompatibleDC(screenDevice);
- ReleaseDC(0, screenDevice);
+ ReleaseDC(nullptr, screenDevice);
ICONINFO iconinfo;
const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
@@ -299,25 +531,27 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
return QPixmap();
}
- const int w = iconinfo.xHotspot * 2;
- const int h = iconinfo.yHotspot * 2;
+ const int w = int(iconinfo.xHotspot) * 2;
+ const int h = int(iconinfo.yHotspot) * 2;
BITMAPINFOHEADER bitmapInfo;
- initBitMapInfoHeader(w, h, false, &bitmapInfo);
+ initBitMapInfoHeader(w, h, false, BI_RGB, 32u, &bitmapInfo);
DWORD* bits;
- HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0);
- HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);
- DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
+ HBITMAP winBitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bitmapInfo),
+ DIB_RGB_COLORS, reinterpret_cast<VOID **>(&bits),
+ nullptr, 0);
+ HGDIOBJ oldhdc = static_cast<HBITMAP>(SelectObject(hdc, winBitmap));
+ DrawIconEx(hdc, 0, 0, icon, w, h, 0, nullptr, DI_NORMAL);
QImage image = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
if (!image.isNull() && !hasAlpha(image)) { //If no alpha was found, we use the mask to set alpha values
- DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
+ DrawIconEx( hdc, 0, 0, icon, w, h, 0, nullptr, DI_MASK);
const QImage mask = qt_imageFromWinIconHBITMAP(hdc, winBitmap, w, h);
for (int y = 0 ; y < h ; y++){
QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y));
- const QRgb *scanlineMask = mask.isNull() ? 0 : reinterpret_cast<const QRgb *>(mask.scanLine(y));
+ const QRgb *scanlineMask = mask.isNull() ? nullptr : reinterpret_cast<const QRgb *>(mask.scanLine(y));
for (int x = 0; x < w ; x++){
if (scanlineMask && qRed(scanlineMask[x]) != 0)
scanlineImage[x] = 0; //mask out this pixel
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 4b8b1203d6..3d1652f68b 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -86,7 +86,17 @@ QT_BEGIN_NAMESPACE
\sa QCache, QPixmap
*/
-static int cache_limit = 10240; // 10 MB cache limit
+static const int cache_limit_default = 10240; // 10 MB cache limit
+
+static inline int cost(const QPixmap &pixmap)
+{
+ // make sure to do a 64bit calculation
+ const qint64 costKb = static_cast<qint64>(pixmap.width()) *
+ pixmap.height() * pixmap.depth() / (8 * 1024);
+ const qint64 costMax = std::numeric_limits<int>::max();
+ // a small pixmap should have at least a cost of 1(kb)
+ return static_cast<int>(qBound(1LL, costKb, costMax));
+}
/*!
\class QPixmapCache::Key
@@ -237,7 +247,7 @@ uint qHash(const QPixmapCache::Key &k)
QPMCache::QPMCache()
: QObject(0),
- QCache<QPixmapCache::Key, QPixmapCacheEntry>(cache_limit * 1024),
+ QCache<QPixmapCache::Key, QPixmapCacheEntry>(cache_limit_default),
keyArray(0), theid(0), ps(0), keyArraySize(0), freeKey(0), t(false)
{
}
@@ -553,7 +563,7 @@ bool QPixmapCache::find(const Key &key, QPixmap* pixmap)
bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
{
- return pm_cache()->insert(key, pixmap, pixmap.width() * pixmap.height() * pixmap.depth() / 8);
+ return pm_cache()->insert(key, pixmap, cost(pixmap));
}
/*!
@@ -573,7 +583,7 @@ bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
*/
QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap)
{
- return pm_cache()->insert(pixmap, pixmap.width() * pixmap.height() * pixmap.depth() / 8);
+ return pm_cache()->insert(pixmap, cost(pixmap));
}
/*!
@@ -590,7 +600,7 @@ bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap)
//The key is not valid anymore, a flush happened before probably
if (!key.d || !key.d->isValid)
return false;
- return pm_cache()->replace(key, pixmap, pixmap.width() * pixmap.height() * pixmap.depth() / 8);
+ return pm_cache()->replace(key, pixmap, cost(pixmap));
}
/*!
@@ -603,7 +613,7 @@ bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap)
int QPixmapCache::cacheLimit()
{
- return cache_limit;
+ return pm_cache()->maxCost();
}
/*!
@@ -616,8 +626,7 @@ int QPixmapCache::cacheLimit()
void QPixmapCache::setCacheLimit(int n)
{
- cache_limit = n;
- pm_cache()->setMaxCost(1024 * cache_limit);
+ pm_cache()->setMaxCost(n);
}
/*!
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 42b9e71087..242d8cd63b 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -245,7 +245,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
png_set_interlace_handling(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY) {
- // Black & White or 8-bit grayscale
+ // Black & White or grayscale
if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
png_set_invert_mono(png_ptr);
png_read_update_info(png_ptr, info_ptr);
@@ -266,19 +266,22 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
else if (g == 1)
image.setColor(0, qRgba(255, 255, 255, 0));
}
- } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- png_set_expand(png_ptr);
- png_set_strip_16(png_ptr);
+ } else if (bit_depth == 16) {
+ bool hasMask = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
+ if (!hasMask)
+ png_set_filler(png_ptr, 0xffff, PNG_FILLER_AFTER);
+ else
+ png_set_expand(png_ptr);
png_set_gray_to_rgb(png_ptr);
- if (image.size() != QSize(width, height) || image.format() != QImage::Format_ARGB32) {
- image = QImage(width, height, QImage::Format_ARGB32);
+ QImage::Format format = hasMask ? QImage::Format_RGBA64 : QImage::Format_RGBX64;
+ if (image.size() != QSize(width, height) || image.format() != format) {
+ image = QImage(width, height, format);
if (image.isNull())
return;
}
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- png_set_swap_alpha(png_ptr);
-
png_read_update_info(png_ptr, info_ptr);
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
+ png_set_swap(png_ptr);
} else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_expand(png_ptr);
if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale8) {
@@ -289,9 +292,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
png_read_update_info(png_ptr, info_ptr);
} else {
- if (bit_depth == 16)
- png_set_strip_16(png_ptr);
- else if (bit_depth < 8)
+ if (bit_depth < 8)
png_set_packing(png_ptr);
int ncols = bit_depth < 8 ? 1 << bit_depth : 256;
png_read_update_info(png_ptr, info_ptr);
@@ -352,6 +353,26 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
);
i++;
}
+ // Qt==ARGB==Big(ARGB)==Little(BGRA)
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
+ png_set_bgr(png_ptr);
+ }
+ } else if (bit_depth == 16 && !(color_type & PNG_COLOR_MASK_PALETTE)) {
+ QImage::Format format = QImage::Format_RGBA64;
+ if (!(color_type & PNG_COLOR_MASK_ALPHA) && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ png_set_filler(png_ptr, 0xffff, PNG_FILLER_AFTER);
+ format = QImage::Format_RGBX64;
+ }
+ if (!(color_type & PNG_COLOR_MASK_COLOR))
+ png_set_gray_to_rgb(png_ptr);
+ if (image.size() != QSize(width, height) || image.format() != format) {
+ image = QImage(width, height, format);
+ if (image.isNull())
+ return;
+ }
+ png_read_update_info(png_ptr, info_ptr);
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
+ png_set_swap(png_ptr);
} else {
// 32-bit
if (bit_depth == 16)
@@ -388,12 +409,12 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
png_set_swap_alpha(png_ptr);
- png_read_update_info(png_ptr, info_ptr);
- }
+ // Qt==ARGB==Big(ARGB)==Little(BGRA)
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
+ png_set_bgr(png_ptr);
+ }
- // Qt==ARGB==Big(ARGB)==Little(BGRA)
- if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
- png_set_bgr(png_ptr);
+ png_read_update_info(png_ptr, info_ptr);
}
}
@@ -662,11 +683,11 @@ QImage::Format QPngHandlerPrivate::readImageFormat()
int num_palette;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
if (color_type == PNG_COLOR_TYPE_GRAY) {
- // Black & White or 8-bit grayscale
+ // Black & White or grayscale
if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
format = QImage::Format_Mono;
- } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- format = QImage::Format_ARGB32;
+ } else if (bit_depth == 16) {
+ format = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? QImage::Format_RGBA64 : QImage::Format_RGBX64;
} else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
format = QImage::Format_Grayscale8;
} else {
@@ -678,6 +699,10 @@ QImage::Format QPngHandlerPrivate::readImageFormat()
{
// 1-bit and 8-bit color
format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
+ } else if (bit_depth == 16 && !(color_type & PNG_COLOR_MASK_PALETTE)) {
+ format = QImage::Format_RGBA64;
+ if (!(color_type & PNG_COLOR_MASK_ALPHA) && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ format = QImage::Format_RGBX64;
} else {
// 32-bit
format = QImage::Format_ARGB32;
@@ -843,8 +868,24 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, c
else
color_type = PNG_COLOR_TYPE_RGB;
+ int bpc = 0;
+ switch (image.format()) {
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ bpc = 1;
+ break;
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ bpc = 16;
+ break;
+ default:
+ bpc = 8;
+ break;
+ }
+
png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
- image.depth() == 1 ? 1 : 8, // per channel
+ bpc, // per channel
color_type, 0, 0, 0); // sets #channels
if (gamma != 0.0) {
@@ -880,13 +921,31 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, c
// Swap ARGB to RGBA (normal PNG format) before saving on
// BigEndian machines
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- png_set_swap_alpha(png_ptr);
+ switch (image.format()) {
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ break;
+ default:
+ png_set_swap_alpha(png_ptr);
+ }
}
// Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless
- if (QSysInfo::ByteOrder == QSysInfo::LittleEndian
- && image.format() != QImage::Format_RGB888) {
- png_set_bgr(png_ptr);
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
+ switch (image.format()) {
+ case QImage::Format_RGB888:
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ break;
+ default:
+ png_set_bgr(png_ptr);
+ }
}
if (off_x || off_y) {
@@ -909,10 +968,32 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, c
if (image.depth() != 1)
png_set_packing(png_ptr);
- if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888)
- png_set_filler(png_ptr, 0,
- QSysInfo::ByteOrder == QSysInfo::BigEndian ?
- PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
+ if (color_type == PNG_COLOR_TYPE_RGB) {
+ switch (image.format()) {
+ case QImage::Format_RGB888:
+ break;
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBX64:
+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+ break;
+ default:
+ png_set_filler(png_ptr, 0,
+ QSysInfo::ByteOrder == QSysInfo::BigEndian ?
+ PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
+ }
+ }
+
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
+ switch (image.format()) {
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ png_set_swap(png_ptr);
+ break;
+ default:
+ break;
+ }
+ }
if (looping >= 0 && frames_written == 0) {
uchar data[13] = "NETSCAPE2.0";
@@ -940,6 +1021,10 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, c
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_RGB888:
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
{
png_bytep* row_pointers = new png_bytep[height];
for (int y=0; y<height; y++)
@@ -948,6 +1033,17 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, c
delete [] row_pointers;
}
break;
+ case QImage::Format_RGBA64_Premultiplied:
+ {
+ QImage row;
+ png_bytep row_pointers[1];
+ for (int y=0; y<height; y++) {
+ row = image.copy(0, y, width, 1).convertToFormat(QImage::Format_RGBA64);
+ row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0));
+ png_write_rows(png_ptr, row_pointers, 1);
+ }
+ }
+ break;
default:
{
QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32;
diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp
index 155a4f88b4..24d86e116d 100644
--- a/src/gui/image/qxbmhandler.cpp
+++ b/src/gui/image/qxbmhandler.cpp
@@ -241,7 +241,7 @@ static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const
}
}
}
-#if defined(_MSC_VER) && _MSC_VER >= 1400
+#ifdef Q_CC_MSVC
strcpy_s(p, sizeof(" };\n"), " };\n");
#else
strcpy(p, " };\n");
diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp
index 9c54b9ada4..17272ffe69 100644
--- a/src/gui/image/qxpmhandler.cpp
+++ b/src/gui/image/qxpmhandler.cpp
@@ -741,10 +741,6 @@ static const struct XPMRGBData {
{ QRGB(139,139, 0), "yellow4" },
{ QRGB(154,205, 50), "yellowgreen" } };
-#if defined(Q_CC_MSVC) && _MSC_VER < 1600
-inline bool operator<(const XPMRGBData &data1, const XPMRGBData &data2)
-{ return qstrcmp(data1.name, data2.name) < 0; }
-#endif
inline bool operator<(const char *name, const XPMRGBData &data)
{ return qstrcmp(name, data.name) < 0; }
diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp
index 235bc5bd7d..8ec88ebc60 100644
--- a/src/gui/itemmodels/qstandarditemmodel.cpp
+++ b/src/gui/itemmodels/qstandarditemmodel.cpp
@@ -306,8 +306,11 @@ const QMap<int, QVariant> QStandardItemPrivate::itemData() const
{
QMap<int, QVariant> result;
QVector<QStandardItemData>::const_iterator it;
- for (it = values.begin(); it != values.end(); ++it)
- result.insert((*it).role, (*it).value);
+ for (it = values.cbegin(); it != values.cend(); ++it){
+ // Qt::UserRole - 1 is used internally to store the flags
+ if (it->role != Qt::UserRole - 1)
+ result.insert(it->role, it->value);
+ }
return result;
}
@@ -931,6 +934,21 @@ void QStandardItem::setData(const QVariant &value, int role)
}
/*!
+ \since 5.12
+ Removes all the data from all roles previously set.
+ \sa data(), setData()
+*/
+void QStandardItem::clearData()
+{
+ Q_D(QStandardItem);
+ if (d->values.isEmpty())
+ return;
+ d->values.clear();
+ if (d->model)
+ d->model->d_func()->itemChanged(this, QVector<int>{});
+}
+
+/*!
Returns the item's data for the given \a role, or an invalid
QVariant if there is no data for the role.
@@ -2924,8 +2942,10 @@ bool QStandardItemModel::insertRows(int row, int count, const QModelIndex &paren
QMap<int, QVariant> QStandardItemModel::itemData(const QModelIndex &index) const
{
Q_D(const QStandardItemModel);
- QStandardItem *item = d->itemFromIndex(index);
- return item ? item->d_func()->itemData() : QMap<int, QVariant>();
+ const QStandardItem *const item = d->itemFromIndex(index);
+ if (!item || item == d->root.data())
+ return QMap<int, QVariant>();
+ return item->d_func()->itemData();
}
/*!
@@ -2991,6 +3011,23 @@ bool QStandardItemModel::setData(const QModelIndex &index, const QVariant &value
}
/*!
+ \since 5.12
+ Removes the data stored in all the roles for the given \a index.
+ \sa setData(), data()
+*/
+bool QStandardItemModel::clearItemData(const QModelIndex &index)
+{
+ if (!checkIndex(index, CheckIndexOption::IndexIsValid))
+ return false;
+ Q_D(QStandardItemModel);
+ QStandardItem *item = d->itemFromIndex(index);
+ if (!item)
+ return false;
+ item->clearData();
+ return true;
+}
+
+/*!
\reimp
*/
bool QStandardItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
diff --git a/src/gui/itemmodels/qstandarditemmodel.h b/src/gui/itemmodels/qstandarditemmodel.h
index 827179b31d..a9ee25da75 100644
--- a/src/gui/itemmodels/qstandarditemmodel.h
+++ b/src/gui/itemmodels/qstandarditemmodel.h
@@ -69,6 +69,7 @@ public:
virtual QVariant data(int role = Qt::UserRole + 1) const;
virtual void setData(const QVariant &value, int role = Qt::UserRole + 1);
+ void clearData();
inline QString text() const {
return qvariant_cast<QString>(data(Qt::DisplayRole));
@@ -343,6 +344,8 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ // Qt 6: add override keyword
+ bool clearItemData(const QModelIndex &index);
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 3b9afdfe8b..1f137fc46f 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -74,8 +74,8 @@ HEADERS += \
kernel/qplatformgraphicsbufferhelper.h \
kernel/qinputdevicemanager_p.h \
kernel/qinputdevicemanager_p_p.h \
- kernel/qhighdpiscaling_p.h
-
+ kernel/qhighdpiscaling_p.h \
+ kernel/qtestsupport_gui.h
SOURCES += \
kernel/qgenericpluginfactory.cpp \
@@ -128,7 +128,8 @@ SOURCES += \
kernel/qplatformgraphicsbuffer.cpp \
kernel/qplatformgraphicsbufferhelper.cpp \
kernel/qinputdevicemanager.cpp \
- kernel/qhighdpiscaling.cpp
+ kernel/qhighdpiscaling.cpp \
+ kernel/qtestsupport_gui.cpp
qtConfig(draganddrop) {
HEADERS += \
diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h
index cc00bc1442..5f6db07987 100644
--- a/src/gui/kernel/qdnd_p.h
+++ b/src/gui/kernel/qdnd_p.h
@@ -63,10 +63,6 @@
#include "private/qobject_p.h"
#include "QtGui/qbackingstore.h"
-// ### Remove the following include, once everybody includes
-// qinternalmimedata_p.h for QInternalMimeData.
-#include "qinternalmimedata_p.h"
-
QT_REQUIRE_CONFIG(draganddrop);
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 4207697c01..0e35fb7d7b 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -783,7 +783,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, int delta,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
Qt::Orientation orient)
: QInputEvent(Wheel, modifiers), p(pos), qt4D(delta), qt4O(orient), mouseState(buttons),
- ph(Qt::NoScrollPhase), src(Qt::MouseEventNotSynthesized), invertedScrolling(false)
+ src(Qt::MouseEventNotSynthesized), invertedScrolling(false), ph(Qt::NoScrollPhase)
{
g = QCursor::pos();
if (orient == Qt::Vertical)
@@ -818,7 +818,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
Qt::Orientation orient)
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), qt4D(delta), qt4O(orient), mouseState(buttons),
- ph(Qt::NoScrollPhase), src(Qt::MouseEventNotSynthesized), invertedScrolling(false)
+ src(Qt::MouseEventNotSynthesized), invertedScrolling(false), ph(Qt::NoScrollPhase)
{
if (orient == Qt::Vertical)
angleD = QPoint(0, delta);
@@ -959,10 +959,49 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source, bool inverted)
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta),
- angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(phase), src(source),
- invertedScrolling(inverted)
+ angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), src(source),
+ invertedScrolling(inverted), ph(phase)
{}
+/*!
+ Constructs a wheel event object.
+
+ The \a pos provides the location of the mouse cursor
+ within the window. The position in global coordinates is specified
+ by \a globalPos.
+
+ \a pixelDelta contains the scrolling distance in pixels on screen, while
+ \a angleDelta contains the wheel rotation distance. \a pixelDelta is
+ optional and can be null.
+
+ The mouse and keyboard states at the time of the event are specified by
+ \a buttons and \a modifiers.
+
+ The scrolling phase of the event is specified by \a phase.
+
+ If the wheel event comes from a physical mouse wheel, \a source is set to
+ Qt::MouseEventNotSynthesized. If it comes from a gesture detected by the
+ operating system, or from a non-mouse hardware device, such that \a
+ pixelDelta is directly related to finger movement, \a source is set to
+ Qt::MouseEventSynthesizedBySystem. If it comes from Qt, source would be set
+ to Qt::MouseEventSynthesizedByQt.
+
+ If the system is configured to invert the delta values delivered with the
+ event (such as natural scrolling of the touchpad on macOS), \a inverted
+ should be \c true. Otherwise, \a inverted is \c false
+
+ \sa posF(), globalPosF(), angleDelta(), pixelDelta(), phase()
+*/
+QWheelEvent::QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoint angleDelta,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase,
+ bool inverted, Qt::MouseEventSource source)
+ : QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta), angleD(angleDelta),
+ qt4O(qAbs(angleDelta.x()) > qAbs(angleDelta.y()) ? Qt::Horizontal : Qt::Vertical),
+ mouseState(buttons), src(source), invertedScrolling(inverted), ph(phase)
+{
+ qt4D = (qt4O == Qt::Horizontal ? angleDelta.x() : angleDelta.y());
+}
+
#endif // QT_CONFIG(wheelevent)
/*!
@@ -1536,8 +1575,8 @@ QMoveEvent::~QMoveEvent()
\ingroup events
- Expose events are sent to windows when an area of the window is invalidated
- or window exposure in the windowing system changes.
+ Expose events are sent to windows when an area of the window is invalidated,
+ for example when window exposure in the windowing system changes.
A Window with a client area that is completely covered by another window, or
is otherwise not visible may be considered obscured by Qt and may in such
@@ -4031,7 +4070,12 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
# if QT_CONFIG(wheelevent)
case QEvent::Wheel: {
const QWheelEvent *we = static_cast<const QWheelEvent *>(e);
- dbg << "QWheelEvent(" << "pixelDelta=" << we->pixelDelta() << ", angleDelta=" << we->angleDelta() << ')';
+ dbg << "QWheelEvent(" << we->phase();
+ if (!we->pixelDelta().isNull() || !we->angleDelta().isNull())
+ dbg << ", pixelDelta=" << we->pixelDelta() << ", angleDelta=" << we->angleDelta();
+ else if (int qt4Delta = we->delta())
+ dbg << ", delta=" << qt4Delta << ", orientation=" << we->orientation();
+ dbg << ')';
}
break;
# endif // QT_CONFIG(wheelevent)
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 033d24d665..2b1c6a6e31 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -193,6 +193,10 @@ public:
QWheelEvent(const QPointF &pos, const QPointF &globalPos, QPoint pixelDelta, QPoint angleDelta,
int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source, bool inverted);
+
+ QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoint angleDelta,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase,
+ bool inverted, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
~QWheelEvent();
@@ -225,13 +229,14 @@ protected:
QPointF g;
QPoint pixelD;
QPoint angleD;
- int qt4D;
- Qt::Orientation qt4O;
+ int qt4D = 0;
+ Qt::Orientation qt4O = Qt::Vertical;
Qt::MouseButtons mouseState;
- uint ph : 2;
+ uint _unused_ : 2; // Kept for binary compatibility
uint src: 2;
bool invertedScrolling : 1;
- int reserved : 27;
+ uint ph : 3;
+ int reserved : 24;
friend class QApplication;
};
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index e81c88cc71..9bf2a33e2a 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -114,6 +114,10 @@
# include <QtCore/QLibraryInfo>
#endif // Q_OS_WIN
+#ifdef Q_OS_WASM
+#include <emscripten.h>
+#endif
+
#include <qtgui_tracepoints_p.h>
#include <ctype.h>
@@ -143,6 +147,8 @@ Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationI
bool QGuiApplicationPrivate::highDpiScalingUpdated = false;
+QPointer<QWindow> QGuiApplicationPrivate::currentDragWindow;
+
QVector<QGuiApplicationPrivate::TabletPointData> QGuiApplicationPrivate::tabletDevicePoints;
QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
@@ -250,10 +256,10 @@ static inline void clearFontUnlocked()
QGuiApplicationPrivate::app_font = 0;
}
-static bool checkRunningUnderFlatpak()
+static bool checkNeedPortalSupport()
{
#if QT_CONFIG(dbus)
- return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty();
+ return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty() || qEnvironmentVariableIsSet("SNAP");
#else
return false;
#endif // QT_CONFIG(dbus)
@@ -592,6 +598,9 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
By default, they will be used if the application is not an
instance of QApplication or for Qt Quick Controls 2
applications.
+
+ \li \c {altgr}, detect the key \c {AltGr} found on some keyboards as
+ Qt::GroupSwitchModifier.
\endlist
The following parameter is available for \c {-platform cocoa} (on macOS):
@@ -668,6 +677,7 @@ QGuiApplication::~QGuiApplication()
QGuiApplicationPrivate::currentMousePressWindow = QGuiApplicationPrivate::currentMouseWindow = nullptr;
QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive;
QGuiApplicationPrivate::highDpiScalingUpdated = false;
+ QGuiApplicationPrivate::currentDragWindow = nullptr;
QGuiApplicationPrivate::tabletDevicePoints.clear();
#ifndef QT_NO_SESSIONMANAGER
QGuiApplicationPrivate::is_fallback_session_management_enabled = true;
@@ -1215,9 +1225,9 @@ static void init_platform(const QString &pluginNamesWithArguments, const QString
if (!platformThemeName.isEmpty())
themeNames.append(platformThemeName);
- // 2) Special case - check whether we are in sandbox to use flatpak platform theme for portals support
- if (checkRunningUnderFlatpak()) {
- themeNames.append(QStringLiteral("flatpak"));
+ // 2) Special case - check whether it's a flatpak or snap app to use xdg-desktop-portal platform theme for portals support
+ if (checkNeedPortalSupport()) {
+ themeNames.append(QStringLiteral("xdgdesktopportal"));
}
// 3) Ask the platform integration for a list of theme names
@@ -1409,7 +1419,7 @@ void QGuiApplicationPrivate::eventDispatcherReady()
void QGuiApplicationPrivate::init()
{
- Q_TRACE(qguiapplicationprivate_init_entry);
+ Q_TRACE(QGuiApplicationPrivate_init_entry);
#if defined(Q_OS_MACOS)
QMacAutoReleasePool pool;
@@ -1574,7 +1584,7 @@ void QGuiApplicationPrivate::init()
QObject::connect(q, &QGuiApplication::applicationNameChanged,
q, &QGuiApplication::applicationDisplayNameChanged);
- Q_TRACE(qguiapplicationprivate_init_exit);
+ Q_TRACE(QGuiApplicationPrivate_init_exit);
}
extern void qt_cleanupFontDatabase();
@@ -1614,7 +1624,13 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
qt_gl_set_global_share_context(0);
}
#endif
-
+#ifdef Q_OS_WASM
+ EM_ASM(
+ // unmount persistent directory as IDBFS
+ // see QTBUG-70002
+ FS.unmount('/home/web_user');
+ );
+#endif
platform_integration->destroy();
delete platform_theme;
@@ -1690,7 +1706,7 @@ Qt::KeyboardModifiers QGuiApplication::queryKeyboardModifiers()
/*!
Returns the current state of the buttons on the mouse. The current state is
- updated syncronously as the event queue is emptied of events that will
+ updated synchronously as the event queue is emptied of events that will
spontaneously change the mouse state (QEvent::MouseButtonPress and
QEvent::MouseButtonRelease events).
@@ -1765,8 +1781,11 @@ int QGuiApplication::exec()
*/
bool QGuiApplication::notify(QObject *object, QEvent *event)
{
- if (object->isWindowType())
- QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(object), event);
+ if (object->isWindowType()) {
+ if (QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(object), event))
+ return true; // Platform plugin ate the event
+ }
+
return QCoreApplication::notify(object, event);
}
@@ -1788,18 +1807,18 @@ bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEvent
return QCoreApplication::compressEvent(event, receiver, postedEvents);
}
-void QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event)
+bool QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event)
{
if (!window)
- return;
+ return false;
QPlatformWindow *platformWindow = window->handle();
if (!platformWindow)
- return;
+ return false;
// spontaneous events come from the platform integration already, we don't need to send the events back
if (event->spontaneous())
- return;
+ return false;
// let the platform window do any handling it needs to as well
- platformWindow->windowEvent(event);
+ return platformWindow->windowEvent(event);
}
bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result)
@@ -1809,7 +1828,7 @@ bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArra
void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
{
- Q_TRACE(qguiapplicationprivate_processwsevents_entry, e->type);
+ Q_TRACE(QGuiApplicationPrivate_processWindowSystemEvent_entry, e->type);
switch(e->type) {
case QWindowSystemInterfacePrivate::Mouse:
@@ -1920,7 +1939,7 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
break;
}
- Q_TRACE(qguiapplicationprivate_processwsevents_exit, e->type);
+ Q_TRACE(QGuiApplicationPrivate_processWindowSystemEvent_exit, e->type);
}
/*! \internal
@@ -2332,11 +2351,11 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
if (QWindow *window = wse->window.data()) {
if (window->screen() == wse->screen.data())
return;
- if (window->isTopLevel()) {
+ if (QWindow *topLevelWindow = window->d_func()->topLevelWindow(QWindow::ExcludeTransients)) {
if (QScreen *screen = wse->screen.data())
- window->d_func()->setTopLevelScreen(screen, false /* recreate */);
+ topLevelWindow->d_func()->setTopLevelScreen(screen, false /* recreate */);
else // Fall back to default behavior, and try to find some appropriate screen
- window->setScreen(0);
+ topLevelWindow->setScreen(0);
}
// we may have changed scaling, so trigger resize event if needed
if (window->handle()) {
@@ -3047,9 +3066,56 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E
#if QT_CONFIG(draganddrop)
-QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
+/*! \internal
+
+ This function updates an internal state to keep the source compatibility. Documentation of
+ QGuiApplication::mouseButtons() states - "The current state is updated synchronously as
+ the event queue is emptied of events that will spontaneously change the mouse state
+ (QEvent::MouseButtonPress and QEvent::MouseButtonRelease events)". But internally we have
+ been updating these state variables from various places to keep buttons returned by
+ mouseButtons() in sync with the systems state. This is not the documented behavior.
+
+ ### Qt6 - Remove QGuiApplication::mouseButtons()/keyboardModifiers() API? And here
+ are the reasons:
+
+ - It is an easy to misuse API by:
+
+ a) Application developers: The only place where the values of this API can be trusted is
+ when using within mouse handling callbacks. In these callbacks we work with the state
+ that was provided directly by the windowing system. Anywhere else it might not reflect what
+ user wrongly expects. We might not always receive a matching mouse release for a press event
+ (e.g. When dismissing a popup window on X11. Or when dnd enter Qt application with mouse
+ button down, we update mouse_buttons and then dnd leaves Qt application and does a drop
+ somewhere else) and hence mouseButtons() will be out-of-sync from users perspective, see
+ for example QTBUG-33161. BUT THIS IS NOT HOW THE API IS SUPPOSED TO BE USED. Since the only
+ safe place to use this API is from mouse event handlers, we might as well deprecate it and
+ pass down the button state if we are not already doing that everywhere where it matters.
+
+ b) Qt framework developers:
+
+ We see users complaining, we start adding hacks everywhere just to keep buttons in sync ;)
+ There are corner cases that can not be solved and adding this kind of hacks is never ending
+ task.
+
+ - Real mouse events, tablet mouse events, etc: all go through QGuiApplication::processMouseEvent,
+ and all share mouse_buttons. What if we want to support multiple mice in future? The API must
+ go.
+
+ - Motivation why this API is public is not clear. Could the same be achieved by a user by
+ installing an event filter?
+*/
+static void updateMouseAndModifierButtonState(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
{
- static QPointer<QWindow> currentDragWindow;
+ QGuiApplicationPrivate::mouse_buttons = buttons;
+ QGuiApplicationPrivate::modifier_buttons = modifiers;
+}
+
+QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
+{
+ updateMouseAndModifierButtonState(buttons, modifiers);
+
static Qt::DropAction lastAcceptedDropAction = Qt::IgnoreAction;
QPlatformDrag *platformDrag = platformIntegration()->drag();
if (!platformDrag || (w && w->d_func()->blockedByModalWindow)) {
@@ -3058,15 +3124,13 @@ QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QM
}
if (!dropData) {
- if (currentDragWindow.data() == w)
- currentDragWindow = 0;
+ currentDragWindow = nullptr;
QDragLeaveEvent e;
QGuiApplication::sendEvent(w, &e);
lastAcceptedDropAction = Qt::IgnoreAction;
return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
}
- QDragMoveEvent me(p, supportedActions, dropData,
- QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ QDragMoveEvent me(p, supportedActions, dropData, buttons, modifiers);
if (w != currentDragWindow) {
lastAcceptedDropAction = Qt::IgnoreAction;
@@ -3075,8 +3139,7 @@ QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QM
QGuiApplication::sendEvent(currentDragWindow, &e);
}
currentDragWindow = w;
- QDragEnterEvent e(p, supportedActions, dropData,
- QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ QDragEnterEvent e(p, supportedActions, dropData, buttons, modifiers);
QGuiApplication::sendEvent(w, &e);
if (e.isAccepted() && e.dropAction() != Qt::IgnoreAction)
lastAcceptedDropAction = e.dropAction();
@@ -3094,10 +3157,15 @@ QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QM
return QPlatformDragQtResponse(me.isAccepted(), lastAcceptedDropAction, me.answerRect());
}
-QPlatformDropQtResponse QGuiApplicationPrivate::processDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
+QPlatformDropQtResponse QGuiApplicationPrivate::processDrop(QWindow *w, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
{
- QDropEvent de(p, supportedActions, dropData,
- QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ updateMouseAndModifierButtonState(buttons, modifiers);
+
+ currentDragWindow = nullptr;
+
+ QDropEvent de(p, supportedActions, dropData, buttons, modifiers);
QGuiApplication::sendEvent(w, &de);
Qt::DropAction acceptedAction = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index f6f7aa7f8c..79c1a1c820 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -163,13 +163,17 @@ public:
#endif
#if QT_CONFIG(draganddrop)
- static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
- static QPlatformDropQtResponse processDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
+ static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
+ static QPlatformDropQtResponse processDrop(QWindow *w, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
#endif
static bool processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result);
- static void sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event);
+ static bool sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event);
static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
{
@@ -213,6 +217,7 @@ public:
static QWindow *currentMousePressWindow;
static Qt::ApplicationState applicationState;
static bool highDpiScalingUpdated;
+ static QPointer<QWindow> currentDragWindow;
struct TabletPointData {
TabletPointData(qint64 devId = 0) : deviceId(devId), state(Qt::NoButton), target(nullptr) {}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 8689f9f3b1..a455aa639d 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -244,7 +244,8 @@ static inline bool usePixelDensity()
return false;
return QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling)
|| (screenEnvValueOk && screenEnvValue > 0)
- || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) && qgetenv(legacyDevicePixelEnvVar).toLower() == "auto");
+ || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) &&
+ qgetenv(legacyDevicePixelEnvVar).compare("auto", Qt::CaseInsensitive) == 0);
}
void QHighDpiScaling::initHighDpiScaling()
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 9a9677b476..a428da8ca4 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -1062,6 +1062,8 @@ int QKeySequence::decodeString(const QString &str)
int QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceFormat format)
{
+ Q_ASSERT(!accel.isEmpty());
+
int ret = 0;
accel = std::move(accel).toLower();
bool nativeText = (format == QKeySequence::NativeText);
@@ -1121,7 +1123,10 @@ int QKeySequencePrivate::decodeString(QString accel, QKeySequence::SequenceForma
sl = accel;
}
}
+ if (accel.isEmpty()) // Incomplete, like for "Meta+Shift+"
+ return Qt::Key_unknown;
#endif
+
int i = 0;
int lastI = 0;
while ((i = sl.indexOf(QLatin1Char('+'), i + 1)) != -1) {
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 4efa5a40f3..c5d5490ea0 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -945,7 +945,7 @@ GLuint QOpenGLContext::defaultFramebufferObject() const
Avoid calling this function from a different thread than the one the
QOpenGLContext instance lives in. If you wish to use QOpenGLContext from a
- different thread you should first call make sure it's not current in the
+ different thread you should first make sure it's not current in the
current thread, by calling doneCurrent() if necessary. Then call
moveToThread(otherThread) before using it in the other thread.
@@ -977,67 +977,66 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
if (!surface->surfaceHandle())
return false;
if (!surface->supportsOpenGL()) {
+#ifndef Q_OS_WASM // ### work around the WASM platform plugin using QOpenGLContext with raster surfaces.
+ // see QTBUG-70076
qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface" << surface;
return false;
+#endif
}
- QOpenGLContext *previous = QOpenGLContextPrivate::setCurrentContext(this);
-
- if (d->platformGLContext->makeCurrent(surface->surfaceHandle())) {
- static bool needsWorkaroundSet = false;
- static bool needsWorkaround = false;
+ if (!d->platformGLContext->makeCurrent(surface->surfaceHandle()))
+ return false;
- if (!needsWorkaroundSet) {
- QByteArray env;
-#ifdef Q_OS_ANDROID
- env = qgetenv(QByteArrayLiteral("QT_ANDROID_DISABLE_GLYPH_CACHE_WORKAROUND"));
- needsWorkaround = env.isEmpty() || env == QByteArrayLiteral("0") || env == QByteArrayLiteral("false");
+ QOpenGLContextPrivate::setCurrentContext(this);
+#ifndef QT_NO_DEBUG
+ QOpenGLContextPrivate::toggleMakeCurrentTracker(this, true);
#endif
- env = qgetenv(QByteArrayLiteral("QT_ENABLE_GLYPH_CACHE_WORKAROUND"));
- if (env == QByteArrayLiteral("1") || env == QByteArrayLiteral("true"))
- needsWorkaround = true;
-
- if (!needsWorkaround) {
- const char *rendererString = reinterpret_cast<const char *>(functions()->glGetString(GL_RENDERER));
- if (rendererString)
- needsWorkaround =
- qstrncmp(rendererString, "Mali-4xx", 6) == 0 // Mali-400, Mali-450
- || qstrcmp(rendererString, "Mali-T880") == 0
- || qstrncmp(rendererString, "Adreno (TM) 2xx", 13) == 0 // Adreno 200, 203, 205
- || qstrncmp(rendererString, "Adreno 2xx", 8) == 0 // Same as above but without the '(TM)'
- || qstrncmp(rendererString, "Adreno (TM) 3xx", 13) == 0 // Adreno 302, 305, 320, 330
- || qstrncmp(rendererString, "Adreno 3xx", 8) == 0 // Same as above but without the '(TM)'
- || qstrncmp(rendererString, "Adreno (TM) 4xx", 13) == 0 // Adreno 405, 418, 420, 430
- || qstrncmp(rendererString, "Adreno 4xx", 8) == 0 // Same as above but without the '(TM)'
- || qstrncmp(rendererString, "Adreno (TM) 5xx", 13) == 0 // Adreno 505, 506, 510, 530, 540
- || qstrncmp(rendererString, "Adreno 5xx", 8) == 0 // Same as above but without the '(TM)'
- || qstrncmp(rendererString, "Adreno (TM) 6xx", 13) == 0 // Adreno 610, 620, 630
- || qstrncmp(rendererString, "Adreno 6xx", 8) == 0 // Same as above but without the '(TM)'
- || qstrcmp(rendererString, "GC800 core") == 0
- || qstrcmp(rendererString, "GC1000 core") == 0
- || strstr(rendererString, "GC2000") != 0
- || qstrcmp(rendererString, "Immersion.16") == 0;
- }
- needsWorkaroundSet = true;
- }
-
- if (needsWorkaround)
- d->workaround_brokenFBOReadBack = true;
- d->surface = surface;
+ d->surface = surface;
- d->shareGroup->d_func()->deletePendingResources(this);
+ static bool needsWorkaroundSet = false;
+ static bool needsWorkaround = false;
-#ifndef QT_NO_DEBUG
- QOpenGLContextPrivate::toggleMakeCurrentTracker(this, true);
+ if (!needsWorkaroundSet) {
+ QByteArray env;
+#ifdef Q_OS_ANDROID
+ env = qgetenv(QByteArrayLiteral("QT_ANDROID_DISABLE_GLYPH_CACHE_WORKAROUND"));
+ needsWorkaround = env.isEmpty() || env == QByteArrayLiteral("0") || env == QByteArrayLiteral("false");
#endif
-
- return true;
+ env = qgetenv(QByteArrayLiteral("QT_ENABLE_GLYPH_CACHE_WORKAROUND"));
+ if (env == QByteArrayLiteral("1") || env == QByteArrayLiteral("true"))
+ needsWorkaround = true;
+
+ if (!needsWorkaround) {
+ const char *rendererString = reinterpret_cast<const char *>(functions()->glGetString(GL_RENDERER));
+ if (rendererString)
+ needsWorkaround =
+ qstrncmp(rendererString, "Mali-4xx", 6) == 0 // Mali-400, Mali-450
+ || qstrcmp(rendererString, "Mali-T880") == 0
+ || qstrncmp(rendererString, "Adreno (TM) 2xx", 13) == 0 // Adreno 200, 203, 205
+ || qstrncmp(rendererString, "Adreno 2xx", 8) == 0 // Same as above but without the '(TM)'
+ || qstrncmp(rendererString, "Adreno (TM) 3xx", 13) == 0 // Adreno 302, 305, 320, 330
+ || qstrncmp(rendererString, "Adreno 3xx", 8) == 0 // Same as above but without the '(TM)'
+ || qstrncmp(rendererString, "Adreno (TM) 4xx", 13) == 0 // Adreno 405, 418, 420, 430
+ || qstrncmp(rendererString, "Adreno 4xx", 8) == 0 // Same as above but without the '(TM)'
+ || qstrncmp(rendererString, "Adreno (TM) 5xx", 13) == 0 // Adreno 505, 506, 510, 530, 540
+ || qstrncmp(rendererString, "Adreno 5xx", 8) == 0 // Same as above but without the '(TM)'
+ || qstrncmp(rendererString, "Adreno (TM) 6xx", 13) == 0 // Adreno 610, 620, 630
+ || qstrncmp(rendererString, "Adreno 6xx", 8) == 0 // Same as above but without the '(TM)'
+ || qstrcmp(rendererString, "GC800 core") == 0
+ || qstrcmp(rendererString, "GC1000 core") == 0
+ || strstr(rendererString, "GC2000") != 0
+ || qstrcmp(rendererString, "Immersion.16") == 0;
+ }
+ needsWorkaroundSet = true;
}
- QOpenGLContextPrivate::setCurrentContext(previous);
+ if (needsWorkaround)
+ d->workaround_brokenFBOReadBack = true;
+
+ d->shareGroup->d_func()->deletePendingResources(this);
- return false;
+ return true;
}
/*!
@@ -1078,7 +1077,8 @@ QSurface *QOpenGLContext::surface() const
Swap the back and front buffers of \a surface.
Call this to finish a frame of OpenGL rendering, and make sure to
- call makeCurrent() again before you begin a new frame.
+ call makeCurrent() again before issuing any further OpenGL commands,
+ for example as part of a new frame.
*/
void QOpenGLContext::swapBuffers(QSurface *surface)
{
diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp
index c3a264f1e8..8b052d92ae 100644
--- a/src/gui/kernel/qopenglwindow.cpp
+++ b/src/gui/kernel/qopenglwindow.cpp
@@ -511,7 +511,7 @@ GLuint QOpenGLWindow::defaultFramebufferObject() const
extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
/*!
- Returns a 32-bit RGB image of the framebuffer.
+ Returns a copy of the framebuffer.
\note This is a potentially expensive operation because it relies on
glReadPixels() to read back the pixels. This may be slow and can stall the
@@ -531,7 +531,9 @@ QImage QOpenGLWindow::grabFramebuffer()
return QImage();
makeCurrent();
- QImage img = qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false);
+
+ const bool hasAlpha = format().hasAlpha();
+ QImage img = qt_gl_read_framebuffer(size() * devicePixelRatio(), hasAlpha, hasAlpha);
img.setDevicePixelRatio(devicePixelRatio());
return img;
}
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index 4905e51e01..9ccfb9b819 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -316,6 +316,21 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button)
*/
/*!
+ \fn const QBrush & QPalette::placeholderText() const
+ \since 5.12
+
+ Returns the placeholder text brush of the current color group.
+
+ \note Before Qt 5.12, the placeholder text color was hard-coded in the code as
+ QPalette::text().color() where an alpha of 128 was applied.
+ We continue to support this behavior by default, unless you set your own brush.
+ One can get back the original placeholder color setting the special QBrush default
+ constructor as placeholder brush.
+
+ \sa ColorRole, brush()
+*/
+
+/*!
\fn ColorGroup QPalette::currentColorGroup() const
Returns the palette's current color group.
@@ -444,6 +459,9 @@ static void qt_palette_from_color(QPalette &pal, const QColor &button)
of QPalette, because tool tips are not active
windows.
+ \value PlaceholderText Used as the placeholder color for various text input widgets.
+ This enum value has been introduced in Qt 5.12
+
\value Text The foreground color used with \c Base. This is usually
the same as the \c WindowText, in which case it must provide
good contrast with \c Window and \c Base.
@@ -765,11 +783,32 @@ void QPalette::setBrush(ColorGroup cg, ColorRole cr, const QBrush &b)
cg = Active;
}
+ // For placeholder we want to continue to respect the original behavior, which is
+ // derivating the text color, but only if user has not yet set his own brush.
+ // We then use Qt::NoBrush as an inernal way to know if the brush is customized or not.
+
+ // ### Qt 6 - remove this special case
+ // Part 1 - Restore initial color to the given color group
+ if (cr == PlaceholderText && b == QBrush()) {
+ QColor col = brush(Text).color();
+ col.setAlpha(128);
+ setBrush(cg, PlaceholderText, QBrush(col, Qt::NoBrush));
+ return;
+ }
+
if (d->br[cg][cr] != b) {
detach();
d->br[cg][cr] = b;
}
data.resolve_mask |= (1<<cr);
+
+ // ### Qt 6 - remove this special case
+ // Part 2 - Update initial color to the given color group
+ if (cr == Text && d->br[cg][PlaceholderText].style() == Qt::NoBrush) {
+ QColor col = brush(Text).color();
+ col.setAlpha(128);
+ setBrush(cg, PlaceholderText, QBrush(col, Qt::NoBrush));
+ }
}
/*!
@@ -962,7 +1001,7 @@ QDataStream &operator<<(QDataStream &s, const QPalette &p)
for (int i = 0; i < NumOldRoles; ++i)
s << p.d->br[grp][oldRoles[i]].color();
} else {
- int max = QPalette::ToolTipText + 1;
+ int max = (int)QPalette::NColorRoles;
if (s.version() <= QDataStream::Qt_2_1)
max = QPalette::HighlightedText + 1;
else if (s.version() <= QDataStream::Qt_4_3)
@@ -1159,7 +1198,7 @@ QDebug operator<<(QDebug dbg, const QPalette &p)
{"WindowText", "Button", "Light", "Midlight", "Dark", "Mid", "Text",
"BrightText", "ButtonText", "Base", "Window", "Shadow", "Highlight",
"HighlightedText", "Link", "LinkVisited", "AlternateBase", "NoRole",
- "ToolTipBase","ToolTipText" };
+ "ToolTipBase","ToolTipText", "PlaceholderText" };
QDebugStateSaver saver(dbg);
QDebug nospace = dbg.nospace();
const uint mask = p.resolve();
diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h
index 71f3d0c3b8..071eddbc4d 100644
--- a/src/gui/kernel/qpalette.h
+++ b/src/gui/kernel/qpalette.h
@@ -96,7 +96,8 @@ public:
AlternateBase,
NoRole,
ToolTipBase, ToolTipText,
- NColorRoles = ToolTipText + 1,
+ PlaceholderText,
+ NColorRoles = PlaceholderText + 1,
Foreground = WindowText, Background = Window
};
Q_ENUM(ColorRole)
@@ -141,6 +142,7 @@ public:
inline const QBrush &highlightedText() const { return brush(HighlightedText); }
inline const QBrush &link() const { return brush(Link); }
inline const QBrush &linkVisited() const { return brush(LinkVisited); }
+ inline const QBrush &placeholderText() const { return brush(PlaceholderText); }
bool operator==(const QPalette &p) const;
inline bool operator!=(const QPalette &p) const { return !(operator==(p)); }
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index b456c1ca31..b787629f6a 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -44,6 +44,7 @@
#include <QtCore/QSharedData>
#include <QtCore/QSettings>
#include <QtCore/QUrl>
+#include <QtCore/QVector>
#include <QtGui/QColor>
#include <algorithm>
@@ -786,7 +787,8 @@ class QMessageDialogOptionsPrivate : public QSharedData
public:
QMessageDialogOptionsPrivate() :
icon(QMessageDialogOptions::NoIcon),
- buttons(QPlatformDialogHelper::Ok)
+ buttons(QPlatformDialogHelper::Ok),
+ nextCustomButtonId(QPlatformDialogHelper::LastButton + 1)
{}
QString windowTitle;
@@ -795,6 +797,8 @@ public:
QString informativeText;
QString detailedText;
QPlatformDialogHelper::StandardButtons buttons;
+ QVector<QMessageDialogOptions::CustomButton> customButtons;
+ int nextCustomButtonId;
};
QMessageDialogOptions::QMessageDialogOptions(QMessageDialogOptionsPrivate *dd)
@@ -886,6 +890,35 @@ QPlatformDialogHelper::StandardButtons QMessageDialogOptions::standardButtons()
return d->buttons;
}
+int QMessageDialogOptions::addButton(const QString &label, QPlatformDialogHelper::ButtonRole role,
+ void *buttonImpl)
+{
+ const CustomButton b(d->nextCustomButtonId++, label, role, buttonImpl);
+ d->customButtons.append(b);
+ return b.id;
+}
+
+static inline bool operator==(const QMessageDialogOptions::CustomButton &a,
+ const QMessageDialogOptions::CustomButton &b) {
+ return a.id == b.id;
+}
+
+void QMessageDialogOptions::removeButton(int id)
+{
+ d->customButtons.removeOne(CustomButton(id));
+}
+
+const QVector<QMessageDialogOptions::CustomButton> &QMessageDialogOptions::customButtons()
+{
+ return d->customButtons;
+}
+
+const QMessageDialogOptions::CustomButton *QMessageDialogOptions::customButton(int id)
+{
+ int i = d->customButtons.indexOf(CustomButton(id));
+ return (i < 0 ? nullptr : &d->customButtons.at(i));
+}
+
QPlatformDialogHelper::ButtonRole QPlatformDialogHelper::buttonRole(QPlatformDialogHelper::StandardButton button)
{
switch (button) {
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index f58dcf17f0..bfcb658172 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -150,6 +150,7 @@ public:
MacModelessLayout,
AndroidLayout
};
+ Q_ENUM(ButtonLayout)
QPlatformDialogHelper();
virtual ~QPlatformDialogHelper();
@@ -459,6 +460,26 @@ public:
void setStandardButtons(QPlatformDialogHelper::StandardButtons buttons);
QPlatformDialogHelper::StandardButtons standardButtons() const;
+ struct CustomButton {
+ explicit CustomButton(
+ int id = -1, const QString &label = QString(),
+ QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::InvalidRole,
+ void *button = nullptr) :
+ label(label), role(role), id(id), button(button)
+ {}
+
+ QString label;
+ QPlatformDialogHelper::ButtonRole role;
+ int id;
+ void *button; // strictly internal use only
+ };
+
+ int addButton(const QString &label, QPlatformDialogHelper::ButtonRole role,
+ void *buttonImpl = nullptr);
+ void removeButton(int id);
+ const QVector<CustomButton> &customButtons();
+ const CustomButton *customButton(int id);
+
private:
QMessageDialogOptionsPrivate *d;
};
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
index 2afb5e6ba5..924266997d 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
@@ -57,24 +57,28 @@
QT_BEGIN_NAMESPACE
/*!
- Convenience function to both lock and bind the buffer to a texture. This
- function will first try and lock with texture read and texture write
+ Convenience function to both lock and bind the \a graphicsBuffer to a texture.
+ This function will first try to lock with texture read and texture write
access. If this succeeds it will use the bindToTexture function to bind the
- content to the currently bound texture. If this fail it will try and lock
- with SWReadAccess and then use the bindSWToTexture convenience function.
+ content to the currently bound texture, and if \a premultiplied is provided,
+ it is set to false.
- \a swizzle is suppose to be used by the caller to figure out if the Red and
+ If it fails, it will try to lock with SWReadAccess and then use the
+ bindSWToTexture convenience function. If \a premultiplied is provided, it is
+ passed to the bindSWToTexture() function.
+
+ \a swizzle is meant to be used by the caller to figure out if the Red and
Blue color channels need to be swizzled when rendering.
\a rect is the subrect which is desired to be bounded to the texture. This
- argument has a no less than semantic, meaning more (if not all) of the buffer
+ argument has a not less than semantic, meaning more (if not all) of the buffer
can be bounded to the texture. An empty QRect is interpreted as entire buffer
should be bound.
The user should use the AccessTypes returned by isLocked to figure out what
lock has been obtained.
- returns true if the buffer has successfully been bound to the currently
+ Returns true if the buffer has successfully been bound to the currently
bound texture, otherwise returns false.
*/
bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer,
@@ -103,26 +107,29 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer
}
/*!
- Convenience function that uploads the current raster content to the currently bound texture.
+ Convenience function that uploads the current raster content to the currently
+ bound texture.
- \a swizzleRandB is suppose to be used by the caller to figure out if the Red and
+ \a swizzleRandB is meant to be used by the caller to decide if the Red and
Blue color channels need to be swizzled when rendering. This is an
optimization. Qt often renders to software buffers interpreting pixels as
unsigned ints. When these buffers are uploaded to textures and each color
channel per pixel is interpreted as a byte (read sequentially), then the
- Red and Blue channels are swapped. Conveniently the Alpha buffer will be
- correct since Qt historically has had the alpha channel as the first
+ Red and Blue channels are swapped. Conveniently, the Alpha buffer will be
+ correct, since Qt historically has had the alpha channel as the first
channel, while OpenGL typically expects the alpha channel to be the last
channel.
- \a subRect is the subrect which is desired to be bounded to the texture. This
- argument has a no less than semantic, meaning more (if not all) of the buffer
- can be bounded to the texture. An empty QRect is interpreted as entire buffer
- should be bound.
+ \a subRect is the region to be bound to the texture. This argument has a
+ not less than semantic, meaning more (if not all) of the buffer can be
+ bound to the texture. An empty QRect is interpreted as meaning the entire
+ buffer should be bound.
- This function fails for buffers not capable of locking to SWAccess.
+ This function fails if the \a graphicsBuffer is not locked to SWAccess.
- Returns true on success, otherwise false.
+ Returns true on success, otherwise false. If \a premultipliedB is
+ provided, it is set according to what happens, if the function returns
+ true.
*/
bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer,
bool *swizzleRandB, bool *premultipliedB,
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index dfb8f60915..6e285a8fa5 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -99,8 +99,8 @@ QPlatformClipboard *QPlatformIntegration::clipboard() const
/*!
Accessor for the platform integration's drag object.
- Default implementation returns 0, implying no drag and drop support.
-
+ Default implementation returns QSimpleDrag. This class supports only drag
+ and drop operations within the same Qt application.
*/
QPlatformDrag *QPlatformIntegration::drag() const
{
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index e3fa5c71b1..28c29a704c 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -158,6 +158,7 @@ public:
virtual void removeMenu(QPlatformMenu *menu) = 0;
virtual void syncMenu(QPlatformMenu *menuItem) = 0;
virtual void handleReparent(QWindow *newParentWindow) = 0;
+ virtual QWindow *parentWindow() const { return nullptr; }
virtual QPlatformMenu *menuForTag(quintptr tag) const = 0;
virtual QPlatformMenu *createMenu() const;
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index 358ff16930..9614be7f3e 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -72,7 +72,7 @@ QPlatformScreen::~QPlatformScreen()
This function is called when Qt needs to be able to grab the content of a window.
- Returnes the content of the window specified with the WId handle within the boundaries of
+ Returns the content of the window specified with the WId handle within the boundaries of
QRect(x,y,width,height).
*/
QPixmap QPlatformScreen::grabWindow(WId window, int x, int y, int width, int height) const
diff --git a/src/gui/kernel/qplatformsurface.cpp b/src/gui/kernel/qplatformsurface.cpp
index f091c04ebb..fdb2cf567d 100644
--- a/src/gui/kernel/qplatformsurface.cpp
+++ b/src/gui/kernel/qplatformsurface.cpp
@@ -38,6 +38,10 @@
****************************************************************************/
#include "qplatformsurface.h"
+#ifndef QT_NO_DEBUG_STREAM
+#include <QtCore/qdebug.h>
+#include <QtGui/qwindow.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -64,5 +68,26 @@ QPlatformSurface::QPlatformSurface(QSurface *surface) : m_surface(surface)
{
}
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QPlatformSurface *surface)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "QPlatformSurface(" << (const void *)surface;
+ if (surface) {
+ QSurface *s = surface->surface();
+ auto surfaceClass = s->surfaceClass();
+ debug << ", class=" << surfaceClass;
+ debug << ", type=" << s->surfaceType();
+ if (surfaceClass == QSurface::Window)
+ debug << ", window=" << static_cast<QWindow *>(s);
+ else
+ debug << ", surface=" << s;
+ }
+ debug << ')';
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformsurface.h b/src/gui/kernel/qplatformsurface.h
index 76e8767a05..4d8854fb40 100644
--- a/src/gui/kernel/qplatformsurface.h
+++ b/src/gui/kernel/qplatformsurface.h
@@ -58,6 +58,10 @@ QT_BEGIN_NAMESPACE
class QPlatformScreen;
+#ifndef QT_NO_DEBUG_STREAM
+class QDebug;
+#endif
+
class Q_GUI_EXPORT QPlatformSurface
{
public:
@@ -76,6 +80,11 @@ private:
friend class QPlatformOffscreenSurface;
};
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QPlatformSurface *surface);
+#endif
+
QT_END_NAMESPACE
#endif //QPLATFORMSURFACE_H
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index a66420c364..50f05721f7 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -140,7 +140,7 @@ void QPlatformWindow::setGeometry(const QRect &rect)
}
/*!
- Returnes the current geometry of a window
+ Returns the current geometry of a window
*/
QRect QPlatformWindow::geometry() const
{
@@ -340,6 +340,20 @@ void QPlatformWindow::setWindowFilePath(const QString &filePath) { Q_UNUSED(file
void QPlatformWindow::setWindowIcon(const QIcon &icon) { Q_UNUSED(icon); }
/*!
+ Reimplement to let the platform handle non-spontaneous window close.
+
+ When reimplementing make sure to call the base class implementation
+ or QWindowSystemInterface::handleCloseEvent(), which will prompt the
+ user to accept the window close (if needed) and then close the QWindow.
+*/
+bool QPlatformWindow::close()
+{
+ bool accepted = false;
+ QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(window(), &accepted);
+ return accepted;
+}
+
+/*!
Reimplement to be able to let Qt raise windows to the top of the desktop
*/
void QPlatformWindow::raise() { qWarning("This plugin does not support raise()"); }
@@ -447,14 +461,26 @@ bool QPlatformWindow::setWindowModified(bool modified)
/*!
Reimplement this method to be able to do any platform specific event
- handling. All events for window() are passed to this function before being
- sent to QWindow::event().
+ handling. All non-synthetic events for window() are passed to this
+ function before being sent to QWindow::event().
- The default implementation is empty and does nothing with \a event.
+ Return true if the event should not be passed on to the QWindow.
+
+ Subclasses should always call the base class implementation.
*/
-void QPlatformWindow::windowEvent(QEvent *event)
+bool QPlatformWindow::windowEvent(QEvent *event)
{
- Q_UNUSED(event);
+ Q_D(QPlatformWindow);
+
+ if (event->type() == QEvent::Timer) {
+ if (static_cast<QTimerEvent *>(event)->timerId() == d->updateTimer.timerId()) {
+ d->updateTimer.stop();
+ deliverUpdateRequest();
+ return true;
+ }
+ }
+
+ return false;
}
/*!
@@ -710,7 +736,7 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
QPlatformWindow subclasses can re-implement this function to
provide display refresh synchronized updates. The event
- should be delivered using QWindowPrivate::deliverUpdateRequest()
+ should be delivered using QPlatformWindow::deliverUpdateRequest()
to not get out of sync with the the internal state of QWindow.
The default implementation posts an UpdateRequest event to the
@@ -720,18 +746,44 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
*/
void QPlatformWindow::requestUpdate()
{
- static int timeout = -1;
- if (timeout == -1) {
+ Q_D(QPlatformWindow);
+
+ static int updateInterval = []() {
bool ok = false;
- timeout = qEnvironmentVariableIntValue("QT_QPA_UPDATE_IDLE_TIME", &ok);
- if (!ok)
- timeout = 5;
- }
+ int customUpdateInterval = qEnvironmentVariableIntValue("QT_QPA_UPDATE_IDLE_TIME", &ok);
+ return ok ? customUpdateInterval : 5;
+ }();
+
+ Q_ASSERT(!d->updateTimer.isActive());
+ d->updateTimer.start(updateInterval, Qt::PreciseTimer, window());
+}
+
+/*!
+ Returns true if the window has a pending update request.
+
+ \sa requestUpdate(), deliverUpdateRequest()
+*/
+bool QPlatformWindow::hasPendingUpdateRequest() const
+{
+ return qt_window_private(window())->updateRequestPending;
+}
+
+/*!
+ Delivers an QEvent::UpdateRequest event to the window.
+
+ QPlatformWindow subclasses can re-implement this function to
+ provide e.g. logging or tracing of the delivery, but should
+ always call the base class function.
+*/
+void QPlatformWindow::deliverUpdateRequest()
+{
+ Q_ASSERT(hasPendingUpdateRequest());
QWindow *w = window();
- QWindowPrivate *wp = (QWindowPrivate *) QObjectPrivate::get(w);
- Q_ASSERT(wp->updateTimer == 0);
- wp->updateTimer = w->startTimer(timeout, Qt::PreciseTimer);
+ QWindowPrivate *wp = qt_window_private(w);
+ wp->updateRequestPending = false;
+ QEvent request(QEvent::UpdateRequest);
+ QCoreApplication::sendEvent(w, &request);
}
/*!
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 84dff681d5..1590a10554 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -100,6 +100,7 @@ public:
virtual void setWindowTitle(const QString &title);
virtual void setWindowFilePath(const QString &title);
virtual void setWindowIcon(const QIcon &icon);
+ virtual bool close();
virtual void raise();
virtual void lower();
@@ -126,7 +127,7 @@ public:
virtual bool setWindowModified(bool modified);
- virtual void windowEvent(QEvent *event);
+ virtual bool windowEvent(QEvent *event);
virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner);
virtual bool startSystemMove(const QPoint &pos);
@@ -143,6 +144,8 @@ public:
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
virtual void requestUpdate();
+ bool hasPendingUpdateRequest() const;
+ virtual void deliverUpdateRequest();
// Window property accessors. Platform plugins should use these
// instead of accessing QWindow directly.
diff --git a/src/gui/kernel/qplatformwindow_p.h b/src/gui/kernel/qplatformwindow_p.h
index 62ecd61d9e..00dae9334c 100644
--- a/src/gui/kernel/qplatformwindow_p.h
+++ b/src/gui/kernel/qplatformwindow_p.h
@@ -52,6 +52,7 @@
//
#include <QtGui/private/qtguiglobal_p.h>
+#include <QtCore/qbasictimer.h>
#include <QtCore/qrect.h>
QT_BEGIN_NAMESPACE
@@ -60,6 +61,7 @@ class QPlatformWindowPrivate
{
public:
QRect rect;
+ QBasicTimer updateTimer;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index fa1eb6f6bf..3bb42c1c0b 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -540,6 +540,19 @@ void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl,
{
Q_D(QShortcutMap);
QList<int> possibleKeys = QKeyMapper::possibleKeys(e);
+#if defined(DEBUG_QSHORTCUTMAP)
+ {
+ QDebug debug = qDebug().nospace();
+ debug << __FUNCTION__ << '(' << e << ", ignoredModifiers="
+ << Qt::KeyboardModifiers(ignoredModifiers) << "), possibleKeys=(";
+ for (int i = 0, size = possibleKeys.size(); i < size; ++i) {
+ if (i)
+ debug << ", ";
+ debug << QKeySequence(possibleKeys.at(i));
+ }
+ debug << ')';
+ }
+#endif // DEBUG_QSHORTCUTMAP
int pkTotal = possibleKeys.count();
if (!pkTotal)
return;
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index 12e204a09f..a84f873437 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -94,11 +94,7 @@ static QWindow* topLevelAt(const QPoint &pos)
(within the Qt application or outside) accepts the drag and sets the state accordingly.
*/
-QBasicDrag::QBasicDrag() :
- m_current_window(nullptr), m_restoreCursor(false), m_eventLoop(nullptr),
- m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
- m_drag(nullptr), m_drag_icon_window(nullptr), m_useCompositing(true),
- m_screen(nullptr)
+QBasicDrag::QBasicDrag()
{
}
@@ -158,7 +154,8 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
case QEvent::MouseMove:
{
QPoint nativePosition = getNativeMousePos(e, m_drag_icon_window);
- move(nativePosition);
+ auto mouseMove = static_cast<QMouseEvent *>(e);
+ move(nativePosition, mouseMove->buttons(), mouseMove->modifiers());
return true; // Eat all mouse move events
}
case QEvent::MouseButtonRelease:
@@ -166,7 +163,8 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
disableEventFilter();
if (canDrop()) {
QPoint nativePosition = getNativeMousePos(e, m_drag_icon_window);
- drop(nativePosition);
+ auto mouseRelease = static_cast<QMouseEvent *>(e);
+ drop(nativePosition, mouseRelease->buttons(), mouseRelease->modifiers());
} else {
cancel();
}
@@ -179,9 +177,9 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
// make the event relative to the window where the drag started. (QTBUG-66103)
const QMouseEvent *release = static_cast<QMouseEvent *>(e);
const QWindow *releaseWindow = topLevelAt(release->globalPos());
- qCDebug(lcDnd) << "mouse released over" << releaseWindow << "after drag from" << m_current_window << "globalPos" << release->globalPos();
+ qCDebug(lcDnd) << "mouse released over" << releaseWindow << "after drag from" << m_sourceWindow << "globalPos" << release->globalPos();
if (!releaseWindow)
- releaseWindow = m_current_window;
+ releaseWindow = m_sourceWindow;
QPoint releaseWindowPos = (releaseWindow ? releaseWindow->mapFromGlobal(release->globalPos()) : release->globalPos());
QMouseEvent *newRelease = new QMouseEvent(release->type(),
releaseWindowPos, releaseWindowPos, release->screenPos(),
@@ -204,18 +202,15 @@ Qt::DropAction QBasicDrag::drag(QDrag *o)
m_drag = o;
m_executed_drop_action = Qt::IgnoreAction;
m_can_drop = false;
- m_restoreCursor = true;
-#ifndef QT_NO_CURSOR
- qApp->setOverrideCursor(Qt::DragCopyCursor);
- updateCursor(m_executed_drop_action);
-#endif
+
startDrag();
m_eventLoop = new QEventLoop;
m_eventLoop->exec();
delete m_eventLoop;
- m_eventLoop = 0;
- m_drag = 0;
+ m_eventLoop = nullptr;
+ m_drag = nullptr;
endDrag();
+
return m_executed_drop_action;
}
@@ -227,16 +222,6 @@ void QBasicDrag::cancelDrag()
}
}
-void QBasicDrag::restoreCursor()
-{
- if (m_restoreCursor) {
-#ifndef QT_NO_CURSOR
- QGuiApplication::restoreOverrideCursor();
-#endif
- m_restoreCursor = false;
- }
-}
-
void QBasicDrag::startDrag()
{
QPoint pos;
@@ -287,7 +272,7 @@ void QBasicDrag::moveShapedPixmapWindow(const QPoint &globalPos)
m_drag_icon_window->updateGeometry(globalPos);
}
-void QBasicDrag::drop(const QPoint &)
+void QBasicDrag::drop(const QPoint &, Qt::MouseButtons, Qt::KeyboardModifiers)
{
disableEventFilter();
restoreCursor();
@@ -318,25 +303,34 @@ void QBasicDrag::updateCursor(Qt::DropAction action)
}
}
- QCursor *cursor = QGuiApplication::overrideCursor();
QPixmap pixmap = m_drag->dragCursor(action);
- if (!cursor) {
- QGuiApplication::changeOverrideCursor((pixmap.isNull()) ? QCursor(cursorShape) : QCursor(pixmap));
+
+ if (!m_dndHasSetOverrideCursor) {
+ QCursor newCursor = !pixmap.isNull() ? QCursor(pixmap) : QCursor(cursorShape);
+ QGuiApplication::setOverrideCursor(newCursor);
+ m_dndHasSetOverrideCursor = true;
} else {
+ QCursor *cursor = QGuiApplication::overrideCursor();
if (!pixmap.isNull()) {
- if ((cursor->pixmap().cacheKey() != pixmap.cacheKey())) {
+ if (cursor->pixmap().cacheKey() != pixmap.cacheKey())
QGuiApplication::changeOverrideCursor(QCursor(pixmap));
- }
- } else {
- if (cursorShape != cursor->shape()) {
- QGuiApplication::changeOverrideCursor(QCursor(cursorShape));
- }
+ } else if (cursorShape != cursor->shape()) {
+ QGuiApplication::changeOverrideCursor(QCursor(cursorShape));
}
}
#endif
updateAction(action);
}
+void QBasicDrag::restoreCursor()
+{
+#ifndef QT_NO_CURSOR
+ if (m_dndHasSetOverrideCursor) {
+ QGuiApplication::restoreOverrideCursor();
+ m_dndHasSetOverrideCursor = false;
+ }
+#endif
+}
static inline QPoint fromNativeGlobalPixels(const QPoint &point)
{
@@ -374,57 +368,83 @@ QSimpleDrag::QSimpleDrag()
void QSimpleDrag::startDrag()
{
+ setExecutedDropAction(Qt::IgnoreAction);
+
QBasicDrag::startDrag();
- m_current_window = topLevelAt(QCursor::pos());
- if (m_current_window) {
- QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_current_window, drag()->mimeData(), QHighDpi::toNativePixels(QCursor::pos(), m_current_window), drag()->supportedActions());
- setCanDrop(response.isAccepted());
- updateCursor(response.acceptedAction());
+ // Here we can be fairly sure that QGuiApplication::mouseButtons/keyboardModifiers() will
+ // contain sensible values as startDrag() normally is called from mouse event handlers
+ // by QDrag::exec(). A better API would be if we could pass something like "input device
+ // pointer" to QDrag::exec(). My guess is that something like that might be required for
+ // QTBUG-52430.
+ m_sourceWindow = topLevelAt(QCursor::pos());
+ m_windowUnderCursor = m_sourceWindow;
+ if (m_sourceWindow) {
+ auto nativePixelPos = QHighDpi::toNativePixels(QCursor::pos(), m_sourceWindow);
+ move(nativePixelPos, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
} else {
setCanDrop(false);
updateCursor(Qt::IgnoreAction);
}
- setExecutedDropAction(Qt::IgnoreAction);
- qCDebug(lcDnd) << "drag began from" << m_current_window<< "cursor pos" << QCursor::pos() << "can drop?" << canDrop();
+
+ qCDebug(lcDnd) << "drag began from" << m_sourceWindow << "cursor pos" << QCursor::pos() << "can drop?" << canDrop();
+}
+
+static void sendDragLeave(QWindow *window)
+{
+ QWindowSystemInterface::handleDrag(window, nullptr, QPoint(), Qt::IgnoreAction, 0, 0);
}
void QSimpleDrag::cancel()
{
QBasicDrag::cancel();
- if (drag() && m_current_window) {
- QWindowSystemInterface::handleDrag(m_current_window, 0, QPoint(), Qt::IgnoreAction);
- m_current_window = 0;
+ if (drag() && m_sourceWindow) {
+ sendDragLeave(m_sourceWindow);
+ m_sourceWindow = nullptr;
}
}
-void QSimpleDrag::move(const QPoint &nativeGlobalPos)
+void QSimpleDrag::move(const QPoint &nativeGlobalPos, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers)
{
QPoint globalPos = fromNativeGlobalPixels(nativeGlobalPos);
moveShapedPixmapWindow(globalPos);
QWindow *window = topLevelAt(globalPos);
- if (!window)
- return;
+
+ if (!window || window != m_windowUnderCursor) {
+ if (m_windowUnderCursor)
+ sendDragLeave(m_windowUnderCursor);
+ m_windowUnderCursor = window;
+ if (!window) {
+ // QSimpleDrag supports only in-process dnd, we can't drop anywhere else.
+ setCanDrop(false);
+ updateCursor(Qt::IgnoreAction);
+ return;
+ }
+ }
const QPoint pos = nativeGlobalPos - window->handle()->geometry().topLeft();
- const QPlatformDragQtResponse qt_response =
- QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions());
+ const QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(
+ window, drag()->mimeData(), pos, drag()->supportedActions(),
+ buttons, modifiers);
- updateCursor(qt_response.acceptedAction());
setCanDrop(qt_response.isAccepted());
+ updateCursor(qt_response.acceptedAction());
}
-void QSimpleDrag::drop(const QPoint &nativeGlobalPos)
+void QSimpleDrag::drop(const QPoint &nativeGlobalPos, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers)
{
QPoint globalPos = fromNativeGlobalPixels(nativeGlobalPos);
- QBasicDrag::drop(nativeGlobalPos);
+ QBasicDrag::drop(nativeGlobalPos, buttons, modifiers);
QWindow *window = topLevelAt(globalPos);
if (!window)
return;
const QPoint pos = nativeGlobalPos - window->handle()->geometry().topLeft();
- const QPlatformDropQtResponse response =
- QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions());
+ const QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(
+ window, drag()->mimeData(), pos, drag()->supportedActions(),
+ buttons, modifiers);
if (response.isAccepted()) {
setExecutedDropAction(response.acceptedAction());
} else {
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index d980a3c49d..f9e8a83a39 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -55,13 +55,14 @@
#include <qpa/qplatformdrag.h>
#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtGui/QWindow>
QT_REQUIRE_CONFIG(draganddrop);
QT_BEGIN_NAMESPACE
class QMouseEvent;
-class QWindow;
class QEventLoop;
class QDropData;
class QShapedPixmapWindow;
@@ -82,8 +83,8 @@ protected:
virtual void startDrag();
virtual void cancel();
- virtual void move(const QPoint &globalPos) = 0;
- virtual void drop(const QPoint &globalPos) = 0;
+ virtual void move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) = 0;
+ virtual void drop(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) = 0;
virtual void endDrag();
@@ -106,7 +107,8 @@ protected:
QDrag *drag() const { return m_drag; }
protected:
- QWindow *m_current_window;
+ QWindow *m_sourceWindow = nullptr;
+ QPointer<QWindow> m_windowUnderCursor = nullptr;
private:
void enableEventFilter();
@@ -114,14 +116,16 @@ private:
void restoreCursor();
void exitDndEventLoop();
- bool m_restoreCursor;
- QEventLoop *m_eventLoop;
- Qt::DropAction m_executed_drop_action;
- bool m_can_drop;
- QDrag *m_drag;
- QShapedPixmapWindow *m_drag_icon_window;
- bool m_useCompositing;
- QScreen *m_screen;
+#ifndef QT_NO_CURSOR
+ bool m_dndHasSetOverrideCursor = false;
+#endif
+ QEventLoop *m_eventLoop = nullptr;
+ Qt::DropAction m_executed_drop_action = Qt::IgnoreAction;
+ bool m_can_drop = false;
+ QDrag *m_drag = nullptr;
+ QShapedPixmapWindow *m_drag_icon_window = nullptr;
+ bool m_useCompositing = true;
+ QScreen *m_screen = nullptr;
};
class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
@@ -132,8 +136,8 @@ public:
protected:
virtual void startDrag() override;
virtual void cancel() override;
- virtual void move(const QPoint &globalPos) override;
- virtual void drop(const QPoint &globalPos) override;
+ virtual void move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override;
+ virtual void drop(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
index 63651ee822..415e64b39c 100644
--- a/src/gui/kernel/qsurface.cpp
+++ b/src/gui/kernel/qsurface.cpp
@@ -80,6 +80,10 @@ QT_BEGIN_NAMESPACE
in conjunction with OpenVG contexts.
\value VulkanSurface The surface is a Vulkan compatible surface and can be used
in conjunction with the Vulkan graphics API.
+ \value MetalSurface The surface is a Metal compatible surface and can be used
+ in conjunction with Apple's Metal graphics API. This surface type is supported
+ on macOS only.
+
*/
diff --git a/src/gui/kernel/qsurface.h b/src/gui/kernel/qsurface.h
index 7e09449d12..521593ea5c 100644
--- a/src/gui/kernel/qsurface.h
+++ b/src/gui/kernel/qsurface.h
@@ -55,19 +55,23 @@ class QSurfacePrivate;
class Q_GUI_EXPORT QSurface
{
+ Q_GADGET
public:
enum SurfaceClass {
Window,
Offscreen
};
+ Q_ENUM(SurfaceClass)
enum SurfaceType {
RasterSurface,
OpenGLSurface,
RasterGLSurface,
OpenVGSurface,
- VulkanSurface
+ VulkanSurface,
+ MetalSurface
};
+ Q_ENUM(SurfaceType)
virtual ~QSurface();
diff --git a/src/gui/kernel/qtestsupport_gui.cpp b/src/gui/kernel/qtestsupport_gui.cpp
new file mode 100644
index 0000000000..56e0eb52b3
--- /dev/null
+++ b/src/gui/kernel/qtestsupport_gui.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestsupport_gui.h"
+#include "qwindow.h"
+
+#include <QtCore/qtestsupport_core.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \fn bool qWaitForWindowActive(QWindow *window, int timeout)
+ \relates QTest
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a window is active.
+
+ Returns \c true if \c window is active within \a timeout milliseconds, otherwise returns \c false.
+
+ \sa QTest::qWaitForWindowExposed(), QWindow::isActive()
+*/
+Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
+{
+ return QTest::qWaitFor([&]() { return window->isActive(); }, timeout);
+}
+
+/*! \fn bool qWaitForWindowExposed(QWindow *window, int timeout)
+ \relates QTest
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a window is exposed.
+ Returns \c true if \c window is exposed within \a timeout milliseconds, otherwise returns \c false.
+
+ This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
+ time after being asked to show itself on the screen.
+
+ Note that a window that is mapped to screen may still not be considered exposed if the window client
+ area is completely covered by other windows, or if the window is otherwise not visible. This function
+ will then time out when waiting for such a window.
+
+ \sa QTest::qWaitForWindowActive(), QWindow::isExposed()
+*/
+Q_GUI_EXPORT bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
+{
+ return QTest::qWaitFor([&]() { return window->isExposed(); }, timeout);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qtestsupport_gui.h b/src/gui/kernel/qtestsupport_gui.h
new file mode 100644
index 0000000000..82a81e9214
--- /dev/null
+++ b/src/gui/kernel/qtestsupport_gui.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTSUPPORT_GUI_H
+#define QTESTSUPPORT_GUI_H
+
+#include <QtGui/qtguiglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+
+namespace QTest {
+Q_GUI_EXPORT Q_REQUIRED_RESULT bool qWaitForWindowActive(QWindow *window, int timeout = 5000);
+Q_GUI_EXPORT Q_REQUIRED_RESULT bool qWaitForWindowExposed(QWindow *window, int timeout = 5000);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 55fe75d220..3d7d22959d 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -115,9 +115,10 @@ QT_BEGIN_NAMESPACE
physical area of the screen. On windowing systems that have exposure
notifications, the isExposed() accessor describes whether the window should
be treated as directly visible on screen. The exposeEvent() function is
- called whenever the windows exposure in the windowing system changes. On
- windowing systems that do not make this information visible to the
- application, isExposed() will simply return the same value as isVisible().
+ called whenever an area of the window is invalidated, for example due to the
+ exposure in the windowing system changing. On windowing systems that do not
+ make this information visible to the application, isExposed() will simply
+ return the same value as isVisible().
QWindow::Visibility queried through visibility() is a convenience API
combining the functions of visible() and windowStates().
@@ -2150,15 +2151,13 @@ bool QWindow::close()
if (!d->platformWindow)
return true;
- bool accepted = false;
- QWindowSystemInterface::handleCloseEvent(this, &accepted);
- QWindowSystemInterface::flushWindowSystemEvents();
- return accepted;
+ return d->platformWindow->close();
}
/*!
- The expose event (\a ev) is sent by the window system whenever the window's
- exposure on screen changes.
+ The expose event (\a ev) is sent by the window system whenever an area of
+ the window is invalidated, for example due to the exposure in the windowing
+ system changing.
The application can start rendering into the window with QBackingStore
and QOpenGLContext as soon as it gets an exposeEvent() such that
@@ -2335,18 +2334,6 @@ bool QWindow::event(QEvent *ev)
break;
#endif
- case QEvent::Timer: {
- Q_D(QWindow);
- if (static_cast<QTimerEvent *>(ev)->timerId() == d->updateTimer) {
- killTimer(d->updateTimer);
- d->updateTimer = 0;
- d->deliverUpdateRequest();
- } else {
- QObject::event(ev);
- }
- break;
- }
-
case QEvent::PlatformSurface: {
if ((static_cast<QPlatformSurfaceEvent *>(ev))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) {
#ifndef QT_NO_OPENGL
@@ -2364,14 +2351,6 @@ bool QWindow::event(QEvent *ev)
return true;
}
-void QWindowPrivate::deliverUpdateRequest()
-{
- Q_Q(QWindow);
- updateRequestPending = false;
- QEvent request(QEvent::UpdateRequest);
- QCoreApplication::sendEvent(q, &request);
-}
-
/*!
Schedules a QEvent::UpdateRequest event to be delivered to this window.
@@ -2626,14 +2605,14 @@ void QWindowPrivate::maybeQuitOnLastWindowClosed()
}
}
-QWindow *QWindowPrivate::topLevelWindow() const
+QWindow *QWindowPrivate::topLevelWindow(QWindow::AncestorMode mode) const
{
Q_Q(const QWindow);
QWindow *window = const_cast<QWindow *>(q);
while (window) {
- QWindow *parent = window->parent(QWindow::IncludeTransients);
+ QWindow *parent = window->parent(mode);
if (!parent)
break;
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 7ef73eb410..bf5e645114 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -97,7 +97,6 @@ public:
, modality(Qt::NonModal)
, blockedByModalWindow(false)
, updateRequestPending(false)
- , updateTimer(0)
, transientParent(0)
, topLevelScreen(0)
#ifndef QT_NO_CURSOR
@@ -124,11 +123,9 @@ public:
bool applyCursor();
#endif
- void deliverUpdateRequest();
-
QPoint globalPosition() const;
- QWindow *topLevelWindow() const;
+ QWindow *topLevelWindow(QWindow::AncestorMode mode = QWindow::IncludeTransients) const;
#if QT_CONFIG(opengl)
virtual QOpenGLContext *shareContext() const;
@@ -194,7 +191,6 @@ public:
bool blockedByModalWindow;
bool updateRequestPending;
- int updateTimer;
QPointer<QWindow> transientParent;
QPointer<QScreen> topLevelScreen;
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 6edcdfc255..07ece5689e 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -339,12 +339,12 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleExposeEvent, QWindow *window, const QReg
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
-void QWindowSystemInterface::handleCloseEvent(QWindow *window, bool *accepted)
+QT_DEFINE_QPA_EVENT_HANDLER(void, handleCloseEvent, QWindow *window, bool *accepted)
{
if (window) {
QWindowSystemInterfacePrivate::CloseEvent *e =
new QWindowSystemInterfacePrivate::CloseEvent(window, accepted);
- QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
}
@@ -795,14 +795,44 @@ void QWindowSystemInterface::handleThemeChange(QWindow *window)
}
#if QT_CONFIG(draganddrop)
-QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *window, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
+#if QT_DEPRECATED_SINCE(5, 11)
+QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *window, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions)
+{
+ return QGuiApplicationPrivate::processDrag(window, dropData, p, supportedActions,
+ QGuiApplication::mouseButtons(),
+ QGuiApplication::keyboardModifiers());
+}
+
+QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *window, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions)
+{
+ return QGuiApplicationPrivate::processDrop(window, dropData, p, supportedActions,
+ QGuiApplication::mouseButtons(),
+ QGuiApplication::keyboardModifiers());
+}
+#endif // QT_DEPRECATED_SINCE(5, 11)
+/*!
+ Drag and drop events are sent immediately.
+
+ ### FIXME? Perhaps DnD API should add some convenience APIs that are more
+ intuitive for the possible DND operations. Here passing nullptr as drop data is used to
+ indicate that drop was canceled and QDragLeaveEvent should be sent as a result.
+*/
+QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *window, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
{
- return QGuiApplicationPrivate::processDrag(window, dropData, QHighDpi::fromNativeLocalPosition(p, window) ,supportedActions);
+ auto pos = QHighDpi::fromNativeLocalPosition(p, window);
+ return QGuiApplicationPrivate::processDrag(window, dropData, pos, supportedActions, buttons, modifiers);
}
-QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *window, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
+QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *window, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
{
- return QGuiApplicationPrivate::processDrop(window, dropData, QHighDpi::fromNativeLocalPosition(p, window),supportedActions);
+ auto pos = QHighDpi::fromNativeLocalPosition(p, window);
+ return QGuiApplicationPrivate::processDrop(window, dropData, pos, supportedActions, buttons, modifiers);
}
#endif // QT_CONFIG(draganddrop)
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index bba0b05c5a..6bf6ee645c 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -193,6 +193,7 @@ public:
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleExposeEvent(QWindow *window, const QRegion &region);
+ template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleCloseEvent(QWindow *window, bool *accepted = nullptr);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
@@ -215,10 +216,19 @@ public:
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
#if QT_CONFIG(draganddrop)
- // Drag and drop. These events are sent immediately.
- static QPlatformDragQtResponse handleDrag(QWindow *window, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
- static QPlatformDropQtResponse handleDrop(QWindow *window, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions);
-#endif
+#if QT_DEPRECATED_SINCE(5, 11)
+ QT_DEPRECATED static QPlatformDragQtResponse handleDrag(QWindow *window, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions);
+ QT_DEPRECATED static QPlatformDropQtResponse handleDrop(QWindow *window, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions);
+#endif // #if QT_DEPRECATED_SINCE(5, 11)
+ static QPlatformDragQtResponse handleDrag(QWindow *window, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
+ static QPlatformDropQtResponse handleDrop(QWindow *window, const QMimeData *dropData,
+ const QPoint &p, Qt::DropActions supportedActions,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
+#endif // QT_CONFIG(draganddrop)
static bool handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result);
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index c3fb19d21a..492f559f22 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -365,7 +365,7 @@ public:
QUrl url;
};
- class TabletEvent : public InputEvent {
+ class Q_GUI_EXPORT TabletEvent : public InputEvent {
public:
static void handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global,
int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp
index 7c02b5ad5d..c04f8b1cbf 100644
--- a/src/gui/math3d/qvector2d.cpp
+++ b/src/gui/math3d/qvector2d.cpp
@@ -49,6 +49,39 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_VECTOR2D
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector2D>::value, "QVector2D is supposed to be standard layout");
+Q_STATIC_ASSERT_X(sizeof(QVector2D) == sizeof(float) * 2, "QVector2D is not supposed to have padding at the end");
+
+// QVector2D used to be defined as class QVector2D { float x, y; };,
+// now instead it is defined as classs QVector2D { float v[2]; };.
+// Check that binary compatibility is preserved.
+// ### Qt 6: remove all of these checks.
+
+namespace {
+
+struct QVector2DOld
+{
+ float x, y;
+};
+
+struct QVector2DNew
+{
+ float v[2];
+};
+
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector2DOld>::value, "Binary compatibility break in QVector2D");
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector2DNew>::value, "Binary compatibility break in QVector2D");
+
+Q_STATIC_ASSERT_X(sizeof(QVector2DOld) == sizeof(QVector2DNew), "Binary compatibility break in QVector2D");
+
+// requires a constexpr offsetof
+#if !defined(Q_CC_MSVC) || (_MSC_VER >= 1910)
+Q_STATIC_ASSERT_X(offsetof(QVector2DOld, x) == offsetof(QVector2DNew, v) + sizeof(QVector2DNew::v[0]) * 0, "Binary compatibility break in QVector2D");
+Q_STATIC_ASSERT_X(offsetof(QVector2DOld, y) == offsetof(QVector2DNew, v) + sizeof(QVector2DNew::v[0]) * 1, "Binary compatibility break in QVector2D");
+#endif
+
+} // anonymous namespace
+
/*!
\class QVector2D
\brief The QVector2D class represents a vector or vertex in 2D space.
@@ -105,8 +138,8 @@ QT_BEGIN_NAMESPACE
*/
QVector2D::QVector2D(const QVector3D& vector)
{
- xp = vector.xp;
- yp = vector.yp;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
}
#endif
@@ -121,8 +154,8 @@ QVector2D::QVector2D(const QVector3D& vector)
*/
QVector2D::QVector2D(const QVector4D& vector)
{
- xp = vector.xp;
- yp = vector.yp;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
}
#endif
@@ -193,8 +226,8 @@ QVector2D::QVector2D(const QVector4D& vector)
float QVector2D::length() const
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]);
return float(std::sqrt(len));
}
@@ -206,7 +239,7 @@ float QVector2D::length() const
*/
float QVector2D::lengthSquared() const
{
- return xp * xp + yp * yp;
+ return v[0] * v[0] + v[1] * v[1];
}
/*!
@@ -221,13 +254,13 @@ float QVector2D::lengthSquared() const
QVector2D QVector2D::normalized() const
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]);
if (qFuzzyIsNull(len - 1.0f)) {
return *this;
} else if (!qFuzzyIsNull(len)) {
double sqrtLen = std::sqrt(len);
- return QVector2D(float(double(xp) / sqrtLen), float(double(yp) / sqrtLen));
+ return QVector2D(float(double(v[0]) / sqrtLen), float(double(v[1]) / sqrtLen));
} else {
return QVector2D();
}
@@ -242,15 +275,15 @@ QVector2D QVector2D::normalized() const
void QVector2D::normalize()
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]);
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return;
len = std::sqrt(len);
- xp = float(double(xp) / len);
- yp = float(double(yp) / len);
+ v[0] = float(double(v[0]) / len);
+ v[1] = float(double(v[1]) / len);
}
/*!
@@ -344,7 +377,7 @@ float QVector2D::distanceToLine
*/
float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
{
- return v1.xp * v2.xp + v1.yp * v2.yp;
+ return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1];
}
/*!
@@ -458,7 +491,7 @@ float QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2)
*/
QVector3D QVector2D::toVector3D() const
{
- return QVector3D(xp, yp, 0.0f);
+ return QVector3D(v[0], v[1], 0.0f);
}
#endif
@@ -472,7 +505,7 @@ QVector3D QVector2D::toVector3D() const
*/
QVector4D QVector2D::toVector4D() const
{
- return QVector4D(xp, yp, 0.0f, 0.0f);
+ return QVector4D(v[0], v[1], 0.0f, 0.0f);
}
#endif
diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h
index 2af5132665..88d8bc199e 100644
--- a/src/gui/math3d/qvector2d.h
+++ b/src/gui/math3d/qvector2d.h
@@ -123,7 +123,7 @@ public:
operator QVariant() const;
private:
- float xp, yp;
+ float v[2];
friend class QVector3D;
friend class QVector4D;
@@ -131,76 +131,76 @@ private:
Q_DECLARE_TYPEINFO(QVector2D, Q_PRIMITIVE_TYPE);
-Q_DECL_CONSTEXPR inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D() : v{0.0f, 0.0f} {}
-Q_DECL_CONSTEXPR inline QVector2D::QVector2D(float xpos, float ypos) : xp(xpos), yp(ypos) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(float xpos, float ypos) : v{xpos, ypos} {}
-Q_DECL_CONSTEXPR inline QVector2D::QVector2D(const QPoint& point) : xp(point.x()), yp(point.y()) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(const QPoint& point) : v{float(point.x()), float(point.y())} {}
-Q_DECL_CONSTEXPR inline QVector2D::QVector2D(const QPointF& point) : xp(float(point.x())), yp(float(point.y())) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(const QPointF& point) : v{float(point.x()), float(point.y())} {}
inline bool QVector2D::isNull() const
{
- return qIsNull(xp) && qIsNull(yp);
+ return qIsNull(v[0]) && qIsNull(v[1]);
}
-Q_DECL_CONSTEXPR inline float QVector2D::x() const { return xp; }
-Q_DECL_CONSTEXPR inline float QVector2D::y() const { return yp; }
+Q_DECL_CONSTEXPR inline float QVector2D::x() const { return v[0]; }
+Q_DECL_CONSTEXPR inline float QVector2D::y() const { return v[1]; }
-inline void QVector2D::setX(float aX) { xp = aX; }
-inline void QVector2D::setY(float aY) { yp = aY; }
+inline void QVector2D::setX(float aX) { v[0] = aX; }
+inline void QVector2D::setY(float aY) { v[1] = aY; }
inline float &QVector2D::operator[](int i)
{
Q_ASSERT(uint(i) < 2u);
- return *(&xp + i);
+ return v[i];
}
inline float QVector2D::operator[](int i) const
{
Q_ASSERT(uint(i) < 2u);
- return *(&xp + i);
+ return v[i];
}
inline QVector2D &QVector2D::operator+=(const QVector2D &vector)
{
- xp += vector.xp;
- yp += vector.yp;
+ v[0] += vector.v[0];
+ v[1] += vector.v[1];
return *this;
}
inline QVector2D &QVector2D::operator-=(const QVector2D &vector)
{
- xp -= vector.xp;
- yp -= vector.yp;
+ v[0] -= vector.v[0];
+ v[1] -= vector.v[1];
return *this;
}
inline QVector2D &QVector2D::operator*=(float factor)
{
- xp *= factor;
- yp *= factor;
+ v[0] *= factor;
+ v[1] *= factor;
return *this;
}
inline QVector2D &QVector2D::operator*=(const QVector2D &vector)
{
- xp *= vector.xp;
- yp *= vector.yp;
+ v[0] *= vector.v[0];
+ v[1] *= vector.v[1];
return *this;
}
inline QVector2D &QVector2D::operator/=(float divisor)
{
- xp /= divisor;
- yp /= divisor;
+ v[0] /= divisor;
+ v[1] /= divisor;
return *this;
}
inline QVector2D &QVector2D::operator/=(const QVector2D &vector)
{
- xp /= vector.xp;
- yp /= vector.yp;
+ v[0] /= vector.v[0];
+ v[1] /= vector.v[1];
return *this;
}
@@ -209,68 +209,68 @@ QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
Q_DECL_CONSTEXPR inline bool operator==(const QVector2D &v1, const QVector2D &v2)
{
- return v1.xp == v2.xp && v1.yp == v2.yp;
+ return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1];
}
Q_DECL_CONSTEXPR inline bool operator!=(const QVector2D &v1, const QVector2D &v2)
{
- return v1.xp != v2.xp || v1.yp != v2.yp;
+ return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1];
}
QT_WARNING_POP
Q_DECL_CONSTEXPR inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2)
{
- return QVector2D(v1.xp + v2.xp, v1.yp + v2.yp);
+ return QVector2D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1]);
}
Q_DECL_CONSTEXPR inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2)
{
- return QVector2D(v1.xp - v2.xp, v1.yp - v2.yp);
+ return QVector2D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1]);
}
Q_DECL_CONSTEXPR inline const QVector2D operator*(float factor, const QVector2D &vector)
{
- return QVector2D(vector.xp * factor, vector.yp * factor);
+ return QVector2D(vector.v[0] * factor, vector.v[1] * factor);
}
Q_DECL_CONSTEXPR inline const QVector2D operator*(const QVector2D &vector, float factor)
{
- return QVector2D(vector.xp * factor, vector.yp * factor);
+ return QVector2D(vector.v[0] * factor, vector.v[1] * factor);
}
Q_DECL_CONSTEXPR inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2)
{
- return QVector2D(v1.xp * v2.xp, v1.yp * v2.yp);
+ return QVector2D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1]);
}
Q_DECL_CONSTEXPR inline const QVector2D operator-(const QVector2D &vector)
{
- return QVector2D(-vector.xp, -vector.yp);
+ return QVector2D(-vector.v[0], -vector.v[1]);
}
Q_DECL_CONSTEXPR inline const QVector2D operator/(const QVector2D &vector, float divisor)
{
- return QVector2D(vector.xp / divisor, vector.yp / divisor);
+ return QVector2D(vector.v[0] / divisor, vector.v[1] / divisor);
}
Q_DECL_CONSTEXPR inline const QVector2D operator/(const QVector2D &vector, const QVector2D &divisor)
{
- return QVector2D(vector.xp / divisor.xp, vector.yp / divisor.yp);
+ return QVector2D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1]);
}
Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2)
{
- return qFuzzyCompare(v1.xp, v2.xp) && qFuzzyCompare(v1.yp, v2.yp);
+ return qFuzzyCompare(v1.v[0], v2.v[0]) && qFuzzyCompare(v1.v[1], v2.v[1]);
}
Q_DECL_CONSTEXPR inline QPoint QVector2D::toPoint() const
{
- return QPoint(qRound(xp), qRound(yp));
+ return QPoint(qRound(v[0]), qRound(v[1]));
}
Q_DECL_CONSTEXPR inline QPointF QVector2D::toPointF() const
{
- return QPointF(qreal(xp), qreal(yp));
+ return QPointF(qreal(v[0]), qreal(v[1]));
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index 8aaf1b0eaa..12a7902272 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -51,6 +51,41 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_VECTOR3D
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector3D>::value, "QVector3D is supposed to be standard layout");
+Q_STATIC_ASSERT_X(sizeof(QVector3D) == sizeof(float) * 3, "QVector3D is not supposed to have padding at the end");
+
+// QVector3D used to be defined as class QVector3D { float x, y, z; };,
+// now instead it is defined as classs QVector3D { float v[3]; };.
+// Check that binary compatibility is preserved.
+// ### Qt 6: remove all of these checks.
+
+namespace {
+
+struct QVector3DOld
+{
+ float x, y, z;
+};
+
+struct QVector3DNew
+{
+ float v[3];
+};
+
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector3DOld>::value, "Binary compatibility break in QVector3D");
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector3DNew>::value, "Binary compatibility break in QVector3D");
+
+Q_STATIC_ASSERT_X(sizeof(QVector3DOld) == sizeof(QVector3DNew), "Binary compatibility break in QVector3D");
+
+// requires a constexpr offsetof
+#if !defined(Q_CC_MSVC) || (_MSC_VER >= 1910)
+Q_STATIC_ASSERT_X(offsetof(QVector3DOld, x) == offsetof(QVector3DNew, v) + sizeof(QVector3DNew::v[0]) * 0, "Binary compatibility break in QVector3D");
+Q_STATIC_ASSERT_X(offsetof(QVector3DOld, y) == offsetof(QVector3DNew, v) + sizeof(QVector3DNew::v[0]) * 1, "Binary compatibility break in QVector3D");
+Q_STATIC_ASSERT_X(offsetof(QVector3DOld, z) == offsetof(QVector3DNew, v) + sizeof(QVector3DNew::v[0]) * 2, "Binary compatibility break in QVector3D");
+#endif
+
+
+} // anonymous namespace
+
/*!
\class QVector3D
\brief The QVector3D class represents a vector or vertex in 3D space.
@@ -112,9 +147,9 @@ QT_BEGIN_NAMESPACE
*/
QVector3D::QVector3D(const QVector2D& vector)
{
- xp = vector.xp;
- yp = vector.yp;
- zp = 0.0f;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
+ v[2] = 0.0f;
}
/*!
@@ -125,9 +160,9 @@ QVector3D::QVector3D(const QVector2D& vector)
*/
QVector3D::QVector3D(const QVector2D& vector, float zpos)
{
- xp = vector.xp;
- yp = vector.yp;
- zp = zpos;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
+ v[2] = zpos;
}
#endif
@@ -142,9 +177,9 @@ QVector3D::QVector3D(const QVector2D& vector, float zpos)
*/
QVector3D::QVector3D(const QVector4D& vector)
{
- xp = vector.xp;
- yp = vector.yp;
- zp = vector.zp;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
+ v[2] = vector.v[2];
}
#endif
@@ -235,16 +270,16 @@ QVector3D::QVector3D(const QVector4D& vector)
QVector3D QVector3D::normalized() const
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp) +
- double(zp) * double(zp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]) +
+ double(v[2]) * double(v[2]);
if (qFuzzyIsNull(len - 1.0f)) {
return *this;
} else if (!qFuzzyIsNull(len)) {
double sqrtLen = std::sqrt(len);
- return QVector3D(float(double(xp) / sqrtLen),
- float(double(yp) / sqrtLen),
- float(double(zp) / sqrtLen));
+ return QVector3D(float(double(v[0]) / sqrtLen),
+ float(double(v[1]) / sqrtLen),
+ float(double(v[2]) / sqrtLen));
} else {
return QVector3D();
}
@@ -259,17 +294,17 @@ QVector3D QVector3D::normalized() const
void QVector3D::normalize()
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp) +
- double(zp) * double(zp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]) +
+ double(v[2]) * double(v[2]);
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return;
len = std::sqrt(len);
- xp = float(double(xp) / len);
- yp = float(double(yp) / len);
- zp = float(double(zp) / len);
+ v[0] = float(double(v[0]) / len);
+ v[1] = float(double(v[1]) / len);
+ v[2] = float(double(v[2]) / len);
}
/*!
@@ -336,7 +371,7 @@ void QVector3D::normalize()
*/
float QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2)
{
- return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp;
+ return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1] + v1.v[2] * v2.v[2];
}
/*!
@@ -347,9 +382,9 @@ float QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2)
*/
QVector3D QVector3D::crossProduct(const QVector3D& v1, const QVector3D& v2)
{
- return QVector3D(v1.yp * v2.zp - v1.zp * v2.yp,
- v1.zp * v2.xp - v1.xp * v2.zp,
- v1.xp * v2.yp - v1.yp * v2.xp);
+ return QVector3D(v1.v[1] * v2.v[2] - v1.v[2] * v2.v[1],
+ v1.v[2] * v2.v[0] - v1.v[0] * v2.v[2],
+ v1.v[0] * v2.v[1] - v1.v[1] * v2.v[0]);
}
/*!
@@ -629,7 +664,7 @@ float QVector3D::distanceToLine
*/
QVector2D QVector3D::toVector2D() const
{
- return QVector2D(xp, yp);
+ return QVector2D(v[0], v[1]);
}
#endif
@@ -643,7 +678,7 @@ QVector2D QVector3D::toVector2D() const
*/
QVector4D QVector3D::toVector4D() const
{
- return QVector4D(xp, yp, zp, 0.0f);
+ return QVector4D(v[0], v[1], v[2], 0.0f);
}
#endif
@@ -682,9 +717,9 @@ QVector3D::operator QVariant() const
float QVector3D::length() const
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp) +
- double(zp) * double(zp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]) +
+ double(v[2]) * double(v[2]);
return float(std::sqrt(len));
}
@@ -696,7 +731,7 @@ float QVector3D::length() const
*/
float QVector3D::lengthSquared() const
{
- return xp * xp + yp * yp + zp * zp;
+ return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h
index f3e8c976b7..1b49f3e7b9 100644
--- a/src/gui/math3d/qvector3d.h
+++ b/src/gui/math3d/qvector3d.h
@@ -59,7 +59,7 @@ class Q_GUI_EXPORT QVector3D
public:
Q_DECL_CONSTEXPR QVector3D();
explicit QVector3D(Qt::Initialization) {}
- Q_DECL_CONSTEXPR QVector3D(float xpos, float ypos, float zpos) : xp(xpos), yp(ypos), zp(zpos) {}
+ Q_DECL_CONSTEXPR QVector3D(float xpos, float ypos, float zpos) : v{xpos, ypos, zpos} {}
Q_DECL_CONSTEXPR explicit QVector3D(const QPoint& point);
Q_DECL_CONSTEXPR explicit QVector3D(const QPointF& point);
@@ -138,7 +138,7 @@ public:
operator QVariant() const;
private:
- float xp, yp, zp;
+ float v[3];
friend class QVector2D;
friend class QVector4D;
@@ -150,82 +150,82 @@ private:
Q_DECLARE_TYPEINFO(QVector3D, Q_PRIMITIVE_TYPE);
-Q_DECL_CONSTEXPR inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D() : v{0.0f, 0.0f, 0.0f} {}
-Q_DECL_CONSTEXPR inline QVector3D::QVector3D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D(const QPoint& point) : v{float(point.x()), float(point.y()), float(0.0f)} {}
-Q_DECL_CONSTEXPR inline QVector3D::QVector3D(const QPointF& point) : xp(float(point.x())), yp(float(point.y())), zp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D(const QPointF& point) : v{float(point.x()), float(point.y()), 0.0f} {}
inline bool QVector3D::isNull() const
{
- return qIsNull(xp) && qIsNull(yp) && qIsNull(zp);
+ return qIsNull(v[0]) && qIsNull(v[1]) && qIsNull(v[2]);
}
-Q_DECL_CONSTEXPR inline float QVector3D::x() const { return xp; }
-Q_DECL_CONSTEXPR inline float QVector3D::y() const { return yp; }
-Q_DECL_CONSTEXPR inline float QVector3D::z() const { return zp; }
+Q_DECL_CONSTEXPR inline float QVector3D::x() const { return v[0]; }
+Q_DECL_CONSTEXPR inline float QVector3D::y() const { return v[1]; }
+Q_DECL_CONSTEXPR inline float QVector3D::z() const { return v[2]; }
-inline void QVector3D::setX(float aX) { xp = aX; }
-inline void QVector3D::setY(float aY) { yp = aY; }
-inline void QVector3D::setZ(float aZ) { zp = aZ; }
+inline void QVector3D::setX(float aX) { v[0] = aX; }
+inline void QVector3D::setY(float aY) { v[1] = aY; }
+inline void QVector3D::setZ(float aZ) { v[2] = aZ; }
inline float &QVector3D::operator[](int i)
{
Q_ASSERT(uint(i) < 3u);
- return *(&xp + i);
+ return v[i];
}
inline float QVector3D::operator[](int i) const
{
Q_ASSERT(uint(i) < 3u);
- return *(&xp + i);
+ return v[i];
}
inline QVector3D &QVector3D::operator+=(const QVector3D &vector)
{
- xp += vector.xp;
- yp += vector.yp;
- zp += vector.zp;
+ v[0] += vector.v[0];
+ v[1] += vector.v[1];
+ v[2] += vector.v[2];
return *this;
}
inline QVector3D &QVector3D::operator-=(const QVector3D &vector)
{
- xp -= vector.xp;
- yp -= vector.yp;
- zp -= vector.zp;
+ v[0] -= vector.v[0];
+ v[1] -= vector.v[1];
+ v[2] -= vector.v[2];
return *this;
}
inline QVector3D &QVector3D::operator*=(float factor)
{
- xp *= factor;
- yp *= factor;
- zp *= factor;
+ v[0] *= factor;
+ v[1] *= factor;
+ v[2] *= factor;
return *this;
}
inline QVector3D &QVector3D::operator*=(const QVector3D& vector)
{
- xp *= vector.xp;
- yp *= vector.yp;
- zp *= vector.zp;
+ v[0] *= vector.v[0];
+ v[1] *= vector.v[1];
+ v[2] *= vector.v[2];
return *this;
}
inline QVector3D &QVector3D::operator/=(float divisor)
{
- xp /= divisor;
- yp /= divisor;
- zp /= divisor;
+ v[0] /= divisor;
+ v[1] /= divisor;
+ v[2] /= divisor;
return *this;
}
inline QVector3D &QVector3D::operator/=(const QVector3D &vector)
{
- xp /= vector.xp;
- yp /= vector.yp;
- zp /= vector.zp;
+ v[0] /= vector.v[0];
+ v[1] /= vector.v[1];
+ v[2] /= vector.v[2];
return *this;
}
@@ -234,70 +234,70 @@ QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
Q_DECL_CONSTEXPR inline bool operator==(const QVector3D &v1, const QVector3D &v2)
{
- return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp;
+ return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2];
}
Q_DECL_CONSTEXPR inline bool operator!=(const QVector3D &v1, const QVector3D &v2)
{
- return v1.xp != v2.xp || v1.yp != v2.yp || v1.zp != v2.zp;
+ return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1] || v1.v[2] != v2.v[2];
}
QT_WARNING_POP
Q_DECL_CONSTEXPR inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2)
{
- return QVector3D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp);
+ return QVector3D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1], v1.v[2] + v2.v[2]);
}
Q_DECL_CONSTEXPR inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2)
{
- return QVector3D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp);
+ return QVector3D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1], v1.v[2] - v2.v[2]);
}
Q_DECL_CONSTEXPR inline const QVector3D operator*(float factor, const QVector3D &vector)
{
- return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor);
+ return QVector3D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor);
}
Q_DECL_CONSTEXPR inline const QVector3D operator*(const QVector3D &vector, float factor)
{
- return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor);
+ return QVector3D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor);
}
Q_DECL_CONSTEXPR inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2)
{
- return QVector3D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp);
+ return QVector3D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1], v1.v[2] * v2.v[2]);
}
Q_DECL_CONSTEXPR inline const QVector3D operator-(const QVector3D &vector)
{
- return QVector3D(-vector.xp, -vector.yp, -vector.zp);
+ return QVector3D(-vector.v[0], -vector.v[1], -vector.v[2]);
}
Q_DECL_CONSTEXPR inline const QVector3D operator/(const QVector3D &vector, float divisor)
{
- return QVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor);
+ return QVector3D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor);
}
Q_DECL_CONSTEXPR inline const QVector3D operator/(const QVector3D &vector, const QVector3D &divisor)
{
- return QVector3D(vector.xp / divisor.xp, vector.yp / divisor.yp, vector.zp / divisor.zp);
+ return QVector3D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1], vector.v[2] / divisor.v[2]);
}
Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2)
{
- return qFuzzyCompare(v1.xp, v2.xp) &&
- qFuzzyCompare(v1.yp, v2.yp) &&
- qFuzzyCompare(v1.zp, v2.zp);
+ return qFuzzyCompare(v1.v[0], v2.v[0]) &&
+ qFuzzyCompare(v1.v[1], v2.v[1]) &&
+ qFuzzyCompare(v1.v[2], v2.v[2]);
}
Q_DECL_CONSTEXPR inline QPoint QVector3D::toPoint() const
{
- return QPoint(qRound(xp), qRound(yp));
+ return QPoint(qRound(v[0]), qRound(v[1]));
}
Q_DECL_CONSTEXPR inline QPointF QVector3D::toPointF() const
{
- return QPointF(qreal(xp), qreal(yp));
+ return QPointF(qreal(v[0]), qreal(v[1]));
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp
index 331144ba33..3a68bd6cb7 100644
--- a/src/gui/math3d/qvector4d.cpp
+++ b/src/gui/math3d/qvector4d.cpp
@@ -49,6 +49,42 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_VECTOR4D
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector4D>::value, "QVector4D is supposed to be standard layout");
+Q_STATIC_ASSERT_X(sizeof(QVector4D) == sizeof(float) * 4, "QVector4D is not supposed to have padding at the end");
+
+// QVector4D used to be defined as class QVector4D { float x, y, z, w; };,
+// now instead it is defined as classs QVector4D { float v[4]; };.
+// Check that binary compatibility is preserved.
+// ### Qt 6: remove all of these checks.
+
+namespace {
+
+struct QVector4DOld
+{
+ float x, y, z, w;
+};
+
+struct QVector4DNew
+{
+ float v[4];
+};
+
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector4DOld>::value, "Binary compatibility break in QVector4D");
+Q_STATIC_ASSERT_X(std::is_standard_layout<QVector4DNew>::value, "Binary compatibility break in QVector4D");
+
+Q_STATIC_ASSERT_X(sizeof(QVector4DOld) == sizeof(QVector4DNew), "Binary compatibility break in QVector4D");
+
+// requires a constexpr offsetof
+#if !defined(Q_CC_MSVC) || (_MSC_VER >= 1910)
+Q_STATIC_ASSERT_X(offsetof(QVector4DOld, x) == offsetof(QVector4DNew, v) + sizeof(QVector4DNew::v[0]) * 0, "Binary compatibility break in QVector4D");
+Q_STATIC_ASSERT_X(offsetof(QVector4DOld, y) == offsetof(QVector4DNew, v) + sizeof(QVector4DNew::v[0]) * 1, "Binary compatibility break in QVector4D");
+Q_STATIC_ASSERT_X(offsetof(QVector4DOld, z) == offsetof(QVector4DNew, v) + sizeof(QVector4DNew::v[0]) * 2, "Binary compatibility break in QVector4D");
+Q_STATIC_ASSERT_X(offsetof(QVector4DOld, w) == offsetof(QVector4DNew, v) + sizeof(QVector4DNew::v[0]) * 3, "Binary compatibility break in QVector4D");
+#endif
+
+
+} // anonymous namespace
+
/*!
\class QVector4D
\brief The QVector4D class represents a vector or vertex in 4D space.
@@ -106,10 +142,10 @@ QT_BEGIN_NAMESPACE
*/
QVector4D::QVector4D(const QVector2D& vector)
{
- xp = vector.xp;
- yp = vector.yp;
- zp = 0.0f;
- wp = 0.0f;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
+ v[2] = 0.0f;
+ v[3] = 0.0f;
}
/*!
@@ -120,10 +156,10 @@ QVector4D::QVector4D(const QVector2D& vector)
*/
QVector4D::QVector4D(const QVector2D& vector, float zpos, float wpos)
{
- xp = vector.xp;
- yp = vector.yp;
- zp = zpos;
- wp = wpos;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
+ v[2] = zpos;
+ v[3] = wpos;
}
#endif
@@ -138,10 +174,10 @@ QVector4D::QVector4D(const QVector2D& vector, float zpos, float wpos)
*/
QVector4D::QVector4D(const QVector3D& vector)
{
- xp = vector.xp;
- yp = vector.yp;
- zp = vector.zp;
- wp = 0.0f;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
+ v[2] = vector.v[2];
+ v[3] = 0.0f;
}
/*!
@@ -152,10 +188,10 @@ QVector4D::QVector4D(const QVector3D& vector)
*/
QVector4D::QVector4D(const QVector3D& vector, float wpos)
{
- xp = vector.xp;
- yp = vector.yp;
- zp = vector.zp;
- wp = wpos;
+ v[0] = vector.v[0];
+ v[1] = vector.v[1];
+ v[2] = vector.v[2];
+ v[3] = wpos;
}
#endif
@@ -258,10 +294,10 @@ QVector4D::QVector4D(const QVector3D& vector, float wpos)
float QVector4D::length() const
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp) +
- double(zp) * double(zp) +
- double(wp) * double(wp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]) +
+ double(v[2]) * double(v[2]) +
+ double(v[3]) * double(v[3]);
return float(std::sqrt(len));
}
@@ -273,7 +309,7 @@ float QVector4D::length() const
*/
float QVector4D::lengthSquared() const
{
- return xp * xp + yp * yp + zp * zp + wp * wp;
+ return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
}
/*!
@@ -288,18 +324,18 @@ float QVector4D::lengthSquared() const
QVector4D QVector4D::normalized() const
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp) +
- double(zp) * double(zp) +
- double(wp) * double(wp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]) +
+ double(v[2]) * double(v[2]) +
+ double(v[3]) * double(v[3]);
if (qFuzzyIsNull(len - 1.0f)) {
return *this;
} else if (!qFuzzyIsNull(len)) {
double sqrtLen = std::sqrt(len);
- return QVector4D(float(double(xp) / sqrtLen),
- float(double(yp) / sqrtLen),
- float(double(zp) / sqrtLen),
- float(double(wp) / sqrtLen));
+ return QVector4D(float(double(v[0]) / sqrtLen),
+ float(double(v[1]) / sqrtLen),
+ float(double(v[2]) / sqrtLen),
+ float(double(v[3]) / sqrtLen));
} else {
return QVector4D();
}
@@ -314,19 +350,19 @@ QVector4D QVector4D::normalized() const
void QVector4D::normalize()
{
// Need some extra precision if the length is very small.
- double len = double(xp) * double(xp) +
- double(yp) * double(yp) +
- double(zp) * double(zp) +
- double(wp) * double(wp);
+ double len = double(v[0]) * double(v[0]) +
+ double(v[1]) * double(v[1]) +
+ double(v[2]) * double(v[2]) +
+ double(v[3]) * double(v[3]);
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return;
len = std::sqrt(len);
- xp = float(double(xp) / len);
- yp = float(double(yp) / len);
- zp = float(double(zp) / len);
- wp = float(double(wp) / len);
+ v[0] = float(double(v[0]) / len);
+ v[1] = float(double(v[1]) / len);
+ v[2] = float(double(v[2]) / len);
+ v[3] = float(double(v[3]) / len);
}
/*!
@@ -387,7 +423,7 @@ void QVector4D::normalize()
*/
float QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
{
- return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp + v1.wp * v2.wp;
+ return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1] + v1.v[2] * v2.v[2] + v1.v[3] * v2.v[3];
}
/*!
@@ -503,7 +539,7 @@ float QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2)
*/
QVector2D QVector4D::toVector2D() const
{
- return QVector2D(xp, yp);
+ return QVector2D(v[0], v[1]);
}
/*!
@@ -515,9 +551,9 @@ QVector2D QVector4D::toVector2D() const
*/
QVector2D QVector4D::toVector2DAffine() const
{
- if (qIsNull(wp))
+ if (qIsNull(v[3]))
return QVector2D();
- return QVector2D(xp / wp, yp / wp);
+ return QVector2D(v[0] / v[3], v[1] / v[3]);
}
#endif
@@ -531,7 +567,7 @@ QVector2D QVector4D::toVector2DAffine() const
*/
QVector3D QVector4D::toVector3D() const
{
- return QVector3D(xp, yp, zp);
+ return QVector3D(v[0], v[1], v[2]);
}
/*!
@@ -542,9 +578,9 @@ QVector3D QVector4D::toVector3D() const
*/
QVector3D QVector4D::toVector3DAffine() const
{
- if (qIsNull(wp))
+ if (qIsNull(v[3]))
return QVector3D();
- return QVector3D(xp / wp, yp / wp, zp / wp);
+ return QVector3D(v[0] / v[3], v[1] / v[3], v[2] / v[3]);
}
#endif
diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h
index 3f14b41e8e..08cb423484 100644
--- a/src/gui/math3d/qvector4d.h
+++ b/src/gui/math3d/qvector4d.h
@@ -128,7 +128,7 @@ public:
operator QVariant() const;
private:
- float xp, yp, zp, wp;
+ float v[4];
friend class QVector2D;
friend class QVector3D;
@@ -140,92 +140,92 @@ private:
Q_DECLARE_TYPEINFO(QVector4D, Q_PRIMITIVE_TYPE);
-Q_DECL_CONSTEXPR inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D() : v{0.0f, 0.0f, 0.0f, 0.0f} {}
-Q_DECL_CONSTEXPR inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) : v{xpos, ypos, zpos, wpos} {}
-Q_DECL_CONSTEXPR inline QVector4D::QVector4D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(const QPoint& point) : v{float(point.x()), float(point.y()), 0.0f, 0.0f} {}
-Q_DECL_CONSTEXPR inline QVector4D::QVector4D(const QPointF& point) : xp(float(point.x())), yp(float(point.y())), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(const QPointF& point) : v{float(point.x()), float(point.y()), 0.0f, 0.0f} {}
inline bool QVector4D::isNull() const
{
- return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp);
+ return qIsNull(v[0]) && qIsNull(v[1]) && qIsNull(v[2]) && qIsNull(v[3]);
}
-Q_DECL_CONSTEXPR inline float QVector4D::x() const { return xp; }
-Q_DECL_CONSTEXPR inline float QVector4D::y() const { return yp; }
-Q_DECL_CONSTEXPR inline float QVector4D::z() const { return zp; }
-Q_DECL_CONSTEXPR inline float QVector4D::w() const { return wp; }
+Q_DECL_CONSTEXPR inline float QVector4D::x() const { return v[0]; }
+Q_DECL_CONSTEXPR inline float QVector4D::y() const { return v[1]; }
+Q_DECL_CONSTEXPR inline float QVector4D::z() const { return v[2]; }
+Q_DECL_CONSTEXPR inline float QVector4D::w() const { return v[3]; }
-inline void QVector4D::setX(float aX) { xp = aX; }
-inline void QVector4D::setY(float aY) { yp = aY; }
-inline void QVector4D::setZ(float aZ) { zp = aZ; }
-inline void QVector4D::setW(float aW) { wp = aW; }
+inline void QVector4D::setX(float aX) { v[0] = aX; }
+inline void QVector4D::setY(float aY) { v[1] = aY; }
+inline void QVector4D::setZ(float aZ) { v[2] = aZ; }
+inline void QVector4D::setW(float aW) { v[3] = aW; }
inline float &QVector4D::operator[](int i)
{
Q_ASSERT(uint(i) < 4u);
- return *(&xp + i);
+ return v[i];
}
inline float QVector4D::operator[](int i) const
{
Q_ASSERT(uint(i) < 4u);
- return *(&xp + i);
+ return v[i];
}
inline QVector4D &QVector4D::operator+=(const QVector4D &vector)
{
- xp += vector.xp;
- yp += vector.yp;
- zp += vector.zp;
- wp += vector.wp;
+ v[0] += vector.v[0];
+ v[1] += vector.v[1];
+ v[2] += vector.v[2];
+ v[3] += vector.v[3];
return *this;
}
inline QVector4D &QVector4D::operator-=(const QVector4D &vector)
{
- xp -= vector.xp;
- yp -= vector.yp;
- zp -= vector.zp;
- wp -= vector.wp;
+ v[0] -= vector.v[0];
+ v[1] -= vector.v[1];
+ v[2] -= vector.v[2];
+ v[3] -= vector.v[3];
return *this;
}
inline QVector4D &QVector4D::operator*=(float factor)
{
- xp *= factor;
- yp *= factor;
- zp *= factor;
- wp *= factor;
+ v[0] *= factor;
+ v[1] *= factor;
+ v[2] *= factor;
+ v[3] *= factor;
return *this;
}
inline QVector4D &QVector4D::operator*=(const QVector4D &vector)
{
- xp *= vector.xp;
- yp *= vector.yp;
- zp *= vector.zp;
- wp *= vector.wp;
+ v[0] *= vector.v[0];
+ v[1] *= vector.v[1];
+ v[2] *= vector.v[2];
+ v[3] *= vector.v[3];
return *this;
}
inline QVector4D &QVector4D::operator/=(float divisor)
{
- xp /= divisor;
- yp /= divisor;
- zp /= divisor;
- wp /= divisor;
+ v[0] /= divisor;
+ v[1] /= divisor;
+ v[2] /= divisor;
+ v[3] /= divisor;
return *this;
}
inline QVector4D &QVector4D::operator/=(const QVector4D &vector)
{
- xp /= vector.xp;
- yp /= vector.yp;
- zp /= vector.zp;
- wp /= vector.wp;
+ v[0] /= vector.v[0];
+ v[1] /= vector.v[1];
+ v[2] /= vector.v[2];
+ v[3] /= vector.v[3];
return *this;
}
@@ -234,71 +234,71 @@ QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
Q_DECL_CONSTEXPR inline bool operator==(const QVector4D &v1, const QVector4D &v2)
{
- return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp && v1.wp == v2.wp;
+ return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2] && v1.v[3] == v2.v[3];
}
Q_DECL_CONSTEXPR inline bool operator!=(const QVector4D &v1, const QVector4D &v2)
{
- return v1.xp != v2.xp || v1.yp != v2.yp || v1.zp != v2.zp || v1.wp != v2.wp;
+ return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1] || v1.v[2] != v2.v[2] || v1.v[3] != v2.v[3];
}
QT_WARNING_POP
Q_DECL_CONSTEXPR inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2)
{
- return QVector4D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp, v1.wp + v2.wp);
+ return QVector4D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1], v1.v[2] + v2.v[2], v1.v[3] + v2.v[3]);
}
Q_DECL_CONSTEXPR inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2)
{
- return QVector4D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp, v1.wp - v2.wp);
+ return QVector4D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1], v1.v[2] - v2.v[2], v1.v[3] - v2.v[3]);
}
Q_DECL_CONSTEXPR inline const QVector4D operator*(float factor, const QVector4D &vector)
{
- return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor);
+ return QVector4D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor, vector.v[3] * factor);
}
Q_DECL_CONSTEXPR inline const QVector4D operator*(const QVector4D &vector, float factor)
{
- return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor);
+ return QVector4D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor, vector.v[3] * factor);
}
Q_DECL_CONSTEXPR inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2)
{
- return QVector4D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp, v1.wp * v2.wp);
+ return QVector4D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1], v1.v[2] * v2.v[2], v1.v[3] * v2.v[3]);
}
Q_DECL_CONSTEXPR inline const QVector4D operator-(const QVector4D &vector)
{
- return QVector4D(-vector.xp, -vector.yp, -vector.zp, -vector.wp);
+ return QVector4D(-vector.v[0], -vector.v[1], -vector.v[2], -vector.v[3]);
}
Q_DECL_CONSTEXPR inline const QVector4D operator/(const QVector4D &vector, float divisor)
{
- return QVector4D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, vector.wp / divisor);
+ return QVector4D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor, vector.v[3] / divisor);
}
Q_DECL_CONSTEXPR inline const QVector4D operator/(const QVector4D &vector, const QVector4D &divisor)
{
- return QVector4D(vector.xp / divisor.xp, vector.yp / divisor.yp, vector.zp / divisor.zp, vector.wp / divisor.wp);
+ return QVector4D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1], vector.v[2] / divisor.v[2], vector.v[3] / divisor.v[3]);
}
Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
{
- return qFuzzyCompare(v1.xp, v2.xp) &&
- qFuzzyCompare(v1.yp, v2.yp) &&
- qFuzzyCompare(v1.zp, v2.zp) &&
- qFuzzyCompare(v1.wp, v2.wp);
+ return qFuzzyCompare(v1.v[0], v2.v[0]) &&
+ qFuzzyCompare(v1.v[1], v2.v[1]) &&
+ qFuzzyCompare(v1.v[2], v2.v[2]) &&
+ qFuzzyCompare(v1.v[3], v2.v[3]);
}
Q_DECL_CONSTEXPR inline QPoint QVector4D::toPoint() const
{
- return QPoint(qRound(xp), qRound(yp));
+ return QPoint(qRound(v[0]), qRound(v[1]));
}
Q_DECL_CONSTEXPR inline QPointF QVector4D::toPointF() const
{
- return QPointF(qreal(xp), qreal(yp));
+ return QPointF(qreal(v[0]), qreal(v[1]));
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri
index 4c778b184e..24758afdeb 100644
--- a/src/gui/opengl/opengl.pri
+++ b/src/gui/opengl/opengl.pri
@@ -32,6 +32,7 @@ qtConfig(opengl) {
opengl/qopengltexture.h \
opengl/qopengltexture_p.h \
opengl/qopengltexturehelper_p.h \
+ opengl/qopengltextureuploader_p.h \
opengl/qopenglpixeltransferoptions.h \
opengl/qopenglextrafunctions.h \
opengl/qopenglprogrambinarycache_p.h
@@ -56,6 +57,7 @@ qtConfig(opengl) {
opengl/qopengltextureblitter.cpp \
opengl/qopengltexture.cpp \
opengl/qopengltexturehelper.cpp \
+ opengl/qopengltextureuploader.cpp \
opengl/qopenglpixeltransferoptions.cpp \
opengl/qopenglprogrambinarycache.cpp
diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h
index b4657fa118..3a2393ea58 100644
--- a/src/gui/opengl/qopengl.h
+++ b/src/gui/opengl/qopengl.h
@@ -239,7 +239,7 @@ typedef unsigned long long int uint64_t;
typedef long int int32_t;
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
-#elif defined(_WIN32) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1600))
+#elif defined(_WIN32) && (defined(__GNUC__) || defined(_MSC_VER))
#include <stdint.h>
#elif defined(_WIN32)
typedef __int32 int32_t;
diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp
index 69c2baa8d9..000494244d 100644
--- a/src/gui/opengl/qopenglbuffer.cpp
+++ b/src/gui/opengl/qopenglbuffer.cpp
@@ -43,6 +43,10 @@
#include "qopenglbuffer.h"
#include <private/qopenglextensions_p.h>
+#ifndef GL_CONTEXT_LOST
+#define GL_CONTEXT_LOST 0x0507
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -346,7 +350,14 @@ bool QOpenGLBuffer::read(int offset, void *data, int count)
Q_D(QOpenGLBuffer);
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
return false;
- while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state.
+
+ while (true) { // Clear error state.
+ GLenum error = d->funcs->glGetError();
+ if (error == GL_NO_ERROR)
+ break;
+ if (error == GL_CONTEXT_LOST)
+ return false;
+ };
d->funcs->glGetBufferSubData(d->type, offset, count, data);
return d->funcs->glGetError() == GL_NO_ERROR;
#else
diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp
index f6c3af37dd..7072db5af4 100644
--- a/src/gui/opengl/qopengldebug.cpp
+++ b/src/gui/opengl/qopengldebug.cpp
@@ -100,6 +100,10 @@ QT_BEGIN_NAMESPACE
\endcode
+ If you try to clear the error stack, make sure not just keep going until
+ GL_NO_ERROR is returned but also break on GL_CONTEXT_LOST as that error
+ value will keep repeating.
+
There are also many other information we are interested in (as application
developers), for instance performance issues, or warnings about using
deprecated APIs. Those kind of messages are not reported through the
diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp
index 2f7afa4a66..b7bac2728a 100644
--- a/src/gui/opengl/qopenglengineshadermanager.cpp
+++ b/src/gui/opengl/qopenglengineshadermanager.cpp
@@ -153,12 +153,8 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[AffinePositionWithRadialGradientBrushVertexShader] = qopenglslAffinePositionWithRadialGradientBrushVertexShader_core;
code[AffinePositionWithTextureBrushVertexShader] = qopenglslAffinePositionWithTextureBrushVertexShader_core;
- code[MainFragmentShader_CMO] = qopenglslMainFragmentShader_CMO_core;
- code[MainFragmentShader_CM] = qopenglslMainFragmentShader_CM_core;
code[MainFragmentShader_MO] = qopenglslMainFragmentShader_MO_core;
code[MainFragmentShader_M] = qopenglslMainFragmentShader_M_core;
- code[MainFragmentShader_CO] = qopenglslMainFragmentShader_CO_core;
- code[MainFragmentShader_C] = qopenglslMainFragmentShader_C_core;
code[MainFragmentShader_O] = qopenglslMainFragmentShader_O_core;
code[MainFragmentShader] = qopenglslMainFragmentShader_core;
code[MainFragmentShader_ImageArrays] = qopenglslMainFragmentShader_ImageArrays_core;
@@ -171,7 +167,7 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader_core; // Calls "customShader", which must be appended
code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader_core;
- code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop_core;
+ code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_core;
code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader_core;
code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader_core;
code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader_core;
@@ -203,12 +199,8 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[AffinePositionWithRadialGradientBrushVertexShader] = qopenglslAffinePositionWithRadialGradientBrushVertexShader;
code[AffinePositionWithTextureBrushVertexShader] = qopenglslAffinePositionWithTextureBrushVertexShader;
- code[MainFragmentShader_CMO] = qopenglslMainFragmentShader_CMO;
- code[MainFragmentShader_CM] = qopenglslMainFragmentShader_CM;
code[MainFragmentShader_MO] = qopenglslMainFragmentShader_MO;
code[MainFragmentShader_M] = qopenglslMainFragmentShader_M;
- code[MainFragmentShader_CO] = qopenglslMainFragmentShader_CO;
- code[MainFragmentShader_C] = qopenglslMainFragmentShader_C;
code[MainFragmentShader_O] = qopenglslMainFragmentShader_O;
code[MainFragmentShader] = qopenglslMainFragmentShader;
code[MainFragmentShader_ImageArrays] = qopenglslMainFragmentShader_ImageArrays;
@@ -220,10 +212,7 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[AlphaImageSrcFragmentShader] = qopenglslAlphaImageSrcFragmentShader;
code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader;
- if (context->isOpenGLES())
- code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_ES;
- else
- code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop;
+ code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader;
code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader;
code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader;
code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader;
@@ -238,21 +227,20 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[RgbMaskWithGammaFragmentShader] = ""; //###
}
- // These shaders are not implemented yet and therefore are the same
- // for all profiles. Implementations should make a version for both
- // profiles and put the appropriate lines in the if-statement above.
+ // The composition shaders are just layout qualifiers and the same
+ // for all profiles that support them.
code[NoCompositionModeFragmentShader] = "";
- code[MultiplyCompositionModeFragmentShader] = ""; //###
- code[ScreenCompositionModeFragmentShader] = ""; //###
- code[OverlayCompositionModeFragmentShader] = ""; //###
- code[DarkenCompositionModeFragmentShader] = ""; //###
- code[LightenCompositionModeFragmentShader] = ""; //###
- code[ColorDodgeCompositionModeFragmentShader] = ""; //###
- code[ColorBurnCompositionModeFragmentShader] = ""; //###
- code[HardLightCompositionModeFragmentShader] = ""; //###
- code[SoftLightCompositionModeFragmentShader] = ""; //###
- code[DifferenceCompositionModeFragmentShader] = ""; //###
- code[ExclusionCompositionModeFragmentShader] = ""; //###
+ code[MultiplyCompositionModeFragmentShader] = qopenglslMultiplyCompositionModeFragmentShader;
+ code[ScreenCompositionModeFragmentShader] = qopenglslScreenCompositionModeFragmentShader;
+ code[OverlayCompositionModeFragmentShader] = qopenglslOverlayCompositionModeFragmentShader;
+ code[DarkenCompositionModeFragmentShader] = qopenglslDarkenCompositionModeFragmentShader;
+ code[LightenCompositionModeFragmentShader] = qopenglslLightenCompositionModeFragmentShader;
+ code[ColorDodgeCompositionModeFragmentShader] = qopenglslColorDodgeCompositionModeFragmentShader;
+ code[ColorBurnCompositionModeFragmentShader] = qopenglslColorBurnCompositionModeFragmentShader;
+ code[HardLightCompositionModeFragmentShader] = qopenglslHardLightCompositionModeFragmentShader;
+ code[SoftLightCompositionModeFragmentShader] = qopenglslSoftLightCompositionModeFragmentShader;
+ code[DifferenceCompositionModeFragmentShader] = qopenglslDifferenceCompositionModeFragmentShader;
+ code[ExclusionCompositionModeFragmentShader] = qopenglslExclusionCompositionModeFragmentShader;
#if defined(QT_DEBUG)
// Check that all the elements have been filled:
@@ -612,8 +600,11 @@ void QOpenGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mo
if (compositionMode == mode)
return;
+ bool wasAdvanced = compositionMode > QPainter::CompositionMode_Plus;
+ bool isAdvanced = mode > QPainter::CompositionMode_Plus;
+
compositionMode = mode;
- shaderProgNeedsChanging = true; //###
+ shaderProgNeedsChanging = shaderProgNeedsChanging || wasAdvanced || isAdvanced;
}
void QOpenGLEngineShaderManager::setCustomStage(QOpenGLCustomShaderStage* stage)
@@ -783,21 +774,13 @@ bool QOpenGLEngineShaderManager::useCorrectShaderProg()
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_ImageArrays;
} else {
bool useGlobalOpacity = (opacityMode == UniformOpacity);
- if (hasCompose && hasMask && useGlobalOpacity)
- requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CMO;
- if (hasCompose && hasMask && !useGlobalOpacity)
- requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CM;
- if (!hasCompose && hasMask && useGlobalOpacity)
+ if (hasMask && useGlobalOpacity)
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_MO;
- if (!hasCompose && hasMask && !useGlobalOpacity)
+ if (hasMask && !useGlobalOpacity)
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_M;
- if (hasCompose && !hasMask && useGlobalOpacity)
- requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CO;
- if (hasCompose && !hasMask && !useGlobalOpacity)
- requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_C;
- if (!hasCompose && !hasMask && useGlobalOpacity)
+ if (!hasMask && useGlobalOpacity)
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_O;
- if (!hasCompose && !hasMask && !useGlobalOpacity)
+ if (!hasMask && !useGlobalOpacity)
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader;
}
diff --git a/src/gui/opengl/qopenglengineshadermanager_p.h b/src/gui/opengl/qopenglengineshadermanager_p.h
index 377501457d..d43788d777 100644
--- a/src/gui/opengl/qopenglengineshadermanager_p.h
+++ b/src/gui/opengl/qopenglengineshadermanager_p.h
@@ -281,12 +281,8 @@ public:
AffinePositionWithTextureBrushVertexShader,
// MainFragmentShader_CMO must be first in the list:
- MainFragmentShader_CMO,
- MainFragmentShader_CM,
MainFragmentShader_MO,
MainFragmentShader_M,
- MainFragmentShader_CO,
- MainFragmentShader_C,
MainFragmentShader_O,
MainFragmentShader,
MainFragmentShader_ImageArrays,
diff --git a/src/gui/opengl/qopenglengineshadersource_p.h b/src/gui/opengl/qopenglengineshadersource_p.h
index a165643839..3ac599b6c2 100644
--- a/src/gui/opengl/qopenglengineshadersource_p.h
+++ b/src/gui/opengl/qopenglengineshadersource_p.h
@@ -303,17 +303,7 @@ static const char* const qopenglslPositionWithTextureBrushVertexShader = "\n\
static const char* const qopenglslAffinePositionWithTextureBrushVertexShader
= qopenglslPositionWithTextureBrushVertexShader;
-// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
-// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
-// TODO: Special case POT textures which don't need this emulation
-static const char* const qopenglslTextureBrushSrcFragmentShader_ES = "\n\
- varying highp vec2 brushTextureCoords; \n\
- uniform sampler2D brushTexture; \n\
- lowp vec4 srcPixel() { \n\
- return texture2D(brushTexture, fract(brushTextureCoords)); \n\
- }\n";
-
-static const char* const qopenglslTextureBrushSrcFragmentShader_desktop = "\n\
+static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
@@ -403,25 +393,6 @@ static const char* const qopenglslMainFragmentShader_ImageArrays = "\n\
gl_FragColor = srcPixel() * opacity; \n\
}\n";
-static const char* const qopenglslMainFragmentShader_CMO = "\n\
- uniform lowp float globalOpacity; \n\
- lowp vec4 srcPixel(); \n\
- lowp vec4 applyMask(lowp vec4); \n\
- lowp vec4 compose(lowp vec4); \n\
- void main() \n\
- { \n\
- gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\
- }\n";
-
-static const char* const qopenglslMainFragmentShader_CM = "\n\
- lowp vec4 srcPixel(); \n\
- lowp vec4 applyMask(lowp vec4); \n\
- lowp vec4 compose(lowp vec4); \n\
- void main() \n\
- { \n\
- gl_FragColor = applyMask(compose(srcPixel())); \n\
- }\n";
-
static const char* const qopenglslMainFragmentShader_MO = "\n\
uniform lowp float globalOpacity; \n\
lowp vec4 srcPixel(); \n\
@@ -439,23 +410,6 @@ static const char* const qopenglslMainFragmentShader_M = "\n\
gl_FragColor = applyMask(srcPixel()); \n\
}\n";
-static const char* const qopenglslMainFragmentShader_CO = "\n\
- uniform lowp float globalOpacity; \n\
- lowp vec4 srcPixel(); \n\
- lowp vec4 compose(lowp vec4); \n\
- void main() \n\
- { \n\
- gl_FragColor = compose(srcPixel()*globalOpacity); \n\
- }\n";
-
-static const char* const qopenglslMainFragmentShader_C = "\n\
- lowp vec4 srcPixel(); \n\
- lowp vec4 compose(lowp vec4); \n\
- void main() \n\
- { \n\
- gl_FragColor = compose(srcPixel()); \n\
- }\n";
-
static const char* const qopenglslMainFragmentShader_O = "\n\
uniform lowp float globalOpacity; \n\
lowp vec4 srcPixel(); \n\
@@ -513,22 +467,65 @@ static const char* const qopenglslRgbMaskFragmentShaderPass2 = "\n\
return src * mask; \n\
}\n";
+static const char* const qopenglslMultiplyCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_multiply) out;\n\
+ #endif\n";
+
+static const char* const qopenglslScreenCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_screen) out;\n\
+ #endif\n";
+
+static const char* const qopenglslOverlayCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_overlay) out;\n\
+ #endif\n";
+
+static const char* const qopenglslDarkenCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_darken) out;\n\
+ #endif\n";
+
+static const char* const qopenglslLightenCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_lighten) out;\n\
+ #endif\n";
+
+static const char* const qopenglslColorDodgeCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_colordodge) out;\n\
+ #endif\n";
+
+static const char* const qopenglslColorBurnCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_colorburn) out;\n\
+ #endif\n";
+
+static const char* const qopenglslHardLightCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_hardlight) out;\n\
+ #endif\n";
+
+static const char* const qopenglslSoftLightCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_softlight) out;\n\
+ #endif\n";
+
+static const char* const qopenglslDifferenceCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_difference) out;\n\
+ #endif\n";
+
+static const char* const qopenglslExclusionCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_exclusion) out;\n\
+ #endif\n";
+
/*
Left to implement:
RgbMaskFragmentShader,
RgbMaskWithGammaFragmentShader,
-
- MultiplyCompositionModeFragmentShader,
- ScreenCompositionModeFragmentShader,
- OverlayCompositionModeFragmentShader,
- DarkenCompositionModeFragmentShader,
- LightenCompositionModeFragmentShader,
- ColorDodgeCompositionModeFragmentShader,
- ColorBurnCompositionModeFragmentShader,
- HardLightCompositionModeFragmentShader,
- SoftLightCompositionModeFragmentShader,
- DifferenceCompositionModeFragmentShader,
- ExclusionCompositionModeFragmentShader,
*/
/*
@@ -788,7 +785,7 @@ static const char* const qopenglslPositionWithTextureBrushVertexShader_core = "\
static const char* const qopenglslAffinePositionWithTextureBrushVertexShader_core
= qopenglslPositionWithTextureBrushVertexShader_core;
-static const char* const qopenglslTextureBrushSrcFragmentShader_desktop_core = "\n\
+static const char* const qopenglslTextureBrushSrcFragmentShader_core = "\n\
in vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
vec4 srcPixel() \n\
@@ -880,29 +877,6 @@ static const char* const qopenglslMainFragmentShader_ImageArrays_core =
fragColor = srcPixel() * opacity; \n\
}\n";
-static const char* const qopenglslMainFragmentShader_CMO_core =
- "#version 150 core\n\
- out vec4 fragColor; \n\
- uniform float globalOpacity; \n\
- vec4 srcPixel(); \n\
- vec4 applyMask(vec4); \n\
- vec4 compose(vec4); \n\
- void main() \n\
- { \n\
- fragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\
- }\n";
-
-static const char* const qopenglslMainFragmentShader_CM_core =
- "#version 150 core\n\
- out vec4 fragColor; \n\
- vec4 srcPixel(); \n\
- vec4 applyMask(vec4); \n\
- vec4 compose(vec4); \n\
- void main() \n\
- { \n\
- fragColor = applyMask(compose(srcPixel())); \n\
- }\n";
-
static const char* const qopenglslMainFragmentShader_MO_core =
"#version 150 core\n\
out vec4 fragColor; \n\
@@ -924,27 +898,6 @@ static const char* const qopenglslMainFragmentShader_M_core =
fragColor = applyMask(srcPixel()); \n\
}\n";
-static const char* const qopenglslMainFragmentShader_CO_core =
- "#version 150 core\n\
- out vec4 fragColor; \n\
- uniform float globalOpacity; \n\
- vec4 srcPixel(); \n\
- vec4 compose(vec4); \n\
- void main() \n\
- { \n\
- fragColor = compose(srcPixel()*globalOpacity); \n\
- }\n";
-
-static const char* const qopenglslMainFragmentShader_C_core =
- "#version 150 core\n\
- out vec4 fragColor; \n\
- vec4 srcPixel(); \n\
- vec4 compose(vec4); \n\
- void main() \n\
- { \n\
- fragColor = compose(srcPixel()); \n\
- }\n";
-
static const char* const qopenglslMainFragmentShader_O_core =
"#version 150 core\n\
out vec4 fragColor; \n\
@@ -1010,18 +963,6 @@ static const char* const qopenglslRgbMaskFragmentShaderPass2_core = "\n\
Left to implement:
RgbMaskFragmentShader_core,
RgbMaskWithGammaFragmentShader_core,
-
- MultiplyCompositionModeFragmentShader_core,
- ScreenCompositionModeFragmentShader_core,
- OverlayCompositionModeFragmentShader_core,
- DarkenCompositionModeFragmentShader_core,
- LightenCompositionModeFragmentShader_core,
- ColorDodgeCompositionModeFragmentShader_core,
- ColorBurnCompositionModeFragmentShader_core,
- HardLightCompositionModeFragmentShader_core,
- SoftLightCompositionModeFragmentShader_core,
- DifferenceCompositionModeFragmentShader_core,
- ExclusionCompositionModeFragmentShader_core,
*/
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h
index a5f1a2cc88..af8ee8201d 100644
--- a/src/gui/opengl/qopenglextensions_p.h
+++ b/src/gui/opengl/qopenglextensions_p.h
@@ -90,7 +90,8 @@ public:
MapBufferRange = 0x00100000,
Sized8Formats = 0x00200000,
DiscardFramebuffer = 0x00400000,
- Sized16Formats = 0x00800000
+ Sized16Formats = 0x00800000,
+ TextureSwizzle = 0x01000000,
};
Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension)
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 83bc568ba7..cae3d516c4 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -110,6 +110,10 @@ QT_BEGIN_NAMESPACE
#define GL_RGB10 0x8052
#endif
+#ifndef GL_RGB16
+#define GL_RGB16 0x8054
+#endif
+
#ifndef GL_RGBA8
#define GL_RGBA8 0x8058
#endif
@@ -118,6 +122,10 @@ QT_BEGIN_NAMESPACE
#define GL_RGB10_A2 0x8059
#endif
+#ifndef GL_RGBA16
+#define GL_RGBA16 0x805B
+#endif
+
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
@@ -134,6 +142,15 @@ QT_BEGIN_NAMESPACE
#define GL_CONTEXT_LOST 0x0507
#endif
+#ifndef GL_DEPTH_STENCIL_ATTACHMENT
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#endif
+
+#ifndef GL_DEPTH_STENCIL
+#define GL_DEPTH_STENCIL 0x84F9
+#endif
+
+
/*!
\class QOpenGLFramebufferObjectFormat
@@ -530,6 +547,8 @@ void QOpenGLFramebufferObjectPrivate::initTexture(int idx)
GLuint pixelType = GL_UNSIGNED_BYTE;
if (color.internalFormat == GL_RGB10_A2 || color.internalFormat == GL_RGB10)
pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ else if (color.internalFormat == GL_RGB16 || color.internalFormat == GL_RGBA16)
+ pixelType = GL_UNSIGNED_SHORT;
funcs.glTexImage2D(target, 0, color.internalFormat, color.size.width(), color.size.height(), 0,
GL_RGBA, pixelType, NULL);
@@ -567,11 +586,16 @@ void QOpenGLFramebufferObjectPrivate::initColorBuffer(int idx, GLint *samples)
GLenum storageFormat = color.internalFormat;
// ES requires a sized format. The older desktop extension does not. Correct the format on ES.
- if (ctx->isOpenGLES() && color.internalFormat == GL_RGBA) {
- if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats))
- storageFormat = GL_RGBA8;
- else
- storageFormat = GL_RGBA4;
+ if (ctx->isOpenGLES()) {
+ if (color.internalFormat == GL_RGBA) {
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats))
+ storageFormat = GL_RGBA8;
+ else
+ storageFormat = GL_RGBA4;
+ } else if (color.internalFormat == GL_RGB10) {
+ // GL_RGB10 is not allowed in ES for glRenderbufferStorage.
+ storageFormat = GL_RGB10_A2;
+ }
}
funcs.glGenRenderbuffers(1, &color_buffer);
@@ -603,7 +627,11 @@ void QOpenGLFramebufferObjectPrivate::initDepthStencilAttachments(QOpenGLContext
// free existing attachments
if (depth_buffer_guard) {
+#ifdef Q_OS_WASM
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+#else
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+#endif
depth_buffer_guard->free();
}
if (stencil_buffer_guard) {
@@ -621,7 +649,35 @@ void QOpenGLFramebufferObjectPrivate::initDepthStencilAttachments(QOpenGLContext
// In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
// separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer
// might not be supported while separate buffers are, according to QTBUG-12861.
+#ifdef Q_OS_WASM
+ // WebGL doesn't allow separately attach buffers to
+ // STENCIL_ATTACHMENT and DEPTH_ATTACHMENT
+ // QTBUG-69913
+ if (attachment == QOpenGLFramebufferObject::CombinedDepthStencil) {
+ funcs.glGenRenderbuffers(1, &depth_buffer);
+ funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
+ Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
+ GLenum storageFormat = GL_DEPTH_STENCIL;
+
+ if (samples != 0 ) {
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ storageFormat, dsSize.width(), dsSize.height());
+ } else {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, storageFormat,
+ dsSize.width(), dsSize.height());
+ }
+
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, depth_buffer);
+
+ valid = checkFramebufferStatus(ctx);
+ if (!valid) {
+ funcs.glDeleteRenderbuffers(1, &depth_buffer);
+ depth_buffer = 0;
+ }
+ }
+#else
if (attachment == QOpenGLFramebufferObject::CombinedDepthStencil
&& funcs.hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil))
{
@@ -713,11 +769,16 @@ void QOpenGLFramebufferObjectPrivate::initDepthStencilAttachments(QOpenGLContext
stencil_buffer = 0;
}
}
+#endif //Q_OS_WASM
// The FBO might have become valid after removing the depth or stencil buffer.
valid = checkFramebufferStatus(ctx);
+#ifdef Q_OS_WASM
+ if (depth_buffer) {
+#else
if (depth_buffer && stencil_buffer) {
+#endif
fbo_attachment = QOpenGLFramebufferObject::CombinedDepthStencil;
} else if (depth_buffer) {
fbo_attachment = QOpenGLFramebufferObject::Depth;
@@ -1307,6 +1368,14 @@ static inline QImage qt_gl_read_framebuffer_rgb10a2(const QSize &size, bool incl
return img;
}
+static inline QImage qt_gl_read_framebuffer_rgba16(const QSize &size, bool include_alpha, QOpenGLContext *context)
+{
+ // We assume OpenGL 1.2+ or ES 3.0+ here.
+ QImage img(size, include_alpha ? QImage::Format_RGBA64_Premultiplied : QImage::Format_RGBX64);
+ context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_SHORT, img.bits());
+ return img;
+}
+
static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format, bool include_alpha, bool flip)
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
@@ -1324,6 +1393,10 @@ static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format,
return qt_gl_read_framebuffer_rgb10a2(size, false, ctx).mirrored(false, flip);
case GL_RGB10_A2:
return qt_gl_read_framebuffer_rgb10a2(size, include_alpha, ctx).mirrored(false, flip);
+ case GL_RGB16:
+ return qt_gl_read_framebuffer_rgba16(size, false, ctx).mirrored(false, flip);
+ case GL_RGBA16:
+ return qt_gl_read_framebuffer_rgba16(size, include_alpha, ctx).mirrored(false, flip);
case GL_RGBA:
case GL_RGBA8:
default:
@@ -1352,7 +1425,8 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
is used only when internalTextureFormat() is set to \c GL_RGB. Since Qt 5.2
the function will fall back to premultiplied RGBA8888 or RGBx8888 when
reading to (A)RGB32 is not supported, and this includes OpenGL ES. Since Qt
- 5.4 an A2BGR30 image is returned if the internal format is RGB10_A2.
+ 5.4 an A2BGR30 image is returned if the internal format is RGB10_A2, and since
+ Qt 5.12 a RGBA64 image is return if the internal format is RGBA16.
If the rendering in the framebuffer was not done with premultiplied alpha in mind,
create a wrapper QImage with a non-premultiplied format. This is necessary before
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 977565516f..4f48604a88 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -45,6 +45,7 @@
#include <QtGui/private/qopengl_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformnativeinterface.h>
#ifdef Q_OS_INTEGRITY
#include <EGL/egl.h>
@@ -294,9 +295,19 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
static int qt_gl_resolve_features()
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLExtensionMatcher extensions;
+ int features = 0;
+ if ((extensions.match("GL_KHR_blend_equation_advanced")
+ || extensions.match("GL_NV_blend_equation_advanced")) &&
+ (extensions.match("GL_KHR_blend_equation_advanced_coherent")
+ || extensions.match("GL_NV_blend_equation_advanced_coherent"))) {
+ // We need both the advanced equations and the coherency for us
+ // to be able to easily use the new blend equations
+ features |= QOpenGLFunctions::BlendEquationAdvanced;
+ }
if (ctx->isOpenGLES()) {
// OpenGL ES
- int features = QOpenGLFunctions::Multitexture |
+ features |= QOpenGLFunctions::Multitexture |
QOpenGLFunctions::Shaders |
QOpenGLFunctions::Buffers |
QOpenGLFunctions::Framebuffers |
@@ -308,7 +319,6 @@ static int qt_gl_resolve_features()
QOpenGLFunctions::CompressedTextures |
QOpenGLFunctions::Multisample |
QOpenGLFunctions::StencilSeparate;
- QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_IMG_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures;
if (extensions.match("GL_OES_texture_npot"))
@@ -320,14 +330,18 @@ static int qt_gl_resolve_features()
if (!(renderer && strstr(renderer, "Mesa")))
features |= QOpenGLFunctions::TextureRGFormats;
}
- if (ctx->format().majorVersion() >= 3)
+ if (ctx->format().majorVersion() >= 3) {
features |= QOpenGLFunctions::MultipleRenderTargets;
+ if (ctx->format().minorVersion() >= 2 && extensions.match("GL_KHR_blend_equation_advanced_coherent")) {
+ // GL_KHR_blend_equation_advanced is included in OpenGL ES/3.2
+ features |= QOpenGLFunctions::BlendEquationAdvanced;
+ }
+ }
return features;
} else {
// OpenGL
- int features = QOpenGLFunctions::TextureRGFormats;
+ features |= QOpenGLFunctions::TextureRGFormats;
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
- QOpenGLExtensionMatcher extensions;
if (format.majorVersion() >= 3)
features |= QOpenGLFunctions::Framebuffers | QOpenGLFunctions::MultipleRenderTargets;
@@ -411,6 +425,8 @@ static int qt_gl_resolve_extensions()
extensions |= QOpenGLExtensions::NVFloatBuffer;
if (extensionMatcher.match("GL_ARB_pixel_buffer_object"))
extensions |= QOpenGLExtensions::PixelBufferObject;
+ if (extensionMatcher.match("GL_ARB_texture_swizzle") || extensionMatcher.match("GL_EXT_texture_swizzle"))
+ extensions |= QOpenGLExtensions::TextureSwizzle;
if (ctx->isOpenGLES()) {
if (format.majorVersion() >= 2)
@@ -423,7 +439,8 @@ static int qt_gl_resolve_extensions()
| QOpenGLExtensions::MapBufferRange
| QOpenGLExtensions::FramebufferBlit
| QOpenGLExtensions::FramebufferMultisample
- | QOpenGLExtensions::Sized8Formats;
+ | QOpenGLExtensions::Sized8Formats
+ | QOpenGLExtensions::TextureSwizzle;
} else {
// Recognize features by extension name.
if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
@@ -449,6 +466,17 @@ static int qt_gl_resolve_extensions()
// We don't match GL_APPLE_texture_format_BGRA8888 here because it has different semantics.
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+ QString *deviceName =
+ static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName"));
+ static bool wrongfullyReportsBgra8888Support = deviceName != 0
+ && (deviceName->compare(QLatin1String("samsung SM-T211"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QLatin1String("samsung SM-T210"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QLatin1String("samsung SM-T215"), Qt::CaseInsensitive) == 0);
+ if (wrongfullyReportsBgra8888Support)
+ extensions &= ~QOpenGLExtensions::BGRATextureFormat;
+#endif
+
if (extensionMatcher.match("GL_EXT_discard_framebuffer"))
extensions |= QOpenGLExtensions::DiscardFramebuffer;
if (extensionMatcher.match("GL_EXT_texture_norm16"))
@@ -482,6 +510,9 @@ static int qt_gl_resolve_extensions()
if (format.version() >= qMakePair(3, 2) || extensionMatcher.match("GL_ARB_geometry_shader4"))
extensions |= QOpenGLExtensions::GeometryShaders;
+ if (format.version() >= qMakePair(3, 3))
+ extensions |= QOpenGLExtensions::TextureSwizzle;
+
if (extensionMatcher.match("GL_ARB_map_buffer_range"))
extensions |= QOpenGLExtensions::MapBufferRange;
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index 1a43f13d9b..00287b0665 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -277,7 +277,8 @@ public:
NPOTTextureRepeat = 0x2000,
FixedFunctionPipeline = 0x4000,
TextureRGFormats = 0x8000,
- MultipleRenderTargets = 0x10000
+ MultipleRenderTargets = 0x10000,
+ BlendEquationAdvanced = 0x20000,
};
Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature)
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index 6a89089f18..001cb839fa 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -87,8 +87,27 @@
#include <QDebug>
-QT_BEGIN_NAMESPACE
+#ifndef GL_KHR_blend_equation_advanced
+#define GL_KHR_blend_equation_advanced 1
+#define GL_MULTIPLY_KHR 0x9294
+#define GL_SCREEN_KHR 0x9295
+#define GL_OVERLAY_KHR 0x9296
+#define GL_DARKEN_KHR 0x9297
+#define GL_LIGHTEN_KHR 0x9298
+#define GL_COLORDODGE_KHR 0x9299
+#define GL_COLORBURN_KHR 0x929A
+#define GL_HARDLIGHT_KHR 0x929B
+#define GL_SOFTLIGHT_KHR 0x929C
+#define GL_DIFFERENCE_KHR 0x929E
+#define GL_EXCLUSION_KHR 0x92A0
+#endif /* GL_KHR_blend_equation_advanced */
+
+#ifndef GL_KHR_blend_equation_advanced_coherent
+#define GL_KHR_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285
+#endif /* GL_KHR_blend_equation_advanced_coherent */
+QT_BEGIN_NAMESPACE
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
@@ -244,7 +263,7 @@ GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient)
struct ImageWithBindOptions
{
const QImage &image;
- QOpenGLTextureCache::BindOptions options;
+ QOpenGLTextureUploader::BindOptions options;
};
template<>
@@ -253,6 +272,12 @@ GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const ImageWithBindOptions &ima
return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, imageWithOptions.image, imageWithOptions.options);
}
+inline static bool isPowerOfTwo(int x)
+{
+ // Assumption: x >= 1
+ return x == (x & -x);
+}
+
void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
{
Q_Q(QOpenGL2PaintEngineEx);
@@ -285,16 +310,18 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
currentBrushImage = currentBrush.textureImage();
int max_texture_size = ctx->d_func()->maxTextureSize();
- if (currentBrushImage.width() > max_texture_size || currentBrushImage.height() > max_texture_size)
- currentBrushImage = currentBrushImage.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
+ QSize newSize = currentBrushImage.size();
+ newSize = newSize.boundedTo(QSize(max_texture_size, max_texture_size));
+ if (!QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat)) {
+ if (!isPowerOfTwo(newSize.width()) || !isPowerOfTwo(newSize.height())) {
+ newSize.setHeight(qNextPowerOfTwo(newSize.height() - 1));
+ newSize.setWidth(qNextPowerOfTwo(newSize.width() - 1));
+ }
+ }
+ if (currentBrushImage.size() != newSize)
+ currentBrushImage = currentBrushImage.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
GLuint wrapMode = GL_REPEAT;
- if (QOpenGLContext::currentContext()->isOpenGLES()) {
- // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
- // we emulate GL_REPEAT by only taking the fractional part of the texture coords
- // in the qopenglslTextureBrushSrcFragmentShader program.
- wrapMode = GL_CLAMP_TO_EDGE;
- }
updateTexture(QT_BRUSH_TEXTURE_UNIT, currentBrushImage, wrapMode, filterMode, ForceUpdate);
}
@@ -498,6 +525,21 @@ void QOpenGL2PaintEngineExPrivate::updateCompositionMode()
// NOTE: The entire paint engine works on pre-multiplied data - which is why some of these
// composition modes look odd.
// qDebug() << "QOpenGL2PaintEngineExPrivate::updateCompositionMode() - Setting GL composition mode for " << q->state()->composition_mode;
+ if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::BlendEquationAdvanced)) {
+ if (q->state()->composition_mode <= QPainter::CompositionMode_Plus) {
+ funcs.glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
+ funcs.glBlendEquation(GL_FUNC_ADD);
+ } else {
+ funcs.glEnable(GL_BLEND_ADVANCED_COHERENT_KHR);
+ }
+ shaderManager->setCompositionMode(q->state()->composition_mode);
+ } else {
+ if (q->state()->composition_mode > QPainter::CompositionMode_Plus) {
+ qWarning("Unsupported composition mode");
+ compositionModeDirty = false;
+ return;
+ }
+ }
switch(q->state()->composition_mode) {
case QPainter::CompositionMode_SourceOver:
funcs.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -538,6 +580,39 @@ void QOpenGL2PaintEngineExPrivate::updateCompositionMode()
case QPainter::CompositionMode_Plus:
funcs.glBlendFunc(GL_ONE, GL_ONE);
break;
+ case QPainter::CompositionMode_Multiply:
+ funcs.glBlendEquation(GL_MULTIPLY_KHR);
+ break;
+ case QPainter::CompositionMode_Screen:
+ funcs.glBlendEquation(GL_SCREEN_KHR);
+ break;
+ case QPainter::CompositionMode_Overlay:
+ funcs.glBlendEquation(GL_OVERLAY_KHR);
+ break;
+ case QPainter::CompositionMode_Darken:
+ funcs.glBlendEquation(GL_DARKEN_KHR);
+ break;
+ case QPainter::CompositionMode_Lighten:
+ funcs.glBlendEquation(GL_LIGHTEN_KHR);
+ break;
+ case QPainter::CompositionMode_ColorDodge:
+ funcs.glBlendEquation(GL_COLORDODGE_KHR);
+ break;
+ case QPainter::CompositionMode_ColorBurn:
+ funcs.glBlendEquation(GL_COLORBURN_KHR);
+ break;
+ case QPainter::CompositionMode_HardLight:
+ funcs.glBlendEquation(GL_HARDLIGHT_KHR);
+ break;
+ case QPainter::CompositionMode_SoftLight:
+ funcs.glBlendEquation(GL_SOFTLIGHT_KHR);
+ break;
+ case QPainter::CompositionMode_Difference:
+ funcs.glBlendEquation(GL_DIFFERENCE_KHR);
+ break;
+ case QPainter::CompositionMode_Exclusion:
+ funcs.glBlendEquation(GL_EXCLUSION_KHR);
+ break;
default:
qWarning("Unsupported composition mode");
break;
@@ -1487,25 +1562,26 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c
ensureActive();
d->transferMode(ImageDrawingMode);
- QOpenGLTextureCache::BindOptions bindOption = QOpenGLTextureCache::PremultipliedAlphaBindOption;
+ QOpenGLTextureUploader::BindOptions bindOption = QOpenGLTextureUploader::PremultipliedAlphaBindOption;
// Use specialized bind for formats we have specialized shaders for.
switch (image.format()) {
case QImage::Format_RGBA8888:
case QImage::Format_ARGB32:
+ case QImage::Format_RGBA64:
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::NonPremultipliedImageSrc);
bindOption = 0;
break;
case QImage::Format_Alpha8:
if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats)) {
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::AlphaImageSrc);
- bindOption = QOpenGLTextureCache::UseRedFor8BitBindOption;
+ bindOption = QOpenGLTextureUploader::UseRedFor8BitBindOption;
} else
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
break;
case QImage::Format_Grayscale8:
if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats)) {
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::GrayscaleImageSrc);
- bindOption = QOpenGLTextureCache::UseRedFor8BitBindOption;
+ bindOption = QOpenGLTextureUploader::UseRedFor8BitBindOption;
} else
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
break;
diff --git a/src/gui/opengl/qopenglprogrambinarycache.cpp b/src/gui/opengl/qopenglprogrambinarycache.cpp
index d16173df83..0f03101329 100644
--- a/src/gui/opengl/qopenglprogrambinarycache.cpp
+++ b/src/gui/opengl/qopenglprogrambinarycache.cpp
@@ -54,6 +54,10 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(DBG_SHADER_CACHE)
+#ifndef GL_CONTEXT_LOST
+#define GL_CONTEXT_LOST 0x0507
+#endif
+
#ifndef GL_PROGRAM_BINARY_LENGTH
#define GL_PROGRAM_BINARY_LENGTH 0x8741
#endif
@@ -62,6 +66,7 @@ const quint32 BINSHADER_MAGIC = 0x5174;
const quint32 BINSHADER_VERSION = 0x2;
const quint32 BINSHADER_QTVERSION = QT_VERSION;
+namespace {
struct GLEnvInfo
{
GLEnvInfo();
@@ -70,6 +75,7 @@ struct GLEnvInfo
QByteArray glrenderer;
QByteArray glversion;
};
+}
GLEnvInfo::GLEnvInfo()
{
@@ -159,7 +165,11 @@ bool QOpenGLProgramBinaryCache::verifyHeader(const QByteArray &buf) const
bool QOpenGLProgramBinaryCache::setProgramBinary(uint programId, uint blobFormat, const void *p, uint blobSize)
{
QOpenGLExtraFunctions *funcs = QOpenGLContext::currentContext()->extraFunctions();
- while (funcs->glGetError() != GL_NO_ERROR) { }
+ while (true) {
+ GLenum error = funcs->glGetError();
+ if (error == GL_NO_ERROR || error == GL_CONTEXT_LOST)
+ break;
+ }
funcs->glProgramBinary(programId, blobFormat, p, blobSize);
GLenum err = funcs->glGetError();
@@ -335,7 +345,11 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId)
QOpenGLExtraFunctions *funcs = QOpenGLContext::currentContext()->extraFunctions();
GLint blobSize = 0;
- while (funcs->glGetError() != GL_NO_ERROR) { }
+ while (true) {
+ GLenum error = funcs->glGetError();
+ if (error == GL_NO_ERROR || error == GL_CONTEXT_LOST)
+ break;
+ }
funcs->glGetProgramiv(programId, GL_PROGRAM_BINARY_LENGTH, &blobSize);
const int headerSize = FULL_HEADER_SIZE(info.glvendor.size() + info.glrenderer.size() + info.glversion.size());
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index 2ae9c6d327..6d7aecac6f 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -496,6 +496,13 @@ static const char redefineHighp[] =
"#endif\n";
#endif
+// Boiler-plate header to have the layout attributes available we need later
+static const char blendEquationAdvancedHeader[] =
+ "#ifdef GL_KHR_blend_equation_advanced\n"
+ "#extension GL_ARB_fragment_coord_conventions : enable\n"
+ "#extension GL_KHR_blend_equation_advanced : enable\n"
+ "#endif\n";
+
struct QVersionDirectivePosition
{
Q_DECL_CONSTEXPR QVersionDirectivePosition(int position = 0, int line = -1)
@@ -636,6 +643,10 @@ bool QOpenGLShader::compileSourceCode(const char *source)
}
}
}
+ if (d->shaderType == Fragment) {
+ sourceChunks.append(blendEquationAdvancedHeader);
+ sourceChunkLengths.append(GLint(sizeof(blendEquationAdvancedHeader) - 1));
+ }
// The precision qualifiers are useful on OpenGL/ES systems,
// but usually not present on desktop systems.
diff --git a/src/gui/opengl/qopengltexturecache.cpp b/src/gui/opengl/qopengltexturecache.cpp
index 27aa8db33a..8de0b25fee 100644
--- a/src/gui/opengl/qopengltexturecache.cpp
+++ b/src/gui/opengl/qopengltexturecache.cpp
@@ -38,39 +38,14 @@
****************************************************************************/
#include "qopengltexturecache_p.h"
+#include "qopengltextureuploader_p.h"
#include <qmath.h>
#include <qopenglfunctions.h>
-#include <private/qopenglcontext_p.h>
-#include <private/qopenglextensions_p.h>
#include <private/qimagepixmapcleanuphooks_p.h>
#include <qpa/qplatformpixmap.h>
QT_BEGIN_NAMESPACE
-#ifndef GL_RED
-#define GL_RED 0x1903
-#endif
-
-#ifndef GL_RGB10_A2
-#define GL_RGB10_A2 0x8059
-#endif
-
-#ifndef GL_BGR
-#define GL_BGR 0x80E0
-#endif
-
-#ifndef GL_BGRA
-#define GL_BGRA 0x80E1
-#endif
-
-#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
-#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
-#endif
-
-#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
-#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
-#endif
-
class QOpenGLTextureCacheWrapper
{
public:
@@ -130,7 +105,7 @@ QOpenGLTextureCache::~QOpenGLTextureCache()
{
}
-GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap &pixmap, BindOptions options)
+GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap &pixmap, QOpenGLTextureUploader::BindOptions options)
{
if (pixmap.isNull())
return 0;
@@ -153,7 +128,7 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap &
return id;
}
-GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &image, BindOptions options)
+GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &image, QOpenGLTextureUploader::BindOptions options)
{
if (image.isNull())
return 0;
@@ -170,16 +145,8 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i
}
QImage img = image;
- if (!context->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)) {
- // Scale the pixmap if needed. GL textures needs to have the
- // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL
- // 2.0 or use the GL_TEXTURE_RECTANGLE texture target
- int tx_w = qNextPowerOfTwo(image.width() - 1);
- int tx_h = qNextPowerOfTwo(image.height() - 1);
- if (tx_w != image.width() || tx_h != image.height()) {
- img = img.scaled(tx_w, tx_h);
- }
- }
+ if (!context->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures))
+ options |= QOpenGLTextureUploader::PowerOfTwoBindOption;
GLuint id = bindTexture(context, key, img, options);
if (id > 0)
@@ -188,164 +155,16 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i
return id;
}
-GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, const QImage &image, BindOptions options)
+GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, const QImage &image, QOpenGLTextureUploader::BindOptions options)
{
GLuint id;
QOpenGLFunctions *funcs = context->functions();
funcs->glGenTextures(1, &id);
funcs->glBindTexture(GL_TEXTURE_2D, id);
- QImage tx;
- GLenum externalFormat;
- GLenum internalFormat;
- GLuint pixelType;
- QImage::Format targetFormat = QImage::Format_Invalid;
- const bool isOpenGL12orBetter = !context->isOpenGLES() && (context->format().majorVersion() >= 2 || context->format().minorVersion() >= 2);
-
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- if (isOpenGL12orBetter) {
- externalFormat = GL_BGRA;
- internalFormat = GL_RGBA;
- pixelType = GL_UNSIGNED_INT_8_8_8_8_REV;
- } else {
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- // Without GL_UNSIGNED_INT_8_8_8_8_REV, BGRA only matches ARGB on little endian.
- break;
-#endif
- if (static_cast<QOpenGLExtensions*>(context->functions())->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat)) {
- // GL_EXT_bgra or GL_EXT_texture_format_BGRA8888 extensions.
- if (context->isOpenGLES()) {
- // The GL_EXT_texture_format_BGRA8888 extension requires the internal format to match the external.
- externalFormat = internalFormat = GL_BGRA;
- } else {
- // OpenGL BGRA/BGR format is not allowed as an internal format
- externalFormat = GL_BGRA;
- internalFormat = GL_RGBA;
- }
- pixelType = GL_UNSIGNED_BYTE;
- } else if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_APPLE_texture_format_BGRA8888"))) {
- // Is only allowed as an external format like OpenGL.
- externalFormat = GL_BGRA;
- internalFormat = GL_RGBA;
- pixelType = GL_UNSIGNED_BYTE;
- } else {
- // No support for direct ARGB32 upload.
- break;
- }
- }
- targetFormat = image.format();
- break;
- case QImage::Format_BGR30:
- case QImage::Format_A2BGR30_Premultiplied:
- if (isOpenGL12orBetter || (context->isOpenGLES() && context->format().majorVersion() >= 3)) {
- pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
- externalFormat = GL_RGBA;
- internalFormat = GL_RGB10_A2;
- targetFormat = image.format();
- }
- break;
- case QImage::Format_RGB30:
- case QImage::Format_A2RGB30_Premultiplied:
- if (isOpenGL12orBetter) {
- pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
- externalFormat = GL_BGRA;
- internalFormat = GL_RGB10_A2;
- targetFormat = image.format();
- } else if (context->isOpenGLES() && context->format().majorVersion() >= 3) {
- pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
- externalFormat = GL_RGBA;
- internalFormat = GL_RGB10_A2;
- targetFormat = QImage::Format_A2BGR30_Premultiplied;
- }
- break;
- case QImage::Format_RGB444:
- case QImage::Format_RGB555:
- case QImage::Format_RGB16:
- if (isOpenGL12orBetter || context->isOpenGLES()) {
- externalFormat = internalFormat = GL_RGB;
- pixelType = GL_UNSIGNED_SHORT_5_6_5;
- targetFormat = QImage::Format_RGB16;
- }
- break;
- case QImage::Format_RGB666:
- case QImage::Format_RGB888:
- externalFormat = internalFormat = GL_RGB;
- pixelType = GL_UNSIGNED_BYTE;
- targetFormat = QImage::Format_RGB888;
- break;
- case QImage::Format_RGBX8888:
- case QImage::Format_RGBA8888:
- case QImage::Format_RGBA8888_Premultiplied:
- externalFormat = internalFormat = GL_RGBA;
- pixelType = GL_UNSIGNED_BYTE;
- targetFormat = image.format();
- break;
- case QImage::Format_Indexed8:
- if (options & UseRedFor8BitBindOption) {
- externalFormat = internalFormat = GL_RED;
- pixelType = GL_UNSIGNED_BYTE;
- targetFormat = image.format();
- }
- break;
- case QImage::Format_Alpha8:
- if (options & UseRedFor8BitBindOption) {
- externalFormat = internalFormat = GL_RED;
- pixelType = GL_UNSIGNED_BYTE;
- targetFormat = image.format();
- } else if (context->isOpenGLES() || context->format().profile() != QSurfaceFormat::CoreProfile) {
- externalFormat = internalFormat = GL_ALPHA;
- pixelType = GL_UNSIGNED_BYTE;
- targetFormat = image.format();
- }
- break;
- case QImage::Format_Grayscale8:
- if (options & UseRedFor8BitBindOption) {
- externalFormat = internalFormat = GL_RED;
- pixelType = GL_UNSIGNED_BYTE;
- targetFormat = image.format();
- } else if (context->isOpenGLES() || context->format().profile() != QSurfaceFormat::CoreProfile) {
- externalFormat = internalFormat = GL_LUMINANCE;
- pixelType = GL_UNSIGNED_BYTE;
- targetFormat = image.format();
- }
- break;
- default:
- break;
- }
-
- if (targetFormat == QImage::Format_Invalid) {
- externalFormat = internalFormat = GL_RGBA;
- pixelType = GL_UNSIGNED_BYTE;
- if (!image.hasAlphaChannel())
- targetFormat = QImage::Format_RGBX8888;
- else
- targetFormat = QImage::Format_RGBA8888;
- }
-
- if (options & PremultipliedAlphaBindOption) {
- if (targetFormat == QImage::Format_ARGB32)
- targetFormat = QImage::Format_ARGB32_Premultiplied;
- else if (targetFormat == QImage::Format_RGBA8888)
- targetFormat = QImage::Format_RGBA8888_Premultiplied;
- } else {
- if (targetFormat == QImage::Format_ARGB32_Premultiplied)
- targetFormat = QImage::Format_ARGB32;
- else if (targetFormat == QImage::Format_RGBA8888_Premultiplied)
- targetFormat = QImage::Format_RGBA8888;
- }
-
- if (image.format() != targetFormat)
- tx = image.convertToFormat(targetFormat);
- else
- tx = image;
-
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, tx.width(), tx.height(), 0, externalFormat, pixelType, const_cast<const QImage &>(tx).bits());
+ int cost = QOpenGLTextureUploader::textureImage(GL_TEXTURE_2D, image, options);
- int cost = tx.width() * tx.height() * tx.depth() / (1024 * 8);
- m_cache.insert(key, new QOpenGLCachedTexture(id, options, context), cost);
+ m_cache.insert(key, new QOpenGLCachedTexture(id, options, context), cost / 1024);
return id;
}
@@ -371,7 +190,7 @@ static void freeTexture(QOpenGLFunctions *funcs, GLuint id)
funcs->glDeleteTextures(1, &id);
}
-QOpenGLCachedTexture::QOpenGLCachedTexture(GLuint id, QOpenGLTextureCache::BindOptions options, QOpenGLContext *context) : m_options(options)
+QOpenGLCachedTexture::QOpenGLCachedTexture(GLuint id, QOpenGLTextureUploader::BindOptions options, QOpenGLContext *context) : m_options(options)
{
m_resource = new QOpenGLSharedResourceGuard(context, id, freeTexture);
}
diff --git a/src/gui/opengl/qopengltexturecache_p.h b/src/gui/opengl/qopengltexturecache_p.h
index b9d7df91e3..88ef06e744 100644
--- a/src/gui/opengl/qopengltexturecache_p.h
+++ b/src/gui/opengl/qopengltexturecache_p.h
@@ -56,6 +56,7 @@
#include <QObject>
#include <QCache>
#include <private/qopenglcontext_p.h>
+#include <private/qopengltextureuploader_p.h>
#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
@@ -70,15 +71,10 @@ public:
QOpenGLTextureCache(QOpenGLContext *);
~QOpenGLTextureCache();
- enum BindOption {
- NoBindOption = 0x0000,
- PremultipliedAlphaBindOption = 0x0001,
- UseRedFor8BitBindOption = 0x0002,
- };
- Q_DECLARE_FLAGS(BindOptions, BindOption)
-
- GLuint bindTexture(QOpenGLContext *context, const QPixmap &pixmap, QOpenGLTextureCache::BindOptions options = PremultipliedAlphaBindOption);
- GLuint bindTexture(QOpenGLContext *context, const QImage &image, QOpenGLTextureCache::BindOptions options = PremultipliedAlphaBindOption);
+ GLuint bindTexture(QOpenGLContext *context, const QPixmap &pixmap,
+ QOpenGLTextureUploader::BindOptions options = QOpenGLTextureUploader::PremultipliedAlphaBindOption);
+ GLuint bindTexture(QOpenGLContext *context, const QImage &image,
+ QOpenGLTextureUploader::BindOptions options = QOpenGLTextureUploader::PremultipliedAlphaBindOption);
void invalidate(qint64 key);
@@ -86,26 +82,24 @@ public:
void freeResource(QOpenGLContext *ctx) override;
private:
- GLuint bindTexture(QOpenGLContext *context, qint64 key, const QImage &image, QOpenGLTextureCache::BindOptions options);
+ GLuint bindTexture(QOpenGLContext *context, qint64 key, const QImage &image, QOpenGLTextureUploader::BindOptions options);
QMutex m_mutex;
QCache<quint64, QOpenGLCachedTexture> m_cache;
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLTextureCache::BindOptions)
-
class QOpenGLCachedTexture
{
public:
- QOpenGLCachedTexture(GLuint id, QOpenGLTextureCache::BindOptions options, QOpenGLContext *context);
+ QOpenGLCachedTexture(GLuint id, QOpenGLTextureUploader::BindOptions options, QOpenGLContext *context);
~QOpenGLCachedTexture() { m_resource->free(); }
GLuint id() const { return m_resource->id(); }
- QOpenGLTextureCache::BindOptions options() const { return m_options; }
+ QOpenGLTextureUploader::BindOptions options() const { return m_options; }
private:
QOpenGLSharedResourceGuard *m_resource;
- QOpenGLTextureCache::BindOptions m_options;
+ QOpenGLTextureUploader::BindOptions m_options;
};
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltextureuploader.cpp b/src/gui/opengl/qopengltextureuploader.cpp
new file mode 100644
index 0000000000..2428baed93
--- /dev/null
+++ b/src/gui/opengl/qopengltextureuploader.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengltextureuploader_p.h"
+
+#include <qimage.h>
+#include <qmath.h>
+#include <qopenglfunctions.h>
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglextensions_p.h>
+
+#ifndef GL_RED
+#define GL_RED 0x1903
+#endif
+
+#ifndef GL_GREEN
+#define GL_GREEN 0x1904
+#endif
+
+#ifndef GL_BLUE
+#define GL_BLUE 0x1905
+#endif
+
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif
+
+#ifndef GL_RGBA16
+#define GL_RGBA16 0x805B
+#endif
+
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
+
+#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#endif
+
+#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#endif
+
+#ifndef GL_TEXTURE_SWIZZLE_RGBA
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#endif
+
+#ifndef GL_SRGB
+#define GL_SRGB 0x8C40
+#endif
+#ifndef GL_SRGB_ALPHA
+#define GL_SRGB_ALPHA 0x8C42
+#endif
+
+QT_BEGIN_NAMESPACE
+
+qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &image, QOpenGLTextureUploader::BindOptions options, QSize maxSize)
+{
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ QOpenGLExtensions *funcs = static_cast<QOpenGLExtensions*>(context->functions());
+
+ QImage tx;
+ GLenum externalFormat;
+ GLenum internalFormat;
+ GLuint pixelType;
+ QImage::Format targetFormat = QImage::Format_Invalid;
+ const bool isOpenGL12orBetter = !context->isOpenGLES() && (context->format().majorVersion() >= 2 || context->format().minorVersion() >= 2);
+ const bool isOpenGLES3orBetter = context->isOpenGLES() && context->format().majorVersion() >= 3;
+ const bool sRgbBinding = (options & SRgbBindOption);
+ Q_ASSERT(isOpenGL12orBetter || context->isOpenGLES());
+ Q_ASSERT((options & (SRgbBindOption | UseRedFor8BitBindOption)) != (SRgbBindOption | UseRedFor8BitBindOption));
+
+ switch (image.format()) {
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
+ case QImage::Format_ARGB32_Premultiplied:
+ if (isOpenGL12orBetter) {
+ externalFormat = GL_BGRA;
+ internalFormat = GL_RGBA;
+ pixelType = GL_UNSIGNED_INT_8_8_8_8_REV;
+ } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle) && false) {
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
+ funcs->glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+#else
+ GLint swizzle[4] = { GL_GREEN, GL_BLUE, GL_ALPHA, GL_RED };
+ funcs->glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+#endif
+ externalFormat = internalFormat = GL_RGBA;
+ pixelType = GL_UNSIGNED_BYTE;
+ } else {
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ // Without GL_UNSIGNED_INT_8_8_8_8_REV, BGRA only matches ARGB on little endian.
+ if (funcs->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat) && !sRgbBinding) {
+ // The GL_EXT_texture_format_BGRA8888 extension requires the internal format to match the external.
+ externalFormat = internalFormat = GL_BGRA;
+ pixelType = GL_UNSIGNED_BYTE;
+ } else if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_APPLE_texture_format_BGRA8888"))) {
+ // Is only allowed as an external format like OpenGL.
+ externalFormat = GL_BGRA;
+ internalFormat = GL_RGBA;
+ pixelType = GL_UNSIGNED_BYTE;
+ } else {
+ // No support for direct ARGB32 upload.
+ break;
+ }
+#else
+ // Big endian requires GL_UNSIGNED_INT_8_8_8_8_REV for ARGB to match BGRA
+ break;
+#endif
+ }
+ targetFormat = image.format();
+ break;
+ case QImage::Format_BGR30:
+ case QImage::Format_A2BGR30_Premultiplied:
+ if (sRgbBinding) {
+ // Always needs conversion
+ break;
+ } else if (isOpenGL12orBetter || isOpenGLES3orBetter) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ externalFormat = GL_RGBA;
+ internalFormat = GL_RGB10_A2;
+ targetFormat = image.format();
+ }
+ break;
+ case QImage::Format_RGB30:
+ case QImage::Format_A2RGB30_Premultiplied:
+ if (sRgbBinding) {
+ // Always needs conversion
+ break;
+ } else if (isOpenGL12orBetter) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ externalFormat = GL_BGRA;
+ internalFormat = GL_RGB10_A2;
+ targetFormat = image.format();
+ } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle) && (isOpenGL12orBetter || isOpenGLES3orBetter)) {
+ pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ externalFormat = GL_RGBA;
+ internalFormat = GL_RGB10_A2;
+ GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
+ funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+ targetFormat = image.format();
+ }
+ break;
+ case QImage::Format_RGB444:
+ case QImage::Format_RGB555:
+ case QImage::Format_RGB16:
+ if (isOpenGL12orBetter || context->isOpenGLES()) {
+ externalFormat = internalFormat = GL_RGB;
+ pixelType = GL_UNSIGNED_SHORT_5_6_5;
+ targetFormat = QImage::Format_RGB16;
+ }
+ break;
+ case QImage::Format_RGB666:
+ case QImage::Format_RGB888:
+ externalFormat = internalFormat = GL_RGB;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = QImage::Format_RGB888;
+ break;
+ case QImage::Format_RGBX8888:
+ case QImage::Format_RGBA8888:
+ case QImage::Format_RGBA8888_Premultiplied:
+ externalFormat = internalFormat = GL_RGBA;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = image.format();
+ break;
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
+ externalFormat = internalFormat = GL_RGBA;
+ if (isOpenGL12orBetter || (context->isOpenGLES() && context->format().majorVersion() >= 3))
+ internalFormat = GL_RGBA16;
+ pixelType = GL_UNSIGNED_SHORT;
+ targetFormat = image.format();
+ break;
+ case QImage::Format_Indexed8:
+ if (sRgbBinding) {
+ // Always needs conversion
+ break;
+ } else if (options & UseRedFor8BitBindOption) {
+ externalFormat = internalFormat = GL_RED;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = image.format();
+ }
+ break;
+ case QImage::Format_Alpha8:
+ if (sRgbBinding) {
+ // Always needs conversion
+ break;
+ } else if (options & UseRedFor8BitBindOption) {
+ externalFormat = internalFormat = GL_RED;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = image.format();
+ } else if (context->isOpenGLES() || context->format().profile() != QSurfaceFormat::CoreProfile) {
+ externalFormat = internalFormat = GL_ALPHA;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = image.format();
+ } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
+ GLint swizzle[4] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED };
+ funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+ externalFormat = internalFormat = GL_RED;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = image.format();
+ }
+ break;
+ case QImage::Format_Grayscale8:
+ if (sRgbBinding) {
+ // Always needs conversion
+ break;
+ } else if (options & UseRedFor8BitBindOption) {
+ externalFormat = internalFormat = GL_RED;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = image.format();
+ } else if (context->isOpenGLES() || context->format().profile() != QSurfaceFormat::CoreProfile) {
+ externalFormat = internalFormat = GL_LUMINANCE;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = image.format();
+ } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
+ GLint swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
+ funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
+ externalFormat = internalFormat = GL_RED;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = image.format();
+ }
+ break;
+ default:
+ break;
+ }
+
+ // If no direct upload was detected above, convert to RGBA8888 and upload that
+ if (targetFormat == QImage::Format_Invalid) {
+ externalFormat = internalFormat = GL_RGBA;
+ pixelType = GL_UNSIGNED_BYTE;
+ if (!image.hasAlphaChannel())
+ targetFormat = QImage::Format_RGBX8888;
+ else
+ targetFormat = QImage::Format_RGBA8888;
+ }
+
+ if (options & PremultipliedAlphaBindOption) {
+ if (targetFormat == QImage::Format_ARGB32)
+ targetFormat = QImage::Format_ARGB32_Premultiplied;
+ else if (targetFormat == QImage::Format_RGBA8888)
+ targetFormat = QImage::Format_RGBA8888_Premultiplied;
+ else if (targetFormat == QImage::Format_RGBA64)
+ targetFormat = QImage::Format_RGBA64_Premultiplied;
+ } else {
+ if (targetFormat == QImage::Format_ARGB32_Premultiplied)
+ targetFormat = QImage::Format_ARGB32;
+ else if (targetFormat == QImage::Format_RGBA8888_Premultiplied)
+ targetFormat = QImage::Format_RGBA8888;
+ else if (targetFormat == QImage::Format_RGBA64_Premultiplied)
+ targetFormat = QImage::Format_RGBA64;
+ }
+
+ if (sRgbBinding) {
+ Q_ASSERT(internalFormat == GL_RGBA || internalFormat == GL_RGB);
+ if (image.hasAlphaChannel())
+ internalFormat = GL_SRGB_ALPHA;
+ else
+ internalFormat = GL_SRGB;
+ }
+
+ if (image.format() != targetFormat)
+ tx = image.convertToFormat(targetFormat);
+ else
+ tx = image;
+
+ QSize newSize = tx.size();
+ if (!maxSize.isEmpty())
+ newSize = newSize.boundedTo(maxSize);
+ if (options & PowerOfTwoBindOption) {
+ newSize.setWidth(qNextPowerOfTwo(newSize.width() - 1));
+ newSize.setHeight(qNextPowerOfTwo(newSize.height() - 1));
+ }
+
+ if (newSize != tx.size())
+ tx = tx.scaled(newSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+
+ // Handle cases where the QImage is actually a sub image of its image data:
+ qsizetype naturalBpl = ((qsizetype(tx.width()) * tx.depth() + 31) >> 5) << 2;
+ if (tx.bytesPerLine() != naturalBpl)
+ tx = tx.copy(tx.rect());
+
+ funcs->glTexImage2D(target, 0, internalFormat, tx.width(), tx.height(), 0, externalFormat, pixelType, tx.constBits());
+
+ qsizetype cost = qint64(tx.width()) * tx.height() * tx.depth() / 8;
+
+ return cost;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltextureuploader_p.h b/src/gui/opengl/qopengltextureuploader_p.h
new file mode 100644
index 0000000000..d758b3787b
--- /dev/null
+++ b/src/gui/opengl/qopengltextureuploader_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// 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.
+//
+
+#ifndef QOPENGLTEXTUREUPLOADER_P_H
+#define QOPENGLTEXTUREUPLOADER_P_H
+
+#include <QtCore/qsize.h>
+#include <QtGui/private/qtguiglobal_p.h>
+#include <QtGui/private/qopenglcontext_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QImage;
+
+class Q_GUI_EXPORT QOpenGLTextureUploader
+{
+public:
+ enum BindOption {
+ NoBindOption = 0x0000,
+ PremultipliedAlphaBindOption = 0x0001,
+ UseRedFor8BitBindOption = 0x0002,
+ SRgbBindOption = 0x0004,
+ PowerOfTwoBindOption = 0x0008
+ };
+ Q_DECLARE_FLAGS(BindOptions, BindOption)
+ Q_FLAGS(BindOptions)
+
+ static qsizetype textureImage(GLenum target, const QImage &image, BindOptions options, QSize maxSize = QSize());
+
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLTextureUploader::BindOptions)
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/gui/painting/WEBGRADIENTS_LICENSE.txt b/src/gui/painting/WEBGRADIENTS_LICENSE.txt
new file mode 100644
index 0000000000..1a4d527a4d
--- /dev/null
+++ b/src/gui/painting/WEBGRADIENTS_LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 itmeo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 29bef14f0c..c3585a4647 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -99,8 +99,13 @@ SOURCES += \
painting/qplatformbackingstore.cpp \
painting/qpathsimplifier.cpp
+webgradients.files = painting/webgradients.binaryjson
+webgradients.prefix = qgradient
+webgradients.base = painting
+
RESOURCES += \
- painting/qpdf.qrc
+ painting/qpdf.qrc \
+ webgradients
darwin {
HEADERS += painting/qcoregraphics_p.h
@@ -122,7 +127,7 @@ SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
painting/qimagescale_sse4.cpp
-AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
+ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp
NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index a4a091a29f..2dd5144e40 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -430,28 +430,28 @@ struct Blend_RGB32_on_RGB32_ConstAlpha {
};
struct Blend_ARGB32_on_ARGB32_SourceAlpha {
- inline void write(quint32 *dst, quint32 src) {
- *dst = src + BYTE_MUL(*dst, qAlpha(~src));
+ inline void write(quint32 *dst, quint32 src)
+ {
+ blend_pixel(*dst, src);
}
inline void flush(void *) {}
};
struct Blend_ARGB32_on_ARGB32_SourceAndConstAlpha {
- inline Blend_ARGB32_on_ARGB32_SourceAndConstAlpha(quint32 alpha) {
+ inline Blend_ARGB32_on_ARGB32_SourceAndConstAlpha(quint32 alpha)
+ {
m_alpha = (alpha * 255) >> 8;
- m_ialpha = 255 - m_alpha;
}
- inline void write(quint32 *dst, quint32 src) {
- src = BYTE_MUL(src, m_alpha);
- *dst = src + BYTE_MUL(*dst, qAlpha(~src));
+ inline void write(quint32 *dst, quint32 src)
+ {
+ blend_pixel(*dst, src, m_alpha);
}
inline void flush(void *) {}
quint32 m_alpha;
- quint32 m_ialpha;
};
void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 5c13308d94..860653cc4c 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -46,9 +46,13 @@
#include "qvariant.h"
#include "qline.h"
#include "qdebug.h"
+#include <QtCore/qjsondocument.h>
+#include <QtCore/qjsonarray.h>
#include <QtCore/qcoreapplication.h>
#include "private/qhexstring_p.h"
#include <QtCore/qnumeric.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
@@ -1073,7 +1077,10 @@ QDataStream &operator<<(QDataStream &s, const QBrush &b)
s << type_as_int;
if (s.version() >= QDataStream::Qt_4_3) {
s << int(gradient->spread());
- s << int(gradient->coordinateMode());
+ QGradient::CoordinateMode co_mode = gradient->coordinateMode();
+ if (s.version() < QDataStream::Qt_5_12 && co_mode == QGradient::ObjectMode)
+ co_mode = QGradient::ObjectBoundingMode;
+ s << int(co_mode);
}
if (s.version() >= QDataStream::Qt_4_5)
@@ -1330,6 +1337,72 @@ QGradient::QGradient()
{
}
+/*!
+ \enum QGradient::Preset
+ \since 5.12
+
+ This enum specifies a set of predefined presets for QGradient,
+ based on the gradients from https://webgradients.com/.
+*/
+
+/*!
+ \fn QGradient::QGradient(QGradient::Preset preset)
+ \since 5.12
+
+ Constructs a gradient based on a predefined \a preset.
+
+ The coordinate mode of the resulting gradient is
+ QGradient::ObjectMode, allowing the preset
+ to be applied to arbitrary object sizes.
+*/
+QGradient::QGradient(Preset preset)
+ : QGradient()
+{
+ static QHash<int, QGradient> cachedPresets;
+ static QMutex cacheMutex;
+ QMutexLocker locker(&cacheMutex);
+ if (cachedPresets.contains(preset)) {
+ const QGradient &cachedPreset = cachedPresets.value(preset);
+ m_type = cachedPreset.m_type;
+ m_data = cachedPreset.m_data;
+ m_stops = cachedPreset.m_stops;
+ m_spread = cachedPreset.m_spread;
+ dummy = cachedPreset.dummy;
+ } else {
+ static QJsonDocument jsonPresets = []() {
+ QFile webGradients(QLatin1String(":/qgradient/webgradients.binaryjson"));
+ webGradients.open(QFile::ReadOnly);
+ return QJsonDocument::fromBinaryData(webGradients.readAll());
+ }();
+
+ const QJsonValue presetData = jsonPresets[preset - 1];
+ if (!presetData.isObject())
+ return;
+
+ m_type = LinearGradient;
+ setCoordinateMode(ObjectMode);
+ setSpread(PadSpread);
+
+ const QJsonValue start = presetData[QLatin1Literal("start")];
+ const QJsonValue end = presetData[QLatin1Literal("end")];
+ m_data.linear.x1 = start[QLatin1Literal("x")].toDouble();
+ m_data.linear.y1 = start[QLatin1Literal("y")].toDouble();
+ m_data.linear.x2 = end[QLatin1Literal("x")].toDouble();
+ m_data.linear.y2 = end[QLatin1Literal("y")].toDouble();
+
+ for (const QJsonValue &stop : presetData[QLatin1String("stops")].toArray()) {
+ setColorAt(stop[QLatin1Literal("position")].toDouble(),
+ QColor(QRgb(stop[QLatin1Literal("color")].toInt())));
+ }
+
+ cachedPresets.insert(preset, *this);
+ }
+}
+
+QT_END_NAMESPACE
+static void initGradientPresets() { Q_INIT_RESOURCE(qmake_webgradients); }
+Q_CONSTRUCTOR_FUNCTION(initGradientPresets);
+QT_BEGIN_NAMESPACE
/*!
\enum QGradient::Type
@@ -1492,14 +1565,19 @@ QGradientStops QGradient::stops() const
\value LogicalMode This is the default mode. The gradient coordinates
are specified logical space just like the object coordinates.
+ \value ObjectMode In this mode the gradient coordinates are
+ relative to the bounding rectangle of the object being drawn, with
+ (0,0) in the top left corner, and (1,1) in the bottom right corner
+ of the object's bounding rectangle. This value was added in Qt
+ 5.12.
\value StretchToDeviceMode In this mode the gradient coordinates
are relative to the bounding rectangle of the paint device,
with (0,0) in the top left corner, and (1,1) in the bottom right
corner of the paint device.
- \value ObjectBoundingMode In this mode the gradient coordinates are
- relative to the bounding rectangle of the object being drawn, with
- (0,0) in the top left corner, and (1,1) in the bottom right corner
- of the object's bounding rectangle.
+ \value ObjectBoundingMode This mode is the same as ObjectMode, except that
+ the {QBrush::transform()} {brush transform}, if any, is applied relative to
+ the logical space instead of the object space. This enum value is
+ deprecated and should not be used in new code.
*/
/*!
diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h
index e5cff9cc9b..aee51c526d 100644
--- a/src/gui/painting/qbrush.h
+++ b/src/gui/painting/qbrush.h
@@ -194,7 +194,8 @@ public:
enum CoordinateMode {
LogicalMode,
StretchToDeviceMode,
- ObjectBoundingMode
+ ObjectBoundingMode,
+ ObjectMode
};
Q_ENUM(CoordinateMode)
@@ -203,7 +204,180 @@ public:
ComponentInterpolation
};
+ enum Preset {
+ WarmFlame = 1,
+ NightFade = 2,
+ SpringWarmth = 3,
+ JuicyPeach = 4,
+ YoungPassion = 5,
+ LadyLips = 6,
+ SunnyMorning = 7,
+ RainyAshville = 8,
+ FrozenDreams = 9,
+ WinterNeva = 10,
+ DustyGrass = 11,
+ TemptingAzure = 12,
+ HeavyRain = 13,
+ AmyCrisp = 14,
+ MeanFruit = 15,
+ DeepBlue = 16,
+ RipeMalinka = 17,
+ CloudyKnoxville = 18,
+ MalibuBeach = 19,
+ NewLife = 20,
+ TrueSunset = 21,
+ MorpheusDen = 22,
+ RareWind = 23,
+ NearMoon = 24,
+ WildApple = 25,
+ SaintPetersburg = 26,
+ PlumPlate = 28,
+ EverlastingSky = 29,
+ HappyFisher = 30,
+ Blessing = 31,
+ SharpeyeEagle = 32,
+ LadogaBottom = 33,
+ LemonGate = 34,
+ ItmeoBranding = 35,
+ ZeusMiracle = 36,
+ OldHat = 37,
+ StarWine = 38,
+ HappyAcid = 41,
+ AwesomePine = 42,
+ NewYork = 43,
+ ShyRainbow = 44,
+ MixedHopes = 46,
+ FlyHigh = 47,
+ StrongBliss = 48,
+ FreshMilk = 49,
+ SnowAgain = 50,
+ FebruaryInk = 51,
+ KindSteel = 52,
+ SoftGrass = 53,
+ GrownEarly = 54,
+ SharpBlues = 55,
+ ShadyWater = 56,
+ DirtyBeauty = 57,
+ GreatWhale = 58,
+ TeenNotebook = 59,
+ PoliteRumors = 60,
+ SweetPeriod = 61,
+ WideMatrix = 62,
+ SoftCherish = 63,
+ RedSalvation = 64,
+ BurningSpring = 65,
+ NightParty = 66,
+ SkyGlider = 67,
+ HeavenPeach = 68,
+ PurpleDivision = 69,
+ AquaSplash = 70,
+ SpikyNaga = 72,
+ LoveKiss = 73,
+ CleanMirror = 75,
+ PremiumDark = 76,
+ ColdEvening = 77,
+ CochitiLake = 78,
+ SummerGames = 79,
+ PassionateBed = 80,
+ MountainRock = 81,
+ DesertHump = 82,
+ JungleDay = 83,
+ PhoenixStart = 84,
+ OctoberSilence = 85,
+ FarawayRiver = 86,
+ AlchemistLab = 87,
+ OverSun = 88,
+ PremiumWhite = 89,
+ MarsParty = 90,
+ EternalConstance = 91,
+ JapanBlush = 92,
+ SmilingRain = 93,
+ CloudyApple = 94,
+ BigMango = 95,
+ HealthyWater = 96,
+ AmourAmour = 97,
+ RiskyConcrete = 98,
+ StrongStick = 99,
+ ViciousStance = 100,
+ PaloAlto = 101,
+ HappyMemories = 102,
+ MidnightBloom = 103,
+ Crystalline = 104,
+ PartyBliss = 106,
+ ConfidentCloud = 107,
+ LeCocktail = 108,
+ RiverCity = 109,
+ FrozenBerry = 110,
+ ChildCare = 112,
+ FlyingLemon = 113,
+ NewRetrowave = 114,
+ HiddenJaguar = 115,
+ AboveTheSky = 116,
+ Nega = 117,
+ DenseWater = 118,
+ Seashore = 120,
+ MarbleWall = 121,
+ CheerfulCaramel = 122,
+ NightSky = 123,
+ MagicLake = 124,
+ YoungGrass = 125,
+ ColorfulPeach = 126,
+ GentleCare = 127,
+ PlumBath = 128,
+ HappyUnicorn = 129,
+ AfricanField = 131,
+ SolidStone = 132,
+ OrangeJuice = 133,
+ GlassWater = 134,
+ NorthMiracle = 136,
+ FruitBlend = 137,
+ MillenniumPine = 138,
+ HighFlight = 139,
+ MoleHall = 140,
+ SpaceShift = 142,
+ ForestInei = 143,
+ RoyalGarden = 144,
+ RichMetal = 145,
+ JuicyCake = 146,
+ SmartIndigo = 147,
+ SandStrike = 148,
+ NorseBeauty = 149,
+ AquaGuidance = 150,
+ SunVeggie = 151,
+ SeaLord = 152,
+ BlackSea = 153,
+ GrassShampoo = 154,
+ LandingAircraft = 155,
+ WitchDance = 156,
+ SleeplessNight = 157,
+ AngelCare = 158,
+ CrystalRiver = 159,
+ SoftLipstick = 160,
+ SaltMountain = 161,
+ PerfectWhite = 162,
+ FreshOasis = 163,
+ StrictNovember = 164,
+ MorningSalad = 165,
+ DeepRelief = 166,
+ SeaStrike = 167,
+ NightCall = 168,
+ SupremeSky = 169,
+ LightBlue = 170,
+ MindCrawl = 171,
+ LilyMeadow = 172,
+ SugarLollipop = 173,
+ SweetDessert = 174,
+ MagicRay = 175,
+ TeenParty = 176,
+ FrozenHeat = 177,
+ GagarinView = 178,
+ FabledSunset = 179,
+ PerfectBlue = 180,
+ };
+ Q_ENUM(Preset)
+
QGradient();
+ QGradient(Preset);
Type type() const { return m_type; }
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index c55bcb12c9..1d7375d1df 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -304,11 +304,6 @@ static const int rgbTblSize = sizeof(rgbTbl) / sizeof(RGBData);
#undef rgb
-#if defined(Q_CC_MSVC) && _MSC_VER < 1600
-inline bool operator<(const RGBData &data1, const RGBData &data2)
-{ return qstrcmp(data1.name, data2.name) < 0; }
-#endif
-
inline bool operator<(const char *name, const RGBData &data)
{ return qstrcmp(name, data.name) < 0; }
inline bool operator<(const RGBData &data, const char *name)
diff --git a/src/gui/painting/qcompositionfunctions.cpp b/src/gui/painting/qcompositionfunctions.cpp
index 339a9749b8..027bf23115 100644
--- a/src/gui/painting/qcompositionfunctions.cpp
+++ b/src/gui/painting/qcompositionfunctions.cpp
@@ -64,125 +64,354 @@ QT_BEGIN_NAMESPACE
where the source is an array of pixels.
*/
-#if defined __SSE2__
-# define LOAD(ptr) _mm_loadl_epi64(reinterpret_cast<const __m128i *>(ptr))
+struct Argb32OperationsC
+{
+ typedef QRgb Type;
+ typedef quint8 Scalar;
+ typedef QRgb OptimalType;
+ typedef quint8 OptimalScalar;
+
+ static const Type clear;
+ static bool isOpaque(Type val)
+ { return qAlpha(val) == 255; }
+ static bool isTransparent(Type val)
+ { return qAlpha(val) == 0; }
+ static Scalar scalarFrom8bit(uint8_t a)
+ { return a; }
+ static void memfill(Type *ptr, Type value, qsizetype len)
+ { qt_memfill32(ptr, value, len); }
+ static void memcpy(Type *Q_DECL_RESTRICT dest, const Type *Q_DECL_RESTRICT src, qsizetype len)
+ { ::memcpy(dest, src, len * sizeof(Type)); }
+
+ static OptimalType load(const Type *ptr)
+ { return *ptr; }
+ static OptimalType convert(const Type &val)
+ { return val; }
+ static void store(Type *ptr, OptimalType value)
+ { *ptr = value; }
+ static OptimalType add(OptimalType a, OptimalType b)
+ { return a + b; }
+ static OptimalScalar add(OptimalScalar a, OptimalScalar b)
+ { return a + b; }
+ static OptimalType plus(OptimalType a, OptimalType b)
+ { return comp_func_Plus_one_pixel(a, b); }
+ static OptimalScalar alpha(OptimalType val)
+ { return qAlpha(val); }
+ static OptimalScalar invAlpha(OptimalScalar c)
+ { return 255 - c; }
+ static OptimalScalar invAlpha(OptimalType val)
+ { return alpha(~val); }
+ static OptimalScalar scalar(Scalar v)
+ { return v; }
+ static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
+ { return BYTE_MUL(val, a); }
+ static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
+ { return INTERPOLATE_PIXEL_255(x, a1, y, a2); }
+ static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
+ { return BYTE_MUL(val, a); }
+ static OptimalScalar multiplyAlpha8bit(OptimalScalar val, uint8_t a)
+ { return qt_div_255(val * a); }
+ static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, OptimalScalar a2)
+ { return INTERPOLATE_PIXEL_255(x, a1, y, a2); }
+};
+
+const Argb32OperationsC::Type Argb32OperationsC::clear = 0;
+
+struct Rgba64OperationsBase
+{
+ typedef QRgba64 Type;
+ typedef quint16 Scalar;
+
+ static const Type clear;
+
+ static bool isOpaque(Type val)
+ { return val.isOpaque(); }
+ static bool isTransparent(Type val)
+ { return val.isTransparent(); }
+ static Scalar scalarFrom8bit(uint8_t a)
+ { return a * 257; }
+
+ static void memfill(Type *ptr, Type value, qsizetype len)
+ { qt_memfill64((quint64*)ptr, value, len); }
+ static void memcpy(Type *Q_DECL_RESTRICT dest, const Type *Q_DECL_RESTRICT src, qsizetype len)
+ { ::memcpy(dest, src, len * sizeof(Type)); }
+};
+
+const Rgba64OperationsBase::Type Rgba64OperationsBase::clear = QRgba64::fromRgba64(0);
+
+struct Rgba64OperationsC : public Rgba64OperationsBase
+{
+ typedef QRgba64 OptimalType;
+ typedef quint16 OptimalScalar;
+
+ static OptimalType load(const Type *ptr)
+ { return *ptr; }
+ static OptimalType convert(const Type &val)
+ { return val; }
+ static void store(Type *ptr, OptimalType value)
+ { *ptr = value; }
+ static OptimalType add(OptimalType a, OptimalType b)
+ { return QRgba64::fromRgba64((quint64)a + (quint64)b); }
+ static OptimalScalar add(OptimalScalar a, OptimalScalar b)
+ { return a + b; }
+ static OptimalType plus(OptimalType a, OptimalType b)
+ { return addWithSaturation(a, b); }
+ static OptimalScalar alpha(OptimalType val)
+ { return val.alpha(); }
+ static OptimalScalar invAlpha(Scalar c)
+ { return 65535 - c; }
+ static OptimalScalar invAlpha(OptimalType val)
+ { return 65535 - alpha(val); }
+ static OptimalScalar scalar(Scalar v)
+ { return v; }
+ static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
+ { return multiplyAlpha255(val, a); }
+ static OptimalScalar multiplyAlpha8bit(OptimalScalar val, uint8_t a)
+ { return qt_div_255(val * a); }
+ static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
+ { return interpolate255(x, a1, y, a2); }
+ static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
+ { return multiplyAlpha65535(val, a); }
+ static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, OptimalScalar a2)
+ { return interpolate65535(x, a1, y, a2); }
+};
+
+#if defined(__SSE2__)
+struct Rgba64OperationsSSE2 : public Rgba64OperationsBase
+{
+ typedef __m128i OptimalType;
+ typedef __m128i OptimalScalar;
+
+ static OptimalType load(const Type *ptr)
+ {
+ return _mm_loadl_epi64(reinterpret_cast<const __m128i *>(ptr));
+ }
+ static OptimalType convert(const Type &value)
+ {
#ifdef Q_PROCESSOR_X86_64
-# define CONVERT(value) _mm_cvtsi64_si128(value)
+ return _mm_cvtsi64_si128(value);
#else
-# define CONVERT(value) LOAD(&value)
+ return load(&value);
#endif
-# define STORE(ptr, value) _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr), value)
-# define ADD(p, q) _mm_add_epi32(p, q)
-# define ALPHA(c) _mm_shufflelo_epi16(c, _MM_SHUFFLE(3, 3, 3, 3))
-# define CONST(n) _mm_shufflelo_epi16(_mm_cvtsi32_si128(n), _MM_SHUFFLE(0, 0, 0, 0))
-# define INVALPHA(c) _mm_sub_epi32(CONST(65535), ALPHA(c))
-#elif defined __ARM_NEON__
-# define LOAD(ptr) vreinterpret_u16_u64(vld1_u64(reinterpret_cast<const uint64_t *>(ptr)))
-# define CONVERT(value) vreinterpret_u16_u64(vmov_n_u64(value))
-# define STORE(ptr, value) vst1_u64(reinterpret_cast<uint64_t *>(ptr), vreinterpret_u64_u16(value))
-# define ADD(p, q) vadd_u16(p, q)
-# define ALPHA(c) vdup_lane_u16(c, 3)
-# define CONST(n) vdup_n_u16(n)
-# define INVALPHA(c) vmvn_u16(ALPHA(c))
-#else
-# define LOAD(ptr) *ptr
-# define CONVERT(value) value
-# define STORE(ptr, value) *ptr = value
-# define ADD(p, q) (p + q)
-# define ALPHA(c) (c).alpha()
-# define CONST(n) n
-# define INVALPHA(c) (65535 - ALPHA(c))
+ }
+ static void store(Type *ptr, OptimalType value)
+ {
+ _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr), value);
+ }
+ static OptimalType add(OptimalType a, OptimalType b)
+ {
+ return _mm_add_epi16(a, b);
+ }
+// same as above:
+// static OptimalScalar add(OptimalScalar a, OptimalScalar b)
+ static OptimalType plus(OptimalType a, OptimalType b)
+ {
+ return _mm_adds_epu16(a, b);
+ }
+ static OptimalScalar alpha(OptimalType c)
+ {
+ return _mm_shufflelo_epi16(c, _MM_SHUFFLE(3, 3, 3, 3));
+ }
+ static OptimalScalar invAlpha(Scalar c)
+ {
+ return scalar(65535 - c);
+ }
+ static OptimalScalar invAlpha(OptimalType c)
+ {
+ return _mm_xor_si128(_mm_set1_epi16(-1), alpha(c));
+ }
+ static OptimalScalar scalar(Scalar n)
+ {
+ return _mm_shufflelo_epi16(_mm_cvtsi32_si128(n), _MM_SHUFFLE(0, 0, 0, 0));
+ }
+ static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
+ {
+ return multiplyAlpha255(val, a);
+ }
+// same as above:
+// static OptimalScalar multiplyAlpha8bit(OptimalScalar a, uint8_t a)
+ static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
+ {
+ return interpolate255(x, a1, y, a2);
+ }
+ static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
+ {
+ return multiplyAlpha65535(val, a);
+ }
+ // a2 is const-ref because otherwise MSVC2015@x86 complains that it can't 16-byte align the argument.
+ static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, const OptimalScalar &a2)
+ {
+ return interpolate65535(x, a1, y, a2);
+ }
+};
#endif
+#if defined(__ARM_NEON__)
+struct Rgba64OperationsNEON : public Rgba64OperationsBase
+{
+ typedef uint16x4_t OptimalType;
+ typedef uint16x4_t OptimalScalar;
+
+ static OptimalType load(const Type *ptr)
+ {
+ return vreinterpret_u16_u64(vld1_u64(reinterpret_cast<const uint64_t *>(ptr)));
+ }
+ static OptimalType convert(const Type &val)
+ {
+ return vreinterpret_u16_u64(vmov_n_u64(val));
+ }
+ static void store(Type *ptr, OptimalType value)
+ {
+ vst1_u64(reinterpret_cast<uint64_t *>(ptr), vreinterpret_u64_u16(value));
+ }
+ static OptimalType add(OptimalType a, OptimalType b)
+ {
+ return vadd_u16(a, b);
+ }
+// same as above:
+// static OptimalScalar add(OptimalScalar a, OptimalScalar b)
+ static OptimalType plus(OptimalType a, OptimalType b)
+ {
+ return vqadd_u16(a, b);
+ }
+ static OptimalScalar alpha(OptimalType c)
+ {
+ return vdup_lane_u16(c, 3);
+ }
+ static OptimalScalar invAlpha(Scalar c)
+ {
+ return scalar(65535 - c);
+ }
+ static OptimalScalar invAlpha(OptimalType c)
+ {
+ return vmvn_u16(alpha(c));
+ }
+ static OptimalScalar scalar(Scalar n)
+ {
+ return vdup_n_u16(n);
+ }
+ static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
+ {
+ return multiplyAlpha255(val, a);
+ }
+// same as above:
+// static OptimalScalar multiplyAlpha8bit(OptimalScalar a, uint8_t a)
+ static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
+ {
+ return interpolate255(x, a1, y, a2);
+ }
+ static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
+ {
+ return multiplyAlpha65535(val, a);
+ }
+ static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, OptimalScalar a2)
+ {
+ return interpolate65535(x, a1, y, a2);
+ }
+};
+
+#endif
+
+typedef Argb32OperationsC Argb32Operations;
+#if defined(__SSE2__)
+typedef Rgba64OperationsSSE2 Rgba64Operations;
+#elif defined(__ARM_NEON__)
+typedef Rgba64OperationsNEON Rgba64Operations;
+#else
+typedef Rgba64OperationsC Rgba64Operations;
+#endif
/*
result = 0
d = d * cia
*/
-void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
+template<class Ops>
+inline static void comp_func_Clear_template(typename Ops::Type *dest, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- qt_memfill32(dest, 0, length);
- } else {
+ if (const_alpha == 255)
+ Ops::memfill(dest, Ops::clear, length);
+ else {
uint ialpha = 255 - const_alpha;
- for (int i = 0; i < length; ++i)
- dest[i] = BYTE_MUL(dest[i], ialpha);
+ for (int i = 0; i < length; ++i) {
+ Ops::store(&dest[i], Ops::multiplyAlpha8bit(Ops::load(&dest[i]), ialpha));
+ }
}
}
+void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
+{
+ comp_func_Clear_template<Argb32Operations>(dest, length, const_alpha);
+}
+
void QT_FASTCALL comp_func_solid_Clear_rgb64(QRgba64 *dest, int length, QRgba64, uint const_alpha)
{
- if (const_alpha == 255) {
- qt_memfill64((quint64*)dest, 0, length);
- } else {
- uint ialpha = 255 - const_alpha;
- for (int i = 0; i < length; ++i)
- STORE(&dest[i], multiplyAlpha255(LOAD(&dest[i]), ialpha));
- }
+ comp_func_Clear_template<Rgba64Operations>(dest, length, const_alpha);
}
void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
{
- comp_func_solid_Clear(dest, length, 0, const_alpha);
+ comp_func_Clear_template<Argb32Operations>(dest, length, const_alpha);
}
void QT_FASTCALL comp_func_Clear_rgb64(QRgba64 *dest, const QRgba64 *, int length, uint const_alpha)
{
- comp_func_solid_Clear_rgb64(dest, length, QRgba64(), const_alpha);
+ comp_func_Clear_template<Rgba64Operations>(dest, length, const_alpha);
}
/*
result = s
dest = s * ca + d * cia
*/
-void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_Source_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
- if (const_alpha == 255) {
- qt_memfill32(dest, color, length);
- } else {
- uint ialpha = 255 - const_alpha;
- color = BYTE_MUL(color, const_alpha);
+ if (const_alpha == 255)
+ Ops::memfill(dest, color, length);
+ else {
+ const uint ialpha = 255 - const_alpha;
+ auto s = Ops::multiplyAlpha8bit(Ops::convert(color), const_alpha);
for (int i = 0; i < length; ++i) {
- dest[i] = color + BYTE_MUL(dest[i], ialpha);
+ auto d = Ops::multiplyAlpha8bit(Ops::load(&dest[i]), ialpha);
+ Ops::store(&dest[i], Ops::add(s, d));
}
}
}
-void QT_FASTCALL comp_func_solid_Source_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_Source_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255)
- qt_memfill64((quint64*)dest, color, length);
+ Ops::memcpy(dest, src, length);
else {
- uint ialpha = 255 - const_alpha;
- auto c = multiplyAlpha255(CONVERT(color), const_alpha);
+ const uint ialpha = 255 - const_alpha;
for (int i = 0; i < length; ++i) {
- STORE(&dest[i], ADD(c, multiplyAlpha255(LOAD(&dest[i]), ialpha)));
+ auto s = Ops::load(src + i);
+ auto d = Ops::load(dest + i);
+ Ops::store(&dest[i], Ops::interpolate8bit(s, const_alpha, d, ialpha));
}
}
}
+void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_Source_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_Source_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_Source_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
void QT_FASTCALL comp_func_Source(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- ::memcpy(dest, src, size_t(length) * sizeof(uint));
- } else {
- uint ialpha = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- dest[i] = INTERPOLATE_PIXEL_255(src[i], const_alpha, dest[i], ialpha);
- }
- }
+ comp_func_Source_template<Argb32Operations>(dest, src, length, const_alpha);
}
void QT_FASTCALL comp_func_Source_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255)
- ::memcpy(dest, src, size_t(length) * sizeof(quint64));
- else {
- uint ialpha = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- STORE(&dest[i], interpolate255(LOAD(&src[i]), const_alpha, LOAD(&dest[i]), ialpha));
- }
- }
+ comp_func_Source_template<Rgba64Operations>(dest, src, length, const_alpha);
}
void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
@@ -207,68 +436,66 @@ void QT_FASTCALL comp_func_Destination_rgb64(QRgba64 *, const QRgba64 *, int, ui
= s * ca + d * (sia * ca + cia)
= s * ca + d * (1 - sa*ca)
*/
-void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_SourceOver_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
- if ((const_alpha & qAlpha(color)) == 255) {
- qt_memfill32(dest, color, length);
- } else {
+ if (const_alpha == 255 && Ops::isOpaque(color))
+ Ops::memfill(dest, color, length);
+ else {
+ auto c = Ops::convert(color);
if (const_alpha != 255)
- color = BYTE_MUL(color, const_alpha);
+ c = Ops::multiplyAlpha8bit(c, const_alpha);
+ auto cAlpha = Ops::invAlpha(c);
for (int i = 0; i < length; ++i) {
- dest[i] = color + BYTE_MUL(dest[i], qAlpha(~color));
+ auto d = Ops::multiplyAlpha(Ops::load(&dest[i]), cAlpha);
+ Ops::store(&dest[i], Ops::add(c, d));
}
}
}
-void QT_FASTCALL comp_func_solid_SourceOver_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_SourceOver_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
- if (const_alpha == 255 && color.isOpaque()) {
- qt_memfill64((quint64*)dest, color, length);
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ auto c = src[i];
+ if (Ops::isOpaque(c))
+ Ops::store(&dest[i], Ops::convert(c));
+ else if (!Ops::isTransparent(c)) {
+ auto s = Ops::convert(c);
+ auto d = Ops::multiplyAlpha(Ops::load(&dest[i]), Ops::invAlpha(s));
+ Ops::store(&dest[i], Ops::add(s, d));
+ }
+ }
} else {
- auto c = CONVERT(color);
- if (const_alpha != 255)
- c = multiplyAlpha255(c, const_alpha);
- auto cAlpha = INVALPHA(c);
for (int i = 0; i < length; ++i) {
- STORE(&dest[i], ADD(c, multiplyAlpha65535(LOAD(&dest[i]), cAlpha)));
+ auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
+ auto d = Ops::multiplyAlpha(Ops::load(&dest[i]), Ops::invAlpha(s));
+ Ops::store(&dest[i], Ops::add(s, d));
}
}
}
+void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_SourceOver_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_SourceOver_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_SourceOver_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
void QT_FASTCALL comp_func_SourceOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- uint s = src[i];
- if (s >= 0xff000000)
- dest[i] = s;
- else if (s != 0)
- dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s));
- }
- } else {
- for (int i = 0; i < length; ++i) {
- uint s = BYTE_MUL(src[i], const_alpha);
- dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s));
- }
- }
+ comp_func_SourceOver_template<Argb32Operations>(dest, src, length, const_alpha);
}
void QT_FASTCALL comp_func_SourceOver_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- QRgba64 s = src[i];
- if (s.isOpaque())
- dest[i] = s;
- else if (!s.isTransparent())
- STORE(&dest[i], ADD(CONVERT(s), multiplyAlpha65535(LOAD(&dest[i]), 65535 - s.alpha())));
- }
- } else {
- for (int i = 0; i < length; ++i) {
- auto s = multiplyAlpha255(LOAD(&src[i]), const_alpha);
- STORE(&dest[i], ADD(s, multiplyAlpha65535(LOAD(&dest[i]), INVALPHA(s))));
- }
- }
+ comp_func_SourceOver_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
@@ -276,128 +503,122 @@ void QT_FASTCALL comp_func_SourceOver_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const
dest = (d + s * dia) * ca + d * cia
= d + s * dia * ca
*/
-void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha != 255)
- color = BYTE_MUL(color, const_alpha);
- for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- dest[i] = d + BYTE_MUL(color, qAlpha(~d));
- }
-}
-
-void QT_FASTCALL comp_func_solid_DestinationOver_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_DestinationOver_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
- auto c = CONVERT(color);
+ auto c = Ops::convert(color);
if (const_alpha != 255)
- c = multiplyAlpha255(c, const_alpha);
+ c = Ops::multiplyAlpha8bit(c, const_alpha);
for (int i = 0; i < length; ++i) {
- auto d = LOAD(&dest[i]);
- STORE(&dest[i], ADD(d, multiplyAlpha65535(c, INVALPHA(d))));
+ auto d = Ops::load(&dest[i]);
+ auto s = Ops::multiplyAlpha(c, Ops::invAlpha(d));
+ Ops::store(&dest[i], Ops::add(s, d));
}
}
-void QT_FASTCALL comp_func_DestinationOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+template<class Ops>
+inline static void comp_func_DestinationOver_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- dest[i] = d + BYTE_MUL(src[i], qAlpha(~d));
+ auto d = Ops::load(&dest[i]);
+ auto s = Ops::multiplyAlpha(Ops::load(&src[i]), Ops::invAlpha(d));
+ Ops::store(&dest[i], Ops::add(s, d));
}
} else {
for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- uint s = BYTE_MUL(src[i], const_alpha);
- dest[i] = d + BYTE_MUL(s, qAlpha(~d));
+ auto d = Ops::load(&dest[i]);
+ auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
+ s = Ops::multiplyAlpha(s, Ops::invAlpha(d));
+ Ops::store(&dest[i], Ops::add(s, d));
}
}
}
+void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_DestinationOver_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_DestinationOver_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_DestinationOver_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_DestinationOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ comp_func_DestinationOver_template<Argb32Operations>(dest, src, length, const_alpha);
+}
+
void QT_FASTCALL comp_func_DestinationOver_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- auto d = LOAD(&dest[i]);
- STORE(&dest[i], ADD(d, multiplyAlpha65535(LOAD(&src[i]), INVALPHA(d))));
- }
- } else {
- for (int i = 0; i < length; ++i) {
- auto d = LOAD(&dest[i]);
- auto s = multiplyAlpha255(LOAD(&src[i]), const_alpha);
- STORE(&dest[i], ADD(d, multiplyAlpha65535(s, INVALPHA(d))));
- }
- }
+ comp_func_DestinationOver_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
result = s * da
dest = s * da * ca + d * cia
*/
-void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_SourceIn_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
if (const_alpha == 255) {
+ auto c = Ops::convert(color);
for (int i = 0; i < length; ++i) {
- dest[i] = BYTE_MUL(color, qAlpha(dest[i]));
+ Ops::store(&dest[i], Ops::multiplyAlpha(c, Ops::alpha(Ops::load(&dest[i]))));
}
} else {
- color = BYTE_MUL(color, const_alpha);
- uint cia = 255 - const_alpha;
+ auto c = Ops::multiplyAlpha8bit(Ops::convert(color), const_alpha);
+ auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(d), d, cia);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(c, Ops::alpha(d), d, cia));
}
}
}
-void QT_FASTCALL comp_func_solid_SourceIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_SourceIn_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255) {
- auto c = CONVERT(color);
for (int i = 0; i < length; ++i) {
- STORE(&dest[i], multiplyAlpha65535(c, dest[i].alpha()));
+ auto s = Ops::load(&src[i]);
+ Ops::store(&dest[i], Ops::multiplyAlpha(s, Ops::alpha(Ops::load(&dest[i]))));
}
} else {
- uint ca = const_alpha * 257;
- auto cia = CONST(65535 - ca);
- auto c = multiplyAlpha65535(CONVERT(color), ca);
+ auto ca = Ops::scalarFrom8bit(const_alpha);
+ auto cia = Ops::invAlpha(ca);
+ auto cav = Ops::scalar(ca);
for (int i = 0; i < length; ++i) {
- auto d = LOAD(&dest[i]);
- STORE(&dest[i], interpolate65535(c, ALPHA(d), d, cia));
+ auto d = Ops::load(&dest[i]);
+ auto s = Ops::multiplyAlpha(Ops::load(&src[i]), cav);
+ Ops::store(&dest[i], Ops::interpolate(s, Ops::alpha(d), d, cia));
}
}
}
+void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_SourceIn_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_SourceIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_SourceIn_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
void QT_FASTCALL comp_func_SourceIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- dest[i] = BYTE_MUL(src[i], qAlpha(dest[i]));
- }
- } else {
- uint cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- uint s = BYTE_MUL(src[i], const_alpha);
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, cia);
- }
- }
+ comp_func_SourceIn_template<Argb32Operations>(dest, src, length, const_alpha);
}
void QT_FASTCALL comp_func_SourceIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- STORE(&dest[i], multiplyAlpha65535(LOAD(&src[i]), dest[i].alpha()));
- }
- } else {
- uint ca = const_alpha * 257;
- auto cia = CONST(65535 - ca);
- for (int i = 0; i < length; ++i) {
- auto d = LOAD(&dest[i]);
- auto s = multiplyAlpha65535(LOAD(&src[i]), ca);
- STORE(&dest[i], interpolate65535(s, ALPHA(d), d, cia));
- }
- }
+ comp_func_SourceIn_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
@@ -405,128 +626,120 @@ void QT_FASTCALL comp_func_SourceIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const Q
dest = d * sa * ca + d * cia
= d * (sa * ca + cia)
*/
-void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_DestinationIn_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
- uint a = qAlpha(color);
+ auto sa = Ops::alpha(Ops::convert(color));
if (const_alpha != 255) {
- a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
- }
- for (int i = 0; i < length; ++i) {
- dest[i] = BYTE_MUL(dest[i], a);
+ sa = Ops::multiplyAlpha8bit(sa, const_alpha);
+ sa = Ops::add(sa, Ops::invAlpha(Ops::scalarFrom8bit(const_alpha)));
}
-}
-void QT_FASTCALL comp_func_solid_DestinationIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
-{
- uint a = color.alpha();
- uint ca64k = const_alpha * 257;
- if (const_alpha != 255)
- a = qt_div_65535(a * ca64k) + 65535 - ca64k;
for (int i = 0; i < length; ++i) {
- STORE(&dest[i], multiplyAlpha65535(LOAD(&dest[i]), a));
+ Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sa));
}
}
-void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+template<class Ops>
+inline static void comp_func_DestinationIn_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- dest[i] = BYTE_MUL(dest[i], qAlpha(src[i]));
+ auto a = Ops::alpha(Ops::load(&src[i]));
+ Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), a));
}
} else {
- uint cia = 255 - const_alpha;
+ auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
for (int i = 0; i < length; ++i) {
- uint a = BYTE_MUL(qAlpha(src[i]), const_alpha) + cia;
- dest[i] = BYTE_MUL(dest[i], a);
+ auto sa = Ops::multiplyAlpha8bit(Ops::alpha(Ops::load(&src[i])), const_alpha);
+ sa = Ops::add(sa, cia);
+ Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sa));
}
}
}
+void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_DestinationIn_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_DestinationIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_DestinationIn_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ comp_func_DestinationIn_template<Argb32Operations>(dest, src, length, const_alpha);
+}
+
void QT_FASTCALL comp_func_DestinationIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- STORE(&dest[i], multiplyAlpha65535(LOAD(&dest[i]), src[i].alpha()));
- }
- } else {
- uint ca = const_alpha * 257;
- uint cia = 65535 - ca;
- for (int i = 0; i < length; ++i) {
- uint a = qt_div_65535(src[i].alpha() * ca) + cia;
- STORE(&dest[i], multiplyAlpha65535(LOAD(&dest[i]), a));
- }
- }
+ comp_func_DestinationIn_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
result = s * dia
dest = s * dia * ca + d * cia
*/
-
-void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_SourceOut_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
+ auto c = Ops::convert(color);
if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- dest[i] = BYTE_MUL(color, qAlpha(~dest[i]));
- }
+ for (int i = 0; i < length; ++i)
+ Ops::store(&dest[i], Ops::multiplyAlpha(c, Ops::invAlpha(Ops::load(&dest[i]))));
} else {
- color = BYTE_MUL(color, const_alpha);
- uint cia = 255 - const_alpha;
+ auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
+ c = Ops::multiplyAlpha8bit(c, const_alpha);
for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, cia);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(c, Ops::invAlpha(d), d, cia));
}
}
}
-void QT_FASTCALL comp_func_solid_SourceOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_SourceOut_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- dest[i] = multiplyAlpha65535(color, 65535 - dest[i].alpha());
+ auto s = Ops::load(&src[i]);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::multiplyAlpha(s, Ops::invAlpha(d)));
}
} else {
- uint ca = const_alpha * 257;
- uint cia = 65535 - ca;
- color = multiplyAlpha65535(color, ca);
+ auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
for (int i = 0; i < length; ++i) {
- QRgba64 d = dest[i];
- dest[i] = interpolate65535(color, 65535 - d.alpha(), d, cia);
+ auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, cia));
}
}
}
+void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_SourceOut_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_SourceOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_SourceOut_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
void QT_FASTCALL comp_func_SourceOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- dest[i] = BYTE_MUL(src[i], qAlpha(~dest[i]));
- }
- } else {
- uint cia = 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- uint s = BYTE_MUL(src[i], const_alpha);
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, cia);
- }
- }
+ comp_func_SourceOut_template<Argb32Operations>(dest, src, length, const_alpha);
}
void QT_FASTCALL comp_func_SourceOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- dest[i] = multiplyAlpha65535(src[i], 65535 - dest[i].alpha());
- }
- } else {
- uint ca = const_alpha * 257;
- uint cia = 65535 - ca;
- for (int i = 0; i < length; ++i) {
- QRgba64 d = dest[i];
- QRgba64 s = multiplyAlpha65535(src[i], ca);
- dest[i] = interpolate65535(s, 65535 - d.alpha(), d, cia);
- }
- }
+ comp_func_SourceOut_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
@@ -534,56 +747,58 @@ void QT_FASTCALL comp_func_SourceOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const
dest = d * sia * ca + d * cia
= d * (sia * ca + cia)
*/
-void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_DestinationOut_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
- uint a = qAlpha(~color);
- if (const_alpha != 255)
- a = BYTE_MUL(a, const_alpha) + 255 - const_alpha;
- for (int i = 0; i < length; ++i) {
- dest[i] = BYTE_MUL(dest[i], a);
+ auto sai = Ops::invAlpha(Ops::convert(color));
+ if (const_alpha != 255) {
+ sai = Ops::multiplyAlpha8bit(sai, const_alpha);
+ sai = Ops::add(sai, Ops::invAlpha(Ops::scalarFrom8bit(const_alpha)));
}
-}
-void QT_FASTCALL comp_func_solid_DestinationOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
-{
- uint a = 65535 - color.alpha();
- uint ca64k = const_alpha * 257;
- if (const_alpha != 255)
- a = qt_div_65535(a * ca64k) + 65535 - ca64k;
for (int i = 0; i < length; ++i) {
- dest[i] = multiplyAlpha65535(dest[i], a);
+ Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sai));
}
}
-void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+template<class Ops>
+inline static void comp_func_DestinationOut_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- dest[i] = BYTE_MUL(dest[i], qAlpha(~src[i]));
+ auto sia = Ops::invAlpha(Ops::load(&src[i]));
+ Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sia));
}
} else {
- uint cia = 255 - const_alpha;
+ auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
for (int i = 0; i < length; ++i) {
- uint sia = BYTE_MUL(qAlpha(~src[i]), const_alpha) + cia;
- dest[i] = BYTE_MUL(dest[i], sia);
+ auto sia = Ops::multiplyAlpha8bit(Ops::invAlpha(Ops::load(&src[i])), const_alpha);
+ sia = Ops::add(sia, cia);
+ Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sia));
}
}
}
+void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_DestinationOut_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_DestinationOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_DestinationOut_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ comp_func_DestinationOut_template<Argb32Operations>(dest, src, length, const_alpha);
+}
+
void QT_FASTCALL comp_func_DestinationOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- dest[i] = multiplyAlpha65535(dest[i], 65535 - src[i].alpha());
- }
- } else {
- uint ca = const_alpha * 257;
- uint cia = 65535 - ca;
- for (int i = 0; i < length; ++i) {
- uint a = qt_div_65535((65535 - src[i].alpha()) * ca) + cia;
- dest[i] = multiplyAlpha65535(dest[i], a);
- }
- }
+ comp_func_DestinationOut_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
@@ -592,59 +807,57 @@ void QT_FASTCALL comp_func_DestinationOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, c
= s*ca * da + d * (sia*ca + cia)
= s*ca * da + d * (1 - sa*ca)
*/
-void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
-{
- if (const_alpha != 255) {
- color = BYTE_MUL(color, const_alpha);
- }
- uint sia = qAlpha(~color);
- for (int i = 0; i < length; ++i) {
- dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(dest[i]), dest[i], sia);
- }
-}
-
-void QT_FASTCALL comp_func_solid_SourceAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_SourceAtop_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
+ auto c = Ops::convert(color);
if (const_alpha != 255)
- color = multiplyAlpha255(color, const_alpha);
- uint sia = 65535 - color.alpha();
+ c = Ops::multiplyAlpha8bit(c, const_alpha);
+ auto sia = Ops::invAlpha(c);
for (int i = 0; i < length; ++i) {
- dest[i] = interpolate65535(color, dest[i].alpha(), dest[i], sia);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(c, Ops::alpha(d), d, sia));
}
}
-void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+template<class Ops>
+inline static void comp_func_SourceAtop_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- uint s = src[i];
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, qAlpha(~s));
+ auto s = Ops::load(&src[i]);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(s, Ops::alpha(d), d, Ops::invAlpha(s)));
}
} else {
for (int i = 0; i < length; ++i) {
- uint s = BYTE_MUL(src[i], const_alpha);
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(d), d, qAlpha(~s));
+ auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(s, Ops::alpha(d), d, Ops::invAlpha(s)));
}
}
}
+void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_SourceAtop_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_SourceAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_SourceAtop_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ comp_func_SourceAtop_template<Argb32Operations>(dest, src, length, const_alpha);
+}
+
void QT_FASTCALL comp_func_SourceAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- QRgba64 s = src[i];
- QRgba64 d = dest[i];
- dest[i] = interpolate65535(s, d.alpha(), d, 65535 - s.alpha());
- }
- } else {
- for (int i = 0; i < length; ++i) {
- QRgba64 s = multiplyAlpha255(src[i], const_alpha);
- QRgba64 d = dest[i];
- dest[i] = interpolate65535(s, d.alpha(), d, 65535 - s.alpha());
- }
- }
+ comp_func_SourceAtop_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
@@ -652,69 +865,63 @@ void QT_FASTCALL comp_func_SourceAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const
dest = d*sa*ca + s*dia*ca + d *cia
= s*ca * dia + d * (sa*ca + cia)
*/
-void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_DestinationAtop_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
- uint a = qAlpha(color);
+ auto c = Ops::convert(color);
+ auto sa = Ops::alpha(c);
if (const_alpha != 255) {
- color = BYTE_MUL(color, const_alpha);
- a = qAlpha(color) + 255 - const_alpha;
- }
- for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(d, a, color, qAlpha(~d));
+ c = Ops::multiplyAlpha8bit(c, const_alpha);
+ auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
+ sa = Ops::add(Ops::alpha(c), cia);
}
-}
-void QT_FASTCALL comp_func_solid_DestinationAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
-{
- uint a = color.alpha();
- if (const_alpha != 255) {
- color = multiplyAlpha255(color, const_alpha);
- a = color.alpha() + 65535 - (const_alpha * 257);
- }
for (int i = 0; i < length; ++i) {
- QRgba64 d = dest[i];
- dest[i] = interpolate65535(d, a, color, 65535 - d.alpha());
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(c, Ops::invAlpha(d), d, sa));
}
}
-void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+template<class Ops>
+inline static void comp_func_DestinationAtop_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- uint s = src[i];
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(d, qAlpha(s), s, qAlpha(~d));
+ auto s = Ops::load(&src[i]);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, Ops::alpha(s)));
}
} else {
- uint cia = 255 - const_alpha;
+ auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
for (int i = 0; i < length; ++i) {
- uint s = BYTE_MUL(src[i], const_alpha);
- uint d = dest[i];
- uint a = qAlpha(s) + cia;
- dest[i] = INTERPOLATE_PIXEL_255(d, a, s, qAlpha(~d));
+ auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
+ auto d = Ops::load(&dest[i]);
+ auto sa = Ops::add(Ops::alpha(s), cia);
+ Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, sa));
}
}
}
+void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_DestinationAtop_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_DestinationAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_DestinationAtop_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ comp_func_DestinationAtop_template<Argb32Operations>(dest, src, length, const_alpha);
+}
+
void QT_FASTCALL comp_func_DestinationAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- QRgba64 s = src[i];
- QRgba64 d = dest[i];
- dest[i] = interpolate65535(d, s.alpha(), s, 65535 - d.alpha());
- }
- } else {
- uint ca = const_alpha * 257;
- uint cia = 65535 - ca;
- for (int i = 0; i < length; ++i) {
- QRgba64 s = multiplyAlpha65535(src[i], ca);
- QRgba64 d = dest[i];
- uint a = s.alpha() + cia;
- dest[i] = interpolate65535(d, a, s, 65535 - d.alpha());
- }
- }
+ comp_func_DestinationAtop_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
@@ -723,62 +930,58 @@ void QT_FASTCALL comp_func_DestinationAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest,
= s*ca * dia + d * (sia*ca + cia)
= s*ca * dia + d * (1 - sa*ca)
*/
-void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_solid_XOR_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
+ auto c = Ops::convert(color);
if (const_alpha != 255)
- color = BYTE_MUL(color, const_alpha);
- uint sia = qAlpha(~color);
+ c = Ops::multiplyAlpha8bit(c, const_alpha);
+ auto sia = Ops::invAlpha(c);
for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- dest[i] = INTERPOLATE_PIXEL_255(color, qAlpha(~d), d, sia);
+ auto d = Ops::load(&dest[i]);
+ Ops::store(&dest[i], Ops::interpolate(c, Ops::invAlpha(d), d, sia));
}
}
-void QT_FASTCALL comp_func_solid_XOR_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
-{
- if (const_alpha != 255)
- color = multiplyAlpha255(color, const_alpha);
- auto s = CONVERT(color);
- auto sia = CONST(65535 - color.alpha());
- for (int i = 0; i < length; ++i) {
- auto d = LOAD(&dest[i]);
- STORE(&dest[i], interpolate65535(s, INVALPHA(d), d, sia));
- }
-}
-
-void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+template<class Ops>
+inline static void comp_func_XOR_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- uint s = src[i];
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s));
+ auto d = Ops::load(&dest[i]);
+ auto s = Ops::load(&src[i]);
+ Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, Ops::invAlpha(s)));
}
} else {
for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- uint s = BYTE_MUL(src[i], const_alpha);
- dest[i] = INTERPOLATE_PIXEL_255(s, qAlpha(~d), d, qAlpha(~s));
+ auto d = Ops::load(&dest[i]);
+ auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
+ Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, Ops::invAlpha(s)));
}
}
}
+void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
+{
+ comp_func_solid_XOR_template<Argb32Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_solid_XOR_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_XOR_template<Rgba64Operations>(dest, length, color, const_alpha);
+}
+
+void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
+{
+ comp_func_XOR_template<Argb32Operations>(dest, src, length, const_alpha);
+}
+
void QT_FASTCALL comp_func_XOR_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- auto d = LOAD(&dest[i]);
- auto s = LOAD(&src[i]);
- STORE(&dest[i], interpolate65535(s, INVALPHA(d), d, INVALPHA(s)));
- }
- } else {
- for (int i = 0; i < length; ++i) {
- auto d = LOAD(&dest[i]);
- auto s = multiplyAlpha255(LOAD(&src[i]), const_alpha);
- STORE(&dest[i], interpolate65535(s, INVALPHA(d), d, INVALPHA(s)));
- }
- }
+ comp_func_XOR_template<Rgba64Operations>(dest, src, length, const_alpha);
}
struct QFullCoverage {
@@ -827,84 +1030,67 @@ static inline uint mix_alpha_rgb64(uint da, uint sa)
Dca' = Sca.Da + Dca.Sa + Sca.(1 - Da) + Dca.(1 - Sa)
= Sca + Dca
*/
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Plus_impl(uint *dest, int length, uint color, const T &coverage)
+template<class Ops>
+inline static void comp_func_solid_Plus_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
{
- uint s = color;
-
- for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- d = comp_func_Plus_one_pixel(d, s);
- coverage.store(&dest[i], d);
+ auto c = Ops::convert(color);
+ if (const_alpha == 255) {
+ for (int i = 0; i < length; ++i) {
+ auto d = Ops::load(&dest[i]);
+ d = Ops::plus(d, c);
+ Ops::store(&dest[i], d);
+ }
+ } else {
+ uint ia = 255 - const_alpha;
+ for (int i = 0; i < length; ++i) {
+ auto d = Ops::load(&dest[i]);
+ d = Ops::interpolate8bit(Ops::plus(d, c), const_alpha, d, ia);
+ Ops::store(&dest[i], d);
+ }
}
}
-void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
+template<class Ops>
+inline static void comp_func_Plus_template(typename Ops::Type *Q_DECL_RESTRICT dest,
+ const typename Ops::Type *Q_DECL_RESTRICT src,
+ int length, uint const_alpha)
{
- if (const_alpha == 255)
- comp_func_solid_Plus_impl(dest, length, color, QFullCoverage());
- else
- comp_func_solid_Plus_impl(dest, length, color, QPartialCoverage(const_alpha));
-}
-
-void QT_FASTCALL comp_func_solid_Plus_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
-{
- auto b = CONVERT(color);
if (const_alpha == 255) {
for (int i = 0; i < length; ++i) {
- auto a = LOAD(&dest[i]);
- a = addWithSaturation(a, b);
- STORE(&dest[i], a);
+ auto d = Ops::load(&dest[i]);
+ auto s = Ops::load(&src[i]);
+ d = Ops::plus(d, s);
+ Ops::store(&dest[i], d);
}
} else {
+ uint ia = 255 - const_alpha;
for (int i = 0; i < length; ++i) {
- auto a = LOAD(&dest[i]);
- auto d = addWithSaturation(a, b);
- a = interpolate255(d, const_alpha, a, 255 - const_alpha);
- STORE(&dest[i], a);
+ auto d = Ops::load(&dest[i]);
+ auto s = Ops::load(&src[i]);
+ d = Ops::interpolate8bit(Ops::plus(d, s), const_alpha, d, ia);
+ Ops::store(&dest[i], d);
}
}
}
-template <typename T>
-Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Plus_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
+void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
{
- for (int i = 0; i < length; ++i) {
- uint d = dest[i];
- uint s = src[i];
-
- d = comp_func_Plus_one_pixel(d, s);
+ comp_func_solid_Plus_template<Argb32Operations>(dest, length, color, const_alpha);
+}
- coverage.store(&dest[i], d);
- }
+void QT_FASTCALL comp_func_solid_Plus_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
+{
+ comp_func_solid_Plus_template<Rgba64Operations>(dest, length, color, const_alpha);
}
void QT_FASTCALL comp_func_Plus(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255)
- comp_func_Plus_impl(dest, src, length, QFullCoverage());
- else
- comp_func_Plus_impl(dest, src, length, QPartialCoverage(const_alpha));
+ comp_func_Plus_template<Argb32Operations>(dest, src, length, const_alpha);
}
void QT_FASTCALL comp_func_Plus_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
{
- if (const_alpha == 255) {
- for (int i = 0; i < length; ++i) {
- auto a = LOAD(&dest[i]);
- auto b = LOAD(&src[i]);
- a = addWithSaturation(a, b);
- STORE(&dest[i], a);
- }
- } else {
- for (int i = 0; i < length; ++i) {
- auto a = LOAD(&dest[i]);
- auto b = LOAD(&src[i]);
- auto d = addWithSaturation(a, b);
- a = interpolate255(d, const_alpha, a, 255 - const_alpha);
- STORE(&dest[i], a);
- }
- }
+ comp_func_Plus_template<Rgba64Operations>(dest, src, length, const_alpha);
}
/*
diff --git a/src/gui/painting/qcosmeticstroker_p.h b/src/gui/painting/qcosmeticstroker_p.h
index 68f4e00cdc..082ddee30f 100644
--- a/src/gui/painting/qcosmeticstroker_p.h
+++ b/src/gui/painting/qcosmeticstroker_p.h
@@ -85,6 +85,7 @@ public:
// used to avoid drop outs or duplicated points
enum Direction {
+ NoDirection = 0,
TopToBottom = 0x1,
BottomToTop = 0x2,
LeftToRight = 0x4,
@@ -104,7 +105,7 @@ public:
patternOffset(0),
legacyRounding(false),
current_span(0),
- lastDir(LeftToRight),
+ lastDir(NoDirection),
lastAxisAligned(false)
{ setup(); }
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 0f2d163840..0264059a5c 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -73,9 +73,6 @@ enum {
half_point = 1 << 15
};
-// must be multiple of 4 for easier SIMD implementations
-static const int buffer_size = 2048;
-
template<QImage::Format> Q_DECL_CONSTEXPR uint redWidth();
template<QImage::Format> Q_DECL_CONSTEXPR uint redShift();
template<QImage::Format> Q_DECL_CONSTEXPR uint greenWidth();
@@ -94,6 +91,10 @@ template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB4444_Premultiplied>
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; }
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGBX8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGBA8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGBA8888_Premultiplied>() { return 8; }
+
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB16>() { return 11; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB444>() { return 8; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB555>() { return 10; }
@@ -103,6 +104,15 @@ template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB4444_Premultiplied>
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8555_Premultiplied>() { return 18; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8565_Premultiplied>() { return 19; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB6666_Premultiplied>() { return 12; }
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGBX8888>() { return 24; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGBA8888>() { return 24; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGBA8888_Premultiplied>() { return 24; }
+#else
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGBX8888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGBA8888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGBA8888_Premultiplied>() { return 0; }
+#endif
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB16>() { return 6; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB444>() { return 4; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB555>() { return 5; }
@@ -112,6 +122,10 @@ template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB4444_Premultiplie
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8565_Premultiplied>() { return 6; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGBX8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGBA8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGBA8888_Premultiplied>() { return 8; }
+
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB16>() { return 5; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB444>() { return 4; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB555>() { return 5; }
@@ -121,6 +135,15 @@ template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB4444_Premultiplie
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8555_Premultiplied>() { return 13; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8565_Premultiplied>() { return 13; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGBX8888>() { return 16; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGBA8888>() { return 16; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGBA8888_Premultiplied>() { return 16; }
+#else
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGBX8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGBA8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGBA8888_Premultiplied>() { return 8; }
+#endif
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB16>() { return 5; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB444>() { return 4; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB555>() { return 5; }
@@ -130,6 +153,10 @@ template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB4444_Premultiplied
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGBX8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGBA8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGBA8888_Premultiplied>() { return 8; }
+
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB16>() { return 0; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB444>() { return 0; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB555>() { return 0; }
@@ -139,6 +166,15 @@ template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB4444_Premultiplied
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8555_Premultiplied>() { return 8; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8565_Premultiplied>() { return 8; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB6666_Premultiplied>() { return 0; }
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGBX8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGBA8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGBA8888_Premultiplied>() { return 8; }
+#else
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGBX8888>() { return 16; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGBA8888>() { return 16; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGBA8888_Premultiplied>() { return 16; }
+#endif
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB16>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB444>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB555>() { return 0; }
@@ -148,6 +184,10 @@ template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB4444_Premultiplie
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8555_Premultiplied>() { return 8; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8565_Premultiplied>() { return 8; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGBX8888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGBA8888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGBA8888_Premultiplied>() { return 8; }
+
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB16>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB444>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB555>() { return 0; }
@@ -157,138 +197,200 @@ template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB4444_Premultiplie
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8555_Premultiplied>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8565_Premultiplied>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB6666_Premultiplied>() { return 18; }
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGBX8888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGBA8888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGBA8888_Premultiplied>() { return 0; }
+#else
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGBX8888>() { return 24; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGBA8888>() { return 24; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGBA8888_Premultiplied>() { return 24; }
+#endif
-template<QImage::Format> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel();
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB16>() { return QPixelLayout::BPP16; }
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB444>() { return QPixelLayout::BPP16; }
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB555>() { return QPixelLayout::BPP16; }
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB666>() { return QPixelLayout::BPP24; }
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB888>() { return QPixelLayout::BPP24; }
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB4444_Premultiplied>() { return QPixelLayout::BPP16; }
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8555_Premultiplied>() { return QPixelLayout::BPP24; }
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8565_Premultiplied>() { return QPixelLayout::BPP24; }
-template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB6666_Premultiplied>() { return QPixelLayout::BPP24; }
+template<QImage::Format> constexpr QPixelLayout::BPP bitsPerPixel();
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB16>() { return QPixelLayout::BPP16; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB444>() { return QPixelLayout::BPP16; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB555>() { return QPixelLayout::BPP16; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB666>() { return QPixelLayout::BPP24; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB888>() { return QPixelLayout::BPP24; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB4444_Premultiplied>() { return QPixelLayout::BPP16; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8555_Premultiplied>() { return QPixelLayout::BPP24; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8565_Premultiplied>() { return QPixelLayout::BPP24; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB6666_Premultiplied>() { return QPixelLayout::BPP24; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGBX8888>() { return QPixelLayout::BPP32; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGBA8888>() { return QPixelLayout::BPP32; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGBA8888_Premultiplied>() { return QPixelLayout::BPP32; }
-template<QImage::Format Format>
-static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count);
+
+template <QPixelLayout::BPP bpp> static
+uint QT_FASTCALL fetchPixel(const uchar *, int)
{
- auto conversion = [](uint s) {
- // MSVC needs these constexpr defined in here otherwise it will create a capture.
- Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
- Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
- Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+ Q_UNREACHABLE();
+ return 0;
+}
- Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
- Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
- Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP1LSB>(const uchar *src, int index)
+{
+ return (src[index >> 3] >> (index & 7)) & 1;
+}
- Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
- Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
- Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP1MSB>(const uchar *src, int index)
+{
+ return (src[index >> 3] >> (~index & 7)) & 1;
+}
- uint red = (s >> redShift<Format>()) & redMask;
- uint green = (s >> greenShift<Format>()) & greenMask;
- uint blue = (s >> blueShift<Format>()) & blueMask;
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP8>(const uchar *src, int index)
+{
+ return src[index];
+}
- red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
- green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
- blue = (blue << blueLeftShift) | (blue >> blueRightShift);
- return 0xff000000 | red | green | blue;
- };
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP16>(const uchar *src, int index)
+{
+ return reinterpret_cast<const quint16 *>(src)[index];
+}
- UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion);
- return buffer;
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP24>(const uchar *src, int index)
+{
+ return reinterpret_cast<const quint24 *>(src)[index];
}
-template<QImage::Format Format>
-static const QRgba64 *QT_FASTCALL convertToRGB64(QRgba64 *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP32>(const uchar *src, int index)
{
- Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
- Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
- Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+ return reinterpret_cast<const uint *>(src)[index];
+}
- Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
- Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
- Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
+template <>
+inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP64>(const uchar *src, int index)
+{
+ // We have to do the conversion in fetch to fit into a 32bit uint
+ QRgba64 c = reinterpret_cast<const QRgba64 *>(src)[index];
+ return c.toArgb32();
+}
- Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
- Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
- Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
+template <QPixelLayout::BPP bpp>
+static quint64 QT_FASTCALL fetchPixel64(const uchar *src, int index)
+{
+ Q_STATIC_ASSERT(bpp != QPixelLayout::BPP64);
+ return fetchPixel<bpp>(src, index);
+}
- for (int i = 0; i < count; ++i) {
- uint red = (src[i] >> redShift<Format>()) & redMask;
- uint green = (src[i] >> greenShift<Format>()) & greenMask;
- uint blue = (src[i] >> blueShift<Format>()) & blueMask;
+template <QPixelLayout::BPP width> static
+void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel);
- red = ((red << redLeftShift) | (red >> redRightShift));
- green = ((green << greenLeftShift) | (green >> greenRightShift));
- blue = (blue << blueLeftShift) | (blue >> blueRightShift);
- buffer[i] = QRgba64::fromRgba(red, green, blue, 255);
- }
+template <>
+inline void QT_FASTCALL storePixel<QPixelLayout::BPP16>(uchar *dest, int index, uint pixel)
+{
+ reinterpret_cast<quint16 *>(dest)[index] = quint16(pixel);
+}
- return buffer;
+template <>
+inline void QT_FASTCALL storePixel<QPixelLayout::BPP24>(uchar *dest, int index, uint pixel)
+{
+ reinterpret_cast<quint24 *>(dest)[index] = quint24(pixel);
}
+typedef uint (QT_FASTCALL *FetchPixelFunc)(const uchar *src, int index);
+
+static const FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = {
+ 0, // BPPNone
+ fetchPixel<QPixelLayout::BPP1MSB>, // BPP1MSB
+ fetchPixel<QPixelLayout::BPP1LSB>, // BPP1LSB
+ fetchPixel<QPixelLayout::BPP8>, // BPP8
+ fetchPixel<QPixelLayout::BPP16>, // BPP16
+ fetchPixel<QPixelLayout::BPP24>, // BPP24
+ fetchPixel<QPixelLayout::BPP32>, // BPP32
+ fetchPixel<QPixelLayout::BPP64> // BPP64
+};
+
template<QImage::Format Format>
-static const uint *QT_FASTCALL convertARGBPMToARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static Q_ALWAYS_INLINE uint convertPixelToRGB32(uint s)
{
- Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1);
Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
- Q_CONSTEXPR uchar alphaLeftShift = 8 - alphaWidth<Format>();
Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
- Q_CONSTEXPR uchar alphaRightShift = 2 * alphaWidth<Format>() - 8;
Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
- Q_CONSTEXPR bool mustMin = (alphaWidth<Format>() != redWidth<Format>()) ||
- (alphaWidth<Format>() != greenWidth<Format>()) ||
- (alphaWidth<Format>() != blueWidth<Format>());
+ uint red = (s >> redShift<Format>()) & redMask;
+ uint green = (s >> greenShift<Format>()) & greenMask;
+ uint blue = (s >> blueShift<Format>()) & blueMask;
- if (mustMin) {
- for (int i = 0; i < count; ++i) {
- uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask;
- uint red = (src[i] >> redShift<Format>()) & redMask;
- uint green = (src[i] >> greenShift<Format>()) & greenMask;
- uint blue = (src[i] >> blueShift<Format>()) & blueMask;
-
- alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
- red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift));
- green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift));
- blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift));
- buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue;
- }
- } else {
- for (int i = 0; i < count; ++i) {
- uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask;
- uint red = (src[i] >> redShift<Format>()) & redMask;
- uint green = (src[i] >> greenShift<Format>()) & greenMask;
- uint blue = (src[i] >> blueShift<Format>()) & blueMask;
-
- alpha = ((alpha << alphaLeftShift) | (alpha >> alphaRightShift)) << 24;
- red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
- green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
- blue = (blue << blueLeftShift) | (blue >> blueRightShift);
- buffer[i] = alpha | red | green | blue;
- }
+ red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
+ green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+ return 0xff000000 | red | green | blue;
+}
+
+template<QImage::Format Format>
+static void QT_FASTCALL convertToRGB32(uint *buffer, int count, const QVector<QRgb> *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = convertPixelToRGB32<Format>(buffer[i]);
+}
+
+#if defined(__SSE2__) && !defined(__SSSE3__) && QT_COMPILER_SUPPORTS_SSSE3
+extern const uint * QT_FASTCALL fetchPixelsBPP24_ssse3(uint *dest, const uchar*src, int index, int count);
+#endif
+
+template<QImage::Format Format>
+static const uint *QT_FASTCALL fetchRGBToRGB32(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ constexpr QPixelLayout::BPP BPP = bitsPerPixel<Format>();
+#if defined(__SSE2__) && !defined(__SSSE3__) && QT_COMPILER_SUPPORTS_SSSE3
+ if (BPP == QPixelLayout::BPP24 && qCpuHasFeature(SSSE3)) {
+ // With SSE2 can convertToRGB32 be vectorized, but it takes SSSE3
+ // to vectorize the deforested version below.
+ fetchPixelsBPP24_ssse3(buffer, src, index, count);
+ convertToRGB32<Format>(buffer, count, nullptr);
+ return buffer;
}
+#endif
+ for (int i = 0; i < count; ++i)
+ buffer[i] = convertPixelToRGB32<Format>(fetchPixel<BPP>(src, index + i));
+ return buffer;
+}
+template<QImage::Format Format>
+static Q_ALWAYS_INLINE QRgba64 convertPixelToRGB64(uint s)
+{
+ return QRgba64::fromArgb32(convertPixelToRGB32<Format>(s));
+}
+
+template<QImage::Format Format>
+static const QRgba64 *QT_FASTCALL convertToRGB64(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = convertPixelToRGB64<Format>(src[i]);
return buffer;
}
template<QImage::Format Format>
-static const QRgba64 *QT_FASTCALL convertARGBPMToARGB64PM(QRgba64 *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static const QRgba64 *QT_FASTCALL fetchRGBToRGB64(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = convertPixelToRGB64<Format>(fetchPixel<bitsPerPixel<Format>()>(src, index + i));
+ return buffer;
+}
+
+template<QImage::Format Format>
+static Q_ALWAYS_INLINE uint convertPixelToARGB32PM(uint s)
{
Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1);
Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
@@ -309,62 +411,101 @@ static const QRgba64 *QT_FASTCALL convertARGBPMToARGB64PM(QRgba64 *buffer, const
(alphaWidth<Format>() != greenWidth<Format>()) ||
(alphaWidth<Format>() != blueWidth<Format>());
+ uint alpha = (s >> alphaShift<Format>()) & alphaMask;
+ uint red = (s >> redShift<Format>()) & redMask;
+ uint green = (s >> greenShift<Format>()) & greenMask;
+ uint blue = (s >> blueShift<Format>()) & blueMask;
+
+ alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
+ red = (red << redLeftShift) | (red >> redRightShift);
+ green = (green << greenLeftShift) | (green >> greenRightShift);
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+
if (mustMin) {
- for (int i = 0; i < count; ++i) {
- uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask;
- uint red = (src[i] >> redShift<Format>()) & redMask;
- uint green = (src[i] >> greenShift<Format>()) & greenMask;
- uint blue = (src[i] >> blueShift<Format>()) & blueMask;
-
- alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
- red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift));
- green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift));
- blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift));
- buffer[i] = QRgba64::fromRgba(red, green, blue, alpha);
- }
- } else {
- for (int i = 0; i < count; ++i) {
- uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask;
- uint red = (src[i] >> redShift<Format>()) & redMask;
- uint green = (src[i] >> greenShift<Format>()) & greenMask;
- uint blue = (src[i] >> blueShift<Format>()) & blueMask;
-
- alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
- red = (red << redLeftShift) | (red >> redRightShift);
- green = (green << greenLeftShift) | (green >> greenRightShift);
- blue = (blue << blueLeftShift) | (blue >> blueRightShift);
- buffer[i] = QRgba64::fromRgba(red, green, blue, alpha);
- }
+ red = qMin(alpha, red);
+ green = qMin(alpha, green);
+ blue = qMin(alpha, blue);
}
+ return (alpha << 24) | (red << 16) | (green << 8) | blue;
+}
+
+template<QImage::Format Format>
+static void QT_FASTCALL convertARGBPMToARGB32PM(uint *buffer, int count, const QVector<QRgb> *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = convertPixelToARGB32PM<Format>(buffer[i]);
+}
+
+template<QImage::Format Format>
+static const uint *QT_FASTCALL fetchARGBPMToARGB32PM(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ constexpr QPixelLayout::BPP BPP = bitsPerPixel<Format>();
+#if defined(__SSE2__) && !defined(__SSSE3__) && QT_COMPILER_SUPPORTS_SSSE3
+ if (BPP == QPixelLayout::BPP24 && qCpuHasFeature(SSSE3)) {
+ // With SSE2 can convertToRGB32 be vectorized, but it takes SSSE3
+ // to vectorize the deforested version below.
+ fetchPixelsBPP24_ssse3(buffer, src, index, count);
+ convertARGBPMToARGB32PM<Format>(buffer, count, nullptr);
+ return buffer;
+ }
+#endif
+ for (int i = 0; i < count; ++i)
+ buffer[i] = convertPixelToARGB32PM<Format>(fetchPixel<BPP>(src, index + i));
+ return buffer;
+}
+
+template<QImage::Format Format>
+static Q_ALWAYS_INLINE QRgba64 convertPixelToRGBA64PM(uint s)
+{
+ return QRgba64::fromArgb32(convertPixelToARGB32PM<Format>(s));
+}
+
+template<QImage::Format Format>
+static const QRgba64 *QT_FASTCALL convertARGBPMToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = convertPixelToRGB64<Format>(src[i]);
+ return buffer;
+}
+
+template<QImage::Format Format>
+static const QRgba64 *QT_FASTCALL fetchARGBPMToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ constexpr QPixelLayout::BPP bpp = bitsPerPixel<Format>();
+ for (int i = 0; i < count; ++i)
+ buffer[i] = convertPixelToRGBA64PM<Format>(fetchPixel<bpp>(src, index + i));
return buffer;
}
template<QImage::Format Format, bool fromRGB>
-static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *dither)
+static void QT_FASTCALL storeRGBFromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *dither)
{
Q_CONSTEXPR uchar rWidth = redWidth<Format>();
Q_CONSTEXPR uchar gWidth = greenWidth<Format>();
Q_CONSTEXPR uchar bWidth = blueWidth<Format>();
+ constexpr QPixelLayout::BPP BPP = bitsPerPixel<Format>();
// RGB32 -> RGB888 is not a precision loss.
if (!dither || (rWidth == 8 && gWidth == 8 && bWidth == 8)) {
- auto conversion = [](uint s) {
- const uint c = fromRGB ? s : qUnpremultiply(s);
- Q_CONSTEXPR uint rMask = (1 << redWidth<Format>()) - 1;
- Q_CONSTEXPR uint gMask = (1 << greenWidth<Format>()) - 1;
- Q_CONSTEXPR uint bMask = (1 << blueWidth<Format>()) - 1;
- Q_CONSTEXPR uchar rRightShift = 24 - redWidth<Format>();
- Q_CONSTEXPR uchar gRightShift = 16 - greenWidth<Format>();
- Q_CONSTEXPR uchar bRightShift = 8 - blueWidth<Format>();
+ Q_CONSTEXPR uint rMask = (1 << redWidth<Format>()) - 1;
+ Q_CONSTEXPR uint gMask = (1 << greenWidth<Format>()) - 1;
+ Q_CONSTEXPR uint bMask = (1 << blueWidth<Format>()) - 1;
+ Q_CONSTEXPR uchar rRightShift = 24 - redWidth<Format>();
+ Q_CONSTEXPR uchar gRightShift = 16 - greenWidth<Format>();
+ Q_CONSTEXPR uchar bRightShift = 8 - blueWidth<Format>();
+ for (int i = 0; i < count; ++i) {
+ const uint c = fromRGB ? src[i] : qUnpremultiply(src[i]);
const uint r = ((c >> rRightShift) & rMask) << redShift<Format>();
const uint g = ((c >> gRightShift) & gMask) << greenShift<Format>();
const uint b = ((c >> bRightShift) & bMask) << blueShift<Format>();
- return r | g | b;
+ storePixel<BPP>(dest, index + i, r | g | b);
};
- UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion);
} else {
// We do ordered dither by using a rounding conversion, but instead of
// adding half of input precision, we add the adjusted result from the
@@ -384,38 +525,39 @@ static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *
r = (r + ((dr - r) >> rWidth) + 1) >> (8 - rWidth);
g = (g + ((dg - g) >> gWidth) + 1) >> (8 - gWidth);
b = (b + ((db - b) >> bWidth) + 1) >> (8 - bWidth);
- buffer[i] = (r << redShift<Format>())
- | (g << greenShift<Format>())
- | (b << blueShift<Format>());
+ const uint s = (r << redShift<Format>())
+ | (g << greenShift<Format>())
+ | (b << blueShift<Format>());
+ storePixel<BPP>(dest, index + i, s);
}
}
- return buffer;
}
template<QImage::Format Format, bool fromRGB>
-static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *dither)
+static void QT_FASTCALL storeARGBPMFromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *dither)
{
+ constexpr QPixelLayout::BPP BPP = bitsPerPixel<Format>();
if (!dither) {
- auto conversion = [](uint c) {
- Q_CONSTEXPR uint aMask = (1 << alphaWidth<Format>()) - 1;
- Q_CONSTEXPR uint rMask = (1 << redWidth<Format>()) - 1;
- Q_CONSTEXPR uint gMask = (1 << greenWidth<Format>()) - 1;
- Q_CONSTEXPR uint bMask = (1 << blueWidth<Format>()) - 1;
-
- Q_CONSTEXPR uchar aRightShift = 32 - alphaWidth<Format>();
- Q_CONSTEXPR uchar rRightShift = 24 - redWidth<Format>();
- Q_CONSTEXPR uchar gRightShift = 16 - greenWidth<Format>();
- Q_CONSTEXPR uchar bRightShift = 8 - blueWidth<Format>();
-
- Q_CONSTEXPR uint aOpaque = aMask << alphaShift<Format>();
+ Q_CONSTEXPR uint aMask = (1 << alphaWidth<Format>()) - 1;
+ Q_CONSTEXPR uint rMask = (1 << redWidth<Format>()) - 1;
+ Q_CONSTEXPR uint gMask = (1 << greenWidth<Format>()) - 1;
+ Q_CONSTEXPR uint bMask = (1 << blueWidth<Format>()) - 1;
+
+ Q_CONSTEXPR uchar aRightShift = 32 - alphaWidth<Format>();
+ Q_CONSTEXPR uchar rRightShift = 24 - redWidth<Format>();
+ Q_CONSTEXPR uchar gRightShift = 16 - greenWidth<Format>();
+ Q_CONSTEXPR uchar bRightShift = 8 - blueWidth<Format>();
+
+ Q_CONSTEXPR uint aOpaque = aMask << alphaShift<Format>();
+ for (int i = 0; i < count; ++i) {
+ const uint c = src[i];
const uint a = fromRGB ? aOpaque : (((c >> aRightShift) & aMask) << alphaShift<Format>());
const uint r = ((c >> rRightShift) & rMask) << redShift<Format>();
const uint g = ((c >> gRightShift) & gMask) << greenShift<Format>();
const uint b = ((c >> bRightShift) & bMask) << blueShift<Format>();
- return a | r | g | b;
+ storePixel<BPP>(dest, index + i, a | r | g | b);
};
- UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion);
} else {
Q_CONSTEXPR uchar aWidth = alphaWidth<Format>();
Q_CONSTEXPR uchar rWidth = redWidth<Format>();
@@ -441,59 +583,147 @@ static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uin
r = (r + ((dr - r) >> rWidth) + 1) >> (8 - rWidth);
g = (g + ((dg - g) >> gWidth) + 1) >> (8 - gWidth);
b = (b + ((db - b) >> bWidth) + 1) >> (8 - bWidth);
- buffer[i] = (a << alphaShift<Format>())
- | (r << redShift<Format>())
- | (g << greenShift<Format>())
- | (b << blueShift<Format>());
+ uint s = (a << alphaShift<Format>())
+ | (r << redShift<Format>())
+ | (g << greenShift<Format>())
+ | (b << blueShift<Format>());
+ storePixel<BPP>(dest, index + i, s);
}
}
- return buffer;
}
+template<QImage::Format Format>
+static void QT_FASTCALL rbSwap(uchar *dst, const uchar *src, int count)
+{
+ Q_CONSTEXPR uchar aWidth = alphaWidth<Format>();
+ Q_CONSTEXPR uchar aShift = alphaShift<Format>();
+ Q_CONSTEXPR uchar rWidth = redWidth<Format>();
+ Q_CONSTEXPR uchar rShift = redShift<Format>();
+ Q_CONSTEXPR uchar gWidth = greenWidth<Format>();
+ Q_CONSTEXPR uchar gShift = greenShift<Format>();
+ Q_CONSTEXPR uchar bWidth = blueWidth<Format>();
+ Q_CONSTEXPR uchar bShift = blueShift<Format>();
#ifdef Q_COMPILER_CONSTEXPR
+ Q_STATIC_ASSERT(rWidth == bWidth);
+#endif
+ Q_CONSTEXPR uint redBlueMask = (1 << rWidth) - 1;
+ Q_CONSTEXPR uint alphaGreenMask = (((1 << aWidth) - 1) << aShift)
+ | (((1 << gWidth) - 1) << gShift);
+ constexpr QPixelLayout::BPP bpp = bitsPerPixel<Format>();
+
+ for (int i = 0; i < count; ++i) {
+ const uint c = fetchPixel<bpp>(src, i);
+ const uint r = (c >> rShift) & redBlueMask;
+ const uint b = (c >> bShift) & redBlueMask;
+ const uint t = (c & alphaGreenMask)
+ | (r << bShift)
+ | (b << rShift);
+ storePixel<bpp>(dst, i, t);
+ }
+}
+
+static void QT_FASTCALL rbSwap_rgb32(uchar *d, const uchar *s, int count)
+{
+ const uint *src = reinterpret_cast<const uint *>(s);
+ uint *dest = reinterpret_cast<uint *>(d);
+ for (int i = 0; i < count; ++i) {
+ const uint c = src[i];
+ const uint ag = c & 0xff00ff00;
+ const uint rb = c & 0x00ff00ff;
+ dest[i] = ag | (rb << 16) | (rb >> 16);
+ }
+}
+
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+template<>
+void QT_FASTCALL rbSwap<QImage::Format_RGBA8888>(uchar *d, const uchar *s, int count)
+{
+ return rbSwap_rgb32(d, s, count);
+}
+#else
+template<>
+void QT_FASTCALL rbSwap<QImage::Format_RGBA8888>(uchar *d, const uchar *s, int count)
+{
+ const uint *src = reinterpret_cast<const uint *>(s);
+ uint *dest = reinterpret_cast<uint *>(d);
+ for (int i = 0; i < count; ++i) {
+ const uint c = src[i];
+ const uint rb = c & 0xff00ff00;
+ const uint ga = c & 0x00ff00ff;
+ dest[i] = ga | (rb << 16) | (rb >> 16);
+ }
+}
+#endif
+
+static void QT_FASTCALL rbSwap_rgb30(uchar *d, const uchar *s, int count)
+{
+ const uint *src = reinterpret_cast<const uint *>(s);
+ uint *dest = reinterpret_cast<uint *>(d);
+ for (int i = 0; i < count; ++i)
+ dest[i] = qRgbSwapRgb30(src[i]);
+}
template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB()
{
return QPixelLayout{
- uchar(redWidth<Format>()), uchar(redShift<Format>()),
- uchar(greenWidth<Format>()), uchar(greenShift<Format>()),
- uchar(blueWidth<Format>()), uchar(blueShift<Format>()),
- 0, 0,
- false, bitsPerPixel<Format>(),
+ false,
+ false,
+ bitsPerPixel<Format>(),
+ rbSwap<Format>,
convertToRGB32<Format>,
- convertRGBFromARGB32PM<Format, false>,
- convertRGBFromARGB32PM<Format, true>,
- convertToRGB64<Format>
+ convertToRGB64<Format>,
+ fetchRGBToRGB32<Format>,
+ fetchRGBToRGB64<Format>,
+ storeRGBFromARGB32PM<Format, false>,
+ storeRGBFromARGB32PM<Format, true>
};
}
template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutARGBPM()
{
return QPixelLayout{
- uchar(redWidth<Format>()), uchar(redShift<Format>()),
- uchar(greenWidth<Format>()), uchar(greenShift<Format>()),
- uchar(blueWidth<Format>()), uchar(blueShift<Format>()),
- uchar(alphaWidth<Format>()), uchar(alphaShift<Format>()),
- true, bitsPerPixel<Format>(),
+ true,
+ true,
+ bitsPerPixel<Format>(),
+ rbSwap<Format>,
convertARGBPMToARGB32PM<Format>,
- convertARGBPMFromARGB32PM<Format, false>,
- convertARGBPMFromARGB32PM<Format, true>,
- convertARGBPMToARGB64PM<Format>
+ convertARGBPMToRGBA64PM<Format>,
+ fetchARGBPMToARGB32PM<Format>,
+ fetchARGBPMToRGBA64PM<Format>,
+ storeARGBPMFromARGB32PM<Format, false>,
+ storeARGBPMFromARGB32PM<Format, true>
};
}
-#endif
-
-// To convert in place, let 'dest' and 'src' be the same.
-static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *clut, QDitherInfo *)
+static void QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, int count, const QVector<QRgb> *clut)
{
for (int i = 0; i < count; ++i)
- buffer[i] = qPremultiply(clut->at(src[i]));
+ buffer[i] = qPremultiply(clut->at(buffer[i]));
+}
+
+template<QPixelLayout::BPP BPP>
+static const uint *QT_FASTCALL fetchIndexedToARGB32PM(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *clut, QDitherInfo *)
+{
+ for (int i = 0; i < count; ++i) {
+ const uint s = fetchPixel<BPP>(src, index + i);
+ buffer[i] = qPremultiply(clut->at(s));
+ }
+ return buffer;
+}
+
+template<QPixelLayout::BPP BPP>
+static const QRgba64 *QT_FASTCALL fetchIndexedToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *clut, QDitherInfo *)
+{
+ for (int i = 0; i < count; ++i) {
+ const uint s = fetchPixel<BPP>(src, index + i);
+ buffer[i] = QRgba64::fromArgb32(clut->at(s)).premultiplied();
+ }
return buffer;
}
-static const QRgba64 *QT_FASTCALL convertIndexedToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+static const QRgba64 *QT_FASTCALL convertIndexedToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *clut, QDitherInfo *)
{
for (int i = 0; i < count; ++i)
@@ -501,44 +731,77 @@ static const QRgba64 *QT_FASTCALL convertIndexedToARGB64PM(QRgba64 *buffer, cons
return buffer;
}
-static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL convertPassThrough(uint *, int, const QVector<QRgb> *)
{
- return src;
}
-static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static const uint *QT_FASTCALL fetchPassThrough(uint *, const uchar *src, int index, int,
+ const QVector<QRgb> *, QDitherInfo *)
{
- return qt_convertARGB32ToARGB32PM(buffer, src, count);
+ return reinterpret_cast<const uint *>(src) + index;
}
-static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static const QRgba64 *QT_FASTCALL fetchPassThrough64(QRgba64 *, const uchar *src, int index, int,
+ const QVector<QRgb> *, QDitherInfo *)
{
- UNALIASED_CONVERSION_LOOP(buffer, src, count, RGBA2ARGB);
- return buffer;
+ return reinterpret_cast<const QRgba64 *>(src) + index;
}
-static const uint *QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL storePassThrough(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- return qt_convertRGBA8888ToARGB32PM(buffer, src, count);
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ if (d != src)
+ memcpy(d, src, count * sizeof(uint));
}
-static const uint *QT_FASTCALL convertAlpha8ToRGB32(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, int count, const QVector<QRgb> *)
+{
+ qt_convertARGB32ToARGB32PM(buffer, buffer, count);
+}
+
+static const uint *QT_FASTCALL fetchARGB32ToARGB32PM(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ return qt_convertARGB32ToARGB32PM(buffer, reinterpret_cast<const uint *>(src) + index, count);
+}
+
+static void QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, int count, const QVector<QRgb> *)
{
for (int i = 0; i < count; ++i)
- buffer[i] = qRgba(0, 0, 0, src[i]);
+ buffer[i] = RGBA2ARGB(buffer[i]);
+}
+
+static const uint *QT_FASTCALL fetchRGBA8888PMToARGB32PM(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ const uint *s = reinterpret_cast<const uint *>(src) + index;
+ UNALIASED_CONVERSION_LOOP(buffer, s, count, RGBA2ARGB);
return buffer;
}
-static const uint *QT_FASTCALL convertGrayscale8ToRGB32(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, int count, const QVector<QRgb> *)
+{
+ qt_convertRGBA8888ToARGB32PM(buffer, buffer, count);
+}
+
+static const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ return qt_convertRGBA8888ToARGB32PM(buffer, reinterpret_cast<const uint *>(src) + index, count);
+}
+
+static void QT_FASTCALL convertAlpha8ToRGB32(uint *buffer, int count, const QVector<QRgb> *)
{
for (int i = 0; i < count; ++i)
- buffer[i] = qRgb(src[i], src[i], src[i]);
+ buffer[i] = qRgba(0, 0, 0, buffer[i]);
+}
+
+static const uint *QT_FASTCALL fetchAlpha8ToRGB32(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qRgba(0, 0, 0, src[index + i]);
return buffer;
}
@@ -549,6 +812,31 @@ static const QRgba64 *QT_FASTCALL convertAlpha8ToRGB64(QRgba64 *buffer, const ui
buffer[i] = QRgba64::fromRgba(0, 0, 0, src[i]);
return buffer;
}
+static const QRgba64 *QT_FASTCALL fetchAlpha8ToRGB64(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromRgba(0, 0, 0, src[index + i]);
+ return buffer;
+}
+
+static void QT_FASTCALL convertGrayscale8ToRGB32(uint *buffer, int count, const QVector<QRgb> *)
+{
+ for (int i = 0; i < count; ++i) {
+ const uint s = buffer[i];
+ buffer[i] = qRgb(s, s, s);
+ }
+}
+
+static const uint *QT_FASTCALL fetchGrayscale8ToRGB32(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ for (int i = 0; i < count; ++i) {
+ const uint s = src[index + i];
+ buffer[i] = qRgb(s, s, s);
+ }
+ return buffer;
+}
static const QRgba64 *QT_FASTCALL convertGrayscale8ToRGB64(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
@@ -558,24 +846,33 @@ static const QRgba64 *QT_FASTCALL convertGrayscale8ToRGB64(QRgba64 *buffer, cons
return buffer;
}
-static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count,
+static const QRgba64 *QT_FASTCALL fetchGrayscale8ToRGB64(QRgba64 *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qUnpremultiply(src[i]);
+ for (int i = 0; i < count; ++i) {
+ const uint s = src[index + i];
+ buffer[i] = QRgba64::fromRgba(s, s, s, 255);
+ }
return buffer;
}
-static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL storeARGB32FromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- UNALIASED_CONVERSION_LOOP(buffer, src, count, ARGB2RGBA);
- return buffer;
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ UNALIASED_CONVERSION_LOOP(d, src, count, [](uint c) { return qUnpremultiply(c); });
+}
+
+static void QT_FASTCALL storeRGBA8888PMFromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ UNALIASED_CONVERSION_LOOP(d, src, count, ARGB2RGBA);
}
#ifdef __SSE2__
template<bool RGBA, bool maskAlpha>
-static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count)
+static inline void qConvertARGB32PMToRGBA64PM_sse2(QRgba64 *buffer, const uint *src, int count)
{
if (count <= 0)
return;
@@ -618,6 +915,66 @@ static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint *
*buffer++ = QRgba64::fromArgb32(s);
}
}
+
+template<QtPixelOrder PixelOrder>
+static inline void qConvertRGBA64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *buffer, int count)
+{
+ const __m128i gmask = _mm_set1_epi32(0x000ffc00);
+ const __m128i cmask = _mm_set1_epi32(0x000003ff);
+ int i = 0;
+ __m128i vr, vg, vb, va;
+ for (; i < count && uintptr_t(buffer) & 0xF; ++i) {
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+ }
+
+ for (; i < count-15; i += 16) {
+ // Repremultiplying is really expensive and hard to do in SIMD without AVX2,
+ // so we try to avoid it by checking if it is needed 16 samples at a time.
+ __m128i vOr = _mm_set1_epi32(0);
+ __m128i vAnd = _mm_set1_epi32(0xffffffff);
+ for (int j = 0; j < 16; j += 2) {
+ __m128i vs = _mm_load_si128((const __m128i*)(buffer + j));
+ vOr = _mm_or_si128(vOr, vs);
+ vAnd = _mm_and_si128(vAnd, vs);
+ }
+ const quint16 orAlpha = ((uint)_mm_extract_epi16(vOr, 3)) | ((uint)_mm_extract_epi16(vOr, 7));
+ const quint16 andAlpha = ((uint)_mm_extract_epi16(vAnd, 3)) & ((uint)_mm_extract_epi16(vAnd, 7));
+
+ if (andAlpha == 0xffff) {
+ for (int j = 0; j < 16; j += 2) {
+ __m128i vs = _mm_load_si128((const __m128i*)buffer);
+ buffer += 2;
+ vr = _mm_srli_epi64(vs, 6);
+ vg = _mm_srli_epi64(vs, 16 + 6 - 10);
+ vb = _mm_srli_epi64(vs, 32 + 6);
+ vr = _mm_and_si128(vr, cmask);
+ vg = _mm_and_si128(vg, gmask);
+ vb = _mm_and_si128(vb, cmask);
+ va = _mm_srli_epi64(vs, 48 + 14);
+ if (PixelOrder == PixelOrderRGB)
+ vr = _mm_slli_epi32(vr, 20);
+ else
+ vb = _mm_slli_epi32(vb, 20);
+ va = _mm_slli_epi32(va, 30);
+ __m128i vd = _mm_or_si128(_mm_or_si128(vr, vg), _mm_or_si128(vb, va));
+ vd = _mm_shuffle_epi32(vd, _MM_SHUFFLE(3, 1, 2, 0));
+ _mm_storel_epi64((__m128i*)dest, vd);
+ dest += 2;
+ }
+ } else if (orAlpha == 0) {
+ for (int j = 0; j < 16; ++j) {
+ *dest++ = 0;
+ buffer++;
+ }
+ } else {
+ for (int j = 0; j < 16; ++j)
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+ }
+ }
+
+ SIMD_EPILOGUE(i, count, 15)
+ *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
+}
#elif defined(__ARM_NEON__)
template<bool RGBA, bool maskAlpha>
static inline void qConvertARGB32PMToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count)
@@ -671,7 +1028,7 @@ static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uin
const QVector<QRgb> *, QDitherInfo *)
{
#ifdef __SSE2__
- qConvertARGB32PMToARGB64PM_sse2<false, true>(buffer, src, count);
+ qConvertARGB32PMToRGBA64PM_sse2<false, true>(buffer, src, count);
#elif defined(__ARM_NEON__)
qConvertARGB32PMToRGBA64PM_neon<false, true>(buffer, src, count);
#else
@@ -681,11 +1038,17 @@ static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uin
return buffer;
}
-static const QRgba64 *QT_FASTCALL convertARGB32ToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+static const QRgba64 *QT_FASTCALL fetchRGB32ToRGB64(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ return convertRGB32ToRGB64(buffer, reinterpret_cast<const uint *>(src) + index, count, nullptr, nullptr);
+}
+
+static const QRgba64 *QT_FASTCALL convertARGB32ToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
#ifdef __SSE2__
- qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count);
+ qConvertARGB32PMToRGBA64PM_sse2<false, false>(buffer, src, count);
for (int i = 0; i < count; ++i)
buffer[i] = buffer[i].premultiplied();
#elif defined(__ARM_NEON__)
@@ -699,11 +1062,17 @@ static const QRgba64 *QT_FASTCALL convertARGB32ToARGB64PM(QRgba64 *buffer, const
return buffer;
}
-static const QRgba64 *QT_FASTCALL convertARGB32PMToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+static const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ return convertARGB32ToRGBA64PM(buffer, reinterpret_cast<const uint *>(src) + index, count, nullptr, nullptr);
+}
+
+static const QRgba64 *QT_FASTCALL convertARGB32PMToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
#ifdef __SSE2__
- qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count);
+ qConvertARGB32PMToRGBA64PM_sse2<false, false>(buffer, src, count);
#elif defined(__ARM_NEON__)
qConvertARGB32PMToRGBA64PM_neon<false, false>(buffer, src, count);
#else
@@ -713,11 +1082,36 @@ static const QRgba64 *QT_FASTCALL convertARGB32PMToARGB64PM(QRgba64 *buffer, con
return buffer;
}
-static const QRgba64 *QT_FASTCALL convertRGBA8888ToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+static const QRgba64 *QT_FASTCALL fetchARGB32PMToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ return convertARGB32PMToRGBA64PM(buffer, reinterpret_cast<const uint *>(src) + index, count, nullptr, nullptr);
+}
+
+static void convertRGBA64ToRGBA64PM(QRgba64 *buffer, int count)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = buffer[i].premultiplied();
+}
+
+static void convertRGBA64PMToRGBA64PM(QRgba64 *, int)
+{
+}
+
+static const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ const QRgba64 *s = reinterpret_cast<const QRgba64 *>(src) + index;
+ for (int i = 0; i < count; ++i)
+ buffer[i] = QRgba64::fromRgba64(s[i]).premultiplied();
+ return buffer;
+}
+
+static const QRgba64 *QT_FASTCALL convertRGBA8888ToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
#ifdef __SSE2__
- qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count);
+ qConvertARGB32PMToRGBA64PM_sse2<true, false>(buffer, src, count);
for (int i = 0; i < count; ++i)
buffer[i] = buffer[i].premultiplied();
#elif defined(__ARM_NEON__)
@@ -731,11 +1125,17 @@ static const QRgba64 *QT_FASTCALL convertRGBA8888ToARGB64PM(QRgba64 *buffer, con
return buffer;
}
-static const QRgba64 *QT_FASTCALL convertRGBA8888PMToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+static const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ return convertRGBA8888ToRGBA64PM(buffer, reinterpret_cast<const uint *>(src) + index, count, nullptr, nullptr);
+}
+
+static const QRgba64 *QT_FASTCALL convertRGBA8888PMToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
#ifdef __SSE2__
- qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count);
+ qConvertARGB32PMToRGBA64PM_sse2<true, false>(buffer, src, count);
#elif defined(__ARM_NEON__)
qConvertARGB32PMToRGBA64PM_neon<true, false>(buffer, src, count);
#else
@@ -745,33 +1145,45 @@ static const QRgba64 *QT_FASTCALL convertRGBA8888PMToARGB64PM(QRgba64 *buffer, c
return buffer;
}
-static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static const QRgba64 *QT_FASTCALL fetchRGBA8888PMToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = ARGB2RGBA(qUnpremultiply(src[i]));
- return buffer;
+ return convertRGBA8888PMToRGBA64PM(buffer, reinterpret_cast<const uint *>(src) + index, count, nullptr, nullptr);
}
-static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL storeRGBA8888FromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- UNALIASED_CONVERSION_LOOP(buffer, src, count, [](uint c) { return ARGB2RGBA(0xff000000 | c); });
- return buffer;
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ UNALIASED_CONVERSION_LOOP(d, src, count, [](uint c) { return ARGB2RGBA(qUnpremultiply(c)); });
}
-static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL storeRGBXFromRGB32(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ UNALIASED_CONVERSION_LOOP(d, src, count, [](uint c) { return ARGB2RGBA(0xff000000 | c); });
+}
+
+static void QT_FASTCALL storeRGBXFromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ UNALIASED_CONVERSION_LOOP(d, src, count, [](uint c) { return ARGB2RGBA(0xff000000 | qUnpremultiply(c)); });
+}
+
+template<QtPixelOrder PixelOrder>
+static void QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, int count, const QVector<QRgb> *)
{
for (int i = 0; i < count; ++i)
- buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply(src[i]));
- return buffer;
+ buffer[i] = qConvertA2rgb30ToArgb32<PixelOrder>(buffer[i]);
}
template<QtPixelOrder PixelOrder>
-static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *dither)
+static const uint *QT_FASTCALL fetchA2RGB30PMToARGB32PM(uint *buffer, const uchar *s, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *dither)
{
+ const uint *src = reinterpret_cast<const uint *>(s) + index;
if (!dither) {
UNALIASED_CONVERSION_LOOP(buffer, src, count, qConvertA2rgb30ToArgb32<PixelOrder>);
} else {
@@ -796,7 +1208,7 @@ static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const ui
#ifdef __SSE2__
template<QtPixelOrder PixelOrder>
-static inline void qConvertA2RGB30PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count)
+static inline void qConvertA2RGB30PMToRGBA64PM_sse2(QRgba64 *buffer, const uint *src, int count)
{
if (count <= 0)
return;
@@ -839,11 +1251,11 @@ static inline void qConvertA2RGB30PMToARGB64PM_sse2(QRgba64 *buffer, const uint
#endif
template<QtPixelOrder PixelOrder>
-static const QRgba64 *QT_FASTCALL convertA2RGB30PMToARGB64PM(QRgba64 *buffer, const uint *src, int count,
+static const QRgba64 *QT_FASTCALL convertA2RGB30PMToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
#ifdef __SSE2__
- qConvertA2RGB30PMToARGB64PM_sse2<PixelOrder>(buffer, src, count);
+ qConvertA2RGB30PMToRGBA64PM_sse2<PixelOrder>(buffer, src, count);
#else
for (int i = 0; i < count; ++i)
buffer[i] = qConvertA2rgb30ToRgb64<PixelOrder>(src[i]);
@@ -852,290 +1264,334 @@ static const QRgba64 *QT_FASTCALL convertA2RGB30PMToARGB64PM(QRgba64 *buffer, co
}
template<QtPixelOrder PixelOrder>
-static const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static const QRgba64 *QT_FASTCALL fetchA2RGB30PMToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- UNALIASED_CONVERSION_LOOP(buffer, src, count, qConvertArgb32ToA2rgb30<PixelOrder>);
- return buffer;
+ return convertA2RGB30PMToRGBA64PM<PixelOrder>(buffer, reinterpret_cast<const uint *>(src) + index, count, nullptr, nullptr);
}
template<QtPixelOrder PixelOrder>
-static const uint *QT_FASTCALL convertRGB30FromRGB32(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL storeA2RGB30PMFromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qConvertRgb32ToRgb30<PixelOrder>(src[i]);
- return buffer;
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ UNALIASED_CONVERSION_LOOP(d, src, count, qConvertArgb32ToA2rgb30<PixelOrder>);
}
template<QtPixelOrder PixelOrder>
-static const uint *QT_FASTCALL convertRGB30FromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static void QT_FASTCALL storeRGB30FromRGB32(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- UNALIASED_CONVERSION_LOOP(buffer, src, count, qConvertRgb32ToRgb30<PixelOrder>);
- return buffer;
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ UNALIASED_CONVERSION_LOOP(d, src, count, qConvertRgb32ToRgb30<PixelOrder>);
}
-static const uint *QT_FASTCALL convertAlpha8FromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+template<QtPixelOrder PixelOrder>
+static void QT_FASTCALL storeRGB30FromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qAlpha(src[i]);
- return buffer;
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ UNALIASED_CONVERSION_LOOP(d, src, count, qConvertRgb32ToRgb30<PixelOrder>);
}
-static const uint *QT_FASTCALL convertGrayscale8FromRGB32(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+template<bool RGBA>
+void qt_convertRGBA64ToARGB32(uint *dst, const QRgba64 *src, int count)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qGray(src[i]);
- return buffer;
+ int i = 0;
+#ifdef __SSE2__
+ if (((uintptr_t)dst & 0x7) && count > 0) {
+ uint s = (*src++).toArgb32();
+ if (RGBA)
+ s = ARGB2RGBA(s);
+ *dst++ = s;
+ i++;
+ }
+ const __m128i vhalf = _mm_set1_epi32(0x80);
+ const __m128i vzero = _mm_setzero_si128();
+ for (; i < count-1; i += 2) {
+ __m128i vs = _mm_loadu_si128((const __m128i*)src);
+ src += 2;
+ if (!RGBA) {
+ vs = _mm_shufflelo_epi16(vs, _MM_SHUFFLE(3, 0, 1, 2));
+ vs = _mm_shufflehi_epi16(vs, _MM_SHUFFLE(3, 0, 1, 2));
+ }
+ __m128i v1 = _mm_unpacklo_epi16(vs, vzero);
+ __m128i v2 = _mm_unpackhi_epi16(vs, vzero);
+ v1 = _mm_add_epi32(v1, vhalf);
+ v2 = _mm_add_epi32(v2, vhalf);
+ v1 = _mm_sub_epi32(v1, _mm_srli_epi32(v1, 8));
+ v2 = _mm_sub_epi32(v2, _mm_srli_epi32(v2, 8));
+ v1 = _mm_srli_epi32(v1, 8);
+ v2 = _mm_srli_epi32(v2, 8);
+ v1 = _mm_packs_epi32(v1, v2);
+ v1 = _mm_packus_epi16(v1, vzero);
+ _mm_storel_epi64((__m128i*)(dst), v1);
+ dst += 2;
+ }
+#endif
+ for (; i < count; i++) {
+ uint s = (*src++).toArgb32();
+ if (RGBA)
+ s = ARGB2RGBA(s);
+ *dst++ = s;
+ }
}
+template void qt_convertRGBA64ToARGB32<false>(uint *dst, const QRgba64 *src, int count);
+template void qt_convertRGBA64ToARGB32<true>(uint *dst, const QRgba64 *src, int count);
-static const uint *QT_FASTCALL convertGrayscale8FromARGB32PM(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+
+static void QT_FASTCALL storeAlpha8FromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
for (int i = 0; i < count; ++i)
- buffer[i] = qGray(qUnpremultiply(src[i]));
- return buffer;
+ dest[index + i] = qAlpha(src[i]);
}
-template <QPixelLayout::BPP bpp> static
-uint QT_FASTCALL fetchPixel(const uchar *, int)
+static void QT_FASTCALL storeGrayscale8FromRGB32(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- Q_UNREACHABLE();
- return 0;
+ for (int i = 0; i < count; ++i)
+ dest[index + i] = qGray(src[i]);
}
-template <>
-inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP1LSB>(const uchar *src, int index)
+static void QT_FASTCALL storeGrayscale8FromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- return (src[index >> 3] >> (index & 7)) & 1;
+ for (int i = 0; i < count; ++i)
+ dest[index + i] = qGray(qUnpremultiply(src[i]));
}
-template <>
-inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP1MSB>(const uchar *src, int index)
+static const uint *QT_FASTCALL fetchRGB64ToRGB32(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- return (src[index >> 3] >> (~index & 7)) & 1;
+ const QRgba64 *s = reinterpret_cast<const QRgba64 *>(src) + index;
+ for (int i = 0; i < count; ++i)
+ buffer[i] = toArgb32(s[i]);
+ return buffer;
}
-template <>
-inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP8>(const uchar *src, int index)
+static void QT_FASTCALL storeRGB64FromRGB32(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- return src[index];
+ QRgba64 *d = reinterpret_cast<QRgba64 *>(dest) + index;
+ for (int i = 0; i < count; ++i)
+ d[i] = QRgba64::fromArgb32(src[i]);
}
-template <>
-inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP16>(const uchar *src, int index)
+static const uint *QT_FASTCALL fetchRGBA64ToARGB32PM(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- return reinterpret_cast<const quint16 *>(src)[index];
+ const QRgba64 *s = reinterpret_cast<const QRgba64 *>(src) + index;
+ for (int i = 0; i < count; ++i)
+ buffer[i] = toArgb32(s[i].premultiplied());
+ return buffer;
}
-template <>
-inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP24>(const uchar *src, int index)
+static void QT_FASTCALL storeRGBA64FromARGB32PM(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- return reinterpret_cast<const quint24 *>(src)[index];
+ QRgba64 *d = reinterpret_cast<QRgba64 *>(dest) + index;
+ for (int i = 0; i < count; ++i)
+ d[i] = QRgba64::fromArgb32(src[i]).unpremultiplied();
}
-template <>
-inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP32>(const uchar *src, int index)
-{
- return reinterpret_cast<const uint *>(src)[index];
-}
+// Note:
+// convertToArgb32() assumes that no color channel is less than 4 bits.
+// storeRGBFromARGB32PM() assumes that no color channel is more than 8 bits.
+// QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits.
+QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
+ { false, false, QPixelLayout::BPPNone, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }, // Format_Invalid
+ { false, false, QPixelLayout::BPP1MSB, nullptr,
+ convertIndexedToARGB32PM, convertIndexedToRGBA64PM,
+ fetchIndexedToARGB32PM<QPixelLayout::BPP1MSB>, fetchIndexedToRGBA64PM<QPixelLayout::BPP1MSB>,
+ nullptr, nullptr }, // Format_Mono
+ { false, false, QPixelLayout::BPP1LSB, nullptr,
+ convertIndexedToARGB32PM, convertIndexedToRGBA64PM,
+ fetchIndexedToARGB32PM<QPixelLayout::BPP1LSB>, fetchIndexedToRGBA64PM<QPixelLayout::BPP1LSB>,
+ nullptr, nullptr }, // Format_MonoLSB
+ { false, false, QPixelLayout::BPP8, nullptr,
+ convertIndexedToARGB32PM, convertIndexedToRGBA64PM,
+ fetchIndexedToARGB32PM<QPixelLayout::BPP8>, fetchIndexedToRGBA64PM<QPixelLayout::BPP8>,
+ nullptr, nullptr }, // Format_Indexed8
+ // Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong,
+ // but everywhere this generic conversion would be wrong is currently overloaded.
+ { false, false, QPixelLayout::BPP32, rbSwap_rgb32, convertPassThrough,
+ convertRGB32ToRGB64, fetchPassThrough, fetchRGB32ToRGB64, storePassThrough, storePassThrough }, // Format_RGB32
+ { true, false, QPixelLayout::BPP32, rbSwap_rgb32, convertARGB32ToARGB32PM,
+ convertARGB32ToRGBA64PM, fetchARGB32ToARGB32PM, fetchARGB32ToRGBA64PM, storeARGB32FromARGB32PM, storePassThrough }, // Format_ARGB32
+ { true, true, QPixelLayout::BPP32, rbSwap_rgb32, convertPassThrough,
+ convertARGB32PMToRGBA64PM, fetchPassThrough, fetchARGB32PMToRGBA64PM, storePassThrough, storePassThrough }, // Format_ARGB32_Premultiplied
+ pixelLayoutRGB<QImage::Format_RGB16>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB8565_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB666>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB6666_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB555>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB8555_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB888>(),
+ pixelLayoutRGB<QImage::Format_RGB444>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB4444_Premultiplied>(),
+ { false, false, QPixelLayout::BPP32, rbSwap<QImage::Format_RGBA8888>, convertRGBA8888PMToARGB32PM,
+ convertRGBA8888PMToRGBA64PM, fetchRGBA8888PMToARGB32PM, fetchRGBA8888PMToRGBA64PM, storeRGBXFromARGB32PM, storeRGBXFromRGB32 }, // Format_RGBX8888
+ { true, false, QPixelLayout::BPP32, rbSwap<QImage::Format_RGBA8888>, convertRGBA8888ToARGB32PM,
+ convertRGBA8888ToRGBA64PM, fetchRGBA8888ToARGB32PM, fetchRGBA8888ToRGBA64PM, storeRGBA8888FromARGB32PM, storeRGBXFromRGB32 }, // Format_RGBA8888
+ { true, true, QPixelLayout::BPP32, rbSwap<QImage::Format_RGBA8888>, convertRGBA8888PMToARGB32PM,
+ convertRGBA8888PMToRGBA64PM, fetchRGBA8888PMToARGB32PM, fetchRGBA8888PMToRGBA64PM, storeRGBA8888PMFromARGB32PM, storeRGBXFromRGB32 }, // Format_RGBA8888_Premultiplied
+ { false, false, QPixelLayout::BPP32, rbSwap_rgb30,
+ convertA2RGB30PMToARGB32PM<PixelOrderBGR>,
+ convertA2RGB30PMToRGBA64PM<PixelOrderBGR>,
+ fetchA2RGB30PMToARGB32PM<PixelOrderBGR>,
+ fetchA2RGB30PMToRGBA64PM<PixelOrderBGR>,
+ storeRGB30FromARGB32PM<PixelOrderBGR>,
+ storeRGB30FromRGB32<PixelOrderBGR>
+ }, // Format_BGR30
+ { true, true, QPixelLayout::BPP32, rbSwap_rgb30,
+ convertA2RGB30PMToARGB32PM<PixelOrderBGR>,
+ convertA2RGB30PMToRGBA64PM<PixelOrderBGR>,
+ fetchA2RGB30PMToARGB32PM<PixelOrderBGR>,
+ fetchA2RGB30PMToRGBA64PM<PixelOrderBGR>,
+ storeA2RGB30PMFromARGB32PM<PixelOrderBGR>,
+ storeRGB30FromRGB32<PixelOrderBGR>
+ }, // Format_A2BGR30_Premultiplied
+ { false, false, QPixelLayout::BPP32, rbSwap_rgb30,
+ convertA2RGB30PMToARGB32PM<PixelOrderRGB>,
+ convertA2RGB30PMToRGBA64PM<PixelOrderRGB>,
+ fetchA2RGB30PMToARGB32PM<PixelOrderRGB>,
+ fetchA2RGB30PMToRGBA64PM<PixelOrderRGB>,
+ storeRGB30FromARGB32PM<PixelOrderRGB>,
+ storeRGB30FromRGB32<PixelOrderRGB>
+ }, // Format_RGB30
+ { true, true, QPixelLayout::BPP32, rbSwap_rgb30,
+ convertA2RGB30PMToARGB32PM<PixelOrderRGB>,
+ convertA2RGB30PMToRGBA64PM<PixelOrderRGB>,
+ fetchA2RGB30PMToARGB32PM<PixelOrderRGB>,
+ fetchA2RGB30PMToRGBA64PM<PixelOrderRGB>,
+ storeA2RGB30PMFromARGB32PM<PixelOrderRGB>,
+ storeRGB30FromRGB32<PixelOrderRGB>
+ }, // Format_A2RGB30_Premultiplied
+ { true, true, QPixelLayout::BPP8, nullptr,
+ convertAlpha8ToRGB32, convertAlpha8ToRGB64,
+ fetchAlpha8ToRGB32, fetchAlpha8ToRGB64,
+ storeAlpha8FromARGB32PM, nullptr }, // Format_Alpha8
+ { false, false, QPixelLayout::BPP8, nullptr,
+ convertGrayscale8ToRGB32, convertGrayscale8ToRGB64,
+ fetchGrayscale8ToRGB32, fetchGrayscale8ToRGB64,
+ storeGrayscale8FromARGB32PM, storeGrayscale8FromRGB32 }, // Format_Grayscale8
+ { false, false, QPixelLayout::BPP64, nullptr,
+ convertPassThrough, nullptr,
+ fetchRGB64ToRGB32, fetchPassThrough64,
+ storeRGB64FromRGB32, storeRGB64FromRGB32 }, // Format_RGBX64
+ { true, false, QPixelLayout::BPP64, nullptr,
+ convertARGB32ToARGB32PM, nullptr,
+ fetchRGBA64ToARGB32PM, fetchRGBA64ToRGBA64PM,
+ storeRGBA64FromARGB32PM, storeRGB64FromRGB32 }, // Format_RGBA64
+ { true, true, QPixelLayout::BPP64, nullptr,
+ convertPassThrough, nullptr,
+ fetchRGB64ToRGB32, fetchPassThrough64,
+ storeRGB64FromRGB32, storeRGB64FromRGB32 } // Format_RGBA64_Premultiplied
+};
-template <QPixelLayout::BPP bpp>
-inline const uint *QT_FASTCALL fetchPixels(uint *buffer, const uchar *src, int index, int count)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = fetchPixel<bpp>(src, index + i);
- return buffer;
-}
+Q_STATIC_ASSERT(sizeof(qPixelLayouts) / sizeof(*qPixelLayouts) == QImage::NImageFormats);
-template <>
-inline const uint *QT_FASTCALL fetchPixels<QPixelLayout::BPP32>(uint *, const uchar *src, int index, int)
+static void QT_FASTCALL convertFromRgb64(uint *dest, const QRgba64 *src, int length)
{
- return reinterpret_cast<const uint *>(src) + index;
+ for (int i = 0; i < length; ++i) {
+ dest[i] = toArgb32(src[i]);
+ }
}
-template <QPixelLayout::BPP width> static
-void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel);
-
-template <>
-inline void QT_FASTCALL storePixel<QPixelLayout::BPP1LSB>(uchar *dest, int index, uint pixel)
+template<QImage::Format format>
+static void QT_FASTCALL storeGenericFromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *clut, QDitherInfo *dither)
{
- if (pixel)
- dest[index >> 3] |= 1 << (index & 7);
- else
- dest[index >> 3] &= ~(1 << (index & 7));
+ uint buffer[BufferSize];
+ convertFromRgb64(buffer, src, count);
+ qPixelLayouts[format].storeFromARGB32PM(dest, buffer, index, count, clut, dither);
}
-template <>
-inline void QT_FASTCALL storePixel<QPixelLayout::BPP1MSB>(uchar *dest, int index, uint pixel)
+static void QT_FASTCALL storeARGB32FromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- if (pixel)
- dest[index >> 3] |= 1 << (~index & 7);
- else
- dest[index >> 3] &= ~(1 << (~index & 7));
+ uint *d = (uint*)dest + index;
+ for (int i = 0; i < count; ++i)
+ d[i] = toArgb32(src[i].unpremultiplied());
}
-template <>
-inline void QT_FASTCALL storePixel<QPixelLayout::BPP8>(uchar *dest, int index, uint pixel)
+static void QT_FASTCALL storeRGBA8888FromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- dest[index] = uchar(pixel);
+ uint *d = (uint*)dest + index;
+ for (int i = 0; i < count; ++i)
+ d[i] = toRgba8888(src[i].unpremultiplied());
}
-template <>
-inline void QT_FASTCALL storePixel<QPixelLayout::BPP16>(uchar *dest, int index, uint pixel)
+template<QtPixelOrder PixelOrder>
+static void QT_FASTCALL storeRGB30FromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- reinterpret_cast<quint16 *>(dest)[index] = quint16(pixel);
+ uint *d = (uint*)dest + index;
+#ifdef __SSE2__
+ qConvertRGBA64PMToA2RGB30PM_sse2<PixelOrder>(d, src, count);
+#else
+ for (int i = 0; i < count; ++i)
+ d[i] = qConvertRgb64ToRgb30<PixelOrder>(src[i]);
+#endif
}
-template <>
-inline void QT_FASTCALL storePixel<QPixelLayout::BPP24>(uchar *dest, int index, uint pixel)
+static void QT_FASTCALL storeRGBX64FromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- reinterpret_cast<quint24 *>(dest)[index] = quint24(pixel);
+ QRgba64 *d = reinterpret_cast<QRgba64*>(dest) + index;
+ for (int i = 0; i < count; ++i) {
+ d[i] = src[i].unpremultiplied();
+ d[i].setAlpha(65535);
+ }
}
-template <QPixelLayout::BPP width>
-inline void QT_FASTCALL storePixels(uchar *dest, const uint *src, int index, int count)
+static void QT_FASTCALL storeRGBA64FromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
+ QRgba64 *d = reinterpret_cast<QRgba64*>(dest) + index;
for (int i = 0; i < count; ++i)
- storePixel<width>(dest, index + i, src[i]);
+ d[i] = src[i].unpremultiplied();
}
-template <>
-inline void QT_FASTCALL storePixels<QPixelLayout::BPP32>(uchar *dest, const uint *src, int index, int count)
+static void QT_FASTCALL storeRGBA64PMFromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- memcpy(reinterpret_cast<uint *>(dest) + index, src, count * sizeof(uint));
-}
-
-// Note:
-// convertToArgb32() assumes that no color channel is less than 4 bits.
-// convertFromArgb32() assumes that no color channel is more than 8 bits.
-// QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits.
-QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0, 0, 0 }, // Format_Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Mono
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_MonoLSB
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Indexed8
- // Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong,
- // but everywhere this generic conversion would be wrong is currently overloaded.
- { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough, convertRGB32ToRGB64 }, // Format_RGB32
- { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, convertPassThrough, convertARGB32ToARGB64PM }, // Format_ARGB32
- { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough, convertARGB32PMToARGB64PM }, // Format_ARGB32_Premultiplied
-#ifdef Q_COMPILER_CONSTEXPR
- pixelLayoutRGB<QImage::Format_RGB16>(),
- pixelLayoutARGBPM<QImage::Format_ARGB8565_Premultiplied>(),
- pixelLayoutRGB<QImage::Format_RGB666>(),
- pixelLayoutARGBPM<QImage::Format_ARGB6666_Premultiplied>(),
- pixelLayoutRGB<QImage::Format_RGB555>(),
- pixelLayoutARGBPM<QImage::Format_ARGB8555_Premultiplied>(),
- pixelLayoutRGB<QImage::Format_RGB888>(),
- pixelLayoutRGB<QImage::Format_RGB444>(),
- pixelLayoutARGBPM<QImage::Format_ARGB4444_Premultiplied>(),
-#else
- { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16,
- convertToRGB32<QImage::Format_RGB16>,
- convertRGBFromARGB32PM<QImage::Format_RGB16, false>,
- convertRGBFromARGB32PM<QImage::Format_RGB16, true>,
- convertToRGB64<QImage::Format_RGB16>,
- },
- { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24,
- convertARGBPMToARGB32PM<QImage::Format_ARGB8565_Premultiplied>,
- convertARGBPMFromARGB32PM<QImage::Format_ARGB8565_Premultiplied, false>,
- convertARGBPMFromARGB32PM<QImage::Format_ARGB8565_Premultiplied, true>,
- convertARGBPMToARGB64PM<QImage::Format_ARGB8565_Premultiplied>,
- },
- { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24,
- convertToRGB32<QImage::Format_RGB666>,
- convertRGBFromARGB32PM<QImage::Format_RGB666, false>,
- convertRGBFromARGB32PM<QImage::Format_RGB666, true>,
- convertToRGB64<QImage::Format_RGB666>,
- },
- { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24,
- convertARGBPMToARGB32PM<QImage::Format_ARGB6666_Premultiplied>,
- convertARGBPMFromARGB32PM<QImage::Format_ARGB6666_Premultiplied, false>,
- convertARGBPMFromARGB32PM<QImage::Format_ARGB6666_Premultiplied, true>,
- convertARGBPMToARGB64PM<QImage::Format_ARGB6666_Premultiplied>,
- },
- { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16,
- convertToRGB32<QImage::Format_RGB555>,
- convertRGBFromARGB32PM<QImage::Format_RGB555, false>,
- convertRGBFromARGB32PM<QImage::Format_RGB555, true>,
- convertToRGB64<QImage::Format_RGB555>,
- },
- { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24,
- convertARGBPMToARGB32PM<QImage::Format_ARGB8555_Premultiplied>,
- convertARGBPMFromARGB32PM<QImage::Format_ARGB8555_Premultiplied, false>,
- convertARGBPMFromARGB32PM<QImage::Format_ARGB8555_Premultiplied, true>,
- convertARGBPMToARGB64PM<QImage::Format_ARGB8555_Premultiplied>,
- },
- { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24,
- convertToRGB32<QImage::Format_RGB888>,
- convertRGBFromARGB32PM<QImage::Format_RGB888, false>,
- convertRGBFromARGB32PM<QImage::Format_RGB888, true>,
- convertToRGB64<QImage::Format_RGB888>,
- },
- { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16,
- convertToRGB32<QImage::Format_RGB444>,
- convertRGBFromARGB32PM<QImage::Format_RGB444, false>,
- convertRGBFromARGB32PM<QImage::Format_RGB444, true>,
- convertToRGB64<QImage::Format_RGB444>,
- },
- { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16,
- convertARGBPMToARGB32PM<QImage::Format_ARGB4444_Premultiplied>,
- convertARGBPMFromARGB32PM<QImage::Format_ARGB4444_Premultiplied, false>,
- convertARGBPMFromARGB32PM<QImage::Format_ARGB4444_Premultiplied, true>,
- convertARGBPMToARGB64PM<QImage::Format_ARGB4444_Premultiplied>,
- },
-#endif
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888
- { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888
- { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM}, // Format_RGBA8888_Premultiplied
-#else
- { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888
- { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888 (ABGR32)
- { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBA8888_Premultiplied
-#endif
- { 10, 20, 10, 10, 10, 0, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertRGB30FromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR>, convertA2RGB30PMToARGB64PM<PixelOrderBGR> }, // Format_BGR30
- { 10, 20, 10, 10, 10, 0, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertA2RGB30PMFromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR>, convertA2RGB30PMToARGB64PM<PixelOrderBGR> }, // Format_A2BGR30_Premultiplied
- { 10, 0, 10, 10, 10, 20, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertRGB30FromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB>, convertA2RGB30PMToARGB64PM<PixelOrderRGB> }, // Format_RGB30
- { 10, 0, 10, 10, 10, 20, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertA2RGB30PMFromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB>, convertA2RGB30PMToARGB64PM<PixelOrderRGB> }, // Format_A2RGB30_Premultiplied
- { 0, 0, 0, 0, 0, 0, 8, 0, true, QPixelLayout::BPP8, convertAlpha8ToRGB32, convertAlpha8FromARGB32PM, 0, convertAlpha8ToRGB64 }, // Format_Alpha8
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertGrayscale8ToRGB32, convertGrayscale8FromARGB32PM, convertGrayscale8FromRGB32, convertGrayscale8ToRGB64 } // Format_Grayscale8
-};
-
-const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = {
- 0, // BPPNone
- fetchPixels<QPixelLayout::BPP1MSB>, // BPP1MSB
- fetchPixels<QPixelLayout::BPP1LSB>, // BPP1LSB
- fetchPixels<QPixelLayout::BPP8>, // BPP8
- fetchPixels<QPixelLayout::BPP16>, // BPP16
- fetchPixels<QPixelLayout::BPP24>, // BPP24
- fetchPixels<QPixelLayout::BPP32> // BPP32
-};
-
-StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = {
- 0, // BPPNone
- storePixels<QPixelLayout::BPP1MSB>, // BPP1MSB
- storePixels<QPixelLayout::BPP1LSB>, // BPP1LSB
- storePixels<QPixelLayout::BPP8>, // BPP8
- storePixels<QPixelLayout::BPP16>, // BPP16
- storePixels<QPixelLayout::BPP24>, // BPP24
- storePixels<QPixelLayout::BPP32> // BPP32
-};
-
-typedef uint (QT_FASTCALL *FetchPixelFunc)(const uchar *src, int index);
-
-static const FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = {
- 0, // BPPNone
- fetchPixel<QPixelLayout::BPP1MSB>, // BPP1MSB
- fetchPixel<QPixelLayout::BPP1LSB>, // BPP1LSB
- fetchPixel<QPixelLayout::BPP8>, // BPP8
- fetchPixel<QPixelLayout::BPP16>, // BPP16
- fetchPixel<QPixelLayout::BPP24>, // BPP24
- fetchPixel<QPixelLayout::BPP32> // BPP32
+ QRgba64 *d = reinterpret_cast<QRgba64*>(dest) + index;
+ if (d != src)
+ memcpy(d, src, count * sizeof(QRgba64));
+}
+
+ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = {
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ storeGenericFromRGBA64PM<QImage::Format_RGB32>,
+ storeARGB32FromRGBA64PM,
+ storeGenericFromRGBA64PM<QImage::Format_ARGB32_Premultiplied>,
+ storeGenericFromRGBA64PM<QImage::Format_RGB16>,
+ storeGenericFromRGBA64PM<QImage::Format_ARGB8565_Premultiplied>,
+ storeGenericFromRGBA64PM<QImage::Format_RGB666>,
+ storeGenericFromRGBA64PM<QImage::Format_ARGB6666_Premultiplied>,
+ storeGenericFromRGBA64PM<QImage::Format_RGB555>,
+ storeGenericFromRGBA64PM<QImage::Format_ARGB8555_Premultiplied>,
+ storeGenericFromRGBA64PM<QImage::Format_RGB888>,
+ storeGenericFromRGBA64PM<QImage::Format_RGB444>,
+ storeGenericFromRGBA64PM<QImage::Format_ARGB4444_Premultiplied>,
+ storeGenericFromRGBA64PM<QImage::Format_RGBX8888>,
+ storeRGBA8888FromRGBA64PM,
+ storeGenericFromRGBA64PM<QImage::Format_RGBA8888_Premultiplied>,
+ storeRGB30FromRGBA64PM<PixelOrderBGR>,
+ storeRGB30FromRGBA64PM<PixelOrderBGR>,
+ storeRGB30FromRGBA64PM<PixelOrderRGB>,
+ storeRGB30FromRGBA64PM<PixelOrderRGB>,
+ storeGenericFromRGBA64PM<QImage::Format_Alpha8>,
+ storeGenericFromRGBA64PM<QImage::Format_Grayscale8>,
+ storeRGBX64FromRGBA64PM,
+ storeRGBA64FromRGBA64PM,
+ storeRGBA64PMFromRGBA64PM
};
/*
@@ -1185,23 +1641,23 @@ static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuff
static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
{
const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
- const uint *ptr = qFetchPixels[layout->bpp](buffer, rasterBuffer->scanLine(y), x, length);
- return const_cast<uint *>(layout->convertToARGB32PM(buffer, ptr, length, 0, 0));
+ return const_cast<uint *>(layout->fetchToARGB32PM(buffer, rasterBuffer->scanLine(y), x, length, nullptr, nullptr));
+}
+
+static uint *QT_FASTCALL destFetchUndefined(uint *buffer, QRasterBuffer *, int, int, int)
+{
+ return buffer;
}
static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
{
const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
- uint buffer32[buffer_size];
- const uint *ptr = qFetchPixels[layout->bpp](buffer32, rasterBuffer->scanLine(y), x, length);
- return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, ptr, length, 0, 0));
+ return const_cast<QRgba64 *>(layout->fetchToRGBA64PM(buffer, rasterBuffer->scanLine(y), x, length, nullptr, nullptr));
}
-static QRgba64 *QT_FASTCALL destFetch64uint32(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
+static QRgba64 * QT_FASTCALL destFetchRGB64(QRgba64 *, QRasterBuffer *rasterBuffer, int x, int y, int)
{
- const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
- const uint *src = ((const uint *)rasterBuffer->scanLine(y)) + x;
- return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, src, length, 0, 0));
+ return (QRgba64 *)rasterBuffer->scanLine(y) + x;
}
static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *, int, int, int)
@@ -1236,6 +1692,9 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
destFetch, // Format_A2RGB30_Premultiplied
destFetch, // Format_Alpha8
destFetch, // Format_Grayscale8
+ destFetch, // Format_RGBX64
+ destFetch, // Format_RGBA64
+ destFetch, // Format_RGBA64_Premultiplied
};
static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
@@ -1244,9 +1703,9 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
0, // Format_Mono,
0, // Format_MonoLSB
0, // Format_Indexed8
- destFetch64uint32, // Format_RGB32
- destFetch64uint32, // Format_ARGB32,
- destFetch64uint32, // Format_ARGB32_Premultiplied
+ destFetch64, // Format_RGB32
+ destFetch64, // Format_ARGB32,
+ destFetch64, // Format_ARGB32_Premultiplied
destFetch64, // Format_RGB16
destFetch64, // Format_ARGB8565_Premultiplied
destFetch64, // Format_RGB666
@@ -1256,15 +1715,18 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
destFetch64, // Format_RGB888
destFetch64, // Format_RGB444
destFetch64, // Format_ARGB4444_Premultiplied
- destFetch64uint32, // Format_RGBX8888
- destFetch64uint32, // Format_RGBA8888
- destFetch64uint32, // Format_RGBA8888_Premultiplied
- destFetch64uint32, // Format_BGR30
- destFetch64uint32, // Format_A2BGR30_Premultiplied
- destFetch64uint32, // Format_RGB30
- destFetch64uint32, // Format_A2RGB30_Premultiplied
+ destFetch64, // Format_RGBX8888
+ destFetch64, // Format_RGBA8888
+ destFetch64, // Format_RGBA8888_Premultiplied
+ destFetch64, // Format_BGR30
+ destFetch64, // Format_A2BGR30_Premultiplied
+ destFetch64, // Format_RGB30
+ destFetch64, // Format_A2RGB30_Premultiplied
destFetch64, // Format_Alpha8
destFetch64, // Format_Grayscale8
+ destFetchRGB64, // Format_RGBX64
+ destFetch64, // Format_RGBA64
+ destFetchRGB64, // Format_RGBA64_Premultiplied
};
/*
@@ -1365,143 +1827,29 @@ static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer, int x, int y
static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length)
{
- uint buf[buffer_size];
const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
- StorePixelsFunc store = qStorePixels[layout->bpp];
+ ConvertAndStorePixelsFunc store = layout->storeFromARGB32PM;
+ if (!layout->premultiplied && !layout->hasAlphaChannel)
+ store = layout->storeFromRGB32;
uchar *dest = rasterBuffer->scanLine(y);
- while (length) {
- int l = qMin(length, buffer_size);
- const uint *ptr = 0;
- if (!layout->premultiplied && !layout->alphaWidth)
- ptr = layout->convertFromRGB32(buf, buffer, l, 0, 0);
- else
- ptr = layout->convertFromARGB32PM(buf, buffer, l, 0, 0);
- store(dest, ptr, x, l);
- length -= l;
- buffer += l;
- x += l;
- }
-}
-
-static void QT_FASTCALL convertFromRgb64(uint *dest, const QRgba64 *src, int length)
-{
- for (int i = 0; i < length; ++i) {
- dest[i] = toArgb32(src[i]);
- }
+ store(dest, buffer, x, length, nullptr, nullptr);
}
static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
{
- uint buf[buffer_size];
- const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format];
- StorePixelsFunc store = qStorePixels[layout->bpp];
+ auto store = qStoreFromRGBA64PM[rasterBuffer->format];
uchar *dest = rasterBuffer->scanLine(y);
- while (length) {
- int l = qMin(length, buffer_size);
- const uint *ptr = 0;
- convertFromRgb64(buf, buffer, l);
- if (!layout->premultiplied && !layout->alphaWidth)
- ptr = layout->convertFromRGB32(buf, buf, l, 0, 0);
- else
- ptr = layout->convertFromARGB32PM(buf, buf, l, 0, 0);
- store(dest, ptr, x, l);
- length -= l;
- buffer += l;
- x += l;
- }
+ store(dest, buffer, x, length, nullptr, nullptr);
}
-#ifdef __SSE2__
-template<QtPixelOrder PixelOrder>
-static inline void qConvertARGB64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *buffer, int count)
+static void QT_FASTCALL destStore64RGBA64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
{
- const __m128i gmask = _mm_set1_epi32(0x000ffc00);
- const __m128i cmask = _mm_set1_epi32(0x000003ff);
- int i = 0;
- __m128i vr, vg, vb, va;
- for (; i < count && uintptr_t(buffer) & 0xF; ++i) {
- *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
- }
-
- for (; i < count-15; i += 16) {
- // Repremultiplying is really expensive and hard to do in SIMD without AVX2,
- // so we try to avoid it by checking if it is needed 16 samples at a time.
- __m128i vOr = _mm_set1_epi32(0);
- __m128i vAnd = _mm_set1_epi32(0xffffffff);
- for (int j = 0; j < 16; j += 2) {
- __m128i vs = _mm_load_si128((const __m128i*)(buffer + j));
- vOr = _mm_or_si128(vOr, vs);
- vAnd = _mm_and_si128(vAnd, vs);
- }
- const quint16 orAlpha = ((uint)_mm_extract_epi16(vOr, 3)) | ((uint)_mm_extract_epi16(vOr, 7));
- const quint16 andAlpha = ((uint)_mm_extract_epi16(vAnd, 3)) & ((uint)_mm_extract_epi16(vAnd, 7));
-
- if (andAlpha == 0xffff) {
- for (int j = 0; j < 16; j += 2) {
- __m128i vs = _mm_load_si128((const __m128i*)buffer);
- buffer += 2;
- vr = _mm_srli_epi64(vs, 6);
- vg = _mm_srli_epi64(vs, 16 + 6 - 10);
- vb = _mm_srli_epi64(vs, 32 + 6);
- vr = _mm_and_si128(vr, cmask);
- vg = _mm_and_si128(vg, gmask);
- vb = _mm_and_si128(vb, cmask);
- va = _mm_srli_epi64(vs, 48 + 14);
- if (PixelOrder == PixelOrderRGB)
- vr = _mm_slli_epi32(vr, 20);
- else
- vb = _mm_slli_epi32(vb, 20);
- va = _mm_slli_epi32(va, 30);
- __m128i vd = _mm_or_si128(_mm_or_si128(vr, vg), _mm_or_si128(vb, va));
- vd = _mm_shuffle_epi32(vd, _MM_SHUFFLE(3, 1, 2, 0));
- _mm_storel_epi64((__m128i*)dest, vd);
- dest += 2;
- }
- } else if (orAlpha == 0) {
- for (int j = 0; j < 16; ++j) {
- *dest++ = 0;
- buffer++;
- }
- } else {
- for (int j = 0; j < 16; ++j)
- *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
- }
- }
-
- SIMD_EPILOGUE(i, count, 15)
- *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++);
-}
-#endif
-
-static void QT_FASTCALL destStore64ARGB32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
-{
- uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
+ QRgba64 *dest = reinterpret_cast<QRgba64*>(rasterBuffer->scanLine(y)) + x;
for (int i = 0; i < length; ++i) {
- dest[i] = toArgb32(buffer[i].unpremultiplied());
+ dest[i] = buffer[i].unpremultiplied();
}
}
-static void QT_FASTCALL destStore64RGBA8888(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
-{
- uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
- for (int i = 0; i < length; ++i) {
- dest[i] = toRgba8888(buffer[i].unpremultiplied());
- }
-}
-
-template<QtPixelOrder PixelOrder>
-static void QT_FASTCALL destStore64RGB30(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
-{
- uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
-#ifdef __SSE2__
- qConvertARGB64PMToA2RGB30PM_sse2<PixelOrder>(dest, buffer, length);
-#else
- for (int i = 0; i < length; ++i) {
- dest[i] = qConvertRgb64ToRgb30<PixelOrder>(buffer[i]);
- }
-#endif
-}
-
static DestStoreProc destStoreProc[QImage::NImageFormats] =
{
0, // Format_Invalid
@@ -1529,16 +1877,19 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
destStore, // Format_A2RGB30_Premultiplied
destStore, // Format_Alpha8
destStore, // Format_Grayscale8
+ destStore, // Format_RGBX64
+ destStore, // Format_RGBA64
+ destStore, // Format_RGBA64_Premultiplied
};
static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
{
0, // Format_Invalid
- destStore64, // Format_Mono,
- destStore64, // Format_MonoLSB
+ 0, // Format_Mono,
+ 0, // Format_MonoLSB
0, // Format_Indexed8
destStore64, // Format_RGB32
- destStore64ARGB32, // Format_ARGB32,
+ destStore64, // Format_ARGB32,
destStore64, // Format_ARGB32_Premultiplied
destStore64, // Format_RGB16
destStore64, // Format_ARGB8565_Premultiplied
@@ -1550,14 +1901,17 @@ static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
destStore64, // Format_RGB444
destStore64, // Format_ARGB4444_Premultiplied
destStore64, // Format_RGBX8888
- destStore64RGBA8888, // Format_RGBA8888
+ destStore64, // Format_RGBA8888
destStore64, // Format_RGBA8888_Premultiplied
- destStore64RGB30<PixelOrderBGR>, // Format_BGR30
- destStore64RGB30<PixelOrderBGR>, // Format_A2BGR30_Premultiplied
- destStore64RGB30<PixelOrderRGB>, // Format_RGB30
- destStore64RGB30<PixelOrderRGB>, // Format_A2RGB30_Premultiplied
+ destStore64, // Format_BGR30
+ destStore64, // Format_A2BGR30_Premultiplied
+ destStore64, // Format_RGB30
+ destStore64, // Format_A2RGB30_Premultiplied
destStore64, // Format_Alpha8
destStore64, // Format_Grayscale8
+ 0, // Format_RGBX64
+ destStore64RGBA64, // Format_RGBA64
+ 0 // Format_RGBA64_Premultiplied
};
/*
@@ -1589,15 +1943,14 @@ static const uint *QT_FASTCALL fetchUntransformed(uint *buffer, const Operator *
const QSpanData *data, int y, int x, int length)
{
const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
- const uint *ptr = qFetchPixels[layout->bpp](buffer, data->texture.scanLine(y), x, length);
- return layout->convertToARGB32PM(buffer, ptr, length, data->texture.colorTable, 0);
+ return layout->fetchToARGB32PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable, nullptr);
}
static const uint *QT_FASTCALL fetchUntransformedARGB32PM(uint *, const Operator *,
const QSpanData *data, int y, int x, int)
{
const uchar *scanLine = data->texture.scanLine(y);
- return ((const uint *)scanLine) + x;
+ return reinterpret_cast<const uint *>(scanLine) + x;
}
static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer, const Operator *,
@@ -1614,39 +1967,47 @@ static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer, const Op
const QSpanData *data, int y, int x, int length)
{
const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
- if (layout->bpp != QPixelLayout::BPP32) {
- uint buffer32[buffer_size];
- const uint *ptr = qFetchPixels[layout->bpp](buffer32, data->texture.scanLine(y), x, length);
- return layout->convertToARGB64PM(buffer, ptr, length, data->texture.colorTable, 0);
+ return layout->fetchToRGBA64PM(buffer, data->texture.scanLine(y), x, length, data->texture.colorTable, nullptr);
+}
+
+static const QRgba64 *QT_FASTCALL fetchUntransformedRGBA64PM(QRgba64 *, const Operator *,
+ const QSpanData *data, int y, int x, int)
+{
+ const uchar *scanLine = data->texture.scanLine(y);
+ return reinterpret_cast<const QRgba64 *>(scanLine) + x;
+}
+
+template<TextureBlendType blendType>
+inline void fetchTransformed_pixelBounds(int max, int l1, int l2, int &v)
+{
+ Q_STATIC_ASSERT(blendType == BlendTransformed || blendType == BlendTransformedTiled);
+ if (blendType == BlendTransformedTiled) {
+ if (v < 0 || v >= max) {
+ v %= max;
+ if (v < 0) v += max;
+ }
} else {
- const uint *src = (const uint *)data->texture.scanLine(y) + x;
- return layout->convertToARGB64PM(buffer, src, length, data->texture.colorTable, 0);
+ v = qBound(l1, v, l2);
}
}
-template<TextureBlendType blendType, QPixelLayout::BPP bpp>
-static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data,
- int y, int x, int length)
+template<TextureBlendType blendType, QPixelLayout::BPP bpp, typename T>
+static void QT_FASTCALL fetchTransformed_fetcher(T *buffer, const QSpanData *data,
+ int y, int x, int length)
{
Q_STATIC_ASSERT(blendType == BlendTransformed || blendType == BlendTransformedTiled);
- const int image_width = data->texture.width;
- const int image_height = data->texture.height;
- const int image_x1 = data->texture.x1;
- const int image_y1 = data->texture.y1;
- const int image_x2 = data->texture.x2 - 1;
- const int image_y2 = data->texture.y2 - 1;
+ const QTextureData &image = data->texture;
const qreal cx = x + qreal(0.5);
const qreal cy = y + qreal(0.5);
+ constexpr bool useFetch = (bpp < QPixelLayout::BPP32) && sizeof(T) == sizeof(uint);
const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
- if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1
+ if (!useFetch)
Q_ASSERT(layout->bpp == bpp);
// When templated 'fetch' should be inlined at compile time:
const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel<bpp>);
- uint *const end = buffer + length;
- uint *b = buffer;
if (data->fast_matrix) {
// The increment pr x in the scanline
int fdx = (int)(data->m11 * fixed_scale);
@@ -1657,24 +2018,105 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *,
int fy = int((data->m22 * cy
+ data->m12 * cx + data->dy) * fixed_scale);
- while (b < end) {
- int px = fx >> 16;
- int py = fy >> 16;
-
- if (blendType == BlendTransformedTiled) {
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
- } else {
- px = qBound(image_x1, px, image_x2);
- py = qBound(image_y1, py, image_y2);
+ if (fdy == 0) { // simple scale, no rotation or shear
+ int py = (fy >> 16);
+ fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
+ const uchar *src = image.scanLine(py);
+
+ int i = 0;
+ if (blendType == BlendTransformed) {
+ int fastLen = length;
+ if (fdx > 0)
+ fastLen = qMin(fastLen, int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
+ else if (fdx < 0)
+ fastLen = qMin(fastLen, int((qint64(image.x1) * fixed_scale - fx) / fdx));
+
+ for (; i < fastLen; ++i) {
+ int x1 = (fx >> 16);
+ int x2 = x1;
+ fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
+ if (x1 == x2)
+ break;
+ if (useFetch)
+ buffer[i] = fetch(src, x1);
+ else
+ buffer[i] = reinterpret_cast<const T*>(src)[x1];
+ fx += fdx;
+ }
+
+ for (; i < fastLen; ++i) {
+ int px = (fx >> 16);
+ if (useFetch)
+ buffer[i] = fetch(src, px);
+ else
+ buffer[i] = reinterpret_cast<const T*>(src)[px];
+ fx += fdx;
+ }
}
- *b = fetch(data->texture.scanLine(py), px);
- fx += fdx;
- fy += fdy;
- ++b;
+ for (; i < length; ++i) {
+ int px = (fx >> 16);
+ fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
+ if (useFetch)
+ buffer[i] = fetch(src, px);
+ else
+ buffer[i] = reinterpret_cast<const T*>(src)[px];
+ fx += fdx;
+ }
+ } else { // rotation or shear
+ int i = 0;
+ if (blendType == BlendTransformed) {
+ int fastLen = length;
+ if (fdx > 0)
+ fastLen = qMin(fastLen, int((qint64(image.x2 - 1) * fixed_scale - fx) / fdx));
+ else if (fdx < 0)
+ fastLen = qMin(fastLen, int((qint64(image.x1) * fixed_scale - fx) / fdx));
+ if (fdy > 0)
+ fastLen = qMin(fastLen, int((qint64(image.y2 - 1) * fixed_scale - fy) / fdy));
+ else if (fdy < 0)
+ fastLen = qMin(fastLen, int((qint64(image.y1) * fixed_scale - fy) / fdy));
+
+ for (; i < fastLen; ++i) {
+ int x1 = (fx >> 16);
+ int y1 = (fy >> 16);
+ int x2 = x1;
+ int y2 = y1;
+ fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1);
+ fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1);
+ if (x1 == x2 && y1 == y2)
+ break;
+ if (useFetch)
+ buffer[i] = fetch(image.scanLine(y1), x1);
+ else
+ buffer[i] = reinterpret_cast<const T*>(image.scanLine(y1))[x1];
+ fx += fdx;
+ fy += fdy;
+ }
+
+ for (; i < fastLen; ++i) {
+ int px = (fx >> 16);
+ int py = (fy >> 16);
+ if (useFetch)
+ buffer[i] = fetch(image.scanLine(py), px);
+ else
+ buffer[i] = reinterpret_cast<const T*>(image.scanLine(py))[px];
+ fx += fdx;
+ fy += fdy;
+ }
+ }
+
+ for (; i < length; ++i) {
+ int px = (fx >> 16);
+ int py = (fy >> 16);
+ fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
+ fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
+ if (useFetch)
+ buffer[i] = fetch(image.scanLine(py), px);
+ else
+ buffer[i] = reinterpret_cast<const T*>(image.scanLine(py))[px];
+ fx += fdx;
+ fy += fdy;
+ }
}
} else {
const qreal fdx = data->m11;
@@ -1685,23 +2127,21 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *,
qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
+ T *const end = buffer + length;
+ T *b = buffer;
while (b < end) {
const qreal iw = fw == 0 ? 1 : 1 / fw;
const qreal tx = fx * iw;
const qreal ty = fy * iw;
- int px = int(tx) - (tx < 0);
- int py = int(ty) - (ty < 0);
-
- if (blendType == BlendTransformedTiled) {
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
- } else {
- px = qBound(image_x1, px, image_x2);
- py = qBound(image_y1, py, image_y2);
- }
- *b = fetch(data->texture.scanLine(py), px);
+ int px = qFloor(tx);
+ int py = qFloor(ty);
+
+ fetchTransformed_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, py);
+ fetchTransformed_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, px);
+ if (useFetch)
+ *b = fetch(image.scanLine(py), px);
+ else
+ *b = reinterpret_cast<const T*>(image.scanLine(py))[px];
fx += fdx;
fy += fdy;
@@ -1713,115 +2153,37 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *,
++b;
}
}
- return layout->convertToARGB32PM(buffer, buffer, length, data->texture.colorTable, 0);
+}
+
+template<TextureBlendType blendType, QPixelLayout::BPP bpp>
+static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data,
+ int y, int x, int length)
+{
+ Q_STATIC_ASSERT(blendType == BlendTransformed || blendType == BlendTransformedTiled);
+ const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
+ fetchTransformed_fetcher<blendType, bpp, uint>(buffer, data, y, x, length);
+ layout->convertToARGB32PM(buffer, length, data->texture.colorTable);
+ return buffer;
}
template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */
static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer, const Operator *, const QSpanData *data,
int y, int x, int length)
{
- const int image_width = data->texture.width;
- const int image_height = data->texture.height;
- const int image_x1 = data->texture.x1;
- const int image_y1 = data->texture.y1;
- const int image_x2 = data->texture.x2 - 1;
- const int image_y2 = data->texture.y2 - 1;
-
- const qreal cx = x + qreal(0.5);
- const qreal cy = y + qreal(0.5);
-
const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
- FetchPixelFunc fetch = qFetchPixel[layout->bpp];
- const QVector<QRgb> *clut = data->texture.colorTable;
-
- uint buffer32[buffer_size];
- QRgba64 *b = buffer;
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- int fdx = (int)(data->m11 * fixed_scale);
- int fdy = (int)(data->m12 * fixed_scale);
-
- int fx = int((data->m21 * cy
- + data->m11 * cx + data->dx) * fixed_scale);
- int fy = int((data->m22 * cy
- + data->m12 * cx + data->dy) * fixed_scale);
-
- int i = 0, j = 0;
- while (i < length) {
- if (j == buffer_size) {
- layout->convertToARGB64PM(b, buffer32, buffer_size, clut, 0);
- b += buffer_size;
- j = 0;
- }
- int px = fx >> 16;
- int py = fy >> 16;
-
- if (blendType == BlendTransformedTiled) {
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
- } else {
- px = qBound(image_x1, px, image_x2);
- py = qBound(image_y1, py, image_y2);
- }
- buffer32[j] = fetch(data->texture.scanLine(py), px);
-
- fx += fdx;
- fy += fdy;
- ++i; ++j;
- }
- if (j > 0) {
- layout->convertToARGB64PM(b, buffer32, j, clut, 0);
- b += j;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
-
- qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
- qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
- qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
-
- int i = 0, j = 0;
- while (i < length) {
- if (j == buffer_size) {
- layout->convertToARGB64PM(b, buffer32, buffer_size, clut, 0);
- b += buffer_size;
- j = 0;
- }
- const qreal iw = fw == 0 ? 1 : 1 / fw;
- const qreal tx = fx * iw;
- const qreal ty = fy * iw;
- int px = int(tx) - (tx < 0);
- int py = int(ty) - (ty < 0);
-
- if (blendType == BlendTransformedTiled) {
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
- } else {
- px = qBound(image_x1, px, image_x2);
- py = qBound(image_y1, py, image_y2);
- }
- buffer32[j] = fetch(data->texture.scanLine(py), px);
-
- fx += fdx;
- fy += fdy;
- fw += fdw;
- //force increment to avoid /0
- if (!fw) {
- fw += fdw;
- }
- ++i; ++j;
- }
- if (j > 0) {
- layout->convertToARGB64PM(b, buffer32, j, clut, 0);
- b += j;
- }
+ if (layout->bpp != QPixelLayout::BPP64) {
+ uint buffer32[BufferSize];
+ Q_ASSERT(length <= BufferSize);
+ if (layout->bpp == QPixelLayout::BPP32)
+ fetchTransformed_fetcher<blendType, QPixelLayout::BPP32, uint>(buffer32, data, y, x, length);
+ else
+ fetchTransformed_fetcher<blendType, QPixelLayout::BPPNone, uint>(buffer32, data, y, x, length);
+ return layout->convertToRGBA64PM(buffer, buffer32, length, data->texture.colorTable, nullptr);
}
+
+ fetchTransformed_fetcher<blendType, QPixelLayout::BPP64, QRgba64>(buffer, data, y, x, length);
+ if (data->texture.format == QImage::Format_RGBA64)
+ convertRGBA64ToRGBA64PM(buffer, length);
return buffer;
}
@@ -1915,43 +2277,6 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, u
}
#endif
-#if defined(__SSE2__)
-static inline QRgba64 interpolate_4_pixels_rgb64(QRgba64 t[], QRgba64 b[], uint distx, uint disty)
-{
- __m128i vt = _mm_loadu_si128((const __m128i*)t);
- if (disty) {
- __m128i vb = _mm_loadu_si128((const __m128i*)b);
- vt = _mm_mulhi_epu16(vt, _mm_set1_epi16(0x10000 - disty));
- vb = _mm_mulhi_epu16(vb, _mm_set1_epi16(disty));
- vt = _mm_add_epi16(vt, vb);
- }
- if (distx) {
- const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
- const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
- vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
- vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
- }
-#ifdef Q_PROCESSOR_X86_64
- return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt));
-#else
- QRgba64 out;
- _mm_storel_epi64((__m128i*)&out, vt);
- return out;
-#endif
-}
-#else
-static inline QRgba64 interpolate_4_pixels_rgb64(QRgba64 t[], QRgba64 b[], uint distx, uint disty)
-{
- const uint dx = distx>>8;
- const uint dy = disty>>8;
- const uint idx = 256 - dx;
- const uint idy = 256 - dy;
- QRgba64 xtop = interpolate256(t[0], idx, t[1], dx);
- QRgba64 xbot = interpolate256(b[0], idx, b[1], dx);
- return interpolate256(xtop, idy, xbot, dy);
-}
-#endif
-
template<TextureBlendType blendType>
void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2);
@@ -1982,7 +2307,7 @@ inline void fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(int,
}
enum FastTransformTypes {
- SimpleUpscaleTransform,
+ SimpleScaleTransform,
UpscaleTransform,
DownscaleTransform,
RotateTransform,
@@ -1990,11 +2315,38 @@ enum FastTransformTypes {
NFastTransformTypes
};
+// Completes the partial interpolation stored in IntermediateBuffer.
+// by performing the x-axis interpolation and joining the RB and AG buffers.
+static void QT_FASTCALL intermediate_adder(uint *b, uint *end, const IntermediateBuffer &intermediate, int offset, int &fx, int fdx)
+{
+#if defined(QT_COMPILER_SUPPORTS_AVX2)
+ extern void QT_FASTCALL intermediate_adder_avx2(uint *b, uint *end, const IntermediateBuffer &intermediate, int offset, int &fx, int fdx);
+ if (qCpuHasFeature(AVX2))
+ return intermediate_adder_avx2(b, end, intermediate, offset, fx, fdx);
+#endif
+
+ // Switch to intermediate buffer coordinates
+ fx -= offset * fixed_scale;
+
+ while (b < end) {
+ const int x = (fx >> 16);
+
+ const uint distx = (fx & 0x0000ffff) >> 8;
+ const uint idistx = 256 - distx;
+ const uint rb = (intermediate.buffer_rb[x] * idistx + intermediate.buffer_rb[x + 1] * distx) & 0xff00ff00;
+ const uint ag = (intermediate.buffer_ag[x] * idistx + intermediate.buffer_ag[x + 1] * distx) & 0xff00ff00;
+ *b = (rb >> 8) | ag;
+ b++;
+ fx += fdx;
+ }
+ fx += offset * fixed_scale;
+}
+
typedef void (QT_FASTCALL *BilinearFastTransformHelper)(uint *b, uint *end, const QTextureData &image, int &fx, int &fy, int fdx, int fdy);
template<TextureBlendType blendType>
-static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper(uint *b, uint *end, const QTextureData &image,
- int &fx, int &fy, int fdx, int /*fdy*/)
+static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper(uint *b, uint *end, const QTextureData &image,
+ int &fx, int &fy, int fdx, int /*fdy*/)
{
int y1 = (fy >> 16);
int y2;
@@ -2011,16 +2363,12 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper(u
const int offset = (fx + adjust) >> 16;
int x = offset;
- // The idea is first to do the interpolation between the row s1 and the row s2
- // into an intermediate buffer, then we interpolate between two pixel of this buffer.
-
- // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
- // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG
- // +1 for the last pixel to interpolate with, and +1 for rounding errors.
- quint32 intermediate_buffer[2][buffer_size + 2];
- // count is the size used in the intermediate_buffer.
+ IntermediateBuffer intermediate;
+ // count is the size used in the intermediate.buffer.
int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
- Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
+ // length is supposed to be <= BufferSize either because data->m11 < 1 or
+ // data->m11 < 2, and any larger buffers split
+ Q_ASSERT(count <= BufferSize + 2);
int f = 0;
int lim = count;
if (blendType == BlendTransformedBilinearTiled) {
@@ -2035,8 +2383,8 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper(u
quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
do {
- intermediate_buffer[0][f] = rb;
- intermediate_buffer[1][f] = ag;
+ intermediate.buffer_rb[f] = rb;
+ intermediate.buffer_ag[f] = ag;
f++;
x++;
} while (x < image.x1 && f < lim);
@@ -2069,10 +2417,10 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper(u
// Add the values, and shift to only keep 8 significant bits per colors
__m128i rAG =_mm_add_epi16(topAG, bottomAG);
rAG = _mm_srli_epi16(rAG, 8);
- _mm_storeu_si128((__m128i*)(&intermediate_buffer[1][f]), rAG);
+ _mm_storeu_si128((__m128i*)(&intermediate.buffer_ag[f]), rAG);
__m128i rRB =_mm_add_epi16(topRB, bottomRB);
rRB = _mm_srli_epi16(rRB, 8);
- _mm_storeu_si128((__m128i*)(&intermediate_buffer[0][f]), rRB);
+ _mm_storeu_si128((__m128i*)(&intermediate.buffer_rb[f]), rRB);
}
#elif defined(__ARM_NEON__)
const int16x8_t disty_ = vdupq_n_s16(disty);
@@ -2099,10 +2447,10 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper(u
// Add the values, and shift to only keep 8 significant bits per colors
int16x8_t rAG = vaddq_s16(topAG, bottomAG);
rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8));
- vst1q_s16((int16_t*)(&intermediate_buffer[1][f]), rAG);
+ vst1q_s16((int16_t*)(&intermediate.buffer_ag[f]), rAG);
int16x8_t rRB = vaddq_s16(topRB, bottomRB);
rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8));
- vst1q_s16((int16_t*)(&intermediate_buffer[0][f]), rRB);
+ vst1q_s16((int16_t*)(&intermediate.buffer_rb[f]), rRB);
}
#endif
}
@@ -2116,28 +2464,13 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper(u
uint t = s1[x];
uint b = s2[x];
- intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
- intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ intermediate.buffer_rb[f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ intermediate.buffer_ag[f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
x++;
}
- // Now interpolate the values from the intermediate_buffer to get the final result.
- fx -= offset * fixed_scale; // Switch to intermediate buffer coordinates
-
- while (b < end) {
- int x1 = (fx >> 16);
- int x2 = x1 + 1;
- Q_ASSERT(x1 >= 0);
- Q_ASSERT(x2 < count);
-
- int distx = (fx & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int rb = ((intermediate_buffer[0][x1] * idistx + intermediate_buffer[0][x2] * distx) >> 8) & 0xff00ff;
- int ag = (intermediate_buffer[1][x1] * idistx + intermediate_buffer[1][x2] * distx) & 0xff00ff00;
- *b = rb | ag;
- b++;
- fx += fdx;
- }
+ // Now interpolate the values from the intermediate.buffer to get the final result.
+ intermediate_adder(b, end, intermediate, offset, fx, fdx);
}
template<TextureBlendType blendType>
@@ -2603,14 +2936,14 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint
static BilinearFastTransformHelper bilinearFastTransformHelperARGB32PM[2][NFastTransformTypes] = {
{
- fetchTransformedBilinearARGB32PM_simple_upscale_helper<BlendTransformedBilinear>,
+ fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinear>,
fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinear>,
fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinear>,
fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinear>,
fetchTransformedBilinearARGB32PM_fast_rotate_helper<BlendTransformedBilinear>
},
{
- fetchTransformedBilinearARGB32PM_simple_upscale_helper<BlendTransformedBilinearTiled>,
+ fetchTransformedBilinearARGB32PM_simple_scale_helper<BlendTransformedBilinearTiled>,
fetchTransformedBilinearARGB32PM_upscale_helper<BlendTransformedBilinearTiled>,
fetchTransformedBilinearARGB32PM_downscale_helper<BlendTransformedBilinearTiled>,
fetchTransformedBilinearARGB32PM_rotate_helper<BlendTransformedBilinearTiled>,
@@ -2645,7 +2978,13 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
if (fdy == 0) { // simple scale, no rotation or shear
if (qAbs(fdx) <= fixed_scale) {
// simple scale up on X
- bilinearFastTransformHelperARGB32PM[tiled][SimpleUpscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
+ bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
+ } else if (qAbs(fdx) <= 2 * fixed_scale) {
+ // simple scale down on X, less than 2x
+ const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
+ bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
+ if (mid != length)
+ bilinearFastTransformHelperARGB32PM[tiled][SimpleScaleTransform](buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
} else if (qAbs(data->m22) < qreal(1./8.)) {
// scale up more than 8x (on Y)
bilinearFastTransformHelperARGB32PM[tiled][UpscaleTransform](b, end, data->texture, fx, fy, fdx, fdy);
@@ -2713,16 +3052,13 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
return buffer;
}
-template<TextureBlendType blendType, QPixelLayout::BPP bpp>
-static void QT_FASTCALL fetchTransformedBilinear_simple_upscale_helper(uint *b, uint *end, const QTextureData &image,
- int &fx, int &fy, int fdx, int /*fdy*/)
+template<TextureBlendType blendType>
+static void QT_FASTCALL fetchTransformedBilinear_simple_scale_helper(uint *b, uint *end, const QTextureData &image,
+ int &fx, int &fy, int fdx, int /*fdy*/)
{
const QPixelLayout *layout = &qPixelLayouts[image.format];
const QVector<QRgb> *clut = image.colorTable;
- Q_ASSERT(bpp == QPixelLayout::BPPNone || bpp == layout->bpp);
- // When templated 'fetch' should be inlined at compile time:
- const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : fetchPixels<bpp>;
- const ConvertFunc convertToARGB32PM = layout->convertToARGB32PM;
+ const FetchAndConvertPixelsFunc fetch = layout->fetchToARGB32PM;
int y1 = (fy >> 16);
int y2;
@@ -2739,16 +3075,14 @@ static void QT_FASTCALL fetchTransformedBilinear_simple_upscale_helper(uint *b,
const int offset = (fx + adjust) >> 16;
int x = offset;
- // The idea is first to do the interpolation between the row s1 and the row s2
- // into an intermediate buffer, then we interpolate between two pixel of this buffer.
- // +1 for the last pixel to interpolate with, and +1 for rounding errors.
- uint buf1[buffer_size + 2];
- uint buf2[buffer_size + 2];
+ IntermediateBuffer intermediate;
+ uint *buf1 = intermediate.buffer_rb;
+ uint *buf2 = intermediate.buffer_ag;
const uint *ptr1;
const uint *ptr2;
int count = (qint64(length) * qAbs(fdx) + fixed_scale - 1) / fixed_scale + 2;
- Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
+ Q_ASSERT(count <= BufferSize + 2);
if (blendType == BlendTransformedBilinearTiled) {
x %= image.width;
@@ -2757,10 +3091,8 @@ static void QT_FASTCALL fetchTransformedBilinear_simple_upscale_helper(uint *b,
int len1 = qMin(count, image.width - x);
int len2 = qMin(x, count - len1);
- ptr1 = fetch(buf1, s1, x, len1);
- ptr1 = convertToARGB32PM(buf1, ptr1, len1, clut, 0);
- ptr2 = fetch(buf2, s2, x, len1);
- ptr2 = convertToARGB32PM(buf2, ptr2, len1, clut, 0);
+ ptr1 = fetch(buf1, s1, x, len1, clut, nullptr);
+ ptr2 = fetch(buf2, s2, x, len1, clut, nullptr);
for (int i = 0; i < len1; ++i) {
uint t = ptr1[i];
uint b = ptr2[i];
@@ -2769,10 +3101,8 @@ static void QT_FASTCALL fetchTransformedBilinear_simple_upscale_helper(uint *b,
}
if (len2) {
- ptr1 = fetch(buf1 + len1, s1, 0, len2);
- ptr1 = convertToARGB32PM(buf1 + len1, ptr1, len2, clut, 0);
- ptr2 = fetch(buf2 + len1, s2, 0, len2);
- ptr2 = convertToARGB32PM(buf2 + len1, ptr2, len2, clut, 0);
+ ptr1 = fetch(buf1 + len1, s1, 0, len2, clut, nullptr);
+ ptr2 = fetch(buf2 + len1, s2, 0, len2, clut, nullptr);
for (int i = 0; i < len2; ++i) {
uint t = ptr1[i];
uint b = ptr2[i];
@@ -2780,6 +3110,7 @@ static void QT_FASTCALL fetchTransformedBilinear_simple_upscale_helper(uint *b,
buf2[i + len1] = ((((t >> 8) & 0xff00ff) * idisty + ((b >> 8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
}
}
+ // Generate the rest by repeatedly repeating the previous set of pixels
for (int i = image.width; i < count; ++i) {
buf1[i] = buf1[i - image.width];
buf2[i] = buf2[i - image.width];
@@ -2790,10 +3121,8 @@ static void QT_FASTCALL fetchTransformedBilinear_simple_upscale_helper(uint *b,
int len = qMax(1, end - start);
int leading = start - x;
- ptr1 = fetch(buf1 + leading, s1, start, len);
- ptr1 = convertToARGB32PM(buf1 + leading, ptr1, len, clut, 0);
- ptr2 = fetch(buf2 + leading, s2, start, len);
- ptr2 = convertToARGB32PM(buf2 + leading, ptr2, len, clut, 0);
+ ptr1 = fetch(buf1 + leading, s1, start, len, clut, nullptr);
+ ptr2 = fetch(buf2 + leading, s2, start, len, clut, nullptr);
for (int i = 0; i < len; ++i) {
uint t = ptr1[i];
@@ -2812,35 +3141,21 @@ static void QT_FASTCALL fetchTransformedBilinear_simple_upscale_helper(uint *b,
}
}
- // Now interpolate the values from the intermediate_buffer to get the final result.
- fx -= offset * fixed_scale; // Switch to intermediate buffer coordinates
-
- while (b < end) {
- int x1 = (fx >> 16);
- int x2 = x1 + 1;
- Q_ASSERT(x1 >= 0);
- Q_ASSERT(x2 < count);
-
- int distx = (fx & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int rb = ((buf1[x1] * idistx + buf1[x2] * distx) >> 8) & 0xff00ff;
- int ag = (buf2[x1] * idistx + buf2[x2] * distx) & 0xff00ff00;
- *b++ = rb | ag;
- fx += fdx;
- }
+ // Now interpolate the values from the intermediate.buffer to get the final result.
+ intermediate_adder(b, end, intermediate, offset, fx, fdx);
}
-typedef void (QT_FASTCALL *BilinearFastTransformFetcher)(uint *buf1, uint *buf2, const int len, const QTextureData &image,
- int fx, int fy, const int fdx, const int fdy);
-
-template<TextureBlendType blendType, QPixelLayout::BPP bpp>
-static void QT_FASTCALL fetchTransformedBilinear_fetcher(uint *buf1, uint *buf2, const int len, const QTextureData &image,
+template<TextureBlendType blendType, QPixelLayout::BPP bpp, typename T>
+static void QT_FASTCALL fetchTransformedBilinear_fetcher(T *buf1, T *buf2, const int len, const QTextureData &image,
int fx, int fy, const int fdx, const int fdy)
{
const QPixelLayout &layout = qPixelLayouts[image.format];
- Q_ASSERT(bpp == QPixelLayout::BPPNone || bpp == layout.bpp);
- // When templated 'fetch1' should be inlined at compile time:
+ constexpr bool useFetch = (bpp < QPixelLayout::BPP32);
+ if (useFetch)
+ Q_ASSERT(sizeof(T) == sizeof(uint));
+ else
+ Q_ASSERT(layout.bpp == bpp);
const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout.bpp] : fetchPixel<bpp>;
if (fdy == 0) {
int y1 = (fy >> 16);
@@ -2857,8 +3172,13 @@ static void QT_FASTCALL fetchTransformedBilinear_fetcher(uint *buf1, uint *buf2,
fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
if (x1 != x2)
break;
- buf1[i * 2 + 0] = buf1[i * 2 + 1] = fetch1(s1, x1);
- buf2[i * 2 + 0] = buf2[i * 2 + 1] = fetch1(s2, x1);
+ if (useFetch) {
+ buf1[i * 2 + 0] = buf1[i * 2 + 1] = fetch1(s1, x1);
+ buf2[i * 2 + 0] = buf2[i * 2 + 1] = fetch1(s2, x1);
+ } else {
+ buf1[i * 2 + 0] = buf1[i * 2 + 1] = reinterpret_cast<const T *>(s1)[x1];
+ buf2[i * 2 + 0] = buf2[i * 2 + 1] = reinterpret_cast<const T *>(s2)[x1];
+ }
fx += fdx;
}
int fastLen = len;
@@ -2869,10 +3189,17 @@ static void QT_FASTCALL fetchTransformedBilinear_fetcher(uint *buf1, uint *buf2,
for (; i < fastLen; ++i) {
int x = (fx >> 16);
- buf1[i * 2 + 0] = fetch1(s1, x);
- buf1[i * 2 + 1] = fetch1(s1, x + 1);
- buf2[i * 2 + 0] = fetch1(s2, x);
- buf2[i * 2 + 1] = fetch1(s2, x + 1);
+ if (useFetch) {
+ buf1[i * 2 + 0] = fetch1(s1, x);
+ buf1[i * 2 + 1] = fetch1(s1, x + 1);
+ buf2[i * 2 + 0] = fetch1(s2, x);
+ buf2[i * 2 + 1] = fetch1(s2, x + 1);
+ } else {
+ buf1[i * 2 + 0] = reinterpret_cast<const T *>(s1)[x];
+ buf1[i * 2 + 1] = reinterpret_cast<const T *>(s1)[x + 1];
+ buf2[i * 2 + 0] = reinterpret_cast<const T *>(s2)[x];
+ buf2[i * 2 + 1] = reinterpret_cast<const T *>(s2)[x + 1];
+ }
fx += fdx;
}
}
@@ -2881,10 +3208,17 @@ static void QT_FASTCALL fetchTransformedBilinear_fetcher(uint *buf1, uint *buf2,
int x1 = (fx >> 16);
int x2;
fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
- buf1[i * 2 + 0] = fetch1(s1, x1);
- buf1[i * 2 + 1] = fetch1(s1, x2);
- buf2[i * 2 + 0] = fetch1(s2, x1);
- buf2[i * 2 + 1] = fetch1(s2, x2);
+ if (useFetch) {
+ buf1[i * 2 + 0] = fetch1(s1, x1);
+ buf1[i * 2 + 1] = fetch1(s1, x2);
+ buf2[i * 2 + 0] = fetch1(s2, x1);
+ buf2[i * 2 + 1] = fetch1(s2, x2);
+ } else {
+ buf1[i * 2 + 0] = reinterpret_cast<const T *>(s1)[x1];
+ buf1[i * 2 + 1] = reinterpret_cast<const T *>(s1)[x2];
+ buf2[i * 2 + 0] = reinterpret_cast<const T *>(s2)[x1];
+ buf2[i * 2 + 1] = reinterpret_cast<const T *>(s2)[x2];
+ }
fx += fdx;
}
} else {
@@ -2901,10 +3235,17 @@ static void QT_FASTCALL fetchTransformedBilinear_fetcher(uint *buf1, uint *buf2,
break;
const uchar *s1 = image.scanLine(y1);
const uchar *s2 = image.scanLine(y2);
- buf1[i * 2 + 0] = fetch1(s1, x1);
- buf1[i * 2 + 1] = fetch1(s1, x2);
- buf2[i * 2 + 0] = fetch1(s2, x1);
- buf2[i * 2 + 1] = fetch1(s2, x2);
+ if (useFetch) {
+ buf1[i * 2 + 0] = fetch1(s1, x1);
+ buf1[i * 2 + 1] = fetch1(s1, x2);
+ buf2[i * 2 + 0] = fetch1(s2, x1);
+ buf2[i * 2 + 1] = fetch1(s2, x2);
+ } else {
+ buf1[i * 2 + 0] = reinterpret_cast<const T *>(s1)[x1];
+ buf1[i * 2 + 1] = reinterpret_cast<const T *>(s1)[x2];
+ buf2[i * 2 + 0] = reinterpret_cast<const T *>(s2)[x1];
+ buf2[i * 2 + 1] = reinterpret_cast<const T *>(s2)[x2];
+ }
fx += fdx;
fy += fdy;
}
@@ -2923,10 +3264,17 @@ static void QT_FASTCALL fetchTransformedBilinear_fetcher(uint *buf1, uint *buf2,
int y = (fy >> 16);
const uchar *s1 = image.scanLine(y);
const uchar *s2 = s1 + image.bytesPerLine;
- buf1[i * 2 + 0] = fetch1(s1, x);
- buf1[i * 2 + 1] = fetch1(s1, x + 1);
- buf2[i * 2 + 0] = fetch1(s2, x);
- buf2[i * 2 + 1] = fetch1(s2, x + 1);
+ if (useFetch) {
+ buf1[i * 2 + 0] = fetch1(s1, x);
+ buf1[i * 2 + 1] = fetch1(s1, x + 1);
+ buf2[i * 2 + 0] = fetch1(s2, x);
+ buf2[i * 2 + 1] = fetch1(s2, x + 1);
+ } else {
+ buf1[i * 2 + 0] = reinterpret_cast<const T *>(s1)[x];
+ buf1[i * 2 + 1] = reinterpret_cast<const T *>(s1)[x + 1];
+ buf2[i * 2 + 0] = reinterpret_cast<const T *>(s2)[x];
+ buf2[i * 2 + 1] = reinterpret_cast<const T *>(s2)[x + 1];
+ }
fx += fdx;
fy += fdy;
}
@@ -2942,10 +3290,17 @@ static void QT_FASTCALL fetchTransformedBilinear_fetcher(uint *buf1, uint *buf2,
const uchar *s1 = image.scanLine(y1);
const uchar *s2 = image.scanLine(y2);
- buf1[i * 2 + 0] = fetch1(s1, x1);
- buf1[i * 2 + 1] = fetch1(s1, x2);
- buf2[i * 2 + 0] = fetch1(s2, x1);
- buf2[i * 2 + 1] = fetch1(s2, x2);
+ if (useFetch) {
+ buf1[i * 2 + 0] = fetch1(s1, x1);
+ buf1[i * 2 + 1] = fetch1(s1, x2);
+ buf2[i * 2 + 0] = fetch1(s2, x1);
+ buf2[i * 2 + 1] = fetch1(s2, x2);
+ } else {
+ buf1[i * 2 + 0] = reinterpret_cast<const T *>(s1)[x1];
+ buf1[i * 2 + 1] = reinterpret_cast<const T *>(s1)[x2];
+ buf2[i * 2 + 0] = reinterpret_cast<const T *>(s2)[x1];
+ buf2[i * 2 + 1] = reinterpret_cast<const T *>(s2)[x2];
+ }
fx += fdx;
fy += fdy;
}
@@ -2977,18 +3332,23 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
if (fdy == 0) { // simple scale, no rotation or shear
if (qAbs(fdx) <= fixed_scale) { // scale up on X
- fetchTransformedBilinear_simple_upscale_helper<blendType, bpp>(buffer, buffer + length, data->texture, fx, fy, fdx, fdy);
+ fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + length, data->texture, fx, fy, fdx, fdy);
+ } else if (qAbs(fdx) <= 2 * fixed_scale) { // scale down on X less than 2x
+ const int mid = (length * 2 < BufferSize) ? length : ((length + 1) / 2);
+ fetchTransformedBilinear_simple_scale_helper<blendType>(buffer, buffer + mid, data->texture, fx, fy, fdx, fdy);
+ if (mid != length)
+ fetchTransformedBilinear_simple_scale_helper<blendType>(buffer + mid, buffer + length, data->texture, fx, fy, fdx, fdy);
} else {
- const BilinearFastTransformFetcher fetcher = fetchTransformedBilinear_fetcher<blendType,bpp>;
+ const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
- uint buf1[buffer_size];
- uint buf2[buffer_size];
+ uint buf1[BufferSize];
+ uint buf2[BufferSize];
uint *b = buffer;
while (length) {
- int len = qMin(length, buffer_size / 2);
+ int len = qMin(length, BufferSize / 2);
fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, 0);
- layout->convertToARGB32PM(buf1, buf1, len * 2, clut, 0);
- layout->convertToARGB32PM(buf2, buf2, len * 2, clut, 0);
+ layout->convertToARGB32PM(buf1, len * 2, clut);
+ layout->convertToARGB32PM(buf2, len * 2, clut);
if (hasFastInterpolate4() || qAbs(data->m22) < qreal(1./8.)) { // scale up more than 8x (on Y)
int disty = (fy & 0x0000ffff) >> 8;
@@ -3014,16 +3374,16 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
}
}
} else { // rotation or shear
- const BilinearFastTransformFetcher fetcher = fetchTransformedBilinear_fetcher<blendType,bpp>;
+ const auto fetcher = fetchTransformedBilinear_fetcher<blendType,bpp,uint>;
- uint buf1[buffer_size];
- uint buf2[buffer_size];
+ uint buf1[BufferSize];
+ uint buf2[BufferSize];
uint *b = buffer;
while (length) {
- int len = qMin(length, buffer_size / 2);
+ int len = qMin(length, BufferSize / 2);
fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
- layout->convertToARGB32PM(buf1, buf1, len * 2, clut, 0);
- layout->convertToARGB32PM(buf2, buf2, len * 2, clut, 0);
+ layout->convertToARGB32PM(buf1, len * 2, clut);
+ layout->convertToARGB32PM(buf2, len * 2, clut);
if (hasFastInterpolate4() || qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.)) {
// If we are zooming more than 8 times, we use 8bit precision for the position.
@@ -3070,15 +3430,15 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
- uint buf1[buffer_size];
- uint buf2[buffer_size];
+ uint buf1[BufferSize];
+ uint buf2[BufferSize];
uint *b = buffer;
- int distxs[buffer_size / 2];
- int distys[buffer_size / 2];
+ int distxs[BufferSize / 2];
+ int distys[BufferSize / 2];
while (length) {
- int len = qMin(length, buffer_size / 2);
+ int len = qMin(length, BufferSize / 2);
for (int i = 0; i < len; ++i) {
const qreal iw = fw == 0 ? 1 : 1 / fw;
const qreal px = fx * iw - qreal(0.5);
@@ -3110,8 +3470,8 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
fw += fdw;
}
- layout->convertToARGB32PM(buf1, buf1, len * 2, clut, 0);
- layout->convertToARGB32PM(buf2, buf2, len * 2, clut, 0);
+ layout->convertToARGB32PM(buf1, len * 2, clut);
+ layout->convertToARGB32PM(buf2, len * 2, clut);
for (int i = 0; i < len; ++i) {
int distx = distxs[i];
@@ -3128,19 +3488,27 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
}
template<TextureBlendType blendType>
-static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, const Operator *,
- const QSpanData *data, int y, int x, int length)
+static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buffer, const QSpanData *data,
+ int y, int x, int length)
{
- const QPixelLayout *layout = &qPixelLayouts[data->texture.format];
+ const QTextureData &texture = data->texture;
+ const QPixelLayout *layout = &qPixelLayouts[texture.format];
const QVector<QRgb> *clut = data->texture.colorTable;
const qreal cx = x + qreal(0.5);
const qreal cy = y + qreal(0.5);
+ uint sbuf1[BufferSize];
+ uint sbuf2[BufferSize];
+ QRgba64 buf1[BufferSize];
+ QRgba64 buf2[BufferSize];
+ QRgba64 *end = buffer + length;
+ QRgba64 *b = buffer;
+
if (data->fast_matrix) {
// The increment pr x in the scanline
- int fdx = (int)(data->m11 * fixed_scale);
- int fdy = (int)(data->m12 * fixed_scale);
+ const int fdx = (int)(data->m11 * fixed_scale);
+ const int fdy = (int)(data->m12 * fixed_scale);
int fx = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
int fy = int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
@@ -3148,20 +3516,14 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
fx -= half_point;
fy -= half_point;
- const BilinearFastTransformFetcher fetcher =
+ const auto fetcher =
(layout->bpp == QPixelLayout::BPP32)
- ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32>
- : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone>;
+ ? fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP32, uint>
+ : fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPPNone, uint>;
if (fdy == 0) { //simple scale, no rotation
-
- uint sbuf1[buffer_size];
- uint sbuf2[buffer_size];
- quint64 buf1[buffer_size];
- quint64 buf2[buffer_size];
- QRgba64 *b = buffer;
while (length) {
- int len = qMin(length, buffer_size / 2);
+ int len = qMin(length, BufferSize / 2);
int disty = (fy & 0x0000ffff);
#if defined(__SSE2__)
const __m128i vdy = _mm_set1_epi16(disty);
@@ -3169,9 +3531,9 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
#endif
fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
- layout->convertToARGB64PM((QRgba64 *)buf1, sbuf1, len * 2, clut, 0);
+ layout->convertToRGBA64PM(buf1, sbuf1, len * 2, clut, 0);
if (disty)
- layout->convertToARGB64PM((QRgba64 *)buf2, sbuf2, len * 2, clut, 0);
+ layout->convertToRGBA64PM(buf2, sbuf2, len * 2, clut, 0);
for (int i = 0; i < len; ++i) {
int distx = (fx & 0x0000ffff);
@@ -3191,33 +3553,26 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
}
_mm_storel_epi64((__m128i*)(b+i), vt);
#else
- b[i] = interpolate_4_pixels_rgb64((QRgba64 *)buf1 + i*2, (QRgba64 *)buf2 + i*2, distx, disty);
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
#endif
fx += fdx;
}
length -= len;
b += len;
}
- } else { //rotation
- uint sbuf1[buffer_size];
- uint sbuf2[buffer_size];
- quint64 buf1[buffer_size];
- quint64 buf2[buffer_size];
- QRgba64 *end = buffer + length;
- QRgba64 *b = buffer;
-
+ } else { // rotation or shear
while (b < end) {
- int len = qMin(length, buffer_size / 2);
+ int len = qMin(length, BufferSize / 2);
fetcher(sbuf1, sbuf2, len, data->texture, fx, fy, fdx, fdy);
- layout->convertToARGB64PM((QRgba64 *)buf1, sbuf1, len * 2, clut, 0);
- layout->convertToARGB64PM((QRgba64 *)buf2, sbuf2, len * 2, clut, 0);
+ layout->convertToRGBA64PM(buf1, sbuf1, len * 2, clut, 0);
+ layout->convertToRGBA64PM(buf2, sbuf2, len * 2, clut, 0);
for (int i = 0; i < len; ++i) {
int distx = (fx & 0x0000ffff);
int disty = (fy & 0x0000ffff);
- b[i] = interpolate_4_pixels_rgb64((QRgba64 *)buf1 + i*2, (QRgba64 *)buf2 + i*2, distx, disty);
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
fx += fdx;
fy += fdy;
}
@@ -3226,7 +3581,7 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
b += len;
}
}
- } else {
+ } else { // !(data->fast_matrix)
const QTextureData &image = data->texture;
const qreal fdx = data->m11;
@@ -3238,17 +3593,12 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
FetchPixelFunc fetch = qFetchPixel[layout->bpp];
- uint sbuf1[buffer_size];
- uint sbuf2[buffer_size];
- quint64 buf1[buffer_size];
- quint64 buf2[buffer_size];
- QRgba64 *b = buffer;
- int distxs[buffer_size / 2];
- int distys[buffer_size / 2];
+ int distxs[BufferSize / 2];
+ int distys[BufferSize / 2];
- while (length) {
- int len = qMin(length, buffer_size / 2);
+ while (b < end) {
+ int len = qMin(length, BufferSize / 2);
for (int i = 0; i < len; ++i) {
const qreal iw = fw == 0 ? 1 : 1 / fw;
const qreal px = fx * iw - qreal(0.5);
@@ -3265,21 +3615,165 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
- const uchar *s1 = data->texture.scanLine(y1);
- const uchar *s2 = data->texture.scanLine(y2);
+ const uchar *s1 = texture.scanLine(y1);
+ const uchar *s2 = texture.scanLine(y2);
- if (layout->bpp == QPixelLayout::BPP32) {
- sbuf1[i * 2 + 0] = ((const uint*)s1)[x1];
- sbuf1[i * 2 + 1] = ((const uint*)s1)[x2];
- sbuf2[i * 2 + 0] = ((const uint*)s2)[x1];
- sbuf2[i * 2 + 1] = ((const uint*)s2)[x2];
+ sbuf1[i * 2 + 0] = fetch(s1, x1);
+ sbuf1[i * 2 + 1] = fetch(s1, x2);
+ sbuf2[i * 2 + 0] = fetch(s2, x1);
+ sbuf2[i * 2 + 1] = fetch(s2, x2);
- } else {
- sbuf1[i * 2 + 0] = fetch(s1, x1);
- sbuf1[i * 2 + 1] = fetch(s1, x2);
- sbuf2[i * 2 + 0] = fetch(s2, x1);
- sbuf2[i * 2 + 1] = fetch(s2, x2);
+ fx += fdx;
+ fy += fdy;
+ fw += fdw;
+ //force increment to avoid /0
+ if (!fw)
+ fw += fdw;
+ }
+
+ layout->convertToRGBA64PM(buf1, sbuf1, len * 2, clut, 0);
+ layout->convertToRGBA64PM(buf2, sbuf2, len * 2, clut, 0);
+
+ for (int i = 0; i < len; ++i) {
+ int distx = distxs[i];
+ int disty = distys[i];
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
+ }
+
+ length -= len;
+ b += len;
+ }
+ }
+ return buffer;
+}
+
+template<TextureBlendType blendType>
+static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint64(QRgba64 *buffer, const QSpanData *data,
+ int y, int x, int length)
+{
+ const QTextureData &texture = data->texture;
+ Q_ASSERT(qPixelLayouts[texture.format].bpp == QPixelLayout::BPP64);
+ const auto convert = (data->texture.format == QImage::Format_RGBA64) ? convertRGBA64ToRGBA64PM : convertRGBA64PMToRGBA64PM;
+
+ const qreal cx = x + qreal(0.5);
+ const qreal cy = y + qreal(0.5);
+
+ QRgba64 buf1[BufferSize];
+ QRgba64 buf2[BufferSize];
+ QRgba64 *end = buffer + length;
+ QRgba64 *b = buffer;
+
+ if (data->fast_matrix) {
+ // The increment pr x in the scanline
+ const int fdx = (int)(data->m11 * fixed_scale);
+ const int fdy = (int)(data->m12 * fixed_scale);
+
+ int fx = int((data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale);
+ int fy = int((data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale);
+
+ fx -= half_point;
+ fy -= half_point;
+ const auto fetcher = fetchTransformedBilinear_fetcher<blendType, QPixelLayout::BPP64, QRgba64>;
+
+ if (fdy == 0) { //simple scale, no rotation
+ while (length) {
+ int len = qMin(length, BufferSize / 2);
+ int disty = (fy & 0x0000ffff);
+#if defined(__SSE2__)
+ const __m128i vdy = _mm_set1_epi16(disty);
+ const __m128i vidy = _mm_set1_epi16(0x10000 - disty);
+#endif
+ fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
+
+ convert(buf1, len * 2);
+ if (disty)
+ convert(buf2, len * 2);
+
+ for (int i = 0; i < len; ++i) {
+ int distx = (fx & 0x0000ffff);
+#if defined(__SSE2__)
+ __m128i vt = _mm_loadu_si128((const __m128i*)(buf1 + i*2));
+ if (disty) {
+ __m128i vb = _mm_loadu_si128((const __m128i*)(buf2 + i*2));
+ vt = _mm_mulhi_epu16(vt, vidy);
+ vb = _mm_mulhi_epu16(vb, vdy);
+ vt = _mm_add_epi16(vt, vb);
+ }
+ if (distx) {
+ const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
+ vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
+ vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
+ }
+ _mm_storel_epi64((__m128i*)(b+i), vt);
+#else
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
+#endif
+ fx += fdx;
}
+ length -= len;
+ b += len;
+ }
+ } else { // rotation or shear
+ while (b < end) {
+ int len = qMin(length, BufferSize / 2);
+
+ fetcher(buf1, buf2, len, data->texture, fx, fy, fdx, fdy);
+
+ convert(buf1, len * 2);
+ convert(buf2, len * 2);
+
+ for (int i = 0; i < len; ++i) {
+ int distx = (fx & 0x0000ffff);
+ int disty = (fy & 0x0000ffff);
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
+ fx += fdx;
+ fy += fdy;
+ }
+
+ length -= len;
+ b += len;
+ }
+ }
+ } else { // !(data->fast_matrix)
+ const QTextureData &image = data->texture;
+
+ const qreal fdx = data->m11;
+ const qreal fdy = data->m12;
+ const qreal fdw = data->m13;
+
+ qreal fx = data->m21 * cy + data->m11 * cx + data->dx;
+ qreal fy = data->m22 * cy + data->m12 * cx + data->dy;
+ qreal fw = data->m23 * cy + data->m13 * cx + data->m33;
+
+ int distxs[BufferSize / 2];
+ int distys[BufferSize / 2];
+
+ while (b < end) {
+ int len = qMin(length, BufferSize / 2);
+ for (int i = 0; i < len; ++i) {
+ const qreal iw = fw == 0 ? 1 : 1 / fw;
+ const qreal px = fx * iw - qreal(0.5);
+ const qreal py = fy * iw - qreal(0.5);
+
+ int x1 = int(px) - (px < 0);
+ int x2;
+ int y1 = int(py) - (py < 0);
+ int y2;
+
+ distxs[i] = int((px - x1) * (1<<16));
+ distys[i] = int((py - y1) * (1<<16));
+
+ fetchTransformedBilinear_pixelBounds<blendType>(image.width, image.x1, image.x2 - 1, x1, x2);
+ fetchTransformedBilinear_pixelBounds<blendType>(image.height, image.y1, image.y2 - 1, y1, y2);
+
+ const uchar *s1 = texture.scanLine(y1);
+ const uchar *s2 = texture.scanLine(y2);
+
+ buf1[i * 2 + 0] = reinterpret_cast<const QRgba64 *>(s1)[x1];
+ buf1[i * 2 + 1] = reinterpret_cast<const QRgba64 *>(s1)[x2];
+ buf2[i * 2 + 0] = reinterpret_cast<const QRgba64 *>(s2)[x1];
+ buf2[i * 2 + 1] = reinterpret_cast<const QRgba64 *>(s2)[x2];
fx += fdx;
fy += fdy;
@@ -3289,23 +3783,31 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co
fw += fdw;
}
- layout->convertToARGB64PM((QRgba64 *)buf1, sbuf1, len * 2, clut, 0);
- layout->convertToARGB64PM((QRgba64 *)buf2, sbuf2, len * 2, clut, 0);
+ convert(buf1, len * 2);
+ convert(buf2, len * 2);
for (int i = 0; i < len; ++i) {
int distx = distxs[i];
int disty = distys[i];
- b[i] = interpolate_4_pixels_rgb64((QRgba64 *)buf1 + i*2, (QRgba64 *)buf2 + i*2, distx, disty);
+ b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty);
}
length -= len;
b += len;
}
}
-
return buffer;
}
+template<TextureBlendType blendType>
+static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, const Operator *,
+ const QSpanData *data, int y, int x, int length)
+{
+ if (qPixelLayouts[data->texture.format].bpp == QPixelLayout::BPP64)
+ return fetchTransformedBilinear64_uint64<blendType>(buffer, data, y, x, length);
+ return fetchTransformedBilinear64_uint32<blendType>(buffer, data, y, x, length);
+}
+
// FetchUntransformed can have more specialized methods added depending on SIMD features.
static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
0, // Invalid
@@ -3333,6 +3835,9 @@ static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
fetchUntransformed, // Format_A2RGB30_Premultiplied
fetchUntransformed, // Alpha8
fetchUntransformed, // Grayscale8
+ fetchUntransformed, // RGBX64
+ fetchUntransformed, // RGBA64
+ fetchUntransformed, // RGBA64_Premultiplied
};
static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = {
@@ -3353,6 +3858,15 @@ static SourceFetchProc sourceFetchARGB32PM[NBlendTypes] = {
fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled> // BilinearTiled
};
+static SourceFetchProc sourceFetchAny16[NBlendTypes] = {
+ fetchUntransformed, // Untransformed
+ fetchUntransformed, // Tiled
+ fetchTransformed<BlendTransformed, QPixelLayout::BPP16>, // Transformed
+ fetchTransformed<BlendTransformedTiled, QPixelLayout::BPP16>, // TransformedTiled
+ fetchTransformedBilinear<BlendTransformedBilinear, QPixelLayout::BPP16>, // TransformedBilinear
+ fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP16> // TransformedBilinearTiled
+};
+
static SourceFetchProc sourceFetchAny32[NBlendTypes] = {
fetchUntransformed, // Untransformed
fetchUntransformed, // Tiled
@@ -3371,17 +3885,35 @@ static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = {
fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
};
+static const SourceFetchProc64 sourceFetchRGBA64PM[NBlendTypes] = {
+ fetchUntransformedRGBA64PM, // Untransformed
+ fetchUntransformedRGBA64PM, // Tiled
+ fetchTransformed64<BlendTransformed>, // Transformed
+ fetchTransformed64<BlendTransformedTiled>, // TransformedTiled
+ fetchTransformedBilinear64<BlendTransformedBilinear>, // Bilinear
+ fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
+};
+
static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
{
if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
return sourceFetchARGB32PM[blendType];
if (blendType == BlendUntransformed || blendType == BlendTiled)
return sourceFetchUntransformed[format];
+ if (qPixelLayouts[format].bpp == QPixelLayout::BPP16)
+ return sourceFetchAny16[blendType];
if (qPixelLayouts[format].bpp == QPixelLayout::BPP32)
return sourceFetchAny32[blendType];
return sourceFetchGeneric[blendType];
}
+static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format)
+{
+ if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
+ return sourceFetchRGBA64PM[blendType];
+ return sourceFetchGeneric64[blendType];
+}
+
#define FIXPT_BITS 8
#define FIXPT_SIZE (1<<FIXPT_BITS)
@@ -3724,7 +4256,7 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
case QSpanData::Texture:
solidSource = !data->texture.hasAlpha;
op.srcFetch = getSourceFetch(getBlendType(data), data->texture.format);
- op.srcFetch64 = sourceFetchGeneric64[getBlendType(data)];
+ op.srcFetch64 = getSourceFetch64(getBlendType(data), data->texture.format);;
break;
default:
Q_UNREACHABLE();
@@ -3752,8 +4284,9 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in
// If all spans are opaque we do not need to fetch dest.
// But don't clear passthrough destFetch as they are just as fast and save destStore.
if (op.destFetch != destFetchARGB32P)
- op.destFetch = 0;
- op.destFetch64 = destFetch64Undefined;
+ op.destFetch = destFetchUndefined;
+ if (op.destFetch64 != destFetchRGB64)
+ op.destFetch64 = destFetch64Undefined;
}
}
@@ -3778,7 +4311,7 @@ static
void blend_color_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- uint buffer[buffer_size];
+ uint buffer[BufferSize];
Operator op = getOperator(data, spans, count);
const uint color = data->solid.color.toArgb32();
@@ -3786,8 +4319,8 @@ void blend_color_generic(int count, const QSpan *spans, void *userData)
int x = spans->x;
int length = spans->len;
while (length) {
- int l = qMin(buffer_size, length);
- uint *dest = op.destFetch ? op.destFetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
+ int l = qMin(BufferSize, length);
+ uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans->y, l);
op.funcSolid(dest, l, color, spans->coverage);
if (op.destStore)
op.destStore(data->rasterBuffer, x, spans->y, dest, l);
@@ -3802,7 +4335,7 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- Operator op = getOperator(data, spans, count);
+ const Operator op = getOperator(data, spans, count);
const uint color = data->solid.color.toArgb32();
if (op.mode == QPainter::CompositionMode_Source) {
@@ -3838,17 +4371,31 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData)
return blend_color_generic(count, spans, userData);
}
- quint64 buffer[buffer_size];
+ quint64 buffer[BufferSize];
const QRgba64 color = data->solid.color;
+ bool solidFill = data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source
+ || (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver && color.isOpaque());
+ bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32;
while (count--) {
int x = spans->x;
int length = spans->len;
+ if (solidFill && isBpp32 && spans->coverage == 255) {
+ // If dest doesn't matter we don't need to bother with blending or converting all the identical pixels
+ if (length > 0) {
+ op.destStore64(data->rasterBuffer, x, spans->y, &color, 1);
+ uint *dest = (uint*)data->rasterBuffer->scanLine(spans->y) + x;
+ qt_memfill32(dest + 1, dest[0], length - 1);
+ length = 0;
+ }
+ }
+
while (length) {
- int l = qMin(buffer_size, length);
+ int l = qMin(BufferSize, length);
QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l);
op.funcSolid64(dest, l, color, spans->coverage);
- op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
+ if (op.destStore64)
+ op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
length -= l;
x += l;
}
@@ -3950,7 +4497,7 @@ void handleSpans(int count, const QSpan *spans, const QSpanData *data, T &handle
int length = right - x;
while (length) {
- int l = qMin(buffer_size, length);
+ int l = qMin(BufferSize, length);
length -= l;
int process_length = l;
@@ -3997,8 +4544,8 @@ struct QBlendBase
BlendType *dest;
- BlendType buffer[buffer_size];
- BlendType src_buffer[buffer_size];
+ BlendType buffer[BufferSize];
+ BlendType src_buffer[BufferSize];
};
class BlendSrcGeneric : public QBlendBase<uint>
@@ -4011,7 +4558,7 @@ public:
const uint *fetch(int x, int y, int len)
{
- dest = op.destFetch ? op.destFetch(buffer, data->rasterBuffer, x, y, len) : buffer;
+ dest = op.destFetch(buffer, data->rasterBuffer, x, y, len);
return op.srcFetch(src_buffer, &op, data, y, x, len);
}
@@ -4037,7 +4584,7 @@ public:
bool isSupported() const
{
- return op.func64 && op.destFetch64 && op.destStore64;
+ return op.func64 && op.destFetch64;
}
const quint64 *fetch(int x, int y, int len)
@@ -4053,7 +4600,8 @@ public:
void store(int x, int y, int len)
{
- op.destStore64(data->rasterBuffer, x, y, (QRgba64 *)dest, len);
+ if (op.destStore64)
+ op.destStore64(data->rasterBuffer, x, y, (QRgba64 *)dest, len);
}
};
@@ -4082,8 +4630,8 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- uint buffer[buffer_size];
- uint src_buffer[buffer_size];
+ uint buffer[BufferSize];
+ uint src_buffer[BufferSize];
Operator op = getOperator(data, spans, count);
const int image_width = data->texture.width;
@@ -4107,9 +4655,9 @@ static void blend_untransformed_generic(int count, const QSpan *spans, void *use
if (length > 0) {
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
while (length) {
- int l = qMin(buffer_size, length);
+ int l = qMin(BufferSize, length);
const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
- uint *dest = op.destFetch ? op.destFetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
+ uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans->y, l);
op.func(dest, src, l, coverage);
if (op.destStore)
op.destStore(data->rasterBuffer, x, spans->y, dest, l);
@@ -4132,8 +4680,8 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
qCDebug(lcQtGuiDrawHelper, "blend_untransformed_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
return blend_untransformed_generic(count, spans, userData);
}
- quint64 buffer[buffer_size];
- quint64 src_buffer[buffer_size];
+ quint64 buffer[BufferSize];
+ quint64 src_buffer[BufferSize];
const int image_width = data->texture.width;
const int image_height = data->texture.height;
@@ -4156,11 +4704,12 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi
if (length > 0) {
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
while (length) {
- int l = qMin(buffer_size, length);
+ int l = qMin(BufferSize, length);
const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, l);
QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l);
op.func64(dest, src, l, coverage);
- op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
+ if (op.destStore64)
+ op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
x += l;
sx += l;
length -= l;
@@ -4320,8 +4869,8 @@ static void blend_tiled_generic(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- uint buffer[buffer_size];
- uint src_buffer[buffer_size];
+ uint buffer[BufferSize];
+ uint src_buffer[BufferSize];
Operator op = getOperator(data, spans, count);
const int image_width = data->texture.width;
@@ -4347,10 +4896,10 @@ static void blend_tiled_generic(int count, const QSpan *spans, void *userData)
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
while (length) {
int l = qMin(image_width - sx, length);
- if (buffer_size < l)
- l = buffer_size;
+ if (BufferSize < l)
+ l = BufferSize;
const uint *src = op.srcFetch(src_buffer, &op, data, sy, sx, l);
- uint *dest = op.destFetch ? op.destFetch(buffer, data->rasterBuffer, x, spans->y, l) : buffer;
+ uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans->y, l);
op.func(dest, src, l, coverage);
if (op.destStore)
op.destStore(data->rasterBuffer, x, spans->y, dest, l);
@@ -4373,8 +4922,8 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD
qCDebug(lcQtGuiDrawHelper, "blend_tiled_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit");
return blend_tiled_generic(count, spans, userData);
}
- quint64 buffer[buffer_size];
- quint64 src_buffer[buffer_size];
+ quint64 buffer[BufferSize];
+ quint64 src_buffer[BufferSize];
const int image_width = data->texture.width;
const int image_height = data->texture.height;
@@ -4386,6 +4935,50 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD
if (yoff < 0)
yoff += image_height;
+ bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32;
+ if (op.destFetch64 == destFetch64Undefined && image_width <= BufferSize && isBpp32) {
+ // If destination isn't blended into the result, we can do the tiling directly on destination pixels.
+ while (count--) {
+ int x = spans->x;
+ int y = spans->y;
+ int length = spans->len;
+ int sx = (xoff + spans->x) % image_width;
+ int sy = (spans->y + yoff) % image_height;
+ if (sx < 0)
+ sx += image_width;
+ if (sy < 0)
+ sy += image_height;
+
+ int sl = qMin(image_width, length);
+ if (sx > 0 && sl > 0) {
+ int l = qMin(image_width - sx, sl);
+ const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, l);
+ op.destStore64(data->rasterBuffer, x, y, src, l);
+ x += l;
+ sx += l;
+ sl -= l;
+ if (sx >= image_width)
+ sx = 0;
+ }
+ if (sl > 0) {
+ Q_ASSERT(sx == 0);
+ const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, sl);
+ op.destStore64(data->rasterBuffer, x, y, src, sl);
+ x += sl;
+ sx += sl;
+ sl -= sl;
+ if (sx >= image_width)
+ sx = 0;
+ }
+ uint *dest = (uint*)data->rasterBuffer->scanLine(y) + x - image_width;
+ for (int i = image_width; i < length; ++i) {
+ dest[i] = dest[i - image_width];
+ }
+ ++spans;
+ }
+ return;
+ }
+
while (count--) {
int x = spans->x;
int length = spans->len;
@@ -4399,12 +4992,13 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
while (length) {
int l = qMin(image_width - sx, length);
- if (buffer_size < l)
- l = buffer_size;
+ if (BufferSize < l)
+ l = BufferSize;
const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, l);
QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l);
op.func64(dest, src, l, coverage);
- op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
+ if (op.destStore64)
+ op.destStore64(data->rasterBuffer, x, spans->y, dest, l);
x += l;
sx += l;
length -= l;
@@ -4449,8 +5043,8 @@ static void blend_tiled_argb(int count, const QSpan *spans, void *userData)
const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
while (length) {
int l = qMin(image_width - sx, length);
- if (buffer_size < l)
- l = buffer_size;
+ if (BufferSize < l)
+ l = BufferSize;
const uint *src = (const uint *)data->texture.scanLine(sy) + sx;
uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x;
op.func(dest, src, l, coverage);
@@ -4509,8 +5103,8 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
int tx = x;
while (length) {
int l = qMin(image_width - sx, length);
- if (buffer_size < l)
- l = buffer_size;
+ if (BufferSize < l)
+ l = BufferSize;
quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + tx;
const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx;
memcpy(dest, src, l * sizeof(quint16));
@@ -4545,8 +5139,8 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
if (alpha > 0) {
while (length) {
int l = qMin(image_width - sx, length);
- if (buffer_size < l)
- l = buffer_size;
+ if (BufferSize < l)
+ l = BufferSize;
quint16 *dest = ((quint16 *)data->rasterBuffer->scanLine(spans->y)) + x;
const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx;
blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha);
@@ -4562,723 +5156,12 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
}
}
-static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData*>(userData);
- QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
-
- if (data->texture.format != QImage::Format_RGB16
- || (mode != QPainter::CompositionMode_SourceOver
- && mode != QPainter::CompositionMode_Source))
- {
- blend_src_generic(count, spans, userData);
- return;
- }
-
- quint16 buffer[buffer_size];
-
- const int src_minx = data->texture.x1;
- const int src_miny = data->texture.y1;
- const int src_maxx = data->texture.x2 - 1;
- const int src_maxy = data->texture.y2 - 1;
-
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- const int fdx = (int)(data->m11 * fixed_scale);
- const int fdy = (int)(data->m12 * fixed_scale);
-
- while (count--) {
- const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- const quint8 alpha = (coverage + 1) >> 3;
- const quint8 ialpha = 0x20 - alpha;
- if (alpha == 0) {
- ++spans;
- continue;
- }
-
- quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
- int x = int((data->m21 * cy
- + data->m11 * cx + data->dx) * fixed_scale) - half_point;
- int y = int((data->m22 * cy
- + data->m12 * cx + data->dy) * fixed_scale) - half_point;
- int length = spans->len;
-
- while (length) {
- int l;
- quint16 *b;
- if (ialpha == 0) {
- l = length;
- b = dest;
- } else {
- l = qMin(length, buffer_size);
- b = buffer;
- }
- const quint16 *end = b + l;
-
- while (b < end) {
- int x1 = (x >> 16);
- int x2;
- int y1 = (y >> 16);
- int y2;
-
- fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_minx, src_maxx, x1, x2);
- fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2);
-
- const quint16 *src1 = (const quint16*)data->texture.scanLine(y1);
- const quint16 *src2 = (const quint16*)data->texture.scanLine(y2);
- quint16 tl = src1[x1];
- const quint16 tr = src1[x2];
- quint16 bl = src2[x1];
- const quint16 br = src2[x2];
-
- const uint distxsl8 = x & 0xff00;
- const uint distysl8 = y & 0xff00;
- const uint distx = distxsl8 >> 8;
- const uint disty = distysl8 >> 8;
- const uint distxy = distx * disty;
-
- const uint tlw = 0x10000 - distxsl8 - distysl8 + distxy; // (256 - distx) * (256 - disty)
- const uint trw = distxsl8 - distxy; // distx * (256 - disty)
- const uint blw = distysl8 - distxy; // (256 - distx) * disty
- const uint brw = distxy; // distx * disty
- uint red = ((tl & 0xf800) * tlw + (tr & 0xf800) * trw
- + (bl & 0xf800) * blw + (br & 0xf800) * brw) & 0xf8000000;
- uint green = ((tl & 0x07e0) * tlw + (tr & 0x07e0) * trw
- + (bl & 0x07e0) * blw + (br & 0x07e0) * brw) & 0x07e00000;
- uint blue = ((tl & 0x001f) * tlw + (tr & 0x001f) * trw
- + (bl & 0x001f) * blw + (br & 0x001f) * brw);
- *b = quint16((red | green | blue) >> 16);
-
- ++b;
- x += fdx;
- y += fdy;
- }
-
- if (ialpha != 0)
- blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
-
- dest += l;
- length -= l;
- }
- ++spans;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
-
- while (count--) {
- const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- const quint8 alpha = (coverage + 1) >> 3;
- const quint8 ialpha = 0x20 - alpha;
- if (alpha == 0) {
- ++spans;
- continue;
- }
-
- quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
-
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
-
- qreal x = data->m21 * cy + data->m11 * cx + data->dx;
- qreal y = data->m22 * cy + data->m12 * cx + data->dy;
- qreal w = data->m23 * cy + data->m13 * cx + data->m33;
-
- int length = spans->len;
- while (length) {
- int l;
- quint16 *b;
- if (ialpha == 0) {
- l = length;
- b = dest;
- } else {
- l = qMin(length, buffer_size);
- b = buffer;
- }
- const quint16 *end = b + l;
-
- while (b < end) {
- const qreal iw = w == 0 ? 1 : 1 / w;
- const qreal px = x * iw - qreal(0.5);
- const qreal py = y * iw - qreal(0.5);
-
- int x1 = int(px) - (px < 0);
- int x2;
- int y1 = int(py) - (py < 0);
- int y2;
-
- fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_minx, src_maxx, x1, x2);
- fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(0, src_miny, src_maxy, y1, y2);
-
- const quint16 *src1 = (const quint16 *)data->texture.scanLine(y1);
- const quint16 *src2 = (const quint16 *)data->texture.scanLine(y2);
- quint16 tl = src1[x1];
- const quint16 tr = src1[x2];
- quint16 bl = src2[x1];
- const quint16 br = src2[x2];
-
- const uint distx = uint((px - x1) * 256);
- const uint disty = uint((py - y1) * 256);
- const uint distxsl8 = distx << 8;
- const uint distysl8 = disty << 8;
- const uint distxy = distx * disty;
-
- const uint tlw = 0x10000 - distxsl8 - distysl8 + distxy; // (256 - distx) * (256 - disty)
- const uint trw = distxsl8 - distxy; // distx * (256 - disty)
- const uint blw = distysl8 - distxy; // (256 - distx) * disty
- const uint brw = distxy; // distx * disty
- uint red = ((tl & 0xf800) * tlw + (tr & 0xf800) * trw
- + (bl & 0xf800) * blw + (br & 0xf800) * brw) & 0xf8000000;
- uint green = ((tl & 0x07e0) * tlw + (tr & 0x07e0) * trw
- + (bl & 0x07e0) * blw + (br & 0x07e0) * brw) & 0x07e00000;
- uint blue = ((tl & 0x001f) * tlw + (tr & 0x001f) * trw
- + (bl & 0x001f) * blw + (br & 0x001f) * brw);
- *b = quint16((red | green | blue) >> 16);
-
- ++b;
- x += fdx;
- y += fdy;
- w += fdw;
- }
-
- if (ialpha != 0)
- blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
-
- dest += l;
- length -= l;
- }
- ++spans;
- }
- }
-}
-
-static void blend_transformed_argb(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- if (data->texture.format != QImage::Format_ARGB32_Premultiplied
- && data->texture.format != QImage::Format_RGB32) {
- blend_src_generic(count, spans, userData);
- return;
- }
-
- CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];
- uint buffer[buffer_size];
- quint32 mask = (data->texture.format == QImage::Format_RGB32) ? 0xff000000 : 0;
-
- const int image_x1 = data->texture.x1;
- const int image_y1 = data->texture.y1;
- const int image_x2 = data->texture.x2 - 1;
- const int image_y2 = data->texture.y2 - 1;
-
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- int fdx = (int)(data->m11 * fixed_scale);
- int fdy = (int)(data->m12 * fixed_scale);
-
- while (count--) {
- void *t = data->rasterBuffer->scanLine(spans->y);
-
- uint *target = ((uint *)t) + spans->x;
-
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
-
- int x = int((data->m21 * cy
- + data->m11 * cx + data->dx) * fixed_scale);
- int y = int((data->m22 * cy
- + data->m12 * cx + data->dy) * fixed_scale);
-
- int length = spans->len;
- const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
- while (length) {
- int l = qMin(length, buffer_size);
- const uint *end = buffer + l;
- uint *b = buffer;
- while (b < end) {
- int px = qBound(image_x1, x >> 16, image_x2);
- int py = qBound(image_y1, y >> 16, image_y2);
- *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px] | mask;
-
- x += fdx;
- y += fdy;
- ++b;
- }
- func(target, buffer, l, coverage);
- target += l;
- length -= l;
- }
- ++spans;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
- while (count--) {
- void *t = data->rasterBuffer->scanLine(spans->y);
-
- uint *target = ((uint *)t) + spans->x;
-
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
-
- qreal x = data->m21 * cy + data->m11 * cx + data->dx;
- qreal y = data->m22 * cy + data->m12 * cx + data->dy;
- qreal w = data->m23 * cy + data->m13 * cx + data->m33;
-
- int length = spans->len;
- const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
- while (length) {
- int l = qMin(length, buffer_size);
- const uint *end = buffer + l;
- uint *b = buffer;
- while (b < end) {
- const qreal iw = w == 0 ? 1 : 1 / w;
- const qreal tx = x * iw;
- const qreal ty = y * iw;
- const int px = qBound(image_x1, int(tx) - (tx < 0), image_x2);
- const int py = qBound(image_y1, int(ty) - (ty < 0), image_y2);
-
- *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px] | mask;
- x += fdx;
- y += fdy;
- w += fdw;
-
- ++b;
- }
- func(target, buffer, l, coverage);
- target += l;
- length -= l;
- }
- ++spans;
- }
- }
-}
-
-static void blend_transformed_rgb565(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData*>(userData);
- QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
-
- if (data->texture.format != QImage::Format_RGB16
- || (mode != QPainter::CompositionMode_SourceOver
- && mode != QPainter::CompositionMode_Source))
- {
- blend_src_generic(count, spans, userData);
- return;
- }
-
- quint16 buffer[buffer_size];
- const int image_x1 = data->texture.x1;
- const int image_y1 = data->texture.y1;
- const int image_x2 = data->texture.x2 - 1;
- const int image_y2 = data->texture.y2 - 1;
-
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- const int fdx = (int)(data->m11 * fixed_scale);
- const int fdy = (int)(data->m12 * fixed_scale);
-
- while (count--) {
- const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- const quint8 alpha = (coverage + 1) >> 3;
- const quint8 ialpha = 0x20 - alpha;
- if (alpha == 0) {
- ++spans;
- continue;
- }
-
- quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
- int x = int((data->m21 * cy
- + data->m11 * cx + data->dx) * fixed_scale);
- int y = int((data->m22 * cy
- + data->m12 * cx + data->dy) * fixed_scale);
- int length = spans->len;
-
- while (length) {
- int l;
- quint16 *b;
- if (ialpha == 0) {
- l = length;
- b = dest;
- } else {
- l = qMin(length, buffer_size);
- b = buffer;
- }
- const quint16 *end = b + l;
-
- while (b < end) {
- const int px = qBound(image_x1, x >> 16, image_x2);
- const int py = qBound(image_y1, y >> 16, image_y2);
-
- *b = ((const quint16 *)data->texture.scanLine(py))[px];
- ++b;
-
- x += fdx;
- y += fdy;
- }
-
- if (ialpha != 0)
- blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
-
- dest += l;
- length -= l;
- }
- ++spans;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
-
- while (count--) {
- const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- const quint8 alpha = (coverage + 1) >> 3;
- const quint8 ialpha = 0x20 - alpha;
- if (alpha == 0) {
- ++spans;
- continue;
- }
-
- quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
-
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
-
- qreal x = data->m21 * cy + data->m11 * cx + data->dx;
- qreal y = data->m22 * cy + data->m12 * cx + data->dy;
- qreal w = data->m23 * cy + data->m13 * cx + data->m33;
-
- int length = spans->len;
- while (length) {
- int l;
- quint16 *b;
- if (ialpha == 0) {
- l = length;
- b = dest;
- } else {
- l = qMin(length, buffer_size);
- b = buffer;
- }
- const quint16 *end = b + l;
-
- while (b < end) {
- const qreal iw = w == 0 ? 1 : 1 / w;
- const qreal tx = x * iw;
- const qreal ty = y * iw;
-
- const int px = qBound(image_x1, int(tx) - (tx < 0), image_x2);
- const int py = qBound(image_y1, int(ty) - (ty < 0), image_y2);
-
- *b = ((const quint16 *)data->texture.scanLine(py))[px];
- ++b;
-
- x += fdx;
- y += fdy;
- w += fdw;
- }
-
- if (ialpha != 0)
- blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
-
- dest += l;
- length -= l;
- }
- ++spans;
- }
- }
-}
-
-static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- if (data->texture.format != QImage::Format_ARGB32_Premultiplied
- && data->texture.format != QImage::Format_RGB32) {
- blend_src_generic(count, spans, userData);
- return;
- }
-
- CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];
- uint buffer[buffer_size];
-
- int image_width = data->texture.width;
- int image_height = data->texture.height;
- const qsizetype scanline_offset = data->texture.bytesPerLine / 4;
-
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- int fdx = (int)(data->m11 * fixed_scale);
- int fdy = (int)(data->m12 * fixed_scale);
-
- while (count--) {
- void *t = data->rasterBuffer->scanLine(spans->y);
-
- uint *target = ((uint *)t) + spans->x;
- const uint *image_bits = (const uint *)data->texture.imageData;
-
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
-
- int x = int((data->m21 * cy
- + data->m11 * cx + data->dx) * fixed_scale);
- int y = int((data->m22 * cy
- + data->m12 * cx + data->dy) * fixed_scale);
-
- const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
- int length = spans->len;
- while (length) {
- int l = qMin(length, buffer_size);
- const uint *end = buffer + l;
- uint *b = buffer;
- int px16 = x % (image_width << 16);
- int py16 = y % (image_height << 16);
- int px_delta = fdx % (image_width << 16);
- int py_delta = fdy % (image_height << 16);
- while (b < end) {
- if (px16 < 0) px16 += image_width << 16;
- if (py16 < 0) py16 += image_height << 16;
- int px = px16 >> 16;
- int py = py16 >> 16;
- int y_offset = py * scanline_offset;
-
- Q_ASSERT(px >= 0 && px < image_width);
- Q_ASSERT(py >= 0 && py < image_height);
-
- *b = image_bits[y_offset + px];
- x += fdx;
- y += fdy;
- px16 += px_delta;
- if (px16 >= image_width << 16)
- px16 -= image_width << 16;
- py16 += py_delta;
- if (py16 >= image_height << 16)
- py16 -= image_height << 16;
- ++b;
- }
- func(target, buffer, l, coverage);
- target += l;
- length -= l;
- }
- ++spans;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
- while (count--) {
- void *t = data->rasterBuffer->scanLine(spans->y);
-
- uint *target = ((uint *)t) + spans->x;
- const uint *image_bits = (const uint *)data->texture.imageData;
-
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
-
- qreal x = data->m21 * cy + data->m11 * cx + data->dx;
- qreal y = data->m22 * cy + data->m12 * cx + data->dy;
- qreal w = data->m23 * cy + data->m13 * cx + data->m33;
-
- const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;
- int length = spans->len;
- while (length) {
- int l = qMin(length, buffer_size);
- const uint *end = buffer + l;
- uint *b = buffer;
- while (b < end) {
- const qreal iw = w == 0 ? 1 : 1 / w;
- const qreal tx = x * iw;
- const qreal ty = y * iw;
- int px = int(tx) - (tx < 0);
- int py = int(ty) - (ty < 0);
-
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
- int y_offset = py * scanline_offset;
-
- Q_ASSERT(px >= 0 && px < image_width);
- Q_ASSERT(py >= 0 && py < image_height);
-
- *b = image_bits[y_offset + px];
- x += fdx;
- y += fdy;
- w += fdw;
- //force increment to avoid /0
- if (!w) {
- w += fdw;
- }
- ++b;
- }
- func(target, buffer, l, coverage);
- target += l;
- length -= l;
- }
- ++spans;
- }
- }
-}
-
-static void blend_transformed_tiled_rgb565(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData*>(userData);
- QPainter::CompositionMode mode = data->rasterBuffer->compositionMode;
-
- if (data->texture.format != QImage::Format_RGB16
- || (mode != QPainter::CompositionMode_SourceOver
- && mode != QPainter::CompositionMode_Source))
- {
- blend_src_generic(count, spans, userData);
- return;
- }
-
- quint16 buffer[buffer_size];
- const int image_width = data->texture.width;
- const int image_height = data->texture.height;
-
- if (data->fast_matrix) {
- // The increment pr x in the scanline
- const int fdx = (int)(data->m11 * fixed_scale);
- const int fdy = (int)(data->m12 * fixed_scale);
-
- while (count--) {
- const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- const quint8 alpha = (coverage + 1) >> 3;
- const quint8 ialpha = 0x20 - alpha;
- if (alpha == 0) {
- ++spans;
- continue;
- }
-
- quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
- int x = int((data->m21 * cy
- + data->m11 * cx + data->dx) * fixed_scale);
- int y = int((data->m22 * cy
- + data->m12 * cx + data->dy) * fixed_scale);
- int length = spans->len;
-
- while (length) {
- int l;
- quint16 *b;
- if (ialpha == 0) {
- l = length;
- b = dest;
- } else {
- l = qMin(length, buffer_size);
- b = buffer;
- }
- const quint16 *end = b + l;
-
- while (b < end) {
- int px = (x >> 16) % image_width;
- int py = (y >> 16) % image_height;
-
- if (px < 0)
- px += image_width;
- if (py < 0)
- py += image_height;
-
- *b = ((const quint16 *)data->texture.scanLine(py))[px];
- ++b;
-
- x += fdx;
- y += fdy;
- }
-
- if (ialpha != 0)
- blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
-
- dest += l;
- length -= l;
- }
- ++spans;
- }
- } else {
- const qreal fdx = data->m11;
- const qreal fdy = data->m12;
- const qreal fdw = data->m13;
-
- while (count--) {
- const quint8 coverage = (data->texture.const_alpha * spans->coverage) >> 8;
- const quint8 alpha = (coverage + 1) >> 3;
- const quint8 ialpha = 0x20 - alpha;
- if (alpha == 0) {
- ++spans;
- continue;
- }
-
- quint16 *dest = (quint16 *)data->rasterBuffer->scanLine(spans->y) + spans->x;
-
- const qreal cx = spans->x + qreal(0.5);
- const qreal cy = spans->y + qreal(0.5);
-
- qreal x = data->m21 * cy + data->m11 * cx + data->dx;
- qreal y = data->m22 * cy + data->m12 * cx + data->dy;
- qreal w = data->m23 * cy + data->m13 * cx + data->m33;
-
- int length = spans->len;
- while (length) {
- int l;
- quint16 *b;
- if (ialpha == 0) {
- l = length;
- b = dest;
- } else {
- l = qMin(length, buffer_size);
- b = buffer;
- }
- const quint16 *end = b + l;
-
- while (b < end) {
- const qreal iw = w == 0 ? 1 : 1 / w;
- const qreal tx = x * iw;
- const qreal ty = y * iw;
-
- int px = int(tx) - (tx < 0);
- int py = int(ty) - (ty < 0);
-
- px %= image_width;
- py %= image_height;
- if (px < 0)
- px += image_width;
- if (py < 0)
- py += image_height;
-
- *b = ((const quint16 *)data->texture.scanLine(py))[px];
- ++b;
-
- x += fdx;
- y += fdy;
- w += fdw;
- // force increment to avoid /0
- if (!w)
- w += fdw;
- }
-
- if (ialpha != 0)
- blend_sourceOver_rgb16_rgb16(dest, buffer, l, alpha, ialpha);
-
- dest += l;
- length -= l;
- }
- ++spans;
- }
- }
-}
-
-
/* Image formats here are target formats */
static const ProcessSpans processTextureSpansARGB32PM[NBlendTypes] = {
blend_untransformed_argb, // Untransformed
blend_tiled_argb, // Tiled
- blend_transformed_argb, // Transformed
- blend_transformed_tiled_argb, // TransformedTiled
+ blend_src_generic, // Transformed
+ blend_src_generic, // TransformedTiled
blend_src_generic, // TransformedBilinear
blend_src_generic // TransformedBilinearTiled
};
@@ -5286,9 +5169,9 @@ static const ProcessSpans processTextureSpansARGB32PM[NBlendTypes] = {
static const ProcessSpans processTextureSpansRGB16[NBlendTypes] = {
blend_untransformed_rgb565, // Untransformed
blend_tiled_rgb565, // Tiled
- blend_transformed_rgb565, // Transformed
- blend_transformed_tiled_rgb565, // TransformedTiled
- blend_transformed_bilinear_rgb565, // TransformedBilinear
+ blend_src_generic, // Transformed
+ blend_src_generic, // TransformedTiled
+ blend_src_generic, // TransformedBilinear
blend_src_generic // TransformedBilinearTiled
};
@@ -5330,6 +5213,9 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
case QImage::Format_A2BGR30_Premultiplied:
case QImage::Format_RGB30:
case QImage::Format_A2RGB30_Premultiplied:
+ case QImage::Format_RGBX64:
+ case QImage::Format_RGBA64:
+ case QImage::Format_RGBA64_Premultiplied:
proc = processTextureSpansGeneric64[blendType];
break;
case QImage::Format_Invalid:
@@ -5586,7 +5472,7 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
- quint64 buffer[buffer_size];
+ quint64 buffer[BufferSize];
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
@@ -5595,13 +5481,14 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
int i = x;
int length = mapWidth;
while (length > 0) {
- int l = qMin(buffer_size, length);
+ int l = qMin(BufferSize, length);
QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, i, y + ly, l);
for (int j=0; j < l; ++j) {
const int coverage = map[j + (i - x)];
alphamapblend_generic(coverage, dest, j, srcColor, color, colorProfile);
}
- destStore64(rasterBuffer, i, y + ly, dest, l);
+ if (destStore64)
+ destStore64(rasterBuffer, i, y + ly, dest, l);
length -= l;
i += l;
}
@@ -5624,14 +5511,15 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
int end = qMin<int>(x + mapWidth, clip.x + clip.len);
if (end <= start)
continue;
- Q_ASSERT(end - start <= buffer_size);
+ Q_ASSERT(end - start <= BufferSize);
QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start);
for (int xp=start; xp<end; ++xp) {
const int coverage = map[xp - x];
alphamapblend_generic(coverage, dest, xp - start, srcColor, color, colorProfile);
}
- destStore64(rasterBuffer, start, clip.y, dest, end - start);
+ if (destStore64)
+ destStore64(rasterBuffer, start, clip.y, dest, end - start);
} // for (i -> line.count)
map += mapStride;
} // for (yp -> bottom)
@@ -5903,7 +5791,7 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied();
}
- quint64 buffer[buffer_size];
+ quint64 buffer[BufferSize];
const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format];
const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format];
@@ -5912,13 +5800,14 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
int i = x;
int length = mapWidth;
while (length > 0) {
- int l = qMin(buffer_size, length);
+ int l = qMin(BufferSize, length);
QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, i, y + ly, l);
for (int j=0; j < l; ++j) {
const uint coverage = src[j + (i - x)];
alphargbblend_generic(coverage, dest, j, srcColor, color, colorProfile);
}
- destStore64(rasterBuffer, i, y + ly, dest, l);
+ if (destStore64)
+ destStore64(rasterBuffer, i, y + ly, dest, l);
length -= l;
i += l;
}
@@ -5941,14 +5830,15 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
int end = qMin<int>(x + mapWidth, clip.x + clip.len);
if (end <= start)
continue;
- Q_ASSERT(end - start <= buffer_size);
+ Q_ASSERT(end - start <= BufferSize);
QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start);
for (int xp=start; xp<end; ++xp) {
const uint coverage = src[xp - x];
alphargbblend_generic(coverage, dest, xp - start, srcColor, color, colorProfile);
}
- destStore64(rasterBuffer, start, clip.y, dest, end - start);
+ if (destStore64)
+ destStore64(rasterBuffer, start, clip.y, dest, end - start);
} // for (i -> line.count)
src += srcStride;
} // for (yp -> bottom)
@@ -6031,8 +5921,24 @@ static void qt_rectfill_quint16(QRasterBuffer *rasterBuffer,
int x, int y, int width, int height,
const QRgba64 &color)
{
+ const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
+ quint32 c32 = color.toArgb32();
+ quint16 c16;
+ layout.storeFromARGB32PM(reinterpret_cast<uchar *>(&c16), &c32, 0, 1, nullptr, nullptr);
qt_rectfill<quint16>(reinterpret_cast<quint16 *>(rasterBuffer->buffer()),
- color.toRgb16(), x, y, width, height, rasterBuffer->bytesPerLine());
+ c16, x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
+static void qt_rectfill_quint24(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ const QRgba64 &color)
+{
+ const QPixelLayout &layout = qPixelLayouts[rasterBuffer->format];
+ quint32 c32 = color.toArgb32();
+ quint24 c24;
+ layout.storeFromARGB32PM(reinterpret_cast<uchar *>(&c24), &c32, 0, 1, nullptr, nullptr);
+ qt_rectfill<quint24>(reinterpret_cast<quint24 *>(rasterBuffer->buffer()),
+ c24, x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_nonpremul_argb32(QRasterBuffer *rasterBuffer,
@@ -6084,6 +5990,17 @@ static void qt_rectfill_gray(QRasterBuffer *rasterBuffer,
qGray(color.toArgb32()), x, y, width, height, rasterBuffer->bytesPerLine());
}
+static void qt_rectfill_quint64(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ const QRgba64 &color)
+{
+ const auto store = qStoreFromRGBA64PM[rasterBuffer->format];
+ quint64 c64;
+ store(reinterpret_cast<uchar *>(&c64), &color, 0, 1, nullptr, nullptr);
+ qt_rectfill<quint64>(reinterpret_cast<quint64 *>(rasterBuffer->buffer()),
+ c64, x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
// Map table for destination image format. Contains function pointers
// for blends of various types unto the destination
@@ -6152,7 +6069,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
- 0
+ qt_rectfill_quint24
},
// Format_RGB666
{
@@ -6161,7 +6078,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
- 0
+ qt_rectfill_quint24
},
// Format_ARGB6666_Premultiplied
{
@@ -6170,7 +6087,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
- 0
+ qt_rectfill_quint24
},
// Format_RGB555
{
@@ -6179,7 +6096,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
- 0
+ qt_rectfill_quint16
},
// Format_ARGB8555_Premultiplied
{
@@ -6188,7 +6105,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
- 0
+ qt_rectfill_quint24
},
// Format_RGB888
{
@@ -6197,7 +6114,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
- 0
+ qt_rectfill_quint24
},
// Format_RGB444
{
@@ -6206,7 +6123,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
- 0
+ qt_rectfill_quint16
},
// Format_ARGB4444_Premultiplied
{
@@ -6215,7 +6132,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
0,
qt_alphamapblit_generic,
qt_alphargbblit_generic,
- 0
+ qt_rectfill_quint16
},
// Format_RGBX8888
{
@@ -6298,6 +6215,33 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_alphargbblit_generic,
qt_rectfill_gray
},
+ // Format_RGBX64
+ {
+ blend_color_generic_rgb64,
+ blend_src_generic_rgb64,
+ 0,
+ qt_alphamapblit_generic,
+ qt_alphargbblit_generic,
+ qt_rectfill_quint64
+ },
+ // Format_RGBA64
+ {
+ blend_color_generic_rgb64,
+ blend_src_generic_rgb64,
+ 0,
+ qt_alphamapblit_generic,
+ qt_alphargbblit_generic,
+ qt_rectfill_quint64
+ },
+ // Format_RGBA64_Premultiplied
+ {
+ blend_color_generic_rgb64,
+ blend_src_generic_rgb64,
+ 0,
+ qt_alphamapblit_generic,
+ qt_alphargbblit_generic,
+ qt_rectfill_quint64
+ },
};
#if defined(Q_CC_MSVC) && !defined(_MIPS_)
@@ -6370,7 +6314,7 @@ void qt_memfill32(quint32 *dest, quint32 color, int count)
#endif
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
-template<QtPixelOrder> const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QVector<QRgb> *, QDitherInfo *);
+template<QtPixelOrder> void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, const QVector<QRgb> *, QDitherInfo *);
#endif
extern void qInitBlendFunctions();
@@ -6439,42 +6383,54 @@ static void qInitDrawhelperFunctions()
int w, int h,
int const_alpha);
- extern void QT_FASTCALL storePixelsBPP24_ssse3(uchar *dest, const uint *src, int index, int count);
extern const uint * QT_FASTCALL qt_fetchUntransformed_888_ssse3(uint *buffer, const Operator *, const QSpanData *data,
int y, int x, int length);
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
- qStorePixels[QPixelLayout::BPP24] = storePixelsBPP24_ssse3;
sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_ssse3;
}
#endif // SSSE3
#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
if (qCpuHasFeature(SSE4_1)) {
- extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ extern void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, int count, const QVector<QRgb> *);
+ extern void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, int count, const QVector<QRgb> *);
+ extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_sse4(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
- extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ extern void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
- extern const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *);
- extern const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ extern void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
- extern const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count,
+ extern void QT_FASTCALL storeRGBXFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
+ extern void QT_FASTCALL storeARGB32FromRGBA64PM_sse4(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern void QT_FASTCALL storeRGBA8888FromRGBA64PM_sse4(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
+ extern void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
+ qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_sse4;
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4;
+ qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_sse4;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4;
- qPixelLayouts[QImage::Format_ARGB32].convertFromARGB32PM = convertARGB32FromARGB32PM_sse4;
- qPixelLayouts[QImage::Format_RGBA8888].convertFromARGB32PM = convertRGBA8888FromARGB32PM_sse4;
- qPixelLayouts[QImage::Format_RGBX8888].convertFromARGB32PM = convertRGBXFromARGB32PM_sse4;
- qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].convertFromARGB32PM = convertA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>;
- qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].convertFromARGB32PM = convertA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>;
+ qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4;
+ qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4;
+ qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_sse4;
+ qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>;
+ qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>;
+ qStoreFromRGBA64PM[QImage::Format_ARGB32] = storeARGB32FromRGBA64PM_sse4;
+ qStoreFromRGBA64PM[QImage::Format_RGBA8888] = storeRGBA8888FromRGBA64PM_sse4;
+ destStoreProc64[QImage::Format_ARGB32] = destStore64ARGB32_sse4;
+ destStoreProc64[QImage::Format_RGBA8888] = destStore64RGBA8888_sse4;
}
#endif
#if defined(QT_COMPILER_SUPPORTS_AVX2)
- if (qCpuHasFeature(AVX2)) {
+ if (qCpuHasFeature(ArchHaswell)) {
extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h, int const_alpha);
@@ -6504,14 +6460,14 @@ static void qInitDrawhelperFunctions()
qt_functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_avx2;
qt_functionForModeSolid64_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_rgb64_avx2;
- extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper_avx2(uint *b, uint *end, const QTextureData &image,
- int &fx, int &fy, int fdx, int /*fdy*/);
+ extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end, const QTextureData &image,
+ int &fx, int &fy, int fdx, int /*fdy*/);
extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_avx2(uint *b, uint *end, const QTextureData &image,
int &fx, int &fy, int fdx, int /*fdy*/);
extern void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint *b, uint *end, const QTextureData &image,
int &fx, int &fy, int fdx, int fdy);
- bilinearFastTransformHelperARGB32PM[0][SimpleUpscaleTransform] = fetchTransformedBilinearARGB32PM_simple_upscale_helper_avx2;
+ bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2;
bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_avx2;
bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2;
}
@@ -6543,11 +6499,15 @@ static void qInitDrawhelperFunctions()
sourceFetchUntransformed[QImage::Format_RGB888] = qt_fetchUntransformed_888_neon;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, const uint *src, int count,
+ extern void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *);
+ extern void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *);
+ extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
+ extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
- extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *);
+ qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon;
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon;
+ qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon;
#endif
diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp
index 3a70524a9d..ec6643deed 100644
--- a/src/gui/painting/qdrawhelper_avx2.cpp
+++ b/src/gui/painting/qdrawhelper_avx2.cpp
@@ -45,8 +45,6 @@
QT_BEGIN_NAMESPACE
-static Q_CONSTEXPR int BufferSize = 2048;
-
enum {
FixedScale = 1 << 16,
HalfPoint = 1 << 15
@@ -576,8 +574,10 @@ inline void fetchTransformedBilinear_pixelBounds(int, int l1, int l2, int &v1, i
Q_ASSERT(v2 >= l1 && v2 <= l2);
}
-void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper_avx2(uint *b, uint *end, const QTextureData &image,
- int &fx, int &fy, int fdx, int /*fdy*/)
+void QT_FASTCALL intermediate_adder_avx2(uint *b, uint *end, const IntermediateBuffer &intermediate, int offset, int &fx, int fdx);
+
+void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2(uint *b, uint *end, const QTextureData &image,
+ int &fx, int &fy, int fdx, int /*fdy*/)
{
int y1 = (fy >> 16);
int y2;
@@ -594,16 +594,12 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper_avx2(uin
const int offset = (fx + adjust) >> 16;
int x = offset;
- // The idea is first to do the interpolation between the row s1 and the row s2
- // into an intermediate buffer, then we interpolate between two pixel of this buffer.
-
- // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
- // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG
- // +1 for the last pixel to interpolate with, and +1 for rounding errors.
- quint32 intermediate_buffer[2][BufferSize + 2];
+ IntermediateBuffer intermediate;
// count is the size used in the intermediate_buffer.
int count = (qint64(length) * qAbs(fdx) + FixedScale - 1) / FixedScale + 2;
- Q_ASSERT(count <= BufferSize + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case
+ // length is supposed to be <= BufferSize either because data->m11 < 1 or
+ // data->m11 < 2, and any larger buffers split
+ Q_ASSERT(count <= BufferSize + 2);
int f = 0;
int lim = qMin(count, image.x2 - x);
if (x < image.x1) {
@@ -613,8 +609,8 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper_avx2(uin
quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
do {
- intermediate_buffer[0][f] = rb;
- intermediate_buffer[1][f] = ag;
+ intermediate.buffer_rb[f] = rb;
+ intermediate.buffer_ag[f] = ag;
f++;
x++;
} while (x < image.x1 && f < lim);
@@ -644,10 +640,10 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper_avx2(uin
// Add the values, and shift to only keep 8 significant bits per colors
__m256i rAG =_mm256_add_epi16(topAG, bottomAG);
rAG = _mm256_srli_epi16(rAG, 8);
- _mm256_storeu_si256((__m256i*)(&intermediate_buffer[1][f]), rAG);
+ _mm256_storeu_si256((__m256i*)(&intermediate.buffer_ag[f]), rAG);
__m256i rRB =_mm256_add_epi16(topRB, bottomRB);
rRB = _mm256_srli_epi16(rRB, 8);
- _mm256_storeu_si256((__m256i*)(&intermediate_buffer[0][f]), rRB);
+ _mm256_storeu_si256((__m256i*)(&intermediate.buffer_rb[f]), rRB);
}
for (; f < count; f++) { // Same as above but without simd
@@ -656,30 +652,37 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper_avx2(uin
uint t = s1[x];
uint b = s2[x];
- intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
- intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ intermediate.buffer_rb[f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff;
+ intermediate.buffer_ag[f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff;
x++;
}
+
// Now interpolate the values from the intermediate_buffer to get the final result.
+ intermediate_adder_avx2(b, end, intermediate, offset, fx, fdx);
+}
+
+void QT_FASTCALL intermediate_adder_avx2(uint *b, uint *end, const IntermediateBuffer &intermediate, int offset, int &fx, int fdx)
+{
fx -= offset * FixedScale;
const __m128i v_fdx = _mm_set1_epi32(fdx * 4);
const __m128i v_blend = _mm_set1_epi32(0x00800080);
+ const __m128i vdx_shuffle = _mm_set_epi8(char(0x80), 13, char(0x80), 13, char(0x80), 9, char(0x80), 9,
+ char(0x80), 5, char(0x80), 5, char(0x80), 1, char(0x80), 1);
__m128i v_fx = _mm_setr_epi32(fx, fx + fdx, fx + fdx + fdx, fx + fdx + fdx + fdx);
while (b < end - 3) {
const __m128i offset = _mm_srli_epi32(v_fx, 16);
- __m256i vrb = _mm256_i32gather_epi64((const long long *)intermediate_buffer[0], offset, 4);
- __m256i vag = _mm256_i32gather_epi64((const long long *)intermediate_buffer[1], offset, 4);
+ __m256i vrb = _mm256_i32gather_epi64((const long long *)intermediate.buffer_rb, offset, 4);
+ __m256i vag = _mm256_i32gather_epi64((const long long *)intermediate.buffer_ag, offset, 4);
- __m128i vdx = _mm_and_si128(v_fx, _mm_set1_epi32(0x0000ffff));
- vdx = _mm_srli_epi16(vdx, 8);
- __m128i vidx = _mm_sub_epi32(_mm_set1_epi32(256), vdx);
+ __m128i vdx = _mm_shuffle_epi8(v_fx, vdx_shuffle);
+ __m128i vidx = _mm_sub_epi16(_mm_set1_epi16(256), vdx);
__m256i vmulx = _mm256_castsi128_si256(_mm_unpacklo_epi32(vidx, vdx));
vmulx = _mm256_inserti128_si256(vmulx, _mm_unpackhi_epi32(vidx, vdx), 1);
- vrb = _mm256_mullo_epi32(vrb, vmulx);
- vag = _mm256_mullo_epi32(vag, vmulx);
+ vrb = _mm256_mullo_epi16(vrb, vmulx);
+ vag = _mm256_mullo_epi16(vag, vmulx);
__m256i vrbag = _mm256_hadd_epi32(vrb, vag);
vrbag = _mm256_permute4x64_epi64(vrbag, _MM_SHUFFLE(3, 1, 2, 0));
@@ -691,21 +694,21 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_simple_upscale_helper_avx2(uin
_mm_storeu_si128((__m128i*)b, _mm_blendv_epi8(ag, rb, v_blend));
b += 4;
- fx += 4 * fdx;
v_fx = _mm_add_epi32(v_fx, v_fdx);
}
+ fx = _mm_cvtsi128_si32(v_fx);
while (b < end) {
- int x = (fx >> 16);
-
- uint distx = (fx & 0x0000ffff) >> 8;
- uint idistx = 256 - distx;
+ const int x = (fx >> 16);
- uint rb = ((intermediate_buffer[0][x] * idistx + intermediate_buffer[0][x + 1] * distx) >> 8) & 0xff00ff;
- uint ag = (intermediate_buffer[1][x] * idistx + intermediate_buffer[1][x + 1] * distx) & 0xff00ff00;
- *b = rb | ag;
+ const uint distx = (fx & 0x0000ffff) >> 8;
+ const uint idistx = 256 - distx;
+ const uint rb = (intermediate.buffer_rb[x] * idistx + intermediate.buffer_rb[x + 1] * distx) & 0xff00ff00;
+ const uint ag = (intermediate.buffer_ag[x] * idistx + intermediate.buffer_ag[x + 1] * distx) & 0xff00ff00;
+ *b = (rb >> 8) | ag;
b++;
fx += fdx;
}
+ fx += offset * FixedScale;
}
void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper_avx2(uint *b, uint *end, const QTextureData &image,
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index e126f4b670..98995f485a 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -1153,17 +1153,27 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int
}
}
-const uint *QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *)
+{
+ convertARGBToARGB32PM_neon<false>(buffer, buffer, count);
+}
+
+void QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *)
{
- convertARGBToARGB32PM_neon<false>(buffer, src, count);
+ convertARGBToARGB32PM_neon<true>(buffer, buffer, count);
+}
+
+const uint *QT_FASTCALL fetchARGB32ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToARGB32PM_neon<false>(buffer, reinterpret_cast<const uint *>(src) + index, count);
return buffer;
}
-const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_neon(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
- convertARGBToARGB32PM_neon<true>(buffer, src, count);
+ convertARGBToARGB32PM_neon<true>(buffer, reinterpret_cast<const uint *>(src) + index, count);
return buffer;
}
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 6f3c92ca64..fb08261205 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -747,6 +747,77 @@ static constexpr inline bool hasFastInterpolate4() { return false; }
#endif
+static inline QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
+{
+ return QRgba64::fromRgba64((rgba64.red() * alpha256) >> 8,
+ (rgba64.green() * alpha256) >> 8,
+ (rgba64.blue() * alpha256) >> 8,
+ (rgba64.alpha() * alpha256) >> 8);
+}
+static inline QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
+{
+ return QRgba64::fromRgba64(multiplyAlpha256(x, alpha1) + multiplyAlpha256(y, alpha2));
+}
+
+#ifdef __SSE2__
+static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
+{
+ __m128i vt = _mm_loadu_si128((const __m128i*)t);
+ if (disty) {
+ __m128i vb = _mm_loadu_si128((const __m128i*)b);
+ vt = _mm_mulhi_epu16(vt, _mm_set1_epi16(0x10000 - disty));
+ vb = _mm_mulhi_epu16(vb, _mm_set1_epi16(disty));
+ vt = _mm_add_epi16(vt, vb);
+ }
+ if (distx) {
+ const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
+ vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
+ vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
+ }
+#ifdef Q_PROCESSOR_X86_64
+ return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt));
+#else
+ QRgba64 out;
+ _mm_storel_epi64((__m128i*)&out, vt);
+ return out;
+#endif // Q_PROCESSOR_X86_64
+}
+#elif defined(__ARM_NEON__)
+static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
+{
+ uint64x1x2_t vt = vld2_u64(reinterpret_cast<const uint64_t *>(t));
+ if (disty) {
+ uint64x1x2_t vb = vld2_u64(reinterpret_cast<const uint64_t *>(b));
+ uint32x4_t vt0 = vmull_n_u16(vreinterpret_u16_u64(vt.val[0]), 0x10000 - disty);
+ uint32x4_t vt1 = vmull_n_u16(vreinterpret_u16_u64(vt.val[1]), 0x10000 - disty);
+ vt0 = vmlal_n_u16(vt0, vreinterpret_u16_u64(vb.val[0]), disty);
+ vt1 = vmlal_n_u16(vt1, vreinterpret_u16_u64(vb.val[1]), disty);
+ vt.val[0] = vreinterpret_u64_u16(vshrn_n_u32(vt0, 16));
+ vt.val[1] = vreinterpret_u64_u16(vshrn_n_u32(vt1, 16));
+ }
+ if (distx) {
+ uint32x4_t vt0 = vmull_n_u16(vreinterpret_u16_u64(vt.val[0]), 0x10000 - distx);
+ vt0 = vmlal_n_u16(vt0, vreinterpret_u16_u64(vt.val[1]), distx);
+ vt.val[0] = vreinterpret_u64_u16(vshrn_n_u32(vt0, 16));
+ }
+ QRgba64 out;
+ vst1_u64(reinterpret_cast<uint64_t *>(&out), vt.val[0]);
+ return out;
+}
+#else
+static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
+{
+ const uint dx = distx>>8;
+ const uint dy = disty>>8;
+ const uint idx = 256 - dx;
+ const uint idy = 256 - dy;
+ QRgba64 xtop = interpolate256(t[0], idx, t[1], dx);
+ QRgba64 xbot = interpolate256(b[0], idx, b[1], dx);
+ return interpolate256(xtop, idy, xbot, dy);
+}
+#endif // __SSE2__
+
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
quint32 rgb = x >> 8;
@@ -798,6 +869,7 @@ static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c)
}
struct quint24 {
+ quint24() = default;
quint24(uint value);
operator uint() const;
uchar data[3];
@@ -1142,6 +1214,8 @@ static Q_ALWAYS_INLINE const uint *qt_convertRGBA8888ToARGB32PM(uint *buffer, co
return buffer;
}
+template<bool RGBA> void qt_convertRGBA64ToARGB32(uint *dst, const QRgba64 *src, int count);
+
const uint qt_bayer_matrix[16][16] = {
{ 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},
@@ -1205,15 +1279,43 @@ inline uint comp_func_Plus_one_pixel(uint d, const uint s)
#undef MIX
#undef AMIX
+// must be multiple of 4 for easier SIMD implementations
+static Q_CONSTEXPR int BufferSize = 2048;
+
+// A buffer of intermediate results used by simple bilinear scaling.
+struct IntermediateBuffer
+{
+ // The idea is first to do the interpolation between the row s1 and the row s2
+ // into this intermediate buffer, then later interpolate between two pixel of this buffer.
+ //
+ // buffer_rb is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
+ // buffer_ag is the alpha-green component of the pixel, in the form 0x00AA00GG
+ // +1 for the last pixel to interpolate with, and +1 for rounding errors.
+ quint32 buffer_rb[BufferSize+2];
+ quint32 buffer_ag[BufferSize+2];
+};
+
struct QDitherInfo {
int x;
int y;
};
-typedef const uint *(QT_FASTCALL *ConvertFunc)(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *clut, QDitherInfo *dither);
-typedef const QRgba64 *(QT_FASTCALL *ConvertFunc64)(QRgba64 *buffer, const uint *src, int count,
- const QVector<QRgb> *clut, QDitherInfo *dither);
+typedef const uint *(QT_FASTCALL *FetchAndConvertPixelsFunc)(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *clut, QDitherInfo *dither);
+typedef void (QT_FASTCALL *ConvertAndStorePixelsFunc)(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *clut, QDitherInfo *dither);
+
+typedef const QRgba64 *(QT_FASTCALL *FetchAndConvertPixelsFunc64)(QRgba64 *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *clut, QDitherInfo *dither);
+typedef void (QT_FASTCALL *ConvertAndStorePixelsFunc64)(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *clut, QDitherInfo *dither);
+
+typedef void (QT_FASTCALL *ConvertFunc)(uint *buffer, int count, const QVector<QRgb> *clut);
+typedef void (QT_FASTCALL *Convert64Func)(quint64 *buffer, int count, const QVector<QRgb> *clut);
+typedef const QRgba64 *(QT_FASTCALL *ConvertTo64Func)(QRgba64 *buffer, const uint *src, int count,
+ const QVector<QRgb> *clut, QDitherInfo *dither);
+typedef void (QT_FASTCALL *RbSwapFunc)(uchar *dst, const uchar *src, int count);
+
struct QPixelLayout
{
@@ -1226,36 +1328,28 @@ struct QPixelLayout
BPP16,
BPP24,
BPP32,
+ BPP64,
BPPCount
};
- // All numbers in bits.
- uchar redWidth;
- uchar redShift;
- uchar greenWidth;
- uchar greenShift;
- uchar blueWidth;
- uchar blueShift;
- uchar alphaWidth;
- uchar alphaShift;
+ bool hasAlphaChannel;
bool premultiplied;
BPP bpp;
+ RbSwapFunc rbSwap;
ConvertFunc convertToARGB32PM;
- ConvertFunc convertFromARGB32PM;
- ConvertFunc convertFromRGB32;
- ConvertFunc64 convertToARGB64PM;
+ ConvertTo64Func convertToRGBA64PM;
+ FetchAndConvertPixelsFunc fetchToARGB32PM;
+ FetchAndConvertPixelsFunc64 fetchToRGBA64PM;
+ ConvertAndStorePixelsFunc storeFromARGB32PM;
+ ConvertAndStorePixelsFunc storeFromRGB32;
};
-typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count);
-typedef void (QT_FASTCALL *StorePixelsFunc)(uchar *dest, const uint *src, int index, int count);
+extern ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats];
extern QPixelLayout qPixelLayouts[QImage::NImageFormats];
-extern const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount];
-extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount];
extern MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3];
-
QT_END_NAMESPACE
#endif // QDRAWHELPER_P_H
diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp
index 14bfaabf09..e3cc1dd43e 100644
--- a/src/gui/painting/qdrawhelper_sse4.cpp
+++ b/src/gui/painting/qdrawhelper_sse4.cpp
@@ -39,13 +39,14 @@
#include <private/qdrawhelper_p.h>
#include <private/qdrawingprimitive_sse2_p.h>
+#include <private/qpaintengine_raster_p.h>
#if defined(QT_COMPILER_SUPPORTS_SSE4_1)
QT_BEGIN_NAMESPACE
template<bool RGBA>
-static inline void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int count)
+static void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int count)
{
int i = 0;
const __m128i alphaMask = _mm_set1_epi32(0xff000000);
@@ -83,7 +84,7 @@ static inline void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int
_mm_storeu_si128((__m128i *)&buffer[i], srcVector);
}
} else {
- _mm_storeu_si128((__m128i *)&buffer[i], _mm_setzero_si128());
+ _mm_storeu_si128((__m128i *)&buffer[i], zero);
}
}
@@ -93,59 +94,264 @@ static inline void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int
}
}
-const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+static inline __m128 reciprocal_mul_ps(__m128 a, float mul)
{
- convertARGBToARGB32PM_sse4<false>(buffer, src, count);
- return buffer;
+ __m128 ia = _mm_rcp_ps(a); // Approximate 1/a
+ // Improve precision of ia using Newton-Raphson
+ ia = _mm_sub_ps(_mm_add_ps(ia, ia), _mm_mul_ps(ia, _mm_mul_ps(ia, a)));
+ ia = _mm_mul_ps(ia, _mm_set1_ps(mul));
+ return ia;
}
-const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+template<bool RGBA, bool RGBx>
+static inline void convertARGBFromARGB32PM_sse4(uint *buffer, const uint *src, int count)
{
- convertARGBToARGB32PM_sse4<true>(buffer, src, count);
- return buffer;
+ int i = 0;
+ const __m128i alphaMask = _mm_set1_epi32(0xff000000);
+ const __m128i rgbaMask = _mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15);
+ const __m128i zero = _mm_setzero_si128();
+
+ for (; i < count - 3; i += 4) {
+ __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[i]);
+ if (!_mm_testz_si128(srcVector, alphaMask)) {
+ if (!_mm_testc_si128(srcVector, alphaMask)) {
+ __m128i srcVectorAlpha = _mm_srli_epi32(srcVector, 24);
+ if (RGBA)
+ srcVector = _mm_shuffle_epi8(srcVector, rgbaMask);
+ const __m128 a = _mm_cvtepi32_ps(srcVectorAlpha);
+ const __m128 ia = reciprocal_mul_ps(a, 255.0f);
+ __m128i src1 = _mm_unpacklo_epi8(srcVector, zero);
+ __m128i src3 = _mm_unpackhi_epi8(srcVector, zero);
+ __m128i src2 = _mm_unpackhi_epi16(src1, zero);
+ __m128i src4 = _mm_unpackhi_epi16(src3, zero);
+ src1 = _mm_unpacklo_epi16(src1, zero);
+ src3 = _mm_unpacklo_epi16(src3, zero);
+ __m128 ia1 = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 ia2 = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 ia3 = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 ia4 = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(3, 3, 3, 3));
+ src1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(src1), ia1));
+ src2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(src2), ia2));
+ src3 = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(src3), ia3));
+ src4 = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(src4), ia4));
+ src1 = _mm_packus_epi32(src1, src2);
+ src3 = _mm_packus_epi32(src3, src4);
+ src1 = _mm_packus_epi16(src1, src3);
+ // Handle potential alpha == 0 values:
+ __m128i srcVectorAlphaMask = _mm_cmpeq_epi32(srcVectorAlpha, zero);
+ src1 = _mm_andnot_si128(srcVectorAlphaMask, src1);
+ // Fixup alpha values:
+ if (RGBx)
+ srcVector = _mm_or_si128(src1, alphaMask);
+ else
+ srcVector = _mm_blendv_epi8(src1, srcVector, alphaMask);
+ _mm_storeu_si128((__m128i *)&buffer[i], srcVector);
+ } else {
+ if (RGBA)
+ _mm_storeu_si128((__m128i *)&buffer[i], _mm_shuffle_epi8(srcVector, rgbaMask));
+ else if (buffer != src)
+ _mm_storeu_si128((__m128i *)&buffer[i], srcVector);
+ }
+ } else {
+ if (RGBx)
+ _mm_storeu_si128((__m128i *)&buffer[i], alphaMask);
+ else
+ _mm_storeu_si128((__m128i *)&buffer[i], zero);
+ }
+ }
+
+ SIMD_EPILOGUE(i, count, 3) {
+ uint v = qUnpremultiply_sse4(src[i]);
+ if (RGBx)
+ v = 0xff000000 | v;
+ if (RGBA)
+ v = ARGB2RGBA(v);
+ buffer[i] = v;
+ }
}
-const uint *QT_FASTCALL convertARGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+template<bool RGBA>
+static inline void convertARGBFromRGBA64PM_sse4(uint *buffer, const QRgba64 *src, int count)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qUnpremultiply_sse4(src[i]);
- return buffer;
+ int i = 0;
+ const __m128i alphaMask = _mm_set1_epi64x(Q_UINT64_C(0xffff) << 48);
+ const __m128i alphaMask32 = _mm_set1_epi32(0xff000000);
+ const __m128i rgbaMask = _mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15);
+ const __m128i zero = _mm_setzero_si128();
+
+ for (; i < count - 3; i += 4) {
+ __m128i srcVector1 = _mm_loadu_si128((const __m128i *)&src[i]);
+ __m128i srcVector2 = _mm_loadu_si128((const __m128i *)&src[i + 2]);
+ bool transparent1 = _mm_testz_si128(srcVector1, alphaMask);
+ bool opaque1 = _mm_testc_si128(srcVector1, alphaMask);
+ bool transparent2 = _mm_testz_si128(srcVector2, alphaMask);
+ bool opaque2 = _mm_testc_si128(srcVector2, alphaMask);
+
+ if (!(transparent1 && transparent2)) {
+ if (!(opaque1 && opaque2)) {
+ __m128i srcVector1Alpha = _mm_srli_epi64(srcVector1, 48);
+ __m128i srcVector2Alpha = _mm_srli_epi64(srcVector2, 48);
+ __m128i srcVectorAlpha = _mm_packus_epi32(srcVector1Alpha, srcVector2Alpha);
+ const __m128 a = _mm_cvtepi32_ps(srcVectorAlpha);
+ // Convert srcVectorAlpha to final 8-bit alpha channel
+ srcVectorAlpha = _mm_add_epi32(srcVectorAlpha, _mm_set1_epi32(128));
+ srcVectorAlpha = _mm_sub_epi32(srcVectorAlpha, _mm_srli_epi32(srcVectorAlpha, 8));
+ srcVectorAlpha = _mm_srli_epi32(srcVectorAlpha, 8);
+ srcVectorAlpha = _mm_slli_epi32(srcVectorAlpha, 24);
+ const __m128 ia = reciprocal_mul_ps(a, 255.0f);
+ __m128i src1 = _mm_unpacklo_epi16(srcVector1, zero);
+ __m128i src2 = _mm_unpackhi_epi16(srcVector1, zero);
+ __m128i src3 = _mm_unpacklo_epi16(srcVector2, zero);
+ __m128i src4 = _mm_unpackhi_epi16(srcVector2, zero);
+ __m128 ia1 = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 ia2 = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 ia3 = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(2, 2, 2, 2));
+ __m128 ia4 = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(3, 3, 3, 3));
+ src1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(src1), ia1));
+ src2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(src2), ia2));
+ src3 = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(src3), ia3));
+ src4 = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(src4), ia4));
+ src1 = _mm_packus_epi32(src1, src2);
+ src3 = _mm_packus_epi32(src3, src4);
+ // Handle potential alpha == 0 values:
+ __m128i srcVector1AlphaMask = _mm_cmpeq_epi64(srcVector1Alpha, zero);
+ __m128i srcVector2AlphaMask = _mm_cmpeq_epi64(srcVector2Alpha, zero);
+ src1 = _mm_andnot_si128(srcVector1AlphaMask, src1);
+ src3 = _mm_andnot_si128(srcVector2AlphaMask, src3);
+ src1 = _mm_packus_epi16(src1, src3);
+ // Fixup alpha values:
+ src1 = _mm_blendv_epi8(src1, srcVectorAlpha, alphaMask32);
+ // Fix RGB order
+ if (!RGBA)
+ src1 = _mm_shuffle_epi8(src1, rgbaMask);
+ _mm_storeu_si128((__m128i *)&buffer[i], src1);
+ } else {
+ __m128i src1 = _mm_unpacklo_epi16(srcVector1, zero);
+ __m128i src2 = _mm_unpackhi_epi16(srcVector1, zero);
+ __m128i src3 = _mm_unpacklo_epi16(srcVector2, zero);
+ __m128i src4 = _mm_unpackhi_epi16(srcVector2, zero);
+ src1 = _mm_add_epi32(src1, _mm_set1_epi32(128));
+ src2 = _mm_add_epi32(src2, _mm_set1_epi32(128));
+ src3 = _mm_add_epi32(src3, _mm_set1_epi32(128));
+ src4 = _mm_add_epi32(src4, _mm_set1_epi32(128));
+ src1 = _mm_sub_epi32(src1, _mm_srli_epi32(src1, 8));
+ src2 = _mm_sub_epi32(src2, _mm_srli_epi32(src2, 8));
+ src3 = _mm_sub_epi32(src3, _mm_srli_epi32(src3, 8));
+ src4 = _mm_sub_epi32(src4, _mm_srli_epi32(src4, 8));
+ src1 = _mm_srli_epi32(src1, 8);
+ src2 = _mm_srli_epi32(src2, 8);
+ src3 = _mm_srli_epi32(src3, 8);
+ src4 = _mm_srli_epi32(src4, 8);
+ src1 = _mm_packus_epi32(src1, src2);
+ src3 = _mm_packus_epi32(src3, src4);
+ src1 = _mm_packus_epi16(src1, src3);
+ if (!RGBA)
+ src1 = _mm_shuffle_epi8(src1, rgbaMask);
+ _mm_storeu_si128((__m128i *)&buffer[i], src1);
+ }
+ } else {
+ _mm_storeu_si128((__m128i *)&buffer[i], zero);
+ }
+ }
+
+ SIMD_EPILOGUE(i, count, 3) {
+ buffer[i] = qConvertRgba64ToRgb32_sse4<RGBA ? PixelOrderRGB : PixelOrderBGR>(src[i]);
+ }
}
-const uint *QT_FASTCALL convertRGBA8888FromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, int count, const QVector<QRgb> *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = ARGB2RGBA(qUnpremultiply_sse4(src[i]));
+ convertARGBToARGB32PM_sse4<false>(buffer, buffer, count);
+}
+
+void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, int count, const QVector<QRgb> *)
+{
+ convertARGBToARGB32PM_sse4<true>(buffer, buffer, count);
+}
+
+const uint *QT_FASTCALL fetchARGB32ToARGB32PM_sse4(uint *buffer, const uchar *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ convertARGBToARGB32PM_sse4<false>(buffer, reinterpret_cast<const uint *>(src) + index, count);
return buffer;
}
-const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *src, int count,
+const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply_sse4(src[i]));
+ convertARGBToARGB32PM_sse4<true>(buffer, reinterpret_cast<const uint *>(src) + index, count);
return buffer;
}
+void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ convertARGBFromARGB32PM_sse4<false,true>(d, src, count);
+}
+
+void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ convertARGBFromARGB32PM_sse4<false,false>(d, src, count);
+}
+
+void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ convertARGBFromARGB32PM_sse4<true,false>(d, src, count);
+}
+
+void QT_FASTCALL storeRGBXFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
+ convertARGBFromARGB32PM_sse4<true,true>(d, src, count);
+}
+
template<QtPixelOrder PixelOrder>
-const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *)
+void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
{
+ uint *d = reinterpret_cast<uint *>(dest) + index;
for (int i = 0; i < count; ++i)
- buffer[i] = qConvertArgb32ToA2rgb30_sse4<PixelOrder>(src[i]);
- return buffer;
+ d[i] = qConvertArgb32ToA2rgb30_sse4<PixelOrder>(src[i]);
+}
+
+void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
+{
+ uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
+ convertARGBFromRGBA64PM_sse4<false>(dest, buffer, length);
+}
+
+void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
+{
+ uint *dest = (uint*)rasterBuffer->scanLine(y) + x;
+ convertARGBFromRGBA64PM_sse4<true>(dest, buffer, length);
+}
+
+void QT_FASTCALL storeARGB32FromRGBA64PM_sse4(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = (uint*)dest + index;
+ convertARGBFromRGBA64PM_sse4<false>(d, src, count);
+}
+
+void QT_FASTCALL storeRGBA8888FromRGBA64PM_sse4(uchar *dest, const QRgba64 *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *)
+{
+ uint *d = (uint*)dest + index;
+ convertARGBFromRGBA64PM_sse4<true>(d, src, count);
}
template
-const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *);
+void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
template
-const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>(uint *buffer, const uint *src, int count,
- const QVector<QRgb> *, QDitherInfo *);
+void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>(uchar *dest, const uint *src, int index, int count,
+ const QVector<QRgb> *, QDitherInfo *);
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index 45ecc8b422..42d760d5cc 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -167,61 +167,12 @@ void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl,
}
}
-static inline void store_uint24_ssse3(uchar *dst, const uint *src, int len)
+const uint *QT_FASTCALL fetchPixelsBPP24_ssse3(uint *buffer, const uchar *src, int index, int count)
{
- int i = 0;
-
- quint24 *dst24 = reinterpret_cast<quint24*>(dst);
- // Align dst on 16 bytes
- for (; i < len && (reinterpret_cast<quintptr>(dst24) & 0xf); ++i)
- *dst24++ = quint24(*src++);
-
- // Shuffle masks for first and second half of every output, all outputs are aligned so the shuffled ends are not used.
- const __m128i shuffleMask1 = _mm_setr_epi8(char(0x80), char(0x80), char(0x80), char(0x80), 2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12);
- const __m128i shuffleMask2 = _mm_setr_epi8(2, 1, 0, 6, 5, 4, 10, 9, 8, 14, 13, 12, char(0x80), char(0x80), char(0x80), char(0x80));
-
- const __m128i *inVectorPtr = (const __m128i *)src;
- __m128i *dstVectorPtr = (__m128i *)dst24;
-
- for (; i < (len - 15); i += 16) {
- // Load four vectors, store three.
- // Create each output vector by combining two shuffled input vectors.
- __m128i srcVector1 = _mm_loadu_si128(inVectorPtr);
- ++inVectorPtr;
- __m128i srcVector2 = _mm_loadu_si128(inVectorPtr);
- ++inVectorPtr;
- __m128i outputVector1 = _mm_shuffle_epi8(srcVector1, shuffleMask1);
- __m128i outputVector2 = _mm_shuffle_epi8(srcVector2, shuffleMask2);
- __m128i outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 4);
- _mm_store_si128(dstVectorPtr, outputVector);
- ++dstVectorPtr;
-
- srcVector1 = _mm_loadu_si128(inVectorPtr);
- ++inVectorPtr;
- outputVector1 = _mm_shuffle_epi8(srcVector2, shuffleMask1);
- outputVector2 = _mm_shuffle_epi8(srcVector1, shuffleMask2);
- outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 8);
- _mm_store_si128(dstVectorPtr, outputVector);
- ++dstVectorPtr;
-
- srcVector2 = _mm_loadu_si128(inVectorPtr);
- ++inVectorPtr;
- outputVector1 = _mm_shuffle_epi8(srcVector1, shuffleMask1);
- outputVector2 = _mm_shuffle_epi8(srcVector2, shuffleMask2);
- outputVector = _mm_alignr_epi8(outputVector2, outputVector1, 12);
- _mm_store_si128(dstVectorPtr, outputVector);
- ++dstVectorPtr;
- }
- dst24 = reinterpret_cast<quint24*>(dstVectorPtr);
- src = reinterpret_cast<const uint*>(inVectorPtr);
-
- SIMD_EPILOGUE(i, len, 15)
- *dst24++ = quint24(*src++);
-}
-
-void QT_FASTCALL storePixelsBPP24_ssse3(uchar *dest, const uint *src, int index, int count)
-{
- store_uint24_ssse3(dest + index * 3, src, count);
+ const quint24 *s = reinterpret_cast<const quint24 *>(src);
+ for (int i = 0; i < count; ++i)
+ buffer[i] = s[index + i];
+ return buffer;
}
extern void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len);
diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h
index 93e4b9f572..b237ea1611 100644
--- a/src/gui/painting/qdrawingprimitive_sse2_p.h
+++ b/src/gui/painting/qdrawingprimitive_sse2_p.h
@@ -43,6 +43,7 @@
#include <QtGui/private/qtguiglobal_p.h>
#include <private/qsimd_p.h>
#include "qdrawhelper_p.h"
+#include "qrgba64_p.h"
#ifdef __SSE2__
@@ -230,21 +231,31 @@ QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
+QT_FUNCTION_TARGET(SSE2)
+Q_ALWAYS_INLINE void reciprocal_mul_ss(__m128 &ia, const __m128 a, float mul)
+{
+ ia = _mm_rcp_ss(a); // Approximate 1/a
+ // Improve precision of ia using Newton-Raphson
+ ia = _mm_sub_ss(_mm_add_ss(ia, ia), _mm_mul_ss(ia, _mm_mul_ss(ia, a)));
+ ia = _mm_mul_ss(ia, _mm_set_ss(mul));
+ ia = _mm_shuffle_ps(ia, ia, _MM_SHUFFLE(0,0,0,0));
+}
+
QT_FUNCTION_TARGET(SSE4_1)
inline QRgb qUnpremultiply_sse4(QRgb p)
{
const uint alpha = qAlpha(p);
- if (alpha == 255 || alpha == 0)
+ if (alpha == 255)
return p;
- const uint invAlpha = qt_inv_premul_factor[alpha];
- const __m128i via = _mm_set1_epi32(invAlpha);
- const __m128i vr = _mm_set1_epi32(0x8000);
+ if (alpha == 0)
+ return 0;
+ const __m128 va = _mm_set1_ps(alpha);
+ __m128 via;
+ reciprocal_mul_ss(via, va, 255.0f); // Approximate 1/a
__m128i vl = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(p));
- vl = _mm_mullo_epi32(vl, via);
- vl = _mm_add_epi32(vl, vr);
- vl = _mm_srai_epi32(vl, 16);
- vl = _mm_insert_epi32(vl, alpha, 3);
+ vl = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(vl), via));
vl = _mm_packus_epi32(vl, vl);
+ vl = _mm_insert_epi16(vl, alpha, 3);
vl = _mm_packus_epi16(vl, vl);
return _mm_cvtsi128_si32(vl);
}
@@ -258,21 +269,14 @@ inline uint qConvertArgb32ToA2rgb30_sse4(QRgb p)
return qConvertRgb32ToRgb30<PixelOrder>(p);
if (alpha == 0)
return 0;
- Q_CONSTEXPR uint mult = 255 / (255 >> 6);
- const uint invAlpha = qt_inv_premul_factor[alpha];
+ Q_CONSTEXPR float mult = 1023.0f / (255 >> 6);
const uint newalpha = (alpha >> 6);
- const __m128i via = _mm_set1_epi32(invAlpha);
- const __m128i vna = _mm_set1_epi32(mult * newalpha);
- const __m128i vr1 = _mm_set1_epi32(0x1000);
- const __m128i vr2 = _mm_set1_epi32(0x80);
- __m128i vl = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(p));
- vl = _mm_mullo_epi32(vl, via);
- vl = _mm_add_epi32(vl, vr1);
- vl = _mm_srli_epi32(vl, 14);
- vl = _mm_mullo_epi32(vl, vna);
- vl = _mm_add_epi32(vl, _mm_srli_epi32(vl, 8));
- vl = _mm_add_epi32(vl, vr2);
- vl = _mm_srli_epi32(vl, 8);
+ const __m128 va = _mm_set1_ps(alpha);
+ __m128 via;
+ reciprocal_mul_ss(via, va, mult * newalpha);
+ __m128i vl = _mm_cvtsi32_si128(p);
+ vl = _mm_cvtepu8_epi32(vl);
+ vl = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(vl), via));
vl = _mm_packus_epi32(vl, vl);
uint rgb30 = (newalpha << 30);
rgb30 |= ((uint)_mm_extract_epi16(vl, 1)) << 10;
@@ -285,6 +289,27 @@ inline uint qConvertArgb32ToA2rgb30_sse4(QRgb p)
}
return rgb30;
}
+
+template<enum QtPixelOrder PixelOrder>
+QT_FUNCTION_TARGET(SSE4_1)
+inline uint qConvertRgba64ToRgb32_sse4(QRgba64 p)
+{
+ if (p.isTransparent())
+ return 0;
+ __m128i vl = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(&p));
+ if (!p.isOpaque()) {
+ const __m128 va = _mm_set1_ps(p.alpha());
+ __m128 via;
+ reciprocal_mul_ss(via, va, 65535.0f);
+ vl = _mm_unpacklo_epi16(vl, _mm_setzero_si128());
+ vl = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(vl) , via));
+ vl = _mm_packus_epi32(vl, vl);
+ vl = _mm_insert_epi16(vl, p.alpha(), 3);
+ }
+ if (PixelOrder == PixelOrderBGR)
+ vl = _mm_shufflelo_epi16(vl, _MM_SHUFFLE(3, 0, 1, 2));
+ return toArgb32(vl);
+}
#endif
QT_END_NAMESPACE
diff --git a/src/gui/painting/qemulationpaintengine.cpp b/src/gui/painting/qemulationpaintengine.cpp
index e6686e3721..0c0df0fb13 100644
--- a/src/gui/painting/qemulationpaintengine.cpp
+++ b/src/gui/painting/qemulationpaintengine.cpp
@@ -74,10 +74,11 @@ QPainterState *QEmulationPaintEngine::createState(QPainterState *orig) const
static inline void combineXForm(QBrush *brush, const QRectF &r)
{
- QTransform t = brush->transform();
- t.translate(r.x(), r.y());
- t.scale(r.width(), r.height());
- brush->setTransform(t);
+ QTransform t(r.width(), 0, 0, r.height(), r.x(), r.y());
+ if (brush->gradient() && brush->gradient()->coordinateMode() != QGradient::ObjectMode)
+ brush->setTransform(t * brush->transform()); // compat mode
+ else
+ brush->setTransform(brush->transform() * t);
}
void QEmulationPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
@@ -96,11 +97,19 @@ void QEmulationPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
if (coMode > QGradient::LogicalMode) {
QBrush copy = brush;
const QPaintDevice *d = real_engine->painter()->device();
- QRectF r = (coMode == QGradient::ObjectBoundingMode) ? path.controlPointRect() : QRectF(0, 0, d->width(), d->height());
+ QRectF r = (coMode == QGradient::StretchToDeviceMode) ? QRectF(0, 0, d->width(), d->height()) : path.controlPointRect();
combineXForm(&copy, r);
real_engine->fill(path, copy);
return;
}
+ } else if (style == Qt::TexturePattern) {
+ qreal dpr = qHasPixmapTexture(brush) ? brush.texture().devicePixelRatioF() : brush.textureImage().devicePixelRatioF();
+ if (!qFuzzyCompare(dpr, 1.0)) {
+ QBrush copy = brush;
+ combineXForm(&copy, QRectF(0, 0, 1.0/dpr, 1.0/dpr));
+ real_engine->fill(path, copy);
+ return;
+ }
}
real_engine->fill(path, brush);
@@ -124,7 +133,7 @@ void QEmulationPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
QGradient::CoordinateMode coMode = brush.gradient()->coordinateMode();
if (coMode > QGradient::LogicalMode) {
const QPaintDevice *d = real_engine->painter()->device();
- QRectF r = (coMode == QGradient::ObjectBoundingMode) ? path.controlPointRect() : QRectF(0, 0, d->width(), d->height());
+ QRectF r = (coMode == QGradient::StretchToDeviceMode) ? QRectF(0, 0, d->width(), d->height()) : path.controlPointRect();
combineXForm(&brush, r);
copy.setBrush(brush);
real_engine->stroke(path, copy);
@@ -166,9 +175,9 @@ void QEmulationPaintEngine::drawTextItem(const QPointF &p, const QTextItem &text
QBrush copy = s->pen.brush();
const QPaintDevice *d = real_engine->painter()->device();
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
- QRectF r = (g.coordinateMode() == QGradient::ObjectBoundingMode) ?
- QRectF(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal()) :
- QRectF(0, 0, d->width(), d->height());
+ QRectF r = (g.coordinateMode() == QGradient::StretchToDeviceMode) ?
+ QRectF(0, 0, d->width(), d->height()) :
+ QRectF(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
combineXForm(&copy, r);
g.setCoordinateMode(QGradient::LogicalMode);
QBrush brush(g);
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 22787b91fe..96da5e029c 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -41,6 +41,7 @@
#include "qimage.h"
#include "qcolor.h"
+#include "qrgba64_p.h"
QT_BEGIN_NAMESPACE
@@ -85,7 +86,7 @@ QT_BEGIN_NAMESPACE
* #ifdef'ed code, and removal of unneeded border calculation code.
* Later the code has been refactored, an SSE4.1 optimizated path have been
* added instead of the removed MMX assembler, and scaling of clipped area
- * removed.
+ * removed, and an RGBA64 version written
*
* Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code
* is by Willem Monsuwe <willem@stack.nl>. All other modifications are
@@ -94,12 +95,11 @@ QT_BEGIN_NAMESPACE
namespace QImageScale {
- const unsigned int** qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh);
- int* qimageCalcXPoints(int sw, int dw);
- int* qimageCalcApoints(int s, int d, int up);
- QImageScaleInfo* qimageFreeScaleInfo(QImageScaleInfo *isi);
- QImageScaleInfo *qimageCalcScaleInfo(const QImage &img, int sw, int sh,
- int dw, int dh, char aa);
+ static const unsigned int** qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh);
+ static int* qimageCalcXPoints(int sw, int dw);
+ static int* qimageCalcApoints(int s, int d, int up);
+ static QImageScaleInfo* qimageFreeScaleInfo(QImageScaleInfo *isi);
+ static QImageScaleInfo *qimageCalcScaleInfo(const QImage &img, int sw, int sh, int dw, int dh, char aa);
}
using namespace QImageScale;
@@ -108,8 +108,8 @@ using namespace QImageScale;
// Code ported from Imlib...
//
-const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src,
- int sw, int sh, int dh)
+static const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src,
+ int sw, int sh, int dh)
{
const unsigned int **p;
int j = 0, rv = 0;
@@ -138,7 +138,7 @@ const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src,
return(p);
}
-int* QImageScale::qimageCalcXPoints(int sw, int dw)
+static int* QImageScale::qimageCalcXPoints(int sw, int dw)
{
int *p, j = 0, rv = 0;
qint64 val, inc;
@@ -167,7 +167,7 @@ int* QImageScale::qimageCalcXPoints(int sw, int dw)
return p;
}
-int* QImageScale::qimageCalcApoints(int s, int d, int up)
+static int* QImageScale::qimageCalcApoints(int s, int d, int up)
{
int *p, j = 0, rv = 0;
@@ -214,7 +214,7 @@ int* QImageScale::qimageCalcApoints(int s, int d, int up)
return p;
}
-QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi)
+static QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi)
{
if (isi) {
delete[] isi->xpoints;
@@ -226,9 +226,9 @@ QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi)
return 0;
}
-QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img,
- int sw, int sh,
- int dw, int dh, char aa)
+static QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img,
+ int sw, int sh,
+ int dw, int dh, char aa)
{
QImageScaleInfo *isi;
int scw, sch;
@@ -333,7 +333,7 @@ static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
}
}
-/* scale by area sampling */
+/* scale by area sampling - with alpha */
static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
int dw, int dh, int dow, int sow)
{
@@ -529,6 +529,207 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des
}
}
+static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow);
+
+static void qt_qimageScaleRgba64_down_x_up_y(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow);
+
+static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow);
+
+static void qt_qimageScaleRgba64_up_xy(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const QRgba64 **ypoints = (const QRgba64 **)isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ const QRgba64 *sptr = ypoints[y];
+ QRgba64 *dptr = dest + (y * dow);
+ const int yap = yapoints[y];
+ if (yap > 0) {
+ for (int x = 0; x < dw; x++) {
+ const QRgba64 *pix = sptr + xpoints[x];
+ const int xap = xapoints[x];
+ if (xap > 0)
+ *dptr = interpolate_4_pixels_rgb64(pix, pix + sow, xap * 256, yap * 256);
+ else
+ *dptr = interpolate256(pix[0], 256 - yap, pix[sow], yap);
+ dptr++;
+ }
+ } else {
+ for (int x = 0; x < dw; x++) {
+ const QRgba64 *pix = sptr + xpoints[x];
+ const int xap = xapoints[x];
+ if (xap > 0)
+ *dptr = interpolate256(pix[0], 256 - xap, pix[1], xap);
+ else
+ *dptr = pix[0];
+ dptr++;
+ }
+ }
+ }
+}
+
+void qt_qimageScaleRgba64(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ if (isi->xup_yup == 3)
+ qt_qimageScaleRgba64_up_xy(isi, dest, dw, dh, dow, sow);
+ else if (isi->xup_yup == 1)
+ qt_qimageScaleRgba64_up_x_down_y(isi, dest, dw, dh, dow, sow);
+ else if (isi->xup_yup == 2)
+ qt_qimageScaleRgba64_down_x_up_y(isi, dest, dw, dh, dow, sow);
+ else
+ qt_qimageScaleRgba64_down_xy(isi, dest, dw, dh, dow, sow);
+}
+
+inline static void qt_qimageScaleRgba64_helper(const QRgba64 *pix, int xyap, int Cxy, int step, qint64 &r, qint64 &g, qint64 &b, qint64 &a)
+{
+ r = pix->red() * xyap;
+ g = pix->green() * xyap;
+ b = pix->blue() * xyap;
+ a = pix->alpha() * xyap;
+ int j;
+ for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy ){
+ pix += step;
+ r += pix->red() * Cxy;
+ g += pix->green() * Cxy;
+ b += pix->blue() * Cxy;
+ a += pix->alpha() * Cxy;
+ }
+ pix += step;
+ r += pix->red() * j;
+ g += pix->green() * j;
+ b += pix->blue() * j;
+ a += pix->alpha() * j;
+}
+
+static void qt_qimageScaleRgba64_up_x_down_y(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const QRgba64 **ypoints = (const QRgba64 **)isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ int Cy = (yapoints[y]) >> 16;
+ int yap = (yapoints[y]) & 0xffff;
+
+ QRgba64 *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ const QRgba64 *sptr = ypoints[y] + xpoints[x];
+ qint64 r, g, b, a;
+ qt_qimageScaleRgba64_helper(sptr, yap, Cy, sow, r, g, b, a);
+
+ int xap = xapoints[x];
+ if (xap > 0) {
+ qint64 rr, gg, bb, aa;
+ qt_qimageScaleRgba64_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa);
+
+ r = r * (256 - xap);
+ g = g * (256 - xap);
+ b = b * (256 - xap);
+ a = a * (256 - xap);
+ r = (r + (rr * xap)) >> 8;
+ g = (g + (gg * xap)) >> 8;
+ b = (b + (bb * xap)) >> 8;
+ a = (a + (aa * xap)) >> 8;
+ }
+ *dptr++ = qRgba64(r >> 14, g >> 14, b >> 14, a >> 14);
+ }
+ }
+}
+
+static void qt_qimageScaleRgba64_down_x_up_y(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const QRgba64 **ypoints = (const QRgba64 **)isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ QRgba64 *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ int Cx = xapoints[x] >> 16;
+ int xap = xapoints[x] & 0xffff;
+
+ const QRgba64 *sptr = ypoints[y] + xpoints[x];
+ qint64 r, g, b, a;
+ qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, r, g, b, a);
+
+ int yap = yapoints[y];
+ if (yap > 0) {
+ qint64 rr, gg, bb, aa;
+ qt_qimageScaleRgba64_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa);
+
+ r = r * (256 - yap);
+ g = g * (256 - yap);
+ b = b * (256 - yap);
+ a = a * (256 - yap);
+ r = (r + (rr * yap)) >> 8;
+ g = (g + (gg * yap)) >> 8;
+ b = (b + (bb * yap)) >> 8;
+ a = (a + (aa * yap)) >> 8;
+ }
+ *dptr = qRgba64(r >> 14, g >> 14, b >> 14, a >> 14);
+ dptr++;
+ }
+ }
+}
+
+static void qt_qimageScaleRgba64_down_xy(QImageScaleInfo *isi, QRgba64 *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const QRgba64 **ypoints = (const QRgba64 **)isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ int Cy = (yapoints[y]) >> 16;
+ int yap = (yapoints[y]) & 0xffff;
+
+ QRgba64 *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ int Cx = xapoints[x] >> 16;
+ int xap = xapoints[x] & 0xffff;
+
+ const QRgba64 *sptr = ypoints[y] + xpoints[x];
+ qint64 rx, gx, bx, ax;
+ qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
+
+ qint64 r = rx * yap;
+ qint64 g = gx * yap;
+ qint64 b = bx * yap;
+ qint64 a = ax * yap;
+ int j;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
+ sptr += sow;
+ qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
+ r += rx * Cy;
+ g += gx * Cy;
+ b += bx * Cy;
+ a += ax * Cy;
+ }
+ sptr += sow;
+ qt_qimageScaleRgba64_helper(sptr, xap, Cx, 1, rx, gx, bx, ax);
+ r += rx * j;
+ g += gx * j;
+ b += bx * j;
+ a += ax * j;
+
+ *dptr = qRgba64(r >> 28, g >> 28, b >> 28, a >> 28);
+ dptr++;
+ }
+ }
+}
+
static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest,
int dw, int dh, int dow, int sow);
@@ -745,7 +946,10 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh)
return QImage();
}
- if (src.hasAlphaChannel())
+ if (src.depth() > 32)
+ qt_qimageScaleRgba64(scaleinfo, (QRgba64 *)buffer.scanLine(0),
+ dw, dh, dw, src.bytesPerLine() / 8);
+ else if (src.hasAlphaChannel())
qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0),
dw, dh, dw, src.bytesPerLine() / 4);
else
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 25aa6a3122..43aeff3268 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -239,6 +239,12 @@ inline void qt_memrotate90_template<quint32>(const quint32 *src, int w, int h, i
qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride);
}
+template <>
+inline void qt_memrotate90_template<quint64>(const quint64 *src, int w, int h, int sstride, quint64 *dest, int dstride)
+{
+ qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride);
+}
+
template <class T>
Q_STATIC_TEMPLATE_FUNCTION
inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T *dest, int dstride)
@@ -275,6 +281,12 @@ inline void qt_memrotate270_template<quint32>(const quint32 *src, int w, int h,
qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride);
}
+template <>
+inline void qt_memrotate270_template<quint64>(const quint64 *src, int w, int h, int sstride, quint64 *dest, int dstride)
+{
+ qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride);
+}
+
#define QT_IMPL_MEMROTATE(type) \
Q_GUI_EXPORT void qt_memrotate90(const type *src, int w, int h, int sstride, \
type *dest, int dstride) \
@@ -309,9 +321,7 @@ Q_GUI_EXPORT void qt_memrotate270(const type *src, int w, int h, int sstride, \
qt_memrotate270_tiled_unpacked(src, w, h, sstride, dest, dstride); \
}
-
-
-
+QT_IMPL_MEMROTATE(quint64)
QT_IMPL_MEMROTATE(quint32)
QT_IMPL_MEMROTATE(quint16)
QT_IMPL_MEMROTATE(quint24)
@@ -377,6 +387,22 @@ void qt_memrotate270_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *d
qt_memrotate270((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl);
}
+
+void qt_memrotate90_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
+{
+ qt_memrotate90((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
+}
+
+void qt_memrotate180_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
+{
+ qt_memrotate180((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
+}
+
+void qt_memrotate270_64(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl)
+{
+ qt_memrotate270((const quint64 *)srcPixels, w, h, sbpl, (quint64 *)destPixels, dbpl);
+}
+
MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3] =
// 90, 180, 270
{
@@ -387,6 +413,7 @@ MemRotateFunc qMemRotateFunctions[QPixelLayout::BPPCount][3] =
{ qt_memrotate90_16, qt_memrotate180_16, qt_memrotate270_16 }, // BPP16,
{ qt_memrotate90_24, qt_memrotate180_24, qt_memrotate270_24 }, // BPP24
{ qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // BPP32
+ { qt_memrotate90_64, qt_memrotate180_64, qt_memrotate270_64 }, // BPP64
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h
index 9bc3fd1010..677fd57af9 100644
--- a/src/gui/painting/qmemrotate_p.h
+++ b/src/gui/painting/qmemrotate_p.h
@@ -65,6 +65,7 @@ QT_DECL_MEMROTATE(quint32);
QT_DECL_MEMROTATE(quint16);
QT_DECL_MEMROTATE(quint24);
QT_DECL_MEMROTATE(quint8);
+QT_DECL_MEMROTATE(quint64);
#undef QT_DECL_MEMROTATE
diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp
index 1c7d6471b6..613a686848 100644
--- a/src/gui/painting/qpagedpaintdevice.cpp
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -42,6 +42,41 @@
QT_BEGIN_NAMESPACE
+class QDummyPagedPaintDevicePrivate : public QPagedPaintDevicePrivate
+{
+ bool setPageLayout(const QPageLayout &newPageLayout) override
+ {
+ m_pageLayout = newPageLayout;
+ return m_pageLayout.isEquivalentTo(newPageLayout);
+ }
+
+ bool setPageSize(const QPageSize &pageSize) override
+ {
+ m_pageLayout.setPageSize(pageSize);
+ return m_pageLayout.pageSize().isEquivalentTo(pageSize);
+ }
+
+ bool setPageOrientation(QPageLayout::Orientation orientation) override
+ {
+ m_pageLayout.setOrientation(orientation);
+ return m_pageLayout.orientation() == orientation;
+ }
+
+ bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override
+ {
+ m_pageLayout.setUnits(units);
+ m_pageLayout.setMargins(margins);
+ return m_pageLayout.margins() == margins && m_pageLayout.units() == units;
+ }
+
+ QPageLayout pageLayout() const override
+ {
+ return m_pageLayout;
+ }
+
+ QPageLayout m_pageLayout;
+};
+
QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate()
{
}
@@ -61,9 +96,11 @@ QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate()
/*!
Constructs a new paged paint device.
+
+ \deprecated
*/
QPagedPaintDevice::QPagedPaintDevice()
- : d(new QPagedPaintDevicePrivate)
+ : d(new QDummyPagedPaintDevicePrivate)
{
}
@@ -263,7 +300,7 @@ QPagedPaintDevicePrivate *QPagedPaintDevice::dd()
*/
void QPagedPaintDevice::setPageSize(PageSize size)
{
- d->m_pageLayout.setPageSize(QPageSize(QPageSize::PageSizeId(size)));
+ d->setPageSize(QPageSize(QPageSize::PageSizeId(size)));
}
/*!
@@ -271,7 +308,7 @@ void QPagedPaintDevice::setPageSize(PageSize size)
*/
QPagedPaintDevice::PageSize QPagedPaintDevice::pageSize() const
{
- return PageSize(d->m_pageLayout.pageSize().id());
+ return PageSize(d->pageLayout().pageSize().id());
}
/*!
@@ -282,7 +319,7 @@ QPagedPaintDevice::PageSize QPagedPaintDevice::pageSize() const
*/
void QPagedPaintDevice::setPageSizeMM(const QSizeF &size)
{
- d->m_pageLayout.setPageSize(QPageSize(size, QPageSize::Millimeter));
+ d->setPageSize(QPageSize(size, QPageSize::Millimeter));
}
/*!
@@ -290,7 +327,7 @@ void QPagedPaintDevice::setPageSizeMM(const QSizeF &size)
*/
QSizeF QPagedPaintDevice::pageSizeMM() const
{
- return d->m_pageLayout.pageSize().size(QPageSize::Millimeter);
+ return d->pageLayout().pageSize().size(QPageSize::Millimeter);
}
/*!
@@ -305,8 +342,7 @@ QSizeF QPagedPaintDevice::pageSizeMM() const
*/
void QPagedPaintDevice::setMargins(const Margins &margins)
{
- d->m_pageLayout.setUnits(QPageLayout::Millimeter);
- d->m_pageLayout.setMargins(QMarginsF(margins.left, margins.top, margins.right, margins.bottom));
+ d->setPageMargins(QMarginsF(margins.left, margins.top, margins.right, margins.bottom), QPageLayout::Millimeter);
}
/*!
@@ -318,7 +354,7 @@ void QPagedPaintDevice::setMargins(const Margins &margins)
*/
QPagedPaintDevice::Margins QPagedPaintDevice::margins() const
{
- QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Millimeter);
+ QMarginsF margins = d->pageLayout().margins(QPageLayout::Millimeter);
Margins result;
result.left = margins.left();
result.top = margins.top();
@@ -413,7 +449,7 @@ bool QPagedPaintDevice::setPageOrientation(QPageLayout::Orientation orientation)
bool QPagedPaintDevice::setPageMargins(const QMarginsF &margins)
{
- return d->setPageMargins(margins);
+ return setPageMargins(margins, pageLayout().units());
}
/*!
@@ -458,23 +494,30 @@ QPageLayout QPagedPaintDevice::pageLayout() const
/*!
\internal
+ \deprecated
+
Returns the internal device page layout.
*/
QPageLayout QPagedPaintDevice::devicePageLayout() const
{
- return d->m_pageLayout;
+ qWarning("QPagedPaintDevice::devicePageLayout() is deprecated, just use QPagedPaintDevice::pageLayout()");
+ return d->pageLayout();
}
/*!
\internal
+ \deprecated
+
Returns the internal device page layout.
*/
QPageLayout &QPagedPaintDevice::devicePageLayout()
{
- return d->m_pageLayout;
+ qWarning("QPagedPaintDevice::devicePageLayout() is deprecated, you shouldn't be using this at all.");
+ static QPageLayout dummy;
+ return dummy;
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h
index 66dd6fa8cf..c8957edab8 100644
--- a/src/gui/painting/qpagedpaintdevice.h
+++ b/src/gui/painting/qpagedpaintdevice.h
@@ -55,7 +55,7 @@ class QPagedPaintDevicePrivate;
class Q_GUI_EXPORT QPagedPaintDevice : public QPaintDevice
{
public:
- QPagedPaintDevice();
+ QT_DEPRECATED QPagedPaintDevice();
~QPagedPaintDevice();
virtual bool newPage() = 0;
@@ -243,8 +243,8 @@ public:
protected:
QPagedPaintDevice(QPagedPaintDevicePrivate *dd);
QPagedPaintDevicePrivate *dd();
- QPageLayout devicePageLayout() const;
- QPageLayout &devicePageLayout();
+ QT_DEPRECATED QPageLayout devicePageLayout() const;
+ QT_DEPRECATED QPageLayout &devicePageLayout();
friend class QPagedPaintDevicePrivate;
QPagedPaintDevicePrivate *d;
};
diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h
index a993ea4cac..3a43bd7828 100644
--- a/src/gui/painting/qpagedpaintdevice_p.h
+++ b/src/gui/painting/qpagedpaintdevice_p.h
@@ -60,8 +60,7 @@ class Q_GUI_EXPORT QPagedPaintDevicePrivate
{
public:
QPagedPaintDevicePrivate()
- : m_pageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0)),
- fromPage(0),
+ : fromPage(0),
toPage(0),
pageOrderAscending(true),
printSelectionOnly(false)
@@ -70,46 +69,19 @@ public:
virtual ~QPagedPaintDevicePrivate();
- // ### Qt6 Remove these and make public class methods virtual
- virtual bool setPageLayout(const QPageLayout &newPageLayout)
- {
- m_pageLayout = newPageLayout;
- return m_pageLayout.isEquivalentTo(newPageLayout);;
- }
- virtual bool setPageSize(const QPageSize &pageSize)
- {
- m_pageLayout.setPageSize(pageSize);
- return m_pageLayout.pageSize().isEquivalentTo(pageSize);
- }
+ virtual bool setPageLayout(const QPageLayout &newPageLayout) = 0;
- virtual bool setPageOrientation(QPageLayout::Orientation orientation)
- {
- m_pageLayout.setOrientation(orientation);
- return m_pageLayout.orientation() == orientation;
- }
+ virtual bool setPageSize(const QPageSize &pageSize) = 0;
- virtual bool setPageMargins(const QMarginsF &margins)
- {
- return setPageMargins(margins, m_pageLayout.units());
- }
+ virtual bool setPageOrientation(QPageLayout::Orientation orientation) = 0;
- virtual bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
- {
- m_pageLayout.setUnits(units);
- m_pageLayout.setMargins(margins);
- return m_pageLayout.margins() == margins && m_pageLayout.units() == units;
- }
+ virtual bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) = 0;
- virtual QPageLayout pageLayout() const
- {
- return m_pageLayout;
- }
+ virtual QPageLayout pageLayout() const = 0;
static inline QPagedPaintDevicePrivate *get(QPagedPaintDevice *pd) { return pd->d; }
- QPageLayout m_pageLayout;
-
// These are currently required to keep QPrinter functionality working in QTextDocument::print()
int fromPage;
int toPage;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index cade334ea6..7caaf3a8fa 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2590,10 +2590,13 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
if (image.depth() == 1)
image = d->rasterBuffer->colorizeBitmap(image, s->pen.color());
- if (s->matrix.type() > QTransform::TxTranslate) {
+ const qreal pixmapDevicePixelRatio = pixmap.devicePixelRatio();
+ if (s->matrix.type() > QTransform::TxTranslate || pixmapDevicePixelRatio > qreal(1.0)) {
QTransform copy = s->matrix;
copy.translate(r.x(), r.y());
copy.translate(-sr.x(), -sr.y());
+ const qreal inverseDpr = qreal(1.0) / pixmapDevicePixelRatio;
+ copy.scale(inverseDpr, inverseDpr);
d->image_filler_xform.clip = d->clip();
d->image_filler_xform.initTexture(&image, s->intOpacity, QTextureData::Tiled);
if (!d->image_filler_xform.blend)
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 0643a7cbb6..9f07af92e4 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -948,6 +948,8 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con
{
QBrush brush(state()->pen.color(), pixmap);
QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y());
+ if (!qFuzzyCompare(pixmap.devicePixelRatioF(), 1.0))
+ xform.scale(1.0/pixmap.devicePixelRatioF(), 1.0/pixmap.devicePixelRatioF());
brush.setTransform(xform);
qreal pts[] = { r.x(), r.y(),
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index b992e8f55d..b70b29e54e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -190,6 +190,13 @@ void QPainterPrivate::checkEmulation()
if (pg && pg->coordinateMode() > QGradient::LogicalMode)
doEmulation = true;
+ if (state->brush.style() == Qt::TexturePattern) {
+ if (qHasPixmapTexture(state->brush))
+ doEmulation |= !qFuzzyCompare(state->brush.texture().devicePixelRatioF(), 1.0);
+ else
+ doEmulation |= !qFuzzyCompare(state->brush.textureImage().devicePixelRatioF(), 1.0);
+ }
+
if (doEmulation && extended->flags() & QPaintEngineEx::DoNotEmulate)
return;
@@ -523,7 +530,10 @@ static inline QBrush stretchGradientToUserSpace(const QBrush &brush, const QRect
g.setCoordinateMode(QGradient::LogicalMode);
QBrush b(g);
- b.setTransform(gradientToUser * b.transform());
+ if (brush.gradient()->coordinateMode() == QGradient::ObjectMode)
+ b.setTransform(b.transform() * gradientToUser);
+ else
+ b.setTransform(gradientToUser * b.transform());
return b;
}
@@ -562,7 +572,7 @@ void QPainterPrivate::drawStretchedGradient(const QPainterPath &path, DrawOperat
} else {
needsFill = true;
- if (brushMode == QGradient::ObjectBoundingMode) {
+ if (brushMode == QGradient::ObjectBoundingMode || brushMode == QGradient::ObjectMode) {
Q_ASSERT(engine->hasFeature(QPaintEngine::PatternTransform));
boundingRect = path.boundingRect();
q->setBrush(stretchGradientToUserSpace(brush, boundingRect));
@@ -606,11 +616,11 @@ void QPainterPrivate::drawStretchedGradient(const QPainterPath &path, DrawOperat
changedBrush = true;
}
- if (penMode == QGradient::ObjectBoundingMode) {
+ if (penMode == QGradient::ObjectBoundingMode || penMode == QGradient::ObjectMode) {
Q_ASSERT(engine->hasFeature(QPaintEngine::PatternTransform));
// avoid computing the bounding rect twice
- if (!needsFill || brushMode != QGradient::ObjectBoundingMode)
+ if (!needsFill || (brushMode != QGradient::ObjectBoundingMode && brushMode != QGradient::ObjectMode))
boundingRect = path.boundingRect();
QPen p = pen;
@@ -842,8 +852,8 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s)
gradientStretch |= (brushMode == QGradient::StretchToDeviceMode);
gradientStretch |= (penMode == QGradient::StretchToDeviceMode);
- objectBoundingMode |= (brushMode == QGradient::ObjectBoundingMode);
- objectBoundingMode |= (penMode == QGradient::ObjectBoundingMode);
+ objectBoundingMode |= (brushMode == QGradient::ObjectBoundingMode || brushMode == QGradient::ObjectMode);
+ objectBoundingMode |= (penMode == QGradient::ObjectBoundingMode || penMode == QGradient::ObjectMode);
}
if (gradientStretch)
s->emulationSpecifier |= QGradient_StretchToDevice;
@@ -1287,7 +1297,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
itself and its bounding rectangle: The bounding rect contains
pixels with alpha == 0 (i.e the pixels surrounding the
primitive). These pixels will overwrite the other image's pixels,
- affectively clearing those, while the primitive only overwrites
+ effectively clearing those, while the primitive only overwrites
its own area.
\table 100%
@@ -1377,7 +1387,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
clip.
\li Composition Modes \c QPainter::CompositionMode_Source and
- QPainter::CompositionMode_SourceOver
+ QPainter::CompositionMode_SourceOver.
\li Rounded rectangle filling using solid color and two-color
linear gradients fills.
@@ -6657,6 +6667,16 @@ QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextO
potentially much more efficient depending on the underlying window
system.
+ drawTiledPixmap() will produce the same visual tiling pattern on
+ high-dpi displays (with devicePixelRatio > 1), compared to normal-
+ dpi displays. Set the devicePixelRatio on the \a pixmap to control
+ the tile size. For example, setting it to 2 halves the tile width
+ and height (on both 1x and 2x displays), and produces high-resolution
+ output on 2x displays.
+
+ The \a position offset is always in the painter coordinate system,
+ indepentent of display devicePixelRatio.
+
\sa drawPixmap()
*/
void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp)
@@ -6840,7 +6860,8 @@ static inline bool needsResolving(const QBrush &brush)
Qt::BrushStyle s = brush.style();
return ((s == Qt::LinearGradientPattern || s == Qt::RadialGradientPattern ||
s == Qt::ConicalGradientPattern) &&
- brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode);
+ (brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode ||
+ brush.gradient()->coordinateMode() == QGradient::ObjectMode));
}
/*!
@@ -7068,6 +7089,37 @@ void QPainter::fillRect(const QRectF &r, const QColor &color)
*/
/*!
+ \fn void QPainter::fillRect(int x, int y, int width, int height, QGradient::Preset preset)
+
+ \overload
+
+ Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
+ width and \a height, using the given gradient \a preset.
+
+ \since 5.12
+*/
+
+/*!
+ \fn void QPainter::fillRect(const QRect &rectangle, QGradient::Preset preset);
+
+ \overload
+
+ Fills the given \a rectangle with the specified gradient \a preset.
+
+ \since 5.12
+*/
+
+/*!
+ \fn void QPainter::fillRect(const QRectF &rectangle, QGradient::Preset preset);
+
+ \overload
+
+ Fills the given \a rectangle with the specified gradient \a preset.
+
+ \since 5.12
+*/
+
+/*!
Sets the given render \a hint on the painter if \a on is true;
otherwise clears the render hint.
@@ -8207,6 +8259,7 @@ void QPainter::setTransform(const QTransform &transform, bool combine )
}
/*!
+ Alias for worldTransform().
Returns the world transformation matrix.
\sa worldTransform()
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index 12a9c720a8..482f5fb63d 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -448,6 +448,10 @@ public:
inline void fillRect(const QRect &r, Qt::BrushStyle style);
inline void fillRect(const QRectF &r, Qt::BrushStyle style);
+ inline void fillRect(int x, int y, int w, int h, QGradient::Preset preset);
+ inline void fillRect(const QRect &r, QGradient::Preset preset);
+ inline void fillRect(const QRectF &r, QGradient::Preset preset);
+
void eraseRect(const QRectF &);
inline void eraseRect(int x, int y, int w, int h);
inline void eraseRect(const QRect &);
@@ -746,6 +750,20 @@ inline void QPainter::fillRect(const QRectF &r, Qt::BrushStyle style)
fillRect(r, QBrush(style));
}
+inline void QPainter::fillRect(int x, int y, int w, int h, QGradient::Preset p)
+{
+ fillRect(QRect(x, y, w, h), QGradient(p));
+}
+
+inline void QPainter::fillRect(const QRect &r, QGradient::Preset p)
+{
+ fillRect(r, QGradient(p));
+}
+
+inline void QPainter::fillRect(const QRectF &r, QGradient::Preset p)
+{
+ fillRect(r, QGradient(p));
+}
inline void QPainter::setBrushOrigin(int x, int y)
{
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index e58f9cee4c..4fd0d3c8fe 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1109,8 +1109,9 @@ void QPdfEngine::updateState(const QPaintEngineState &state)
d->hasPen = d->pen.style() != Qt::NoPen;
d->stroker.setPen(d->pen, state.renderHints());
QBrush penBrush = d->pen.brush();
+ bool cosmeticPen = qt_pen_is_cosmetic(d->pen, state.renderHints());
bool oldSimple = d->simplePen;
- d->simplePen = (d->hasPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque() && d->opacity == 1.0);
+ d->simplePen = (d->hasPen && !cosmeticPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque() && d->opacity == 1.0);
if (oldSimple != d->simplePen)
flags |= DirtyTransform;
} else if (flags & DirtyHints) {
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
index 2f24c7efcb..e6c5cabd7f 100644
--- a/src/gui/painting/qpdfwriter.cpp
+++ b/src/gui/painting/qpdfwriter.cpp
@@ -83,41 +83,28 @@ public:
{
// Try to set the paint engine page layout
pd->engine->setPageLayout(newPageLayout);
- // Set QPagedPaintDevice layout to match the current paint engine layout
- m_pageLayout = pd->engine->pageLayout();
- return m_pageLayout.isEquivalentTo(newPageLayout);
+ return pageLayout().isEquivalentTo(newPageLayout);
}
bool setPageSize(const QPageSize &pageSize) override
{
// Try to set the paint engine page size
pd->engine->setPageSize(pageSize);
- // Set QPagedPaintDevice layout to match the current paint engine layout
- m_pageLayout = pd->engine->pageLayout();
- return m_pageLayout.pageSize().isEquivalentTo(pageSize);
+ return pageLayout().pageSize().isEquivalentTo(pageSize);
}
bool setPageOrientation(QPageLayout::Orientation orientation) override
{
// Set the print engine value
pd->engine->setPageOrientation(orientation);
- // Set QPagedPaintDevice layout to match the current paint engine layout
- m_pageLayout = pd->engine->pageLayout();
- return m_pageLayout.orientation() == orientation;
- }
-
- bool setPageMargins(const QMarginsF &margins) override
- {
- return setPageMargins(margins, pageLayout().units());
+ return pageLayout().orientation() == orientation;
}
bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override
{
// Try to set engine margins
pd->engine->setPageMargins(margins, units);
- // Set QPagedPaintDevice layout to match the current paint engine layout
- m_pageLayout = pd->engine->pageLayout();
- return m_pageLayout.margins() == margins && m_pageLayout.units() == units;
+ return pageLayout().margins() == margins && pageLayout().units() == units;
}
QPageLayout pageLayout() const override
@@ -150,9 +137,6 @@ QPdfWriter::QPdfWriter(const QString &filename)
Q_D(QPdfWriter);
d->engine->setOutputFilename(filename);
-
- // Set QPagedPaintDevice layout to match the current paint engine layout
- devicePageLayout() = d->engine->pageLayout();
}
/*!
@@ -165,9 +149,6 @@ QPdfWriter::QPdfWriter(QIODevice *device)
Q_D(QPdfWriter);
d->engine->d_func()->outDevice = device;
-
- // Set QPagedPaintDevice layout to match the current paint engine layout
- devicePageLayout() = d->engine->pageLayout();
}
/*!
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index cc8d850689..373722cdb4 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -80,6 +80,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore", QtWarningMsg);
+
class QPlatformBackingStorePrivate
{
public:
@@ -331,16 +333,19 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->context->setScreen(d_ptr->window->screen());
d_ptr->context->setShareContext(qt_window_private(d_ptr->window)->shareContext());
if (!d_ptr->context->create()) {
- qWarning("composeAndFlush: QOpenGLContext creation failed");
+ qCWarning(lcQpaBackingStore, "composeAndFlush: QOpenGLContext creation failed");
return;
}
}
if (!d_ptr->context->makeCurrent(window)) {
- qWarning("composeAndFlush: makeCurrent() failed");
+ qCWarning(lcQpaBackingStore, "composeAndFlush: makeCurrent() failed");
return;
}
+ qCDebug(lcQpaBackingStore) << "Composing and flushing" << region << "of" << window
+ << "at offset" << offset << "with" << textures->count() << "texture(s) in" << textures;
+
QWindowPrivate::get(window)->lastComposeTime.start();
QOpenGLFunctions *funcs = d_ptr->context->functions();
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index 381c564079..de5ba964dc 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -50,6 +50,7 @@
//
#include <QtGui/qtguiglobal.h>
+#include <QtCore/qloggingcategory.h>
#include <QtCore/qrect.h>
#include <QtCore/qobject.h>
@@ -59,6 +60,7 @@
QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore)
class QRegion;
class QRect;
diff --git a/src/gui/painting/qrgba64.h b/src/gui/painting/qrgba64.h
index 2c8f8fa8c4..0e5344cacb 100644
--- a/src/gui/painting/qrgba64.h
+++ b/src/gui/painting/qrgba64.h
@@ -127,6 +127,10 @@ public:
Q_DECL_RELAXED_CONSTEXPR QRgba64 premultiplied() const
{
+ if (isOpaque())
+ return *this;
+ if (isTransparent())
+ return QRgba64::fromRgba64(0);
const quint32 a = alpha();
const quint16 r = div_65535(red() * a);
const quint16 g = div_65535(green() * a);
diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h
index adceda2210..b7e4d4d905 100644
--- a/src/gui/painting/qrgba64_p.h
+++ b/src/gui/painting/qrgba64_p.h
@@ -51,10 +51,11 @@
// We mean it.
//
+#include "qrgba64.h"
+#include "qdrawhelper_p.h"
+
+#include <QtCore/private/qsimd_p.h>
#include <QtGui/private/qtguiglobal_p.h>
-#include <QtGui/qrgba64.h>
-#include <QtGui/private/qdrawhelper_p.h>
-#include <private/qsimd_p.h>
QT_BEGIN_NAMESPACE
@@ -63,14 +64,6 @@ inline QRgba64 combineAlpha256(QRgba64 rgba64, uint alpha256)
return QRgba64::fromRgba64(rgba64.red(), rgba64.green(), rgba64.blue(), (rgba64.alpha() * alpha256) >> 8);
}
-inline QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
-{
- return QRgba64::fromRgba64((rgba64.red() * alpha256) >> 8,
- (rgba64.green() * alpha256) >> 8,
- (rgba64.blue() * alpha256) >> 8,
- (rgba64.alpha() * alpha256) >> 8);
-}
-
inline QRgba64 multiplyAlpha65535(QRgba64 rgba64, uint alpha65535)
{
return QRgba64::fromRgba64(qt_div_65535(rgba64.red() * alpha65535),
@@ -125,11 +118,6 @@ inline T multiplyAlpha255(T rgba64, uint alpha255)
#endif
}
-inline QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
-{
- return QRgba64::fromRgba64(multiplyAlpha256(x, alpha1) + multiplyAlpha256(y, alpha2));
-}
-
inline QRgba64 interpolate255(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
{
return QRgba64::fromRgba64(multiplyAlpha255(x, alpha1) + multiplyAlpha255(y, alpha2));
@@ -159,7 +147,7 @@ Q_ALWAYS_INLINE __m128i interpolate65535(__m128i x, uint alpha1, __m128i y, uint
{
return _mm_add_epi32(multiplyAlpha65535(x, alpha1), multiplyAlpha65535(y, alpha2));
}
-// alpha2 below is const-ref because otherwise MSVC2013 complains that it can't 16-byte align the argument.
+// alpha2 below is const-ref because otherwise MSVC2015 complains that it can't 16-byte align the argument.
Q_ALWAYS_INLINE __m128i interpolate65535(__m128i x, __m128i alpha1, __m128i y, const __m128i &alpha2)
{
return _mm_add_epi32(multiplyAlpha65535(x, alpha1), multiplyAlpha65535(y, alpha2));
@@ -185,7 +173,8 @@ inline QRgba64 addWithSaturation(QRgba64 a, QRgba64 b)
qMin(a.alpha() + b.alpha(), 65535));
}
-#if defined __SSE2__
+#if QT_COMPILER_SUPPORTS_HERE(SSE2)
+QT_FUNCTION_TARGET(SSE2)
Q_ALWAYS_INLINE uint toArgb32(__m128i v)
{
v = _mm_unpacklo_epi16(v, _mm_setzero_si128());
@@ -239,20 +228,6 @@ inline uint toRgba8888(QRgba64 rgba64)
#endif
}
-#if defined(__SSE2__)
-Q_ALWAYS_INLINE __m128i addWithSaturation(__m128i a, __m128i b)
-{
- return _mm_adds_epu16(a, b);
-}
-#endif
-
-#if defined(__ARM_NEON__)
-Q_ALWAYS_INLINE uint16x4_t addWithSaturation(uint16x4_t a, uint16x4_t b)
-{
- return vqmovn_u32(vaddl_u16(a, b));
-}
-#endif
-
inline QRgba64 rgbBlend(QRgba64 d, QRgba64 s, uint rgbAlpha)
{
QRgba64 blend;
diff --git a/src/gui/painting/qt_attribution.json b/src/gui/painting/qt_attribution.json
index 7eb7db4876..9d3debc1b9 100644
--- a/src/gui/painting/qt_attribution.json
+++ b/src/gui/painting/qt_attribution.json
@@ -27,5 +27,19 @@
"Copyright": "Copyright (C) 2004, 2005 Daniel M. Duley.
(C) Carsten Haitzler and various contributors.
(C) Willem Monsuwe <willem@stack.nl>"
+ },
+ {
+ "Id": "webgradients",
+ "Name": "WebGradients",
+ "QDocModule": "qtgui",
+ "QtUsage": "Used in Qt GUI to provide presets for QGradient.",
+ "Files": "webgradients.css",
+
+ "Description": "WebGradients is a free collection of 180 linear gradients.",
+ "Homepage": "https://webgradients.com/",
+ "License": "MIT License",
+ "LicenseId": "MIT",
+ "LicenseFile": "WEBGRADIENTS_LICENSE.txt",
+ "Copyright": "Copyright (c) 2017 itmeo"
}
]
diff --git a/src/gui/painting/webgradients.binaryjson b/src/gui/painting/webgradients.binaryjson
new file mode 100644
index 0000000000..75edd487be
--- /dev/null
+++ b/src/gui/painting/webgradients.binaryjson
Binary files differ
diff --git a/src/gui/painting/webgradients.css b/src/gui/painting/webgradients.css
new file mode 100644
index 0000000000..870866bb46
--- /dev/null
+++ b/src/gui/painting/webgradients.css
@@ -0,0 +1,909 @@
+/*001 Warm Flame*/
+.warm_flame{
+ background-image: linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);
+}
+
+/*002 Night Fade*/
+.night_fade{
+ background-image: linear-gradient(to top, #a18cd1 0%, #fbc2eb 100%);
+}
+
+/*003 Spring Warmth*/
+.spring_warmth{
+ background-image: linear-gradient(to top, #fad0c4 0%, #fad0c4 1%, #ffd1ff 100%);
+}
+
+/*004 Juicy Peach*/
+.juicy_peach{
+ background-image: linear-gradient(to right, #ffecd2 0%, #fcb69f 100%);
+}
+
+/*005 Young Passion*/
+.young_passion{
+ background-image: linear-gradient(to right, #ff8177 0%, #ff867a 0%, #ff8c7f 21%, #f99185 52%, #cf556c 78%, #b12a5b 100%);
+}
+
+/*006 Lady Lips*/
+.lady_lips{
+ background-image: linear-gradient(to top, #ff9a9e 0%, #fecfef 99%, #fecfef 100%);
+}
+
+/*007 Sunny Morning*/
+.sunny_morning{
+ background-image: linear-gradient(120deg, #f6d365 0%, #fda085 100%);
+}
+
+/*008 Rainy Ashville*/
+.rainy_ashville{
+ background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);
+}
+
+/*009 Frozen Dreams*/
+.frozen_dreams{
+ background-image: linear-gradient(to top, #fdcbf1 0%, #fdcbf1 1%, #e6dee9 100%);
+}
+
+/*010 Winter Neva*/
+.winter_neva{
+ background-image: linear-gradient(120deg, #a1c4fd 0%, #c2e9fb 100%);
+}
+
+/*011 Dusty Grass*/
+.dusty_grass{
+ background-image: linear-gradient(120deg, #d4fc79 0%, #96e6a1 100%);
+}
+
+/*012 Tempting Azure*/
+.tempting_azure{
+ background-image: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);
+}
+
+/*013 Heavy Rain*/
+.heavy_rain{
+ background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%);
+}
+
+/*014 Amy Crisp*/
+.amy_crisp{
+ background-image: linear-gradient(120deg, #a6c0fe 0%, #f68084 100%);
+}
+
+/*015 Mean Fruit*/
+.mean_fruit{
+ background-image: linear-gradient(120deg, #fccb90 0%, #d57eeb 100%);
+}
+
+/*016 Deep Blue*/
+.deep_blue{
+ background-image: linear-gradient(120deg, #e0c3fc 0%, #8ec5fc 100%);
+}
+
+/*017 Ripe Malinka*/
+.ripe_malinka{
+ background-image: linear-gradient(120deg, #f093fb 0%, #f5576c 100%);
+}
+
+/*018 Cloudy Knoxville*/
+.cloudy_knoxville{
+ background-image: linear-gradient(120deg, #fdfbfb 0%, #ebedee 100%);
+}
+
+/*019 Malibu Beach*/
+.malibu_beach{
+ background-image: linear-gradient(to right, #4facfe 0%, #00f2fe 100%);
+}
+
+/*020 New Life*/
+.new_life{
+ background-image: linear-gradient(to right, #43e97b 0%, #38f9d7 100%);
+}
+
+/*021 True Sunset*/
+.true_sunset{
+ background-image: linear-gradient(to right, #fa709a 0%, #fee140 100%);
+}
+
+/*022 Morpheus Den*/
+.morpheus_den{
+ background-image: linear-gradient(to top, #30cfd0 0%, #330867 100%);
+}
+
+/*023 Rare Wind*/
+.rare_wind{
+ background-image: linear-gradient(to top, #a8edea 0%, #fed6e3 100%);
+}
+
+/*024 Near Moon*/
+.near_moon{
+ background-image: linear-gradient(to top, #5ee7df 0%, #b490ca 100%);
+}
+
+/*025 Wild Apple*/
+.wild_apple{
+ background-image: linear-gradient(to top, #d299c2 0%, #fef9d7 100%);
+}
+
+/*026 Saint Petersburg*/
+.saint_petersburg{
+ background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
+}
+
+/*027 Arielle's Smile*/
+.arielles_smile{
+ background-image: radial-gradient(circle 248px at center, #16d9e3 0%, #30c7ec 47%, #46aef7 100%);
+}
+
+/*028 Plum Plate*/
+.plum_plate{
+ background-image: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+}
+
+/*029 Everlasting Sky*/
+.everlasting_sky{
+ background-image: linear-gradient(135deg, #fdfcfb 0%, #e2d1c3 100%);
+}
+
+/*030 Happy Fisher*/
+.happy_fisher{
+ background-image: linear-gradient(120deg, #89f7fe 0%, #66a6ff 100%);
+}
+
+/*031 Blessing*/
+.blessing{
+ background-image: linear-gradient(to top, #fddb92 0%, #d1fdff 100%);
+}
+
+/*032 Sharpeye Eagle*/
+.sharpeye_eagle{
+ background-image: linear-gradient(to top, #9890e3 0%, #b1f4cf 100%);
+}
+
+/*033 Ladoga Bottom*/
+.ladoga_bottom{
+ background-image: linear-gradient(to top, #ebc0fd 0%, #d9ded8 100%);
+}
+
+/*034 Lemon Gate*/
+.lemon_gate{
+ background-image: linear-gradient(to top, #96fbc4 0%, #f9f586 100%);
+}
+
+/*035 Itmeo Branding*/
+.itmeo_branding{
+ background-image: linear-gradient(180deg, #2af598 0%, #009efd 100%);
+}
+
+/*036 Zeus Miracle*/
+.zeus_miracle{
+ background-image: linear-gradient(to top, #cd9cf2 0%, #f6f3ff 100%);
+}
+
+/*037 Old Hat*/
+.old_hat{
+ background-image: linear-gradient(to right, #e4afcb 0%, #b8cbb8 0%, #b8cbb8 0%, #e2c58b 30%, #c2ce9c 64%, #7edbdc 100%);
+}
+
+/*038 Star Wine*/
+.star_wine{
+ background-image: linear-gradient(to right, #b8cbb8 0%, #b8cbb8 0%, #b465da 0%, #cf6cc9 33%, #ee609c 66%, #ee609c 100%);
+}
+
+/*039 Deep Blue*/
+.deep_blue{
+ background-image: linear-gradient(to right, #6a11cb 0%, #2575fc 100%);
+}
+
+/*040 Coup de Grace*/
+.coup_de_grace{
+ background: #DCD9D4 linear-gradient(to bottom, rgba(255, 255, 255, 0.50) 0%, rgba(0, 0, 0, 0.50) 100%), radial-gradient(at 50% 0%, rgba(255, 255, 255, 0.10) 0%, rgba(0, 0, 0, 0.50) 50%);
+ background-blend-mode: soft-light,screen;
+}
+
+/*041 Happy Acid*/
+.happy_acid{
+ background-image: linear-gradient(to top, #37ecba 0%, #72afd3 100%);
+}
+
+/*042 Awesome Pine*/
+.awesome_pine{
+ background-image: linear-gradient(to top, #ebbba7 0%, #cfc7f8 100%);
+}
+
+/*043 New York*/
+.new_york{
+ background-image: linear-gradient(to top, #fff1eb 0%, #ace0f9 100%);
+}
+
+/*044 Shy Rainbow*/
+.shy_rainbow{
+ background-image: linear-gradient(to right, #eea2a2 0%, #bbc1bf 19%, #57c6e1 42%, #b49fda 79%, #7ac5d8 100%);
+}
+
+/*045 Loon Crest*/
+.loon_crest{
+ background: linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898;
+ background-blend-mode: multiply,multiply;
+}
+
+/*046 Mixed Hopes*/
+.mixed_hopes{
+ background-image: linear-gradient(to top, #c471f5 0%, #fa71cd 100%);
+}
+
+/*047 Fly High*/
+.fly_high{
+ background-image: linear-gradient(to top, #48c6ef 0%, #6f86d6 100%);
+}
+
+/*048 Strong Bliss*/
+.strong_bliss{
+ background-image: linear-gradient(to right, #f78ca0 0%, #f9748f 19%, #fd868c 60%, #fe9a8b 100%);
+}
+
+/*049 Fresh Milk*/
+.fresh_milk{
+ background-image: linear-gradient(to top, #feada6 0%, #f5efef 100%);
+}
+
+/*050 Snow Again*/
+.snow_again{
+ background-image: linear-gradient(to top, #e6e9f0 0%, #eef1f5 100%);
+}
+
+/*051 February Ink*/
+.february_ink{
+ background-image: linear-gradient(to top, #accbee 0%, #e7f0fd 100%);
+}
+
+/*052 Kind Steel*/
+.kind_steel{
+ background-image: linear-gradient(-20deg, #e9defa 0%, #fbfcdb 100%);
+}
+
+/*053 Soft Grass*/
+.soft_grass{
+ background-image: linear-gradient(to top, #c1dfc4 0%, #deecdd 100%);
+}
+
+/*054 Grown Early*/
+.grown_early{
+ background-image: linear-gradient(to top, #0ba360 0%, #3cba92 100%);
+}
+
+/*055 Sharp Blues*/
+.sharp_blues{
+ background-image: linear-gradient(to top, #00c6fb 0%, #005bea 100%);
+}
+
+/*056 Shady Water*/
+.shady_water{
+ background-image: linear-gradient(to right, #74ebd5 0%, #9face6 100%);
+}
+
+/*057 Dirty Beauty*/
+.dirty_beauty{
+ background-image: linear-gradient(to top, #6a85b6 0%, #bac8e0 100%);
+}
+
+/*058 Great Whale*/
+.great_whale{
+ background-image: linear-gradient(to top, #a3bded 0%, #6991c7 100%);
+}
+
+/*059 Teen Notebook*/
+.teen_notebook{
+ background-image: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%);
+}
+
+/*060 Polite Rumors*/
+.polite_rumors{
+ background-image: linear-gradient(to top, #a7a6cb 0%, #8989ba 52%, #8989ba 100%);
+}
+
+/*061 Sweet Period*/
+.sweet_period{
+ background-image: linear-gradient(to top, #3f51b1 0%, #5a55ae 13%, #7b5fac 25%, #8f6aae 38%, #a86aa4 50%, #cc6b8e 62%, #f18271 75%, #f3a469 87%, #f7c978 100%);
+}
+
+/*062 Wide Matrix*/
+.wide_matrix{
+ background-image: linear-gradient(to top, #fcc5e4 0%, #fda34b 15%, #ff7882 35%, #c8699e 52%, #7046aa 71%, #0c1db8 87%, #020f75 100%);
+}
+
+/*063 Soft Cherish*/
+.soft_cherish{
+ background-image: linear-gradient(to top, #dbdcd7 0%, #dddcd7 24%, #e2c9cc 30%, #e7627d 46%, #b8235a 59%, #801357 71%, #3d1635 84%, #1c1a27 100%);
+}
+
+/*064 Red Salvation*/
+.red_salvation{
+ background-image: linear-gradient(to top, #f43b47 0%, #453a94 100%);
+}
+
+/*065 Burning Spring*/
+.burning_spring{
+ background-image: linear-gradient(to top, #4fb576 0%, #44c489 30%, #28a9ae 46%, #28a2b7 59%, #4c7788 71%, #6c4f63 86%, #432c39 100%);
+}
+
+/*066 Night Party*/
+.night_party{
+ background-image: linear-gradient(to top, #0250c5 0%, #d43f8d 100%);
+}
+
+/*067 Sky Glider*/
+.sky_glider{
+ background-image: linear-gradient(to top, #88d3ce 0%, #6e45e2 100%);
+}
+
+/*068 Heaven Peach*/
+.heaven_peach{
+ background-image: linear-gradient(to top, #d9afd9 0%, #97d9e1 100%);
+}
+
+/*069 Purple Division*/
+.purple_division{
+ background-image: linear-gradient(to top, #7028e4 0%, #e5b2ca 100%);
+}
+
+/*070 Aqua Splash*/
+.aqua_splash{
+ background-image: linear-gradient(15deg, #13547a 0%, #80d0c7 100%);
+}
+
+/*071 Above Clouds*/
+.above_clouds{
+ background-image: linear-gradient(to left, #BDBBBE 0%, #9D9EA3 100%), radial-gradient(88% 271%, rgba(255, 255, 255, 0.25) 0%, rgba(254, 254, 254, 0.25) 1%, rgba(0, 0, 0, 0.25) 100%), radial-gradient(50% 100%, rgba(255, 255, 255, 0.30) 0%, rgba(0, 0, 0, 0.30) 100%);
+ background-blend-mode: normal, lighten, soft-light;
+}
+
+/*072 Spiky Naga*/
+.spiky_naga{
+ background-image: linear-gradient(to top, #505285 0%, #585e92 12%, #65689f 25%, #7474b0 37%, #7e7ebb 50%, #8389c7 62%, #9795d4 75%, #a2a1dc 87%, #b5aee4 100%);
+}
+
+/*073 Love Kiss*/
+.love_kiss{
+ background-image: linear-gradient(to top, #ff0844 0%, #ffb199 100%);
+}
+
+/*074 Sharp Glass*/
+.sharp_glass{
+ background: #C9CCD3 linear-gradient(-180deg, rgba(255, 255, 255, 0.50) 0%, rgba(0, 0, 0, 0.50) 100%);
+ background-blend-mode: lighten;
+}
+
+/*075 Clean Mirror*/
+.clean_mirror{
+ background-image: linear-gradient(45deg, #93a5cf 0%, #e4efe9 100%);
+}
+
+/*076 Premium Dark*/
+.premium_dark{
+ background-image: linear-gradient(to right, #434343 0%, black 100%);
+}
+
+/*077 Cold Evening*/
+.cold_evening{
+ background-image: linear-gradient(to top, #0c3483 0%, #a2b6df 100%, #6b8cce 100%, #a2b6df 100%);
+}
+
+/*078 Cochiti Lake*/
+.cochiti_lake{
+ background-image: linear-gradient(45deg, #93a5cf 0%, #e4efe9 100%);
+}
+
+/*079 Summer Games*/
+.summer_games{
+ background-image: linear-gradient(to right, #92fe9d 0%, #00c9ff 100%);
+}
+
+/*080 Passionate Bed*/
+.passionate_bed{
+ background-image: linear-gradient(to right, #ff758c 0%, #ff7eb3 100%);
+}
+
+/*081 Mountain Rock*/
+.mountain_rock{
+ background-image: linear-gradient(to right, #868f96 0%, #596164 100%);
+}
+
+/*082 Desert Hump*/
+.desert_hump{
+ background-image: linear-gradient(to top, #c79081 0%, #dfa579 100%);
+}
+
+/*083 Jungle Day*/
+.jungle_day{
+ background-image: linear-gradient(45deg, #8baaaa 0%, #ae8b9c 100%);
+}
+
+/*084 Phoenix Start*/
+.phoenix_start{
+ background-image: linear-gradient(to right, #f83600 0%, #f9d423 100%);
+}
+
+/*085 October Silence*/
+.october_silence{
+ background-image: linear-gradient(-20deg, #b721ff 0%, #21d4fd 100%);
+}
+
+/*086 Faraway River*/
+.faraway_river{
+ background-image: linear-gradient(-20deg, #6e45e2 0%, #88d3ce 100%);
+}
+
+/*087 Alchemist Lab*/
+.alchemist_lab{
+ background-image: linear-gradient(-20deg, #d558c8 0%, #24d292 100%);
+}
+
+/*088 Over Sun*/
+.over_sun{
+ background-image: linear-gradient(60deg, #abecd6 0%, #fbed96 100%);
+}
+
+/*089 Premium White*/
+.premium_white{
+ background-image: linear-gradient(to top, #d5d4d0 0%, #d5d4d0 1%, #eeeeec 31%, #efeeec 75%, #e9e9e7 100%);
+}
+
+/*090 Mars Party*/
+.mars_party{
+ background-image: linear-gradient(to top, #5f72bd 0%, #9b23ea 100%);
+}
+
+/*091 Eternal Constance*/
+.eternal_constance{
+ background-image: linear-gradient(to top, #09203f 0%, #537895 100%);
+}
+
+/*092 Japan Blush*/
+.japan_blush{
+ background-image: linear-gradient(-20deg, #ddd6f3 0%, #faaca8 100%, #faaca8 100%);
+}
+
+/*093 Smiling Rain*/
+.smiling_rain{
+ background-image: linear-gradient(-20deg, #dcb0ed 0%, #99c99c 100%);
+}
+
+/*094 Cloudy Apple*/
+.cloudy_apple{
+ background-image: linear-gradient(to top, #f3e7e9 0%, #e3eeff 99%, #e3eeff 100%);
+}
+
+/*095 Big Mango*/
+.big_mango{
+ background-image: linear-gradient(to top, #c71d6f 0%, #d09693 100%);
+}
+
+/*096 Healthy Water*/
+.healthy_water{
+ background-image: linear-gradient(60deg, #96deda 0%, #50c9c3 100%);
+}
+
+/*097 Amour Amour*/
+.amour_amour{
+ background-image: linear-gradient(to top, #f77062 0%, #fe5196 100%);
+}
+
+/*098 Risky Concrete*/
+.risky_concrete{
+ background-image: linear-gradient(to top, #c4c5c7 0%, #dcdddf 52%, #ebebeb 100%);
+}
+
+/*099 Strong Stick*/
+.strong_stick{
+ background-image: linear-gradient(to right, #a8caba 0%, #5d4157 100%);
+}
+
+/*100 Vicious Stance*/
+.vicious_stance{
+ background-image: linear-gradient(60deg, #29323c 0%, #485563 100%);
+}
+
+/*101 Palo Alto*/
+.palo_alto{
+ background-image: linear-gradient(-60deg, #16a085 0%, #f4d03f 100%);
+}
+
+/*102 Happy Memories*/
+.happy_memories{
+ background-image: linear-gradient(-60deg, #ff5858 0%, #f09819 100%);
+}
+
+/*103 Midnight Bloom*/
+.midnight_bloom{
+ background-image: linear-gradient(-20deg, #2b5876 0%, #4e4376 100%);
+}
+
+/*104 Crystalline*/
+.crystalline{
+ background-image: linear-gradient(-20deg, #00cdac 0%, #8ddad5 100%);
+}
+
+/*105 Raccoon Back*/
+.raccoon_back{
+ background: linear-gradient(-180deg, #BCC5CE 0%, #929EAD 98%), radial-gradient(at top left, rgba(255,255,255,0.30) 0%, rgba(0,0,0,0.30) 100%);
+ background-blend-mode: screen;
+}
+
+/*106 Party Bliss*/
+.party_bliss{
+ background-image: linear-gradient(to top, #4481eb 0%, #04befe 100%);
+}
+
+/*107 Confident Cloud*/
+.confident_cloud{
+ background-image: linear-gradient(to top, #dad4ec 0%, #dad4ec 1%, #f3e7e9 100%);
+}
+
+/*108 Le Cocktail*/
+.le_cocktail{
+ background-image: linear-gradient(45deg, #874da2 0%, #c43a30 100%);
+}
+
+/*109 River City*/
+.river_city{
+ background-image: linear-gradient(to top, #4481eb 0%, #04befe 100%);
+}
+
+/*110 Frozen Berry*/
+.frozen_berry{
+ background-image: linear-gradient(to top, #e8198b 0%, #c7eafd 100%);
+}
+
+/*111 Elegance*/
+.elegance{
+ background-image: radial-gradient(73% 147%, #EADFDF 59%, #ECE2DF 100%), radial-gradient(91% 146%, rgba(255,255,255,0.50) 47%, rgba(0,0,0,0.50) 100%);
+ background-blend-mode: screen;
+}
+
+/*112 Child Care*/
+.child_care{
+ background-image: linear-gradient(-20deg, #f794a4 0%, #fdd6bd 100%);
+}
+
+/*113 Flying Lemon*/
+.flying_lemon{
+ background-image: linear-gradient(60deg, #64b3f4 0%, #c2e59c 100%);
+}
+
+/*114 New Retrowave*/
+.new_retrowave{
+ background-image: linear-gradient(to top, #3b41c5 0%, #a981bb 49%, #ffc8a9 100%);
+}
+
+/*115 Hidden Jaguar*/
+.hidden_jaguar{
+ background-image: linear-gradient(to top, #0fd850 0%, #f9f047 100%);
+}
+
+/*116 Above The Sky*/
+.above_the_sky{
+ background-image: linear-gradient(to top, lightgrey 0%, lightgrey 1%, #e0e0e0 26%, #efefef 48%, #d9d9d9 75%, #bcbcbc 100%);
+}
+
+/*117 Nega*/
+.nega{
+ background-image: linear-gradient(45deg, #ee9ca7 0%, #ffdde1 100%);
+}
+
+/*118 Dense Water*/
+.dense_water{
+ background-image: linear-gradient(to right, #3ab5b0 0%, #3d99be 31%, #56317a 100%);
+}
+
+/*119 Chemic Aqua*/
+.chemic_aqua{
+ background: #CDDCDC radial-gradient(at 50% 100%, rgba(255, 255, 255, 0.50) 0%, rgba(0, 0, 0, 0.50) 100%), linear-gradient(to bottom, rgba(255, 255, 255, 0.25) 0%, rgba(0, 0, 0, 0.25) 100%);
+ background-blend-mode: screen, overlay;
+}
+
+/*120 Seashore*/
+.seashore{
+ background-image: linear-gradient(to top, #209cff 0%, #68e0cf 100%);
+}
+
+/*121 Marble Wall*/
+.marble_wall{
+ background-image: linear-gradient(to top, #bdc2e8 0%, #bdc2e8 1%, #e6dee9 100%);
+}
+
+/*122 Cheerful Caramel*/
+.cheerful_caramel{
+ background-image: linear-gradient(to top, #e6b980 0%, #eacda3 100%);
+}
+
+/*123 Night Sky*/
+.night_sky{
+ background-image: linear-gradient(to top, #1e3c72 0%, #1e3c72 1%, #2a5298 100%);
+}
+
+/*124 Magic Lake*/
+.magic_lake{
+ background-image: linear-gradient(to top, #d5dee7 0%, #ffafbd 0%, #c9ffbf 100%);
+}
+
+/*125 Young Grass*/
+.young_grass{
+ background-image: linear-gradient(to top, #9be15d 0%, #00e3ae 100%);
+}
+
+/*126 Colorful Peach*/
+.colorful_peach{
+ background-image: linear-gradient(to right, #ed6ea0 0%, #ec8c69 100%);
+}
+
+/*127 Gentle Care*/
+.gentle_care{
+ background-image: linear-gradient(to right, #ffc3a0 0%, #ffafbd 100%);
+}
+
+/*128 Plum Bath*/
+.plum_bath{
+ background-image: linear-gradient(to top, #cc208e 0%, #6713d2 100%);
+}
+
+/*129 Happy Unicorn*/
+.happy_unicorn{
+ background-image: linear-gradient(to top, #b3ffab 0%, #12fff7 100%);
+}
+
+/*130 Full Metal*/
+.full_metal{
+ background: linear-gradient(to bottom, #D5DEE7 0%, #E8EBF2 50%, #E2E7ED 100%), linear-gradient(to bottom, rgba(0,0,0,0.02) 50%, rgba(255,255,255,0.02) 61%, rgba(0,0,0,0.02) 73%), linear-gradient(33deg, rgba(255,255,255,0.20) 0%, rgba(0,0,0,0.20) 100%);
+ background-blend-mode: normal,color-burn;
+}
+
+/*131 African Field*/
+.african_field{
+ background-image: linear-gradient(to top, #65bd60 0%, #5ac1a8 25%, #3ec6ed 50%, #b7ddb7 75%, #fef381 100%);
+}
+
+/*132 Solid Stone*/
+.solid_stone{
+ background-image: linear-gradient(to right, #243949 0%, #517fa4 100%);
+}
+
+/*133 Orange Juice*/
+.orange_juice{
+ background-image: linear-gradient(-20deg, #fc6076 0%, #ff9a44 100%);
+}
+
+/*134 Glass Water*/
+.glass_water{
+ background-image: linear-gradient(to top, #dfe9f3 0%, white 100%);
+}
+
+/*135 Slick Carbon*/
+.slick_carbon{
+ background: linear-gradient(to bottom, #323232 0%, #3F3F3F 40%, #1C1C1C 150%), linear-gradient(to top, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.25) 200%);
+ background-blend-mode: multiply;
+}
+
+/*136 North Miracle*/
+.north_miracle{
+ background-image: linear-gradient(to right, #00dbde 0%, #fc00ff 100%);
+}
+
+/*137 Fruit Blend*/
+.fruit_blend{
+ background-image: linear-gradient(to right, #f9d423 0%, #ff4e50 100%);
+}
+
+/*138 Millennium Pine*/
+.millennium_pine{
+ background-image: linear-gradient(to top, #50cc7f 0%, #f5d100 100%);
+}
+
+/*139 High Flight*/
+.high_flight{
+ background-image: linear-gradient(to right, #0acffe 0%, #495aff 100%);
+}
+
+/*140 Mole Hall*/
+.mole_hall{
+ background-image: linear-gradient(-20deg, #616161 0%, #9bc5c3 100%);
+}
+
+/*141 Earl Gray*/
+.earl_gray{
+ background: #E4E4E1 radial-gradient(at top center, rgba(255, 255, 255, 0.03) 0%, rgba(0, 0, 0, 0.03) 100%), linear-gradient(to top, rgba(255, 255, 255, 0.1) 0%, rgba(143, 152, 157, 0.60) 100%);
+ background-blend-mode: normal, multiply;
+}
+
+/*142 Space Shift*/
+.space_shift{
+ background-image: linear-gradient(60deg, #3d3393 0%, #2b76b9 37%, #2cacd1 65%, #35eb93 100%);
+}
+
+/*143 Forest Inei*/
+.forest_inei{
+ background-image: linear-gradient(to top, #df89b5 0%, #bfd9fe 100%);
+}
+
+/*144 Royal Garden*/
+.royal_garden{
+ background-image: linear-gradient(to right, #ed6ea0 0%, #ec8c69 100%);
+}
+
+/*145 Rich Metal*/
+.rich_metal{
+ background-image: linear-gradient(to right, #d7d2cc 0%, #304352 100%);
+}
+
+/*146 Juicy Cake*/
+.juicy_cake{
+ background-image: linear-gradient(to top, #e14fad 0%, #f9d423 100%);
+}
+
+/*147 Smart Indigo*/
+.smart_indigo{
+ background-image: linear-gradient(to top, #b224ef 0%, #7579ff 100%);
+}
+
+/*148 Sand Strike*/
+.sand_strike{
+ background-image: linear-gradient(to right, #c1c161 0%, #c1c161 0%, #d4d4b1 100%);
+}
+
+/*149 Norse Beauty*/
+.norse_beauty{
+ background-image: linear-gradient(to right, #ec77ab 0%, #7873f5 100%);
+}
+
+/*150 Aqua Guidance*/
+.aqua_guidance{
+ background-image: linear-gradient(to top, #007adf 0%, #00ecbc 100%);
+}
+
+/*151 Sun Veggie*/
+.sun_veggie{
+ background-image: linear-gradient(-225deg, #20E2D7 0%, #F9FEA5 100%);
+}
+
+/*152 Sea Lord*/
+.sea_lord{
+ background-image: linear-gradient(-225deg, #2CD8D5 0%, #C5C1FF 56%, #FFBAC3 100%);
+}
+
+/*153 Black Sea*/
+.black_sea{
+ background-image: linear-gradient(-225deg, #2CD8D5 0%, #6B8DD6 48%, #8E37D7 100%);
+}
+
+/*154 Grass Shampoo*/
+.grass_shampoo{
+ background-image: linear-gradient(-225deg, #DFFFCD 0%, #90F9C4 48%, #39F3BB 100%);
+}
+
+/*155 Landing Aircraft*/
+.landing_aircraft{
+ background-image: linear-gradient(-225deg, #5D9FFF 0%, #B8DCFF 48%, #6BBBFF 100%);
+}
+
+/*156 Witch Dance*/
+.witch_dance{
+ background-image: linear-gradient(-225deg, #A8BFFF 0%, #884D80 100%);
+}
+
+/*157 Sleepless Night*/
+.sleepless_night{
+ background-image: linear-gradient(-225deg, #5271C4 0%, #B19FFF 48%, #ECA1FE 100%);
+}
+
+/*158 Angel Care*/
+.angel_care{
+ background-image: linear-gradient(-225deg, #FFE29F 0%, #FFA99F 48%, #FF719A 100%);
+}
+
+/*159 Crystal River*/
+.crystal_river{
+ background-image: linear-gradient(-225deg, #22E1FF 0%, #1D8FE1 48%, #625EB1 100%);
+}
+
+/*160 Soft Lipstick*/
+.soft_lipstick{
+ background-image: linear-gradient(-225deg, #B6CEE8 0%, #F578DC 100%);
+}
+
+/*161 Salt Mountain*/
+.salt_mountain{
+ background-image: linear-gradient(-225deg, #FFFEFF 0%, #D7FFFE 100%);
+}
+
+/*162 Perfect White*/
+.perfect_white{
+ background-image: linear-gradient(-225deg, #E3FDF5 0%, #FFE6FA 100%);
+}
+
+/*163 Fresh Oasis*/
+.fresh_oasis{
+ background-image: linear-gradient(-225deg, #7DE2FC 0%, #B9B6E5 100%);
+}
+
+/*164 Strict November*/
+.strict_november{
+ background-image: linear-gradient(-225deg, #CBBACC 0%, #2580B3 100%);
+}
+
+/*165 Morning Salad*/
+.morning_salad{
+ background-image: linear-gradient(-225deg, #B7F8DB 0%, #50A7C2 100%);
+}
+
+/*166 Deep Relief*/
+.deep_relief{
+ background-image: linear-gradient(-225deg, #7085B6 0%, #87A7D9 50%, #DEF3F8 100%);
+}
+
+/*167 Sea Strike*/
+.sea_strike{
+ background-image: linear-gradient(-225deg, #77FFD2 0%, #6297DB 48%, #1EECFF 100%);
+}
+
+/*168 Night Call*/
+.night_call{
+ background-image: linear-gradient(-225deg, #AC32E4 0%, #7918F2 48%, #4801FF 100%);
+}
+
+/*169 Supreme Sky*/
+.supreme_sky{
+ background-image: linear-gradient(-225deg, #D4FFEC 0%, #57F2CC 48%, #4596FB 100%);
+}
+
+/*170 Light Blue*/
+.light_blue{
+ background-image: linear-gradient(-225deg, #9EFBD3 0%, #57E9F2 48%, #45D4FB 100%);
+}
+
+/*171 Mind Crawl*/
+.mind_crawl{
+ background-image: linear-gradient(-225deg, #473B7B 0%, #3584A7 51%, #30D2BE 100%);
+}
+
+/*172 Lily Meadow*/
+.lily_meadow{
+ background-image: linear-gradient(-225deg, #65379B 0%, #886AEA 53%, #6457C6 100%);
+}
+
+/*173 Sugar Lollipop*/
+.sugar_lollipop{
+ background-image: linear-gradient(-225deg, #A445B2 0%, #D41872 52%, #FF0066 100%);
+}
+
+/*174 Sweet Dessert*/
+.sweet_dessert{
+ background-image: linear-gradient(-225deg, #7742B2 0%, #F180FF 52%, #FD8BD9 100%);
+}
+
+/*175 Magic Ray*/
+.magic_ray{
+ background-image: linear-gradient(-225deg, #FF3CAC 0%, #562B7C 52%, #2B86C5 100%);
+}
+
+/*176 Teen Party*/
+.teen_party{
+ background-image: linear-gradient(-225deg, #FF057C 0%, #8D0B93 50%, #321575 100%);
+}
+
+/*177 Frozen Heat*/
+.frozen_heat{
+ background-image: linear-gradient(-225deg, #FF057C 0%, #7C64D5 48%, #4CC3FF 100%);
+}
+
+/*178 Gagarin View*/
+.gagarin_view{
+ background-image: linear-gradient(-225deg, #69EACB 0%, #EACCF8 48%, #6654F1 100%);
+}
+
+/*179 Fabled Sunset*/
+.fabled_sunset{
+ background-image: linear-gradient(-225deg, #231557 0%, #44107A 29%, #FF1361 67%, #FFF800 100%);
+}
+
+/*180 Perfect Blue*/
+.perfect_blue{
+ background-image: linear-gradient(-225deg, #3D4E81 0%, #5753C9 48%, #6E7FF3 100%);
+}
diff --git a/src/gui/qtgui.tracepoints b/src/gui/qtgui.tracepoints
index aa8a8ede57..2c232a0af8 100644
--- a/src/gui/qtgui.tracepoints
+++ b/src/gui/qtgui.tracepoints
@@ -1,8 +1,10 @@
-qfontdatabase_addapplicationfont(const QString &filename)
-qfontdatabase_load(const QString &family, int pointSize)
-qfontdatabase_loadengine(const QString &family, int pointSize)
-qfontdatabaseprivate_addappfont(const QString &fileName)
-qguiapplicationprivate_init_entry()
-qguiapplicationprivate_init_exit()
-qguiapplicationprivate_processwsevents_entry(int type)
-qguiapplicationprivate_processwsevents_exit(int type)
+QGuiApplicationPrivate_init_entry()
+QGuiApplicationPrivate_init_exit()
+
+QGuiApplicationPrivate_processWindowSystemEvent_entry(int type)
+QGuiApplicationPrivate_processWindowSystemEvent_exit(int type)
+
+QFontDatabase_addApplicationFont(const QString &filename)
+QFontDatabase_load(const QString &family, int pointSize)
+QFontDatabase_loadEngine(const QString &family, int pointSize)
+QFontDatabasePrivate_addAppFont(const QString &fileName)
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 64adeaa260..70623939e1 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -345,13 +345,6 @@ static const QCssKnownValue styleFeatures[NumKnownStyleFeatures - 1] = {
{ "none", StyleFeature_None }
};
-#if defined(Q_CC_MSVC) && _MSC_VER < 1600
-static bool operator<(const QCssKnownValue &prop1, const QCssKnownValue &prop2)
-{
- return QString::compare(QString::fromLatin1(prop1.name), QLatin1String(prop2.name), Qt::CaseInsensitive) < 0;
-}
-#endif
-
static bool operator<(const QString &name, const QCssKnownValue &prop)
{
return QString::compare(name, QLatin1String(prop.name), Qt::CaseInsensitive) < 0;
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index f7462b65c8..580a09427c 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -2703,18 +2703,6 @@ static const int slow_timeout = 300000; // 5m
const uint QFontCache::min_cost = 4*1024; // 4mb
-#ifdef QT_NO_THREAD
-Q_GLOBAL_STATIC(QFontCache, theFontCache)
-
-QFontCache *QFontCache::instance()
-{
- return theFontCache();
-}
-
-void QFontCache::cleanup()
-{
-}
-#else
Q_GLOBAL_STATIC(QThreadStorage<QFontCache *>, theFontCache)
QFontCache *QFontCache::instance()
@@ -2736,7 +2724,6 @@ void QFontCache::cleanup()
if (cache && cache->hasLocalData())
cache->setLocalData(0);
}
-#endif // QT_NO_THREAD
QBasicAtomicInt font_cache_id = Q_BASIC_ATOMIC_INITIALIZER(1);
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index a4e5130937..196eebb353 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -689,7 +689,6 @@ static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDe
if (!multi)
fontDef->style = desc.style->key.style;
fontDef->fixedPitch = desc.family->fixedPitch;
- fontDef->stretch = desc.style->key.stretch;
fontDef->ignorePitch = false;
}
@@ -1010,7 +1009,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size);
if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
- Q_TRACE(qfontdatabase_loadengine, request.family, request.pointSize);
+ Q_TRACE(QFontDatabase_loadEngine, request.family, request.pointSize);
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script));
@@ -2442,7 +2441,7 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
font.data = fontData;
font.fileName = fileName;
- Q_TRACE(qfontdatabaseprivate_addappfont, fileName);
+ Q_TRACE(QFontDatabasePrivate_addAppFont, fileName);
int i;
for (i = 0; i < applicationFonts.count(); ++i)
@@ -2500,7 +2499,7 @@ int QFontDatabase::addApplicationFont(const QString &fileName)
if (!f.open(QIODevice::ReadOnly))
return -1;
- Q_TRACE(qfontdatabase_addapplicationfont, fileName);
+ Q_TRACE(QFontDatabase_addApplicationFont, fileName);
data = f.readAll();
}
@@ -2800,7 +2799,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
QFontEngine *fe = nullptr;
- Q_TRACE(qfontdatabase_load, req.family, req.pointSize);
+ Q_TRACE(QFontDatabase_load, req.family, req.pointSize);
req.fallBackFamilies = fallBackFamilies;
if (!req.fallBackFamilies.isEmpty())
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 3b64ee0136..64623c86df 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1327,7 +1327,7 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
resolveTable:
*isSymbolFont = (symbolTable > -1);
- quint32 unicode_table;
+ quint32 unicode_table = 0;
if (!qSafeFromBigEndian(maps + 8 * tableToUse + 4, endPtr, &unicode_table))
return 0;
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 2f90754274..0026e3edfb 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -39,6 +39,7 @@
#include "qstatictext.h"
#include "qstatictext_p.h"
+#include <qmath.h>
#include <private/qtextengine_p.h>
#include <private/qfontengine_p.h>
#include <qabstracttextdocumentlayout.h>
@@ -611,22 +612,22 @@ void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p,
textLayout.setTextOption(textOption);
textLayout.setCacheEnabled(true);
- qreal leading = QFontMetricsF(font).leading();
- qreal height = -leading;
-
+ qreal height = 0;
textLayout.beginLayout();
while (1) {
QTextLine line = textLayout.createLine();
if (!line.isValid())
break;
+ line.setLeadingIncluded(true);
if (textWidth >= 0.0)
line.setLineWidth(textWidth);
else
line.setLineWidth(QFIXED_MAX);
- height += leading;
line.setPosition(QPointF(0.0, height));
height += line.height();
+ if (line.leading() < 0)
+ height += qCeil(line.leading());
}
textLayout.endLayout();
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 44d1b2f201..5d88530e65 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -75,6 +75,18 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION unsigned int qt_int_sqrt(unsigned int n);
+
+/*!
+ Returns \c true if the string \a text is likely to be rich text;
+ otherwise returns \c false.
+
+ This function uses a fast and therefore simple heuristic. It
+ mainly checks whether there is something that looks like a tag
+ before the first line break. Although the result may be correct
+ for common cases, there is no guarantee.
+
+ This function is defined in the \c <QTextDocument> header file.
+*/
bool Qt::mightBeRichText(const QString& text)
{
if (text.isEmpty())
@@ -133,6 +145,16 @@ bool Qt::mightBeRichText(const QString& text)
return false;
}
+/*!
+ Converts the plain text string \a plain to an HTML-formatted
+ paragraph while preserving most of its look.
+
+ \a mode defines how whitespace is handled.
+
+ This function is defined in the \c <QTextDocument> header file.
+
+ \sa escape(), mightBeRichText()
+*/
QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode)
{
int col = 0;
@@ -181,6 +203,12 @@ QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode)
return rich;
}
+/*!
+ \fn QTextCodec *Qt::codecForHtml(const QByteArray &ba)
+ \internal
+
+ This function is defined in the \c <QTextDocument> header file.
+*/
#ifndef QT_NO_TEXTCODEC
QTextCodec *Qt::codecForHtml(const QByteArray &ba)
{
@@ -1989,7 +2017,6 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
int fromPage = pd->fromPage;
int toPage = pd->toPage;
- bool ascending = true;
if (fromPage == 0 && toPage == 0) {
fromPage = 1;
@@ -2005,6 +2032,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
return;
}
+// bool ascending = true;
// if (printer->pageOrder() == QPrinter::LastPageFirst) {
// int tmp = fromPage;
// fromPage = toPage;
@@ -2018,12 +2046,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
if (page == toPage)
break;
-
- if (ascending)
- ++page;
- else
- --page;
-
+ ++page;
if (!printer->newPage())
return;
}
@@ -2908,7 +2931,11 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block)
html += QLatin1Char('>');
html += QLatin1String("<pre");
} else if (!list) {
- html += QLatin1String("<p");
+ int headingLevel = blockFormat.headingLevel();
+ if (headingLevel > 0 && headingLevel <= 6)
+ html += QLatin1String("<h") + QString::number(headingLevel);
+ else
+ html += QLatin1String("<p");
}
emitBlockAttributes(block);
@@ -2931,8 +2958,13 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block)
html += QLatin1String("</pre>");
else if (list)
html += QLatin1String("</li>");
- else
- html += QLatin1String("</p>");
+ else {
+ int headingLevel = blockFormat.headingLevel();
+ if (headingLevel > 0 && headingLevel <= 6)
+ html += QLatin1String("</h") + QString::number(headingLevel) + QLatin1Char('>');
+ else
+ html += QLatin1String("</p>");
+ }
if (list) {
if (list->itemNumber(block) == list->count() - 1) { // last item? close list
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 64e39d4648..33c0b48683 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -70,17 +70,15 @@ class QTextCursor;
template<typename T> class QVector;
-#ifndef Q_CLANG_QDOC
namespace Qt
{
Q_GUI_EXPORT bool mightBeRichText(const QString&);
Q_GUI_EXPORT QString convertFromPlainText(const QString &plain, WhiteSpaceMode mode = WhiteSpacePre);
-#ifndef QT_NO_TEXTCODEC
+#if !defined(QT_NO_TEXTCODEC) || defined(Q_CLANG_QDOC)
Q_GUI_EXPORT QTextCodec *codecForHtml(const QByteArray &ba);
#endif
}
-#endif
class Q_GUI_EXPORT QAbstractUndoItem
{
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index ea37695f4e..f0eff2d4f3 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -420,7 +420,7 @@ static QTextListFormat::Style nextListStyle(QTextListFormat::Style style)
}
QTextHtmlImporter::QTextHtmlImporter(QTextDocument *_doc, const QString &_html, ImportMode mode, const QTextDocument *resourceProvider)
- : indent(0), compressNextWhitespace(PreserveWhiteSpace), doc(_doc), importMode(mode)
+ : indent(0), headingLevel(0), compressNextWhitespace(PreserveWhiteSpace), doc(_doc), importMode(mode)
{
cursor = QTextCursor(doc);
wsm = QTextHtmlParserNode::WhiteSpaceNormal;
@@ -724,9 +724,9 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processSpecialNodes()
cursor.insertImage(fmt, QTextFrameFormat::Position(currentNode->cssFloat));
- cursor.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
cursor.mergeCharFormat(currentNode->charFormat);
- cursor.movePosition(QTextCursor::Right);
+ cursor.movePosition(QTextCursor::NextCharacter);
compressNextWhitespace = CollapseWhiteSpace;
hasBlock = false;
@@ -747,8 +747,28 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processSpecialNodes()
return ContinueWithNextNode;
}
+ case Html_h1:
+ headingLevel = 1;
+ break;
+ case Html_h2:
+ headingLevel = 2;
+ break;
+ case Html_h3:
+ headingLevel = 3;
+ break;
+ case Html_h4:
+ headingLevel = 4;
+ break;
+ case Html_h5:
+ headingLevel = 5;
+ break;
+ case Html_h6:
+ headingLevel = 6;
+ break;
+
default: break;
}
+
return ContinueWithCurrentNode;
}
@@ -832,6 +852,15 @@ bool QTextHtmlImporter::closeTag()
}
}
break;
+ case Html_h1:
+ case Html_h2:
+ case Html_h3:
+ case Html_h4:
+ case Html_h5:
+ case Html_h6:
+ headingLevel = 0;
+ blockTagClosed = true;
+ break;
default:
if (closedNode->isBlock())
blockTagClosed = true;
@@ -1093,6 +1122,11 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode()
modifiedBlockFormat = true;
}
+ if (headingLevel) {
+ block.setHeadingLevel(headingLevel);
+ modifiedBlockFormat = true;
+ }
+
if (currentNode->blockFormat.propertyCount() > 0) {
modifiedBlockFormat = true;
block.merge(currentNode->blockFormat);
diff --git a/src/gui/text/qtextdocumentfragment_p.h b/src/gui/text/qtextdocumentfragment_p.h
index e8699545f7..02a6a429fa 100644
--- a/src/gui/text/qtextdocumentfragment_p.h
+++ b/src/gui/text/qtextdocumentfragment_p.h
@@ -152,6 +152,7 @@ private:
friend class QTypeInfo<List>;
QVector<List> lists;
int indent;
+ int headingLevel;
// insert a named anchor the next time we emit a char format,
// either in a block or in regular text
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index 2957b8d5c0..a9227f0171 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -399,26 +399,6 @@ static bool operator<(const QCheckPoint &checkPoint, int pos)
return checkPoint.positionInFrame < pos;
}
-#if defined(Q_CC_MSVC) && _MSC_VER < 1600
-//The STL implementation of MSVC 2008 requires the definitions
-
-static bool operator<(const QCheckPoint &checkPoint1, const QCheckPoint &checkPoint2)
-{
- return checkPoint1.y < checkPoint2.y;
-}
-
-static bool operator<(QFixed y, const QCheckPoint &checkPoint)
-{
- return y < checkPoint.y;
-}
-
-static bool operator<(int pos, const QCheckPoint &checkPoint)
-{
- return pos < checkPoint.positionInFrame;
-}
-
-#endif
-
static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, const QPointF &origin, const QRectF &gradientRect = QRectF())
{
p->save();
@@ -2569,12 +2549,14 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayout
}
static inline void getLineHeightParams(const QTextBlockFormat &blockFormat, const QTextLine &line, qreal scaling,
- QFixed *lineAdjustment, QFixed *lineBreakHeight, QFixed *lineHeight)
+ QFixed *lineAdjustment, QFixed *lineBreakHeight, QFixed *lineHeight, QFixed *lineBottom)
{
- *lineHeight = QFixed::fromReal(blockFormat.lineHeight(line.height(), scaling));
+ qreal rawHeight = qCeil(line.ascent() + line.descent() + line.leading());
+ *lineHeight = QFixed::fromReal(blockFormat.lineHeight(rawHeight, scaling));
+ *lineBottom = QFixed::fromReal(blockFormat.lineHeight(line.height(), scaling));
if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight || blockFormat.lineHeightType() == QTextBlockFormat::MinimumHeight) {
- *lineBreakHeight = *lineHeight;
+ *lineBreakHeight = *lineBottom;
if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight)
*lineAdjustment = QFixed::fromReal(line.ascent() + qMax(line.leading(), qreal(0.0))) - ((*lineHeight * 4) / 5);
else
@@ -2652,6 +2634,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
const QFixed cy = layoutStruct->y;
const QFixed l = layoutStruct->x_left + totalLeftMargin;
const QFixed r = layoutStruct->x_right - totalRightMargin;
+ QFixed bottom;
tl->beginLayout();
bool firstLine = true;
@@ -2721,10 +2704,10 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
}
- QFixed lineBreakHeight, lineHeight, lineAdjustment;
+ QFixed lineBreakHeight, lineHeight, lineAdjustment, lineBottom;
qreal scaling = (q->paintDevice() && q->paintDevice()->logicalDpiY() != qt_defaultDpi()) ?
qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1;
- getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight);
+ getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight, &lineBottom);
if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom) {
layoutStruct->newPage();
@@ -2739,6 +2722,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
}
line.setPosition(QPointF((left - layoutStruct->x_left).toReal(), (layoutStruct->y - cy - lineAdjustment).toReal()));
+ bottom = layoutStruct->y + lineBottom;
layoutStruct->y += lineHeight;
layoutStruct->contentsWidth
= qMax<QFixed>(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + line.naturalTextWidth()) + totalRightMargin);
@@ -2750,27 +2734,31 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
}
layoutStruct->pendingFloats.clear();
}
+ layoutStruct->y = qMax(layoutStruct->y, bottom);
tl->endLayout();
} else {
const int cnt = tl->lineCount();
+ QFixed bottom;
for (int i = 0; i < cnt; ++i) {
LDEBUG << "going to move text line" << i;
QTextLine line = tl->lineAt(i);
layoutStruct->contentsWidth
= qMax(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + tl->lineAt(i).naturalTextWidth()) + totalRightMargin);
- QFixed lineBreakHeight, lineHeight, lineAdjustment;
+ QFixed lineBreakHeight, lineHeight, lineAdjustment, lineBottom;
qreal scaling = (q->paintDevice() && q->paintDevice()->logicalDpiY() != qt_defaultDpi()) ?
qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1;
- getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight);
+ getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight, &lineBottom);
if (layoutStruct->pageHeight != QFIXED_MAX) {
if (layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom)
layoutStruct->newPage();
line.setPosition(QPointF(line.position().x(), (layoutStruct->y - lineAdjustment).toReal() - tl->position().y()));
}
+ bottom = layoutStruct->y + lineBottom;
layoutStruct->y += lineHeight;
}
+ layoutStruct->y = qMax(layoutStruct->y, bottom);
if (layoutStruct->updateRect.isValid()
&& blockLength > 1) {
if (layoutFrom >= blockPosition + blockLength) {
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 87dc63d59c..4e9b00f9c9 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -597,7 +597,13 @@ struct QBidiAlgorithm {
} else if (current == QChar::DirBN) {
current = last;
} else {
- Q_ASSERT(current != QChar::DirLRE && current != QChar::DirRLE && current != QChar::DirLRO && current != QChar::DirRLO && current != QChar::DirPDF); // there shouldn't be any explicit embedding marks here
+ // there shouldn't be any explicit embedding marks here
+ Q_ASSERT(current != QChar::DirLRE);
+ Q_ASSERT(current != QChar::DirRLE);
+ Q_ASSERT(current != QChar::DirLRO);
+ Q_ASSERT(current != QChar::DirRLO);
+ Q_ASSERT(current != QChar::DirPDF);
+
last = current;
}
@@ -1939,7 +1945,7 @@ const QCharAttributes *QTextEngine::attributes() const
QVarLengthArray<QUnicodeTools::ScriptItem> scriptItems(layoutData->items.size());
for (int i = 0; i < layoutData->items.size(); ++i) {
- const QScriptItem &si = layoutData->items[i];
+ const QScriptItem &si = layoutData->items.at(i);
scriptItems[i].position = si.position;
scriptItems[i].script = si.analysis.script;
}
@@ -1956,14 +1962,14 @@ const QCharAttributes *QTextEngine::attributes() const
void QTextEngine::shape(int item) const
{
- if (layoutData->items[item].analysis.flags == QScriptAnalysis::Object) {
+ if (layoutData->items.at(item).analysis.flags == QScriptAnalysis::Object) {
ensureSpace(1);
if (block.docHandle()) {
docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast<QTextEngine *>(this)),
layoutData->items[item].position + block.position(),
format(&layoutData->items[item]));
}
- } else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) {
+ } else if (layoutData->items.at(item).analysis.flags == QScriptAnalysis::Tab) {
// set up at least the ascent/descent/leading of the script item for the tab
fontEngine(layoutData->items[item],
&layoutData->items[item].ascent,
@@ -2076,7 +2082,7 @@ void QTextEngine::itemize() const
case QChar::Space:
case QChar::Nbsp:
if (option.flags() & QTextOption::ShowTabsAndSpaces) {
- analysis->flags = QScriptAnalysis::Space;
+ analysis->flags = (*uc == QChar::Space) ? QScriptAnalysis::Space : QScriptAnalysis::Nbsp;
break;
}
Q_FALLTHROUGH();
@@ -2204,9 +2210,9 @@ int QTextEngine::findItem(int strPos, int firstItem) const
int right = layoutData->items.size()-1;
while(left <= right) {
int middle = ((right-left)/2)+left;
- if (strPos > layoutData->items[middle].position)
+ if (strPos > layoutData->items.at(middle).position)
left = middle+1;
- else if(strPos < layoutData->items[middle].position)
+ else if (strPos < layoutData->items.at(middle).position)
right = middle-1;
else {
return middle;
@@ -2598,7 +2604,7 @@ void QTextEngine::justify(const QScriptLine &line)
int end = line.from + (int)line.length + line.trailingSpaces;
if (end == layoutData->string.length())
return; // no justification at end of paragraph
- if (end && layoutData->items[findItem(end-1)].analysis.flags == QScriptAnalysis::LineOrParagraphSeparator)
+ if (end && layoutData->items.at(findItem(end - 1)).analysis.flags == QScriptAnalysis::LineOrParagraphSeparator)
return; // no justification at the end of an explicitly separated line
}
@@ -2632,13 +2638,13 @@ void QTextEngine::justify(const QScriptLine &line)
// store pointers to the glyph data that could get reallocated by the shaping
// process.
for (int i = 0; i < nItems; ++i) {
- QScriptItem &si = layoutData->items[firstItem + i];
+ const QScriptItem &si = layoutData->items.at(firstItem + i);
if (!si.num_glyphs)
shape(firstItem + i);
}
for (int i = 0; i < nItems; ++i) {
- QScriptItem &si = layoutData->items[firstItem + i];
+ const QScriptItem &si = layoutData->items.at(firstItem + i);
int kashida_type = Justification_Arabic_Normal;
int kashida_pos = -1;
@@ -2934,7 +2940,7 @@ int QTextEngine::formatIndex(const QScriptItem *si) const
if (specialData && !specialData->resolvedFormats.isEmpty()) {
QTextFormatCollection *collection = formatCollection();
Q_ASSERT(collection);
- return collection->indexForFormat(specialData->resolvedFormats.at(si - &layoutData->items[0]));
+ return collection->indexForFormat(specialData->resolvedFormats.at(si - &layoutData->items.at(0)));
}
QTextDocumentPrivate *p = block.docHandle();
@@ -3140,7 +3146,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
if (!attributes)
return QString();
for (int i = 0; i < layoutData->items.size(); ++i) {
- QScriptItem &si = layoutData->items[i];
+ const QScriptItem &si = layoutData->items.at(i);
if (!si.num_glyphs)
shape(i);
@@ -3325,24 +3331,29 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
QList<QTextOption::Tab> tabArray = option.tabs();
if (!tabArray.isEmpty()) {
if (isRightToLeft()) { // rebase the tabArray positions.
- QList<QTextOption::Tab> newTabs;
- newTabs.reserve(tabArray.count());
- QList<QTextOption::Tab>::Iterator iter = tabArray.begin();
- while(iter != tabArray.end()) {
- QTextOption::Tab tab = *iter;
- if (tab.type == QTextOption::LeftTab)
- tab.type = QTextOption::RightTab;
- else if (tab.type == QTextOption::RightTab)
- tab.type = QTextOption::LeftTab;
- newTabs << tab;
- ++iter;
+ auto isLeftOrRightTab = [](const QTextOption::Tab &tab) {
+ return tab.type == QTextOption::LeftTab || tab.type == QTextOption::RightTab;
+ };
+ const auto cbegin = tabArray.cbegin();
+ const auto cend = tabArray.cend();
+ const auto cit = std::find_if(cbegin, cend, isLeftOrRightTab);
+ if (cit != cend) {
+ const int index = std::distance(cbegin, cit);
+ auto iter = tabArray.begin() + index;
+ const auto end = tabArray.end();
+ while (iter != end) {
+ QTextOption::Tab &tab = *iter;
+ if (tab.type == QTextOption::LeftTab)
+ tab.type = QTextOption::RightTab;
+ else if (tab.type == QTextOption::RightTab)
+ tab.type = QTextOption::LeftTab;
+ ++iter;
+ }
}
- tabArray = newTabs;
}
- for (int i = 0; i < tabArray.size(); ++i) {
- QFixed tab = QFixed::fromReal(tabArray[i].position) * dpiScale;
+ for (const QTextOption::Tab &tabSpec : qAsConst(tabArray)) {
+ QFixed tab = QFixed::fromReal(tabSpec.position) * dpiScale;
if (tab > x) { // this is the tab we need.
- QTextOption::Tab tabSpec = tabArray[i];
int tabSectionEnd = layoutData->string.count();
if (tabSpec.type == QTextOption::RightTab || tabSpec.type == QTextOption::CenterTab) {
// find next tab to calculate the width required.
@@ -3363,7 +3374,7 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
QFixed length;
// Calculate the length of text between this tab and the tabSectionEnd
for (int i=item; i < layoutData->items.count(); i++) {
- QScriptItem &item = layoutData->items[i];
+ const QScriptItem &item = layoutData->items.at(i);
if (item.position > tabSectionEnd || item.position <= si.position)
continue;
shape(i); // first, lets make sure relevant text is already shaped
@@ -3663,11 +3674,12 @@ int QTextEngine::lineNumberForTextPosition(int pos)
return -1;
}
-void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoints)
+std::vector<int> QTextEngine::insertionPointsForLine(int lineNum)
{
QTextLineItemIterator iterator(this, lineNum);
- insertionPoints.reserve(iterator.line.length);
+ std::vector<int> insertionPoints;
+ insertionPoints.reserve(size_t(iterator.line.length));
bool lastLine = lineNum >= lines.size() - 1;
@@ -3685,25 +3697,22 @@ void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoi
insertionPoints.push_back(i);
}
}
+ return insertionPoints;
}
int QTextEngine::endOfLine(int lineNum)
{
- QVector<int> insertionPoints;
- insertionPointsForLine(lineNum, insertionPoints);
-
+ const auto insertionPoints = insertionPointsForLine(lineNum);
if (insertionPoints.size() > 0)
- return insertionPoints.constLast();
+ return insertionPoints.back();
return 0;
}
int QTextEngine::beginningOfLine(int lineNum)
{
- QVector<int> insertionPoints;
- insertionPointsForLine(lineNum, insertionPoints);
-
+ const auto insertionPoints = insertionPointsForLine(lineNum);
if (insertionPoints.size() > 0)
- return insertionPoints.constFirst();
+ return insertionPoints.front();
return 0;
}
@@ -3720,10 +3729,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation
if (lineNum < 0)
return pos;
- QVector<int> insertionPoints;
- insertionPointsForLine(lineNum, insertionPoints);
- int i, max = insertionPoints.size();
- for (i = 0; i < max; i++)
+ const auto insertionPoints = insertionPointsForLine(lineNum);
+ for (size_t i = 0, max = insertionPoints.size(); i < max; ++i)
if (pos == insertionPoints[i]) {
if (moveRight) {
if (i + 1 < max)
@@ -4001,7 +4008,7 @@ QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, co
QVarLengthArray<uchar> levels(nItems);
for (int i = 0; i < nItems; ++i)
- levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
+ levels[i] = eng->layoutData->items.at(i + firstItem).analysis.bidiLevel;
QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
eng->shapeLine(line);
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index f9eb055478..e9187ea605 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -74,6 +74,7 @@
#include <private/qunicodetools_p.h>
#include <stdlib.h>
+#include <vector>
QT_BEGIN_NAMESPACE
@@ -142,9 +143,10 @@ struct Q_AUTOTEST_EXPORT QScriptAnalysis
LineOrParagraphSeparator = 4,
Space = 5,
SpaceTabOrObject = Space,
- Tab = 6,
+ Nbsp = 6,
+ Tab = 7,
TabOrObject = Tab,
- Object = 7
+ Object = 8
};
enum BidiFlags {
BidiBN = 1,
@@ -632,7 +634,7 @@ public:
int nextLogicalPosition(int oldPos) const;
int lineNumberForTextPosition(int pos);
int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op);
- void insertionPointsForLine(int lineNum, QVector<int> &insertionPoints);
+ std::vector<int> insertionPointsForLine(int lineNum);
void resetFontEngineCache();
void enableDelayDecorations(bool enable = true) { delayDecorations = enable; }
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 08106db6ce..4957da1908 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -514,7 +514,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value BlockFormat The object formats a text block
\value CharFormat The object formats a single character
\value ListFormat The object formats a list
- \omitvalue TableFormat Unused Value, a table's FormatType is FrameFormat.
+ \omitvalue TableFormat \omit Unused Value, a table's FormatType is FrameFormat. \endomit
\value FrameFormat The object formats a frame
\value UserFormat
@@ -556,6 +556,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value LineHeightType
\value BlockNonBreakableLines
\value BlockTrailingHorizontalRulerWidth The width of a horizontal ruler element.
+ \value HeadingLevel The level of a heading, for example 1 corresponds to an HTML H1 tag; otherwise 0.
+ This enum value has been added in Qt 5.12.
Character properties
@@ -2246,6 +2248,34 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const
/*!
+ \fn void QTextBlockFormat::setHeadingLevel(int level)
+ \since 5.12
+
+ Sets the paragraph's heading level, where 1 is the highest-level heading
+ type (usually with the largest possible heading font size), and increasing
+ values are progressively deeper into the document (and usually with smaller
+ font sizes). For example when reading an HTML H1 tag, the heading level is
+ set to 1. Setting the heading level does not automatically change the font
+ size; however QTextDocumentFragment::fromHtml() sets both the heading level
+ and the font size simultaneously.
+
+ If the paragraph is not a heading, the level should be set to 0 (the default).
+
+ \sa headingLevel()
+*/
+
+
+/*!
+ \fn int QTextBlockFormat::headingLevel() const
+ \since 5.12
+
+ Returns the paragraph's heading level if it is a heading, or 0 if not.
+
+ \sa setHeadingLevel()
+*/
+
+
+/*!
\fn void QTextBlockFormat::setLineHeight(qreal height, int heightType)
\since 4.8
@@ -3047,7 +3077,8 @@ QTextTableFormat::QTextTableFormat(const QTextFormat &fmt)
REPLACEMENT CHARACTER) which has an associated QTextImageFormat. The
image format specifies a name with setName() that is used to
locate the image. The size of the rectangle that the image will
- occupy is specified using setWidth() and setHeight().
+ occupy is specified in pixels using setWidth() and setHeight().
+ The desired image quality may be set with setQuality().
Images can be supplied in any format for which Qt has an image
reader, so SVG drawings can be included alongside PNG, TIFF and
@@ -3137,6 +3168,28 @@ QTextImageFormat::QTextImageFormat(const QTextFormat &fmt)
*/
/*!
+ \fn void QTextImageFormat::setQuality(int quality = 100)
+ \since 5.12
+
+ Sets the quality that should be used by exporters when exporting the image. QTextDocumentWriter
+ will export jpg images with the \a quality set here when exporting to ODF files if \a quality is
+ set to a value between 0 and 100. Or it will export png images if \a quality is set to 100
+ (default) or greater.
+
+ \sa quality()
+*/
+
+
+/*!
+ \fn qreal QTextImageFormat::quality() const
+ \since 5.12
+
+ Returns the value set by setQuality().
+
+ \sa setQuality()
+*/
+
+/*!
\fn void QTextCharFormat::setFontCapitalization(QFont::Capitalization capitalization)
\since 4.4
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index 28c3035537..a8e573d5a4 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -175,6 +175,7 @@ public:
LineHeightType = 0x1049,
BlockNonBreakableLines = 0x1050,
BlockTrailingHorizontalRulerWidth = 0x1060,
+ HeadingLevel = 0x1070,
// character properties
FirstFontProperty = 0x1FE0,
@@ -249,6 +250,7 @@ public:
ImageName = 0x5000,
ImageWidth = 0x5010,
ImageHeight = 0x5011,
+ ImageQuality = 0x5014,
// internal
/*
@@ -624,6 +626,11 @@ public:
inline int indent() const
{ return intProperty(BlockIndent); }
+ inline void setHeadingLevel(int alevel)
+ { setProperty(HeadingLevel, alevel); }
+ inline int headingLevel() const
+ { return intProperty(HeadingLevel); }
+
inline void setLineHeight(qreal height, int heightType)
{ setProperty(LineHeight, height); setProperty(LineHeightType, heightType); }
inline qreal lineHeight(qreal scriptLineHeight, qreal scaling) const;
@@ -748,6 +755,10 @@ public:
inline qreal height() const
{ return doubleProperty(ImageHeight); }
+ inline void setQuality(int quality = 100);
+ inline int quality() const
+ { return intProperty(ImageQuality); }
+
protected:
explicit QTextImageFormat(const QTextFormat &format);
friend class QTextFormat;
@@ -764,6 +775,9 @@ inline void QTextImageFormat::setWidth(qreal awidth)
inline void QTextImageFormat::setHeight(qreal aheight)
{ setProperty(ImageHeight, aheight); }
+inline void QTextImageFormat::setQuality(int aquality)
+{ setProperty(ImageQuality, aquality); }
+
class Q_GUI_EXPORT QTextFrameFormat : public QTextFormat
{
public:
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 9154182df1..4be800b251 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -448,13 +448,6 @@ static const QTextHtmlElement elements[Html_NumElements]= {
{ "var", Html_var, QTextHtmlElement::DisplayInline },
};
-#if defined(Q_CC_MSVC) && _MSC_VER < 1600
-static bool operator<(const QTextHtmlElement &e1, const QTextHtmlElement &e2)
-{
- return QLatin1String(e1.name) < QLatin1String(e2.name);
-}
-#endif
-
static bool operator<(const QString &str, const QTextHtmlElement &e)
{
return str < QLatin1String(e.name);
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 6e824b2ed1..ca6866d836 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -1006,10 +1006,8 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo
}
if (lastSelectionWidth > 0) {
- QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
- rect.moveLeft(qFloor(rect.left()));
- rect.moveTop(qFloor(rect.top()));
- region->addRect(rect);
+ const QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
+ region->addRect(rect.toAlignedRect());
}
lastSelectionX = selectionX;
@@ -1017,10 +1015,8 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo
}
}
if (lastSelectionWidth > 0) {
- QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
- rect.moveLeft(qFloor(rect.left()));
- rect.moveTop(qFloor(rect.top()));
- region->addRect(rect);
+ const QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
+ region->addRect(rect.toAlignedRect());
}
}
@@ -2135,7 +2131,7 @@ static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const Q
QBrush bg = chf.background();
if (bg.style() != Qt::NoBrush && !chf.property(SuppressBackground).toBool())
- p->fillRect(QRectF(qFloor(r.x()), qFloor(r.y()), r.width(), r.height()), bg);
+ p->fillRect(r.toAlignedRect(), bg);
if (c.style() != Qt::NoBrush) {
p->setPen(QPen(c, 0));
}
@@ -2614,12 +2610,13 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
QPainterPrivate::get(p)->drawTextItem(pos, gf, eng);
}
- if (si.analysis.flags == QScriptAnalysis::Space
+ if ((si.analysis.flags == QScriptAnalysis::Space
+ || si.analysis.flags == QScriptAnalysis::Nbsp)
&& (eng->option.flags() & QTextOption::ShowTabsAndSpaces)) {
QBrush c = format.foreground();
if (c.style() != Qt::NoBrush)
p->setPen(c.color());
- QChar visualSpace((ushort)0xb7);
+ QChar visualSpace(si.analysis.flags == QScriptAnalysis::Space ? (ushort)0xb7 : (ushort)0xb0);
p->drawText(QPointF(iterator.x.toReal(), itemBaseLine.toReal()), visualSpace);
p->setPen(pen);
}
@@ -2845,9 +2842,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
bool rtl = eng->isRightToLeft();
eng->shapeLine(line);
- QVector<int> insertionPoints;
- if (visual && rtl)
- eng->insertionPointsForLine(lineNum, insertionPoints);
+ const auto insertionPoints = (visual && rtl) ? eng->insertionPointsForLine(lineNum) : std::vector<int>();
int nchars = 0;
for (int i = 0; i < nItems; ++i) {
int item = visualOrder[i]+firstItem;
@@ -2979,7 +2974,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
continue;
}
if (rtl && nchars > 0)
- return insertionPoints[lastLine ? nchars : nchars - 1];
+ return insertionPoints[size_t(lastLine ? nchars : nchars - 1)];
}
return eng->positionInLigature(&si, end, x, pos, -1,
cpos == QTextLine::CursorOnCharacter);
@@ -3007,9 +3002,8 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
// character between lines is a space and we want
// to position the cursor to the left of that
// character.
- // ###### breaks with japanese for example
if (this->index < eng->lines.count() - 1)
- --maxPos;
+ maxPos = eng->previousLogicalPosition(maxPos);
pos = qMin(pos, maxPos);
return pos;
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 30f5bc1051..d8218ab613 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -183,6 +183,35 @@ static QString bulletChar(QTextListFormat::Style style)
}
}
+static QString borderStyleName(QTextFrameFormat::BorderStyle style)
+{
+ switch (style) {
+ case QTextFrameFormat::BorderStyle_None:
+ return QString::fromLatin1("none");
+ case QTextFrameFormat::BorderStyle_Dotted:
+ return QString::fromLatin1("dotted");
+ case QTextFrameFormat::BorderStyle_Dashed:
+ return QString::fromLatin1("dashed");
+ case QTextFrameFormat::BorderStyle_Solid:
+ return QString::fromLatin1("solid");
+ case QTextFrameFormat::BorderStyle_Double:
+ return QString::fromLatin1("double");
+ case QTextFrameFormat::BorderStyle_DotDash:
+ return QString::fromLatin1("dashed");
+ case QTextFrameFormat::BorderStyle_DotDotDash:
+ return QString::fromLatin1("dotted");
+ case QTextFrameFormat::BorderStyle_Groove:
+ return QString::fromLatin1("groove");
+ case QTextFrameFormat::BorderStyle_Ridge:
+ return QString::fromLatin1("ridge");
+ case QTextFrameFormat::BorderStyle_Inset:
+ return QString::fromLatin1("inset");
+ case QTextFrameFormat::BorderStyle_Outset:
+ return QString::fromLatin1("outset");
+ }
+ return QString::fromLatin1("");
+}
+
void QTextOdfWriter::writeFrame(QXmlStreamWriter &writer, const QTextFrame *frame)
{
Q_ASSERT(frame);
@@ -190,8 +219,21 @@ void QTextOdfWriter::writeFrame(QXmlStreamWriter &writer, const QTextFrame *fram
if (table) { // Start a table.
writer.writeStartElement(tableNS, QString::fromLatin1("table"));
- writer.writeEmptyElement(tableNS, QString::fromLatin1("table-column"));
- writer.writeAttribute(tableNS, QString::fromLatin1("number-columns-repeated"), QString::number(table->columns()));
+ writer.writeAttribute(tableNS, QString::fromLatin1("style-name"),
+ QString::fromLatin1("Table%1").arg(table->formatIndex()));
+ // check if column widths are set, if so add TableNS line above for all columns and link to style
+ if (m_tableFormatsWithColWidthConstraints.contains(table->formatIndex())) {
+ for (int colit = 0; colit < table->columns(); ++colit) {
+ writer.writeStartElement(tableNS, QString::fromLatin1("table-column"));
+ writer.writeAttribute(tableNS, QString::fromLatin1("style-name"),
+ QString::fromLatin1("Table%1.%2").arg(table->formatIndex()).arg(colit));
+ writer.writeEndElement();
+ }
+ } else {
+ writer.writeEmptyElement(tableNS, QString::fromLatin1("table-column"));
+ writer.writeAttribute(tableNS, QString::fromLatin1("number-columns-repeated"),
+ QString::number(table->columns()));
+ }
} else if (frame->document() && frame->document()->rootFrame() != frame) { // start a section
writer.writeStartElement(textNS, QString::fromLatin1("section"));
}
@@ -219,7 +261,15 @@ void QTextOdfWriter::writeFrame(QXmlStreamWriter &writer, const QTextFrame *fram
if (cell.rowSpan() > 1)
writer.writeAttribute(tableNS, QString::fromLatin1("number-rows-spanned"), QString::number(cell.rowSpan()));
if (cell.format().isTableCellFormat()) {
- writer.writeAttribute(tableNS, QString::fromLatin1("style-name"), QString::fromLatin1("T%1").arg(cell.tableCellFormatIndex()));
+ if (m_cellFormatsInTablesWithBorders.contains(cell.tableCellFormatIndex()) ) {
+ // writing table:style-name tag in <table:table-cell> element
+ writer.writeAttribute(tableNS, QString::fromLatin1("style-name"),
+ QString::fromLatin1("TB%1.%2").arg(table->formatIndex())
+ .arg(cell.tableCellFormatIndex()));
+ } else {
+ writer.writeAttribute(tableNS, QString::fromLatin1("style-name"),
+ QString::fromLatin1("T%1").arg(cell.tableCellFormatIndex()));
+ }
}
}
writeBlock(writer, block);
@@ -326,7 +376,10 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc
if (i < fragmentText.count()) {
if (character.unicode() == 0x2028) { // soft-return
//if (exportedIndex < i)
- writer.writeCharacters(fragmentText.mid(exportedIndex, i - exportedIndex));
+ writer.writeCharacters(fragmentText.mid(exportedIndex, i - exportedIndex));
+ // adding tab before line-break, so last line in justified paragraph
+ // will not stretch to the end
+ writer.writeEmptyElement(textNS, QString::fromLatin1("tab"));
writer.writeEmptyElement(textNS, QString::fromLatin1("line-break"));
exportedIndex = i+1;
continue;
@@ -367,7 +420,6 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
QTextImageFormat imageFormat = fragment.charFormat().toImageFormat();
writer.writeAttribute(drawNS, QString::fromLatin1("name"), imageFormat.name());
- // vvv Copy pasted mostly from Qt =================
QImage image;
QString name = imageFormat.name();
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
@@ -387,26 +439,33 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
}
}
- // ^^^ Copy pasted mostly from Qt =================
if (! image.isNull()) {
QBuffer imageBytes;
- QImageWriter imageWriter(&imageBytes, "png");
- imageWriter.write(image);
QString filename = m_strategy->createUniqueImageName();
- m_strategy->addFile(filename, QString::fromLatin1("image/png"), imageBytes.data());
-
+ int imgQuality = imageFormat.quality();
+ if (imgQuality >= 100 || imgQuality < 0 || image.hasAlphaChannel()) {
+ QImageWriter imageWriter(&imageBytes, "png");
+ imageWriter.write(image);
+ m_strategy->addFile(filename, QString::fromLatin1("image/png"), imageBytes.data());
+ } else {
+ // Write images without alpha channel as jpg with quality set by QTextImageFormat
+ QImageWriter imageWriter(&imageBytes, "jpg");
+ imageWriter.setQuality(imgQuality);
+ imageWriter.write(image);
+ m_strategy->addFile(filename, QString::fromLatin1("image/jpg"), imageBytes.data());
+ }
// get the width/height from the format.
- qreal width = (imageFormat.hasProperty(QTextFormat::ImageWidth)) ? imageFormat.width() : image.width();
+ qreal width = imageFormat.hasProperty(QTextFormat::ImageWidth)
+ ? imageFormat.width() : image.width();
writer.writeAttribute(svgNS, QString::fromLatin1("width"), pixelToPoint(width));
- qreal height = (imageFormat.hasProperty(QTextFormat::ImageHeight)) ? imageFormat.height() : image.height();
+ qreal height = imageFormat.hasProperty(QTextFormat::ImageHeight)
+ ? imageFormat.height() : image.height();
writer.writeAttribute(svgNS, QString::fromLatin1("height"), pixelToPoint(height));
-
writer.writeStartElement(drawNS, QString::fromLatin1("image"));
writer.writeAttribute(xlinkNS, QString::fromLatin1("href"), filename);
writer.writeEndElement(); // image
}
}
-
writer.writeEndElement(); // frame
}
@@ -421,7 +480,7 @@ void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, const QSet<int> &for
switch (textFormat.type()) {
case QTextFormat::CharFormat:
if (textFormat.isTableCellFormat())
- writeTableCellFormat(writer, textFormat.toTableCellFormat(), formatIndex);
+ writeTableCellFormat(writer, textFormat.toTableCellFormat(), formatIndex, allStyles);
else
writeCharacterFormat(writer, textFormat.toCharFormat(), formatIndex);
break;
@@ -432,10 +491,15 @@ void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, const QSet<int> &for
writeListFormat(writer, textFormat.toListFormat(), formatIndex);
break;
case QTextFormat::FrameFormat:
- writeFrameFormat(writer, textFormat.toFrameFormat(), formatIndex);
+ if (textFormat.isTableFormat())
+ writeTableFormat(writer, textFormat.toTableFormat(), formatIndex);
+ else
+ writeFrameFormat(writer, textFormat.toFrameFormat(), formatIndex);
break;
case QTextFormat::TableFormat:
- ;break;
+ // this case never happens, because TableFormat is a FrameFormat
+ Q_UNREACHABLE();
+ break;
}
}
@@ -449,6 +513,36 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat
writer.writeAttribute(styleNS, QString::fromLatin1("family"), QString::fromLatin1("paragraph"));
writer.writeStartElement(styleNS, QString::fromLatin1("paragraph-properties"));
+ if (format.hasProperty(QTextBlockFormat::LineHeightType)) {
+ const int blockLineHeightType = format.lineHeightType();
+ const qreal blockLineHeight = format.lineHeight();
+ QString type, value;
+ switch (blockLineHeightType) {
+ case QTextBlockFormat::SingleHeight:
+ type = QString::fromLatin1("line-height");
+ value = QString::fromLatin1("100%");
+ break;
+ case QTextBlockFormat::ProportionalHeight:
+ type = QString::fromLatin1("line-height");
+ value = QString::number(blockLineHeight) + QString::fromLatin1("%");
+ break;
+ case QTextBlockFormat::FixedHeight:
+ type = QString::fromLatin1("line-height");
+ value = pixelToPoint(qMax(qreal(0.), blockLineHeight));
+ break;
+ case QTextBlockFormat::MinimumHeight:
+ type = QString::fromLatin1("line-height-at-least");
+ value = pixelToPoint(qMax(qreal(0.), blockLineHeight));
+ break;
+ case QTextBlockFormat::LineDistanceHeight:
+ type = QString::fromLatin1("line-spacing");
+ value = pixelToPoint(qMax(qreal(0.), blockLineHeight));
+ }
+
+ if (!type.isNull())
+ writer.writeAttribute(styleNS, type, value);
+ }
+
if (format.hasProperty(QTextFormat::BlockAlignment)) {
const Qt::Alignment alignment = format.alignment() & Qt::AlignHorizontal_Mask;
QString value;
@@ -693,14 +787,108 @@ void QTextOdfWriter::writeFrameFormat(QXmlStreamWriter &writer, QTextFrameFormat
// PageBreakFlags pageBreakPolicy () const
}
-void QTextOdfWriter::writeTableCellFormat(QXmlStreamWriter &writer, QTextTableCellFormat format, int formatIndex) const
+void QTextOdfWriter::writeTableFormat(QXmlStreamWriter &writer, QTextTableFormat format, int formatIndex) const
{
+ // start writing table style element
writer.writeStartElement(styleNS, QString::fromLatin1("style"));
- writer.writeAttribute(styleNS, QString::fromLatin1("name"), QString::fromLatin1("T%1").arg(formatIndex));
+ writer.writeAttribute(styleNS, QString::fromLatin1("name"),
+ QString::fromLatin1("Table%1").arg(formatIndex));
writer.writeAttribute(styleNS, QString::fromLatin1("family"), QString::fromLatin1("table"));
writer.writeEmptyElement(styleNS, QString::fromLatin1("table-properties"));
+ if (m_tableFormatsWithBorders.contains(formatIndex)) {
+ // write border format collapsing to table style
+ writer.writeAttribute(tableNS, QString::fromLatin1("border-model"),
+ QString::fromLatin1("collapsing"));
+ }
+ const char* align = nullptr;
+ switch (format.alignment()) {
+ case Qt::AlignLeft:
+ align = "left";
+ break;
+ case Qt::AlignRight:
+ align = "right";
+ break;
+ case Qt::AlignHCenter:
+ align = "center";
+ break;
+ case Qt::AlignJustify:
+ align = "margins";
+ break;
+ }
+ if (align)
+ writer.writeAttribute(tableNS, QString::fromLatin1("align"), QString::fromLatin1(align));
+ if (format.width().rawValue()) {
+ writer.writeAttribute(styleNS, QString::fromLatin1("width"),
+ QString::number(format.width().rawValue()) + QLatin1String("pt"));
+ }
+ writer.writeEndElement();
+ // start writing table-column style element
+ if (format.columnWidthConstraints().size()) {
+ // write table-column-properties for columns with constraints
+ m_tableFormatsWithColWidthConstraints.insert(formatIndex); // needed for linking of columns to styles
+ for (int colit = 0; colit < format.columnWidthConstraints().size(); ++colit) {
+ writer.writeStartElement(styleNS, QString::fromLatin1("style"));
+ writer.writeAttribute(styleNS, QString::fromLatin1("name"),
+ QString::fromLatin1("Table%1.%2").arg(formatIndex).arg(colit));
+ writer.writeAttribute(styleNS, QString::fromLatin1("family"), QString::fromLatin1("table-column"));
+ writer.writeEmptyElement(styleNS, QString::fromLatin1("table-column-properties"));
+ QString columnWidth;
+ if (format.columnWidthConstraints().at(colit).type() == QTextLength::PercentageLength) {
+ columnWidth = QString::number(format.columnWidthConstraints().at(colit).rawValue())
+ + QLatin1String("%");
+ } else if (format.columnWidthConstraints().at(colit).type() == QTextLength::FixedLength) {
+ columnWidth = QString::number(format.columnWidthConstraints().at(colit).rawValue())
+ + QLatin1String("pt");
+ } else {
+ //!! HARD-CODING variableWidth Constraints to 100% / nr constraints
+ columnWidth = QString::number(100 / format.columnWidthConstraints().size())
+ + QLatin1String("%");
+ }
+ writer.writeAttribute(styleNS, QString::fromLatin1("column-width"), columnWidth);
+ writer.writeEndElement();
+ }
+ }
+}
+
+void QTextOdfWriter::writeTableCellFormat(QXmlStreamWriter &writer, QTextTableCellFormat format,
+ int formatIndex, QVector<QTextFormat> &styles) const
+{
+ // check for all table cells here if they are in a table with border
+ if (m_cellFormatsInTablesWithBorders.contains(formatIndex)) {
+ const QVector<int> tableIdVector = m_cellFormatsInTablesWithBorders.value(formatIndex);
+ for (const auto &tableId : tableIdVector) {
+ const auto &tmpStyle = styles.at(tableId);
+ if (tmpStyle.isTableFormat()) {
+ QTextTableFormat tableFormatTmp = tmpStyle.toTableFormat();
+ tableCellStyleElement(writer, formatIndex, format, true, tableId, tableFormatTmp);
+ } else {
+ qDebug("QTextOdfWriter::writeTableCellFormat: ERROR writing table border format");
+ }
+ }
+ }
+ tableCellStyleElement(writer, formatIndex, format, false);
+}
+void QTextOdfWriter::tableCellStyleElement(QXmlStreamWriter &writer, const int &formatIndex,
+ const QTextTableCellFormat &format,
+ bool hasBorder, int tableId,
+ const QTextTableFormat tableFormatTmp) const {
+ writer.writeStartElement(styleNS, QString::fromLatin1("style"));
+ if (hasBorder) {
+ writer.writeAttribute(styleNS, QString::fromLatin1("name"),
+ QString::fromLatin1("TB%1.%2").arg(tableId).arg(formatIndex));
+ } else {
+ writer.writeAttribute(styleNS, QString::fromLatin1("name"), QString::fromLatin1("T%1").arg(formatIndex));
+ }
+ writer.writeAttribute(styleNS, QString::fromLatin1("family"), QString::fromLatin1("table-cell"));
+ writer.writeEmptyElement(styleNS, QString::fromLatin1("table-cell-properties"));
+ if (hasBorder) {
+ writer.writeAttribute(foNS, QString::fromLatin1("border"),
+ pixelToPoint(tableFormatTmp.border()) + QLatin1String(" ")
+ + borderStyleName(tableFormatTmp.borderStyle())
+ + QLatin1String(" #000000")); //!! HARD-CODING color black
+ }
qreal padding = format.topPadding();
if (padding > 0 && padding == format.bottomPadding()
&& padding == format.leftPadding() && padding == format.rightPadding()) {
@@ -710,16 +898,19 @@ void QTextOdfWriter::writeTableCellFormat(QXmlStreamWriter &writer, QTextTableCe
if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(padding));
if (format.bottomPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-bottom"), pixelToPoint(format.bottomPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-bottom"),
+ pixelToPoint(format.bottomPadding()));
if (format.leftPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-left"), pixelToPoint(format.leftPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-left"),
+ pixelToPoint(format.leftPadding()));
if (format.rightPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-right"), pixelToPoint(format.rightPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-right"),
+ pixelToPoint(format.rightPadding()));
}
if (format.hasProperty(QTextFormat::TextVerticalAlignment)) {
QString pos;
- switch (format.verticalAlignment()) {
+ switch (format.verticalAlignment()) { // TODO - review: doesn't handle all cases
case QTextCharFormat::AlignMiddle:
pos = QString::fromLatin1("middle"); break;
case QTextCharFormat::AlignTop:
@@ -736,8 +927,6 @@ void QTextOdfWriter::writeTableCellFormat(QXmlStreamWriter &writer, QTextTableCe
// ODF just search for style-table-cell-properties-attlist)
// QTextFormat::BackgroundImageUrl
// format.background
- // QTextFormat::FrameBorder
-
writer.writeEndElement(); // style
}
@@ -815,8 +1004,28 @@ bool QTextOdfWriter::writeAll()
const QList<int> copy = formats.toList();
for (auto index : copy) {
QTextObject *object = m_document->objectForFormat(allFormats[index]);
- if (object)
+ if (object) {
formats << object->formatIndex();
+ if (auto *tableobject = qobject_cast<QTextTable *>(object)) {
+ if (tableobject->format().borderStyle()) {
+ int tableID = tableobject->formatIndex();
+ m_tableFormatsWithBorders.insert(tableID);
+ // loop through all rows and cols of table and store cell IDs,
+ // create Hash with cell ID as Key and table IDs as Vector
+ for (int rowindex = 0; rowindex < tableobject->rows(); ++rowindex) {
+ for (int colindex = 0; colindex < tableobject->columns(); ++colindex) {
+ const int cellFormatID = tableobject->cellAt(rowindex, colindex).tableCellFormatIndex();
+ QVector<int> tableIdsTmp;
+ if (m_cellFormatsInTablesWithBorders.contains(cellFormatID))
+ tableIdsTmp = m_cellFormatsInTablesWithBorders.value(cellFormatID);
+ if (!tableIdsTmp.contains(tableID))
+ tableIdsTmp.append(tableID);
+ m_cellFormatsInTablesWithBorders.insert(cellFormatID, tableIdsTmp);
+ }
+ }
+ }
+ }
+ }
}
writeFormats(writer, formats);
diff --git a/src/gui/text/qtextodfwriter_p.h b/src/gui/text/qtextodfwriter_p.h
index d0dd7d2b5c..98a6fdfa96 100644
--- a/src/gui/text/qtextodfwriter_p.h
+++ b/src/gui/text/qtextodfwriter_p.h
@@ -56,8 +56,10 @@
//
#include <QtCore/QXmlStreamWriter>
+#include <QtCore/qhash.h>
#include <QtCore/qset.h>
#include <QtCore/qstack.h>
+#include <QtCore/qvector.h>
#include "qtextdocument_p.h"
#include "qtextdocumentwriter.h"
@@ -94,11 +96,21 @@ public:
void writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFormat format, int formatIndex) const;
void writeListFormat(QXmlStreamWriter &writer, QTextListFormat format, int formatIndex) const;
void writeFrameFormat(QXmlStreamWriter &writer, QTextFrameFormat format, int formatIndex) const;
- void writeTableCellFormat(QXmlStreamWriter &writer, QTextTableCellFormat format, int formatIndex) const;
+ void writeTableFormat(QXmlStreamWriter &writer, QTextTableFormat format, int formatIndex) const;
+ void writeTableCellFormat(QXmlStreamWriter &writer, QTextTableCellFormat format, int formatIndex,
+ QVector<QTextFormat> &styles) const;
void writeFrame(QXmlStreamWriter &writer, const QTextFrame *frame);
void writeInlineCharacter(QXmlStreamWriter &writer, const QTextFragment &fragment) const;
const QString officeNS, textNS, styleNS, foNS, tableNS, drawNS, xlinkNS, svgNS;
+ const int defaultImageResolution = 11811; // 11811 dots per meter = (about) 300 dpi
+
+protected:
+ void tableCellStyleElement(QXmlStreamWriter &writer, const int &formatIndex,
+ const QTextTableCellFormat &format,
+ bool hasBorder, int tableId = 0,
+ const QTextTableFormat tableFormatTmp = QTextTableFormat()) const;
+
private:
const QTextDocument *m_document;
QIODevice *m_device;
@@ -108,6 +120,10 @@ private:
bool m_createArchive;
QStack<QTextList *> m_listStack;
+
+ QHash<int, QVector<int>> m_cellFormatsInTablesWithBorders;
+ QSet<int> m_tableFormatsWithBorders;
+ mutable QSet<int> m_tableFormatsWithColWidthConstraints;
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp
index a3fa0e7351..2c2c05567f 100644
--- a/src/gui/text/qtextoption.cpp
+++ b/src/gui/text/qtextoption.cpp
@@ -307,7 +307,8 @@ QList<QTextOption::Tab> QTextOption::tabs() const
\value IncludeTrailingSpaces When this option is set, QTextLine::naturalTextWidth() and naturalTextRect() will
return a value that includes the width of trailing spaces in the text; otherwise
this width is excluded.
- \value ShowTabsAndSpaces Visualize spaces with little dots, and tabs with little arrows.
+ \value ShowTabsAndSpaces Visualize spaces with little dots, and tabs with little arrows. Non-breaking spaces are
+ shown differently to breaking spaces.
\value ShowLineAndParagraphSeparators Visualize line and paragraph separators with appropriate symbol characters.
\value ShowDocumentTerminator Visualize the end of the document with a section sign. This enum value was added
in Qt 5.7.
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp
index b68c36fd9e..fc7fbcac12 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -391,7 +391,6 @@ struct CentralFileHeader
uchar internal_file_attributes[2];
uchar external_file_attributes[4];
uchar offset_local_header[4];
- LocalFileHeader toLocalHeader() const;
};
Q_DECLARE_TYPEINFO(CentralFileHeader, Q_PRIMITIVE_TYPE);
@@ -541,19 +540,19 @@ public:
void addEntry(EntryType type, const QString &fileName, const QByteArray &contents);
};
-LocalFileHeader CentralFileHeader::toLocalHeader() const
+static LocalFileHeader toLocalHeader(const CentralFileHeader &ch)
{
LocalFileHeader h;
writeUInt(h.signature, 0x04034b50);
- copyUShort(h.version_needed, version_needed);
- copyUShort(h.general_purpose_bits, general_purpose_bits);
- copyUShort(h.compression_method, compression_method);
- copyUInt(h.last_mod_file, last_mod_file);
- copyUInt(h.crc_32, crc_32);
- copyUInt(h.compressed_size, compressed_size);
- copyUInt(h.uncompressed_size, uncompressed_size);
- copyUShort(h.file_name_length, file_name_length);
- copyUShort(h.extra_field_length, extra_field_length);
+ copyUShort(h.version_needed, ch.version_needed);
+ copyUShort(h.general_purpose_bits, ch.general_purpose_bits);
+ copyUShort(h.compression_method, ch.compression_method);
+ copyUInt(h.last_mod_file, ch.last_mod_file);
+ copyUInt(h.crc_32, ch.crc_32);
+ copyUInt(h.compressed_size, ch.compressed_size);
+ copyUInt(h.uncompressed_size, ch.uncompressed_size);
+ copyUShort(h.file_name_length, ch.file_name_length);
+ copyUShort(h.extra_field_length, ch.extra_field_length);
return h;
}
@@ -751,7 +750,7 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const
fileHeaders.append(header);
- LocalFileHeader h = header.h.toLocalHeader();
+ LocalFileHeader h = toLocalHeader(header.h);
device->write((const char *)&h, sizeof(LocalFileHeader));
device->write(header.file_name);
device->write(data);
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index dfd190ddd0..de9d087c21 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -141,6 +141,10 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler)
same argument, and it will try to open the URL using the
appropriate mechanism for the user's desktop environment.
+ Combined with platform specific settings, the schemes registered by the
+ openUrl() function can also be exposed to other applications, opening up
+ for application deep linking or a very basic URL-based IPC mechanism.
+
\note Since Qt 5, storageLocation() and displayName() are replaced by functionality
provided by the QStandardPaths class.
@@ -245,6 +249,24 @@ bool QDesktopServices::openUrl(const QUrl &url)
The provided method must be implemented as a slot that only accepts a single QUrl
argument.
+ To use this function for receiving data from other apps on iOS you also need to
+ add the custom scheme to the \c CFBundleURLSchemes list in your Info.plist file:
+
+ \code
+ <key>CFBundleURLTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>myapp</string>
+ </array>
+ </dict>
+ </array>
+ \endcode
+
+ For more information, see the Apple Developer Documentation for
+ \l{https://developer.apple.com/documentation/uikit/core_app/allowing_apps_and_websites_to_link_to_your_content/communicating_with_other_apps_using_custom_urls?language=objc}{Communicating with Other Apps Using Custom URLs}.
+
If setUrlHandler() is used to set a new handler for a scheme which already
has a handler, the existing handler is simply replaced with the new one.
Since QDesktopServices does not take ownership of handlers, no objects are
diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp
new file mode 100644
index 0000000000..7eda4c46fb
--- /dev/null
+++ b/src/gui/util/qktxhandler.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qktxhandler_p.h"
+#include "qtexturefiledata_p.h"
+#include <QtEndian>
+#include <QSize>
+
+//#define KTX_DEBUG
+#ifdef KTX_DEBUG
+#include <QDebug>
+#include <QMetaEnum>
+#include <QOpenGLTexture>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#define KTX_IDENTIFIER_LENGTH 12
+static const char ktxIdentifier[KTX_IDENTIFIER_LENGTH] = { '\xAB', 'K', 'T', 'X', ' ', '1', '1', '\xBB', '\r', '\n', '\x1A', '\n' };
+static const quint32 platformEndianIdentifier = 0x04030201;
+static const quint32 inversePlatformEndianIdentifier = 0x01020304;
+
+struct KTXHeader {
+ quint8 identifier[KTX_IDENTIFIER_LENGTH]; // Must match ktxIdentifier
+ quint32 endianness; // Either platformEndianIdentifier or inversePlatformEndianIdentifier, other values not allowed.
+ quint32 glType;
+ quint32 glTypeSize;
+ quint32 glFormat;
+ quint32 glInternalFormat;
+ quint32 glBaseInternalFormat;
+ quint32 pixelWidth;
+ quint32 pixelHeight;
+ quint32 pixelDepth;
+ quint32 numberOfArrayElements;
+ quint32 numberOfFaces;
+ quint32 numberOfMipmapLevels;
+ quint32 bytesOfKeyValueData;
+};
+
+static const quint32 headerSize = sizeof(KTXHeader);
+
+// Currently unused, declared for future reference
+struct KTXKeyValuePairItem {
+ quint32 keyAndValueByteSize;
+ /*
+ quint8 keyAndValue[keyAndValueByteSize];
+ quint8 valuePadding[3 - ((keyAndValueByteSize + 3) % 4)];
+ */
+};
+
+struct KTXMipmapLevel {
+ quint32 imageSize;
+ /*
+ for each array_element in numberOfArrayElements*
+ for each face in numberOfFaces
+ for each z_slice in pixelDepth*
+ for each row or row_of_blocks in pixelHeight*
+ for each pixel or block_of_pixels in pixelWidth
+ Byte data[format-specific-number-of-bytes]**
+ end
+ end
+ end
+ Byte cubePadding[0-3]
+ end
+ end
+ quint8 mipPadding[3 - ((imageSize + 3) % 4)]
+ */
+};
+
+bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
+{
+ Q_UNUSED(suffix)
+
+ return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0);
+}
+
+QTextureFileData QKtxHandler::read()
+{
+ if (!device())
+ return QTextureFileData();
+
+ QByteArray buf = device()->readAll();
+ const quint32 dataSize = quint32(buf.size());
+ if (dataSize < headerSize || !canRead(QByteArray(), buf)) {
+ qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.constData());
+ if (!checkHeader(*header)) {
+ qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ QTextureFileData texData;
+ texData.setData(buf);
+
+ texData.setSize(QSize(decode(header->pixelWidth), decode(header->pixelHeight)));
+ texData.setGLFormat(decode(header->glFormat));
+ texData.setGLInternalFormat(decode(header->glInternalFormat));
+ texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat));
+
+ texData.setNumLevels(decode(header->numberOfMipmapLevels));
+ quint32 offset = headerSize + decode(header->bytesOfKeyValueData);
+ const int maxLevels = qMin(texData.numLevels(), 32); // Cap iterations in case of corrupt file.
+ for (int i = 0; i < maxLevels; i++) {
+ if (offset + sizeof(KTXMipmapLevel) > dataSize) // Corrupt file; avoid oob read
+ break;
+ const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel *>(buf.constData() + offset);
+ quint32 levelLen = decode(level->imageSize);
+ texData.setDataOffset(offset + sizeof(KTXMipmapLevel::imageSize), i);
+ texData.setDataLength(levelLen, i);
+ offset += sizeof(KTXMipmapLevel::imageSize) + levelLen + (3 - ((levelLen + 3) % 4));
+ }
+
+ if (!texData.isValid()) {
+ qCDebug(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ texData.setLogName(logName());
+
+#ifdef KTX_DEBUG
+ qDebug() << "KTX file handler read" << texData;
+#endif
+
+ return texData;
+}
+
+bool QKtxHandler::checkHeader(const KTXHeader &header)
+{
+ if (header.endianness != platformEndianIdentifier && header.endianness != inversePlatformEndianIdentifier)
+ return false;
+ inverseEndian = (header.endianness == inversePlatformEndianIdentifier);
+#ifdef KTX_DEBUG
+ QMetaEnum tfme = QMetaEnum::fromType<QOpenGLTexture::TextureFormat>();
+ QMetaEnum ptme = QMetaEnum::fromType<QOpenGLTexture::PixelType>();
+ qDebug("Header of %s:", logName().constData());
+ qDebug(" glType: 0x%x (%s)", decode(header.glType), ptme.valueToKey(decode(header.glType)));
+ qDebug(" glTypeSize: %u", decode(header.glTypeSize));
+ qDebug(" glFormat: 0x%x (%s)", decode(header.glFormat), tfme.valueToKey(decode(header.glFormat)));
+ qDebug(" glInternalFormat: 0x%x (%s)", decode(header.glInternalFormat), tfme.valueToKey(decode(header.glInternalFormat)));
+ qDebug(" glBaseInternalFormat: 0x%x (%s)", decode(header.glBaseInternalFormat), tfme.valueToKey(decode(header.glBaseInternalFormat)));
+ qDebug(" pixelWidth: %u", decode(header.pixelWidth));
+ qDebug(" pixelHeight: %u", decode(header.pixelHeight));
+ qDebug(" pixelDepth: %u", decode(header.pixelDepth));
+ qDebug(" numberOfArrayElements: %u", decode(header.numberOfArrayElements));
+ qDebug(" numberOfFaces: %u", decode(header.numberOfFaces));
+ qDebug(" numberOfMipmapLevels: %u", decode(header.numberOfMipmapLevels));
+ qDebug(" bytesOfKeyValueData: %u", decode(header.bytesOfKeyValueData));
+#endif
+ return ((decode(header.glType) == 0) &&
+ (decode(header.glFormat) == 0) &&
+ (decode(header.pixelDepth) == 0) &&
+ (decode(header.numberOfFaces) == 1));
+}
+
+quint32 QKtxHandler::decode(quint32 val)
+{
+ return inverseEndian ? qbswap<quint32>(val) : val;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qktxhandler_p.h b/src/gui/util/qktxhandler_p.h
new file mode 100644
index 0000000000..19f7b0e79a
--- /dev/null
+++ b/src/gui/util/qktxhandler_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKTXHANDLER_H
+#define QKTXHANDLER_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 "qtexturefilehandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+struct KTXHeader;
+
+class QKtxHandler : public QTextureFileHandler
+{
+public:
+ using QTextureFileHandler::QTextureFileHandler;
+
+ static bool canRead(const QByteArray &suffix, const QByteArray &block);
+
+ QTextureFileData read() override;
+
+private:
+ bool checkHeader(const KTXHeader &header);
+ quint32 decode(quint32 val);
+
+ bool inverseEndian = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKTXHANDLER_H
diff --git a/src/gui/util/qpkmhandler.cpp b/src/gui/util/qpkmhandler.cpp
new file mode 100644
index 0000000000..e0c3b75efe
--- /dev/null
+++ b/src/gui/util/qpkmhandler.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpkmhandler_p.h"
+#include "qtexturefiledata_p.h"
+
+#include <QFile>
+#include <QDebug>
+#include <QSize>
+#include <qendian.h>
+
+//#define ETC_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+static const int headerSize = 16;
+
+struct PkmType
+{
+ quint32 glFormat;
+ quint32 bytesPerBlock;
+};
+
+static PkmType typeMap[5] = {
+ { 0x8D64, 8 }, // GL_ETC1_RGB8_OES
+ { 0x9274, 8 }, // GL_COMPRESSED_RGB8_ETC2
+ { 0, 0 }, // unused (obsolete)
+ { 0x9278, 16}, // GL_COMPRESSED_RGBA8_ETC2_EAC
+ { 0x9276, 8 } // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+};
+
+bool QPkmHandler::canRead(const QByteArray &suffix, const QByteArray &block)
+{
+ Q_UNUSED(suffix)
+
+ return block.startsWith("PKM ");
+}
+
+QTextureFileData QPkmHandler::read()
+{
+ QTextureFileData texData;
+
+ if (!device())
+ return texData;
+
+ QByteArray fileData = device()->readAll();
+ if (fileData.size() < headerSize || !canRead(QByteArray(), fileData)) {
+ qCDebug(lcQtGuiTextureIO, "Invalid PKM file %s", logName().constData());
+ return QTextureFileData();
+ }
+ texData.setData(fileData);
+
+ const char *rawData = fileData.constData();
+
+ // ignore version (rawData + 4 & 5)
+
+ // texture type
+ quint16 type = qFromBigEndian<quint16>(rawData + 6);
+ if (type >= sizeof(typeMap)/sizeof(typeMap[0])) {
+ qCDebug(lcQtGuiTextureIO, "Unknown compression format in PKM file %s", logName().constData());
+ return QTextureFileData();
+ }
+ texData.setGLFormat(0); // 0 for compressed textures
+ texData.setGLInternalFormat(typeMap[type].glFormat);
+ //### setBaseInternalFormat
+
+ // texture size
+ texData.setNumLevels(1);
+ const int bpb = typeMap[type].bytesPerBlock;
+ QSize paddedSize(qFromBigEndian<quint16>(rawData + 8), qFromBigEndian<quint16>(rawData + 10));
+ texData.setDataLength((paddedSize.width() / 4) * (paddedSize.height() / 4) * bpb);
+ QSize texSize(qFromBigEndian<quint16>(rawData + 12), qFromBigEndian<quint16>(rawData + 14));
+ texData.setSize(texSize);
+
+ texData.setDataOffset(headerSize);
+
+ if (!texData.isValid()) {
+ qCDebug(lcQtGuiTextureIO, "Invalid values in header of PKM file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ texData.setLogName(logName());
+
+#ifdef ETC_DEBUG
+ qDebug() << "PKM file handler read" << texData;
+#endif
+ return texData;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qpkmhandler_p.h b/src/gui/util/qpkmhandler_p.h
new file mode 100644
index 0000000000..2f7618bc53
--- /dev/null
+++ b/src/gui/util/qpkmhandler_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPKMHANDLER_H
+#define QPKMHANDLER_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 "qtexturefilehandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QPkmHandler : public QTextureFileHandler
+{
+public:
+ using QTextureFileHandler::QTextureFileHandler;
+
+ static bool canRead(const QByteArray &suffix, const QByteArray &block);
+
+ QTextureFileData read() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPKMHANDLER_H
diff --git a/src/gui/util/qshadergraphloader.cpp b/src/gui/util/qshadergraphloader.cpp
index 8d92c73a5a..99a9f7869e 100644
--- a/src/gui/util/qshadergraphloader.cpp
+++ b/src/gui/util/qshadergraphloader.cpp
@@ -39,6 +39,8 @@
#include "qshadergraphloader_p.h"
+#include "qshadernodesloader_p.h"
+
#include <QtCore/qdebug.h>
#include <QtCore/qiodevice.h>
#include <QtCore/qjsonarray.h>
@@ -129,6 +131,19 @@ void QShaderGraphLoader::load()
bool hasError = false;
+ const auto prototypesValue = root.value(QStringLiteral("prototypes"));
+ if (!prototypesValue.isUndefined()) {
+ if (prototypesValue.isObject()) {
+ QShaderNodesLoader loader;
+ loader.load(prototypesValue.toObject());
+ m_prototypes.unite(loader.nodes());
+ } else {
+ qWarning() << "Invalid prototypes property, should be an object";
+ m_status = Error;
+ return;
+ }
+ }
+
const auto nodes = nodesValue.toArray();
for (const auto &nodeValue : nodes) {
if (!nodeValue.isObject()) {
diff --git a/src/gui/util/qshadernodesloader.cpp b/src/gui/util/qshadernodesloader.cpp
index db34b6d44d..692653ee44 100644
--- a/src/gui/util/qshadernodesloader.cpp
+++ b/src/gui/util/qshadernodesloader.cpp
@@ -99,11 +99,15 @@ void QShaderNodesLoader::load()
}
const auto root = document.object();
+ load(root);
+}
+void QShaderNodesLoader::load(const QJsonObject &prototypesObject)
+{
bool hasError = false;
- for (const auto &property : root.keys()) {
- const auto nodeValue = root.value(property);
+ for (const auto &property : prototypesObject.keys()) {
+ const auto nodeValue = prototypesObject.value(property);
if (!nodeValue.isObject()) {
qWarning() << "Invalid node found";
hasError = true;
diff --git a/src/gui/util/qshadernodesloader_p.h b/src/gui/util/qshadernodesloader_p.h
index 2696e958b6..0bec871857 100644
--- a/src/gui/util/qshadernodesloader_p.h
+++ b/src/gui/util/qshadernodesloader_p.h
@@ -78,6 +78,7 @@ public:
Q_GUI_EXPORT void setDevice(QIODevice *device) Q_DECL_NOTHROW;
Q_GUI_EXPORT void load();
+ Q_GUI_EXPORT void load(const QJsonObject &prototypesObject);
private:
Status m_status;
diff --git a/src/gui/util/qtexturefiledata.cpp b/src/gui/util/qtexturefiledata.cpp
new file mode 100644
index 0000000000..ebf46f8e4e
--- /dev/null
+++ b/src/gui/util/qtexturefiledata.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtexturefiledata_p.h"
+#include <QMetaEnum>
+#include <QSize>
+#if QT_CONFIG(opengl)
+#include <QOpenGLTexture>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcQtGuiTextureIO, "qt.gui.textureio");
+
+class QTextureFileDataPrivate : public QSharedData
+{
+public:
+ QTextureFileDataPrivate()
+ {
+ }
+
+ QTextureFileDataPrivate(const QTextureFileDataPrivate &other)
+ : QSharedData(other),
+ logName(other.logName),
+ data(other.data),
+ offsets(other.offsets),
+ lengths(other.lengths),
+ size(other.size),
+ format(other.format)
+ {
+ }
+
+ ~QTextureFileDataPrivate()
+ {
+ }
+
+ void ensureLevels(int num, bool force = false)
+ {
+ const int newSize = force ? num : qMax(offsets.size(), num);
+ offsets.resize(newSize);
+ lengths.resize(newSize);
+ }
+
+ QByteArray logName;
+ QByteArray data;
+ QVector<int> offsets;
+ QVector<int> lengths;
+ QSize size;
+ quint32 format = 0;
+ quint32 internalFormat = 0;
+ quint32 baseInternalFormat = 0;
+};
+
+
+
+QTextureFileData::QTextureFileData()
+{
+}
+
+QTextureFileData::QTextureFileData(const QTextureFileData &other)
+ : d(other.d)
+{
+}
+
+QTextureFileData &QTextureFileData::operator=(const QTextureFileData &other)
+{
+ d = other.d;
+ return *this;
+}
+
+QTextureFileData::~QTextureFileData()
+{
+}
+
+bool QTextureFileData::isNull() const
+{
+ return !d;
+}
+
+bool QTextureFileData::isValid() const
+{
+ if (!d)
+ return false;
+
+ if (d->data.isEmpty() || d->size.isEmpty() || (!d->format && !d->internalFormat))
+ return false;
+
+ const int numChunks = d->offsets.size();
+ if (numChunks == 0 || (d->lengths.size() != numChunks))
+ return false;
+
+ const qint64 sz = d->data.size();
+ for (int i = 0; i < numChunks; i++) {
+ qint64 offi = d->offsets.at(i);
+ qint64 leni = d->lengths.at(i);
+ if (offi < 0 || offi >= sz || leni <= 0 || (offi + leni > sz))
+ return false;
+ }
+ return true;
+}
+
+void QTextureFileData::clear()
+{
+ d = nullptr;
+}
+
+QByteArray QTextureFileData::data() const
+{
+ return d ? d->data : QByteArray();
+}
+
+void QTextureFileData::setData(const QByteArray &data)
+{
+ if (!d.constData()) //### uh think about this design, this is the only way to create; should be constructor instead at least
+ d = new QTextureFileDataPrivate;
+
+ d->data = data;
+}
+
+int QTextureFileData::dataOffset(int level) const
+{
+ return (d && d->offsets.size() > level) ? d->offsets.at(level) : 0;
+}
+
+void QTextureFileData::setDataOffset(int offset, int level)
+{
+ if (d.constData() && level >= 0) {
+ d->ensureLevels(level + 1);
+ d->offsets[level] = offset;
+ }
+}
+
+int QTextureFileData::dataLength(int level) const
+{
+ return (d && d->lengths.size() > level) ? d->lengths.at(level) : 0;
+}
+
+void QTextureFileData::setDataLength(int length, int level)
+{
+ if (d.constData() && level >= 0) {
+ d->ensureLevels(level + 1);
+ d->lengths[level] = length;
+ }
+}
+
+int QTextureFileData::numLevels() const
+{
+ return d ? d->offsets.size() : 0;
+}
+
+void QTextureFileData::setNumLevels(int num)
+{
+ if (d && num >= 0)
+ d->ensureLevels(num, true);
+}
+
+QSize QTextureFileData::size() const
+{
+ return d ? d->size : QSize();
+}
+
+void QTextureFileData::setSize(const QSize &size)
+{
+ if (d.constData())
+ d->size = size;
+}
+
+quint32 QTextureFileData::glFormat() const
+{
+ return d ? d->format : 0;
+}
+
+void QTextureFileData::setGLFormat(quint32 format)
+{
+ if (d.constData())
+ d->format = format;
+}
+
+quint32 QTextureFileData::glInternalFormat() const
+{
+ return d ? d->internalFormat : 0;
+}
+
+void QTextureFileData::setGLInternalFormat(quint32 format)
+{
+ if (d.constData())
+ d->internalFormat = format;
+}
+
+quint32 QTextureFileData::glBaseInternalFormat() const
+{
+ return d ? d->baseInternalFormat : 0;
+}
+
+void QTextureFileData::setGLBaseInternalFormat(quint32 format)
+{
+ if (d.constData())
+ d->baseInternalFormat = format;
+}
+
+QByteArray QTextureFileData::logName() const
+{
+ return d ? d->logName : QByteArray();
+}
+
+void QTextureFileData::setLogName(const QByteArray &name)
+{
+ if (d.constData())
+ d->logName = name;
+}
+
+static QByteArray glFormatName(quint32 fmt)
+{
+ const char *id = 0;
+#if QT_CONFIG(opengl)
+ id = QMetaEnum::fromType<QOpenGLTexture::TextureFormat>().valueToKey(fmt);
+#endif
+ QByteArray res(id ? id : "(?)");
+ res += " [0x" + QByteArray::number(fmt, 16).rightJustified(4, '0') + ']';
+ return res;
+}
+
+QDebug operator<<(QDebug dbg, const QTextureFileData &d)
+{
+ QDebugStateSaver saver(dbg);
+
+ dbg.nospace() << "QTextureFileData(";
+ if (!d.isNull()) {
+ dbg.space() << d.logName() << d.size();
+ dbg << "glFormat:" << glFormatName(d.glFormat());
+ dbg << "glInternalFormat:" << glFormatName(d.glInternalFormat());
+ dbg << "glBaseInternalFormat:" << glFormatName(d.glBaseInternalFormat());
+ dbg.nospace() << "Levels: " << d.numLevels();
+ if (!d.isValid())
+ dbg << " {Invalid}";
+ dbg << ")";
+ } else {
+ dbg << "null)";
+ }
+
+ return dbg;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qtexturefiledata_p.h b/src/gui/util/qtexturefiledata_p.h
new file mode 100644
index 0000000000..2df23de33c
--- /dev/null
+++ b/src/gui/util/qtexturefiledata_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEXTUREFILEDATA_P_H
+#define QTEXTUREFILEDATA_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 <QtGui/qtguiglobal.h>
+#include <QSharedDataPointer>
+#include <QLoggingCategory>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcQtGuiTextureIO)
+
+class QTextureFileDataPrivate;
+
+class Q_GUI_EXPORT QTextureFileData
+{
+public:
+ QTextureFileData();
+ QTextureFileData(const QTextureFileData &other);
+ QTextureFileData &operator=(const QTextureFileData &other);
+ ~QTextureFileData();
+
+ bool isNull() const;
+ bool isValid() const;
+
+ void clear();
+
+ QByteArray data() const;
+ void setData(const QByteArray &data);
+
+ int dataOffset(int level = 0) const;
+ void setDataOffset(int offset, int level = 0);
+
+ int dataLength(int level = 0) const;
+ void setDataLength(int length, int level = 0);
+
+ int numLevels() const;
+ void setNumLevels(int num);
+
+ QSize size() const;
+ void setSize(const QSize &size);
+
+ quint32 glFormat() const;
+ void setGLFormat(quint32 format);
+
+ quint32 glInternalFormat() const;
+ void setGLInternalFormat(quint32 format);
+
+ quint32 glBaseInternalFormat() const;
+ void setGLBaseInternalFormat(quint32 format);
+
+ QByteArray logName() const;
+ void setLogName(const QByteArray &name);
+
+private:
+ QSharedDataPointer<QTextureFileDataPrivate> d;
+};
+
+Q_DECLARE_TYPEINFO(QTextureFileData, Q_MOVABLE_TYPE);
+
+Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QTextureFileData &d);
+
+QT_END_NAMESPACE
+
+#endif // QABSTRACTLAYOUTSTYLEINFO_P_H
diff --git a/src/gui/util/qtexturefilehandler_p.h b/src/gui/util/qtexturefilehandler_p.h
new file mode 100644
index 0000000000..b808d3e7db
--- /dev/null
+++ b/src/gui/util/qtexturefilehandler_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEXTUREFILEHANDLER_P_H
+#define QTEXTUREFILEHANDLER_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 "qtexturefiledata_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTextureFileHandler
+{
+public:
+ QTextureFileHandler(QIODevice *device, const QByteArray &logName = QByteArray())
+ : m_device(device)
+ {
+ m_logName = !logName.isEmpty() ? logName : QByteArrayLiteral("(unknown)");
+ }
+ virtual ~QTextureFileHandler() {}
+
+ virtual QTextureFileData read() = 0;
+ QIODevice *device() const { return m_device; }
+ QByteArray logName() const { return m_logName; }
+
+private:
+ QIODevice *m_device = nullptr;
+ QByteArray m_logName;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTEXTUREFILEHANDLER_P_H
diff --git a/src/gui/util/qtexturefilereader.cpp b/src/gui/util/qtexturefilereader.cpp
new file mode 100644
index 0000000000..5d4bd600e0
--- /dev/null
+++ b/src/gui/util/qtexturefilereader.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtexturefilereader_p.h"
+
+#include "qpkmhandler_p.h"
+#include "qktxhandler_p.h"
+
+#include <QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+QTextureFileReader::QTextureFileReader(QIODevice *device, const QString &fileName)
+ : m_device(device), m_fileName(fileName)
+{
+}
+
+QTextureFileReader::~QTextureFileReader()
+{
+ delete m_handler;
+}
+
+QTextureFileData QTextureFileReader::read()
+{
+ if (!canRead())
+ return QTextureFileData();
+ return m_handler->read();
+}
+
+bool QTextureFileReader::canRead()
+{
+ if (!checked) {
+ checked = true;
+ if (!init())
+ return false;
+
+ QByteArray headerBlock = m_device->peek(64);
+ QFileInfo fi(m_fileName);
+ QByteArray suffix = fi.suffix().toLower().toLatin1();
+ QByteArray logName = fi.fileName().toUtf8();
+
+ // Currently the handlers are hardcoded; later maybe a list of plugins
+ if (QPkmHandler::canRead(suffix, headerBlock)) {
+ m_handler = new QPkmHandler(m_device, logName);
+ } else if (QKtxHandler::canRead(suffix, headerBlock)) {
+ m_handler = new QKtxHandler(m_device, logName);
+ }
+ // else if OtherHandler::canRead() ...etc.
+ }
+ return (m_handler != nullptr);
+}
+
+QList<QByteArray> QTextureFileReader::supportedFileFormats()
+{
+ // Hardcoded for now
+ return {QByteArrayLiteral("pkm"), QByteArrayLiteral("ktx")};
+}
+
+bool QTextureFileReader::init()
+{
+ if (!m_device)
+ return false;
+ return m_device->isReadable();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qtexturefilereader_p.h b/src/gui/util/qtexturefilereader_p.h
new file mode 100644
index 0000000000..2ec0b0cc49
--- /dev/null
+++ b/src/gui/util/qtexturefilereader_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEXTUREFILEREADER_H
+#define QTEXTUREFILEREADER_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 "qtexturefiledata_p.h"
+#include <QString>
+#include <QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+class QTextureFileHandler;
+
+class Q_GUI_EXPORT QTextureFileReader
+{
+public:
+ QTextureFileReader(QIODevice *device, const QString &fileName = QString()); //### drop this logname thing?
+ ~QTextureFileReader();
+
+ bool canRead();
+ QTextureFileData read();
+
+ // TBD access function to params
+ // TBD ask for identified fmt
+
+ static QList<QByteArray> supportedFileFormats();
+
+private:
+ bool init();
+ QIODevice *m_device = nullptr;
+ QString m_fileName;
+ QTextureFileHandler *m_handler = nullptr;
+ bool checked = false;
+};
+
+QT_END_NAMESPACE
+
+
+#endif // QTEXTUREFILEREADER_H
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index 7982ad967e..2237b016e9 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -411,13 +411,15 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
if (buff.isEmpty())
return Intermediate;
- if (b >= 0 && buff.startsWith('-'))
+ const bool startsWithMinus(buff[0] == '-');
+ if (b >= 0 && startsWithMinus)
return Invalid;
- if (t < 0 && buff.startsWith('+'))
+ const bool startsWithPlus(buff[0] == '+');
+ if (t < 0 && startsWithPlus)
return Invalid;
- if (buff.size() == 1 && (buff.at(0) == '+' || buff.at(0) == '-'))
+ if (buff.size() == 1 && (startsWithPlus || startsWithMinus))
return Intermediate;
bool ok;
@@ -433,7 +435,15 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
if (entered >= 0) {
// the -entered < b condition is necessary to allow people to type
// the minus last (e.g. for right-to-left languages)
- return (entered > t && -entered < b) ? Invalid : Intermediate;
+ // The buffLength > tLength condition validates values consisting
+ // of a number of digits equal to or less than the max value as intermediate.
+
+ int buffLength = buff.size();
+ if (startsWithPlus)
+ buffLength--;
+ const int tLength = t != 0 ? static_cast<int>(std::log10(qAbs(t))) + 1 : 1;
+
+ return (entered > t && -entered < b && buffLength > tLength) ? Invalid : Intermediate;
} else {
return (entered < b) ? Invalid : Intermediate;
}
@@ -624,10 +634,10 @@ QDoubleValidator::~QDoubleValidator()
that is within the valid range and is in the correct format.
Returns \l Intermediate if \a input contains a double that is
- outside the range or is in the wrong format; e.g. with too many
- digits after the decimal point or is empty.
+ outside the range or is in the wrong format; e.g. is empty.
- Returns \l Invalid if the \a input is not a double.
+ Returns \l Invalid if the \a input is not a double or with too many
+ digits after the decimal point.
Note: If the valid range consists of just positive doubles (e.g. 0.0 to 100.0)
and \a input is a negative double then \l Invalid is returned. If notation()
@@ -690,8 +700,16 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
if (notation == QDoubleValidator::StandardNotation) {
double max = qMax(qAbs(q->b), qAbs(q->t));
if (max < LLONG_MAX) {
- qlonglong n = pow10(numDigits(qlonglong(max))) - 1;
- if (qAbs(i) > n)
+ qlonglong n = pow10(numDigits(qlonglong(max)));
+ // In order to get the highest possible number in the intermediate
+ // range we need to get 10 to the power of the number of digits
+ // after the decimal's and subtract that from the top number.
+ //
+ // For example, where q->dec == 2 and with a range of 0.0 - 9.0
+ // then the minimum possible number is 0.00 and the maximum
+ // possible is 9.99. Therefore 9.999 and 10.0 should be seen as
+ // invalid.
+ if (qAbs(i) > (n - std::pow(10, -q->dec)))
return QValidator::Invalid;
}
}
@@ -1061,7 +1079,7 @@ void QRegularExpressionValidatorPrivate::setRegularExpression(const QRegularExpr
if (origRe != re) {
usedRe = origRe = re; // copies also the pattern options
- usedRe.setPattern(QLatin1String("\\A(?:") + re.pattern() + QLatin1String(")\\z"));
+ usedRe.setPattern(QRegularExpression::anchoredPattern(re.pattern()));
emit q->regularExpressionChanged(re);
emit q->changed();
}
diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
index cf3cbee48e..6324642505 100644
--- a/src/gui/util/util.pri
+++ b/src/gui/util/util.pri
@@ -14,7 +14,12 @@ HEADERS += \
util/qshaderlanguage_p.h \
util/qshadernode_p.h \
util/qshadernodeport_p.h \
- util/qshadernodesloader_p.h
+ util/qshadernodesloader_p.h \
+ util/qtexturefiledata_p.h \
+ util/qtexturefilereader_p.h \
+ util/qtexturefilehandler_p.h \
+ util/qpkmhandler_p.h \
+ util/qktxhandler_p.h
SOURCES += \
util/qdesktopservices.cpp \
@@ -29,4 +34,8 @@ SOURCES += \
util/qshaderlanguage.cpp \
util/qshadernode.cpp \
util/qshadernodeport.cpp \
- util/qshadernodesloader.cpp
+ util/qshadernodesloader.cpp \
+ util/qtexturefiledata.cpp \
+ util/qtexturefilereader.cpp \
+ util/qpkmhandler.cpp \
+ util/qktxhandler.cpp
diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp
index e45a16170e..2e65ab49c5 100644
--- a/src/gui/vulkan/qvulkanwindow.cpp
+++ b/src/gui/vulkan/qvulkanwindow.cpp
@@ -989,7 +989,7 @@ bool QVulkanWindowPrivate::createDefaultRenderPass()
attDesc[1].samples = sampleCount;
attDesc[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attDesc[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- attDesc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ attDesc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attDesc[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attDesc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
attDesc[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
@@ -999,7 +999,7 @@ bool QVulkanWindowPrivate::createDefaultRenderPass()
attDesc[2].format = colorFormat;
attDesc[2].samples = sampleCount;
attDesc[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- attDesc[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ attDesc[2].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attDesc[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attDesc[2].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
attDesc[2].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -2164,8 +2164,8 @@ void QVulkanWindowPrivate::addReadback()
barrier.image = frameGrabImage;
devFuncs->vkCmdPipelineBarrier(image.cmdBuf,
- VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
+ VK_PIPELINE_STAGE_HOST_BIT,
0, 0, nullptr, 0, nullptr,
1, &barrier);
}
@@ -2298,6 +2298,11 @@ uint32_t QVulkanWindow::hostVisibleMemoryIndex() const
\note Calling this function is only valid from the invocation of
QVulkanWindowRenderer::initResources() up until
QVulkanWindowRenderer::releaseResources().
+
+ \note It is not guaranteed that this memory type is always suitable. The
+ correct, cross-implementation solution - especially for device local images
+ - is to manually pick a memory type after checking the mask returned from
+ \c{vkGetImageMemoryRequirements}.
*/
uint32_t QVulkanWindow::deviceLocalMemoryIndex() const
{
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index ec0273377f..8a92308f12 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -74,6 +74,13 @@ qtConfig(settings) {
mac: LIBS_PRIVATE += -framework Security
+wasm {
+ SOURCES += \
+ access/qnetworkreplywasmimpl.cpp
+ HEADERS += \
+ access/qnetworkreplywasmimpl_p.h
+}
+
include($$PWD/../../3rdparty/zlib_dependency.pri)
qtConfig(http) {
diff --git a/src/network/access/http2/http2protocol.cpp b/src/network/access/http2/http2protocol.cpp
index f51af4be5c..0be72042c6 100644
--- a/src/network/access/http2/http2protocol.cpp
+++ b/src/network/access/http2/http2protocol.cpp
@@ -287,7 +287,8 @@ bool is_protocol_upgraded(const QHttpNetworkReply &reply)
// Do some minimal checks here - we expect 'Upgrade: h2c' to be found.
const auto &header = reply.header();
for (const QPair<QByteArray, QByteArray> &field : header) {
- if (field.first.toLower() == "upgrade" && field.second.toLower() == "h2c")
+ if (field.first.compare("upgrade", Qt::CaseInsensitive) == 0 &&
+ field.second.compare("h2c", Qt::CaseInsensitive) == 0)
return true;
}
}
diff --git a/src/network/access/qhsts.cpp b/src/network/access/qhsts.cpp
index af913ca015..ce70b6af90 100644
--- a/src/network/access/qhsts.cpp
+++ b/src/network/access/qhsts.cpp
@@ -470,8 +470,7 @@ bool QHstsHeaderParser::processDirective(const QByteArray &name, const QByteArra
{
Q_ASSERT(name.size());
// RFC6797 6.1/3 Directive names are case-insensitive
- const auto lcName = name.toLower();
- if (lcName == "max-age") {
+ if (name.compare("max-age", Qt::CaseInsensitive) == 0) {
// RFC 6797, 6.1.1
// The syntax of the max-age directive's REQUIRED value (after
// quoted-string unescaping, if necessary) is defined as:
@@ -494,7 +493,7 @@ bool QHstsHeaderParser::processDirective(const QByteArray &name, const QByteArra
maxAge = age;
maxAgeFound = true;
- } else if (lcName == "includesubdomains") {
+ } else if (name.compare("includesubdomains", Qt::CaseInsensitive) == 0) {
// RFC 6797, 6.1.2. The includeSubDomains Directive.
// The OPTIONAL "includeSubDomains" directive is a valueless directive.
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index c207d6e240..df7f87efd4 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -97,16 +97,18 @@ HPack::HttpHeader build_headers(const QHttpNetworkRequest &request, quint32 maxH
if (size.second > maxHeaderListSize)
break;
- QByteArray key(field.first.toLower());
- if (key == "connection" || key == "host" || key == "keep-alive"
- || key == "proxy-connection" || key == "transfer-encoding")
+ if (field.first.compare("connection", Qt::CaseInsensitive) == 0 ||
+ field.first.compare("host", Qt::CaseInsensitive) == 0 ||
+ field.first.compare("keep-alive", Qt::CaseInsensitive) == 0 ||
+ field.first.compare("proxy-connection", Qt::CaseInsensitive) == 0 ||
+ field.first.compare("transfer-encoding", Qt::CaseInsensitive) == 0)
continue; // Those headers are not valid (section 3.2.1) - from QSpdyProtocolHandler
// TODO: verify with specs, which fields are valid to send ....
// toLower - 8.1.2 .... "header field names MUST be converted to lowercase prior
// to their encoding in HTTP/2.
// A request or response containing uppercase header field names
// MUST be treated as malformed (Section 8.1.2.6)".
- header.push_back(HeaderField(key, field.second));
+ header.push_back(HeaderField(field.first.toLower(), field.second));
}
return header;
@@ -1404,8 +1406,9 @@ bool QHttp2ProtocolHandler::tryReserveStream(const Http2::Frame &pushPromiseFram
return false;
}
- const auto method = pseudoHeaders[":method"].toLower();
- if (method != "get" && method != "head")
+ const QByteArray method = pseudoHeaders[":method"];
+ if (method.compare("get", Qt::CaseInsensitive) != 0 &&
+ method.compare("head", Qt::CaseInsensitive) != 0)
return false;
QUrl url;
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 0e2c257952..c58fd24a44 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -528,7 +528,7 @@ QUrl QHttpNetworkConnectionPrivate::parseRedirectResponse(QAbstractSocket *socke
QUrl redirectUrl;
const QList<QPair<QByteArray, QByteArray> > fields = reply->header();
for (const QNetworkReply::RawHeaderPair &header : fields) {
- if (header.first.toLower() == "location") {
+ if (header.first.compare("location", Qt::CaseInsensitive) == 0) {
redirectUrl = QUrl::fromEncoded(header.second);
break;
}
diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp
index 3326f89d2f..8ad01174b4 100644
--- a/src/network/access/qhttpnetworkheader.cpp
+++ b/src/network/access/qhttpnetworkheader.cpp
@@ -64,7 +64,7 @@ qint64 QHttpNetworkHeaderPrivate::contentLength() const
QList<QPair<QByteArray, QByteArray> >::ConstIterator it = fields.constBegin(),
end = fields.constEnd();
for ( ; it != end; ++it)
- if (qstricmp("content-length", it->first) == 0) {
+ if (it->first.compare("content-length", Qt::CaseInsensitive) == 0) {
value = it->second;
break;
}
@@ -95,7 +95,7 @@ QList<QByteArray> QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray
QList<QPair<QByteArray, QByteArray> >::ConstIterator it = fields.constBegin(),
end = fields.constEnd();
for ( ; it != end; ++it)
- if (qstricmp(name.constData(), it->first) == 0)
+ if (name.compare(it->first, Qt::CaseInsensitive) == 0)
result += it->second;
return result;
@@ -104,7 +104,7 @@ QList<QByteArray> QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray
void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QByteArray &data)
{
auto firstEqualsName = [&name](const QPair<QByteArray, QByteArray> &header) {
- return qstricmp(name.constData(), header.first) == 0;
+ return name.compare(header.first, Qt::CaseInsensitive) == 0;
};
fields.erase(std::remove_if(fields.begin(), fields.end(),
firstEqualsName),
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index a657346958..c9c3172304 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -390,7 +390,8 @@ qint64 QHttpNetworkReplyPrivate::bytesAvailable() const
bool QHttpNetworkReplyPrivate::isCompressed()
{
QByteArray encoding = headerField("content-encoding");
- return qstricmp(encoding.constData(), "gzip") == 0 || qstricmp(encoding.constData(), "deflate") == 0;
+ return encoding.compare("gzip", Qt::CaseInsensitive) == 0 ||
+ encoding.compare("deflate", Qt::CaseInsensitive) == 0;
}
void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
@@ -401,7 +402,7 @@ void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(),
end = fields.end();
while (it != end) {
- if (qstricmp(name.constData(), it->first.constData()) == 0) {
+ if (name.compare(it->first, Qt::CaseInsensitive) == 0) {
removedContentLength = strtoull(it->second.constData(), nullptr, 0);
fields.erase(it);
break;
diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp
index d7914e4143..67a856506c 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend.cpp
+++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp
@@ -107,8 +107,8 @@ void QNetworkAccessDebugPipeBackend::open()
bareProtocol = QUrlQuery(url()).queryItemValue(QLatin1String("bare")) == QLatin1String("1");
if (operation() == QNetworkAccessManager::PutOperation) {
- uploadByteDevice = createUploadByteDevice();
- QObject::connect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(uploadReadyReadSlot()));
+ createUploadByteDevice();
+ QObject::connect(uploadByteDevice.data(), SIGNAL(readyRead()), this, SLOT(uploadReadyReadSlot()));
QMetaObject::invokeMethod(this, "uploadReadyReadSlot", Qt::QueuedConnection);
}
}
diff --git a/src/network/access/qnetworkaccessdebugpipebackend_p.h b/src/network/access/qnetworkaccessdebugpipebackend_p.h
index d9a7aabdad..761c7055b8 100644
--- a/src/network/access/qnetworkaccessdebugpipebackend_p.h
+++ b/src/network/access/qnetworkaccessdebugpipebackend_p.h
@@ -77,7 +77,6 @@ protected:
void pushFromSocketToDownstream();
void pushFromUpstreamToSocket();
void possiblyFinish();
- QNonContiguousByteDevice *uploadByteDevice;
private slots:
void uploadReadyReadSlot();
diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp
index d4ca9c22fc..60353cb03e 100644
--- a/src/network/access/qnetworkaccessfilebackend.cpp
+++ b/src/network/access/qnetworkaccessfilebackend.cpp
@@ -99,7 +99,7 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,
}
QNetworkAccessFileBackend::QNetworkAccessFileBackend()
- : uploadByteDevice(0), totalBytes(0), hasUploadFinished(false)
+ : totalBytes(0), hasUploadFinished(false)
{
}
@@ -154,8 +154,8 @@ void QNetworkAccessFileBackend::open()
break;
case QNetworkAccessManager::PutOperation:
mode = QIODevice::WriteOnly | QIODevice::Truncate;
- uploadByteDevice = createUploadByteDevice();
- QObject::connect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(uploadReadyReadSlot()));
+ createUploadByteDevice();
+ QObject::connect(uploadByteDevice.data(), SIGNAL(readyRead()), this, SLOT(uploadReadyReadSlot()));
QMetaObject::invokeMethod(this, "uploadReadyReadSlot", Qt::QueuedConnection);
break;
default:
diff --git a/src/network/access/qnetworkaccessfilebackend_p.h b/src/network/access/qnetworkaccessfilebackend_p.h
index 2c01fb1121..2204958ee0 100644
--- a/src/network/access/qnetworkaccessfilebackend_p.h
+++ b/src/network/access/qnetworkaccessfilebackend_p.h
@@ -73,8 +73,6 @@ public:
public slots:
void uploadReadyReadSlot();
-protected:
- QNonContiguousByteDevice *uploadByteDevice;
private:
QFile file;
qint64 totalBytes;
diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp
index bc44a78a9a..fd6589b396 100644
--- a/src/network/access/qnetworkaccessftpbackend.cpp
+++ b/src/network/access/qnetworkaccessftpbackend.cpp
@@ -102,8 +102,8 @@ public:
};
QNetworkAccessFtpBackend::QNetworkAccessFtpBackend()
- : ftp(0), uploadDevice(0), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1),
- supportsSize(false), supportsMdtm(false), state(Idle)
+ : ftp(0), uploadDevice(0), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), pwdId(-1),
+ supportsSize(false), supportsMdtm(false), supportsPwd(false), state(Idle)
{
}
@@ -302,13 +302,38 @@ void QNetworkAccessFtpBackend::ftpDone()
if (state == LoggingIn) {
state = CheckingFeatures;
- if (operation() == QNetworkAccessManager::GetOperation) {
- // send help command to find out if server supports "SIZE" and "MDTM"
+ // send help command to find out if server supports SIZE, MDTM, and PWD
+ if (operation() == QNetworkAccessManager::GetOperation
+ || operation() == QNetworkAccessManager::PutOperation) {
helpId = ftp->rawCommand(QLatin1String("HELP")); // get supported commands
} else {
ftpDone();
}
} else if (state == CheckingFeatures) {
+ // If a URL path starts with // prefix (/%2F decoded), the resource will
+ // be retrieved by an absolute path starting with the root directory.
+ // For the other URLs, the working directory is retrieved by PWD command
+ // and prepended to the resource path as an absolute path starting with
+ // the working directory.
+ state = ResolvingPath;
+ QString path = url().path();
+ if (path.startsWith(QLatin1String("//")) || supportsPwd == false) {
+ ftpDone(); // no commands sent, move to the next state
+ } else {
+ // If a path starts with /~/ prefix, its prefix will be replaced by
+ // the working directory as an absolute path starting with working
+ // directory.
+ if (path.startsWith(QLatin1String("/~/"))) {
+ // Remove leading /~ symbols
+ QUrl newUrl = url();
+ newUrl.setPath(path.mid(2));
+ setUrl(newUrl);
+ }
+
+ // send PWD command to retrieve the working directory
+ pwdId = ftp->rawCommand(QLatin1String("PWD"));
+ }
+ } else if (state == ResolvingPath) {
state = Statting;
if (operation() == QNetworkAccessManager::GetOperation) {
// logged in successfully, send the stat requests (if supported)
@@ -366,6 +391,34 @@ void QNetworkAccessFtpBackend::ftpRawCommandReply(int code, const QString &text)
supportsSize = true;
if (text.contains(QLatin1String("MDTM"), Qt::CaseSensitive))
supportsMdtm = true;
+ if (text.contains(QLatin1String("PWD"), Qt::CaseSensitive))
+ supportsPwd = true;
+ } else if (id == pwdId && code == 257) {
+ QString pwdPath;
+ int startIndex = text.indexOf('"');
+ int stopIndex = text.lastIndexOf('"');
+ if (stopIndex - startIndex) {
+ // The working directory is a substring between \" symbols.
+ startIndex++; // skip the first \" symbol
+ pwdPath = text.mid(startIndex, stopIndex - startIndex);
+ } else {
+ // If there is no or only one \" symbol, use all the characters of
+ // text.
+ pwdPath = text;
+ }
+
+ // If a URL path starts with the working directory prefix, its resource
+ // will be retrieved from the working directory. Otherwise, the path of
+ // the working directory is prepended to the resource path.
+ QString urlPath = url().path();
+ if (!urlPath.startsWith(pwdPath)) {
+ if (pwdPath.endsWith(QLatin1Char('/')))
+ pwdPath.chop(1);
+ // Prepend working directory to the URL path
+ QUrl newUrl = url();
+ newUrl.setPath(pwdPath % urlPath);
+ setUrl(newUrl);
+ }
} else if (code == 213) { // file status
if (id == sizeId) {
// reply to the size command
diff --git a/src/network/access/qnetworkaccessftpbackend_p.h b/src/network/access/qnetworkaccessftpbackend_p.h
index 4bd082fb67..0b3d35dcd3 100644
--- a/src/network/access/qnetworkaccessftpbackend_p.h
+++ b/src/network/access/qnetworkaccessftpbackend_p.h
@@ -76,6 +76,7 @@ public:
//Connecting,
LoggingIn,
CheckingFeatures,
+ ResolvingPath,
Statting,
Transferring,
Disconnecting
@@ -107,8 +108,8 @@ private:
QPointer<QNetworkAccessCachedFtpConnection> ftp;
QIODevice *uploadDevice;
qint64 totalBytes;
- int helpId, sizeId, mdtmId;
- bool supportsSize, supportsMdtm;
+ int helpId, sizeId, mdtmId, pwdId;
+ bool supportsSize, supportsMdtm, supportsPwd;
State state;
};
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index a2649fe77c..263469ce38 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -86,6 +86,9 @@
#include <SystemConfiguration/SystemConfiguration.h>
#include <Security/SecKeychain.h>
#endif
+#ifdef Q_OS_WASM
+#include "qnetworkreplywasmimpl_p.h"
+#endif
QT_BEGIN_NAMESPACE
@@ -940,7 +943,7 @@ QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QHttpM
/*!
Uploads the contents of \a data to the destination \a request and
- returnes a new QNetworkReply object that will be open for reply.
+ returns a new QNetworkReply object that will be open for reply.
\a data must be opened for reading when this function is called
and must remain valid until the finished() signal is emitted for
@@ -1357,6 +1360,16 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
bool isLocalFile = req.url().isLocalFile();
QString scheme = req.url().scheme();
+#ifdef Q_OS_WASM
+ if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) {
+ QNetworkReplyWasmImpl *reply = new QNetworkReplyWasmImpl(this);
+ QNetworkReplyWasmImplPrivate *priv = reply->d_func();
+ priv->manager = this;
+ priv->setup(op, req, outgoingData);
+ return reply;
+ }
+#endif
+
// fast path for GET on file:// URLs
// The QNetworkAccessFileBackend will right now only be used for PUT
if (op == QNetworkAccessManager::GetOperation
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index a0ce3eddcd..67b3a8b71b 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -195,6 +195,9 @@ private:
friend class QNetworkReplyHttpImplPrivate;
friend class QNetworkReplyFileImpl;
+#ifdef Q_OS_WASM
+ friend class QNetworkReplyWasmImpl;
+#endif
Q_DECLARE_PRIVATE(QNetworkAccessManager)
Q_PRIVATE_SLOT(d_func(), void _q_replyFinished())
Q_PRIVATE_SLOT(d_func(), void _q_replyEncrypted())
diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp
index c9d658225e..df2e4902a4 100644
--- a/src/network/access/qnetworkdiskcache.cpp
+++ b/src/network/access/qnetworkdiskcache.cpp
@@ -189,7 +189,7 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData)
const auto headers = metaData.rawHeaders();
for (const auto &header : headers) {
- if (header.first.toLower() == "content-length") {
+ if (header.first.compare("content-length", Qt::CaseInsensitive) == 0) {
const qint64 size = header.second.toLongLong();
if (size > (maximumCacheSize() * 3)/4)
return 0;
@@ -642,7 +642,7 @@ bool QCacheItem::canCompress() const
bool typeOk = false;
const auto headers = metaData.rawHeaders();
for (const auto &header : headers) {
- if (header.first.toLower() == "content-length") {
+ if (header.first.compare("content-length", Qt::CaseInsensitive) == 0) {
qint64 size = header.second.toLongLong();
if (size > MAX_COMPRESSION_SIZE)
return false;
@@ -650,7 +650,7 @@ bool QCacheItem::canCompress() const
sizeOk = true;
}
- if (header.first.toLower() == "content-type") {
+ if (header.first.compare("content-type", Qt::CaseInsensitive) == 0) {
QByteArray type = header.second;
if (type.startsWith("text/")
|| (type.startsWith("application/")
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 9067dea8e3..8750a841f6 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -1318,7 +1318,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte
if (!value.isEmpty()) {
// Why are we appending values for headers which are already
// present?
- if (qstricmp(it->first.constData(), "set-cookie") == 0)
+ if (it->first.compare("set-cookie", Qt::CaseInsensitive) == 0)
value += '\n';
else
value += ", ";
@@ -1584,7 +1584,7 @@ bool QNetworkReplyHttpImplPrivate::sendCacheContents(const QNetworkCacheMetaData
QUrl redirectUrl;
for ( ; it != end; ++it) {
if (httpRequest.isFollowRedirects() &&
- !qstricmp(it->first.toLower().constData(), "location"))
+ !it->first.compare("location", Qt::CaseInsensitive))
redirectUrl = QUrl::fromEncoded(it->second);
setRawHeader(it->first, it->second);
}
diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp
new file mode 100644
index 0000000000..9c2ff8fb89
--- /dev/null
+++ b/src/network/access/qnetworkreplywasmimpl.cpp
@@ -0,0 +1,640 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkreplywasmimpl_p.h"
+#include "qnetworkrequest.h"
+
+#include <QtCore/qtimer.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qthread.h>
+
+#include <private/qnetworkaccessmanager_p.h>
+#include <private/qnetworkfile_p.h>
+
+#include <iostream>
+
+QT_BEGIN_NAMESPACE
+
+QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate()
+ : QNetworkReplyPrivate()
+ , managerPrivate(0)
+ , downloadBufferReadPosition(0)
+ , downloadBufferCurrentSize(0)
+ , totalDownloadSize(0)
+ , percentFinished(0)
+{
+}
+
+QNetworkReplyWasmImplPrivate::~QNetworkReplyWasmImplPrivate()
+{
+}
+
+QNetworkReplyWasmImpl::~QNetworkReplyWasmImpl()
+{
+}
+
+QNetworkReplyWasmImpl::QNetworkReplyWasmImpl(QObject *parent)
+ : QNetworkReply(*new QNetworkReplyWasmImplPrivate(), parent)
+{
+}
+
+QByteArray QNetworkReplyWasmImpl::methodName() const
+{
+ switch (operation()) {
+ case QNetworkAccessManager::HeadOperation:
+ return "HEAD";
+ case QNetworkAccessManager::GetOperation:
+ return "GET";
+ case QNetworkAccessManager::PutOperation:
+ return "PUT";
+ case QNetworkAccessManager::PostOperation:
+ return "POST";
+ case QNetworkAccessManager::DeleteOperation:
+ return "DELETE";
+ default:
+ break;
+ }
+ return QByteArray();
+}
+
+void QNetworkReplyWasmImpl::close()
+{
+ QNetworkReply::close();
+}
+
+void QNetworkReplyWasmImpl::abort()
+{
+ close();
+}
+
+qint64 QNetworkReplyWasmImpl::bytesAvailable() const
+{
+ Q_D(const QNetworkReplyWasmImpl);
+
+ if (!d->isFinished)
+ return QNetworkReply::bytesAvailable();
+
+ return QNetworkReply::bytesAvailable() + d->downloadBufferCurrentSize - d->downloadBufferReadPosition;
+}
+
+bool QNetworkReplyWasmImpl::isSequential() const
+{
+ return true;
+}
+
+qint64 QNetworkReplyWasmImpl::size() const
+{
+ return QNetworkReply::size();
+}
+
+/*!
+ \internal
+*/
+qint64 QNetworkReplyWasmImpl::readData(char *data, qint64 maxlen)
+{
+ Q_D(QNetworkReplyWasmImpl);
+
+ qint64 howMuch = qMin(maxlen, (d->downloadBuffer.size() - d->downloadBufferReadPosition));
+ memcpy(data, d->downloadBuffer.constData(), howMuch);
+ d->downloadBufferReadPosition += howMuch;
+
+ return howMuch;
+}
+
+void QNetworkReplyWasmImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *data)
+{
+ Q_Q(QNetworkReplyWasmImpl);
+
+ outgoingData = data;
+ request = req;
+ url = request.url();
+ operation = op;
+
+ q->QIODevice::open(QIODevice::ReadOnly);
+ if (outgoingData && outgoingData->isSequential()) {
+ bool bufferingDisallowed =
+ request.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute, false).toBool();
+
+ if (bufferingDisallowed) {
+ // if a valid content-length header for the request was supplied, we can disable buffering
+ // if not, we will buffer anyway
+ if (!request.header(QNetworkRequest::ContentLengthHeader).isValid()) {
+ state = Buffering;
+ _q_bufferOutgoingData();
+ return;
+ }
+ } else {
+ // doSendRequest will be called when the buffering has finished.
+ state = Buffering;
+ _q_bufferOutgoingData();
+ return;
+ }
+ }
+ // No outgoing data (POST, ..)
+ doSendRequest();
+}
+
+void QNetworkReplyWasmImplPrivate::onLoadCallback(void *data, int statusCode, int statusReason, int readyState, int buffer, int bufferSize)
+{
+ QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data);
+
+ const QString reasonStr = QString::fromUtf8(reinterpret_cast<char *>(statusReason));
+
+ switch (readyState) {
+ case 0://unsent
+ break;
+ case 1://opened
+ break;
+ case 2://headers received
+ break;
+ case 3://loading
+ break;
+ case 4: {//done
+ handler->q_func()->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode);
+ if (!reasonStr.isEmpty())
+ handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, reasonStr);
+
+ if (statusCode >= 400) {
+ if (!reasonStr.isEmpty())
+ handler->emitReplyError(handler->statusCodeFromHttp(statusCode, handler->request.url()), reasonStr);
+ } else {
+ handler->dataReceived(reinterpret_cast<char *>(buffer), bufferSize);
+ }
+ }
+ break;
+ };
+ }
+
+void QNetworkReplyWasmImplPrivate::onProgressCallback(void* data, int bytesWritten, int total, uint timestamp)
+{
+ Q_UNUSED(timestamp);
+
+ QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data);
+ handler->emitDataReadProgress(bytesWritten, total);
+}
+
+void QNetworkReplyWasmImplPrivate::onRequestErrorCallback(void* data, int statusCode, int statusReason)
+{
+ QString reasonStr = QString::fromUtf8(reinterpret_cast<char *>(statusReason));
+
+ QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data);
+
+ handler->q_func()->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode);
+ if (!reasonStr.isEmpty())
+ handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, reasonStr);
+
+ if (statusCode >= 400) {
+ if (!reasonStr.isEmpty())
+ handler->emitReplyError(handler->statusCodeFromHttp(statusCode, handler->request.url()), reasonStr);
+ }
+}
+
+void QNetworkReplyWasmImplPrivate::onResponseHeadersCallback(void* data, int headers)
+{
+ QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data);
+ handler->headersReceived(reinterpret_cast<char *>(headers));
+}
+
+void QNetworkReplyWasmImplPrivate::doSendRequest()
+{
+ Q_Q(QNetworkReplyWasmImpl);
+ totalDownloadSize = 0;
+ jsRequest(QString::fromUtf8(q->methodName()), // GET POST
+ request.url().toString(),
+ (void *)&onLoadCallback,
+ (void *)&onProgressCallback,
+ (void *)&onRequestErrorCallback,
+ (void *)&onResponseHeadersCallback);
+}
+
+/* const QString &body, const QList<QPair<QByteArray, QByteArray> > &headers ,*/
+void QNetworkReplyWasmImplPrivate::jsRequest(const QString &verb, const QString &url,
+ void *loadCallback, void *progressCallback,
+ void *errorCallback, void *onResponseHeadersCallback)
+{
+ QString extraDataString;
+
+ QByteArray extraData;
+ if (outgoingData)
+ extraData = outgoingData->readAll();
+
+ if (extraData.size() > 0)
+ extraDataString.fromUtf8(extraData);
+
+ if (extraDataString.size() >= 0 && verb == QStringLiteral("POST") && extraDataString.startsWith(QStringLiteral("?")))
+ extraDataString.remove(QStringLiteral("?"));
+
+ // Probably a good idea to save any shared pointers as members in C++
+ // so the objects they point to survive as long as you need them
+
+ QStringList headersList;
+ for (auto header : request.rawHeaderList())
+ headersList << QString::fromUtf8(header + ":" + request.rawHeader(header));
+
+ EM_ASM_ARGS({
+ var verb = Pointer_stringify($0);
+ var url = Pointer_stringify($1);
+ var onLoadCallbackPointer = $2;
+ var onProgressCallbackPointer = $3;
+ var onErrorCallbackPointer = $4;
+ var onHeadersCallback = $5;
+ var handler = $8;
+
+ var dataToSend;
+ var extraRequestData = Pointer_stringify($6); // request parameters
+ var headersData = Pointer_stringify($7);
+
+ var xhr;
+ xhr = new XMLHttpRequest();
+ xhr.responseType = 'arraybuffer';
+
+ xhr.open(verb, url, true); //async
+
+ function handleError(xhrStatusCode, xhrStatusText) {
+ var errorPtr = allocate(intArrayFromString(xhrStatusText), 'i8', ALLOC_NORMAL);
+ Runtime.dynCall('viii', onErrorCallbackPointer, [handler, xhrStatusCode, errorPtr]);
+ _free(errorPtr);
+ }
+
+ if (headersData) {
+ var headers = headersData.split("&");
+ for (var i = 0; i < headers.length; i++) {
+ var header = headers[i].split(":")[0];
+ var value = headers[i].split(":")[1];
+
+ if (verb === 'POST' && value.toLowerCase().includes('json')) {
+ if (extraRequestData) {
+ xhr.responseType = 'json';
+ dataToSend = extraRequestData;
+ }
+ }
+ if (verb === 'POST' && value.toLowerCase().includes('form')) {
+ if (extraRequestData) {
+ var formData = new FormData();
+ var extra = extraRequestData.split("&");
+ for (var i = 0; i < extra.length; i++) {
+ formData.append(extra[i].split("=")[0],extra[i].split("=")[1]);
+ }
+ dataToSend = formData;
+ }
+ }
+ xhr.setRequestHeader(header, value);
+ }
+ }
+
+ xhr.onprogress = function(e) {
+ switch (xhr.status) {
+ case 200:
+ case 206:
+ case 300:
+ case 301:
+ case 302: {
+ var date = xhr.getResponseHeader('Last-Modified');
+ date = ((date != null) ? new Date(date).getTime() / 1000 : 0);
+ Runtime.dynCall('viiii', onProgressCallbackPointer, [handler, e.loaded, e.total, date]);
+ }
+ break;
+ }
+ };
+
+ xhr.onreadystatechange = function() {
+ if (this.readyState == this.HEADERS_RECEIVED) {
+ var responseStr = this.getAllResponseHeaders();
+ if (responseStr.length > 0) {
+ var ptr = allocate(intArrayFromString(responseStr), 'i8', ALLOC_NORMAL);
+ Runtime.dynCall('vii', onHeadersCallback, [handler, ptr]);
+ _free(ptr);
+ }
+ }
+ };
+
+ xhr.onload = function(e) {
+ if (xhr.status >= 300) { //error
+ handleError(xhr.status, xhr.statusText);
+ } else {
+ if (this.status == 200 || this.status == 203) {
+ var datalength;
+ var byteArray = 0;
+ var buffer;
+ if (this.responseType.length === 0 || this.responseType === 'document') {
+ byteArray = new Uint8Array(this.responseText);
+ } else if (this.responseType === 'json') {
+ var jsonResponse = JSON.stringify(this.response);
+ buffer = allocate(intArrayFromString(jsonResponse), 'i8', ALLOC_NORMAL);
+ datalength = jsonResponse.length;
+ } else if (this.responseType === 'arraybuffer') {
+ byteArray = new Uint8Array(xhr.response);
+ }
+ if (byteArray != 0 ) {
+ datalength = byteArray.length;
+ buffer = _malloc(datalength);
+ HEAPU8.set(byteArray, buffer);
+ }
+ var reasonPtr = allocate(intArrayFromString(this.statusText), 'i8', ALLOC_NORMAL);
+ Runtime.dynCall('viiiiii', onLoadCallbackPointer, [handler, this.status, reasonPtr, this.readyState, buffer, datalength]);
+ _free(buffer);
+ _free(reasonPtr);
+ }
+ }
+ };
+
+ xhr.onerror = function(e) {
+ handleError(xhr.status, xhr.statusText);
+ };
+ //TODO other operations, handle user/pass, handle binary data, data streaming
+ xhr.send(dataToSend);
+
+ }, verb.toLatin1().data(),
+ url.toLatin1().data(),
+ loadCallback,
+ progressCallback,
+ errorCallback,
+ onResponseHeadersCallback,
+ extraDataString.size() > 0 ? extraDataString.toLatin1().data() : extraData.data(),
+ headersList.join(QStringLiteral("&")).toLatin1().data(),
+ this
+ );
+}
+
+void QNetworkReplyWasmImplPrivate::emitReplyError(QNetworkReply::NetworkError errorCode, const QString &errorString)
+{
+ Q_UNUSED(errorCode)
+ Q_Q(QNetworkReplyWasmImpl);
+
+ q->setError(errorCode, errorString);
+ emit q->error(errorCode);
+
+ q->setFinished(true);
+ emit q->finished();
+}
+
+void QNetworkReplyWasmImplPrivate::emitDataReadProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ Q_Q(QNetworkReplyWasmImpl);
+
+ totalDownloadSize = bytesTotal;
+
+ percentFinished = (bytesReceived / bytesTotal) * 100;
+
+ emit q->downloadProgress(bytesReceived, totalDownloadSize);
+}
+
+void QNetworkReplyWasmImplPrivate::dataReceived(char *buffer, int bufferSize)
+{
+ Q_Q(QNetworkReplyWasmImpl);
+
+ if (bufferSize > 0)
+ q->setReadBufferSize(bufferSize);
+
+ bytesDownloaded = bufferSize;
+
+ if (percentFinished != 100)
+ downloadBufferCurrentSize += bufferSize;
+ else
+ downloadBufferCurrentSize = bufferSize;
+
+ totalDownloadSize = downloadBufferCurrentSize;
+
+ downloadBuffer.append(buffer, bufferSize);
+
+ if (downloadBufferCurrentSize == totalDownloadSize) {
+ q->setFinished(true);
+ emit q->finished();
+ }
+}
+
+//taken from qnetworkrequest.cpp
+static int parseHeaderName(const QByteArray &headerName)
+{
+ if (headerName.isEmpty())
+ return -1;
+
+ switch (tolower(headerName.at(0))) {
+ case 'c':
+ if (qstricmp(headerName.constData(), "content-type") == 0)
+ return QNetworkRequest::ContentTypeHeader;
+ else if (qstricmp(headerName.constData(), "content-length") == 0)
+ return QNetworkRequest::ContentLengthHeader;
+ else if (qstricmp(headerName.constData(), "cookie") == 0)
+ return QNetworkRequest::CookieHeader;
+ break;
+
+ case 'l':
+ if (qstricmp(headerName.constData(), "location") == 0)
+ return QNetworkRequest::LocationHeader;
+ else if (qstricmp(headerName.constData(), "last-modified") == 0)
+ return QNetworkRequest::LastModifiedHeader;
+ break;
+
+ case 's':
+ if (qstricmp(headerName.constData(), "set-cookie") == 0)
+ return QNetworkRequest::SetCookieHeader;
+ else if (qstricmp(headerName.constData(), "server") == 0)
+ return QNetworkRequest::ServerHeader;
+ break;
+
+ case 'u':
+ if (qstricmp(headerName.constData(), "user-agent") == 0)
+ return QNetworkRequest::UserAgentHeader;
+ break;
+ }
+
+ return -1; // nothing found
+}
+
+
+void QNetworkReplyWasmImplPrivate::headersReceived(char *buffer)
+{
+ Q_Q(QNetworkReplyWasmImpl);
+
+ QString bufferString = QString::fromUtf8(buffer);
+ if (!bufferString.isEmpty()) {
+ QStringList headers = bufferString.split(QString::fromUtf8("\r\n"), QString::SkipEmptyParts);
+
+ for (int i = 0; i < headers.size(); i++) {
+ QString headerName = headers.at(i).split(QString::fromUtf8(": ")).at(0);
+ QString headersValue = headers.at(i).split(QString::fromUtf8(": ")).at(1);
+ if (headerName.isEmpty() || headersValue.isEmpty())
+ continue;
+
+ int headerIndex = parseHeaderName(headerName.toLocal8Bit());
+
+ if (headerIndex == -1)
+ q->setRawHeader(headerName.toLocal8Bit(), headersValue.toLocal8Bit());
+ else
+ q->setHeader(static_cast<QNetworkRequest::KnownHeaders>(headerIndex), (QVariant)headersValue);
+ }
+ }
+ emit q->metaDataChanged();
+}
+
+void QNetworkReplyWasmImplPrivate::_q_bufferOutgoingDataFinished()
+{
+ Q_Q(QNetworkReplyWasmImpl);
+
+ // make sure this is only called once, ever.
+ //_q_bufferOutgoingData may call it or the readChannelFinished emission
+ if (state != Buffering)
+ return;
+
+ // disconnect signals
+ QObject::disconnect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData()));
+ QObject::disconnect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished()));
+
+ // finally, start the request
+ doSendRequest();
+}
+
+void QNetworkReplyWasmImplPrivate::_q_bufferOutgoingData()
+{
+ Q_Q(QNetworkReplyWasmImpl);
+
+ if (!outgoingDataBuffer) {
+ // first call, create our buffer
+ outgoingDataBuffer = QSharedPointer<QRingBuffer>::create();
+
+ QObject::connect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData()));
+ QObject::connect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished()));
+ }
+
+ qint64 bytesBuffered = 0;
+ qint64 bytesToBuffer = 0;
+
+ // read data into our buffer
+ forever {
+ bytesToBuffer = outgoingData->bytesAvailable();
+ // unknown? just try 2 kB, this also ensures we always try to read the EOF
+ if (bytesToBuffer <= 0)
+ bytesToBuffer = 2*1024;
+
+ char *dst = outgoingDataBuffer->reserve(bytesToBuffer);
+ bytesBuffered = outgoingData->read(dst, bytesToBuffer);
+
+ if (bytesBuffered == -1) {
+ // EOF has been reached.
+ outgoingDataBuffer->chop(bytesToBuffer);
+
+ _q_bufferOutgoingDataFinished();
+ break;
+ } else if (bytesBuffered == 0) {
+ // nothing read right now, just wait until we get called again
+ outgoingDataBuffer->chop(bytesToBuffer);
+
+ break;
+ } else {
+ // don't break, try to read() again
+ outgoingDataBuffer->chop(bytesToBuffer - bytesBuffered);
+ }
+ }
+}
+
+//taken from qhttpthreaddelegate.cpp
+QNetworkReply::NetworkError QNetworkReplyWasmImplPrivate::statusCodeFromHttp(int httpStatusCode, const QUrl &url)
+{
+ QNetworkReply::NetworkError code;
+ // we've got an error
+ switch (httpStatusCode) {
+ case 400: // Bad Request
+ code = QNetworkReply::ProtocolInvalidOperationError;
+ break;
+
+ case 401: // Authorization required
+ code = QNetworkReply::AuthenticationRequiredError;
+ break;
+
+ case 403: // Access denied
+ code = QNetworkReply::ContentAccessDenied;
+ break;
+
+ case 404: // Not Found
+ code = QNetworkReply::ContentNotFoundError;
+ break;
+
+ case 405: // Method Not Allowed
+ code = QNetworkReply::ContentOperationNotPermittedError;
+ break;
+
+ case 407:
+ code = QNetworkReply::ProxyAuthenticationRequiredError;
+ break;
+
+ case 409: // Resource Conflict
+ code = QNetworkReply::ContentConflictError;
+ break;
+
+ case 410: // Content no longer available
+ code = QNetworkReply::ContentGoneError;
+ break;
+
+ case 418: // I'm a teapot
+ code = QNetworkReply::ProtocolInvalidOperationError;
+ break;
+
+ case 500: // Internal Server Error
+ code = QNetworkReply::InternalServerError;
+ break;
+
+ case 501: // Server does not support this functionality
+ code = QNetworkReply::OperationNotImplementedError;
+ break;
+
+ case 503: // Service unavailable
+ code = QNetworkReply::ServiceUnavailableError;
+ break;
+
+ default:
+ if (httpStatusCode > 500) {
+ // some kind of server error
+ code = QNetworkReply::UnknownServerError;
+ } else if (httpStatusCode >= 400) {
+ // content error we did not handle above
+ code = QNetworkReply::UnknownContentError;
+ } else {
+ qWarning("QNetworkAccess: got HTTP status code %d which is not expected from url: \"%s\"",
+ httpStatusCode, qPrintable(url.toString()));
+ code = QNetworkReply::ProtocolFailure;
+ }
+ };
+
+ return code;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkreplywasmimpl_p.h b/src/network/access/qnetworkreplywasmimpl_p.h
new file mode 100644
index 0000000000..a707390503
--- /dev/null
+++ b/src/network/access/qnetworkreplywasmimpl_p.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKREPLYWASMIMPL_H
+#define QNETWORKREPLYWASMIMPL_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworkreply.h"
+#include "qnetworkreply_p.h"
+#include "qnetworkaccessmanager.h"
+
+#include <QtCore/qfile.h>
+
+#include <private/qtnetworkglobal_p.h>
+#include <private/qabstractfileengine_p.h>
+
+#include <emscripten.h>
+#include <emscripten/html5.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+
+class QNetworkReplyWasmImplPrivate;
+class QNetworkReplyWasmImpl: public QNetworkReply
+{
+ Q_OBJECT
+public:
+ QNetworkReplyWasmImpl(QObject *parent = nullptr);
+ ~QNetworkReplyWasmImpl();
+ virtual void abort() override;
+
+ // reimplemented from QNetworkReply
+ virtual void close() override;
+ virtual qint64 bytesAvailable() const override;
+ virtual bool isSequential () const override;
+ qint64 size() const override;
+
+ virtual qint64 readData(char *data, qint64 maxlen) override;
+
+ void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request,
+ QIODevice *outgoingData);
+
+ Q_DECLARE_PRIVATE(QNetworkReplyWasmImpl)
+
+ Q_PRIVATE_SLOT(d_func(), void emitReplyError(QNetworkReply::NetworkError errorCode, const QString &errorString))
+ Q_PRIVATE_SLOT(d_func(), void emitDataReadProgress(qint64 done, qint64 total))
+ Q_PRIVATE_SLOT(d_func(), void dataReceived(char *buffer, int bufferSize))
+
+private:
+ QByteArray methodName() const;
+
+};
+
+class QNetworkReplyWasmImplPrivate: public QNetworkReplyPrivate
+{
+public:
+ QNetworkReplyWasmImplPrivate();
+ ~QNetworkReplyWasmImplPrivate();
+
+ QNetworkAccessManagerPrivate *managerPrivate;
+ void doSendRequest();
+
+ void jsRequest(const QString &verb, const QString &url, void *, void *, void *, void *);
+
+ static void onLoadCallback(void *data, int statusCode, int statusReason, int readyState, int textBuffer, int size);
+ static void onProgressCallback(void *data, int done, int bytesTotal, uint timestamp);
+ static void onRequestErrorCallback(void *data, int statusCode, int statusReason);
+ static void onStateChangedCallback(int status);
+ static void onResponseHeadersCallback(void *data, int headers);
+
+ void emitReplyError(QNetworkReply::NetworkError errorCode, const QString &);
+ void emitDataReadProgress(qint64 done, qint64 total);
+ void dataReceived(char *buffer, int bufferSize);
+ void headersReceived(char *buffer);
+
+ void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request,
+ QIODevice *outgoingData);
+
+ State state;
+ void _q_bufferOutgoingData();
+ void _q_bufferOutgoingDataFinished();
+
+ QSharedPointer<QAtomicInt> pendingDownloadData;
+ QSharedPointer<QAtomicInt> pendingDownloadProgress;
+
+ qint64 bytesDownloaded;
+ qint64 bytesBuffered;
+
+ qint64 downloadBufferReadPosition;
+ qint64 downloadBufferCurrentSize;
+ qint64 totalDownloadSize;
+ qint64 percentFinished;
+ QByteArray downloadBuffer;
+
+ QIODevice *outgoingData;
+ QSharedPointer<QRingBuffer> outgoingDataBuffer;
+
+ static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const QUrl &url);
+ Q_DECLARE_PUBLIC(QNetworkReplyWasmImpl)
+};
+
+QT_END_NAMESPACE
+
+//Q_DECLARE_METATYPE(QNetworkRequest::KnownHeaders)
+
+#endif // QNETWORKREPLYWASMIMPL_H
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 4cb93805dc..689eecfbb9 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -98,6 +98,25 @@ QT_BEGIN_NAMESPACE
header and contains a QDateTime representing the last modification
date of the contents.
+ \value IfModifiedSinceHeader Corresponds to the HTTP If-Modified-Since
+ header and contains a QDateTime. It is usually added to a
+ QNetworkRequest. The server shall send a 304 (Not Modified) response
+ if the resource has not changed since this time.
+
+ \value ETagHeader Corresponds to the HTTP ETag
+ header and contains a QString representing the last modification
+ state of the contents.
+
+ \value IfMatchHeader Corresponds to the HTTP If-Match
+ header and contains a QStringList. It is usually added to a
+ QNetworkRequest. The server shall send a 412 (Precondition Failed)
+ response if the resource does not match.
+
+ \value IfNoneMatchHeader Corresponds to the HTTP If-None-Match
+ header and contains a QStringList. It is usually added to a
+ QNetworkRequest. The server shall send a 304 (Not Modified) response
+ if the resource does match.
+
\value CookieHeader Corresponds to the HTTP Cookie header
and contains a QList<QNetworkCookie> representing the cookies to
be sent back to the server.
@@ -785,6 +804,18 @@ static QByteArray headerName(QNetworkRequest::KnownHeaders header)
case QNetworkRequest::LastModifiedHeader:
return "Last-Modified";
+ case QNetworkRequest::IfModifiedSinceHeader:
+ return "If-Modified-Since";
+
+ case QNetworkRequest::ETagHeader:
+ return "ETag";
+
+ case QNetworkRequest::IfMatchHeader:
+ return "If-Match";
+
+ case QNetworkRequest::IfNoneMatchHeader:
+ return "If-None-Match";
+
case QNetworkRequest::CookieHeader:
return "Cookie";
@@ -815,6 +846,9 @@ static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVaria
case QNetworkRequest::ContentDispositionHeader:
case QNetworkRequest::UserAgentHeader:
case QNetworkRequest::ServerHeader:
+ case QNetworkRequest::ETagHeader:
+ case QNetworkRequest::IfMatchHeader:
+ case QNetworkRequest::IfNoneMatchHeader:
return value.toByteArray();
case QNetworkRequest::LocationHeader:
@@ -827,6 +861,7 @@ static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVaria
}
case QNetworkRequest::LastModifiedHeader:
+ case QNetworkRequest::IfModifiedSinceHeader:
switch (value.userType()) {
case QMetaType::QDate:
case QMetaType::QDateTime:
@@ -880,32 +915,46 @@ static int parseHeaderName(const QByteArray &headerName)
switch (tolower(headerName.at(0))) {
case 'c':
- if (qstricmp(headerName.constData(), "content-type") == 0)
+ if (headerName.compare("content-type", Qt::CaseInsensitive) == 0)
return QNetworkRequest::ContentTypeHeader;
- else if (qstricmp(headerName.constData(), "content-length") == 0)
+ else if (headerName.compare("content-length", Qt::CaseInsensitive) == 0)
return QNetworkRequest::ContentLengthHeader;
- else if (qstricmp(headerName.constData(), "cookie") == 0)
+ else if (headerName.compare("cookie", Qt::CaseInsensitive) == 0)
return QNetworkRequest::CookieHeader;
else if (qstricmp(headerName.constData(), "content-disposition") == 0)
return QNetworkRequest::ContentDispositionHeader;
break;
+ case 'e':
+ if (qstricmp(headerName.constData(), "etag") == 0)
+ return QNetworkRequest::ETagHeader;
+ break;
+
+ case 'i':
+ if (qstricmp(headerName.constData(), "if-modified-since") == 0)
+ return QNetworkRequest::IfModifiedSinceHeader;
+ if (qstricmp(headerName.constData(), "if-match") == 0)
+ return QNetworkRequest::IfMatchHeader;
+ if (qstricmp(headerName.constData(), "if-none-match") == 0)
+ return QNetworkRequest::IfNoneMatchHeader;
+ break;
+
case 'l':
- if (qstricmp(headerName.constData(), "location") == 0)
+ if (headerName.compare("location", Qt::CaseInsensitive) == 0)
return QNetworkRequest::LocationHeader;
- else if (qstricmp(headerName.constData(), "last-modified") == 0)
+ else if (headerName.compare("last-modified", Qt::CaseInsensitive) == 0)
return QNetworkRequest::LastModifiedHeader;
break;
case 's':
- if (qstricmp(headerName.constData(), "set-cookie") == 0)
+ if (headerName.compare("set-cookie", Qt::CaseInsensitive) == 0)
return QNetworkRequest::SetCookieHeader;
- else if (qstricmp(headerName.constData(), "server") == 0)
+ else if (headerName.compare("server", Qt::CaseInsensitive) == 0)
return QNetworkRequest::ServerHeader;
break;
case 'u':
- if (qstricmp(headerName.constData(), "user-agent") == 0)
+ if (headerName.compare("user-agent", Qt::CaseInsensitive) == 0)
return QNetworkRequest::UserAgentHeader;
break;
}
@@ -936,6 +985,61 @@ static QVariant parseCookieHeader(const QByteArray &raw)
return QVariant::fromValue(result);
}
+static QVariant parseETag(const QByteArray &raw)
+{
+ const QByteArray trimmed = raw.trimmed();
+ if (!trimmed.startsWith('"') && !trimmed.startsWith(R"(W/")"))
+ return QVariant();
+
+ if (!trimmed.endsWith('"'))
+ return QVariant();
+
+ return QString::fromLatin1(trimmed);
+}
+
+static QVariant parseIfMatch(const QByteArray &raw)
+{
+ const QByteArray trimmedRaw = raw.trimmed();
+ if (trimmedRaw == "*")
+ return QStringList(QStringLiteral("*"));
+
+ QStringList tags;
+ const QList<QByteArray> split = trimmedRaw.split(',');
+ for (const QByteArray &element : split) {
+ const QByteArray trimmed = element.trimmed();
+ if (!trimmed.startsWith('"'))
+ continue;
+
+ if (!trimmed.endsWith('"'))
+ continue;
+
+ tags += QString::fromLatin1(trimmed);
+ }
+ return tags;
+}
+
+static QVariant parseIfNoneMatch(const QByteArray &raw)
+{
+ const QByteArray trimmedRaw = raw.trimmed();
+ if (trimmedRaw == "*")
+ return QStringList(QStringLiteral("*"));
+
+ QStringList tags;
+ const QList<QByteArray> split = trimmedRaw.split(',');
+ for (const QByteArray &element : split) {
+ const QByteArray trimmed = element.trimmed();
+ if (!trimmed.startsWith('"') && !trimmed.startsWith(R"(W/")"))
+ continue;
+
+ if (!trimmed.endsWith('"'))
+ continue;
+
+ tags += QString::fromLatin1(trimmed);
+ }
+ return tags;
+}
+
+
static QVariant parseHeaderValue(QNetworkRequest::KnownHeaders header, const QByteArray &value)
{
// header is always a valid value
@@ -963,8 +1067,18 @@ static QVariant parseHeaderValue(QNetworkRequest::KnownHeaders header, const QBy
}
case QNetworkRequest::LastModifiedHeader:
+ case QNetworkRequest::IfModifiedSinceHeader:
return parseHttpDate(value);
+ case QNetworkRequest::ETagHeader:
+ return parseETag(value);
+
+ case QNetworkRequest::IfMatchHeader:
+ return parseIfMatch(value);
+
+ case QNetworkRequest::IfNoneMatchHeader:
+ return parseIfNoneMatch(value);
+
case QNetworkRequest::CookieHeader:
return parseCookieHeader(value);
@@ -983,7 +1097,7 @@ QNetworkHeadersPrivate::findRawHeader(const QByteArray &key) const
RawHeadersList::ConstIterator it = rawHeaders.constBegin();
RawHeadersList::ConstIterator end = rawHeaders.constEnd();
for ( ; it != end; ++it)
- if (qstricmp(it->first.constData(), key.constData()) == 0)
+ if (it->first.compare(key, Qt::CaseInsensitive) == 0)
return it;
return end; // not found
@@ -1064,7 +1178,7 @@ void QNetworkHeadersPrivate::setCookedHeader(QNetworkRequest::KnownHeaders heade
void QNetworkHeadersPrivate::setRawHeaderInternal(const QByteArray &key, const QByteArray &value)
{
auto firstEqualsKey = [&key](const RawHeaderPair &header) {
- return qstricmp(header.first.constData(), key.constData()) == 0;
+ return header.first.compare(key, Qt::CaseInsensitive) == 0;
};
rawHeaders.erase(std::remove_if(rawHeaders.begin(), rawHeaders.end(),
firstEqualsKey),
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index e104c139d9..8462eae8c8 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -63,7 +63,11 @@ public:
SetCookieHeader,
ContentDispositionHeader, // added for QMultipartMessage
UserAgentHeader,
- ServerHeader
+ ServerHeader,
+ IfModifiedSinceHeader,
+ ETagHeader,
+ IfMatchHeader,
+ IfNoneMatchHeader
};
enum Attribute {
HttpStatusCodeAttribute,
diff --git a/src/network/configure.json b/src/network/configure.json
index 4cbc476837..327131ba11 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -14,6 +14,7 @@
"openssl": { "type": "optionalString", "values": [ "no", "yes", "linked", "runtime" ] },
"openssl-linked": { "type": "void", "name": "openssl", "value": "linked" },
"openssl-runtime": { "type": "void", "name": "openssl", "value": "runtime" },
+ "dtls": "boolean",
"sctp": "boolean",
"securetransport": "boolean",
"ssl": "boolean",
@@ -149,6 +150,19 @@
"type": "compile",
"test": "unix/openssl11",
"use": "openssl"
+ },
+ "dtls": {
+ "label": "DTLS support in OpenSSL",
+ "type": "compile",
+ "test": {
+ "include": "openssl/ssl.h",
+ "tail": [
+ "#if defined(OPENSSL_NO_DTLS) || !defined(DTLS1_2_VERSION)",
+ "# error OpenSSL without DTLS support",
+ "#endif"
+ ]
+ },
+ "use": "openssl"
}
},
@@ -184,7 +198,7 @@
"label": "OpenSSL",
"enable": "input.openssl == 'yes' || input.openssl == 'linked' || input.openssl == 'runtime'",
"disable": "input.openssl == 'no' || input.ssl == 'no'",
- "autoDetect": "!config.winrt",
+ "autoDetect": "!config.winrt && !config.wasm",
"condition": "!features.securetransport && (features.openssl-linked || libs.openssl_headers)",
"output": [
"privateFeature",
@@ -216,6 +230,13 @@
"condition": "config.winrt || features.securetransport || features.openssl",
"output": [ "publicFeature", "feature" ]
},
+ "dtls": {
+ "label": "DTLS",
+ "purpose": "Provides a DTLS implementation",
+ "section": "Networking",
+ "condition": "features.openssl && tests.dtls",
+ "output": [ "publicFeature" ]
+ },
"opensslv11": {
"label": "OpenSSL 1.1",
"condition": "features.openssl && tests.openssl11",
@@ -242,6 +263,7 @@
"label": "HTTP",
"purpose": "Provides support for the Hypertext Transfer Protocol in QNetworkAccessManager.",
"section": "Networking",
+ "condition": "features.thread",
"output": [ "publicFeature", "feature" ]
},
"udpsocket": {
@@ -266,6 +288,7 @@
"networkinterface": {
"label": "QNetworkInterface",
"purpose": "Supports enumerating a host's IP addresses and network interfaces.",
+ "condition": "!config.wasm",
"section": "Networking",
"output": [ "publicFeature", "feature" ]
},
@@ -280,7 +303,7 @@
"label": "Bearer management",
"purpose": "Provides bearer management for the network stack.",
"section": "Networking",
- "condition": "features.library && features.networkinterface && features.properties",
+ "condition": "features.thread && features.library && features.networkinterface && features.properties",
"output": [ "publicFeature", "feature" ]
},
"localserver": {
@@ -346,6 +369,7 @@ For example:
"openssl",
"openssl-linked",
"opensslv11",
+ "dtls",
"sctp",
"system-proxies"
]
diff --git a/src/network/configure.pri b/src/network/configure.pri
index f87b7f635f..fa502db1d1 100644
--- a/src/network/configure.pri
+++ b/src/network/configure.pri
@@ -3,7 +3,7 @@
defineTest(qtConfLibrary_openssl) {
libs = $$getenv("OPENSSL_LIBS")
!isEmpty(libs) {
- $${1}.libs = $$libs
+ eval($${1}.libs = $$libs)
export($${1}.libs)
return(true)
}
diff --git a/src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp b/src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp
index 873b74363f..aed74e308e 100644
--- a/src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp
+++ b/src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp
@@ -50,8 +50,8 @@
//! [0]
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
-connect(manager, SIGNAL(finished(QNetworkReply*)),
- this, SLOT(replyFinished(QNetworkReply*)));
+connect(manager, &QNetworkAccessManager::finished,
+ this, &MyClass::replyFinished);
manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
//! [0]
@@ -63,11 +63,11 @@ request.setUrl(QUrl("http://qt-project.org"));
request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
QNetworkReply *reply = manager->get(request);
-connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
-connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
- this, SLOT(slotError(QNetworkReply::NetworkError)));
-connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
- this, SLOT(slotSslErrors(QList<QSslError>)));
+connect(reply, &QIODevice::readyRead, this, &MyClass::slotReadyRead);
+connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
+ this, &MyClass::slotError);
+connect(reply, &QNetworkReply::sslErrors,
+ this, &MyClass::slotSslErrors);
//! [1]
//! [2]
diff --git a/src/network/doc/snippets/code/src_network_ssl_qdtls.cpp b/src/network/doc/snippets/code/src_network_ssl_qdtls.cpp
new file mode 100644
index 0000000000..2132b48338
--- /dev/null
+++ b/src/network/doc/snippets/code/src_network_ssl_qdtls.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+// A client initiates a handshake:
+QUdpSocket clientSocket;
+QDtls clientDtls;
+clientDtls.setPeer(address, port, peerName);
+clientDtls.doHandshake(&clientSocket);
+
+// A server accepting an incoming connection; address, port, clientHello are
+// read by QUdpSocket::readDatagram():
+QByteArray clientHello(serverSocket.pendingDatagramSize(), Qt::Uninitialized);
+QHostAddress address;
+quin16 port = {};
+serverSocket.readDatagram(clientHello.data(), clientHello.size(), &address, &port);
+
+QDtls serverDtls;
+serverDtls.setPeer(address, port);
+serverDtls.doHandshake(&serverSocket, clientHello);
+
+// Handshake completion, both for server and client:
+void DtlsConnection::continueHandshake(const QByteArray &datagram)
+{
+ if (dtls.doHandshake(&udpSocket, datagram)) {
+ // Check handshake status:
+ if (dtls.handshakeStatus() == QDlts::HandshakeComplete) {
+ // Secure DTLS connection is now established.
+ }
+ } else {
+ // Error handling.
+ }
+}
+
+//! [0]
+
+//! [1]
+DtlsClient::DtlsClient()
+{
+ // Some initialization code here ...
+ connect(&clientDtls, &QDtls::handshakeTimeout, this, &DtlsClient::handleTimeout);
+}
+
+void DtlsClient::handleTimeout()
+{
+ clientDtls.handleTimeout(&clientSocket);
+}
+//! [1]
+
+//! [2]
+// Sending an encrypted datagram:
+dtlsConnection.writeDatagramEncrypted(&clientSocket, "Hello DTLS server!");
+
+// Decryption:
+QByteArray encryptedMessage(dgramSize);
+socket.readDatagram(encryptedMessage.data(), dgramSize);
+const QByteArray plainText = dtlsConnection.decryptDatagram(&socket, encryptedMessage);
+//! [2]
+
+//! [3]
+DtlsClient::~DtlsClient()
+{
+ clientDtls.shutdown(&clientSocket);
+}
+//! [3]
+
+//! [4]
+auto config = QSslConfiguration::defaultDtlsConfiguration();
+config.setDtlsCookieVerificationEnabled(false);
+// Some other customization ...
+dtlsConnection.setDtlsConfiguration(config);
+//! [4]
+
+//! [5]
+if (!dtls.doHandshake(&socket, dgram)) {
+ if (dtls.dtlsError() == QDtlsError::PeerVerificationError)
+ dtls.abortAfterError(&socket);
+}
+//! [5]
+
+//! [6]
+QList<QSslCertificate> cert = QSslCertificate::fromPath(QLatin1String("server-certificate.pem"));
+QSslError error(QSslError::SelfSignedCertificate, cert.at(0));
+QList<QSslError> expectedSslErrors;
+expectedSslErrors.append(error);
+
+QDtls dtls;
+dtls.ignoreVerificationErrors(expectedSslErrors);
+dtls.doHandshake(udpSocket);
+//! [6]
+
diff --git a/src/network/doc/snippets/code/src_network_ssl_qdtlscookie.cpp b/src/network/doc/snippets/code/src_network_ssl_qdtlscookie.cpp
new file mode 100644
index 0000000000..a9e596eca5
--- /dev/null
+++ b/src/network/doc/snippets/code/src_network_ssl_qdtlscookie.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+class DtlsServer : public QObject
+{
+public:
+ bool listen(const QHostAddress &address, quint16 port);
+ // ...
+
+private:
+ void readyRead();
+ // ...
+
+ QUdpSocket serverSocket;
+ QDtlsClientVerifier verifier;
+ // ...
+};
+
+bool DtlsServer::listen(const QHostAddress &serverAddress, quint16 serverPort)
+{
+ if (serverSocket.bind(serverAddress, serverPort))
+ connect(&serverSocket, &QUdpSocket::readyRead, this, &DtlsServer::readyRead);
+ return serverSocket.state() == QAbstractSocket::BoundState;
+}
+
+void DtlsServer::readyRead()
+{
+ QByteArray dgram(serverSocket.pendingDatagramSize(), Qt::Uninitialized);
+ QHostAddress address;
+ quint16 port = {};
+ serverSocket.readDatagram(dgram.data(), dgram.size(), &address, &port);
+ if (verifiedClients.contains({address, port}) {
+ // This client was verified previously, we either continue the
+ // handshake or decrypt the incoming message.
+ } else if (verifier.verifyClient(&serverSocket, dgram, address, port)) {
+ // Apparently we have a real DTLS client who wants to send us
+ // encrypted datagrams. Remember this client as verified
+ // and proceed with a handshake.
+ } else {
+ // No matching cookie was found in the incoming datagram,
+ // verifyClient() has sent a ClientVerify message.
+ // We'll hear from the client again soon, if they're real.
+ }
+}
+//! [0]
+
+//! [1]
+void DtlsServer::updateServerSecret()
+{
+ const QByteArray newSecret(generateCryptoStrongSecret());
+ if (newSecret.size()) {
+ usedCookies.append(newSecret);
+ verifier.setCookieGeneratorParameters({QCryptographicHash::Sha1, newSecret});
+ }
+}
+//! [1]
+
+//! [2]
+if (!verifier.verifyClient(&socket, message, address, port)) {
+ switch (verifyClient.dtlsError()) {
+ case QDtlsError::NoError:
+ // Not verified yet, but no errors found and we have to wait for the next
+ // message from this client.
+ return;
+ case QDtlsError::TlsInitializationError:
+ // This error is fatal, nothing we can do about it.
+ // Probably, quit the server after reporting the error.
+ return;
+ case QDtlsError::UnderlyingSocketError:
+ // There is some problem in QUdpSocket, handle it (see QUdpSocket::error())
+ return;
+ case QDtlsError::InvalidInputParameters:
+ default:
+ Q_UNREACHABLE();
+ }
+}
+//! [2]
diff --git a/src/network/doc/src/ssl.qdoc b/src/network/doc/src/ssl.qdoc
index e4948c393c..840cec9e5b 100644
--- a/src/network/doc/src/ssl.qdoc
+++ b/src/network/doc/src/ssl.qdoc
@@ -67,6 +67,15 @@
To disable SSL support in a Qt build, configure Qt with the \c{-no-openssl}
option.
+ \section1 Datagram Transport Layer Security
+
+ Datagram Transport Layer Security (DTLS) is a protocol that enables security
+ for datagram-based applications, providing them with protection against
+ eavesdropping, tampering, or message forgery. The DTLS protocol is based on the
+ stream-oriented Transport Layer Security (TLS) protocol. QtNetwork enables
+ the use of DTLS with User Datagram Protocol (UDP), as defined by
+ \l {https://tools.ietf.org/html/rfc6347}{RFC 6347}.
+
\section1 Import and Export Restrictions
Due to import and export restrictions in some parts of the world, we
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index c995e3fef2..34db5b4b31 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -412,7 +412,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
QByteArray headerVal;
for (int i = 0; i < values.size(); ++i) {
const QPair<QByteArray, QByteArray> &current = values.at(i);
- if (current.first.toLower() != search)
+ if (current.first.compare(search, Qt::CaseInsensitive) != 0)
continue;
QByteArray str = current.second.toLower();
if (method < Basic && str.startsWith("basic")) {
@@ -443,7 +443,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
break;
case DigestMd5: {
this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
- if (options.value("stale").toLower() == "true")
+ if (options.value("stale").compare("true", Qt::CaseInsensitive) == 0)
phase = Start;
if (user.isEmpty() && password.isEmpty())
phase = Done;
@@ -630,7 +630,7 @@ static QByteArray digestMd5ResponseHelper(
hash.addData(":", 1);
hash.addData(password);
QByteArray ha1 = hash.result();
- if (alg.toLower() == "md5-sess") {
+ if (alg.compare("md5-sess", Qt::CaseInsensitive) == 0) {
hash.reset();
// RFC 2617 contains an error, it was:
// hash.addData(ha1);
@@ -650,7 +650,7 @@ static QByteArray digestMd5ResponseHelper(
hash.addData(method);
hash.addData(":", 1);
hash.addData(digestUri);
- if (qop.toLower() == "auth-int") {
+ if (qop.compare("auth-int", Qt::CaseInsensitive) == 0) {
hash.addData(":", 1);
hash.addData(hEntity);
}
diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp
index bea24b0af2..c51e9968f8 100644
--- a/src/network/kernel/qhostinfo_win.cpp
+++ b/src/network/kernel/qhostinfo_win.cpp
@@ -92,13 +92,13 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
sockaddr *sa;
QT_SOCKLEN_T saSize;
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
- sa = (sockaddr *)&sa4;
+ sa = reinterpret_cast<sockaddr *>(&sa4);
saSize = sizeof(sa4);
memset(&sa4, 0, sizeof(sa4));
sa4.sin_family = AF_INET;
sa4.sin_addr.s_addr = htonl(address.toIPv4Address());
} else {
- sa = (sockaddr *)&sa6;
+ sa = reinterpret_cast<sockaddr *>(&sa6);
saSize = sizeof(sa6);
memset(&sa6, 0, sizeof(sa6));
sa6.sin6_family = AF_INET6;
@@ -132,14 +132,14 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
switch (p->ai_family) {
case AF_INET: {
QHostAddress addr;
- addr.setAddress(ntohl(((sockaddr_in *) p->ai_addr)->sin_addr.s_addr));
+ addr.setAddress(ntohl(reinterpret_cast<sockaddr_in *>(p->ai_addr)->sin_addr.s_addr));
if (!addresses.contains(addr))
addresses.append(addr);
}
break;
case AF_INET6: {
QHostAddress addr;
- addr.setAddress(((sockaddr_in6 *) p->ai_addr)->sin6_addr.s6_addr);
+ addr.setAddress(reinterpret_cast<const sockaddr_in6 *>(p->ai_addr)->sin6_addr.s6_addr);
if (!addresses.contains(addr))
addresses.append(addr);
}
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 150553f673..a8d56a9b11 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -74,15 +74,16 @@ static QHostAddress addressFromSockaddr(sockaddr *sa)
if (!sa)
return address;
- if (sa->sa_family == AF_INET)
- address.setAddress(htonl(((sockaddr_in *)sa)->sin_addr.s_addr));
- else if (sa->sa_family == AF_INET6) {
- address.setAddress(((sockaddr_in6 *)sa)->sin6_addr.s6_addr);
- int scope = ((sockaddr_in6 *)sa)->sin6_scope_id;
- if (scope)
- address.setScopeId(QNetworkInterfaceManager::interfaceNameFromIndex(scope));
- } else
+ if (sa->sa_family == AF_INET) {
+ address.setAddress(htonl(reinterpret_cast<const sockaddr_in *>(sa)->sin_addr.s_addr));
+ } else if (sa->sa_family == AF_INET6) {
+ auto sai6 = reinterpret_cast<const sockaddr_in6 *>(sa);
+ address.setAddress(sai6->sin6_addr.s6_addr);
+ if (sai6->sin6_scope_id)
+ address.setScopeId(QNetworkInterfaceManager::interfaceNameFromIndex(sai6->sin6_scope_id));
+ } else {
qWarning("Got unknown socket family %d", sa->sa_family);
+ }
return address;
}
@@ -121,7 +122,7 @@ static QList<QNetworkInterfacePrivate *> interfaceListing()
ULONG retval = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize);
if (retval == ERROR_BUFFER_OVERFLOW) {
// need more memory
- pAdapter = (IP_ADAPTER_ADDRESSES *)malloc(bufSize);
+ pAdapter = reinterpret_cast<IP_ADAPTER_ADDRESSES *>(malloc(bufSize));
if (!pAdapter)
return interfaces;
// try again
@@ -255,7 +256,7 @@ QString QHostInfo::localDomainName()
ULONG bufSize = sizeof info;
pinfo = &info;
if (GetNetworkParams(pinfo, &bufSize) == ERROR_BUFFER_OVERFLOW) {
- pinfo = (FIXED_INFO *)malloc(bufSize);
+ pinfo = reinterpret_cast<FIXED_INFO *>(malloc(bufSize));
if (!pinfo)
return QString();
// try again
diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp
index 949f9fe12b..db51732bd3 100644
--- a/src/network/kernel/qnetworkproxy_win.cpp
+++ b/src/network/kernel/qnetworkproxy_win.cpp
@@ -370,7 +370,10 @@ static QList<QNetworkProxy> parseServerList(const QNetworkProxyQuery &query, con
#if !defined(Q_OS_WINRT)
namespace {
class QRegistryWatcher {
+ Q_DISABLE_COPY(QRegistryWatcher)
public:
+ QRegistryWatcher() = default;
+
void addLocation(HKEY hive, const QString& path)
{
HKEY openedKey;
@@ -422,6 +425,7 @@ private:
class QWindowsSystemProxy
{
+ Q_DISABLE_COPY(QWindowsSystemProxy)
public:
QWindowsSystemProxy();
~QWindowsSystemProxy();
@@ -566,7 +570,7 @@ void QWindowsSystemProxy::init()
WINHTTP_AUTO_DETECT_TYPE_DNS_A;
} else {
autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
- autoProxyOptions.lpszAutoConfigUrl = (LPCWSTR)autoConfigUrl.utf16();
+ autoProxyOptions.lpszAutoConfigUrl = reinterpret_cast<LPCWSTR>(autoConfigUrl.utf16());
}
}
@@ -608,7 +612,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
}
bool getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession,
- (LPCWSTR)urlQueryString.utf16(),
+ reinterpret_cast<LPCWSTR>(urlQueryString.utf16()),
&sp->autoProxyOptions,
&proxyInfo);
DWORD getProxyError = GetLastError();
@@ -623,9 +627,10 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
} else {
//pac file URL is specified as well, try using that
sp->autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
- sp->autoProxyOptions.lpszAutoConfigUrl = (LPCWSTR)sp->autoConfigUrl.utf16();
+ sp->autoProxyOptions.lpszAutoConfigUrl =
+ reinterpret_cast<LPCWSTR>(sp->autoConfigUrl.utf16());
getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession,
- (LPCWSTR)urlQueryString.utf16(),
+ reinterpret_cast<LPCWSTR>(urlQueryString.utf16()),
&sp->autoProxyOptions,
&proxyInfo);
getProxyError = GetLastError();
@@ -638,7 +643,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
// But now we've to enable it (http://msdn.microsoft.com/en-us/library/aa383153%28v=VS.85%29.aspx)
sp->autoProxyOptions.fAutoLogonIfChallenged = TRUE;
getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession,
- (LPCWSTR)urlQueryString.utf16(),
+ reinterpret_cast<LPCWSTR>(urlQueryString.utf16()),
&sp->autoProxyOptions,
&proxyInfo);
getProxyError = GetLastError();
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 13e10e4102..4d9fda00ce 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1609,7 +1609,10 @@ bool QAbstractSocketPrivate::bind(const QHostAddress &address, quint16 port, QAb
localPort = socketEngine->localPort();
emit q->stateChanged(state);
- if (socketType == QAbstractSocket::UdpSocket)
+ // A slot attached to stateChanged() signal can break our invariant:
+ // by closing the socket it will reset its socket engine - thus we
+ // have additional check (isValid()) ...
+ if (q->isValid() && socketType == QAbstractSocket::UdpSocket)
socketEngine->setReadNotificationEnabled(true);
return true;
}
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index b543ea7981..9427c3b00d 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -627,10 +627,9 @@ void QHttpSocketEngine::slotSocketReadNotification()
// from http spec is also allowed.
if (proxyConnectionHeader.isEmpty())
proxyConnectionHeader = d->reply->headerField("Connection");
- proxyConnectionHeader = proxyConnectionHeader.toLower();
- if (proxyConnectionHeader == "close") {
+ if (proxyConnectionHeader.compare("close", Qt::CaseSensitive) == 0) {
willClose = true;
- } else if (proxyConnectionHeader == "keep-alive") {
+ } else if (proxyConnectionHeader.compare("keep-alive", Qt::CaseInsensitive) == 0) {
willClose = false;
} else {
// no Proxy-Connection header, so use the default
diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp
index ced923ced1..2d71a7e730 100644
--- a/src/network/socket/qlocalserver_win.cpp
+++ b/src/network/socket/qlocalserver_win.cpp
@@ -89,7 +89,7 @@ bool QLocalServerPrivate::addListener()
DWORD dwBufferSize = 0;
GetTokenInformation(hToken, TokenUser, 0, 0, &dwBufferSize);
tokenUserBuffer.fill(0, dwBufferSize);
- PTOKEN_USER pTokenUser = (PTOKEN_USER)tokenUserBuffer.data();
+ auto pTokenUser = reinterpret_cast<PTOKEN_USER>(tokenUserBuffer.data());
if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwBufferSize, &dwBufferSize)) {
setError(QLatin1String("QLocalServerPrivate::addListener"));
CloseHandle(hToken);
@@ -99,7 +99,7 @@ bool QLocalServerPrivate::addListener()
dwBufferSize = 0;
GetTokenInformation(hToken, TokenPrimaryGroup, 0, 0, &dwBufferSize);
tokenGroupBuffer.fill(0, dwBufferSize);
- PTOKEN_PRIMARY_GROUP pTokenGroup = (PTOKEN_PRIMARY_GROUP)tokenGroupBuffer.data();
+ auto pTokenGroup = reinterpret_cast<PTOKEN_PRIMARY_GROUP>(tokenGroupBuffer.data());
if (!GetTokenInformation(hToken, TokenPrimaryGroup, pTokenGroup, dwBufferSize, &dwBufferSize)) {
setError(QLatin1String("QLocalServerPrivate::addListener"));
CloseHandle(hToken);
@@ -140,7 +140,7 @@ bool QLocalServerPrivate::addListener()
aclSize = (aclSize + (sizeof(DWORD) - 1)) & 0xfffffffc;
aclBuffer.fill(0, aclSize);
- PACL acl = (PACL)aclBuffer.data();
+ auto acl = reinterpret_cast<PACL>(aclBuffer.data());
InitializeAcl(acl, aclSize, ACL_REVISION_DS);
if (socketOptions & QLocalServer::UserAccessOption) {
@@ -176,7 +176,7 @@ bool QLocalServerPrivate::addListener()
}
listener.handle = CreateNamedPipe(
- (const wchar_t *)fullServerName.utf16(), // pipe name
+ reinterpret_cast<const wchar_t *>(fullServerName.utf16()), // pipe name
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access
PIPE_TYPE_BYTE | // byte type pipe
PIPE_READMODE_BYTE | // byte-read mode
@@ -299,7 +299,7 @@ void QLocalServerPrivate::_q_onNewConnection()
tryAgain = true;
// Make this the last thing so connected slots can wreak the least havoc
- q->incomingConnection((quintptr)handle);
+ q->incomingConnection(reinterpret_cast<quintptr>(handle));
} else {
if (GetLastError() != ERROR_IO_INCOMPLETE) {
q->close();
diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp
index 6fec2fdbd2..1c34cd13ee 100644
--- a/src/network/socket/qlocalsocket.cpp
+++ b/src/network/socket/qlocalsocket.cpp
@@ -368,7 +368,7 @@ QLocalSocket::QLocalSocket(QObject * parent)
*/
QLocalSocket::~QLocalSocket()
{
- close();
+ QLocalSocket::close();
#if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)
Q_D(QLocalSocket);
d->unixSocket.setParent(0);
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index ae94cb9d51..8e20f9efbe 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -155,7 +155,7 @@ void QLocalSocket::connectToServer(OpenMode openMode)
forever {
DWORD permissions = (openMode & QIODevice::ReadOnly) ? GENERIC_READ : 0;
permissions |= (openMode & QIODevice::WriteOnly) ? GENERIC_WRITE : 0;
- localSocket = CreateFile((const wchar_t *)d->fullServerName.utf16(), // pipe name
+ localSocket = CreateFile(reinterpret_cast<const wchar_t *>(d->fullServerName.utf16()), // pipe name
permissions,
0, // no sharing
NULL, // default security attributes
@@ -183,7 +183,7 @@ void QLocalSocket::connectToServer(OpenMode openMode)
}
// we have a valid handle
- if (setSocketDescriptor((qintptr)localSocket, ConnectedState, openMode))
+ if (setSocketDescriptor(reinterpret_cast<qintptr>(localSocket), ConnectedState, openMode))
emit connected();
}
@@ -371,7 +371,7 @@ void QLocalSocketPrivate::_q_canWrite()
qintptr QLocalSocket::socketDescriptor() const
{
Q_D(const QLocalSocket);
- return (qintptr)d->handle;
+ return reinterpret_cast<qintptr>(d->handle);
}
qint64 QLocalSocket::readBufferSize() const
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 1b84b26d83..c999bd2088 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -294,7 +294,8 @@ static inline QAbstractSocket::SocketType qt_socket_getType(qintptr socketDescri
{
int value = 0;
QT_SOCKLEN_T valueSize = sizeof(value);
- if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_TYPE, (char *) &value, &valueSize) != 0) {
+ if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_TYPE,
+ reinterpret_cast<char *>(&value), &valueSize) != 0) {
WS_ERROR_DEBUG(WSAGetLastError());
} else {
if (value == SOCK_STREAM)
@@ -361,7 +362,7 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
#ifdef HANDLE_FLAG_INHERIT
if (socket != INVALID_SOCKET) {
// make non inheritable the old way
- BOOL handleFlags = SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0);
+ BOOL handleFlags = SetHandleInformation(reinterpret_cast<HANDLE>(socket), HANDLE_FLAG_INHERIT, 0);
#ifdef QNATIVESOCKETENGINE_DEBUG
qDebug() << "QNativeSocketEnginePrivate::createNewSocket - set inheritable" << handleFlags;
#else
@@ -1443,7 +1444,7 @@ qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len)
for (;;) {
WSABUF buf;
- buf.buf = (char*)data + ret;
+ buf.buf = const_cast<char*>(data) + ret;
buf.len = bytesToSend;
DWORD flags = 0;
DWORD bytesWritten = 0;
diff --git a/src/network/ssl/qasn1element_p.h b/src/network/ssl/qasn1element_p.h
index 2c5019b4f7..2068254a95 100644
--- a/src/network/ssl/qasn1element_p.h
+++ b/src/network/ssl/qasn1element_p.h
@@ -58,10 +58,62 @@
QT_BEGIN_NAMESPACE
-#define RSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.113549.1.1.1")
+// General
+#define RSADSI_OID "1.2.840.113549."
+
+#define RSA_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.1.1")
#define DSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10040.4.1")
#define EC_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10045.2.1")
+// These are mostly from the RFC for PKCS#5
+// PKCS#5: https://tools.ietf.org/html/rfc8018#appendix-B
+#define PKCS5_OID RSADSI_OID "1.5."
+// PKCS#12: https://tools.ietf.org/html/rfc7292#appendix-D)
+#define PKCS12_OID RSADSI_OID "1.12."
+
+// -PBES1
+#define PKCS5_MD2_DES_CBC_OID QByteArrayLiteral(PKCS5_OID "1") // Not (yet) implemented
+#define PKCS5_MD2_RC2_CBC_OID QByteArrayLiteral(PKCS5_OID "4") // Not (yet) implemented
+#define PKCS5_MD5_DES_CBC_OID QByteArrayLiteral(PKCS5_OID "3")
+#define PKCS5_MD5_RC2_CBC_OID QByteArrayLiteral(PKCS5_OID "6")
+#define PKCS5_SHA1_DES_CBC_OID QByteArrayLiteral(PKCS5_OID "10")
+#define PKCS5_SHA1_RC2_CBC_OID QByteArrayLiteral(PKCS5_OID "11")
+#define PKCS12_SHA1_RC4_128_OID QByteArrayLiteral(PKCS12_OID "1.1") // Not (yet) implemented
+#define PKCS12_SHA1_RC4_40_OID QByteArrayLiteral(PKCS12_OID "1.2") // Not (yet) implemented
+#define PKCS12_SHA1_3KEY_3DES_CBC_OID QByteArrayLiteral(PKCS12_OID "1.3")
+#define PKCS12_SHA1_2KEY_3DES_CBC_OID QByteArrayLiteral(PKCS12_OID "1.4")
+#define PKCS12_SHA1_RC2_128_CBC_OID QByteArrayLiteral(PKCS12_OID "1.5")
+#define PKCS12_SHA1_RC2_40_CBC_OID QByteArrayLiteral(PKCS12_OID "1.6")
+
+// -PBKDF2
+#define PKCS5_PBKDF2_ENCRYPTION_OID QByteArrayLiteral(PKCS5_OID "12")
+
+// -PBES2
+#define PKCS5_PBES2_ENCRYPTION_OID QByteArrayLiteral(PKCS5_OID "13")
+
+// Digest
+#define DIGEST_ALGORITHM_OID RSADSI_OID "2."
+// -HMAC-SHA-1
+#define HMAC_WITH_SHA1 QByteArrayLiteral(DIGEST_ALGORITHM_OID "7")
+// -HMAC-SHA-2
+#define HMAC_WITH_SHA224 QByteArrayLiteral(DIGEST_ALGORITHM_OID "8")
+#define HMAC_WITH_SHA256 QByteArrayLiteral(DIGEST_ALGORITHM_OID "9")
+#define HMAC_WITH_SHA384 QByteArrayLiteral(DIGEST_ALGORITHM_OID "10")
+#define HMAC_WITH_SHA512 QByteArrayLiteral(DIGEST_ALGORITHM_OID "11")
+#define HMAC_WITH_SHA512_224 QByteArrayLiteral(DIGEST_ALGORITHM_OID "12")
+#define HMAC_WITH_SHA512_256 QByteArrayLiteral(DIGEST_ALGORITHM_OID "13")
+
+// Encryption algorithms
+#define ENCRYPTION_ALGORITHM_OID RSADSI_OID "3."
+#define DES_CBC_ENCRYPTION_OID QByteArrayLiteral("1.3.14.3.2.7")
+#define DES_EDE3_CBC_ENCRYPTION_OID QByteArrayLiteral(ENCRYPTION_ALGORITHM_OID "7")
+#define RC2_CBC_ENCRYPTION_OID QByteArrayLiteral(ENCRYPTION_ALGORITHM_OID "2")
+#define RC5_CBC_ENCRYPTION_OID QByteArrayLiteral(ENCRYPTION_ALGORITHM_OID "9") // Not (yet) implemented
+#define AES_OID "2.16.840.1.101.3.4.1."
+#define AES128_CBC_ENCRYPTION_OID QByteArrayLiteral(AES_OID "2")
+#define AES192_CBC_ENCRYPTION_OID QByteArrayLiteral(AES_OID "22") // Not (yet) implemented
+#define AES256_CBC_ENCRYPTION_OID QByteArrayLiteral(AES_OID "42") // Not (yet) implemented
+
class Q_AUTOTEST_EXPORT QAsn1Element
{
public:
diff --git a/src/network/ssl/qdtls.cpp b/src/network/ssl/qdtls.cpp
new file mode 100644
index 0000000000..bbb22aa527
--- /dev/null
+++ b/src/network/ssl/qdtls.cpp
@@ -0,0 +1,1163 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsslconfiguration.h"
+#include "qdtls_openssl_p.h"
+#include "qudpsocket.h"
+#include "qdtls_p.h"
+#include "qssl_p.h"
+#include "qdtls.h"
+
+#include "qglobal.h"
+
+/*!
+ \class QDtlsClientVerifier
+ \brief This class implements server-side DTLS cookie generation and verification.
+ \since 5.12
+
+ \ingroup network
+ \ingroup ssl
+ \inmodule QtNetwork
+
+ The QDtlsClientVerifier class implements server-side DTLS cookie generation
+ and verification. Datagram security protocols are highly susceptible to a
+ variety of Denial-of-Service attacks. According to \l {https://tools.ietf.org/html/rfc6347#section-4.2.1}{RFC 6347, section 4.2.1},
+ these are two of the more common types of attack:
+
+ \list
+ \li An attacker transmits a series of handshake initiation requests, causing
+ a server to allocate excessive resources and potentially perform expensive
+ cryptographic operations.
+ \li An attacker transmits a series of handshake initiation requests with
+ a forged source of the victim, making the server act as an amplifier.
+ Normally, the server would reply to the victim machine with a Certificate message,
+ which can be quite large, thus flooding the victim machine with datagrams.
+ \endlist
+
+ As a countermeasure to these attacks, \l {https://tools.ietf.org/html/rfc6347#section-4.2.1}{RFC 6347, section 4.2.1}
+ proposes a stateless cookie technique that a server may deploy:
+
+ \list
+ \li In response to the initial ClientHello message, the server sends a HelloVerifyRequest,
+ which contains a cookie. This cookie is a cryptographic hash and is generated using the
+ client's address, port number, and the server's secret (which is a cryptographically strong
+ pseudo-random sequence of bytes).
+ \li A reachable DTLS client is expected to reply with a new ClientHello message
+ containing this cookie.
+ \li When the server receives the ClientHello message with a cookie, it
+ generates a new cookie as described above. This new cookie is compared to the
+ one found in the ClientHello message.
+ \li In the cookies are equal, the client is considered to be real, and the
+ server can continue with a TLS handshake procedure.
+ \endlist
+
+ \note A DTLS server is not required to use DTLS cookies.
+
+ QDtlsClientVerifier is designed to work in pair with QUdpSocket, as shown in
+ the following code-excerpt:
+
+ \snippet code/src_network_ssl_qdtlscookie.cpp 0
+
+ QDtlsClientVerifier does not impose any restrictions on how the application uses
+ QUdpSocket. For example, it is possible to have a server with a single QUdpSocket
+ in state QAbstractSocket::BoundState, handling multiple DTLS clients
+ simultaneously:
+
+ \list
+ \li Testing if new clients are real DTLS-capable clients.
+ \li Completing TLS handshakes with the verified clients (see QDtls).
+ \li Decrypting datagrams coming from the connected clients (see QDtls).
+ \li Sending encrypted datagrams to the connected clients (see QDtls).
+ \endlist
+
+ This implies that QDtlsClientVerifier does not read directly from a socket,
+ instead it expects the application to read an incoming datagram, extract the
+ sender's address, and port, and then pass this data to verifyClient().
+ To send a HelloVerifyRequest message, verifyClient() can write to the QUdpSocket.
+
+ \note QDtlsClientVerifier does not take ownership of the QUdpSocket object.
+
+ By default QDtlsClientVerifier obtains its secret from a cryptographically
+ strong pseudorandom number generator.
+
+ \note The default secret is shared by all objects of the classes QDtlsClientVerifier
+ and QDtls. Since this can impose security risks, RFC 6347 recommends to change
+ the server's secret frequently. Please see \l {https://tools.ietf.org/html/rfc6347}{RFC 6347, section 4.2.1}
+ for hints about possible server implementations. Cookie generator parameters
+ can be set using the class QDtlsClientVerifier::GeneratorParameters and
+ setCookieGeneratorParameters():
+
+ \snippet code/src_network_ssl_qdtlscookie.cpp 1
+
+ The \l{secureudpserver}{DTLS server} example illustrates how to use
+ QDtlsClientVerifier in a server application.
+
+ \sa QUdpSocket, QAbstractSocket::BoundState, QDtls, verifyClient(),
+ GeneratorParameters, setCookieGeneratorParameters(), cookieGeneratorParameters(),
+ QDtls::setCookieGeneratorParameters(),
+ QDtls::cookieGeneratorParameters(),
+ QCryptographicHash::Algorithm,
+ QDtlsError, dtlsError(), dtlsErrorString()
+*/
+
+/*!
+ \class QDtlsClientVerifier::GeneratorParameters
+ \brief This class defines parameters for DTLS cookie generator.
+ \since 5.12
+
+ \ingroup network
+ \ingroup ssl
+ \inmodule QtNetwork
+
+ An object of this class provides the parameters that QDtlsClientVerifier
+ will use to generate DTLS cookies. They include a cryptographic hash
+ algorithm and a secret.
+
+ \note An empty secret is considered to be invalid by
+ QDtlsClientVerifier::setCookieGeneratorParameters().
+
+ \sa QDtlsClientVerifier::setCookieGeneratorParameters(),
+ QDtlsClientVerifier::cookieGeneratorParameters(),
+ QDtls::setCookieGeneratorParameters(),
+ QDtls::cookieGeneratorParameters(),
+ QCryptographicHash::Algorithm
+*/
+
+/*!
+ \enum QDtlsError
+ \brief Describes errors that can be found by QDtls and QDtlsClientVerifier.
+ \relates QDtls
+ \since 5.12
+
+ \ingroup network
+ \ingroup ssl
+ \inmodule QtNetwork
+
+ This enum describes general and TLS-specific errors that can be encountered
+ by objects of the classes QDtlsClientVerifier and QDtls.
+
+ \value NoError No error occurred, the last operation was successful.
+ \value InvalidInputParameters Input parameters provided by a caller were
+ invalid.
+ \value InvalidOperation An operation was attempted in a state that did not
+ permit it.
+ \value UnderlyingSocketError QUdpSocket::writeDatagram() failed, QUdpSocket::error()
+ and QUdpSocket::errorString() can provide more specific information.
+ \value RemoteClosedConnectionError TLS shutdown alert message was received.
+ \value PeerVerificationError Peer's identity could not be verified during the
+ TLS handshake.
+ \value TlsInitializationError An error occurred while initializing an underlying
+ TLS backend.
+ \value TlsFatalError A fatal error occurred during TLS handshake, other
+ than peer verification error or TLS initialization error.
+ \value TlsNonFatalError A failure to encrypt or decrypt a datagram, non-fatal,
+ meaning QDtls can continue working after this error.
+*/
+
+/*!
+ \class QDtls
+ \brief This class provides encryption for UDP sockets.
+ \since 5.12
+
+ \ingroup network
+ \ingroup ssl
+ \inmodule QtNetwork
+
+ The QDtls class can be used to establish a secure connection with a network
+ peer using User Datagram Protocol (UDP). DTLS connection over essentially
+ connectionless UDP means that two peers first have to successfully complete
+ a TLS handshake by calling doHandshake(). After the handshake has completed,
+ encrypted datagrams can be sent to the peer using writeDatagramEncrypted().
+ Encrypted datagrams coming from the peer can be decrypted by decryptDatagram().
+
+ QDtls is designed to work with QUdpSocket. Since QUdpSocket can receive
+ datagrams coming from different peers, an application must implement
+ demultiplexing, forwarding datagrams coming from different peers to their
+ corresponding instances of QDtls. An association between a network peer
+ and its QDtls object can be established using the peer's address and port
+ number. Before starting a handshake, the application must set the peer's
+ address and port number using setPeer().
+
+ QDtls does not read datagrams from QUdpSocket, this is expected to be done by
+ the application, for example, in a slot attached to the QUdpSocket::readyRead()
+ signal. Then, these datagrams must be processed by QDtls.
+
+ \note QDtls does \e not take ownership of the QUdpSocket object.
+
+ Normally, several datagrams are to be received and sent by both peers during
+ the handshake phase. Upon reading datagrams, server and client must pass these
+ datagrams to doHandshake() until some error is found or handshakeState()
+ returns HandshakeComplete:
+
+ \snippet code/src_network_ssl_qdtls.cpp 0
+
+ For a server, the first call to doHandshake() requires a non-empty datagram
+ containing a ClientHello message. If the server also deploys QDtlsClientVerifier,
+ the first ClientHello message is expected to be the one verified by QDtlsClientVerifier.
+
+ In case the peer's identity cannot be validated during the handshake, the application
+ must inspect errors returned by peerVerificationErrors() and then either
+ ignore errors by calling ignoreVerificationErrors() or abort the handshake
+ by calling abortHandshake(). If errors were ignored, the handshake can be
+ resumed by calling resumeHandshake().
+
+ After the handshake has been completed, datagrams can be sent to and received
+ from the network peer securely:
+
+ \snippet code/src_network_ssl_qdtls.cpp 2
+
+ A DTLS connection may be closed using shutdown().
+
+ \snippet code/src_network_ssl_qdtls.cpp 3
+
+ \warning It's recommended to call shutdown() before destroying the client's QDtls
+ object if you are planning to re-use the same port number to connect to the
+ server later. Otherwise, the server may drop incoming ClientHello messages,
+ see \l{https://tools.ietf.org/html/rfc6347#page-25}{RFC 6347, section 4.2.8}
+ for more details and implementation hints.
+
+ If the server does not use QDtlsClientVerifier, it \e must configure its
+ QDtls objects to disable the cookie verification procedure:
+
+ \snippet code/src_network_ssl_qdtls.cpp 4
+
+ A server that uses cookie verification with non-default generator parameters
+ \e must set the same parameters for its QDtls object before starting the handshake.
+
+ \note The DTLS protocol leaves Path Maximum Transmission Unit (PMTU) discovery
+ to the application. The application may provide QDtls with the MTU using
+ setMtuHint(). This hint affects only the handshake phase, since only handshake
+ messages can be fragmented and reassembled by the DTLS. All other messages sent
+ by the application must fit into a single datagram.
+ \note DTLS-specific headers add some overhead to application data further
+ reducing the possible message size.
+ \warning A server configured to reply with HelloVerifyRequest will drop
+ all fragmented ClientHello messages, never starting a handshake.
+
+ The \l{secureudpserver}{DTLS server} and \l{secureudpclient}{DTLS client}
+ examples illustrate how to use QDtls in applications.
+
+ \sa QUdpSocket, QDtlsClientVerifier, HandshakeState, QDtlsError, QSslConfiguration
+*/
+
+/*!
+ \typedef QDtls::GeneratorParameters
+
+ This is a synonym for QDtlsClientVerifier::GeneratorParameters.
+*/
+
+/*!
+ \fn void QDtls::handshakeTimeout()
+
+ Packet loss can result in timeouts during the handshake phase. In this case
+ QDtls emits a handshakeTimeout() signal. Call handleTimeout() to retransmit
+ the handshake messages:
+
+ \snippet code/src_network_ssl_qdtls.cpp 1
+
+ \sa handleTimeout()
+*/
+
+/*!
+ \fn void QDtls::pskRequired(QSslPreSharedKeyAuthenticator *authenticator)
+
+ QDtls emits this signal when it negotiates a PSK ciphersuite, and therefore
+ a PSK authentication is then required.
+
+ When using PSK, the client must send to the server a valid identity and a
+ valid pre shared key, in order for the TLS handshake to continue.
+ Applications can provide this information in a slot connected to this
+ signal, by filling in the passed \a authenticator object according to their
+ needs.
+
+ \note Ignoring this signal, or failing to provide the required credentials,
+ will cause the handshake to fail, and therefore the connection to be aborted.
+
+ \note The \a authenticator object is owned by QDtls and must not be deleted
+ by the application.
+
+ \sa QSslPreSharedKeyAuthenticator
+*/
+
+/*!
+ \enum QDtls::HandshakeState
+ \brief Describes the current state of DTLS handshake.
+ \since 5.12
+
+ \ingroup network
+ \ingroup ssl
+ \inmodule QtNetwork
+
+ This enum describes the current state of DTLS handshake for a QDtls
+ connection.
+
+ \value HandshakeNotStarted Nothing done yet.
+ \value HandshakeInProgress Handshake was initiated and no errors were found so far.
+ \value PeerVerificationFailed The identity of the peer can't be established.
+ \value HandshakeComplete Handshake completed successfully and encrypted connection
+ was established.
+
+ \sa QDtls::doHandshake(), QDtls::handshakeState()
+*/
+
+
+QT_BEGIN_NAMESPACE
+
+QSslConfiguration QDtlsBasePrivate::configuration() const
+{
+ auto copyPrivate = new QSslConfigurationPrivate(dtlsConfiguration);
+ copyPrivate->ref.store(0); // the QSslConfiguration constructor refs up
+ QSslConfiguration copy(copyPrivate);
+ copyPrivate->sessionCipher = sessionCipher;
+ copyPrivate->sessionProtocol = sessionProtocol;
+
+ return copy;
+}
+
+void QDtlsBasePrivate::setConfiguration(const QSslConfiguration &configuration)
+{
+ dtlsConfiguration.localCertificateChain = configuration.localCertificateChain();
+ dtlsConfiguration.privateKey = configuration.privateKey();
+ dtlsConfiguration.ciphers = configuration.ciphers();
+ dtlsConfiguration.ellipticCurves = configuration.ellipticCurves();
+ dtlsConfiguration.preSharedKeyIdentityHint = configuration.preSharedKeyIdentityHint();
+ dtlsConfiguration.dhParams = configuration.diffieHellmanParameters();
+ dtlsConfiguration.caCertificates = configuration.caCertificates();
+ dtlsConfiguration.peerVerifyDepth = configuration.peerVerifyDepth();
+ dtlsConfiguration.peerVerifyMode = configuration.peerVerifyMode();
+ dtlsConfiguration.protocol = configuration.protocol();
+ dtlsConfiguration.sslOptions = configuration.d->sslOptions;
+ dtlsConfiguration.sslSession = configuration.sessionTicket();
+ dtlsConfiguration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
+ dtlsConfiguration.nextAllowedProtocols = configuration.allowedNextProtocols();
+ dtlsConfiguration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
+ dtlsConfiguration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
+ dtlsConfiguration.dtlsCookieEnabled = configuration.dtlsCookieVerificationEnabled();
+ dtlsConfiguration.allowRootCertOnDemandLoading = configuration.d->allowRootCertOnDemandLoading;
+
+ clearDtlsError();
+}
+
+bool QDtlsBasePrivate::setCookieGeneratorParameters(QCryptographicHash::Algorithm alg,
+ const QByteArray &key)
+{
+ if (!key.size()) {
+ setDtlsError(QDtlsError::InvalidInputParameters,
+ QDtls::tr("Invalid (empty) secret"));
+ return false;
+ }
+
+ clearDtlsError();
+
+ hashAlgorithm = alg;
+ secret = key;
+
+ return true;
+}
+
+bool QDtlsBasePrivate::isDtlsProtocol(QSsl::SslProtocol protocol)
+{
+ switch (protocol) {
+ case QSsl::DtlsV1_0:
+ case QSsl::DtlsV1_0OrLater:
+ case QSsl::DtlsV1_2:
+ case QSsl::DtlsV1_2OrLater:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static QString msgUnsupportedMulticastAddress()
+{
+ return QDtls::tr("Multicast and broadcast addresses are not supported");
+}
+
+/*!
+ Default constructs GeneratorParameters object with QCryptographicHash::Sha1
+ as its algorithm and an empty secret.
+
+ \sa QDtlsClientVerifier::setCookieGeneratorParameters(),
+ QDtlsClientVerifier::cookieGeneratorParameters(),
+ QDtls::setCookieGeneratorParameters(),
+ QDtls::cookieGeneratorParameters()
+ */
+QDtlsClientVerifier::GeneratorParameters::GeneratorParameters()
+{
+}
+
+/*!
+ Constructs GeneratorParameters object from \a algorithm and \a secret.
+
+ \sa QDtlsClientVerifier::setCookieGeneratorParameters(),
+ QDtlsClientVerifier::cookieGeneratorParameters(),
+ QDtls::setCookieGeneratorParameters(),
+ QDtls::cookieGeneratorParameters()
+ */
+QDtlsClientVerifier::GeneratorParameters::GeneratorParameters(QCryptographicHash::Algorithm algorithm, const QByteArray &secret)
+ : hash(algorithm), secret(secret)
+{
+}
+
+/*!
+ Constructs a QDtlsClientVerifier object, \a parent is passed to QObject's
+ constructor.
+*/
+QDtlsClientVerifier::QDtlsClientVerifier(QObject *parent)
+ : QObject(*new QDtlsClientVerifierOpenSSL, parent)
+{
+ Q_D(QDtlsClientVerifier);
+
+ d->mode = QSslSocket::SslServerMode;
+ // The default configuration suffices: verifier never does a full
+ // handshake and upon verifying a cookie in a client hello message,
+ // it reports success.
+ auto conf = QSslConfiguration::defaultDtlsConfiguration();
+ conf.setPeerVerifyMode(QSslSocket::VerifyNone);
+ d->setConfiguration(conf);
+}
+
+/*!
+ Destroys the QDtlsClientVerifier object.
+*/
+QDtlsClientVerifier::~QDtlsClientVerifier()
+{
+}
+
+/*!
+ Sets the secret and the cryptographic hash algorithm from \a params. This
+ QDtlsClientVerifier will use these to generate cookies. If the new secret
+ has size zero, this function returns \c false and does not change the
+ cookie generator parameters.
+
+ \note The secret is supposed to be a cryptographically secure sequence of bytes.
+
+ \sa QDtlsClientVerifier::GeneratorParameters, cookieGeneratorParameters(),
+ QCryptographicHash::Algorithm
+*/
+bool QDtlsClientVerifier::setCookieGeneratorParameters(const GeneratorParameters &params)
+{
+ Q_D(QDtlsClientVerifier);
+
+ return d->setCookieGeneratorParameters(params.hash, params.secret);
+}
+
+/*!
+ Returns the current secret and hash algorithm used to generate cookies.
+ The default hash algorithm is QCryptographicHash::Sha256 if Qt was configured
+ to support it, QCryptographicHash::Sha1 otherwise. The default secret is
+ obtained from the backend-specific cryptographically strong pseudorandom
+ number generator.
+
+ \sa QCryptographicHash::Algorithm, QDtlsClientVerifier::GeneratorParameters,
+ setCookieGeneratorParameters()
+*/
+QDtlsClientVerifier::GeneratorParameters QDtlsClientVerifier::cookieGeneratorParameters() const
+{
+ Q_D(const QDtlsClientVerifier);
+
+ return {d->hashAlgorithm, d->secret};
+}
+
+/*!
+ \a socket must be a valid pointer, \a dgram must be a non-empty
+ datagram, \a address cannot be null, broadcast, or multicast.
+ \a port is the remote peer's port. This function returns \c true
+ if \a dgram contains a ClientHello message with a valid cookie.
+ If no matching cookie is found, verifyClient() will send a
+ HelloVerifyRequest message using \a socket and return \c false.
+
+ The following snippet shows how a server application may check for errors:
+
+ \snippet code/src_network_ssl_qdtlscookie.cpp 2
+
+ \sa QHostAddress::isNull(), QHostAddress::isBroadcast(), QHostAddress::isMulticast(),
+ setCookieGeneratorParameters(), cookieGeneratorParameters()
+*/
+bool QDtlsClientVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgram,
+ const QHostAddress &address, quint16 port)
+{
+ Q_D(QDtlsClientVerifier);
+
+ if (!socket || address.isNull() || !dgram.size()) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters,
+ tr("A valid UDP socket, non-empty datagram, valid address/port were expected"));
+ return false;
+ }
+
+ if (address.isBroadcast() || address.isMulticast()) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters,
+ msgUnsupportedMulticastAddress());
+ return false;
+ }
+
+ return d->verifyClient(socket, dgram, address, port);
+}
+
+/*!
+ Convenience function. Returns the last ClientHello message that was successfully
+ verified, or an empty QByteArray if no verification has completed.
+
+ \sa verifyClient()
+*/
+QByteArray QDtlsClientVerifier::verifiedHello() const
+{
+ Q_D(const QDtlsClientVerifier);
+
+ return d->verifiedClientHello;
+}
+
+/*!
+ Returns the last error that occurred or QDtlsError::NoError.
+
+ \sa QDtlsError, dtlsErrorString()
+*/
+QDtlsError QDtlsClientVerifier::dtlsError() const
+{
+ Q_D(const QDtlsClientVerifier);
+
+ return d->errorCode;
+}
+
+/*!
+ Returns a textual description of the last error, or an empty string.
+
+ \sa dtlsError()
+ */
+QString QDtlsClientVerifier::dtlsErrorString() const
+{
+ Q_D(const QDtlsBase);
+
+ return d->errorDescription;
+}
+
+/*!
+ Creates a QDtls object, \a parent is passed to the QObject constructor.
+ \a mode is QSslSocket::SslServerMode for a server-side DTLS connection or
+ QSslSocket::SslClientMode for a client.
+
+ \sa sslMode(), QSslSocket::SslMode
+*/
+QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent)
+ : QObject(*new QDtlsPrivateOpenSSL, parent)
+{
+ Q_D(QDtls);
+
+ d->mode = mode;
+ setDtlsConfiguration(QSslConfiguration::defaultDtlsConfiguration());
+}
+
+/*!
+ Destroys the QDtls object.
+*/
+QDtls::~QDtls()
+{
+}
+
+/*!
+ Sets the peer's address, \a port, and host name and returns \c true
+ if successful. \a address must not be null, multicast, or broadcast.
+ \a verificationName is the host name used for the certificate validation.
+
+ \sa peerAddress(), peerPort(), peerVerificationName()
+ */
+bool QDtls::setPeer(const QHostAddress &address, quint16 port,
+ const QString &verificationName)
+{
+ Q_D(QDtls);
+
+ if (d->handshakeState != HandshakeNotStarted) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot set peer after handshake started"));
+ return false;
+ }
+
+ if (address.isNull()) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters,
+ tr("Invalid address"));
+ return false;
+ }
+
+ if (address.isBroadcast() || address.isMulticast()) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters,
+ msgUnsupportedMulticastAddress());
+ return false;
+ }
+
+ d->clearDtlsError();
+
+ d->remoteAddress = address;
+ d->remotePort = port;
+ d->peerVerificationName = verificationName;
+
+ return true;
+}
+
+/*!
+ Sets the host \a name that will be used for the certificate validation
+ and returns \c true if successful.
+
+ \note This function must be called before the handshake starts.
+
+ \sa peerVerificationName(), setPeer()
+*/
+bool QDtls::setPeerVerificationName(const QString &name)
+{
+ Q_D(QDtls);
+
+ if (d->handshakeState != HandshakeNotStarted) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot set verification name after handshake started"));
+ return false;
+ }
+
+ d->clearDtlsError();
+ d->peerVerificationName = name;
+
+ return true;
+}
+
+/*!
+ Returns the peer's address, set by setPeer(), or QHostAddress::Null.
+
+ \sa setPeer()
+*/
+QHostAddress QDtls::peerAddress() const
+{
+ Q_D(const QDtls);
+
+ return d->remoteAddress;
+}
+
+/*!
+ Returns the peer's port number, set by setPeer(), or 0.
+
+ \sa setPeer()
+*/
+quint16 QDtls::peerPort() const
+{
+ Q_D(const QDtlsBase);
+
+ return d->remotePort;
+}
+
+/*!
+ Returns the host name set by setPeer() or setPeerVerificationName().
+ The default value is an empty string.
+
+ \sa setPeerVerificationName(), setPeer()
+*/
+QString QDtls::peerVerificationName() const
+{
+ Q_D(const QDtls);
+
+ return d->peerVerificationName;
+}
+
+/*!
+ Returns QSslSocket::SslServerMode for a server-side connection and
+ QSslSocket::SslClientMode for a client.
+
+ \sa QDtls(), QSslSocket::SslMode
+*/
+QSslSocket::SslMode QDtls::sslMode() const
+{
+ Q_D(const QDtls);
+
+ return d->mode;
+}
+
+/*!
+ \a mtuHint is the maximum transmission unit (MTU), either discovered or guessed
+ by the application. The application is not required to set this value.
+
+ \sa mtuHint(), QAbstractSocket::PathMtuSocketOption
+ */
+void QDtls::setMtuHint(quint16 mtuHint)
+{
+ Q_D(QDtls);
+
+ d->mtuHint = mtuHint;
+}
+
+/*!
+ Returns the value previously set by setMtuHint(). The default value is 0.
+
+ \sa setMtuHint()
+ */
+quint16 QDtls::mtuHint() const
+{
+ Q_D(const QDtls);
+
+ return d->mtuHint;
+}
+
+/*!
+ Sets the cryptographic hash algorithm and the secret from \a params.
+ This function is only needed for a server-side QDtls connection.
+ Returns \c true if successful.
+
+ \note This function must be called before the handshake starts.
+
+ \sa cookieGeneratorParameters(), doHandshake(), QDtlsClientVerifier,
+ QDtlsClientVerifier::cookieGeneratorParameters()
+*/
+bool QDtls::setCookieGeneratorParameters(const GeneratorParameters &params)
+{
+ Q_D(QDtls);
+
+ return d->setCookieGeneratorParameters(params.hash, params.secret);
+}
+
+/*!
+ Returns the current hash algorithm and secret, either default ones or previously
+ set by a call to setCookieGeneratorParameters().
+
+ The default hash algorithm is QCryptographicHash::Sha256 if Qt was
+ configured to support it, QCryptographicHash::Sha1 otherwise. The default
+ secret is obtained from the backend-specific cryptographically strong
+ pseudorandom number generator.
+
+ \sa QDtlsClientVerifier, cookieGeneratorParameters()
+*/
+QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const
+{
+ Q_D(const QDtls);
+
+ return {d->hashAlgorithm, d->secret};
+}
+
+/*!
+ Sets the connection's TLS configuration from \a configuration
+ and returns \c true if successful.
+
+ \note This function must be called before the handshake starts.
+
+ \sa dtlsConfiguration(), doHandshake()
+*/
+bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)
+{
+ Q_D(QDtls);
+
+ if (d->handshakeState != HandshakeNotStarted) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot set configuration after handshake started"));
+ return false;
+ }
+
+ d->setConfiguration(configuration);
+ return true;
+}
+
+/*!
+ Returns either the default DTLS configuration or the configuration set by an
+ earlier call to setDtlsConfiguration().
+
+ \sa setDtlsConfiguration(), QSslConfiguration::defaultDtlsConfiguration()
+*/
+QSslConfiguration QDtls::dtlsConfiguration() const
+{
+ Q_D(const QDtls);
+
+ return d->configuration();
+}
+
+/*!
+ Returns the current handshake state for this QDtls.
+
+ \sa doHandshake(), QDtls::HandshakeState
+ */
+QDtls::HandshakeState QDtls::handshakeState()const
+{
+ Q_D(const QDtls);
+
+ return d->handshakeState;
+}
+
+/*!
+ Starts or continues a DTLS handshake. \a socket must be a valid pointer.
+ When starting a server-side DTLS handshake, \a dgram must contain the initial
+ ClientHello message read from QUdpSocket. This function returns \c true if
+ no error was found. Handshake state can be tested using handshakeState().
+ \c false return means some error occurred, use dtlsError() for more
+ detailed information.
+
+ \note If the identity of the peer can't be established, the error is set to
+ QDtlsError::PeerVerificationError. If you want to ignore verification errors
+ and continue connecting, you must call ignoreVerificationErrors() and then
+ resumeHandshake(). If the errors cannot be ignored, you must call
+ abortHandshake().
+
+ \snippet code/src_network_ssl_qdtls.cpp 5
+
+ \sa handshakeState(), dtlsError(), ignoreVerificationErrors(), resumeHandshake(),
+ abortHandshake()
+*/
+bool QDtls::doHandshake(QUdpSocket *socket, const QByteArray &dgram)
+{
+ Q_D(QDtls);
+
+ if (d->handshakeState == HandshakeNotStarted)
+ return startHandshake(socket, dgram);
+ else if (d->handshakeState == HandshakeInProgress)
+ return continueHandshake(socket, dgram);
+
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot start/continue handshake, invalid handshake state"));
+ return false;
+}
+
+/*!
+ \internal
+*/
+bool QDtls::startHandshake(QUdpSocket *socket, const QByteArray &datagram)
+{
+ Q_D(QDtls);
+
+ if (!socket) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
+ return false;
+ }
+
+ if (d->remoteAddress.isNull()) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("To start a handshake you must set peer's address and port first"));
+ return false;
+ }
+
+ if (sslMode() == QSslSocket::SslServerMode && !datagram.size()) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters,
+ tr("To start a handshake, DTLS server requires non-empty datagram (client hello)"));
+ return false;
+ }
+
+ if (d->handshakeState != HandshakeNotStarted) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot start handshake, already done/in progress"));
+ return false;
+ }
+
+ return d->startHandshake(socket, datagram);
+}
+
+/*!
+ If a timeout occures during the handshake, the handshakeTimeout() signal
+ is emitted. The application must call handleTimeout() to retransmit handshake
+ messages; handleTimeout() returns \c true if a timeout has occurred, false
+ otherwise. \a socket must be a valid pointer.
+
+ \sa handshakeTimeout()
+*/
+bool QDtls::handleTimeout(QUdpSocket *socket)
+{
+ Q_D(QDtls);
+
+ if (!socket) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
+ return false;
+ }
+
+ return d->handleTimeout(socket);
+}
+
+/*!
+ \internal
+*/
+bool QDtls::continueHandshake(QUdpSocket *socket, const QByteArray &datagram)
+{
+ Q_D(QDtls);
+
+ if (!socket || !datagram.size()) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters,
+ tr("A valid QUdpSocket and non-empty datagram are needed to continue the handshake"));
+ return false;
+ }
+
+ if (d->handshakeState != HandshakeInProgress) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot continue handshake, not in InProgress state"));
+ return false;
+ }
+
+ return d->continueHandshake(socket, datagram);
+}
+
+/*!
+ If peer verification errors were ignored during the handshake,
+ resumeHandshake() resumes and completes the handshake and returns
+ \c true. \a socket must be a valid pointer. Returns \c false if
+ the handshake could not be resumed.
+
+ \sa doHandshake(), abortHandshake() peerVerificationErrors(), ignoreVerificationErrors()
+*/
+bool QDtls::resumeHandshake(QUdpSocket *socket)
+{
+ Q_D(QDtls);
+
+ if (!socket) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
+ return false;
+ }
+
+ if (d->handshakeState != PeerVerificationFailed) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot resume, not in VerificationError state"));
+ return false;
+ }
+
+ return d->resumeHandshake(socket);
+}
+
+/*!
+ Aborts the ongoing handshake. Returns true if one was on-going on \a socket;
+ otherwise, sets a suitable error and returns false.
+
+ \sa doHandshake(), resumeHandshake()
+ */
+bool QDtls::abortHandshake(QUdpSocket *socket)
+{
+ Q_D(QDtls);
+
+ if (!socket) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
+ return false;
+ }
+
+ if (d->handshakeState != PeerVerificationFailed && d->handshakeState != HandshakeInProgress) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("No handshake in progress, nothing to abort"));
+ return false;
+ }
+
+ d->abortHandshake(socket);
+ return true;
+}
+
+/*!
+ Sends an encrypted shutdown alert message and closes the DTLS connection.
+ Handshake state changes to QDtls::HandshakeNotStarted. \a socket must be a
+ valid pointer. This function returns \c true on success.
+
+ \sa doHandshake()
+ */
+bool QDtls::shutdown(QUdpSocket *socket)
+{
+ Q_D(QDtls);
+
+ if (!socket) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters,
+ tr("Invalid (nullptr) socket"));
+ return false;
+ }
+
+ if (!d->connectionEncrypted) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot send shutdown alert, not encrypted"));
+ return false;
+ }
+
+ d->sendShutdownAlert(socket);
+ return true;
+}
+
+/*!
+ Returns \c true if DTLS handshake completed successfully.
+
+ \sa doHandshake(), handshakeState()
+ */
+bool QDtls::isConnectionEncrypted() const
+{
+ Q_D(const QDtls);
+
+ return d->connectionEncrypted;
+}
+
+/*!
+ Returns the cryptographic \l {QSslCipher} {cipher} used by this connection,
+ or a null cipher if the connection isn't encrypted. The cipher for the
+ session is selected during the handshake phase. The cipher is used to encrypt
+ and decrypt data.
+
+ QSslConfiguration provides functions for setting the ordered list of ciphers
+ from which the handshake phase will eventually select the session cipher.
+ This ordered list must be in place before the handshake phase begins.
+
+ \sa QSslConfiguration, setDtlsConfiguration(), dtlsConfiguration()
+*/
+QSslCipher QDtls::sessionCipher() const
+{
+ Q_D(const QDtls);
+
+ return d->sessionCipher;
+}
+
+/*!
+ Returns the DTLS protocol version used by this connection, or UnknownProtocol
+ if the connection isn't encrypted yet. The protocol for the connection is selected
+ during the handshake phase.
+
+ setDtlsConfiguration() can set the preferred version before the handshake starts.
+
+ \sa setDtlsConfiguration(), QSslConfiguration, QSslConfiguration::defaultDtlsConfiguration(),
+ QSslConfiguration::setProtocol()
+*/
+QSsl::SslProtocol QDtls::sessionProtocol() const
+{
+ Q_D(const QDtls);
+
+ return d->sessionProtocol;
+}
+
+/*!
+ Encrypts \a dgram and writes the encrypted data into \a socket. Returns the
+ number of bytes written, or -1 in case of error. The handshake must be completed
+ before writing encrypted data. \a socket must be a valid
+ pointer.
+
+ \sa doHandshake(), handshakeState(), isConnectionEncrypted(), dtlsError()
+*/
+qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)
+{
+ Q_D(QDtls);
+
+ if (!socket) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
+ return -1;
+ }
+
+ if (!isConnectionEncrypted()) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot write a datagram, not in encrypted state"));
+ return -1;
+ }
+
+ return d->writeDatagramEncrypted(socket, dgram);
+}
+
+/*!
+ Decrypts \a dgram and returns its contents as plain text. The handshake must
+ be completed before datagrams can be decrypted. Depending on the type of the
+ TLS message the connection may write into \a socket, which must be a valid
+ pointer.
+*/
+QByteArray QDtls::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
+{
+ Q_D(QDtls);
+
+ if (!socket) {
+ d->setDtlsError(QDtlsError::InvalidInputParameters, tr("Invalid (nullptr) socket"));
+ return {};
+ }
+
+ if (!isConnectionEncrypted()) {
+ d->setDtlsError(QDtlsError::InvalidOperation,
+ tr("Cannot read a datagram, not in encrypted state"));
+ return {};
+ }
+
+ if (!dgram.size())
+ return {};
+
+ return d->decryptDatagram(socket, dgram);
+}
+
+/*!
+ Returns the last error encountered by the connection or QDtlsError::NoError.
+
+ \sa dtlsErrorString(), QDtlsError
+*/
+QDtlsError QDtls::dtlsError() const
+{
+ Q_D(const QDtls);
+
+ return d->errorCode;
+}
+
+/*!
+ Returns a textual description for the last error encountered by the connection
+ or empty string.
+
+ \sa dtlsError()
+*/
+QString QDtls::dtlsErrorString() const
+{
+ Q_D(const QDtls);
+
+ return d->errorDescription;
+}
+
+/*!
+ Returns errors found while establishing the identity of the peer.
+
+ If you want to continue connecting despite the errors that have occurred,
+ you must call ignoreVerificationErrors().
+*/
+QVector<QSslError> QDtls::peerVerificationErrors() const
+{
+ Q_D(const QDtls);
+
+ return d->tlsErrors;
+}
+
+/*!
+ This method tells QDtls to ignore only the errors given in \a errorsToIgnore.
+
+ If, for instance, you want to connect to a server that uses a self-signed
+ certificate, consider the following snippet:
+
+ \snippet code/src_network_ssl_qdtls.cpp 6
+
+ You can also call this function after doHandshake() encountered the
+ QDtlsError::PeerVerificationError error, and then resume the handshake by
+ calling resumeHandshake().
+
+ Later calls to this function will replace the list of errors that were
+ passed in previous calls. You can clear the list of errors you want to ignore
+ by calling this function with an empty list.
+
+ \sa doHandshake(), resumeHandshake(), QSslError
+*/
+void QDtls::ignoreVerificationErrors(const QVector<QSslError> &errorsToIgnore)
+{
+ Q_D(QDtls);
+
+ d->tlsErrorsToIgnore = errorsToIgnore;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qdtls.h b/src/network/ssl/qdtls.h
new file mode 100644
index 0000000000..8505b00d5e
--- /dev/null
+++ b/src/network/ssl/qdtls.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDTLS_H
+#define QDTLS_H
+
+#include <QtNetwork/qtnetworkglobal.h>
+
+#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qssl.h>
+
+#include <QtCore/qcryptographichash.h>
+#include <QtCore/qobject.h>
+
+QT_REQUIRE_CONFIG(dtls);
+
+QT_BEGIN_NAMESPACE
+
+enum class QDtlsError : unsigned char
+{
+ NoError,
+ InvalidInputParameters,
+ InvalidOperation,
+ UnderlyingSocketError,
+ RemoteClosedConnectionError,
+ PeerVerificationError,
+ TlsInitializationError,
+ TlsFatalError,
+ TlsNonFatalError
+};
+
+class QHostAddress;
+class QUdpSocket;
+class QByteArray;
+class QString;
+
+class QDtlsClientVerifierPrivate;
+class Q_NETWORK_EXPORT QDtlsClientVerifier : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ explicit QDtlsClientVerifier(QObject *parent = nullptr);
+ ~QDtlsClientVerifier();
+
+ struct Q_NETWORK_EXPORT GeneratorParameters
+ {
+ GeneratorParameters();
+ GeneratorParameters(QCryptographicHash::Algorithm a, const QByteArray &s);
+ QCryptographicHash::Algorithm hash = QCryptographicHash::Sha1;
+ QByteArray secret;
+ };
+
+ bool setCookieGeneratorParameters(const GeneratorParameters &params);
+ GeneratorParameters cookieGeneratorParameters() const;
+
+ bool verifyClient(QUdpSocket *socket, const QByteArray &dgram,
+ const QHostAddress &address, quint16 port);
+ QByteArray verifiedHello() const;
+
+ QDtlsError dtlsError() const;
+ QString dtlsErrorString() const;
+
+private:
+
+ Q_DECLARE_PRIVATE(QDtlsClientVerifier)
+ Q_DISABLE_COPY(QDtlsClientVerifier)
+};
+
+class QSslPreSharedKeyAuthenticator;
+template<class> class QVector;
+class QSslConfiguration;
+class QSslCipher;
+class QSslError;
+
+class QDtlsPrivate;
+class Q_NETWORK_EXPORT QDtls : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum HandshakeState
+ {
+ HandshakeNotStarted,
+ HandshakeInProgress,
+ PeerVerificationFailed,
+ HandshakeComplete
+ };
+
+ explicit QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr);
+ ~QDtls();
+
+ bool setPeer(const QHostAddress &address, quint16 port,
+ const QString &verificationName = {});
+ bool setPeerVerificationName(const QString &name);
+ QHostAddress peerAddress() const;
+ quint16 peerPort() const;
+ QString peerVerificationName() const;
+ QSslSocket::SslMode sslMode() const;
+
+ void setMtuHint(quint16 mtuHint);
+ quint16 mtuHint() const;
+
+ using GeneratorParameters = QDtlsClientVerifier::GeneratorParameters;
+ bool setCookieGeneratorParameters(const GeneratorParameters &params);
+ GeneratorParameters cookieGeneratorParameters() const;
+
+ bool setDtlsConfiguration(const QSslConfiguration &configuration);
+ QSslConfiguration dtlsConfiguration() const;
+
+ HandshakeState handshakeState() const;
+
+ bool doHandshake(QUdpSocket *socket, const QByteArray &dgram = {});
+ bool handleTimeout(QUdpSocket *socket);
+ bool resumeHandshake(QUdpSocket *socket);
+ bool abortHandshake(QUdpSocket *socket);
+ bool shutdown(QUdpSocket *socket);
+
+ bool isConnectionEncrypted() const;
+ QSslCipher sessionCipher() const;
+ QSsl::SslProtocol sessionProtocol() const;
+
+ qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram);
+ QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &dgram);
+
+ QDtlsError dtlsError() const;
+ QString dtlsErrorString() const;
+
+ QVector<QSslError> peerVerificationErrors() const;
+ void ignoreVerificationErrors(const QVector<QSslError> &errorsToIgnore);
+
+Q_SIGNALS:
+
+ void pskRequired(QSslPreSharedKeyAuthenticator *authenticator);
+ void handshakeTimeout();
+
+private:
+
+ bool startHandshake(QUdpSocket *socket, const QByteArray &dgram);
+ bool continueHandshake(QUdpSocket *socket, const QByteArray &dgram);
+
+ Q_DECLARE_PRIVATE(QDtls)
+ Q_DISABLE_COPY(QDtls)
+};
+
+QT_END_NAMESPACE
+
+#endif // QDTLS_H
diff --git a/src/network/ssl/qdtls_openssl.cpp b/src/network/ssl/qdtls_openssl.cpp
new file mode 100644
index 0000000000..8be53df24f
--- /dev/null
+++ b/src/network/ssl/qdtls_openssl.cpp
@@ -0,0 +1,1462 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif // NOMINMAX
+#include "private/qnativesocketengine_p.h"
+
+#include "qsslpresharedkeyauthenticator_p.h"
+#include "qsslsocket_openssl_symbols_p.h"
+#include "qsslsocket_openssl_p.h"
+#include "qsslcertificate_p.h"
+#include "qdtls_openssl_p.h"
+#include "qudpsocket.h"
+#include "qssl_p.h"
+
+#include "qmessageauthenticationcode.h"
+#include "qcryptographichash.h"
+
+#include "qdebug.h"
+
+#include <cstring>
+#include <cstddef>
+
+QT_BEGIN_NAMESPACE
+
+#define QT_DTLS_VERBOSE 0
+
+#if QT_DTLS_VERBOSE
+
+#define qDtlsWarning(arg) qWarning(arg)
+#define qDtlsDebug(arg) qDebug(arg)
+
+#else
+
+#define qDtlsWarning(arg)
+#define qDtlsDebug(arg)
+
+#endif // QT_DTLS_VERBOSE
+
+namespace dtlsutil
+{
+
+QByteArray cookie_for_peer(SSL *ssl)
+{
+ Q_ASSERT(ssl);
+
+ // SSL_get_rbio does not increment the reference count
+ BIO *readBIO = q_SSL_get_rbio(ssl);
+ if (!readBIO) {
+ qCWarning(lcSsl, "No BIO (dgram) found in SSL object");
+ return {};
+ }
+
+ auto listener = static_cast<dtlsopenssl::DtlsState *>(q_BIO_get_app_data(readBIO));
+ if (!listener) {
+ qCWarning(lcSsl, "BIO_get_app_data returned invalid (nullptr) value");
+ return {};
+ }
+
+ const QHostAddress peerAddress(listener->remoteAddress);
+ const quint16 peerPort(listener->remotePort);
+ QByteArray peerData;
+ if (peerAddress.protocol() == QAbstractSocket::IPv6Protocol) {
+ const Q_IPV6ADDR sin6_addr(peerAddress.toIPv6Address());
+ peerData.resize(int(sizeof sin6_addr + sizeof peerPort));
+ char *dst = peerData.data();
+ std::memcpy(dst, &peerPort, sizeof peerPort);
+ dst += sizeof peerPort;
+ std::memcpy(dst, &sin6_addr, sizeof sin6_addr);
+ } else if (peerAddress.protocol() == QAbstractSocket::IPv4Protocol) {
+ const quint32 sin_addr(peerAddress.toIPv4Address());
+ peerData.resize(int(sizeof sin_addr + sizeof peerPort));
+ char *dst = peerData.data();
+ std::memcpy(dst, &peerPort, sizeof peerPort);
+ dst += sizeof peerPort;
+ std::memcpy(dst, &sin_addr, sizeof sin_addr);
+ } else {
+ Q_UNREACHABLE();
+ }
+
+ return peerData;
+}
+
+struct FallbackCookieSecret
+{
+ FallbackCookieSecret()
+ {
+ key.resize(32);
+ const int status = q_RAND_bytes(reinterpret_cast<unsigned char *>(key.data()),
+ key.size());
+ if (status <= 0)
+ key.clear();
+ }
+
+ QByteArray key;
+
+ Q_DISABLE_COPY(FallbackCookieSecret)
+};
+
+QByteArray fallbackSecret()
+{
+ static const FallbackCookieSecret generator;
+ return generator.key;
+}
+
+int next_timeoutMs(SSL *tlsConnection)
+{
+ Q_ASSERT(tlsConnection);
+ timeval timeLeft = {};
+ q_DTLSv1_get_timeout(tlsConnection, &timeLeft);
+ return timeLeft.tv_sec * 1000;
+}
+
+
+void delete_connection(SSL *ssl)
+{
+ // The 'deleter' for QSharedPointer<SSL>.
+ if (ssl)
+ q_SSL_free(ssl);
+}
+
+#if QT_CONFIG(opensslv11)
+
+void delete_BIO_ADDR(BIO_ADDR *bio)
+{
+ // A deleter for QSharedPointer<BIO_ADDR>
+ if (bio)
+ q_BIO_ADDR_free(bio);
+}
+
+void delete_bio_method(BIO_METHOD *method)
+{
+ // The 'deleter' for QSharedPointer<BIO_METHOD>.
+ if (method)
+ q_BIO_meth_free(method);
+}
+
+#endif // openssl 1.1
+
+// The 'deleter' for QScopedPointer<BIO>.
+struct bio_deleter
+{
+ static void cleanup(BIO *bio)
+ {
+ if (bio)
+ q_BIO_free(bio);
+ }
+};
+
+// The path MTU discovery is non-trivial: it's a mix of getsockopt/setsockopt
+// (IP_MTU/IP6_MTU/IP_MTU_DISCOVER) and fallback MTU values. It's not
+// supported on all platforms, worse so - imposes specific requirements on
+// underlying UDP socket etc. So for now, we either try a user-proposed MTU
+// hint or rely on our own fallback value. As a fallback mtu OpenSSL uses 576
+// for IPv4 and 1280 for IPv6 (RFC 791, RFC 2460). To KIS we use 576. This
+// rather small MTU value does not affect the size that can be read/written
+// by QDtls, only a handshake (which is allowed to fragment).
+enum class MtuGuess : long
+{
+ defaultMtu = 576
+};
+
+} // namespace dtlsutil
+
+namespace dtlscallbacks
+{
+
+extern "C" int q_generate_cookie_callback(SSL *ssl, unsigned char *dst,
+ unsigned *cookieLength)
+{
+ if (!ssl || !dst || !cookieLength) {
+ qCWarning(lcSsl,
+ "Failed to generate cookie - invalid (nullptr) parameter(s)");
+ return 0;
+ }
+
+ void *generic = q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData);
+ if (!generic) {
+ qCWarning(lcSsl, "SSL_get_ex_data returned nullptr, cannot generate cookie");
+ return 0;
+ }
+
+ *cookieLength = 0;
+
+ auto dtls = static_cast<dtlsopenssl::DtlsState *>(generic);
+ if (!dtls->secret.size())
+ return 0;
+
+ const QByteArray peerData(dtlsutil::cookie_for_peer(ssl));
+ if (!peerData.size())
+ return 0;
+
+ QMessageAuthenticationCode hmac(dtls->hashAlgorithm, dtls->secret);
+ hmac.addData(peerData);
+ const QByteArray cookie = hmac.result();
+ Q_ASSERT(cookie.size() >= 0);
+ // DTLS1_COOKIE_LENGTH is erroneously 256 bytes long, must be 255 - RFC 6347, 4.2.1.
+ *cookieLength = qMin(DTLS1_COOKIE_LENGTH - 1, cookie.size());
+ std::memcpy(dst, cookie.constData(), *cookieLength);
+
+ return 1;
+}
+
+extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
+ unsigned cookieLength)
+{
+ if (!ssl || !cookie || !cookieLength) {
+ qCWarning(lcSsl, "Could not verify cookie, invalid (nullptr or zero) parameters");
+ return 0;
+ }
+
+ unsigned char newCookie[DTLS1_COOKIE_LENGTH] = {};
+ unsigned newCookieLength = 0;
+ if (q_generate_cookie_callback(ssl, newCookie, &newCookieLength) != 1)
+ return 0;
+
+ return newCookieLength == cookieLength
+ && !std::memcmp(cookie, newCookie, cookieLength);
+}
+
+extern "C" int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx)
+{
+ if (!ok) {
+ // Store the error and at which depth the error was detected.
+ SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(ctx, q_SSL_get_ex_data_X509_STORE_CTX_idx()));
+ if (!ssl) {
+ qCWarning(lcSsl, "X509_STORE_CTX_get_ex_data returned nullptr, handshake failure");
+ return 0;
+ }
+
+ void *generic = q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData);
+ if (!generic) {
+ qCWarning(lcSsl, "SSL_get_ex_data returned nullptr, handshake failure");
+ return 0;
+ }
+
+ auto dtls = static_cast<dtlsopenssl::DtlsState *>(generic);
+ dtls->x509Errors.append(QSslErrorEntry::fromStoreContext(ctx));
+ }
+
+ // Always return 1 (OK) to allow verification to continue. We handle the
+ // errors gracefully after collecting all errors, after verification has
+ // completed.
+ return 1;
+}
+
+extern "C" unsigned q_PSK_client_callback(SSL *ssl, const char *hint, char *identity,
+ unsigned max_identity_len, unsigned char *psk,
+ unsigned max_psk_len)
+{
+ auto *dtls = static_cast<dtlsopenssl::DtlsState *>(q_SSL_get_ex_data(ssl,
+ QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ if (!dtls)
+ return 0;
+
+ Q_ASSERT(dtls->dtlsPrivate);
+ return dtls->dtlsPrivate->pskClientCallback(hint, identity, max_identity_len, psk, max_psk_len);
+}
+
+extern "C" unsigned q_PSK_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
+ unsigned max_psk_len)
+{
+ auto *dtls = static_cast<dtlsopenssl::DtlsState *>(q_SSL_get_ex_data(ssl,
+ QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ if (!dtls)
+ return 0;
+
+ Q_ASSERT(dtls->dtlsPrivate);
+ return dtls->dtlsPrivate->pskServerCallback(identity, psk, max_psk_len);
+}
+
+} // namespace dtlscallbacks
+
+namespace dtlsbio
+{
+
+extern "C" int q_dgram_read(BIO *bio, char *dst, int bytesToRead)
+{
+ if (!bio || !dst || bytesToRead <= 0) {
+ qCWarning(lcSsl, "invalid input parameter(s)");
+ return 0;
+ }
+
+ q_BIO_clear_retry_flags(bio);
+
+ auto dtls = static_cast<dtlsopenssl::DtlsState *>(q_BIO_get_app_data(bio));
+ // It's us who set data, if OpenSSL does too, the logic here is wrong
+ // then and we have to use BIO_set_app_data then!
+ Q_ASSERT(dtls);
+ int bytesRead = 0;
+ if (dtls->dgram.size()) {
+ bytesRead = qMin(dtls->dgram.size(), bytesToRead);
+ std::memcpy(dst, dtls->dgram.constData(), bytesRead);
+
+ if (!dtls->peeking)
+ dtls->dgram = dtls->dgram.mid(bytesRead);
+ } else {
+ bytesRead = -1;
+ }
+
+ if (bytesRead <= 0)
+ q_BIO_set_retry_read(bio);
+
+ return bytesRead;
+}
+
+extern "C" int q_dgram_write(BIO *bio, const char *src, int bytesToWrite)
+{
+ if (!bio || !src || bytesToWrite <= 0) {
+ qCWarning(lcSsl, "invalid input parameter(s)");
+ return 0;
+ }
+
+ q_BIO_clear_retry_flags(bio);
+
+ auto dtls = static_cast<dtlsopenssl::DtlsState *>(q_BIO_get_app_data(bio));
+ Q_ASSERT(dtls);
+ if (dtls->writeSuppressed) {
+ // See the comment in QDtls::startHandshake.
+ return bytesToWrite;
+ }
+
+ QUdpSocket *udpSocket = dtls->udpSocket;
+ Q_ASSERT(udpSocket);
+
+ const QByteArray dgram(QByteArray::fromRawData(src, bytesToWrite));
+ qint64 bytesWritten = -1;
+ if (udpSocket->state() == QAbstractSocket::ConnectedState) {
+ bytesWritten = udpSocket->write(dgram);
+ } else {
+ bytesWritten = udpSocket->writeDatagram(dgram, dtls->remoteAddress,
+ dtls->remotePort);
+ }
+
+ if (bytesWritten <= 0)
+ q_BIO_set_retry_write(bio);
+
+ Q_ASSERT(bytesWritten <= std::numeric_limits<int>::max());
+ return int(bytesWritten);
+}
+
+extern "C" int q_dgram_puts(BIO *bio, const char *src)
+{
+ if (!bio || !src) {
+ qCWarning(lcSsl, "invalid input parameter(s)");
+ return 0;
+ }
+
+ return q_dgram_write(bio, src, int(std::strlen(src)));
+}
+
+extern "C" long q_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+ // This is our custom BIO_ctrl. bio.h defines a lot of BIO_CTRL_*
+ // and BIO_* constants and BIO_somename macros that expands to BIO_ctrl
+ // call with one of those constants as argument. What exactly BIO_ctrl
+ // does - depends on the 'cmd' and the type of BIO (so BIO_ctrl does
+ // not even have a single well-defined value meaning success or failure).
+ // We handle only the most generic commands - the ones documented for
+ // BIO_ctrl - and also DGRAM specific ones. And even for them - in most
+ // cases we do nothing but report a success or some non-error value.
+ // Documents also state: "Source/sink BIOs return an 0 if they do not
+ // recognize the BIO_ctrl() operation." - these are covered by 'default'
+ // label in the switch-statement below. Debug messages in the switch mean:
+ // 1) we got a command that is unexpected for dgram BIO, or:
+ // 2) we do not call any function that would lead to OpenSSL using this
+ // command.
+
+ if (!bio) {
+ qDebug(lcSsl, "invalid 'bio' parameter (nullptr)");
+ return -1;
+ }
+
+ auto dtls = static_cast<dtlsopenssl::DtlsState *>(q_BIO_get_app_data(bio));
+ Q_ASSERT(dtls);
+
+#if !QT_CONFIG(opensslv11)
+ Q_UNUSED(num)
+#endif
+
+ switch (cmd) {
+ // Let's start from the most generic ones, in the order in which they are
+ // documented (as BIO_ctrl):
+ case BIO_CTRL_RESET:
+ // BIO_reset macro.
+ // From documentation:
+ // "BIO_reset() normally returns 1 for success and 0 or -1 for failure.
+ // File BIOs are an exception, they return 0 for success and -1 for
+ // failure."
+ // We have nothing to reset and we are not file BIO.
+ return 1;
+ case BIO_C_FILE_SEEK:
+ case BIO_C_FILE_TELL:
+ qDtlsWarning("Unexpected cmd (BIO_C_FILE_SEEK/BIO_C_FILE_TELL)");
+ // These are for BIO_seek, BIO_tell. We are not a file BIO.
+ // Non-negative return value means success.
+ return 0;
+ case BIO_CTRL_FLUSH:
+ // BIO_flush, nothing to do, we do not buffer any data.
+ // 0 or -1 means error, 1 - success.
+ return 1;
+ case BIO_CTRL_EOF:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_EOF)");
+ // BIO_eof, 1 means EOF read. Makes no sense for us.
+ return 0;
+ case BIO_CTRL_SET_CLOSE:
+ // BIO_set_close with BIO_CLOSE/BIO_NOCLOSE flags. Documented as
+ // always returning 1.
+ // From the documentation:
+ // "Typically BIO_CLOSE is used in a source/sink BIO to indicate that
+ // the underlying I/O stream should be closed when the BIO is freed."
+ //
+ // QUdpSocket we work with is not BIO's business, ignoring.
+ return 1;
+ case BIO_CTRL_GET_CLOSE:
+ // BIO_get_close. No, never, see the comment above.
+ return 0;
+ case BIO_CTRL_PENDING:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_PENDING)");
+ // BIO_pending. Not used by DTLS/OpenSSL (we are not buffering).
+ return 0;
+ case BIO_CTRL_WPENDING:
+ // No, we have nothing buffered.
+ return 0;
+ // The constants below are not documented as a part BIO_ctrl documentation,
+ // but they are also not type-specific.
+ case BIO_CTRL_DUP:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DUP)");
+ // BIO_dup_state, not used by DTLS (and socket-related BIOs in general).
+ // For some very specific BIO type this 'cmd' would copy some state
+ // from 'bio' to (BIO*)'ptr'. 1 means success.
+ return 0;
+ case BIO_CTRL_SET_CALLBACK:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_SET_CALLBACK)");
+ // BIO_set_info_callback. We never call this, OpenSSL does not do this
+ // on its own (normally it's used if client code wants to have some
+ // debug information, for example, dumping handshake state via
+ // BIO_printf from SSL info_callback).
+ return 0;
+ case BIO_CTRL_GET_CALLBACK:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_GET_CALLBACK)");
+ // BIO_get_info_callback. We never call this.
+ if (ptr)
+ *static_cast<bio_info_cb **>(ptr) = nullptr;
+ return 0;
+ case BIO_CTRL_SET:
+ case BIO_CTRL_GET:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_SET/BIO_CTRL_GET)");
+ // Somewhat 'documented' as setting/getting IO type. Not used anywhere
+ // except BIO_buffer_get_num_lines (which contradics 'get IO type').
+ // Ignoring.
+ return 0;
+ // DGRAM-specific operation, we have to return some reasonable value
+ // (so far, I've encountered only peek mode switching, connect).
+ case BIO_CTRL_DGRAM_CONNECT:
+ // BIO_ctrl_dgram_connect. Not needed. Our 'dtls' already knows
+ // the peer's address/port. Report success though.
+ return 1;
+ case BIO_CTRL_DGRAM_SET_CONNECTED:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_SET_CONNECTED)");
+ // BIO_ctrl_dgram_set_connected. We never call it, OpenSSL does
+ // not call it on its own (so normally it's done by client code).
+ // Similar to BIO_CTRL_DGRAM_CONNECT, but it also informs the BIO
+ // that its UDP socket is connected. We never need it though.
+ return -1;
+ case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_SET_RECV_TIMEOUT)");
+ // Essentially setsockopt with SO_RCVTIMEO, not needed, our sockets
+ // are non-blocking.
+ return -1;
+ case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_GET_RECV_TIMEOUT)");
+ // getsockopt with SO_RCVTIMEO, not needed, our sockets are
+ // non-blocking. ptr is timeval *.
+ return -1;
+ case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_SET_SEND_TIMEOUT)");
+ // setsockopt, SO_SNDTIMEO, cannot happen.
+ return -1;
+ case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_GET_SEND_TIMEOUT)");
+ // getsockopt, SO_SNDTIMEO, cannot happen.
+ return -1;
+ case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+ // BIO_dgram_recv_timedout. No, we are non-blocking.
+ return 0;
+ case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
+ // BIO_dgram_send_timedout. No, we are non-blocking.
+ return 0;
+ case BIO_CTRL_DGRAM_MTU_DISCOVER:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_MTU_DISCOVER)");
+ // setsockopt, IP_MTU_DISCOVER/IP6_MTU_DISCOVER, to be done
+ // in QUdpSocket instead. OpenSSL never calls it, only client
+ // code.
+ return 1;
+ case BIO_CTRL_DGRAM_QUERY_MTU:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_QUERY_MTU)");
+ // To be done in QUdpSocket instead.
+ return 1;
+ case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
+ qDtlsWarning("Unexpected command *BIO_CTRL_DGRAM_GET_FALLBACK_MTU)");
+ // Without SSL_OP_NO_QUERY_MTU set on SSL, OpenSSL can request for
+ // fallback MTU after several re-transmissions.
+ // Should never happen in our case.
+ return long(dtlsutil::MtuGuess::defaultMtu);
+ case BIO_CTRL_DGRAM_GET_MTU:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_GET_MTU)");
+ return -1;
+ case BIO_CTRL_DGRAM_SET_MTU:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_SET_MTU)");
+ // Should not happen (we don't call BIO_ctrl with this parameter)
+ // and set MTU on SSL instead.
+ return -1; // num is mtu and it's a return value meaning success.
+ case BIO_CTRL_DGRAM_MTU_EXCEEDED:
+ qDtlsWarning("Unexpected cmd (BIO_CTRL_DGRAM_MTU_EXCEEDED)");
+ return 0;
+ case BIO_CTRL_DGRAM_GET_PEER:
+ qDtlsDebug("BIO_CTRL_DGRAM_GET_PEER");
+ // BIO_dgram_get_peer. We do not return a real address (DTLS is not
+ // using this address), but let's pretend a success.
+ switch (dtls->remoteAddress.protocol()) {
+ case QAbstractSocket::IPv6Protocol:
+ return sizeof(sockaddr_in6);
+ case QAbstractSocket::IPv4Protocol:
+ return sizeof(sockaddr_in);
+ default:
+ return -1;
+ }
+ case BIO_CTRL_DGRAM_SET_PEER:
+ // Similar to BIO_CTRL_DGRAM_CONNECTED.
+ return 1;
+ case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+ // DTLSTODO: I'm not sure yet, how it's used by OpenSSL.
+ return 1;
+ case BIO_CTRL_DGRAM_SET_DONT_FRAG:
+ qDtlsDebug("BIO_CTRL_DGRAM_SET_DONT_FRAG");
+ // To be done in QUdpSocket, it's about IP_DONTFRAG etc.
+ return 1;
+ case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+ // AFAIK it's 28 for IPv4 and 48 for IPv6, but let's pretend it's 0
+ // so that OpenSSL does not start suddenly fragmenting the first
+ // client hello (which will result in DTLSv1_listen rejecting it).
+ return 0;
+#if QT_CONFIG(opensslv11)
+ case BIO_CTRL_DGRAM_SET_PEEK_MODE:
+ dtls->peeking = num;
+ return 1;
+#endif
+ default:;
+#if QT_DTLS_VERBOSE
+ qWarning() << "Unexpected cmd (" << cmd << ")";
+#endif
+ }
+
+ return 0;
+}
+
+extern "C" int q_dgram_create(BIO *bio)
+{
+#if QT_CONFIG(opensslv11)
+ q_BIO_set_init(bio, 1);
+#else
+ bio->init = 1;
+#endif
+ // With a custom BIO you'd normally allocate some implementation-specific
+ // data and append it to this new BIO: bio->ptr = ... (pre 1.0.2) or
+ // BIO_set_data (1.1). We don't need it and thus q_dgram_destroy below
+ // is a noop.
+ return 1;
+}
+
+extern "C" int q_dgram_destroy(BIO *bio)
+{
+ Q_UNUSED(bio)
+ return 1;
+}
+
+const char * const qdtlsMethodName = "qdtlsbio";
+
+#if !QT_CONFIG(opensslv11)
+
+/*
+typedef struct bio_method_st {
+ int type;
+ const char *name;
+ int (*bwrite) (BIO *, const char *, int);
+ int (*bread) (BIO *, char *, int);
+ int (*bputs) (BIO *, const char *);
+ int (*bgets) (BIO *, char *, int);
+ long (*ctrl) (BIO *, int, long, void *);
+ int (*create) (BIO *);
+ int (*destroy) (BIO *);
+ long (*callback_ctrl) (BIO *, int, bio_info_cb *);
+} BIO_METHOD;
+*/
+
+bio_method_st qdtlsCustomBioMethod =
+{
+ BIO_TYPE_DGRAM,
+ qdtlsMethodName,
+ q_dgram_write,
+ q_dgram_read,
+ q_dgram_puts,
+ nullptr,
+ q_dgram_ctrl,
+ q_dgram_create,
+ q_dgram_destroy,
+ nullptr
+};
+
+#endif // openssl < 1.1
+
+} // namespace dtlsbio
+
+namespace dtlsopenssl
+{
+
+bool DtlsState::init(QDtlsBasePrivate *dtlsBase, QUdpSocket *socket,
+ const QHostAddress &remote, quint16 port,
+ const QByteArray &receivedMessage)
+{
+ Q_ASSERT(dtlsBase);
+ Q_ASSERT(socket);
+
+ if (!tlsContext.data() && !initTls(dtlsBase))
+ return false;
+
+ udpSocket = socket;
+
+ setLinkMtu(dtlsBase);
+
+ dgram = receivedMessage;
+ remoteAddress = remote;
+ remotePort = port;
+
+ // SSL_get_rbio does not increment a reference count.
+ BIO *bio = q_SSL_get_rbio(tlsConnection.data());
+ Q_ASSERT(bio);
+ q_BIO_set_app_data(bio, this);
+
+ return true;
+}
+
+void DtlsState::reset()
+{
+ tlsConnection.reset();
+ tlsContext.reset();
+}
+
+bool DtlsState::initTls(QDtlsBasePrivate *dtlsBase)
+{
+ if (tlsContext.data())
+ return true;
+
+ if (!QSslSocket::supportsSsl())
+ return false;
+
+ if (!initCtxAndConnection(dtlsBase))
+ return false;
+
+ if (!initBIO(dtlsBase)) {
+ tlsConnection.reset();
+ tlsContext.reset();
+ return false;
+ }
+
+ return true;
+}
+
+static QString msgFunctionFailed(const char *function)
+{
+ //: %1: Some function
+ return QDtls::tr("%1 failed").arg(QLatin1String(function));
+}
+
+bool DtlsState::initCtxAndConnection(QDtlsBasePrivate *dtlsBase)
+{
+ Q_ASSERT(dtlsBase);
+ Q_ASSERT(QSslSocket::supportsSsl());
+
+ if (dtlsBase->mode == QSslSocket::UnencryptedMode) {
+ dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
+ QDtls::tr("Invalid SslMode, SslServerMode or SslClientMode expected"));
+ return false;
+ }
+
+ if (!QDtlsBasePrivate::isDtlsProtocol(dtlsBase->dtlsConfiguration.protocol)) {
+ dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
+ QDtls::tr("Invalid protocol version, DTLS protocol expected"));
+ return false;
+ }
+
+ // Create a deep copy of our configuration
+ auto configurationCopy = new QSslConfigurationPrivate(dtlsBase->dtlsConfiguration);
+ configurationCopy->ref.store(0); // the QSslConfiguration constructor refs up
+
+ // DTLSTODO: check we do not set something DTLS-incompatible there ...
+ TlsContext newContext(QSslContext::sharedFromConfiguration(dtlsBase->mode,
+ configurationCopy,
+ dtlsBase->dtlsConfiguration.allowRootCertOnDemandLoading));
+
+ if (newContext->error() != QSslError::NoError) {
+ dtlsBase->setDtlsError(QDtlsError::TlsInitializationError, newContext->errorString());
+ return false;
+ }
+
+ TlsConnection newConnection(newContext->createSsl(), dtlsutil::delete_connection);
+ if (!newConnection.data()) {
+ dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
+ msgFunctionFailed("SSL_new"));
+ return false;
+ }
+
+ const int set = q_SSL_set_ex_data(newConnection.data(),
+ QSslSocketBackendPrivate::s_indexForSSLExtraData,
+ this);
+
+ if (set != 1 && configurationCopy->peerVerifyMode != QSslSocket::VerifyNone) {
+ dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
+ msgFunctionFailed("SSL_set_ex_data"));
+ return false;
+ }
+
+ if (dtlsBase->mode == QSslSocket::SslServerMode) {
+ if (dtlsBase->dtlsConfiguration.dtlsCookieEnabled)
+ q_SSL_set_options(newConnection.data(), SSL_OP_COOKIE_EXCHANGE);
+ q_SSL_set_psk_server_callback(newConnection.data(), dtlscallbacks::q_PSK_server_callback);
+ } else {
+ q_SSL_set_psk_client_callback(newConnection.data(), dtlscallbacks::q_PSK_client_callback);
+ }
+
+ tlsContext.swap(newContext);
+ tlsConnection.swap(newConnection);
+
+ return true;
+}
+
+bool DtlsState::initBIO(QDtlsBasePrivate *dtlsBase)
+{
+ Q_ASSERT(dtlsBase);
+ Q_ASSERT(tlsContext.data() && tlsConnection.data());
+
+#if QT_CONFIG(opensslv11)
+ BioMethod customMethod(q_BIO_meth_new(BIO_TYPE_DGRAM, dtlsbio::qdtlsMethodName),
+ dtlsutil::delete_bio_method);
+ if (!customMethod.data()) {
+ dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
+ msgFunctionFailed("BIO_meth_new"));
+ return false;
+ }
+
+ BIO_METHOD *biom = customMethod.data();
+ q_BIO_meth_set_create(biom, dtlsbio::q_dgram_create);
+ q_BIO_meth_set_destroy(biom, dtlsbio::q_dgram_destroy);
+ q_BIO_meth_set_read(biom, dtlsbio::q_dgram_read);
+ q_BIO_meth_set_write(biom, dtlsbio::q_dgram_write);
+ q_BIO_meth_set_puts(biom, dtlsbio::q_dgram_puts);
+ q_BIO_meth_set_ctrl(biom, dtlsbio::q_dgram_ctrl);
+#else
+ BIO_METHOD *biom = &dtlsbio::qdtlsCustomBioMethod;
+#endif // openssl 1.1
+
+ QScopedPointer<BIO, dtlsutil::bio_deleter> newBio(q_BIO_new(biom));
+ BIO *bio = newBio.data();
+ if (!bio) {
+ dtlsBase->setDtlsError(QDtlsError::TlsInitializationError,
+ msgFunctionFailed("BIO_new"));
+ return false;
+ }
+
+ q_SSL_set_bio(tlsConnection.data(), bio, bio);
+ newBio.take();
+
+#if QT_CONFIG(opensslv11)
+ bioMethod.swap(customMethod);
+#endif // openssl 1.1
+
+ return true;
+}
+
+void DtlsState::setLinkMtu(QDtlsBasePrivate *dtlsBase)
+{
+ Q_ASSERT(dtlsBase);
+ Q_ASSERT(udpSocket);
+ Q_ASSERT(tlsConnection.data());
+
+ long mtu = dtlsBase->mtuHint;
+ if (!mtu) {
+ // If the underlying QUdpSocket was connected, getsockopt with
+ // IP_MTU/IP6_MTU can give us some hint:
+ bool optionFound = false;
+ if (udpSocket->state() == QAbstractSocket::ConnectedState) {
+ const QVariant val(udpSocket->socketOption(QAbstractSocket::PathMtuSocketOption));
+ if (val.isValid() && val.canConvert<int>())
+ mtu = val.toInt(&optionFound);
+ }
+
+ if (!optionFound || mtu <= 0) {
+ // OK, our own initial guess.
+ mtu = long(dtlsutil::MtuGuess::defaultMtu);
+ }
+ }
+
+ // For now, we disable this option.
+ q_SSL_set_options(tlsConnection.data(), SSL_OP_NO_QUERY_MTU);
+
+ q_DTLS_set_link_mtu(tlsConnection.data(), mtu);
+}
+
+} // namespace dtlsopenssl
+
+QDtlsClientVerifierOpenSSL::QDtlsClientVerifierOpenSSL()
+{
+ secret = dtlsutil::fallbackSecret();
+}
+
+bool QDtlsClientVerifierOpenSSL::verifyClient(QUdpSocket *socket, const QByteArray &dgram,
+ const QHostAddress &address, quint16 port)
+{
+ Q_ASSERT(socket);
+ Q_ASSERT(dgram.size());
+ Q_ASSERT(!address.isNull());
+ Q_ASSERT(port);
+
+ clearDtlsError();
+ verifiedClientHello.clear();
+
+ if (!dtls.init(this, socket, address, port, dgram))
+ return false;
+
+ dtls.secret = secret;
+ dtls.hashAlgorithm = hashAlgorithm;
+
+ Q_ASSERT(dtls.tlsConnection.data());
+#if QT_CONFIG(opensslv11)
+ QSharedPointer<BIO_ADDR> peer(q_BIO_ADDR_new(), dtlsutil::delete_BIO_ADDR);
+ if (!peer.data()) {
+ setDtlsError(QDtlsError::TlsInitializationError,
+ QDtlsClientVerifier::tr("BIO_ADDR_new failed, ignoring client hello"));
+ return false;
+ }
+
+ const int ret = q_DTLSv1_listen(dtls.tlsConnection.data(), peer.data());
+ if (ret < 0) {
+ // Since 1.1 - it's a fatal error (not so in 1.0.2 for non-blocking socket)
+ setDtlsError(QDtlsError::TlsFatalError, QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ return false;
+ }
+#else
+ qt_sockaddr peer;
+ const int ret = q_DTLSv1_listen(dtls.tlsConnection.data(), &peer);
+#endif
+ if (ret > 0) {
+ verifiedClientHello = dgram;
+ return true;
+ }
+
+ return false;
+}
+
+void QDtlsPrivateOpenSSL::TimeoutHandler::start(int hintMs)
+{
+ Q_ASSERT(timerId == -1);
+ timerId = startTimer(hintMs > 0 ? hintMs : timeoutMs, Qt::PreciseTimer);
+}
+
+void QDtlsPrivateOpenSSL::TimeoutHandler::doubleTimeout()
+{
+ if (timeoutMs * 2 < 60000)
+ timeoutMs *= 2;
+ else
+ timeoutMs = 60000;
+}
+
+void QDtlsPrivateOpenSSL::TimeoutHandler::stop()
+{
+ if (timerId != -1) {
+ killTimer(timerId);
+ timerId = -1;
+ }
+}
+
+void QDtlsPrivateOpenSSL::TimeoutHandler::timerEvent(QTimerEvent *event)
+{
+ Q_UNUSED(event)
+ Q_ASSERT(timerId != -1);
+
+ killTimer(timerId);
+ timerId = -1;
+
+ Q_ASSERT(dtlsConnection);
+ dtlsConnection->reportTimeout();
+}
+
+QDtlsPrivateOpenSSL::QDtlsPrivateOpenSSL()
+{
+ secret = dtlsutil::fallbackSecret();
+ dtls.dtlsPrivate = this;
+}
+
+bool QDtlsPrivateOpenSSL::startHandshake(QUdpSocket *socket, const QByteArray &dgram)
+{
+ Q_ASSERT(socket);
+ Q_ASSERT(handshakeState == QDtls::HandshakeNotStarted);
+
+ clearDtlsError();
+ connectionEncrypted = false;
+
+ if (!dtls.init(this, socket, remoteAddress, remotePort, dgram))
+ return false;
+
+ if (mode == QSslSocket::SslServerMode && dtlsConfiguration.dtlsCookieEnabled) {
+ dtls.secret = secret;
+ dtls.hashAlgorithm = hashAlgorithm;
+ // Let's prepare the state machine so that message sequence 1 does not
+ // surprise DTLS/OpenSSL (such a message would be disregarded as
+ // 'stale or future' in SSL_accept otherwise):
+ int result = 0;
+#if QT_CONFIG(opensslv11)
+ QSharedPointer<BIO_ADDR> peer(q_BIO_ADDR_new(), dtlsutil::delete_BIO_ADDR);
+ if (!peer.data()) {
+ setDtlsError(QDtlsError::TlsInitializationError,
+ QDtls::tr("BIO_ADD_new failed, cannot start handshake"));
+ return false;
+ }
+
+ // If it's an invalid/unexpected ClientHello, we don't want to send
+ // VerifyClientRequest - it's a job of QDtlsClientVerifier - so we
+ // suppress any attempts to write into socket:
+ dtls.writeSuppressed = true;
+ result = q_DTLSv1_listen(dtls.tlsConnection.data(), peer.data());
+ dtls.writeSuppressed = false;
+#else
+ qt_sockaddr peer;
+ result = q_DTLSv1_listen(dtls.tlsConnection.data(), &peer);
+#endif
+ if (result <= 0) {
+ setDtlsError(QDtlsError::TlsFatalError,
+ QDtls::tr("Cannot start the handshake, verified client hello expected"));
+ dtls.reset();
+ return false;
+ }
+ }
+
+ handshakeState = QDtls::HandshakeInProgress;
+ opensslErrors.clear();
+ tlsErrors.clear();
+
+ return continueHandshake(socket, dgram);
+}
+
+bool QDtlsPrivateOpenSSL::continueHandshake(QUdpSocket *socket, const QByteArray &dgram)
+{
+ Q_ASSERT(socket);
+
+ Q_ASSERT(handshakeState == QDtls::HandshakeInProgress);
+
+ clearDtlsError();
+
+ if (timeoutHandler.data())
+ timeoutHandler->stop();
+
+ if (!dtls.init(this, socket, remoteAddress, remotePort, dgram))
+ return false;
+
+ dtls.x509Errors.clear();
+
+ int result = 0;
+ if (mode == QSslSocket::SslServerMode)
+ result = q_SSL_accept(dtls.tlsConnection.data());
+ else
+ result = q_SSL_connect(dtls.tlsConnection.data());
+
+ // DTLSTODO: Investigate/test if it makes sense - QSslSocket can emit
+ // peerVerifyError at this point (and thus potentially client code
+ // will close the underlying TCP connection immediately), but we are using
+ // QUdpSocket, no connection to close, our verification callback returns 1
+ // (verified OK) and this probably means OpenSSL has already sent a reply
+ // to the server's hello/certificate.
+
+ opensslErrors << dtls.x509Errors;
+
+ if (result <= 0) {
+ const auto code = q_SSL_get_error(dtls.tlsConnection.data(), result);
+ switch (code) {
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ // DTLSTODO: to be tested - in principle, if it was the first call to
+ // continueHandshake and server for some reason discards the client
+ // hello message (even the verified one) - our 'this' will probably
+ // forever stay in this strange InProgress state? (the client
+ // will dully re-transmit the same hello and we discard it again?)
+ // SSL_get_state can provide more information about state
+ // machine and we can switch to NotStarted (since we have not
+ // replied with our hello ...)
+ if (!timeoutHandler.data()) {
+ timeoutHandler.reset(new TimeoutHandler);
+ timeoutHandler->dtlsConnection = this;
+ } else {
+ // Back to 1s.
+ timeoutHandler->resetTimeout();
+ }
+
+ timeoutHandler->start();
+
+ return true; // The handshake is not yet complete.
+ default:
+ storePeerCertificates();
+ setDtlsError(QDtlsError::TlsFatalError,
+ QSslSocketBackendPrivate::msgErrorsDuringHandshake());
+ dtls.reset();
+ handshakeState = QDtls::HandshakeNotStarted;
+ return false;
+ }
+ }
+
+ storePeerCertificates();
+ fetchNegotiatedParameters();
+
+ const bool doVerifyPeer = dtlsConfiguration.peerVerifyMode == QSslSocket::VerifyPeer
+ || (dtlsConfiguration.peerVerifyMode == QSslSocket::AutoVerifyPeer
+ && mode == QSslSocket::SslClientMode);
+
+ if (!doVerifyPeer || verifyPeer() || tlsErrorsWereIgnored()) {
+ connectionEncrypted = true;
+ handshakeState = QDtls::HandshakeComplete;
+ return true;
+ }
+
+ setDtlsError(QDtlsError::PeerVerificationError, QDtls::tr("Peer verification failed"));
+ handshakeState = QDtls::PeerVerificationFailed;
+ return false;
+}
+
+
+bool QDtlsPrivateOpenSSL::handleTimeout(QUdpSocket *socket)
+{
+ Q_ASSERT(socket);
+
+ Q_ASSERT(timeoutHandler.data());
+ Q_ASSERT(dtls.tlsConnection.data());
+
+ clearDtlsError();
+
+ dtls.udpSocket = socket;
+
+ if (q_DTLSv1_handle_timeout(dtls.tlsConnection.data()) > 0) {
+ timeoutHandler->doubleTimeout();
+ timeoutHandler->start();
+ } else {
+ timeoutHandler->start(dtlsutil::next_timeoutMs(dtls.tlsConnection.data()));
+ }
+
+ return true;
+}
+
+bool QDtlsPrivateOpenSSL::resumeHandshake(QUdpSocket *socket)
+{
+ Q_UNUSED(socket);
+ Q_ASSERT(socket);
+ Q_ASSERT(handshakeState == QDtls::PeerVerificationFailed);
+
+ clearDtlsError();
+
+ if (tlsErrorsWereIgnored()) {
+ handshakeState = QDtls::HandshakeComplete;
+ connectionEncrypted = true;
+ tlsErrors.clear();
+ tlsErrorsToIgnore.clear();
+ return true;
+ }
+
+ return false;
+}
+
+void QDtlsPrivateOpenSSL::abortHandshake(QUdpSocket *socket)
+{
+ Q_ASSERT(socket);
+ Q_ASSERT(handshakeState == QDtls::PeerVerificationFailed
+ || handshakeState == QDtls::HandshakeInProgress);
+
+ clearDtlsError();
+
+ if (handshakeState == QDtls::PeerVerificationFailed) {
+ // Yes, while peer verification failed, we were actually encrypted.
+ // Let's play it nice - inform our peer about connection shut down.
+ sendShutdownAlert(socket);
+ } else {
+ resetDtls();
+ }
+}
+
+void QDtlsPrivateOpenSSL::sendShutdownAlert(QUdpSocket *socket)
+{
+ Q_ASSERT(socket);
+
+ clearDtlsError();
+
+ if (connectionEncrypted && !connectionWasShutdown) {
+ dtls.udpSocket = socket;
+ Q_ASSERT(dtls.tlsConnection.data());
+ q_SSL_shutdown(dtls.tlsConnection.data());
+ }
+
+ resetDtls();
+}
+
+qint64 QDtlsPrivateOpenSSL::writeDatagramEncrypted(QUdpSocket *socket,
+ const QByteArray &dgram)
+{
+ Q_ASSERT(socket);
+ Q_ASSERT(dtls.tlsConnection.data());
+ Q_ASSERT(connectionEncrypted);
+
+ clearDtlsError();
+
+ dtls.udpSocket = socket;
+ const int written = q_SSL_write(dtls.tlsConnection.data(),
+ dgram.constData(), dgram.size());
+ if (written > 0)
+ return written;
+
+ const unsigned long errorCode = q_ERR_get_error();
+ if (!dgram.size() && errorCode == SSL_ERROR_NONE) {
+ // With OpenSSL <= 1.1 this can happen. For example, DTLS client
+ // tries to reconnect (while re-using the same address/port) -
+ // DTLS server drops a message with unexpected epoch but says - no
+ // error. We leave to client code to resolve such problems until
+ // OpenSSL provides something better.
+ return 0;
+ }
+
+ switch (errorCode) {
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ // We do not set any error/description ... a user can probably re-try
+ // sending a datagram.
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ connectionWasShutdown = true;
+ setDtlsError(QDtlsError::TlsFatalError, QDtls::tr("The DTLS connection has been closed"));
+ handshakeState = QDtls::HandshakeNotStarted;
+ dtls.reset();
+ break;
+ case SSL_ERROR_SYSCALL:
+ case SSL_ERROR_SSL:
+ default:
+ // DTLSTODO: we don't know yet what to do. Tests needed - probably,
+ // some errors can be just ignored (it's UDP, not TCP after all).
+ // Unlike QSslSocket we do not abort though.
+ QString description(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ if (socket->error() != QAbstractSocket::UnknownSocketError && description.isEmpty()) {
+ setDtlsError(QDtlsError::UnderlyingSocketError, socket->errorString());
+ } else {
+ setDtlsError(QDtlsError::TlsFatalError,
+ QDtls::tr("Error while writing: %1").arg(description));
+ }
+ }
+
+ return -1;
+}
+
+QByteArray QDtlsPrivateOpenSSL::decryptDatagram(QUdpSocket *socket, const QByteArray &tlsdgram)
+{
+ Q_ASSERT(socket);
+ Q_ASSERT(tlsdgram.size());
+
+ Q_ASSERT(dtls.tlsConnection.data());
+ Q_ASSERT(connectionEncrypted);
+
+ dtls.dgram = tlsdgram;
+ dtls.udpSocket = socket;
+
+ clearDtlsError();
+
+ QByteArray dgram;
+ dgram.resize(tlsdgram.size());
+ const int read = q_SSL_read(dtls.tlsConnection.data(), dgram.data(),
+ dgram.size());
+
+ if (read > 0) {
+ dgram.resize(read);
+ return dgram;
+ }
+
+ dgram.clear();
+ unsigned long errorCode = q_ERR_get_error();
+ if (errorCode == SSL_ERROR_NONE) {
+ const int shutdown = q_SSL_get_shutdown(dtls.tlsConnection.data());
+ if (shutdown & SSL_RECEIVED_SHUTDOWN)
+ errorCode = SSL_ERROR_ZERO_RETURN;
+ else
+ return dgram;
+ }
+
+ switch (errorCode) {
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ return dgram;
+ case SSL_ERROR_ZERO_RETURN:
+ // "The connection was shut down cleanly" ... hmm, whatever,
+ // needs testing (DTLSTODO).
+ connectionWasShutdown = true;
+ setDtlsError(QDtlsError::RemoteClosedConnectionError,
+ QDtls::tr("The DTLS connection has been shutdown"));
+ dtls.reset();
+ connectionEncrypted = false;
+ handshakeState = QDtls::HandshakeNotStarted;
+ return dgram;
+ case SSL_ERROR_SYSCALL: // some IO error
+ case SSL_ERROR_SSL: // error in the SSL library
+ // DTLSTODO: Apparently, some errors can be ignored, for example,
+ // ECONNRESET etc. This all needs a lot of testing!!!
+ default:
+ setDtlsError(QDtlsError::TlsNonFatalError,
+ QDtls::tr("Error while reading: %1")
+ .arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()));
+ return dgram;
+ }
+}
+
+unsigned QDtlsPrivateOpenSSL::pskClientCallback(const char *hint, char *identity,
+ unsigned max_identity_len,
+ unsigned char *psk,
+ unsigned max_psk_len)
+{
+ // The code below is taken (with some modifications) from qsslsocket_openssl
+ // - alas, we cannot simply re-use it, it's in QSslSocketPrivate.
+
+ Q_Q(QDtls);
+
+ {
+ QSslPreSharedKeyAuthenticator authenticator;
+ // Fill in some read-only fields (for client code)
+ if (hint) {
+ identityHint.clear();
+ identityHint.append(hint);
+ // From the original code in QSslSocket:
+ // "it's NULL terminated, but do not include the NULL" == this fromRawData(ptr/size).
+ authenticator.d->identityHint = QByteArray::fromRawData(identityHint.constData(),
+ int(std::strlen(hint)));
+ }
+
+ authenticator.d->maximumIdentityLength = int(max_identity_len) - 1; // needs to be NULL terminated
+ authenticator.d->maximumPreSharedKeyLength = int(max_psk_len);
+
+ pskAuthenticator.swap(authenticator);
+ }
+
+ // Let the client provide the remaining bits...
+ emit q->pskRequired(&pskAuthenticator);
+
+ // No PSK set? Return now to make the handshake fail
+ if (pskAuthenticator.preSharedKey().isEmpty())
+ return 0;
+
+ // Copy data back into OpenSSL
+ const int identityLength = qMin(pskAuthenticator.identity().length(),
+ pskAuthenticator.maximumIdentityLength());
+ std::memcpy(identity, pskAuthenticator.identity().constData(), identityLength);
+ identity[identityLength] = 0;
+
+ const int pskLength = qMin(pskAuthenticator.preSharedKey().length(),
+ pskAuthenticator.maximumPreSharedKeyLength());
+ std::memcpy(psk, pskAuthenticator.preSharedKey().constData(), pskLength);
+
+ return pskLength;
+}
+
+unsigned QDtlsPrivateOpenSSL::pskServerCallback(const char *identity, unsigned char *psk,
+ unsigned max_psk_len)
+{
+ Q_Q(QDtls);
+
+ {
+ QSslPreSharedKeyAuthenticator authenticator;
+ // Fill in some read-only fields (for the user)
+ authenticator.d->identityHint = dtlsConfiguration.preSharedKeyIdentityHint;
+ authenticator.d->identity = identity;
+ authenticator.d->maximumIdentityLength = 0; // user cannot set an identity
+ authenticator.d->maximumPreSharedKeyLength = int(max_psk_len);
+
+ pskAuthenticator.swap(authenticator);
+ }
+
+ // Let the client provide the remaining bits...
+ emit q->pskRequired(&pskAuthenticator);
+
+ // No PSK set? Return now to make the handshake fail
+ if (pskAuthenticator.preSharedKey().isEmpty())
+ return 0;
+
+ // Copy data back into OpenSSL
+ const int pskLength = qMin(pskAuthenticator.preSharedKey().length(),
+ pskAuthenticator.maximumPreSharedKeyLength());
+
+ std::memcpy(psk, pskAuthenticator.preSharedKey().constData(), pskLength);
+
+ return pskLength;
+}
+
+// The definition is located in qsslsocket_openssl.cpp.
+QSslError _q_OpenSSL_to_QSslError(int errorCode, const QSslCertificate &cert);
+
+bool QDtlsPrivateOpenSSL::verifyPeer()
+{
+ // DTLSTODO: Windows-specific code for CA fetcher is not here yet.
+ QVector<QSslError> errors;
+
+ // Check the whole chain for blacklisting (including root, as we check for
+ // subjectInfo and issuer)
+ for (const QSslCertificate &cert : qAsConst(dtlsConfiguration.peerCertificateChain)) {
+ if (QSslCertificatePrivate::isBlacklisted(cert))
+ errors << QSslError(QSslError::CertificateBlacklisted, cert);
+ }
+
+ if (dtlsConfiguration.peerCertificate.isNull()) {
+ errors << QSslError(QSslError::NoPeerCertificate);
+ } else if (mode == QSslSocket::SslClientMode) {
+ // Check the peer certificate itself. First try the subject's common name
+ // (CN) as a wildcard, then try all alternate subject name DNS entries the
+ // same way.
+
+ // QSslSocket has a rather twisted logic: if verificationPeerName
+ // is empty, we call QAbstractSocket::peerName(), which returns
+ // either peerName (can be set by setPeerName) or host name
+ // (can be set as a result of connectToHost).
+ QString name = peerVerificationName;
+ if (name.isEmpty()) {
+ Q_ASSERT(dtls.udpSocket);
+ name = dtls.udpSocket->peerName();
+ }
+
+ if (!QSslSocketPrivate::isMatchingHostname(dtlsConfiguration.peerCertificate, name))
+ errors << QSslError(QSslError::HostNameMismatch, dtlsConfiguration.peerCertificate);
+ }
+
+ // Translate errors from the error list into QSslErrors
+ errors.reserve(errors.size() + opensslErrors.size());
+ for (const auto &error : qAsConst(opensslErrors)) {
+ errors << _q_OpenSSL_to_QSslError(error.code,
+ dtlsConfiguration.peerCertificateChain.value(error.depth));
+ }
+
+ tlsErrors = errors;
+ return tlsErrors.isEmpty();
+}
+
+void QDtlsPrivateOpenSSL::storePeerCertificates()
+{
+ Q_ASSERT(dtls.tlsConnection.data());
+ // Store the peer certificate and chain. For clients, the peer certificate
+ // chain includes the peer certificate; for servers, it doesn't. Both the
+ // peer certificate and the chain may be empty if the peer didn't present
+ // any certificate.
+ X509 *x509 = q_SSL_get_peer_certificate(dtls.tlsConnection.data());
+ dtlsConfiguration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509);
+ q_X509_free(x509);
+ if (dtlsConfiguration.peerCertificateChain.isEmpty()) {
+ auto stack = q_SSL_get_peer_cert_chain(dtls.tlsConnection.data());
+ dtlsConfiguration.peerCertificateChain = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(stack);
+ if (!dtlsConfiguration.peerCertificate.isNull() && mode == QSslSocket::SslServerMode)
+ dtlsConfiguration.peerCertificateChain.prepend(dtlsConfiguration.peerCertificate);
+ }
+}
+
+bool QDtlsPrivateOpenSSL::tlsErrorsWereIgnored() const
+{
+ // check whether the errors we got are all in the list of expected errors
+ // (applies only if the method QDtlsConnection::ignoreTlsErrors(const
+ // QVector<QSslError> &errors) was called)
+ for (const QSslError &error : tlsErrors) {
+ if (!tlsErrorsToIgnore.contains(error))
+ return false;
+ }
+
+ return !tlsErrorsToIgnore.empty();
+}
+
+void QDtlsPrivateOpenSSL::fetchNegotiatedParameters()
+{
+ Q_ASSERT(dtls.tlsConnection.data());
+
+ const SSL_CIPHER *cipher = q_SSL_get_current_cipher(dtls.tlsConnection.data());
+ sessionCipher = cipher ? QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(cipher)
+ : QSslCipher();
+
+ // Note: cipher's protocol version will be reported as either TLS 1.0 or
+ // TLS 1.2, that's how it's set by OpenSSL (and that's what they are?).
+
+ switch (q_SSL_version(dtls.tlsConnection.data())) {
+ case DTLS1_VERSION:
+ sessionProtocol = QSsl::DtlsV1_0;
+ break;
+ case DTLS1_2_VERSION:
+ sessionProtocol = QSsl::DtlsV1_2;
+ break;
+ default:
+ qCWarning(lcSsl, "unknown protocol version");
+ sessionProtocol = QSsl::UnknownProtocol;
+ }
+}
+
+void QDtlsPrivateOpenSSL::reportTimeout()
+{
+ Q_Q(QDtls);
+
+ emit q->handshakeTimeout();
+}
+
+void QDtlsPrivateOpenSSL::resetDtls()
+{
+ dtls.reset();
+ connectionEncrypted = false;
+ tlsErrors.clear();
+ tlsErrorsToIgnore.clear();
+ dtlsConfiguration.peerCertificate.clear();
+ dtlsConfiguration.peerCertificateChain.clear();
+ connectionWasShutdown = false;
+ handshakeState = QDtls::HandshakeNotStarted;
+ sessionCipher = {};
+ sessionProtocol = QSsl::UnknownProtocol;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qdtls_openssl_p.h b/src/network/ssl/qdtls_openssl_p.h
new file mode 100644
index 0000000000..9306fa2433
--- /dev/null
+++ b/src/network/ssl/qdtls_openssl_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDTLS_OPENSSL_P_H
+#define QDTLS_OPENSSL_P_H
+
+#include <private/qtnetworkglobal_p.h>
+
+#include <QtCore/qglobal.h>
+
+#include <openssl/ossl_typ.h>
+
+#include "qdtls_p.h"
+
+#include <private/qsslcontext_openssl_p.h>
+#include <private/qsslsocket_openssl_p.h>
+
+#include <QtNetwork/qsslpresharedkeyauthenticator.h>
+#include <QtNetwork/qhostaddress.h>
+
+#include <QtCore/qcryptographichash.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qvector.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.
+//
+
+QT_REQUIRE_CONFIG(openssl);
+QT_REQUIRE_CONFIG(dtls);
+
+QT_BEGIN_NAMESPACE
+
+class QDtlsPrivateOpenSSL;
+class QUdpSocket;
+
+namespace dtlsopenssl
+{
+
+class DtlsState
+{
+public:
+ // Note, bioMethod, if allocated (i.e. OpenSSL version >= 1.1) _must_
+ // outlive BIOs it was used to create. Thus the order of declarations
+ // here matters.
+ using BioMethod = QSharedPointer<BIO_METHOD>;
+ BioMethod bioMethod;
+
+ using TlsContext = QSharedPointer<QSslContext>;
+ TlsContext tlsContext;
+
+ using TlsConnection = QSharedPointer<SSL>;
+ TlsConnection tlsConnection;
+
+ QByteArray dgram;
+
+ QHostAddress remoteAddress;
+ quint16 remotePort = 0;
+
+ QVector<QSslErrorEntry> x509Errors;
+
+ long peeking = false;
+ QUdpSocket *udpSocket = nullptr;
+ bool writeSuppressed = false;
+
+ bool init(QDtlsBasePrivate *dtlsBase, QUdpSocket *socket,
+ const QHostAddress &remote, quint16 port,
+ const QByteArray &receivedMessage);
+
+ void reset();
+
+ QDtlsPrivateOpenSSL *dtlsPrivate = nullptr;
+ QByteArray secret;
+
+#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha1;
+#else
+ QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha256;
+#endif
+
+private:
+
+ bool initTls(QDtlsBasePrivate *dtlsBase);
+ bool initCtxAndConnection(QDtlsBasePrivate *dtlsBase);
+ bool initBIO(QDtlsBasePrivate *dtlsBase);
+ void setLinkMtu(QDtlsBasePrivate *dtlsBase);
+};
+
+} // namespace dtlsopenssl
+
+class QDtlsClientVerifierOpenSSL : public QDtlsClientVerifierPrivate
+{
+public:
+
+ QDtlsClientVerifierOpenSSL();
+
+ bool verifyClient(QUdpSocket *socket, const QByteArray &dgram,
+ const QHostAddress &address, quint16 port) override;
+
+private:
+ dtlsopenssl::DtlsState dtls;
+};
+
+class QDtlsPrivateOpenSSL : public QDtlsPrivate
+{
+public:
+ QDtlsPrivateOpenSSL();
+
+ bool startHandshake(QUdpSocket *socket, const QByteArray &datagram) override;
+ bool continueHandshake(QUdpSocket *socket, const QByteArray &datagram) override;
+ bool resumeHandshake(QUdpSocket *socket) override;
+ void abortHandshake(QUdpSocket *socket) override;
+ bool handleTimeout(QUdpSocket *socket) override;
+ void sendShutdownAlert(QUdpSocket *socket) override;
+
+ qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &datagram) override;
+ QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &tlsdgram) override;
+
+ unsigned pskClientCallback(const char *hint, char *identity, unsigned max_identity_len,
+ unsigned char *psk, unsigned max_psk_len);
+ unsigned pskServerCallback(const char *identity, unsigned char *psk,
+ unsigned max_psk_len);
+
+private:
+
+ bool verifyPeer();
+ void storePeerCertificates();
+ bool tlsErrorsWereIgnored() const;
+ void fetchNegotiatedParameters();
+ void reportTimeout();
+ void resetDtls();
+
+ QVector<QSslErrorEntry> opensslErrors;
+ dtlsopenssl::DtlsState dtls;
+
+ // We have to externally handle timeouts since we have non-blocking
+ // sockets and OpenSSL(DTLS) with non-blocking UDP sockets does not
+ // know if a timeout has occurred.
+ struct TimeoutHandler : QObject
+ {
+ TimeoutHandler() = default;
+
+ void start(int hintMs = 0);
+ void doubleTimeout();
+ void resetTimeout() {timeoutMs = 1000;}
+ void stop();
+ void timerEvent(QTimerEvent *event);
+
+ int timerId = -1;
+ int timeoutMs = 1000;
+
+ QDtlsPrivateOpenSSL *dtlsConnection = nullptr;
+ };
+
+ // We will initialize it 'lazily', just in case somebody wants to move
+ // QDtls to another thread.
+ QScopedPointer<TimeoutHandler> timeoutHandler;
+ bool connectionWasShutdown = false;
+ QSslPreSharedKeyAuthenticator pskAuthenticator;
+ QByteArray identityHint;
+
+ Q_DECLARE_PUBLIC(QDtls)
+};
+
+
+
+QT_END_NAMESPACE
+
+#endif // QDTLS_OPENSSL_P_H
diff --git a/src/network/ssl/qdtls_p.h b/src/network/ssl/qdtls_p.h
new file mode 100644
index 0000000000..bdc001502b
--- /dev/null
+++ b/src/network/ssl/qdtls_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDTLS_P_H
+#define QDTLS_P_H
+
+#include <private/qtnetworkglobal_p.h>
+
+#include "qdtls.h"
+
+#include <private/qsslconfiguration_p.h>
+#include <private/qobject_p.h>
+
+#include <QtNetwork/qabstractsocket.h>
+#include <QtNetwork/qhostaddress.h>
+#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qsslcipher.h>
+#include <QtNetwork/qssl.h>
+
+#include <QtCore/qcryptographichash.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qstring.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.
+//
+
+QT_REQUIRE_CONFIG(dtls);
+
+QT_BEGIN_NAMESPACE
+
+class QHostAddress;
+
+class QDtlsBasePrivate : public QObjectPrivate
+{
+public:
+
+ void setDtlsError(QDtlsError code, const QString &description)
+ {
+ errorCode = code;
+ errorDescription = description;
+ }
+
+ void clearDtlsError()
+ {
+ errorCode = QDtlsError::NoError;
+ errorDescription.clear();
+ }
+
+ void setConfiguration(const QSslConfiguration &configuration);
+ QSslConfiguration configuration() const;
+
+ bool setCookieGeneratorParameters(QCryptographicHash::Algorithm alg,
+ const QByteArray &secret);
+
+ static bool isDtlsProtocol(QSsl::SslProtocol protocol);
+
+ QHostAddress remoteAddress;
+ quint16 remotePort = 0;
+ quint16 mtuHint = 0;
+
+ QDtlsError errorCode = QDtlsError::NoError;
+ QString errorDescription;
+ QSslConfigurationPrivate dtlsConfiguration;
+ QSslSocket::SslMode mode = QSslSocket::SslClientMode;
+ QSslCipher sessionCipher;
+ QSsl::SslProtocol sessionProtocol = QSsl::UnknownProtocol;
+ QString peerVerificationName;
+ QByteArray secret;
+
+#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha1;
+#else
+ QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha256;
+#endif
+};
+
+class QDtlsClientVerifierPrivate : public QDtlsBasePrivate
+{
+public:
+
+ QByteArray verifiedClientHello;
+
+ virtual bool verifyClient(QUdpSocket *socket, const QByteArray &dgram,
+ const QHostAddress &address, quint16 port) = 0;
+};
+
+class QDtlsPrivate : public QDtlsBasePrivate
+{
+public:
+
+ virtual bool startHandshake(QUdpSocket *socket, const QByteArray &dgram) = 0;
+ virtual bool handleTimeout(QUdpSocket *socket) = 0;
+ virtual bool continueHandshake(QUdpSocket *socket, const QByteArray &dgram) = 0;
+ virtual bool resumeHandshake(QUdpSocket *socket) = 0;
+ virtual void abortHandshake(QUdpSocket *socket) = 0;
+ virtual void sendShutdownAlert(QUdpSocket *socket) = 0;
+
+ virtual qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram) = 0;
+ virtual QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &dgram) = 0;
+
+ QDtls::HandshakeState handshakeState = QDtls::HandshakeNotStarted;
+
+ QVector<QSslError> tlsErrors;
+ QVector<QSslError> tlsErrorsToIgnore;
+
+ bool connectionEncrypted = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDTLS_P_H
diff --git a/src/network/ssl/qpassworddigestor.cpp b/src/network/ssl/qpassworddigestor.cpp
new file mode 100644
index 0000000000..127d94e849
--- /dev/null
+++ b/src/network/ssl/qpassworddigestor.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpassworddigestor.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QMessageAuthenticationCode>
+#include <QtCore/QtEndian>
+
+#include <limits>
+
+QT_BEGIN_NAMESPACE
+namespace QPasswordDigestor {
+
+/*!
+ \namespace QPasswordDigestor
+ \inmodule QtNetwork
+
+ \brief The QPasswordDigestor namespace contains functions which you can use
+ to generate hashes or keys.
+*/
+
+/*!
+ \since 5.12
+
+ Returns a hash computed using the PBKDF1-algorithm as defined in
+ \l {https://tools.ietf.org/html/rfc8018#section-5.1} {RFC 8018}.
+
+ The function takes the \a data and \a salt, and then hashes it repeatedly
+ for \a iterations iterations using the specified hash \a algorithm. If the
+ resulting hash is longer than \a dkLen then it is truncated before it is
+ returned.
+
+ This function only supports SHA-1 and MD5! The max output size is 160 bits
+ (20 bytes) when using SHA-1, or 128 bits (16 bytes) when using MD5.
+ Specifying a value for \a dkLen which is greater than this results in a
+ warning and an empty QByteArray is returned. To programmatically check this
+ limit you can use \l {QCryptographicHash::hashLength}. Furthermore: the
+ \a salt must always be 8 bytes long!
+
+ \note This function is provided for use with legacy applications and all
+ new applications are recommended to use \l {pbkdf2} {PBKDF2}.
+
+ \sa deriveKeyPbkdf2, QCryptographicHash, QCryptographicHash::hashLength
+*/
+Q_NETWORK_EXPORT QByteArray deriveKeyPbkdf1(QCryptographicHash::Algorithm algorithm,
+ const QByteArray &data, const QByteArray &salt,
+ int iterations, quint64 dkLen)
+{
+ // https://tools.ietf.org/html/rfc8018#section-5.1
+
+ if (algorithm != QCryptographicHash::Sha1
+#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ && algorithm != QCryptographicHash::Md5
+#endif
+ ) {
+ qWarning("The only supported algorithms for pbkdf1 are SHA-1 and MD5!");
+ return QByteArray();
+ }
+
+ if (salt.size() != 8) {
+ qWarning("The salt must be 8 bytes long!");
+ return QByteArray();
+ }
+ if (iterations < 1 || dkLen < 1)
+ return QByteArray();
+
+ if (dkLen > quint64(QCryptographicHash::hashLength(algorithm))) {
+ qWarning() << "Derived key too long:\n"
+ << algorithm << "was chosen which produces output of length"
+ << QCryptographicHash::hashLength(algorithm) << "but" << dkLen
+ << "was requested.";
+ return QByteArray();
+ }
+
+ QCryptographicHash hash(algorithm);
+ hash.addData(data);
+ hash.addData(salt);
+ QByteArray key = hash.result();
+
+ for (int i = 1; i < iterations; i++) {
+ hash.reset();
+ hash.addData(key);
+ key = hash.result();
+ }
+ return key.left(dkLen);
+}
+
+/*!
+ \since 5.12
+
+ Derive a key using the PBKDF2-algorithm as defined in
+ \l {https://tools.ietf.org/html/rfc8018#section-5.2} {RFC 8018}.
+
+ This function takes the \a data and \a salt, and then applies HMAC-X, where
+ the X is \a algorithm, repeatedly. It internally concatenates intermediate
+ results to the final output until at least \a dkLen amount of bytes have
+ been computed and it will execute HMAC-X \a iterations times each time a
+ concatenation is required. The total number of times it will execute HMAC-X
+ depends on \a iterations, \a dkLen and \a algorithm and can be calculated
+ as
+ \c{iterations * ceil(dkLen / QCryptographicHash::hashLength(algorithm))}.
+
+ \sa deriveKeyPbkdf1, QMessageAuthenticationCode, QCryptographicHash
+*/
+Q_NETWORK_EXPORT QByteArray deriveKeyPbkdf2(QCryptographicHash::Algorithm algorithm,
+ const QByteArray &data, const QByteArray &salt,
+ int iterations, quint64 dkLen)
+{
+ // https://tools.ietf.org/html/rfc8018#section-5.2
+
+ // The RFC recommends checking that 'dkLen' is not greater than '(2^32 - 1) * hLen'
+ int hashLen = QCryptographicHash::hashLength(algorithm);
+ const quint64 maxLen = quint64(std::numeric_limits<quint32>::max() - 1) * hashLen;
+ if (dkLen > maxLen) {
+ qWarning().nospace() << "Derived key too long:\n"
+ << algorithm << " was chosen which produces output of length "
+ << maxLen << " but " << dkLen << " was requested.";
+ return QByteArray();
+ }
+
+ if (iterations < 1 || dkLen < 1)
+ return QByteArray();
+
+ QByteArray key;
+ quint32 currentIteration = 1;
+ QMessageAuthenticationCode hmac(algorithm, data);
+ QByteArray index(4, Qt::Uninitialized);
+ while (quint64(key.length()) < dkLen) {
+ hmac.addData(salt);
+
+ qToBigEndian(currentIteration, index.data());
+ hmac.addData(index);
+
+ QByteArray u = hmac.result();
+ hmac.reset();
+ QByteArray tkey = u;
+ for (int iter = 1; iter < iterations; iter++) {
+ hmac.addData(u);
+ u = hmac.result();
+ hmac.reset();
+ std::transform(tkey.cbegin(), tkey.cend(), u.cbegin(), tkey.begin(),
+ std::bit_xor<char>());
+ }
+ key += tkey;
+ currentIteration++;
+ }
+ return key.left(dkLen);
+}
+} // namespace QPasswordDigestor
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qpassworddigestor.h b/src/network/ssl/qpassworddigestor.h
new file mode 100644
index 0000000000..0f88643298
--- /dev/null
+++ b/src/network/ssl/qpassworddigestor.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPASSWORDDIGESTOR_H
+#define QPASSWORDDIGESTOR_H
+
+#include <QtNetwork/qtnetworkglobal.h>
+#include <QtCore/QByteArray>
+#include <QtCore/QCryptographicHash>
+
+QT_BEGIN_NAMESPACE
+
+namespace QPasswordDigestor {
+Q_NETWORK_EXPORT QByteArray deriveKeyPbkdf1(QCryptographicHash::Algorithm algorithm,
+ const QByteArray &password, const QByteArray &salt,
+ int iterations, quint64 dkLen);
+Q_NETWORK_EXPORT QByteArray deriveKeyPbkdf2(QCryptographicHash::Algorithm algorithm,
+ const QByteArray &password, const QByteArray &salt,
+ int iterations, quint64 dkLen);
+} // namespace QPasswordDigestor
+
+QT_END_NAMESPACE
+
+#endif // QPASSWORDDIGESTOR_H
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp
index 51779dec33..3a0983e8b5 100644
--- a/src/network/ssl/qssl.cpp
+++ b/src/network/ssl/qssl.cpp
@@ -125,6 +125,10 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl");
\value TlsV1_1OrLater TLSv1.1 and later versions. This option is not available when using the WinRT backend due to platform limitations.
\value TlsV1_2 TLSv1.2. When using the WinRT backend this option will also enable TLSv1.0 and TLSv1.1.
\value TlsV1_2OrLater TLSv1.2 and later versions. This option is not available when using the WinRT backend due to platform limitations.
+ \value DtlsV1_0 DTLSv1.0
+ \value DtlsV1_0OrLater DTLSv1.0 and later versions.
+ \value DtlsV1_2 DTLSv1.2
+ \value DtlsV1_2OrLater DTLSv1.2 and later versions.
\value UnknownProtocol The cipher's protocol cannot be determined.
\value AnyProtocol The socket understands SSLv2, SSLv3, TLSv1.0 and all
supported later versions of TLS. This value is used by QSslSocket only.
diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h
index c2a468c97c..dd268cd86d 100644
--- a/src/network/ssl/qssl.h
+++ b/src/network/ssl/qssl.h
@@ -91,6 +91,13 @@ namespace QSsl {
TlsV1_1OrLater,
TlsV1_2OrLater,
+#if QT_CONFIG(dtls) || defined(Q_CLANG_QDOC)
+ DtlsV1_0,
+ DtlsV1_0OrLater,
+ DtlsV1_2,
+ DtlsV1_2OrLater,
+#endif
+
UnknownProtocol = -1
};
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index 9ddcb70b1d..d153e0b929 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -125,7 +125,9 @@
#include "qssl_p.h"
#include "qsslcertificate.h"
#include "qsslcertificate_p.h"
+#ifndef QT_NO_SSL
#include "qsslkey_p.h"
+#endif
#include <QtCore/qdir.h>
#include <QtCore/qdiriterator.h>
@@ -142,8 +144,12 @@ QT_BEGIN_NAMESPACE
QSslCertificate::QSslCertificate(QIODevice *device, QSsl::EncodingFormat format)
: d(new QSslCertificatePrivate)
{
+#ifndef QT_NO_OPENSSL
QSslSocketPrivate::ensureInitialized();
if (device && QSslSocket::supportsSsl())
+#else
+ if (device)
+#endif
d->init(device->readAll(), format);
}
@@ -156,8 +162,10 @@ QSslCertificate::QSslCertificate(QIODevice *device, QSsl::EncodingFormat format)
QSslCertificate::QSslCertificate(const QByteArray &data, QSsl::EncodingFormat format)
: d(new QSslCertificatePrivate)
{
+#ifndef QT_NO_OPENSSL
QSslSocketPrivate::ensureInitialized();
if (QSslSocket::supportsSsl())
+#endif
d->init(data, format);
}
@@ -557,6 +565,8 @@ QList<QSslCertificate> QSslCertificate::fromData(const QByteArray &data, QSsl::E
: QSslCertificatePrivate::certificatesFromDer(data);
}
+#ifndef QT_NO_SSL
+
/*!
Verifies a certificate chain. The chain to be verified is passed in the
\a certificateChain parameter. The first certificate in the list should
@@ -600,6 +610,8 @@ bool QSslCertificate::importPkcs12(QIODevice *device,
return QSslSocketBackendPrivate::importPkcs12(device, key, certificate, caCertificates, passPhrase);
}
+#endif
+
// These certificates are known to be fraudulent and were created during the comodo
// compromise. See http://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html
static const char *const certificate_blacklist[] = {
@@ -647,12 +659,12 @@ static const char *const certificate_blacklist[] = {
"27:83", "NIC Certifying Authority", // intermediate certificate from NIC India (2007)
"27:92", "NIC CA 2011", // intermediate certificate from NIC India (2011)
"27:b1", "NIC CA 2014", // intermediate certificate from NIC India (2014)
- 0
+ nullptr
};
bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate)
{
- for (int a = 0; certificate_blacklist[a] != 0; a++) {
+ for (int a = 0; certificate_blacklist[a] != nullptr; a++) {
QString blacklistedCommonName = QString::fromUtf8(certificate_blacklist[(a+1)]);
if (certificate.serialNumber() == certificate_blacklist[a++] &&
(certificate.subjectInfo(QSslCertificate::CommonName).contains(blacklistedCommonName) ||
@@ -680,6 +692,56 @@ QByteArray QSslCertificatePrivate::subjectInfoToString(QSslCertificate::SubjectI
}
/*!
+ \since 5.12
+
+ Returns a name that describes the issuer. It returns the QSslCertificate::CommonName
+ if available, otherwise falls back to the first QSslCertificate::Organization or the
+ first QSslCertificate::OrganizationalUnitName.
+
+ \sa issuerInfo()
+*/
+QString QSslCertificate::issuerDisplayName() const
+{
+ QStringList names;
+ names = issuerInfo(QSslCertificate::CommonName);
+ if (!names.isEmpty())
+ return names.first();
+ names = issuerInfo(QSslCertificate::Organization);
+ if (!names.isEmpty())
+ return names.first();
+ names = issuerInfo(QSslCertificate::OrganizationalUnitName);
+ if (!names.isEmpty())
+ return names.first();
+
+ return QString();
+}
+
+/*!
+ \since 5.12
+
+ Returns a name that describes the subject. It returns the QSslCertificate::CommonName
+ if available, otherwise falls back to the first QSslCertificate::Organization or the
+ first QSslCertificate::OrganizationalUnitName.
+
+ \sa subjectInfo()
+*/
+QString QSslCertificate::subjectDisplayName() const
+{
+ QStringList names;
+ names = subjectInfo(QSslCertificate::CommonName);
+ if (!names.isEmpty())
+ return names.first();
+ names = subjectInfo(QSslCertificate::Organization);
+ if (!names.isEmpty())
+ return names.first();
+ names = subjectInfo(QSslCertificate::OrganizationalUnitName);
+ if (!names.isEmpty())
+ return names.first();
+
+ return QString();
+}
+
+/*!
\fn uint qHash(const QSslCertificate &key, uint seed)
Returns the hash value for the \a key, using \a seed to seed the calculation.
@@ -696,8 +758,8 @@ QDebug operator<<(QDebug debug, const QSslCertificate &certificate)
<< certificate.version()
<< ", " << certificate.serialNumber()
<< ", " << certificate.digest().toBase64()
- << ", " << certificate.issuerInfo(QSslCertificate::Organization)
- << ", " << certificate.subjectInfo(QSslCertificate::Organization)
+ << ", " << certificate.issuerDisplayName()
+ << ", " << certificate.subjectDisplayName()
<< ", " << certificate.subjectAlternativeNames()
#if QT_CONFIG(datestring)
<< ", " << certificate.effectiveDate()
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index 6cd66fd20f..266fcdacb4 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -55,8 +55,6 @@
#include <QtCore/qmap.h>
#include <QtNetwork/qssl.h>
-#ifndef QT_NO_SSL
-
QT_BEGIN_NAMESPACE
class QDateTime;
@@ -122,6 +120,9 @@ public:
QStringList issuerInfo(const QByteArray &attribute) const;
QStringList subjectInfo(SubjectInfo info) const;
QStringList subjectInfo(const QByteArray &attribute) const;
+ QString issuerDisplayName() const;
+ QString subjectDisplayName() const;
+
QList<QByteArray> subjectInfoAttributes() const;
QList<QByteArray> issuerInfoAttributes() const;
#if QT_DEPRECATED_SINCE(5,0)
@@ -131,7 +132,9 @@ public:
QMultiMap<QSsl::AlternativeNameEntryType, QString> subjectAlternativeNames() const;
QDateTime effectiveDate() const;
QDateTime expiryDate() const;
+#ifndef QT_NO_SSL
QSslKey publicKey() const;
+#endif
QList<QSslCertificateExtension> extensions() const;
QByteArray toPem() const;
@@ -146,6 +149,7 @@ public:
static QList<QSslCertificate> fromData(
const QByteArray &data, QSsl::EncodingFormat format = QSsl::Pem);
+#ifndef QT_NO_SSL
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName = QString());
#else
@@ -156,6 +160,7 @@ public:
QSslKey *key, QSslCertificate *cert,
QList<QSslCertificate> *caCertificates = nullptr,
const QByteArray &passPhrase=QByteArray());
+#endif
Qt::HANDLE handle() const;
@@ -178,6 +183,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QSslCertificate)
-#endif // QT_NO_SSL
-
#endif
diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp
index fce150d79d..e87264c972 100644
--- a/src/network/ssl/qsslcertificate_openssl.cpp
+++ b/src/network/ssl/qsslcertificate_openssl.cpp
@@ -187,7 +187,8 @@ QMultiMap<QSsl::AlternativeNameEntryType, QString> QSslCertificate::subjectAlter
if (!d->x509)
return result;
- STACK_OF(GENERAL_NAME) *altNames = (STACK_OF(GENERAL_NAME)*)q_X509_get_ext_d2i(d->x509, NID_subject_alt_name, 0, 0);
+ STACK_OF(GENERAL_NAME) *altNames = (STACK_OF(GENERAL_NAME) *)q_X509_get_ext_d2i(
+ d->x509, NID_subject_alt_name, nullptr, nullptr);
if (altNames) {
for (int i = 0; i < q_sk_GENERAL_NAME_num(altNames); ++i) {
@@ -289,7 +290,7 @@ static QVariant x509UnknownExtensionToValue(X509_EXTENSION *ext)
// If this extension can be converted
if (meth->i2v && ext_internal) {
- STACK_OF(CONF_VALUE) *val = meth->i2v(meth, ext_internal, 0);
+ STACK_OF(CONF_VALUE) *val = meth->i2v(meth, ext_internal, nullptr);
QVariantMap map;
QVariantList list;
@@ -527,7 +528,7 @@ QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::Encodi
}
// Use i2d_X509 to convert the X509 to an array.
- int length = q_i2d_X509(x509, 0);
+ int length = q_i2d_X509(x509, nullptr);
QByteArray array;
array.resize(length);
char *data = array.data();
@@ -604,11 +605,11 @@ static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name)
X509_NAME_ENTRY *e = q_X509_NAME_get_entry(name, i);
QByteArray name = QSslCertificatePrivate::asn1ObjectName(q_X509_NAME_ENTRY_get_object(e));
- unsigned char *data = 0;
+ unsigned char *data = nullptr;
int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e));
info.insertMulti(name, QString::fromUtf8((char*)data, size));
#if QT_CONFIG(opensslv11)
- q_CRYPTO_free(data, 0, 0);
+ q_CRYPTO_free(data, nullptr, 0);
#else
q_CRYPTO_free(data);
#endif
@@ -679,7 +680,7 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromPem(const QByteAr
QByteArray::fromRawData(pem.data() + startPos, endPos - startPos));
const unsigned char *data = (const unsigned char *)decoded.data();
- if (X509 *x509 = q_d2i_X509(0, &data, decoded.size())) {
+ if (X509 *x509 = q_d2i_X509(nullptr, &data, decoded.size())) {
certificates << QSslCertificate_from_X509(x509);
q_X509_free(x509);
}
@@ -697,7 +698,7 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteAr
int size = der.size();
while (size > 0 && (count == -1 || certificates.size() < count)) {
- if (X509 *x509 = q_d2i_X509(0, &data, size)) {
+ if (X509 *x509 = q_d2i_X509(nullptr, &data, size)) {
certificates << QSslCertificate_from_X509(x509);
q_X509_free(x509);
} else {
diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h
index 0397845f8d..dfdceab502 100644
--- a/src/network/ssl/qsslcertificate_p.h
+++ b/src/network/ssl/qsslcertificate_p.h
@@ -55,7 +55,9 @@
// We mean it.
//
+#ifndef QT_NO_SSL
#include "qsslsocket_p.h"
+#endif
#include "qsslcertificateextension.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qmap.h>
@@ -83,7 +85,9 @@ public:
QSslCertificatePrivate()
: null(true), x509(0)
{
+#ifndef QT_NO_SSL
QSslSocketPrivate::ensureInitialized();
+#endif
}
~QSslCertificatePrivate()
diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp
index 1cc2b1f964..dfdfd529e5 100644
--- a/src/network/ssl/qsslcertificate_qt.cpp
+++ b/src/network/ssl/qsslcertificate_qt.cpp
@@ -41,8 +41,10 @@
#include "qsslcertificate_p.h"
#include "qssl_p.h"
+#ifndef QT_NO_SSL
#include "qsslkey.h"
#include "qsslkey_p.h"
+#endif
#include "qsslcertificateextension.h"
#include "qsslcertificateextension_p.h"
#include "qasn1element_p.h"
@@ -141,10 +143,11 @@ QDateTime QSslCertificate::expiryDate() const
Qt::HANDLE QSslCertificate::handle() const
{
Q_UNIMPLEMENTED();
- return 0;
+ return nullptr;
}
#endif
+#ifndef QT_NO_SSL
QSslKey QSslCertificate::publicKey() const
{
QSslKey key;
@@ -155,6 +158,7 @@ QSslKey QSslCertificate::publicKey() const
}
return key;
}
+#endif
QList<QSslCertificateExtension> QSslCertificate::extensions() const
{
diff --git a/src/network/ssl/qsslcertificate_winrt.cpp b/src/network/ssl/qsslcertificate_winrt.cpp
index eb926d217d..e601307c17 100644
--- a/src/network/ssl/qsslcertificate_winrt.cpp
+++ b/src/network/ssl/qsslcertificate_winrt.cpp
@@ -102,10 +102,11 @@ Qt::HANDLE QSslCertificate::handle() const
HRESULT hr;
ComPtr<IBuffer> buffer;
hr = g->bufferFactory->CreateFromByteArray(d->derData.length(), (BYTE *)d->derData.data(), &buffer);
- RETURN_IF_FAILED("Failed to create the certificate data buffer", return 0);
+ RETURN_IF_FAILED("Failed to create the certificate data buffer", return nullptr);
hr = g->certificateFactory->CreateCertificate(buffer.Get(), &d->certificate);
- RETURN_IF_FAILED("Failed to create the certificate handle from the data buffer", return 0);
+ RETURN_IF_FAILED("Failed to create the certificate handle from the data buffer",
+ return nullptr);
}
return d->certificate.Get();
diff --git a/src/network/ssl/qsslcertificateextension.h b/src/network/ssl/qsslcertificateextension.h
index 2ce2112687..c2910e1707 100644
--- a/src/network/ssl/qsslcertificateextension.h
+++ b/src/network/ssl/qsslcertificateextension.h
@@ -48,9 +48,6 @@
QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_SSL
-
class QSslCertificateExtensionPrivate;
class Q_NETWORK_EXPORT QSslCertificateExtension
@@ -80,8 +77,6 @@ private:
Q_DECLARE_SHARED(QSslCertificateExtension)
-#endif // QT_NO_SSL
-
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 46df181496..df5660d4c3 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -227,7 +227,8 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint &&
d->nextAllowedProtocols == other.d->nextAllowedProtocols &&
d->nextNegotiatedProtocol == other.d->nextNegotiatedProtocol &&
- d->nextProtocolNegotiationStatus == other.d->nextProtocolNegotiationStatus;
+ d->nextProtocolNegotiationStatus == other.d->nextProtocolNegotiationStatus &&
+ d->dtlsCookieEnabled == other.d->dtlsCookieEnabled;
}
/*!
@@ -1030,6 +1031,65 @@ void QSslConfiguration::setDefaultConfiguration(const QSslConfiguration &configu
QSslConfigurationPrivate::setDefaultConfiguration(configuration);
}
+#if QT_CONFIG(dtls) || defined(Q_CLANG_QDOC)
+
+/*!
+ This function returns true if DTLS cookie verification was enabled on a
+ server-side socket.
+
+ \sa setDtlsCookieVerificationEnabled()
+ */
+bool QSslConfiguration::dtlsCookieVerificationEnabled() const
+{
+ return d->dtlsCookieEnabled;
+}
+
+/*!
+ This function enables DTLS cookie verification when \a enable is true.
+
+ \sa dtlsCookieVerificationEnabled()
+ */
+void QSslConfiguration::setDtlsCookieVerificationEnabled(bool enable)
+{
+ d->dtlsCookieEnabled = enable;
+}
+
+/*!
+ Returns the default DTLS configuration to be used in new DTLS
+ connections.
+
+ The default DTLS configuration consists of:
+
+ \list
+ \li no local certificate and no private key
+ \li protocol DtlsV1_2OrLater
+ \li the system's default CA certificate list
+ \li the cipher list equal to the list of the SSL libraries'
+ supported TLS 1.2 ciphers that use 128 or more secret bits
+ for the cipher.
+ \endlist
+
+ \sa setDefaultDtlsConfiguration()
+*/
+QSslConfiguration QSslConfiguration::defaultDtlsConfiguration()
+{
+ return QSslConfigurationPrivate::defaultDtlsConfiguration();
+}
+
+/*!
+ Sets the default DTLS configuration to be used in new DTLS
+ connections to be \a configuration. Existing connections are not
+ affected by this call.
+
+ \sa defaultDtlsConfiguration()
+*/
+void QSslConfiguration::setDefaultDtlsConfiguration(const QSslConfiguration &configuration)
+{
+ QSslConfigurationPrivate::setDefaultDtlsConfiguration(configuration);
+}
+
+#endif // dtls
+
/*! \internal
*/
bool QSslConfigurationPrivate::peerSessionWasShared(const QSslConfiguration &configuration) {
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index fe4181d755..454ac0cee3 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -73,6 +73,11 @@ class QSslKey;
class QSslEllipticCurve;
class QSslDiffieHellmanParameters;
+namespace dtlsopenssl
+{
+class DtlsState;
+}
+
class QSslConfigurationPrivate;
class Q_NETWORK_EXPORT QSslConfiguration
{
@@ -157,6 +162,14 @@ public:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
+#if QT_CONFIG(dtls) || defined(Q_CLANG_QDOC)
+ bool dtlsCookieVerificationEnabled() const;
+ void setDtlsCookieVerificationEnabled(bool enable);
+
+ static QSslConfiguration defaultDtlsConfiguration();
+ static void setDefaultDtlsConfiguration(const QSslConfiguration &configuration);
+#endif // dtls
+
enum NextProtocolNegotiationStatus {
NextProtocolNegotiationNone,
NextProtocolNegotiationNegotiated,
@@ -182,6 +195,8 @@ private:
friend class QSslConfigurationPrivate;
friend class QSslSocketBackendPrivate;
friend class QSslContext;
+ friend class QDtlsBasePrivate;
+ friend class dtlsopenssl::DtlsState;
QSslConfiguration(QSslConfigurationPrivate *dd);
QSharedDataPointer<QSslConfigurationPrivate> d;
};
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 38a98239db..6c23165c6a 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -137,10 +137,19 @@ public:
QByteArray nextNegotiatedProtocol;
QSslConfiguration::NextProtocolNegotiationStatus nextProtocolNegotiationStatus;
+#if QT_CONFIG(dtls)
+ bool dtlsCookieEnabled = true;
+#else
+ const bool dtlsCookieEnabled = false;
+#endif // dtls
+
// in qsslsocket.cpp:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
static void deepCopyDefaultConfiguration(QSslConfigurationPrivate *config);
+
+ static QSslConfiguration defaultDtlsConfiguration();
+ static void setDefaultDtlsConfiguration(const QSslConfiguration &configuration);
};
// implemented here for inlining purposes
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp
index 41b759364b..35cca9f01a 100644
--- a/src/network/ssl/qsslcontext_openssl.cpp
+++ b/src/network/ssl/qsslcontext_openssl.cpp
@@ -55,9 +55,9 @@ static inline QString msgErrorSettingBackendConfig(const QString &why)
}
QSslContext::QSslContext()
- : ctx(0),
- pkey(0),
- session(0),
+ : ctx(nullptr),
+ pkey(nullptr),
+ session(nullptr),
m_sessionTicketLifeTimeHint(-1)
{
}
@@ -137,7 +137,8 @@ SSL* QSslContext::createSsl()
if (!session && !sessionASN1().isEmpty()
&& !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
const unsigned char *data = reinterpret_cast<const unsigned char *>(m_sessionASN1.constData());
- session = q_d2i_SSL_SESSION(0, &data, m_sessionASN1.size()); // refcount is 1 already, set by function above
+ session = q_d2i_SSL_SESSION(
+ nullptr, &data, m_sessionASN1.size()); // refcount is 1 already, set by function above
}
if (session) {
@@ -145,7 +146,7 @@ SSL* QSslContext::createSsl()
if (!q_SSL_set_session(ssl, session)) {
qCWarning(lcSsl, "could not set SSL session");
q_SSL_SESSION_free(session);
- session = 0;
+ session = nullptr;
}
}
@@ -204,7 +205,7 @@ bool QSslContext::cacheSession(SSL* ssl)
session = q_SSL_get1_session(ssl);
if (session && !sslConfiguration.testSslOption(QSsl::SslOptionDisableSessionPersistence)) {
- int sessionSize = q_i2d_SSL_SESSION(session, 0);
+ int sessionSize = q_i2d_SSL_SESSION(session, nullptr);
if (sessionSize > 0) {
m_sessionASN1.resize(sessionSize);
unsigned char *data = reinterpret_cast<unsigned char *>(m_sessionASN1.data());
@@ -214,7 +215,7 @@ bool QSslContext::cacheSession(SSL* ssl)
}
}
- return (session != 0);
+ return (session != nullptr);
}
QByteArray QSslContext::sessionASN1() const
diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp
index 4fb33cb0a4..708cb7bb0e 100644
--- a/src/network/ssl/qsslcontext_openssl11.cpp
+++ b/src/network/ssl/qsslcontext_openssl11.cpp
@@ -59,11 +59,26 @@ QT_BEGIN_NAMESPACE
extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
extern QString getErrorsFromOpenSsl();
+#if QT_CONFIG(dtls)
+// defined in qdtls_openssl.cpp:
+namespace dtlscallbacks
+{
+extern "C" int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx);
+extern "C" int q_generate_cookie_callback(SSL *ssl, unsigned char *dst,
+ unsigned *cookieLength);
+extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
+ unsigned cookieLength);
+}
+#endif // dtls
+
static inline QString msgErrorSettingEllipticCurves(const QString &why)
{
return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
}
+// Defined in qsslsocket.cpp
+QList<QSslCipher> q_getDefaultDtlsCiphers();
+
// static
void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
{
@@ -74,14 +89,27 @@ void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mo
bool reinitialized = false;
bool unsupportedProtocol = false;
+ bool isDtls = false;
init_context:
if (sslContext->sslConfiguration.protocol() == QSsl::SslV2) {
// SSL 2 is no longer supported, but chosen deliberately -> error
sslContext->ctx = nullptr;
unsupportedProtocol = true;
} else {
- // The ssl options will actually control the supported methods
- sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method());
+ switch (sslContext->sslConfiguration.protocol()) {
+#if QT_CONFIG(dtls)
+ case QSsl::DtlsV1_0:
+ case QSsl::DtlsV1_0OrLater:
+ case QSsl::DtlsV1_2:
+ case QSsl::DtlsV1_2OrLater:
+ isDtls = true;
+ sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method());
+ break;
+#endif // dtls
+ default:
+ // The ssl options will actually control the supported methods
+ sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method());
+ }
}
if (!sslContext->ctx) {
@@ -100,8 +128,15 @@ init_context:
return;
}
- long minVersion = TLS_ANY_VERSION;
- long maxVersion = TLS_ANY_VERSION;
+ const long anyVersion =
+#if QT_CONFIG(dtls)
+ isDtls ? DTLS_ANY_VERSION : TLS_ANY_VERSION;
+#else
+ TLS_ANY_VERSION;
+#endif // dtls
+ long minVersion = anyVersion;
+ long maxVersion = anyVersion;
+
switch (sslContext->sslConfiguration.protocol()) {
// The single-protocol versions first:
case QSsl::SslV3:
@@ -139,6 +174,24 @@ init_context:
minVersion = TLS1_2_VERSION;
maxVersion = 0;
break;
+#if QT_CONFIG(dtls)
+ case QSsl::DtlsV1_0:
+ minVersion = DTLS1_VERSION;
+ maxVersion = DTLS1_VERSION;
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ minVersion = DTLS1_VERSION;
+ maxVersion = DTLS_MAX_VERSION;
+ break;
+ case QSsl::DtlsV1_2:
+ minVersion = DTLS1_2_VERSION;
+ maxVersion = DTLS1_2_VERSION;
+ break;
+ case QSsl::DtlsV1_2OrLater:
+ minVersion = DTLS1_2_VERSION;
+ maxVersion = DTLS_MAX_VERSION;
+ break;
+#endif // dtls
case QSsl::SslV2:
// This protocol is not supported by OpenSSL 1.1 and we handle
// it as an error (see the code above).
@@ -148,14 +201,14 @@ init_context:
break;
}
- if (minVersion != TLS_ANY_VERSION
+ if (minVersion != anyVersion
&& !q_SSL_CTX_set_min_proto_version(sslContext->ctx, minVersion)) {
sslContext->errorStr = QSslSocket::tr("Error while setting the minimal protocol version");
sslContext->errorCode = QSslError::UnspecifiedError;
return;
}
- if (maxVersion != TLS_ANY_VERSION
+ if (maxVersion != anyVersion
&& !q_SSL_CTX_set_max_proto_version(sslContext->ctx, maxVersion)) {
sslContext->errorStr = QSslSocket::tr("Error while setting the maximum protocol version");
sslContext->errorCode = QSslError::UnspecifiedError;
@@ -175,7 +228,8 @@ init_context:
bool first = true;
QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
if (ciphers.isEmpty())
- ciphers = QSslSocketPrivate::defaultCiphers();
+ ciphers = isDtls ? q_getDefaultDtlsCiphers() : QSslSocketPrivate::defaultCiphers();
+
for (const QSslCipher &cipher : qAsConst(ciphers)) {
if (first)
first = false;
@@ -282,8 +336,19 @@ init_context:
if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, nullptr);
} else {
- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback);
+ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER,
+#if QT_CONFIG(dtls)
+ isDtls ? dtlscallbacks::q_X509DtlsCallback :
+#endif // dtls
+ q_X509Callback);
+ }
+
+#if QT_CONFIG(dtls)
+ if (mode == QSslSocket::SslServerMode && isDtls && configuration.dtlsCookieVerificationEnabled()) {
+ q_SSL_CTX_set_cookie_generate_cb(sslContext->ctx, dtlscallbacks::q_generate_cookie_callback);
+ q_SSL_CTX_set_cookie_verify_cb(sslContext->ctx, dtlscallbacks::q_verify_cookie_callback);
}
+#endif // dtls
// Set verification depth.
if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
@@ -305,8 +370,9 @@ init_context:
if (!dhparams.isEmpty()) {
const QByteArray &params = dhparams.d->derData;
const char *ptr = params.constData();
- DH *dh = q_d2i_DHparams(NULL, reinterpret_cast<const unsigned char **>(&ptr), params.length());
- if (dh == NULL)
+ DH *dh = q_d2i_DHparams(nullptr, reinterpret_cast<const unsigned char **>(&ptr),
+ params.length());
+ if (dh == nullptr)
qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form");
q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh);
q_DH_free(dh);
diff --git a/src/network/ssl/qsslcontext_opensslpre11.cpp b/src/network/ssl/qsslcontext_opensslpre11.cpp
index eea821804f..c8be2ecb31 100644
--- a/src/network/ssl/qsslcontext_opensslpre11.cpp
+++ b/src/network/ssl/qsslcontext_opensslpre11.cpp
@@ -56,11 +56,26 @@ QT_BEGIN_NAMESPACE
extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
extern QString getErrorsFromOpenSsl();
+#if QT_CONFIG(dtls)
+// defined in qdtls_openssl.cpp:
+namespace dtlscallbacks
+{
+extern "C" int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx);
+extern "C" int q_generate_cookie_callback(SSL *ssl, unsigned char *dst,
+ unsigned *cookieLength);
+extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
+ unsigned cookieLength);
+}
+#endif // dtls
+
static inline QString msgErrorSettingEllipticCurves(const QString &why)
{
return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
}
+// Defined in qsslsocket.cpp
+QList<QSslCipher> q_getDefaultDtlsCiphers();
+
// static
void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
{
@@ -68,11 +83,28 @@ void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mo
sslContext->errorCode = QSslError::NoError;
bool client = (mode == QSslSocket::SslClientMode);
-
bool reinitialized = false;
bool unsupportedProtocol = false;
+ bool isDtls = false;
init_context:
switch (sslContext->sslConfiguration.protocol()) {
+#if QT_CONFIG(dtls)
+ case QSsl::DtlsV1_0:
+ isDtls = true;
+ sslContext->ctx = q_SSL_CTX_new(client ? q_DTLSv1_client_method() : q_DTLSv1_server_method());
+ break;
+ case QSsl::DtlsV1_2:
+ case QSsl::DtlsV1_2OrLater:
+ // OpenSSL 1.0.2 and below will probably never receive TLS 1.3, so
+ // technically 1.2 or later is 1.2 and will stay so.
+ isDtls = true;
+ sslContext->ctx = q_SSL_CTX_new(client ? q_DTLSv1_2_client_method() : q_DTLSv1_2_server_method());
+ break;
+ case QSsl::DtlsV1_0OrLater:
+ isDtls = true;
+ sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method());
+ break;
+#endif // dtls
case QSsl::SslV2:
#ifndef OPENSSL_NO_SSL2
sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
@@ -138,6 +170,12 @@ init_context:
break;
}
+ if (!client && isDtls && configuration.peerVerifyMode() != QSslSocket::VerifyNone) {
+ sslContext->errorStr = QSslSocket::tr("DTLS server requires a 'VerifyNone' mode with your version of OpenSSL");
+ sslContext->errorCode = QSslError::UnspecifiedError;
+ return;
+ }
+
if (!sslContext->ctx) {
// After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them
// by re-initializing the library.
@@ -155,6 +193,7 @@ init_context:
}
// Enable bug workarounds.
+ // DTLSTODO: check this setupOpenSslOptions ...
long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
q_SSL_CTX_set_options(sslContext->ctx, options);
@@ -170,7 +209,7 @@ init_context:
bool first = true;
QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
if (ciphers.isEmpty())
- ciphers = QSslSocketPrivate::defaultCiphers();
+ ciphers = isDtls ? q_getDefaultDtlsCiphers() : QSslSocketPrivate::defaultCiphers();
for (const QSslCipher &cipher : qAsConst(ciphers)) {
if (first)
first = false;
@@ -277,8 +316,19 @@ init_context:
if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0);
} else {
- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback);
+ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER,
+#if QT_CONFIG(dtls)
+ isDtls ? dtlscallbacks::q_X509DtlsCallback :
+#endif // dtls
+ q_X509Callback);
+ }
+
+#if QT_CONFIG(dtls)
+ if (mode == QSslSocket::SslServerMode && isDtls && configuration.dtlsCookieVerificationEnabled()) {
+ q_SSL_CTX_set_cookie_generate_cb(sslContext->ctx, dtlscallbacks::q_generate_cookie_callback);
+ q_SSL_CTX_set_cookie_verify_cb(sslContext->ctx, CookieVerifyCallback(dtlscallbacks::q_verify_cookie_callback));
}
+#endif // dtls
// Set verification depth.
if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
diff --git a/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
index 00e9be91d8..c36482329a 100644
--- a/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
+++ b/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
@@ -128,7 +128,7 @@ void QSslDiffieHellmanParametersPrivate::decodeDer(const QByteArray &der)
QSslSocketPrivate::ensureInitialized();
- DH *dh = q_d2i_DHparams(NULL, &data, len);
+ DH *dh = q_d2i_DHparams(nullptr, &data, len);
if (dh) {
if (isSafeDH(dh))
derData = der;
@@ -162,7 +162,7 @@ void QSslDiffieHellmanParametersPrivate::decodePem(const QByteArray &pem)
}
DH *dh = nullptr;
- q_PEM_read_bio_DHparams(bio, &dh, 0, 0);
+ q_PEM_read_bio_DHparams(bio, &dh, nullptr, nullptr);
if (dh) {
if (isSafeDH(dh)) {
diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp
index 58df544a0e..9a43e67772 100644
--- a/src/network/ssl/qsslkey_openssl.cpp
+++ b/src/network/ssl/qsslkey_openssl.cpp
@@ -62,24 +62,24 @@ void QSslKeyPrivate::clear(bool deep)
if (algorithm == QSsl::Rsa && rsa) {
if (deep)
q_RSA_free(rsa);
- rsa = 0;
+ rsa = nullptr;
}
if (algorithm == QSsl::Dsa && dsa) {
if (deep)
q_DSA_free(dsa);
- dsa = 0;
+ dsa = nullptr;
}
#ifndef OPENSSL_NO_EC
if (algorithm == QSsl::Ec && ec) {
if (deep)
q_EC_KEY_free(ec);
- ec = 0;
+ ec = nullptr;
}
#endif
if (algorithm == QSsl::Opaque && opaque) {
if (deep)
q_EVP_PKEY_free(opaque);
- opaque = 0;
+ opaque = nullptr;
}
}
@@ -125,10 +125,10 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey)
return false;
}
-void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
+void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhrase, bool deepClear)
{
QMap<QByteArray, QByteArray> headers;
- decodePem(pemFromDer(der, headers), QByteArray(), deepClear);
+ decodePem(pemFromDer(der, headers), passPhrase, deepClear);
}
void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhrase,
@@ -150,21 +150,21 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra
if (algorithm == QSsl::Rsa) {
RSA *result = (type == QSsl::PublicKey)
- ? q_PEM_read_bio_RSA_PUBKEY(bio, &rsa, 0, phrase)
- : q_PEM_read_bio_RSAPrivateKey(bio, &rsa, 0, phrase);
+ ? q_PEM_read_bio_RSA_PUBKEY(bio, &rsa, nullptr, phrase)
+ : q_PEM_read_bio_RSAPrivateKey(bio, &rsa, nullptr, phrase);
if (rsa && rsa == result)
isNull = false;
} else if (algorithm == QSsl::Dsa) {
DSA *result = (type == QSsl::PublicKey)
- ? q_PEM_read_bio_DSA_PUBKEY(bio, &dsa, 0, phrase)
- : q_PEM_read_bio_DSAPrivateKey(bio, &dsa, 0, phrase);
+ ? q_PEM_read_bio_DSA_PUBKEY(bio, &dsa, nullptr, phrase)
+ : q_PEM_read_bio_DSAPrivateKey(bio, &dsa, nullptr, phrase);
if (dsa && dsa == result)
isNull = false;
#ifndef OPENSSL_NO_EC
} else if (algorithm == QSsl::Ec) {
EC_KEY *result = (type == QSsl::PublicKey)
- ? q_PEM_read_bio_EC_PUBKEY(bio, &ec, 0, phrase)
- : q_PEM_read_bio_ECPrivateKey(bio, &ec, 0, phrase);
+ ? q_PEM_read_bio_EC_PUBKEY(bio, &ec, nullptr, phrase)
+ : q_PEM_read_bio_ECPrivateKey(bio, &ec, nullptr, phrase);
if (ec && ec == result)
isNull = false;
#endif
@@ -215,8 +215,8 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
fail = true;
} else {
if (!q_PEM_write_bio_RSAPrivateKey(
- bio, rsa, cipher,
- const_cast<uchar *>((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) {
+ bio, rsa, cipher, const_cast<uchar *>((const uchar *)passPhrase.data()),
+ passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
}
@@ -226,8 +226,8 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
fail = true;
} else {
if (!q_PEM_write_bio_DSAPrivateKey(
- bio, dsa, cipher,
- const_cast<uchar *>((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) {
+ bio, dsa, cipher, const_cast<uchar *>((const uchar *)passPhrase.data()),
+ passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
}
@@ -237,9 +237,9 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const
if (!q_PEM_write_bio_EC_PUBKEY(bio, ec))
fail = true;
} else {
- if (!q_PEM_write_bio_ECPrivateKey(
- bio, ec, cipher,
- const_cast<uchar *>((const uchar *)passPhrase.data()), passPhrase.size(), 0, 0)) {
+ if (!q_PEM_write_bio_ECPrivateKey(bio, ec, cipher,
+ const_cast<uchar *>((const uchar *)passPhrase.data()),
+ passPhrase.size(), nullptr, nullptr)) {
fail = true;
}
}
@@ -272,13 +272,13 @@ Qt::HANDLE QSslKeyPrivate::handle() const
return Qt::HANDLE(ec);
#endif
default:
- return Qt::HANDLE(NULL);
+ return Qt::HANDLE(nullptr);
}
}
static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv, int enc)
{
- const EVP_CIPHER* type = 0;
+ const EVP_CIPHER* type = nullptr;
int i = 0, len = 0;
switch (cipher) {
@@ -314,10 +314,10 @@ static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data,
q_EVP_CIPHER_CTX_init(ctx);
#endif
- q_EVP_CipherInit(ctx, type, NULL, NULL, enc);
+ q_EVP_CipherInit(ctx, type, nullptr, nullptr, enc);
q_EVP_CIPHER_CTX_set_key_length(ctx, key.size());
if (cipher == QSslKeyPrivate::Rc2Cbc)
- q_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, 8 * key.size(), NULL);
+ q_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, 8 * key.size(), nullptr);
#if QT_CONFIG(opensslv11)
// EVP_CipherInit in 1.1 resets the context thus making the calls above useless.
diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp
index e66ec953a0..28e3e2efd8 100644
--- a/src/network/ssl/qsslkey_p.cpp
+++ b/src/network/ssl/qsslkey_p.cpp
@@ -61,6 +61,7 @@
#endif
#include "qsslsocket.h"
#include "qsslsocket_p.h"
+#include "qasn1element_p.h"
#include <QtCore/qatomic.h>
#include <QtCore/qbytearray.h>
@@ -120,6 +121,13 @@ QByteArray QSslKeyPrivate::pemHeader() const
return QByteArray();
}
+static QByteArray pkcs8Header(bool encrypted)
+{
+ return encrypted
+ ? QByteArrayLiteral("-----BEGIN ENCRYPTED PRIVATE KEY-----")
+ : QByteArrayLiteral("-----BEGIN PRIVATE KEY-----");
+}
+
/*!
\internal
*/
@@ -138,6 +146,13 @@ QByteArray QSslKeyPrivate::pemFooter() const
return QByteArray();
}
+static QByteArray pkcs8Footer(bool encrypted)
+{
+ return encrypted
+ ? QByteArrayLiteral("-----END ENCRYPTED PRIVATE KEY-----")
+ : QByteArrayLiteral("-----END PRIVATE KEY-----");
+}
+
/*!
\internal
@@ -166,8 +181,19 @@ QByteArray QSslKeyPrivate::pemFromDer(const QByteArray &der, const QMap<QByteArr
} while (it != headers.constBegin());
extra += '\n';
}
- pem.prepend(pemHeader() + '\n' + extra);
- pem.append(pemFooter() + '\n');
+
+ if (isEncryptedPkcs8(der)) {
+ pem.prepend(pkcs8Header(true) + '\n' + extra);
+ pem.append(pkcs8Footer(true) + '\n');
+#if !QT_CONFIG(openssl)
+ } else if (isPkcs8) {
+ pem.prepend(pkcs8Header(false) + '\n' + extra);
+ pem.append(pkcs8Footer(false) + '\n');
+#endif
+ } else {
+ pem.prepend(pemHeader() + '\n' + extra);
+ pem.append(pemFooter() + '\n');
+ }
return pem;
}
@@ -179,13 +205,27 @@ QByteArray QSslKeyPrivate::pemFromDer(const QByteArray &der, const QMap<QByteArr
*/
QByteArray QSslKeyPrivate::derFromPem(const QByteArray &pem, QMap<QByteArray, QByteArray> *headers) const
{
- const QByteArray header = pemHeader();
- const QByteArray footer = pemFooter();
+ QByteArray header = pemHeader();
+ QByteArray footer = pemFooter();
QByteArray der(pem);
- const int headerIndex = der.indexOf(header);
- const int footerIndex = der.indexOf(footer);
+ int headerIndex = der.indexOf(header);
+ int footerIndex = der.indexOf(footer, headerIndex + header.length());
+ if (type != QSsl::PublicKey) {
+ if (headerIndex == -1 || footerIndex == -1) {
+ header = pkcs8Header(true);
+ footer = pkcs8Footer(true);
+ headerIndex = der.indexOf(header);
+ footerIndex = der.indexOf(footer, headerIndex + header.length());
+ }
+ if (headerIndex == -1 || footerIndex == -1) {
+ header = pkcs8Header(false);
+ footer = pkcs8Footer(false);
+ headerIndex = der.indexOf(header);
+ footerIndex = der.indexOf(footer, headerIndex + header.length());
+ }
+ }
if (headerIndex == -1 || footerIndex == -1)
return QByteArray();
@@ -225,13 +265,47 @@ QByteArray QSslKeyPrivate::derFromPem(const QByteArray &pem, QMap<QByteArray, QB
return QByteArray::fromBase64(der); // ignores newlines
}
+bool QSslKeyPrivate::isEncryptedPkcs8(const QByteArray &der) const
+{
+ static const QVector<QByteArray> pbes1OIds {
+ // PKCS5
+ {PKCS5_MD2_DES_CBC_OID},
+ {PKCS5_MD2_RC2_CBC_OID},
+ {PKCS5_MD5_DES_CBC_OID},
+ {PKCS5_MD5_RC2_CBC_OID},
+ {PKCS5_SHA1_DES_CBC_OID},
+ {PKCS5_SHA1_RC2_CBC_OID},
+ };
+ QAsn1Element elem;
+ if (!elem.read(der) || elem.type() != QAsn1Element::SequenceType)
+ return false;
+
+ const QVector<QAsn1Element> items = elem.toVector();
+ if (items.size() != 2
+ || items[0].type() != QAsn1Element::SequenceType
+ || items[1].type() != QAsn1Element::OctetStringType) {
+ return false;
+ }
+
+ const QVector<QAsn1Element> encryptionSchemeContainer = items[0].toVector();
+ if (encryptionSchemeContainer.size() != 2
+ || encryptionSchemeContainer[0].type() != QAsn1Element::ObjectIdentifierType
+ || encryptionSchemeContainer[1].type() != QAsn1Element::SequenceType) {
+ return false;
+ }
+
+ const QByteArray encryptionScheme = encryptionSchemeContainer[0].toObjectId();
+ return encryptionScheme == PKCS5_PBES2_ENCRYPTION_OID
+ || pbes1OIds.contains(encryptionScheme)
+ || encryptionScheme.startsWith(PKCS12_OID);
+}
+
/*!
Constructs a QSslKey by decoding the string in the byte array
\a encoded using a specified \a algorithm and \a encoding format.
\a type specifies whether the key is public or private.
- If the key is encoded as PEM and encrypted, \a passPhrase is used
- to decrypt it.
+ If the key is encrypted then \a passPhrase is used to decrypt it.
After construction, use isNull() to check if \a encoded contained
a valid key.
@@ -243,7 +317,7 @@ QSslKey::QSslKey(const QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
d->type = type;
d->algorithm = algorithm;
if (encoding == QSsl::Der)
- d->decodeDer(encoded);
+ d->decodeDer(encoded, passPhrase);
else
d->decodePem(encoded, passPhrase);
}
@@ -253,8 +327,7 @@ QSslKey::QSslKey(const QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
\a device using a specified \a algorithm and \a encoding format.
\a type specifies whether the key is public or private.
- If the key is encoded as PEM and encrypted, \a passPhrase is used
- to decrypt it.
+ If the key is encrypted then \a passPhrase is used to decrypt it.
After construction, use isNull() to check if \a device provided
a valid key.
@@ -269,7 +342,7 @@ QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::Encoding
d->type = type;
d->algorithm = algorithm;
if (encoding == QSsl::Der)
- d->decodeDer(encoded);
+ d->decodeDer(encoded, passPhrase);
else
d->decodePem(encoded, passPhrase);
}
diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h
index c93941c198..7ae2cc740b 100644
--- a/src/network/ssl/qsslkey_p.h
+++ b/src/network/ssl/qsslkey_p.h
@@ -81,9 +81,8 @@ public:
#ifndef QT_NO_OPENSSL
bool fromEVP_PKEY(EVP_PKEY *pkey);
#endif
- void decodeDer(const QByteArray &der, bool deepClear = true);
- void decodePem(const QByteArray &pem, const QByteArray &passPhrase,
- bool deepClear = true);
+ void decodeDer(const QByteArray &der, const QByteArray &passPhrase = {}, bool deepClear = true);
+ void decodePem(const QByteArray &pem, const QByteArray &passPhrase, bool deepClear = true);
QByteArray pemHeader() const;
QByteArray pemFooter() const;
QByteArray pemFromDer(const QByteArray &der, const QMap<QByteArray, QByteArray> &headers) const;
@@ -93,6 +92,12 @@ public:
QByteArray toPem(const QByteArray &passPhrase) const;
Qt::HANDLE handle() const;
+ bool isEncryptedPkcs8(const QByteArray &der) const;
+#if !QT_CONFIG(openssl)
+ QByteArray decryptPkcs8(const QByteArray &encrypted, const QByteArray &passPhrase);
+ bool isPkcs8 = false;
+#endif
+
bool isNull;
QSsl::KeyType type;
QSsl::KeyAlgorithm algorithm;
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index a85fed21ed..a13275f3bb 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -43,8 +43,11 @@
#include <QtCore/qdatastream.h>
#include <QtCore/qcryptographichash.h>
+#include <QtCore/QMessageAuthenticationCode>
#include <QtCore/qrandom.h>
+#include <QtNetwork/qpassworddigestor.h>
+
QT_USE_NAMESPACE
static const quint8 bits_table[256] = {
@@ -154,15 +157,86 @@ void QSslKeyPrivate::clear(bool deep)
keyLength = -1;
}
-void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
+static int extractPkcs8KeyLength(const QVector<QAsn1Element> &items, QSslKeyPrivate *that) {
+ Q_ASSERT(items.size() == 3);
+ int keyLength;
+
+ auto getName = [](QSsl::KeyAlgorithm algorithm) {
+ switch (algorithm){
+ case QSsl::Rsa: return "RSA";
+ case QSsl::Dsa: return "DSA";
+ case QSsl::Ec: return "EC";
+ case QSsl::Opaque: return "Opaque";
+ }
+ Q_UNREACHABLE();
+ };
+
+ const QVector<QAsn1Element> pkcs8Info = items[1].toVector();
+ if (pkcs8Info.size() != 2 || pkcs8Info[0].type() != QAsn1Element::ObjectIdentifierType)
+ return -1;
+ const QByteArray value = pkcs8Info[0].toObjectId();
+ if (value == RSA_ENCRYPTION_OID) {
+ if (Q_UNLIKELY(that->algorithm != QSsl::Rsa)) {
+ // We could change the 'algorithm' of QSslKey here and continue loading, but
+ // this is not supported in the openssl back-end, so we'll fail here and give
+ // the user some feedback.
+ qWarning() << "QSslKey: Found RSA key when asked to use" << getName(that->algorithm)
+ << "\nLoading will fail.";
+ return -1;
+ }
+ // Luckily it contains the 'normal' RSA-key format inside, so we can just recurse
+ // and read the key's info.
+ that->decodeDer(items[2].value());
+ // The real info has been filled out in the call above, so return as if it was invalid
+ // to avoid overwriting the data.
+ return -1;
+ } else if (value == EC_ENCRYPTION_OID) {
+ if (Q_UNLIKELY(that->algorithm != QSsl::Ec)) {
+ // As above for RSA.
+ qWarning() << "QSslKey: Found EC key when asked to use" << getName(that->algorithm)
+ << "\nLoading will fail.";
+ return -1;
+ }
+ // I don't know where this is documented, but the elliptic-curve identifier has been
+ // moved into the "pkcs#8 wrapper", which is what we're interested in.
+ if (pkcs8Info[1].type() != QAsn1Element::ObjectIdentifierType)
+ return -1;
+ keyLength = curveBits(pkcs8Info[1].toObjectId());
+ } else if (value == DSA_ENCRYPTION_OID) {
+ if (Q_UNLIKELY(that->algorithm != QSsl::Dsa)) {
+ // As above for RSA.
+ qWarning() << "QSslKey: Found DSA when asked to use" << getName(that->algorithm)
+ << "\nLoading will fail.";
+ return -1;
+ }
+ // DSA's structure is documented here:
+ // https://www.cryptsoft.com/pkcs11doc/STANDARD/v201-95.pdf in section 11.9.
+ if (pkcs8Info[1].type() != QAsn1Element::SequenceType)
+ return -1;
+ const QVector<QAsn1Element> dsaInfo = pkcs8Info[1].toVector();
+ if (dsaInfo.size() != 3 || dsaInfo[0].type() != QAsn1Element::IntegerType)
+ return -1;
+ keyLength = numberOfBits(dsaInfo[0].value());
+ } else {
+ // in case of unexpected formats:
+ qWarning() << "QSslKey: Unsupported PKCS#8 key algorithm:" << value
+ << "\nFile a bugreport to Qt (include the line above).";
+ return -1;
+ }
+ return keyLength;
+}
+
+void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhrase, bool deepClear)
{
clear(deepClear);
if (der.isEmpty())
return;
+ // decryptPkcs8 decrypts if necessary or returns 'der' unaltered
+ QByteArray decryptedDer = decryptPkcs8(der, passPhrase);
QAsn1Element elem;
- if (!elem.read(der) || elem.type() != QAsn1Element::SequenceType)
+ if (!elem.read(decryptedDer) || elem.type() != QAsn1Element::SequenceType)
return;
if (type == QSsl::PublicKey) {
@@ -212,7 +286,16 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
return;
const QByteArray versionHex = items[0].value().toHex();
- if (algorithm == QSsl::Rsa) {
+ if (items.size() == 3 && items[1].type() == QAsn1Element::SequenceType
+ && items[2].type() == QAsn1Element::OctetStringType) {
+ if (versionHex != "00" && versionHex != "01")
+ return;
+ int pkcs8KeyLength = extractPkcs8KeyLength(items, this);
+ if (pkcs8KeyLength == -1)
+ return;
+ isPkcs8 = true;
+ keyLength = pkcs8KeyLength;
+ } else if (algorithm == QSsl::Rsa) {
if (versionHex != "00")
return;
if (items.size() != 9 || items[1].type() != QAsn1Element::IntegerType)
@@ -240,7 +323,7 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
}
}
- derData = der;
+ derData = decryptedDer;
isNull = false;
}
@@ -272,7 +355,7 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra
const QByteArray key = deriveKey(cipher, passPhrase, iv);
data = decrypt(cipher, data, key, iv);
}
- decodeDer(data, deepClear);
+ decodeDer(data, passPhrase, deepClear);
}
int QSslKeyPrivate::length() const
@@ -307,3 +390,320 @@ Qt::HANDLE QSslKeyPrivate::handle() const
{
return opaque;
}
+
+// Maps OIDs to the encryption cipher they specify
+static const QMap<QByteArray, QSslKeyPrivate::Cipher> oidCipherMap {
+ {DES_CBC_ENCRYPTION_OID, QSslKeyPrivate::Cipher::DesCbc},
+ {DES_EDE3_CBC_ENCRYPTION_OID, QSslKeyPrivate::Cipher::DesEde3Cbc},
+ // {PKCS5_MD2_DES_CBC_OID, QSslKeyPrivate::Cipher::DesCbc}, // No MD2
+ {PKCS5_MD5_DES_CBC_OID, QSslKeyPrivate::Cipher::DesCbc},
+ {PKCS5_SHA1_DES_CBC_OID, QSslKeyPrivate::Cipher::DesCbc},
+ // {PKCS5_MD2_RC2_CBC_OID, QSslKeyPrivate::Cipher::Rc2Cbc}, // No MD2
+ {PKCS5_MD5_RC2_CBC_OID, QSslKeyPrivate::Cipher::Rc2Cbc},
+ {PKCS5_SHA1_RC2_CBC_OID, QSslKeyPrivate::Cipher::Rc2Cbc},
+ {RC2_CBC_ENCRYPTION_OID, QSslKeyPrivate::Cipher::Rc2Cbc}
+ // {RC5_CBC_ENCRYPTION_OID, QSslKeyPrivate::Cipher::Rc5Cbc}, // No RC5
+ // {AES128_CBC_ENCRYPTION_OID, QSslKeyPrivate::Cipher::Aes128}, // no AES
+ // {AES192_CBC_ENCRYPTION_OID, QSslKeyPrivate::Cipher::Aes192},
+ // {AES256_CBC_ENCRYPTION_OID, QSslKeyPrivate::Cipher::Aes256}
+};
+
+struct EncryptionData
+{
+ EncryptionData() : initialized(false)
+ {}
+ EncryptionData(QSslKeyPrivate::Cipher cipher, QByteArray key, QByteArray iv)
+ : initialized(true), cipher(cipher), key(key), iv(iv)
+ {}
+ bool initialized;
+ QSslKeyPrivate::Cipher cipher;
+ QByteArray key;
+ QByteArray iv;
+};
+
+static EncryptionData readPbes2(const QVector<QAsn1Element> &element, const QByteArray &passPhrase)
+{
+ // RFC 8018: https://tools.ietf.org/html/rfc8018#section-6.2
+ /*** Scheme: ***
+ * Sequence (scheme-specific info..)
+ * Sequence (key derivation info)
+ * Object Identifier (Key derivation algorithm (e.g. PBKDF2))
+ * Sequence (salt)
+ * CHOICE (this entry can be either of the types it contains)
+ * Octet string (actual salt)
+ * Object identifier (Anything using this is deferred to a later version of PKCS #5)
+ * Integer (iteration count)
+ * Sequence (encryption algorithm info)
+ * Object identifier (identifier for the algorithm)
+ * Algorithm dependent, is covered in the switch further down
+ */
+
+ static const QMap<QByteArray, QCryptographicHash::Algorithm> pbes2OidHashFunctionMap {
+ // PBES2/PBKDF2
+ {HMAC_WITH_SHA1, QCryptographicHash::Sha1},
+ {HMAC_WITH_SHA224, QCryptographicHash::Sha224},
+ {HMAC_WITH_SHA256, QCryptographicHash::Sha256},
+ {HMAC_WITH_SHA512, QCryptographicHash::Sha512},
+ {HMAC_WITH_SHA512_224, QCryptographicHash::Sha512},
+ {HMAC_WITH_SHA512_256, QCryptographicHash::Sha512},
+ {HMAC_WITH_SHA384, QCryptographicHash::Sha384}
+ };
+
+ // Values from their respective sections here: https://tools.ietf.org/html/rfc8018#appendix-B.2
+ static const QMap<QSslKeyPrivate::Cipher, int> cipherKeyLengthMap {
+ {QSslKeyPrivate::Cipher::DesCbc, 8},
+ {QSslKeyPrivate::Cipher::DesEde3Cbc, 24},
+ // @note: variable key-length (https://tools.ietf.org/html/rfc8018#appendix-B.2.3)
+ {QSslKeyPrivate::Cipher::Rc2Cbc, 4}
+ // @todo: AES(, rc5?)
+ };
+
+ const QVector<QAsn1Element> keyDerivationContainer = element[0].toVector();
+ if (keyDerivationContainer.size() != 2
+ || keyDerivationContainer[0].type() != QAsn1Element::ObjectIdentifierType
+ || keyDerivationContainer[1].type() != QAsn1Element::SequenceType) {
+ return {};
+ }
+
+ const QByteArray keyDerivationAlgorithm = keyDerivationContainer[0].toObjectId();
+ const QVector<QAsn1Element> keyDerivationParams = keyDerivationContainer[1].toVector();
+
+ const QVector<QAsn1Element> encryptionAlgorithmContainer = element[1].toVector();
+ if (encryptionAlgorithmContainer.size() != 2
+ || encryptionAlgorithmContainer[0].type() != QAsn1Element::ObjectIdentifierType) {
+ return {};
+ }
+
+ auto iterator = oidCipherMap.constFind(encryptionAlgorithmContainer[0].toObjectId());
+ if (iterator == oidCipherMap.cend()) {
+ qWarning()
+ << "QSslKey: Unsupported encryption cipher OID:" << encryptionAlgorithmContainer[0].toObjectId()
+ << "\nFile a bugreport to Qt (include the line above).";
+ return {};
+ }
+
+ QSslKeyPrivate::Cipher cipher = *iterator;
+ QByteArray key;
+ QByteArray iv;
+ switch (cipher) {
+ case QSslKeyPrivate::Cipher::DesCbc:
+ case QSslKeyPrivate::Cipher::DesEde3Cbc:
+ // https://tools.ietf.org/html/rfc8018#appendix-B.2.1 (DES-CBC-PAD)
+ // https://tools.ietf.org/html/rfc8018#appendix-B.2.2 (DES-EDE3-CBC-PAD)
+ // @todo https://tools.ietf.org/html/rfc8018#appendix-B.2.5 (AES-CBC-PAD)
+ /*** Scheme: ***
+ * Octet string (IV)
+ */
+ if (encryptionAlgorithmContainer[1].type() != QAsn1Element::OctetStringType)
+ return {};
+
+ // @note: All AES identifiers should be able to use this branch!!
+ iv = encryptionAlgorithmContainer[1].value();
+
+ if (iv.size() != 8) // @note: AES needs 16 bytes
+ return {};
+ break;
+ case QSslKeyPrivate::Cipher::Rc2Cbc: {
+ // https://tools.ietf.org/html/rfc8018#appendix-B.2.3
+ /*** Scheme: ***
+ * Sequence (rc2 parameters)
+ * Integer (rc2 parameter version)
+ * Octet string (IV)
+ */
+ if (encryptionAlgorithmContainer[1].type() != QAsn1Element::SequenceType)
+ return {};
+ const QVector<QAsn1Element> rc2ParametersContainer = encryptionAlgorithmContainer[1].toVector();
+ if ((rc2ParametersContainer.size() != 1 && rc2ParametersContainer.size() != 2)
+ || rc2ParametersContainer.back().type() != QAsn1Element::OctetStringType) {
+ return {};
+ }
+ iv = rc2ParametersContainer.back().value();
+ if (iv.size() != 8)
+ return {};
+ break;
+ } // @todo(?): case (RC5 , AES)
+ }
+
+ if (Q_LIKELY(keyDerivationAlgorithm == PKCS5_PBKDF2_ENCRYPTION_OID)) {
+ // Definition: https://tools.ietf.org/html/rfc8018#appendix-A.2
+ QByteArray salt;
+ if (keyDerivationParams[0].type() == QAsn1Element::OctetStringType) {
+ salt = keyDerivationParams[0].value();
+ } else if (keyDerivationParams[0].type() == QAsn1Element::ObjectIdentifierType) {
+ Q_UNIMPLEMENTED();
+ /* See paragraph from https://tools.ietf.org/html/rfc8018#appendix-A.2
+ which ends with: "such facilities are deferred to a future version of PKCS #5"
+ */
+ return {};
+ } else {
+ return {};
+ }
+
+ // Iterations needed to derive the key
+ int iterationCount = keyDerivationParams[1].toInteger();
+ // Optional integer
+ int keyLength = -1;
+ int vectorPos = 2;
+ if (keyDerivationParams.size() > vectorPos
+ && keyDerivationParams[vectorPos].type() == QAsn1Element::IntegerType) {
+ keyLength = keyDerivationParams[vectorPos].toInteger(nullptr);
+ ++vectorPos;
+ } else {
+ keyLength = cipherKeyLengthMap[cipher];
+ }
+
+ // Optional algorithm identifier (default: HMAC-SHA-1)
+ QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha1;
+ if (keyDerivationParams.size() > vectorPos
+ && keyDerivationParams[vectorPos].type() == QAsn1Element::SequenceType) {
+ QVector<QAsn1Element> hashAlgorithmContainer = keyDerivationParams[vectorPos].toVector();
+ hashAlgorithm = pbes2OidHashFunctionMap[hashAlgorithmContainer.front().toObjectId()];
+ Q_ASSERT(hashAlgorithmContainer[1].type() == QAsn1Element::NullType);
+ ++vectorPos;
+ }
+ Q_ASSERT(keyDerivationParams.size() == vectorPos);
+
+ key = QPasswordDigestor::deriveKeyPbkdf2(hashAlgorithm, passPhrase, salt, iterationCount, keyLength);
+ } else {
+ qWarning()
+ << "QSslKey: Unsupported key derivation algorithm OID:" << keyDerivationAlgorithm
+ << "\nFile a bugreport to Qt (include the line above).";
+ return {};
+ }
+ return {cipher, key, iv};
+}
+
+// Maps OIDs to the hash function it specifies
+static const QMap<QByteArray, QCryptographicHash::Algorithm> pbes1OidHashFunctionMap {
+#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ // PKCS5
+ //{PKCS5_MD2_DES_CBC_OID, QCryptographicHash::Md2}, No MD2
+ //{PKCS5_MD2_RC2_CBC_OID, QCryptographicHash::Md2},
+ {PKCS5_MD5_DES_CBC_OID, QCryptographicHash::Md5},
+ {PKCS5_MD5_RC2_CBC_OID, QCryptographicHash::Md5},
+#endif
+ {PKCS5_SHA1_DES_CBC_OID, QCryptographicHash::Sha1},
+ {PKCS5_SHA1_RC2_CBC_OID, QCryptographicHash::Sha1},
+ // PKCS12 (unimplemented)
+ // {PKCS12_SHA1_RC4_128_OID, QCryptographicHash::Sha1}, // No RC4
+ // {PKCS12_SHA1_RC4_40_OID, QCryptographicHash::Sha1},
+ // @todo: lacking support. @note: there might be code to do this inside qsslsocket_mac...
+ // further note that more work may be required for the 3DES variations listed to be available.
+ // {PKCS12_SHA1_3KEY_3DES_CBC_OID, QCryptographicHash::Sha1},
+ // {PKCS12_SHA1_2KEY_3DES_CBC_OID, QCryptographicHash::Sha1},
+ // {PKCS12_SHA1_RC2_128_CBC_OID, QCryptographicHash::Sha1},
+ // {PKCS12_SHA1_RC2_40_CBC_OID, QCryptographicHash::Sha1}
+};
+
+
+static EncryptionData readPbes1(const QVector<QAsn1Element> &element, const QByteArray &encryptionScheme, const QByteArray &passPhrase)
+{
+ // RFC 8018: https://tools.ietf.org/html/rfc8018#section-6.1
+ // Steps refer to this section: https://tools.ietf.org/html/rfc8018#section-6.1.2
+ /*** Scheme: ***
+ * Sequence (PBE Parameter)
+ * Octet string (salt)
+ * Integer (iteration counter)
+ */
+ // Step 1
+ if (element.size() != 2
+ || element[0].type() != QAsn1Element::ElementType::OctetStringType
+ || element[1].type() != QAsn1Element::ElementType::IntegerType) {
+ return {};
+ }
+ QByteArray salt = element[0].value();
+ if (salt.size() != 8)
+ return {};
+
+ int iterationCount = element[1].toInteger();
+ if (iterationCount < 0)
+ return {};
+
+ // Step 2
+ auto iterator = pbes1OidHashFunctionMap.constFind(encryptionScheme);
+ if (iterator == pbes1OidHashFunctionMap.cend()) {
+ // Qt was compiled with ONLY_SHA1 (or it's MD2)
+ return {};
+ }
+ QCryptographicHash::Algorithm hashAlgorithm = *iterator;
+ QByteArray key = QPasswordDigestor::deriveKeyPbkdf1(hashAlgorithm, passPhrase, salt, iterationCount, 16);
+ if (key.size() != 16)
+ return {};
+
+ // Step 3
+ QByteArray iv = key.right(8); // last 8 bytes are used as IV
+ key.truncate(8); // first 8 bytes are used for the key
+
+ QSslKeyPrivate::Cipher cipher = oidCipherMap[encryptionScheme];
+#ifdef Q_OS_WINRT
+ // @todo: document this instead? find some other solution?
+ if (cipher == QSslKeyPrivate::Cipher::Rc2Cbc)
+ qWarning("PBES1 with RC2_CBC doesn't work properly on WinRT.");
+#endif
+ // Steps 4-6 are done after returning
+ return {cipher, key, iv};
+}
+
+QByteArray QSslKeyPrivate::decryptPkcs8(const QByteArray &encrypted, const QByteArray &passPhrase)
+{
+ // RFC 5958: https://tools.ietf.org/html/rfc5958
+ /*** Scheme: ***
+ * Sequence
+ * Sequence
+ * Object Identifier (encryption scheme (currently PBES2, PBES1, @todo PKCS12))
+ * Sequence (scheme parameters)
+ * Octet String (the encrypted data)
+ */
+ QAsn1Element elem;
+ if (!elem.read(encrypted) || elem.type() != QAsn1Element::SequenceType)
+ return encrypted;
+
+ const QVector<QAsn1Element> items = elem.toVector();
+ if (items.size() != 2
+ || items[0].type() != QAsn1Element::SequenceType
+ || items[1].type() != QAsn1Element::OctetStringType) {
+ return encrypted;
+ }
+
+ const QVector<QAsn1Element> encryptionSchemeContainer = items[0].toVector();
+
+ if (encryptionSchemeContainer.size() != 2
+ || encryptionSchemeContainer[0].type() != QAsn1Element::ObjectIdentifierType
+ || encryptionSchemeContainer[1].type() != QAsn1Element::SequenceType) {
+ return encrypted;
+ }
+
+ const QByteArray encryptionScheme = encryptionSchemeContainer[0].toObjectId();
+ const QVector<QAsn1Element> schemeParameterContainer = encryptionSchemeContainer[1].toVector();
+
+ if (schemeParameterContainer.size() != 2
+ && schemeParameterContainer[0].type() != QAsn1Element::SequenceType
+ && schemeParameterContainer[1].type() != QAsn1Element::SequenceType) {
+ return encrypted;
+ }
+
+ EncryptionData data;
+ if (encryptionScheme == PKCS5_PBES2_ENCRYPTION_OID) {
+ data = readPbes2(schemeParameterContainer, passPhrase);
+ } else if (pbes1OidHashFunctionMap.contains(encryptionScheme)) {
+ data = readPbes1(schemeParameterContainer, encryptionScheme, passPhrase);
+ } else if (encryptionScheme.startsWith(PKCS12_OID)) {
+ Q_UNIMPLEMENTED(); // this isn't some 'unknown', I know these aren't implemented
+ return encrypted;
+ } else {
+ qWarning()
+ << "QSslKey: Unsupported encryption scheme OID:" << encryptionScheme
+ << "\nFile a bugreport to Qt (include the line above).";
+ return encrypted;
+ }
+
+ if (!data.initialized) {
+ // something went wrong, return
+ return encrypted;
+ }
+
+ QByteArray decryptedKey = decrypt(data.cipher, items[1].value(), data.key, data.iv);
+ // The data is still wrapped in a octet string, so let's unwrap it
+ QAsn1Element decryptedKeyElement(QAsn1Element::ElementType::OctetStringType, decryptedKey);
+ return decryptedKeyElement.value();
+}
diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.h b/src/network/ssl/qsslpresharedkeyauthenticator.h
index 74ab888000..423f7731b4 100644
--- a/src/network/ssl/qsslpresharedkeyauthenticator.h
+++ b/src/network/ssl/qsslpresharedkeyauthenticator.h
@@ -78,6 +78,7 @@ public:
private:
friend Q_NETWORK_EXPORT bool operator==(const QSslPreSharedKeyAuthenticator &lhs, const QSslPreSharedKeyAuthenticator &rhs);
friend class QSslSocketBackendPrivate;
+ friend class QDtlsPrivateOpenSSL;
QSharedDataPointer<QSslPreSharedKeyAuthenticatorPrivate> d;
};
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 4273904c12..5722f38f45 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -336,12 +336,20 @@ QT_BEGIN_NAMESPACE
class QSslSocketGlobalData
{
public:
- QSslSocketGlobalData() : config(new QSslConfigurationPrivate) {}
+ QSslSocketGlobalData()
+ : config(new QSslConfigurationPrivate),
+ dtlsConfig(new QSslConfigurationPrivate)
+ {
+#if QT_CONFIG(dtls)
+ dtlsConfig->protocol = QSsl::DtlsV1_2OrLater;
+#endif // dtls
+ }
QMutex mutex;
QList<QSslCipher> supportedCiphers;
QVector<QSslEllipticCurve> supportedEllipticCurves;
QExplicitlySharedDataPointer<QSslConfigurationPrivate> config;
+ QExplicitlySharedDataPointer<QSslConfigurationPrivate> dtlsConfig;
};
Q_GLOBAL_STATIC(QSslSocketGlobalData, globalData)
@@ -371,7 +379,7 @@ QSslSocket::~QSslSocket()
qCDebug(lcSsl) << "QSslSocket::~QSslSocket(), this =" << (void *)this;
#endif
delete d->plainSocket;
- d->plainSocket = 0;
+ d->plainSocket = nullptr;
}
/*!
@@ -442,6 +450,12 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, O
return;
}
+ if (!supportsSsl()) {
+ qCWarning(lcSsl, "QSslSocket::connectToHostEncrypted: TLS initialization failed");
+ d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
+ return;
+ }
+
d->init();
d->autoStartHandshake = true;
d->initialized = true;
@@ -473,6 +487,12 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port,
return;
}
+ if (!supportsSsl()) {
+ qCWarning(lcSsl, "QSslSocket::connectToHostEncrypted: TLS initialization failed");
+ d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
+ return;
+ }
+
d->init();
d->autoStartHandshake = true;
d->initialized = true;
@@ -1817,6 +1837,12 @@ void QSslSocket::startClientEncryption()
"QSslSocket::startClientEncryption: cannot start handshake when not connected");
return;
}
+
+ if (!supportsSsl()) {
+ qCWarning(lcSsl, "QSslSocket::startClientEncryption: TLS initialization failed");
+ d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
+ return;
+ }
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << "QSslSocket::startClientEncryption()";
#endif
@@ -1855,6 +1881,11 @@ void QSslSocket::startServerEncryption()
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << "QSslSocket::startServerEncryption()";
#endif
+ if (!supportsSsl()) {
+ qCWarning(lcSsl, "QSslSocket::startServerEncryption: TLS initialization failed");
+ d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
+ return;
+ }
d->mode = SslServerMode;
emit modeChanged(d->mode);
d->startServerEncryption();
@@ -2046,9 +2077,9 @@ QSslSocketPrivate::QSslSocketPrivate()
, connectionEncrypted(false)
, shutdown(false)
, ignoreAllSslErrors(false)
- , readyReadEmittedPointer(0)
+ , readyReadEmittedPointer(nullptr)
, allowRootCertOnDemandLoading(true)
- , plainSocket(0)
+ , plainSocket(nullptr)
, paused(false)
, flushTriggered(false)
{
@@ -2128,6 +2159,26 @@ void QSslSocketPrivate::setDefaultSupportedCiphers(const QList<QSslCipher> &ciph
/*!
\internal
*/
+void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers)
+{
+ QMutexLocker locker(&globalData()->mutex);
+ globalData()->dtlsConfig.detach();
+ globalData()->dtlsConfig->ciphers = ciphers;
+}
+
+/*!
+ \internal
+*/
+QList<QSslCipher> q_getDefaultDtlsCiphers()
+{
+ QSslSocketPrivate::ensureInitialized();
+ QMutexLocker locker(&globalData()->mutex);
+ return globalData()->dtlsConfig->ciphers;
+}
+
+/*!
+ \internal
+*/
QVector<QSslEllipticCurve> QSslSocketPrivate::supportedEllipticCurves()
{
QSslSocketPrivate::ensureInitialized();
@@ -2142,6 +2193,7 @@ void QSslSocketPrivate::setDefaultSupportedEllipticCurves(const QVector<QSslElli
{
const QMutexLocker locker(&globalData()->mutex);
globalData()->config.detach();
+ globalData()->dtlsConfig.detach();
globalData()->supportedEllipticCurves = curves;
}
@@ -2164,6 +2216,8 @@ void QSslSocketPrivate::setDefaultCaCertificates(const QList<QSslCertificate> &c
QMutexLocker locker(&globalData()->mutex);
globalData()->config.detach();
globalData()->config->caCertificates = certs;
+ globalData()->dtlsConfig.detach();
+ globalData()->dtlsConfig->caCertificates = certs;
// when the certificates are set explicitly, we do not want to
// load the system certificates on demand
s_loadRootCertsOnDemand = false;
@@ -2183,6 +2237,8 @@ bool QSslSocketPrivate::addDefaultCaCertificates(const QString &path, QSsl::Enco
QMutexLocker locker(&globalData()->mutex);
globalData()->config.detach();
globalData()->config->caCertificates += certs;
+ globalData()->dtlsConfig.detach();
+ globalData()->dtlsConfig->caCertificates += certs;
return true;
}
@@ -2195,6 +2251,8 @@ void QSslSocketPrivate::addDefaultCaCertificate(const QSslCertificate &cert)
QMutexLocker locker(&globalData()->mutex);
globalData()->config.detach();
globalData()->config->caCertificates += cert;
+ globalData()->dtlsConfig.detach();
+ globalData()->dtlsConfig->caCertificates += cert;
}
/*!
@@ -2206,6 +2264,8 @@ void QSslSocketPrivate::addDefaultCaCertificates(const QList<QSslCertificate> &c
QMutexLocker locker(&globalData()->mutex);
globalData()->config.detach();
globalData()->config->caCertificates += certs;
+ globalData()->dtlsConfig.detach();
+ globalData()->dtlsConfig->caCertificates += certs;
}
/*!
@@ -2258,6 +2318,33 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri
ptr->sslOptions = global->sslOptions;
ptr->ellipticCurves = global->ellipticCurves;
ptr->backendConfig = global->backendConfig;
+#if QT_CONFIG(dtls)
+ ptr->dtlsCookieEnabled = global->dtlsCookieEnabled;
+#endif
+}
+
+/*!
+ \internal
+*/
+QSslConfiguration QSslConfigurationPrivate::defaultDtlsConfiguration()
+{
+ QSslSocketPrivate::ensureInitialized();
+ QMutexLocker locker(&globalData()->mutex);
+
+ return QSslConfiguration(globalData()->dtlsConfig.data());
+}
+
+/*!
+ \internal
+*/
+void QSslConfigurationPrivate::setDefaultDtlsConfiguration(const QSslConfiguration &configuration)
+{
+ QSslSocketPrivate::ensureInitialized();
+ QMutexLocker locker(&globalData()->mutex);
+ if (globalData()->dtlsConfig == configuration.d)
+ return; // nothing to do
+
+ globalData()->dtlsConfig = const_cast<QSslConfigurationPrivate*>(configuration.d.constData());
}
/*!
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index aa0e1b0dd1..730a9552b5 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -48,6 +48,7 @@
#include <QtCore/qmessageauthenticationcode.h>
#include <QtCore/qoperatingsystemversion.h>
+#include <QtCore/qscopedvaluerollback.h>
#include <QtCore/qcryptographichash.h>
#include <QtCore/qsystemdetection.h>
#include <QtCore/qdatastream.h>
@@ -242,48 +243,70 @@ static const uint8_t dhparam[] =
"\x90\x0b\x35\x64\xff\xd9\xe3\xac\xf2\xf2\xeb\x3a\x63\x02\x01\x02";
#endif
-// No ioErr on iOS/tvOS/watchOS. (defined in MacErrors.h on macOS)
-#if defined(QT_PLATFORM_UIKIT)
-# define ioErr -36
-#endif
-
-static OSStatus _q_SSLRead(QTcpSocket *plainSocket, char *data, size_t *dataLength)
+OSStatus QSslSocketBackendPrivate::ReadCallback(QSslSocketBackendPrivate *socket,
+ char *data, size_t *dataLength)
{
- Q_ASSERT(plainSocket);
+ Q_ASSERT(socket);
Q_ASSERT(data);
Q_ASSERT(dataLength);
+ QTcpSocket *plainSocket = socket->plainSocket;
+ Q_ASSERT(plainSocket);
+
+ if (socket->isHandshakeComplete()) {
+ // Check if it's a renegotiation attempt, when the handshake is complete, the
+ // session state is 'kSSLConnected':
+ SSLSessionState currentState = kSSLConnected;
+ const OSStatus result = SSLGetSessionState(socket->context, &currentState);
+ if (result != noErr) {
+ *dataLength = 0;
+ return result;
+ }
+
+ if (currentState == kSSLHandshake) {
+ // Renegotiation detected, don't allow read more yet - 'transmit'
+ // will notice this and will call 'startHandshake':
+ *dataLength = 0;
+ socket->renegotiating = true;
+ return errSSLWouldBlock;
+ }
+ }
+
const qint64 bytes = plainSocket->read(data, *dataLength);
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "read" << bytes;
#endif
if (bytes < 0) {
*dataLength = 0;
- return ioErr;
+ return errSecIO;
}
- const OSStatus err = (size_t(bytes) < *dataLength) ? errSSLWouldBlock : noErr;
+ const OSStatus err = (size_t(bytes) < *dataLength) ? errSSLWouldBlock : errSecSuccess;
*dataLength = bytes;
return err;
}
-static OSStatus _q_SSLWrite(QTcpSocket *plainSocket, const char *data, size_t *dataLength)
+OSStatus QSslSocketBackendPrivate::WriteCallback(QSslSocketBackendPrivate *socket,
+ const char *data, size_t *dataLength)
{
- Q_ASSERT(plainSocket);
+ Q_ASSERT(socket);
Q_ASSERT(data);
Q_ASSERT(dataLength);
+ QTcpSocket *plainSocket = socket->plainSocket;
+ Q_ASSERT(plainSocket);
+
const qint64 bytes = plainSocket->write(data, *dataLength);
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "write" << bytes;
#endif
if (bytes < 0) {
*dataLength = 0;
- return ioErr;
+ return errSecIO;
}
- const OSStatus err = (size_t(bytes) < *dataLength) ? errSSLWouldBlock : noErr;
+ const OSStatus err = (size_t(bytes) < *dataLength) ? errSSLWouldBlock : errSecSuccess;
*dataLength = bytes;
return err;
@@ -387,12 +410,12 @@ void QSslSocketBackendPrivate::continueHandshake()
Q_Q(QSslSocket);
connectionEncrypted = true;
-#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_11_0, __TVOS_11_0, __WATCHOS_4_0)
+#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13, __IPHONE_11_0, __TVOS_11_0, __WATCHOS_4_0)
// Unlike OpenSSL, Secure Transport does not allow to negotiate protocols via
// a callback during handshake. We can only set our list of preferred protocols
// (and send it during handshake) and then receive what our peer has sent to us.
// And here we can finally try to find a match (if any).
- if (__builtin_available(iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
+ if (__builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
const auto &requestedProtocols = configuration.nextAllowedProtocols;
if (const int requestedCount = requestedProtocols.size()) {
configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone;
@@ -423,7 +446,9 @@ void QSslSocketBackendPrivate::continueHandshake()
}
#endif // QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE
- emit q->encrypted();
+ if (!renegotiating)
+ emit q->encrypted();
+
if (autoStartHandshake && pendingClose) {
pendingClose = false;
q->disconnectFromHost();
@@ -452,7 +477,7 @@ void QSslSocketBackendPrivate::disconnectFromHost()
QSslCipher QSslSocketBackendPrivate::sessionCipher() const
{
SSLCipherSuite cipher = 0;
- if (context && SSLGetNegotiatedCipher(context, &cipher) == noErr)
+ if (context && SSLGetNegotiatedCipher(context, &cipher) == errSecSuccess)
return QSslCipher_from_SSLCipherSuite(cipher);
return QSslCipher();
@@ -465,7 +490,7 @@ QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const
SSLProtocol protocol = kSSLProtocolUnknown;
const OSStatus err = SSLGetNegotiatedProtocolVersion(context, &protocol);
- if (err != noErr) {
+ if (err != errSecSuccess) {
qCWarning(lcSsl) << "SSLGetNegotiatedProtocolVersion failed:" << err;
return QSsl::UnknownProtocol;
}
@@ -521,10 +546,10 @@ void QSslSocketBackendPrivate::transmit()
if (!context || shutdown)
return;
- if (!connectionEncrypted)
+ if (!isHandshakeComplete())
startHandshake();
- if (connectionEncrypted && !writeBuffer.isEmpty()) {
+ if (isHandshakeComplete() && !writeBuffer.isEmpty()) {
qint64 totalBytesWritten = 0;
while (writeBuffer.nextDataBlockSize() > 0 && context) {
const size_t nextDataBlockSize = writeBuffer.nextDataBlockSize();
@@ -533,7 +558,7 @@ void QSslSocketBackendPrivate::transmit()
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "SSLWrite returned" << err;
#endif
- if (err != noErr && err != errSSLWouldBlock) {
+ if (err != errSecSuccess && err != errSSLWouldBlock) {
setErrorAndEmit(QAbstractSocket::SslInternalError,
QStringLiteral("SSLWrite failed: %1").arg(err));
break;
@@ -559,7 +584,7 @@ void QSslSocketBackendPrivate::transmit()
}
}
- if (connectionEncrypted) {
+ if (isHandshakeComplete()) {
QVarLengthArray<char, 4096> data;
while (context && (!readBufferMaxSize || buffer.size() < readBufferMaxSize)) {
size_t readBytes = 0;
@@ -573,12 +598,17 @@ void QSslSocketBackendPrivate::transmit()
setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
QSslSocket::tr("The TLS/SSL connection has been closed"));
break;
- } else if (err != noErr && err != errSSLWouldBlock) {
+ } else if (err != errSecSuccess && err != errSSLWouldBlock) {
setErrorAndEmit(QAbstractSocket::SslInternalError,
QStringLiteral("SSLRead failed: %1").arg(err));
break;
}
+ if (err == errSSLWouldBlock && renegotiating) {
+ startHandshake();
+ break;
+ }
+
if (readBytes) {
buffer.append(data.constData(), readBytes);
if (readyReadEmittedPointer)
@@ -861,16 +891,17 @@ bool QSslSocketBackendPrivate::initSslContext()
return false;
}
- const OSStatus err = SSLSetIOFuncs(context, reinterpret_cast<SSLReadFunc>(&_q_SSLRead),
- reinterpret_cast<SSLWriteFunc>(&_q_SSLWrite));
- if (err != noErr) {
+ const OSStatus err = SSLSetIOFuncs(context,
+ reinterpret_cast<SSLReadFunc>(&QSslSocketBackendPrivate::ReadCallback),
+ reinterpret_cast<SSLWriteFunc>(&QSslSocketBackendPrivate::WriteCallback));
+ if (err != errSecSuccess) {
destroySslContext();
setErrorAndEmit(QAbstractSocket::SslInternalError,
QStringLiteral("SSLSetIOFuncs failed: %1").arg(err));
return false;
}
- SSLSetConnection(context, plainSocket);
+ SSLSetConnection(context, this);
if (mode == QSslSocket::SslServerMode
&& !configuration.localCertificateChain.isEmpty()) {
@@ -889,8 +920,8 @@ bool QSslSocketBackendPrivate::initSslContext()
return false;
}
-#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, __IPHONE_11_0, __TVOS_11_0, __WATCHOS_4_0)
- if (__builtin_available(iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
+#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13, __IPHONE_11_0, __TVOS_11_0, __WATCHOS_4_0)
+ if (__builtin_available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
const auto protocolNames = configuration.nextAllowedProtocols;
QCFType<CFMutableArrayRef> cfNames(CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks));
if (cfNames) {
@@ -922,10 +953,10 @@ bool QSslSocketBackendPrivate::initSslContext()
SSLSetPeerDomainName(context, ace.data(), ace.size());
// tell SecureTransport we handle peer verification ourselves
OSStatus err = SSLSetSessionOption(context, kSSLSessionOptionBreakOnServerAuth, true);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetSessionOption(context, kSSLSessionOptionBreakOnCertRequested, true);
- if (err != noErr) {
+ if (err != errSecSuccess) {
destroySslContext();
setErrorAndEmit(QSslSocket::SslInternalError,
QStringLiteral("SSLSetSessionOption failed: %1").arg(err));
@@ -936,13 +967,13 @@ bool QSslSocketBackendPrivate::initSslContext()
if (configuration.peerVerifyMode != QSslSocket::VerifyNone) {
// kAlwaysAuthenticate - always fails even if we set break on client auth.
OSStatus err = SSLSetClientSideAuthenticate(context, kTryAuthenticate);
- if (err == noErr) {
+ if (err == errSecSuccess) {
// We'd like to verify peer ourselves, otherwise handshake will
// most probably fail before we can do anything.
err = SSLSetSessionOption(context, kSSLSessionOptionBreakOnClientAuth, true);
}
- if (err != noErr) {
+ if (err != errSecSuccess) {
destroySslContext();
setErrorAndEmit(QAbstractSocket::SslInternalError,
QStringLiteral("failed to set SSL context option in server mode: %1").arg(err));
@@ -1005,7 +1036,7 @@ bool QSslSocketBackendPrivate::setSessionCertificate(QString &errorDescription,
nullptr, nullptr);
QCFType<CFArrayRef> items;
OSStatus err = SecPKCS12Import(pkcs12, options, &items);
- if (err != noErr) {
+ if (err != errSecSuccess) {
#ifdef QSSLSOCKET_DEBUG
qCWarning(lcSsl) << plainSocket
<< QStringLiteral("SecPKCS12Import failed: %1").arg(err);
@@ -1051,7 +1082,7 @@ bool QSslSocketBackendPrivate::setSessionCertificate(QString &errorDescription,
}
err = SSLSetCertificate(context, certs);
- if (err != noErr) {
+ if (err != errSecSuccess) {
#ifdef QSSLSOCKET_DEBUG
qCWarning(lcSsl) << plainSocket
<< QStringLiteral("Cannot set certificate and key: %1").arg(err);
@@ -1079,35 +1110,35 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
return false;
}
- OSStatus err = noErr;
+ OSStatus err = errSecSuccess;
if (configuration.protocol == QSsl::SslV3) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : SSLv3";
#endif
err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kSSLProtocol3);
} else if (configuration.protocol == QSsl::TlsV1_0) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol1);
} else if (configuration.protocol == QSsl::TlsV1_1) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol11);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol11);
} else if (configuration.protocol == QSsl::TlsV1_2) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol12);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
} else if (configuration.protocol == QSsl::AnyProtocol) {
#ifdef QSSLSOCKET_DEBUG
@@ -1115,42 +1146,42 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
#endif
// kSSLProtocol3, since kSSLProtocol2 is disabled:
err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
} else if (configuration.protocol == QSsl::TlsV1SslV3) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
} else if (configuration.protocol == QSsl::SecureProtocols) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
} else if (configuration.protocol == QSsl::TlsV1_0OrLater) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
} else if (configuration.protocol == QSsl::TlsV1_1OrLater) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1 - TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol11);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
} else if (configuration.protocol == QSsl::TlsV1_2OrLater) {
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
#endif
err = SSLSetProtocolVersionMin(context, kTLSProtocol12);
- if (err == noErr)
+ if (err == errSecSuccess)
err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
} else {
#ifdef QSSLSOCKET_DEBUG
@@ -1159,7 +1190,7 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
return false;
}
- return err == noErr;
+ return err == errSecSuccess;
}
bool QSslSocketBackendPrivate::canIgnoreTrustVerificationFailure() const
@@ -1204,8 +1235,8 @@ bool QSslSocketBackendPrivate::verifyPeerTrust()
QCFType<SecTrustRef> trust;
OSStatus err = SSLCopyPeerTrust(context, &trust);
- // !trust - SSLCopyPeerTrust can return noErr but null trust.
- if (err != noErr || !trust) {
+ // !trust - SSLCopyPeerTrust can return errSecSuccess but null trust.
+ if (err != errSecSuccess || !trust) {
if (!canIgnoreVerify) {
setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
QStringLiteral("Failed to obtain peer trust: %1").arg(err));
@@ -1217,40 +1248,38 @@ bool QSslSocketBackendPrivate::verifyPeerTrust()
}
QList<QSslError> errors;
- // store certificates
- const int certCount = SecTrustGetCertificateCount(trust);
- // TODO: why this test depends on configuration.peerCertificateChain not being empty????
- if (configuration.peerCertificateChain.isEmpty()) {
- // Apple's docs say SetTrustEvaluate must be called before
- // SecTrustGetCertificateAtIndex, but this results
- // in 'kSecTrustResultRecoverableTrustFailure', so
- // here we just ignore 'res' (later we'll use SetAnchor etc.
- // and evaluate again).
- SecTrustResultType res = kSecTrustResultInvalid;
- err = SecTrustEvaluate(trust, &res);
- if (err != noErr) {
- // We can not ignore this, it's not even about trust verification
- // probably ...
- setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
- QStringLiteral("SecTrustEvaluate failed: %1").arg(err));
- plainSocket->disconnectFromHost();
- return false;
- }
- for (int i = 0; i < certCount; ++i) {
- SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, i);
- QCFType<CFDataRef> derData = SecCertificateCopyData(cert);
- configuration.peerCertificateChain << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
- }
+ // Store certificates.
+ // Apple's docs say SetTrustEvaluate must be called before
+ // SecTrustGetCertificateAtIndex, but this results
+ // in 'kSecTrustResultRecoverableTrustFailure', so
+ // here we just ignore 'res' (later we'll use SetAnchor etc.
+ // and evaluate again).
+ SecTrustResultType res = kSecTrustResultInvalid;
+ err = SecTrustEvaluate(trust, &res);
+ if (err != errSecSuccess) {
+ // We can not ignore this, it's not even about trust verification
+ // probably ...
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
+ QStringLiteral("SecTrustEvaluate failed: %1").arg(err));
+ plainSocket->disconnectFromHost();
+ return false;
}
- if (certCount > 0) {
- SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, 0);
+ configuration.peerCertificate.clear();
+ configuration.peerCertificateChain.clear();
+
+ const CFIndex certCount = SecTrustGetCertificateCount(trust);
+ for (CFIndex i = 0; i < certCount; ++i) {
+ SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, i);
QCFType<CFDataRef> derData = SecCertificateCopyData(cert);
- configuration.peerCertificate = QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
+ configuration.peerCertificateChain << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
}
- // check the whole chain for blacklisting (including root, as we check for subjectInfo and issuer)
+ if (configuration.peerCertificateChain.size())
+ configuration.peerCertificate = configuration.peerCertificateChain.at(0);
+
+ // Check the whole chain for blacklisting (including root, as we check for subjectInfo and issuer):
for (const QSslCertificate &cert : qAsConst(configuration.peerCertificateChain)) {
if (QSslCertificatePrivate::isBlacklisted(cert) && !canIgnoreVerify) {
const QSslError error(QSslError::CertificateBlacklisted, cert);
@@ -1294,10 +1323,10 @@ bool QSslSocketBackendPrivate::verifyPeerTrust()
}
// verify certificate chain
- QCFType<CFMutableArrayRef> certArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ QCFType<CFMutableArrayRef> certArray = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks);
for (const QSslCertificate &cert : qAsConst(configuration.caCertificates)) {
QCFType<CFDataRef> certData = cert.d->derData.toCFData();
- if (QCFType<SecCertificateRef> secRef = SecCertificateCreateWithData(NULL, certData))
+ if (QCFType<SecCertificateRef> secRef = SecCertificateCreateWithData(nullptr, certData))
CFArrayAppendValue(certArray, secRef);
else
qCWarning(lcSsl, "Failed to create SecCertificate from QSslCertificate");
@@ -1422,6 +1451,7 @@ bool QSslSocketBackendPrivate::startHandshake()
// Failure means a real error (invalid certificate, no private key, etc).
if (!setSessionCertificate(errorDescription, errorCode)) {
setErrorAndEmit(errorCode, errorDescription);
+ renegotiating = false;
return false;
} else {
// We try to resume a handshake, even if have no
@@ -1436,6 +1466,7 @@ bool QSslSocketBackendPrivate::startHandshake()
return startHandshake();
}
+ renegotiating = false;
setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
QStringLiteral("SSLHandshake failed: %1").arg(err));
plainSocket->disconnectFromHost();
@@ -1445,6 +1476,7 @@ bool QSslSocketBackendPrivate::startHandshake()
// Connection aborted during handshake phase.
if (q->state() != QAbstractSocket::ConnectedState) {
qCDebug(lcSsl) << "connection aborted";
+ renegotiating = false;
return false;
}
@@ -1453,13 +1485,16 @@ bool QSslSocketBackendPrivate::startHandshake()
if (!verifySessionProtocol()) {
setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, QStringLiteral("Protocol version mismatch"));
plainSocket->disconnectFromHost();
+ renegotiating = false;
return false;
}
if (verifyPeerTrust()) {
continueHandshake();
+ renegotiating = false;
return true;
} else {
+ renegotiating = false;
return false;
}
}
diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h
index 34e30ebb16..e37171e56a 100644
--- a/src/network/ssl/qsslsocket_mac_p.h
+++ b/src/network/ssl/qsslsocket_mac_p.h
@@ -120,7 +120,14 @@ private:
bool checkSslErrors();
bool startHandshake();
+ bool isHandshakeComplete() const {return connectionEncrypted && !renegotiating;}
+
+ // IO callbacks:
+ static OSStatus ReadCallback(QSslSocketBackendPrivate *socket, char *data, size_t *dataLength);
+ static OSStatus WriteCallback(QSslSocketBackendPrivate *plainSocket, const char *data, size_t *dataLength);
+
QSecureTransportContext context;
+ bool renegotiating = false;
Q_DISABLE_COPY(QSslSocketBackendPrivate)
};
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index cecb4fb753..ba02d13863 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -66,6 +66,10 @@
#include "qsslpresharedkeyauthenticator.h"
#include "qsslpresharedkeyauthenticator_p.h"
+#ifdef Q_OS_WIN
+#include "qwindowscarootfetcher_p.h"
+#endif
+
#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
@@ -77,15 +81,16 @@
#include <QtCore/qthread.h>
#include <QtCore/qurl.h>
#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qscopedvaluerollback.h>
#include <string.h>
QT_BEGIN_NAMESPACE
#if defined(Q_OS_WIN)
- PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = 0;
- PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = 0;
- PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = 0;
+ PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = nullptr;
+ PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = nullptr;
+ PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = nullptr;
#endif
bool QSslSocketPrivate::s_libraryLoaded = false;
@@ -99,12 +104,13 @@ int QSslSocketBackendPrivate::s_indexForSSLExtraData = -1;
QString QSslSocketBackendPrivate::getErrorsFromOpenSsl()
{
QString errorString;
+ char buf[256] = {}; // OpenSSL docs claim both 120 and 256; use the larger.
unsigned long errNum;
while ((errNum = q_ERR_get_error())) {
- if (! errorString.isEmpty())
+ if (!errorString.isEmpty())
errorString.append(QLatin1String(", "));
- const char *error = q_ERR_error_string(errNum, NULL);
- errorString.append(QString::fromLatin1(error)); // error is ascii according to man ERR_error_string
+ q_ERR_error_string_n(errNum, buf, sizeof buf);
+ errorString.append(QString::fromLatin1(buf)); // error is ascii according to man ERR_error_string
}
return errorString;
}
@@ -134,10 +140,10 @@ static unsigned int q_ssl_psk_server_callback(SSL *ssl,
} // extern "C"
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
- : ssl(0),
- readBio(0),
- writeBio(0),
- session(0)
+ : ssl(nullptr),
+ readBio(nullptr),
+ writeBio(nullptr),
+ session(nullptr)
{
// Calls SSL_library_init().
ensureInitialized();
@@ -188,8 +194,7 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(const SSL_CIPHER
return ciph;
}
-// static
-inline QSslErrorEntry QSslErrorEntry::fromStoreContext(X509_STORE_CTX *ctx)
+QSslErrorEntry QSslErrorEntry::fromStoreContext(X509_STORE_CTX *ctx)
{
return {
q_X509_STORE_CTX_get_error(ctx),
@@ -242,6 +247,33 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx)
return 1;
}
+static void q_loadCiphersForConnection(SSL *connection, QList<QSslCipher> &ciphers,
+ QList<QSslCipher> &defaultCiphers)
+{
+ Q_ASSERT(connection);
+
+ STACK_OF(SSL_CIPHER) *supportedCiphers = q_SSL_get_ciphers(connection);
+ for (int i = 0; i < q_sk_SSL_CIPHER_num(supportedCiphers); ++i) {
+ if (SSL_CIPHER *cipher = q_sk_SSL_CIPHER_value(supportedCiphers, i)) {
+ QSslCipher ciph = QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(cipher);
+ if (!ciph.isNull()) {
+ // Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection
+ if (!ciph.name().toLower().startsWith(QLatin1String("adh")) &&
+ !ciph.name().toLower().startsWith(QLatin1String("exp-adh")) &&
+ !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) {
+ ciphers << ciph;
+
+ if (ciph.usedBits() >= 128)
+ defaultCiphers << ciph;
+ }
+ }
+ }
+ }
+}
+
+// Defined in qsslsocket.cpp
+void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers);
+
long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
{
long options;
@@ -383,7 +415,7 @@ void QSslSocketBackendPrivate::destroySslContext()
{
if (ssl) {
q_SSL_free(ssl);
- ssl = 0;
+ ssl = nullptr;
}
sslContextPointer.clear();
}
@@ -447,29 +479,28 @@ void QSslSocketPrivate::resetDefaultCiphers()
QList<QSslCipher> ciphers;
QList<QSslCipher> defaultCiphers;
- STACK_OF(SSL_CIPHER) *supportedCiphers = q_SSL_get_ciphers(mySsl);
- for (int i = 0; i < q_sk_SSL_CIPHER_num(supportedCiphers); ++i) {
- if (SSL_CIPHER *cipher = q_sk_SSL_CIPHER_value(supportedCiphers, i)) {
- QSslCipher ciph = QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(cipher);
- if (!ciph.isNull()) {
- // Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection
- if (!ciph.name().toLower().startsWith(QLatin1String("adh")) &&
- !ciph.name().toLower().startsWith(QLatin1String("exp-adh")) &&
- !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) {
- ciphers << ciph;
-
- if (ciph.usedBits() >= 128)
- defaultCiphers << ciph;
- }
- }
- }
- }
+ q_loadCiphersForConnection(mySsl, ciphers, defaultCiphers);
q_SSL_CTX_free(myCtx);
q_SSL_free(mySsl);
setDefaultSupportedCiphers(ciphers);
setDefaultCiphers(defaultCiphers);
+
+#if QT_CONFIG(dtls)
+ ciphers.clear();
+ defaultCiphers.clear();
+ myCtx = q_SSL_CTX_new(q_DTLS_client_method());
+ if (myCtx) {
+ mySsl = q_SSL_new(myCtx);
+ if (mySsl) {
+ q_loadCiphersForConnection(mySsl, ciphers, defaultCiphers);
+ q_setDefaultDtlsCiphers(defaultCiphers);
+ q_SSL_free(mySsl);
+ }
+ q_SSL_CTX_free(myCtx);
+ }
+#endif // dtls
}
void QSslSocketPrivate::resetDefaultEllipticCurves()
@@ -615,6 +646,11 @@ void QSslSocketBackendPrivate::transmit()
{
Q_Q(QSslSocket);
+ using ScopedBool = QScopedValueRollback<bool>;
+
+ if (inSetAndEmitError)
+ return;
+
// If we don't have any SSL context, don't bother transmitting.
if (!ssl)
return;
@@ -642,6 +678,7 @@ void QSslSocketBackendPrivate::transmit()
break;
} else {
// ### Better error handling.
+ const ScopedBool bg(inSetAndEmitError, true);
setErrorAndEmit(QAbstractSocket::SslInternalError,
QSslSocket::tr("Unable to write data: %1").arg(
getErrorsFromOpenSsl()));
@@ -687,6 +724,7 @@ void QSslSocketBackendPrivate::transmit()
#endif
if (actualWritten < 0) {
//plain socket write fails if it was in the pending close state.
+ const ScopedBool bg(inSetAndEmitError, true);
setErrorAndEmit(plainSocket->error(), plainSocket->errorString());
return;
}
@@ -712,6 +750,7 @@ void QSslSocketBackendPrivate::transmit()
plainSocket->skip(writtenToBio);
} else {
// ### Better error handling.
+ const ScopedBool bg(inSetAndEmitError, true);
setErrorAndEmit(QAbstractSocket::SslInternalError,
QSslSocket::tr("Unable to decrypt data: %1").arg(
getErrorsFromOpenSsl()));
@@ -789,15 +828,21 @@ void QSslSocketBackendPrivate::transmit()
qCDebug(lcSsl) << "QSslSocketBackendPrivate::transmit: remote disconnect";
#endif
shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves
- setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
- QSslSocket::tr("The TLS/SSL connection has been closed"));
+ {
+ const ScopedBool bg(inSetAndEmitError, true);
+ setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
+ QSslSocket::tr("The TLS/SSL connection has been closed"));
+ }
return;
case SSL_ERROR_SYSCALL: // some IO error
case SSL_ERROR_SSL: // error in the SSL library
// we do not know exactly what the error is, nor whether we can recover from it,
// so just return to prevent an endless loop in the outer "while" statement
- setErrorAndEmit(QAbstractSocket::SslInternalError,
- QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl()));
+ {
+ const ScopedBool bg(inSetAndEmitError, true);
+ setErrorAndEmit(QAbstractSocket::SslInternalError,
+ QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl()));
+ }
return;
default:
// SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: can only happen with a
@@ -805,15 +850,18 @@ void QSslSocketBackendPrivate::transmit()
// SSL_ERROR_WANT_X509_LOOKUP: can only happen with a
// SSL_CTX_set_client_cert_cb(), which we do not call.
// So this default case should never be triggered.
- setErrorAndEmit(QAbstractSocket::SslInternalError,
- QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl()));
+ {
+ const ScopedBool bg(inSetAndEmitError, true);
+ setErrorAndEmit(QAbstractSocket::SslInternalError,
+ QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl()));
+ }
break;
}
} while (ssl && readBytes > 0);
} while (ssl && transmitting);
}
-static QSslError _q_OpenSSL_to_QSslError(int errorCode, const QSslCertificate &cert)
+QSslError _q_OpenSSL_to_QSslError(int errorCode, const QSslCertificate &cert)
{
QSslError error;
switch (errorCode) {
@@ -862,12 +910,24 @@ static QSslError _q_OpenSSL_to_QSslError(int errorCode, const QSslCertificate &c
return error;
}
+QString QSslSocketBackendPrivate::msgErrorsDuringHandshake()
+{
+ return QSslSocket::tr("Error during SSL handshake: %1")
+ .arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+}
+
bool QSslSocketBackendPrivate::startHandshake()
{
Q_Q(QSslSocket);
// Check if the connection has been established. Get all errors from the
// verification stage.
+
+ using ScopedBool = QScopedValueRollback<bool>;
+
+ if (inSetAndEmitError)
+ return false;
+
QMutexLocker locker(&_q_sslErrorList()->mutex);
_q_sslErrorList()->errors.clear();
int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
@@ -897,12 +957,14 @@ bool QSslSocketBackendPrivate::startHandshake()
// The handshake is not yet complete.
break;
default:
- QString errorString
- = QSslSocket::tr("Error during SSL handshake: %1").arg(getErrorsFromOpenSsl());
+ QString errorString = QSslSocketBackendPrivate::msgErrorsDuringHandshake();
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << "QSslSocketBackendPrivate::startHandshake: error!" << errorString;
#endif
- setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, errorString);
+ {
+ const ScopedBool bg(inSetAndEmitError, true);
+ setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, errorString);
+ }
q->abort();
}
return false;
@@ -1172,119 +1234,6 @@ void QSslSocketBackendPrivate::_q_caRootLoaded(QSslCertificate cert, QSslCertifi
}
}
-class QWindowsCaRootFetcherThread : public QThread
-{
-public:
- QWindowsCaRootFetcherThread()
- {
- qRegisterMetaType<QSslCertificate>();
- setObjectName(QStringLiteral("QWindowsCaRootFetcher"));
- start();
- }
- ~QWindowsCaRootFetcherThread()
- {
- quit();
- wait(15500); // worst case, a running request can block for 15 seconds
- }
-};
-
-Q_GLOBAL_STATIC(QWindowsCaRootFetcherThread, windowsCaRootFetcherThread);
-
-QWindowsCaRootFetcher::QWindowsCaRootFetcher(const QSslCertificate &certificate, QSslSocket::SslMode sslMode)
- : cert(certificate), mode(sslMode)
-{
- moveToThread(windowsCaRootFetcherThread());
-}
-
-QWindowsCaRootFetcher::~QWindowsCaRootFetcher()
-{
-}
-
-void QWindowsCaRootFetcher::start()
-{
- QByteArray der = cert.toDer();
- PCCERT_CONTEXT wincert = CertCreateCertificateContext(X509_ASN_ENCODING, (const BYTE *)der.constData(), der.length());
- if (!wincert) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl, "QWindowsCaRootFetcher failed to convert certificate to windows form");
-#endif
- emit finished(cert, QSslCertificate());
- deleteLater();
- return;
- }
-
- CERT_CHAIN_PARA parameters;
- memset(&parameters, 0, sizeof(parameters));
- parameters.cbSize = sizeof(parameters);
- // set key usage constraint
- parameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
- parameters.RequestedUsage.Usage.cUsageIdentifier = 1;
- LPSTR oid = (LPSTR)(mode == QSslSocket::SslClientMode ? szOID_PKIX_KP_SERVER_AUTH : szOID_PKIX_KP_CLIENT_AUTH);
- parameters.RequestedUsage.Usage.rgpszUsageIdentifier = &oid;
-
-#ifdef QSSLSOCKET_DEBUG
- QElapsedTimer stopwatch;
- stopwatch.start();
-#endif
- PCCERT_CHAIN_CONTEXT chain;
- BOOL result = CertGetCertificateChain(
- 0, //default engine
- wincert,
- 0, //current date/time
- 0, //default store
- &parameters,
- 0, //default dwFlags
- 0, //reserved
- &chain);
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "QWindowsCaRootFetcher" << stopwatch.elapsed() << "ms to get chain";
-#endif
-
- QSslCertificate trustedRoot;
- if (result) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "QWindowsCaRootFetcher - examining windows chains";
- if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
- qCDebug(lcSsl) << " - TRUSTED";
- else
- qCDebug(lcSsl) << " - NOT TRUSTED" << chain->TrustStatus.dwErrorStatus;
- if (chain->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED)
- qCDebug(lcSsl) << " - SELF SIGNED";
- qCDebug(lcSsl) << "QSslSocketBackendPrivate::fetchCaRootForCert - dumping simple chains";
- for (unsigned int i = 0; i < chain->cChain; i++) {
- if (chain->rgpChain[i]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
- qCDebug(lcSsl) << " - TRUSTED SIMPLE CHAIN" << i;
- else
- qCDebug(lcSsl) << " - UNTRUSTED SIMPLE CHAIN" << i << "reason:" << chain->rgpChain[i]->TrustStatus.dwErrorStatus;
- for (unsigned int j = 0; j < chain->rgpChain[i]->cElement; j++) {
- QSslCertificate foundCert(QByteArray((const char *)chain->rgpChain[i]->rgpElement[j]->pCertContext->pbCertEncoded
- , chain->rgpChain[i]->rgpElement[j]->pCertContext->cbCertEncoded), QSsl::Der);
- qCDebug(lcSsl) << " - " << foundCert;
- }
- }
- qCDebug(lcSsl) << " - and" << chain->cLowerQualityChainContext << "low quality chains"; //expect 0, we haven't asked for them
-#endif
-
- //based on http://msdn.microsoft.com/en-us/library/windows/desktop/aa377182%28v=vs.85%29.aspx
- //about the final chain rgpChain[cChain-1] which must begin with a trusted root to be valid
- if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR
- && chain->cChain > 0) {
- const PCERT_SIMPLE_CHAIN finalChain = chain->rgpChain[chain->cChain - 1];
- // http://msdn.microsoft.com/en-us/library/windows/desktop/aa377544%28v=vs.85%29.aspx
- // rgpElement[0] is the end certificate chain element. rgpElement[cElement-1] is the self-signed "root" certificate element.
- if (finalChain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR
- && finalChain->cElement > 0) {
- trustedRoot = QSslCertificate(QByteArray((const char *)finalChain->rgpElement[finalChain->cElement - 1]->pCertContext->pbCertEncoded
- , finalChain->rgpElement[finalChain->cElement - 1]->pCertContext->cbCertEncoded), QSsl::Der);
- }
- }
- CertFreeCertificateChain(chain);
- }
- CertFreeCertificateContext(wincert);
-
- emit finished(cert, trustedRoot);
- deleteLater();
-}
#endif
void QSslSocketBackendPrivate::disconnectFromHost()
@@ -1401,7 +1350,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
q_X509_STORE_set_verify_cb(certStore, q_X509Callback);
// Build the chain of intermediate certificates
- STACK_OF(X509) *intermediates = 0;
+ STACK_OF(X509) *intermediates = nullptr;
if (certificateChain.length() > 1) {
intermediates = (STACK_OF(X509) *) q_OPENSSL_sk_new_null();
@@ -1494,9 +1443,10 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device,
BIO *bio = q_BIO_new_mem_buf(const_cast<char *>(pkcs12data.constData()), pkcs12data.size());
// Create the PKCS#12 object
- PKCS12 *p12 = q_d2i_PKCS12_bio(bio, 0);
+ PKCS12 *p12 = q_d2i_PKCS12_bio(bio, nullptr);
if (!p12) {
- qCWarning(lcSsl, "Unable to read PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0));
+ qCWarning(lcSsl, "Unable to read PKCS#12 structure, %s",
+ q_ERR_error_string(q_ERR_get_error(), nullptr));
q_BIO_free(bio);
return false;
}
@@ -1504,10 +1454,11 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device,
// Extract the data
EVP_PKEY *pkey = nullptr;
X509 *x509;
- STACK_OF(X509) *ca = 0;
+ STACK_OF(X509) *ca = nullptr;
if (!q_PKCS12_parse(p12, passPhrase.constData(), &pkey, &x509, &ca)) {
- qCWarning(lcSsl, "Unable to parse PKCS#12 structure, %s", q_ERR_error_string(q_ERR_get_error(), 0));
+ qCWarning(lcSsl, "Unable to parse PKCS#12 structure, %s",
+ q_ERR_error_string(q_ERR_get_error(), nullptr));
q_PKCS12_free(p12);
q_BIO_free(bio);
return false;
diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp
index d028f5fc00..cbbf403672 100644
--- a/src/network/ssl/qsslsocket_openssl11.cpp
+++ b/src/network/ssl/qsslsocket_openssl11.cpp
@@ -248,7 +248,7 @@ void QSslSocketBackendPrivate::continueHandshake()
// we could not agree -> be conservative and use HTTP/1.1
configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1");
} else {
- const unsigned char *proto = 0;
+ const unsigned char *proto = nullptr;
unsigned int proto_len = 0;
q_SSL_get0_alpn_selected(ssl, &proto, &proto_len);
diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
index ac8d46ce6d..844c3437be 100644
--- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
@@ -128,6 +128,45 @@ long q_OpenSSL_version_num();
const char *q_OpenSSL_version(int type);
unsigned long q_SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session);
+unsigned long q_SSL_set_options(SSL *s, unsigned long op);
+
+#if QT_CONFIG(dtls)
+// Functions and types required for DTLS support:
+extern "C"
+{
+
+typedef int (*CookieVerifyCallback)(SSL *, const unsigned char *, unsigned);
+typedef int (*DgramWriteCallback) (BIO *, const char *, int);
+typedef int (*DgramReadCallback) (BIO *, char *, int);
+typedef int (*DgramPutsCallback) (BIO *, const char *);
+typedef long (*DgramCtrlCallback) (BIO *, int, long, void *);
+typedef int (*DgramCreateCallback) (BIO *);
+typedef int (*DgramDestroyCallback) (BIO *);
+
+}
+
+int q_DTLSv1_listen(SSL *s, BIO_ADDR *client);
+BIO_ADDR *q_BIO_ADDR_new();
+void q_BIO_ADDR_free(BIO_ADDR *ap);
+
+// API we need for a custom dgram BIO:
+
+BIO_METHOD *q_BIO_meth_new(int type, const char *name);
+void q_BIO_meth_free(BIO_METHOD *biom);
+int q_BIO_meth_set_write(BIO_METHOD *biom, DgramWriteCallback);
+int q_BIO_meth_set_read(BIO_METHOD *biom, DgramReadCallback);
+int q_BIO_meth_set_puts(BIO_METHOD *biom, DgramPutsCallback);
+int q_BIO_meth_set_ctrl(BIO_METHOD *biom, DgramCtrlCallback);
+int q_BIO_meth_set_create(BIO_METHOD *biom, DgramCreateCallback);
+int q_BIO_meth_set_destroy(BIO_METHOD *biom, DgramDestroyCallback);
+
+#endif // dtls
+
+void q_BIO_set_data(BIO *a, void *ptr);
+void *q_BIO_get_data(BIO *a);
+void q_BIO_set_init(BIO *a, int init);
+int q_BIO_get_shutdown(BIO *a);
+void q_BIO_set_shutdown(BIO *a, int shut);
#define q_SSL_CTX_set_min_proto_version(ctx, version) \
q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, nullptr)
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 2a800cdc34..c16b9d5f76 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -131,6 +131,8 @@ public:
static int s_indexForSSLExtraData; // index used in SSL_get_ex_data to get the matching QSslSocketBackendPrivate
#endif
+ bool inSetAndEmitError = false;
+
// Platform specific functions
void startClientEncryption() override;
void startServerEncryption() override;
@@ -159,24 +161,9 @@ public:
QSslKey *key, QSslCertificate *cert,
QList<QSslCertificate> *caCertificates,
const QByteArray &passPhrase);
-};
-#ifdef Q_OS_WIN
-class QWindowsCaRootFetcher : public QObject
-{
- Q_OBJECT;
-public:
- QWindowsCaRootFetcher(const QSslCertificate &certificate, QSslSocket::SslMode sslMode);
- ~QWindowsCaRootFetcher();
-public slots:
- void start();
-signals:
- void finished(QSslCertificate brokenChain, QSslCertificate caroot);
-private:
- QSslCertificate cert;
- QSslSocket::SslMode mode;
+ static QString msgErrorsDuringHandshake();
};
-#endif
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 466eba0bd0..63cb276d54 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -141,11 +141,11 @@ void qsslSocketCannotResolveSymbolWarning(const char *functionName)
// Below are the functions first introduced in version 1.1:
-DEFINEFUNC(const unsigned char *, ASN1_STRING_get0_data, const ASN1_STRING *a, a, return 0, return)
+DEFINEFUNC(const unsigned char *, ASN1_STRING_get0_data, const ASN1_STRING *a, a, return nullptr, return)
DEFINEFUNC2(int, OPENSSL_init_ssl, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return)
DEFINEFUNC2(int, OPENSSL_init_crypto, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return)
-DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return 0, return)
-DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
+DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return nullptr, return)
+DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return nullptr, return)
DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return)
DEFINEFUNC(int, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX *c, c, return 0, return)
DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
@@ -153,45 +153,66 @@ DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
DEFINEFUNC2(void, OPENSSL_sk_pop_free, OPENSSL_STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
-DEFINEFUNC(OPENSSL_STACK *, OPENSSL_sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(OPENSSL_STACK *, OPENSSL_sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMMYARG)
DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
-DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return 0, return)
+DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return)
DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return)
DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return)
DEFINEFUNC6(int, CRYPTO_get_ex_new_index, int class_index, class_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return)
+DEFINEFUNC2(unsigned long, SSL_set_options, SSL *ssl, ssl, unsigned long op, op, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLS_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLS_client_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLS_server_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(ASN1_TIME *, X509_getm_notBefore, X509 *a, a, return 0, return)
-DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, TLS_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLS_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLS_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(ASN1_TIME *, X509_getm_notBefore, X509 *a, a, return nullptr, return)
+DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return nullptr, return)
DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return)
-DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return 0, return)
+DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return nullptr, return)
DEFINEFUNC2(void, X509_STORE_set_verify_cb, X509_STORE *a, a, X509_STORE_CTX_verify_cb verify_cb, verify_cb, return, DUMMYARG)
-DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return 0, return)
+DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return nullptr, return)
DEFINEFUNC3(void, CRYPTO_free, void *str, str, const char *file, file, int line, line, return, DUMMYARG)
DEFINEFUNC(long, OpenSSL_version_num, void, DUMMYARG, return 0, return)
-DEFINEFUNC(const char *, OpenSSL_version, int a, a, return 0, return)
+DEFINEFUNC(const char *, OpenSSL_version, int a, a, return nullptr, return)
DEFINEFUNC(unsigned long, SSL_SESSION_get_ticket_lifetime_hint, const SSL_SESSION *session, session, return 0, return)
DEFINEFUNC4(void, DH_get0_pqg, const DH *dh, dh, const BIGNUM **p, p, const BIGNUM **q, q, const BIGNUM **g, g, return, DUMMYARG)
DEFINEFUNC(int, DH_bits, DH *dh, dh, return 0, return)
+#if QT_CONFIG(dtls)
+DEFINEFUNC2(int, DTLSv1_listen, SSL *s, s, BIO_ADDR *c, c, return -1, return)
+DEFINEFUNC(BIO_ADDR *, BIO_ADDR_new, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(void, BIO_ADDR_free, BIO_ADDR *ap, ap, return, DUMMYARG)
+DEFINEFUNC2(BIO_METHOD *, BIO_meth_new, int type, type, const char *name, name, return nullptr, return)
+DEFINEFUNC(void, BIO_meth_free, BIO_METHOD *biom, biom, return, DUMMYARG)
+DEFINEFUNC2(int, BIO_meth_set_write, BIO_METHOD *biom, biom, DgramWriteCallback write, write, return 0, return)
+DEFINEFUNC2(int, BIO_meth_set_read, BIO_METHOD *biom, biom, DgramReadCallback read, read, return 0, return)
+DEFINEFUNC2(int, BIO_meth_set_puts, BIO_METHOD *biom, biom, DgramPutsCallback puts, puts, return 0, return)
+DEFINEFUNC2(int, BIO_meth_set_ctrl, BIO_METHOD *biom, biom, DgramCtrlCallback ctrl, ctrl, return 0, return)
+DEFINEFUNC2(int, BIO_meth_set_create, BIO_METHOD *biom, biom, DgramCreateCallback crt, crt, return 0, return)
+DEFINEFUNC2(int, BIO_meth_set_destroy, BIO_METHOD *biom, biom, DgramDestroyCallback dtr, dtr, return 0, return)
+#endif // dtls
+
+DEFINEFUNC2(void, BIO_set_data, BIO *a, a, void *ptr, ptr, return, DUMMYARG)
+DEFINEFUNC(void *, BIO_get_data, BIO *a, a, return nullptr, return)
+DEFINEFUNC2(void, BIO_set_init, BIO *a, a, int init, init, return, DUMMYARG)
+DEFINEFUNC(int, BIO_get_shutdown, BIO *a, a, return -1, return)
+DEFINEFUNC2(void, BIO_set_shutdown, BIO *a, a, int shut, shut, return, DUMMYARG)
+
#else // QT_CONFIG(opensslv11)
// Functions below are either deprecated or removed in OpenSSL >= 1.1:
-DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return)
+DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return nullptr, return)
#ifdef SSLEAY_MACROS
-DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return)
+DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return nullptr, return)
#endif
-DEFINEFUNC2(BIO *, BIO_new_file, const char *filename, filename, const char *mode, mode, return 0, return)
+DEFINEFUNC2(BIO *, BIO_new_file, const char *filename, filename, const char *mode, mode, return nullptr, return)
DEFINEFUNC(void, ERR_clear_error, DUMMYARG, DUMMYARG, return, DUMMYARG)
-DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
-DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
+DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return nullptr, return)
+DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return nullptr, return)
DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
@@ -202,23 +223,23 @@ DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
#ifdef SSLEAY_MACROS
-DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
-DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
+DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return nullptr, return)
+DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return nullptr, return)
#endif // SSLEAY_MACROS
DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG)
DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
-DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return)
+DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return nullptr, return)
#else
-DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void, sk_push, STACK *a, a, char *b, b, return, DUMMYARG)
DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
-DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
+DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return nullptr, return)
#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
@@ -230,49 +251,49 @@ DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
-DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
-DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#else
#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
#ifndef OPENSSL_NO_SSL2
-DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
-DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return 0, return)
+DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return nullptr, return)
#ifdef SSLEAY_MACROS
DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
@@ -280,17 +301,25 @@ DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, retur
#ifndef OPENSSL_NO_EC
DEFINEFUNC2(int, i2d_ECPrivateKey, const EC_KEY *a, a, unsigned char **b, b, return -1, return)
#endif
-DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return)
-DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return)
+DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return nullptr, return)
+DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return 0, return)
+DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return nullptr, return)
#endif
#endif
-DEFINEFUNC(char *, CONF_get1_default_config_file, DUMMYARG, DUMMYARG, return 0, return)
+
+#if QT_CONFIG(dtls)
+DEFINEFUNC(const SSL_METHOD *, DTLSv1_server_method, void, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, DTLSv1_client_method, void, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, DTLSv1_2_server_method, void, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, DTLSv1_2_client_method, void, DUMMYARG, return nullptr, return)
+#endif // dtls
+
+DEFINEFUNC(char *, CONF_get1_default_config_file, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
-DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
+DEFINEFUNC(const char *, SSLeay_version, int a, a, return nullptr, return)
#endif // QT_CONFIG(opensslv11)
@@ -299,22 +328,23 @@ DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return)
DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return)
-DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return 0, return)
+DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return nullptr, return)
DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return)
DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return)
DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return)
DEFINEFUNC2(BN_ULONG, BN_mod_word, const BIGNUM *a, a, BN_ULONG w, w, return static_cast<BN_ULONG>(-1), return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return 0, return)
+DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return nullptr, return)
DEFINEFUNC(int, EC_GROUP_get_degree, const EC_GROUP* g, g, return 0, return)
#endif
-DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
-DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return 0, return)
-DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return)
+DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return nullptr, return)
+DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return nullptr, return)
+DEFINEFUNC3(void, ERR_error_string_n, unsigned long e, e, char *b, b, size_t len, len, return, DUMMYARG)
DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, void, DUMMYARG, return 0, return)
+DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, void, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, EVP_CIPHER_CTX_free, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
DEFINEFUNC4(int, EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX *ctx, ctx, int type, type, int arg, arg, void *ptr, ptr, return 0, return)
DEFINEFUNC2(int, EVP_CIPHER_CTX_set_key_length, EVP_CIPHER_CTX *ctx, ctx, int keylen, keylen, return 0, return)
@@ -323,13 +353,13 @@ DEFINEFUNC6(int, EVP_CipherInit_ex, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *
DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return)
DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return)
#ifndef OPENSSL_NO_DES
-DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return 0, return)
-DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
#ifndef OPENSSL_NO_RC2
-DEFINEFUNC(const EVP_CIPHER *, EVP_rc2_cbc, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const EVP_CIPHER *, EVP_rc2_cbc, DUMMYARG, DUMMYARG, return nullptr, return)
#endif
-DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
@@ -337,16 +367,16 @@ DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return
DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return)
#endif
DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
-DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return)
-DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return 0, return)
+DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return)
+DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return 0, return)
+DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return nullptr, return)
#endif
-DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return)
DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return)
-DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return 0, return)
-DEFINEFUNC(const char *, OBJ_nid2ln, int a, a, return 0, return)
+DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return nullptr, return)
+DEFINEFUNC(const char *, OBJ_nid2ln, int a, a, return nullptr, return)
DEFINEFUNC(int, OBJ_sn2nid, const char *s, s, return 0, return)
DEFINEFUNC(int, OBJ_ln2nid, const char *s, s, return 0, return)
DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, return -1, return)
@@ -355,24 +385,24 @@ DEFINEFUNC4(int, OBJ_obj2txt, char *a, a, int b, b, ASN1_OBJECT *c, c, int d, d,
DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
#ifndef SSLEAY_MACROS
-DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
-DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
-DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#endif
-DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
#endif
#endif // !SSLEAY_MACROS
-DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
-DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
-DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
+DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
+DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return)
#endif
DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return)
DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return)
@@ -381,20 +411,22 @@ DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, ret
#endif
DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG)
DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
-DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC2(int, RAND_bytes, unsigned char *b, b, int n, n, return 0, return)
+DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG)
DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return)
DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return)
-DEFINEFUNC3(char *, SSL_CIPHER_description, const SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return)
+DEFINEFUNC3(char *, SSL_CIPHER_description, const SSL_CIPHER *a, a, char *b, b, int c, c, return nullptr, return)
DEFINEFUNC2(int, SSL_CIPHER_get_bits, const SSL_CIPHER *a, a, int *b, b, return 0, return)
+DEFINEFUNC(BIO *, SSL_get_rbio, const SSL *s, s, return nullptr, return)
DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return)
DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return)
DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return)
DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return 0, return)
+DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return nullptr, return)
#else
-DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return 0, return)
+DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return nullptr, return)
#endif
DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return)
DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return)
@@ -405,9 +437,9 @@ DEFINEFUNC3(int, SSL_CTX_use_certificate_file, SSL_CTX *a, a, const char *b, b,
DEFINEFUNC2(int, SSL_CTX_use_PrivateKey, SSL_CTX *a, a, EVP_PKEY *b, b, return -1, return)
DEFINEFUNC2(int, SSL_CTX_use_RSAPrivateKey, SSL_CTX *a, a, RSA *b, b, return -1, return)
DEFINEFUNC3(int, SSL_CTX_use_PrivateKey_file, SSL_CTX *a, a, const char *b, b, int c, c, return -1, return)
-DEFINEFUNC(X509_STORE *, SSL_CTX_get_cert_store, const SSL_CTX *a, a, return 0, return)
+DEFINEFUNC(X509_STORE *, SSL_CTX_get_cert_store, const SSL_CTX *a, a, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
-DEFINEFUNC(SSL_CONF_CTX *, SSL_CONF_CTX_new, DUMMYARG, DUMMYARG, return 0, return);
+DEFINEFUNC(SSL_CONF_CTX *, SSL_CONF_CTX_new, DUMMYARG, DUMMYARG, return nullptr, return);
DEFINEFUNC(void, SSL_CONF_CTX_free, SSL_CONF_CTX *a, a, return ,return);
DEFINEFUNC2(void, SSL_CONF_CTX_set_ssl_ctx, SSL_CONF_CTX *a, a, SSL_CTX *b, b, return, return);
DEFINEFUNC2(unsigned int, SSL_CONF_CTX_set_flags, SSL_CONF_CTX *a, a, unsigned int b, b, return 0, return);
@@ -415,36 +447,37 @@ DEFINEFUNC(int, SSL_CONF_CTX_finish, SSL_CONF_CTX *a, a, return 0, return);
DEFINEFUNC3(int, SSL_CONF_cmd, SSL_CONF_CTX *a, a, const char *b, b, const char *c, c, return 0, return);
#endif
DEFINEFUNC(void, SSL_free, SSL *a, a, return, DUMMYARG)
-DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return 0, return)
+DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
+DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return)
#else
-DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return)
+DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return)
#endif
DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
-DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return 0, return)
-DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return 0, return)
+DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
+DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
// 0.9.8 broke SC and BC by changing this function's signature.
DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
#else
DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
#endif
-DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return 0, return)
+DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return)
DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return)
DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG)
DEFINEFUNC(void, SSL_set_accept_state, SSL *a, a, return, DUMMYARG)
DEFINEFUNC(void, SSL_set_connect_state, SSL *a, a, return, DUMMYARG)
DEFINEFUNC(int, SSL_shutdown, SSL *a, a, return -1, return)
+DEFINEFUNC(int, SSL_get_shutdown, const SSL *ssl, ssl, return 0, return)
DEFINEFUNC2(int, SSL_set_session, SSL* to, to, SSL_SESSION *session, session, return -1, return)
DEFINEFUNC(void, SSL_SESSION_free, SSL_SESSION *ses, ses, return, DUMMYARG)
-DEFINEFUNC(SSL_SESSION*, SSL_get1_session, SSL *ssl, ssl, return 0, return)
-DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return 0, return)
+DEFINEFUNC(SSL_SESSION*, SSL_get1_session, SSL *ssl, ssl, return nullptr, return)
+DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
DEFINEFUNC3(int, SSL_set_ex_data, SSL *ssl, ssl, int idx, idx, void *arg, arg, return 0, return)
-DEFINEFUNC2(void *, SSL_get_ex_data, const SSL *ssl, ssl, int idx, idx, return NULL, return)
+DEFINEFUNC2(void *, SSL_get_ex_data, const SSL *ssl, ssl, int idx, idx, return nullptr, return)
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
DEFINEFUNC2(void, SSL_set_psk_client_callback, SSL* ssl, ssl, q_psk_client_callback_t callback, callback, return, DUMMYARG)
@@ -455,18 +488,18 @@ DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, re
DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return)
DEFINEFUNC4(int, X509_digest, const X509 *x509, x509, const EVP_MD *type, type, unsigned char *md, md, unsigned int *len, len, return -1, return)
#ifndef SSLEAY_MACROS
-DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return 0, return)
+DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return nullptr, return)
#endif
DEFINEFUNC2(void, X509_print, BIO *a, a, X509 *b, b, return, DUMMYARG);
-DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return 0, return)
+DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return nullptr, return)
DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG)
-DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return 0, return)
+DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return nullptr, return)
DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return)
-DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return 0, return)
-DEFINEFUNC(const X509V3_EXT_METHOD *, X509V3_EXT_get, X509_EXTENSION *a, a, return 0, return)
-DEFINEFUNC(void *, X509V3_EXT_d2i, X509_EXTENSION *a, a, return 0, return)
+DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return nullptr, return)
+DEFINEFUNC(const X509V3_EXT_METHOD *, X509V3_EXT_get, X509_EXTENSION *a, a, return nullptr, return)
+DEFINEFUNC(void *, X509V3_EXT_d2i, X509_EXTENSION *a, a, return nullptr, return)
DEFINEFUNC(int, X509_EXTENSION_get_critical, X509_EXTENSION *a, a, return 0, return)
-DEFINEFUNC(ASN1_OCTET_STRING *, X509_EXTENSION_get_data, X509_EXTENSION *a, a, return 0, return)
+DEFINEFUNC(ASN1_OCTET_STRING *, X509_EXTENSION_get_data, X509_EXTENSION *a, a, return nullptr, return)
DEFINEFUNC(void, BASIC_CONSTRAINTS_free, BASIC_CONSTRAINTS *a, a, return, DUMMYARG)
DEFINEFUNC(void, AUTHORITY_KEYID_free, AUTHORITY_KEYID *a, a, return, DUMMYARG)
DEFINEFUNC(void, GENERAL_NAME_free, GENERAL_NAME *a, a, return, DUMMYARG)
@@ -476,28 +509,30 @@ DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, const ASN1_STRING *b, b, return 0
DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, ASN1_STRING *b, b, return 0, return)
#endif
DEFINEFUNC2(int, X509_check_issued, X509 *a, a, X509 *b, b, return -1, return)
-DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
-DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
-DEFINEFUNC(ASN1_INTEGER *, X509_get_serialNumber, X509 *a, a, return 0, return)
+DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return nullptr, return)
+DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return nullptr, return)
+DEFINEFUNC(ASN1_INTEGER *, X509_get_serialNumber, X509 *a, a, return nullptr, return)
DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return)
-DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return)
-DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return 0, return)
-DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return 0, return)
-DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return 0, return)
+DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return nullptr, return)
+DEFINEFUNC(ASN1_STRING *, X509_NAME_ENTRY_get_data, X509_NAME_ENTRY *a, a, return nullptr, return)
+DEFINEFUNC(ASN1_OBJECT *, X509_NAME_ENTRY_get_object, X509_NAME_ENTRY *a, a, return nullptr, return)
+DEFINEFUNC(EVP_PKEY *, X509_PUBKEY_get, X509_PUBKEY *a, a, return nullptr, return)
DEFINEFUNC(void, X509_STORE_free, X509_STORE *a, a, return, DUMMYARG)
-DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(X509_STORE *, X509_STORE_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(int, X509_STORE_add_cert, X509_STORE *a, a, X509 *b, b, return 0, return)
DEFINEFUNC(void, X509_STORE_CTX_free, X509_STORE_CTX *a, a, return, DUMMYARG)
DEFINEFUNC4(int, X509_STORE_CTX_init, X509_STORE_CTX *a, a, X509_STORE *b, b, X509 *c, c, STACK_OF(X509) *d, d, return -1, return)
DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, return -1, return)
DEFINEFUNC(int, X509_STORE_CTX_get_error, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(int, X509_STORE_CTX_get_error_depth, X509_STORE_CTX *a, a, return -1, return)
-DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return 0, return)
-DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return nullptr, return)
+DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC2(void *, X509_STORE_CTX_get_ex_data, X509_STORE_CTX *ctx, ctx, int idx, idx, return nullptr, return)
+DEFINEFUNC(int, SSL_get_ex_data_X509_STORE_CTX_idx, DUMMYARG, DUMMYARG, return -1, return)
DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return)
-DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return 0, return)
+DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
DEFINEFUNC6(int, SSL_select_next_proto, unsigned char **out, out, unsigned char *outlen, outlen,
const unsigned char *in, in, unsigned int inlen, inlen,
@@ -524,15 +559,28 @@ DEFINEFUNC3(void, SSL_get0_alpn_selected, const SSL *s, s, const unsigned char *
unsigned *len, len, return, DUMMYARG)
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
-DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return 0, return)
+
+// DTLS:
+#if QT_CONFIG(dtls)
+DEFINEFUNC2(void, SSL_CTX_set_cookie_generate_cb, SSL_CTX *ctx, ctx, CookieGenerateCallback cb, cb, return, DUMMYARG)
+DEFINEFUNC2(void, SSL_CTX_set_cookie_verify_cb, SSL_CTX *ctx, ctx, CookieVerifyCallback cb, cb, return, DUMMYARG)
+DEFINEFUNC(const SSL_METHOD *, DTLS_server_method, DUMMYARG, DUMMYARG, return nullptr, return)
+DEFINEFUNC(const SSL_METHOD *, DTLS_client_method, DUMMYARG, DUMMYARG, return nullptr, return)
+#endif // dtls
+DEFINEFUNC2(void, BIO_set_flags, BIO *b, b, int flags, flags, return, DUMMYARG)
+DEFINEFUNC2(void, BIO_clear_flags, BIO *b, b, int flags, flags, return, DUMMYARG)
+DEFINEFUNC2(void *, BIO_get_ex_data, BIO *b, b, int idx, idx, return nullptr, return)
+DEFINEFUNC3(int, BIO_set_ex_data, BIO *b, b, int idx, idx, void *data, data, return -1, return)
+
+DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
-DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return 0, return)
+DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
-DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return 0, return)
+DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
#ifndef OPENSSL_NO_EC
-DEFINEFUNC(EC_KEY *, EC_KEY_dup, const EC_KEY *ec, ec, return 0, return)
-DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return 0, return)
+DEFINEFUNC(EC_KEY *, EC_KEY_dup, const EC_KEY *ec, ec, return nullptr, return)
+DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return nullptr, return)
DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG)
DEFINEFUNC2(size_t, EC_get_builtin_curves, EC_builtin_curve * r, r, size_t nitems, nitems, return 0, return)
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
@@ -542,7 +590,7 @@ DEFINEFUNC(int, EC_curve_nist2nid, const char *name, name, return 0, return)
DEFINEFUNC5(int, PKCS12_parse, PKCS12 *p12, p12, const char *pass, pass, EVP_PKEY **pkey, pkey, \
X509 **cert, cert, STACK_OF(X509) **ca, ca, return 1, return);
-DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, return 0, return);
+DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, return nullptr, return);
DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG)
#define RESOLVEFUNC(func) \
@@ -626,7 +674,7 @@ static QStringList libraryPathList()
// search in .app/Contents/Frameworks
UInt32 packageType;
- CFBundleGetPackageInfo(CFBundleGetMainBundle(), &packageType, NULL);
+ CFBundleGetPackageInfo(CFBundleGetMainBundle(), &packageType, nullptr);
if (packageType == FOUR_CHAR_CODE('APPL')) {
QUrl bundleUrl = QUrl::fromCFURL(QCFType<CFURLRef>(CFBundleCopyBundleURL(CFBundleGetMainBundle())));
QUrl frameworksUrl = QUrl::fromCFURL(QCFType<CFURLRef>(CFBundleCopyPrivateFrameworksURL(CFBundleGetMainBundle())));
@@ -855,13 +903,11 @@ bool q_resolveOpenSslSymbols()
{
static bool symbolsResolved = false;
static bool triedToResolveSymbols = false;
-#ifndef QT_NO_THREAD
#if QT_CONFIG(opensslv11)
QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_OPENSSL_init_ssl));
#else
QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
#endif
-#endif
if (symbolsResolved)
return true;
if (triedToResolveSymbols)
@@ -897,6 +943,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_SESSION_get_master_key)
RESOLVEFUNC(SSL_session_reused)
RESOLVEFUNC(SSL_get_session)
+ RESOLVEFUNC(SSL_set_options)
RESOLVEFUNC(CRYPTO_get_ex_new_index)
RESOLVEFUNC(TLS_method)
RESOLVEFUNC(TLS_client_method)
@@ -923,6 +970,25 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(DH_bits)
RESOLVEFUNC(DSA_bits)
+#if QT_CONFIG(dtls)
+ RESOLVEFUNC(DTLSv1_listen)
+ RESOLVEFUNC(BIO_ADDR_new)
+ RESOLVEFUNC(BIO_ADDR_free)
+ RESOLVEFUNC(BIO_meth_new)
+ RESOLVEFUNC(BIO_meth_free)
+ RESOLVEFUNC(BIO_meth_set_write)
+ RESOLVEFUNC(BIO_meth_set_read)
+ RESOLVEFUNC(BIO_meth_set_puts)
+ RESOLVEFUNC(BIO_meth_set_ctrl)
+ RESOLVEFUNC(BIO_meth_set_create)
+ RESOLVEFUNC(BIO_meth_set_destroy)
+#endif // dtls
+
+ RESOLVEFUNC(BIO_set_data)
+ RESOLVEFUNC(BIO_get_data)
+ RESOLVEFUNC(BIO_set_init)
+ RESOLVEFUNC(BIO_get_shutdown)
+ RESOLVEFUNC(BIO_set_shutdown)
#else // !opensslv11
RESOLVEFUNC(ASN1_STRING_data)
@@ -987,6 +1053,14 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(d2i_DSAPrivateKey)
RESOLVEFUNC(d2i_RSAPrivateKey)
#endif
+
+#if QT_CONFIG(dtls)
+ RESOLVEFUNC(DTLSv1_server_method)
+ RESOLVEFUNC(DTLSv1_client_method)
+ RESOLVEFUNC(DTLSv1_2_server_method)
+ RESOLVEFUNC(DTLSv1_2_client_method)
+#endif // dtls
+
RESOLVEFUNC(CONF_get1_default_config_file)
RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
@@ -1025,6 +1099,11 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(BIO_read)
RESOLVEFUNC(BIO_s_mem)
RESOLVEFUNC(BIO_write)
+ RESOLVEFUNC(BIO_set_flags)
+ RESOLVEFUNC(BIO_clear_flags)
+ RESOLVEFUNC(BIO_set_ex_data)
+ RESOLVEFUNC(BIO_get_ex_data)
+
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EC_KEY_get0_group)
RESOLVEFUNC(EC_GROUP_get_degree)
@@ -1037,6 +1116,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(DSA_new)
RESOLVEFUNC(DSA_free)
RESOLVEFUNC(ERR_error_string)
+ RESOLVEFUNC(ERR_error_string_n)
RESOLVEFUNC(ERR_get_error)
RESOLVEFUNC(EVP_CIPHER_CTX_new)
RESOLVEFUNC(EVP_CIPHER_CTX_free)
@@ -1104,10 +1184,12 @@ bool q_resolveOpenSslSymbols()
#endif
RESOLVEFUNC(RAND_seed)
RESOLVEFUNC(RAND_status)
+ RESOLVEFUNC(RAND_bytes)
RESOLVEFUNC(RSA_new)
RESOLVEFUNC(RSA_free)
RESOLVEFUNC(SSL_CIPHER_description)
RESOLVEFUNC(SSL_CIPHER_get_bits)
+ RESOLVEFUNC(SSL_get_rbio)
RESOLVEFUNC(SSL_CTX_check_private_key)
RESOLVEFUNC(SSL_CTX_ctrl)
RESOLVEFUNC(SSL_CTX_free)
@@ -1148,6 +1230,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_set_bio)
RESOLVEFUNC(SSL_set_connect_state)
RESOLVEFUNC(SSL_shutdown)
+ RESOLVEFUNC(SSL_get_shutdown)
RESOLVEFUNC(SSL_set_session)
RESOLVEFUNC(SSL_SESSION_free)
RESOLVEFUNC(SSL_get1_session)
@@ -1155,6 +1238,7 @@ bool q_resolveOpenSslSymbols()
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
RESOLVEFUNC(SSL_set_ex_data)
RESOLVEFUNC(SSL_get_ex_data)
+ RESOLVEFUNC(SSL_get_ex_data_X509_STORE_CTX_idx)
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
RESOLVEFUNC(SSL_set_psk_client_callback)
@@ -1178,6 +1262,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_STORE_CTX_get_error_depth)
RESOLVEFUNC(X509_STORE_CTX_get_current_cert)
RESOLVEFUNC(X509_cmp)
+ RESOLVEFUNC(X509_STORE_CTX_get_ex_data)
+
#ifndef SSLEAY_MACROS
RESOLVEFUNC(X509_dup)
#endif
@@ -1216,6 +1302,12 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_set_alpn_select_cb)
RESOLVEFUNC(SSL_get0_alpn_selected)
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
+#if QT_CONFIG(dtls)
+ RESOLVEFUNC(SSL_CTX_set_cookie_generate_cb)
+ RESOLVEFUNC(SSL_CTX_set_cookie_verify_cb)
+ RESOLVEFUNC(DTLS_server_method)
+ RESOLVEFUNC(DTLS_client_method)
+#endif // dtls
RESOLVEFUNC(DH_new)
RESOLVEFUNC(DH_free)
RESOLVEFUNC(d2i_DHparams)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 68b519d74e..bfdfbf0efc 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -257,6 +257,7 @@ DSA *q_DSA_new();
void q_DSA_free(DSA *a);
X509 *q_d2i_X509(X509 **a, const unsigned char **b, long c);
char *q_ERR_error_string(unsigned long a, char *b);
+void q_ERR_error_string_n(unsigned long e, char *buf, size_t len);
unsigned long q_ERR_get_error();
EVP_CIPHER_CTX *q_EVP_CIPHER_CTX_new();
void q_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);
@@ -331,12 +332,14 @@ int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b);
#endif
void q_RAND_seed(const void *a, int b);
int q_RAND_status();
+int q_RAND_bytes(unsigned char *b, int n);
RSA *q_RSA_new();
void q_RSA_free(RSA *a);
int q_SSL_accept(SSL *a);
int q_SSL_clear(SSL *a);
char *q_SSL_CIPHER_description(const SSL_CIPHER *a, char *b, int c);
int q_SSL_CIPHER_get_bits(const SSL_CIPHER *a, int *b);
+BIO *q_SSL_get_rbio(const SSL *s);
int q_SSL_connect(SSL *a);
int q_SSL_CTX_check_private_key(const SSL_CTX *a);
long q_SSL_CTX_ctrl(SSL_CTX *a, int b, long c, void *d);
@@ -383,6 +386,7 @@ void q_SSL_set_bio(SSL *a, BIO *b, BIO *c);
void q_SSL_set_accept_state(SSL *a);
void q_SSL_set_connect_state(SSL *a);
int q_SSL_shutdown(SSL *a);
+int q_SSL_get_shutdown(const SSL *ssl);
int q_SSL_set_session(SSL *to, SSL_SESSION *session);
void q_SSL_SESSION_free(SSL_SESSION *ses);
SSL_SESSION *q_SSL_get1_session(SSL *ssl);
@@ -529,6 +533,40 @@ void q_SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
#endif
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+#if QT_CONFIG(dtls)
+
+extern "C"
+{
+typedef int (*CookieGenerateCallback)(SSL *, unsigned char *, unsigned *);
+}
+
+void q_SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, CookieGenerateCallback cb);
+void q_SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, CookieVerifyCallback cb);
+const SSL_METHOD *q_DTLS_server_method();
+const SSL_METHOD *q_DTLS_client_method();
+
+#endif // dtls
+
+void *q_X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx);
+int q_SSL_get_ex_data_X509_STORE_CTX_idx();
+
+#if QT_CONFIG(dtls)
+#define q_DTLS_set_link_mtu(ssl, mtu) q_SSL_ctrl((ssl), DTLS_CTRL_SET_LINK_MTU, (mtu), nullptr)
+#define q_DTLSv1_get_timeout(ssl, arg) q_SSL_ctrl(ssl, DTLS_CTRL_GET_TIMEOUT, 0, arg)
+#define q_DTLSv1_handle_timeout(ssl) q_SSL_ctrl(ssl, DTLS_CTRL_HANDLE_TIMEOUT, 0, nullptr)
+#endif // dtls
+
+void q_BIO_set_flags(BIO *b, int flags);
+void q_BIO_clear_flags(BIO *b, int flags);
+void *q_BIO_get_ex_data(BIO *b, int idx);
+int q_BIO_set_ex_data(BIO *b, int idx, void *data);
+
+#define q_BIO_set_retry_read(b) q_BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+#define q_BIO_set_retry_write(b) q_BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+#define q_BIO_clear_retry_flags(b) q_BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+#define q_BIO_set_app_data(s,arg) q_BIO_set_ex_data(s,0,arg)
+#define q_BIO_get_app_data(s) q_BIO_get_ex_data(s,0)
+
// Helper function
class QDateTime;
QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime);
diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
index 9686d22b98..b7bac5d2a2 100644
--- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
@@ -204,6 +204,7 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
#endif // SSLEAY_MACROS
#define q_SSL_CTX_set_options(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
+#define q_SSL_set_options(ssl,op) q_SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),nullptr)
#define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_sk_num)(st)
#define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_sk_value)(st, i)
#define q_X509_getm_notAfter(x) X509_get_notAfter(x)
@@ -226,5 +227,19 @@ void q_OPENSSL_add_all_algorithms_conf();
long q_SSLeay();
const char *q_SSLeay_version(int type);
+#if QT_CONFIG(dtls)
+// DTLS:
+extern "C"
+{
+typedef int (*CookieVerifyCallback)(SSL *, unsigned char *, unsigned);
+}
+
+#define q_DTLSv1_listen(ssl, peer) q_SSL_ctrl(ssl, DTLS_CTRL_LISTEN, 0, (void *)peer)
+
+const SSL_METHOD *q_DTLSv1_server_method();
+const SSL_METHOD *q_DTLSv1_client_method();
+const SSL_METHOD *q_DTLSv1_2_server_method();
+const SSL_METHOD *q_DTLSv1_2_client_method();
+#endif // dtls
#endif // QSSLSOCKET_OPENSSL_PRE11_SYMBOLS_P_H
diff --git a/src/network/ssl/qwindowscarootfetcher.cpp b/src/network/ssl/qwindowscarootfetcher.cpp
new file mode 100644
index 0000000000..f83f96886c
--- /dev/null
+++ b/src/network/ssl/qwindowscarootfetcher.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowscarootfetcher_p.h"
+
+#include <QtCore/QThread>
+#include <QtGlobal>
+
+#ifdef QSSLSOCKET_DEBUG
+#include "qssl_p.h" // for debug categories
+#include <QtCore/QElapsedTimer>
+#endif
+
+#include "qsslsocket_p.h" // Transitively includes Wincrypt.h
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsCaRootFetcherThread : public QThread
+{
+public:
+ QWindowsCaRootFetcherThread()
+ {
+ qRegisterMetaType<QSslCertificate>();
+ setObjectName(QStringLiteral("QWindowsCaRootFetcher"));
+ start();
+ }
+ ~QWindowsCaRootFetcherThread()
+ {
+ quit();
+ wait(15500); // worst case, a running request can block for 15 seconds
+ }
+};
+
+Q_GLOBAL_STATIC(QWindowsCaRootFetcherThread, windowsCaRootFetcherThread);
+
+QWindowsCaRootFetcher::QWindowsCaRootFetcher(const QSslCertificate &certificate, QSslSocket::SslMode sslMode)
+ : cert(certificate), mode(sslMode)
+{
+ moveToThread(windowsCaRootFetcherThread());
+}
+
+QWindowsCaRootFetcher::~QWindowsCaRootFetcher()
+{
+}
+
+void QWindowsCaRootFetcher::start()
+{
+ QByteArray der = cert.toDer();
+ PCCERT_CONTEXT wincert = CertCreateCertificateContext(X509_ASN_ENCODING, (const BYTE *)der.constData(), der.length());
+ if (!wincert) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "QWindowsCaRootFetcher failed to convert certificate to windows form");
+#endif
+ emit finished(cert, QSslCertificate());
+ deleteLater();
+ return;
+ }
+
+ CERT_CHAIN_PARA parameters;
+ memset(&parameters, 0, sizeof(parameters));
+ parameters.cbSize = sizeof(parameters);
+ // set key usage constraint
+ parameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
+ parameters.RequestedUsage.Usage.cUsageIdentifier = 1;
+ LPSTR oid = (LPSTR)(mode == QSslSocket::SslClientMode ? szOID_PKIX_KP_SERVER_AUTH : szOID_PKIX_KP_CLIENT_AUTH);
+ parameters.RequestedUsage.Usage.rgpszUsageIdentifier = &oid;
+
+#ifdef QSSLSOCKET_DEBUG
+ QElapsedTimer stopwatch;
+ stopwatch.start();
+#endif
+ PCCERT_CHAIN_CONTEXT chain;
+ BOOL result = CertGetCertificateChain(
+ nullptr, //default engine
+ wincert,
+ nullptr, //current date/time
+ nullptr, //default store
+ &parameters,
+ 0, //default dwFlags
+ nullptr, //reserved
+ &chain);
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "QWindowsCaRootFetcher" << stopwatch.elapsed() << "ms to get chain";
+#endif
+
+ QSslCertificate trustedRoot;
+ if (result) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << "QWindowsCaRootFetcher - examining windows chains";
+ if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
+ qCDebug(lcSsl) << " - TRUSTED";
+ else
+ qCDebug(lcSsl) << " - NOT TRUSTED" << chain->TrustStatus.dwErrorStatus;
+ if (chain->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED)
+ qCDebug(lcSsl) << " - SELF SIGNED";
+ qCDebug(lcSsl) << "QSslSocketBackendPrivate::fetchCaRootForCert - dumping simple chains";
+ for (unsigned int i = 0; i < chain->cChain; i++) {
+ if (chain->rgpChain[i]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
+ qCDebug(lcSsl) << " - TRUSTED SIMPLE CHAIN" << i;
+ else
+ qCDebug(lcSsl) << " - UNTRUSTED SIMPLE CHAIN" << i << "reason:" << chain->rgpChain[i]->TrustStatus.dwErrorStatus;
+ for (unsigned int j = 0; j < chain->rgpChain[i]->cElement; j++) {
+ QSslCertificate foundCert(QByteArray((const char *)chain->rgpChain[i]->rgpElement[j]->pCertContext->pbCertEncoded
+ , chain->rgpChain[i]->rgpElement[j]->pCertContext->cbCertEncoded), QSsl::Der);
+ qCDebug(lcSsl) << " - " << foundCert;
+ }
+ }
+ qCDebug(lcSsl) << " - and" << chain->cLowerQualityChainContext << "low quality chains"; //expect 0, we haven't asked for them
+#endif
+
+ //based on http://msdn.microsoft.com/en-us/library/windows/desktop/aa377182%28v=vs.85%29.aspx
+ //about the final chain rgpChain[cChain-1] which must begin with a trusted root to be valid
+ if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR
+ && chain->cChain > 0) {
+ const PCERT_SIMPLE_CHAIN finalChain = chain->rgpChain[chain->cChain - 1];
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa377544%28v=vs.85%29.aspx
+ // rgpElement[0] is the end certificate chain element. rgpElement[cElement-1] is the self-signed "root" certificate element.
+ if (finalChain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR
+ && finalChain->cElement > 0) {
+ trustedRoot = QSslCertificate(QByteArray((const char *)finalChain->rgpElement[finalChain->cElement - 1]->pCertContext->pbCertEncoded
+ , finalChain->rgpElement[finalChain->cElement - 1]->pCertContext->cbCertEncoded), QSsl::Der);
+ }
+ }
+ CertFreeCertificateChain(chain);
+ }
+ CertFreeCertificateContext(wincert);
+
+ emit finished(cert, trustedRoot);
+ deleteLater();
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qwindowscarootfetcher_p.h b/src/network/ssl/qwindowscarootfetcher_p.h
new file mode 100644
index 0000000000..181c309388
--- /dev/null
+++ b/src/network/ssl/qwindowscarootfetcher_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCAROOTFETCHER_P_H
+#define QWINDOWSCAROOTFETCHER_P_H
+
+#include <QtCore/QtGlobal>
+#include <QtCore/QObject>
+
+#include "qsslsocket.h"
+#include "qsslcertificate.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.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsCaRootFetcher : public QObject
+{
+ Q_OBJECT;
+public:
+ QWindowsCaRootFetcher(const QSslCertificate &certificate, QSslSocket::SslMode sslMode);
+ ~QWindowsCaRootFetcher();
+public slots:
+ void start();
+signals:
+ void finished(QSslCertificate brokenChain, QSslCertificate caroot);
+private:
+ QSslCertificate cert;
+ QSslSocket::SslMode mode;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSCAROOTFETCHER_P_H
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index 2783effaf1..6975264038 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -1,12 +1,23 @@
# OpenSSL support; compile in QSslSocket.
+
+HEADERS += ssl/qasn1element_p.h \
+ ssl/qssl.h \
+ ssl/qssl_p.h \
+ ssl/qsslcertificate.h \
+ ssl/qsslcertificate_p.h \
+ ssl/qsslcertificateextension.h \
+ ssl/qsslcertificateextension_p.h
+
+SOURCES += ssl/qasn1element.cpp \
+ ssl/qssl.cpp \
+ ssl/qsslcertificate.cpp \
+ ssl/qsslcertificateextension.cpp
+
+!qtConfig(openssl): SOURCES += ssl/qsslcertificate_qt.cpp
+
qtConfig(ssl) {
- HEADERS += ssl/qasn1element_p.h \
- ssl/qssl.h \
- ssl/qssl_p.h \
- ssl/qsslcertificate.h \
- ssl/qsslcertificate_p.h \
- ssl/qsslconfiguration.h \
- ssl/qsslconfiguration_p.h \
+ HEADERS += ssl/qsslconfiguration.h \
+ ssl/qsslconfiguration_p.h \
ssl/qsslcipher.h \
ssl/qsslcipher_p.h \
ssl/qssldiffiehellmanparameters.h \
@@ -18,26 +29,19 @@ qtConfig(ssl) {
ssl/qsslsocket.h \
ssl/qsslsocket_p.h \
ssl/qsslpresharedkeyauthenticator.h \
- ssl/qsslpresharedkeyauthenticator_p.h \
- ssl/qsslcertificateextension.h \
- ssl/qsslcertificateextension_p.h
- SOURCES += ssl/qasn1element.cpp \
- ssl/qssl.cpp \
- ssl/qsslcertificate.cpp \
- ssl/qsslconfiguration.cpp \
+ ssl/qsslpresharedkeyauthenticator_p.h
+ SOURCES += ssl/qsslconfiguration.cpp \
ssl/qsslcipher.cpp \
ssl/qssldiffiehellmanparameters.cpp \
ssl/qsslellipticcurve.cpp \
ssl/qsslkey_p.cpp \
ssl/qsslerror.cpp \
ssl/qsslsocket.cpp \
- ssl/qsslpresharedkeyauthenticator.cpp \
- ssl/qsslcertificateextension.cpp
+ ssl/qsslpresharedkeyauthenticator.cpp
winrt {
HEADERS += ssl/qsslsocket_winrt_p.h
- SOURCES += ssl/qsslcertificate_qt.cpp \
- ssl/qsslcertificate_winrt.cpp \
+ SOURCES += ssl/qsslcertificate_winrt.cpp \
ssl/qssldiffiehellmanparameters_dummy.cpp \
ssl/qsslkey_qt.cpp \
ssl/qsslkey_winrt.cpp \
@@ -47,8 +51,7 @@ qtConfig(ssl) {
qtConfig(securetransport) {
HEADERS += ssl/qsslsocket_mac_p.h
- SOURCES += ssl/qsslcertificate_qt.cpp \
- ssl/qssldiffiehellmanparameters_dummy.cpp \
+ SOURCES += ssl/qssldiffiehellmanparameters_dummy.cpp \
ssl/qsslkey_qt.cpp \
ssl/qsslkey_mac.cpp \
ssl/qsslsocket_mac_shared.cpp \
@@ -56,6 +59,13 @@ qtConfig(ssl) {
ssl/qsslellipticcurve_dummy.cpp
}
+ qtConfig(dtls) {
+ HEADERS += ssl/qdtls.h \
+ ssl/qdtls_p.h
+
+ SOURCES += ssl/qdtls.cpp
+ }
+
qtConfig(openssl) {
HEADERS += ssl/qsslcontext_openssl_p.h \
ssl/qsslsocket_openssl_p.h \
@@ -66,7 +76,12 @@ qtConfig(ssl) {
ssl/qsslellipticcurve_openssl.cpp \
ssl/qsslkey_openssl.cpp \
ssl/qsslsocket_openssl.cpp \
- ssl/qsslcontext_openssl.cpp
+ ssl/qsslcontext_openssl.cpp \
+
+ qtConfig(dtls) {
+ HEADERS += ssl/qdtls_openssl_p.h
+ SOURCES += ssl/qdtls_openssl.cpp
+ }
qtConfig(opensslv11) {
HEADERS += ssl/qsslsocket_openssl11_symbols_p.h
@@ -95,6 +110,13 @@ qtConfig(ssl) {
QMAKE_USE_FOR_PRIVATE += openssl
else: \
QMAKE_USE_FOR_PRIVATE += openssl/nolink
- win32: LIBS_PRIVATE += -lcrypt32
+ win32 {
+ LIBS_PRIVATE += -lcrypt32
+ HEADERS += ssl/qwindowscarootfetcher_p.h
+ SOURCES += ssl/qwindowscarootfetcher.cpp
+ }
}
}
+
+HEADERS += ssl/qpassworddigestor.h
+SOURCES += ssl/qpassworddigestor.cpp
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 6365a7421b..cc97bed3f7 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -2099,9 +2099,8 @@ bool QGL2PaintEngineEx::end()
d->device->endPaint();
ctx->d_ptr->active_engine = 0;
-
+ ctx->makeCurrent();
d->resetOpenGLContextActiveEngine();
-
d->resetGLState();
delete d->shaderManager;
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index d9f2113c14..e136ddcff2 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2104,17 +2104,17 @@ struct DDSFormat {
would mirror the image and automatically generate mipmaps. This
option helps preserve this default behavior.
- \omitvalue CanFlipNativePixmapBindOption Used by x11 from pixmap to choose
- whether or not it can bind the pixmap upside down or not.
+ \omitvalue CanFlipNativePixmapBindOption \omit Used by x11 from pixmap to choose
+ whether or not it can bind the pixmap upside down or not. \endomit
- \omitvalue MemoryManagedBindOption Used by paint engines to
+ \omitvalue MemoryManagedBindOption \omit Used by paint engines to
indicate that the pixmap should be memory managed along side with
the pixmap/image that it stems from, e.g. installing destruction
- hooks in them.
+ hooks in them. \endomit
- \omitvalue TemporarilyCachedBindOption Used by paint engines on some
+ \omitvalue TemporarilyCachedBindOption \omit Used by paint engines on some
platforms to indicate that the pixmap or image texture is possibly
- cached only temporarily and must be destroyed immediately after the use.
+ cached only temporarily and must be destroyed immediately after the use. \endomit
\omitvalue InternalBindOption
*/
@@ -3603,7 +3603,8 @@ void QGLContext::makeCurrent()
\fn void QGLContext::swapBuffers() const
Call this to finish a frame of OpenGL rendering, and make sure to
- call makeCurrent() again before you begin a new frame.
+ call makeCurrent() again before issuing any further OpenGL commands,
+ for example as part of a new frame.
*/
void QGLContext::swapBuffers() const
{
@@ -4084,7 +4085,13 @@ bool QGLWidget::isSharing() const
void QGLWidget::makeCurrent()
{
Q_D(QGLWidget);
- d->glcx->makeCurrent();
+ d->makeCurrent();
+}
+
+bool QGLWidgetPrivate::makeCurrent()
+{
+ glcx->makeCurrent();
+ return QGLContext::currentContext() == glcx;
}
/*!
@@ -4422,7 +4429,8 @@ void QGLWidget::resizeEvent(QResizeEvent *e)
QWidget::resizeEvent(e);
if (!isValid())
return;
- makeCurrent();
+ if (!d->makeCurrent())
+ return;
if (!d->glcx->initialized())
glInit();
const qreal scaleFactor = (window() && window()->windowHandle()) ?
@@ -4537,7 +4545,8 @@ void QGLWidget::glInit()
Q_D(QGLWidget);
if (!isValid())
return;
- makeCurrent();
+ if (!d->makeCurrent())
+ return;
initializeGL();
d->glcx->setInitialized(true);
}
@@ -4555,7 +4564,8 @@ void QGLWidget::glDraw()
Q_D(QGLWidget);
if (!isValid())
return;
- makeCurrent();
+ if (!d->makeCurrent())
+ return;
#ifndef QT_OPENGL_ES
if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isOpenGLES())
qgl1_functions()->glDrawBuffer(GL_FRONT);
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 6b4d83888f..ed364283cc 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -145,6 +145,8 @@ public:
glcx->reset();
}
+ bool makeCurrent();
+
QGLContext *glcx;
QGLWidgetGLPaintDevice glDevice;
bool autoSwap;
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 0b386ededc..0b2ddf97fe 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -103,6 +103,14 @@ extern QImage qt_gl_read_frame_buffer(const QSize&, bool, bool);
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#endif
+#ifndef GL_DEPTH_STENCIL_ATTACHMENT
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#endif
+
+#ifndef GL_DEPTH_STENCIL
+#define GL_DEPTH_STENCIL 0x84F9
+#endif
+
/*!
\class QGLFramebufferObjectFormat
\inmodule QtOpenGL
@@ -562,6 +570,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
funcs.glGenRenderbuffers(1, &depth_buffer);
funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
+#ifndef Q_OS_WASM
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
GL_DEPTH24_STENCIL8, size.width(), size.height());
@@ -574,6 +583,19 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
GL_RENDERBUFFER, depth_buffer);
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
+#else
+ // webgl does not allow separate depth and stencil attachments
+ if (samples != 0) {
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_STENCIL, size.width(), size.height());
+ } else {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL,
+ size.width(), size.height());
+ }
+ stencil_buffer = depth_buffer;
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, depth_buffer);
+#endif
valid = checkFramebufferStatus();
if (!valid) {
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
index b29f71ad2e..c5151f66bb 100644
--- a/src/opengl/qglpaintdevice.cpp
+++ b/src/opengl/qglpaintdevice.cpp
@@ -126,6 +126,7 @@ void QGLPaintDevice::endPaint()
{
// Make sure the FBO bound at beginPaint is re-bound again here:
QGLContext *ctx = context();
+ ctx->makeCurrent();
ctx->d_func()->refreshCurrentFbo();
diff --git a/src/platformheaders/cocoafunctions/qcocoawindowfunctions.qdoc b/src/platformheaders/cocoafunctions/qcocoawindowfunctions.qdoc
index 876096e40f..e164a92e22 100644
--- a/src/platformheaders/cocoafunctions/qcocoawindowfunctions.qdoc
+++ b/src/platformheaders/cocoafunctions/qcocoawindowfunctions.qdoc
@@ -46,7 +46,7 @@
/*!
\fn QByteArray QCocoaWindowFunctions::bottomLeftClippedByNSWindowOffsetIdentifier()
- This function returnes the bytearray that can be used to query
+ This function returns the bytearray that can be used to query
QGuiApplication::platformFunction to retrieve the BottomLeftClippedByNSWindowOffset function.
*/
diff --git a/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h b/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h
deleted file mode 100644
index fc24dd0f6e..0000000000
--- a/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QXCBINTEGRATIONFUNCTIONS_H
-#define QXCBINTEGRATIONFUNCTIONS_H
-
-#include <QtPlatformHeaders/QPlatformHeaderHelper>
-
-QT_BEGIN_NAMESPACE
-
-class QXcbIntegrationFunctions
-{
-public:
- typedef bool (*XEmbedSystemTrayVisualHasAlphaChannel)();
- static const QByteArray xEmbedSystemTrayVisualHasAlphaChannelIdentifier() { return QByteArrayLiteral("XcbXEmbedSystemTrayVisualHasAlphaChannel"); }
- static bool xEmbedSystemTrayVisualHasAlphaChannel()
- {
- return QPlatformHeaderHelper::callPlatformFunction<bool, XEmbedSystemTrayVisualHasAlphaChannel>(xEmbedSystemTrayVisualHasAlphaChannelIdentifier());
- }
-};
-
-QT_END_NAMESPACE
-
-#endif /*QXCBINTEGRATIONFUNCTIONS_H*/
diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h
index b6c3b1db73..b0e6cb6a1d 100644
--- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h
+++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h
@@ -90,27 +90,6 @@ public:
return QPlatformHeaderHelper::callPlatformFunction<void, SetWmWindowIconText, QWindow *, const QString &>(setWmWindowIconTextIdentifier(), window, text);
}
- typedef void (*SetParentRelativeBackPixmap)(const QWindow *window);
- static const QByteArray setParentRelativeBackPixmapIdentifier() { return QByteArrayLiteral("XcbSetParentRelativeBackPixmap"); }
- static void setParentRelativeBackPixmap(const QWindow *window)
- {
- return QPlatformHeaderHelper::callPlatformFunction<void, SetParentRelativeBackPixmap, const QWindow *>(setParentRelativeBackPixmapIdentifier(), window);
- }
-
- typedef bool (*RequestSystemTrayWindowDock)(const QWindow *window);
- static const QByteArray requestSystemTrayWindowDockIdentifier() { return QByteArrayLiteral("XcbRequestSystemTrayWindowDockIdentifier"); }
- static bool requestSystemTrayWindowDock(const QWindow *window)
- {
- return QPlatformHeaderHelper::callPlatformFunction<bool, RequestSystemTrayWindowDock, const QWindow *>(requestSystemTrayWindowDockIdentifier(), window);
- }
-
- typedef QRect (*SystemTrayWindowGlobalGeometry)(const QWindow *window);
- static const QByteArray systemTrayWindowGlobalGeometryIdentifier() { return QByteArrayLiteral("XcbSystemTrayWindowGlobalGeometryIdentifier"); }
- static QRect systemTrayWindowGlobalGeometry(const QWindow *window)
- {
- return QPlatformHeaderHelper::callPlatformFunction<QRect, SystemTrayWindowGlobalGeometry, const QWindow *>(systemTrayWindowGlobalGeometryIdentifier(), window);
- }
-
typedef uint (*VisualId)(QWindow *window);
static const QByteArray visualIdIdentifier() { return QByteArrayLiteral("XcbVisualId"); }
diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc
index fab473b91b..5e2aa2cbf2 100644
--- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc
+++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc
@@ -138,81 +138,6 @@
*/
/*!
- \typedef QXcbWindowFunctions::SetParentRelativeBackPixmap
-
- This is the typedef for the function returned by
- QGuiApplication::platformFunction when passed the
- value returned by setParentRelativeBackPixmapIdentifier().
-*/
-
-/*!
- \fn const QByteArray QXcbWindowFunctions::setParentRelativeBackPixmapIdentifier()
-
- This function returns the byte array that can be used to query
- QGuiApplication::platformFunction to retrieve the SetParentRelativeBackPixmap function.
-*/
-
-/*!
- \fn void QXcbWindowFunctions::setParentRelativeBackPixmap(const QWindow *window)
-
- This is a convenience function that can be used directly instead
- of resolving the function pointer. \a window will be
- relayed to the function retrieved by QGuiApplication.
-*/
-
-/*!
- \typedef QXcbWindowFunctions::RequestSystemTrayWindowDock
-
- This is the typedef for the function returned by
- QGuiApplication::platformFunction when passed the
- value returned by requestSystemTrayWindowDockIdentifier().
-*/
-
-/*!
- \fn const QByteArray QXcbWindowFunctions::requestSystemTrayWindowDockIdentifier()
-
- This function returns the byte array that can be used to query
- QGuiApplication::platformFunction to retrieve the RequestSystemTrayWindowDock function.
-*/
-
-/*!
- \fn bool QXcbWindowFunctions::requestSystemTrayWindowDock(const QWindow *window)
-
- This is a convenience function that can be used directly instead
- of resolving the function pointer. \a window will be
- relayed to the function retrieved by QGuiApplication.
-
- Returns the boolean result of calling the function or false if the
- function was not found.
-*/
-
-/*!
- \typedef QXcbWindowFunctions::SystemTrayWindowGlobalGeometry
-
- This is the typedef for the function returned by
- QGuiApplication::platformFunction when passed the
- value returned by systemTrayWindowGlobalGeometryIdentifier().
-*/
-
-/*!
- \fn const QByteArray QXcbWindowFunctions::systemTrayWindowGlobalGeometryIdentifier()
-
- This function returns the byte array that can be used to query
- QGuiApplication::platformFunction to retrieve the SystemTrayWindowGlobalGeometry function.
-*/
-
-/*!
- \fn QRect QXcbWindowFunctions::systemTrayWindowGlobalGeometry(const QWindow *window)
-
- This is a convenience function that can be used directly instead
- of resolving the function pointer. \a window will be
- relayed to the function retrieved by QGuiApplication.
-
- Returns the QRect result of calling the function or an empty
- QRect if the function was not found.
-*/
-
-/*!
\typedef QXcbWindowFunctions::VisualId
This is the typedef for the function returned by
diff --git a/src/platformheaders/xcbfunctions/xcbfunctions.pri b/src/platformheaders/xcbfunctions/xcbfunctions.pri
index 3f2bcb2b34..3fbee53854 100644
--- a/src/platformheaders/xcbfunctions/xcbfunctions.pri
+++ b/src/platformheaders/xcbfunctions/xcbfunctions.pri
@@ -1,4 +1,3 @@
HEADERS += \
$$PWD/qxcbwindowfunctions.h \
- $$PWD/qxcbintegrationfunctions.h \
$$PWD/qxcbscreenfunctions.h
diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm
index 09901ba0a5..caa2ccc6e5 100644
--- a/src/platformsupport/clipboard/qmacmime.mm
+++ b/src/platformsupport/clipboard/qmacmime.mm
@@ -536,13 +536,13 @@ QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList
// Read RTF into to NSAttributedString, then convert the string to HTML
NSAttributedString *string = [[NSAttributedString alloc] initWithData:data.at(0).toNSData()
- options:[NSDictionary dictionaryWithObject:NSRTFTextDocumentType forKey:NSDocumentTypeDocumentAttribute]
+ options:@{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType}
documentAttributes:nil
error:nil];
NSError *error;
NSRange range = NSMakeRange(0, [string length]);
- NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute];
+ NSDictionary *dict = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [string dataFromRange:range documentAttributes:dict error:&error];
return QByteArray::fromNSData(htmlData);
}
@@ -554,13 +554,13 @@ QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime
return ret;
NSAttributedString *string = [[NSAttributedString alloc] initWithData:data.toByteArray().toNSData()
- options:[NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute]
+ options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}
documentAttributes:nil
error:nil];
NSError *error;
NSRange range = NSMakeRange(0, [string length]);
- NSDictionary *dict = [NSDictionary dictionaryWithObject:NSRTFTextDocumentType forKey:NSDocumentTypeDocumentAttribute];
+ NSDictionary *dict = @{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType};
NSData *rtfData = [string dataFromRange:range documentAttributes:dict error:&error];
ret << QByteArray::fromNSData(rtfData);
return ret;
@@ -853,8 +853,8 @@ QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q
QImage img = qvariant_cast<QImage>(variant);
NSDictionary *props = @{
- static_cast<NSString *>(kCGImagePropertyPixelWidth) : [NSNumber numberWithInt:img.width()],
- static_cast<NSString *>(kCGImagePropertyPixelHeight) : [NSNumber numberWithInt:img.height()]
+ static_cast<NSString *>(kCGImagePropertyPixelWidth): @(img.width()),
+ static_cast<NSString *>(kCGImagePropertyPixelHeight): @(img.height())
};
CGImageDestinationAddImage(imageDestination, qt_mac_toCGImage(img), static_cast<CFDictionaryRef>(props));
diff --git a/src/platformsupport/edid/qedidparser.cpp b/src/platformsupport/edid/qedidparser.cpp
index ccf12e9eb3..ccaa50704c 100644
--- a/src/platformsupport/edid/qedidparser.cpp
+++ b/src/platformsupport/edid/qedidparser.cpp
@@ -100,11 +100,11 @@ bool QEdidParser::parse(const QByteArray &blob)
* 7654321076543210
* |\---/\---/\---/
* R C1 C2 C3 */
- char id[3];
- id[0] = 'A' + ((data[EDID_OFFSET_PNP_ID] & 0x7c) / 4) - 1;
- id[1] = 'A' + ((data[EDID_OFFSET_PNP_ID] & 0x3) * 8) + ((data[EDID_OFFSET_PNP_ID + 1] & 0xe0) / 32) - 1;
- id[2] = 'A' + (data[EDID_OFFSET_PNP_ID + 1] & 0x1f) - 1;
- identifier = QString::fromLatin1(id, 3);
+ char pnpId[3];
+ pnpId[0] = 'A' + ((data[EDID_OFFSET_PNP_ID] & 0x7c) / 4) - 1;
+ pnpId[1] = 'A' + ((data[EDID_OFFSET_PNP_ID] & 0x3) * 8) + ((data[EDID_OFFSET_PNP_ID + 1] & 0xe0) / 32) - 1;
+ pnpId[2] = 'A' + (data[EDID_OFFSET_PNP_ID + 1] & 0x1f) - 1;
+ QString pnpIdString = QString::fromLatin1(pnpId, 3);
// Clear manufacturer
manufacturer = QString();
@@ -136,12 +136,11 @@ bool QEdidParser::parse(const QByteArray &blob)
}
// Try to use cache first because it is potentially more updated
- if (m_vendorCache.contains(identifier)) {
- manufacturer = m_vendorCache[identifier];
- } else {
+ manufacturer = m_vendorCache.value(pnpIdString);
+ if (manufacturer.isEmpty()) {
// Find the manufacturer from the vendor lookup table
for (size_t i = 0; i < ARRAY_LENGTH(q_edidVendorTable); i++) {
- if (strcmp(q_edidVendorTable[i].id, identifier.toLatin1().constData()) == 0) {
+ if (strncmp(q_edidVendorTable[i].id, pnpId, 3) == 0) {
manufacturer = QString::fromUtf8(q_edidVendorTable[i].name);
break;
}
@@ -150,7 +149,7 @@ bool QEdidParser::parse(const QByteArray &blob)
// If we don't know the manufacturer, fallback to PNP ID
if (manufacturer.isEmpty())
- manufacturer = identifier;
+ manufacturer = pnpIdString;
// Physical size
physicalSize = QSizeF(data[EDID_PHYSICAL_WIDTH], data[EDID_OFFSET_PHYSICAL_HEIGHT]) * 10;
@@ -160,7 +159,7 @@ bool QEdidParser::parse(const QByteArray &blob)
QString QEdidParser::parseEdidString(const quint8 *data)
{
- QByteArray buffer(reinterpret_cast<const char *>(data), 12);
+ QByteArray buffer(reinterpret_cast<const char *>(data), 13);
// Erase carriage return and line feed
buffer = buffer.replace('\r', '\0').replace('\n', '\0');
diff --git a/src/platformsupport/edid/qedidvendortable_p.h b/src/platformsupport/edid/qedidvendortable_p.h
index 6ec399df05..5768dbe992 100644
--- a/src/platformsupport/edid/qedidvendortable_p.h
+++ b/src/platformsupport/edid/qedidvendortable_p.h
@@ -38,9 +38,9 @@
****************************************************************************/
/*
- * This lookup table was generated from https://git.fedorahosted.org/cgit/hwdata.git/plain/pnp.ids
+ * This lookup table was generated from https://github.com/vcrhonek/hwdata/raw/master/pnp.ids
*
- * Do not change directly this file, instead edit the
+ * Do not change this file directly, instead edit the
* qtbase/util/edid/qedidvendortable.py script and regenerate this file.
*/
@@ -66,2240 +66,2240 @@ typedef struct VendorTable {
} VendorTable;
static const struct VendorTable q_edidVendorTable[] = {
- { "LLL", "L-3 Communications" },
- { "GMX", "GMX Inc" },
- { "FOS", "Foss Tecator" },
- { "PHI", "DO NOT USE - PHI" },
- { "DNV", "DiCon" },
- { "KZN", "K-Zone International" },
- { "TIC", "Trigem KinfoComm" },
- { "FNC", "Fanuc LTD" },
- { "ESY", "E-Systems Inc" },
- { "TGM", "TriGem Computer,Inc." },
- { "DBN", "DB Networks Inc" },
- { "GCS", "Grey Cell Systems Ltd" },
- { "AVR", "AVer Information Inc." },
- { "OKI", "OKI Electric Industrial Company Ltd" },
- { "GDI", "G. Diehl ISDN GmbH" },
- { "SPC", "SpinCore Technologies, Inc" },
- { "ICV", "Inside Contactless" },
- { "UNY", "Unicate" },
- { "NMP", "Nokia Mobile Phones" },
- { "HMC", "Hualon Microelectric Corporation" },
- { "OPT", "OPTi Inc" },
- { "TSG", "The Software Group Ltd" },
- { "IMN", "Impossible Production" },
- { "DHQ", "Quadram" },
- { "UFG", "UNIGRAF-USA" },
- { "CLA", "Clarion Company Ltd" },
- { "IOM", "Iomega" },
- { "MTS", "Multi-Tech Systems" },
- { "TXN", "Texas Insturments" },
- { "SDH", "Communications Specialies, Inc." },
- { "DCC", "Dale Computer Corporation" },
- { "PAK", "Many CNC System Co., Ltd." },
- { "TDC", "Teradici" },
- { "XAC", "XAC Automation Corp" },
- { "DRI", "Data Race Inc" },
- { "HAN", "Hanchang System Corporation" },
- { "NTR", "N-trig Innovative Technologies, Inc." },
- { "PDR", "Pure Data Inc" },
- { "BNS", "Boulder Nonlinear Systems" },
- { "EGO", "Ergo Electronics" },
- { "ETS", "Electronic Trade Solutions Ltd" },
- { "CNN", "Canon Inc" },
- { "CSB", "Transtex SA" },
- { "NAK", "Nakano Engineering Co.,Ltd." },
- { "IME", "Imagraph" },
- { "CYT", "Cytechinfo Inc" },
+ { "AAA", "Avolites Ltd" },
+ { "AAE", "Anatek Electronics Inc." },
+ { "AAT", "Ann Arbor Technologies" },
+ { "ABA", "ABBAHOME INC." },
+ { "ABC", "AboCom System Inc" },
+ { "ABD", "Allen Bradley Company" },
+ { "ABE", "Alcatel Bell" },
+ { "ABO", "D-Link Systems Inc" },
+ { "ABT", "Anchor Bay Technologies, Inc." },
+ { "ABV", "Advanced Research Technology" },
+ { "ACA", "Ariel Corporation" },
+ { "ACB", "Aculab Ltd" },
+ { "ACC", "Accton Technology Corporation" },
+ { "ACD", "AWETA BV" },
+ { "ACE", "Actek Engineering Pty Ltd" },
+ { "ACG", "A&R Cambridge Ltd" },
+ { "ACH", "Archtek Telecom Corporation" },
+ { "ACI", "Ancor Communications Inc" },
+ { "ACK", "Acksys" },
+ { "ACL", "Apricot Computers" },
+ { "ACM", "Acroloop Motion Control Systems Inc" },
+ { "ACO", "Allion Computer Inc." },
+ { "ACP", "Aspen Tech Inc" },
+ { "ACR", "Acer Technologies" },
+ { "ACS", "Altos Computer Systems" },
+ { "ACT", "Applied Creative Technology" },
+ { "ACU", "Acculogic" },
+ { "ACV", "ActivCard S.A" },
+ { "ADA", "Addi-Data GmbH" },
+ { "ADB", "Aldebbaron" },
+ { "ADC", "Acnhor Datacomm" },
+ { "ADD", "Advanced Peripheral Devices Inc" },
+ { "ADE", "Arithmos, Inc." },
+ { "ADH", "Aerodata Holdings Ltd" },
+ { "ADI", "ADI Systems Inc" },
+ { "ADK", "Adtek System Science Company Ltd" },
+ { "ADL", "ASTRA Security Products Ltd" },
{ "ADM", "Ad Lib MultiMedia Inc" },
- { "IBC", "Integrated Business Systems" },
- { "TMT", "T-Metrics Inc." },
+ { "ADN", "Analog & Digital Devices Tel. Inc" },
+ { "ADP", "Adaptec Inc" },
+ { "ADR", "Nasa Ames Research Center" },
+ { "ADS", "Analog Devices Inc" },
+ { "ADT", "Aved Display Technologies" },
+ { "ADV", "Advanced Micro Devices Inc" },
+ { "ADX", "Adax Inc" },
+ { "AEC", "Antex Electronics Corporation" },
+ { "AED", "Advanced Electronic Designs, Inc." },
+ { "AEI", "Actiontec Electric Inc" },
+ { "AEJ", "Alpha Electronics Company" },
+ { "AEM", "ASEM S.p.A." },
+ { "AEN", "Avencall" },
+ { "AEP", "Aetas Peripheral International" },
+ { "AET", "Aethra Telecomunicazioni S.r.l." },
+ { "AFA", "Alfa Inc" },
+ { "AGC", "Beijing Aerospace Golden Card Electronic Engineering Co.,Ltd." },
+ { "AGI", "Artish Graphics Inc" },
+ { "AGL", "Argolis" },
+ { "AGM", "Advan Int'l Corporation" },
+ { "AGT", "Agilent Technologies" },
+ { "AHC", "Advantech Co., Ltd." },
+ { "AIC", "Arnos Insturments & Computer Systems" },
+ { "AIE", "Altmann Industrieelektronik" },
+ { "AII", "Amptron International Inc." },
+ { "AIL", "Altos India Ltd" },
+ { "AIM", "AIMS Lab Inc" },
+ { "AIR", "Advanced Integ. Research Inc" },
+ { "AIS", "Alien Internet Services" },
+ { "AIW", "Aiwa Company Ltd" },
+ { "AIX", "ALTINEX, INC." },
+ { "AJA", "AJA Video Systems, Inc." },
+ { "AKB", "Akebia Ltd" },
+ { "AKE", "AKAMI Electric Co.,Ltd" },
+ { "AKI", "AKIA Corporation" },
+ { "AKL", "AMiT Ltd" },
+ { "AKM", "Asahi Kasei Microsystems Company Ltd" },
+ { "AKP", "Atom Komplex Prylad" },
+ { "AKY", "Askey Computer Corporation" },
+ { "ALA", "Alacron Inc" },
+ { "ALC", "Altec Corporation" },
+ { "ALD", "In4S Inc" },
+ { "ALG", "Realtek Semiconductor Corp." },
+ { "ALH", "AL Systems" },
+ { "ALI", "Acer Labs" },
+ { "ALJ", "Altec Lansing" },
+ { "ALK", "Acrolink Inc" },
+ { "ALL", "Alliance Semiconductor Corporation" },
+ { "ALM", "Acutec Ltd." },
+ { "ALN", "Alana Technologies" },
+ { "ALO", "Algolith Inc." },
{ "ALP", "Alps Electric Company Ltd" },
- { "TWX", "TEKWorx Limited" },
- { "CDP", "CalComp" },
- { "KSX", "King Tester Corporation" },
+ { "ALR", "Advanced Logic" },
+ { "ALS", "Texas Advanced optoelectronics Solutions, Inc" },
+ { "ALT", "Altra" },
+ { "ALV", "AlphaView LCD" },
+ { "ALX", "ALEXON Co.,Ltd." },
+ { "AMA", "Asia Microelectronic Development Inc" },
+ { "AMB", "Ambient Technologies, Inc." },
+ { "AMC", "Attachmate Corporation" },
+ { "AMD", "Amdek Corporation" },
{ "AMI", "American Megatrends Inc" },
- { "KBI", "Kidboard Inc" },
- { "COO", "coolux GmbH" },
- { "CBR", "Cebra Tech A/S" },
+ { "AML", "Anderson Multimedia Communications (HK) Limited" },
+ { "AMN", "Amimon LTD." },
+ { "AMO", "Amino Technologies PLC and Amino Communications Limited" },
+ { "AMP", "AMP Inc" },
+ { "AMS", "ARMSTEL, Inc." },
+ { "AMT", "AMT International Industry" },
+ { "AMX", "AMX LLC" },
{ "ANA", "Anakron" },
- { "ACT", "Applied Creative Technology" },
- { "PGS", "Princeton Graphic Systems" },
- { "DCL", "Dynamic Controls Ltd" },
- { "TCH", "Interaction Systems, Inc" },
- { "STP", "StreamPlay Ltd" },
- { "PCG", "First Industrial Computer Inc" },
- { "SSE", "Samsung Electronic Co." },
- { "TXT", "Textron Defense System" },
- { "XRO", "XORO ELECTRONICS (CHENGDU) LIMITED" },
- { "MTU", "Mark of the Unicorn Inc" },
- { "ERG", "Ergo System" },
- { "GFN", "Gefen Inc." },
- { "UNE", "Unisys Corporation" },
- { "DDD", "Danka Data Devices" },
- { "ZGT", "Zenith Data Systems" },
- { "NAL", "Network Alchemy" },
- { "FVX", "C-C-C Group Plc" },
- { "AJA", "AJA Video Systems, Inc." },
+ { "ANC", "Ancot" },
+ { "AND", "Adtran Inc" },
+ { "ANI", "Anigma Inc" },
+ { "ANK", "Anko Electronic Company Ltd" },
+ { "ANL", "Analogix Semiconductor, Inc" },
+ { "ANO", "Anorad Corporation" },
+ { "ANP", "Andrew Network Production" },
+ { "ANR", "ANR Ltd" },
+ { "ANS", "Ansel Communication Company" },
+ { "ANT", "Ace CAD Enterprise Company Ltd" },
+ { "ANX", "Acer Netxus Inc" },
+ { "AOA", "AOpen Inc." },
+ { "AOE", "Advanced Optics Electronics, Inc." },
+ { "AOL", "America OnLine" },
+ { "AOT", "Alcatel" },
+ { "APC", "American Power Conversion" },
+ { "APD", "AppliAdata" },
+ { "APE", "Alpine Electronics, Inc." },
+ { "APG", "Horner Electric Inc" },
+ { "API", "A Plus Info Corporation" },
+ { "APL", "Aplicom Oy" },
+ { "APM", "Applied Memory Tech" },
+ { "APN", "Appian Tech Inc" },
+ { "APP", "Apple Computer Inc" },
+ { "APR", "Aprilia s.p.a." },
+ { "APS", "Autologic Inc" },
+ { "APT", "Audio Processing Technology Ltd" },
+ { "APV", "A+V Link" },
+ { "APX", "AP Designs Ltd" },
+ { "ARC", "Alta Research Corporation" },
+ { "ARE", "ICET S.p.A." },
+ { "ARG", "Argus Electronics Co., LTD" },
+ { "ARI", "Argosy Research Inc" },
+ { "ARK", "Ark Logic Inc" },
+ { "ARL", "Arlotto Comnet Inc" },
+ { "ARM", "Arima" },
+ { "ARO", "Poso International B.V." },
+ { "ARS", "Arescom Inc" },
+ { "ART", "Corion Industrial Corporation" },
+ { "ASC", "Ascom Strategic Technology Unit" },
+ { "ASD", "USC Information Sciences Institute" },
+ { "ASE", "AseV Display Labs" },
+ { "ASI", "Ahead Systems" },
+ { "ASK", "Ask A/S" },
+ { "ASL", "AccuScene Corporation Ltd" },
+ { "ASM", "ASEM S.p.A." },
+ { "ASN", "Asante Tech Inc" },
+ { "ASP", "ASP Microelectronics Ltd" },
+ { "AST", "AST Research Inc" },
+ { "ASU", "Asuscom Network Inc" },
+ { "ASX", "AudioScience" },
+ { "ASY", "Rockwell Collins / Airshow Systems" },
+ { "ATA", "Allied Telesyn International (Asia) Pte Ltd" },
+ { "ATC", "Ably-Tech Corporation" },
+ { "ATD", "Alpha Telecom Inc" },
+ { "ATE", "Innovate Ltd" },
+ { "ATH", "Athena Informatica S.R.L." },
+ { "ATI", "Allied Telesis KK" },
+ { "ATK", "Allied Telesyn Int'l" },
+ { "ATL", "Arcus Technology Ltd" },
+ { "ATM", "ATM Ltd" },
+ { "ATN", "Athena Smartcard Solutions Ltd." },
+ { "ATO", "ASTRO DESIGN, INC." },
+ { "ATP", "Alpha-Top Corporation" },
+ { "ATT", "AT&T" },
+ { "ATV", "Office Depot, Inc." },
+ { "ATX", "Athenix Corporation" },
+ { "AUI", "Alps Electric Inc" },
+ { "AUO", "AU Optronics" },
+ { "AUR", "Aureal Semiconductor" },
+ { "AUT", "Autotime Corporation" },
+ { "AVA", "Avaya Communication" },
+ { "AVC", "Auravision Corporation" },
+ { "AVD", "Avid Electronics Corporation" },
+ { "AVE", "Add Value Enterpises (Asia) Pte Ltd" },
+ { "AVI", "Nippon Avionics Co.,Ltd" },
+ { "AVL", "Avalue Technology Inc." },
+ { "AVM", "AVM GmbH" },
+ { "AVN", "Advance Computer Corporation" },
+ { "AVO", "Avocent Corporation" },
+ { "AVR", "AVer Information Inc." },
+ { "AVT", "Avtek (Electronics) Pty Ltd" },
+ { "AVV", "SBS Technologies (Canada), Inc. (was Avvida Systems, Inc.)" },
+ { "AVX", "AVerMedia Technologies, Inc." },
+ { "AWC", "Access Works Comm Inc" },
+ { "AWL", "Aironet Wireless Communications, Inc" },
+ { "AWS", "Wave Systems" },
+ { "AXB", "Adrienne Electronics Corporation" },
+ { "AXC", "AXIOMTEK CO., LTD." },
+ { "AXE", "D-Link Systems Inc" },
+ { "AXI", "American Magnetics" },
+ { "AXL", "Axel" },
+ { "AXO", "Axonic Labs LLC" },
+ { "AXP", "American Express" },
+ { "AXT", "Axtend Technologies Inc" },
+ { "AXX", "Axxon Computer Corporation" },
+ { "AXY", "AXYZ Automation Services, Inc" },
+ { "AYD", "Aydin Displays" },
+ { "AYR", "Airlib, Inc" },
+ { "AZM", "AZ Middelheim - Radiotherapy" },
{ "AZT", "Aztech Systems Ltd" },
- { "CIS", "Cisco Systems Inc" },
- { "DUA", "Dosch & Amand GmbH & Company KG" },
- { "INP", "Interphase Corporation" },
- { "DMS", "DOME imaging systems" },
- { "COW", "Polycow Productions" },
- { "PTC", "PS Technology Corporation" },
- { "PRD", "Praim S.R.L." },
- { "DEC", "Digital Equipment Corporation" },
- { "SMT", "Silcom Manufacturing Tech Inc" },
- { "MII", "Mitec Inc" },
- { "QLC", "Q-Logic" },
- { "PRG", "The Phoenix Research Group Inc" },
- { "LNV", "Lenovo" },
- { "IND", "ILC" },
- { "MXL", "Hitachi Maxell, Ltd." },
- { "DAU", "Daou Tech Inc" },
- { "SNK", "S&K Electronics" },
- { "SYE", "SY Electronics Ltd" },
+ { "BAC", "Biometric Access Corporation" },
+ { "BAN", "Banyan" },
+ { "BBB", "an-najah university" },
+ { "BBH", "B&Bh" },
+ { "BBL", "Brain Boxes Limited" },
{ "BCC", "Beaver Computer Corporaton" },
- { "LPI", "Design Technology" },
- { "CLO", "Clone Computers" },
- { "CMI", "C-Media Electronics" },
- { "ESK", "ES&S" },
- { "HCW", "Hauppauge Computer Works Inc" },
- { "KPC", "King Phoenix Company" },
- { "DXS", "Signet" },
- { "OLY", "OLYMPUS CORPORATION" },
- { "OOS", "OSRAM" },
- { "NOE", "NordicEye AB" },
- { "DXP", "Data Expert Corporation" },
- { "ITP", "IT-PRO Consulting und Systemhaus GmbH" },
- { "MMS", "MMS Electronics" },
- { "FDC", "Future Domain" },
- { "ASM", "ASEM S.p.A." },
- { "AIC", "Arnos Insturments & Computer Systems" },
- { "ANC", "Ancot" },
- { "SEE", "SeeColor Corporation" },
- { "JAS", "Janz Automationssysteme AG" },
- { "TGV", "Grass Valley Germany GmbH" },
- { "LTI", "Jongshine Tech Inc" },
- { "JVC", "JVC" },
- { "TLV", "S3 Inc" },
- { "MGC", "Mentor Graphics Corporation" },
- { "NBS", "National Key Lab. on ISN" },
- { "GTI", "Goldtouch" },
- { "SPI", "SPACE-I Co., Ltd." },
- { "ZNX", "Znyx Adv. Systems" },
- { "EMC", "eMicro Corporation" },
- { "WDE", "Westinghouse Digital Electronics" },
- { "CEN", "Centurion Technologies P/L" },
+ { "BCD", "Barco GmbH" },
+ { "BCM", "Broadcom" },
+ { "BCQ", "Deutsche Telekom Berkom GmbH" },
+ { "BCS", "Booria CAD/CAM systems" },
+ { "BDO", "Brahler ICS" },
+ { "BDR", "Blonder Tongue Labs, Inc." },
+ { "BDS", "Barco Display Systems" },
+ { "BEC", "Elektro Beckhoff GmbH" },
+ { "BEI", "Beckworth Enterprises Inc" },
+ { "BEK", "Beko Elektronik A.S." },
+ { "BEL", "Beltronic Industrieelektronik GmbH" },
+ { "BEO", "Baug & Olufsen" },
{ "BFE", "B.F. Engineering Corporation" },
- { "DTL", "e-Net Inc" },
- { "FTL", "FUJITSU TEN LIMITED" },
- { "HSC", "Hagiwara Sys-Com Company Ltd" },
- { "ECP", "Elecom Company Ltd" },
- { "LJX", "Datalogic Corporation" },
- { "DRC", "Data Ray Corp." },
- { "STM", "SGS Thomson Microelectronics" },
- { "GDT", "Vortex Computersysteme GmbH" },
- { "JSK", "SANKEN ELECTRIC CO., LTD" },
- { "TMC", "Techmedia Computer Systems Corporation" },
- { "CFG", "Atlantis" },
- { "DCO", "Dialogue Technology Corporation" },
- { "NEC", "NEC Corporation" },
- { "SAE", "Saab Aerotech" },
- { "STA", "ST Electronics Systems Assembly Pte Ltd" },
- { "GEO", "GEO Sense" },
- { "SLH", "Silicon Library Inc." },
- { "SAG", "Sedlbauer" },
- { "VEK", "Vektrex" },
- { "ADA", "Addi-Data GmbH" },
- { "NCT", "NEC CustomTechnica, Ltd." },
- { "STX", "ST-Ericsson" },
- { "PRM", "Prometheus" },
- { "DPA", "DigiTalk Pro AV" },
- { "SLF", "StarLeaf" },
- { "AXY", "AXYZ Automation Services, Inc" },
- { "CPX", "Powermatic Data Systems" },
- { "DLL", "Dell Inc" },
- { "PLF", "Panasonic Avionics Corporation" },
- { "FRI", "Fibernet Research Inc" },
- { "BRM", "Braemar Inc" },
- { "MSK", "Megasoft Inc" },
- { "ECT", "Enciris Technologies" },
- { "TKO", "TouchKo, Inc." },
- { "CYC", "Cylink Corporation" },
- { "SMR", "B.& V. s.r.l." },
- { "SRT", "SeeReal Technologies GmbH" },
- { "GES", "GES Singapore Pte Ltd" },
- { "DHT", "Projectavision Inc" },
- { "ESC", "Eden Sistemas de Computacao S/A" },
- { "BYD", "byd:sign corporation" },
+ { "BGB", "Barco Graphics N.V" },
+ { "BGT", "Budzetron Inc" },
+ { "BHZ", "BitHeadz, Inc." },
+ { "BIC", "Big Island Communications" },
+ { "BII", "Boeckeler Instruments Inc" },
+ { "BIL", "Billion Electric Company Ltd" },
+ { "BIO", "BioLink Technologies International, Inc." },
+ { "BIT", "Bit 3 Computer" },
+ { "BLI", "Busicom" },
+ { "BLN", "BioLink Technologies" },
+ { "BLP", "Bloomberg L.P." },
+ { "BMD", "Blackmagic Design" },
{ "BMI", "Benson Medical Instruments Company" },
- { "XSY", "XSYS" },
- { "MYX", "Micronyx Inc" },
- { "OUK", "OUK Company Ltd" },
- { "MPI", "Mediatrix Peripherals Inc" },
+ { "BML", "BIOMED Lab" },
+ { "BMS", "BIOMEDISYS" },
+ { "BNE", "Bull AB" },
+ { "BNK", "Banksia Tech Pty Ltd" },
+ { "BNO", "Bang & Olufsen" },
+ { "BNS", "Boulder Nonlinear Systems" },
+ { "BOB", "Rainy Orchard" },
+ { "BOE", "BOE" },
+ { "BOI", "NINGBO BOIGLE DIGITAL TECHNOLOGY CO.,LTD" },
+ { "BOS", "BOS" },
+ { "BPD", "Micro Solutions, Inc." },
+ { "BPU", "Best Power" },
+ { "BRA", "Braemac Pty Ltd" },
+ { "BRC", "BARC" },
+ { "BRG", "Bridge Information Co., Ltd" },
+ { "BRI", "Boca Research Inc" },
+ { "BRM", "Braemar Inc" },
+ { "BRO", "BROTHER INDUSTRIES,LTD." },
+ { "BSE", "Bose Corporation" },
+ { "BSL", "Biomedical Systems Laboratory" },
+ { "BSN", "BRIGHTSIGN, LLC" },
+ { "BST", "BodySound Technologies, Inc." },
+ { "BTC", "Bit 3 Computer" },
+ { "BTE", "Brilliant Technology" },
+ { "BTF", "Bitfield Oy" },
+ { "BTI", "BusTech Inc" },
+ { "BTO", "BioTao Ltd" },
+ { "BUF", "Yasuhiko Shirai Melco Inc" },
+ { "BUG", "B.U.G., Inc." },
+ { "BUJ", "ATI Tech Inc" },
+ { "BUL", "Bull" },
+ { "BUR", "Bernecker & Rainer Ind-Eletronik GmbH" },
{ "BUS", "BusTek" },
- { "LCN", "LEXICON" },
- { "ADS", "Analog Devices Inc" },
- { "XTL", "Crystal Computer" },
- { "CEF", "Cefar Digital Vision" },
- { "IPP", "IP Power Technologies GmbH" },
- { "CDV", "Convergent Design Inc." },
- { "OLD", "Olidata S.p.A." },
- { "GNN", "GN Nettest Inc" },
- { "ADH", "Aerodata Holdings Ltd" },
- { "IMM", "Immersion Corporation" },
+ { "BUT", "21ST CENTURY ENTERTAINMENT" },
+ { "BWK", "Bitworks Inc." },
+ { "BXE", "Buxco Electronics" },
+ { "BYD", "byd:sign corporation" },
+ { "CAA", "Castles Automation Co., Ltd" },
+ { "CAC", "CA & F Elettronica" },
+ { "CAG", "CalComp" },
+ { "CAI", "Canon Inc." },
+ { "CAL", "Acon" },
+ { "CAM", "Cambridge Audio" },
+ { "CAN", "CORNEA" },
+ { "CAR", "Cardinal Company Ltd" },
+ { "CAS", "CASIO COMPUTER CO.,LTD" },
+ { "CAT", "Consultancy in Advanced Technology" },
+ { "CAV", "Cavium Networks, Inc" },
+ { "CBI", "ComputerBoards Inc" },
+ { "CBR", "Cebra Tech A/S" },
{ "CBT", "Cabletime Ltd" },
- { "RVI", "Realvision Inc" },
- { "HNS", "Hughes Network Systems" },
- { "HAR", "Harris Corporation" },
- { "ACV", "ActivCard S.A" },
- { "RUN", "RUNCO International" },
- { "WDC", "Western Digital" },
- { "SIG", "Sigma Designs Inc" },
- { "PNR", "Planar Systems, Inc." },
- { "PRS", "Leutron Vision" },
- { "KEM", "Kontron Embedded Modules GmbH" },
- { "LAN", "Sodeman Lancom Inc" },
+ { "CBX", "Cybex Computer Products Corporation" },
+ { "CCC", "C-Cube Microsystems" },
+ { "CCI", "Cache" },
+ { "CCJ", "CONTEC CO.,LTD." },
+ { "CCL", "CCL/ITRI" },
+ { "CCP", "Capetronic USA Inc" },
+ { "CDC", "Core Dynamics Corporation" },
+ { "CDD", "Convergent Data Devices" },
+ { "CDE", "Colin.de" },
+ { "CDG", "Christie Digital Systems Inc" },
+ { "CDI", "Concept Development Inc" },
+ { "CDK", "Cray Communications" },
+ { "CDN", "Codenoll Technical Corporation" },
+ { "CDP", "CalComp" },
+ { "CDS", "Computer Diagnostic Systems" },
+ { "CDT", "IBM Corporation" },
+ { "CDV", "Convergent Design Inc." },
+ { "CEA", "Consumer Electronics Association" },
+ { "CEC", "Chicony Electronics Company Ltd" },
+ { "CED", "Cambridge Electronic Design Ltd" },
+ { "CEF", "Cefar Digital Vision" },
+ { "CEI", "Crestron Electronics, Inc." },
{ "CEM", "MEC Electronics GmbH" },
- { "RHD", "RightHand Technologies" },
+ { "CEN", "Centurion Technologies P/L" },
+ { "CEP", "C-DAC" },
+ { "CER", "Ceronix" },
+ { "CET", "TEC CORPORATION" },
+ { "CFG", "Atlantis" },
+ { "CGA", "Chunghwa Picture Tubes, LTD" },
+ { "CGS", "Chyron Corp" },
+ { "CGT", "congatec AG" },
+ { "CHA", "Chase Research PLC" },
+ { "CHC", "Chic Technology Corp." },
+ { "CHD", "ChangHong Electric Co.,Ltd" },
{ "CHE", "Acer Inc" },
- { "POL", "PolyComp (PTY) Ltd." },
- { "MST", "MS Telematica" },
- { "ALA", "Alacron Inc" },
- { "EDI", "Edimax Tech. Company Ltd" },
- { "EGN", "Egenera, Inc." },
- { "PIX", "Pixie Tech Inc" },
- { "AVN", "Advance Computer Corporation" },
- { "CTN", "Computone Products" },
- { "SFM", "TORNADO Company" },
- { "ATA", "Allied Telesyn International (Asia) Pte Ltd" },
- { "SIA", "SIEMENS AG" },
- { "NAV", "Navigation Corporation" },
- { "PRF", "Digital Electronics Corporation" },
- { "HRE", "Qingdao Haier Electronics Co., Ltd." },
- { "NAC", "Ncast Corporation" },
- { "ELM", "Elmic Systems Inc" },
- { "HYR", "Hypertec Pty Ltd" },
- { "EMB", "Embedded computing inc ltd" },
- { "MWR", "mware" },
- { "KGL", "KEISOKU GIKEN Co.,Ltd." },
- { "NRL", "U.S. Naval Research Lab" },
- { "TNM", "TECNIMAGEN SA" },
- { "GTT", "General Touch Technology Co., Ltd." },
- { "BTE", "Brilliant Technology" },
- { "KDS", "KDS USA" },
- { "EEP", "E.E.P.D. GmbH" },
- { "NCI", "NewCom Inc" },
+ { "CHG", "Sichuan Changhong Electric CO, LTD." },
+ { "CHI", "Chrontel Inc" },
+ { "CHL", "Chloride-R&D" },
+ { "CHM", "CHIC TECHNOLOGY CORP." },
+ { "CHO", "Sichuang Changhong Corporation" },
+ { "CHP", "CH Products" },
+ { "CHS", "Agentur Chairos" },
+ { "CHT", "Chunghwa Picture Tubes,LTD." },
+ { "CHY", "Cherry GmbH" },
+ { "CIC", "Comm. Intelligence Corporation" },
+ { "CII", "Cromack Industries Inc" },
+ { "CIL", "Citicom Infotech Private Limited" },
+ { "CIN", "Citron GmbH" },
{ "CIP", "Ciprico Inc" },
- { "RTL", "Realtek Semiconductor Company Ltd" },
- { "MUK", "mainpine limited" },
- { "SLX", "Specialix" },
- { "HCM", "HCL Peripherals" },
- { "CHA", "Chase Research PLC" },
- { "VOB", "MaxData Computer AG" },
- { "ANK", "Anko Electronic Company Ltd" },
- { "FWR", "Flat Connections Inc" },
- { "DXL", "Dextera Labs Inc" },
- { "QVU", "Quartics" },
- { "MPS", "mps Software GmbH" },
- { "AVM", "AVM GmbH" },
- { "TDY", "Tandy Electronics" },
- { "MJS", "MJS Designs" },
- { "SNC", "Sentronic International Corp." },
- { "IPT", "International Power Technologies" },
- { "API", "A Plus Info Corporation" },
- { "TLT", "Dai Telecom S.p.A." },
- { "PCC", "PowerCom Technology Company Ltd" },
- { "TRM", "Tekram Technology Company Ltd" },
- { "DEL", "Dell Inc." },
- { "CYW", "Cyberware" },
- { "TDS", "Tri-Data Systems Inc" },
- { "FPE", "Fujitsu Peripherals Ltd" },
- { "SPN", "Sapience Corporation" },
+ { "CIR", "Cirrus Logic Inc" },
+ { "CIS", "Cisco Systems Inc" },
+ { "CIT", "Citifax Limited" },
+ { "CKC", "The Concept Keyboard Company Ltd" },
+ { "CKJ", "Carina System Co., Ltd." },
+ { "CLA", "Clarion Company Ltd" },
+ { "CLD", "COMMAT L.t.d." },
+ { "CLE", "Classe Audio" },
+ { "CLG", "CoreLogic" },
+ { "CLI", "Cirrus Logic Inc" },
+ { "CLM", "CrystaLake Multimedia" },
+ { "CLO", "Clone Computers" },
+ { "CLT", "automated computer control systems" },
+ { "CLV", "Clevo Company" },
+ { "CLX", "CardLogix" },
+ { "CMC", "CMC Ltd" },
+ { "CMD", "Colorado MicroDisplay, Inc." },
+ { "CMG", "Chenming Mold Ind. Corp." },
+ { "CMI", "C-Media Electronics" },
+ { "CMM", "Comtime GmbH" },
+ { "CMN", "Chimei Innolux Corporation" },
+ { "CMO", "Chi Mei Optoelectronics corp." },
+ { "CMR", "Cambridge Research Systems Ltd" },
+ { "CMS", "CompuMaster Srl" },
+ { "CMX", "Comex Electronics AB" },
+ { "CNB", "American Power Conversion" },
+ { "CNC", "Alvedon Computers Ltd" },
+ { "CNE", "Cine-tal" },
+ { "CNI", "Connect Int'l A/S" },
+ { "CNN", "Canon Inc" },
+ { "CNT", "COINT Multimedia Systems" },
+ { "COB", "COBY Electronics Co., Ltd" },
+ { "COD", "CODAN Pty. Ltd." },
+ { "COI", "Codec Inc." },
+ { "COL", "Rockwell Collins, Inc." },
+ { "COM", "Comtrol Corporation" },
+ { "CON", "Contec Company Ltd" },
+ { "COO", "coolux GmbH" },
+ { "COR", "Corollary Inc" },
+ { "COS", "CoStar Corporation" },
+ { "COT", "Core Technology Inc" },
+ { "COW", "Polycow Productions" },
{ "COX", "Comrex" },
- { "STE", "SII Ido-Tsushin Inc" },
- { "RVC", "RSI Systems Inc" },
- { "HMK", "hmk Daten-System-Technik BmbH" },
- { "TTA", "Topson Technology Co., Ltd." },
+ { "CPC", "Ciprico Inc" },
+ { "CPD", "CompuAdd" },
+ { "CPI", "Computer Peripherals Inc" },
+ { "CPL", "Compal Electronics Inc" },
+ { "CPM", "Capella Microsystems Inc." },
+ { "CPQ", "Compaq Computer Company" },
+ { "CPT", "cPATH" },
+ { "CPX", "Powermatic Data Systems" },
+ { "CRC", "CONRAC GmbH" },
+ { "CRD", "Cardinal Technical Inc" },
+ { "CRE", "Creative Labs Inc" },
+ { "CRI", "Crio Inc." },
+ { "CRL", "Creative Logic" },
+ { "CRN", "Cornerstone Imaging" },
+ { "CRO", "Extraordinary Technologies PTY Limited" },
+ { "CRQ", "Cirque Corporation" },
+ { "CRS", "Crescendo Communication Inc" },
+ { "CRV", "Cerevo Inc." },
+ { "CRX", "Cyrix Corporation" },
+ { "CSB", "Transtex SA" },
+ { "CSC", "Crystal Semiconductor" },
+ { "CSD", "Cresta Systems Inc" },
+ { "CSE", "Concept Solutions & Engineering" },
+ { "CSI", "Cabletron System Inc" },
{ "CSM", "Cosmic Engineering Inc." },
- { "PTL", "Pantel Inc" },
- { "EQX", "Equinox Systems Inc" },
- { "HEL", "Hitachi Micro Systems Europe Ltd" },
- { "TIX", "Tixi.Com GmbH" },
- { "CMD", "Colorado MicroDisplay, Inc." },
- { "VIS", "Visioneer" },
- { "MTH", "Micro-Tech Hearing Instruments" },
- { "ISR", "INSIS Co., LTD." },
- { "EME", "EMiNE TECHNOLOGY COMPANY, LTD." },
- { "DMT", "Distributed Management Task Force, Inc. (DMTF)" },
- { "JFX", "Jones Futurex Inc" },
- { "SMB", "Schlumberger" },
- { "GTM", "Garnet System Company Ltd" },
+ { "CSO", "California Institute of Technology" },
+ { "CSS", "CSS Laboratories" },
+ { "CST", "CSTI Inc" },
+ { "CTA", "CoSystems Inc" },
+ { "CTC", "CTC Communication Development Company Ltd" },
+ { "CTE", "Chunghwa Telecom Co., Ltd." },
+ { "CTL", "Creative Technology Ltd" },
+ { "CTM", "Computerm Corporation" },
+ { "CTN", "Computone Products" },
+ { "CTP", "Computer Technology Corporation" },
+ { "CTS", "Comtec Systems Co., Ltd." },
+ { "CTX", "Creatix Polymedia GmbH" },
+ { "CUB", "Cubix Corporation" },
+ { "CUK", "Calibre UK Ltd" },
+ { "CVA", "Covia Inc." },
+ { "CVI", "Colorado Video, Inc." },
+ { "CVS", "Clarity Visual Systems" },
+ { "CWR", "Connectware Inc" },
+ { "CXT", "Conexant Systems" },
+ { "CYB", "CyberVision" },
+ { "CYC", "Cylink Corporation" },
+ { "CYD", "Cyclades Corporation" },
+ { "CYL", "Cyberlabs" },
+ { "CYT", "Cytechinfo Inc" },
+ { "CYV", "Cyviz AS" },
+ { "CYW", "Cyberware" },
+ { "CYX", "Cyrix Corporation" },
+ { "CZE", "Carl Zeiss AG" },
+ { "DAC", "Digital Acoustics Corporation" },
+ { "DAE", "Digatron Industrie Elektronik GmbH" },
+ { "DAI", "DAIS SET Ltd." },
+ { "DAK", "Daktronics" },
+ { "DAL", "Digital Audio Labs Inc" },
+ { "DAN", "Danelec Marine A/S" },
+ { "DAS", "DAVIS AS" },
+ { "DAT", "Datel Inc" },
+ { "DAU", "Daou Tech Inc" },
+ { "DAV", "Davicom Semiconductor Inc" },
+ { "DAW", "DA2 Technologies Inc" },
+ { "DAX", "Data Apex Ltd" },
+ { "DBD", "Diebold Inc." },
+ { "DBI", "DigiBoard Inc" },
{ "DBK", "Databook Inc" },
- { "IQT", "IMAGEQUEST Co., Ltd" },
+ { "DBL", "Doble Engineering Company" },
+ { "DBN", "DB Networks Inc" },
+ { "DCA", "Digital Communications Association" },
+ { "DCC", "Dale Computer Corporation" },
+ { "DCD", "Datacast LLC" },
+ { "DCE", "dSPACE GmbH" },
+ { "DCI", "Concepts Inc" },
+ { "DCL", "Dynamic Controls Ltd" },
+ { "DCM", "DCM Data Products" },
+ { "DCO", "Dialogue Technology Corporation" },
+ { "DCR", "Decros Ltd" },
+ { "DCS", "Diamond Computer Systems Inc" },
+ { "DCT", "Dancall Telecom A/S" },
+ { "DCV", "Datatronics Technology Inc" },
+ { "DDA", "DA2 Technologies Corporation" },
+ { "DDD", "Danka Data Devices" },
+ { "DDE", "Datasat Digital Entertainment" },
+ { "DDI", "Data Display AG" },
+ { "DDS", "Barco, n.v." },
+ { "DDT", "Datadesk Technologies Inc" },
+ { "DDV", "Delta Information Systems, Inc" },
+ { "DEC", "Digital Equipment Corporation" },
+ { "DEI", "Deico Electronics" },
+ { "DEL", "Dell Inc." },
+ { "DEN", "Densitron Computers Ltd" },
+ { "DEX", "idex displays" },
+ { "DFI", "DFI" },
+ { "DFK", "SharkTec A/S" },
+ { "DFT", "DEI Holdings dba Definitive Technology" },
+ { "DGA", "Digiital Arts Inc" },
+ { "DGC", "Data General Corporation" },
+ { "DGI", "DIGI International" },
+ { "DGK", "DugoTech Co., LTD" },
+ { "DGP", "Digicorp European sales S.A." },
+ { "DGS", "Diagsoft Inc" },
+ { "DGT", "The Dearborn Group" },
+ { "DHP", "DH Print" },
+ { "DHQ", "Quadram" },
+ { "DHT", "Projectavision Inc" },
+ { "DIA", "Diadem" },
+ { "DIG", "Digicom S.p.A." },
+ { "DII", "Dataq Instruments Inc" },
+ { "DIM", "dPict Imaging, Inc." },
+ { "DIN", "Daintelecom Co., Ltd" },
+ { "DIS", "Diseda S.A." },
+ { "DIT", "Dragon Information Technology" },
+ { "DJE", "Capstone Visual Product Development" },
+ { "DJP", "Maygay Machines, Ltd" },
+ { "DKY", "Datakey Inc" },
+ { "DLB", "Dolby Laboratories Inc." },
+ { "DLC", "Diamond Lane Comm. Corporation" },
+ { "DLG", "Digital-Logic GmbH" },
+ { "DLK", "D-Link Systems Inc" },
+ { "DLL", "Dell Inc" },
+ { "DLT", "Digitelec Informatique Park Cadera" },
+ { "DMB", "Digicom Systems Inc" },
+ { "DMC", "Dune Microsystems Corporation" },
+ { "DMM", "Dimond Multimedia Systems Inc" },
+ { "DMP", "D&M Holdings Inc, Professional Business Company" },
+ { "DMS", "DOME imaging systems" },
+ { "DMT", "Distributed Management Task Force, Inc. (DMTF)" },
+ { "DMV", "NDS Ltd" },
+ { "DNA", "DNA Enterprises, Inc." },
+ { "DNG", "Apache Micro Peripherals Inc" },
+ { "DNI", "Deterministic Networks Inc." },
+ { "DNT", "Dr. Neuhous Telekommunikation GmbH" },
+ { "DNV", "DiCon" },
+ { "DOL", "Dolman Technologies Group Inc" },
+ { "DOM", "Dome Imaging Systems" },
+ { "DON", "DENON, Ltd." },
+ { "DOT", "Dotronic Mikroelektronik GmbH" },
+ { "DPA", "DigiTalk Pro AV" },
+ { "DPC", "Delta Electronics Inc" },
+ { "DPI", "DocuPoint" },
+ { "DPL", "Digital Projection Limited" },
+ { "DPM", "ADPM Synthesis sas" },
+ { "DPS", "Digital Processing Systems" },
+ { "DPT", "DPT" },
+ { "DPX", "DpiX, Inc." },
+ { "DQB", "Datacube Inc" },
+ { "DRB", "Dr. Bott KG" },
+ { "DRC", "Data Ray Corp." },
+ { "DRD", "DIGITAL REFLECTION INC." },
+ { "DRI", "Data Race Inc" },
+ { "DRS", "DRS Defense Solutions, LLC" },
+ { "DSD", "DS Multimedia Pte Ltd" },
+ { "DSI", "Digitan Systems Inc" },
+ { "DSM", "DSM Digital Services GmbH" },
+ { "DSP", "Domain Technology Inc" },
+ { "DTA", "DELTATEC" },
+ { "DTC", "DTC Tech Corporation" },
+ { "DTE", "Dimension Technologies, Inc." },
+ { "DTI", "Diversified Technology, Inc." },
+ { "DTK", "Dynax Electronics (HK) Ltd" },
+ { "DTL", "e-Net Inc" },
+ { "DTN", "Datang Telephone Co" },
+ { "DTO", "Deutsche Thomson OHG" },
+ { "DTT", "Design & Test Technology, Inc." },
{ "DTX", "Data Translation" },
- { "QSI", "Quantum Solutions, Inc." },
- { "BEL", "Beltronic Industrieelektronik GmbH" },
- { "PJT", "Pan Jit International Inc." },
- { "WST", "Wistron Corporation" },
- { "ASN", "Asante Tech Inc" },
- { "ROS", "Rohde & Schwarz" },
- { "NWP", "NovaWeb Technologies Inc" },
- { "CLG", "CoreLogic" },
+ { "DUA", "Dosch & Amand GmbH & Company KG" },
+ { "DUN", "NCR Corporation" },
+ { "DVD", "Dictaphone Corporation" },
+ { "DVL", "Devolo AG" },
+ { "DVS", "Digital Video System" },
+ { "DVT", "Data Video" },
+ { "DWE", "Daewoo Electronics Company Ltd" },
+ { "DXC", "Digipronix Control Systems" },
+ { "DXD", "DECIMATOR DESIGN PTY LTD" },
+ { "DXL", "Dextera Labs Inc" },
+ { "DXP", "Data Expert Corporation" },
+ { "DXS", "Signet" },
+ { "DYC", "Dycam Inc" },
+ { "DYM", "Dymo-CoStar Corporation" },
+ { "DYN", "Askey Computer Corporation" },
+ { "DYX", "Dynax Electronics (HK) Ltd" },
+ { "EAS", "Evans and Sutherland Computer" },
+ { "EBH", "Data Price Informatica" },
+ { "EBT", "HUALONG TECHNOLOGY CO., LTD" },
+ { "ECA", "Electro Cam Corp." },
+ { "ECC", "ESSential Comm. Corporation" },
+ { "ECI", "Enciris Technologies" },
+ { "ECK", "Eugene Chukhlomin Sole Proprietorship, d.b.a." },
+ { "ECL", "Excel Company Ltd" },
+ { "ECM", "E-Cmos Tech Corporation" },
+ { "ECO", "Echo Speech Corporation" },
+ { "ECP", "Elecom Company Ltd" },
{ "ECS", "Elitegroup Computer Systems Company Ltd" },
- { "PER", "Perceptive Signal Technologies" },
- { "SPR", "pmns GmbH" },
- { "DLB", "Dolby Laboratories Inc." },
- { "SRF", "Surf Communication Solutions Ltd" },
- { "ATM", "ATM Ltd" },
- { "MED", "Messeltronik Dresden GmbH" },
- { "SGD", "Sigma Designs, Inc." },
- { "RJA", "Roland Corporation" },
+ { "ECT", "Enciris Technologies" },
{ "EDC", "e.Digital Corporation" },
- { "CON", "Contec Company Ltd" },
- { "CCJ", "CONTEC CO.,LTD." },
- { "GVC", "GVC Corporation" },
- { "TRI", "Tricord Systems" },
- { "SLB", "Shlumberger Ltd" },
- { "PRO", "Proteon" },
- { "DSI", "Digitan Systems Inc" },
- { "SDF", "SODIFF E&T CO., Ltd." },
- { "VDC", "VDC Display Systems" },
- { "PSL", "Perle Systems Limited" },
- { "SCR", "Systran Corporation" },
- { "DEX", "idex displays" },
- { "CDS", "Computer Diagnostic Systems" },
- { "RAY", "Raylar Design, Inc." },
- { "MMF", "Minnesota Mining and Manufacturing" },
- { "MMA", "Micromedia AG" },
- { "FUS", "Fujitsu Siemens Computers GmbH" },
+ { "EDG", "Electronic-Design GmbH" },
+ { "EDI", "Edimax Tech. Company Ltd" },
+ { "EDM", "EDMI" },
+ { "EDT", "Emerging Display Technologies Corp" },
+ { "EEE", "ET&T Technology Company Ltd" },
+ { "EEH", "EEH Datalink GmbH" },
+ { "EEP", "E.E.P.D. GmbH" },
+ { "EES", "EE Solutions, Inc." },
+ { "EGA", "Elgato Systems LLC" },
+ { "EGD", "EIZO GmbH Display Technologies" },
+ { "EGL", "Eagle Technology" },
+ { "EGN", "Egenera, Inc." },
+ { "EGO", "Ergo Electronics" },
+ { "EHJ", "Epson Research" },
+ { "EHN", "Enhansoft" },
+ { "EIC", "Eicon Technology Corporation" },
+ { "EKA", "MagTek Inc." },
+ { "EKC", "Eastman Kodak Company" },
+ { "EKS", "EKSEN YAZILIM" },
+ { "ELA", "ELAD srl" },
+ { "ELC", "Electro Scientific Ind" },
+ { "ELE", "Elecom Company Ltd" },
+ { "ELG", "Elmeg GmbH Kommunikationstechnik" },
+ { "ELI", "Edsun Laboratories" },
+ { "ELL", "Electrosonic Ltd" },
+ { "ELM", "Elmic Systems Inc" },
+ { "ELO", "Tyco Electronics" },
+ { "ELS", "ELSA GmbH" },
+ { "ELT", "Element Labs, Inc." },
+ { "ELX", "Elonex PLC" },
+ { "EMB", "Embedded computing inc ltd" },
+ { "EMC", "eMicro Corporation" },
+ { "EME", "EMiNE TECHNOLOGY COMPANY, LTD." },
+ { "EMG", "EMG Consultants Inc" },
+ { "EMI", "Ex Machina Inc" },
+ { "EMK", "Emcore Corporation" },
+ { "EMO", "ELMO COMPANY, LIMITED" },
+ { "EMU", "Emulex Corporation" },
+ { "ENC", "Eizo Nanao Corporation" },
+ { "END", "ENIDAN Technologies Ltd" },
+ { "ENE", "ENE Technology Inc." },
+ { "ENI", "Efficient Networks" },
+ { "ENS", "Ensoniq Corporation" },
+ { "ENT", "Enterprise Comm. & Computing Inc" },
+ { "EPC", "Empac" },
+ { "EPH", "Epiphan Systems Inc." },
+ { "EPI", "Envision Peripherals, Inc" },
+ { "EPN", "EPiCON Inc." },
+ { "EPS", "KEPS" },
+ { "EQP", "Equipe Electronics Ltd." },
+ { "EQX", "Equinox Systems Inc" },
+ { "ERG", "Ergo System" },
+ { "ERI", "Ericsson Mobile Communications AB" },
+ { "ERN", "Ericsson, Inc." },
+ { "ERP", "Euraplan GmbH" },
+ { "ERT", "Escort Insturments Corporation" },
+ { "ESA", "Elbit Systems of America" },
+ { "ESC", "Eden Sistemas de Computacao S/A" },
+ { "ESD", "Ensemble Designs, Inc" },
+ { "ESG", "ELCON Systemtechnik GmbH" },
+ { "ESI", "Extended Systems, Inc." },
+ { "ESK", "ES&S" },
+ { "ESL", "Esterline Technologies" },
+ { "ESN", "eSATURNUS" },
{ "ESS", "ESS Technology Inc" },
- { "SIX", "Zuniq Data Corporation" },
- { "ISS", "ISS Inc" },
- { "PFT", "Telia ProSoft AB" },
- { "SOL", "Solitron Technologies Inc" },
- { "ZTM", "ZT Group Int'l Inc." },
- { "GZE", "GUNZE Limited" },
- { "CHS", "Agentur Chairos" },
- { "CBI", "ComputerBoards Inc" },
- { "DTA", "DELTATEC" },
- { "CSC", "Crystal Semiconductor" },
- { "MPC", "M-Pact Inc" },
- { "HHI", "Fraunhofer Heinrich-Hertz-Institute" },
- { "BIT", "Bit 3 Computer" },
- { "ICP", "ICP Electronics, Inc./iEi Technology Corp." },
- { "FOA", "FOR-A Company Limited" },
- { "NWC", "NW Computer Engineering" },
- { "MRO", "Medikro Oy" },
- { "IDT", "International Display Technology" },
- { "NMV", "NEC-Mitsubishi Electric Visual Systems Corporation" },
- { "COT", "Core Technology Inc" },
- { "PEL", "Primax Electric Ltd" },
- { "ZMZ", "Z Microsystems" },
- { "TYN", "Tyan Computer Corporation" },
- { "DIN", "Daintelecom Co., Ltd" },
- { "QTH", "Questech Ltd" },
- { "CYL", "Cyberlabs" },
- { "DGC", "Data General Corporation" },
- { "PPM", "Clinton Electronics Corp." },
- { "ITD", "Internet Technology Corporation" },
- { "MMM", "Electronic Measurements" },
- { "CMM", "Comtime GmbH" },
- { "NDC", "National DataComm Corporaiton" },
- { "TAS", "Taskit Rechnertechnik GmbH" },
- { "MFR", "MediaFire Corp." },
- { "HIC", "Hitachi Information Technology Co., Ltd." },
- { "CMC", "CMC Ltd" },
- { "TSE", "Tottori Sanyo Electric" },
- { "TMR", "Taicom International Inc" },
- { "SIE", "Siemens" },
- { "IMD", "ImasDe Canarias S.A." },
- { "SCE", "Sun Corporation" },
- { "PJD", "Projectiondesign AS" },
- { "VML", "Vine Micros Limited" },
+ { "EST", "Embedded Solution Technology" },
+ { "ESY", "E-Systems Inc" },
+ { "ETC", "Everton Technology Company Ltd" },
+ { "ETD", "ELAN MICROELECTRONICS CORPORATION" },
+ { "ETH", "Etherboot Project" },
+ { "ETI", "Eclipse Tech Inc" },
+ { "ETK", "eTEK Labs Inc." },
{ "ETL", "Evertz Microsystems Ltd." },
- { "MAZ", "MAZeT GmbH" },
- { "UNC", "Unisys Corporation" },
- { "MEG", "Abeam Tech Ltd" },
- { "FCS", "Focus Enhancements, Inc." },
- { "MDV", "MET Development Inc" },
- { "GLD", "Goldmund - Digital Audio SA" },
- { "MRC", "Marconi Simulation & Ty-Coch Way Training" },
- { "FEC", "FURUNO ELECTRIC CO., LTD." },
- { "ALR", "Advanced Logic" },
- { "AEJ", "Alpha Electronics Company" },
- { "QCC", "QuakeCom Company Ltd" },
- { "TDK", "TDK USA Corporation" },
- { "TKN", "Teknor Microsystem Inc" },
- { "FMC", "Ford Microelectronics Inc" },
- { "KTI", "Konica Technical Inc" },
- { "AEI", "Actiontec Electric Inc" },
- { "TGI", "TriGem Computer Inc" },
- { "HIL", "Hilevel Technology" },
- { "WNI", "WillNet Inc." },
- { "FTI", "FastPoint Technologies, Inc." },
- { "ASU", "Asuscom Network Inc" },
- { "MEJ", "Mac-Eight Co., LTD." },
- { "SLS", "Schnick-Schnack-Systems GmbH" },
- { "SXG", "SELEX GALILEO" },
+ { "ETS", "Electronic Trade Solutions Ltd" },
+ { "ETT", "E-Tech Inc" },
+ { "EUT", "Ericsson Mobile Networks B.V." },
+ { "EVE", "Advanced Micro Peripherals Ltd" },
+ { "EVI", "eviateg GmbH" },
+ { "EVX", "Everex" },
+ { "EXA", "Exabyte" },
+ { "EXC", "Excession Audio" },
+ { "EXI", "Exide Electronics" },
+ { "EXN", "RGB Systems, Inc. dba Extron Electronics" },
{ "EXP", "Data Export Corporation" },
- { "TPR", "Topro Technology Inc" },
- { "RCE", "Parc d'Activite des Bellevues" },
- { "VIK", "Viking Connectors" },
- { "TGS", "Torus Systems Ltd" },
- { "IDO", "IDEO Product Development" },
- { "MCE", "Metz-Werke GmbH & Co KG" },
- { "PHC", "Pijnenburg Beheer N.V." },
- { "BTF", "Bitfield Oy" },
- { "MCD", "McDATA Corporation" },
+ { "EXT", "Exatech Computadores & Servicos Ltda" },
+ { "EXX", "Exxact GmbH" },
{ "EXY", "Exterity Ltd" },
- { "ZTI", "Zoom Telephonics Inc" },
- { "MTI", "Motorola Inc." },
- { "ONK", "ONKYO Corporation" },
- { "SEC", "Seiko Epson Corporation" },
- { "TTB", "National Semiconductor Japan Ltd" },
- { "SNO", "SINOSUN TECHNOLOGY CO., LTD" },
- { "SHG", "Soft & Hardware development Goldammer GmbH" },
- { "GEM", "Gem Plus" },
- { "BOS", "BOS" },
- { "SAK", "Saitek Ltd" },
- { "CNE", "Cine-tal" },
- { "BOB", "Rainy Orchard" },
- { "UNF", "Unisys Corporation" },
- { "MCG", "Motorola Computer Group" },
- { "RTC", "Relia Technologies" },
- { "ASD", "USC Information Sciences Institute" },
- { "BMS", "BIOMEDISYS" },
- { "LPE", "El-PUSK Co., Ltd." },
- { "CTA", "CoSystems Inc" },
- { "SVI", "Sun Microsystems" },
- { "PCS", "TOSHIBA PERSONAL COMPUTER SYSTEM CORPRATION" },
- { "GEN", "Genesys ATE Inc" },
- { "CRI", "Crio Inc." },
- { "TOG", "The OPEN Group" },
- { "SYT", "Seyeon Tech Company Ltd" },
- { "CRE", "Creative Labs Inc" },
- { "ALK", "Acrolink Inc" },
- { "TNC", "TNC Industrial Company Ltd" },
- { "PLV", "PLUS Vision Corp." },
- { "CCL", "CCL/ITRI" },
- { "PLY", "Polycom Inc." },
- { "RMC", "Raritan Computer, Inc" },
- { "XRC", "Xircom Inc" },
- { "BRC", "BARC" },
- { "CUK", "Calibre UK Ltd" },
- { "KME", "KIMIN Electronics Co., Ltd." },
- { "TBS", "Turtle Beach System" },
- { "ASY", "Rockwell Collins / Airshow Systems" },
- { "ALV", "AlphaView LCD" },
- { "VSD", "3M" },
- { "MTN", "Mtron Storage Technology Co., Ltd." },
- { "LMG", "Lucent Technologies" },
- { "HWP", "Hewlett Packard" },
- { "UEG", "Elitegroup Computer Systems Company Ltd" },
- { "FIC", "Formosa Industrial Computing Inc" },
- { "CRV", "Cerevo Inc." },
- { "AIL", "Altos India Ltd" },
- { "EMI", "Ex Machina Inc" },
- { "DPC", "Delta Electronics Inc" },
- { "ADN", "Analog & Digital Devices Tel. Inc" },
- { "LGC", "Logic Ltd" },
- { "DMP", "D&M Holdings Inc, Professional Business Company" },
- { "CEC", "Chicony Electronics Company Ltd" },
- { "BTC", "Bit 3 Computer" },
- { "IWX", "Intelliworxx, Inc." },
- { "SML", "Sumitomo Metal Industries, Ltd." },
- { "JWY", "Jetway Information Co., Ltd" },
- { "OMC", "OBJIX Multimedia Corporation" },
- { "CIT", "Citifax Limited" },
- { "AOE", "Advanced Optics Electronics, Inc." },
- { "SYC", "Sysmic" },
- { "ZTT", "Z3 Technology" },
- { "LCS", "Longshine Electronics Company" },
- { "NXQ", "Nexiq Technologies, Inc." },
- { "PSY", "Prodea Systems Inc." },
- { "CUB", "Cubix Corporation" },
- { "JWL", "Jewell Instruments, LLC" },
- { "SUB", "Subspace Comm. Inc" },
- { "PTG", "Cipher Systems Inc" },
- { "TON", "TONNA" },
- { "VBR", "VBrick Systems Inc." },
- { "RTI", "Rancho Tech Inc" },
- { "IMG", "IMAGENICS Co., Ltd." },
- { "AEP", "Aetas Peripheral International" },
- { "PTH", "Pathlight Technology Inc" },
- { "ZYX", "Zyxel" },
- { "NXP", "NXP Semiconductors bv." },
- { "OYO", "Shadow Systems" },
- { "PVM", "Penta Studiotechnik GmbH" },
- { "AVC", "Auravision Corporation" },
- { "SYM", "Symicron Computer Communications Ltd." },
- { "AVI", "Nippon Avionics Co.,Ltd" },
{ "EYE", "eyevis GmbH" },
- { "PLM", "PROLINK Microsystems Corp." },
- { "NFC", "BTC Korea Co., Ltd" },
- { "PIE", "Pacific Image Electronics Company Ltd" },
- { "SRC", "Integrated Tech Express Inc" },
- { "CMX", "Comex Electronics AB" },
- { "OPP", "OPPO Digital, Inc." },
- { "GAL", "Galil Motion Control" },
- { "YHW", "Exacom SA" },
- { "SSD", "FlightSafety International" },
- { "FSC", "Future Systems Consulting KK" },
- { "HRI", "Hall Research" },
- { "PSA", "Advanced Signal Processing Technologies" },
- { "MSI", "Microstep" },
- { "IMI", "International Microsystems Inc" },
- { "IDX", "IDEXX Labs" },
- { "SCO", "SORCUS Computer GmbH" },
- { "DIS", "Diseda S.A." },
- { "SVA", "SGEG" },
- { "SMA", "SMART Modular Technologies" },
- { "SXL", "SolutionInside" },
- { "WRC", "WiNRADiO Communications" },
- { "NIT", "Network Info Technology" },
- { "EKS", "EKSEN YAZILIM" },
- { "GEF", "GE Fanuc Embedded Systems" },
- { "DEI", "Deico Electronics" },
- { "DCD", "Datacast LLC" },
- { "MEE", "Mitsubishi Electric Engineering Co., Ltd." },
- { "LSC", "LifeSize Communications" },
- { "PDV", "Prodrive B.V." },
- { "HIB", "Hibino Corporation" },
- { "SKT", "Samsung Electro-Mechanics Company Ltd" },
- { "SAN", "Sanyo Electric Co.,Ltd." },
- { "RCO", "Rockwell Collins" },
- { "SNY", "Sony" },
- { "ANR", "ANR Ltd" },
- { "DKY", "Datakey Inc" },
- { "OPC", "Opcode Inc" },
- { "TBC", "Turbo Communication, Inc" },
- { "CNT", "COINT Multimedia Systems" },
- { "HDC", "HardCom Elektronik & Datateknik" },
- { "UNB", "Unisys Corporation" },
- { "IOD", "I-O Data Device Inc" },
- { "APR", "Aprilia s.p.a." },
- { "AXX", "Axxon Computer Corporation" },
- { "AED", "Advanced Electronic Designs, Inc." },
- { "MTX", "Matrox" },
- { "TAX", "Taxan (Europe) Ltd" },
- { "TVS", "TVS Electronics Limited" },
- { "CZE", "Carl Zeiss AG" },
- { "SMI", "SpaceLabs Medical Inc" },
+ { "EZE", "EzE Technologies" },
+ { "EZP", "Storm Technology" },
+ { "FAR", "Farallon Computing" },
+ { "FBI", "Interface Corporation" },
{ "FCB", "Furukawa Electric Company Ltd" },
- { "AXP", "American Express" },
- { "FST", "Modesto PC Inc" },
- { "PSI", "PSI-Perceptive Solutions Inc" },
- { "MCR", "Marina Communicaitons" },
- { "JCE", "Jace Tech Inc" },
- { "GRE", "GOLD RAIN ENTERPRISES CORP." },
- { "SYN", "Synaptics Inc" },
- { "MBC", "MBC" },
- { "SIB", "Sanyo Electric Company Ltd" },
- { "TCT", "Telecom Technology Centre Co. Ltd." },
- { "BIC", "Big Island Communications" },
- { "UNI", "Unisys Corporation" },
- { "ELX", "Elonex PLC" },
- { "ZDS", "Zenith Data Systems" },
- { "XLX", "Xilinx, Inc." },
- { "MIC", "Micom Communications Inc" },
- { "SEB", "system elektronik GmbH" },
- { "WIN", "Wintop Technology Inc" },
- { "CDG", "Christie Digital Systems Inc" },
- { "HUB", "GAI-Tronics, A Hubbell Company" },
- { "CSE", "Concept Solutions & Engineering" },
- { "SUR", "Surenam Computer Corporation" },
- { "VTM", "Miltope Corporation" },
- { "ATK", "Allied Telesyn Int'l" },
- { "MGT", "Megatech R & D Company" },
- { "SLK", "Silitek Corporation" },
- { "DYN", "Askey Computer Corporation" },
- { "KEY", "Key Tech Inc" },
- { "DVD", "Dictaphone Corporation" },
- { "OTT", "OPTO22, Inc." },
- { "TCI", "Tulip Computers Int'l B.V." },
- { "ACB", "Aculab Ltd" },
- { "PAD", "Promotion and Display Technology Ltd." },
- { "CMG", "Chenming Mold Ind. Corp." },
- { "UJR", "Ueda Japan Radio Co., Ltd." },
- { "LHA", "Lars Haagh ApS" },
- { "SIM", "S3 Inc" },
- { "TPC", "Touch Panel Systems Corporation" },
- { "TVD", "Tecnovision" },
- { "FZI", "FZI Forschungszentrum Informatik" },
- { "AIW", "Aiwa Company Ltd" },
- { "LTW", "Lightware, Inc" },
- { "DSP", "Domain Technology Inc" },
- { "ILS", "Innotech Corporation" },
- { "VDM", "Vadem" },
- { "KYK", "Samsung Electronics America Inc" },
- { "NTW", "Networth Inc" },
- { "SID", "Seiko Instruments Information Devices Inc" },
- { "MRT", "Merging Technologies" },
- { "MGL", "M-G Technology Ltd" },
- { "UBL", "Ubinetics Ltd." },
- { "PSM", "Prosum" },
- { "MDR", "Medar Inc" },
- { "STN", "Samsung Electronics America" },
- { "NCR", "NCR Electronics" },
- { "INU", "Inovatec S.p.A." },
- { "WAL", "Wave Access" },
- { "BLN", "BioLink Technologies" },
- { "RXT", "Tectona SoftSolutions (P) Ltd.," },
- { "MRL", "Miratel" },
- { "ZAZ", "Zazzle Technologies" },
- { "NIC", "National Instruments Corporation" },
- { "FMZ", "Formoza-Altair" },
- { "MDG", "Madge Networks" },
- { "VIA", "VIA Tech Inc" },
- { "KOD", "Eastman Kodak Company" },
- { "SAI", "Sage Inc" },
+ { "FCG", "First International Computer Ltd" },
+ { "FCS", "Focus Enhancements, Inc." },
+ { "FDC", "Future Domain" },
+ { "FDT", "Fujitsu Display Technologies Corp." },
+ { "FEC", "FURUNO ELECTRIC CO., LTD." },
{ "FEL", "Fellowes & Questec" },
- { "SLI", "Symbios Logic Inc" },
- { "ELE", "Elecom Company Ltd" },
- { "FRE", "Forvus Research Inc" },
- { "TTL", "2-Tel B.V." },
- { "PPX", "Perceptive Pixel Inc." },
- { "NAT", "NaturalPoint Inc." },
- { "SLC", "Syslogic Datentechnik AG" },
- { "PAM", "Peter Antesberger Messtechnik" },
- { "JPW", "Wallis Hamilton Industries" },
- { "AVA", "Avaya Communication" },
- { "EEH", "EEH Datalink GmbH" },
- { "WMT", "Winmate Communication Inc" },
- { "LWC", "Labway Corporation" },
- { "HYO", "HYC CO., LTD." },
- { "MCC", "Micro Industries" },
- { "IOA", "CRE Technology Corporation" },
- { "AGI", "Artish Graphics Inc" },
- { "TDT", "TDT" },
- { "UNO", "Unisys Corporation" },
- { "LIN", "Lenovo Beijing Co. Ltd." },
- { "MAG", "MAG InnoVision" },
- { "HCL", "HCL America Inc" },
- { "BWK", "Bitworks Inc." },
- { "BSN", "BRIGHTSIGN, LLC" },
- { "INM", "InnoMedia Inc" },
- { "MIN", "Minicom Digital Signage" },
- { "ARE", "ICET S.p.A." },
- { "TPZ", "Ypoaz Systems Inc" },
- { "BRO", "BROTHER INDUSTRIES,LTD." },
- { "MEX", "MSC Vertriebs GmbH" },
+ { "FEN", "Fen Systems Ltd." },
+ { "FER", "Ferranti Int'L" },
+ { "FFC", "FUJIFILM Corporation" },
+ { "FFI", "Fairfield Industries" },
+ { "FGD", "Lisa Draexlmaier GmbH" },
+ { "FGL", "Fujitsu General Limited." },
+ { "FHL", "FHLP" },
+ { "FIC", "Formosa Industrial Computing Inc" },
+ { "FIL", "Forefront Int'l Ltd" },
+ { "FIN", "Finecom Co., Ltd." },
+ { "FIR", "Chaplet Systems Inc" },
+ { "FIS", "FLY-IT Simulators" },
+ { "FIT", "Feature Integration Technology Inc." },
{ "FJC", "Fujitsu Takamisawa Component Limited" },
- { "HRT", "HERCULES" },
- { "MOM", "Momentum Data Systems" },
- { "RSV", "Ross Video Ltd" },
- { "RAN", "Rancho Tech Inc" },
- { "HOL", "Holoeye Photonics AG" },
- { "SOT", "Sotec Company Ltd" },
- { "AAE", "Anatek Electronics Inc." },
- { "ZYT", "Zytex Computers" },
- { "APP", "Apple Computer Inc" },
- { "MCM", "Metricom Inc" },
- { "NXC", "NextCom K.K." },
- { "CBX", "Cybex Computer Products Corporation" },
{ "FJS", "Fujitsu Spain" },
- { "SNI", "Siemens Microdesign GmbH" },
- { "MPL", "Maple Research Inst. Company Ltd" },
- { "PLX", "Parallax Graphics" },
- { "EAS", "Evans and Sutherland Computer" },
- { "ZBR", "Zebra Technologies International, LLC" },
- { "MSL", "MicroSlate Inc." },
- { "XOC", "DO NOT USE - XOC" },
- { "EMG", "EMG Consultants Inc" },
- { "SMC", "Standard Microsystems Corporation" },
- { "RAD", "Radisys Corporation" },
- { "NMS", "Natural Micro System" },
- { "APT", "Audio Processing Technology Ltd" },
- { "MLI", "McIntosh Laboratory Inc." },
- { "ISI", "Interface Solutions" },
- { "RAT", "Rent-A-Tech" },
- { "BAN", "Banyan" },
- { "PCL", "pentel.co.,ltd" },
- { "CSI", "Cabletron System Inc" },
- { "IVS", "Intevac Photonics Inc." },
- { "MAT", "Matsushita Electric Ind. Company Ltd" },
- { "LWR", "Lightware Visual Engineering" },
+ { "FJT", "F.J. Tieman BV" },
+ { "FLE", "ADTI Media, Inc" },
+ { "FLI", "Faroudja Laboratories" },
+ { "FLY", "Butterfly Communications" },
+ { "FMA", "Fast Multimedia AG" },
+ { "FMC", "Ford Microelectronics Inc" },
+ { "FMI", "Fujitsu Microelect Inc" },
+ { "FML", "Fujitsu Microelect Ltd" },
+ { "FMZ", "Formoza-Altair" },
+ { "FNC", "Fanuc LTD" },
+ { "FNI", "Funai Electric Co., Ltd." },
+ { "FOA", "FOR-A Company Limited" },
+ { "FOS", "Foss Tecator" },
+ { "FOX", "HON HAI PRECISON IND.CO.,LTD." },
+ { "FPE", "Fujitsu Peripherals Ltd" },
+ { "FPS", "Deltec Corporation" },
+ { "FPX", "Cirel Systemes" },
+ { "FRC", "Force Computers" },
+ { "FRD", "Freedom Scientific BLV" },
+ { "FRE", "Forvus Research Inc" },
+ { "FRI", "Fibernet Research Inc" },
+ { "FRO", "FARO Technologies" },
+ { "FRS", "South Mountain Technologies, LTD" },
+ { "FSC", "Future Systems Consulting KK" },
+ { "FSI", "Fore Systems Inc" },
+ { "FST", "Modesto PC Inc" },
+ { "FTC", "Futuretouch Corporation" },
+ { "FTE", "Frontline Test Equipment Inc." },
+ { "FTG", "FTG Data Systems" },
+ { "FTI", "FastPoint Technologies, Inc." },
+ { "FTL", "FUJITSU TEN LIMITED" },
+ { "FTN", "Fountain Technologies Inc" },
+ { "FTR", "Mediasonic" },
+ { "FTW", "MindTribe Product Engineering, Inc." },
+ { "FUJ", "Fujitsu Ltd" },
+ { "FUN", "sisel muhendislik" },
+ { "FUS", "Fujitsu Siemens Computers GmbH" },
+ { "FVC", "First Virtual Corporation" },
+ { "FVX", "C-C-C Group Plc" },
{ "FWA", "Attero Tech, LLC" },
- { "ORI", "OSR Open Systems Resources, Inc." },
- { "ARG", "Argus Electronics Co., LTD" },
- { "CAS", "CASIO COMPUTER CO.,LTD" },
- { "DHP", "DH Print" },
- { "TTS", "TechnoTrend Systemtechnik GmbH" },
- { "HHC", "HIRAKAWA HEWTECH CORP." },
+ { "FWR", "Flat Connections Inc" },
+ { "FXX", "Fuji Xerox" },
+ { "FZC", "Founder Group Shenzhen Co." },
+ { "FZI", "FZI Forschungszentrum Informatik" },
+ { "GAG", "Gage Applied Sciences Inc" },
+ { "GAL", "Galil Motion Control" },
+ { "GAU", "Gaudi Co., Ltd." },
+ { "GCC", "GCC Technologies Inc" },
+ { "GCI", "Gateway Comm. Inc" },
+ { "GCS", "Grey Cell Systems Ltd" },
+ { "GDC", "General Datacom" },
+ { "GDI", "G. Diehl ISDN GmbH" },
+ { "GDS", "GDS" },
+ { "GDT", "Vortex Computersysteme GmbH" },
+ { "GED", "General Dynamics C4 Systems" },
+ { "GEF", "GE Fanuc Embedded Systems" },
+ { "GEH", "GE Intelligent Platforms - Huntsville" },
+ { "GEM", "Gem Plus" },
+ { "GEN", "Genesys ATE Inc" },
+ { "GEO", "GEO Sense" },
+ { "GER", "GERMANEERS GmbH" },
+ { "GES", "GES Singapore Pte Ltd" },
+ { "GET", "Getac Technology Corporation" },
+ { "GFM", "GFMesstechnik GmbH" },
+ { "GFN", "Gefen Inc." },
+ { "GGL", "Google Inc." },
+ { "GIC", "General Inst. Corporation" },
+ { "GIM", "Guillemont International" },
+ { "GIP", "GI Provision Ltd" },
+ { "GIS", "AT&T Global Info Solutions" },
+ { "GJN", "Grand Junction Networks" },
+ { "GLD", "Goldmund - Digital Audio SA" },
+ { "GLE", "AD electronics" },
+ { "GLM", "Genesys Logic" },
+ { "GLS", "Gadget Labs LLC" },
+ { "GMK", "GMK Electronic Design GmbH" },
+ { "GML", "General Information Systems" },
+ { "GMM", "GMM Research Inc" },
+ { "GMN", "GEMINI 2000 Ltd" },
+ { "GMX", "GMX Inc" },
+ { "GND", "Gennum Corporation" },
+ { "GNN", "GN Nettest Inc" },
+ { "GNZ", "Gunze Ltd" },
+ { "GRA", "Graphica Computer" },
+ { "GRE", "GOLD RAIN ENTERPRISES CORP." },
+ { "GRH", "Granch Ltd" },
{ "GRM", "Garmin International" },
- { "BUL", "Bull" },
- { "AFA", "Alfa Inc" },
- { "OVR", "Oculus VR, Inc." },
- { "EPI", "Envision Peripherals, Inc" },
+ { "GRV", "Advanced Gravis" },
+ { "GRY", "Robert Gray Company" },
+ { "GSB", "NIPPONDENCHI CO,.LTD" },
{ "GSC", "General Standards Corporation" },
- { "DNG", "Apache Micro Peripherals Inc" },
- { "VIN", "Vine Micros Ltd" },
- { "PTW", "DO NOT USE - PTW" },
- { "MFI", "Micro Firmware" },
- { "SMP", "Simple Computing" },
- { "HCA", "DAT" },
- { "PHL", "Philips Consumer Electronics Company" },
- { "ADC", "Acnhor Datacomm" },
- { "VBT", "Valley Board Ltda" },
- { "MPX", "Micropix Technologies, Ltd." },
- { "VSP", "Vision Systems GmbH" },
- { "PJA", "Projecta" },
- { "AMT", "AMT International Industry" },
- { "VCI", "VistaCom Inc" },
- { "XIR", "Xirocm Inc" },
- { "MBV", "Moreton Bay" },
- { "NSC", "National Semiconductor Corporation" },
- { "TPV", "Top Victory Electronics ( Fujian ) Company Ltd" },
+ { "GSM", "LG Electronics" },
+ { "GST", "Graphic SystemTechnology" },
+ { "GSY", "Grossenbacher Systeme AG" },
+ { "GTC", "Graphtec Corporation" },
+ { "GTI", "Goldtouch" },
+ { "GTK", "G-Tech Corporation" },
+ { "GTM", "Garnet System Company Ltd" },
+ { "GTS", "Geotest Marvin Test Systems Inc" },
+ { "GTT", "General Touch Technology Co., Ltd." },
+ { "GUD", "Guntermann & Drunck GmbH" },
+ { "GUZ", "Guzik Technical Enterprises" },
+ { "GVC", "GVC Corporation" },
+ { "GVL", "Global Village Communication" },
+ { "GWI", "GW Instruments" },
+ { "GWY", "Gateway 2000" },
+ { "GZE", "GUNZE Limited" },
{ "HAE", "Haider electronics" },
- { "PKA", "Acco UK ltd." },
- { "PXC", "Phoenix Contact" },
- { "BXE", "Buxco Electronics" },
- { "OZC", "OZ Corporation" },
- { "TXL", "Trixel Ltd" },
- { "MXD", "MaxData Computer GmbH & Co.KG" },
- { "ASK", "Ask A/S" },
- { "KSC", "Kinetic Systems Corporation" },
- { "XAD", "Alpha Data" },
- { "MVI", "Media Vision Inc" },
- { "BPU", "Best Power" },
- { "LAF", "Microline" },
- { "SPS", "Synopsys Inc" },
- { "WXT", "Woxter Technology Co. Ltd" },
- { "NIX", "Seanix Technology Inc" },
- { "HPA", "Zytor Communications" },
- { "SPK", "SpeakerCraft" },
- { "CHP", "CH Products" },
- { "SNX", "Sonix Comm. Ltd" },
- { "LZX", "Lightwell Company Ltd" },
- { "ART", "Corion Industrial Corporation" },
- { "IFS", "In Focus Systems Inc" },
- { "DAL", "Digital Audio Labs Inc" },
- { "STR", "Starlight Networks Inc" },
- { "PRT", "Parade Technologies, Ltd." },
- { "VRC", "Virtual Resources Corporation" },
- { "IIC", "ISIC Innoscan Industrial Computers A/S" },
- { "AUR", "Aureal Semiconductor" },
- { "ATC", "Ably-Tech Corporation" },
- { "ODR", "Odrac" },
- { "LIP", "Linked IP GmbH" },
- { "FLI", "Faroudja Laboratories" },
- { "AVV", "SBS Technologies (Canada), Inc. (was Avvida Systems, Inc.)" },
- { "ECM", "E-Cmos Tech Corporation" },
- { "LAG", "Laguna Systems" },
- { "FFC", "FUJIFILM Corporation" },
- { "MAX", "Rogen Tech Distribution Inc" },
- { "HUM", "IMP Electronics Ltd." },
- { "VTX", "Vestax Corporation" },
- { "NST", "Network Security Technology Co" },
- { "FLY", "Butterfly Communications" },
- { "ETT", "E-Tech Inc" },
- { "NXS", "Technology Nexus Secure Open Systems AB" },
- { "VES", "Vestel Elektronik Sanayi ve Ticaret A. S." },
- { "EBT", "HUALONG TECHNOLOGY CO., LTD" },
- { "HPK", "HAMAMATSU PHOTONICS K.K." },
- { "RGB", "RGB Spectrum" },
- { "AUI", "Alps Electric Inc" },
- { "ICI", "Infotek Communication Inc" },
- { "NTS", "Nits Technology Inc." },
- { "EVI", "eviateg GmbH" },
- { "CRD", "Cardinal Technical Inc" },
- { "MOD", "Modular Technology" },
- { "CCP", "Capetronic USA Inc" },
- { "DGS", "Diagsoft Inc" },
- { "IFT", "Informtech" },
- { "LWW", "Lanier Worldwide" },
- { "SDK", "SAIT-Devlonics" },
- { "UWC", "Uniwill Computer Corp." },
- { "MXV", "MaxVision Corporation" },
+ { "HAI", "Haivision Systems Inc." },
+ { "HAL", "Halberthal" },
+ { "HAN", "Hanchang System Corporation" },
+ { "HAR", "Harris Corporation" },
+ { "HAY", "Hayes Microcomputer Products Inc" },
+ { "HCA", "DAT" },
+ { "HCE", "Hitachi Consumer Electronics Co., Ltd" },
+ { "HCL", "HCL America Inc" },
+ { "HCM", "HCL Peripherals" },
+ { "HCP", "Hitachi Computer Products Inc" },
+ { "HCW", "Hauppauge Computer Works Inc" },
+ { "HDC", "HardCom Elektronik & Datateknik" },
+ { "HDI", "HD-INFO d.o.o." },
+ { "HDV", "Holografika kft." },
+ { "HEC", "Hitachi Engineering Company Ltd" },
+ { "HEL", "Hitachi Micro Systems Europe Ltd" },
+ { "HER", "Ascom Business Systems" },
+ { "HET", "HETEC Datensysteme GmbH" },
+ { "HHC", "HIRAKAWA HEWTECH CORP." },
+ { "HHI", "Fraunhofer Heinrich-Hertz-Institute" },
+ { "HIB", "Hibino Corporation" },
+ { "HIC", "Hitachi Information Technology Co., Ltd." },
+ { "HIK", "Hikom Co., Ltd." },
+ { "HIL", "Hilevel Technology" },
+ { "HIQ", "Kaohsiung Opto Electronics Americas, Inc." },
+ { "HIT", "Hitachi America Ltd" },
+ { "HJI", "Harris & Jeffries Inc" },
+ { "HKA", "HONKO MFG. CO., LTD." },
+ { "HKG", "Josef Heim KG" },
+ { "HMC", "Hualon Microelectric Corporation" },
+ { "HMK", "hmk Daten-System-Technik BmbH" },
+ { "HMX", "HUMAX Co., Ltd." },
+ { "HNS", "Hughes Network Systems" },
+ { "HOB", "HOB Electronic GmbH" },
{ "HOE", "Hosiden Corporation" },
- { "SGE", "Kansai Electric Company Ltd" },
- { "URD", "Video Computer S.p.A." },
- { "TSV", "TRANSVIDEO" },
- { "MBM", "Marshall Electronics" },
- { "TLA", "Ferrari Electronic GmbH" },
- { "GLM", "Genesys Logic" },
- { "LEN", "Lenovo Group Limited" },
- { "SAM", "Samsung Electric Company" },
- { "VTL", "Vivid Technology Pte Ltd" },
- { "UTD", "Up to Date Tech" },
- { "ITC", "Intercom Inc" },
- { "ENI", "Efficient Networks" },
- { "GDC", "General Datacom" },
- { "XIT", "Xitel Pty ltd" },
- { "CMN", "Chimei Innolux Corporation" },
- { "AVE", "Add Value Enterpises (Asia) Pte Ltd" },
- { "WEC", "Winbond Electronics Corporation" },
- { "OAK", "Oak Tech Inc" },
- { "DON", "DENON, Ltd." },
- { "ITR", "Infotronic America, Inc." },
- { "CAC", "CA & F Elettronica" },
- { "VIM", "Via Mons Ltd." },
- { "DGP", "Digicorp European sales S.A." },
+ { "HOL", "Holoeye Photonics AG" },
+ { "HON", "Sonitronix" },
+ { "HPA", "Zytor Communications" },
+ { "HPC", "Hewlett Packard Co." },
{ "HPD", "Hewlett Packard" },
- { "USD", "U.S. Digital Corporation" },
- { "TAM", "Tamura Seisakusyo Ltd" },
- { "SGZ", "Systec Computer GmbH" },
- { "NGS", "A D S Exports" },
- { "FSI", "Fore Systems Inc" },
- { "SIL", "Silicon Laboratories, Inc" },
- { "QCP", "Qualcomm Inc" },
- { "SDA", "SAT (Societe Anonyme)" },
- { "SEI", "Seitz & Associates Inc" },
- { "RSI", "Rampage Systems Inc" },
- { "VIZ", "VIZIO, Inc" },
- { "EPN", "EPiCON Inc." },
- { "OIC", "Option Industrial Computers" },
- { "KDE", "KDE" },
- { "CLV", "Clevo Company" },
- { "GRA", "Graphica Computer" },
- { "HIK", "Hikom Co., Ltd." },
- { "LCE", "La Commande Electronique" },
- { "MNP", "Microcom" },
- { "ERI", "Ericsson Mobile Communications AB" },
- { "REX", "RATOC Systems, Inc." },
- { "PPP", "Purup Prepress AS" },
- { "JAT", "Jaton Corporation" },
- { "GLE", "AD electronics" },
- { "VAL", "Valence Computing Corporation" },
- { "CDN", "Codenoll Technical Corporation" },
- { "SDT", "Siemens AG" },
- { "RSC", "PhotoTelesis" },
- { "FFI", "Fairfield Industries" },
- { "VPR", "Best Buy" },
- { "IPM", "IPM Industria Politecnica Meridionale SpA" },
+ { "HPI", "Headplay, Inc." },
+ { "HPK", "HAMAMATSU PHOTONICS K.K." },
+ { "HPQ", "HP" },
+ { "HPR", "H.P.R. Electronics GmbH" },
+ { "HRC", "Hercules" },
+ { "HRE", "Qingdao Haier Electronics Co., Ltd." },
+ { "HRI", "Hall Research" },
+ { "HRL", "Herolab GmbH" },
+ { "HRS", "Harris Semiconductor" },
+ { "HRT", "HERCULES" },
+ { "HSC", "Hagiwara Sys-Com Company Ltd" },
+ { "HSD", "HannStar Display Corp" },
{ "HSM", "AT&T Microelectronics" },
- { "YHQ", "Yokogawa Electric Corporation" },
- { "UEC", "Ultima Electronics Corporation" },
- { "NME", "Navico, Inc." },
- { "GVL", "Global Village Communication" },
- { "TEK", "Tektronix Inc" },
- { "SBD", "Softbed - Consulting & Development Ltd" },
- { "PSD", "Peus-Systems GmbH" },
- { "DCA", "Digital Communications Association" },
+ { "HSP", "HannStar Display Corp" },
+ { "HTC", "Hitachi Ltd" },
+ { "HTI", "Hampshire Company, Inc." },
+ { "HTK", "Holtek Microelectronics Inc" },
+ { "HTX", "Hitex Systementwicklung GmbH" },
+ { "HUB", "GAI-Tronics, A Hubbell Company" },
+ { "HUM", "IMP Electronics Ltd." },
+ { "HWA", "Harris Canada Inc" },
{ "HWC", "DBA Hans Wedemeyer" },
- { "DFK", "SharkTec A/S" },
- { "DMB", "Digicom Systems Inc" },
- { "IPW", "IPWireless, Inc" },
- { "ACC", "Accton Technology Corporation" },
- { "CPM", "Capella Microsystems Inc." },
- { "AAT", "Ann Arbor Technologies" },
- { "LAS", "LASAT Comm. A/S" },
- { "TWI", "Easytel oy" },
- { "HJI", "Harris & Jeffries Inc" },
- { "SGX", "Silicon Graphics Inc" },
- { "TSL", "Tottori SANYO Electric Co., Ltd." },
- { "SVD", "SVD Computer" },
- { "CLT", "automated computer control systems" },
- { "WLD", "Wildfire Communications Inc" },
- { "LCI", "Lite-On Communication Inc" },
- { "AEC", "Antex Electronics Corporation" },
- { "ACA", "Ariel Corporation" },
- { "KML", "Kensington Microware Ltd" },
- { "KDT", "KDDI Technology Corporation" },
- { "BSE", "Bose Corporation" },
- { "WSP", "Wireless And Smart Products Inc." },
- { "GNZ", "Gunze Ltd" },
- { "PMM", "Point Multimedia System" },
- { "ASC", "Ascom Strategic Technology Unit" },
- { "EVX", "Everex" },
- { "WBN", "MicroSoftWare" },
- { "FGL", "Fujitsu General Limited." },
- { "JSI", "Jupiter Systems, Inc." },
- { "SII", "Silicon Image, Inc." },
- { "SMM", "Shark Multimedia Inc" },
- { "XYC", "Xycotec Computer GmbH" },
- { "PEC", "POTRANS Electrical Corp." },
- { "TSD", "TechniSat Digital GmbH" },
- { "ZSE", "Zenith Data Systems" },
- { "ENC", "Eizo Nanao Corporation" },
- { "MWY", "Microway Inc" },
- { "OLI", "Olivetti" },
- { "WIL", "WIPRO Information Technology Ltd" },
- { "LKM", "Likom Technology Sdn. Bhd." },
- { "KOU", "KOUZIRO Co.,Ltd." },
- { "VHI", "Macrocad Development Inc." },
- { "FIT", "Feature Integration Technology Inc." },
- { "MXP", "Maxpeed Corporation" },
- { "SCD", "Sanyo Electric Company Ltd" },
- { "NBL", "N*Able Technologies Inc" },
- { "SPT", "Sceptre Tech Inc" },
- { "IPN", "Performance Technologies" },
- { "BMD", "Blackmagic Design" },
- { "MDK", "Mediatek Corporation" },
- { "DCS", "Diamond Computer Systems Inc" },
- { "ICE", "IC Ensemble" },
- { "LSY", "LSI Systems Inc" },
- { "AMC", "Attachmate Corporation" },
- { "TCO", "Thomas-Conrad Corporation" },
- { "NOK", "Nokia Display Products" },
- { "VFI", "VeriFone Inc" },
- { "OPV", "Optivision Inc" },
- { "LCM", "Latitude Comm." },
- { "LSL", "Logical Solutions" },
- { "TVO", "TV One Ltd" },
- { "KVA", "Kvaser AB" },
- { "PMT", "Promate Electronic Co., Ltd." },
- { "ZZZ", "Boca Research Inc" },
- { "ELC", "Electro Scientific Ind" },
- { "SIR", "Sirius Technologies Pty Ltd" },
- { "DCE", "dSPACE GmbH" },
- { "WAN", "DO NOT USE - WAN" },
- { "PCT", "PC-Tel Inc" },
- { "BEO", "Baug & Olufsen" },
- { "LUM", "Lumagen, Inc." },
- { "DNA", "DNA Enterprises, Inc." },
- { "WEY", "WEY Design AG" },
- { "IAF", "Institut f r angewandte Funksystemtechnik GmbH" },
- { "QFF", "Padix Co., Inc." },
- { "JIC", "Jaeik Information & Communication Co., Ltd." },
- { "VIT", "Visitech AS" },
- { "QUA", "Quatographic AG" },
- { "BNK", "Banksia Tech Pty Ltd" },
- { "TME", "AT&T Microelectronics" },
- { "DRB", "Dr. Bott KG" },
- { "NET", "Mettler Toledo" },
- { "CDE", "Colin.de" },
- { "ATI", "Allied Telesis KK" },
- { "PMD", "TDK USA Corporation" },
- { "SKY", "SKYDATA S.P.A." },
- { "FTN", "Fountain Technologies Inc" },
- { "DBD", "Diebold Inc." },
- { "ECA", "Electro Cam Corp." },
- { "TLI", "TOSHIBA TELI CORPORATION" },
- { "CTC", "CTC Communication Development Company Ltd" },
- { "NVT", "Navatek Engineering Corporation" },
- { "CKC", "The Concept Keyboard Company Ltd" },
- { "FIR", "Chaplet Systems Inc" },
+ { "HWD", "Highwater Designs Ltd" },
+ { "HWP", "Hewlett Packard" },
+ { "HXM", "Hexium Ltd." },
+ { "HYC", "Hypercope Gmbh Aachen" },
{ "HYD", "Hydis Technologies.Co.,LTD" },
- { "TTY", "TRIDELITY Display Solutions GmbH" },
- { "DAE", "Digatron Industrie Elektronik GmbH" },
- { "AUT", "Autotime Corporation" },
- { "GTC", "Graphtec Corporation" },
- { "MYR", "Myriad Solutions Ltd" },
- { "DLT", "Digitelec Informatique Park Cadera" },
- { "SDR", "SDR Systems" },
- { "ACS", "Altos Computer Systems" },
- { "SVC", "Intellix Corp." },
- { "ZTE", "ZTE Corporation" },
- { "ERT", "Escort Insturments Corporation" },
- { "WII", "Innoware Inc" },
- { "DOL", "Dolman Technologies Group Inc" },
- { "RLD", "MEPCO" },
- { "HRL", "Herolab GmbH" },
- { "IRD", "IRdata" },
- { "IVI", "Intervoice Inc" },
- { "ICS", "Integrated Circuit Systems" },
- { "ASE", "AseV Display Labs" },
- { "SYX", "Prime Systems, Inc." },
- { "SOI", "Silicon Optix Corporation" },
- { "OCS", "Open Connect Solutions" },
- { "HON", "Sonitronix" },
- { "TAG", "Teles AG" },
- { "PEP", "Peppercon AG" },
- { "INT", "Interphase Corporation" },
+ { "HYO", "HYC CO., LTD." },
+ { "HYP", "Hyphen Ltd" },
+ { "HYR", "Hypertec Pty Ltd" },
+ { "HYT", "Heng Yu Technology (HK) Limited" },
+ { "HYV", "Hynix Semiconductor" },
+ { "IAF", "Institut f r angewandte Funksystemtechnik GmbH" },
+ { "IAI", "Integration Associates, Inc." },
+ { "IAT", "IAT Germany GmbH" },
+ { "IBC", "Integrated Business Systems" },
+ { "IBI", "INBINE.CO.LTD" },
+ { "IBM", "IBM France" },
+ { "IBP", "IBP Instruments GmbH" },
{ "IBR", "IBR GmbH" },
- { "WYS", "Wyse Technology" },
- { "TRE", "Tremetrics" },
- { "RKC", "Reakin Technolohy Corporation" },
- { "SEG", "DO NOT USE - SEG" },
- { "CAV", "Cavium Networks, Inc" },
- { "ELA", "ELAD srl" },
- { "MMD", "Micromed Biotecnologia Ltd" },
- { "SGL", "Super Gate Technology Company Ltd" },
- { "SIS", "Silicon Integrated Systems Corporation" },
- { "XFO", "EXFO Electro Optical Engineering" },
- { "ING", "Integraph Corporation" },
- { "NEU", "NEUROTEC - EMPRESA DE PESQUISA E DESENVOLVIMENTO EM BIOMEDICINA" },
- { "ZIC", "Nationz Technologies Inc." },
- { "CVI", "Colorado Video, Inc." },
- { "VCC", "Virtual Computer Corporation" },
- { "INZ", "Best Buy" },
- { "ELO", "Tyco Electronics" },
- { "EPH", "Epiphan Systems Inc." },
- { "SYL", "Sylvania Computer Products" },
- { "MXI", "Macronix Inc" },
- { "GEH", "GE Intelligent Platforms - Huntsville" },
- { "BBB", "an-najah university" },
- { "ARK", "Ark Logic Inc" },
- { "IVM", "Iiyama North America" },
- { "XTE", "X2E GmbH" },
- { "DMV", "NDS Ltd" },
- { "CPD", "CompuAdd" },
- { "CYD", "Cyclades Corporation" },
- { "ALX", "ALEXON Co.,Ltd." },
- { "COB", "COBY Electronics Co., Ltd" },
- { "HCE", "Hitachi Consumer Electronics Co., Ltd" },
- { "EXX", "Exxact GmbH" },
- { "TAB", "Todos Data System AB" },
- { "MPN", "Mainpine Limited" },
- { "ATH", "Athena Informatica S.R.L." },
- { "AWL", "Aironet Wireless Communications, Inc" },
- { "FNI", "Funai Electric Co., Ltd." },
- { "PLT", "PT Hartono Istana Teknologi" },
- { "DEN", "Densitron Computers Ltd" },
- { "MIM", "Mimio – A Newell Rubbermaid Company" },
- { "GER", "GERMANEERS GmbH" },
- { "CAI", "Canon Inc." },
- { "DNI", "Deterministic Networks Inc." },
- { "DOT", "Dotronic Mikroelektronik GmbH" },
- { "MVX", "COM 1" },
- { "WTC", "ACC Microelectronics" },
- { "HIT", "Hitachi America Ltd" },
- { "ALM", "Acutec Ltd." },
- { "TIP", "TIPTEL AG" },
- { "END", "ENIDAN Technologies Ltd" },
- { "PAR", "Parallan Comp Inc" },
- { "DVL", "Devolo AG" },
- { "ADV", "Advanced Micro Devices Inc" },
- { "TKS", "TimeKeeping Systems, Inc." },
- { "MLD", "Deep Video Imaging Ltd" },
- { "IUC", "ICSL" },
- { "MNL", "Monorail Inc" },
- { "HRC", "Hercules" },
- { "ANS", "Ansel Communication Company" },
- { "UAS", "Ultima Associates Pte Ltd" },
- { "SBS", "SBS-or Industrial Computers GmbH" },
- { "DVT", "Data Video" },
- { "PTS", "Plain Tree Systems Inc" },
- { "CSD", "Cresta Systems Inc" },
- { "LDT", "LogiDataTech Electronic GmbH" },
- { "AGM", "Advan Int'l Corporation" },
- { "TLD", "Telindus" },
- { "SPU", "SIM2 Multimedia S.P.A." },
- { "BCS", "Booria CAD/CAM systems" },
- { "CRQ", "Cirque Corporation" },
- { "MIL", "Marconi Instruments Ltd" },
- { "FTE", "Frontline Test Equipment Inc." },
- { "RWC", "Red Wing Corporation" },
- { "TLS", "Teleste Educational OY" },
- { "DAT", "Datel Inc" },
- { "SIT", "Sitintel" },
- { "QTI", "Quicknet Technologies Inc" },
- { "EBH", "Data Price Informatica" },
- { "PCK", "PCBANK21" },
- { "VSC", "ViewSonic Corporation" },
- { "BBL", "Brain Boxes Limited" },
- { "UFO", "UFO Systems Inc" },
- { "NTI", "New Tech Int'l Company" },
- { "WAV", "Wavephore" },
- { "NOT", "Not Limited Inc" },
- { "GRH", "Granch Ltd" },
- { "VTC", "VTel Corporation" },
- { "UNA", "Unisys DSD" },
- { "LAB", "ACT Labs Ltd" },
- { "UIC", "Uniform Industrial Corporation" },
+ { "ICA", "ICA Inc" },
+ { "ICC", "BICC Data Networks Ltd" },
+ { "ICD", "ICD Inc" },
+ { "ICE", "IC Ensemble" },
+ { "ICI", "Infotek Communication Inc" },
+ { "ICM", "Intracom SA" },
+ { "ICN", "Sanyo Icon" },
+ { "ICO", "Intel Corp" },
+ { "ICP", "ICP Electronics, Inc./iEi Technology Corp." },
+ { "ICS", "Integrated Circuit Systems" },
+ { "ICV", "Inside Contactless" },
+ { "ICX", "ICCC A/S" },
+ { "IDC", "International Datacasting Corporation" },
+ { "IDE", "IDE Associates" },
{ "IDK", "IDK Corporation" },
- { "CHI", "Chrontel Inc" },
- { "QCH", "Metronics Inc" },
- { "CER", "Ceronix" },
- { "PCB", "OCTAL S.A." },
- { "VTV", "VATIV Technologies" },
- { "BTI", "BusTech Inc" },
- { "RVL", "Reveal Computer Prod" },
- { "CHC", "Chic Technology Corp." },
- { "QDS", "Quanta Display Inc." },
- { "DAW", "DA2 Technologies Inc" },
- { "MTR", "Mitron computer Inc" },
- { "PCP", "Procomp USA Inc" },
- { "AZM", "AZ Middelheim - Radiotherapy" },
- { "NHT", "Vinci Labs" },
- { "ROB", "Robust Electronics GmbH" },
- { "RIC", "RICOH COMPANY, LTD." },
- { "PCI", "Pioneer Computer Inc" },
- { "EKA", "MagTek Inc." },
- { "SWL", "Sharedware Ltd" },
- { "GSM", "Goldstar Company Ltd" },
+ { "IDN", "Idneo Technologies" },
+ { "IDO", "IDEO Product Development" },
{ "IDP", "Integrated Device Technology, Inc." },
- { "BPD", "Micro Solutions, Inc." },
- { "UNS", "Unisys Corporation" },
- { "PBN", "Packard Bell NEC" },
- { "KRM", "Kroma Telecom" },
- { "ENT", "Enterprise Comm. & Computing Inc" },
- { "ATL", "Arcus Technology Ltd" },
- { "VDT", "Viditec, Inc." },
- { "JUK", "Janich & Klass Computertechnik GmbH" },
- { "PVG", "Proview Global Co., Ltd" },
- { "INX", "Communications Supply Corporation (A division of WESCO)" },
- { "GDS", "GDS" },
- { "UHB", "XOCECO" },
- { "MEI", "Panasonic Industry Company" },
- { "OXU", "Oxus Research S.A." },
- { "SGO", "Logos Design A/S" },
- { "STU", "Sentelic Corporation" },
- { "PUL", "Pulse-Eight Ltd" },
- { "BRA", "Braemac Pty Ltd" },
- { "MBD", "Microbus PLC" },
- { "OAS", "Oasys Technology Company" },
- { "MDS", "Micro Display Systems Inc" },
- { "SCS", "Nanomach Anstalt" },
- { "DAS", "DAVIS AS" },
- { "NLC", "Next Level Communications" },
- { "MSU", "motorola" },
- { "MAD", "Xedia Corporation" },
- { "LOE", "Loewe Opta GmbH" },
- { "EEE", "ET&T Technology Company Ltd" },
- { "ANX", "Acer Netxus Inc" },
+ { "IDS", "Interdigital Sistemas de Informacao" },
+ { "IDT", "International Display Technology" },
+ { "IDX", "IDEXX Labs" },
+ { "IEC", "Interlace Engineering Corporation" },
{ "IEE", "IEE" },
- { "ALL", "Alliance Semiconductor Corporation" },
- { "DCT", "Dancall Telecom A/S" },
- { "AII", "Amptron International Inc." },
- { "DPT", "DPT" },
- { "TNJ", "DO NOT USE - TNJ" },
- { "FTC", "Futuretouch Corporation" },
- { "ESG", "ELCON Systemtechnik GmbH" },
- { "SYV", "SYVAX Inc" },
- { "RAC", "Racore Computer Products Inc" },
- { "IBM", "IBM France" },
- { "LTV", "Leitch Technology International Inc." },
- { "AKE", "AKAMI Electric Co.,Ltd" },
- { "VDO", "Video & Display Oriented Corporation" },
- { "MEN", "MEN Mikroelectronik Nueruberg GmbH" },
- { "UNT", "Unisys Corporation" },
- { "TTK", "Totoku Electric Company Ltd" },
- { "DII", "Dataq Instruments Inc" },
- { "AMO", "Amino Technologies PLC and Amino Communications Limited" },
+ { "IEI", "Interlink Electronics" },
+ { "IFS", "In Focus Systems Inc" },
+ { "IFT", "Informtech" },
+ { "IFX", "Infineon Technologies AG" },
+ { "IFZ", "Infinite Z" },
+ { "IGC", "Intergate Pty Ltd" },
+ { "IGM", "IGM Communi" },
+ { "IHE", "InHand Electronics" },
+ { "IIC", "ISIC Innoscan Industrial Computers A/S" },
+ { "III", "Intelligent Instrumentation" },
+ { "IIN", "IINFRA Co., Ltd" },
+ { "IKS", "Ikos Systems Inc" },
+ { "ILC", "Image Logic Corporation" },
+ { "ILS", "Innotech Corporation" },
+ { "IMA", "Imagraph" },
+ { "IMB", "ART s.r.l." },
{ "IMC", "IMC Networks" },
- { "STG", "StereoGraphics Corp." },
- { "RRI", "Radicom Research Inc" },
- { "HTI", "Hampshire Company, Inc." },
- { "SOR", "Sorcus Computer GmbH" },
- { "AXL", "Axel" },
- { "SNS", "Cirtech (UK) Ltd" },
+ { "IMD", "ImasDe Canarias S.A." },
+ { "IME", "Imagraph" },
+ { "IMG", "IMAGENICS Co., Ltd." },
+ { "IMI", "International Microsystems Inc" },
+ { "IMM", "Immersion Corporation" },
+ { "IMN", "Impossible Production" },
+ { "IMP", "Impression Products Incorporated" },
+ { "IMT", "Inmax Technology Corporation" },
+ { "INC", "Home Row Inc" },
+ { "IND", "ILC" },
+ { "INE", "Inventec Electronics (M) Sdn. Bhd." },
+ { "INF", "Inframetrics Inc" },
+ { "ING", "Integraph Corporation" },
+ { "INI", "Initio Corporation" },
+ { "INK", "Indtek Co., Ltd." },
+ { "INL", "InnoLux Display Corporation" },
+ { "INM", "InnoMedia Inc" },
+ { "INN", "Innovent Systems, Inc." },
+ { "INO", "Innolab Pte Ltd" },
+ { "INP", "Interphase Corporation" },
+ { "INS", "Ines GmbH" },
+ { "INT", "Interphase Corporation" },
+ { "INU", "Inovatec S.p.A." },
+ { "INV", "Inviso, Inc." },
+ { "INX", "Communications Supply Corporation (A division of WESCO)" },
+ { "INZ", "Best Buy" },
+ { "IOA", "CRE Technology Corporation" },
+ { "IOD", "I-O Data Device Inc" },
+ { "IOM", "Iomega" },
+ { "ION", "Inside Out Networks" },
+ { "IOS", "i-O Display System" },
+ { "IOT", "I/OTech Inc" },
+ { "IPC", "IPC Corporation" },
{ "IPD", "Industrial Products Design, Inc." },
- { "FMI", "Fujitsu Microelect Inc" },
- { "FMA", "Fast Multimedia AG" },
- { "MIT", "MCM Industrial Technology GmbH" },
- { "RII", "Racal Interlan Inc" },
- { "PDN", "AT&T Paradyne" },
- { "TRU", "Aashima Technology B.V." },
- { "BEI", "Beckworth Enterprises Inc" },
- { "RSS", "Rockwell Semiconductor Systems" },
- { "SHR", "Digital Discovery" },
- { "CDT", "IBM Corporation" },
- { "TKC", "Taiko Electric Works.LTD" },
+ { "IPI", "Intelligent Platform Management Interface (IPMI) forum (Intel, HP, NEC, Dell)" },
+ { "IPM", "IPM Industria Politecnica Meridionale SpA" },
+ { "IPN", "Performance Technologies" },
+ { "IPP", "IP Power Technologies GmbH" },
+ { "IPR", "Ithaca Peripherals" },
+ { "IPS", "IPS, Inc. (Intellectual Property Solutions, Inc.)" },
+ { "IPT", "International Power Technologies" },
+ { "IPW", "IPWireless, Inc" },
+ { "IQI", "IneoQuest Technologies, Inc" },
+ { "IQT", "IMAGEQUEST Co., Ltd" },
+ { "IRD", "IRdata" },
+ { "ISA", "Symbol Technologies" },
+ { "ISC", "Id3 Semiconductors" },
+ { "ISG", "Insignia Solutions Inc" },
+ { "ISI", "Interface Solutions" },
+ { "ISL", "Isolation Systems" },
+ { "ISM", "Image Stream Medical" },
+ { "ISP", "IntreSource Systems Pte Ltd" },
+ { "ISR", "INSIS Co., LTD." },
+ { "ISS", "ISS Inc" },
+ { "IST", "Intersolve Technologies" },
+ { "ISY", "International Integrated Systems,Inc.(IISI)" },
+ { "ITA", "Itausa Export North America" },
+ { "ITC", "Intercom Inc" },
+ { "ITD", "Internet Technology Corporation" },
+ { "ITE", "Integrated Tech Express Inc" },
+ { "ITK", "ITK Telekommunikation AG" },
+ { "ITL", "Inter-Tel" },
{ "ITM", "ITM inc." },
- { "QUE", "Questra Consulting" },
- { "CMR", "Cambridge Research Systems Ltd" },
- { "LCC", "LCI" },
- { "MDO", "Panasonic" },
- { "IEC", "Interlace Engineering Corporation" },
- { "DPL", "Digital Projection Limited" },
- { "INV", "Inviso, Inc." },
+ { "ITN", "The NTI Group" },
+ { "ITP", "IT-PRO Consulting und Systemhaus GmbH" },
+ { "ITR", "Infotronic America, Inc." },
+ { "ITS", "IDTECH" },
+ { "ITT", "I&T Telecom." },
+ { "ITX", "integrated Technology Express Inc" },
+ { "IUC", "ICSL" },
+ { "IVI", "Intervoice Inc" },
+ { "IVM", "Iiyama North America" },
+ { "IVS", "Intevac Photonics Inc." },
+ { "IWR", "Icuiti Corporation" },
+ { "IWX", "Intelliworxx, Inc." },
+ { "IXD", "Intertex Data AB" },
+ { "JAC", "Astec Inc" },
+ { "JAE", "Japan Aviation Electronics Industry, Limited" },
+ { "JAS", "Janz Automationssysteme AG" },
+ { "JAT", "Jaton Corporation" },
+ { "JAZ", "Carrera Computer Inc" },
+ { "JCE", "Jace Tech Inc" },
+ { "JDL", "Japan Digital Laboratory Co.,Ltd." },
+ { "JEN", "N-Vision" },
+ { "JET", "JET POWER TECHNOLOGY CO., LTD." },
+ { "JFX", "Jones Futurex Inc" },
+ { "JGD", "University College" },
+ { "JIC", "Jaeik Information & Communication Co., Ltd." },
+ { "JKC", "JVC KENWOOD Corporation" },
+ { "JMT", "Micro Technical Company Ltd" },
+ { "JPC", "JPC Technology Limited" },
+ { "JPW", "Wallis Hamilton Industries" },
+ { "JQE", "CNet Technical Inc" },
{ "JSD", "JS DigiTech, Inc" },
- { "TOE", "TOEI Electronics Co., Ltd." },
- { "HAY", "Hayes Microcomputer Products Inc" },
- { "SSJ", "Sankyo Seiki Mfg.co., Ltd" },
- { "NNC", "NNC" },
- { "PHE", "Philips Medical Systems Boeblingen GmbH" },
- { "MWI", "Multiwave Innovation Pte Ltd" },
- { "WYT", "Wooyoung Image & Information Co.,Ltd." },
- { "AIM", "AIMS Lab Inc" },
- { "CSS", "CSS Laboratories" },
- { "TRS", "Torus Systems Ltd" },
- { "ROK", "Rockwell International" },
- { "SXD", "Silex technology, Inc." },
- { "PHS", "Philips Communication Systems" },
- { "CLM", "CrystaLake Multimedia" },
- { "ALO", "Algolith Inc." },
- { "SIU", "Seiko Instruments USA Inc" },
- { "TUA", "T+A elektroakustik GmbH" },
- { "CTE", "Chunghwa Telecom Co., Ltd." },
- { "SDD", "Intrada-SDD Ltd" },
- { "RMT", "Roper Mobile" },
- { "SSP", "Spectrum Signal Proecessing Inc" },
- { "VTN", "VIDEOTRON CORP." },
- { "VAD", "Vaddio, LLC" },
- { "SFT", "Mikroforum Ring 3" },
- { "DGK", "DugoTech Co., LTD" },
- { "ACH", "Archtek Telecom Corporation" },
- { "ABT", "Anchor Bay Technologies, Inc." },
- { "STC", "STAC Electronics" },
- { "DRS", "DRS Defense Solutions, LLC" },
- { "OQI", "Oksori Company Ltd" },
- { "IMT", "Inmax Technology Corporation" },
- { "ENE", "ENE Technology Inc." },
- { "WBS", "WB Systemtechnik GmbH" },
- { "PRC", "PerComm" },
- { "PSC", "Philips Semiconductors" },
- { "RJS", "Advanced Engineering" },
- { "STS", "SITECSYSTEM CO., LTD." },
- { "LAV", "Lava Computer MFG Inc" },
- { "RCH", "Reach Technology Inc" },
- { "DWE", "Daewoo Electronics Company Ltd" },
- { "KTC", "Kingston Tech Corporation" },
- { "GLS", "Gadget Labs LLC" },
- { "COS", "CoStar Corporation" },
- { "SBI", "SMART Technologies Inc." },
- { "ATP", "Alpha-Top Corporation" },
- { "DQB", "Datacube Inc" },
- { "INN", "Innovent Systems, Inc." },
- { "DNT", "Dr. Neuhous Telekommunikation GmbH" },
+ { "JSI", "Jupiter Systems, Inc." },
+ { "JSK", "SANKEN ELECTRIC CO., LTD" },
+ { "JTS", "JS Motorsports" },
+ { "JTY", "jetway security micro,inc" },
+ { "JUK", "Janich & Klass Computertechnik GmbH" },
+ { "JUP", "Jupiter Systems" },
+ { "JVC", "JVC" },
+ { "JWD", "Video International Inc." },
+ { "JWL", "Jewell Instruments, LLC" },
+ { "JWS", "JWSpencer & Co." },
+ { "JWY", "Jetway Information Co., Ltd" },
+ { "KAR", "Karna" },
+ { "KBI", "Kidboard Inc" },
+ { "KBL", "Kobil Systems GmbH" },
+ { "KCD", "Chunichi Denshi Co.,LTD." },
+ { "KCL", "Keycorp Ltd" },
+ { "KDE", "KDE" },
+ { "KDK", "Kodiak Tech" },
+ { "KDM", "Korea Data Systems Co., Ltd." },
+ { "KDS", "KDS USA" },
+ { "KDT", "KDDI Technology Corporation" },
+ { "KEC", "Kyushu Electronics Systems Inc" },
+ { "KEM", "Kontron Embedded Modules GmbH" },
+ { "KES", "Kesa Corporation" },
+ { "KEY", "Key Tech Inc" },
+ { "KFC", "SCD Tech" },
+ { "KFE", "Komatsu Forest" },
{ "KFX", "Kofax Image Products" },
- { "APE", "Alpine Electronics, Inc." },
- { "DSM", "DSM Digital Services GmbH" },
- { "RES", "ResMed Pty Ltd" },
- { "HMX", "HUMAX Co., Ltd." },
- { "PCW", "Pacific CommWare Inc" },
+ { "KGL", "KEISOKU GIKEN Co.,Ltd." },
+ { "KIS", "KiSS Technology A/S" },
+ { "KMC", "Mitsumi Company Ltd" },
+ { "KME", "KIMIN Electronics Co., Ltd." },
+ { "KML", "Kensington Microware Ltd" },
+ { "KNC", "Konica corporation" },
+ { "KNX", "Nutech Marketing PTL" },
+ { "KOB", "Kobil Systems GmbH" },
+ { "KOD", "Eastman Kodak Company" },
+ { "KOE", "KOLTER ELECTRONIC" },
+ { "KOL", "Kollmorgen Motion Technologies Group" },
+ { "KOU", "KOUZIRO Co.,Ltd." },
+ { "KOW", "KOWA Company,LTD." },
+ { "KPC", "King Phoenix Company" },
+ { "KRL", "Krell Industries Inc." },
+ { "KRM", "Kroma Telecom" },
+ { "KRY", "Kroy LLC" },
+ { "KSC", "Kinetic Systems Corporation" },
+ { "KSL", "Karn Solutions Ltd." },
+ { "KSX", "King Tester Corporation" },
+ { "KTC", "Kingston Tech Corporation" },
+ { "KTD", "Takahata Electronics Co.,Ltd." },
+ { "KTE", "K-Tech" },
+ { "KTG", "Kayser-Threde GmbH" },
+ { "KTI", "Konica Technical Inc" },
+ { "KTK", "Key Tronic Corporation" },
+ { "KTN", "Katron Tech Inc" },
+ { "KUR", "Kurta Corporation" },
+ { "KVA", "Kvaser AB" },
+ { "KVX", "KeyView" },
+ { "KWD", "Kenwood Corporation" },
{ "KYC", "Kyocera Corporation" },
- { "VSN", "Ingram Macrotron" },
- { "SNT", "SuperNet Inc" },
- { "TEL", "Promotion and Display Technology Ltd." },
- { "IFX", "Infineon Technologies AG" },
- { "PVC", "DO NOT USE - PVC" },
- { "JKC", "JVC KENWOOD Corporation" },
- { "MSV", "Mosgi Corporation" },
- { "BUR", "Bernecker & Rainer Ind-Eletronik GmbH" },
- { "PTA", "PAR Tech Inc." },
- { "GGL", "Google Inc." },
- { "COM", "Comtrol Corporation" },
- { "JEN", "N-Vision" },
- { "AMP", "AMP Inc" },
- { "HDI", "HD-INFO d.o.o." },
- { "BOE", "BOE" },
- { "ICM", "Intracom SA" },
- { "ADD", "Advanced Peripheral Devices Inc" },
- { "PRI", "Priva Hortimation BV" },
- { "ANL", "Analogix Semiconductor, Inc" },
- { "AVO", "Avocent Corporation" },
+ { "KYE", "KYE Syst Corporation" },
+ { "KYK", "Samsung Electronics America Inc" },
+ { "KZI", "K-Zone International co. Ltd." },
+ { "KZN", "K-Zone International" },
+ { "LAB", "ACT Labs Ltd" },
+ { "LAC", "LaCie" },
+ { "LAF", "Microline" },
+ { "LAG", "Laguna Systems" },
+ { "LAN", "Sodeman Lancom Inc" },
+ { "LAS", "LASAT Comm. A/S" },
+ { "LAV", "Lava Computer MFG Inc" },
+ { "LBO", "Lubosoft" },
+ { "LCC", "LCI" },
+ { "LCD", "Toshiba Matsushita Display Technology Co., Ltd" },
+ { "LCE", "La Commande Electronique" },
+ { "LCI", "Lite-On Communication Inc" },
+ { "LCM", "Latitude Comm." },
+ { "LCN", "LEXICON" },
+ { "LCS", "Longshine Electronics Company" },
+ { "LCT", "Labcal Technologies" },
+ { "LDT", "LogiDataTech Electronic GmbH" },
+ { "LEC", "Lectron Company Ltd" },
+ { "LED", "Long Engineering Design Inc" },
{ "LEG", "Legerity, Inc" },
- { "DTE", "Dimension Technologies, Inc." },
- { "WPA", "Matsushita Communication Industrial Co., Ltd." },
- { "OLV", "Olitec S.A." },
- { "RNB", "Rainbow Technologies" },
- { "LVI", "LVI Low Vision International AB" },
- { "LOC", "Locamation B.V." },
- { "TGC", "Toshiba Global Commerce Solutions, Inc." },
- { "STI", "Smart Tech Inc" },
- { "TLF", "Teleforce.,co,ltd" },
- { "PLC", "Pro-Log Corporation" },
- { "HSD", "HannStar Display Corp" },
- { "ONE", "Oneac Corporation" },
- { "CLE", "Classe Audio" },
- { "MCI", "Micronics Computers" },
- { "VTG", "Voice Technologies Group Inc" },
- { "VTI", "VLSI Tech Inc" },
- { "DAI", "DAIS SET Ltd." },
- { "UNM", "Unisys Corporation" },
- { "MCQ", "Mat's Computers" },
- { "IPC", "IPC Corporation" },
- { "ADE", "Arithmos, Inc." },
- { "PON", "Perpetual Technologies, LLC" },
- { "EXA", "Exabyte" },
- { "CHD", "ChangHong Electric Co.,Ltd" },
- { "FDT", "Fujitsu Display Technologies Corp." },
- { "DBL", "Doble Engineering Company" },
- { "CTP", "Computer Technology Corporation" },
- { "CLD", "COMMAT L.t.d." },
- { "BLI", "Busicom" },
- { "FRS", "South Mountain Technologies, LTD" },
- { "CDD", "Convergent Data Devices" },
- { "SHT", "Shin Ho Tech" },
- { "EPC", "Empac" },
- { "RDS", "Radius Inc" },
- { "NEX", "Nexgen Mediatech Inc.," },
- { "AGC", "Beijing Aerospace Golden Card Electronic Engineering Co.,Ltd." },
- { "MCP", "Magni Systems Inc" },
- { "WMO", "Westermo Teleindustri AB" },
- { "NMX", "Neomagic" },
- { "BDS", "Barco Display Systems" },
- { "RIV", "Rivulet Communications" },
- { "TRA", "TriTech Microelectronics International" },
- { "CYX", "Cyrix Corporation" },
- { "TCM", "3Com Corporation" },
- { "ZYP", "Zypcom Inc" },
- { "VIB", "Tatung UK Ltd" },
- { "IEI", "Interlink Electronics" },
- { "BGB", "Barco Graphics N.V" },
- { "ISP", "IntreSource Systems Pte Ltd" },
- { "BGT", "Budzetron Inc" },
- { "DPS", "Digital Processing Systems" },
- { "SSS", "S3 Inc" },
- { "AXB", "Adrienne Electronics Corporation" },
- { "HKA", "HONKO MFG. CO., LTD." },
- { "TPK", "TOPRE CORPORATION" },
- { "NPI", "Network Peripherals Inc" },
+ { "LEN", "Lenovo Group Limited" },
+ { "LEO", "First International Computer Inc" },
+ { "LEX", "Lexical Ltd" },
+ { "LGC", "Logic Ltd" },
+ { "LGI", "Logitech Inc" },
+ { "LGS", "LG Semicom Company Ltd" },
+ { "LGX", "Lasergraphics, Inc." },
+ { "LHA", "Lars Haagh ApS" },
+ { "LHE", "Lung Hwa Electronics Company Ltd" },
+ { "LHT", "Lighthouse Technologies Limited" },
+ { "LIN", "Lenovo Beijing Co. Ltd." },
+ { "LIP", "Linked IP GmbH" },
+ { "LIT", "Lithics Silicon Technology" },
+ { "LJX", "Datalogic Corporation" },
+ { "LKM", "Likom Technology Sdn. Bhd." },
+ { "LLL", "L-3 Communications" },
+ { "LMG", "Lucent Technologies" },
+ { "LMI", "Lexmark Int'l Inc" },
{ "LMP", "Leda Media Products" },
- { "MAI", "Mutoh America Inc" },
- { "ATX", "Athenix Corporation" },
- { "MVM", "SOBO VISION" },
- { "ALI", "Acer Labs" },
- { "HPR", "H.P.R. Electronics GmbH" },
- { "BIL", "Billion Electric Company Ltd" },
- { "CRO", "Extraordinary Technologies PTY Limited" },
- { "KTG", "Kayser-Threde GmbH" },
- { "SCI", "System Craft" },
- { "MVD", "Microvitec PLC" },
- { "IST", "Intersolve Technologies" },
- { "ICD", "ICD Inc" },
- { "PDS", "PD Systems International Ltd" },
- { "CPQ", "Compaq Computer Company" },
- { "QCL", "Quadrant Components Inc" },
- { "PRA", "PRO/AUTOMATION" },
+ { "LMT", "Laser Master" },
+ { "LND", "Land Computer Company Ltd" },
+ { "LNK", "Link Tech Inc" },
+ { "LNR", "Linear Systems Ltd." },
+ { "LNT", "LANETCO International" },
+ { "LNV", "Lenovo" },
+ { "LOC", "Locamation B.V." },
+ { "LOE", "Loewe Opta GmbH" },
+ { "LOG", "Logicode Technology Inc" },
+ { "LOL", "Litelogic Operations Ltd" },
+ { "LPE", "El-PUSK Co., Ltd." },
+ { "LPI", "Design Technology" },
+ { "LPL", "LG Philips" },
+ { "LSC", "LifeSize Communications" },
+ { "LSD", "Intersil Corporation" },
+ { "LSI", "Loughborough Sound Images" },
+ { "LSJ", "LSI Japan Company Ltd" },
+ { "LSL", "Logical Solutions" },
+ { "LSY", "LSI Systems Inc" },
+ { "LTC", "Labtec Inc" },
+ { "LTI", "Jongshine Tech Inc" },
+ { "LTK", "Lucidity Technology Company Ltd" },
+ { "LTN", "Litronic Inc" },
+ { "LTS", "LTS Scale LLC" },
+ { "LTV", "Leitch Technology International Inc." },
+ { "LTW", "Lightware, Inc" },
+ { "LUC", "Lucent Technologies" },
+ { "LUM", "Lumagen, Inc." },
+ { "LUX", "Luxxell Research Inc" },
+ { "LVI", "LVI Low Vision International AB" },
+ { "LWC", "Labway Corporation" },
+ { "LWR", "Lightware Visual Engineering" },
+ { "LWW", "Lanier Worldwide" },
+ { "LXC", "LXCO Technologies AG" },
+ { "LXN", "Luxeon" },
+ { "LXS", "ELEA CardWare" },
+ { "LZX", "Lightwell Company Ltd" },
{ "MAC", "MAC System Company Ltd" },
- { "TOP", "Orion Communications Co., Ltd." },
- { "AGT", "Agilent Technologies" },
- { "SWI", "Sierra Wireless Inc." },
- { "ATT", "AT&T" },
+ { "MAD", "Xedia Corporation" },
+ { "MAE", "Maestro Pty Ltd" },
+ { "MAG", "MAG InnoVision" },
+ { "MAI", "Mutoh America Inc" },
+ { "MAL", "Meridian Audio Ltd" },
+ { "MAN", "LGIC" },
+ { "MAS", "Mass Inc." },
+ { "MAT", "Matsushita Electric Ind. Company Ltd" },
+ { "MAX", "Rogen Tech Distribution Inc" },
+ { "MAY", "Maynard Electronics" },
+ { "MAZ", "MAZeT GmbH" },
+ { "MBC", "MBC" },
+ { "MBD", "Microbus PLC" },
+ { "MBM", "Marshall Electronics" },
+ { "MBV", "Moreton Bay" },
+ { "MCA", "American Nuclear Systems Inc" },
+ { "MCC", "Micro Industries" },
+ { "MCD", "McDATA Corporation" },
+ { "MCE", "Metz-Werke GmbH & Co KG" },
+ { "MCG", "Motorola Computer Group" },
+ { "MCI", "Micronics Computers" },
{ "MCL", "Motorola Communications Israel" },
- { "NCS", "Northgate Computer Systems" },
- { "RSX", "Rapid Tech Corporation" },
- { "ATV", "Office Depot, Inc." },
- { "MRD", "MicroDisplay Corporation" },
- { "SCH", "Schlumberger Cards" },
- { "ONW", "OPEN Networks Ltd" },
- { "DTC", "DTC Tech Corporation" },
- { "HYV", "Hynix Semiconductor" },
- { "WEL", "W-DEV" },
- { "AND", "Adtran Inc" },
- { "AMN", "Amimon LTD." },
- { "PXL", "The Moving Pixel Company" },
- { "ZCT", "ZeitControl cardsystems GmbH" },
- { "ALH", "AL Systems" },
- { "VCJ", "Victor Company of Japan, Limited" },
- { "COD", "CODAN Pty. Ltd." },
- { "TMM", "Time Management, Inc." },
- { "PPR", "PicPro" },
- { "INL", "InnoLux Display Corporation" },
- { "LTC", "Labtec Inc" },
- { "PNP", "Microsoft" },
- { "FIL", "Forefront Int'l Ltd" },
- { "OSR", "Oksori Company Ltd" },
- { "PEI", "PEI Electronics Inc" },
- { "EZP", "Storm Technology" },
- { "TCE", "Century Corporation" },
- { "KAR", "Karna" },
- { "ALS", "Texas Advanced optoelectronics Solutions, Inc" },
- { "COI", "Codec Inc." },
- { "NRT", "Beijing Northern Radiantelecom Co." },
- { "FTR", "Mediasonic" },
- { "SUN", "Sun Electronics Corporation" },
- { "OZO", "Tribe Computer Works Inc" },
+ { "MCM", "Metricom Inc" },
+ { "MCN", "Micron Electronics Inc" },
{ "MCO", "Motion Computing Inc." },
- { "UBI", "Ungermann-Bass Inc" },
- { "ZNI", "Zetinet Inc" },
- { "FUN", "sisel muhendislik" },
- { "RMP", "Research Machines" },
- { "DGT", "The Dearborn Group" },
- { "SPX", "Simplex Time Recorder Co." },
- { "COR", "Corollary Inc" },
- { "AMX", "AMX LLC" },
- { "AKY", "Askey Computer Corporation" },
- { "RAR", "Raritan, Inc." },
- { "VDS", "Vidisys GmbH & Company" },
- { "SCL", "Sigmacom Co., Ltd." },
- { "KSL", "Karn Solutions Ltd." },
- { "ACK", "Acksys" },
- { "NWS", "Newisys, Inc." },
- { "TRX", "Trex Enterprises" },
- { "BOI", "NINGBO BOIGLE DIGITAL TECHNOLOGY CO.,LTD" },
- { "NTT", "NTT Advanced Technology Corporation" },
- { "GUZ", "Guzik Technical Enterprises" },
- { "MDY", "Microdyne Inc" },
- { "EDM", "EDMI" },
- { "DTI", "Diversified Technology, Inc." },
- { "MMI", "Multimax" },
- { "SCB", "SeeCubic B.V." },
- { "UPS", "Systems Enhancement" },
- { "AKB", "Akebia Ltd" },
- { "NBT", "NingBo Bestwinning Technology CO., Ltd" },
- { "TCD", "Taicom Data Systems Co., Ltd." },
- { "XMM", "C3PO S.L." },
- { "OIM", "Option International" },
- { "DAV", "Davicom Semiconductor Inc" },
- { "CKJ", "Carina System Co., Ltd." },
- { "ATD", "Alpha Telecom Inc" },
- { "XQU", "SHANGHAI SVA-DAV ELECTRONICS CO., LTD" },
- { "KOL", "Kollmorgen Motion Technologies Group" },
- { "HWA", "Harris Canada Inc" },
- { "INE", "Inventec Electronics (M) Sdn. Bhd." },
- { "ORN", "ORION ELECTRIC CO., LTD." },
- { "KES", "Kesa Corporation" },
- { "CRC", "CONRAC GmbH" },
- { "AXT", "Axtend Technologies Inc" },
- { "NAX", "Naxos Tecnologia" },
- { "DAN", "Danelec Marine A/S" },
- { "ADP", "Adaptec Inc" },
- { "ICA", "ICA Inc" },
- { "AGL", "Argolis" },
- { "ECC", "ESSential Comm. Corporation" },
- { "AWS", "Wave Systems" },
- { "APN", "Appian Tech Inc" },
- { "DGI", "DIGI International" },
+ { "MCP", "Magni Systems Inc" },
+ { "MCQ", "Mat's Computers" },
+ { "MCR", "Marina Communicaitons" },
{ "MCS", "Micro Computer Systems" },
- { "ITA", "Itausa Export North America" },
- { "CII", "Cromack Industries Inc" },
- { "IPS", "IPS, Inc. (Intellectual Property Solutions, Inc.)" },
- { "KOE", "KOLTER ELECTRONIC" },
+ { "MCT", "Microtec" },
+ { "MDA", "Media4 Inc" },
+ { "MDC", "Midori Electronics" },
+ { "MDD", "MODIS" },
+ { "MDG", "Madge Networks" },
+ { "MDI", "Micro Design Inc" },
+ { "MDK", "Mediatek Corporation" },
+ { "MDO", "Panasonic" },
+ { "MDR", "Medar Inc" },
+ { "MDS", "Micro Display Systems Inc" },
+ { "MDT", "Magus Data Tech" },
+ { "MDV", "MET Development Inc" },
+ { "MDX", "MicroDatec GmbH" },
+ { "MDY", "Microdyne Inc" },
+ { "MEC", "Mega System Technologies Inc" },
+ { "MED", "Messeltronik Dresden GmbH" },
+ { "MEE", "Mitsubishi Electric Engineering Co., Ltd." },
+ { "MEG", "Abeam Tech Ltd" },
+ { "MEI", "Panasonic Industry Company" },
+ { "MEJ", "Mac-Eight Co., LTD." },
+ { "MEL", "Mitsubishi Electric Corporation" },
+ { "MEN", "MEN Mikroelectronik Nueruberg GmbH" },
{ "MEP", "Meld Technology" },
- { "IMA", "Imagraph" },
- { "DDV", "Delta Information Systems, Inc" },
- { "GML", "General Information Systems" },
- { "SSC", "Sierra Semiconductor Inc" },
- { "WNX", "Wincor Nixdorf International GmbH" },
- { "ABD", "Allen Bradley Company" },
- { "CMS", "CompuMaster Srl" },
- { "INK", "Indtek Co., Ltd." },
- { "DTT", "Design & Test Technology, Inc." },
+ { "MEQ", "Matelect Ltd." },
+ { "MET", "Metheus Corporation" },
+ { "MEX", "MSC Vertriebs GmbH" },
+ { "MFG", "MicroField Graphics Inc" },
+ { "MFI", "Micro Firmware" },
+ { "MFR", "MediaFire Corp." },
{ "MGA", "Mega System Technologies, Inc." },
- { "SMO", "STMicroelectronics" },
- { "SSI", "S-S Technology Inc" },
- { "CIR", "Cirrus Logic Inc" },
- { "EKC", "Eastman Kodak Company" },
- { "LNR", "Linear Systems Ltd." },
- { "VCM", "Vector Magnetics, LLC" },
- { "HKG", "Josef Heim KG" },
- { "ORG", "ORGA Kartensysteme GmbH" },
- { "ELG", "Elmeg GmbH Kommunikationstechnik" },
- { "NSI", "NISSEI ELECTRIC CO.,LTD" },
- { "RDM", "Tremon Enterprises Company Ltd" },
- { "HAI", "Haivision Systems Inc." },
- { "CIC", "Comm. Intelligence Corporation" },
- { "LTS", "LTS Scale LLC" },
- { "SAS", "Stores Automated Systems Inc" },
- { "OEC", "ORION ELECTRIC CO.,LTD" },
- { "BRG", "Bridge Information Co., Ltd" },
- { "SQT", "Sequent Computer Systems Inc" },
- { "CCI", "Cache" },
- { "PRX", "Proxima Corporation" },
- { "ADR", "Nasa Ames Research Center" },
- { "SNW", "Snell & Wilcox" },
- { "CDI", "Concept Development Inc" },
- { "SEA", "Seanix Technology Inc." },
- { "STY", "SDS Technologies" },
- { "PCA", "Philips BU Add On Card" },
- { "NYC", "nakayo telecommunications,inc." },
- { "JMT", "Micro Technical Company Ltd" },
+ { "MGC", "Mentor Graphics Corporation" },
+ { "MGE", "Schneider Electric S.A." },
+ { "MGL", "M-G Technology Ltd" },
+ { "MGT", "Megatech R & D Company" },
+ { "MIC", "Micom Communications Inc" },
+ { "MID", "miro Displays" },
+ { "MII", "Mitec Inc" },
+ { "MIL", "Marconi Instruments Ltd" },
+ { "MIM", "Mimio – A Newell Rubbermaid Company" },
+ { "MIN", "Minicom Digital Signage" },
+ { "MIP", "micronpc.com" },
+ { "MIR", "Miro Computer Prod." },
+ { "MIS", "Modular Industrial Solutions Inc" },
+ { "MIT", "MCM Industrial Technology GmbH" },
+ { "MJI", "MARANTZ JAPAN, INC." },
+ { "MJS", "MJS Designs" },
+ { "MKC", "Media Tek Inc." },
+ { "MKT", "MICROTEK Inc." },
+ { "MKV", "Trtheim Technology" },
+ { "MLD", "Deep Video Imaging Ltd" },
+ { "MLG", "Micrologica AG" },
+ { "MLI", "McIntosh Laboratory Inc." },
+ { "MLM", "Millennium Engineering Inc" },
+ { "MLN", "Mark Levinson" },
+ { "MLS", "Milestone EPE" },
+ { "MLX", "Mylex Corporation" },
+ { "MMA", "Micromedia AG" },
+ { "MMD", "Micromed Biotecnologia Ltd" },
+ { "MMF", "Minnesota Mining and Manufacturing" },
+ { "MMI", "Multimax" },
+ { "MMM", "Electronic Measurements" },
+ { "MMN", "MiniMan Inc" },
+ { "MMS", "MMS Electronics" },
+ { "MNC", "Mini Micro Methods Ltd" },
+ { "MNL", "Monorail Inc" },
+ { "MNP", "Microcom" },
+ { "MOD", "Modular Technology" },
+ { "MOM", "Momentum Data Systems" },
+ { "MOS", "Moses Corporation" },
+ { "MOT", "Motorola UDS" },
+ { "MPC", "M-Pact Inc" },
+ { "MPI", "Mediatrix Peripherals Inc" },
+ { "MPJ", "Microlab" },
+ { "MPL", "Maple Research Inst. Company Ltd" },
+ { "MPN", "Mainpine Limited" },
+ { "MPS", "mps Software GmbH" },
+ { "MPX", "Micropix Technologies, Ltd." },
+ { "MQP", "MultiQ Products AB" },
+ { "MRA", "Miranda Technologies Inc" },
+ { "MRC", "Marconi Simulation & Ty-Coch Way Training" },
+ { "MRD", "MicroDisplay Corporation" },
+ { "MRK", "Maruko & Company Ltd" },
+ { "MRL", "Miratel" },
+ { "MRO", "Medikro Oy" },
+ { "MRT", "Merging Technologies" },
+ { "MSA", "Micro Systemation AB" },
+ { "MSC", "Mouse Systems Corporation" },
+ { "MSD", "Datenerfassungs- und Informationssysteme" },
+ { "MSF", "M-Systems Flash Disk Pioneers" },
+ { "MSG", "MSI GmbH" },
+ { "MSH", "Microsoft" },
+ { "MSI", "Microstep" },
+ { "MSK", "Megasoft Inc" },
+ { "MSL", "MicroSlate Inc." },
+ { "MSM", "Advanced Digital Systems" },
+ { "MSP", "Mistral Solutions [P] Ltd." },
+ { "MSR", "MASPRO DENKOH Corp." },
+ { "MST", "MS Telematica" },
+ { "MSU", "motorola" },
+ { "MSV", "Mosgi Corporation" },
+ { "MSX", "Micomsoft Co., Ltd." },
+ { "MSY", "MicroTouch Systems Inc" },
+ { "MTB", "Media Technologies Ltd." },
+ { "MTC", "Mars-Tech Corporation" },
{ "MTD", "MindTech Display Co. Ltd" },
+ { "MTE", "MediaTec GmbH" },
+ { "MTH", "Micro-Tech Hearing Instruments" },
+ { "MTI", "Motorola Inc." },
+ { "MTK", "Microtek International Inc." },
+ { "MTL", "Mitel Corporation" },
+ { "MTM", "Motium" },
+ { "MTN", "Mtron Storage Technology Co., Ltd." },
+ { "MTR", "Mitron computer Inc" },
+ { "MTS", "Multi-Tech Systems" },
+ { "MTU", "Mark of the Unicorn Inc" },
+ { "MTX", "Matrox" },
+ { "MUD", "Multi-Dimension Institute" },
+ { "MUK", "mainpine limited" },
+ { "MVD", "Microvitec PLC" },
+ { "MVI", "Media Vision Inc" },
+ { "MVM", "SOBO VISION" },
+ { "MVS", "Microvision" },
+ { "MVX", "COM 1" },
+ { "MWI", "Multiwave Innovation Pte Ltd" },
+ { "MWR", "mware" },
+ { "MWY", "Microway Inc" },
+ { "MXD", "MaxData Computer GmbH & Co.KG" },
+ { "MXI", "Macronix Inc" },
+ { "MXL", "Hitachi Maxell, Ltd." },
+ { "MXP", "Maxpeed Corporation" },
+ { "MXT", "Maxtech Corporation" },
+ { "MXV", "MaxVision Corporation" },
+ { "MYA", "Monydata" },
+ { "MYR", "Myriad Solutions Ltd" },
+ { "MYX", "Micronyx Inc" },
+ { "NAC", "Ncast Corporation" },
+ { "NAD", "NAD Electronics" },
+ { "NAK", "Nakano Engineering Co.,Ltd." },
+ { "NAL", "Network Alchemy" },
+ { "NAT", "NaturalPoint Inc." },
+ { "NAV", "Navigation Corporation" },
+ { "NAX", "Naxos Tecnologia" },
+ { "NBL", "N*Able Technologies Inc" },
+ { "NBS", "National Key Lab. on ISN" },
+ { "NBT", "NingBo Bestwinning Technology CO., Ltd" },
+ { "NCA", "Nixdorf Company" },
+ { "NCC", "NCR Corporation" },
+ { "NCE", "Norcent Technology, Inc." },
+ { "NCI", "NewCom Inc" },
+ { "NCL", "NetComm Ltd" },
+ { "NCR", "NCR Electronics" },
+ { "NCS", "Northgate Computer Systems" },
+ { "NCT", "NEC CustomTechnica, Ltd." },
+ { "NDC", "National DataComm Corporaiton" },
+ { "NDI", "National Display Systems" },
+ { "NDK", "Naitoh Densei CO., LTD." },
+ { "NDL", "Network Designers" },
+ { "NDS", "Nokia Data" },
+ { "NEC", "NEC Corporation" },
+ { "NEO", "NEO TELECOM CO.,LTD." },
+ { "NET", "Mettler Toledo" },
+ { "NEU", "NEUROTEC - EMPRESA DE PESQUISA E DESENVOLVIMENTO EM BIOMEDICINA" },
+ { "NEX", "Nexgen Mediatech Inc.," },
+ { "NFC", "BTC Korea Co., Ltd" },
+ { "NFS", "Number Five Software" },
+ { "NGC", "Network General" },
+ { "NGS", "A D S Exports" },
+ { "NHT", "Vinci Labs" },
+ { "NIC", "National Instruments Corporation" },
+ { "NIS", "Nissei Electric Company" },
+ { "NIT", "Network Info Technology" },
+ { "NIX", "Seanix Technology Inc" },
+ { "NLC", "Next Level Communications" },
+ { "NME", "Navico, Inc." },
+ { "NMP", "Nokia Mobile Phones" },
+ { "NMS", "Natural Micro System" },
+ { "NMV", "NEC-Mitsubishi Electric Visual Systems Corporation" },
+ { "NMX", "Neomagic" },
+ { "NNC", "NNC" },
+ { "NOE", "NordicEye AB" },
+ { "NOI", "North Invent A/S" },
+ { "NOK", "Nokia Display Products" },
+ { "NOR", "Norand Corporation" },
+ { "NOT", "Not Limited Inc" },
+ { "NPI", "Network Peripherals Inc" },
+ { "NRL", "U.S. Naval Research Lab" },
+ { "NRT", "Beijing Northern Radiantelecom Co." },
+ { "NRV", "Taugagreining hf" },
+ { "NSC", "National Semiconductor Corporation" },
+ { "NSI", "NISSEI ELECTRIC CO.,LTD" },
{ "NSP", "Nspire System Inc." },
- { "DSD", "DS Multimedia Pte Ltd" },
- { "PBI", "Pitney Bowes" },
- { "ARO", "Poso International B.V." },
- { "TTE", "TTE, Inc." },
- { "DDA", "DA2 Technologies Corporation" },
- { "MAS", "Mass Inc." },
- { "LAC", "LaCie" },
- { "CRX", "Cyrix Corporation" },
- { "EMO", "ELMO COMPANY, LIMITED" },
- { "OSP", "OPTI-UPS Corporation" },
- { "GED", "General Dynamics C4 Systems" },
- { "PPI", "Practical Peripherals" },
- { "VPI", "Video Products Inc" },
- { "TOS", "Toshiba Corporation" },
- { "ASL", "AccuScene Corporation Ltd" },
- { "ANT", "Ace CAD Enterprise Company Ltd" },
- { "GRV", "Advanced Gravis" },
- { "ANO", "Anorad Corporation" },
- { "LNK", "Link Tech Inc" },
- { "DIG", "Digicom S.p.A." },
- { "ALC", "Altec Corporation" },
- { "IAI", "Integration Associates, Inc." },
- { "APG", "Horner Electric Inc" },
- { "TWK", "TOWITOKO electronics GmbH" },
- { "BRI", "Boca Research Inc" },
- { "SVS", "SVSI" },
- { "QCI", "Quanta Computer Inc" },
- { "MDD", "MODIS" },
- { "PDT", "PDTS - Prozessdatentechnik und Systeme" },
- { "IMP", "Impression Products Incorporated" },
- { "EXI", "Exide Electronics" },
- { "WNV", "Winnov L.P." },
- { "ALG", "Realtek Semiconductor Corp." },
- { "ESA", "Elbit Systems of America" },
- { "OLC", "Olicom A/S" },
- { "DPX", "DpiX, Inc." },
- { "GSB", "NIPPONDENCHI CO,.LTD" },
- { "MCA", "American Nuclear Systems Inc" },
- { "EST", "Embedded Solution Technology" },
- { "ADX", "Adax Inc" },
- { "MSA", "Micro Systemation AB" },
- { "HDV", "Holografika kft." },
- { "GIP", "GI Provision Ltd" },
- { "XTN", "X-10 (USA) Inc" },
- { "VEC", "Vector Informatik GmbH" },
- { "DTN", "Datang Telephone Co" },
- { "CST", "CSTI Inc" },
- { "ECO", "Echo Speech Corporation" },
- { "TDD", "Tandberg Data Display AS" },
+ { "NSS", "Newport Systems Solutions" },
+ { "NST", "Network Security Technology Co" },
+ { "NTC", "NeoTech S.R.L" },
+ { "NTI", "New Tech Int'l Company" },
+ { "NTL", "National Transcomm. Ltd" },
+ { "NTN", "Nuvoton Technology Corporation" },
+ { "NTR", "N-trig Innovative Technologies, Inc." },
+ { "NTS", "Nits Technology Inc." },
+ { "NTT", "NTT Advanced Technology Corporation" },
+ { "NTW", "Networth Inc" },
+ { "NTX", "Netaccess Inc" },
+ { "NUG", "NU Technology, Inc." },
+ { "NUI", "NU Inc." },
+ { "NVC", "NetVision Corporation" },
+ { "NVD", "Nvidia" },
+ { "NVI", "NuVision US, Inc." },
{ "NVL", "Novell Inc" },
- { "CHT", "Chunghwa Picture Tubes,LTD." },
- { "SCP", "Scriptel Corporation" },
- { "TMS", "Trident Microsystems Ltd" },
- { "ABO", "D-Link Systems Inc" },
- { "JTY", "jetway security micro,inc" },
- { "LSD", "Intersil Corporation" },
- { "SEP", "SEP Eletronica Ltda." },
- { "SHI", "Jiangsu Shinco Electronic Group Co., Ltd" },
- { "FTG", "FTG Data Systems" },
- { "ESN", "eSATURNUS" },
- { "DJE", "Capstone Visual Product Development" },
- { "BEC", "Elektro Beckhoff GmbH" },
- { "FVC", "First Virtual Corporation" },
- { "JUP", "Jupiter Systems" },
- { "XNT", "XN Technologies, Inc." },
- { "RTK", "DO NOT USE - RTK" },
- { "ACL", "Apricot Computers" },
- { "TAA", "Tandberg" },
- { "WIP", "Wipro Infotech" },
- { "KRL", "Krell Industries Inc." },
- { "INO", "Innolab Pte Ltd" },
- { "ELT", "Element Labs, Inc." },
- { "KTE", "K-Tech" },
- { "CVA", "Covia Inc." },
- { "SIC", "Sysmate Corporation" },
- { "STH", "Semtech Corporation" },
- { "ACD", "AWETA BV" },
- { "EHN", "Enhansoft" },
- { "VMI", "Vermont Microsystems" },
- { "TTC", "Telecommunications Techniques Corporation" },
- { "KYE", "KYE Syst Corporation" },
- { "QDI", "Quantum Data Incorporated" },
- { "ELL", "Electrosonic Ltd" },
- { "FLE", "ADTI Media, Inc" },
- { "KTD", "Takahata Electronics Co.,Ltd." },
- { "MAL", "Meridian Audio Ltd" },
- { "TRV", "Trivisio Prototyping GmbH" },
- { "TWH", "Twinhead International Corporation" },
- { "SYP", "SYPRO Co Ltd" },
- { "GCC", "GCC Technologies Inc" },
- { "POR", "Portalis LC" },
- { "PIM", "Prism, LLC" },
- { "MLX", "Mylex Corporation" },
+ { "NVT", "Navatek Engineering Corporation" },
+ { "NWC", "NW Computer Engineering" },
+ { "NWP", "NovaWeb Technologies Inc" },
+ { "NWS", "Newisys, Inc." },
+ { "NXC", "NextCom K.K." },
+ { "NXG", "Nexgen" },
+ { "NXP", "NXP Semiconductors bv." },
+ { "NXQ", "Nexiq Technologies, Inc." },
+ { "NXS", "Technology Nexus Secure Open Systems AB" },
+ { "NYC", "nakayo telecommunications,inc." },
+ { "OAK", "Oak Tech Inc" },
+ { "OAS", "Oasys Technology Company" },
+ { "OBS", "Optibase Technologies" },
+ { "OCD", "Macraigor Systems Inc" },
+ { "OCN", "Olfan" },
+ { "OCS", "Open Connect Solutions" },
+ { "ODM", "ODME Inc." },
+ { "ODR", "Odrac" },
+ { "OEC", "ORION ELECTRIC CO.,LTD" },
+ { "OEI", "Optum Engineering Inc." },
+ { "OIC", "Option Industrial Computers" },
+ { "OIM", "Option International" },
+ { "OIN", "Option International" },
+ { "OKI", "OKI Electric Industrial Company Ltd" },
+ { "OLC", "Olicom A/S" },
+ { "OLD", "Olidata S.p.A." },
+ { "OLI", "Olivetti" },
+ { "OLT", "Olitec S.A." },
+ { "OLV", "Olitec S.A." },
+ { "OLY", "OLYMPUS CORPORATION" },
+ { "OMC", "OBJIX Multimedia Corporation" },
+ { "OMN", "Omnitel" },
+ { "OMR", "Omron Corporation" },
+ { "ONE", "Oneac Corporation" },
+ { "ONK", "ONKYO Corporation" },
{ "ONL", "OnLive, Inc" },
- { "NIS", "Nissei Electric Company" },
- { "ISM", "Image Stream Medical" },
- { "EPS", "KEPS" },
- { "PAC", "Pacific Avionics Corporation" },
- { "AXC", "AXIOMTEK CO., LTD." },
- { "DYX", "Dynax Electronics (HK) Ltd" },
- { "WEB", "WebGear Inc" },
- { "RIT", "Ritech Inc" },
- { "INI", "Initio Corporation" },
- { "LBO", "Lubosoft" },
- { "PGM", "Paradigm Advanced Research Centre" },
+ { "ONS", "On Systems Inc" },
+ { "ONW", "OPEN Networks Ltd" },
+ { "ONX", "SOMELEC Z.I. Du Vert Galanta" },
+ { "OOS", "OSRAM" },
+ { "OPC", "Opcode Inc" },
+ { "OPI", "D.N.S. Corporation" },
+ { "OPP", "OPPO Digital, Inc." },
+ { "OPT", "OPTi Inc" },
+ { "OPV", "Optivision Inc" },
+ { "OQI", "Oksori Company Ltd" },
+ { "ORG", "ORGA Kartensysteme GmbH" },
+ { "ORI", "OSR Open Systems Resources, Inc." },
+ { "ORN", "ORION ELECTRIC CO., LTD." },
{ "OSA", "OSAKA Micro Computer, Inc." },
- { "SIN", "Singular Technology Co., Ltd." },
- { "CIN", "Citron GmbH" },
+ { "OSP", "OPTI-UPS Corporation" },
+ { "OSR", "Oksori Company Ltd" },
{ "OTB", "outsidetheboxstuff.com" },
- { "ARL", "Arlotto Comnet Inc" },
- { "HOB", "HOB Electronic GmbH" },
- { "QQQ", "Chuomusen Co., Ltd." },
- { "AXE", "D-Link Systems Inc" },
- { "CCC", "C-Cube Microsystems" },
- { "CPT", "cPATH" },
- { "SEM", "Samsung Electronics Company Ltd" },
- { "PVI", "Prime view international Co., Ltd" },
- { "TAT", "Teleliaison Inc" },
- { "SON", "Sony" },
- { "ITT", "I&T Telecom." },
- { "SLM", "Solomon Technology Corporation" },
- { "MAN", "LGIC" },
- { "AIX", "ALTINEX, INC." },
- { "ASP", "ASP Microelectronics Ltd" },
- { "VUT", "Vutrix (UK) Ltd" },
- { "MTE", "MediaTec GmbH" },
- { "UPP", "UPPI" },
- { "DCM", "DCM Data Products" },
- { "DYC", "Dycam Inc" },
- { "DAK", "Daktronics" },
- { "JAZ", "Carrera Computer Inc" },
- { "FOX", "HON HAI PRECISON IND.CO.,LTD." },
- { "UEI", "Universal Electronics Inc" },
- { "OPI", "D.N.S. Corporation" },
- { "CXT", "Conexant Systems" },
- { "VTK", "Viewteck Co., Ltd." },
- { "AVL", "Avalue Technology Inc." },
- { "TSI", "TeleVideo Systems" },
+ { "OTI", "Orchid Technology" },
+ { "OTM", "Optoma Corporation" },
+ { "OTT", "OPTO22, Inc." },
+ { "OUK", "OUK Company Ltd" },
+ { "OVR", "Oculus VR, Inc." },
+ { "OWL", "Mediacom Technologies Pte Ltd" },
+ { "OXU", "Oxus Research S.A." },
+ { "OYO", "Shadow Systems" },
+ { "OZC", "OZ Corporation" },
+ { "OZO", "Tribe Computer Works Inc" },
+ { "PAC", "Pacific Avionics Corporation" },
+ { "PAD", "Promotion and Display Technology Ltd." },
+ { "PAK", "Many CNC System Co., Ltd." },
+ { "PAM", "Peter Antesberger Messtechnik" },
{ "PAN", "The Panda Project" },
- { "CED", "Cambridge Electronic Design Ltd" },
- { "RUP", "Ups Manufactoring s.r.l." },
- { "MIP", "micronpc.com" },
- { "REM", "SCI Systems Inc." },
- { "NSS", "Newport Systems Solutions" },
- { "FBI", "Interface Corporation" },
- { "FER", "Ferranti Int'L" },
- { "DLG", "Digital-Logic GmbH" },
- { "TSY", "TouchSystems" },
+ { "PAR", "Parallan Comp Inc" },
+ { "PBI", "Pitney Bowes" },
+ { "PBL", "Packard Bell Electronics" },
+ { "PBN", "Packard Bell NEC" },
+ { "PBV", "Pitney Bowes" },
+ { "PCA", "Philips BU Add On Card" },
+ { "PCB", "OCTAL S.A." },
+ { "PCC", "PowerCom Technology Company Ltd" },
+ { "PCG", "First Industrial Computer Inc" },
+ { "PCI", "Pioneer Computer Inc" },
+ { "PCK", "PCBANK21" },
+ { "PCL", "pentel.co.,ltd" },
+ { "PCM", "PCM Systems Corporation" },
+ { "PCO", "Performance Concepts Inc.," },
+ { "PCP", "Procomp USA Inc" },
+ { "PCS", "TOSHIBA PERSONAL COMPUTER SYSTEM CORPRATION" },
+ { "PCT", "PC-Tel Inc" },
+ { "PCW", "Pacific CommWare Inc" },
+ { "PCX", "PC Xperten" },
+ { "PDM", "Psion Dacom Plc." },
+ { "PDN", "AT&T Paradyne" },
+ { "PDR", "Pure Data Inc" },
+ { "PDS", "PD Systems International Ltd" },
+ { "PDT", "PDTS - Prozessdatentechnik und Systeme" },
+ { "PDV", "Prodrive B.V." },
+ { "PEC", "POTRANS Electrical Corp." },
+ { "PEI", "PEI Electronics Inc" },
+ { "PEL", "Primax Electric Ltd" },
+ { "PEN", "Interactive Computer Products Inc" },
+ { "PEP", "Peppercon AG" },
+ { "PER", "Perceptive Signal Technologies" },
+ { "PET", "Practical Electronic Tools" },
+ { "PFT", "Telia ProSoft AB" },
+ { "PGI", "PACSGEAR, Inc." },
+ { "PGM", "Paradigm Advanced Research Centre" },
+ { "PGP", "propagamma kommunikation" },
+ { "PGS", "Princeton Graphic Systems" },
+ { "PHC", "Pijnenburg Beheer N.V." },
+ { "PHE", "Philips Medical Systems Boeblingen GmbH" },
+ { "PHI", "DO NOT USE - PHI" },
+ { "PHL", "Philips Consumer Electronics Company" },
+ { "PHO", "Photonics Systems Inc." },
+ { "PHS", "Philips Communication Systems" },
+ { "PHY", "Phylon Communications" },
+ { "PIE", "Pacific Image Electronics Company Ltd" },
+ { "PIM", "Prism, LLC" },
{ "PIO", "Pioneer Electronic Corporation" },
+ { "PIX", "Pixie Tech Inc" },
+ { "PJA", "Projecta" },
+ { "PJD", "Projectiondesign AS" },
+ { "PJT", "Pan Jit International Inc." },
+ { "PKA", "Acco UK ltd." },
+ { "PLC", "Pro-Log Corporation" },
+ { "PLF", "Panasonic Avionics Corporation" },
+ { "PLM", "PROLINK Microsystems Corp." },
+ { "PLT", "PT Hartono Istana Teknologi" },
+ { "PLV", "PLUS Vision Corp." },
+ { "PLX", "Parallax Graphics" },
+ { "PLY", "Polycom Inc." },
+ { "PMC", "PMC Consumer Electronics Ltd" },
+ { "PMD", "TDK USA Corporation" },
+ { "PMM", "Point Multimedia System" },
+ { "PMT", "Promate Electronic Co., Ltd." },
+ { "PMX", "Photomatrix" },
{ "PNG", "P.I. Engineering Inc" },
- { "OIN", "Option International" },
- { "RED", "Research Electronics Development Inc" },
- { "NOI", "North Invent A/S" },
- { "MAY", "Maynard Electronics" },
- { "BTO", "BioTao Ltd" },
- { "ZYD", "Zydacron Inc" },
- { "KCD", "Chunichi Denshi Co.,LTD." },
- { "TTI", "Trenton Terminals Inc" },
- { "TRD", "Trident Microsystem Inc" },
- { "TDP", "3D Perception" },
- { "TER", "TerraTec Electronic GmbH" },
- { "AEM", "ASEM S.p.A." },
- { "IBI", "INBINE.CO.LTD" },
- { "ECK", "Eugene Chukhlomin Sole Proprietorship, d.b.a." },
- { "AVT", "Avtek (Electronics) Pty Ltd" },
+ { "PNL", "Panelview, Inc." },
+ { "PNP", "Microsoft" },
+ { "PNR", "Planar Systems, Inc." },
+ { "PNS", "PanaScope" },
+ { "PNX", "Phoenix Technologies, Ltd." },
+ { "POL", "PolyComp (PTY) Ltd." },
+ { "PON", "Perpetual Technologies, LLC" },
+ { "POR", "Portalis LC" },
+ { "PPC", "Phoenixtec Power Company Ltd" },
+ { "PPD", "MEPhI" },
+ { "PPI", "Practical Peripherals" },
+ { "PPM", "Clinton Electronics Corp." },
+ { "PPP", "Purup Prepress AS" },
+ { "PPR", "PicPro" },
+ { "PPX", "Perceptive Pixel Inc." },
+ { "PQI", "Pixel Qi" },
+ { "PRA", "PRO/AUTOMATION" },
+ { "PRC", "PerComm" },
+ { "PRD", "Praim S.R.L." },
+ { "PRF", "Digital Electronics Corporation" },
+ { "PRG", "The Phoenix Research Group Inc" },
+ { "PRI", "Priva Hortimation BV" },
+ { "PRM", "Prometheus" },
+ { "PRO", "Proteon" },
+ { "PRS", "Leutron Vision" },
+ { "PRT", "Parade Technologies, Ltd." },
+ { "PRX", "Proxima Corporation" },
+ { "PSA", "Advanced Signal Processing Technologies" },
+ { "PSC", "Philips Semiconductors" },
+ { "PSD", "Peus-Systems GmbH" },
+ { "PSE", "Practical Solutions Pte., Ltd." },
+ { "PSI", "PSI-Perceptive Solutions Inc" },
+ { "PSL", "Perle Systems Limited" },
+ { "PSM", "Prosum" },
{ "PST", "Global Data SA" },
- { "FPS", "Deltec Corporation" },
- { "SHP", "Sharp Corporation" },
+ { "PSY", "Prodea Systems Inc." },
+ { "PTA", "PAR Tech Inc." },
+ { "PTC", "PS Technology Corporation" },
+ { "PTG", "Cipher Systems Inc" },
+ { "PTH", "Pathlight Technology Inc" },
+ { "PTI", "Promise Technology Inc" },
+ { "PTL", "Pantel Inc" },
+ { "PTS", "Plain Tree Systems Inc" },
+ { "PTW", "DO NOT USE - PTW" },
+ { "PUL", "Pulse-Eight Ltd" },
+ { "PVC", "DO NOT USE - PVC" },
+ { "PVG", "Proview Global Co., Ltd" },
+ { "PVI", "Prime view international Co., Ltd" },
+ { "PVM", "Penta Studiotechnik GmbH" },
+ { "PVN", "Pixel Vision" },
+ { "PVP", "Klos Technologies, Inc." },
+ { "PXC", "Phoenix Contact" },
+ { "PXE", "PIXELA CORPORATION" },
+ { "PXL", "The Moving Pixel Company" },
+ { "PXM", "Proxim Inc" },
+ { "QCC", "QuakeCom Company Ltd" },
+ { "QCH", "Metronics Inc" },
+ { "QCI", "Quanta Computer Inc" },
+ { "QCK", "Quick Corporation" },
+ { "QCL", "Quadrant Components Inc" },
+ { "QCP", "Qualcomm Inc" },
+ { "QDI", "Quantum Data Incorporated" },
+ { "QDM", "Quadram" },
+ { "QDS", "Quanta Display Inc." },
+ { "QFF", "Padix Co., Inc." },
+ { "QFI", "Quickflex, Inc" },
+ { "QLC", "Q-Logic" },
+ { "QQQ", "Chuomusen Co., Ltd." },
+ { "QSI", "Quantum Solutions, Inc." },
+ { "QTD", "Quantum 3D Inc" },
+ { "QTH", "Questech Ltd" },
+ { "QTI", "Quicknet Technologies Inc" },
+ { "QTM", "Quantum" },
+ { "QTR", "Qtronix Corporation" },
+ { "QUA", "Quatographic AG" },
+ { "QUE", "Questra Consulting" },
+ { "QVU", "Quartics" },
+ { "RAC", "Racore Computer Products Inc" },
+ { "RAD", "Radisys Corporation" },
+ { "RAI", "Rockwell Automation/Intecolor" },
+ { "RAN", "Rancho Tech Inc" },
+ { "RAR", "Raritan, Inc." },
+ { "RAS", "RAScom Inc" },
+ { "RAT", "Rent-A-Tech" },
+ { "RAY", "Raylar Design, Inc." },
+ { "RCE", "Parc d'Activite des Bellevues" },
+ { "RCH", "Reach Technology Inc" },
+ { "RCI", "RC International" },
+ { "RCN", "Radio Consult SRL" },
+ { "RCO", "Rockwell Collins" },
+ { "RDI", "Rainbow Displays, Inc." },
+ { "RDM", "Tremon Enterprises Company Ltd" },
{ "RDN", "RADIODATA GmbH" },
- { "TRC", "Trioc AB" },
- { "ABE", "Alcatel Bell" },
- { "VCX", "VCONEX" },
- { "PBL", "Packard Bell Electronics" },
- { "TLK", "Telelink AG" },
- { "DMM", "Dimond Multimedia Systems Inc" },
- { "IGM", "IGM Communi" },
- { "KFC", "SCD Tech" },
- { "GUD", "Guntermann & Drunck GmbH" },
- { "MDA", "Media4 Inc" },
- { "VWB", "Vweb Corp." },
- { "ISG", "Insignia Solutions Inc" },
- { "AMS", "ARMSTEL, Inc." },
- { "NTL", "National Transcomm. Ltd" },
- { "LSJ", "LSI Japan Company Ltd" },
- { "NDL", "Network Designers" },
- { "DIA", "Diadem" },
- { "SDX", "SDX Business Systems Ltd" },
- { "LPL", "LG Philips" },
- { "CAG", "CalComp" },
- { "FZC", "Founder Group Shenzhen Co." },
- { "PCX", "PC Xperten" },
- { "TSF", "Racal-Airtech Software Forge Ltd" },
+ { "RDS", "Radius Inc" },
+ { "REA", "Real D" },
+ { "REC", "ReCom" },
+ { "RED", "Research Electronics Development Inc" },
+ { "REF", "Reflectivity, Inc." },
+ { "REH", "Rehan Electronics Ltd." },
+ { "REL", "Reliance Electric Ind Corporation" },
+ { "REM", "SCI Systems Inc." },
+ { "REN", "Renesas Technology Corp." },
+ { "RES", "ResMed Pty Ltd" },
+ { "RET", "Resonance Technology, Inc." },
+ { "REX", "RATOC Systems, Inc." },
+ { "RGB", "RGB Spectrum" },
{ "RGL", "Robertson Geologging Ltd" },
- { "MSD", "Datenerfassungs- und Informationssysteme" },
- { "NVC", "NetVision Corporation" },
- { "SKD", "Schneider & Koch" },
- { "CRS", "Crescendo Communication Inc" },
- { "AXI", "American Magnetics" },
- { "HRS", "Harris Semiconductor" },
- { "AEN", "Avencall" },
- { "TCL", "Technical Concepts Ltd" },
- { "SST", "SystemSoft Corporation" },
- { "OMN", "Omnitel" },
- { "GCI", "Gateway Comm. Inc" },
- { "SEN", "Sencore" },
- { "MDT", "Magus Data Tech" },
- { "ALN", "Alana Technologies" },
- { "AVD", "Avid Electronics Corporation" },
- { "DOM", "Dome Imaging Systems" },
- { "KBL", "Kobil Systems GmbH" },
- { "ITS", "IDTECH" },
- { "CGS", "Chyron Corp" },
- { "CYV", "Cyviz AS" },
- { "CSO", "California Institute of Technology" },
- { "ADT", "Aved Display Technologies" },
- { "ACP", "Aspen Tech Inc" },
- { "AKI", "AKIA Corporation" },
- { "LCT", "Labcal Technologies" },
- { "NDS", "Nokia Data" },
- { "WCS", "Woodwind Communications Systems Inc" },
- { "XFG", "Jan Strapko - FOTO" },
- { "CPI", "Computer Peripherals Inc" },
- { "FCG", "First International Computer Ltd" },
- { "EVE", "Advanced Micro Peripherals Ltd" },
- { "ATO", "ASTRO DESIGN, INC." },
- { "SGW", "Shanghai Guowei Science and Technology Co., Ltd." },
- { "CNB", "American Power Conversion" },
- { "TCX", "FREEMARS Heavy Industries" },
- { "ITN", "The NTI Group" },
- { "HWD", "Highwater Designs Ltd" },
- { "NUG", "NU Technology, Inc." },
- { "ISL", "Isolation Systems" },
- { "CIL", "Citicom Infotech Private Limited" },
- { "IOT", "I/OTech Inc" },
- { "GET", "Getac Technology Corporation" },
- { "ULT", "Ultra Network Tech" },
- { "TVV", "TV1 GmbH" },
- { "OWL", "Mediacom Technologies Pte Ltd" },
- { "TMX", "Thermotrex Corporation" },
- { "ARC", "Alta Research Corporation" },
- { "SEL", "Way2Call Communications" },
- { "ELS", "ELSA GmbH" },
- { "STD", "STD Computer Inc" },
- { "GST", "Graphic SystemTechnology" },
- { "SME", "Sysmate Company" },
- { "ARS", "Arescom Inc" },
- { "SCN", "Scanport, Inc." },
- { "CTX", "Creatix Polymedia GmbH" },
- { "DIM", "dPict Imaging, Inc." },
- { "MDI", "Micro Design Inc" },
+ { "RHD", "RightHand Technologies" },
+ { "RHM", "Rohm Company Ltd" },
+ { "RHT", "Red Hat, Inc." },
+ { "RIC", "RICOH COMPANY, LTD." },
+ { "RII", "Racal Interlan Inc" },
+ { "RIO", "Rios Systems Company Ltd" },
+ { "RIT", "Ritech Inc" },
+ { "RIV", "Rivulet Communications" },
+ { "RJA", "Roland Corporation" },
+ { "RJS", "Advanced Engineering" },
+ { "RKC", "Reakin Technolohy Corporation" },
+ { "RLD", "MEPCO" },
+ { "RLN", "RadioLAN Inc" },
+ { "RMC", "Raritan Computer, Inc" },
+ { "RMP", "Research Machines" },
+ { "RMT", "Roper Mobile" },
+ { "RNB", "Rainbow Technologies" },
+ { "ROB", "Robust Electronics GmbH" },
+ { "ROH", "Rohm Co., Ltd." },
+ { "ROK", "Rockwell International" },
+ { "ROP", "Roper International Ltd" },
+ { "ROS", "Rohde & Schwarz" },
+ { "RPI", "RoomPro Technologies" },
+ { "RPT", "R.P.T.Intergroups" },
+ { "RRI", "Radicom Research Inc" },
+ { "RSC", "PhotoTelesis" },
+ { "RSH", "ADC-Centre" },
+ { "RSI", "Rampage Systems Inc" },
+ { "RSN", "Radiospire Networks, Inc." },
+ { "RSQ", "R Squared" },
+ { "RSS", "Rockwell Semiconductor Systems" },
+ { "RSV", "Ross Video Ltd" },
+ { "RSX", "Rapid Tech Corporation" },
+ { "RTC", "Relia Technologies" },
+ { "RTI", "Rancho Tech Inc" },
+ { "RTK", "DO NOT USE - RTK" },
+ { "RTL", "Realtek Semiconductor Company Ltd" },
+ { "RTS", "Raintree Systems" },
+ { "RUN", "RUNCO International" },
+ { "RUP", "Ups Manufactoring s.r.l." },
+ { "RVC", "RSI Systems Inc" },
+ { "RVI", "Realvision Inc" },
+ { "RVL", "Reveal Computer Prod" },
+ { "RWC", "Red Wing Corporation" },
+ { "RXT", "Tectona SoftSolutions (P) Ltd.," },
+ { "SAA", "Sanritz Automation Co.,Ltd." },
+ { "SAE", "Saab Aerotech" },
+ { "SAG", "Sedlbauer" },
+ { "SAI", "Sage Inc" },
+ { "SAK", "Saitek Ltd" },
+ { "SAM", "Samsung Electric Company" },
+ { "SAN", "Sanyo Electric Co.,Ltd." },
+ { "SAS", "Stores Automated Systems Inc" },
+ { "SAT", "Shuttle Tech" },
+ { "SBC", "Shanghai Bell Telephone Equip Mfg Co" },
+ { "SBD", "Softbed - Consulting & Development Ltd" },
+ { "SBI", "SMART Technologies Inc." },
+ { "SBS", "SBS-or Industrial Computers GmbH" },
+ { "SBT", "Senseboard Technologies AB" },
+ { "SCB", "SeeCubic B.V." },
+ { "SCC", "SORD Computer Corporation" },
+ { "SCD", "Sanyo Electric Company Ltd" },
+ { "SCE", "Sun Corporation" },
+ { "SCH", "Schlumberger Cards" },
+ { "SCI", "System Craft" },
+ { "SCL", "Sigmacom Co., Ltd." },
{ "SCM", "SCM Microsystems Inc" },
- { "CEA", "Consumer Electronics Association" },
- { "OTI", "Orchid Technology" },
- { "ADK", "Adtek System Science Company Ltd" },
- { "ETC", "Everton Technology Company Ltd" },
- { "PCO", "Performance Concepts Inc.," },
- { "DMC", "Dune Microsystems Corporation" },
- { "SGM", "SAGEM" },
- { "OBS", "Optibase Technologies" },
- { "PMX", "Photomatrix" },
+ { "SCN", "Scanport, Inc." },
+ { "SCO", "SORCUS Computer GmbH" },
+ { "SCP", "Scriptel Corporation" },
+ { "SCR", "Systran Corporation" },
+ { "SCS", "Nanomach Anstalt" },
+ { "SCT", "Smart Card Technology" },
+ { "SDA", "SAT (Societe Anonyme)" },
+ { "SDD", "Intrada-SDD Ltd" },
+ { "SDE", "Sherwood Digital Electronics Corporation" },
+ { "SDF", "SODIFF E&T CO., Ltd." },
+ { "SDH", "Communications Specialies, Inc." },
{ "SDI", "Samtron Displays Inc" },
- { "GMM", "GMM Research Inc" },
- { "DUN", "NCR Corporation" },
- { "CAL", "Acon" },
- { "MIR", "Miro Computer Prod." },
- { "PEN", "Interactive Computer Products Inc" },
- { "CRL", "Creative Logic" },
- { "SBT", "Senseboard Technologies AB" },
- { "AST", "AST Research Inc" },
- { "INS", "Ines GmbH" },
+ { "SDK", "SAIT-Devlonics" },
+ { "SDR", "SDR Systems" },
+ { "SDS", "SunRiver Data System" },
+ { "SDT", "Siemens AG" },
+ { "SDX", "SDX Business Systems Ltd" },
+ { "SEA", "Seanix Technology Inc." },
+ { "SEB", "system elektronik GmbH" },
+ { "SEC", "Seiko Epson Corporation" },
+ { "SEE", "SeeColor Corporation" },
+ { "SEG", "DO NOT USE - SEG" },
+ { "SEI", "Seitz & Associates Inc" },
+ { "SEL", "Way2Call Communications" },
+ { "SEM", "Samsung Electronics Company Ltd" },
+ { "SEN", "Sencore" },
+ { "SEO", "SEOS Ltd" },
+ { "SEP", "SEP Eletronica Ltda." },
+ { "SER", "Sony Ericsson Mobile Communications Inc." },
+ { "SES", "Session Control LLC" },
+ { "SET", "SendTek Corporation" },
+ { "SFM", "TORNADO Company" },
+ { "SFT", "Mikroforum Ring 3" },
{ "SGC", "Spectragraphics Corporation" },
- { "DBI", "DigiBoard Inc" },
- { "LEO", "First International Computer Inc" },
- { "TSP", "U.S. Navy" },
- { "MTK", "Microtek International Inc." },
- { "TCN", "Tecnetics (PTY) Ltd" },
- { "DPM", "ADPM Synthesis sas" },
- { "LGS", "LG Semicom Company Ltd" },
- { "LGI", "Logitech Inc" },
- { "PBV", "Pitney Bowes" },
- { "ELI", "Edsun Laboratories" },
- { "HPQ", "HP" },
- { "RPT", "R.P.T.Intergroups" },
- { "BDO", "Brahler ICS" },
- { "ARM", "Arima" },
- { "JTS", "JS Motorsports" },
- { "TNY", "Tennyson Tech Pty Ltd" },
- { "UDN", "Uniden Corporation" },
- { "KNC", "Konica corporation" },
- { "GND", "Gennum Corporation" },
- { "MSG", "MSI GmbH" },
- { "REH", "Rehan Electronics Ltd." },
- { "COL", "Rockwell Collins, Inc." },
- { "MDC", "Midori Electronics" },
- { "TRN", "Datacommunicatie Tron B.V." },
- { "VDA", "Victor Data Systems" },
- { "TOU", "Touchstone Technology" },
- { "ETD", "ELAN MICROELECTRONICS CORPORATION" },
- { "CYB", "CyberVision" },
- { "SWC", "Software Café" },
- { "EXN", "RGB Systems, Inc. dba Extron Electronics" },
- { "HSP", "HannStar Display Corp" },
- { "WTK", "Wearnes Thakral Pte" },
- { "GFM", "GFMesstechnik GmbH" },
- { "INC", "Home Row Inc" },
- { "LEC", "Lectron Company Ltd" },
- { "WTS", "Restek Electric Company Ltd" },
- { "ACE", "Actek Engineering Pty Ltd" },
- { "MSH", "Microsoft" },
- { "CHL", "Chloride-R&D" },
- { "ALT", "Altra" },
- { "EES", "EE Solutions, Inc." },
- { "ASX", "AudioScience" },
- { "DAC", "Digital Acoustics Corporation" },
- { "HAL", "Halberthal" },
- { "HPC", "Hewlett Packard Co." },
- { "GRY", "Robert Gray Company" },
- { "AXO", "Axonic Labs LLC" },
- { "ALJ", "Altec Lansing" },
+ { "SGD", "Sigma Designs, Inc." },
+ { "SGE", "Kansai Electric Company Ltd" },
+ { "SGI", "Scan Group Ltd" },
+ { "SGL", "Super Gate Technology Company Ltd" },
+ { "SGM", "SAGEM" },
+ { "SGO", "Logos Design A/S" },
+ { "SGT", "Stargate Technology" },
+ { "SGW", "Shanghai Guowei Science and Technology Co., Ltd." },
+ { "SGX", "Silicon Graphics Inc" },
+ { "SGZ", "Systec Computer GmbH" },
+ { "SHC", "ShibaSoku Co., Ltd." },
+ { "SHG", "Soft & Hardware development Goldammer GmbH" },
+ { "SHI", "Jiangsu Shinco Electronic Group Co., Ltd" },
+ { "SHP", "Sharp Corporation" },
+ { "SHR", "Digital Discovery" },
+ { "SHT", "Shin Ho Tech" },
+ { "SIA", "SIEMENS AG" },
+ { "SIB", "Sanyo Electric Company Ltd" },
+ { "SIC", "Sysmate Corporation" },
+ { "SID", "Seiko Instruments Information Devices Inc" },
+ { "SIE", "Siemens" },
+ { "SIG", "Sigma Designs Inc" },
+ { "SII", "Silicon Image, Inc." },
+ { "SIL", "Silicon Laboratories, Inc" },
+ { "SIM", "S3 Inc" },
+ { "SIN", "Singular Technology Co., Ltd." },
+ { "SIR", "Sirius Technologies Pty Ltd" },
+ { "SIS", "Silicon Integrated Systems Corporation" },
+ { "SIT", "Sitintel" },
+ { "SIU", "Seiko Instruments USA Inc" },
+ { "SIX", "Zuniq Data Corporation" },
+ { "SJE", "Sejin Electron Inc" },
+ { "SKD", "Schneider & Koch" },
+ { "SKT", "Samsung Electro-Mechanics Company Ltd" },
+ { "SKY", "SKYDATA S.P.A." },
+ { "SLA", "Systeme Lauer GmbH&Co KG" },
+ { "SLB", "Shlumberger Ltd" },
+ { "SLC", "Syslogic Datentechnik AG" },
+ { "SLF", "StarLeaf" },
+ { "SLH", "Silicon Library Inc." },
+ { "SLI", "Symbios Logic Inc" },
+ { "SLK", "Silitek Corporation" },
+ { "SLM", "Solomon Technology Corporation" },
+ { "SLR", "Schlumberger Technology Corporate" },
+ { "SLS", "Schnick-Schnack-Systems GmbH" },
+ { "SLT", "Salt Internatioinal Corp." },
+ { "SLX", "Specialix" },
+ { "SMA", "SMART Modular Technologies" },
+ { "SMB", "Schlumberger" },
+ { "SMC", "Standard Microsystems Corporation" },
+ { "SME", "Sysmate Company" },
+ { "SMI", "SpaceLabs Medical Inc" },
+ { "SMK", "SMK CORPORATION" },
+ { "SML", "Sumitomo Metal Industries, Ltd." },
+ { "SMM", "Shark Multimedia Inc" },
+ { "SMO", "STMicroelectronics" },
+ { "SMP", "Simple Computing" },
+ { "SMR", "B.& V. s.r.l." },
{ "SMS", "Silicom Multimedia Systems Inc" },
- { "HPI", "Headplay, Inc." },
- { "FRO", "FARO Technologies" },
- { "GAU", "Gaudi Co., Ltd." },
+ { "SMT", "Silcom Manufacturing Tech Inc" },
+ { "SNC", "Sentronic International Corp." },
+ { "SNI", "Siemens Microdesign GmbH" },
+ { "SNK", "S&K Electronics" },
+ { "SNO", "SINOSUN TECHNOLOGY CO., LTD" },
+ { "SNP", "Siemens Nixdorf Info Systems" },
+ { "SNS", "Cirtech (UK) Ltd" },
+ { "SNT", "SuperNet Inc" },
+ { "SNW", "Snell & Wilcox" },
+ { "SNX", "Sonix Comm. Ltd" },
+ { "SNY", "Sony" },
+ { "SOI", "Silicon Optix Corporation" },
+ { "SOL", "Solitron Technologies Inc" },
+ { "SON", "Sony" },
+ { "SOR", "Sorcus Computer GmbH" },
+ { "SOT", "Sotec Company Ltd" },
+ { "SOY", "SOYO Group, Inc" },
+ { "SPC", "SpinCore Technologies, Inc" },
+ { "SPE", "SPEA Software AG" },
+ { "SPH", "G&W Instruments GmbH" },
+ { "SPI", "SPACE-I Co., Ltd." },
+ { "SPK", "SpeakerCraft" },
+ { "SPL", "Smart Silicon Systems Pty Ltd" },
+ { "SPN", "Sapience Corporation" },
+ { "SPR", "pmns GmbH" },
+ { "SPS", "Synopsys Inc" },
+ { "SPT", "Sceptre Tech Inc" },
+ { "SPU", "SIM2 Multimedia S.P.A." },
+ { "SPX", "Simplex Time Recorder Co." },
+ { "SQT", "Sequent Computer Systems Inc" },
+ { "SRC", "Integrated Tech Express Inc" },
+ { "SRD", "Setred" },
+ { "SRF", "Surf Communication Solutions Ltd" },
+ { "SRG", "Intuitive Surgical, Inc." },
{ "SRS", "SR-Systems e.K." },
- { "APL", "Aplicom Oy" },
- { "JGD", "University College" },
- { "NVD", "Nvidia" },
- { "CEP", "C-DAC" },
- { "BDR", "Blonder Tongue Labs, Inc." },
- { "AUO", "AU Optronics" },
- { "DCR", "Decros Ltd" },
- { "DLK", "D-Link Systems Inc" },
- { "SWS", "Static" },
- { "WSC", "CIS Technology Inc" },
- { "ESL", "Esterline Technologies" },
- { "ISC", "Id3 Semiconductors" },
- { "XSN", "Xscreen AS" },
- { "FML", "Fujitsu Microelect Ltd" },
- { "WPI", "Wearnes Peripherals International (Pte) Ltd" },
- { "EGL", "Eagle Technology" },
- { "EGA", "Elgato Systems LLC" },
- { "GAG", "Gage Applied Sciences Inc" },
- { "HCP", "Hitachi Computer Products Inc" },
- { "UET", "Universal Empowering Technologies" },
- { "ITL", "Inter-Tel" },
- { "SDE", "Sherwood Digital Electronics Corporation" },
- { "CAA", "Castles Automation Co., Ltd" },
- { "ZRN", "Zoran Corporation" },
- { "VLT", "VideoLan Technologies" },
- { "EUT", "Ericsson Mobile Networks B.V." },
- { "REA", "Real D" },
- { "BUT", "21ST CENTURY ENTERTAINMENT" },
- { "THN", "Thundercom Holdings Sdn. Bhd." },
- { "CHO", "Sichuang Changhong Corporation" },
- { "SCC", "SORD Computer Corporation" },
- { "MSY", "MicroTouch Systems Inc" },
- { "ERP", "Euraplan GmbH" },
- { "CPL", "Compal Electronics Inc" },
- { "ACM", "Acroloop Motion Control Systems Inc" },
- { "VTS", "VTech Computers Ltd" },
- { "ETH", "Etherboot Project" },
- { "CGT", "congatec AG" },
- { "FEN", "Fen Systems Ltd." },
- { "MLN", "Mark Levinson" },
- { "UMC", "United Microelectr Corporation" },
- { "CAR", "Cardinal Company Ltd" },
- { "LIT", "Lithics Silicon Technology" },
- { "AWC", "Access Works Comm Inc" },
- { "PPC", "Phoenixtec Power Company Ltd" },
- { "SVT", "SEVIT Co., Ltd." },
- { "MDX", "MicroDatec GmbH" },
- { "XIN", "Xinex Networks Inc" },
- { "KTN", "Katron Tech Inc" },
- { "MJI", "MARANTZ JAPAN, INC." },
- { "CTM", "Computerm Corporation" },
- { "PDM", "Psion Dacom Plc." },
- { "AKM", "Asahi Kasei Microsystems Company Ltd" },
- { "GSY", "Grossenbacher Systeme AG" },
- { "OMR", "Omron Corporation" },
- { "RSH", "ADC-Centre" },
- { "MTM", "Motium" },
- { "XDM", "XDM Ltd." },
- { "MSX", "Micomsoft Co., Ltd." },
- { "VNC", "Vinca Corporation" },
+ { "SRT", "SeeReal Technologies GmbH" },
+ { "SSC", "Sierra Semiconductor Inc" },
+ { "SSD", "FlightSafety International" },
+ { "SSE", "Samsung Electronic Co." },
+ { "SSI", "S-S Technology Inc" },
+ { "SSJ", "Sankyo Seiki Mfg.co., Ltd" },
+ { "SSP", "Spectrum Signal Proecessing Inc" },
+ { "SSS", "S3 Inc" },
+ { "SST", "SystemSoft Corporation" },
+ { "STA", "ST Electronics Systems Assembly Pte Ltd" },
+ { "STB", "STB Systems Inc" },
+ { "STC", "STAC Electronics" },
+ { "STD", "STD Computer Inc" },
+ { "STE", "SII Ido-Tsushin Inc" },
+ { "STF", "Starflight Electronics" },
+ { "STG", "StereoGraphics Corp." },
+ { "STH", "Semtech Corporation" },
+ { "STI", "Smart Tech Inc" },
{ "STK", "SANTAK CORP." },
- { "JET", "JET POWER TECHNOLOGY CO., LTD." },
- { "SLR", "Schlumberger Technology Corporate" },
- { "GWI", "GW Instruments" },
- { "TMI", "Texas Microsystem" },
- { "EXT", "Exatech Computadores & Servicos Ltda" },
- { "SXB", "Syntax-Brillian" },
- { "HYT", "Heng Yu Technology (HK) Limited" },
- { "TST", "Transtream Inc" },
- { "FIS", "FLY-IT Simulators" },
- { "VMW", "VMware Inc.," },
- { "PET", "Practical Electronic Tools" },
- { "BLP", "Bloomberg L.P." },
- { "MVS", "Microvision" },
- { "ZMT", "Zalman Tech Co., Ltd." },
- { "QTD", "Quantum 3D Inc" },
- { "ITE", "Integrated Tech Express Inc" },
- { "MIS", "Modular Industrial Solutions Inc" },
- { "KOB", "Kobil Systems GmbH" },
- { "KOW", "KOWA Company,LTD." },
- { "SHC", "ShibaSoku Co., Ltd." },
- { "IKS", "Ikos Systems Inc" },
- { "PGP", "propagamma kommunikation" },
- { "AYD", "Aydin Displays" },
- { "MFG", "MicroField Graphics Inc" },
- { "APS", "Autologic Inc" },
- { "APM", "Applied Memory Tech" },
- { "ACO", "Allion Computer Inc." },
- { "IWR", "Icuiti Corporation" },
- { "RCI", "RC International" },
- { "YMH", "Yamaha Corporation" },
- { "SPE", "SPEA Software AG" },
- { "ADL", "ASTRA Security Products Ltd" },
- { "QFI", "Quickflex, Inc" },
- { "FRD", "Freedom Scientific BLV" },
- { "PCM", "PCM Systems Corporation" },
- { "RHM", "Rohm Company Ltd" },
- { "EQP", "Equipe Electronics Ltd." },
- { "UND", "Unisys Corporation" },
- { "ITX", "integrated Technology Express Inc" },
- { "WML", "Wolfson Microelectronics Ltd" },
- { "IPR", "Ithaca Peripherals" },
- { "NCE", "Norcent Technology, Inc." },
- { "GWY", "Gateway 2000" },
- { "DAX", "Data Apex Ltd" },
- { "MKT", "MICROTEK Inc." },
- { "AOL", "America OnLine" },
- { "BIO", "BioLink Technologies International, Inc." },
- { "DCI", "Concepts Inc" },
- { "LOL", "Litelogic Operations Ltd" },
- { "ADI", "ADI Systems Inc" },
- { "TPJ", "Junnila" },
- { "JDL", "Japan Digital Laboratory Co.,Ltd." },
- { "MMN", "MiniMan Inc" },
- { "MNC", "Mini Micro Methods Ltd" },
- { "SUM", "Summagraphics Corporation" },
- { "SXT", "SHARP TAKAYA ELECTRONIC INDUSTRY CO.,LTD." },
- { "CAT", "Consultancy in Advanced Technology" },
- { "MSM", "Advanced Digital Systems" },
- { "CHY", "Cherry GmbH" },
- { "VLB", "ValleyBoard Ltda." },
- { "DDS", "Barco, n.v." },
{ "STL", "SigmaTel Inc" },
- { "AIE", "Altmann Industrieelektronik" },
- { "CHM", "CHIC TECHNOLOGY CORP." },
- { "KTK", "Key Tronic Corporation" },
- { "LTN", "Litronic Inc" },
- { "IDC", "International Datacasting Corporation" },
- { "TWA", "Tidewater Association" },
- { "ARI", "Argosy Research Inc" },
+ { "STM", "SGS Thomson Microelectronics" },
+ { "STN", "Samsung Electronics America" },
+ { "STO", "Stollmann E+V GmbH" },
+ { "STP", "StreamPlay Ltd" },
+ { "STR", "Starlight Networks Inc" },
+ { "STS", "SITECSYSTEM CO., LTD." },
{ "STT", "Star Paging Telecom Tech (Shenzhen) Co. Ltd." },
- { "MYA", "Monydata" },
- { "JAE", "Japan Aviation Electronics Industry, Limited" },
- { "BBH", "B&Bh" },
- { "GIC", "General Inst. Corporation" },
- { "TIV", "OOO Technoinvest" },
- { "ION", "Inside Out Networks" },
- { "KZI", "K-Zone International co. Ltd." },
- { "IDE", "IDE Associates" },
- { "IQI", "IneoQuest Technologies, Inc" },
- { "NDI", "National Display Systems" },
- { "REL", "Reliance Electric Ind Corporation" },
- { "SPH", "G&W Instruments GmbH" },
- { "RPI", "RoomPro Technologies" },
- { "LUC", "Lucent Technologies" },
- { "CTL", "Creative Technology Ltd" },
- { "SDS", "SunRiver Data System" },
- { "USR", "U.S. Robotics Inc" },
- { "GJN", "Grand Junction Networks" },
- { "YED", "Y-E Data Inc" },
- { "RHT", "Red Hat, Inc." },
- { "AOT", "Alcatel" },
- { "TCR", "Thomson Consumer Electronics" },
- { "ILC", "Image Logic Corporation" },
- { "IGC", "Intergate Pty Ltd" },
- { "HYC", "Hypercope Gmbh Aachen" },
- { "SPL", "Smart Silicon Systems Pty Ltd" },
- { "DLC", "Diamond Lane Comm. Corporation" },
- { "TBB", "Triple S Engineering Inc" },
- { "MLS", "Milestone EPE" },
- { "QDM", "Quadram" },
- { "AIR", "Advanced Integ. Research Inc" },
- { "SLA", "Systeme Lauer GmbH&Co KG" },
- { "IBP", "IBP Instruments GmbH" },
- { "DDI", "Data Display AG" },
- { "LED", "Long Engineering Design Inc" },
- { "MSC", "Mouse Systems Corporation" },
- { "LXS", "ELEA CardWare" },
- { "ATE", "Innovate Ltd" },
- { "APV", "A+V Link" },
- { "FRC", "Force Computers" },
- { "ZTC", "ZyDAS Technology Corporation" },
- { "ANP", "Andrew Network Production" },
- { "LOG", "Logicode Technology Inc" },
- { "RAI", "Rockwell Automation/Intecolor" },
- { "MPJ", "Microlab" },
- { "CMO", "Chi Mei Optoelectronics corp." },
- { "ROH", "Rohm Co., Ltd." },
- { "HYP", "Hyphen Ltd" },
- { "ICO", "Intel Corp" },
- { "ACI", "Ancor Communications Inc" },
- { "SLT", "Salt Internatioinal Corp." },
- { "TSC", "Sanyo Electric Company Ltd" },
- { "APC", "American Power Conversion" },
- { "PSE", "Practical Solutions Pte., Ltd." },
- { "MET", "Metheus Corporation" },
- { "SAT", "Shuttle Tech" },
+ { "STU", "Sentelic Corporation" },
+ { "STW", "Starwin Inc." },
+ { "STX", "ST-Ericsson" },
+ { "STY", "SDS Technologies" },
+ { "SUB", "Subspace Comm. Inc" },
+ { "SUM", "Summagraphics Corporation" },
+ { "SUN", "Sun Electronics Corporation" },
+ { "SUP", "Supra Corporation" },
+ { "SUR", "Surenam Computer Corporation" },
+ { "SVA", "SGEG" },
+ { "SVC", "Intellix Corp." },
+ { "SVD", "SVD Computer" },
+ { "SVI", "Sun Microsystems" },
+ { "SVS", "SVSI" },
+ { "SVT", "SEVIT Co., Ltd." },
+ { "SWC", "Software Café" },
+ { "SWI", "Sierra Wireless Inc." },
+ { "SWL", "Sharedware Ltd" },
+ { "SWS", "Static" },
+ { "SWT", "Software Technologies Group,Inc." },
+ { "SXB", "Syntax-Brillian" },
+ { "SXD", "Silex technology, Inc." },
+ { "SXG", "SELEX GALILEO" },
+ { "SXL", "SolutionInside" },
+ { "SXT", "SHARP TAKAYA ELECTRONIC INDUSTRY CO.,LTD." },
+ { "SYC", "Sysmic" },
+ { "SYE", "SY Electronics Ltd" },
{ "SYK", "Stryker Communications" },
- { "BCQ", "Deutsche Telekom Berkom GmbH" },
- { "DPI", "DocuPoint" },
- { "FAR", "Farallon Computing" },
- { "ROP", "Roper International Ltd" },
- { "STB", "STB Systems Inc" },
- { "CNC", "Alvedon Computers Ltd" },
- { "DGA", "Digiital Arts Inc" },
- { "EDT", "Emerging Display Technologies Corp" },
- { "IPI", "Intelligent Platform Management Interface (IPMI) forum (Intel, HP, NEC, Dell)" },
- { "VQ@", "Vision Quest" },
- { "EMK", "Emcore Corporation" },
- { "XTD", "Icuiti Corporation" },
- { "KNX", "Nutech Marketing PTL" },
- { "WHI", "Whistle Communications" },
- { "KDM", "Korea Data Systems Co., Ltd." },
- { "QCK", "Quick Corporation" },
- { "QTR", "Qtronix Corporation" },
- { "NFS", "Number Five Software" },
- { "HTK", "Holtek Microelectronics Inc" },
- { "TRL", "Royal Information" },
- { "LXN", "Luxeon" },
- { "VLK", "Vislink International Ltd" },
- { "TWE", "Kontron Electronik" },
- { "DFI", "DFI" },
- { "JWS", "JWSpencer & Co." },
- { "FTW", "MindTribe Product Engineering, Inc." },
+ { "SYL", "Sylvania Computer Products" },
+ { "SYM", "Symicron Computer Communications Ltd." },
+ { "SYN", "Synaptics Inc" },
+ { "SYP", "SYPRO Co Ltd" },
+ { "SYS", "Sysgration Ltd" },
+ { "SYT", "Seyeon Tech Company Ltd" },
+ { "SYV", "SYVAX Inc" },
+ { "SYX", "Prime Systems, Inc." },
+ { "TAA", "Tandberg" },
+ { "TAB", "Todos Data System AB" },
+ { "TAG", "Teles AG" },
+ { "TAI", "Toshiba America Info Systems Inc" },
+ { "TAM", "Tamura Seisakusyo Ltd" },
+ { "TAS", "Taskit Rechnertechnik GmbH" },
+ { "TAT", "Teleliaison Inc" },
+ { "TAX", "Taxan (Europe) Ltd" },
+ { "TBB", "Triple S Engineering Inc" },
+ { "TBC", "Turbo Communication, Inc" },
+ { "TBS", "Turtle Beach System" },
+ { "TCC", "Tandon Corporation" },
+ { "TCD", "Taicom Data Systems Co., Ltd." },
+ { "TCE", "Century Corporation" },
+ { "TCH", "Interaction Systems, Inc" },
+ { "TCI", "Tulip Computers Int'l B.V." },
+ { "TCJ", "TEAC America Inc" },
+ { "TCL", "Technical Concepts Ltd" },
+ { "TCM", "3Com Corporation" },
+ { "TCN", "Tecnetics (PTY) Ltd" },
+ { "TCO", "Thomas-Conrad Corporation" },
+ { "TCR", "Thomson Consumer Electronics" },
+ { "TCS", "Tatung Company of America Inc" },
+ { "TCT", "Telecom Technology Centre Co. Ltd." },
+ { "TCX", "FREEMARS Heavy Industries" },
+ { "TDC", "Teradici" },
+ { "TDD", "Tandberg Data Display AS" },
+ { "TDK", "TDK USA Corporation" },
{ "TDM", "Tandem Computer Europe Inc" },
- { "RAS", "RAScom Inc" },
- { "KVX", "KeyView" },
- { "MOS", "Moses Corporation" },
- { "ONX", "SOMELEC Z.I. Du Vert Galanta" },
- { "STF", "Starflight Electronics" },
- { "HER", "Ascom Business Systems" },
- { "GTS", "Geotest Marvin Test Systems Inc" },
- { "KEC", "Kyushu Electronics Systems Inc" },
- { "MQP", "MultiQ Products AB" },
- { "LUX", "Luxxell Research Inc" },
- { "HEC", "Hitachi Engineering Company Ltd" },
- { "NXG", "Nexgen" },
- { "CNI", "Connect Int'l A/S" },
- { "FUJ", "Fujitsu Ltd" },
- { "APD", "AppliAdata" },
- { "LHE", "Lung Hwa Electronics Company Ltd" },
- { "SCT", "Smart Card Technology" },
- { "SOY", "SOYO Group, Inc" },
- { "ICN", "Sanyo Icon" },
+ { "TDP", "3D Perception" },
+ { "TDS", "Tri-Data Systems Inc" },
+ { "TDT", "TDT" },
{ "TDV", "TDVision Systems, Inc." },
- { "AHC", "Advantech Co., Ltd." },
- { "GTK", "G-Tech Corporation" },
- { "BII", "Boeckeler Instruments Inc" },
- { "TCC", "Tandon Corporation" },
- { "BUJ", "ATI Tech Inc" },
- { "SAA", "Sanritz Automation Co.,Ltd." },
- { "DTK", "Dynax Electronics (HK) Ltd" },
- { "HXM", "Hexium Ltd." },
- { "EGD", "EIZO GmbH Display Technologies" },
- { "NDK", "Naitoh Densei CO., LTD." },
- { "TVR", "TV Interactive Corporation" },
- { "PNL", "Panelview, Inc." },
- { "AET", "Aethra Telecomunicazioni S.r.l." },
- { "REC", "ReCom" },
- { "HET", "HETEC Datensysteme GmbH" },
- { "ZOW", "Zowie Intertainment, Inc" },
- { "MEQ", "Matelect Ltd." },
- { "DRD", "DIGITAL REFLECTION INC." },
- { "MRA", "Miranda Technologies Inc" },
- { "QTM", "Quantum" },
- { "REN", "Renesas Technology Corp." },
- { "XIO", "Xiotech Corporation" },
- { "GIS", "AT&T Global Info Solutions" },
+ { "TDY", "Tandy Electronics" },
{ "TEA", "TEAC System Corporation" },
- { "EMU", "Emulex Corporation" },
- { "VIC", "Victron B.V." },
- { "ATN", "Athena Smartcard Solutions Ltd." },
- { "SYS", "Sysgration Ltd" },
- { "CVS", "Clarity Visual Systems" },
- { "CWR", "Connectware Inc" },
- { "TVI", "Truevision" },
- { "AMB", "Ambient Technologies, Inc." },
- { "USA", "Utimaco Safeware AG" },
- { "LNT", "LANETCO International" },
- { "EDG", "Electronic-Design GmbH" },
- { "MKV", "Trtheim Technology" },
- { "SGT", "Stargate Technology" },
- { "RTS", "Raintree Systems" },
- { "PXM", "Proxim Inc" },
- { "ACG", "A&R Cambridge Ltd" },
- { "FJT", "F.J. Tieman BV" },
- { "LCD", "Toshiba Matsushita Display Technology Co., Ltd" },
- { "IDS", "Interdigital Sistemas de Informacao" },
- { "AOA", "AOpen Inc." },
- { "ACR", "Acer Technologies" },
- { "AKL", "AMiT Ltd" },
- { "IOS", "i-O Display System" },
- { "NOR", "Norand Corporation" },
- { "XST", "XS Technologies Inc" },
- { "BUG", "B.U.G., Inc." },
- { "RCN", "Radio Consult SRL" },
- { "ESI", "Extended Systems, Inc." },
- { "TUT", "Tut Systems" },
- { "VAR", "Varian Australia Pty Ltd" },
- { "DIT", "Dragon Information Technology" },
- { "CET", "TEC CORPORATION" },
- { "WKH", "Uni-Take Int'l Inc." },
- { "BHZ", "BitHeadz, Inc." },
- { "PTI", "Promise Technology Inc" },
- { "HIQ", "Kaohsiung Opto Electronics Americas, Inc." },
- { "SET", "SendTek Corporation" },
- { "KCL", "Keycorp Ltd" },
- { "EIC", "Eicon Technology Corporation" },
- { "TRT", "Tritec Electronic AG" },
- { "ZAN", "Zandar Technologies plc" },
- { "NTN", "Nuvoton Technology Corporation" },
- { "MTC", "Mars-Tech Corporation" },
- { "JQE", "CNet Technical Inc" },
- { "SRG", "Intuitive Surgical, Inc." },
- { "VIR", "Visual Interface, Inc" },
- { "HTX", "Hitex Systementwicklung GmbH" },
+ { "TEC", "Tecmar Inc" },
+ { "TEK", "Tektronix Inc" },
+ { "TEL", "Promotion and Display Technology Ltd." },
+ { "TER", "TerraTec Electronic GmbH" },
+ { "TGC", "Toshiba Global Commerce Solutions, Inc." },
+ { "TGI", "TriGem Computer Inc" },
+ { "TGM", "TriGem Computer,Inc." },
+ { "TGS", "Torus Systems Ltd" },
+ { "TGV", "Grass Valley Germany GmbH" },
+ { "THN", "Thundercom Holdings Sdn. Bhd." },
+ { "TIC", "Trigem KinfoComm" },
+ { "TIP", "TIPTEL AG" },
+ { "TIV", "OOO Technoinvest" },
+ { "TIX", "Tixi.Com GmbH" },
+ { "TKC", "Taiko Electric Works.LTD" },
+ { "TKN", "Teknor Microsystem Inc" },
+ { "TKO", "TouchKo, Inc." },
+ { "TKS", "TimeKeeping Systems, Inc." },
+ { "TLA", "Ferrari Electronic GmbH" },
+ { "TLD", "Telindus" },
+ { "TLF", "Teleforce.,co,ltd" },
+ { "TLI", "TOSHIBA TELI CORPORATION" },
+ { "TLK", "Telelink AG" },
+ { "TLS", "Teleste Educational OY" },
+ { "TLT", "Dai Telecom S.p.A." },
+ { "TLV", "S3 Inc" },
{ "TLX", "Telxon Corporation" },
- { "NGC", "Network General" },
+ { "TMC", "Techmedia Computer Systems Corporation" },
+ { "TME", "AT&T Microelectronics" },
+ { "TMI", "Texas Microsystem" },
+ { "TMM", "Time Management, Inc." },
+ { "TMR", "Taicom International Inc" },
+ { "TMS", "Trident Microsystems Ltd" },
+ { "TMT", "T-Metrics Inc." },
+ { "TMX", "Thermotrex Corporation" },
+ { "TNC", "TNC Industrial Company Ltd" },
+ { "TNJ", "DO NOT USE - TNJ" },
+ { "TNM", "TECNIMAGEN SA" },
+ { "TNY", "Tennyson Tech Pty Ltd" },
+ { "TOE", "TOEI Electronics Co., Ltd." },
+ { "TOG", "The OPEN Group" },
+ { "TON", "TONNA" },
+ { "TOP", "Orion Communications Co., Ltd." },
+ { "TOS", "Toshiba Corporation" },
+ { "TOU", "Touchstone Technology" },
+ { "TPC", "Touch Panel Systems Corporation" },
+ { "TPE", "Technology Power Enterprises Inc" },
+ { "TPJ", "Junnila" },
+ { "TPK", "TOPRE CORPORATION" },
+ { "TPR", "Topro Technology Inc" },
+ { "TPS", "Teleprocessing Systeme GmbH" },
+ { "TPT", "Thruput Ltd" },
+ { "TPV", "Top Victory Electronics ( Fujian ) Company Ltd" },
+ { "TPZ", "Ypoaz Systems Inc" },
+ { "TRA", "TriTech Microelectronics International" },
+ { "TRC", "Trioc AB" },
+ { "TRD", "Trident Microsystem Inc" },
+ { "TRE", "Tremetrics" },
+ { "TRI", "Tricord Systems" },
+ { "TRL", "Royal Information" },
+ { "TRM", "Tekram Technology Company Ltd" },
+ { "TRN", "Datacommunicatie Tron B.V." },
+ { "TRS", "Torus Systems Ltd" },
+ { "TRT", "Tritec Electronic AG" },
+ { "TRU", "Aashima Technology B.V." },
+ { "TRV", "Trivisio Prototyping GmbH" },
+ { "TRX", "Trex Enterprises" },
{ "TSB", "Toshiba America Info Systems Inc" },
- { "SGI", "Scan Group Ltd" },
- { "AIS", "Alien Internet Services" },
- { "MUD", "Multi-Dimension Institute" },
- { "PNS", "PanaScope" },
- { "NEO", "NEO TELECOM CO.,LTD." },
- { "IMB", "ART s.r.l." },
- { "SRD", "Setred" },
- { "LEX", "Lexical Ltd" },
- { "LMI", "Lexmark Int'l Inc" },
- { "ECL", "Excel Company Ltd" },
- { "EXC", "Excession Audio" },
- { "ABA", "ABBAHOME INC." },
- { "CLI", "Cirrus Logic Inc" },
- { "DYM", "Dymo-CoStar Corporation" },
- { "MEL", "Mitsubishi Electric Corporation" },
- { "ZAX", "Zefiro Acoustics" },
- { "TEC", "Tecmar Inc" },
- { "WTI", "WorkStation Tech" },
- { "APX", "AP Designs Ltd" },
- { "MLM", "Millennium Engineering Inc" },
- { "BAC", "Biometric Access Corporation" },
- { "DDE", "Datasat Digital Entertainment" },
- { "GIM", "Guillemont International" },
+ { "TSC", "Sanyo Electric Company Ltd" },
+ { "TSD", "TechniSat Digital GmbH" },
+ { "TSE", "Tottori Sanyo Electric" },
+ { "TSF", "Racal-Airtech Software Forge Ltd" },
+ { "TSG", "The Software Group Ltd" },
+ { "TSI", "TeleVideo Systems" },
+ { "TSL", "Tottori SANYO Electric Co., Ltd." },
+ { "TSP", "U.S. Navy" },
+ { "TST", "Transtream Inc" },
+ { "TSV", "TRANSVIDEO" },
+ { "TSY", "TouchSystems" },
+ { "TTA", "Topson Technology Co., Ltd." },
+ { "TTB", "National Semiconductor Japan Ltd" },
+ { "TTC", "Telecommunications Techniques Corporation" },
+ { "TTE", "TTE, Inc." },
+ { "TTI", "Trenton Terminals Inc" },
+ { "TTK", "Totoku Electric Company Ltd" },
+ { "TTL", "2-Tel B.V." },
+ { "TTS", "TechnoTrend Systemtechnik GmbH" },
+ { "TTY", "TRIDELITY Display Solutions GmbH" },
+ { "TUA", "T+A elektroakustik GmbH" },
+ { "TUT", "Tut Systems" },
+ { "TVD", "Tecnovision" },
+ { "TVI", "Truevision" },
{ "TVM", "Taiwan Video & Monitor Corporation" },
- { "KWD", "Kenwood Corporation" },
- { "STW", "Starwin Inc." },
- { "NRV", "Taugagreining hf" },
- { "SUP", "Supra Corporation" },
- { "MTB", "Media Technologies Ltd." },
- { "INF", "Inframetrics Inc" },
- { "OTM", "Optoma Corporation" },
- { "NTX", "Netaccess Inc" },
- { "LXC", "LXCO Technologies AG" },
- { "CRN", "Cornerstone Imaging" },
- { "PVP", "Klos Technologies, Inc." },
- { "TCJ", "TEAC America Inc" },
- { "WVM", "Wave Systems Corporation" },
- { "ERN", "Ericsson, Inc." },
- { "PVN", "Pixel Vision" },
- { "LMT", "Laser Master" },
- { "MID", "miro Displays" },
+ { "TVO", "TV One Ltd" },
+ { "TVR", "TV Interactive Corporation" },
+ { "TVS", "TVS Electronics Limited" },
+ { "TVV", "TV1 GmbH" },
+ { "TWA", "Tidewater Association" },
+ { "TWE", "Kontron Electronik" },
+ { "TWH", "Twinhead International Corporation" },
+ { "TWI", "Easytel oy" },
+ { "TWK", "TOWITOKO electronics GmbH" },
+ { "TWX", "TEKWorx Limited" },
+ { "TXL", "Trixel Ltd" },
+ { "TXN", "Texas Insturments" },
+ { "TXT", "Textron Defense System" },
+ { "TYN", "Tyan Computer Corporation" },
+ { "UAS", "Ultima Associates Pte Ltd" },
+ { "UBI", "Ungermann-Bass Inc" },
+ { "UBL", "Ubinetics Ltd." },
+ { "UDN", "Uniden Corporation" },
+ { "UEC", "Ultima Electronics Corporation" },
+ { "UEG", "Elitegroup Computer Systems Company Ltd" },
+ { "UEI", "Universal Electronics Inc" },
+ { "UET", "Universal Empowering Technologies" },
+ { "UFG", "UNIGRAF-USA" },
+ { "UFO", "UFO Systems Inc" },
+ { "UHB", "XOCECO" },
+ { "UIC", "Uniform Industrial Corporation" },
+ { "UJR", "Ueda Japan Radio Co., Ltd." },
+ { "ULT", "Ultra Network Tech" },
+ { "UMC", "United Microelectr Corporation" },
+ { "UMG", "Umezawa Giken Co.,Ltd" },
+ { "UMM", "Universal Multimedia" },
+ { "UNA", "Unisys DSD" },
+ { "UNB", "Unisys Corporation" },
+ { "UNC", "Unisys Corporation" },
+ { "UND", "Unisys Corporation" },
+ { "UNE", "Unisys Corporation" },
+ { "UNF", "Unisys Corporation" },
+ { "UNI", "Unisys Corporation" },
+ { "UNM", "Unisys Corporation" },
+ { "UNO", "Unisys Corporation" },
+ { "UNP", "Unitop" },
+ { "UNS", "Unisys Corporation" },
+ { "UNT", "Unisys Corporation" },
+ { "UNY", "Unicate" },
+ { "UPP", "UPPI" },
+ { "UPS", "Systems Enhancement" },
+ { "URD", "Video Computer S.p.A." },
+ { "USA", "Utimaco Safeware AG" },
+ { "USD", "U.S. Digital Corporation" },
+ { "USI", "Universal Scientific Industrial Co., Ltd." },
+ { "USR", "U.S. Robotics Inc" },
+ { "UTD", "Up to Date Tech" },
+ { "UWC", "Uniwill Computer Corp." },
+ { "VAD", "Vaddio, LLC" },
+ { "VAL", "Valence Computing Corporation" },
+ { "VAR", "Varian Australia Pty Ltd" },
+ { "VBR", "VBrick Systems Inc." },
+ { "VBT", "Valley Board Ltda" },
+ { "VCC", "Virtual Computer Corporation" },
+ { "VCI", "VistaCom Inc" },
+ { "VCJ", "Victor Company of Japan, Limited" },
+ { "VCM", "Vector Magnetics, LLC" },
+ { "VCX", "VCONEX" },
+ { "VDA", "Victor Data Systems" },
+ { "VDC", "VDC Display Systems" },
+ { "VDM", "Vadem" },
+ { "VDO", "Video & Display Oriented Corporation" },
+ { "VDS", "Vidisys GmbH & Company" },
+ { "VDT", "Viditec, Inc." },
+ { "VEC", "Vector Informatik GmbH" },
+ { "VEK", "Vektrex" },
+ { "VES", "Vestel Elektronik Sanayi ve Ticaret A. S." },
+ { "VFI", "VeriFone Inc" },
+ { "VHI", "Macrocad Development Inc." },
+ { "VIA", "VIA Tech Inc" },
+ { "VIB", "Tatung UK Ltd" },
+ { "VIC", "Victron B.V." },
{ "VID", "Ingram Macrotron Germany" },
- { "IFZ", "Infinite Z" },
- { "ODM", "ODME Inc." },
- { "ASI", "Ahead Systems" },
- { "ISY", "International Integrated Systems,Inc.(IISI)" },
- { "NCL", "NetComm Ltd" },
- { "ITK", "ITK Telekommunikation AG" },
- { "EZE", "EzE Technologies" },
+ { "VIK", "Viking Connectors" },
+ { "VIM", "Via Mons Ltd." },
+ { "VIN", "Vine Micros Ltd" },
+ { "VIR", "Visual Interface, Inc" },
+ { "VIS", "Visioneer" },
+ { "VIT", "Visitech AS" },
+ { "VIZ", "VIZIO, Inc" },
+ { "VLB", "ValleyBoard Ltda." },
+ { "VLK", "Vislink International Ltd" },
+ { "VLT", "VideoLan Technologies" },
+ { "VMI", "Vermont Microsystems" },
+ { "VML", "Vine Micros Limited" },
+ { "VMW", "VMware Inc.," },
+ { "VNC", "Vinca Corporation" },
+ { "VOB", "MaxData Computer AG" },
+ { "VPI", "Video Products Inc" },
+ { "VPR", "Best Buy" },
+ { "VQ@", "Vision Quest" },
+ { "VRC", "Virtual Resources Corporation" },
+ { "VSC", "ViewSonic Corporation" },
+ { "VSD", "3M" },
+ { "VSI", "VideoServer" },
+ { "VSN", "Ingram Macrotron" },
+ { "VSP", "Vision Systems GmbH" },
{ "VSR", "V-Star Electronics Inc." },
- { "CPC", "Ciprico Inc" },
- { "JWD", "Video International Inc." },
- { "MEC", "Mega System Technologies Inc" },
- { "NVI", "NuVision US, Inc." },
- { "MRK", "Maruko & Company Ltd" },
- { "AAA", "Avolites Ltd" },
- { "CHG", "Sichuan Changhong Electric CO, LTD." },
- { "WWV", "World Wide Video, Inc." },
- { "SEO", "SEOS Ltd" },
- { "XER", "DO NOT USE - XER" },
- { "MCN", "Micron Electronics Inc" },
- { "DXC", "Digipronix Control Systems" },
- { "RSN", "Radiospire Networks, Inc." },
- { "FGD", "Lisa Draexlmaier GmbH" },
- { "SES", "Session Control LLC" },
- { "IIN", "IINFRA Co., Ltd" },
- { "ETI", "Eclipse Tech Inc" },
- { "DXD", "DECIMATOR DESIGN PTY LTD" },
- { "BST", "BodySound Technologies, Inc." },
- { "MTL", "Mitel Corporation" },
- { "LGX", "Lasergraphics, Inc." },
- { "MSP", "Mistral Solutions [P] Ltd." },
- { "SER", "Sony Ericsson Mobile Communications Inc." },
- { "IHE", "InHand Electronics" },
- { "STO", "Stollmann E+V GmbH" },
- { "RET", "Resonance Technology, Inc." },
- { "PXE", "PIXELA CORPORATION" },
- { "USI", "Universal Scientific Industrial Co., Ltd." },
- { "JAC", "Astec Inc" },
+ { "VTC", "VTel Corporation" },
+ { "VTG", "Voice Technologies Group Inc" },
+ { "VTI", "VLSI Tech Inc" },
+ { "VTK", "Viewteck Co., Ltd." },
+ { "VTL", "Vivid Technology Pte Ltd" },
+ { "VTM", "Miltope Corporation" },
+ { "VTN", "VIDEOTRON CORP." },
+ { "VTS", "VTech Computers Ltd" },
+ { "VTV", "VATIV Technologies" },
+ { "VTX", "Vestax Corporation" },
+ { "VUT", "Vutrix (UK) Ltd" },
+ { "VWB", "Vweb Corp." },
{ "WAC", "Wacom Tech" },
- { "BUF", "Yasuhiko Shirai Melco Inc" },
- { "LSI", "Loughborough Sound Images" },
- { "AMA", "Asia Microelectronic Development Inc" },
- { "DJP", "Maygay Machines, Ltd" },
- { "CAN", "CORNEA" },
- { "UMM", "Universal Multimedia" },
- { "ECI", "Enciris Technologies" },
- { "DDT", "Datadesk Technologies Inc" },
- { "MLG", "Micrologica AG" },
- { "NCA", "Nixdorf Company" },
- { "ENS", "Ensoniq Corporation" },
- { "MOT", "Motorola UDS" },
+ { "WAL", "Wave Access" },
+ { "WAN", "DO NOT USE - WAN" },
+ { "WAV", "Wavephore" },
+ { "WBN", "MicroSoftWare" },
+ { "WBS", "WB Systemtechnik GmbH" },
{ "WCI", "Wisecom Inc" },
- { "MXT", "Maxtech Corporation" },
- { "EHJ", "Epson Research" },
- { "KUR", "Kurta Corporation" },
- { "DFT", "DEI Holdings dba Definitive Technology" },
- { "NAD", "NAD Electronics" },
- { "GMK", "GMK Electronic Design GmbH" },
- { "TAI", "Toshiba America Info Systems Inc" },
- { "SNP", "Siemens Nixdorf Info Systems" },
- { "KFE", "Komatsu Forest" },
- { "PPD", "MEPhI" },
- { "UMG", "Umezawa Giken Co.,Ltd" },
- { "PMC", "PMC Consumer Electronics Ltd" },
- { "KIS", "KiSS Technology A/S" },
- { "ABV", "Advanced Research Technology" },
- { "ISA", "Symbol Technologies" },
- { "GMN", "GEMINI 2000 Ltd" },
- { "VSI", "VideoServer" },
- { "DTO", "Deutsche Thomson OHG" },
- { "OCN", "Olfan" },
- { "LTK", "Lucidity Technology Company Ltd" },
- { "CLX", "CardLogix" },
- { "TPT", "Thruput Ltd" },
- { "IXD", "Intertex Data AB" },
- { "ICX", "ICCC A/S" },
- { "REF", "Reflectivity, Inc." },
- { "CDK", "Cray Communications" },
- { "PNX", "Phoenix Technologies, Ltd." },
- { "MCT", "Microtec" },
- { "ESD", "Ensemble Designs, Inc" },
- { "CTS", "Comtec Systems Co., Ltd." },
- { "ADB", "Aldebbaron" },
- { "AML", "Anderson Multimedia Communications (HK) Limited" },
- { "FIN", "Finecom Co., Ltd." },
- { "NCC", "NCR Corporation" },
- { "ONS", "On Systems Inc" },
- { "CGA", "Chunghwa Picture Tubes, LTD" },
- { "NTC", "NeoTech S.R.L" },
- { "AMD", "Amdek Corporation" },
+ { "WCS", "Woodwind Communications Systems Inc" },
+ { "WDC", "Western Digital" },
+ { "WDE", "Westinghouse Digital Electronics" },
+ { "WEB", "WebGear Inc" },
+ { "WEC", "Winbond Electronics Corporation" },
+ { "WEL", "W-DEV" },
+ { "WEY", "WEY Design AG" },
+ { "WHI", "Whistle Communications" },
+ { "WII", "Innoware Inc" },
+ { "WIL", "WIPRO Information Technology Ltd" },
+ { "WIN", "Wintop Technology Inc" },
+ { "WIP", "Wipro Infotech" },
+ { "WKH", "Uni-Take Int'l Inc." },
+ { "WLD", "Wildfire Communications Inc" },
+ { "WML", "Wolfson Microelectronics Ltd" },
+ { "WMO", "Westermo Teleindustri AB" },
+ { "WMT", "Winmate Communication Inc" },
+ { "WNI", "WillNet Inc." },
+ { "WNV", "Winnov L.P." },
+ { "WNX", "Wincor Nixdorf International GmbH" },
+ { "WPA", "Matsushita Communication Industrial Co., Ltd." },
+ { "WPI", "Wearnes Peripherals International (Pte) Ltd" },
+ { "WRC", "WiNRADiO Communications" },
+ { "WSC", "CIS Technology Inc" },
+ { "WSP", "Wireless And Smart Products Inc." },
+ { "WST", "Wistron Corporation" },
+ { "WTC", "ACC Microelectronics" },
+ { "WTI", "WorkStation Tech" },
+ { "WTK", "Wearnes Thakral Pte" },
+ { "WTS", "Restek Electric Company Ltd" },
+ { "WVM", "Wave Systems Corporation" },
{ "WVV", "WolfVision GmbH" },
- { "PHO", "Photonics Systems Inc." },
- { "AVX", "AVerMedia Technologies, Inc." },
- { "SJE", "Sejin Electron Inc" },
- { "BCM", "Broadcom" },
- { "RLN", "RadioLAN Inc" },
- { "CAM", "Cambridge Audio" },
- { "TCS", "Tatung Company of America Inc" },
- { "RIO", "Rios Systems Company Ltd" },
- { "SWT", "Software Technologies Group,Inc." },
- { "BSL", "Biomedical Systems Laboratory" },
- { "DCV", "Datatronics Technology Inc" },
- { "JPC", "JPC Technology Limited" },
- { "ICC", "BICC Data Networks Ltd" },
- { "CEI", "Crestron Electronics, Inc." },
- { "NUI", "NU Inc." },
- { "MAE", "Maestro Pty Ltd" },
- { "AYR", "Airlib, Inc" },
- { "TPS", "Teleprocessing Systeme GmbH" },
- { "SMK", "SMK CORPORATION" },
- { "IAT", "IAT Germany GmbH" },
- { "BNO", "Bang & Olufsen" },
- { "KRY", "Kroy LLC" },
- { "OLT", "Olitec S.A." },
- { "ABC", "AboCom System Inc" },
- { "FXX", "Fuji Xerox" },
- { "ANI", "Anigma Inc" },
- { "OEI", "Optum Engineering Inc." },
- { "TPE", "Technology Power Enterprises Inc" },
- { "RDI", "Rainbow Displays, Inc." },
- { "KDK", "Kodiak Tech" },
- { "LHT", "Lighthouse Technologies Limited" },
- { "BEK", "Beko Elektronik A.S." },
- { "LND", "Land Computer Company Ltd" },
- { "CDC", "Core Dynamics Corporation" },
- { "FHL", "FHLP" },
- { "UNP", "Unitop" },
- { "MSR", "MASPRO DENKOH Corp." },
- { "MKC", "Media Tek Inc." },
- { "BCD", "Barco GmbH" },
- { "PQI", "Pixel Qi" },
- { "ALD", "In4S Inc" },
- { "HTC", "Hitachi Ltd" },
- { "OCD", "Macraigor Systems Inc" },
- { "PHY", "Phylon Communications" },
- { "MSF", "M-Systems Flash Disk Pioneers" },
- { "ETK", "eTEK Labs Inc." },
- { "DVS", "Digital Video System" },
- { "ACU", "Acculogic" },
+ { "WWV", "World Wide Video, Inc." },
+ { "WXT", "Woxter Technology Co. Ltd" },
+ { "WYS", "Wyse Technology" },
+ { "WYT", "Wooyoung Image & Information Co.,Ltd." },
+ { "XAC", "XAC Automation Corp" },
+ { "XAD", "Alpha Data" },
+ { "XDM", "XDM Ltd." },
+ { "XER", "DO NOT USE - XER" },
+ { "XFG", "Jan Strapko - FOTO" },
+ { "XFO", "EXFO Electro Optical Engineering" },
+ { "XIN", "Xinex Networks Inc" },
+ { "XIO", "Xiotech Corporation" },
+ { "XIR", "Xirocm Inc" },
+ { "XIT", "Xitel Pty ltd" },
+ { "XLX", "Xilinx, Inc." },
+ { "XMM", "C3PO S.L." },
+ { "XNT", "XN Technologies, Inc." },
+ { "XOC", "DO NOT USE - XOC" },
+ { "XQU", "SHANGHAI SVA-DAV ELECTRONICS CO., LTD" },
+ { "XRC", "Xircom Inc" },
+ { "XRO", "XORO ELECTRONICS (CHENGDU) LIMITED" },
+ { "XSN", "Xscreen AS" },
+ { "XST", "XS Technologies Inc" },
+ { "XSY", "XSYS" },
+ { "XTD", "Icuiti Corporation" },
+ { "XTE", "X2E GmbH" },
+ { "XTL", "Crystal Computer" },
+ { "XTN", "X-10 (USA) Inc" },
+ { "XYC", "Xycotec Computer GmbH" },
+ { "YED", "Y-E Data Inc" },
+ { "YHQ", "Yokogawa Electric Corporation" },
+ { "YHW", "Exacom SA" },
+ { "YMH", "Yamaha Corporation" },
{ "YOW", "American Biometric Company" },
- { "MGE", "Schneider Electric S.A." },
- { "AKP", "Atom Komplex Prylad" },
- { "PGI", "PACSGEAR, Inc." },
- { "III", "Intelligent Instrumentation" },
- { "BML", "BIOMED Lab" },
- { "KMC", "Mitsumi Company Ltd" },
- { "RSQ", "R Squared" },
- { "SBC", "Shanghai Bell Telephone Equip Mfg Co" },
- { "FPX", "Cirel Systemes" },
- { "IDN", "Idneo Technologies" },
- { "BNE", "Bull AB" },
+ { "ZAN", "Zandar Technologies plc" },
+ { "ZAX", "Zefiro Acoustics" },
+ { "ZAZ", "Zazzle Technologies" },
+ { "ZBR", "Zebra Technologies International, LLC" },
+ { "ZCT", "ZeitControl cardsystems GmbH" },
+ { "ZDS", "Zenith Data Systems" },
+ { "ZGT", "Zenith Data Systems" },
+ { "ZIC", "Nationz Technologies Inc." },
+ { "ZMT", "Zalman Tech Co., Ltd." },
+ { "ZMZ", "Z Microsystems" },
+ { "ZNI", "Zetinet Inc" },
+ { "ZNX", "Znyx Adv. Systems" },
+ { "ZOW", "Zowie Intertainment, Inc" },
+ { "ZRN", "Zoran Corporation" },
+ { "ZSE", "Zenith Data Systems" },
+ { "ZTC", "ZyDAS Technology Corporation" },
+ { "ZTE", "ZTE Corporation" },
+ { "ZTI", "Zoom Telephonics Inc" },
+ { "ZTM", "ZT Group Int'l Inc." },
+ { "ZTT", "Z3 Technology" },
+ { "ZYD", "Zydacron Inc" },
+ { "ZYP", "Zypcom Inc" },
+ { "ZYT", "Zytex Computers" },
+ { "ZYX", "Zyxel" },
+ { "ZZZ", "Boca Research Inc" },
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp
index 11d9c259d5..2e1d81a181 100644
--- a/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp
+++ b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp
@@ -43,7 +43,7 @@
QT_BEGIN_NAMESPACE
-class QAbstractEventDispatcher *createUnixEventDispatcher()
+class QAbstractEventDispatcher *QtGenericUnixDispatcher::createUnixEventDispatcher()
{
#if !defined(QT_NO_GLIB) && !defined(Q_OS_WIN)
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB") && QEventDispatcherGlib::versionSupported())
diff --git a/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h
index adf70adc05..61b4d0515c 100644
--- a/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h
+++ b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h
@@ -56,7 +56,10 @@
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
+namespace QtGenericUnixDispatcher {
QAbstractEventDispatcher* createUnixEventDispatcher();
+}
+using QtGenericUnixDispatcher::createUnixEventDispatcher;
QT_END_NAMESPACE
diff --git a/src/platformsupport/eventdispatchers/qunixeventdispatcher.cpp b/src/platformsupport/eventdispatchers/qunixeventdispatcher.cpp
index 7438ab65c1..44258538ec 100644
--- a/src/platformsupport/eventdispatchers/qunixeventdispatcher.cpp
+++ b/src/platformsupport/eventdispatchers/qunixeventdispatcher.cpp
@@ -43,14 +43,9 @@
#include "private/qguiapplication_p.h"
#include <qpa/qwindowsysteminterface.h>
-#include <QtCore/QElapsedTimer>
-#include <QtCore/QAtomicInt>
-#include <QtCore/QSemaphore>
#include <QtCore/QDebug>
-#include <errno.h>
-
QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE
diff --git a/src/platformsupport/eventdispatchers/qunixeventdispatcher_qpa_p.h b/src/platformsupport/eventdispatchers/qunixeventdispatcher_qpa_p.h
index 23be081ba3..7f775b73ee 100644
--- a/src/platformsupport/eventdispatchers/qunixeventdispatcher_qpa_p.h
+++ b/src/platformsupport/eventdispatchers/qunixeventdispatcher_qpa_p.h
@@ -56,12 +56,9 @@
QT_BEGIN_NAMESPACE
-class QUnixEventDispatcherQPAPrivate;
-
class QUnixEventDispatcherQPA : public QEventDispatcherUNIX
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QUnixEventDispatcherQPA)
public:
explicit QUnixEventDispatcherQPA(QObject *parent = 0);
diff --git a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp
index aa7bb102c6..a37547f513 100644
--- a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp
+++ b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp
@@ -184,7 +184,33 @@ messageDebugEntries[] = {
{WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD", true},
{WM_THEMECHANGED, "WM_THEMECHANGED", true},
{0x90, "WM_UAHDESTROYWINDOW", true},
- {0x272, "WM_UNREGISTER_WINDOW_SERVICES", true}
+ {0x272, "WM_UNREGISTER_WINDOW_SERVICES", true},
+#ifdef WM_POINTERUPDATE
+ {WM_POINTERDEVICECHANGE, "WM_POINTERDEVICECHANGE", true},
+ {WM_POINTERDEVICEINRANGE, "WM_POINTERDEVICEINRANGE", true},
+ {WM_POINTERDEVICEOUTOFRANGE, "WM_POINTERDEVICEOUTOFRANGE", true},
+ {WM_NCPOINTERUPDATE, "WM_NCPOINTERUPDATE", true},
+ {WM_NCPOINTERDOWN, "WM_NCPOINTERDOWN", true},
+ {WM_NCPOINTERUP, "WM_NCPOINTERUP", true},
+ {WM_POINTERUPDATE, "WM_POINTERUPDATE", true},
+ {WM_POINTERDOWN, "WM_POINTERDOWN", true},
+ {WM_POINTERUP, "WM_POINTERUP", true},
+ {WM_POINTERENTER, "WM_POINTERENTER", true},
+ {WM_POINTERLEAVE, "WM_POINTERLEAVE", true},
+ {WM_POINTERACTIVATE, "WM_POINTERACTIVATE", true},
+ {WM_POINTERCAPTURECHANGED, "WM_POINTERCAPTURECHANGED", true},
+ {WM_TOUCHHITTESTING, "WM_TOUCHHITTESTING", true},
+ {WM_POINTERWHEEL, "WM_POINTERWHEEL", true},
+ {WM_POINTERHWHEEL, "WM_POINTERHWHEEL", true},
+#endif // WM_POINTERUPDATE
+#ifdef DM_POINTERHITTEST
+ {DM_POINTERHITTEST, "DM_POINTERHITTEST", true},
+#endif // DM_POINTERHITTEST
+#ifdef WM_POINTERROUTEDTO
+ {WM_POINTERROUTEDTO, "WM_POINTERROUTEDTO", true},
+ {WM_POINTERROUTEDAWAY, "WM_POINTERROUTEDAWAY", true},
+ {WM_POINTERROUTEDRELEASED, "WM_POINTERROUTEDRELEASED", true},
+#endif // WM_POINTERROUTEDTO
};
static inline const MessageDebugEntry *messageDebugEntry(UINT msg)
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index dabe2bc09e..7b4f6aa107 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -139,14 +139,6 @@ QtFreetypeData::~QtFreetypeData()
library = 0;
}
-#ifdef QT_NO_THREAD
-Q_GLOBAL_STATIC(QtFreetypeData, theFreetypeData)
-
-QtFreetypeData *qt_getFreetypeData()
-{
- return theFreetypeData();
-}
-#else
Q_GLOBAL_STATIC(QThreadStorage<QtFreetypeData *>, theFreetypeData)
QtFreetypeData *qt_getFreetypeData()
@@ -169,7 +161,6 @@ QtFreetypeData *qt_getFreetypeData()
}
return freetypeData;
}
-#endif
FT_Library qt_getFreetype()
{
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 91c2dc8cf0..5faeca0618 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -101,14 +101,14 @@ enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) }
#ifdef Q_OS_OSX
static NSInteger languageMapSort(id obj1, id obj2, void *context)
{
- NSArray *map1 = (NSArray *) obj1;
- NSArray *map2 = (NSArray *) obj2;
- NSArray *languages = (NSArray *) context;
+ NSArray<NSString *> *map1 = reinterpret_cast<NSArray<NSString *> *>(obj1);
+ NSArray<NSString *> *map2 = reinterpret_cast<NSArray<NSString *> *>(obj2);
+ NSArray<NSString *> *languages = reinterpret_cast<NSArray<NSString *> *>(context);
- NSString *lang1 = [map1 objectAtIndex: 0];
- NSString *lang2 = [map2 objectAtIndex: 0];
+ NSString *lang1 = [map1 objectAtIndex:0];
+ NSString *lang2 = [map2 objectAtIndex:0];
- return [languages indexOfObject: lang1] - [languages indexOfObject: lang2];
+ return [languages indexOfObject:lang1] - [languages indexOfObject:lang2];
}
#endif
@@ -184,23 +184,9 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase()
CFRelease(ref);
}
-static CFArrayRef availableFamilyNames()
-{
-#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(1060, 100000, 100000, 30000)
- if (&CTFontManagerCopyAvailableFontFamilyNames)
- return CTFontManagerCopyAvailableFontFamilyNames();
-#endif
-#if defined(QT_PLATFORM_UIKIT)
- CFMutableArrayRef familyNames = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, (CFArrayRef)[UIFont familyNames]);
- CFArrayAppendValue(familyNames, CFSTR(".PhoneFallback"));
- return familyNames;
-#endif
- Q_UNREACHABLE();
-}
-
void QCoreTextFontDatabase::populateFontDatabase()
{
- QCFType<CFArrayRef> familyNames = availableFamilyNames();
+ QCFType<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames();
for (NSString *familyName in familyNames.as<const NSArray *>())
QPlatformFontDatabase::registerFontFamily(QString::fromNSString(familyName));
@@ -220,7 +206,7 @@ bool QCoreTextFontDatabase::populateFamilyAliases()
if (m_hasPopulatedAliases)
return false;
- QCFType<CFArrayRef> familyNames = availableFamilyNames();
+ QCFType<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames();
for (NSString *familyName in familyNames.as<const NSArray *>()) {
NSFontManager *fontManager = [NSFontManager sharedFontManager];
NSString *localizedFamilyName = [fontManager localizedNameForFamily:familyName face:nil];
@@ -571,21 +557,21 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
if (!didPopulateStyleFallbacks) {
#if defined(Q_OS_MACX)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSArray *languages = [defaults stringArrayForKey: @"AppleLanguages"];
+ NSArray<NSString *> *languages = [defaults stringArrayForKey:@"AppleLanguages"];
- NSDictionary *fallbackDict = [NSDictionary dictionaryWithContentsOfFile: @"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist"];
+ NSDictionary<NSString *, id> *fallbackDict = [NSDictionary<NSString *, id> dictionaryWithContentsOfFile:@"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist"];
for (NSString *style in [fallbackDict allKeys]) {
- NSArray *list = [fallbackDict valueForKey: style];
+ NSArray *list = [fallbackDict valueForKey:style];
QFont::StyleHint fallbackStyleHint = styleHintFromNSString(style);
QStringList fallbackList;
for (id item in list) {
// sort the array based on system language preferences
- if ([item isKindOfClass: [NSArray class]]) {
- NSArray *langs = [(NSArray *) item sortedArrayUsingFunction: languageMapSort
- context: languages];
- for (NSArray *map in langs)
- fallbackList.append(familyNameFromPostScriptName([map objectAtIndex: 1]));
+ if ([item isKindOfClass:[NSArray class]]) {
+ NSArray *langs = [reinterpret_cast<NSArray *>(item)
+ sortedArrayUsingFunction:languageMapSort context:languages];
+ for (NSArray<NSString *> *map in langs)
+ fallbackList.append(familyNameFromPostScriptName([map objectAtIndex:1]));
}
else if ([item isKindOfClass: [NSString class]])
fallbackList.append(familyNameFromPostScriptName(item));
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 98b753eff9..6543759a3d 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -42,6 +42,7 @@
#include <qpa/qplatformfontdatabase.h>
#include <QtCore/qendian.h>
#include <QtCore/qsettings.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <private/qimage_p.h>
@@ -652,17 +653,36 @@ bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const
QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &matrix)
{
-
glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat);
bool isColorGlyph = glyphFormat == QFontEngine::Format_ARGB;
QImage::Format imageFormat = isColorGlyph ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
QImage im(br.width.ceil().toInt(), br.height.ceil().toInt(), imageFormat);
- im.fill(0);
-
if (!im.width() || !im.height())
return im;
+#if defined(Q_OS_MACOS)
+ CGColorRef glyphColor = CGColorGetConstantColor(kCGColorWhite);
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) {
+ // macOS 10.14 uses a new font smoothing algorithm that takes the fill color into
+ // account. This means our default approach of drawing white on black to produce
+ // the alpha map will result in non-native looking text when then drawn as black
+ // on white during the final blit. As a workaround we use the application's current
+ // appearance to decide whether to draw with white or black fill, and then invert
+ // the glyph image in the latter case, producing an alpha map. This covers the
+ // most common use-cases, but longer term we should propagate the fill color all
+ // the way from the paint engine, and include it in the key for the glyph cache.
+ if (!qt_mac_applicationIsInDarkMode())
+ glyphColor = CGColorGetConstantColor(kCGColorBlack);
+ }
+ const bool blackOnWhiteGlyphs = !isColorGlyph
+ && CGColorEqualToColor(glyphColor, CGColorGetConstantColor(kCGColorBlack));
+ if (blackOnWhiteGlyphs)
+ im.fill(Qt::white);
+ else
+#endif
+ im.fill(0); // Faster than Qt::black
+
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
uint cgflags = isColorGlyph ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
@@ -696,7 +716,11 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
if (!isColorGlyph) {
CGContextSetTextMatrix(ctx, cgMatrix);
+#if defined(Q_OS_MACOS)
+ CGContextSetFillColorWithColor(ctx, glyphColor);
+#else
CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
+#endif
CGContextSetTextDrawingMode(ctx, kCGTextFill);
CGContextSetTextPosition(ctx, pos_x, pos_y);
@@ -721,6 +745,11 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
CGContextRelease(ctx);
CGColorSpaceRelease(colorspace);
+#if defined(Q_OS_MACOS)
+ if (blackOnWhiteGlyphs)
+ im.invertPixels();
+#endif
+
return im;
}
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
index 8df8da1a38..c70d507b99 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
@@ -368,6 +368,7 @@ namespace {
class DirectWriteFontFileStream: public IDWriteFontFileStream
{
+ Q_DISABLE_COPY(DirectWriteFontFileStream)
public:
DirectWriteFontFileStream(const QByteArray &fontData)
: m_fontData(fontData)
@@ -799,9 +800,9 @@ enum PlatformFieldValue {
PlatformId_Microsoft = 3
};
-FontNames qt_getCanonicalFontNames(const uchar *table, quint32 bytes)
+QFontNames qt_getCanonicalFontNames(const uchar *table, quint32 bytes)
{
- FontNames out;
+ QFontNames out;
const int NameRecordSize = 12;
const int MS_LangIdEnglish = 0x009;
@@ -947,7 +948,7 @@ QString qt_getEnglishName(const QString &familyName, bool includeStyle)
goto error;
{
- const FontNames names = qt_getCanonicalFontNames(table, bytes);
+ const QFontNames names = qt_getCanonicalFontNames(table, bytes);
i18n_name = names.name;
if (includeStyle)
i18n_name += QLatin1Char(' ') + names.style;
@@ -963,9 +964,9 @@ error:
}
// Note this duplicates parts of qt_getEnglishName, we should try to unify the two functions.
-FontNames qt_getCanonicalFontNames(const LOGFONT &lf)
+QFontNames qt_getCanonicalFontNames(const LOGFONT &lf)
{
- FontNames fontNames;
+ QFontNames fontNames;
HDC hdc = GetDC(0);
HFONT hfont = CreateFontIndirect(&lf);
@@ -1054,7 +1055,7 @@ static bool addFontToDatabase(QString familyName,
QString subFamilyStyle;
if (ttf) {
// Look-up names registered in the font
- FontNames canonicalNames = qt_getCanonicalFontNames(logFont);
+ QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
englishName = canonicalNames.name;
if (!canonicalNames.preferredName.isEmpty()) {
@@ -1231,7 +1232,6 @@ void QWindowsFontDatabase::populateFontDatabase()
typedef QSharedPointer<QWindowsFontEngineData> QWindowsFontEngineDataPtr;
-#ifndef QT_NO_THREAD
typedef QThreadStorage<QWindowsFontEngineDataPtr> FontEngineThreadLocalData;
Q_GLOBAL_STATIC(FontEngineThreadLocalData, fontEngineThreadLocalData)
@@ -1243,17 +1243,6 @@ QSharedPointer<QWindowsFontEngineData> sharedFontData()
data->setLocalData(QSharedPointer<QWindowsFontEngineData>::create());
return data->localData();
}
-#else // !QT_NO_THREAD
-Q_GLOBAL_STATIC(QWindowsFontEngineDataPtr, fontEngineData)
-
-QWindowsFontEngineDataPtr sharedFontData()
-{
- QWindowsFontEngineDataPtr *data = fontEngineData();
- if (data->isNull())
- *data = QWindowsFontEngineDataPtr::create();
- return *data;
-}
-#endif // QT_NO_THREAD
QWindowsFontDatabase::QWindowsFontDatabase()
{
@@ -1500,7 +1489,7 @@ static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag,
}
static void getFamiliesAndSignatures(const QByteArray &fontData,
- QList<FontNames> *families,
+ QList<QFontNames> *families,
QVector<FONTSIGNATURE> *signatures)
{
const uchar *data = reinterpret_cast<const uchar *>(fontData.constData());
@@ -1516,7 +1505,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
if (!table)
continue;
- FontNames names = qt_getCanonicalFontNames(table, length);
+ QFontNames names = qt_getCanonicalFontNames(table, length);
if (names.name.isEmpty())
continue;
@@ -1547,7 +1536,7 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
WinApplicationFont font;
font.fileName = fileName;
QVector<FONTSIGNATURE> signatures;
- QList<FontNames> families;
+ QList<QFontNames> families;
QStringList familyNames;
if (!fontData.isEmpty()) {
@@ -1616,11 +1605,12 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
void QWindowsFontDatabase::removeApplicationFonts()
{
- foreach (const WinApplicationFont &font, m_applicationFonts) {
+ for (const WinApplicationFont &font : qAsConst(m_applicationFonts)) {
if (font.handle) {
RemoveFontMemResourceEx(font.handle);
} else {
- RemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0);
+ RemoveFontResourceExW(reinterpret_cast<LPCWSTR>(font.fileName.utf16()),
+ FR_PRIVATE, nullptr);
}
}
m_applicationFonts.clear();
@@ -1664,7 +1654,8 @@ void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont)
// ### fixme Qt 6 (QTBUG-58610): See comment at QWindowsFontDatabase::systemDefaultFont()
HFONT QWindowsFontDatabase::systemFont()
{
- static const HFONT stock_sysfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+ static const auto stock_sysfont =
+ reinterpret_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT));
return stock_sysfont;
}
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
index 299dfd40cd..f68ea54dcf 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
@@ -210,7 +210,7 @@ static bool addFontToDatabase(QString familyName,
QString subFamilyStyle;
if (ttf) {
// Look-up names registered in the font
- FontNames canonicalNames = qt_getCanonicalFontNames(logFont);
+ QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
englishName = canonicalNames.name;
if (!canonicalNames.preferredName.isEmpty()) {
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
index 30f5beefdf..ab6d6307c7 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
@@ -85,6 +85,7 @@ public:
class QWindowsFontDatabase : public QPlatformFontDatabase
{
+ Q_DISABLE_COPY(QWindowsFontDatabase)
public:
enum FontOptions {
// Relevant bits from QWindowsIntegration::Options
@@ -93,7 +94,7 @@ public:
};
QWindowsFontDatabase();
- ~QWindowsFontDatabase();
+ ~QWindowsFontDatabase() override;
void populateFontDatabase() override;
void populateFamily(const QString &familyName) override;
@@ -168,7 +169,8 @@ inline quint16 qt_getUShort(const unsigned char *p)
return val;
}
-struct FontNames {
+struct QFontNames
+{
QString name; // e.g. "DejaVu Sans Condensed"
QString style; // e.g. "Italic"
QString preferredName; // e.g. "DejaVu Sans"
@@ -177,7 +179,7 @@ struct FontNames {
bool qt_localizedName(const QString &name);
QString qt_getEnglishName(const QString &familyName, bool includeStyle = false);
-FontNames qt_getCanonicalFontNames(const LOGFONT &lf);
+QFontNames qt_getCanonicalFontNames(const LOGFONT &lf);
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp
index 584e4db05d..2a41209225 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp
@@ -111,9 +111,8 @@ QFixed QWindowsFontEngine::lineThickness() const
static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
{
- int size;
- size = GetOutlineTextMetrics(hdc, 0, 0);
- OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size);
+ const auto size = GetOutlineTextMetrics(hdc, 0, nullptr);
+ auto otm = reinterpret_cast<OUTLINETEXTMETRIC *>(malloc(size));
GetOutlineTextMetrics(hdc, size, otm);
return otm;
}
@@ -1140,7 +1139,7 @@ QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTra
QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32);
for (int y=0; y<mask->height(); ++y) {
- uint *dest = (uint *) rgbMask.scanLine(y);
+ auto dest = reinterpret_cast<uint *>(rgbMask.scanLine(y));
const uint *src = reinterpret_cast<const uint *>(source.constScanLine(y));
for (int x=0; x<mask->width(); ++x) {
dest[x] = 0xffffffff - (0x00ffffff & src[x]);
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h
index 2ec391c4da..a151cf7343 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h
@@ -66,13 +66,14 @@ class QWindowsFontEngineData;
class QWindowsFontEngine : public QFontEngine
{
+ Q_DISABLE_COPY(QWindowsFontEngine)
friend class QWindowsMultiFontEngine;
public:
QWindowsFontEngine(const QString &name, LOGFONT lf,
const QSharedPointer<QWindowsFontEngineData> &fontEngineData);
- ~QWindowsFontEngine();
+ ~QWindowsFontEngine() override;
void initFontInfo(const QFontDef &request,
int dpi);
@@ -89,7 +90,7 @@ public:
void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const override;
void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) override;
- virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags) override;
HGDIOBJ selectDesignFont() const;
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
index 0e017c3b77..57c41938bc 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
@@ -69,15 +69,14 @@ namespace {
class GeometrySink: public IDWriteGeometrySink
{
+ Q_DISABLE_COPY(GeometrySink)
public:
GeometrySink(QPainterPath *path)
: m_refCount(0), m_path(path)
{
Q_ASSERT(m_path != 0);
}
- virtual ~GeometrySink()
- {
- }
+ virtual ~GeometrySink() = default;
IFACEMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT *beziers, UINT bezierCount);
IFACEMETHOD_(void, AddLines)(const D2D1_POINT_2F *points, UINT pointCount);
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
index 83fdddfa26..9326f5aece 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
@@ -72,11 +72,12 @@ class QWindowsFontEngineData;
class QWindowsFontEngineDirectWrite : public QFontEngine
{
+ Q_DISABLE_COPY(QWindowsFontEngineDirectWrite)
public:
explicit QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
qreal pixelSize,
const QSharedPointer<QWindowsFontEngineData> &d);
- ~QWindowsFontEngineDirectWrite();
+ ~QWindowsFontEngineDirectWrite() override;
void initFontInfo(const QFontDef &request, int dpi);
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
index a5895559e6..ef81f6162d 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
@@ -366,6 +366,25 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
if (!cloneSource.isEmpty())
qCDebug(qLcKmsDebug) << "Output" << connectorName << " clones output " << cloneSource;
+ const QByteArray fbsize = userConnectorConfig.value(QStringLiteral("size")).toByteArray().toLower();
+ QSize framebufferSize;
+ framebufferSize.setWidth(modes[selected_mode].hdisplay);
+ framebufferSize.setHeight(modes[selected_mode].vdisplay);
+
+#if QT_CONFIG(drm_atomic)
+ if (hasAtomicSupport()) {
+ if (sscanf(fbsize.constData(), "%dx%d", &framebufferSize.rwidth(), &framebufferSize.rheight()) != 2) {
+ qWarning("Framebuffer size format is invalid.");
+ }
+ } else {
+ qWarning("Setting framebuffer size is only available with DRM atomic API");
+ }
+#else
+ if (fbsize.size())
+ qWarning("Setting framebuffer size is only available with DRM atomic API");
+#endif
+ qCDebug(qLcKmsDebug) << "Output" << connectorName << "framebuffer size is " << framebufferSize;
+
QKmsOutput output;
output.name = QString::fromUtf8(connectorName);
output.connector_id = connector->connector_id;
@@ -385,6 +404,17 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
output.forced_plane_set = false;
output.drm_format = drmFormat;
output.clone_source = cloneSource;
+ output.size = framebufferSize;
+
+#if QT_CONFIG(drm_atomic)
+ if (drmModeCreatePropertyBlob(m_dri_fd, &modes[selected_mode], sizeof(drmModeModeInfo),
+ &output.mode_blob_id) != 0) {
+ qCDebug(qLcKmsDebug) << "Failed to create mode blob for mode" << selected_mode;
+ }
+
+ parseConnectorProperties(output.connector_id, &output);
+ parseCrtcProperties(output.crtc_id, &output);
+#endif
QString planeListStr;
for (const QKmsPlane &plane : qAsConst(m_planes)) {
@@ -392,6 +422,8 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
output.available_planes.append(plane);
planeListStr.append(QString::number(plane.id));
planeListStr.append(QLatin1Char(' '));
+ if (plane.type == QKmsPlane::PrimaryPlane)
+ output.eglfs_plane = (QKmsPlane*)&plane;
}
}
qCDebug(qLcKmsDebug, "Output %s can use %d planes: %s",
@@ -412,6 +444,12 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
output.forced_plane_id = plane->plane_id;
qCDebug(qLcKmsDebug, "Forcing plane index %d, plane id %u (belongs to crtc id %u)",
idx, plane->plane_id, plane->crtc_id);
+
+ for (const QKmsPlane &kmsplane : qAsConst(m_planes)) {
+ if (kmsplane.id == output.forced_plane_id)
+ output.eglfs_plane = (QKmsPlane*)&kmsplane;
+ }
+
drmModeFreePlane(plane);
}
} else {
@@ -420,6 +458,9 @@ QPlatformScreen *QKmsDevice::createScreenForConnector(drmModeResPtr resources,
}
}
+ if (output.eglfs_plane)
+ qCDebug(qLcKmsDebug, "Output eglfs plane is: %d", output.eglfs_plane->id);
+
m_crtc_allocator |= (1 << output.crtc_index);
vinfo->output = output;
@@ -464,6 +505,11 @@ QKmsDevice::QKmsDevice(QKmsScreenConfig *screenConfig, const QString &path)
: m_screenConfig(screenConfig)
, m_path(path)
, m_dri_fd(-1)
+ , m_has_atomic_support(false)
+#if QT_CONFIG(drm_atomic)
+ , m_atomic_request(nullptr)
+ , m_previous_request(nullptr)
+#endif
, m_crtc_allocator(0)
{
if (m_path.isEmpty()) {
@@ -478,6 +524,9 @@ QKmsDevice::QKmsDevice(QKmsScreenConfig *screenConfig, const QString &path)
QKmsDevice::~QKmsDevice()
{
+#if QT_CONFIG(drm_atomic)
+ atomicReset();
+#endif
}
struct OrderedScreen
@@ -522,6 +571,14 @@ void QKmsDevice::createScreens()
drmSetClientCap(m_dri_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+#if QT_CONFIG(drm_atomic)
+ // check atomic support
+ m_has_atomic_support = !drmSetClientCap(m_dri_fd, DRM_CLIENT_CAP_ATOMIC, 1)
+ && qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ATOMIC");
+ if (m_has_atomic_support)
+ qCDebug(qLcKmsDebug) << "Atomic Support found";
+#endif
+
drmModeResPtr resources = drmModeGetResources(m_dri_fd);
if (!resources) {
qErrnoWarning(errno, "drmModeGetResources failed");
@@ -747,6 +804,28 @@ void QKmsDevice::discoverPlanes()
plane.availableRotations |= QKmsPlane::Rotation(1 << prop->enums[i].value);
}
plane.rotationPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "crtc_id")) {
+ plane.crtcPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "fb_id")) {
+ plane.framebufferPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "src_w")) {
+ plane.srcwidthPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "src_h")) {
+ plane.srcheightPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "crtc_w")) {
+ plane.crtcwidthPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "crtc_h")) {
+ plane.crtcheightPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "src_x")) {
+ plane.srcXPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "src_y")) {
+ plane.srcYPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "crtc_x")) {
+ plane.crtcXPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "crtc_y")) {
+ plane.crtcYPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "zpos")) {
+ plane.zposPropertyId = prop->prop_id;
}
});
@@ -773,6 +852,86 @@ void QKmsDevice::setFd(int fd)
m_dri_fd = fd;
}
+
+bool QKmsDevice::hasAtomicSupport()
+{
+ return m_has_atomic_support;
+}
+
+#if QT_CONFIG(drm_atomic)
+drmModeAtomicReq * QKmsDevice::atomic_request()
+{
+ if (!m_atomic_request && m_has_atomic_support)
+ m_atomic_request = drmModeAtomicAlloc();
+
+ return m_atomic_request;
+}
+
+bool QKmsDevice::atomicCommit(void *user_data)
+{
+ if (m_atomic_request) {
+ int ret = drmModeAtomicCommit(m_dri_fd, m_atomic_request,
+ DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_ALLOW_MODESET, user_data);
+
+ if (ret) {
+ qWarning("Failed to commit atomic request (code=%d)", ret);
+ return false;
+ }
+
+ m_previous_request = m_atomic_request;
+ m_atomic_request = nullptr;
+
+ return true;
+ }
+
+ return false;
+}
+
+void QKmsDevice::atomicReset()
+{
+ if (m_previous_request) {
+ drmModeAtomicFree(m_previous_request);
+ m_previous_request = nullptr;
+ }
+}
+#endif
+
+void QKmsDevice::parseConnectorProperties(uint32_t connectorId, QKmsOutput *output)
+{
+ drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(m_dri_fd, connectorId, DRM_MODE_OBJECT_CONNECTOR);
+ if (!objProps) {
+ qCDebug(qLcKmsDebug, "Failed to query connector %d object properties", connectorId);
+ return;
+ }
+
+ enumerateProperties(objProps, [output](drmModePropertyPtr prop, quint64 value) {
+ Q_UNUSED(value);
+ if (!strcasecmp(prop->name, "crtc_id"))
+ output->crtcIdPropertyId = prop->prop_id;
+ });
+
+ drmModeFreeObjectProperties(objProps);
+}
+
+void QKmsDevice::parseCrtcProperties(uint32_t crtcId, QKmsOutput *output)
+{
+ drmModeObjectPropertiesPtr objProps = drmModeObjectGetProperties(m_dri_fd, crtcId, DRM_MODE_OBJECT_CRTC);
+ if (!objProps) {
+ qCDebug(qLcKmsDebug, "Failed to query crtc %d object properties", crtcId);
+ return;
+ }
+
+ enumerateProperties(objProps, [output](drmModePropertyPtr prop, quint64 value) {
+ Q_UNUSED(value)
+ if (!strcasecmp(prop->name, "mode_id"))
+ output->modeIdPropertyId = prop->prop_id;
+ else if (!strcasecmp(prop->name, "active"))
+ output->activePropertyId = prop->prop_id;
+ });
+
+ drmModeFreeObjectProperties(objProps);
+}
+
QKmsScreenConfig *QKmsDevice::screenConfig() const
{
return m_screenConfig;
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice_p.h b/src/platformsupport/kmsconvenience/qkmsdevice_p.h
index 5eecedec39..403972fbb8 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice_p.h
+++ b/src/platformsupport/kmsconvenience/qkmsdevice_p.h
@@ -53,6 +53,7 @@
// We mean it.
//
+#include <QtGui/private/qtguiglobal_p.h>
#include <qpa/qplatformscreen.h>
#include <QtCore/QMap>
#include <QtCore/QVariant>
@@ -166,6 +167,17 @@ struct QKmsPlane
Rotations initialRotation = Rotation0;
Rotations availableRotations = Rotation0;
uint32_t rotationPropertyId = 0;
+ uint32_t crtcPropertyId = 0;
+ uint32_t framebufferPropertyId = 0;
+ uint32_t srcXPropertyId = 0;
+ uint32_t srcYPropertyId = 0;
+ uint32_t crtcXPropertyId = 0;
+ uint32_t crtcYPropertyId = 0;
+ uint32_t srcwidthPropertyId = 0;
+ uint32_t srcheightPropertyId = 0;
+ uint32_t crtcwidthPropertyId = 0;
+ uint32_t crtcheightPropertyId = 0;
+ uint32_t zposPropertyId = 0;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QKmsPlane::Rotations)
@@ -191,6 +203,13 @@ struct QKmsOutput
uint32_t drm_format = DRM_FORMAT_XRGB8888;
QString clone_source;
QVector<QKmsPlane> available_planes;
+ struct QKmsPlane *eglfs_plane = nullptr;
+ QSize size;
+ uint32_t crtcIdPropertyId = 0;
+ uint32_t modeIdPropertyId = 0;
+ uint32_t activePropertyId = 0;
+
+ uint32_t mode_blob_id = 0;
void restoreMode(QKmsDevice *device);
void cleanup(QKmsDevice *device);
@@ -215,6 +234,14 @@ public:
virtual void close() = 0;
virtual void *nativeDisplay() const = 0;
+ bool hasAtomicSupport();
+
+#if QT_CONFIG(drm_atomic)
+ bool atomicCommit(void *user_data);
+ void atomicReset();
+
+ drmModeAtomicReq *atomic_request();
+#endif
void createScreens();
int fd() const;
@@ -243,11 +270,19 @@ protected:
typedef std::function<void(drmModePropertyPtr, quint64)> PropCallback;
void enumerateProperties(drmModeObjectPropertiesPtr objProps, PropCallback callback);
void discoverPlanes();
+ void parseConnectorProperties(uint32_t connectorId, QKmsOutput *output);
+ void parseCrtcProperties(uint32_t crtcId, QKmsOutput *output);
QKmsScreenConfig *m_screenConfig;
QString m_path;
int m_dri_fd;
+ bool m_has_atomic_support;
+
+#if QT_CONFIG(drm_atomic)
+ drmModeAtomicReq *m_atomic_request;
+ drmModeAtomicReq *m_previous_request;
+#endif
quint32 m_crtc_allocator;
QVector<QKmsPlane> m_planes;
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
index cb1e367b9f..67884cef92 100644
--- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
@@ -50,7 +50,7 @@
#include <QtCore/QUrl>
#if QT_CONFIG(dbus)
-// These QtCore includes are needed for flatpak support
+// These QtCore includes are needed for xdg-desktop-portal support
#include <QtCore/private/qcore_unix_p.h>
#include <QtCore/QFileInfo>
@@ -172,12 +172,47 @@ static inline bool launch(const QString &launcher, const QUrl &url)
}
#if QT_CONFIG(dbus)
-static inline bool checkRunningUnderFlatpak()
+static inline bool checkNeedPortalSupport()
{
- return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty();
+ return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty() || qEnvironmentVariableIsSet("SNAP");
}
-static inline bool flatpakOpenUrl(const QUrl &url)
+static inline bool xdgDesktopPortalOpenFile(const QUrl &url)
+{
+ // DBus signature:
+ // OpenFile (IN s parent_window,
+ // IN h fd,
+ // IN a{sv} options,
+ // OUT o handle)
+ // Options:
+ // handle_token (s) - A string that will be used as the last element of the @handle.
+ // writable (b) - Whether to allow the chosen application to write to the file.
+
+#ifdef O_PATH
+ const int fd = qt_safe_open(QFile::encodeName(url.toLocalFile()), O_PATH);
+ if (fd != -1) {
+ QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.OpenURI"),
+ QLatin1String("OpenFile"));
+
+ QDBusUnixFileDescriptor descriptor(fd);
+ qt_safe_close(fd);
+
+ // FIXME parent_window_id and handle writable option
+ message << QString() << QVariant::fromValue(descriptor) << QVariantMap();
+
+ QDBusPendingReply<QDBusObjectPath> reply = QDBusConnection::sessionBus().call(message);
+ return !reply.isError();
+ }
+#else
+ Q_UNUSED(url)
+#endif
+
+ return false;
+}
+
+static inline bool xdgDesktopPortalOpenUrl(const QUrl &url)
{
// DBus signature:
// OpenURI (IN s parent_window,
@@ -185,6 +220,7 @@ static inline bool flatpakOpenUrl(const QUrl &url)
// IN a{sv} options,
// OUT o handle)
// Options:
+ // handle_token (s) - A string that will be used as the last element of the @handle.
// writable (b) - Whether to allow the chosen application to write to the file.
// This key only takes effect the uri points to a local file that is exported in the document portal,
// and the chosen application is sandboxed itself.
@@ -200,7 +236,7 @@ static inline bool flatpakOpenUrl(const QUrl &url)
return !reply.isError();
}
-static inline bool flatpakSendEmail(const QUrl &url)
+static inline bool xdgDesktopPortalSendEmail(const QUrl &url)
{
// DBus signature:
// ComposeEmail (IN s parent_window,
@@ -258,15 +294,15 @@ bool QGenericUnixServices::openUrl(const QUrl &url)
{
if (url.scheme() == QLatin1String("mailto")) {
#if QT_CONFIG(dbus)
- if (checkRunningUnderFlatpak())
- return flatpakSendEmail(url);
+ if (checkNeedPortalSupport())
+ return xdgDesktopPortalSendEmail(url);
#endif
return openDocument(url);
}
#if QT_CONFIG(dbus)
- if (checkRunningUnderFlatpak())
- return flatpakOpenUrl(url);
+ if (checkNeedPortalSupport())
+ return xdgDesktopPortalOpenUrl(url);
#endif
if (m_webBrowser.isEmpty() && !detectWebBrowser(desktopEnvironment(), true, &m_webBrowser)) {
@@ -278,6 +314,11 @@ bool QGenericUnixServices::openUrl(const QUrl &url)
bool QGenericUnixServices::openDocument(const QUrl &url)
{
+#if QT_CONFIG(dbus)
+ if (checkNeedPortalSupport())
+ return xdgDesktopPortalOpenFile(url);
+#endif
+
if (m_documentLauncher.isEmpty() && !detectWebBrowser(desktopEnvironment(), false, &m_documentLauncher)) {
qWarning("Unable to detect a launcher for '%s'", qPrintable(url.toString()));
return false;
diff --git a/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp b/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp
index 382d142334..b9c5669b3f 100644
--- a/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp
+++ b/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance.cpp
@@ -82,6 +82,21 @@ QBasicPlatformVulkanInstance::~QBasicPlatformVulkanInstance()
m_vkDestroyInstance(m_vkInst, nullptr);
}
+void QBasicPlatformVulkanInstance::loadVulkanLibrary(const QString &defaultLibraryName)
+{
+ if (qEnvironmentVariableIsSet("QT_VULKAN_LIB"))
+ m_vulkanLib.setFileName(QString::fromUtf8(qgetenv("QT_VULKAN_LIB")));
+ else
+ m_vulkanLib.setFileName(defaultLibraryName);
+
+ if (!m_vulkanLib.load()) {
+ qWarning("Failed to load %s: %s", qPrintable(m_vulkanLib.fileName()), qPrintable(m_vulkanLib.errorString()));
+ return;
+ }
+
+ init(&m_vulkanLib);
+}
+
void QBasicPlatformVulkanInstance::init(QLibrary *lib)
{
if (m_vkGetInstanceProcAddr)
@@ -256,6 +271,11 @@ void QBasicPlatformVulkanInstance::initInstance(QVulkanInstance *instance, const
if (!m_getPhysDevSurfaceSupport)
qWarning("Failed to find vkGetPhysicalDeviceSurfaceSupportKHR");
+ m_destroySurface = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
+ m_vkGetInstanceProcAddr(m_vkInst, "vkDestroySurfaceKHR"));
+ if (!m_destroySurface)
+ qWarning("Failed to find vkDestroySurfaceKHR");
+
if (!flags.testFlag(QVulkanInstance::NoDebugOutputRedirect))
setupDebugOutput();
}
@@ -310,6 +330,12 @@ bool QBasicPlatformVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevi
return supported;
}
+void QBasicPlatformVulkanInstance::destroySurface(VkSurfaceKHR surface) const
+{
+ if (m_destroySurface && surface)
+ m_destroySurface(m_vkInst, surface, nullptr);
+}
+
static VKAPI_ATTR VkBool32 VKAPI_CALL defaultDebugCallbackFunc(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
diff --git a/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance_p.h b/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance_p.h
index 748b138f01..566140b032 100644
--- a/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance_p.h
+++ b/src/platformsupport/vkconvenience/qbasicvulkanplatforminstance_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtCore/QLibrary>
#include <qpa/qplatformvulkaninstance.h>
QT_BEGIN_NAMESPACE
@@ -72,18 +73,23 @@ public:
QByteArrayList enabledExtensions() const override;
PFN_vkVoidFunction getInstanceProcAddr(const char *name) override;
bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) override;
+ void destroySurface(VkSurfaceKHR surface) const;
protected:
+ void loadVulkanLibrary(const QString &defaultLibraryName);
void init(QLibrary *lib);
void initInstance(QVulkanInstance *instance, const QByteArrayList &extraExts);
VkInstance m_vkInst;
PFN_vkGetInstanceProcAddr m_vkGetInstanceProcAddr;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR m_getPhysDevSurfaceSupport;
+ PFN_vkDestroySurfaceKHR m_destroySurface;
private:
void setupDebugOutput();
+ QLibrary m_vulkanLib;
+
bool m_ownsVkInst;
VkResult m_errorCode;
QVulkanInfoVector<QVulkanLayer> m_supportedLayers;
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm
index 341d3bccf2..c3dd49ff3e 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.mm
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -62,33 +62,29 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time
#include <ifaddrs.h>
@interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject <CWEventDelegate>
-{
- NSNotificationCenter *notificationCenter;
- CWWiFiClient *client;
- QCoreWlanEngine *engine;
- NSLock *locker;
-}
-- (void)powerStateDidChangeForWiFiInterfaceWithName:(NSString *)interfaceName;
-- (void)remove;
-- (void)setEngine:(QCoreWlanEngine *)coreEngine;
-- (QCoreWlanEngine *)engine;
-- (void)dealloc;
@property (assign) QCoreWlanEngine* engine;
@end
-@implementation QT_MANGLE_NAMESPACE(QNSListener)
+@implementation QT_MANGLE_NAMESPACE(QNSListener) {
+ NSNotificationCenter *notificationCenter;
+ CWWiFiClient *client;
+ QCoreWlanEngine *engine;
+ NSLock *locker;
+}
-- (id) init
+- (instancetype)init
{
- [locker lock];
- QMacAutoReleasePool pool;
- notificationCenter = [NSNotificationCenter defaultCenter];
- client = [CWWiFiClient sharedWiFiClient];
- client.delegate = self;
- [client startMonitoringEventWithType:CWEventTypePowerDidChange error:nil];
- [locker unlock];
+ if ((self = [super init])) {
+ [locker lock];
+ QMacAutoReleasePool pool;
+ notificationCenter = [NSNotificationCenter defaultCenter];
+ client = [CWWiFiClient sharedWiFiClient];
+ client.delegate = self;
+ [client startMonitoringEventWithType:CWEventTypePowerDidChange error:nil];
+ [locker unlock];
+ }
return self;
}
@@ -300,7 +296,7 @@ void QScanThread::getUserConfigurations()
if(airportPlist != nil) {
NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"];
- NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"];
+ NSArray<NSString *> *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"];
for (NSString *ssidkey in thisSsidarray) {
QString thisSsid = QString::fromNSString(ssidkey);
if(!userProfiles.contains(thisSsid)) {
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 1cdc28c077..e52a19703c 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -493,10 +493,10 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt
{
const QMap<QString, QString> text = qt_getImageText(image, description);
for (auto it = text.begin(), end = text.end(); it != end; ++it) {
- QByteArray comment = it.key().toLatin1();
+ QByteArray comment = it.key().toUtf8();
if (!comment.isEmpty())
comment += ": ";
- comment += it.value().toLatin1();
+ comment += it.value().toUtf8();
if (comment.length() > 65530)
comment.truncate(65530);
jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)comment.constData(), comment.size());
@@ -904,7 +904,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
for (jpeg_saved_marker_ptr marker = info.marker_list; marker != NULL; marker = marker->next) {
if (marker->marker == JPEG_COM) {
QString key, value;
- QString s = QString::fromLatin1((const char *)marker->data, marker->data_length);
+ QString s = QString::fromUtf8((const char *)marker->data, marker->data_length);
int index = s.indexOf(QLatin1String(": "));
if (index == -1 || s.indexOf(QLatin1Char(' ')) < index) {
key = QLatin1String("Description");
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index dabab553c2..9cdc5de0e1 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -58,7 +58,6 @@ using namespace QtAndroid;
namespace QtAndroidInput
{
-
static bool m_ignoreMouseEvents = false;
static bool m_softwareKeyboardVisible = false;
static QRect m_softwareKeyboardRect;
@@ -124,11 +123,12 @@ namespace QtAndroidInput
return m_softwareKeyboardRect;
}
- void updateHandles(int mode, QPoint cursor, QPoint anchor, bool rtl)
+ void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
{
- QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "updateHandles", "(IIIIIZ)V",
- mode, cursor.x(), cursor.y(), anchor.x(),
- anchor.y(), rtl);
+ QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "updateHandles", "(IIIIIIIIZ)V",
+ mode, editMenuPos.x(), editMenuPos.y(), editButtons,
+ cursor.x(), cursor.y(),
+ anchor.x(), anchor.y(), rtl);
}
static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
@@ -173,7 +173,7 @@ namespace QtAndroidInput
QWindowSystemInterface::handleMouseEvent(tlw,
localPos,
globalPos,
- Qt::MouseButtons(Qt::LeftButton));
+ Qt::MouseButtons(m_mouseGrabber ? Qt::LeftButton : Qt::NoButton));
}
static void mouseWheel(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y, jfloat hdelta, jfloat vdelta)
@@ -195,6 +195,20 @@ namespace QtAndroidInput
angleDelta);
}
+ void releaseMouse(int x, int y)
+ {
+ m_ignoreMouseEvents = true;
+ QPoint globalPos(x,y);
+ QWindow *tlw = topLevelWindowAt(globalPos);
+ QPoint localPos = tlw ? (globalPos-tlw->position()) : globalPos;
+
+ // Release left button
+ QWindowSystemInterface::handleMouseEvent(tlw,
+ localPos,
+ globalPos,
+ Qt::MouseButtons(Qt::NoButton));
+ }
+
static void longPress(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)
{
QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
@@ -805,8 +819,10 @@ namespace QtAndroidInput
QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
if (inputContext && qGuiApp) {
inputContext->emitInputPanelVisibleChanged();
- if (!visibility)
+ if (!visibility) {
inputContext->emitKeyboardRectChanged();
+ QMetaObject::invokeMethod(inputContext, "hideSelectionHandles", Qt::QueuedConnection);
+ }
}
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ KEYBOARDVISIBILITYCHANGED" << inputContext;
diff --git a/src/plugins/platforms/android/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h
index c09b426f49..2e2470ae8f 100644
--- a/src/plugins/platforms/android/androidjniinput.h
+++ b/src/plugins/platforms/android/androidjniinput.h
@@ -58,9 +58,11 @@ namespace QtAndroidInput
// Software keyboard support
// cursor/selection handles
- void updateHandles(int handleCount, QPoint cursor = QPoint(), QPoint anchor = QPoint(), bool rtl = false);
+ void updateHandles(int handleCount, QPoint editMenuPos = QPoint(), uint32_t editButtons = 0, QPoint cursor = QPoint(), QPoint anchor = QPoint(), bool rtl = false);
bool registerNatives(JNIEnv *env);
+
+ void releaseMouse(int x, int y);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index c46a435db1..c5cd0b92d9 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -64,6 +64,29 @@
QT_BEGIN_NAMESPACE
+template <typename T>
+class ScopedValueChangeBack
+{
+public:
+ ScopedValueChangeBack(T &variable, T newValue)
+ : m_oldValue(variable),
+ m_variable(variable)
+ {
+ m_variable = newValue;
+ }
+ inline void setOldValue()
+ {
+ m_variable = m_oldValue;
+ }
+ ~ScopedValueChangeBack()
+ {
+ setOldValue();
+ }
+private:
+ T m_oldValue;
+ T &m_variable;
+};
+
static QAndroidInputContext *m_androidInputContext = 0;
static char const *const QtNativeInputConnectionClassName = "org/qtproject/qt5/android/QtNativeInputConnection";
static char const *const QtExtractedTextClassName = "org/qtproject/qt5/android/QtExtractedText";
@@ -76,6 +99,11 @@ static jfieldID m_selectionStartFieldID = 0;
static jfieldID m_startOffsetFieldID = 0;
static jfieldID m_textFieldID = 0;
+static void runOnQtThread(const std::function<void()> &func)
+{
+ QMetaObject::invokeMethod(m_androidInputContext, "safeCall", Qt::BlockingQueuedConnection, Q_ARG(std::function<void()>, func));
+}
+
static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
{
if (!m_androidInputContext)
@@ -84,10 +112,9 @@ static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ BEGINBATCH");
#endif
-
- return m_androidInputContext->beginBatchEdit();
-
- return JNI_TRUE;
+ jboolean res;
+ runOnQtThread([&res]{res = m_androidInputContext->beginBatchEdit();});
+ return res;
}
static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
@@ -99,9 +126,9 @@ static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
qDebug("@@@ ENDBATCH");
#endif
- return m_androidInputContext->endBatchEdit();
-
- return JNI_TRUE;
+ jboolean res;
+ runOnQtThread([&res]{res = m_androidInputContext->endBatchEdit();});
+ return res;
}
@@ -118,7 +145,9 @@ static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint new
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ COMMIT" << str << newCursorPosition;
#endif
- return m_androidInputContext->commitText(str, newCursorPosition);
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->commitText(str, newCursorPosition);});
+ return res;
}
static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint leftLength, jint rightLength)
@@ -129,7 +158,9 @@ static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint le
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ DELETE" << leftLength << rightLength;
#endif
- return m_androidInputContext->deleteSurroundingText(leftLength, rightLength);
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->deleteSurroundingText(leftLength, rightLength);});
+ return res;
}
static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/)
@@ -140,7 +171,9 @@ static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ FINISH");
#endif
- return m_androidInputContext->finishComposingText();
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->finishComposingText();});
+ return res;
}
static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes)
@@ -148,7 +181,9 @@ static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes)
if (!m_androidInputContext)
return 0;
- return m_androidInputContext->getCursorCapsMode(reqModes);
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->getCursorCapsMode(reqModes);});
+ return res;
}
static jobject getExtractedText(JNIEnv *env, jobject /*thiz*/, int hintMaxChars, int hintMaxLines, jint flags)
@@ -156,8 +191,8 @@ static jobject getExtractedText(JNIEnv *env, jobject /*thiz*/, int hintMaxChars,
if (!m_androidInputContext)
return 0;
- const QAndroidInputContext::ExtractedText &extractedText =
- m_androidInputContext->getExtractedText(hintMaxChars, hintMaxLines, flags);
+ QAndroidInputContext::ExtractedText extractedText;
+ runOnQtThread([&]{extractedText = m_androidInputContext->getExtractedText(hintMaxChars, hintMaxLines, flags);});
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ GETEX" << hintMaxChars << hintMaxLines << QString::fromLatin1("0x") + QString::number(flags,16) << extractedText.text << "partOff:" << extractedText.partialStartOffset << extractedText.partialEndOffset << "sel:" << extractedText.selectionStart << extractedText.selectionEnd << "offset:" << extractedText.startOffset;
@@ -182,7 +217,8 @@ static jstring getSelectedText(JNIEnv *env, jobject /*thiz*/, jint flags)
if (!m_androidInputContext)
return 0;
- const QString &text = m_androidInputContext->getSelectedText(flags);
+ QString text;
+ runOnQtThread([&]{text = m_androidInputContext->getSelectedText(flags);});
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ GETSEL" << text;
#endif
@@ -196,7 +232,8 @@ static jstring getTextAfterCursor(JNIEnv *env, jobject /*thiz*/, jint length, ji
if (!m_androidInputContext)
return 0;
- const QString &text = m_androidInputContext->getTextAfterCursor(length, flags);
+ QString text;
+ runOnQtThread([&]{text = m_androidInputContext->getTextAfterCursor(length, flags);});
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ GETA" << length << text;
#endif
@@ -208,7 +245,8 @@ static jstring getTextBeforeCursor(JNIEnv *env, jobject /*thiz*/, jint length, j
if (!m_androidInputContext)
return 0;
- const QString &text = m_androidInputContext->getTextBeforeCursor(length, flags);
+ QString text;
+ runOnQtThread([&]{text = m_androidInputContext->getTextBeforeCursor(length, flags);});
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ GETB" << length << text;
#endif
@@ -228,7 +266,9 @@ static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, ji
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SET" << str << newCursorPosition;
#endif
- return m_androidInputContext->setComposingText(str, newCursorPosition);
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->setComposingText(str, newCursorPosition);});
+ return res;
}
static jboolean setComposingRegion(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint end)
@@ -239,7 +279,9 @@ static jboolean setComposingRegion(JNIEnv */*env*/, jobject /*thiz*/, jint start
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SETR" << start << end;
#endif
- return m_androidInputContext->setComposingRegion(start, end);
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->setComposingRegion(start, end);});
+ return res;
}
@@ -251,7 +293,10 @@ static jboolean setSelection(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SETSEL" << start << end;
#endif
- return m_androidInputContext->setSelection(start, end);
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->setSelection(start, end);});
+ return res;
+
}
static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/)
@@ -262,7 +307,9 @@ static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ SELALL");
#endif
- return m_androidInputContext->selectAll();
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->selectAll();});
+ return res;
}
static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/)
@@ -273,7 +320,9 @@ static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@");
#endif
- return m_androidInputContext->cut();
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->cut();});
+ return res;
}
static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/)
@@ -284,7 +333,9 @@ static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@");
#endif
- return m_androidInputContext->copy();
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->copy();});
+ return res;
}
static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/)
@@ -295,7 +346,9 @@ static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@");
#endif
- return m_androidInputContext->copyURL();
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->copyURL();});
+ return res;
}
static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/)
@@ -306,7 +359,9 @@ static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ PASTE");
#endif
- return m_androidInputContext->paste();
+ jboolean res;
+ runOnQtThread([&]{res = m_androidInputContext->paste();});
+ return res;
}
static jboolean updateCursorPosition(JNIEnv */*env*/, jobject /*thiz*/)
@@ -317,7 +372,8 @@ static jboolean updateCursorPosition(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ UPDATECURSORPOS");
#endif
- m_androidInputContext->updateCursorPosition();
+
+ runOnQtThread([&]{m_androidInputContext->updateCursorPosition();});
return true;
}
@@ -365,7 +421,7 @@ static QRect inputItemRectangle()
QAndroidInputContext::QAndroidInputContext()
: QPlatformInputContext(), m_composingTextStart(-1), m_blockUpdateSelection(false),
- m_cursorHandleShown(CursorHandleNotShown), m_batchEditNestingLevel(0), m_focusObject(0)
+ m_handleMode(Hidden), m_batchEditNestingLevel(0), m_focusObject(0)
{
jclass clazz = QJNIEnvironmentPrivate::findClass(QtNativeInputConnectionClassName);
if (Q_UNLIKELY(!clazz)) {
@@ -445,10 +501,17 @@ QAndroidInputContext::QAndroidInputContext()
auto im = qGuiApp->inputMethod();
if (!im->inputItemClipRectangle().contains(im->anchorRectangle()) ||
!im->inputItemClipRectangle().contains(im->cursorRectangle())) {
- m_cursorHandleShown = CursorHandleNotShown;
+ m_handleMode = Hidden;
updateSelectionHandles();
}
});
+ m_hideCursorHandleTimer.setInterval(4000);
+ m_hideCursorHandleTimer.setSingleShot(true);
+ m_hideCursorHandleTimer.setTimerType(Qt::VeryCoarseTimer);
+ connect(&m_hideCursorHandleTimer, &QTimer::timeout, this, [this]{
+ m_handleMode = Hidden;
+ updateSelectionHandles();
+ });
}
QAndroidInputContext::~QAndroidInputContext()
@@ -486,9 +549,9 @@ void QAndroidInputContext::reset()
{
clear();
m_batchEditNestingLevel = 0;
- m_cursorHandleShown = QAndroidInputContext::CursorHandleNotShown;
+ m_handleMode = Hidden;
if (qGuiApp->focusObject()) {
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe(Qt::ImEnabled);
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(Qt::ImEnabled);
if (!query.isNull() && query->value(Qt::ImEnabled).toBool()) {
QtAndroidInput::resetSoftwareKeyboard();
return;
@@ -504,7 +567,7 @@ void QAndroidInputContext::commit()
void QAndroidInputContext::updateCursorPosition()
{
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) {
const int cursorPos = getAbsoluteCursorPosition(query);
const int composeLength = m_composingText.length();
@@ -542,9 +605,9 @@ void QAndroidInputContext::updateSelectionHandles()
return;
auto im = qGuiApp->inputMethod();
- if (!m_focusObject || (m_cursorHandleShown == CursorHandleNotShown)) {
+ if (!m_focusObject || ((m_handleMode & 0xff) == Hidden)) {
// Hide the handles
- QtAndroidInput::updateHandles(0);
+ QtAndroidInput::updateHandles(Hidden);
return;
}
QWindow *window = qGuiApp->focusWindow();
@@ -552,25 +615,34 @@ void QAndroidInputContext::updateSelectionHandles()
? QHighDpiScaling::factor(window)
: QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen());
- QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImEnabled | Qt::ImCurrentSelection);
+ QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImEnabled | Qt::ImCurrentSelection | Qt::ImHints | Qt::ImSurroundingText);
QCoreApplication::sendEvent(m_focusObject, &query);
+
int cpos = query.value(Qt::ImCursorPosition).toInt();
int anchor = query.value(Qt::ImAnchorPosition).toInt();
if (cpos == anchor || im->anchorRectangle().isNull()) {
if (!query.value(Qt::ImEnabled).toBool()) {
- QtAndroidInput::updateHandles(0);
+ QtAndroidInput::updateHandles(Hidden);
return;
}
auto curRect = im->cursorRectangle();
QPoint cursorPoint(curRect.center().x(), curRect.bottom());
- QPoint editMenuPoint(curRect.center().x(), curRect.top());
- QtAndroidInput::updateHandles(m_cursorHandleShown, cursorPoint * pixelDensity,
- editMenuPoint * pixelDensity);
+ QPoint editMenuPoint(curRect.x(), curRect.y());
+ m_handleMode &= ShowEditPopup;
+ m_handleMode |= ShowCursor;
+ uint32_t buttons = EditContext::PasteButton;
+ if (!query.value(Qt::ImSurroundingText).toString().isEmpty())
+ buttons |= EditContext::SelectAllButton;
+ QtAndroidInput::updateHandles(m_handleMode, editMenuPoint * pixelDensity, buttons, cursorPoint * pixelDensity);
+ // The VK is hidden, reset the timer
+ if (m_hideCursorHandleTimer.isActive())
+ m_hideCursorHandleTimer.start();
return;
}
+ m_handleMode = ShowSelection | ShowEditPopup ;
auto leftRect = im->cursorRectangle();
auto rightRect = im->anchorRectangle();
if (cpos > anchor)
@@ -578,13 +650,10 @@ void QAndroidInputContext::updateSelectionHandles()
QPoint leftPoint(leftRect.bottomLeft().toPoint() * pixelDensity);
QPoint righPoint(rightRect.bottomRight().toPoint() * pixelDensity);
- QtAndroidInput::updateHandles(CursorHandleShowSelection, leftPoint, righPoint,
+ QPoint editPoint(leftRect.united(rightRect).topLeft().toPoint() * pixelDensity);
+ QtAndroidInput::updateHandles(m_handleMode, editPoint, EditContext::AllButtons, leftPoint, righPoint,
query.value(Qt::ImCurrentSelection).toString().isRightToLeft());
-
- if (m_cursorHandleShown == CursorHandleShowPopup) {
- // make sure the popup does not reappear when the selection menu closes
- m_cursorHandleShown = QAndroidInputContext::CursorHandleNotShown;
- }
+ m_hideCursorHandleTimer.stop();
}
/*
@@ -594,8 +663,10 @@ void QAndroidInputContext::updateSelectionHandles()
*/
void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
{
- if (m_batchEditNestingLevel.load() || m_blockUpdateSelection)
+ if (m_batchEditNestingLevel.load() || m_blockUpdateSelection) {
+ qWarning() << "QAndroidInputContext::handleLocationChanged returned";
return;
+ }
finishComposingText();
@@ -669,34 +740,86 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
void QAndroidInputContext::touchDown(int x, int y)
{
- if (m_focusObject && inputItemRectangle().contains(x, y) && !m_cursorHandleShown) {
+ if (m_focusObject && inputItemRectangle().contains(x, y)) {
// If the user touch the input rectangle, we can show the cursor handle
- m_cursorHandleShown = QAndroidInputContext::CursorHandleShowNormal;
+ m_handleMode = ShowCursor;
+ // The VK will appear in a moment, stop the timer
+ m_hideCursorHandleTimer.stop();
+ finishComposingText();
updateSelectionHandles();
}
}
void QAndroidInputContext::longPress(int x, int y)
{
+ static bool noHandles = qEnvironmentVariableIntValue("QT_QPA_NO_TEXT_HANDLES");
+ if (noHandles)
+ return;
+
if (m_focusObject && inputItemRectangle().contains(x, y)) {
- // Show the paste menu if there is something to paste.
- m_cursorHandleShown = QAndroidInputContext::CursorHandleShowPopup;
+ finishComposingText();
+
+ // Release left button, otherwise the following events will cancel the menu popup
+ QtAndroidInput::releaseMouse(x, y);
+
+ handleLocationChanged(1, x, y);
+ ScopedValueChangeBack<bool> svcb(m_blockUpdateSelection, true);
+
+ QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImTextBeforeCursor | Qt::ImTextAfterCursor);
+ QCoreApplication::sendEvent(m_focusObject, &query);
+ int cursor = query.value(Qt::ImCursorPosition).toInt();
+ int anchor = cursor;
+ QString before = query.value(Qt::ImTextBeforeCursor).toString();
+ QString after = query.value(Qt::ImTextAfterCursor).toString();
+ for (const auto &ch : after) {
+ if (!ch.isLetterOrNumber())
+ break;
+ ++anchor;
+ }
+
+ for (auto itch = before.rbegin(); itch != after.rend(); ++itch) {
+ if (!itch->isLetterOrNumber())
+ break;
+ --cursor;
+ }
+ if (cursor == anchor || cursor < 0 || cursor - anchor > 500) {
+ m_handleMode = ShowCursor | ShowEditPopup;
+ updateSelectionHandles();
+ return;
+ }
+ QList<QInputMethodEvent::Attribute> imAttributes;
+ imAttributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, 0, QVariant()));
+ imAttributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, anchor, cursor - anchor, QVariant()));
+ QInputMethodEvent event(QString(), imAttributes);
+ QGuiApplication::sendEvent(m_focusObject, &event);
+
+ m_handleMode = ShowSelection | ShowEditPopup;
updateSelectionHandles();
}
}
void QAndroidInputContext::keyDown()
{
- if (m_cursorHandleShown) {
+ if (m_handleMode) {
// When the user enter text on the keyboard, we hide the cursor handle
- m_cursorHandleShown = QAndroidInputContext::CursorHandleNotShown;
+ m_handleMode = Hidden;
+ updateSelectionHandles();
+ }
+}
+
+void QAndroidInputContext::hideSelectionHandles()
+{
+ if (m_handleMode & ShowSelection) {
+ m_handleMode = Hidden;
updateSelectionHandles();
+ } else {
+ m_hideCursorHandleTimer.start();
}
}
void QAndroidInputContext::update(Qt::InputMethodQueries queries)
{
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe(queries);
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(queries);
if (query.isNull())
return;
#warning TODO extract the needed data from query
@@ -728,7 +851,7 @@ void QAndroidInputContext::showInputPanel()
connect(qGuiApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(showInputPanelLater(Qt::ApplicationState)));
return;
}
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return;
@@ -752,6 +875,14 @@ void QAndroidInputContext::showInputPanelLater(Qt::ApplicationState state)
showInputPanel();
}
+void QAndroidInputContext::safeCall(const std::function<void()> &func, Qt::ConnectionType conType)
+{
+ if (qGuiApp->thread() == QThread::currentThread())
+ func();
+ else
+ QMetaObject::invokeMethod(this, "safeCall", conType, Q_ARG(std::function<void()>, func));
+}
+
void QAndroidInputContext::hideInputPanel()
{
QtAndroidInput::hideSoftwareKeyboard();
@@ -810,17 +941,15 @@ jboolean QAndroidInputContext::endBatchEdit()
*/
jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPosition)
{
- bool updateSelectionWasBlocked = m_blockUpdateSelection;
- m_blockUpdateSelection = true;
-
+ ScopedValueChangeBack<bool> svcb(m_blockUpdateSelection, true);
QInputMethodEvent event;
event.setCommitString(text);
- sendInputMethodEventThreadSafe(&event);
+ sendInputMethodEvent(&event);
clear();
// Qt has now put the cursor at the end of the text, corresponding to newCursorPosition == 1
if (newCursorPosition != 1) {
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (!query.isNull()) {
QList<QInputMethodEvent::Attribute> attributes;
const int localPos = query->value(Qt::ImCursorPosition).toInt();
@@ -832,15 +961,14 @@ jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPos
newLocalPos, 0));
}
}
- m_blockUpdateSelection = updateSelectionWasBlocked;
-
+ svcb.setOldValue();
updateCursorPosition();
return JNI_TRUE;
}
jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint rightLength)
{
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return JNI_TRUE;
@@ -854,7 +982,7 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right
QInputMethodEvent event;
event.setCommitString(QString(), -leftLength, leftLength+rightLength);
- sendInputMethodEventThreadSafe(&event);
+ sendInputMethodEvent(&event);
clear();
return JNI_TRUE;
@@ -866,7 +994,7 @@ jboolean QAndroidInputContext::finishComposingText()
if (m_composingText.isEmpty())
return JNI_TRUE; // not composing
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return JNI_FALSE;
@@ -879,7 +1007,7 @@ jboolean QAndroidInputContext::finishComposingText()
QInputMethodEvent event(QString(), attributes);
event.setCommitString(m_composingText);
- sendInputMethodEventThreadSafe(&event);
+ sendInputMethodEvent(&event);
clear();
return JNI_TRUE;
@@ -888,7 +1016,7 @@ jboolean QAndroidInputContext::finishComposingText()
jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
{
jint res = 0;
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return res;
@@ -922,7 +1050,7 @@ const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedTex
// updateExtractedText(View, int, ExtractedText) whenever you call
// updateSelection(View, int, int, int, int)." QTBUG-37980
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return m_extractedText;
@@ -967,7 +1095,7 @@ const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedTex
QString QAndroidInputContext::getSelectedText(jint /*flags*/)
{
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return QString();
@@ -977,13 +1105,13 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/)
QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
{
//### the preedit text could theoretically be after the cursor
- QVariant textAfter = queryFocusObjectThreadSafe(Qt::ImTextAfterCursor, QVariant(length));
+ QVariant textAfter = QInputMethod::queryFocusObject(Qt::ImTextAfterCursor, QVariant(length));
if (textAfter.isValid()) {
return textAfter.toString().left(length);
}
//compatibility code for old controls that do not implement the new API
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return QString();
@@ -997,12 +1125,12 @@ QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
{
- QVariant textBefore = queryFocusObjectThreadSafe(Qt::ImTextBeforeCursor, QVariant(length));
+ QVariant textBefore = QInputMethod::queryFocusObject(Qt::ImTextBeforeCursor, QVariant(length));
if (textBefore.isValid())
return textBefore.toString().rightRef(length) + m_composingText;
//compatibility code for old controls that do not implement the new API
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return QString();
@@ -1028,7 +1156,7 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition)
{
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return JNI_FALSE;
@@ -1050,7 +1178,7 @@ jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCur
QVariant(underlined)));
QInputMethodEvent event(m_composingText, attributes);
- sendInputMethodEventThreadSafe(&event);
+ sendInputMethodEvent(&event);
QMetaObject::invokeMethod(this, "keyDown");
@@ -1074,7 +1202,7 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
if (wasComposing)
finishComposingText();
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return JNI_FALSE;
@@ -1095,8 +1223,7 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
int localStart = start - blockPosition; // Qt uses position inside block
int currentCursor = wasComposing ? m_composingCursor : blockPosition + localPos;
- bool updateSelectionWasBlocked = m_blockUpdateSelection;
- m_blockUpdateSelection = true;
+ ScopedValueChangeBack<bool> svcb(m_blockUpdateSelection, true);
QString text = query->value(Qt::ImSurroundingText).toString();
@@ -1120,12 +1247,10 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
QInputMethodEvent event(m_composingText, attributes);
event.setCommitString(QString(), relativeStart, length);
- sendInputMethodEventThreadSafe(&event);
-
- m_blockUpdateSelection = updateSelectionWasBlocked;
+ sendInputMethodEvent(&event);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- QSharedPointer<QInputMethodQueryEvent> query2 = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query2 = focusObjectInputMethodQuery();
if (!query2.isNull()) {
qDebug() << "Setting. Prev local cpos:" << localPos << "block pos:" <<blockPosition << "comp.start:" << m_composingTextStart << "rel.start:" << relativeStart << "len:" << length << "cpos attr:" << localPos - localStart;
qDebug() << "New cursor pos" << getAbsoluteCursorPosition(query2);
@@ -1137,7 +1262,7 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
jboolean QAndroidInputContext::setSelection(jint start, jint end)
{
- QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe();
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return JNI_FALSE;
@@ -1168,26 +1293,31 @@ jboolean QAndroidInputContext::setSelection(jint start, jint end)
end - start));
}
QInputMethodEvent event(m_composingText, attributes);
- sendInputMethodEventThreadSafe(&event);
+ sendInputMethodEvent(&event);
updateCursorPosition();
return JNI_TRUE;
}
jboolean QAndroidInputContext::selectAll()
{
+ finishComposingText();
+ m_handleMode = ShowCursor;
sendShortcut(QKeySequence::SelectAll);
return JNI_TRUE;
}
jboolean QAndroidInputContext::cut()
{
- m_cursorHandleShown = CursorHandleNotShown;
+ finishComposingText();
+ m_handleMode = ShowCursor;
sendShortcut(QKeySequence::Cut);
return JNI_TRUE;
}
jboolean QAndroidInputContext::copy()
{
+ finishComposingText();
+ m_handleMode = ShowCursor;
sendShortcut(QKeySequence::Copy);
return JNI_TRUE;
}
@@ -1201,7 +1331,7 @@ jboolean QAndroidInputContext::copyURL()
jboolean QAndroidInputContext::paste()
{
finishComposingText();
- m_cursorHandleShown = CursorHandleNotShown;
+ m_handleMode = ShowCursor;
sendShortcut(QKeySequence::Paste);
return JNI_TRUE;
}
@@ -1217,65 +1347,24 @@ void QAndroidInputContext::sendShortcut(const QKeySequence &sequence)
}
}
-Q_INVOKABLE QVariant QAndroidInputContext::queryFocusObjectUnsafe(Qt::InputMethodQuery query, QVariant argument)
-{
- return QInputMethod::queryFocusObject(query, argument);
-}
-
-QVariant QAndroidInputContext::queryFocusObjectThreadSafe(Qt::InputMethodQuery query, QVariant argument)
-{
- QVariant retval;
+QSharedPointer<QInputMethodQueryEvent> QAndroidInputContext::focusObjectInputMethodQuery(Qt::InputMethodQueries queries) {
if (!qGuiApp)
- return retval;
- const bool inMainThread = qGuiApp->thread() == QThread::currentThread();
- if (QAndroidEventDispatcherStopper::stopped() && !inMainThread)
- return retval;
- AndroidDeadlockProtector protector;
- if (!inMainThread && !protector.acquire())
- return retval;
-
- QMetaObject::invokeMethod(this, "queryFocusObjectUnsafe",
- inMainThread ? Qt::DirectConnection : Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(QVariant, retval),
- Q_ARG(Qt::InputMethodQuery, query),
- Q_ARG(QVariant, argument));
+ return {};
- return retval;
-}
-
-QSharedPointer<QInputMethodQueryEvent> QAndroidInputContext::focusObjectInputMethodQueryThreadSafe(Qt::InputMethodQueries queries) {
- QSharedPointer<QInputMethodQueryEvent> retval;
- if (!qGuiApp)
- return QSharedPointer<QInputMethodQueryEvent>();
- const bool inMainThread = qGuiApp->thread() == QThread::currentThread();
- if (QAndroidEventDispatcherStopper::stopped() && !inMainThread)
- return QSharedPointer<QInputMethodQueryEvent>();
- AndroidDeadlockProtector protector;
- if (!inMainThread && !protector.acquire())
- return QSharedPointer<QInputMethodQueryEvent>();
-
- QInputMethodQueryEvent *queryEvent = 0;
- QMetaObject::invokeMethod(this, "focusObjectInputMethodQueryUnsafe",
- inMainThread ? Qt::DirectConnection : Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(QInputMethodQueryEvent*, queryEvent),
- Q_ARG(Qt::InputMethodQueries, queries));
-
- return QSharedPointer<QInputMethodQueryEvent>(queryEvent);
-}
-
-QInputMethodQueryEvent *QAndroidInputContext::focusObjectInputMethodQueryUnsafe(Qt::InputMethodQueries queries)
-{
QObject *focusObject = qGuiApp->focusObject();
if (!focusObject)
- return 0;
+ return {};
QInputMethodQueryEvent *ret = new QInputMethodQueryEvent(queries);
QCoreApplication::sendEvent(focusObject, ret);
- return ret;
+ return QSharedPointer<QInputMethodQueryEvent>(ret);
}
-void QAndroidInputContext::sendInputMethodEventUnsafe(QInputMethodEvent *event)
+void QAndroidInputContext::sendInputMethodEvent(QInputMethodEvent *event)
{
+ if (!qGuiApp)
+ return;
+
QObject *focusObject = qGuiApp->focusObject();
if (!focusObject)
return;
@@ -1283,19 +1372,4 @@ void QAndroidInputContext::sendInputMethodEventUnsafe(QInputMethodEvent *event)
QCoreApplication::sendEvent(focusObject, event);
}
-void QAndroidInputContext::sendInputMethodEventThreadSafe(QInputMethodEvent *event)
-{
- if (!qGuiApp)
- return;
- const bool inMainThread = qGuiApp->thread() == QThread::currentThread();
- if (QAndroidEventDispatcherStopper::stopped() && !inMainThread)
- return;
- AndroidDeadlockProtector protector;
- if (!inMainThread && !protector.acquire())
- return;
- QMetaObject::invokeMethod(this, "sendInputMethodEventUnsafe",
- inMainThread ? Qt::DirectConnection : Qt::BlockingQueuedConnection,
- Q_ARG(QInputMethodEvent*, event));
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index e7692bf720..bd3edb30f0 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
@@ -42,8 +42,10 @@
#define ANDROIDINPUTCONTEXT_H
#include <qpa/qplatforminputcontext.h>
+#include <functional>
#include <jni.h>
#include <qevent.h>
+#include <QTimer>
QT_BEGIN_NAMESPACE
@@ -58,6 +60,22 @@ class QAndroidInputContext: public QPlatformInputContext
};
public:
+ enum EditContext : uint32_t {
+ CutButton = 1 << 0,
+ CopyButton = 1 << 1,
+ PasteButton = 1 << 2,
+ SelectAllButton = 1 << 3,
+ AllButtons = CutButton | CopyButton | PasteButton | SelectAllButton
+ };
+
+ enum HandleMode {
+ Hidden = 0,
+ ShowCursor = 1,
+ ShowSelection = 2,
+ ShowEditPopup = 0x100
+ };
+ Q_DECLARE_FLAGS(HandleModes, HandleMode)
+
struct ExtractedText
{
ExtractedText() { clear(); }
@@ -118,25 +136,21 @@ public:
jboolean paste();
public slots:
+ void safeCall(const std::function<void()> &func, Qt::ConnectionType conType = Qt::BlockingQueuedConnection);
void updateCursorPosition();
void updateSelectionHandles();
void handleLocationChanged(int handleId, int x, int y);
void touchDown(int x, int y);
void longPress(int x, int y);
void keyDown();
+ void hideSelectionHandles();
private slots:
void showInputPanelLater(Qt::ApplicationState);
private:
- void sendInputMethodEventThreadSafe(QInputMethodEvent *event);
- Q_INVOKABLE void sendInputMethodEventUnsafe(QInputMethodEvent *event);
-
- QSharedPointer<QInputMethodQueryEvent> focusObjectInputMethodQueryThreadSafe(Qt::InputMethodQueries queries = Qt::ImQueryAll);
- Q_INVOKABLE QInputMethodQueryEvent *focusObjectInputMethodQueryUnsafe(Qt::InputMethodQueries queries);
-
- Q_INVOKABLE QVariant queryFocusObjectUnsafe(Qt::InputMethodQuery query, QVariant argument);
- QVariant queryFocusObjectThreadSafe(Qt::InputMethodQuery query, QVariant argument);
+ void sendInputMethodEvent(QInputMethodEvent *event);
+ QSharedPointer<QInputMethodQueryEvent> focusObjectInputMethodQuery(Qt::InputMethodQueries queries = Qt::ImQueryAll);
private:
ExtractedText m_extractedText;
@@ -145,17 +159,12 @@ private:
int m_composingCursor;
QMetaObject::Connection m_updateCursorPosConnection;
bool m_blockUpdateSelection;
- enum CursorHandleShowMode {
- CursorHandleNotShown,
- CursorHandleShowNormal = 1,
- CursorHandleShowSelection = 2,
- CursorHandleShowPopup = 3
- };
- CursorHandleShowMode m_cursorHandleShown;
+ HandleModes m_handleMode;
QAtomicInt m_batchEditNestingLevel;
QObject *m_focusObject;
+ QTimer m_hideCursorHandleTimer;
};
-
+Q_DECLARE_OPERATORS_FOR_FLAGS(QAndroidInputContext::HandleModes)
QT_END_NAMESPACE
#endif // ANDROIDINPUTCONTEXT_H
diff --git a/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
index ced35c4cfa..9218afa7f5 100644
--- a/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
+++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
** Contact: https://www.qt.io/licensing/
**
@@ -117,6 +118,15 @@ bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
void QAndroidPlatformMessageDialogHelper::addButtons(QSharedPointer<QMessageDialogOptions> opt, ButtonRole role)
{
+ for (const QMessageDialogOptions::CustomButton &b : opt->customButtons()) {
+ if (b.role == role) {
+ QString label = b.label;
+ label.remove(QChar('&'));
+ m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", b.id,
+ QJNIObjectPrivate::fromString(label).object());
+ }
+ }
+
for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) {
StandardButton b = static_cast<StandardButton>(i);
if (buttonRole(b) == role && (opt->standardButtons() & i)) {
@@ -144,6 +154,12 @@ void QAndroidPlatformMessageDialogHelper::dialogResult(int buttonID)
QPlatformDialogHelper::StandardButton standardButton = static_cast<QPlatformDialogHelper::StandardButton>(buttonID);
QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(standardButton);
+ if (buttonID > QPlatformDialogHelper::LastButton) {
+ const QMessageDialogOptions::CustomButton *custom = options()->customButton(buttonID);
+ Q_ASSERT(custom);
+ role = custom->role;
+ }
+
emit clicked(standardButton, role);
}
diff --git a/src/plugins/platforms/android/qandroidplatformmenubar.h b/src/plugins/platforms/android/qandroidplatformmenubar.h
index 0316ea9362..f5935b8177 100644
--- a/src/plugins/platforms/android/qandroidplatformmenubar.h
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.h
@@ -61,7 +61,7 @@ public:
void handleReparent(QWindow *newParentWindow) override;
QPlatformMenu *menuForTag(quintptr tag) const override;
- QWindow *parentWindow() const;
+ QWindow *parentWindow() const override;
PlatformMenusType menus() const;
QMutex *menusListMutex();
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 2694cb3607..8d65cf328f 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -8,7 +8,6 @@ SOURCES += main.mm \
qcocoawindow.mm \
qnsview.mm \
qnswindow.mm \
- qnsviewaccessibility.mm \
qnswindowdelegate.mm \
qcocoanativeinterface.mm \
qcocoaeventdispatcher.mm \
@@ -72,19 +71,25 @@ HEADERS += qcocoaintegration.h \
qtConfig(opengl.*) {
SOURCES += qcocoaglcontext.mm
-
HEADERS += qcocoaglcontext.h
}
+qtConfig(vulkan) {
+ SOURCES += qcocoavulkaninstance.mm
+ HEADERS += qcocoavulkaninstance.h
+}
+
RESOURCES += qcocoaresources.qrc
-LIBS += -framework AppKit -framework Carbon -framework IOKit -framework QuartzCore -lcups
+LIBS += -framework AppKit -framework CoreServices -framework Carbon -framework IOKit -framework QuartzCore -framework CoreVideo -framework Metal -lcups
QT += \
core-private gui-private \
accessibility_support-private clipboard_support-private theme_support-private \
fontdatabase_support-private graphics_support-private
+qtConfig(vulkan): QT += vulkan_support-private
+
CONFIG += no_app_extension_api_only
qtHaveModule(widgets) {
@@ -122,11 +127,6 @@ qtHaveModule(widgets) {
OTHER_FILES += cocoa.json
-# Acccessibility debug support
-# DEFINES += QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
-# include ($$PWD/../../../../util/accessibilityinspector/accessibilityinspector.pri)
-
-
PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = QCocoaIntegrationPlugin
!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm
index f9bfdc7dc7..89ecdf46f9 100644
--- a/src/plugins/platforms/cocoa/main.mm
+++ b/src/plugins/platforms/cocoa/main.mm
@@ -60,7 +60,7 @@ QPlatformIntegration * QCocoaIntegrationPlugin::create(const QString& system, co
if (system.compare(QLatin1String("cocoa"), Qt::CaseInsensitive) == 0)
return new QCocoaIntegration(paramList);
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp
index 8eea1e654e..06e3dd454e 100644
--- a/src/plugins/platforms/cocoa/messages.cpp
+++ b/src/plugins/platforms/cocoa/messages.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,7 +39,8 @@
#include "messages.h"
-#include <QCoreApplication>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qregularexpression.h>
// Translatable messages should go into this .cpp file for them to be picked up by lupdate.
@@ -52,13 +53,13 @@ QString msgAboutQt()
static const char *application_menu_strings[] =
{
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1")
};
QString qt_mac_applicationmenu_string(int type)
@@ -77,8 +78,13 @@ QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption)
QString captionNoAmpersand(caption);
captionNoAmpersand.remove(QLatin1Char('&'));
const QString aboutString = QCoreApplication::translate("QCocoaMenuItem", "About");
- if (captionNoAmpersand.startsWith(aboutString, Qt::CaseInsensitive) || caption.endsWith(aboutString, Qt::CaseInsensitive))
+ if (captionNoAmpersand.startsWith(aboutString, Qt::CaseInsensitive)
+ || captionNoAmpersand.endsWith(aboutString, Qt::CaseInsensitive)) {
+ static const QRegularExpression qtRegExp(QLatin1String("qt$"), QRegularExpression::CaseInsensitiveOption);
+ if (captionNoAmpersand.contains(qtRegExp))
+ return QPlatformMenuItem::AboutQtRole;
return QPlatformMenuItem::AboutRole;
+ }
if (captionNoAmpersand.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Config"), Qt::CaseInsensitive)
|| captionNoAmpersand.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Preference"), Qt::CaseInsensitive)
|| captionNoAmpersand.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Options"), Qt::CaseInsensitive)
diff --git a/src/plugins/platforms/cocoa/messages.h b/src/plugins/platforms/cocoa/messages.h
index e41898fe59..3a9eaf604e 100644
--- a/src/plugins/platforms/cocoa/messages.h
+++ b/src/plugins/platforms/cocoa/messages.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -46,13 +46,13 @@
QT_BEGIN_NAMESPACE
enum {
- ServicesAppMenuItem = 0,
+ AboutAppMenuItem = 0,
+ PreferencesAppMenuItem,
+ ServicesAppMenuItem,
HideAppMenuItem,
HideOthersAppMenuItem,
ShowAllAppMenuItem,
- PreferencesAppMenuItem,
- QuitAppMenuItem,
- AboutAppMenuItem
+ QuitAppMenuItem
};
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
index e456364555..457c158ddc 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
@@ -46,6 +46,8 @@
#ifndef QT_NO_ACCESSIBILITY
+@class QT_MANGLE_NAMESPACE(QMacAccessibilityElement);
+
QT_BEGIN_NAMESPACE
class QCocoaAccessibility : public QPlatformAccessibility
@@ -82,9 +84,8 @@ namespace QCocoaAccessible {
NSString *macRole(QAccessibleInterface *interface);
NSString *macSubrole(QAccessibleInterface *interface);
bool shouldBeIgnored(QAccessibleInterface *interface);
-NSArray *unignoredChildren(QAccessibleInterface *interface);
+NSArray<QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *> *unignoredChildren(QAccessibleInterface *interface);
NSString *getTranslatedAction(const QString &qtAction);
-NSMutableArray *createTranslatedActionsList(const QStringList &qtActions);
QString translateAction(NSString *nsAction, QAccessibleInterface *interface);
bool hasValueAttribute(QAccessibleInterface *interface);
id getValueAttribute(QAccessibleInterface *interface);
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 654e6210c8..368cf56c80 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -256,12 +256,12 @@ bool shouldBeIgnored(QAccessibleInterface *interface)
return false;
}
-NSArray *unignoredChildren(QAccessibleInterface *interface)
+NSArray<QMacAccessibilityElement *> *unignoredChildren(QAccessibleInterface *interface)
{
int numKids = interface->childCount();
// qDebug() << "Children for: " << axid << iface << " are: " << numKids;
- NSMutableArray *kids = [NSMutableArray arrayWithCapacity:numKids];
+ NSMutableArray<QMacAccessibilityElement *> *kids = [NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:numKids];
for (int i = 0; i < numKids; ++i) {
QAccessibleInterface *child = interface->child(i);
if (!child || !child->isValid() || child->state().invalid || child->state().invisible)
@@ -310,7 +310,7 @@ NSString *getTranslatedAction(const QString &qtAction)
// NSAccessibilityCancelAction;
// NSAccessibilityDeleteAction;
- return 0;
+ return nil;
}
@@ -386,7 +386,7 @@ id getValueAttribute(QAccessibleInterface *interface)
}
if (interface->state().checkable) {
- return [NSNumber numberWithInt: (interface->state().checked ? 1 : 0)];
+ return interface->state().checked ? @(1) : @(0);
}
return nil;
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
index 07f3f3a99e..914aaa2b1b 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
@@ -52,13 +52,10 @@
@class QT_MANGLE_NAMESPACE(QMacAccessibilityElement);
-@interface QT_MANGLE_NAMESPACE(QMacAccessibilityElement) : NSObject {
- NSString *role;
- QAccessible::Id axid;
-}
+@interface QT_MANGLE_NAMESPACE(QMacAccessibilityElement) : NSObject
-- (id)initWithId:(QAccessible::Id)anId;
-+ (QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *)elementWithId:(QAccessible::Id)anId;
+- (instancetype)initWithId:(QAccessible::Id)anId;
++ (instancetype)elementWithId:(QAccessible::Id)anId;
@end
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index df2336d08b..03dc895ffb 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -99,9 +99,12 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
*end = curEnd;
}
-@implementation QMacAccessibilityElement
+@implementation QMacAccessibilityElement {
+ NSString *role;
+ QAccessible::Id axid;
+}
-- (id)initWithId:(QAccessible::Id)anId
+- (instancetype)initWithId:(QAccessible::Id)anId
{
Q_ASSERT((int)anId < 0);
self = [super init];
@@ -115,7 +118,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
return self;
}
-+ (id)elementWithId:(QAccessible::Id)anId
++ (instancetype)elementWithId:(QAccessible::Id)anId
{
Q_ASSERT(anId);
if (!anId)
@@ -168,22 +171,15 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
{
QStringRef textBefore = QStringRef(&text, 0, index);
int newlines = textBefore.count(QLatin1Char('\n'));
- return [NSNumber numberWithInt: newlines];
+ return @(newlines);
}
- (BOOL) accessibilityNotifiesWhenDestroyed {
return YES;
}
-- (NSArray *)accessibilityAttributeNames {
- static NSArray *defaultAttributes = nil;
-
- QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
- if (!iface || !iface->isValid())
- return defaultAttributes;
-
- if (defaultAttributes == nil) {
- defaultAttributes = [[NSArray alloc] initWithObjects:
+- (NSArray<NSString *> *)accessibilityAttributeNames {
+ static NSArray<NSString *> *defaultAttributes = [@[
NSAccessibilityRoleAttribute,
NSAccessibilityRoleDescriptionAttribute,
NSAccessibilitySubroleAttribute,
@@ -196,35 +192,36 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
NSAccessibilitySizeAttribute,
NSAccessibilityTitleAttribute,
NSAccessibilityDescriptionAttribute,
- NSAccessibilityEnabledAttribute,
- nil];
- }
+ NSAccessibilityEnabledAttribute
+ ] retain];
+
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface || !iface->isValid())
+ return defaultAttributes;
- NSMutableArray *attributes = [[NSMutableArray alloc] initWithCapacity : [defaultAttributes count]];
- [attributes addObjectsFromArray : defaultAttributes];
+ NSMutableArray<NSString *> *attributes = [[NSMutableArray<NSString *> alloc] initWithCapacity:defaultAttributes.count];
+ [attributes addObjectsFromArray:defaultAttributes];
if (QCocoaAccessible::hasValueAttribute(iface)) {
- [attributes addObject : NSAccessibilityValueAttribute];
+ [attributes addObject:NSAccessibilityValueAttribute];
}
if (iface->textInterface()) {
- [attributes addObjectsFromArray: [[NSArray alloc] initWithObjects:
+ [attributes addObjectsFromArray:@[
NSAccessibilityNumberOfCharactersAttribute,
NSAccessibilitySelectedTextAttribute,
NSAccessibilitySelectedTextRangeAttribute,
NSAccessibilityVisibleCharacterRangeAttribute,
- NSAccessibilityInsertionPointLineNumberAttribute,
- nil
+ NSAccessibilityInsertionPointLineNumberAttribute
]];
// TODO: multi-selection: NSAccessibilitySelectedTextRangesAttribute,
}
if (iface->valueInterface()) {
- [attributes addObjectsFromArray: [[NSArray alloc] initWithObjects:
+ [attributes addObjectsFromArray:@[
NSAccessibilityMinValueAttribute,
- NSAccessibilityMaxValueAttribute,
- nil
+ NSAccessibilityMaxValueAttribute
]];
}
@@ -261,13 +258,13 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (id) minValueAttribute:(QAccessibleInterface*)iface {
if (QAccessibleValueInterface *val = iface->valueInterface())
- return [NSNumber numberWithDouble: val->minimumValue().toDouble()];
+ return @(val->minimumValue().toDouble());
return nil;
}
- (id) maxValueAttribute:(QAccessibleInterface*)iface {
if (QAccessibleValueInterface *val = iface->valueInterface())
- return [NSNumber numberWithDouble: val->maximumValue().toDouble()];
+ return @(val->maximumValue().toDouble());
return nil;
}
@@ -289,7 +286,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
} else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
// Just check if the app thinks we're focused.
id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute];
- return [NSNumber numberWithBool:[focusedElement isEqual:self]];
+ return @([focusedElement isEqual:self]);
} else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) {
return NSAccessibilityUnignoredAncestor([self parentElement]);
} else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) {
@@ -312,7 +309,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
} else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
return iface->text(QAccessible::Description).toNSString();
} else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) {
- return [NSNumber numberWithBool:!iface->state().disabled];
+ return @(!iface->state().disabled);
} else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
// VoiceOver asks for the value attribute for all elements. Return nil
// if we don't want the element to have a value attribute.
@@ -323,7 +320,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
} else if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute]) {
if (QAccessibleTextInterface *text = iface->textInterface())
- return [NSNumber numberWithInt: text->characterCount()];
+ return @(text->characterCount());
return nil;
} else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
if (QAccessibleTextInterface *text = iface->textInterface()) {
@@ -357,7 +354,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
int position = text->cursorPosition();
convertLineOffset(text, &line, &position);
}
- return [NSNumber numberWithInt: line];
+ return @(line);
}
return nil;
} else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) {
@@ -378,18 +375,17 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
}
if (iface->textInterface()) {
- return [[NSArray alloc] initWithObjects:
- NSAccessibilityStringForRangeParameterizedAttribute,
- NSAccessibilityLineForIndexParameterizedAttribute,
- NSAccessibilityRangeForLineParameterizedAttribute,
- NSAccessibilityRangeForPositionParameterizedAttribute,
-// NSAccessibilityRangeForIndexParameterizedAttribute,
- NSAccessibilityBoundsForRangeParameterizedAttribute,
-// NSAccessibilityRTFForRangeParameterizedAttribute,
- NSAccessibilityStyleRangeForIndexParameterizedAttribute,
- NSAccessibilityAttributedStringForRangeParameterizedAttribute,
- nil
- ];
+ return @[
+ NSAccessibilityStringForRangeParameterizedAttribute,
+ NSAccessibilityLineForIndexParameterizedAttribute,
+ NSAccessibilityRangeForLineParameterizedAttribute,
+ NSAccessibilityRangeForPositionParameterizedAttribute,
+// NSAccessibilityRangeForIndexParameterizedAttribute,
+ NSAccessibilityBoundsForRangeParameterizedAttribute,
+// NSAccessibilityRTFForRangeParameterizedAttribute,
+ NSAccessibilityStyleRangeForIndexParameterizedAttribute,
+ NSAccessibilityAttributedStringForRangeParameterizedAttribute
+ ];
}
return nil;
@@ -416,7 +412,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
return nil;
int line = -1;
convertLineOffset(iface->textInterface(), &line, &index);
- return [NSNumber numberWithInt:line];
+ return @(line);
}
if ([attribute isEqualToString: NSAccessibilityRangeForLineParameterizedAttribute]) {
int line = [parameter intValue];
@@ -573,7 +569,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
return NSAccessibilityUnignoredAncestor(self);
// find the deepest child at the point
- QAccessibleInterface *childOfChildInterface = 0;
+ QAccessibleInterface *childOfChildInterface = nullptr;
do {
childOfChildInterface = childInterface->childAt(screenPoint.x(), screenPoint.y());
if (childOfChildInterface && childOfChildInterface->isValid())
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h
index 66a92686bc..15530d8281 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.h
@@ -89,8 +89,7 @@
#import <AppKit/AppKit.h>
-@interface QT_MANGLE_NAMESPACE(QNSApplication) : NSApplication {
-}
+@interface QT_MANGLE_NAMESPACE(QNSApplication) : NSApplication
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSApplication);
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
index d0f27795b6..340191622a 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -113,11 +113,11 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE
static bool qt_filterEvent(NSEvent *event)
{
if (qApp && qApp->eventDispatcher()->
- filterNativeEvent(q_macLocalEventType, static_cast<void*>(event), 0))
+ filterNativeEvent(q_macLocalEventType, static_cast<void*>(event), nullptr))
return true;
- if ([event type] == NSApplicationDefined) {
- switch (static_cast<short>([event subtype])) {
+ if (event.type == NSEventTypeApplicationDefined) {
+ switch (static_cast<short>(event.subtype)) {
case QtCocoaEventSubTypePostMessage:
qt_sendPostedMessage(event);
return true;
@@ -137,7 +137,7 @@ static void qt_maybeSendKeyEquivalentUpEvent(NSEvent *event)
// and forward the key event to the key (focus) window.
// However, non-Qt windows will not (and should not) get
// any special treatment, only QWindow-owned NSWindows.
- if (event.type == NSKeyUp && (event.modifierFlags & NSCommandKeyMask)) {
+ if (event.type == NSEventTypeKeyUp && (event.modifierFlags & NSEventModifierFlagCommand)) {
NSWindow *targetWindow = event.window;
if ([targetWindow.class conformsToProtocol:@protocol(QNSWindowProtocol)])
[targetWindow sendEvent:event];
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
index 59c71017e3..0816730c54 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -90,20 +90,18 @@
#include <qglobal.h>
#include <private/qcore_mac_p.h>
-@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
+Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaNSMenuItem));
-@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate> {
- bool startedQuit;
- NSMenu *dockMenu;
- NSObject <NSApplicationDelegate> *reflectionDelegate;
- bool inLaunch;
-}
-+ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate;
-- (void)setDockMenu:(NSMenu *)newMenu;
-- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate;
-- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
-- (void) removeAppleEventHandlers;
-- (bool) inLaunch;
+@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate>
+@property (nonatomic, retain) NSMenu *dockMenu;
++ (instancetype)sharedDelegate;
+- (void)setReflectionDelegate:(NSObject<NSApplicationDelegate> *)oldDelegate;
+- (void)removeAppleEventHandlers;
+- (bool)inLaunch;
+@end
+
+@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) (MenuAPI)
+- (void)qt_itemFired:(QT_MANGLE_NAMESPACE(QCocoaNSMenuItem) *)item;
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaApplicationDelegate);
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index a94e0dc517..221a8b0866 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -73,9 +73,12 @@
#import "qcocoaapplicationdelegate.h"
-#import "qnswindowdelegate.h"
-#import "qcocoamenuloader.h"
#include "qcocoaintegration.h"
+#include "qcocoamenu.h"
+#include "qcocoamenuloader.h"
+#include "qcocoamenuitem.h"
+#include "qcocoansmenu.h"
+
#include <qevent.h>
#include <qurl.h>
#include <qdebug.h>
@@ -86,7 +89,11 @@
QT_USE_NAMESPACE
-@implementation QCocoaApplicationDelegate
+@implementation QCocoaApplicationDelegate {
+ bool startedQuit;
+ NSObject <NSApplicationDelegate> *reflectionDelegate;
+ bool inLaunch;
+}
+ (instancetype)sharedDelegate
{
@@ -102,7 +109,7 @@ QT_USE_NAMESPACE
return shared;
}
-- (id)init
+- (instancetype)init
{
self = [super init];
if (self) {
@@ -125,7 +132,7 @@ QT_USE_NAMESPACE
- (void)dealloc
{
- [dockMenu release];
+ [_dockMenu release];
if (reflectionDelegate) {
[[NSApplication sharedApplication] setDelegate:reflectionDelegate];
[reflectionDelegate release];
@@ -135,23 +142,16 @@ QT_USE_NAMESPACE
[super dealloc];
}
-- (void)setDockMenu:(NSMenu*)newMenu
-{
- [newMenu retain];
- [dockMenu release];
- dockMenu = newMenu;
-}
-
- (NSMenu *)applicationDockMenu:(NSApplication *)sender
{
Q_UNUSED(sender);
// Manually invoke the delegate's -menuWillOpen: method.
// See QTBUG-39604 (and its fix) for details.
- [[dockMenu delegate] menuWillOpen:dockMenu];
- return [[dockMenu retain] autorelease];
+ [self.dockMenu.delegate menuWillOpen:self.dockMenu];
+ return [[self.dockMenu retain] autorelease];
}
-- (BOOL) canQuit
+- (BOOL)canQuit
{
[[NSApp mainMenu] cancelTracking];
@@ -219,7 +219,7 @@ QT_USE_NAMESPACE
return NSTerminateCancel;
}
-- (void) applicationWillFinishLaunching:(NSNotification *)notification
+- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
Q_UNUSED(notification);
@@ -249,14 +249,14 @@ QT_USE_NAMESPACE
}
// called by QCocoaIntegration's destructor before resetting the application delegate to nil
-- (void) removeAppleEventHandlers
+- (void)removeAppleEventHandlers
{
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
[eventManager removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEQuitApplication];
[eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL];
}
-- (bool) inLaunch
+- (bool)inLaunch
{
return inLaunch;
}
@@ -267,13 +267,11 @@ QT_USE_NAMESPACE
inLaunch = false;
if (qEnvironmentVariableIsEmpty("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM")) {
- if (__builtin_available(macOS 10.12, *)) {
- // Move the application window to front to avoid launching behind the terminal.
- // Ignoring other apps is necessary (we must ignore the terminal), but makes
- // Qt apps play slightly less nice with other apps when lanching from Finder
- // (See the activateIgnoringOtherApps docs.)
- [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
- }
+ // Move the application window to front to avoid launching behind the terminal.
+ // Ignoring other apps is necessary (we must ignore the terminal), but makes
+ // Qt apps play slightly less nice with other apps when lanching from Finder
+ // (See the activateIgnoringOtherApps docs.)
+ [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
}
}
@@ -440,3 +438,48 @@ QT_USE_NAMESPACE
}
@end
+
+@implementation QCocoaApplicationDelegate (Menus)
+
+- (BOOL)validateMenuItem:(NSMenuItem*)item
+{
+ auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(item);
+ if (!nativeItem)
+ return item.enabled; // FIXME Test with with Qt as plugin or embedded QWindow.
+
+ auto *platformItem = nativeItem.platformMenuItem;
+ if (!platformItem) // Try a bit harder with orphan menu itens
+ return item.hasSubmenu || (item.enabled && (item.action != @selector(qt_itemFired:)));
+
+ // Menu-holding items are always enabled, as it's conventional in Cocoa
+ if (platformItem->menu())
+ return YES;
+
+ return platformItem->isEnabled();
+}
+
+@end
+
+@implementation QCocoaApplicationDelegate (MenuAPI)
+
+- (void)qt_itemFired:(QCocoaNSMenuItem *)item
+{
+ if (item.hasSubmenu)
+ return;
+
+ auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(item);
+ Q_ASSERT_X(nativeItem, qPrintable(__FUNCTION__), "Triggered menu item is not a QCocoaNSMenuItem.");
+ auto *platformItem = nativeItem.platformMenuItem;
+ // Menu-holding items also get a target to play nicely
+ // with NSMenuValidation but should not trigger.
+ if (!platformItem || platformItem->menu())
+ return;
+
+ QScopedScopeLevelCounter scopeLevelCounter(QGuiApplicationPrivate::instance()->threadData);
+ QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers:[NSEvent modifierFlags]];
+
+ static QMetaMethod activatedSignal = QMetaMethod::fromSignal(&QCocoaMenuItem::activated);
+ activatedSignal.invoke(platformItem, Qt::QueuedConnection);
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 1343fbc45a..81a0a7d040 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -44,8 +44,6 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcCocoaBackingStore, "qt.qpa.cocoa.backingstore");
-
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
: QRasterBackingStore(window)
{
@@ -69,11 +67,6 @@ QImage::Format QCocoaBackingStore::format() const
return QRasterBackingStore::format();
}
-#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12)
-static const NSCompositingOperation NSCompositingOperationCopy = NSCompositeCopy;
-static const NSCompositingOperation NSCompositingOperationSourceOver = NSCompositeSourceOver;
-#endif
-
/*!
Flushes the given \a region from the specified \a window onto the
screen.
@@ -101,13 +94,13 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion &region, const QPo
QNSView *topLevelView = qnsview_cast(static_cast<QCocoaWindow *>(topLevelWindow->handle())->view());
QNSView *view = qnsview_cast(static_cast<QCocoaWindow *>(window->handle())->view());
- if (lcCocoaBackingStore().isDebugEnabled()) {
+ if (lcQpaBackingStore().isDebugEnabled()) {
QString targetViewDescription;
if (view != topLevelView) {
QDebug targetDebug(&targetViewDescription);
targetDebug << "onto" << topLevelView << "at" << offset;
}
- qCDebug(lcCocoaBackingStore) << "Flushing" << region << "of" << view << qPrintable(targetViewDescription);
+ qCDebug(lcQpaBackingStore) << "Flushing" << region << "of" << view << qPrintable(targetViewDescription);
}
// Prevent potentially costly color conversion by assigning the display color space
@@ -127,118 +120,120 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion &region, const QPo
// FIXME: Figure out if there's a way to do partial updates
view.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage);
if (view != topLevelView) {
+ const CGSize topLevelSize = topLevelView.bounds.size;
view.layer.contentsRect = CGRectApplyAffineTransform(
[view convertRect:view.bounds toView:topLevelView],
// The contentsRect is in unit coordinate system
- CGAffineTransformMakeScale(1.0 / m_image.width(), 1.0 / m_image.height()));
+ CGAffineTransformMakeScale(1.0 / topLevelSize.width, 1.0 / topLevelSize.height));
+ }
+ } else {
+ // Normally a NSView is drawn via drawRect, as part of the display cycle in the
+ // main runloop, via setNeedsDisplay and friends. AppKit will lock focus on each
+ // individual view, starting with the top level and then traversing any subviews,
+ // calling drawRect for each of them. This pull model results in expose events
+ // sent to Qt, which result in drawing to the backingstore and flushing it.
+ // Qt may also decide to paint and flush the backingstore via e.g. timers,
+ // or other events such as mouse events, in which case we're in a push model.
+ // If there is no focused view, it means we're in the latter case, and need
+ // to manually flush the NSWindow after drawing to its graphic context.
+ const bool drawingOutsideOfDisplayCycle = ![NSView focusView];
+
+ // We also need to ensure the flushed view has focus, so that the graphics
+ // context is set up correctly (coordinate system, clipping, etc). Outside
+ // of the normal display cycle there is no focused view, as explained above,
+ // so we have to handle it manually. There's also a corner case inside the
+ // normal display cycle due to way QWidgetBackingStore composits native child
+ // widgets, where we'll get a flush of a native child during the drawRect of
+ // its parent/ancestor, and the parent/ancestor being the one locked by AppKit.
+ // In this case we also need to lock and unlock focus manually.
+ const bool shouldHandleViewLockManually = [NSView focusView] != view;
+ if (shouldHandleViewLockManually && ![view lockFocusIfCanDraw]) {
+ qWarning() << "failed to lock focus of" << view;
+ return;
}
- return;
- }
-
- // Normally a NSView is drawn via drawRect, as part of the display cycle in the
- // main runloop, via setNeedsDisplay and friends. AppKit will lock focus on each
- // individual view, starting with the top level and then traversing any subviews,
- // calling drawRect for each of them. This pull model results in expose events
- // sent to Qt, which result in drawing to the backingstore and flushing it.
- // Qt may also decide to paint and flush the backingstore via e.g. timers,
- // or other events such as mouse events, in which case we're in a push model.
- // If there is no focused view, it means we're in the latter case, and need
- // to manually flush the NSWindow after drawing to its graphic context.
- const bool drawingOutsideOfDisplayCycle = ![NSView focusView];
-
- // We also need to ensure the flushed view has focus, so that the graphics
- // context is set up correctly (coordinate system, clipping, etc). Outside
- // of the normal display cycle there is no focused view, as explained above,
- // so we have to handle it manually. There's also a corner case inside the
- // normal display cycle due to way QWidgetBackingStore composits native child
- // widgets, where we'll get a flush of a native child during the drawRect of
- // its parent/ancestor, and the parent/ancestor being the one locked by AppKit.
- // In this case we also need to lock and unlock focus manually.
- const bool shouldHandleViewLockManually = [NSView focusView] != view;
- if (shouldHandleViewLockManually && ![view lockFocusIfCanDraw]) {
- qWarning() << "failed to lock focus of" << view;
- return;
- }
- const qreal devicePixelRatio = m_image.devicePixelRatio();
+ const qreal devicePixelRatio = m_image.devicePixelRatio();
- // If the flushed window is a content view, and we're filling the drawn area
- // completely, or it doesn't have a window background we need to preserve,
- // we can get away with copying instead of blending the backing store.
- QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
- const NSCompositingOperation compositingOperation = cocoaWindow->isContentView()
- && (cocoaWindow->isOpaque() || view.window.backgroundColor == NSColor.clearColor)
- ? NSCompositingOperationCopy : NSCompositingOperationSourceOver;
+ // If the flushed window is a content view, and we're filling the drawn area
+ // completely, or it doesn't have a window background we need to preserve,
+ // we can get away with copying instead of blending the backing store.
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ const NSCompositingOperation compositingOperation = cocoaWindow->isContentView()
+ && (cocoaWindow->isOpaque() || view.window.backgroundColor == NSColor.clearColor)
+ ? NSCompositingOperationCopy : NSCompositingOperationSourceOver;
#ifdef QT_DEBUG
- static bool debugBackingStoreFlush = [[NSUserDefaults standardUserDefaults]
- boolForKey:@"QtCocoaDebugBackingStoreFlush"];
+ static bool debugBackingStoreFlush = [[NSUserDefaults standardUserDefaults]
+ boolForKey:@"QtCocoaDebugBackingStoreFlush"];
#endif
- // -------------------------------------------------------------------------
+ // -------------------------------------------------------------------------
- // The current contexts is typically a NSWindowGraphicsContext, but can be
- // NSBitmapGraphicsContext e.g. when debugging the view hierarchy in Xcode.
- // If we need to distinguish things here in the future, we can use e.g.
- // [NSGraphicsContext drawingToScreen], or the attributes of the context.
- NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
- Q_ASSERT_X(graphicsContext, "QCocoaBackingStore",
- "Focusing the view should give us a current graphics context");
+ // The current contexts is typically a NSWindowGraphicsContext, but can be
+ // NSBitmapGraphicsContext e.g. when debugging the view hierarchy in Xcode.
+ // If we need to distinguish things here in the future, we can use e.g.
+ // [NSGraphicsContext drawingToScreen], or the attributes of the context.
+ NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
+ Q_ASSERT_X(graphicsContext, "QCocoaBackingStore",
+ "Focusing the view should give us a current graphics context");
- // Create temporary image to use for blitting, without copying image data
- NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease];
+ // Create temporary image to use for blitting, without copying image data
+ NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease];
- QRegion clippedRegion = region;
- for (QWindow *w = window; w; w = w->parent()) {
- if (!w->mask().isEmpty()) {
- clippedRegion &= w == window ? w->mask()
- : w->mask().translated(window->mapFromGlobal(w->mapToGlobal(QPoint(0, 0))));
+ QRegion clippedRegion = region;
+ for (QWindow *w = window; w; w = w->parent()) {
+ if (!w->mask().isEmpty()) {
+ clippedRegion &= w == window ? w->mask()
+ : w->mask().translated(window->mapFromGlobal(w->mapToGlobal(QPoint(0, 0))));
+ }
}
- }
- for (const QRect &viewLocalRect : clippedRegion) {
- QPoint backingStoreOffset = viewLocalRect.topLeft() + offset;
- QRect backingStoreRect(backingStoreOffset * devicePixelRatio, viewLocalRect.size() * devicePixelRatio);
- if (graphicsContext.flipped) // Flip backingStoreRect to match graphics context
- backingStoreRect.moveTop(m_image.height() - (backingStoreRect.y() + backingStoreRect.height()));
+ for (const QRect &viewLocalRect : clippedRegion) {
+ QPoint backingStoreOffset = viewLocalRect.topLeft() + offset;
+ QRect backingStoreRect(backingStoreOffset * devicePixelRatio, viewLocalRect.size() * devicePixelRatio);
+ if (graphicsContext.flipped) // Flip backingStoreRect to match graphics context
+ backingStoreRect.moveTop(m_image.height() - (backingStoreRect.y() + backingStoreRect.height()));
- CGRect viewRect = viewLocalRect.toCGRect();
+ CGRect viewRect = viewLocalRect.toCGRect();
- if (windowHasUnifiedToolbar())
- NSDrawWindowBackground(viewRect);
+ if (windowHasUnifiedToolbar())
+ NSDrawWindowBackground(viewRect);
- [backingStoreImage drawInRect:viewRect fromRect:backingStoreRect.toCGRect()
- operation:compositingOperation fraction:1.0 respectFlipped:YES hints:nil];
+ [backingStoreImage drawInRect:viewRect fromRect:backingStoreRect.toCGRect()
+ operation:compositingOperation fraction:1.0 respectFlipped:YES hints:nil];
#ifdef QT_DEBUG
- if (Q_UNLIKELY(debugBackingStoreFlush)) {
- [[NSColor colorWithCalibratedRed:drand48() green:drand48() blue:drand48() alpha:0.3] set];
- [NSBezierPath fillRect:viewRect];
-
- if (drawingOutsideOfDisplayCycle) {
- [[[NSColor magentaColor] colorWithAlphaComponent:0.5] set];
- [NSBezierPath strokeLineFromPoint:viewLocalRect.topLeft().toCGPoint()
- toPoint:viewLocalRect.bottomRight().toCGPoint()];
+ if (Q_UNLIKELY(debugBackingStoreFlush)) {
+ [[NSColor colorWithCalibratedRed:drand48() green:drand48() blue:drand48() alpha:0.3] set];
+ [NSBezierPath fillRect:viewRect];
+
+ if (drawingOutsideOfDisplayCycle) {
+ [[[NSColor magentaColor] colorWithAlphaComponent:0.5] set];
+ [NSBezierPath strokeLineFromPoint:viewLocalRect.topLeft().toCGPoint()
+ toPoint:viewLocalRect.bottomRight().toCGPoint()];
+ }
}
- }
#endif
+ }
+
+ // -------------------------------------------------------------------------
+
+ if (shouldHandleViewLockManually)
+ [view unlockFocus];
+
+ if (drawingOutsideOfDisplayCycle) {
+ redrawRoundedBottomCorners([view convertRect:region.boundingRect().toCGRect() toView:nil]);
+ [view.window flushWindow];
+ }
}
+ // Done flushing to either CALayer or NSWindow backingstore
+
QCocoaWindow *topLevelCocoaWindow = static_cast<QCocoaWindow *>(topLevelWindow->handle());
if (Q_UNLIKELY(topLevelCocoaWindow->m_needsInvalidateShadow)) {
[topLevelView.window invalidateShadow];
topLevelCocoaWindow->m_needsInvalidateShadow = false;
}
-
- // -------------------------------------------------------------------------
-
- if (shouldHandleViewLockManually)
- [view unlockFocus];
-
- if (drawingOutsideOfDisplayCycle) {
- redrawRoundedBottomCorners([view convertRect:region.boundingRect().toCGRect() toView:nil]);
- [view.window flushWindow];
- }
}
/*
diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
index b4745900dc..a35c153084 100644
--- a/src/plugins/platforms/cocoa/qcocoaclipboard.mm
+++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
@@ -56,13 +56,13 @@ QMimeData *QCocoaClipboard::mimeData(QClipboard::Mode mode)
pasteBoard->sync();
return pasteBoard->mimeData();
}
- return 0;
+ return nullptr;
}
void QCocoaClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
{
if (QMacPasteboard *pasteBoard = pasteboardForMode(mode)) {
- if (data == 0) {
+ if (!data) {
pasteBoard->clear();
}
@@ -90,7 +90,7 @@ QMacPasteboard *QCocoaClipboard::pasteboardForMode(QClipboard::Mode mode) const
else if (mode == QClipboard::FindBuffer)
return m_find.data();
else
- return 0;
+ return nullptr;
}
void QCocoaClipboard::handleApplicationStateChanged(Qt::ApplicationState state)
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
index aa6124507d..d7850b1481 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
@@ -50,7 +50,14 @@
QT_USE_NAMESPACE
@interface QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) : NSObject<NSWindowDelegate, QNSPanelDelegate>
-{
+- (void)restoreOriginalContentView;
+- (void)updateQtColor;
+- (void)finishOffWithCode:(NSInteger)code;
+@end
+
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
+
+@implementation QNSColorPanelDelegate {
@public
NSColorPanel *mColorPanel;
QCocoaColorDialogHelper *mHelper;
@@ -61,22 +68,14 @@ QT_USE_NAMESPACE
BOOL mDialogIsExecuting;
BOOL mResultSet;
BOOL mClosingDueToKnownButton;
-};
-- (void)restoreOriginalContentView;
-- (void)updateQtColor;
-- (void)finishOffWithCode:(NSInteger)code;
-@end
-
-QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
-
-@implementation QNSColorPanelDelegate
+}
-- (id)init
+- (instancetype)init
{
self = [super init];
mColorPanel = [NSColorPanel sharedColorPanel];
- mHelper = 0;
- mStolenContentView = 0;
+ mHelper = nullptr;
+ mStolenContentView = nil;
mPanelButtons = nil;
mResultCode = NSModalResponseCancel;
mDialogIsExecuting = false;
@@ -116,9 +115,9 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
[self restoreOriginalContentView];
} else if (!mStolenContentView) {
// steal the color panel's contents view
- mStolenContentView = [mColorPanel contentView];
+ mStolenContentView = mColorPanel.contentView;
[mStolenContentView retain];
- [mColorPanel setContentView:0];
+ mColorPanel.contentView = nil;
// create a new content view and add the stolen one as a subview
mPanelButtons = [[QNSPanelContentsWrapper alloc] initWithPanelDelegate:self];
@@ -310,7 +309,7 @@ public:
void cleanup(QCocoaColorDialogHelper *helper)
{
if (mDelegate->mHelper == helper)
- mDelegate->mHelper = 0;
+ mDelegate->mHelper = nullptr;
}
bool exec()
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index 8c98dc69f7..87a57c78c8 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -80,15 +80,15 @@ void QCocoaCursor::setPos(const QPoint &position)
pos.x = position.x();
pos.y = position.y();
- CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, kCGMouseButtonLeft);
+ CGEventRef e = CGEventCreateMouseEvent(nullptr, kCGEventMouseMoved, pos, kCGMouseButtonLeft);
CGEventPost(kCGHIDEventTap, e);
CFRelease(e);
}
NSCursor *QCocoaCursor::convertCursor(QCursor *cursor)
{
- if (cursor == nullptr)
- return 0;
+ if (!cursor)
+ return nil;
const Qt::CursorShape newShape = cursor->shape();
NSCursor *cocoaCursor;
@@ -138,11 +138,11 @@ NSCursor *QCocoaCursor::convertCursor(QCursor *cursor)
cocoaCursor = m_cursors.value(newShape);
if (cocoaCursor && cursor->shape() == Qt::BitmapCursor) {
[cocoaCursor release];
- cocoaCursor = 0;
+ cocoaCursor = nil;
}
- if (cocoaCursor == 0) {
+ if (!cocoaCursor) {
cocoaCursor = createCursorData(cursor);
- if (cocoaCursor == 0)
+ if (!cocoaCursor)
return [NSCursor arrowCursor];
m_cursors.insert(newShape, cocoaCursor);
@@ -211,8 +211,8 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor)
0x07, 0xf0, 0x0f, 0xf8, 0x0f, 0xf8, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0,
0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0 };
#endif
- const uchar *cursorData = 0;
- const uchar *cursorMaskData = 0;
+ const uchar *cursorData = nullptr;
+ const uchar *cursorMaskData = nullptr;
QPoint hotspot = cursor->hotSpot();
switch (cursor->shape()) {
@@ -269,7 +269,7 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor)
#endif
default:
qWarning("Qt: QCursor::update: Invalid cursor shape %d", cursor->shape());
- return 0;
+ return nil;
}
// Create an NSCursor from image data if this a self-provided cursor.
@@ -279,7 +279,7 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor)
return (createCursorFromBitmap(&bitmap, &mask, hotspot));
}
- return 0; // should not happen, all cases covered above
+ return nil; // should not happen, all cases covered above
}
NSCursor *QCocoaCursor::createCursorFromBitmap(const QBitmap *bitmap, const QBitmap *mask, const QPoint hotspot)
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index e1f36b47a1..09433194a6 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -50,10 +50,10 @@ QT_BEGIN_NAMESPACE
static const int dragImageMaxChars = 26;
QCocoaDrag::QCocoaDrag() :
- m_drag(0)
+ m_drag(nullptr)
{
- m_lastEvent = 0;
- m_lastView = 0;
+ m_lastEvent = nil;
+ m_lastView = nil;
}
QCocoaDrag::~QCocoaDrag()
@@ -73,7 +73,7 @@ QMimeData *QCocoaDrag::dragMimeData()
if (m_drag)
return m_drag->mimeData();
- return 0;
+ return nullptr;
}
Qt::DropAction QCocoaDrag::defaultAction(Qt::DropActions possibleActions,
@@ -140,7 +140,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
NSPoint event_location = [m_lastEvent locationInWindow];
NSWindow *theWindow = [m_lastEvent window];
- Q_ASSERT(theWindow != nil);
+ Q_ASSERT(theWindow);
event_location.x -= hotSpot.x();
CGFloat flippedY = pmDeviceIndependentSize.height() - hotSpot.y();
event_location.y -= flippedY;
@@ -157,7 +157,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
[nsimage release];
- m_drag = 0;
+ m_drag = nullptr;
return m_executed_drop_action;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index 2ffc1395ba..ebf33cf4e2 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -110,8 +110,8 @@ class QCocoaEventDispatcher : public QAbstractEventDispatcher
Q_DECLARE_PRIVATE(QCocoaEventDispatcher)
public:
- QCocoaEventDispatcher(QAbstractEventDispatcherPrivate &priv, QObject *parent = 0);
- explicit QCocoaEventDispatcher(QObject *parent = 0);
+ QCocoaEventDispatcher(QAbstractEventDispatcherPrivate &priv, QObject *parent = nullptr);
+ explicit QCocoaEventDispatcher(QObject *parent = nullptr);
~QCocoaEventDispatcher();
bool processEvents(QEventLoop::ProcessEventsFlags flags);
@@ -153,6 +153,7 @@ public:
void maybeStopCFRunLoopTimer();
static void runLoopTimerCallback(CFRunLoopTimerRef, void *info);
static void activateTimersSourceCallback(void *info);
+ bool processTimers();
// Set 'blockSendPostedEvents' to true if you _really_ need
// to make sure that qt events are not posted while calling
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index bf9ba4eccf..b0f2b6d940 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -120,20 +120,26 @@ void QCocoaEventDispatcherPrivate::runLoopTimerCallback(CFRunLoopTimerRef, void
void QCocoaEventDispatcherPrivate::activateTimersSourceCallback(void *info)
{
QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info);
- (void) d->timerInfoList.activateTimers();
- d->maybeStartCFRunLoopTimer();
+ d->processTimers();
d->maybeCancelWaitForMoreEvents();
}
+bool QCocoaEventDispatcherPrivate::processTimers()
+{
+ int activated = timerInfoList.activateTimers();
+ maybeStartCFRunLoopTimer();
+ return activated > 0;
+}
+
void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer()
{
if (timerInfoList.isEmpty()) {
// no active timers, so the CFRunLoopTimerRef should not be active either
- Q_ASSERT(runLoopTimerRef == 0);
+ Q_ASSERT(!runLoopTimerRef);
return;
}
- if (runLoopTimerRef == 0) {
+ if (!runLoopTimerRef) {
// start the CFRunLoopTimer
CFAbsoluteTime ttf = CFAbsoluteTimeGetCurrent();
CFTimeInterval interval;
@@ -150,11 +156,11 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer()
}
ttf += interval;
- CFRunLoopTimerContext info = { 0, this, 0, 0, 0 };
+ CFRunLoopTimerContext info = { 0, this, nullptr, nullptr, nullptr };
// create the timer with a large interval, as recommended by the CFRunLoopTimerSetNextFireDate()
// documentation, since we will adjust the timer's time-to-fire as needed to keep Qt timers working
- runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, oneyear, 0, 0, QCocoaEventDispatcherPrivate::runLoopTimerCallback, &info);
- Q_ASSERT(runLoopTimerRef != 0);
+ runLoopTimerRef = CFRunLoopTimerCreate(nullptr, ttf, oneyear, 0, 0, QCocoaEventDispatcherPrivate::runLoopTimerCallback, &info);
+ Q_ASSERT(runLoopTimerRef);
CFRunLoopAddTimer(mainRunLoop(), runLoopTimerRef, kCFRunLoopCommonModes);
} else {
@@ -180,12 +186,12 @@ void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer()
void QCocoaEventDispatcherPrivate::maybeStopCFRunLoopTimer()
{
- if (runLoopTimerRef == 0)
+ if (!runLoopTimerRef)
return;
CFRunLoopTimerInvalidate(runLoopTimerRef);
CFRelease(runLoopTimerRef);
- runLoopTimerRef = 0;
+ runLoopTimerRef = nullptr;
}
void QCocoaEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj)
@@ -293,25 +299,25 @@ static bool IsMouseOrKeyEvent( NSEvent* event )
switch( [event type] )
{
- case NSLeftMouseDown:
- case NSLeftMouseUp:
- case NSRightMouseDown:
- case NSRightMouseUp:
- case NSMouseMoved: // ??
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSMouseEntered:
- case NSMouseExited:
- case NSKeyDown:
- case NSKeyUp:
- case NSFlagsChanged: // key modifiers changed?
- case NSCursorUpdate: // ??
- case NSScrollWheel:
- case NSTabletPoint:
- case NSTabletProximity:
- case NSOtherMouseDown:
- case NSOtherMouseUp:
- case NSOtherMouseDragged:
+ case NSEventTypeLeftMouseDown:
+ case NSEventTypeLeftMouseUp:
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeRightMouseUp:
+ case NSEventTypeMouseMoved: // ??
+ case NSEventTypeLeftMouseDragged:
+ case NSEventTypeRightMouseDragged:
+ case NSEventTypeMouseEntered:
+ case NSEventTypeMouseExited:
+ case NSEventTypeKeyDown:
+ case NSEventTypeKeyUp:
+ case NSEventTypeFlagsChanged: // key modifiers changed?
+ case NSEventTypeCursorUpdate: // ??
+ case NSEventTypeScrollWheel:
+ case NSEventTypeTabletPoint:
+ case NSEventTypeTabletProximity:
+ case NSEventTypeOtherMouseDown:
+ case NSEventTypeOtherMouseUp:
+ case NSEventTypeOtherMouseDragged:
#ifndef QT_NO_GESTURES
case NSEventTypeGesture: // touch events
case NSEventTypeMagnify:
@@ -335,7 +341,7 @@ static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRun
// at least one event occur. Setting 'dequeuing' to 'no' in the following call
// causes it to hang under certain circumstances (QTBUG-28283), so we tell it
// to dequeue instead, just to repost the event again:
- NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:[NSDate distantFuture]
inMode:runLoopMode
dequeue:YES];
@@ -368,13 +374,13 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
break;
QMacAutoReleasePool pool;
- NSEvent* event = 0;
+ NSEvent* event = nil;
// First, send all previously excluded input events, if any:
if (!excludeUserEvents) {
while (!d->queuedUserInputEvents.isEmpty()) {
event = static_cast<NSEvent *>(d->queuedUserInputEvents.takeFirst());
- if (!filterNativeEvent("NSEvent", event, 0)) {
+ if (!filterNativeEvent("NSEvent", event, nullptr)) {
[NSApp sendEvent:event];
retVal = true;
}
@@ -432,7 +438,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
retVal = true;
} else {
int lastSerialCopy = d->lastSerial;
- bool hadModalSession = d->currentModalSessionCached != 0;
+ const bool hadModalSession = d->currentModalSessionCached;
// We cannot block the thread (and run in a tight loop).
// Instead we will process all current pending events and return.
d->ensureNSAppInitialized();
@@ -460,7 +466,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
// Dispatch all non-user events (but que non-user events up for later). In
// this case, we need more control over which events gets dispatched, and
// cannot use [NSApp runModalSession:session]:
- event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:nil
inMode:NSModalPanelRunLoopMode
dequeue: YES];
@@ -471,15 +477,15 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
d->queuedUserInputEvents.append(event);
continue;
}
- if (!filterNativeEvent("NSEvent", event, 0)) {
+ if (!filterNativeEvent("NSEvent", event, nullptr)) {
[NSApp sendEvent:event];
retVal = true;
}
}
- } while (!d->interrupt && event != nil);
+ } while (!d->interrupt && event);
} else do {
// INVARIANT: No modal window is executing.
- event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:nil
inMode:NSDefaultRunLoopMode
dequeue: YES];
@@ -492,18 +498,17 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
continue;
}
}
- if (!filterNativeEvent("NSEvent", event, 0)) {
+ if (!filterNativeEvent("NSEvent", event, nullptr)) {
[NSApp sendEvent:event];
retVal = true;
}
}
- } while (!d->interrupt && event != nil);
+ } while (!d->interrupt && event);
if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
- // when called "manually", always send posted events and timers
+ // When called "manually", always process posted events and timers
d->processPostedEvents();
- retVal = d->timerInfoList.activateTimers() > 0 || retVal;
- d->maybeStartCFRunLoopTimer();
+ retVal = d->processTimers() || retVal;
}
// be sure to return true if the posted event source fired
@@ -514,7 +519,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
// event recursion to ensure that we spin the correct modal session.
// We do the interruptLater at the end of the function to ensure that we don't
// disturb the 'wait for more events' below (as deleteLater will post an event):
- if (hadModalSession && d->currentModalSessionCached == 0)
+ if (hadModalSession && !d->currentModalSessionCached)
interruptLater = true;
}
bool canWait = (d->threadData->canWait
@@ -611,11 +616,11 @@ void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions()
QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
if (info.session) {
[NSApp endModalSession:info.session];
- info.session = 0;
+ info.session = nullptr;
[(NSWindow*) info.nswindow release];
}
}
- currentModalSessionCached = 0;
+ currentModalSessionCached = nullptr;
}
NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
@@ -626,7 +631,7 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
return currentModalSessionCached;
if (cocoaModalSessionStack.isEmpty())
- return 0;
+ return nullptr;
int sessionCount = cocoaModalSessionStack.size();
for (int i=0; i<sessionCount; ++i) {
@@ -637,6 +642,8 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
if (!info.session) {
QMacAutoReleasePool pool;
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(info.window->handle());
+ if (!cocoaWindow)
+ continue;
NSWindow *nswindow = cocoaWindow->nativeWindow();
if (!nswindow)
continue;
@@ -647,6 +654,15 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
[(NSWindow*) info.nswindow retain];
QRect rect = cocoaWindow->geometry();
info.session = [NSApp beginModalSessionForWindow:nswindow];
+
+ // The call to beginModalSessionForWindow above processes events and may
+ // have deleted or destroyed the window. Check if it's still valid.
+ if (!info.window)
+ continue;
+ cocoaWindow = static_cast<QCocoaWindow *>(info.window->handle());
+ if (!cocoaWindow)
+ continue;
+
if (rect != cocoaWindow->geometry())
cocoaWindow->setGeometry(rect);
}
@@ -717,9 +733,9 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions()
currentModalSessionCached = info.session;
break;
}
- currentModalSessionCached = 0;
+ currentModalSessionCached = nullptr;
if (info.session) {
- Q_ASSERT(info.nswindow != 0);
+ Q_ASSERT(info.nswindow);
[NSApp endModalSession:info.session];
[(NSWindow *)info.nswindow release];
}
@@ -746,10 +762,10 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
// currentModalSession). A QCocoaModalSessionInfo is considered pending to be stopped if
// the window pointer is zero, and the session pointer is non-zero (it will be fully
// stopped in cleanupModalSessions()).
- QCocoaModalSessionInfo info = {window, 0, 0};
+ QCocoaModalSessionInfo info = {window, nullptr, nullptr};
cocoaModalSessionStack.push(info);
updateChildrenWorksWhenModal();
- currentModalSessionCached = 0;
+ currentModalSessionCached = nullptr;
}
void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
@@ -768,12 +784,12 @@ void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
if (!info.window)
endedSessions++;
if (info.window == window) {
- info.window = 0;
+ info.window = nullptr;
if (i + endedSessions == stackSize-1) {
// The top sessions ended. Interrupt the event dispatcher to
// start spinning the correct session immediately.
q->interrupt();
- currentModalSessionCached = 0;
+ currentModalSessionCached = nullptr;
cleanupModalSessionsNeeded = true;
}
}
@@ -782,13 +798,13 @@ void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
: processEventsFlags(0),
- runLoopTimerRef(0),
+ runLoopTimerRef(nullptr),
blockSendPostedEvents(false),
currentExecIsNSAppRun(false),
nsAppRunCalledByQt(false),
cleanupModalSessionsNeeded(false),
processEventsCalled(0),
- currentModalSessionCached(0),
+ currentModalSessionCached(nullptr),
lastSerial(-1),
interrupt(false)
{
@@ -925,8 +941,8 @@ void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents()
// In case the event dispatcher is waiting for more
// events somewhere, we post a dummy event to wake it up:
QMacAutoReleasePool pool;
- [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint
- modifierFlags:0 timestamp:0. windowNumber:0 context:0
+ [NSApp postEvent:[NSEvent otherEventWithType:NSEventTypeApplicationDefined location:NSZeroPoint
+ modifierFlags:0 timestamp:0. windowNumber:0 context:nil
subtype:QtCocoaEventSubTypeWakeup data1:0 data2:0] atStart:NO];
}
@@ -1008,7 +1024,7 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher()
CFRelease(d->firstTimeObserver);
}
-QtCocoaInterruptDispatcher* QtCocoaInterruptDispatcher::instance = 0;
+QtCocoaInterruptDispatcher* QtCocoaInterruptDispatcher::instance = nullptr;
QtCocoaInterruptDispatcher::QtCocoaInterruptDispatcher() : cancelled(false)
{
@@ -1025,7 +1041,7 @@ QtCocoaInterruptDispatcher::~QtCocoaInterruptDispatcher()
{
if (cancelled)
return;
- instance = 0;
+ instance = nullptr;
QCocoaEventDispatcher::instance()->interrupt();
}
@@ -1035,7 +1051,7 @@ void QtCocoaInterruptDispatcher::cancelInterruptLater()
return;
instance->cancelled = true;
delete instance;
- instance = 0;
+ instance = nullptr;
}
void QtCocoaInterruptDispatcher::interruptLater()
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 94f2125bad..e7243ec250 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -50,7 +50,6 @@
#include <private/qguiapplication_p.h>
#include "qt_mac_p.h"
#include "qcocoahelpers.h"
-#include "qcocoamenubar.h"
#include "qcocoaeventdispatcher.h"
#include <qregexp.h>
#include <qbuffer.h>
@@ -81,23 +80,6 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
@interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate)
: NSObject<NSOpenSavePanelDelegate>
-{
- @public
- NSOpenPanel *mOpenPanel;
- NSSavePanel *mSavePanel;
- NSView *mAccessoryView;
- NSPopUpButton *mPopUpButton;
- NSTextField *mTextField;
- QCocoaFileDialogHelper *mHelper;
- NSString *mCurrentDir;
-
- int mReturnCode;
-
- SharedPointerFileDialogOptions mOptions;
- QString *mCurrentSelection;
- QStringList *mNameFilterDropDownList;
- QStringList *mSelectedNameFilter;
-}
- (NSString *)strip:(const QString &)label;
- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url;
@@ -117,12 +99,27 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
-@implementation QNSOpenSavePanelDelegate
+@implementation QNSOpenSavePanelDelegate {
+ @public
+ NSOpenPanel *mOpenPanel;
+ NSSavePanel *mSavePanel;
+ NSView *mAccessoryView;
+ NSPopUpButton *mPopUpButton;
+ NSTextField *mTextField;
+ QCocoaFileDialogHelper *mHelper;
+ NSString *mCurrentDir;
+
+ int mReturnCode;
+
+ SharedPointerFileDialogOptions mOptions;
+ QString *mCurrentSelection;
+ QStringList *mNameFilterDropDownList;
+ QStringList *mSelectedNameFilter;
+}
-- (id)initWithAcceptMode:
- (const QString &)selectFile
- options:(SharedPointerFileDialogOptions)options
- helper:(QCocoaFileDialogHelper *)helper
+- (instancetype)initWithAcceptMode:(const QString &)selectFile
+ options:(SharedPointerFileDialogOptions)options
+ helper:(QCocoaFileDialogHelper *)helper
{
self = [super init];
mOptions = options;
@@ -132,7 +129,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
} else {
mSavePanel = [NSSavePanel savePanel];
[mSavePanel setCanSelectHiddenExtension:YES];
- mOpenPanel = 0;
+ mOpenPanel = nil;
}
if ([mSavePanel respondsToSelector:@selector(setLevel:)])
@@ -222,7 +219,6 @@ static QString strippedText(QString s)
|| [self panel:nil shouldEnableURL:url];
[self updateProperties];
- QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
[mSavePanel setNameFieldStringValue:selectable ? info.fileName().toNSString() : @""];
[mOpenPanel beginWithCompletionHandler:^(NSInteger result){
@@ -252,9 +248,7 @@ static QString strippedText(QString s)
// Make sure we don't interrupt the runModal call below.
QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
- QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
mReturnCode = [mSavePanel runModal];
- QCocoaMenuBar::resetKnownMenuItemsToQt();
QAbstractEventDispatcher::instance()->interrupt();
return (mReturnCode == NSModalResponseOK);
@@ -274,7 +268,6 @@ static QString strippedText(QString s)
|| [self panel:nil shouldEnableURL:url];
[self updateProperties];
- QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
[mSavePanel setNameFieldStringValue:selectable ? info.fileName().toNSString() : @""];
@@ -292,7 +285,7 @@ static QString strippedText(QString s)
BOOL hidden = NO;
if (url) {
CFBooleanRef isHiddenProperty;
- if (CFURLCopyResourcePropertyForKey((__bridge CFURLRef)url, kCFURLIsHiddenKey, &isHiddenProperty, NULL)) {
+ if (CFURLCopyResourcePropertyForKey((__bridge CFURLRef)url, kCFURLIsHiddenKey, &isHiddenProperty, nullptr)) {
hidden = CFBooleanGetValue(isHiddenProperty);
CFRelease(isHiddenProperty);
}
@@ -406,9 +399,9 @@ static QString strippedText(QString s)
{
if (mOpenPanel) {
QList<QUrl> result;
- NSArray* array = [mOpenPanel URLs];
- for (NSUInteger i=0; i<[array count]; ++i) {
- QString path = QString::fromNSString([[array objectAtIndex:i] path]).normalized(QString::NormalizationForm_C);
+ NSArray<NSURL *> *array = [mOpenPanel URLs];
+ for (NSURL *url in array) {
+ QString path = QString::fromNSString(url.path).normalized(QString::NormalizationForm_C);
result << QUrl::fromLocalFile(path);
}
return result;
@@ -522,8 +515,8 @@ static QString strippedText(QString s)
NSRect textRect = { { 0.0, 3.0 }, { 100.0, 25.0 } };
mTextField = [[NSTextField alloc] initWithFrame:textRect];
[[mTextField cell] setFont:[NSFont systemFontOfSize:
- [NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
- [mTextField setAlignment:NSRightTextAlignment];
+ [NSFont systemFontSizeForControlSize:NSControlSizeRegular]]];
+ [mTextField setAlignment:NSTextAlignmentRight];
[mTextField setEditable:false];
[mTextField setSelectable:false];
[mTextField setBordered:false];
@@ -576,7 +569,7 @@ static QString strippedText(QString s)
QT_BEGIN_NAMESPACE
QCocoaFileDialogHelper::QCocoaFileDialogHelper()
- :mDelegate(0)
+ : mDelegate(nil)
{
}
@@ -586,7 +579,7 @@ QCocoaFileDialogHelper::~QCocoaFileDialogHelper()
return;
QMacAutoReleasePool pool;
[mDelegate release];
- mDelegate = 0;
+ mDelegate = nil;
}
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_selectionChanged(const QString &newPath)
@@ -596,7 +589,6 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_selectionChanged(const QSt
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
{
- QCocoaMenuBar::resetKnownMenuItemsToQt();
if (accepted) {
emit accept();
} else {
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index 815882ab06..33b102f3eb 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -74,7 +74,15 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
}
@interface QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) : NSObject<NSWindowDelegate, QNSPanelDelegate>
-{
+- (void)restoreOriginalContentView;
+- (void)updateQtFont;
+- (void)changeFont:(id)sender;
+- (void)finishOffWithCode:(NSInteger)code;
+@end
+
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
+
+@implementation QNSFontPanelDelegate {
@public
NSFontPanel *mFontPanel;
QCocoaFontDialogHelper *mHelper;
@@ -84,34 +92,26 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
NSInteger mResultCode;
BOOL mDialogIsExecuting;
BOOL mResultSet;
-};
-- (void)restoreOriginalContentView;
-- (void)updateQtFont;
-- (void)changeFont:(id)sender;
-- (void)finishOffWithCode:(NSInteger)code;
-@end
-
-QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
-
-@implementation QNSFontPanelDelegate
+}
-- (id)init
+- (instancetype)init
{
- self = [super init];
- mFontPanel = [NSFontPanel sharedFontPanel];
- mHelper = 0;
- mStolenContentView = 0;
- mPanelButtons = 0;
- mResultCode = NSModalResponseCancel;
- mDialogIsExecuting = false;
- mResultSet = false;
+ if ((self = [super init])) {
+ mFontPanel = [NSFontPanel sharedFontPanel];
+ mHelper = nullptr;
+ mStolenContentView = nil;
+ mPanelButtons = nil;
+ mResultCode = NSModalResponseCancel;
+ mDialogIsExecuting = false;
+ mResultSet = false;
- [mFontPanel setRestorable:NO];
- [mFontPanel setDelegate:self];
+ [mFontPanel setRestorable:NO];
+ [mFontPanel setDelegate:self];
- [NSFontManager sharedFontManager].target = self; // Action is changeFont:
+ [NSFontManager sharedFontManager].target = self; // Action is changeFont:
- [mFontPanel retain];
+ [mFontPanel retain];
+ }
return self;
}
@@ -135,9 +135,9 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
[self restoreOriginalContentView];
} else if (!mStolenContentView) {
// steal the font panel's contents view
- mStolenContentView = [mFontPanel contentView];
+ mStolenContentView = mFontPanel.contentView;
[mStolenContentView retain];
- [mFontPanel setContentView:0];
+ mFontPanel.contentView = nil;
// create a new content view and add the stolen one as a subview
mPanelButtons = [[QNSPanelContentsWrapper alloc] initWithPanelDelegate:self];
@@ -159,7 +159,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
// return stolen stuff to its rightful owner
[mStolenContentView removeFromSuperview];
[mFontPanel setContentView:mStolenContentView];
- mStolenContentView = 0;
+ mStolenContentView = nil;
[mPanelButtons release];
mPanelButtons = nil;
}
@@ -191,7 +191,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
// Get selected font
NSFontManager *fontManager = [NSFontManager sharedFontManager];
NSFont *selectedFont = [fontManager selectedFont];
- if (selectedFont == nil) {
+ if (!selectedFont) {
selectedFont = [NSFont systemFontOfSize:[NSFont systemFontSize]];
}
NSFont *panelFont = [fontManager convertFont:selectedFont];
@@ -295,7 +295,7 @@ public:
void cleanup(QCocoaFontDialogHelper *helper)
{
if (mDelegate->mHelper == helper)
- mDelegate->mHelper = 0;
+ mDelegate->mHelper = nullptr;
}
bool exec()
@@ -329,7 +329,7 @@ public:
void setCurrentFont(const QFont &font)
{
NSFontManager *mgr = [NSFontManager sharedFontManager];
- const NSFont *nsFont = 0;
+ NSFont *nsFont = nil;
int weight = 5;
NSFontTraitMask mask = 0;
@@ -347,7 +347,7 @@ public:
weight:weight
size:fontInfo.pointSize()];
- [mgr setSelectedFont:const_cast<NSFont *>(nsFont) isMultiple:NO];
+ [mgr setSelectedFont:nsFont isMultiple:NO];
mDelegate->mQtFont = font;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
index 0530aa8201..cef5892989 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.h
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -52,39 +52,33 @@ QT_BEGIN_NAMESPACE
class QCocoaGLContext : public QPlatformOpenGLContext
{
public:
- QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, const QVariant &nativeHandle);
+ QCocoaGLContext(QOpenGLContext *context);
~QCocoaGLContext();
- QSurfaceFormat format() const override;
-
- void swapBuffers(QPlatformSurface *surface) override;
-
bool makeCurrent(QPlatformSurface *surface) override;
+ void swapBuffers(QPlatformSurface *surface) override;
void doneCurrent() override;
- QFunctionPointer getProcAddress(const char *procName) override;
-
void update();
- static NSOpenGLPixelFormat *createNSOpenGLPixelFormat(const QSurfaceFormat &format);
- NSOpenGLContext *nsOpenGLContext() const;
-
+ QSurfaceFormat format() const override;
bool isSharing() const override;
bool isValid() const override;
- void windowWasHidden();
+ NSOpenGLContext *nativeContext() const;
- QVariant nativeHandle() const;
+ QFunctionPointer getProcAddress(const char *procName) override;
private:
- void setActiveWindow(QWindow *window);
+ static NSOpenGLPixelFormat *pixelFormatForSurfaceFormat(const QSurfaceFormat &format);
+
+ bool setDrawable(QPlatformSurface *surface);
void updateSurfaceFormat();
- NSOpenGLContext *m_context;
- NSOpenGLContext *m_shareContext;
+ NSOpenGLContext *m_context = nil;
+ NSOpenGLContext *m_shareContext = nil;
QSurfaceFormat m_format;
- QPointer<QWindow> m_currentWindow;
- bool m_didCheckForSoftwareContext;
+ bool m_didCheckForSoftwareContext = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 7ffe0003d3..069429796e 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -47,8 +47,6 @@
#import <AppKit/AppKit.h>
-QT_BEGIN_NAMESPACE
-
static inline QByteArray getGlString(GLenum param)
{
if (const GLubyte *s = glGetString(param))
@@ -56,109 +54,66 @@ static inline QByteArray getGlString(GLenum param)
return QByteArray();
}
-#if !defined(GL_CONTEXT_FLAGS)
-#define GL_CONTEXT_FLAGS 0x821E
-#endif
-
-#if !defined(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
-#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
-#endif
-
-#if !defined(GL_CONTEXT_PROFILE_MASK)
-#define GL_CONTEXT_PROFILE_MASK 0x9126
-#endif
-
-#if !defined(GL_CONTEXT_CORE_PROFILE_BIT)
-#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
-#endif
-
-#if !defined(GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
-#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
-#endif
-
-static void updateFormatFromContext(QSurfaceFormat *format)
+@implementation NSOpenGLPixelFormat (QtHelpers)
+- (GLint)qt_getAttribute:(NSOpenGLPixelFormatAttribute)attribute
{
- Q_ASSERT(format);
-
- // Update the version, profile, and context bit of the format
- int major = 0, minor = 0;
- QByteArray versionString(getGlString(GL_VERSION));
- if (QPlatformOpenGLContext::parseOpenGLVersion(versionString, major, minor)) {
- format->setMajorVersion(major);
- format->setMinorVersion(minor);
- }
-
- format->setProfile(QSurfaceFormat::NoProfile);
-
- Q_ASSERT(format->renderableType() == QSurfaceFormat::OpenGL);
- if (format->version() < qMakePair(3, 0)) {
- format->setOption(QSurfaceFormat::DeprecatedFunctions);
- return;
- }
-
- // Version 3.0 onwards - check if it includes deprecated functionality
- GLint value = 0;
- glGetIntegerv(GL_CONTEXT_FLAGS, &value);
- if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT))
- format->setOption(QSurfaceFormat::DeprecatedFunctions);
-
- // Debug context option not supported on OS X
-
- if (format->version() < qMakePair(3, 2))
- return;
-
- // Version 3.2 and newer have a profile
- value = 0;
- glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
+ int value = 0;
+ [self getValues:&value forAttribute:attribute forVirtualScreen:0];
+ return value;
+}
+@end
- if (value & GL_CONTEXT_CORE_PROFILE_BIT)
- format->setProfile(QSurfaceFormat::CoreProfile);
- else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
- format->setProfile(QSurfaceFormat::CompatibilityProfile);
+@implementation NSOpenGLContext (QtHelpers)
+- (GLint)qt_getParameter:(NSOpenGLContextParameter)parameter
+{
+ int value = 0;
+ [self getValues:&value forParameter:parameter];
+ return value;
}
+@end
+
+QT_BEGIN_NAMESPACE
- // NSOpenGLContext is not re-entrant (https://openradar.appspot.com/37064579)
-static QMutex s_contextMutex;
+Q_LOGGING_CATEGORY(lcQpaOpenGLContext, "qt.qpa.openglcontext", QtWarningMsg);
-QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
- const QVariant &nativeHandle)
- : m_context(nil),
- m_shareContext(nil),
- m_format(format),
- m_didCheckForSoftwareContext(false)
+QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context)
+ : QPlatformOpenGLContext(), m_format(context->format())
{
+ QVariant nativeHandle = context->nativeHandle();
if (!nativeHandle.isNull()) {
if (!nativeHandle.canConvert<QCocoaNativeContext>()) {
- qWarning("QCocoaGLContext: Requires a QCocoaNativeContext");
+ qCWarning(lcQpaOpenGLContext, "QOpenGLContext native handle must be a QCocoaNativeContext");
return;
}
- QCocoaNativeContext handle = nativeHandle.value<QCocoaNativeContext>();
- NSOpenGLContext *context = handle.context();
- if (!context) {
- qWarning("QCocoaGLContext: No NSOpenGLContext given");
+ m_context = nativeHandle.value<QCocoaNativeContext>().context();
+ if (!m_context) {
+ qCWarning(lcQpaOpenGLContext, "QCocoaNativeContext's NSOpenGLContext can not be null");
return;
}
- m_context = context;
+
[m_context retain];
- m_shareContext = share ? static_cast<QCocoaGLContext *>(share)->nsOpenGLContext() : nil;
- // OpenGL surfaces can be ordered either above(default) or below the NSWindow.
- const GLint order = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER");
- [m_context setValues:&order forParameter:NSOpenGLCPSurfaceOrder];
+
+ // Note: We have no way of knowing whether the NSOpenGLContext was created with the
+ // share context as reported by the QOpenGLContext, but we just have to trust that
+ // it was. It's okey, as the only thing we're using it for is to report isShared().
+ if (QPlatformOpenGLContext *shareContext = context->shareHandle())
+ m_shareContext = static_cast<QCocoaGLContext *>(shareContext)->nativeContext();
+
updateSurfaceFormat();
return;
}
- // we only support OpenGL contexts under Cocoa
+ // ----------- Default case, we own the NSOpenGLContext -----------
+
+ // We only support OpenGL contexts under Cocoa
if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType)
m_format.setRenderableType(QSurfaceFormat::OpenGL);
if (m_format.renderableType() != QSurfaceFormat::OpenGL)
return;
- QMacAutoReleasePool pool; // For the SG Canvas render thread
+ if (QPlatformOpenGLContext *shareContext = context->shareHandle()) {
+ m_shareContext = static_cast<QCocoaGLContext *>(shareContext)->nativeContext();
- m_shareContext = share ? static_cast<QCocoaGLContext *>(share)->nsOpenGLContext() : nil;
-
- if (m_shareContext) {
// Allow sharing between 3.2 Core and 4.1 Core profile versions in
// cases where NSOpenGLContext creates a 4.1 context where a 3.2
// context was requested. Due to the semantics of QSurfaceFormat
@@ -167,312 +122,327 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
GLint shareContextRequestedProfile;
[m_shareContext.pixelFormat getValues:&shareContextRequestedProfile
forAttribute:NSOpenGLPFAOpenGLProfile forVirtualScreen:0];
- auto shareContextActualProfile = share->format().version();
-
- if (shareContextRequestedProfile == NSOpenGLProfileVersion3_2Core &&
- shareContextActualProfile >= qMakePair(4, 1)) {
+ auto shareContextActualProfile = shareContext->format().version();
- // There is a mismatch, downgrade requested format to make the
- // NSOpenGLPFAOpenGLProfile attributes match. (NSOpenGLContext will
- // fail to create a new context if there is a mismatch).
+ if (shareContextRequestedProfile == NSOpenGLProfileVersion3_2Core
+ && shareContextActualProfile >= qMakePair(4, 1)) {
+ // There is a mismatch. Downgrade requested format to make the
+ // NSOpenGLPFAOpenGLProfile attributes match. (NSOpenGLContext
+ // will fail to create a new context if there is a mismatch).
if (m_format.version() >= qMakePair(4, 1))
m_format.setVersion(3, 2);
}
}
- // create native context for the requested pixel format and share
- NSOpenGLPixelFormat *pixelFormat = createNSOpenGLPixelFormat(m_format);
+ // ------------------------- Create NSOpenGLContext -------------------------
+
+ NSOpenGLPixelFormat *pixelFormat = [pixelFormatForSurfaceFormat(m_format) autorelease];
m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:m_shareContext];
- // retry without sharing on context creation failure.
if (!m_context && m_shareContext) {
- m_shareContext = nil;
+ qCWarning(lcQpaOpenGLContext, "Could not create NSOpenGLContext with shared context, "
+ "falling back to unshared context.");
m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
- if (m_context)
- qWarning("QCocoaGLContext: Falling back to unshared context.");
+ m_shareContext = nil;
}
- // give up if we still did not get a native context
- [pixelFormat release];
if (!m_context) {
- qWarning("QCocoaGLContext: Failed to create context.");
+ qCWarning(lcQpaOpenGLContext, "Failed to create NSOpenGLContext");
return;
}
- const GLint interval = format.swapInterval() >= 0 ? format.swapInterval() : 1;
+ // --------------------- Set NSOpenGLContext properties ---------------------
+
+ const GLint interval = m_format.swapInterval() >= 0 ? m_format.swapInterval() : 1;
[m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
- if (format.alphaBufferSize() > 0) {
+ if (m_format.alphaBufferSize() > 0) {
int zeroOpacity = 0;
[m_context setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
}
-
- // OpenGL surfaces can be ordered either above(default) or below the NSWindow.
+ // OpenGL surfaces can be ordered either above(default) or below the NSWindow
+ // FIXME: Promote to QSurfaceFormat option or property
const GLint order = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER");
[m_context setValues:&order forParameter:NSOpenGLCPSurfaceOrder];
updateSurfaceFormat();
}
-QCocoaGLContext::~QCocoaGLContext()
+NSOpenGLPixelFormat *QCocoaGLContext::pixelFormatForSurfaceFormat(const QSurfaceFormat &format)
{
- if (m_currentWindow && m_currentWindow.data()->handle())
- static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+ QVector<NSOpenGLPixelFormatAttribute> attrs;
- [m_context release];
-}
+ attrs << NSOpenGLPFAOpenGLProfile;
+ if (format.profile() == QSurfaceFormat::CoreProfile) {
+ if (format.version() >= qMakePair(4, 1))
+ attrs << NSOpenGLProfileVersion4_1Core;
+ else if (format.version() >= qMakePair(3, 2))
+ attrs << NSOpenGLProfileVersion3_2Core;
+ else
+ attrs << NSOpenGLProfileVersionLegacy;
+ } else {
+ attrs << NSOpenGLProfileVersionLegacy;
+ }
-QVariant QCocoaGLContext::nativeHandle() const
-{
- return QVariant::fromValue<QCocoaNativeContext>(QCocoaNativeContext(m_context));
-}
+ switch (format.swapBehavior()) {
+ case QSurfaceFormat::SingleBuffer:
+ break; // The NSOpenGLPixelFormat default, no attribute to set
+ case QSurfaceFormat::DefaultSwapBehavior:
+ // Technically this should be single-buffered, but we force double-buffered
+ // FIXME: Why do we force double-buffered?
+ Q_FALLTHROUGH();
+ case QSurfaceFormat::DoubleBuffer:
+ attrs.append(NSOpenGLPFADoubleBuffer);
+ break;
+ case QSurfaceFormat::TripleBuffer:
+ attrs.append(NSOpenGLPFATripleBuffer);
+ break;
+ }
-QSurfaceFormat QCocoaGLContext::format() const
-{
- return m_format;
-}
+ if (format.depthBufferSize() > 0)
+ attrs << NSOpenGLPFADepthSize << format.depthBufferSize();
+ if (format.stencilBufferSize() > 0)
+ attrs << NSOpenGLPFAStencilSize << format.stencilBufferSize();
+ if (format.alphaBufferSize() > 0)
+ attrs << NSOpenGLPFAAlphaSize << format.alphaBufferSize();
+ if (format.redBufferSize() > 0 && format.greenBufferSize() > 0 && format.blueBufferSize() > 0) {
+ const int colorSize = format.redBufferSize() + format.greenBufferSize() + format.blueBufferSize();
+ attrs << NSOpenGLPFAColorSize << colorSize << NSOpenGLPFAMinimumPolicy;
+ }
-void QCocoaGLContext::windowWasHidden()
-{
- // If the window is hidden, we need to unset the m_currentWindow
- // variable so that succeeding makeCurrent's will not abort prematurely
- // because of the optimization in setActiveWindow.
- // Doing a full doneCurrent here is not preferable, because the GL context
- // might be rendering in a different thread at this time.
- m_currentWindow.clear();
-}
+ if (format.samples() > 0) {
+ attrs << NSOpenGLPFAMultisample
+ << NSOpenGLPFASampleBuffers << NSOpenGLPixelFormatAttribute(1)
+ << NSOpenGLPFASamples << NSOpenGLPixelFormatAttribute(format.samples());
+ }
-void QCocoaGLContext::swapBuffers(QPlatformSurface *surface)
-{
- if (surface->surface()->surfaceClass() == QSurface::Offscreen)
- return; // Nothing to do
+ // Allow rendering on GPUs without a connected display
+ attrs << NSOpenGLPFAAllowOfflineRenderers;
- QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
- setActiveWindow(window);
+ // FIXME: Pull this information out of the NSView
+ QByteArray useLayer = qgetenv("QT_MAC_WANTS_LAYER");
+ if (!useLayer.isEmpty() && useLayer.toInt() > 0) {
+ // Disable the software rendering fallback. This makes compositing
+ // OpenGL and raster NSViews using Core Animation layers possible.
+ attrs << NSOpenGLPFANoRecovery;
+ }
- QMutexLocker locker(&s_contextMutex);
- [m_context flushBuffer];
+ attrs << 0; // 0-terminate array
+ return [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs.constData()];
}
-bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
+/*!
+ Updates the surface format of this context based on properties of
+ the native context and GL state, so that the result of creating
+ the context is reflected back in QOpenGLContext.
+*/
+void QCocoaGLContext::updateSurfaceFormat()
{
- Q_ASSERT(surface->surface()->supportsOpenGL());
-
- QMacAutoReleasePool pool;
+ NSOpenGLContext *oldContext = [NSOpenGLContext currentContext];
[m_context makeCurrentContext];
- if (surface->surface()->surfaceClass() == QSurface::Offscreen)
- return true;
+ // --------------------- Query GL state ---------------------
- QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
- setActiveWindow(window);
-
- // Disable high-resolution surfaces when using the software renderer, which has the
- // problem that the system silently falls back to a to using a low-resolution buffer
- // when a high-resolution buffer is requested. This is not detectable using the NSWindow
- // convertSizeToBacking and backingScaleFactor APIs. A typical result of this is that Qt
- // will display a quarter of the window content when running in a virtual machine.
- if (!m_didCheckForSoftwareContext) {
- m_didCheckForSoftwareContext = true;
-
- const GLubyte* renderer = glGetString(GL_RENDERER);
- if (qstrcmp((const char *)renderer, "Apple Software Renderer") == 0) {
- NSView *view = static_cast<QCocoaWindow *>(surface)->m_view;
- [view setWantsBestResolutionOpenGLSurface:NO];
- }
+ int major = 0, minor = 0;
+ QByteArray versionString(getGlString(GL_VERSION));
+ if (QPlatformOpenGLContext::parseOpenGLVersion(versionString, major, minor)) {
+ m_format.setMajorVersion(major);
+ m_format.setMinorVersion(minor);
}
- update();
- return true;
-}
+ m_format.setProfile(QSurfaceFormat::NoProfile);
+ if (m_format.version() >= qMakePair(3, 2)) {
+ GLint value = 0;
+ glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
+ if (value & GL_CONTEXT_CORE_PROFILE_BIT)
+ m_format.setProfile(QSurfaceFormat::CoreProfile);
+ else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
+ m_format.setProfile(QSurfaceFormat::CompatibilityProfile);
+ }
-void QCocoaGLContext::setActiveWindow(QWindow *window)
-{
- if (window == m_currentWindow.data())
- return;
+ m_format.setOption(QSurfaceFormat::DeprecatedFunctions, [&]() {
+ if (m_format.version() < qMakePair(3, 0)) {
+ return true;
+ } else {
+ GLint value = 0;
+ glGetIntegerv(GL_CONTEXT_FLAGS, &value);
+ return !(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT);
+ }
+ }());
- if (m_currentWindow && m_currentWindow.data()->handle())
- static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+ // Debug contexts not supported on macOS
+ m_format.setOption(QSurfaceFormat::DebugContext, false);
- Q_ASSERT(window->handle());
+ // Nor are stereo buffers (deprecated in macOS 10.12)
+ m_format.setOption(QSurfaceFormat::StereoBuffers, false);
- m_currentWindow = window;
+ // ------------------ Query the pixel format ------------------
- QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
- cocoaWindow->setCurrentContext(this);
+ NSOpenGLPixelFormat *pixelFormat = m_context.pixelFormat;
- Q_ASSERT(!cocoaWindow->isForeignWindow());
- [qnsview_cast(cocoaWindow->view()) setQCocoaGLContext:this];
-}
+ int colorSize = [pixelFormat qt_getAttribute:NSOpenGLPFAColorSize];
+ colorSize /= 4; // The attribute includes the alpha component
+ m_format.setRedBufferSize(colorSize);
+ m_format.setGreenBufferSize(colorSize);
+ m_format.setBlueBufferSize(colorSize);
-void QCocoaGLContext::updateSurfaceFormat()
-{
- // At present it is impossible to turn an option off on a QSurfaceFormat (see
- // https://codereview.qt-project.org/#change,70599). So we have to populate
- // the actual surface format from scratch
- QSurfaceFormat requestedFormat = m_format;
- m_format = QSurfaceFormat();
- m_format.setRenderableType(QSurfaceFormat::OpenGL);
-
- // CoreGL doesn't require a drawable to make the context current
- CGLContextObj oldContext = CGLGetCurrentContext();
- CGLContextObj ctx = static_cast<CGLContextObj>([m_context CGLContextObj]);
- CGLSetCurrentContext(ctx);
-
- // Get the data that OpenGL provides
- updateFormatFromContext(&m_format);
-
- // Get the data contained within the pixel format
- CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>(CGLGetPixelFormat(ctx));
- NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithCGLPixelFormatObj:cglPixelFormat];
-
- int colorSize = -1;
- [pixelFormat getValues:&colorSize forAttribute:NSOpenGLPFAColorSize forVirtualScreen:0];
- if (colorSize > 0) {
- // This seems to return the total color buffer depth, including alpha
- m_format.setRedBufferSize(colorSize / 4);
- m_format.setGreenBufferSize(colorSize / 4);
- m_format.setBlueBufferSize(colorSize / 4);
- }
+ // Surfaces on macOS always have an alpha channel, but unless the user requested
+ // one via setAlphaBufferSize(), which triggered setting NSOpenGLCPSurfaceOpacity
+ // to make the surface non-opaque, we don't want to report back the actual alpha
+ // size, as that will make the user believe the alpha channel can be used for
+ // something useful, when in reality it can't, due to the surface being opaque.
+ if (m_format.alphaBufferSize() > 0)
+ m_format.setAlphaBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFAAlphaSize]);
- // The pixel format always seems to return 8 for alpha. However, the framebuffer only
- // seems to have alpha enabled if we requested it explicitly. I can't find any other
- // attribute to check explicitly for this so we use our best guess for alpha.
- int alphaSize = -1;
- [pixelFormat getValues:&alphaSize forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:0];
- if (alphaSize > 0 && requestedFormat.alphaBufferSize() > 0)
- m_format.setAlphaBufferSize(alphaSize);
-
- int depthSize = -1;
- [pixelFormat getValues:&depthSize forAttribute:NSOpenGLPFADepthSize forVirtualScreen:0];
- if (depthSize > 0)
- m_format.setDepthBufferSize(depthSize);
-
- int stencilSize = -1;
- [pixelFormat getValues:&stencilSize forAttribute:NSOpenGLPFAStencilSize forVirtualScreen:0];
- if (stencilSize > 0)
- m_format.setStencilBufferSize(stencilSize);
-
- int samples = -1;
- [pixelFormat getValues:&samples forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
- if (samples > 0)
- m_format.setSamples(samples);
-
- int doubleBuffered = -1;
- int tripleBuffered = -1;
- [pixelFormat getValues:&doubleBuffered forAttribute:NSOpenGLPFADoubleBuffer forVirtualScreen:0];
- [pixelFormat getValues:&tripleBuffered forAttribute:NSOpenGLPFATripleBuffer forVirtualScreen:0];
-
- if (tripleBuffered == 1)
+ m_format.setDepthBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFADepthSize]);
+ m_format.setStencilBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFAStencilSize]);
+ m_format.setSamples([pixelFormat qt_getAttribute:NSOpenGLPFASamples]);
+
+ if ([pixelFormat qt_getAttribute:NSOpenGLPFATripleBuffer])
m_format.setSwapBehavior(QSurfaceFormat::TripleBuffer);
- else if (doubleBuffered == 1)
+ else if ([pixelFormat qt_getAttribute:NSOpenGLPFADoubleBuffer])
m_format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
else
m_format.setSwapBehavior(QSurfaceFormat::SingleBuffer);
- int steroBuffers = -1;
- [pixelFormat getValues:&steroBuffers forAttribute:NSOpenGLPFAStereo forVirtualScreen:0];
- if (steroBuffers == 1)
- m_format.setOption(QSurfaceFormat::StereoBuffers);
+ // ------------------- Query the context -------------------
- [pixelFormat release];
+ m_format.setSwapInterval([m_context qt_getParameter:NSOpenGLCPSwapInterval]);
- GLint swapInterval = -1;
- [m_context getValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
- if (swapInterval >= 0)
- m_format.setSwapInterval(swapInterval);
+ if (oldContext)
+ [oldContext makeCurrentContext];
+ else
+ [NSOpenGLContext clearCurrentContext];
+}
- // Restore the original context
- CGLSetCurrentContext(oldContext);
+QCocoaGLContext::~QCocoaGLContext()
+{
+ [m_context release];
}
-void QCocoaGLContext::doneCurrent()
+bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
{
- if (m_currentWindow && m_currentWindow.data()->handle())
- static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+ qCDebug(lcQpaOpenGLContext) << "Making" << m_context << "current"
+ << "in" << QThread::currentThread() << "for" << surface;
+
+ Q_ASSERT(surface->surface()->supportsOpenGL());
- m_currentWindow.clear();
+ if (!setDrawable(surface))
+ return false;
- [NSOpenGLContext clearCurrentContext];
+ [m_context makeCurrentContext];
+
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ // Disable high-resolution surfaces when using the software renderer, which has the
+ // problem that the system silently falls back to a to using a low-resolution buffer
+ // when a high-resolution buffer is requested. This is not detectable using the NSWindow
+ // convertSizeToBacking and backingScaleFactor APIs. A typical result of this is that Qt
+ // will display a quarter of the window content when running in a virtual machine.
+ if (!m_didCheckForSoftwareContext) {
+ // FIXME: This ensures we check only once per context,
+ // but the context may be used for multiple surfaces.
+ m_didCheckForSoftwareContext = true;
+
+ const GLubyte* renderer = glGetString(GL_RENDERER);
+ if (qstrcmp((const char *)renderer, "Apple Software Renderer") == 0) {
+ NSView *view = static_cast<QCocoaWindow *>(surface)->m_view;
+ [view setWantsBestResolutionOpenGLSurface:NO];
+ }
+ }
+
+ update();
+ }
+
+ return true;
}
-QFunctionPointer QCocoaGLContext::getProcAddress(const char *procName)
+/*!
+ Sets the drawable object of the NSOpenGLContext, which is the
+ frame buffer that is the target of OpenGL drawing operations.
+*/
+bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
{
- return (QFunctionPointer)dlsym(RTLD_DEFAULT, procName);
+ // Make sure any surfaces released during this process are deallocated
+ // straight away, otherwise we may run out of surfaces when spinning a
+ // render-loop that doesn't return to one of the outer pools.
+ QMacAutoReleasePool pool;
+
+ if (!surface || surface->surface()->surfaceClass() == QSurface::Offscreen) {
+ // Clear the current drawable and reset the active window, so that GL
+ // commands that don't target a specific FBO will not end up stomping
+ // on the previously set drawable.
+ qCDebug(lcQpaOpenGLContext) << "Clearing current drawable" << m_context.view << "for" << m_context;
+ [m_context clearDrawable];
+ return true;
+ }
+
+ Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window);
+ QNSView *view = qnsview_cast(static_cast<QCocoaWindow *>(surface)->view());
+
+ if (view == m_context.view)
+ return true;
+
+ if ((m_context.view = view) != view) {
+ qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context;
+ return false;
+ }
+
+ qCInfo(lcQpaOpenGLContext) << "Set drawable for" << m_context << "to" << m_context.view;
+
+ return true;
}
+// NSOpenGLContext is not re-entrant. Even when using separate contexts per thread,
+// view, and window, calls into the API will still deadlock. For more information
+// see https://openradar.appspot.com/37064579
+static QMutex s_reentrancyMutex;
+
void QCocoaGLContext::update()
{
- QMutexLocker locker(&s_contextMutex);
+ // Make sure any surfaces released during this process are deallocated
+ // straight away, otherwise we may run out of surfaces when spinning a
+ // render-loop that doesn't return to one of the outer pools.
+ QMacAutoReleasePool pool;
+
+ QMutexLocker locker(&s_reentrancyMutex);
+ qCInfo(lcQpaOpenGLContext) << "Updating" << m_context << "for" << m_context.view;
[m_context update];
}
-NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat(const QSurfaceFormat &format)
+void QCocoaGLContext::swapBuffers(QPlatformSurface *surface)
{
- QVector<NSOpenGLPixelFormatAttribute> attrs;
-
- if (format.swapBehavior() == QSurfaceFormat::DoubleBuffer
- || format.swapBehavior() == QSurfaceFormat::DefaultSwapBehavior)
- attrs.append(NSOpenGLPFADoubleBuffer);
- else if (format.swapBehavior() == QSurfaceFormat::TripleBuffer)
- attrs.append(NSOpenGLPFATripleBuffer);
-
-
- // Select OpenGL profile
- attrs << NSOpenGLPFAOpenGLProfile;
- if (format.profile() == QSurfaceFormat::CoreProfile) {
- if (format.version() >= qMakePair(4, 1))
- attrs << NSOpenGLProfileVersion4_1Core;
- else if (format.version() >= qMakePair(3, 2))
- attrs << NSOpenGLProfileVersion3_2Core;
- else
- attrs << NSOpenGLProfileVersionLegacy;
- } else {
- attrs << NSOpenGLProfileVersionLegacy;
- }
+ qCDebug(lcQpaOpenGLContext) << "Swapping" << m_context
+ << "in" << QThread::currentThread() << "to" << surface;
- if (format.depthBufferSize() > 0)
- attrs << NSOpenGLPFADepthSize << format.depthBufferSize();
- if (format.stencilBufferSize() > 0)
- attrs << NSOpenGLPFAStencilSize << format.stencilBufferSize();
- if (format.alphaBufferSize() > 0)
- attrs << NSOpenGLPFAAlphaSize << format.alphaBufferSize();
- if ((format.redBufferSize() > 0) &&
- (format.greenBufferSize() > 0) &&
- (format.blueBufferSize() > 0)) {
- const int colorSize = format.redBufferSize() +
- format.greenBufferSize() +
- format.blueBufferSize();
- attrs << NSOpenGLPFAColorSize << colorSize << NSOpenGLPFAMinimumPolicy;
- }
+ if (surface->surface()->surfaceClass() == QSurface::Offscreen)
+ return; // Nothing to do
- if (format.samples() > 0) {
- attrs << NSOpenGLPFAMultisample
- << NSOpenGLPFASampleBuffers << (NSOpenGLPixelFormatAttribute) 1
- << NSOpenGLPFASamples << (NSOpenGLPixelFormatAttribute) format.samples();
+ if (!setDrawable(surface)) {
+ qCWarning(lcQpaOpenGLContext) << "Can't flush" << m_context
+ << "without" << surface << "as drawable";
+ return;
}
- if (format.stereo())
- attrs << NSOpenGLPFAStereo;
-
- attrs << NSOpenGLPFAAllowOfflineRenderers;
+ QMutexLocker locker(&s_reentrancyMutex);
+ [m_context flushBuffer];
+}
- QByteArray useLayer = qgetenv("QT_MAC_WANTS_LAYER");
- if (!useLayer.isEmpty() && useLayer.toInt() > 0) {
- // Disable the software rendering fallback. This makes compositing
- // OpenGL and raster NSViews using Core Animation layers possible.
- attrs << NSOpenGLPFANoRecovery;
- }
+void QCocoaGLContext::doneCurrent()
+{
+ qCDebug(lcQpaOpenGLContext) << "Clearing current context"
+ << [NSOpenGLContext currentContext] << "in" << QThread::currentThread();
- attrs << 0;
+ // Note: We do not need to clear the current drawable here.
+ // As long as there is no current context, GL calls will
+ // do nothing.
- return [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs.constData()];
+ [NSOpenGLContext clearCurrentContext];
}
-NSOpenGLContext *QCocoaGLContext::nsOpenGLContext() const
+QSurfaceFormat QCocoaGLContext::format() const
{
- return m_context;
+ return m_format;
}
bool QCocoaGLContext::isValid() const
@@ -485,5 +455,14 @@ bool QCocoaGLContext::isSharing() const
return m_shareContext != nil;
}
-QT_END_NAMESPACE
+NSOpenGLContext *QCocoaGLContext::nativeContext() const
+{
+ return m_context;
+}
+QFunctionPointer QCocoaGLContext::getProcAddress(const char *procName)
+{
+ return (QFunctionPointer)dlsym(RTLD_DEFAULT, procName);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 84632c1487..953bf331bb 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -62,25 +62,33 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSView));
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(lcQpaCocoaWindow)
-Q_DECLARE_LOGGING_CATEGORY(lcQpaCocoaDrawing)
-Q_DECLARE_LOGGING_CATEGORY(lcQpaCocoaMouse)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaDrawing)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaMouse)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen)
class QPixmap;
class QString;
// Conversion functions
-QStringList qt_mac_NSArrayToQStringList(void *nsarray);
-void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list);
-
-inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist)
-{ return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); }
+QStringList qt_mac_NSArrayToQStringList(NSArray<NSString *> *nsarray);
+NSMutableArray<NSString *> *qt_mac_QStringListToNSMutableArray(const QStringList &list);
NSDragOperation qt_mac_mapDropAction(Qt::DropAction action);
NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions);
Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions);
Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions);
+template <typename T>
+typename std::enable_if<std::is_pointer<T>::value, T>::type
+qt_objc_cast(id object)
+{
+ if ([object isKindOfClass:[typename std::remove_pointer<T>::type class]])
+ return static_cast<T>(object);
+
+ return nil;
+}
+
QT_MANGLE_NAMESPACE(QNSView) *qnsview_cast(NSView *view);
// Misc
@@ -91,6 +99,12 @@ QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference);
QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference);
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum);
+Qt::MouseButton cocoaButton2QtButton(NSEvent *event);
+
+QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event);
+
+Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons);
+Qt::MouseButtons currentlyPressedMouseButtons();
// strip out '&' characters, and convert "&&" to a single '&', in menu
// text - since menu text is sometimes decorated with these for Windows
@@ -170,12 +184,7 @@ QT_END_NAMESPACE
- (void)onCancelClicked;
@end
-@interface QT_MANGLE_NAMESPACE(QNSPanelContentsWrapper) : NSView {
- NSButton *_okButton;
- NSButton *_cancelButton;
- NSView *_panelContents;
- NSEdgeInsets _panelContentsMargins;
-}
+@interface QT_MANGLE_NAMESPACE(QNSPanelContentsWrapper) : NSView
@property (nonatomic, readonly) NSButton *okButton;
@property (nonatomic, readonly) NSButton *cancelButton;
@@ -187,6 +196,7 @@ QT_END_NAMESPACE
- (NSButton *)createButtonWithTitle:(const char *)title;
- (void)layout;
+
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSPanelContentsWrapper);
@@ -285,26 +295,17 @@ public:
}
private:
- template <std::size_t... Ts>
- struct index {};
-
- template <std::size_t N, std::size_t... Ts>
- struct gen_seq : gen_seq<N - 1, N - 1, Ts...> {};
-
- template <std::size_t... Ts>
- struct gen_seq<0, Ts...> : index<Ts...> {};
-
template <typename ReturnType, bool V>
using if_requires_stret = typename std::enable_if<objc_msgsend_requires_stret<ReturnType>::value == V, ReturnType>::type;
- template <typename ReturnType, std::size_t... Is>
- if_requires_stret<ReturnType, false> msgSendSuper(std::tuple<Args...>& args, index<Is...>)
+ template <typename ReturnType, int... Is>
+ if_requires_stret<ReturnType, false> msgSendSuper(std::tuple<Args...>& args, QtPrivate::IndexesList<Is...>)
{
return qt_msgSendSuper<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...);
}
- template <typename ReturnType, std::size_t... Is>
- if_requires_stret<ReturnType, true> msgSendSuper(std::tuple<Args...>& args, index<Is...>)
+ template <typename ReturnType, int... Is>
+ if_requires_stret<ReturnType, true> msgSendSuper(std::tuple<Args...>& args, QtPrivate::IndexesList<Is...>)
{
return qt_msgSendSuper_stret<ReturnType>(m_receiver, m_selector, std::get<Is>(args)...);
}
@@ -312,7 +313,7 @@ private:
template <typename ReturnType>
ReturnType msgSendSuper(std::tuple<Args...>& args)
{
- return msgSendSuper<ReturnType>(args, gen_seq<sizeof...(Args)>{});
+ return msgSendSuper<ReturnType>(args, QtPrivate::makeIndexSequence<sizeof...(Args)>{});
}
id m_receiver;
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index e5954f277c..0f5ddfa49a 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -57,29 +57,28 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcQpaCocoaWindow, "qt.qpa.cocoa.window");
-Q_LOGGING_CATEGORY(lcQpaCocoaDrawing, "qt.qpa.cocoa.drawing");
-Q_LOGGING_CATEGORY(lcQpaCocoaMouse, "qt.qpa.cocoa.mouse");
+Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
+Q_LOGGING_CATEGORY(lcQpaDrawing, "qt.qpa.drawing");
+Q_LOGGING_CATEGORY(lcQpaMouse, "qt.qpa.input.mouse");
+Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen");
//
// Conversion Functions
//
-QStringList qt_mac_NSArrayToQStringList(void *nsarray)
+QStringList qt_mac_NSArrayToQStringList(NSArray<NSString *> *array)
{
QStringList result;
- NSArray *array = static_cast<NSArray *>(nsarray);
- for (NSUInteger i=0; i<[array count]; ++i)
- result << QString::fromNSString([array objectAtIndex:i]);
+ for (NSString *string in array)
+ result << QString::fromNSString(string);
return result;
}
-void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
+NSMutableArray<NSString *> *qt_mac_QStringListToNSMutableArray(const QStringList &list)
{
- NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()];
- for (int i=0; i<list.size(); ++i){
- [result addObject:list[i].toNSString()];
- }
+ NSMutableArray<NSString *> *result = [NSMutableArray<NSString *> arrayWithCapacity:list.size()];
+ for (const QString &string : list)
+ [result addObject:string.toNSString()];
return result;
}
@@ -93,6 +92,7 @@ struct dndenum_mapper
static dndenum_mapper dnd_enums[] = {
{ NSDragOperationLink, Qt::LinkAction, true },
{ NSDragOperationMove, Qt::MoveAction, true },
+ { NSDragOperationDelete, Qt::MoveAction, true },
{ NSDragOperationCopy, Qt::CopyAction, true },
{ NSDragOperationGeneric, Qt::CopyAction, false },
{ NSDragOperationEvery, Qt::ActionMask, false },
@@ -161,10 +161,7 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
*/
QNSView *qnsview_cast(NSView *view)
{
- if (![view isKindOfClass:[QNSView class]])
- return nil;
-
- return static_cast<QNSView *>(view);
+ return qt_objc_cast<QNSView *>(view);
}
//
@@ -282,6 +279,90 @@ Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
return Qt::NoButton;
}
+/*!
+ \fn Qt::MouseButton cocoaButton2QtButton(NSEvent *event)
+
+ Returns the Qt::Button that corresponds to an NSEvent.buttonNumber.
+
+ \note AppKit will use buttonNumber 0 to indicate both "left button"
+ and "no button". Only NSEvents that describes mouse press/release/dragging
+ events (e.g NSEventTypeOtherMouseDown) will contain a valid
+ button number.
+
+ \note Wacom tablet might not return the correct button number for NSEvent buttonNumber
+ on right clicks. Decide here that the button is the "right" button.
+*/
+Qt::MouseButton cocoaButton2QtButton(NSEvent *event)
+{
+ switch (event.type) {
+ case NSEventTypeMouseMoved:
+ return Qt::NoButton;
+
+ case NSEventTypeRightMouseUp:
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeRightMouseDragged:
+ return Qt::RightButton;
+
+ default:
+ break;
+ }
+
+ return cocoaButton2QtButton(event.buttonNumber);
+}
+
+/*!
+ \fn QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event)
+
+ Returns the QEvent::Type that corresponds to an NSEvent.type.
+*/
+QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event)
+{
+ switch (event.type) {
+ case NSEventTypeLeftMouseDown:
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeOtherMouseDown:
+ return QEvent::MouseButtonPress;
+
+ case NSEventTypeLeftMouseUp:
+ case NSEventTypeRightMouseUp:
+ case NSEventTypeOtherMouseUp:
+ return QEvent::MouseButtonRelease;
+
+ case NSEventTypeLeftMouseDragged:
+ case NSEventTypeRightMouseDragged:
+ case NSEventTypeOtherMouseDragged:
+ return QEvent::MouseMove;
+
+ case NSEventTypeMouseMoved:
+ return QEvent::MouseMove;
+
+ default:
+ break;
+ }
+
+ return QEvent::None;
+}
+
+/*!
+ \fn Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons)
+
+ Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
+*/
+Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons)
+{
+ return static_cast<Qt::MouseButton>(pressedMouseButtons & Qt::MouseButtonMask);
+}
+
+/*!
+ \fn Qt::MouseButtons currentlyPressedMouseButtons()
+
+ Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
+*/
+Qt::MouseButtons currentlyPressedMouseButtons()
+{
+ return cocoaMouseButtons2QtMouseButtons(NSEvent.pressedMouseButtons);
+}
+
QString qt_mac_removeAmpersandEscapes(QString s)
{
return QPlatformTheme::removeMnemonics(s).trimmed();
@@ -298,7 +379,12 @@ QT_END_NAMESPACE
the target-action for the OK/Cancel buttons and making
sure the layout is consistent.
*/
-@implementation QNSPanelContentsWrapper
+@implementation QNSPanelContentsWrapper {
+ NSButton *_okButton;
+ NSButton *_cancelButton;
+ NSView *_panelContents;
+ NSEdgeInsets _panelContentsMargins;
+}
@synthesize okButton = _okButton;
@synthesize cancelButton = _cancelButton;
@@ -346,7 +432,7 @@ QT_END_NAMESPACE
// FIXME: Not obvious, from Cocoa's documentation, that QString::toNSString() makes a deep copy
button.title = (NSString *)cleanTitle.toCFString();
((NSButtonCell *)button.cell).font =
- [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
+ [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeRegular]];
[self addSubview:button];
return button;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 301771fd53..7de7e073de 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -51,6 +51,9 @@
#include "qcocoadrag.h"
#include "qcocoaservices.h"
#include "qcocoakeymapper.h"
+#if QT_CONFIG(vulkan)
+#include "qcocoavulkaninstance.h"
+#endif
#include <QtCore/QScopedPointer>
#include <qpa/qplatformintegration.h>
@@ -86,6 +89,11 @@ public:
QAbstractEventDispatcher *createEventDispatcher() const override;
+#if QT_CONFIG(vulkan)
+ QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override;
+ QCocoaVulkanInstance *getCocoaVulkanInstance() const;
+#endif
+
QCoreTextFontDatabase *fontDatabase() const override;
QCocoaNativeInterface *nativeInterface() const override;
QPlatformInputContext *inputContext() const override;
@@ -144,6 +152,9 @@ private:
QScopedPointer<QCocoaServices> mServices;
QScopedPointer<QCocoaKeyMapper> mKeyboardMapper;
+#if QT_CONFIG(vulkan)
+ mutable QCocoaVulkanInstance *mCocoaVulkanInstance = nullptr;
+#endif
QHash<QWindow *, NSToolbar *> mToolbars;
QList<QCocoaWindow *> m_popupWindowStack;
};
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 55b3805df3..612290c9bd 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -59,6 +59,8 @@
#include <qpa/qplatformoffscreensurface.h>
#include <QtCore/qcoreapplication.h>
+#include <QtPlatformHeaders/qcocoanativecontext.h>
+
#include <QtGui/private/qcoregraphics_p.h>
#ifdef QT_WIDGETS_LIB
@@ -94,11 +96,11 @@ static QCocoaIntegration::Options parseOptions(const QStringList &paramList)
return options;
}
-QCocoaIntegration *QCocoaIntegration::mInstance = 0;
+QCocoaIntegration *QCocoaIntegration::mInstance = nullptr;
QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
: mOptions(parseOptions(paramList))
- , mFontDb(0)
+ , mFontDb(nullptr)
#ifndef QT_NO_ACCESSIBILITY
, mAccessibility(new QCocoaAccessibility)
#endif
@@ -110,7 +112,7 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
, mServices(new QCocoaServices)
, mKeyboardMapper(new QCocoaKeyMapper)
{
- if (mInstance != 0)
+ if (mInstance)
qWarning("Creating multiple Cocoa platform integrations is not supported");
mInstance = this;
@@ -186,7 +188,7 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
QCocoaIntegration::~QCocoaIntegration()
{
- mInstance = 0;
+ mInstance = nullptr;
qt_resetNSApplicationSendEvent();
@@ -196,7 +198,7 @@ QCocoaIntegration::~QCocoaIntegration()
QCocoaApplicationDelegate *delegate = [QCocoaApplicationDelegate sharedDelegate];
[delegate removeAppleEventHandlers];
// reset the application delegate
- [[NSApplication sharedApplication] setDelegate: 0];
+ [[NSApplication sharedApplication] setDelegate:nil];
}
#ifndef QT_NO_CLIPBOARD
@@ -225,15 +227,13 @@ QCocoaIntegration::Options QCocoaIntegration::options() const
return mOptions;
}
-Q_LOGGING_CATEGORY(lcCocoaScreen, "qt.qpa.cocoa.screens");
-
/*!
\brief Synchronizes the screen list, adds new screens, removes deleted ones
*/
void QCocoaIntegration::updateScreens()
{
- NSArray *scrs = [NSScreen screens];
- NSMutableArray *screens = [NSMutableArray arrayWithArray:scrs];
+ NSArray<NSScreen *> *scrs = [NSScreen screens];
+ NSMutableArray<NSScreen *> *screens = [NSMutableArray<NSScreen *> arrayWithArray:scrs];
if ([screens count] == 0)
if ([NSScreen mainScreen])
[screens addObject:[NSScreen mainScreen]];
@@ -244,7 +244,7 @@ void QCocoaIntegration::updateScreens()
uint screenCount = [screens count];
for (uint i = 0; i < screenCount; i++) {
NSScreen* scr = [screens objectAtIndex:i];
- CGDirectDisplayID dpy = [[[scr deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
+ CGDirectDisplayID dpy = scr.qt_displayId;
// If this screen is a mirror and is not the primary one of the mirror set, ignore it.
// Exception: The NSScreen API has been observed to a return a screen list with one
// mirrored, non-primary screen when Qt is running as a startup item. Always use the
@@ -254,8 +254,8 @@ void QCocoaIntegration::updateScreens()
if (primary != kCGNullDirectDisplay && primary != dpy)
continue;
}
- QCocoaScreen* screen = NULL;
- foreach (QCocoaScreen* existingScr, mScreens)
+ QCocoaScreen* screen = nullptr;
+ foreach (QCocoaScreen* existingScr, mScreens) {
// NSScreen documentation says do not cache the array returned from [NSScreen screens].
// However in practice, we can identify a screen by its pointer: if resolution changes,
// the NSScreen object will be the same instance, just with different values.
@@ -263,14 +263,14 @@ void QCocoaIntegration::updateScreens()
screen = existingScr;
break;
}
+ }
if (screen) {
remainingScreens.remove(screen);
- screen->updateGeometry();
- qCDebug(lcCocoaScreen) << "Updated properties of" << screen;
+ screen->updateProperties();
} else {
screen = new QCocoaScreen(i);
mScreens.append(screen);
- qCDebug(lcCocoaScreen) << "Adding" << screen;
+ qCDebug(lcQpaScreen) << "Adding" << screen;
screenAdded(screen);
}
siblings << screen;
@@ -287,7 +287,7 @@ void QCocoaIntegration::updateScreens()
mScreens.removeOne(screen);
// Prevent stale references to NSScreen during destroy
screen->m_screenIndex = -1;
- qCDebug(lcCocoaScreen) << "Removing" << screen;
+ qCDebug(lcQpaScreen) << "Removing" << screen;
destroyScreen(screen);
}
}
@@ -296,7 +296,7 @@ QCocoaScreen *QCocoaIntegration::screenForNSScreen(NSScreen *nsScreen)
{
NSUInteger index = [[NSScreen screens] indexOfObject:nsScreen];
if (index == NSNotFound)
- return 0;
+ return nullptr;
if (index >= unsigned(mScreens.count()))
updateScreens();
@@ -306,7 +306,7 @@ QCocoaScreen *QCocoaIntegration::screenForNSScreen(NSScreen *nsScreen)
return screen;
}
- return 0;
+ return nullptr;
}
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -361,10 +361,8 @@ QPlatformOffscreenSurface *QCocoaIntegration::createPlatformOffscreenSurface(QOf
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- QCocoaGLContext *glContext = new QCocoaGLContext(context->format(),
- context->shareHandle(),
- context->nativeHandle());
- context->setNativeHandle(glContext->nativeHandle());
+ QCocoaGLContext *glContext = new QCocoaGLContext(context);
+ context->setNativeHandle(QVariant::fromValue<QCocoaNativeContext>(glContext->nativeContext()));
return glContext;
}
#endif
@@ -379,6 +377,19 @@ QAbstractEventDispatcher *QCocoaIntegration::createEventDispatcher() const
return new QCocoaEventDispatcher;
}
+#if QT_CONFIG(vulkan)
+QPlatformVulkanInstance *QCocoaIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
+{
+ mCocoaVulkanInstance = new QCocoaVulkanInstance(instance);
+ return mCocoaVulkanInstance;
+}
+
+QCocoaVulkanInstance *QCocoaIntegration::getCocoaVulkanInstance() const
+{
+ return mCocoaVulkanInstance;
+}
+#endif
+
QCoreTextFontDatabase *QCocoaIntegration::fontDatabase() const
{
return mFontDb.data();
@@ -480,14 +491,14 @@ void QCocoaIntegration::pushPopupWindow(QCocoaWindow *window)
QCocoaWindow *QCocoaIntegration::popPopupWindow()
{
if (m_popupWindowStack.isEmpty())
- return 0;
+ return nullptr;
return m_popupWindowStack.takeLast();
}
QCocoaWindow *QCocoaIntegration::activePopupWindow() const
{
if (m_popupWindowStack.isEmpty())
- return 0;
+ return nullptr;
return m_popupWindowStack.front();
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintrospection.h b/src/plugins/platforms/cocoa/qcocoaintrospection.h
index 1d984b9857..20001ac71d 100644
--- a/src/plugins/platforms/cocoa/qcocoaintrospection.h
+++ b/src/plugins/platforms/cocoa/qcocoaintrospection.h
@@ -76,7 +76,7 @@
QT_BEGIN_NAMESPACE
-void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class proxyClass, SEL replacementSel = 0, SEL backupSel = 0);
+void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class proxyClass, SEL replacementSel = nil, SEL backupSel = nil);
void qt_cocoa_change_back_implementation(Class baseClass, SEL originalSel, SEL backupSel);
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
index 80140505d1..5e279a400b 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
@@ -352,22 +352,22 @@ QCocoaKeyMapper::~QCocoaKeyMapper()
Qt::KeyboardModifiers QCocoaKeyMapper::queryKeyboardModifiers()
{
- return qt_mac_get_modifiers(GetCurrentEventKeyModifiers());
+ return qt_mac_get_modifiers(GetCurrentKeyModifiers());
}
bool QCocoaKeyMapper::updateKeyboard()
{
- const UCKeyboardLayout *uchrData = 0;
+ const UCKeyboardLayout *uchrData = nullptr;
QCFType<TISInputSourceRef> source = TISCopyInputMethodKeyboardLayoutOverride();
if (!source)
source = TISCopyCurrentKeyboardInputSource();
if (keyboard_mode != NullMode && source == currentInputSource) {
return false;
}
- Q_ASSERT(source != 0);
+ Q_ASSERT(source);
CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(source,
kTISPropertyUnicodeKeyLayoutData));
- uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
+ uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : nullptr;
keyboard_kind = LMGetKbdType();
if (uchrData) {
@@ -386,7 +386,7 @@ void QCocoaKeyMapper::deleteLayouts()
for (int i = 0; i < 255; ++i) {
if (keyLayout[i]) {
delete keyLayout[i];
- keyLayout[i] = 0;
+ keyLayout[i] = nullptr;
}
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 6db4e04c61..34d8428188 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index a788ac7d45..7b96fca3f9 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@@ -53,7 +54,7 @@
QT_BEGIN_NAMESPACE
QCocoaMenu::QCocoaMenu() :
- m_attachedItem(0),
+ m_attachedItem(nil),
m_updateTimer(0),
m_enabled(true),
m_parentEnabled(true),
@@ -62,14 +63,14 @@ QCocoaMenu::QCocoaMenu() :
{
QMacAutoReleasePool pool;
- m_nativeMenu = [[QCocoaNSMenu alloc] initWithQPAMenu:this];
+ m_nativeMenu = [[QCocoaNSMenu alloc] initWithPlatformMenu:this];
}
QCocoaMenu::~QCocoaMenu()
{
- foreach (QCocoaMenuItem *item, m_menuItems) {
+ for (auto *item : qAsConst(m_menuItems)) {
if (item->menuParent() == this)
- item->setMenuParent(0);
+ item->setMenuParent(nullptr);
}
[m_nativeMenu release];
@@ -79,7 +80,7 @@ void QCocoaMenu::setText(const QString &text)
{
QMacAutoReleasePool pool;
QString stripped = qt_mac_removeAmpersandEscapes(text);
- [m_nativeMenu setTitle:stripped.toNSString()];
+ m_nativeMenu.title = stripped.toNSString();
}
void QCocoaMenu::setMinimumWidth(int width)
@@ -132,7 +133,7 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
{
- setItemTargetAction(item);
+ item->resolveTargetAction();
NSMenuItem *nativeItem = item->nsItem();
// Someone's adding new items after aboutToShow() was emitted
if (isOpen() && nativeItem && item->menu())
@@ -187,25 +188,25 @@ void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
}
if (cocoaItem->menuParent() == this)
- cocoaItem->setMenuParent(0);
+ cocoaItem->setMenuParent(nullptr);
// Ignore any parent enabled state
cocoaItem->setParentEnabled(true);
m_menuItems.removeOne(cocoaItem);
if (!cocoaItem->isMerged()) {
- if (m_nativeMenu != [cocoaItem->nsItem() menu]) {
+ if (m_nativeMenu != cocoaItem->nsItem().menu) {
qWarning("Item to remove does not belong to this menu");
return;
}
- [m_nativeMenu removeItem: cocoaItem->nsItem()];
+ [m_nativeMenu removeItem:cocoaItem->nsItem()];
}
}
QCocoaMenuItem *QCocoaMenu::itemOrNull(int index) const
{
if ((index < 0) || (index >= m_menuItems.size()))
- return 0;
+ return nullptr;
return m_menuItems.at(index);
}
@@ -247,8 +248,8 @@ void QCocoaMenu::syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUp
// native item was changed for some reason
if (oldItem) {
if (wasMerged) {
- [oldItem setEnabled:NO];
- [oldItem setHidden:YES];
+ oldItem.enabled = NO;
+ oldItem.hidden = YES;
} else {
[m_nativeMenu removeItem:oldItem];
}
@@ -278,31 +279,27 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable)
bool previousIsSeparator = true; // setting to true kills all the separators placed at the top.
NSMenuItem *previousItem = nil;
- NSArray *itemArray = [m_nativeMenu itemArray];
- for (unsigned int i = 0; i < [itemArray count]; ++i) {
- NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]);
- if ([item isSeparatorItem]) {
- QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
- if (cocoaItem)
+ for (NSMenuItem *item in m_nativeMenu.itemArray) {
+ if (item.separatorItem) {
+ if (auto *cocoaItem = qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem)
cocoaItem->setVisible(!previousIsSeparator);
- [item setHidden:previousIsSeparator];
+ item.hidden = previousIsSeparator;
}
- if (![item isHidden]) {
+ if (!item.hidden) {
previousItem = item;
- previousIsSeparator = ([previousItem isSeparatorItem]);
+ previousIsSeparator = previousItem.separatorItem;
}
}
// We now need to check the final item since we don't want any separators at the end of the list.
if (previousItem && previousIsSeparator) {
- QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([previousItem tag]);
- if (cocoaItem)
+ if (auto *cocoaItem = qt_objc_cast<QCocoaNSMenuItem *>(previousItem).platformMenuItem)
cocoaItem->setVisible(false);
- [previousItem setHidden:YES];
+ previousItem.hidden = YES;
}
} else {
- foreach (QCocoaMenuItem *item, m_menuItems) {
+ for (auto *item : qAsConst(m_menuItems)) {
if (!item->isSeparator())
continue;
@@ -324,7 +321,7 @@ void QCocoaMenu::setEnabled(bool enabled)
bool QCocoaMenu::isEnabled() const
{
- return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled && m_parentEnabled;
+ return m_attachedItem ? m_attachedItem.enabled : m_enabled && m_parentEnabled;
}
void QCocoaMenu::setVisible(bool visible)
@@ -337,11 +334,11 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
QMacAutoReleasePool pool;
QPoint pos = QPoint(targetRect.left(), targetRect.top() + targetRect.height());
- QCocoaWindow *cocoaWindow = parentWindow ? static_cast<QCocoaWindow *>(parentWindow->handle()) : 0;
+ QCocoaWindow *cocoaWindow = parentWindow ? static_cast<QCocoaWindow *>(parentWindow->handle()) : nullptr;
NSView *view = cocoaWindow ? cocoaWindow->view() : nil;
NSMenuItem *nsItem = item ? ((QCocoaMenuItem *)item)->nsItem() : nil;
- QScreen *screen = 0;
+ QScreen *screen = nullptr;
if (parentWindow)
screen = parentWindow->screen();
if (!screen && !QGuiApplication::screens().isEmpty())
@@ -360,9 +357,9 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
// respect the menu's minimum width.
NSPopUpButtonCell *popupCell = [[[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]
autorelease];
- [popupCell setAltersStateOfSelectedItem:NO];
- [popupCell setTransparent:YES];
- [popupCell setMenu:m_nativeMenu];
+ popupCell.altersStateOfSelectedItem = NO;
+ popupCell.transparent = YES;
+ popupCell.menu = m_nativeMenu;
[popupCell selectItem:nsItem];
QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(screen->handle());
@@ -394,7 +391,7 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
if (view) {
// Finally, we need to synthesize an event.
- NSEvent *menuEvent = [NSEvent mouseEventWithType:NSRightMouseDown
+ NSEvent *menuEvent = [NSEvent mouseEventWithType:NSEventTypeRightMouseDown
location:nsPos
modifierFlags:0
timestamp:0
@@ -405,7 +402,7 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
pressure:1.0];
[NSMenu popUpContextMenu:m_nativeMenu withEvent:menuEvent forView:view];
} else {
- [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:0];
+ [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:nil];
}
}
@@ -425,17 +422,17 @@ QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const
if (0 <= position && position < m_menuItems.count())
return m_menuItems.at(position);
- return 0;
+ return nullptr;
}
QPlatformMenuItem *QCocoaMenu::menuItemForTag(quintptr tag) const
{
- foreach (QCocoaMenuItem *item, m_menuItems) {
+ for (auto *item : qAsConst(m_menuItems)) {
if (item->tag() == tag)
return item;
}
- return 0;
+ return nullptr;
}
QList<QCocoaMenuItem *> QCocoaMenu::items() const
@@ -446,7 +443,7 @@ QList<QCocoaMenuItem *> QCocoaMenu::items() const
QList<QCocoaMenuItem *> QCocoaMenu::merged() const
{
QList<QCocoaMenuItem *> result;
- foreach (QCocoaMenuItem *item, m_menuItems) {
+ for (auto *item : qAsConst(m_menuItems)) {
if (item->menu()) { // recurse into submenus
result.append(item->menu()->merged());
continue;
@@ -467,7 +464,7 @@ void QCocoaMenu::propagateEnabledState(bool enabled)
if (!m_enabled && enabled) // Some ancestor was enabled, but this menu is not
return;
- foreach (QCocoaMenuItem *item, m_menuItems) {
+ for (auto *item : qAsConst(m_menuItems)) {
if (QCocoaMenu *menu = item->menu())
menu->propagateEnabledState(enabled);
else
@@ -495,11 +492,4 @@ NSMenuItem *QCocoaMenu::attachedItem() const
return m_attachedItem;
}
-void QCocoaMenu::setItemTargetAction(QCocoaMenuItem *item) const
-{
- auto *nsItem = item->nsItem();
- nsItem.target = m_nativeMenu;
- nsItem.action = @selector(qt_itemFired:);
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h
index 6f3aca3a51..50b6e69720 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.h
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@@ -60,17 +60,16 @@ public:
void removeMenu(QPlatformMenu *menu) override;
void syncMenu(QPlatformMenu *menuItem) override;
void handleReparent(QWindow *newParentWindow) override;
+ QWindow *parentWindow() const override;
QPlatformMenu *menuForTag(quintptr tag) const override;
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
- static void redirectKnownMenuItemsToFirstResponder();
- static void resetKnownMenuItemsToQt();
static void updateMenuBarImmediately();
QList<QCocoaMenuItem*> merged() const;
- NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r);
+ NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole role);
QCocoaWindow *cocoaWindow() const;
void syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate);
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 61ac5eb7f0..30bff78a36 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@@ -67,7 +68,7 @@ QCocoaMenuBar::~QCocoaMenuBar()
#ifdef QT_COCOA_ENABLE_MENU_DEBUG
qDebug() << "~QCocoaMenuBar" << this;
#endif
- foreach (QCocoaMenu *menu, m_menus) {
+ for (auto menu : qAsConst(m_menus)) {
if (!menu)
continue;
NSMenuItem *item = nativeItemForMenu(menu);
@@ -79,14 +80,13 @@ QCocoaMenuBar::~QCocoaMenuBar()
static_menubars.removeOne(this);
if (!m_window.isNull() && m_window->menubar() == this) {
- m_window->setMenubar(0);
+ m_window->setMenubar(nullptr);
// Delete the children first so they do not cause
// the native menu items to be hidden after
// the menu bar was updated
qDeleteAll(children());
updateMenuBarImmediately();
- resetKnownMenuItemsToQt();
}
}
@@ -199,8 +199,8 @@ void QCocoaMenuBar::syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate)
// If the NSMenu has no visble items, or only separators, we should hide it
// on the menubar. This can happen after syncing the menu items since they
// can be moved to other menus.
- for (NSMenuItem *item in [cocoaMenu->nsMenu() itemArray])
- if (![item isSeparatorItem] && ![item isHidden]) {
+ for (NSMenuItem *item in cocoaMenu->nsMenu().itemArray)
+ if (!item.separatorItem && !item.hidden) {
shouldHide = NO;
break;
}
@@ -230,7 +230,7 @@ void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
if (!m_window.isNull())
m_window->setMenubar(nullptr);
- if (newParentWindow == nullptr) {
+ if (!newParentWindow) {
m_window.clear();
} else {
newParentWindow->create();
@@ -241,82 +241,28 @@ void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
updateMenuBarImmediately();
}
+QWindow *QCocoaMenuBar::parentWindow() const
+{
+ return m_window ? m_window->window() : nullptr;
+}
+
+
QCocoaWindow *QCocoaMenuBar::findWindowForMenubar()
{
if (qApp->focusWindow())
return static_cast<QCocoaWindow*>(qApp->focusWindow()->handle());
- return NULL;
+ return nullptr;
}
QCocoaMenuBar *QCocoaMenuBar::findGlobalMenubar()
{
- foreach (QCocoaMenuBar *mb, static_menubars) {
- if (mb->m_window.isNull())
- return mb;
+ for (auto *menubar : qAsConst(static_menubars)) {
+ if (menubar->m_window.isNull())
+ return menubar;
}
- return NULL;
-}
-
-void QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder()
-{
- // QTBUG-17291: http://forums.macrumors.com/showthread.php?t=1249452
- // When a dialog is opened, shortcuts for actions inside the dialog (cut, paste, ...)
- // continue to go through the same menu items which claimed those shortcuts.
- // They are not keystrokes which we can intercept in any other way; the OS intercepts them.
- // The menu items had to be created by the application. That's why we need roles
- // to identify those "special" menu items which can be useful even when non-Qt
- // native widgets are in focus. When the native widget is focused it will be the
- // first responder, so the menu item needs to have its target be the first responder;
- // this is done by setting it to nil.
-
- // This function will find all menu items on all menus which have
- // "special" roles, set the target and also set the standard actions which
- // apply to those roles. But afterwards it is necessary to call
- // resetKnownMenuItemsToQt() to put back the target and action so that
- // those menu items will go back to invoking their associated QActions.
- foreach (QCocoaMenuBar *mb, static_menubars)
- foreach (QCocoaMenu *m, mb->m_menus)
- foreach (QCocoaMenuItem *i, m->items()) {
- bool known = true;
- switch (i->effectiveRole()) {
- case QPlatformMenuItem::CutRole:
- [i->nsItem() setAction:@selector(cut:)];
- break;
- case QPlatformMenuItem::CopyRole:
- [i->nsItem() setAction:@selector(copy:)];
- break;
- case QPlatformMenuItem::PasteRole:
- [i->nsItem() setAction:@selector(paste:)];
- break;
- case QPlatformMenuItem::SelectAllRole:
- [i->nsItem() setAction:@selector(selectAll:)];
- break;
- // We may discover later that there are other roles/actions which
- // are meaningful to standard native widgets; they can be added.
- default:
- known = false;
- break;
- }
- if (known)
- [i->nsItem() setTarget:nil];
- }
-}
-
-void QCocoaMenuBar::resetKnownMenuItemsToQt()
-{
- // Undo the effect of redirectKnownMenuItemsToFirstResponder():
- // reset the menu items' target/action.
- foreach (QCocoaMenuBar *mb, static_menubars) {
- foreach (QCocoaMenu *m, mb->m_menus) {
- foreach (QCocoaMenuItem *i, m->items()) {
- if (i->effectiveRole() >= QPlatformMenuItem::ApplicationSpecificRole) {
- m->setItemTargetAction(i);
- }
- }
- }
- }
+ return nullptr;
}
void QCocoaMenuBar::updateMenuBarImmediately()
@@ -325,7 +271,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
QCocoaMenuBar *mb = findGlobalMenubar();
QCocoaWindow *cw = findWindowForMenubar();
- QWindow *win = cw ? cw->window() : 0;
+ QWindow *win = cw ? cw->window() : nullptr;
if (win && (win->flags() & Qt::Popup) == Qt::Popup) {
// context menus, comboboxes, etc. don't need to update the menubar,
// but if an application has only Qt::Tool window(s) on start,
@@ -353,7 +299,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
#endif
bool disableForModal = mb->shouldDisable(cw);
- foreach (QCocoaMenu *menu, mb->m_menus) {
+ for (auto menu : qAsConst(mb->m_menus)) {
if (!menu)
continue;
NSMenuItem *item = mb->nativeItemForMenu(menu);
@@ -368,16 +314,16 @@ void QCocoaMenuBar::updateMenuBarImmediately()
[loader ensureAppMenuInMenu:mb->nsMenu()];
NSMutableSet *mergedItems = [[NSMutableSet setWithCapacity:mb->merged().count()] retain];
- foreach (QCocoaMenuItem *m, mb->merged()) {
- [mergedItems addObject:m->nsItem()];
- m->syncMerged();
+ for (auto mergedItem : mb->merged()) {
+ [mergedItems addObject:mergedItem->nsItem()];
+ mergedItem->syncMerged();
}
// hide+disable all mergeable items we're not currently using
for (NSMenuItem *mergeable in [loader mergeable]) {
if (![mergedItems containsObject:mergeable]) {
- [mergeable setHidden:YES];
- [mergeable setEnabled:NO];
+ mergeable.hidden = YES;
+ mergeable.enabled = NO;
}
}
@@ -389,7 +335,7 @@ void QCocoaMenuBar::updateMenuBarImmediately()
QList<QCocoaMenuItem*> QCocoaMenuBar::merged() const
{
QList<QCocoaMenuItem*> r;
- foreach (QCocoaMenu* menu, m_menus)
+ for (auto menu : qAsConst(m_menus))
r.append(menu->merged());
return r;
@@ -409,11 +355,11 @@ bool QCocoaMenuBar::shouldDisable(QCocoaWindow *active) const
// When there is an application modal window on screen, the entries of
// the menubar should be disabled. The exception in Qt is that if the
// modal window is the only window on screen, then we enable the menu bar.
- foreach (QWindow *w, topWindows) {
- if (w->isVisible() && w->modality() == Qt::ApplicationModal) {
+ for (auto *window : qAsConst(topWindows)) {
+ if (window->isVisible() && window->modality() == Qt::ApplicationModal) {
// check for other visible windows
- foreach (QWindow *other, topWindows) {
- if ((w != other) && (other->isVisible())) {
+ for (auto *other : qAsConst(topWindows)) {
+ if ((window != other) && (other->isVisible())) {
// INVARIANT: we found another visible window
// on screen other than our modalWidget. We therefore
// disable the menu bar to follow normal modality logic:
@@ -433,21 +379,21 @@ bool QCocoaMenuBar::shouldDisable(QCocoaWindow *active) const
QPlatformMenu *QCocoaMenuBar::menuForTag(quintptr tag) const
{
- foreach (QCocoaMenu *menu, m_menus) {
+ for (auto menu : qAsConst(m_menus))
if (menu->tag() == tag)
return menu;
- }
- return 0;
+ return nullptr;
}
-NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r)
+NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole role)
{
- foreach (QCocoaMenu *m, m_menus)
- foreach (QCocoaMenuItem *i, m->items())
- if (i->effectiveRole() == r)
- return i->nsItem();
- return nullptr;
+ for (auto menu : qAsConst(m_menus))
+ for (auto *item : menu->items())
+ if (item->effectiveRole() == role)
+ return item->nsItem();
+
+ return nil;
}
QCocoaWindow *QCocoaMenuBar::cocoaWindow() const
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h
index 2b598ee3a0..20fc741fb8 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@@ -108,6 +108,7 @@ public:
QCocoaMenu *menu() const { return m_menu; }
MenuRole effectiveRole() const;
+ void resolveTargetAction();
private:
QString mergeText();
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index f8f9648822..21faa6d985 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author James Turner <james.turner@kdab.com>
** Contact: https://www.qt.io/licensing/
**
@@ -41,6 +42,7 @@
#include "qcocoamenuitem.h"
+#include "qcocoansmenu.h"
#include "qcocoamenu.h"
#include "qcocoamenubar.h"
#include "messages.h"
@@ -49,7 +51,6 @@
#include "qcocoaapplication.h" // for custom application category
#include "qcocoamenuloader.h"
#include <QtGui/private/qcoregraphics_p.h>
-#include <QtCore/qregularexpression.h>
#include <QtCore/QDebug>
@@ -60,13 +61,13 @@ static quint32 constructModifierMask(quint32 accel_key)
quint32 ret = 0;
const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
if ((accel_key & Qt::CTRL) == Qt::CTRL)
- ret |= (dontSwap ? NSControlKeyMask : NSCommandKeyMask);
+ ret |= (dontSwap ? NSEventModifierFlagControl : NSEventModifierFlagCommand);
if ((accel_key & Qt::META) == Qt::META)
- ret |= (dontSwap ? NSCommandKeyMask : NSControlKeyMask);
+ ret |= (dontSwap ? NSEventModifierFlagCommand : NSEventModifierFlagControl);
if ((accel_key & Qt::ALT) == Qt::ALT)
- ret |= NSAlternateKeyMask;
+ ret |= NSEventModifierFlagOption;
if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
- ret |= NSShiftKeyMask;
+ ret |= NSEventModifierFlagShift;
return ret;
}
@@ -92,9 +93,9 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel)
#endif
QCocoaMenuItem::QCocoaMenuItem() :
- m_native(NULL),
+ m_native(nil),
m_itemView(nil),
- m_menu(NULL),
+ m_menu(nullptr),
m_role(NoRole),
m_iconSize(16),
m_textSynced(false),
@@ -112,9 +113,9 @@ QCocoaMenuItem::~QCocoaMenuItem()
QMacAutoReleasePool pool;
if (m_menu && m_menu->menuParent() == this)
- m_menu->setMenuParent(0);
+ m_menu->setMenuParent(nullptr);
if (m_merged) {
- [m_native setHidden:YES];
+ m_native.hidden = YES;
} else {
if (m_menu && m_menu->attachedItem() == m_native)
m_menu->setAttachedItem(nil);
@@ -140,7 +141,7 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
return;
if (m_menu && m_menu->menuParent() == this) {
- m_menu->setMenuParent(0);
+ m_menu->setMenuParent(nullptr);
// Free the menu from its parent's influence
m_menu->propagateEnabledState(true);
if (m_native && m_menu->attachedItem() == m_native)
@@ -210,82 +211,75 @@ void QCocoaMenuItem::setNativeContents(WId item)
return;
[m_itemView release];
m_itemView = [itemView retain];
- [m_itemView setAutoresizesSubviews:YES];
- [m_itemView setAutoresizingMask:NSViewWidthSizable];
- [m_itemView setHidden:NO];
- [m_itemView setNeedsDisplay:YES];
+ m_itemView.autoresizesSubviews = YES;
+ m_itemView.autoresizingMask = NSViewWidthSizable;
+ m_itemView.hidden = NO;
+ m_itemView.needsDisplay = YES;
}
NSMenuItem *QCocoaMenuItem::sync()
{
- if (m_isSeparator != [m_native isSeparatorItem]) {
+ if (m_isSeparator != m_native.separatorItem) {
[m_native release];
- if (m_isSeparator) {
- m_native = [[NSMenuItem separatorItem] retain];
- [m_native setTag:reinterpret_cast<NSInteger>(this)];
- } else
+ if (m_isSeparator)
+ m_native = [[QCocoaNSMenuItem separatorItemWithPlatformMenuItem:this] retain];
+ else
m_native = nil;
}
if ((m_role != NoRole && !m_textSynced) || m_merged) {
- NSMenuItem *mergeItem = nil;
+ QCocoaMenuBar *menubar = nullptr;
+ if (m_role == TextHeuristicRole) {
+ // Recognized menu roles are only found in the first menus below the menubar
+ QObject *p = menuParent();
+ int depth = 1;
+ while (depth < 3 && p && !(menubar = qobject_cast<QCocoaMenuBar *>(p))) {
+ ++depth;
+ QCocoaMenuObject *menuObject = dynamic_cast<QCocoaMenuObject *>(p);
+ Q_ASSERT(menuObject);
+ p = menuObject->menuParent();
+ }
+
+ if (menubar && depth < 3)
+ m_detectedRole = detectMenuRole(m_text);
+ else
+ m_detectedRole = NoRole;
+ }
+
QCocoaMenuLoader *loader = [QCocoaMenuLoader sharedMenuLoader];
- switch (m_role) {
- case ApplicationSpecificRole:
- mergeItem = [loader appSpecificMenuItem:reinterpret_cast<NSInteger>(this)];
- break;
+ NSMenuItem *mergeItem = nil;
+ const auto role = effectiveRole();
+ switch (role) {
case AboutRole:
mergeItem = [loader aboutMenuItem];
break;
case AboutQtRole:
mergeItem = [loader aboutQtMenuItem];
break;
+ case PreferencesRole:
+ mergeItem = [loader preferencesMenuItem];
+ break;
+ case ApplicationSpecificRole:
+ mergeItem = [loader appSpecificMenuItem:this];
+ break;
case QuitRole:
mergeItem = [loader quitMenuItem];
break;
- case PreferencesRole:
- mergeItem = [loader preferencesMenuItem];
+ case CutRole:
+ case CopyRole:
+ case PasteRole:
+ case SelectAllRole:
+ if (menubar)
+ mergeItem = menubar->itemForRole(role);
break;
- case TextHeuristicRole: {
- QObject *p = menuParent();
- int depth = 1;
- QCocoaMenuBar *menubar = 0;
- while (depth < 3 && p && !(menubar = qobject_cast<QCocoaMenuBar *>(p))) {
- ++depth;
- QCocoaMenuObject *menuObject = dynamic_cast<QCocoaMenuObject *>(p);
- Q_ASSERT(menuObject);
- p = menuObject->menuParent();
- }
- if (depth == 3 || !menubar)
- break; // Menu item too deep in the hierarchy, or not connected to any menubar
-
- m_detectedRole = detectMenuRole(m_text);
- switch (m_detectedRole) {
- case QPlatformMenuItem::AboutRole:
- if (m_text.indexOf(QRegularExpression(QString::fromLatin1("qt$"),
- QRegularExpression::CaseInsensitiveOption)) == -1)
- mergeItem = [loader aboutMenuItem];
- else
- mergeItem = [loader aboutQtMenuItem];
- break;
- case QPlatformMenuItem::PreferencesRole:
- mergeItem = [loader preferencesMenuItem];
- break;
- case QPlatformMenuItem::QuitRole:
- mergeItem = [loader quitMenuItem];
- break;
- default:
- if (m_detectedRole >= CutRole && m_detectedRole < RoleCount && menubar)
- mergeItem = menubar->itemForRole(m_detectedRole);
- if (!m_text.isEmpty())
- m_textSynced = true;
- break;
- }
+ case NoRole:
+ // The heuristic couldn't resolve the menu role
+ m_textSynced = false;
break;
- }
-
default:
- qWarning() << "Menu item" << m_text << "has unsupported role" << m_role;
+ if (!m_text.isEmpty())
+ m_textSynced = true;
+ break;
}
if (mergeItem) {
@@ -294,7 +288,8 @@ NSMenuItem *QCocoaMenuItem::sync()
[mergeItem retain];
[m_native release];
m_native = mergeItem;
- [m_native setTag:reinterpret_cast<NSInteger>(this)];
+ if (auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(m_native))
+ nativeItem.platformMenuItem = this;
} else if (m_merged) {
// was previously merged, but no longer
[m_native release];
@@ -306,14 +301,14 @@ NSMenuItem *QCocoaMenuItem::sync()
}
if (!m_native) {
- m_native = [[NSMenuItem alloc] initWithTitle:m_text.toNSString()
- action:nil
- keyEquivalent:@""];
- [m_native setTag:reinterpret_cast<NSInteger>(this)];
+ m_native = [[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:this];
+ m_native.title = m_text.toNSString();
}
- [m_native setHidden: !m_isVisible];
- [m_native setView:m_itemView];
+ resolveTargetAction();
+
+ m_native.hidden = !m_isVisible;
+ m_native.view = m_itemView;
QString text = mergeText();
#ifndef QT_NO_SHORTCUT
@@ -331,39 +326,35 @@ NSMenuItem *QCocoaMenuItem::sync()
NSFont *customMenuFont = [NSFont fontWithName:m_font.family().toNSString()
size:m_font.pointSize()];
if (customMenuFont) {
- NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil];
- NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil];
- NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
NSAttributedString *str = [[[NSAttributedString alloc] initWithString:finalString.toNSString()
- attributes:attributes] autorelease];
- [m_native setAttributedTitle: str];
+ attributes:@{NSFontAttributeName: customMenuFont}] autorelease];
+ m_native.attributedTitle = str;
useAttributedTitle = true;
}
}
- if (!useAttributedTitle) {
- [m_native setTitle:finalString.toNSString()];
- }
+ if (!useAttributedTitle)
+ m_native.title = finalString.toNSString();
#ifndef QT_NO_SHORTCUT
if (accel.count() == 1) {
- [m_native setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
- [m_native setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
+ m_native.keyEquivalent = keySequenceToKeyEqivalent(accel);
+ m_native.keyEquivalentModifierMask = keySequenceModifierMask(accel);
} else
#endif
{
- [m_native setKeyEquivalent:@""];
- [m_native setKeyEquivalentModifierMask:NSCommandKeyMask];
+ m_native.keyEquivalent = @"";
+ m_native.keyEquivalentModifierMask = NSEventModifierFlagCommand;
}
NSImage *img = nil;
if (!m_icon.isNull()) {
img = qt_mac_create_nsimage(m_icon, m_iconSize);
- [img setSize:NSMakeSize(m_iconSize, m_iconSize)];
+ img.size = CGSizeMake(m_iconSize, m_iconSize);
}
- [m_native setImage:img];
+ m_native.image = img;
[img release];
- [m_native setState:m_checked ? NSOnState : NSOffState];
+ m_native.state = m_checked ? NSOnState : NSOffState;
return m_native;
}
@@ -408,8 +399,8 @@ void QCocoaMenuItem::syncMerged()
qWarning("Trying to sync a non-merged item");
return;
}
- [m_native setTag:reinterpret_cast<NSInteger>(this)];
- [m_native setHidden: !m_isVisible];
+
+ m_native.hidden = !m_isVisible;
}
void QCocoaMenuItem::setParentEnabled(bool enabled)
@@ -434,4 +425,39 @@ void QCocoaMenuItem::setIconSize(int size)
m_iconSize = size;
}
+void QCocoaMenuItem::resolveTargetAction()
+{
+ if (m_native.separatorItem)
+ return;
+
+ // Some items created by QCocoaMenuLoader are not
+ // instances of QCocoaNSMenuItem and have their
+ // target/action set as Interface Builder would.
+ if (![m_native isMemberOfClass:[QCocoaNSMenuItem class]])
+ return;
+
+ // Use the responder chain and ensure native modal dialogs
+ // continue receiving cut/copy/paste/etc. key equivalents.
+ SEL roleAction;
+ switch (effectiveRole()) {
+ case CutRole:
+ roleAction = @selector(cut:);
+ break;
+ case CopyRole:
+ roleAction = @selector(copy:);
+ break;
+ case PasteRole:
+ roleAction = @selector(paste:);
+ break;
+ case SelectAllRole:
+ roleAction = @selector(selectAll:);
+ break;
+ default:
+ roleAction = @selector(qt_itemFired:);
+ }
+
+ m_native.action = roleAction;
+ m_native.target = nil;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h
index 95f347646c..5e83327854 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -54,42 +54,20 @@
#import <AppKit/AppKit.h>
#include <QtCore/private/qcore_mac_p.h>
-@interface QT_MANGLE_NAMESPACE(QCocoaMenuLoader) : NSResponder
-{
- IBOutlet NSMenu *theMenu;
- IBOutlet NSMenu *appMenu;
- IBOutlet NSMenuItem *quitItem;
- IBOutlet NSMenuItem *preferencesItem;
- IBOutlet NSMenuItem *aboutItem;
- IBOutlet NSMenuItem *aboutQtItem;
- IBOutlet NSMenuItem *hideItem;
- NSMenuItem *lastAppSpecificItem;
- NSMenuItem *servicesItem;
- NSMenuItem *hideAllOthersItem;
- NSMenuItem *showAllItem;
-}
+QT_FORWARD_DECLARE_CLASS(QCocoaMenuItem);
+
+@interface QT_MANGLE_NAMESPACE(QCocoaMenuLoader) : NSObject
+ (instancetype)sharedMenuLoader;
-- (instancetype)init;
-- (void)ensureAppMenuInMenu:(NSMenu *)menu;
-- (void)removeActionsFromAppMenu;
-- (NSMenu *)applicationMenu;
- (NSMenu *)menu;
+- (void)ensureAppMenuInMenu:(NSMenu *)menu;
- (NSMenuItem *)quitMenuItem;
- (NSMenuItem *)preferencesMenuItem;
- (NSMenuItem *)aboutMenuItem;
- (NSMenuItem *)aboutQtMenuItem;
- (NSMenuItem *)hideMenuItem;
-- (NSMenuItem *)appSpecificMenuItem:(NSInteger)tag;
-- (IBAction)terminate:(id)sender;
-- (IBAction)orderFrontStandardAboutPanel:(id)sender;
-- (IBAction)hideOtherApplications:(id)sender;
-- (IBAction)unhideAllApplications:(id)sender;
-- (IBAction)hide:(id)sender;
-- (IBAction)qtDispatcherToQPAMenuItem:(id)sender;
-- (void)orderFrontCharacterPalette:(id)sender;
-- (BOOL)validateMenuItem:(NSMenuItem*)menuItem;
+- (NSMenuItem *)appSpecificMenuItem:(QCocoaMenuItem *)platformItem;
- (void)qtTranslateApplicationMenu;
-- (NSArray *)mergeable;
+- (NSArray<NSMenuItem *> *)mergeable;
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuLoader);
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 4432d3e27a..da0fc5c6a1 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -41,6 +41,7 @@
#include "messages.h"
#include "qcocoahelpers.h"
+#include "qcocoansmenu.h"
#include "qcocoamenubar.h"
#include "qcocoamenuitem.h"
#include "qcocoaintegration.h"
@@ -50,7 +51,19 @@
#include <QtCore/qcoreapplication.h>
#include <QtGui/private/qguiapplication_p.h>
-@implementation QCocoaMenuLoader
+@implementation QCocoaMenuLoader {
+ NSMenu *theMenu;
+ NSMenu *appMenu;
+ NSMenuItem *quitItem;
+ NSMenuItem *preferencesItem;
+ NSMenuItem *aboutItem;
+ NSMenuItem *aboutQtItem;
+ NSMenuItem *hideItem;
+ NSMenuItem *lastAppSpecificItem;
+ NSMenuItem *servicesItem;
+ NSMenuItem *hideAllOthersItem;
+ NSMenuItem *showAllItem;
+}
+ (instancetype)sharedMenuLoader
{
@@ -83,17 +96,19 @@
appItem.submenu = appMenu;
// About Application
- aboutItem = [[NSMenuItem alloc] initWithTitle:[@"About " stringByAppendingString:appName]
- action:@selector(orderFrontStandardAboutPanel:)
- keyEquivalent:@""];
+ aboutItem = [[QCocoaNSMenuItem alloc] init];
+ aboutItem.title = [@"About " stringByAppendingString:appName];
+ // FIXME This seems useless since barely adding a QAction
+ // with AboutRole role will reset the target/action
aboutItem.target = self;
+ aboutItem.action = @selector(orderFrontStandardAboutPanel:);
// Disable until a QAction is associated
aboutItem.enabled = NO;
aboutItem.hidden = YES;
[appMenu addItem:aboutItem];
// About Qt (shameless self-promotion)
- aboutQtItem = [[NSMenuItem alloc] init];
+ aboutQtItem = [[QCocoaNSMenuItem alloc] init];
aboutQtItem.title = @"About Qt";
// Disable until a QAction is associated
aboutQtItem.enabled = NO;
@@ -103,15 +118,19 @@
[appMenu addItem:[NSMenuItem separatorItem]];
// Preferences
- preferencesItem = [[NSMenuItem alloc] initWithTitle:@"Preferences…"
- action:@selector(qtDispatcherToQPAMenuItem:)
- keyEquivalent:@","];
- preferencesItem.target = self;
+ preferencesItem = [[QCocoaNSMenuItem alloc] init];
+ preferencesItem.title = @"Preferences…";
+ preferencesItem.keyEquivalent = @",";
// Disable until a QAction is associated
preferencesItem.enabled = NO;
preferencesItem.hidden = YES;
[appMenu addItem:preferencesItem];
+ // We'll be adding app specific items after this. The macOS HIG state that,
+ // "In general, a Preferences menu item should be the first app-specific menu item."
+ // https://developer.apple.com/macos/human-interface-guidelines/menus/menu-bar-menus/
+ lastAppSpecificItem = preferencesItem;
+
[appMenu addItem:[NSMenuItem separatorItem]];
// Services item and menu
@@ -136,7 +155,7 @@
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"];
hideAllOthersItem.target = self;
- hideAllOthersItem.keyEquivalentModifierMask = NSCommandKeyMask | NSAlternateKeyMask;
+ hideAllOthersItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagOption;
[appMenu addItem:hideAllOthersItem];
// Show All
@@ -149,10 +168,13 @@
[appMenu addItem:[NSMenuItem separatorItem]];
// Quit Application
- quitItem = [[NSMenuItem alloc] initWithTitle:[@"Quit " stringByAppendingString:appName]
- action:@selector(terminate:)
- keyEquivalent:@"q"];
- quitItem.target = self;
+ quitItem = [[QCocoaNSMenuItem alloc] init];
+ quitItem.title = [@"Quit " stringByAppendingString:appName];
+ quitItem.keyEquivalent = @"q";
+ // This will remain true until synced with a QCocoaMenuItem.
+ // This way, we will always have a functional Quit menu item
+ // even if no QAction is added.
+ quitItem.action = @selector(terminate:);
[appMenu addItem:quitItem];
}
@@ -184,7 +206,7 @@
// windows with different menu bars), we never recreate this menu, but
// instead pull it out the current menu bar and place into the new one:
NSMenu *mainMenu = [NSApp mainMenu];
- if ([NSApp mainMenu] == menu)
+ if (mainMenu == menu)
return; // nothing to do (menu is the current menu bar)!
#ifndef QT_NAMESPACE
@@ -205,17 +227,11 @@
unparentAppMenu(appMenu.supermenu);
NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
- action:nil keyEquivalent:@""];
- [appMenuItem setSubmenu:appMenu];
+ action:nil keyEquivalent:@""];
+ appMenuItem.submenu = appMenu;
[menu insertItem:appMenuItem atIndex:0];
}
-- (void)removeActionsFromAppMenu
-{
- for (NSMenuItem *item in [appMenu itemArray])
- [item setTag:0];
-}
-
- (NSMenu *)menu
{
return [[theMenu retain] autorelease];
@@ -251,41 +267,32 @@
return [[hideItem retain] autorelease];
}
-- (NSMenuItem *)appSpecificMenuItem:(NSInteger)tag
+- (NSMenuItem *)appSpecificMenuItem:(QCocoaMenuItem *)platformItem
{
- NSMenuItem *item = [appMenu itemWithTag:tag];
-
- // No reason to create the item if it already exists. See QTBUG-27202.
- if (item)
- return [[item retain] autorelease];
+ // No reason to create the item if it already exists.
+ for (NSMenuItem *item in appMenu.itemArray)
+ if (qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem == platformItem)
+ return [[item retain] autorelease];
// Create an App-Specific menu item, insert it into the menu and return
// it as an autorelease item.
- item = [[NSMenuItem alloc] init];
+ QCocoaNSMenuItem *item;
+ if (platformItem->isSeparator())
+ item = [[QCocoaNSMenuItem separatorItemWithPlatformMenuItem:platformItem] retain];
+ else
+ item = [[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:platformItem];
+
+ const auto location = [appMenu indexOfItem:lastAppSpecificItem];
- NSInteger location;
- if (lastAppSpecificItem == nil) {
- location = [appMenu indexOfItem:aboutQtItem];
- } else {
- location = [appMenu indexOfItem:lastAppSpecificItem];
+ if (!lastAppSpecificItem.separatorItem)
[lastAppSpecificItem release];
- }
lastAppSpecificItem = item; // Keep track of this for later (i.e., don't release it)
+
[appMenu insertItem:item atIndex:location + 1];
return [[item retain] autorelease];
}
-- (BOOL) acceptsFirstResponder
-{
- return YES;
-}
-
-- (void)terminate:(id)sender
-{
- [NSApp terminate:sender];
-}
-
- (void)orderFrontStandardAboutPanel:(id)sender
{
[NSApp orderFrontStandardAboutPanel:sender];
@@ -308,61 +315,36 @@
- (void)qtTranslateApplicationMenu
{
-
#ifndef QT_NO_TRANSLATION
- [servicesItem setTitle:qt_mac_applicationmenu_string(ServicesAppMenuItem).toNSString()];
- [hideItem setTitle:qt_mac_applicationmenu_string(HideAppMenuItem).arg(qt_mac_applicationName()).toNSString()];
- [hideAllOthersItem setTitle:qt_mac_applicationmenu_string(HideOthersAppMenuItem).toNSString()];
- [showAllItem setTitle:qt_mac_applicationmenu_string(ShowAllAppMenuItem).toNSString()];
- [preferencesItem setTitle:qt_mac_applicationmenu_string(PreferencesAppMenuItem).toNSString()];
- [quitItem setTitle:qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()).toNSString()];
- [aboutItem setTitle:qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()).toNSString()];
+ aboutItem.title = qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()).toNSString();
+ preferencesItem.title = qt_mac_applicationmenu_string(PreferencesAppMenuItem).toNSString();
+ servicesItem.title = qt_mac_applicationmenu_string(ServicesAppMenuItem).toNSString();
+ hideItem.title = qt_mac_applicationmenu_string(HideAppMenuItem).arg(qt_mac_applicationName()).toNSString();
+ hideAllOthersItem.title = qt_mac_applicationmenu_string(HideOthersAppMenuItem).toNSString();
+ showAllItem.title = qt_mac_applicationmenu_string(ShowAllAppMenuItem).toNSString();
+ quitItem.title = qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()).toNSString();
#endif
}
-- (IBAction)qtDispatcherToQPAMenuItem:(id)sender
-{
- NSMenuItem *item = static_cast<NSMenuItem *>(sender);
- if (item == quitItem) {
- // We got here because someone was once the quitItem, but it has been
- // abandoned (e.g., the menubar was deleted). In the meantime, just do
- // normal QApplication::quit().
- qApp->quit();
- return;
- }
-
- if ([item tag]) {
- QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
- QScopedScopeLevelCounter scopeLevelCounter(QGuiApplicationPrivate::instance()->threadData);
- cocoaItem->activated();
- }
-}
-
-- (void)orderFrontCharacterPalette:(id)sender
-{
- [NSApp orderFrontCharacterPalette:sender];
-}
-
- (BOOL)validateMenuItem:(NSMenuItem*)menuItem
{
- if ([menuItem action] == @selector(hideOtherApplications:)
- || [menuItem action] == @selector(unhideAllApplications:)) {
+ if (menuItem.action == @selector(hideOtherApplications:)
+ || menuItem.action == @selector(unhideAllApplications:))
return [NSApp validateMenuItem:menuItem];
- } else if ([menuItem action] == @selector(hide:)) {
+
+ if (menuItem.action == @selector(hide:)) {
if (QCocoaIntegration::instance()->activePopupWindow())
return NO;
return [NSApp validateMenuItem:menuItem];
- } else if ([menuItem tag]) {
- QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([menuItem tag]);
- return cocoaItem->isEnabled();
- } else {
- return [menuItem isEnabled];
}
+
+ return menuItem.enabled;
}
-- (NSArray*) mergeable
+- (NSArray<NSMenuItem *> *)mergeable
{
- // don't include the quitItem here, since we want it always visible and enabled regardless
+ // Don't include the quitItem here, since we want it always visible and enabled regardless
+ // Note that lastAppSpecificItem may be nil, so we can't use @[] here.
return [NSArray arrayWithObjects:preferencesItem, aboutItem, aboutQtItem, lastAppSpecificItem, nil];
}
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 955b147bfd..7979e430ac 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -71,6 +71,10 @@
#include <AppKit/AppKit.h>
+#if QT_CONFIG(vulkan)
+#include <MoltenVK/mvk_vulkan.h>
+#endif
+
QT_BEGIN_NAMESPACE
QCocoaNativeInterface::QCocoaNativeInterface()
@@ -81,31 +85,32 @@ QCocoaNativeInterface::QCocoaNativeInterface()
void *QCocoaNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
{
if (!context)
- return 0;
+ return nullptr;
if (resourceString.toLower() == "nsopenglcontext")
return nsOpenGLContextForContext(context);
if (resourceString.toLower() == "cglcontextobj")
return cglContextForContext(context);
- return 0;
+ return nullptr;
}
#endif
void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
if (!window->handle())
- return 0;
+ return nullptr;
if (resourceString == "nsview") {
return static_cast<QCocoaWindow *>(window->handle())->m_view;
-#ifndef QT_NO_OPENGL
- } else if (resourceString == "nsopenglcontext") {
- return static_cast<QCocoaWindow *>(window->handle())->currentContext()->nsOpenGLContext();
-#endif
} else if (resourceString == "nswindow") {
return static_cast<QCocoaWindow *>(window->handle())->nativeWindow();
+#if QT_CONFIG(vulkan)
+ } else if (resourceString == "vkSurface") {
+ if (QVulkanInstance *instance = window->vulkanInstance())
+ return static_cast<QCocoaVulkanInstance *>(instance->handle())->createSurface(window);
+#endif
}
- return 0;
+ return nullptr;
}
QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInterface::nativeResourceFunctionForIntegration(const QByteArray &resource)
@@ -143,7 +148,7 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
if (resource.toLower() == "testcontentborderposition")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::testContentBorderPosition);
- return 0;
+ return nullptr;
}
QPlatformPrinterSupport *QCocoaNativeInterface::createPlatformPrinterSupport()
@@ -152,7 +157,7 @@ QPlatformPrinterSupport *QCocoaNativeInterface::createPlatformPrinterSupport()
return new QCocoaPrinterSupport();
#else
qFatal("Printing is not supported when Qt is configured with -no-widgets");
- return 0;
+ return nullptr;
#endif
}
@@ -166,7 +171,7 @@ void *QCocoaNativeInterface::NSPrintInfoForPrintEngine(QPrintEngine *printEngine
#else
Q_UNUSED(printEngine);
qFatal("Printing is not supported when Qt is configured with -no-widgets");
- return 0;
+ return nullptr;
#endif
}
@@ -180,10 +185,10 @@ QPixmap QCocoaNativeInterface::defaultBackgroundPixmapForQWizard()
CFURLRef url = (CFURLRef)CFArrayGetValueAtIndex(urls, 0);
QCFType<CFBundleRef> bundle = CFBundleCreate(kCFAllocatorDefault, url);
if (bundle) {
- url = CFBundleCopyResourceURL(bundle, CFSTR("Background"), CFSTR("png"), 0);
+ url = CFBundleCopyResourceURL(bundle, CFSTR("Background"), CFSTR("png"), nullptr);
if (url) {
- QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithURL(url, 0);
- QCFType<CGImageRef> image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0);
+ QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithURL(url, nullptr);
+ QCFType<CGImageRef> image = CGImageSourceCreateImageAtIndex(imageSource, 0, nullptr);
if (image) {
int width = CGImageGetWidth(image);
int height = CGImageGetHeight(image);
@@ -213,18 +218,16 @@ void *QCocoaNativeInterface::cglContextForContext(QOpenGLContext* context)
NSOpenGLContext *nsOpenGLContext = static_cast<NSOpenGLContext*>(nsOpenGLContextForContext(context));
if (nsOpenGLContext)
return [nsOpenGLContext CGLContextObj];
- return 0;
+ return nullptr;
}
void *QCocoaNativeInterface::nsOpenGLContextForContext(QOpenGLContext* context)
{
if (context) {
- QCocoaGLContext *cocoaGLContext = static_cast<QCocoaGLContext *>(context->handle());
- if (cocoaGLContext) {
- return cocoaGLContext->nsOpenGLContext();
- }
+ if (QCocoaGLContext *cocoaGLContext = static_cast<QCocoaGLContext *>(context->handle()))
+ return cocoaGLContext->nativeContext();
}
- return 0;
+ return nullptr;
}
#endif
@@ -256,7 +259,7 @@ void QCocoaNativeInterface::setDockMenu(QPlatformMenu *platformMenu)
QMacAutoReleasePool pool;
QCocoaMenu *cocoaPlatformMenu = static_cast<QCocoaMenu *>(platformMenu);
NSMenu *menu = cocoaPlatformMenu->nsMenu();
- [[QCocoaApplicationDelegate sharedDelegate] setDockMenu:menu];
+ [QCocoaApplicationDelegate sharedDelegate].dockMenu = menu;
}
void *QCocoaNativeInterface::qMenuToNSMenu(QPlatformMenu *platformMenu)
@@ -285,8 +288,9 @@ QImage QCocoaNativeInterface::cgImageToQImage(CGImageRef image)
void QCocoaNativeInterface::setEmbeddedInForeignView(QPlatformWindow *window, bool embedded)
{
+ Q_UNUSED(embedded); // "embedded" state is now automatically detected
QCocoaWindow *cocoaPlatformWindow = static_cast<QCocoaWindow *>(window);
- cocoaPlatformWindow->setEmbeddedInForeignView(embedded);
+ cocoaPlatformWindow->setEmbeddedInForeignView();
}
void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable)
diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.h b/src/plugins/platforms/cocoa/qcocoansmenu.h
index a9c3e4fff9..6cbb6e4a01 100644
--- a/src/plugins/platforms/cocoa/qcocoansmenu.h
+++ b/src/plugins/platforms/cocoa/qcocoansmenu.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -53,12 +53,10 @@
#import <AppKit/AppKit.h>
-#include <QtCore/qpointer.h>
#include <qcocoahelpers.h>
QT_FORWARD_DECLARE_CLASS(QCocoaMenu);
-typedef QPointer<QCocoaMenu> QCocoaMenuPointer;
-
+QT_FORWARD_DECLARE_CLASS(QCocoaMenuItem);
@interface QT_MANGLE_NAMESPACE(QCocoaNSMenuDelegate) : NSObject <NSMenuDelegate>
@@ -72,18 +70,24 @@ typedef QPointer<QCocoaMenu> QCocoaMenuPointer;
@interface QT_MANGLE_NAMESPACE(QCocoaNSMenu) : NSMenu
-@property (readonly, nonatomic) QCocoaMenuPointer qpaMenu;
+@property (readonly, nonatomic) QCocoaMenu *platformMenu;
+
+- (instancetype)initWithPlatformMenu:(QCocoaMenu *)menu;
+
+@end
-- (instancetype)initWithQPAMenu:(QCocoaMenu *)menu;
+@interface QT_MANGLE_NAMESPACE(QCocoaNSMenuItem) : NSMenuItem
-- (void)qt_itemFired:(NSMenuItem *)item;
+@property (nonatomic) QCocoaMenuItem *platformMenuItem;
-- (BOOL)worksWhenModal;
-- (BOOL)validateMenuItem:(NSMenuItem*)item; // NSMenuValidation
++ (instancetype)separatorItemWithPlatformMenuItem:(QCocoaMenuItem *)menuItem;
+- (instancetype)initWithPlatformMenuItem:(QCocoaMenuItem *)menuItem;
+- (instancetype)init;
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaNSMenu);
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaNSMenuItem);
QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaNSMenuDelegate);
#endif // QCOCOANSMENU_H
diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.mm b/src/plugins/platforms/cocoa/qcocoansmenu.mm
index 19a0f950e4..65b0832d9f 100644
--- a/src/plugins/platforms/cocoa/qcocoansmenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoansmenu.mm
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -44,17 +44,15 @@
#include "qcocoawindow.h"
#import "qnsview.h"
-#include <QtCore/qmetaobject.h>
-#include <QtCore/private/qthread_p.h>
-#include <QtGui/private/qguiapplication_p.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qcoreevent.h>
-static NSString *qt_mac_removePrivateUnicode(NSString* string)
+static NSString *qt_mac_removePrivateUnicode(NSString *string)
{
- int len = [string length];
- if (len) {
- QVarLengthArray <unichar, 10> characters(len);
+ if (const int len = string.length) {
+ QVarLengthArray<unichar, 10> characters(len);
bool changed = false;
- for (int i = 0; i<len; i++) {
+ for (int i = 0; i < len; i++) {
characters[i] = [string characterAtIndex:i];
// check if they belong to key codes in private unicode range
// currently we need to handle only the NSDeleteFunctionKey
@@ -70,11 +68,14 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
}
@implementation QCocoaNSMenu
+{
+ QPointer<QCocoaMenu> _platformMenu;
+}
-- (instancetype)initWithQPAMenu:(QCocoaMenu *)menu
+- (instancetype)initWithPlatformMenu:(QCocoaMenu *)menu
{
if ((self = [super initWithTitle:@"Untitled"])) {
- _qpaMenu = menu;
+ _platformMenu = menu;
self.autoenablesItems = YES;
self.delegate = [QCocoaNSMenuDelegate sharedMenuDelegate];
}
@@ -82,46 +83,58 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
return self;
}
-// Cocoa will query the menu item's target for the worksWhenModal selector.
-// So we need to implement this to allow the items to be handled correctly
-// when a modal dialog is visible. See documentation for NSMenuItem.target.
-- (BOOL)worksWhenModal
+- (QCocoaMenu *)platformMenu
{
- if (!QGuiApplication::modalWindow())
- return YES;
- if (const auto *mb = qobject_cast<QCocoaMenuBar *>(self.qpaMenu->menuParent()))
- return QGuiApplication::modalWindow()->handle() == mb->cocoaWindow() ? YES : NO;
- return YES;
+ return _platformMenu.data();
}
-- (void)qt_itemFired:(NSMenuItem *)item
+@end
+
+@implementation QCocoaNSMenuItem
{
- auto *qpaItem = reinterpret_cast<QCocoaMenuItem *>(item.tag);
- // Menu-holding items also get a target to play nicely
- // with NSMenuValidation but should not trigger.
- if (!qpaItem || qpaItem->menu())
- return;
+ QPointer<QCocoaMenuItem> _platformMenuItem;
+}
- QScopedScopeLevelCounter scopeLevelCounter(QGuiApplicationPrivate::instance()->threadData);
- QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers:[NSEvent modifierFlags]];
++ (instancetype)separatorItemWithPlatformMenuItem:(QCocoaMenuItem *)menuItem
+{
+ // Safe because +[NSMenuItem separatorItem] invokes [[self alloc] init]
+ auto *item = qt_objc_cast<QCocoaNSMenuItem *>([self separatorItem]);
+ Q_ASSERT_X(item, qPrintable(__FUNCTION__),
+ "Did +[NSMenuItem separatorItem] not invoke [[self alloc] init]?");
+ if (item)
+ item.platformMenuItem = menuItem;
+
+ return item;
+}
- static QMetaMethod activatedSignal = QMetaMethod::fromSignal(&QCocoaMenuItem::activated);
- activatedSignal.invoke(qpaItem, Qt::QueuedConnection);
+- (instancetype)initWithPlatformMenuItem:(QCocoaMenuItem *)menuItem
+{
+ if ((self = [super initWithTitle:@"" action:nil keyEquivalent:@""])) {
+ _platformMenuItem = menuItem;
+ }
+
+ return self;
}
-- (BOOL)validateMenuItem:(NSMenuItem*)item
+- (instancetype)init
{
- auto *qpaItem = reinterpret_cast<QCocoaMenuItem *>(item.tag);
- // Menu-holding items are always enabled, as it's conventional in Cocoa
- if (!qpaItem || qpaItem->menu())
- return YES;
+ return [self initWithPlatformMenuItem:nullptr];
+}
- return qpaItem->isEnabled();
+- (QCocoaMenuItem *)platformMenuItem
+{
+ return _platformMenuItem.data();
+}
+
+- (void)setPlatformMenuItem:(QCocoaMenuItem *)menuItem
+{
+ _platformMenuItem = menuItem;
}
@end
-#define CHECK_MENU_CLASS(menu) Q_ASSERT([menu isMemberOfClass:[QCocoaNSMenu class]])
+#define CHECK_MENU_CLASS(menu) Q_ASSERT_X([menu isMemberOfClass:[QCocoaNSMenu class]], \
+ __FUNCTION__, "Menu is not a QCocoaNSMenu")
@implementation QCocoaNSMenuDelegate
@@ -153,14 +166,15 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
if (shouldCancel)
return NO;
- const auto &qpaMenu = static_cast<QCocoaNSMenu *>(menu).qpaMenu;
- if (qpaMenu.isNull())
+ const auto &platformMenu = static_cast<QCocoaNSMenu *>(menu).platformMenu;
+ if (!platformMenu)
return YES;
- auto *menuItem = reinterpret_cast<QCocoaMenuItem *>(item.tag);
- if (qpaMenu->items().contains(menuItem)) {
- if (QCocoaMenu *itemSubmenu = menuItem->menu())
- itemSubmenu->setAttachedItem(item);
+ if (auto *platformItem = qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem) {
+ if (platformMenu->items().contains(platformItem)) {
+ if (auto *itemSubmenu = platformItem->menu())
+ itemSubmenu->setAttachedItem(item);
+ }
}
return YES;
@@ -169,32 +183,31 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
- (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item
{
CHECK_MENU_CLASS(menu);
- auto *qpaItem = reinterpret_cast<QCocoaMenuItem *>(item.tag);
- if (qpaItem)
- qpaItem->hovered();
+ if (auto *platformItem = qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem)
+ emit platformItem->hovered();
}
- (void)menuWillOpen:(NSMenu *)menu
{
CHECK_MENU_CLASS(menu);
- const auto &qpaMenu = static_cast<QCocoaNSMenu *>(menu).qpaMenu;
- if (qpaMenu.isNull())
+ auto *platformMenu = static_cast<QCocoaNSMenu *>(menu).platformMenu;
+ if (!platformMenu)
return;
- qpaMenu->setIsOpen(true);
- emit qpaMenu->aboutToShow();
+ platformMenu->setIsOpen(true);
+ emit platformMenu->aboutToShow();
}
- (void)menuDidClose:(NSMenu *)menu
{
CHECK_MENU_CLASS(menu);
- const auto &qpaMenu = static_cast<QCocoaNSMenu *>(menu).qpaMenu;
- if (qpaMenu.isNull())
+ auto *platformMenu = static_cast<QCocoaNSMenu *>(menu).platformMenu;
+ if (!platformMenu)
return;
- qpaMenu->setIsOpen(false);
+ platformMenu->setIsOpen(false);
// wrong, but it's the best we can do
- emit qpaMenu->aboutToHide();
+ emit platformMenu->aboutToHide();
}
- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action
@@ -212,7 +225,8 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
CHECK_MENU_CLASS(menu);
// Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ...
- static const NSUInteger mask = NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask;
+ static const NSUInteger mask = NSEventModifierFlagShift | NSEventModifierFlagControl
+ | NSEventModifierFlagCommand | NSEventModifierFlagOption;
// Change the private unicode keys to the ones used in setting the "Key Equivalents"
NSString *characters = qt_mac_removePrivateUnicode(event.charactersIgnoringModifiers);
@@ -229,30 +243,17 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
}
if (keyEquivalentItem) {
- if (!keyEquivalentItem.target) {
- // This item was modified by QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder
- // and it looks like we're running a modal session for NSOpenPanel/NSSavePanel.
- // QCocoaFileDialogHelper is actually the only place we use this and we run NSOpenPanel modal
- // (modal sheet, window modal, application modal).
- // Whatever the current first responder is, let's give it a chance
- // and do not touch the Qt's focusObject (which is different from some native view
- // having a focus inside NSSave/OpenPanel.
- *target = nil;
- *action = keyEquivalentItem.action;
- return YES;
- }
-
QObject *object = qApp->focusObject();
if (object) {
QChar ch;
int keyCode;
- ulong nativeModifiers = [event modifierFlags];
- Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers];
- NSString *charactersIgnoringModifiers = [event charactersIgnoringModifiers];
- NSString *characters = [event characters];
+ ulong nativeModifiers = event.modifierFlags;
+ Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers:nativeModifiers];
+ NSString *charactersIgnoringModifiers = event.charactersIgnoringModifiers;
+ NSString *characters = event.characters;
- if ([charactersIgnoringModifiers length] > 0) { // convert the first character into a key code
- if ((modifiers & Qt::ControlModifier) && ([characters length] != 0)) {
+ if (charactersIgnoringModifiers.length > 0) { // convert the first character into a key code
+ if ((modifiers & Qt::ControlModifier) && characters.length > 0) {
ch = QChar([characters characterAtIndex:0]);
} else {
ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
@@ -269,7 +270,7 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
accel_ev.ignore();
QCoreApplication::sendEvent(object, &accel_ev);
if (accel_ev.isAccepted()) {
- [[NSApp keyWindow] sendEvent: event];
+ [[NSApp keyWindow] sendEvent:event];
*target = nil;
*action = nil;
return YES;
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
index bfe6cd09b6..24ec7ca9a4 100644
--- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
+++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
@@ -67,17 +67,17 @@ static QPrint::DuplexMode macToDuplexMode(const PMDuplexMode &mode)
QCocoaPrintDevice::QCocoaPrintDevice()
: QPlatformPrintDevice(),
- m_printer(0),
- m_session(0),
- m_ppd(0)
+ m_printer(nullptr),
+ m_session(nullptr),
+ m_ppd(nullptr)
{
}
QCocoaPrintDevice::QCocoaPrintDevice(const QString &id)
: QPlatformPrintDevice(id),
- m_printer(0),
- m_session(0),
- m_ppd(0)
+ m_printer(nullptr),
+ m_session(nullptr),
+ m_ppd(nullptr)
{
if (!id.isEmpty()) {
m_printer = PMPrinterCreateFromPrinterID(id.toCFString());
@@ -411,7 +411,7 @@ QPrint::ColorMode QCocoaPrintDevice::defaultColorMode() const
ppd_option_t *colorModel = ppdFindOption(m_ppd, "DefaultColorModel");
if (!colorModel)
colorModel = ppdFindOption(m_ppd, "ColorModel");
- if (!colorModel || (colorModel && !qstrcmp(colorModel->defchoice, "Gray")))
+ if (!colorModel || qstrcmp(colorModel->defchoice, "Gray") != 0)
return QPrint::Color;
}
return QPrint::GrayScale;
@@ -443,11 +443,11 @@ bool QCocoaPrintDevice::openPpdFile()
{
if (m_ppd)
ppdClose(m_ppd);
- m_ppd = 0;
- CFURLRef ppdURL = NULL;
+ m_ppd = nullptr;
+ CFURLRef ppdURL = nullptr;
char ppdPath[MAXPATHLEN];
if (PMPrinterCopyDescriptionURL(m_printer, kPMPPDDescriptionType, &ppdURL) == noErr
- && ppdURL != NULL) {
+ && ppdURL) {
if (CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath)))
m_ppd = ppdOpenFile(ppdPath);
CFRelease(ppdURL);
@@ -470,7 +470,7 @@ PMPaper QCocoaPrintDevice::macPaper(const QPageSize &pageSize) const
if (m_macPapers.contains(pageSize.key()))
return m_macPapers.value(pageSize.key());
// For any other page size, whether custom or just unsupported, needs to be a custom PMPaper
- PMPaper paper = 0;
+ PMPaper paper = nullptr;
PMPaperMargins paperMargins;
paperMargins.left = m_customMargins.left();
paperMargins.right = m_customMargins.right();
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h
index 3d59c3de79..9ded98df32 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.h
+++ b/src/plugins/platforms/cocoa/qcocoascreen.h
@@ -75,7 +75,11 @@ public:
// Additional methods
void setVirtualSiblings(const QList<QPlatformScreen *> &siblings) { m_siblings = siblings; }
NSScreen *nativeScreen() const;
- void updateGeometry();
+ void updateProperties();
+
+ void requestUpdate();
+ void deliverUpdateRequests();
+ bool isRunningDisplayLink() const;
static QCocoaScreen *primaryScreen();
@@ -96,6 +100,10 @@ public:
QSizeF m_physicalSize;
QCocoaCursor *m_cursor;
QList<QPlatformScreen *> m_siblings;
+
+ CVDisplayLinkRef m_displayLink = nullptr;
+ dispatch_source_t m_displayLinkSource = nullptr;
+ QAtomicInt m_pendingUpdates;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -104,5 +112,9 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen);
QT_END_NAMESPACE
+@interface NSScreen (QtExtras)
+@property(readonly) CGDirectDisplayID qt_displayId;
+@end
+
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm
index 3e8261dfc2..f82ef202b1 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.mm
+++ b/src/plugins/platforms/cocoa/qcocoascreen.mm
@@ -47,6 +47,10 @@
#include <IOKit/graphics/IOGraphicsLib.h>
+#include <QtGui/private/qwindow_p.h>
+
+#include <QtCore/private/qeventdispatcher_cf_p.h>
+
QT_BEGIN_NAMESPACE
class QCoreTextFontEngine;
@@ -55,18 +59,22 @@ class QFontEngineFT;
QCocoaScreen::QCocoaScreen(int screenIndex)
: QPlatformScreen(), m_screenIndex(screenIndex), m_refreshRate(60.0)
{
- updateGeometry();
+ updateProperties();
m_cursor = new QCocoaCursor;
}
QCocoaScreen::~QCocoaScreen()
{
delete m_cursor;
+
+ CVDisplayLinkRelease(m_displayLink);
+ if (m_displayLinkSource)
+ dispatch_release(m_displayLinkSource);
}
NSScreen *QCocoaScreen::nativeScreen() const
{
- NSArray *screens = [NSScreen screens];
+ NSArray<NSScreen *> *screens = [NSScreen screens];
// Stale reference, screen configuration has changed
if (m_screenIndex < 0 || (NSUInteger)m_screenIndex >= [screens count])
@@ -107,12 +115,17 @@ static QString displayName(CGDirectDisplayID displayID)
return QString();
}
-void QCocoaScreen::updateGeometry()
+void QCocoaScreen::updateProperties()
{
NSScreen *nsScreen = nativeScreen();
if (!nsScreen)
return;
+ const QRect previousGeometry = m_geometry;
+ const QRect previousAvailableGeometry = m_availableGeometry;
+ const QDpi previousLogicalDpi = m_logicalDpi;
+ const qreal previousRefreshRate = m_refreshRate;
+
// The reference screen for the geometry is always the primary screen
QRectF primaryScreenGeometry = QRectF::fromCGRect([[NSScreen screens] firstObject].frame);
m_geometry = qt_mac_flip(QRectF::fromCGRect(nsScreen.frame), primaryScreenGeometry).toRect();
@@ -121,8 +134,7 @@ void QCocoaScreen::updateGeometry()
m_format = QImage::Format_RGB32;
m_depth = NSBitsPerPixelFromDepth([nsScreen depth]);
- NSDictionary *devDesc = [nsScreen deviceDescription];
- CGDirectDisplayID dpy = [[devDesc objectForKey:@"NSScreenNumber"] unsignedIntValue];
+ CGDirectDisplayID dpy = nsScreen.qt_displayId;
CGSize size = CGDisplayScreenSize(dpy);
m_physicalSize = QSizeF(size.width, size.height);
m_logicalDpi.first = 72;
@@ -135,25 +147,230 @@ void QCocoaScreen::updateGeometry()
m_name = displayName(dpy);
- QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
- QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second);
- QWindowSystemInterface::handleScreenRefreshRateChange(screen(), m_refreshRate);
-
- // When a screen changes its geometry, AppKit will send us a NSWindowDidMoveNotification
- // for each window, resulting in calls to handleGeometryChange(), but this happens before
- // the NSApplicationDidChangeScreenParametersNotification, so when we map the new geometry
- // (which is correct at that point) to the screen using QCocoaScreen::mapFromNative(), we
- // end up using the stale screen geometry, and the new window geometry we report is wrong.
- // To make sure we finally report the correct window geometry, we need to do another pass
- // of geometry reporting, now that the screen properties have been updates. FIXME: Ideally
- // this would be solved by not caching the screen properties in QCocoaScreen, but that
- // requires more research.
- for (QWindow *window : windows()) {
- if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow*>(window->handle()))
- cocoaWindow->handleGeometryChange();
+ const bool didChangeGeometry = m_geometry != previousGeometry || m_availableGeometry != previousAvailableGeometry;
+
+ if (didChangeGeometry)
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
+ if (m_logicalDpi != previousLogicalDpi)
+ QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second);
+ if (m_refreshRate != previousRefreshRate)
+ QWindowSystemInterface::handleScreenRefreshRateChange(screen(), m_refreshRate);
+
+ qCDebug(lcQpaScreen) << "Updated properties for" << this;
+
+ if (didChangeGeometry) {
+ // When a screen changes its geometry, AppKit will send us a NSWindowDidMoveNotification
+ // for each window, resulting in calls to handleGeometryChange(), but this happens before
+ // the NSApplicationDidChangeScreenParametersNotification, so when we map the new geometry
+ // (which is correct at that point) to the screen using QCocoaScreen::mapFromNative(), we
+ // end up using the stale screen geometry, and the new window geometry we report is wrong.
+ // To make sure we finally report the correct window geometry, we need to do another pass
+ // of geometry reporting, now that the screen properties have been updates. FIXME: Ideally
+ // this would be solved by not caching the screen properties in QCocoaScreen, but that
+ // requires more research.
+ for (QWindow *window : windows()) {
+ if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow*>(window->handle()))
+ cocoaWindow->handleGeometryChange();
+ }
+ }
+}
+
+// ----------------------- Display link -----------------------
+
+Q_LOGGING_CATEGORY(lcQpaScreenUpdates, "qt.qpa.screen.updates", QtCriticalMsg);
+
+void QCocoaScreen::requestUpdate()
+{
+ if (!m_displayLink) {
+ CVDisplayLinkCreateWithCGDisplay(nativeScreen().qt_displayId, &m_displayLink);
+ CVDisplayLinkSetOutputCallback(m_displayLink, [](CVDisplayLinkRef, const CVTimeStamp*,
+ const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* displayLinkContext) -> int {
+ // FIXME: It would be nice if update requests would include timing info
+ static_cast<QCocoaScreen*>(displayLinkContext)->deliverUpdateRequests();
+ return kCVReturnSuccess;
+ }, this);
+ qCDebug(lcQpaScreenUpdates) << "Display link created for" << this;
+
+ // During live window resizing -[NSWindow _resizeWithEvent:] will spin a local event loop
+ // in event-tracking mode, dequeuing only the mouse drag events needed to update the window's
+ // frame. It will repeatedly spin this loop until no longer receiving any mouse drag events,
+ // and will then update the frame (effectively coalescing/compressing the events). Unfortunately
+ // the events are pulled out using -[NSApplication nextEventMatchingEventMask:untilDate:inMode:dequeue:]
+ // which internally uses CFRunLoopRunSpecific, so the event loop will also process GCD queues and other
+ // runloop sources that have been added to the tracking mode. This includes the GCD display-link
+ // source that we use to marshal the display-link callback over to the main thread. If the
+ // subsequent delivery of the update-request on the main thread stalls due to inefficient
+ // user code, the NSEventThread will have had time to deliver additional mouse drag events,
+ // and the logic in -[NSWindow _resizeWithEvent:] will keep on compressing events and never
+ // get to the point of actually updating the window frame, making it seem like the window
+ // is stuck in its original size. Only when the user stops moving their mouse, and the event
+ // queue is completely drained of drag events, will the window frame be updated.
+
+ // By keeping an event tap listening for drag events, registered as a version 1 runloop source,
+ // we prevent the GCD source from being prioritized, giving the resize logic enough time
+ // to finish coalescing the events. This is incidental, but conveniently gives us the behavior
+ // we are looking for, interleaving display-link updates and resize events.
+ static CFMachPortRef eventTap = []() {
+ CFMachPortRef eventTap = CGEventTapCreateForPid(getpid(), kCGTailAppendEventTap,
+ kCGEventTapOptionListenOnly, NSEventMaskLeftMouseDragged,
+ [](CGEventTapProxy, CGEventType type, CGEventRef event, void *) -> CGEventRef {
+ if (type == kCGEventTapDisabledByTimeout)
+ qCWarning(lcQpaScreenUpdates) << "Event tap disabled due to timeout!";
+ return event; // Listen only tap, so what we return doesn't really matter
+ }, nullptr);
+ CGEventTapEnable(eventTap, false); // Event taps are normally enabled when created
+ static CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
+
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center addObserverForName:NSWindowWillStartLiveResizeNotification object:nil queue:nil
+ usingBlock:^(NSNotification *notification) {
+ qCDebug(lcQpaScreenUpdates) << "Live resize of" << notification.object
+ << "started. Enabling event tap";
+ CGEventTapEnable(eventTap, true);
+ }];
+ [center addObserverForName:NSWindowDidEndLiveResizeNotification object:nil queue:nil
+ usingBlock:^(NSNotification *notification) {
+ qCDebug(lcQpaScreenUpdates) << "Live resize of" << notification.object
+ << "ended. Disabling event tap";
+ CGEventTapEnable(eventTap, false);
+ }];
+ return eventTap;
+ }();
+ Q_UNUSED(eventTap);
+ }
+
+ if (!CVDisplayLinkIsRunning(m_displayLink)) {
+ qCDebug(lcQpaScreenUpdates) << "Starting display link for" << this;
+ CVDisplayLinkStart(m_displayLink);
+ }
+}
+
+// Helper to allow building up debug output in multiple steps
+struct DeferredDebugHelper
+{
+ DeferredDebugHelper(const QLoggingCategory &cat) {
+ if (cat.isDebugEnabled())
+ debug = new QDebug(QMessageLogger().debug(cat).nospace());
+ }
+ ~DeferredDebugHelper() {
+ flushOutput();
+ }
+ void flushOutput() {
+ if (debug) {
+ delete debug;
+ debug = nullptr;
+ }
+ }
+ QDebug *debug = nullptr;
+};
+
+#define qDeferredDebug(helper) if (Q_UNLIKELY(helper.debug)) *helper.debug
+
+void QCocoaScreen::deliverUpdateRequests()
+{
+ if (!QGuiApplication::instance())
+ return;
+
+ // The CVDisplayLink callback is a notification that it's a good time to produce a new frame.
+ // Since the callback is delivered on a separate thread we have to marshal it over to the
+ // main thread, as Qt requires update requests to be delivered there. This needs to happen
+ // asynchronously, as otherwise we may end up deadlocking if the main thread calls back
+ // into any of the CVDisplayLink APIs.
+ if (QThread::currentThread() != QGuiApplication::instance()->thread()) {
+ // We're explicitly not using the data of the GCD source to track the pending updates,
+ // as the data isn't reset to 0 until after the event handler, and also doesn't update
+ // during the event handler, both of which we need to track late frames.
+ const int pendingUpdates = ++m_pendingUpdates;
+
+ DeferredDebugHelper screenUpdates(lcQpaScreenUpdates());
+ qDeferredDebug(screenUpdates) << "display link callback for screen " << m_screenIndex;
+
+ if (const int framesAheadOfDelivery = pendingUpdates - 1) {
+ // If we have more than one update pending it means that a previous display link callback
+ // has not been fully processed on the main thread, either because GCD hasn't delivered
+ // it on the main thread yet, because the processing of the update request is taking
+ // too long, or because the update request was deferred due to window live resizing.
+ qDeferredDebug(screenUpdates) << ", " << framesAheadOfDelivery << " frame(s) ahead";
+
+ // We skip the frame completely if we're live-resizing, to not put any extra
+ // strain on the main thread runloop. Otherwise we assume we should push frames
+ // as fast as possible, and hopefully the callback will be delivered on the
+ // main thread just when the previous finished.
+ if (qt_apple_sharedApplication().keyWindow.inLiveResize) {
+ qDeferredDebug(screenUpdates) << "; waiting for main thread to catch up";
+ return;
+ }
+ }
+
+ qDeferredDebug(screenUpdates) << "; signaling dispatch source";
+
+ if (!m_displayLinkSource) {
+ m_displayLinkSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
+ dispatch_source_set_event_handler(m_displayLinkSource, ^{
+ deliverUpdateRequests();
+ });
+ dispatch_resume(m_displayLinkSource);
+ }
+
+ dispatch_source_merge_data(m_displayLinkSource, 1);
+
+ } else {
+ DeferredDebugHelper screenUpdates(lcQpaScreenUpdates());
+ qDeferredDebug(screenUpdates) << "gcd event handler on main thread";
+
+ const int pendingUpdates = m_pendingUpdates;
+ if (pendingUpdates > 1)
+ qDeferredDebug(screenUpdates) << ", " << (pendingUpdates - 1) << " frame(s) behind display link";
+
+ screenUpdates.flushOutput();
+
+ bool pauseUpdates = true;
+
+ auto windows = QGuiApplication::allWindows();
+ for (int i = 0; i < windows.size(); ++i) {
+ QWindow *window = windows.at(i);
+ QPlatformWindow *platformWindow = window->handle();
+ if (!platformWindow)
+ continue;
+
+ if (!platformWindow->hasPendingUpdateRequest())
+ continue;
+
+ if (window->screen() != screen())
+ continue;
+
+ // Skip windows that are not doing update requests via display link
+ if (!(window->format().swapInterval() > 0))
+ continue;
+
+ platformWindow->deliverUpdateRequest();
+
+ // Another update request was triggered, keep the display link running
+ if (platformWindow->hasPendingUpdateRequest())
+ pauseUpdates = false;
+ }
+
+ if (pauseUpdates) {
+ // Pause the display link if there are no pending update requests
+ qCDebug(lcQpaScreenUpdates) << "Stopping display link for" << this;
+ CVDisplayLinkStop(m_displayLink);
+ }
+
+ if (const int missedUpdates = m_pendingUpdates.fetchAndStoreRelaxed(0) - pendingUpdates) {
+ qCWarning(lcQpaScreenUpdates) << "main thread missed" << missedUpdates
+ << "update(s) from display link during update request delivery";
+ }
}
}
+bool QCocoaScreen::isRunningDisplayLink() const
+{
+ return m_displayLink && CVDisplayLinkIsRunning(m_displayLink);
+}
+
+// -----------------------------------------------------------
+
qreal QCocoaScreen::devicePixelRatio() const
{
QMacAutoReleasePool pool;
@@ -179,7 +396,7 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
// belowWindowWithWindowNumber] may return windows that are not interesting
// to Qt. The search iterates until a suitable window or no window is found.
NSInteger topWindowNumber = 0;
- QWindow *window = 0;
+ QWindow *window = nullptr;
do {
// Get the top-most window, below any previously rejected window.
topWindowNumber = [NSWindow windowNumberAtPoint:screenPoint
@@ -187,7 +404,7 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
// Continue the search if the window does not belong to this process.
NSWindow *nsWindow = [NSApp windowWithWindowNumber:topWindowNumber];
- if (nsWindow == 0)
+ if (!nsWindow)
continue;
// Continue the search if the window does not belong to Qt.
@@ -324,3 +541,12 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen)
#endif // !QT_NO_DEBUG_STREAM
QT_END_NAMESPACE
+
+@implementation NSScreen (QtExtras)
+
+- (CGDirectDisplayID)qt_displayId
+{
+ return [self.deviceDescription[@"NSScreenNumber"] unsignedIntValue];
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index bad91a2d5d..c1711e7cd4 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -45,6 +45,16 @@
#include <QtGui/qfont.h>
#include <QtGui/private/qcoregraphics_p.h>
+#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
+@interface NSColor (MojaveForwardDeclarations)
+@property (class, strong, readonly) NSColor *selectedContentBackgroundColor NS_AVAILABLE_MAC(10_14);
+@property (class, strong, readonly) NSColor *unemphasizedSelectedTextBackgroundColor NS_AVAILABLE_MAC(10_14);
+@property (class, strong, readonly) NSColor *unemphasizedSelectedTextColor NS_AVAILABLE_MAC(10_14);
+@property (class, strong, readonly) NSColor *unemphasizedSelectedContentBackgroundColor NS_AVAILABLE_MAC(10_14);
+@property (class, strong, readonly) NSArray<NSColor *> *alternatingContentBackgroundColors NS_AVAILABLE_MAC(10_14);
+@end
+#endif
+
QT_BEGIN_NAMESPACE
QPalette * qt_mac_createSystemPalette()
@@ -65,18 +75,25 @@ QPalette * qt_mac_createSystemPalette()
palette->setBrush(QPalette::Disabled, QPalette::Text, dark);
palette->setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
palette->setBrush(QPalette::Disabled, QPalette::Base, backgroundBrush);
+ palette->setBrush(QPalette::Active, QPalette::Base, backgroundBrush);
+ palette->setBrush(QPalette::Inactive, QPalette::Base, backgroundBrush);
palette->setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191));
palette->setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191));
palette->setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191));
// System palette initialization:
- palette->setBrush(QPalette::Active, QPalette::Highlight,
- qt_mac_toQBrush([NSColor selectedControlColor]));
- QBrush br = qt_mac_toQBrush([NSColor secondarySelectedControlColor]);
- palette->setBrush(QPalette::Inactive, QPalette::Highlight, br);
- palette->setBrush(QPalette::Disabled, QPalette::Highlight, br);
+ QBrush br = qt_mac_toQBrush([NSColor selectedControlColor]);
+ palette->setBrush(QPalette::Active, QPalette::Highlight, br);
+ if (__builtin_available(macOS 10.14, *)) {
+ const auto inactiveHighlight = qt_mac_toQBrush([NSColor unemphasizedSelectedContentBackgroundColor]);
+ palette->setBrush(QPalette::Inactive, QPalette::Highlight, inactiveHighlight);
+ palette->setBrush(QPalette::Disabled, QPalette::Highlight, inactiveHighlight);
+ } else {
+ palette->setBrush(QPalette::Inactive, QPalette::Highlight, br);
+ palette->setBrush(QPalette::Disabled, QPalette::Highlight, br);
+ }
- palette->setBrush(QPalette::Shadow, background.darker(170));
+ palette->setBrush(QPalette::Shadow, qt_mac_toQColor([NSColor shadowColor]));
qc = qt_mac_toQColor([NSColor controlTextColor]);
palette->setColor(QPalette::Active, QPalette::Text, qc);
@@ -98,10 +115,11 @@ QPalette * qt_mac_createSystemPalette()
struct QMacPaletteMap {
inline QMacPaletteMap(QPlatformTheme::Palette p, NSColor *a, NSColor *i) :
- paletteRole(p), active(a), inactive(i) { }
+ active(a), inactive(i), paletteRole(p) { }
+ NSColor *active;
+ NSColor *inactive;
QPlatformTheme::Palette paletteRole;
- NSColor *active, *inactive;
};
#define MAC_PALETTE_ENTRY(pal, active, inactive) \
@@ -131,7 +149,7 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
QColor qc;
for (int i = 0; i < mac_widget_colors_count; i++) {
QPalette &pal = *qt_mac_createSystemPalette();
- if (mac_widget_colors[i].active != 0) {
+ if (mac_widget_colors[i].active) {
qc = qt_mac_toQColor(mac_widget_colors[i].active);
pal.setColor(QPalette::Active, QPalette::Text, qc);
pal.setColor(QPalette::Inactive, QPalette::Text, qc);
@@ -146,7 +164,18 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
}
if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette
|| mac_widget_colors[i].paletteRole == QPlatformTheme::MenuBarPalette) {
- pal.setBrush(QPalette::Highlight, qt_mac_toQColor([NSColor selectedMenuItemColor]));
+ NSColor *selectedMenuItemColor = nil;
+ if (__builtin_available(macOS 10.14, *)) {
+ // Cheap approximation for NSVisualEffectView (see deprecation note for selectedMenuItemTextColor)
+ selectedMenuItemColor = [[NSColor selectedContentBackgroundColor] highlightWithLevel:0.4];
+ } else {
+ // selectedMenuItemColor would presumably be the correct color to use as the background
+ // for selected menu items. But that color is always blue, and doesn't follow the
+ // appearance color in system preferences. So we therefore deliberatly choose to use
+ // keyboardFocusIndicatorColor instead, which appears to have the same color value.
+ selectedMenuItemColor = [NSColor keyboardFocusIndicatorColor];
+ }
+ pal.setBrush(QPalette::Highlight, qt_mac_toQColor(selectedMenuItemColor));
qc = qt_mac_toQColor([NSColor labelColor]);
pal.setBrush(QPalette::ButtonText, qc);
pal.setBrush(QPalette::Text, qc);
@@ -164,22 +193,41 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
pal.setColor(QPalette::Active, QPalette::ButtonText,
pal.color(QPalette::Active, QPalette::Text));
} else if (mac_widget_colors[i].paletteRole == QPlatformTheme::ItemViewPalette) {
+ NSArray<NSColor *> *baseColors = nil;
+ NSColor *activeHighlightColor = nil;
+ if (__builtin_available(macOS 10.14, *)) {
+ baseColors = [NSColor alternatingContentBackgroundColors];
+ activeHighlightColor = [NSColor selectedContentBackgroundColor];
+ pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
+ qt_mac_toQBrush([NSColor unemphasizedSelectedTextColor]));
+ } else {
+ baseColors = [NSColor controlAlternatingRowBackgroundColors];
+ activeHighlightColor = [NSColor selectedControlColor];
+ pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
+ pal.brush(QPalette::Active, QPalette::Text));
+ }
+ pal.setBrush(QPalette::Base, qt_mac_toQBrush(baseColors[0]));
+ pal.setBrush(QPalette::AlternateBase, qt_mac_toQBrush(baseColors[1]));
pal.setBrush(QPalette::Active, QPalette::Highlight,
- qt_mac_toQBrush([NSColor alternateSelectedControlColor]));
+ qt_mac_toQBrush(activeHighlightColor));
pal.setBrush(QPalette::Active, QPalette::HighlightedText,
qt_mac_toQBrush([NSColor alternateSelectedControlTextColor]));
pal.setBrush(QPalette::Inactive, QPalette::Text,
- pal.brush(QPalette::Active, QPalette::Text));
- pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
- pal.brush(QPalette::Active, QPalette::Text));
+ pal.brush(QPalette::Active, QPalette::Text));
} else if (mac_widget_colors[i].paletteRole == QPlatformTheme::TextEditPalette) {
+ pal.setBrush(QPalette::Active, QPalette::Base, qt_mac_toQColor([NSColor textBackgroundColor]));
pal.setBrush(QPalette::Inactive, QPalette::Text,
pal.brush(QPalette::Active, QPalette::Text));
pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
pal.brush(QPalette::Active, QPalette::Text));
- } else if (mac_widget_colors[i].paletteRole == QPlatformTheme::TextLineEditPalette) {
+ } else if (mac_widget_colors[i].paletteRole == QPlatformTheme::TextLineEditPalette
+ || mac_widget_colors[i].paletteRole == QPlatformTheme::ComboBoxPalette) {
+ pal.setBrush(QPalette::Active, QPalette::Base, qt_mac_toQColor([NSColor textBackgroundColor]));
pal.setBrush(QPalette::Disabled, QPalette::Base,
pal.brush(QPalette::Active, QPalette::Base));
+ } else if (mac_widget_colors[i].paletteRole == QPlatformTheme::LabelPalette) {
+ qc = qt_mac_toQColor([NSColor labelColor]);
+ pal.setBrush(QPalette::Inactive, QPalette::ToolTipText, qc);
}
palettes.insert(mac_widget_colors[i].paletteRole, &pal);
}
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
index 2f1a1e42a9..d831612c22 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h
@@ -55,7 +55,7 @@ class QSystemTrayIconSys;
class Q_GUI_EXPORT QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon
{
public:
- QCocoaSystemTrayIcon() : m_sys(0) {}
+ QCocoaSystemTrayIcon() : m_sys(nullptr) {}
void init() override;
void cleanup() override;
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 5e6913a89a..0158895441 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -95,31 +95,16 @@ QT_USE_NAMESPACE
@class QT_MANGLE_NAMESPACE(QNSImageView);
@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject <NSUserNotificationCenterDelegate>
-{
-@public
- QCocoaSystemTrayIcon *systray;
- NSStatusItem *item;
- QCocoaMenu *menu;
- QIcon icon;
- QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
-}
--(id)initWithSysTray:(QCocoaSystemTrayIcon *)systray;
--(void)dealloc;
--(NSStatusItem*)item;
--(QRectF)geometry;
+@property (nonatomic, assign) QCocoaMenu *menu;
+@property (nonatomic, assign) QIcon icon;
+@property (nonatomic, readonly) NSStatusItem *item;
+@property (nonatomic, readonly) QRectF geometry;
+- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)systray;
- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton;
- (void)doubleClickSelector:(id)sender;
-- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification;
-- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification;
@end
-@interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView {
- BOOL down;
- QT_MANGLE_NAMESPACE(QNSStatusItem) *parent;
-}
--(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent;
--(void)menuTrackingDone:(NSNotification*)notification;
--(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton;
+@interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem);
@@ -162,7 +147,7 @@ QRect QCocoaSystemTrayIcon::geometry() const
void QCocoaSystemTrayIcon::cleanup()
{
delete m_sys;
- m_sys = 0;
+ m_sys = nullptr;
}
static bool heightCompareFunction (QSize a, QSize b) { return (a.height() < b.height()); }
@@ -178,7 +163,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
if (!m_sys)
return;
- m_sys->item->icon = icon;
+ m_sys->item.icon = icon;
// The reccomended maximum title bar icon height is 18 points
// (device independent pixels). The menu height on past and
@@ -249,8 +234,8 @@ void QCocoaSystemTrayIcon::updateMenu(QPlatformMenu *menu)
if (!m_sys)
return;
- m_sys->item->menu = static_cast<QCocoaMenu *>(menu);
- if (menu && [m_sys->item->menu->nsMenu() numberOfItems] > 0) {
+ m_sys->item.menu = static_cast<QCocoaMenu *>(menu);
+ if (menu && [m_sys->item.menu->nsMenu() numberOfItems] > 0) {
[[m_sys->item item] setHighlightMode:YES];
} else {
[[m_sys->item item] setHighlightMode:NO];
@@ -289,23 +274,29 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess
}
QT_END_NAMESPACE
-@implementation QNSImageView
--(id)initWithParent:(QNSStatusItem*)myParent {
+@implementation NSStatusItem (Qt)
+@end
+
+@implementation QNSImageView {
+ BOOL down;
+ QT_MANGLE_NAMESPACE(QNSStatusItem) *parent;
+}
+
+- (instancetype)initWithParent:(QNSStatusItem *)myParent {
self = [super init];
parent = myParent;
down = NO;
return self;
}
--(void)menuTrackingDone:(NSNotification*)notification
+- (void)menuTrackingDone:(NSNotification *)__unused notification
{
- Q_UNUSED(notification);
down = NO;
[self setNeedsDisplay:YES];
}
--(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton
+- (void)mousePressed:(NSEvent *)mouseEvent
{
down = YES;
int clickCount = [mouseEvent clickCount];
@@ -315,16 +306,16 @@ QT_END_NAMESPACE
[self menuTrackingDone:nil];
[parent doubleClickSelector:self];
} else {
- [parent triggerSelector:self button:mouseButton];
+ [parent triggerSelector:self button:cocoaButton2QtButton(mouseEvent)];
}
}
--(void)mouseDown:(NSEvent *)mouseEvent
+- (void)mouseDown:(NSEvent *)mouseEvent
{
- [self mousePressed:mouseEvent button:Qt::LeftButton];
+ [self mousePressed:mouseEvent];
}
--(void)mouseUp:(NSEvent *)mouseEvent
+- (void)mouseUp:(NSEvent *)mouseEvent
{
Q_UNUSED(mouseEvent);
[self menuTrackingDone:nil];
@@ -332,10 +323,10 @@ QT_END_NAMESPACE
- (void)rightMouseDown:(NSEvent *)mouseEvent
{
- [self mousePressed:mouseEvent button:Qt::RightButton];
+ [self mousePressed:mouseEvent];
}
--(void)rightMouseUp:(NSEvent *)mouseEvent
+- (void)rightMouseUp:(NSEvent *)mouseEvent
{
Q_UNUSED(mouseEvent);
[self menuTrackingDone:nil];
@@ -343,29 +334,36 @@ QT_END_NAMESPACE
- (void)otherMouseDown:(NSEvent *)mouseEvent
{
- [self mousePressed:mouseEvent button:cocoaButton2QtButton([mouseEvent buttonNumber])];
+ [self mousePressed:mouseEvent];
}
--(void)otherMouseUp:(NSEvent *)mouseEvent
+- (void)otherMouseUp:(NSEvent *)mouseEvent
{
Q_UNUSED(mouseEvent);
[self menuTrackingDone:nil];
}
--(void)drawRect:(NSRect)rect {
+- (void)drawRect:(NSRect)rect {
[[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down];
[super drawRect:rect];
}
@end
-@implementation QNSStatusItem
+@implementation QNSStatusItem {
+ QCocoaSystemTrayIcon *systray;
+ NSStatusItem *item;
+ QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
+}
+
+@synthesize menu = menu;
+@synthesize icon = icon;
--(id)initWithSysTray:(QCocoaSystemTrayIcon *)sys
+- (instancetype)initWithSysTray:(QCocoaSystemTrayIcon *)sys
{
self = [super init];
if (self) {
item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
- menu = 0;
+ menu = nullptr;
systray = sys;
imageCell = [[QNSImageView alloc] initWithParent:self];
[item setView: imageCell];
@@ -373,19 +371,19 @@ QT_END_NAMESPACE
return self;
}
--(void)dealloc {
+- (void)dealloc {
[[NSStatusBar systemStatusBar] removeStatusItem:item];
[[NSNotificationCenter defaultCenter] removeObserver:imageCell];
[imageCell release];
[item release];
[super dealloc];
-
}
--(NSStatusItem*)item {
+- (NSStatusItem *)item {
return item;
}
--(QRectF)geometry {
+
+- (QRectF)geometry {
if (NSWindow *window = [[item view] window]) {
if (QCocoaScreen *screen = QCocoaIntegration::instance()->screenForNSScreen([window screen]))
return screen->mapFromNative([window frame]);
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index 69eaf8db56..c42fa7d2e8 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -43,7 +43,7 @@
#include <QtCore/QHash>
#include <qpa/qplatformtheme.h>
-Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver));
+Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaThemeAppAppearanceObserver));
QT_BEGIN_NAMESPACE
@@ -78,11 +78,13 @@ public:
static const char *name;
+ void handleSystemThemeChange();
+
private:
mutable QPalette *m_systemPalette;
mutable QHash<QPlatformTheme::Palette, QPalette*> m_palettes;
mutable QHash<QPlatformTheme::Font, QFont*> m_fonts;
- mutable QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) *m_notificationReceiver;
+ QT_MANGLE_NAMESPACE(QCocoaThemeAppAppearanceObserver) *m_appearanceObserver;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 93f0400916..a2229159b5 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -42,6 +42,7 @@
#include "qcocoatheme.h"
#include "messages.h"
+#include <QtCore/QOperatingSystemVersion>
#include <QtCore/QVariant>
#include "qcocoasystemsettings.h"
@@ -75,30 +76,50 @@
#endif
#endif
-#include <Carbon/Carbon.h>
+#include <CoreServices/CoreServices.h>
-@interface QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) : NSObject {
-QCocoaTheme *mPrivate;
-}
-- (id)initWithPrivate:(QCocoaTheme *)priv;
-- (void)systemColorsDidChange:(NSNotification *)notification;
+#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
+@interface NSApplication (MojaveForwardDeclarations)
+@property (readonly, strong) NSAppearance *effectiveAppearance NS_AVAILABLE_MAC(10_14);
@end
+#endif
-QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaThemeNotificationReceiver);
+@interface QT_MANGLE_NAMESPACE(QCocoaThemeAppAppearanceObserver) : NSObject
+@property (readonly, nonatomic) QCocoaTheme *theme;
+- (instancetype)initWithTheme:(QCocoaTheme *)theme;
+@end
-@implementation QCocoaThemeNotificationReceiver
-- (id)initWithPrivate:(QCocoaTheme *)priv
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaThemeAppAppearanceObserver);
+
+@implementation QCocoaThemeAppAppearanceObserver
+- (instancetype)initWithTheme:(QCocoaTheme *)theme
{
- self = [super init];
- mPrivate = priv;
+ if ((self = [super init])) {
+ _theme = theme;
+ [NSApp addObserver:self forKeyPath:@"effectiveAppearance" options:NSKeyValueObservingOptionNew context:nullptr];
+ }
return self;
}
-- (void)systemColorsDidChange:(NSNotification *)notification
+- (void)dealloc
{
- Q_UNUSED(notification);
- mPrivate->reset();
- QWindowSystemInterface::handleThemeChange(nullptr);
+ [NSApp removeObserver:self forKeyPath:@"effectiveAppearance"];
+ [super dealloc];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
+ change:(NSDictionary<NSKeyValueChangeKey, id> *)change context:(void *)context
+{
+ Q_UNUSED(change);
+ Q_UNUSED(context);
+
+ Q_ASSERT(object == NSApp);
+ Q_ASSERT([keyPath isEqualToString:@"effectiveAppearance"]);
+
+ if (__builtin_available(macOS 10.14, *))
+ NSAppearance.currentAppearance = NSApp.effectiveAppearance;
+
+ self.theme->handleSystemThemeChange();
}
@end
@@ -107,19 +128,22 @@ QT_BEGIN_NAMESPACE
const char *QCocoaTheme::name = "cocoa";
QCocoaTheme::QCocoaTheme()
- :m_systemPalette(0)
+ : m_systemPalette(nullptr), m_appearanceObserver(nil)
{
- m_notificationReceiver = [[QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) alloc] initWithPrivate:this];
- [[NSNotificationCenter defaultCenter] addObserver:m_notificationReceiver
- selector:@selector(systemColorsDidChange:)
- name:NSSystemColorsDidChangeNotification
- object:nil];
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave)
+ m_appearanceObserver = [[QCocoaThemeAppAppearanceObserver alloc] initWithTheme:this];
+
+ [[NSNotificationCenter defaultCenter] addObserverForName:NSSystemColorsDidChangeNotification
+ object:nil queue:nil usingBlock:^(NSNotification *) {
+ handleSystemThemeChange();
+ }];
}
QCocoaTheme::~QCocoaTheme()
{
- [[NSNotificationCenter defaultCenter] removeObserver:m_notificationReceiver];
- [m_notificationReceiver release];
+ if (m_appearanceObserver)
+ [m_appearanceObserver release];
+
reset();
qDeleteAll(m_fonts);
}
@@ -132,6 +156,15 @@ void QCocoaTheme::reset()
m_palettes.clear();
}
+void QCocoaTheme::handleSystemThemeChange()
+{
+ reset();
+ m_systemPalette = qt_mac_createSystemPalette();
+ m_palettes = qt_mac_createRolePalettes();
+
+ QWindowSystemInterface::handleThemeChange(nullptr);
+}
+
bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const
{
if (dialogType == QPlatformTheme::FileDialog)
@@ -147,7 +180,7 @@ bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const
return false;
}
-QPlatformDialogHelper * QCocoaTheme::createPlatformDialogHelper(DialogType dialogType) const
+QPlatformDialogHelper *QCocoaTheme::createPlatformDialogHelper(DialogType dialogType) const
{
switch (dialogType) {
#if defined(QT_WIDGETS_LIB) && QT_CONFIG(filedialog)
@@ -163,7 +196,7 @@ QPlatformDialogHelper * QCocoaTheme::createPlatformDialogHelper(DialogType dialo
return new QCocoaFontDialogHelper();
#endif
default:
- return 0;
+ return nullptr;
}
}
@@ -183,9 +216,9 @@ const QPalette *QCocoaTheme::palette(Palette type) const
} else {
if (m_palettes.isEmpty())
m_palettes = qt_mac_createRolePalettes();
- return m_palettes.value(type, 0);
+ return m_palettes.value(type, nullptr);
}
- return 0;
+ return nullptr;
}
QHash<QPlatformTheme::Font, QFont *> qt_mac_createRoleFonts()
@@ -199,7 +232,7 @@ const QFont *QCocoaTheme::font(Font type) const
if (m_fonts.isEmpty()) {
m_fonts = qt_mac_createRoleFonts();
}
- return m_fonts.value(type, 0);
+ return m_fonts.value(type, nullptr);
}
//! \internal
diff --git a/src/plugins/platforms/cocoa/qcocoavulkaninstance.h b/src/plugins/platforms/cocoa/qcocoavulkaninstance.h
new file mode 100644
index 0000000000..5fe6a612af
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoavulkaninstance.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOAVULKANINSTANCE_H
+#define QCOCOAVULKANINSTANCE_H
+
+// Include mvk_vulkan.h first. The order is important since
+// mvk_vulkan.h just defines VK_USE_PLATFORM_MACOS_MVK (or the IOS
+// variant) and includes vulkan.h. If something else included vulkan.h
+// before this then we wouldn't get the MVK specifics...
+#include <MoltenVK/mvk_vulkan.h>
+
+#include <QtCore/QHash>
+#include <QtVulkanSupport/private/qbasicvulkanplatforminstance_p.h>
+
+#include <AppKit/AppKit.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaVulkanInstance : public QBasicPlatformVulkanInstance
+{
+public:
+ QCocoaVulkanInstance(QVulkanInstance *instance);
+ ~QCocoaVulkanInstance();
+
+ void createOrAdoptInstance() override;
+
+ VkSurfaceKHR *createSurface(QWindow *window);
+ VkSurfaceKHR createSurface(NSView *view);
+private:
+ QVulkanInstance *m_instance = nullptr;
+ QLibrary m_lib;
+ VkSurfaceKHR m_nullSurface = nullptr;
+ PFN_vkCreateMacOSSurfaceMVK m_createSurface = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QXCBVULKANINSTANCE_H
diff --git a/src/plugins/platforms/cocoa/qcocoavulkaninstance.mm b/src/plugins/platforms/cocoa/qcocoavulkaninstance.mm
new file mode 100644
index 0000000000..b00fde6c6f
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoavulkaninstance.mm
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoavulkaninstance.h"
+#include "qcocoawindow.h"
+
+QT_BEGIN_NAMESPACE
+
+QCocoaVulkanInstance::QCocoaVulkanInstance(QVulkanInstance *instance)
+ : m_instance(instance)
+{
+ loadVulkanLibrary(QStringLiteral("vulkan"));
+}
+
+QCocoaVulkanInstance::~QCocoaVulkanInstance()
+{
+}
+
+void QCocoaVulkanInstance::createOrAdoptInstance()
+{
+ initInstance(m_instance, QByteArrayList());
+}
+
+VkSurfaceKHR *QCocoaVulkanInstance::createSurface(QWindow *window)
+{
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow->m_vulkanSurface)
+ destroySurface(cocoaWindow->m_vulkanSurface);
+ cocoaWindow->m_vulkanSurface = createSurface(cocoaWindow->m_view);
+ return &cocoaWindow->m_vulkanSurface;
+}
+
+VkSurfaceKHR QCocoaVulkanInstance::createSurface(NSView *view)
+{
+ if (!m_createSurface) {
+ m_createSurface = reinterpret_cast<PFN_vkCreateMacOSSurfaceMVK>(
+ m_vkGetInstanceProcAddr(m_vkInst, "vkCreateMacOSSurfaceMVK"));
+ }
+ if (!m_createSurface) {
+ qWarning("Failed to find vkCreateMacOSSurfaceMVK");
+ return m_nullSurface;
+ }
+
+ VkMacOSSurfaceCreateInfoMVK surfaceInfo;
+ surfaceInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
+ surfaceInfo.pNext = nullptr;
+ surfaceInfo.flags = 0;
+ surfaceInfo.pView = view;
+
+ VkSurfaceKHR surface = nullptr;
+ VkResult err = m_createSurface(m_vkInst, &surfaceInfo, nullptr, &surface);
+ if (err != VK_SUCCESS)
+ qWarning("Failed to create Vulkan surface: %d", err);
+
+ return surface;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index fb91c53a7a..8f1bdb8af0 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -53,6 +53,10 @@
#include "qnswindow.h"
#include "qt_mac_p.h"
+#if QT_CONFIG(vulkan)
+#include <MoltenVK/mvk_vulkan.h>
+#endif
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_DEBUG_STREAM
@@ -112,6 +116,7 @@ public:
void raise() override;
void lower() override;
bool isExposed() const override;
+ bool isEmbedded() const override;
bool isOpaque() const;
void propagateSizeHints() override;
void setOpacity(qreal level) override;
@@ -124,6 +129,8 @@ public:
bool isForeignWindow() const override;
void requestUpdate() override;
+ void deliverUpdateRequest() override;
+
void requestActivateWindow() override;
WId winId() const override;
@@ -132,7 +139,7 @@ public:
NSView *view() const;
NSWindow *nativeWindow() const;
- void setEmbeddedInForeignView(bool subwindow);
+ void setEmbeddedInForeignView();
Q_NOTIFICATION_HANDLER(NSViewFrameDidChangeNotification) void viewDidChangeFrame();
Q_NOTIFICATION_HANDLER(NSViewGlobalFrameDidChangeNotification) void viewDidChangeGlobalFrame();
@@ -162,11 +169,6 @@ public:
NSUInteger windowStyleMask(Qt::WindowFlags flags);
void setWindowZoomButton(Qt::WindowFlags flags);
-#ifndef QT_NO_OPENGL
- void setCurrentContext(QCocoaGLContext *context);
- QCocoaGLContext *currentContext() const;
-#endif
-
bool setWindowModified(bool modified) override;
void setFrameStrutEventsEnabled(bool enabled) override;
@@ -237,11 +239,6 @@ public: // for QNSView
NSView *m_view;
QCocoaNSWindow *m_nsWindow;
- // TODO merge to one variable if possible
- bool m_viewIsEmbedded; // true if the m_view is actually embedded in a "foreign" NSView hiearchy
- bool m_viewIsToBeEmbedded; // true if the m_view is intended to be embedded in a "foreign" NSView hiearchy
-
- Qt::WindowFlags m_windowFlags;
Qt::WindowStates m_lastReportedWindowState;
Qt::WindowModality m_windowModality;
QPointer<QWindow> m_enterLeaveTargetWindow;
@@ -251,9 +248,6 @@ public: // for QNSView
bool m_inSetVisible;
bool m_inSetGeometry;
bool m_inSetStyleMask;
-#ifndef QT_NO_OPENGL
- QCocoaGLContext *m_glContext;
-#endif
QCocoaMenuBar *m_menubar;
bool m_needsInvalidateShadow;
@@ -283,6 +277,10 @@ public: // for QNSView
};
QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false)
+
+#if QT_CONFIG(vulkan)
+ VkSurfaceKHR m_vulkanSurface = nullptr;
+#endif
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 9b10c8b053..1de8577ebe 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -117,24 +117,19 @@ static void qRegisterNotificationCallbacks()
return;
}
- if (lcCocoaNotifications().isDebugEnabled()) {
- if (cocoaWindows.isEmpty()) {
- qCDebug(lcCocoaNotifications) << "Could not find forwarding target for" <<
- qPrintable(notificationName) << "from" << notification.object;
- } else {
- QVector<QCocoaWindow *> debugWindows;
- for (QCocoaWindow *cocoaWindow : cocoaWindows)
- debugWindows += cocoaWindow;
- qCDebug(lcCocoaNotifications) << "Forwarding" << qPrintable(notificationName) <<
- "to" << debugWindows;
- }
+ if (lcCocoaNotifications().isDebugEnabled() && !cocoaWindows.isEmpty()) {
+ QVector<QCocoaWindow *> debugWindows;
+ for (QCocoaWindow *cocoaWindow : cocoaWindows)
+ debugWindows += cocoaWindow;
+ qCDebug(lcCocoaNotifications) << "Forwarding" << qPrintable(notificationName) <<
+ "to" << debugWindows;
}
// FIXME: Could be a foreign window, look up by iterating top level QWindows
for (QCocoaWindow *cocoaWindow : cocoaWindows) {
if (!method.invoke(cocoaWindow, Qt::DirectConnection)) {
- qCWarning(lcQpaCocoaWindow) << "Failed to invoke NSNotification callback for"
+ qCWarning(lcQpaWindow) << "Failed to invoke NSNotification callback for"
<< notification.name << "on" << cocoaWindow;
}
}
@@ -148,9 +143,7 @@ const int QCocoaWindow::NoAlertRequest = -1;
QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle)
: QPlatformWindow(win)
, m_view(nil)
- , m_nsWindow(0)
- , m_viewIsEmbedded(false)
- , m_viewIsToBeEmbedded(false)
+ , m_nsWindow(nil)
, m_lastReportedWindowState(Qt::WindowNoState)
, m_windowModality(Qt::NonModal)
, m_windowUnderMouse(false)
@@ -158,10 +151,7 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle)
, m_inSetVisible(false)
, m_inSetGeometry(false)
, m_inSetStyleMask(false)
-#ifndef QT_NO_OPENGL
- , m_glContext(0)
-#endif
- , m_menubar(0)
+ , m_menubar(nullptr)
, m_needsInvalidateShadow(false)
, m_hasModalSession(false)
, m_frameStrutEventsEnabled(false)
@@ -173,7 +163,7 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle)
, m_topContentBorderThickness(0)
, m_bottomContentBorderThickness(0)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::QCocoaWindow" << window();
+ qCDebug(lcQpaWindow) << "QCocoaWindow::QCocoaWindow" << window();
if (nativeHandle) {
m_view = reinterpret_cast<NSView *>(nativeHandle);
@@ -183,41 +173,24 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle)
void QCocoaWindow::initialize()
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::initialize" << window();
+ qCDebug(lcQpaWindow) << "QCocoaWindow::initialize" << window();
QMacAutoReleasePool pool;
- if (!m_view) {
+ if (!m_view)
m_view = [[QNSView alloc] initWithCocoaWindow:this];
- // Enable high-dpi OpenGL for retina displays. Enabling has the side
- // effect that Cocoa will start calling glViewport(0, 0, width, height),
- // overriding any glViewport calls in application code. This is usually not a
- // problem, except if the appilcation wants to have a "custom" viewport.
- // (like the hellogl example)
- if (window()->supportsOpenGL()) {
- BOOL enable = qt_mac_resolveOption(YES, window(), "_q_mac_wantsBestResolutionOpenGLSurface",
- "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE");
- [m_view setWantsBestResolutionOpenGLSurface:enable];
- // See also QCocoaGLContext::makeCurrent for software renderer workarounds.
- }
- BOOL enable = qt_mac_resolveOption(NO, window(), "_q_mac_wantsLayer",
- "QT_MAC_WANTS_LAYER");
- [m_view setWantsLayer:enable];
- }
setGeometry(initialGeometry(window(), windowGeometry(), defaultWindowWidth, defaultWindowHeight));
recreateWindowIfNeeded();
window()->setGeometry(geometry());
- if (window()->isTopLevel())
- setWindowIcon(window()->icon());
m_initialized = true;
}
QCocoaWindow::~QCocoaWindow()
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::~QCocoaWindow" << window();
+ qCDebug(lcQpaWindow) << "QCocoaWindow::~QCocoaWindow" << window();
QMacAutoReleasePool pool;
[m_nsWindow makeFirstResponder:nil];
@@ -232,10 +205,16 @@ QCocoaWindow::~QCocoaWindow()
if (!isForeignWindow())
[[NSNotificationCenter defaultCenter] removeObserver:m_view];
- // While it is unlikely that this window will be in the popup stack
- // during deletetion we clear any pointers here to make sure.
- if (QCocoaIntegration::instance()) {
- QCocoaIntegration::instance()->popupWindowStack()->removeAll(this);
+ if (QCocoaIntegration *cocoaIntegration = QCocoaIntegration::instance()) {
+ // While it is unlikely that this window will be in the popup stack
+ // during deletetion we clear any pointers here to make sure.
+ cocoaIntegration->popupWindowStack()->removeAll(this);
+
+#if QT_CONFIG(vulkan)
+ auto vulcanInstance = cocoaIntegration->getCocoaVulkanInstance();
+ if (vulcanInstance)
+ vulcanInstance->destroySurface(m_vulkanSurface);
+#endif
}
[m_view release];
@@ -255,7 +234,7 @@ QSurfaceFormat QCocoaWindow::format() const
void QCocoaWindow::setGeometry(const QRect &rectIn)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setGeometry" << window() << rectIn;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::setGeometry" << window() << rectIn;
QBoolBlocker inSetGeometry(m_inSetGeometry, true);
@@ -283,7 +262,7 @@ QRect QCocoaWindow::geometry() const
// QWindows that are embedded in a NSView hiearchy may be considered
// top-level from Qt's point of view but are not from Cocoa's point
// of view. Embedded QWindows get global (screen) geometry.
- if (m_viewIsEmbedded) {
+ if (isEmbedded()) {
NSPoint windowPoint = [m_view convertPoint:NSMakePoint(0, 0) toView:nil];
NSRect screenRect = [[m_view window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
NSPoint screenPoint = screenRect.origin;
@@ -297,12 +276,12 @@ QRect QCocoaWindow::geometry() const
void QCocoaWindow::setCocoaGeometry(const QRect &rect)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setCocoaGeometry" << window() << rect;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::setCocoaGeometry" << window() << rect;
QMacAutoReleasePool pool;
QPlatformWindow::setGeometry(rect);
- if (m_viewIsEmbedded) {
+ if (isEmbedded()) {
if (!isForeignWindow()) {
[m_view setFrame:NSMakeRect(0, 0, rect.width(), rect.height())];
}
@@ -321,12 +300,12 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
void QCocoaWindow::setVisible(bool visible)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setVisible" << window() << visible;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::setVisible" << window() << visible;
m_inSetVisible = true;
QMacAutoReleasePool pool;
- QCocoaWindow *parentCocoaWindow = 0;
+ QCocoaWindow *parentCocoaWindow = nullptr;
if (window()->transientParent())
parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle());
@@ -355,9 +334,9 @@ void QCocoaWindow::setVisible(bool visible)
// Since this isn't a native popup, the window manager doesn't close the popup when you click outside
NSWindow *nativeParentWindow = parentCocoaWindow->nativeWindow();
NSUInteger parentStyleMask = nativeParentWindow.styleMask;
- if ((m_resizableTransientParent = (parentStyleMask & NSResizableWindowMask))
- && !(nativeParentWindow.styleMask & NSFullScreenWindowMask))
- nativeParentWindow.styleMask &= ~NSResizableWindowMask;
+ if ((m_resizableTransientParent = (parentStyleMask & NSWindowStyleMaskResizable))
+ && !(nativeParentWindow.styleMask & NSWindowStyleMaskFullScreen))
+ nativeParentWindow.styleMask &= ~NSWindowStyleMaskResizable;
}
}
@@ -378,13 +357,13 @@ void QCocoaWindow::setVisible(bool visible)
} else if (window()->modality() != Qt::NonModal) {
// show the window as application modal
QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
- Q_ASSERT(cocoaEventDispatcher != 0);
+ Q_ASSERT(cocoaEventDispatcher);
QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
cocoaEventDispatcherPrivate->beginModalSession(window());
m_hasModalSession = true;
} else if ([m_view.window canBecomeKeyWindow]) {
QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
- QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = 0;
+ QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr;
if (cocoaEventDispatcher)
cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
@@ -402,12 +381,15 @@ void QCocoaWindow::setVisible(bool visible)
((NSPanel *)m_view.window).worksWhenModal = YES;
if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) {
removeMonitor();
- monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) {
- QPointF localPoint = QCocoaScreen::mapFromNative([NSEvent mouseLocation]);
- const auto button = e.type == NSEventTypeMouseMoved ? Qt::NoButton : cocoaButton2QtButton([e buttonNumber]);
- const auto eventType = e.type == NSEventTypeMouseMoved ? QEvent::MouseMove : QEvent::MouseButtonPress;
- QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint,
- Qt::MouseButtons(uint(NSEvent.pressedMouseButtons & 0xFFFF)), button, eventType);
+ NSEventMask eventMask = NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown
+ | NSEventMaskOtherMouseDown | NSEventMaskMouseMoved;
+ monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *e) {
+ const auto button = cocoaButton2QtButton(e);
+ const auto buttons = currentlyPressedMouseButtons();
+ const auto eventType = cocoaEvent2QtMouseEvent(e);
+ const auto globalPoint = QCocoaScreen::mapFromNative(NSEvent.mouseLocation);
+ const auto localPoint = window()->mapFromGlobal(globalPoint.toPoint());
+ QWindowSystemInterface::handleMouseEvent(window(), localPoint, globalPoint, buttons, button, eventType);
}];
}
}
@@ -420,12 +402,8 @@ void QCocoaWindow::setVisible(bool visible)
[m_view setHidden:NO];
} else {
// qDebug() << "close" << this;
-#ifndef QT_NO_OPENGL
- if (m_glContext)
- m_glContext->windowWasHidden();
-#endif
QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
- QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = 0;
+ QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr;
if (cocoaEventDispatcher)
cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
if (isContentView()) {
@@ -463,9 +441,9 @@ void QCocoaWindow::setVisible(bool visible)
if (parentCocoaWindow && window()->type() == Qt::Popup) {
NSWindow *nativeParentWindow = parentCocoaWindow->nativeWindow();
if (m_resizableTransientParent
- && !(nativeParentWindow.styleMask & NSFullScreenWindowMask))
+ && !(nativeParentWindow.styleMask & NSWindowStyleMaskFullScreen))
// A window should not be resizable while a transient popup is open
- nativeParentWindow.styleMask |= NSResizableWindowMask;
+ nativeParentWindow.styleMask |= NSWindowStyleMaskResizable;
}
}
@@ -493,7 +471,8 @@ NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags)
// Any "special" window should be in at least the same level as its parent.
if (type != Qt::Window) {
const QWindow * const transientParent = window()->transientParent();
- const QCocoaWindow * const transientParentWindow = transientParent ? static_cast<QCocoaWindow *>(transientParent->handle()) : 0;
+ const QCocoaWindow * const transientParentWindow = transientParent ?
+ static_cast<QCocoaWindow *>(transientParent->handle()) : nullptr;
if (transientParentWindow)
windowLevel = qMax([transientParentWindow->nativeWindow() level], windowLevel);
}
@@ -507,39 +486,39 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
const bool frameless = (flags & Qt::FramelessWindowHint) || windowIsPopupType(type);
// Remove zoom button by disabling resize for CustomizeWindowHint windows, except for
- // Qt::Tool windows (e.g. dock windows) which should always be resizeable.
- const bool resizeable = !(flags & Qt::CustomizeWindowHint) || (type == Qt::Tool);
+ // Qt::Tool windows (e.g. dock windows) which should always be resizable.
+ const bool resizable = !(flags & Qt::CustomizeWindowHint) || (type == Qt::Tool);
// Select base window type. Note that the value of NSBorderlessWindowMask is 0.
- NSUInteger styleMask = (frameless || !resizeable) ? NSBorderlessWindowMask : NSResizableWindowMask;
+ NSUInteger styleMask = (frameless || !resizable) ? NSWindowStyleMaskBorderless : NSWindowStyleMaskResizable;
if (frameless) {
// No further customizations for frameless since there are no window decorations.
} else if (flags & Qt::CustomizeWindowHint) {
if (flags & Qt::WindowTitleHint)
- styleMask |= NSTitledWindowMask;
+ styleMask |= NSWindowStyleMaskTitled;
if (flags & Qt::WindowCloseButtonHint)
- styleMask |= NSClosableWindowMask;
+ styleMask |= NSWindowStyleMaskClosable;
if (flags & Qt::WindowMinimizeButtonHint)
- styleMask |= NSMiniaturizableWindowMask;
+ styleMask |= NSWindowStyleMaskMiniaturizable;
if (flags & Qt::WindowMaximizeButtonHint)
- styleMask |= NSResizableWindowMask;
+ styleMask |= NSWindowStyleMaskResizable;
} else {
- styleMask |= NSClosableWindowMask | NSTitledWindowMask;
+ styleMask |= NSWindowStyleMaskClosable | NSWindowStyleMaskTitled;
if (type != Qt::Dialog)
- styleMask |= NSMiniaturizableWindowMask;
+ styleMask |= NSWindowStyleMaskMiniaturizable;
}
if (type == Qt::Tool)
- styleMask |= NSUtilityWindowMask;
+ styleMask |= NSWindowStyleMaskUtilityWindow;
if (m_drawContentBorderGradient)
- styleMask |= NSTexturedBackgroundWindowMask;
+ styleMask |= NSWindowStyleMaskTexturedBackground;
// Don't wipe fullscreen state
- if (m_view.window.styleMask & NSFullScreenWindowMask)
- styleMask |= NSFullScreenWindowMask;
+ if (m_view.window.styleMask & NSWindowStyleMaskFullScreen)
+ styleMask |= NSWindowStyleMaskFullScreen;
return styleMask;
}
@@ -562,54 +541,283 @@ void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags)
void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (isContentView()) {
- // While setting style mask we can have handleGeometryChange calls on a content
- // view with null geometry, reporting an invalid coordinates as a result.
- m_inSetStyleMask = true;
- m_view.window.styleMask = windowStyleMask(flags);
- m_inSetStyleMask = false;
- m_view.window.level = this->windowLevel(flags);
-
- m_view.window.hasShadow = !(flags & Qt::NoDropShadowWindowHint);
-
- if (!(flags & Qt::FramelessWindowHint))
- setWindowTitle(window()->title());
-
- Qt::WindowType type = window()->type();
- if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) {
- NSWindowCollectionBehavior behavior = m_view.window.collectionBehavior;
- if ((flags & Qt::WindowFullscreenButtonHint) || m_view.window.qt_fullScreen) {
- behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
- behavior &= ~NSWindowCollectionBehaviorFullScreenAuxiliary;
- } else {
- behavior |= NSWindowCollectionBehaviorFullScreenAuxiliary;
- behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
- }
- m_view.window.collectionBehavior = behavior;
+ if (!isContentView())
+ return;
+
+ // While setting style mask we can have handleGeometryChange calls on a content
+ // view with null geometry, reporting an invalid coordinates as a result.
+ m_inSetStyleMask = true;
+ m_view.window.styleMask = windowStyleMask(flags);
+ m_inSetStyleMask = false;
+
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+ if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) {
+ NSWindowCollectionBehavior behavior = m_view.window.collectionBehavior;
+ if ((flags & Qt::WindowFullscreenButtonHint) || m_view.window.qt_fullScreen) {
+ behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
+ behavior &= ~NSWindowCollectionBehaviorFullScreenAuxiliary;
+ } else {
+ behavior |= NSWindowCollectionBehaviorFullScreenAuxiliary;
+ behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
}
- setWindowZoomButton(flags);
-
- // Make window ignore mouse events if WindowTransparentForInput is set.
- // Note that ignoresMouseEvents has a special initial state where events
- // are ignored (passed through) based on window transparency, and that
- // setting the property to false does not return us to that state. Instead,
- // this makes the window capture all mouse events. Take care to only
- // set the property if needed. FIXME: recreate window if needed or find
- // some other way to implement WindowTransparentForInput.
- bool ignoreMouse = flags & Qt::WindowTransparentForInput;
- if (m_view.window.ignoresMouseEvents != ignoreMouse)
- m_view.window.ignoresMouseEvents = ignoreMouse;
+ m_view.window.collectionBehavior = behavior;
}
- m_windowFlags = flags;
+ // Set styleMask and collectionBehavior before applying window level, as
+ // the window level change will trigger verification of the two properties.
+ m_view.window.level = this->windowLevel(flags);
+
+ m_view.window.hasShadow = !(flags & Qt::NoDropShadowWindowHint);
+
+ if (!(flags & Qt::FramelessWindowHint))
+ setWindowTitle(window()->title());
+
+ setWindowZoomButton(flags);
+
+ // Make window ignore mouse events if WindowTransparentForInput is set.
+ // Note that ignoresMouseEvents has a special initial state where events
+ // are ignored (passed through) based on window transparency, and that
+ // setting the property to false does not return us to that state. Instead,
+ // this makes the window capture all mouse events. Take care to only
+ // set the property if needed. FIXME: recreate window if needed or find
+ // some other way to implement WindowTransparentForInput.
+ bool ignoreMouse = flags & Qt::WindowTransparentForInput;
+ if (m_view.window.ignoresMouseEvents != ignoreMouse)
+ m_view.window.ignoresMouseEvents = ignoreMouse;
}
+// ----------------------- Window state -----------------------
+
+/*!
+ Changes the state of the NSWindow, going in/out of minimize/zoomed/fullscreen
+
+ When this is called from QWindow::setWindowState(), the QWindow state has not been
+ updated yet, so window()->windowState() will reflect the previous state that was
+ reported to QtGui.
+*/
void QCocoaWindow::setWindowState(Qt::WindowStates state)
{
if (window()->isVisible())
applyWindowState(state); // Window state set for hidden windows take effect when show() is called
}
+void QCocoaWindow::applyWindowState(Qt::WindowStates requestedState)
+{
+ if (!isContentView())
+ return;
+
+ const Qt::WindowState currentState = windowState();
+ const Qt::WindowState newState = QWindowPrivate::effectiveState(requestedState);
+
+ if (newState == currentState)
+ return;
+
+ qCDebug(lcQpaWindow) << "Applying" << newState << "to" << window() << "in" << currentState;
+
+ const NSSize contentSize = m_view.frame.size;
+ if (contentSize.width <= 0 || contentSize.height <= 0) {
+ // If content view width or height is 0 then the window animations will crash so
+ // do nothing. We report the current state back to reflect the failed operation.
+ qWarning("invalid window content view size, check your window geometry");
+ handleWindowStateChanged(HandleUnconditionally);
+ return;
+ }
+
+ const NSWindow *nsWindow = m_view.window;
+
+ if (nsWindow.styleMask & NSWindowStyleMaskUtilityWindow
+ && newState & (Qt::WindowMinimized | Qt::WindowFullScreen)) {
+ qWarning() << window()->type() << "windows can not be made" << newState;
+ handleWindowStateChanged(HandleUnconditionally);
+ return;
+ }
+
+ const id sender = nsWindow;
+
+ // First we need to exit states that can't transition directly to other states
+ switch (currentState) {
+ case Qt::WindowMinimized:
+ [nsWindow deminiaturize:sender];
+ Q_ASSERT_X(windowState() != Qt::WindowMinimized, "QCocoaWindow",
+ "[NSWindow deminiaturize:] is synchronous");
+ break;
+ case Qt::WindowFullScreen: {
+ toggleFullScreen();
+ // Exiting fullscreen is not synchronous, so we need to wait for the
+ // NSWindowDidExitFullScreenNotification before continuing to apply
+ // the new state.
+ return;
+ }
+ default:;
+ }
+
+ // Then we apply the new state if needed
+ if (newState == windowState())
+ return;
+
+ switch (newState) {
+ case Qt::WindowFullScreen:
+ toggleFullScreen();
+ break;
+ case Qt::WindowMaximized:
+ toggleMaximized();
+ break;
+ case Qt::WindowMinimized:
+ [nsWindow miniaturize:sender];
+ break;
+ case Qt::WindowNoState:
+ if (windowState() == Qt::WindowMaximized)
+ toggleMaximized();
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+}
+
+Qt::WindowState QCocoaWindow::windowState() const
+{
+ // FIXME: Support compound states (Qt::WindowStates)
+
+ NSWindow *window = m_view.window;
+ if (window.miniaturized)
+ return Qt::WindowMinimized;
+ if (window.qt_fullScreen)
+ return Qt::WindowFullScreen;
+ if ((window.zoomed && !isTransitioningToFullScreen())
+ || (m_lastReportedWindowState == Qt::WindowMaximized && isTransitioningToFullScreen()))
+ return Qt::WindowMaximized;
+
+ // Note: We do not report Qt::WindowActive, even if isActive()
+ // is true, as QtGui does not expect this window state to be set.
+
+ return Qt::WindowNoState;
+}
+
+void QCocoaWindow::toggleMaximized()
+{
+ const NSWindow *window = m_view.window;
+
+ // The NSWindow needs to be resizable, otherwise the window will
+ // not be possible to zoom back to non-zoomed state.
+ const bool wasResizable = window.styleMask & NSWindowStyleMaskResizable;
+ window.styleMask |= NSWindowStyleMaskResizable;
+
+ const id sender = window;
+ [window zoom:sender];
+
+ if (!wasResizable)
+ window.styleMask &= ~NSWindowStyleMaskResizable;
+}
+
+void QCocoaWindow::toggleFullScreen()
+{
+ const NSWindow *window = m_view.window;
+
+ // The window needs to have the correct collection behavior for the
+ // toggleFullScreen call to have an effect. The collection behavior
+ // will be reset in windowDidEnterFullScreen/windowDidLeaveFullScreen.
+ window.collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
+
+ const id sender = window;
+ [window toggleFullScreen:sender];
+}
+
+void QCocoaWindow::windowWillEnterFullScreen()
+{
+ if (!isContentView())
+ return;
+
+ // The NSWindow needs to be resizable, otherwise we'll end up with
+ // the normal window geometry, centered in the middle of the screen
+ // on a black background. The styleMask will be reset below.
+ m_view.window.styleMask |= NSWindowStyleMaskResizable;
+}
+
+bool QCocoaWindow::isTransitioningToFullScreen() const
+{
+ NSWindow *window = m_view.window;
+ return window.styleMask & NSWindowStyleMaskFullScreen && !window.qt_fullScreen;
+}
+
+void QCocoaWindow::windowDidEnterFullScreen()
+{
+ if (!isContentView())
+ return;
+
+ Q_ASSERT_X(m_view.window.qt_fullScreen, "QCocoaWindow",
+ "FullScreen category processes window notifications first");
+
+ // Reset to original styleMask
+ setWindowFlags(window()->flags());
+
+ handleWindowStateChanged();
+}
+
+void QCocoaWindow::windowWillExitFullScreen()
+{
+ if (!isContentView())
+ return;
+
+ // The NSWindow needs to be resizable, otherwise we'll end up with
+ // a weird zoom animation. The styleMask will be reset below.
+ m_view.window.styleMask |= NSWindowStyleMaskResizable;
+}
+
+void QCocoaWindow::windowDidExitFullScreen()
+{
+ if (!isContentView())
+ return;
+
+ Q_ASSERT_X(!m_view.window.qt_fullScreen, "QCocoaWindow",
+ "FullScreen category processes window notifications first");
+
+ // Reset to original styleMask
+ setWindowFlags(window()->flags());
+
+ Qt::WindowState requestedState = window()->windowState();
+
+ // Deliver update of QWindow state
+ handleWindowStateChanged();
+
+ if (requestedState != windowState() && requestedState != Qt::WindowFullScreen) {
+ // We were only going out of full screen as an intermediate step before
+ // progressing into the final step, so re-sync the desired state.
+ applyWindowState(requestedState);
+ }
+}
+
+void QCocoaWindow::windowDidMiniaturize()
+{
+ if (!isContentView())
+ return;
+
+ handleWindowStateChanged();
+}
+
+void QCocoaWindow::windowDidDeminiaturize()
+{
+ if (!isContentView())
+ return;
+
+ handleWindowStateChanged();
+}
+
+void QCocoaWindow::handleWindowStateChanged(HandleFlags flags)
+{
+ Qt::WindowState currentState = windowState();
+ if (!(flags & HandleUnconditionally) && currentState == m_lastReportedWindowState)
+ return;
+
+ qCDebug(lcQpaWindow) << "QCocoaWindow::handleWindowStateChanged" <<
+ m_lastReportedWindowState << "-->" << currentState;
+
+ QWindowSystemInterface::handleWindowStateChanged<QWindowSystemInterface::SynchronousDelivery>(
+ window(), currentState, m_lastReportedWindowState);
+ m_lastReportedWindowState = currentState;
+}
+
+// ------------------------------------------------------------
+
void QCocoaWindow::setWindowTitle(const QString &title)
{
if (!isContentView())
@@ -680,7 +888,7 @@ bool QCocoaWindow::isAlertState() const
void QCocoaWindow::raise()
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::raise" << window();
+ qCDebug(lcQpaWindow) << "QCocoaWindow::raise" << window();
// ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
if (!isContentView())
@@ -705,7 +913,7 @@ void QCocoaWindow::raise()
void QCocoaWindow::lower()
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::lower" << window();
+ qCDebug(lcQpaWindow) << "QCocoaWindow::lower" << window();
if (!isContentView())
return;
@@ -718,6 +926,22 @@ bool QCocoaWindow::isExposed() const
return !m_exposedRect.isEmpty();
}
+bool QCocoaWindow::isEmbedded() const
+{
+ // Child QWindows are not embedded
+ if (window()->parent())
+ return false;
+
+ // Top-level QWindows with non-Qt NSWindows are embedded
+ if (m_view.window)
+ return !([m_view.window isKindOfClass:[QNSWindow class]] ||
+ [m_view.window isKindOfClass:[QNSPanel class]]);
+
+ // The window has no QWindow parent but also no NSWindow,
+ // conservatively reuturn false.
+ return false;
+}
+
bool QCocoaWindow::isOpaque() const
{
// OpenGL surfaces can be ordered either above(default) or below the NSWindow.
@@ -737,7 +961,7 @@ void QCocoaWindow::propagateSizeHints()
if (!isContentView())
return;
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::propagateSizeHints" << window()
+ qCDebug(lcQpaWindow) << "QCocoaWindow::propagateSizeHints" << window()
<< "min:" << windowMinimumSize() << "max:" << windowMaximumSize()
<< "increment:" << windowSizeIncrement()
<< "base:" << windowBaseSize();
@@ -754,7 +978,7 @@ void QCocoaWindow::propagateSizeHints()
window.contentMaxSize = NSSizeFromCGSize(windowMaximumSize().toCGSize());
// The window may end up with a fixed size; in this case the zoom button should be disabled.
- setWindowZoomButton(m_windowFlags);
+ setWindowZoomButton(this->window()->flags());
// sizeIncrement is observed to take values of (-1, -1) and (0, 0) for windows that should be
// resizable and that have no specific size increment set. Cocoa expects (1.0, 1.0) in this case.
@@ -771,7 +995,7 @@ void QCocoaWindow::propagateSizeHints()
void QCocoaWindow::setOpacity(qreal level)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setOpacity" << level;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::setOpacity" << level;
if (!isContentView())
return;
@@ -780,7 +1004,7 @@ void QCocoaWindow::setOpacity(qreal level)
void QCocoaWindow::setMask(const QRegion &region)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setMask" << window() << region;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::setMask" << window() << region;
if (m_view.layer) {
if (!region.isEmpty()) {
@@ -803,18 +1027,12 @@ void QCocoaWindow::setMask(const QRegion &region)
// time, and so would not result in an updated backingstore.
m_needsInvalidateShadow = true;
[m_view setNeedsDisplay:YES];
-
- // FIXME: [NSWindow invalidateShadow] has no effect when in layer-backed mode,
- // so if the mask is changed after the initial mask is applied, it will not
- // result in any visual change to the shadow. This is an Apple bug, and there
- // may be ways to work around it, such as calling setFrame on the window to
- // trigger some internal invalidation, but that needs more research.
}
}
bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setKeyboardGrabEnabled" << window() << grab;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::setKeyboardGrabEnabled" << window() << grab;
if (!isContentView())
return false;
@@ -826,7 +1044,7 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
bool QCocoaWindow::setMouseGrabEnabled(bool grab)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setMouseGrabEnabled" << window() << grab;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::setMouseGrabEnabled" << window() << grab;
if (!isContentView())
return false;
@@ -843,10 +1061,10 @@ WId QCocoaWindow::winId() const
void QCocoaWindow::setParent(const QPlatformWindow *parentWindow)
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setParent" << window() << (parentWindow ? parentWindow->window() : 0);
+ qCDebug(lcQpaWindow) << "QCocoaWindow::setParent" << window() << (parentWindow ? parentWindow->window() : 0);
// recreate the window for compatibility
- bool unhideAfterRecreate = parentWindow && !m_viewIsToBeEmbedded && ![m_view isHidden];
+ bool unhideAfterRecreate = parentWindow && !isEmbedded() && ![m_view isHidden];
recreateWindowIfNeeded();
if (unhideAfterRecreate)
[m_view setHidden:NO];
@@ -863,9 +1081,8 @@ NSWindow *QCocoaWindow::nativeWindow() const
return m_view.window;
}
-void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
+void QCocoaWindow::setEmbeddedInForeignView()
{
- m_viewIsToBeEmbedded = embedded;
// Release any previosly created NSWindow.
[m_nsWindow closeAndRelease];
m_nsWindow = 0;
@@ -948,8 +1165,8 @@ void QCocoaWindow::windowDidBecomeKey()
QWindowSystemInterface::handleEnterEvent(m_enterLeaveTargetWindow, windowPoint, screenPoint);
}
- if (!windowIsPopupType() && !qnsview_cast(m_view).isMenuView)
- QWindowSystemInterface::handleWindowActivated(window());
+ if (!windowIsPopupType())
+ QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::SynchronousDelivery>(window());
}
void QCocoaWindow::windowDidResignKey()
@@ -966,82 +1183,8 @@ void QCocoaWindow::windowDidResignKey()
NSWindow *keyWindow = [NSApp keyWindow];
if (!keyWindow || keyWindow == m_view.window) {
// No new key window, go ahead and set the active window to zero
- if (!windowIsPopupType() && !qnsview_cast(m_view).isMenuView)
- QWindowSystemInterface::handleWindowActivated(0);
- }
-}
-
-void QCocoaWindow::windowDidMiniaturize()
-{
- if (!isContentView())
- return;
-
- handleWindowStateChanged();
-}
-
-void QCocoaWindow::windowDidDeminiaturize()
-{
- if (!isContentView())
- return;
-
- handleWindowStateChanged();
-}
-
-void QCocoaWindow::windowWillEnterFullScreen()
-{
- if (!isContentView())
- return;
-
- // The NSWindow needs to be resizable, otherwise we'll end up with
- // the normal window geometry, centered in the middle of the screen
- // on a black background. The styleMask will be reset below.
- m_view.window.styleMask |= NSResizableWindowMask;
-}
-
-void QCocoaWindow::windowDidEnterFullScreen()
-{
- if (!isContentView())
- return;
-
- Q_ASSERT_X(m_view.window.qt_fullScreen, "QCocoaWindow",
- "FullScreen category processes window notifications first");
-
- // Reset to original styleMask
- setWindowFlags(m_windowFlags);
-
- handleWindowStateChanged();
-}
-
-void QCocoaWindow::windowWillExitFullScreen()
-{
- if (!isContentView())
- return;
-
- // The NSWindow needs to be resizable, otherwise we'll end up with
- // a weird zoom animation. The styleMask will be reset below.
- m_view.window.styleMask |= NSResizableWindowMask;
-}
-
-void QCocoaWindow::windowDidExitFullScreen()
-{
- if (!isContentView())
- return;
-
- Q_ASSERT_X(!m_view.window.qt_fullScreen, "QCocoaWindow",
- "FullScreen category processes window notifications first");
-
- // Reset to original styleMask
- setWindowFlags(m_windowFlags);
-
- Qt::WindowState requestedState = window()->windowState();
-
- // Deliver update of QWindow state
- handleWindowStateChanged();
-
- if (requestedState != windowState() && requestedState != Qt::WindowFullScreen) {
- // We were only going out of full screen as an intermediate step before
- // progressing into the final step, so re-sync the desired state.
- applyWindowState(requestedState);
+ if (!windowIsPopupType())
+ QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::SynchronousDelivery>(0);
}
}
@@ -1068,8 +1211,24 @@ void QCocoaWindow::windowDidChangeScreen()
if (!window())
return;
- if (QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen))
- QWindowSystemInterface::handleWindowScreenChanged(window(), cocoaScreen->screen());
+ const bool wasRunningDisplayLink = static_cast<QCocoaScreen *>(screen())->isRunningDisplayLink();
+
+ if (QCocoaScreen *newScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen)) {
+ if (newScreen == screen()) {
+ // Screen properties have changed. Will be handled by
+ // NSApplicationDidChangeScreenParametersNotification
+ // in QCocoaIntegration::updateScreens().
+ return;
+ }
+
+ qCDebug(lcQpaWindow) << window() << "moved to" << newScreen;
+ QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
+
+ if (hasPendingUpdateRequest() && wasRunningDisplayLink)
+ requestUpdate(); // Restart display-link on new screen
+ } else {
+ qCWarning(lcQpaWindow) << "Failed to get QCocoaScreen for" << m_view.window.screen;
+ }
}
void QCocoaWindow::windowWillClose()
@@ -1083,7 +1242,7 @@ void QCocoaWindow::windowWillClose()
bool QCocoaWindow::windowShouldClose()
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::windowShouldClose" << window();
+ qCDebug(lcQpaWindow) << "QCocoaWindow::windowShouldClose" << window();
// This callback should technically only determine if the window
// should (be allowed to) close, but since our QPA API to determine
// that also involves actually closing the window we do both at the
@@ -1104,22 +1263,14 @@ void QCocoaWindow::handleGeometryChange()
if (!m_initialized)
return;
- // Don't send the geometry change if the QWindow is designated to be
- // embedded in a foreign view hierarchy but has not actually been
- // embedded yet - it's too early.
- if (m_viewIsToBeEmbedded && !m_viewIsEmbedded)
- return;
-
// It can happen that the current NSWindow is nil (if we are changing styleMask
// from/to borderless, and the content view is being re-parented), which results
// in invalid coordinates.
if (m_inSetStyleMask && !m_view.window)
return;
- const bool isEmbedded = m_viewIsToBeEmbedded || m_viewIsEmbedded;
-
QRect newGeometry;
- if (isContentView() && !isEmbedded) {
+ if (isContentView() && !isEmbedded()) {
// Content views are positioned at (0, 0) in the window, so we resolve via the window
CGRect contentRect = [m_view.window contentRectForFrameRect:m_view.window.frame];
@@ -1130,7 +1281,7 @@ void QCocoaWindow::handleGeometryChange()
newGeometry = QRectF::fromCGRect(m_view.frame).toRect();
}
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleGeometryChange" << window()
+ qCDebug(lcQpaWindow) << "QCocoaWindow::handleGeometryChange" << window()
<< "current" << geometry() << "new" << newGeometry;
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
@@ -1162,24 +1313,10 @@ void QCocoaWindow::handleExposeEvent(const QRegion &region)
m_exposedRect = QRect();
}
- qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::handleExposeEvent" << window() << region << "isExposed" << isExposed();
+ qCDebug(lcQpaDrawing) << "QCocoaWindow::handleExposeEvent" << window() << region << "isExposed" << isExposed();
QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(window(), region);
}
-void QCocoaWindow::handleWindowStateChanged(HandleFlags flags)
-{
- Qt::WindowState currentState = windowState();
- if (!(flags & HandleUnconditionally) && currentState == m_lastReportedWindowState)
- return;
-
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleWindowStateChanged" <<
- m_lastReportedWindowState << "-->" << currentState;
-
- QWindowSystemInterface::handleWindowStateChanged<QWindowSystemInterface::SynchronousDelivery>(
- window(), currentState, m_lastReportedWindowState);
- m_lastReportedWindowState = currentState;
-}
-
// --------------------------------------------------------------------------
bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const
@@ -1192,18 +1329,6 @@ bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const
return ((type & Qt::Popup) == Qt::Popup);
}
-#ifndef QT_NO_OPENGL
-void QCocoaWindow::setCurrentContext(QCocoaGLContext *context)
-{
- m_glContext = context;
-}
-
-QCocoaGLContext *QCocoaWindow::currentContext() const
-{
- return m_glContext;
-}
-#endif
-
/*!
Checks if the window is the content view of its immediate NSWindow.
@@ -1230,6 +1355,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
QPlatformWindow *parentWindow = QPlatformWindow::parent();
+ const bool isEmbeddedView = isEmbedded();
RecreationReasons recreateReason = RecreationNotNeeded;
QCocoaWindow *oldParentCocoaWindow = nullptr;
@@ -1246,7 +1372,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
if (m_windowModality != window()->modality())
recreateReason |= WindowModalityChanged;
- const bool shouldBeContentView = !parentWindow && !(m_viewIsToBeEmbedded || m_viewIsEmbedded);
+ const bool shouldBeContentView = !parentWindow && !isEmbeddedView;
if (isContentView() != shouldBeContentView)
recreateReason |= ContentViewChanged;
@@ -1258,7 +1384,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
if (isPanel != shouldBePanel)
recreateReason |= PanelChanged;
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::recreateWindowIfNeeded" << window() << recreateReason;
+ qCDebug(lcQpaWindow) << "QCocoaWindow::recreateWindowIfNeeded" << window() << recreateReason;
if (recreateReason == RecreationNotNeeded)
return;
@@ -1268,33 +1394,28 @@ void QCocoaWindow::recreateWindowIfNeeded()
// Remove current window (if any)
if ((isContentView() && !shouldBeContentView) || (recreateReason & PanelChanged)) {
if (m_nsWindow) {
- qCDebug(lcQpaCocoaWindow) << "Getting rid of existing window" << m_nsWindow;
+ qCDebug(lcQpaWindow) << "Getting rid of existing window" << m_nsWindow;
if (m_nsWindow.observationInfo) {
- qCCritical(lcQpaCocoaWindow) << m_nsWindow << "has active key-value observers (KVO)!"
+ qCCritical(lcQpaWindow) << m_nsWindow << "has active key-value observers (KVO)!"
<< "These will stop working now that the window is recreated, and will result in exceptions"
<< "when the observers are removed. Break in QCocoaWindow::recreateWindowIfNeeded to debug.";
}
[m_nsWindow closeAndRelease];
- if (isContentView()) {
+ if (isContentView() && !isEmbeddedView) {
// We explicitly disassociate m_view from the window's contentView,
// as AppKit does not automatically do this in response to removing
// the view from the NSThemeFrame subview list, so we might end up
// with a NSWindow contentView pointing to a deallocated NSView.
m_view.window.contentView = nil;
}
- m_nsWindow = 0;
+ m_nsWindow = nil;
}
}
- if (shouldBeContentView) {
- bool noPreviousWindow = m_nsWindow == 0;
- QCocoaNSWindow *newWindow = nullptr;
- if (noPreviousWindow)
- newWindow = createNSWindow(shouldBePanel);
-
+ if (shouldBeContentView && !m_nsWindow) {
// Move view to new NSWindow if needed
- if (newWindow) {
- qCDebug(lcQpaCocoaWindow) << "Ensuring that" << m_view << "is content view for" << newWindow;
+ if (auto *newWindow = createNSWindow(shouldBePanel)) {
+ qCDebug(lcQpaWindow) << "Ensuring that" << m_view << "is content view for" << newWindow;
[m_view setPostsFrameChangedNotifications:NO];
[newWindow setContentView:m_view];
[m_view setPostsFrameChangedNotifications:YES];
@@ -1304,14 +1425,14 @@ void QCocoaWindow::recreateWindowIfNeeded()
}
}
- if (m_viewIsToBeEmbedded) {
+ if (isEmbeddedView) {
// An embedded window doesn't have its own NSWindow.
} else if (!parentWindow) {
// QPlatformWindow subclasses must sync up with QWindow on creation:
propagateSizeHints();
setWindowFlags(window()->flags());
setWindowTitle(window()->title());
- setWindowFilePath(window()->filePath());
+ setWindowFilePath(window()->filePath()); // Also sets window icon
setWindowState(window()->windowState());
} else {
// Child windows have no NSWindow, link the NSViews instead.
@@ -1334,14 +1455,28 @@ void QCocoaWindow::recreateWindowIfNeeded()
// top-level QWindows may have an attached NSToolBar, call
// update function which will attach to the NSWindow.
- if (!parentWindow)
+ if (!parentWindow && !isEmbeddedView)
updateNSToolbar();
}
void QCocoaWindow::requestUpdate()
{
- qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::requestUpdate" << window();
- QPlatformWindow::requestUpdate();
+ const int swapInterval = format().swapInterval();
+ qCDebug(lcQpaDrawing) << "QCocoaWindow::requestUpdate" << window() << "swapInterval" << swapInterval;
+
+ if (swapInterval > 0) {
+ // Vsync is enabled, deliver via CVDisplayLink
+ static_cast<QCocoaScreen *>(screen())->requestUpdate();
+ } else {
+ // Fall back to the un-throttled timer-based callback
+ QPlatformWindow::requestUpdate();
+ }
+}
+
+void QCocoaWindow::deliverUpdateRequest()
+{
+ qCDebug(lcQpaDrawing) << "Delivering update request to" << window();
+ QPlatformWindow::deliverUpdateRequest();
}
void QCocoaWindow::requestActivateWindow()
@@ -1375,7 +1510,7 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
}
if (!targetScreen) {
- qCWarning(lcQpaCocoaWindow) << "Window position" << rect << "outside any known screen, using primary screen";
+ qCWarning(lcQpaWindow) << "Window position" << rect << "outside any known screen, using primary screen";
targetScreen = QGuiApplication::primaryScreen();
// AppKit will only reposition a window that's outside the target screen area if
// the window has a title bar. If left out, the window ends up with no screen.
@@ -1399,8 +1534,10 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
Q_ASSERT_X(nsWindow.screen == cocoaScreen->nativeScreen(), "QCocoaWindow",
"Resulting NSScreen should match the requested NSScreen");
- if (targetScreen != window()->screen())
- QWindowSystemInterface::handleWindowScreenChanged(window(), targetScreen);
+ if (targetScreen != window()->screen()) {
+ QWindowSystemInterface::handleWindowScreenChanged<
+ QWindowSystemInterface::SynchronousDelivery>(window(), targetScreen);
+ }
nsWindow.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
@@ -1473,138 +1610,6 @@ void QCocoaWindow::removeMonitor()
monitor = nil;
}
-/*!
- Applies the given state to the NSWindow, going in/out of minimize/zoomed/fullscreen
-
- When this is called from QWindow::setWindowState(), the QWindow state has not been
- updated yet, so window()->windowState() will reflect the previous state that was
- reported to QtGui.
-*/
-void QCocoaWindow::applyWindowState(Qt::WindowStates requestedState)
-{
- if (!isContentView())
- return;
-
- const Qt::WindowState currentState = windowState();
- const Qt::WindowState newState = QWindowPrivate::effectiveState(requestedState);
-
- if (newState == currentState)
- return;
-
- const NSSize contentSize = m_view.frame.size;
- if (contentSize.width <= 0 || contentSize.height <= 0) {
- // If content view width or height is 0 then the window animations will crash so
- // do nothing. We report the current state back to reflect the failed operation.
- qWarning("invalid window content view size, check your window geometry");
- handleWindowStateChanged(HandleUnconditionally);
- return;
- }
-
- const NSWindow *nsWindow = m_view.window;
-
- if (nsWindow.styleMask & NSUtilityWindowMask
- && newState & (Qt::WindowMinimized | Qt::WindowFullScreen)) {
- qWarning() << window()->type() << "windows can not be made" << newState;
- handleWindowStateChanged(HandleUnconditionally);
- return;
- }
-
- const id sender = nsWindow;
-
- // First we need to exit states that can't transition directly to other states
- switch (currentState) {
- case Qt::WindowMinimized:
- [nsWindow deminiaturize:sender];
- Q_ASSERT_X(windowState() != Qt::WindowMinimized, "QCocoaWindow",
- "[NSWindow deminiaturize:] is synchronous");
- break;
- case Qt::WindowFullScreen: {
- toggleFullScreen();
- // Exiting fullscreen is not synchronous, so we need to wait for the
- // NSWindowDidExitFullScreenNotification before continuing to apply
- // the new state.
- return;
- }
- default:;
- }
-
- // Then we apply the new state if needed
- if (newState == windowState())
- return;
-
- switch (newState) {
- case Qt::WindowFullScreen:
- toggleFullScreen();
- break;
- case Qt::WindowMaximized:
- toggleMaximized();
- break;
- case Qt::WindowMinimized:
- [nsWindow miniaturize:sender];
- break;
- case Qt::WindowNoState:
- if (windowState() == Qt::WindowMaximized)
- toggleMaximized();
- break;
- default:
- Q_UNREACHABLE();
- }
-}
-
-void QCocoaWindow::toggleMaximized()
-{
- const NSWindow *window = m_view.window;
-
- // The NSWindow needs to be resizable, otherwise the window will
- // not be possible to zoom back to non-zoomed state.
- const bool wasResizable = window.styleMask & NSResizableWindowMask;
- window.styleMask |= NSResizableWindowMask;
-
- const id sender = window;
- [window zoom:sender];
-
- if (!wasResizable)
- window.styleMask &= ~NSResizableWindowMask;
-}
-
-void QCocoaWindow::toggleFullScreen()
-{
- const NSWindow *window = m_view.window;
-
- // The window needs to have the correct collection behavior for the
- // toggleFullScreen call to have an effect. The collection behavior
- // will be reset in windowDidEnterFullScreen/windowDidLeaveFullScreen.
- window.collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
-
- const id sender = window;
- [window toggleFullScreen:sender];
-}
-
-bool QCocoaWindow::isTransitioningToFullScreen() const
-{
- NSWindow *window = m_view.window;
- return window.styleMask & NSFullScreenWindowMask && !window.qt_fullScreen;
-}
-
-Qt::WindowState QCocoaWindow::windowState() const
-{
- // FIXME: Support compound states (Qt::WindowStates)
-
- NSWindow *window = m_view.window;
- if (window.miniaturized)
- return Qt::WindowMinimized;
- if (window.qt_fullScreen)
- return Qt::WindowFullScreen;
- if ((window.zoomed && !isTransitioningToFullScreen())
- || (m_lastReportedWindowState == Qt::WindowMaximized && isTransitioningToFullScreen()))
- return Qt::WindowMaximized;
-
- // Note: We do not report Qt::WindowActive, even if isActive()
- // is true, as QtGui does not expect this window state to be set.
-
- return Qt::WindowNoState;
-}
-
bool QCocoaWindow::setWindowModified(bool modified)
{
if (!isContentView())
@@ -1685,7 +1690,7 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
return;
if (!m_drawContentBorderGradient) {
- window.styleMask = window.styleMask & ~NSTexturedBackgroundWindowMask;
+ window.styleMask = window.styleMask & ~NSWindowStyleMaskTexturedBackground;
[window.contentView.superview setNeedsDisplay:YES];
window.titlebarAppearsTransparent = NO;
return;
@@ -1711,7 +1716,7 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
int effectiveBottomContentBorderThickness = m_bottomContentBorderThickness;
- [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
+ [window setStyleMask:[window styleMask] | NSWindowStyleMaskTexturedBackground];
window.titlebarAppearsTransparent = YES;
[window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge];
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.h b/src/plugins/platforms/cocoa/qmacclipboard.h
index 1d229a55d2..f2f460c048 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.h
+++ b/src/plugins/platforms/cocoa/qmacclipboard.h
@@ -54,7 +54,7 @@ public:
enum DataRequestType { EagerRequest, LazyRequest };
private:
struct Promise {
- Promise() : itemId(0), convertor(0) { }
+ Promise() : itemId(0), convertor(nullptr) { }
static Promise eagerPromise(int itemId, QMacInternalPasteboardMime *c, QString m, QMacMimeData *d, int o = 0);
static Promise lazyPromise(int itemId, QMacInternalPasteboardMime *c, QString m, QMacMimeData *d, int o = 0);
@@ -79,7 +79,7 @@ private:
public:
QMacPasteboard(PasteboardRef p, uchar mime_type=0);
QMacPasteboard(uchar mime_type);
- QMacPasteboard(CFStringRef name=0, uchar mime_type=0);
+ QMacPasteboard(CFStringRef name=nullptr, uchar mime_type=0);
~QMacPasteboard();
bool hasFlavor(QString flavor) const;
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index f3467fdc73..5939003c64 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -75,7 +75,7 @@ QMacPasteboard::Promise::Promise(int itemId, QMacInternalPasteboardMime *c, QStr
// Request the data from the application immediately for eager requests.
if (dataRequestType == QMacPasteboard::EagerRequest) {
variantData = md->variantData(m);
- mimeData = 0;
+ mimeData = nullptr;
} else {
mimeData = md;
}
@@ -94,8 +94,8 @@ QMacPasteboard::QMacPasteboard(uchar mt)
{
mac_mime_source = false;
mime_type = mt ? mt : uchar(QMacInternalPasteboardMime::MIME_ALL);
- paste = 0;
- OSStatus err = PasteboardCreate(0, &paste);
+ paste = nullptr;
+ OSStatus err = PasteboardCreate(nullptr, &paste);
if (err == noErr) {
PasteboardSetPromiseKeeper(paste, promiseKeeper, this);
} else {
@@ -108,7 +108,7 @@ QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt)
{
mac_mime_source = false;
mime_type = mt ? mt : uchar(QMacInternalPasteboardMime::MIME_ALL);
- paste = 0;
+ paste = nullptr;
OSStatus err = PasteboardCreate(name, &paste);
if (err == noErr) {
PasteboardSetPromiseKeeper(paste, promiseKeeper, this);
@@ -165,7 +165,7 @@ OSStatus QMacPasteboard::promiseKeeper(PasteboardRef paste, PasteboardItemID id,
// we have promised this data, but won't be able to convert, so return null data.
// This helps in making the application/x-qt-mime-type-name hidden from normal use.
QByteArray ba;
- QCFType<CFDataRef> data = CFDataCreate(0, (UInt8*)ba.constData(), ba.size());
+ QCFType<CFDataRef> data = CFDataCreate(nullptr, (UInt8*)ba.constData(), ba.size());
PasteboardPutItemFlavor(paste, id, flavor, data, kPasteboardFlavorNoFlags);
return noErr;
}
@@ -196,7 +196,7 @@ OSStatus QMacPasteboard::promiseKeeper(PasteboardRef paste, PasteboardItemID id,
if (md.size() <= promise.offset)
return cantGetFlavorErr;
const QByteArray &ba = md[promise.offset];
- QCFType<CFDataRef> data = CFDataCreate(0, (UInt8*)ba.constData(), ba.size());
+ QCFType<CFDataRef> data = CFDataCreate(nullptr, (UInt8*)ba.constData(), ba.size());
PasteboardPutItemFlavor(paste, id, flavor, data, kPasteboardFlavorNoFlags);
return noErr;
}
@@ -553,7 +553,7 @@ QMacPasteboard::sync() const
const bool fromGlobal = PasteboardSynchronize(paste) & kPasteboardModified;
if (fromGlobal)
- const_cast<QMacPasteboard *>(this)->setMimeData(0);
+ const_cast<QMacPasteboard *>(this)->setMimeData(nullptr);
#ifdef DEBUG_PASTEBOARD
if (fromGlobal)
diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac.mm b/src/plugins/platforms/cocoa/qmultitouch_mac.mm
index 9eca4d2d43..10652dc6a1 100644
--- a/src/plugins/platforms/cocoa/qmultitouch_mac.mm
+++ b/src/plugins/platforms/cocoa/qmultitouch_mac.mm
@@ -107,7 +107,7 @@ QCocoaTouch *QCocoaTouch::findQCocoaTouch(NSTouch *nstouch)
qint64 identity = qint64([nstouch identity]);
if (_currentTouches.contains(identity))
return _currentTouches.value(identity);
- return 0;
+ return nullptr;
}
Qt::TouchPointState QCocoaTouch::toTouchPointState(NSTouchPhase nsState)
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index e2ea862cd5..b40dfe0d14 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -41,111 +41,45 @@
#define QNSVIEW_H
#include <AppKit/AppKit.h>
-
-#include <QtCore/QPointer>
-#include <QtCore/QSet>
-#include <QtGui/QImage>
-#include <QtGui/QAccessible>
+#include <MetalKit/MetalKit.h>
#include "private/qcore_mac_p.h"
QT_BEGIN_NAMESPACE
class QCocoaWindow;
class QCocoaGLContext;
+class QPointF;
QT_END_NAMESPACE
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
+Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaNSMenuItem));
-@interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> {
- QPointer<QCocoaWindow> m_platformWindow;
- NSTrackingArea *m_trackingArea;
- Qt::MouseButtons m_buttons;
- Qt::MouseButtons m_acceptedMouseDowns;
- Qt::MouseButtons m_frameStrutButtons;
- QString m_composingText;
- QPointer<QObject> m_composingFocusObject;
- bool m_sendKeyEvent;
- QStringList *currentCustomDragTypes;
- bool m_dontOverrideCtrlLMB;
- bool m_sendUpAsRightButton;
- Qt::KeyboardModifiers currentWheelModifiers;
-#ifndef QT_NO_OPENGL
- QCocoaGLContext *m_glContext;
- bool m_shouldSetGLContextinDrawRect;
-#endif
- NSString *m_inputSource;
- QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) *m_mouseMoveHelper;
- bool m_resendKeyEvent;
- bool m_scrolling;
- bool m_updatingDrag;
- NSEvent *m_currentlyInterpretedKeyEvent;
- bool m_isMenuView;
- QSet<quint32> m_acceptedKeyDowns;
- bool m_updateRequested;
-}
+@interface QT_MANGLE_NAMESPACE(QNSView) : NSView
@property (nonatomic, retain) NSCursor *cursor;
-- (id)init;
-- (id)initWithCocoaWindow:(QCocoaWindow *)platformWindow;
-#ifndef QT_NO_OPENGL
-- (void)setQCocoaGLContext:(QCocoaGLContext *)context;
-#endif
-- (void)drawRect:(NSRect)dirtyRect;
-- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification;
-- (void)viewDidHide;
-- (void)removeFromSuperview;
-- (void)cancelComposingText;
-
-- (BOOL)isFlipped;
-- (BOOL)acceptsFirstResponder;
-- (BOOL)becomeFirstResponder;
-- (BOOL)isOpaque;
+- (instancetype)initWithCocoaWindow:(QCocoaWindow *)platformWindow;
- (void)convertFromScreen:(NSPoint)mouseLocation toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint;
-- (void)resetMouseButtons;
+@end
-- (void)requestUpdate;
-
-- (void)handleMouseEvent:(NSEvent *)theEvent;
-- (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
-- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
-- (bool)handleMouseUpEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
-- (void)mouseDown:(NSEvent *)theEvent;
-- (void)mouseDragged:(NSEvent *)theEvent;
-- (void)mouseUp:(NSEvent *)theEvent;
-- (void)mouseMovedImpl:(NSEvent *)theEvent;
-- (void)mouseEnteredImpl:(NSEvent *)theEvent;
-- (void)mouseExitedImpl:(NSEvent *)theEvent;
-- (void)rightMouseDown:(NSEvent *)theEvent;
-- (void)rightMouseDragged:(NSEvent *)theEvent;
-- (void)rightMouseUp:(NSEvent *)theEvent;
-- (void)otherMouseDown:(NSEvent *)theEvent;
-- (void)otherMouseDragged:(NSEvent *)theEvent;
-- (void)otherMouseUp:(NSEvent *)theEvent;
+@interface QT_MANGLE_NAMESPACE(QNSView) (MouseAPI)
- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent;
+- (void)resetMouseButtons;
+@end
-#ifndef QT_NO_TABLETEVENT
-- (bool)handleTabletEvent: (NSEvent *)theEvent;
-- (void)tabletPoint: (NSEvent *)theEvent;
-- (void)tabletProximity: (NSEvent *)theEvent;
-#endif
-
-- (int) convertKeyCode : (QChar)keyCode;
-+ (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags;
-- (bool)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType;
-- (void)keyDown:(NSEvent *)theEvent;
-- (void)keyUp:(NSEvent *)theEvent;
-
-- (void)registerDragTypes;
-- (NSDragOperation)handleDrag:(id <NSDraggingInfo>)sender;
+@interface QT_MANGLE_NAMESPACE(QNSView) (KeysAPI)
++ (Qt::KeyboardModifiers)convertKeyModifiers:(ulong)modifierFlags;
+@end
+@interface QT_MANGLE_NAMESPACE(QNSView) (ComplexTextAPI)
+- (void)unmarkText;
+- (void)cancelComposingText;
@end
@interface QT_MANGLE_NAMESPACE(QNSView) (QtExtras)
@property (nonatomic, readonly) QCocoaWindow *platformWindow;
-@property (nonatomic, readonly) BOOL isMenuView;
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSView);
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 1c400a1ec9..9bd53ed334 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -51,7 +51,11 @@
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QTextFormat>
#include <QtCore/QDebug>
+#include <QtCore/QPointer>
+#include <QtCore/QSet>
#include <QtCore/qsysinfo.h>
+#include <QtGui/QAccessible>
+#include <QtGui/QImage>
#include <private/qguiapplication_p.h>
#include <private/qcoregraphics_p.h>
#include <private/qwindow_p.h>
@@ -61,94 +65,112 @@
#endif
#include "qcocoaintegration.h"
-#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
-#include <accessibilityinspector.h>
-#endif
+// Private interface
+@interface QT_MANGLE_NAMESPACE(QNSView) ()
+- (BOOL)isTransparentForUserInput;
+@end
-Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch")
-#ifndef QT_NO_GESTURES
-Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
-#endif
-Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
+@interface QT_MANGLE_NAMESPACE(QNSView) (Drawing) <CALayerDelegate>
+- (BOOL)wantsLayerHelper;
+@end
@interface QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) : NSObject
-{
- QNSView *view;
-}
-
-- (id)initWithView:(QNSView *)theView;
-
+- (instancetype)initWithView:(QNSView *)theView;
- (void)mouseMoved:(NSEvent *)theEvent;
- (void)mouseEntered:(NSEvent *)theEvent;
- (void)mouseExited:(NSEvent *)theEvent;
- (void)cursorUpdate:(NSEvent *)theEvent;
-
@end
-@implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)
-
-- (id)initWithView:(QNSView *)theView
-{
- self = [super init];
- if (self) {
- view = theView;
- }
- return self;
-}
-
-- (void)mouseMoved:(NSEvent *)theEvent
-{
- [view mouseMovedImpl:theEvent];
-}
+@interface QT_MANGLE_NAMESPACE(QNSView) (Mouse)
+- (NSPoint)screenMousePoint:(NSEvent *)theEvent;
+- (void)mouseMovedImpl:(NSEvent *)theEvent;
+- (void)mouseEnteredImpl:(NSEvent *)theEvent;
+- (void)mouseExitedImpl:(NSEvent *)theEvent;
+@end
-- (void)mouseEntered:(NSEvent *)theEvent
-{
- [view mouseEnteredImpl:theEvent];
-}
+@interface QT_MANGLE_NAMESPACE(QNSView) (Touch)
+@end
-- (void)mouseExited:(NSEvent *)theEvent
-{
- [view mouseExitedImpl:theEvent];
-}
+@interface QT_MANGLE_NAMESPACE(QNSView) (Tablet)
+- (bool)handleTabletEvent:(NSEvent *)theEvent;
+@end
-- (void)cursorUpdate:(NSEvent *)theEvent
-{
- [view cursorUpdate:theEvent];
-}
+@interface QT_MANGLE_NAMESPACE(QNSView) (Gestures)
+@end
+@interface QT_MANGLE_NAMESPACE(QNSView) (Dragging)
+-(void)registerDragTypes;
@end
-// Private interface
-@interface QT_MANGLE_NAMESPACE(QNSView) ()
-- (BOOL)isTransparentForUserInput;
+@interface QT_MANGLE_NAMESPACE(QNSView) (Keys)
@end
-@implementation QT_MANGLE_NAMESPACE(QNSView)
+@interface QT_MANGLE_NAMESPACE(QNSView) (ComplexText) <NSTextInputClient>
+- (void)textInputContextKeyboardSelectionDidChangeNotification:(NSNotification *)textInputContextKeyboardSelectionDidChangeNotification;
+@end
-- (id) init
-{
- if (self = [super initWithFrame:NSZeroRect]) {
+@implementation QT_MANGLE_NAMESPACE(QNSView) {
+ QPointer<QCocoaWindow> m_platformWindow;
+ NSTrackingArea *m_trackingArea;
+ Qt::MouseButtons m_buttons;
+ Qt::MouseButtons m_acceptedMouseDowns;
+ Qt::MouseButtons m_frameStrutButtons;
+ QString m_composingText;
+ QPointer<QObject> m_composingFocusObject;
+ bool m_sendKeyEvent;
+ bool m_dontOverrideCtrlLMB;
+ bool m_sendUpAsRightButton;
+ Qt::KeyboardModifiers m_currentWheelModifiers;
+ NSString *m_inputSource;
+ QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) *m_mouseMoveHelper;
+ bool m_resendKeyEvent;
+ bool m_scrolling;
+ bool m_updatingDrag;
+ NSEvent *m_currentlyInterpretedKeyEvent;
+ QSet<quint32> m_acceptedKeyDowns;
+}
+
+- (instancetype)initWithCocoaWindow:(QCocoaWindow *)platformWindow
+{
+ if ((self = [super initWithFrame:NSZeroRect])) {
+ m_platformWindow = platformWindow;
m_buttons = Qt::NoButton;
m_acceptedMouseDowns = Qt::NoButton;
m_frameStrutButtons = Qt::NoButton;
m_sendKeyEvent = false;
-#ifndef QT_NO_OPENGL
- m_glContext = 0;
- m_shouldSetGLContextinDrawRect = false;
-#endif
- currentCustomDragTypes = 0;
- m_dontOverrideCtrlLMB = false;
m_sendUpAsRightButton = false;
- m_inputSource = 0;
+ m_inputSource = nil;
m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self];
m_resendKeyEvent = false;
m_scrolling = false;
m_updatingDrag = false;
- m_currentlyInterpretedKeyEvent = 0;
- m_isMenuView = false;
+ m_currentlyInterpretedKeyEvent = nil;
+ m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, platformWindow->window(),
+ "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB");
+ m_trackingArea = nil;
+
self.focusRingType = NSFocusRingTypeNone;
self.cursor = nil;
- m_updateRequested = false;
+ self.wantsLayer = [self wantsLayerHelper];
+
+ // Enable high-DPI OpenGL for retina displays. Enabling has the side
+ // effect that Cocoa will start calling glViewport(0, 0, width, height),
+ // overriding any glViewport calls in application code. This is usually not a
+ // problem, except if the application wants to have a "custom" viewport.
+ // (like the hellogl example)
+ if (m_platformWindow->window()->supportsOpenGL()) {
+ self.wantsBestResolutionOpenGLSurface = qt_mac_resolveOption(YES, m_platformWindow->window(),
+ "_q_mac_wantsBestResolutionOpenGLSurface", "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE");
+ // See also QCocoaGLContext::makeCurrent for software renderer workarounds.
+ }
+
+ [self registerDragTypes];
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(textInputContextKeyboardSelectionDidChangeNotification:)
+ name:NSTextInputContextKeyboardSelectionDidChangeNotification
+ object:nil];
}
return self;
}
@@ -163,47 +185,9 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
[[NSNotificationCenter defaultCenter] removeObserver:self];
[m_mouseMoveHelper release];
- delete currentCustomDragTypes;
-
[super dealloc];
}
-- (id)initWithCocoaWindow:(QCocoaWindow *)platformWindow
-{
- self = [self init];
- if (!self)
- return 0;
-
- m_platformWindow = platformWindow;
- m_sendKeyEvent = false;
- m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, platformWindow->window(), "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB");
- m_trackingArea = nil;
-
-#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
- // prevent rift in space-time continuum, disable
- // accessibility for the accessibility inspector's windows.
- static bool skipAccessibilityForInspectorWindows = false;
- if (!skipAccessibilityForInspectorWindows) {
-
- // m_accessibleRoot = window->accessibleRoot();
-
- AccessibilityInspector *inspector = new AccessibilityInspector(window);
- skipAccessibilityForInspectorWindows = true;
- inspector->inspectWindow(window);
- skipAccessibilityForInspectorWindows = false;
- }
-#endif
-
- [self registerDragTypes];
-
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(textInputContextKeyboardSelectionDidChangeNotification:)
- name:NSTextInputContextKeyboardSelectionDidChangeNotification
- object:nil];
-
- return self;
-}
-
- (NSString *)description
{
NSMutableString *description = [NSMutableString stringWithString:[super description]];
@@ -220,33 +204,18 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return description;
}
-#ifndef QT_NO_OPENGL
-- (void) setQCocoaGLContext:(QCocoaGLContext *)context
-{
- m_glContext = context;
- [m_glContext->nsOpenGLContext() setView:self];
- if (![m_glContext->nsOpenGLContext() view]) {
- //was unable to set view
- m_shouldSetGLContextinDrawRect = true;
- }
-}
-#endif
-
- (void)viewDidMoveToSuperview
{
if (!m_platformWindow)
return;
- if (!(m_platformWindow->m_viewIsToBeEmbedded))
+ if (!m_platformWindow->isEmbedded())
return;
if ([self superview]) {
- m_platformWindow->m_viewIsEmbedded = true;
QWindowSystemInterface::handleGeometryChange(m_platformWindow->window(), m_platformWindow->geometry());
[self setNeedsDisplay:YES];
QWindowSystemInterface::flushWindowSystemEvents();
- } else {
- m_platformWindow->m_viewIsEmbedded = false;
}
}
@@ -268,15 +237,6 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return focusWindow;
}
-- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification
-{
- Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification)
- if (([NSApp keyWindow] == [self window]) && [[self window] firstResponder] == self) {
- QCocoaInputContext *ic = qobject_cast<QCocoaInputContext *>(QCocoaIntegration::instance()->inputContext());
- ic->updateLocale();
- }
-}
-
- (void)viewDidHide
{
if (!m_platformWindow->isExposed())
@@ -294,107 +254,6 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
[super removeFromSuperview];
}
-- (BOOL) isOpaque
-{
- if (!m_platformWindow)
- return true;
- return m_platformWindow->isOpaque();
-}
-
-- (void)requestUpdate
-{
- if (self.needsDisplay) {
- // If the view already has needsDisplay set it means that there may be code waiting for
- // a real expose event, so we can't issue setNeedsDisplay now as a way to trigger an
- // update request. We will re-trigger requestUpdate from drawRect.
- return;
- }
-
- [self setNeedsDisplay:YES];
- m_updateRequested = true;
-}
-
-- (void)setNeedsDisplayInRect:(NSRect)rect
-{
- [super setNeedsDisplayInRect:rect];
- m_updateRequested = false;
-}
-
-- (void)drawRect:(NSRect)dirtyRect
-{
- Q_UNUSED(dirtyRect);
-
- if (!m_platformWindow)
- return;
-
- QRegion exposedRegion;
- const NSRect *dirtyRects;
- NSInteger numDirtyRects;
- [self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects];
- for (int i = 0; i < numDirtyRects; ++i)
- exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
-
- qCDebug(lcQpaCocoaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
- [self updateRegion:exposedRegion];
-}
-
-- (void)updateRegion:(QRegion)dirtyRegion
-{
-#ifndef QT_NO_OPENGL
- if (m_glContext && m_shouldSetGLContextinDrawRect) {
- [m_glContext->nsOpenGLContext() setView:self];
- m_shouldSetGLContextinDrawRect = false;
- }
-#endif
-
- QWindowPrivate *windowPrivate = qt_window_private(m_platformWindow->window());
-
- if (m_updateRequested) {
- Q_ASSERT(windowPrivate->updateRequestPending);
- qCDebug(lcQpaCocoaWindow) << "Delivering update request to" << m_platformWindow->window();
- windowPrivate->deliverUpdateRequest();
- m_updateRequested = false;
- } else {
- m_platformWindow->handleExposeEvent(dirtyRegion);
- }
-
- if (m_updateRequested && windowPrivate->updateRequestPending) {
- // A call to QWindow::requestUpdate was issued during event delivery above,
- // but AppKit will reset the needsDisplay state of the view after completing
- // the current display cycle, so we need to defer the request to redisplay.
- // FIXME: Perhaps this should be a trigger to enable CADisplayLink?
- qCDebug(lcQpaCocoaDrawing) << "[QNSView drawRect:] issuing deferred setNeedsDisplay due to pending update request";
- dispatch_async(dispatch_get_main_queue (), ^{ [self requestUpdate]; });
- }
-}
-
-- (BOOL)wantsUpdateLayer
-{
- return YES;
-}
-
-- (void)updateLayer
-{
- if (!m_platformWindow)
- return;
-
- qCDebug(lcQpaCocoaDrawing) << "[QNSView updateLayer]" << m_platformWindow->window();
-
- // FIXME: Find out if there's a way to resolve the dirty rect like in drawRect:
- [self updateRegion:QRectF::fromCGRect(self.bounds).toRect()];
-}
-
-- (void)viewDidChangeBackingProperties
-{
- if (self.layer)
- self.layer.contentsScale = self.window.backingScaleFactor;
-}
-
-- (BOOL)isFlipped
-{
- return YES;
-}
-
- (BOOL)isTransparentForUserInput
{
return m_platformWindow->window() &&
@@ -407,7 +266,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return NO;
if ([self isTransparentForUserInput])
return NO;
- if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
+ if (!m_platformWindow->windowIsPopupType())
QWindowSystemInterface::handleWindowActivated([self topLevelWindow]);
return YES;
}
@@ -416,8 +275,6 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
{
if (!m_platformWindow)
return NO;
- if (m_isMenuView)
- return NO;
if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder())
return NO;
if ([self isTransparentForUserInput])
@@ -427,16 +284,6 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return YES;
}
-- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
-{
- Q_UNUSED(theEvent)
- if (!m_platformWindow)
- return NO;
- if ([self isTransparentForUserInput])
- return NO;
- return YES;
-}
-
- (NSView *)hitTest:(NSPoint)aPoint
{
NSView *candidate = [super hitTest:aPoint];
@@ -476,1611 +323,22 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
*qtScreenPoint = QCocoaScreen::mapFromNative(mouseLocation);
}
-- (void)resetMouseButtons
-{
- m_buttons = Qt::NoButton;
- m_frameStrutButtons = Qt::NoButton;
-}
-
-- (NSPoint) screenMousePoint:(NSEvent *)theEvent
-{
- NSPoint screenPoint;
- if (theEvent) {
- NSPoint windowPoint = [theEvent locationInWindow];
- if (qIsNaN(windowPoint.x) || qIsNaN(windowPoint.y)) {
- screenPoint = [NSEvent mouseLocation];
- } else {
- NSRect screenRect = [[theEvent window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
- screenPoint = screenRect.origin;
- }
- } else {
- screenPoint = [NSEvent mouseLocation];
- }
- return screenPoint;
-}
-
-- (void)handleMouseEvent:(NSEvent *)theEvent
-{
- if (!m_platformWindow)
- return;
-
-#ifndef QT_NO_TABLETEVENT
- // Tablet events may come in via the mouse event handlers,
- // check if this is a valid tablet event first.
- if ([self handleTabletEvent: theEvent])
- return;
-#endif
-
- QPointF qtWindowPoint;
- QPointF qtScreenPoint;
- QNSView *targetView = self;
- if (!targetView.platformWindow)
- return;
-
- // Popups implicitly grap mouse events; forward to the active popup if there is one
- if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) {
- // Tooltips must be transparent for mouse events
- // The bug reference is QTBUG-46379
- if (!popup->m_windowFlags.testFlag(Qt::ToolTip)) {
- if (QNSView *popupView = qnsview_cast(popup->view()))
- targetView = popupView;
- }
- }
-
- [targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
- ulong timestamp = [theEvent timestamp] * 1000;
-
- QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- nativeDrag->setLastMouseEvent(theEvent, self);
-
- Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- QWindowSystemInterface::handleMouseEvent(targetView->m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint,
- m_buttons, keyboardModifiers, Qt::MouseEventNotSynthesized);
-}
-
-- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
-{
- if (!m_platformWindow)
- return;
-
- // get m_buttons in sync
- // Don't send frme strut events if we are in the middle of a mouse drag.
- if (m_buttons != Qt::NoButton)
- return;
-
- NSEventType ty = [theEvent type];
- switch (ty) {
- case NSLeftMouseDown:
- m_frameStrutButtons |= Qt::LeftButton;
- break;
- case NSLeftMouseUp:
- m_frameStrutButtons &= ~Qt::LeftButton;
- break;
- case NSRightMouseDown:
- m_frameStrutButtons |= Qt::RightButton;
- break;
- case NSLeftMouseDragged:
- m_frameStrutButtons |= Qt::LeftButton;
- break;
- case NSRightMouseDragged:
- m_frameStrutButtons |= Qt::RightButton;
- break;
- case NSRightMouseUp:
- m_frameStrutButtons &= ~Qt::RightButton;
- break;
- case NSOtherMouseDown:
- m_frameStrutButtons |= cocoaButton2QtButton([theEvent buttonNumber]);
- break;
- case NSOtherMouseUp:
- m_frameStrutButtons &= ~cocoaButton2QtButton([theEvent buttonNumber]);
- default:
- break;
- }
-
- NSWindow *window = [self window];
- NSPoint windowPoint = [theEvent locationInWindow];
-
- int windowScreenY = [window frame].origin.y + [window frame].size.height;
- NSPoint windowCoord = [self convertPoint:[self frame].origin toView:nil];
- int viewScreenY = [window convertRectToScreen:NSMakeRect(windowCoord.x, windowCoord.y, 0, 0)].origin.y;
- int titleBarHeight = windowScreenY - viewScreenY;
-
- NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil];
- QPoint qtWindowPoint = QPoint(nsViewPoint.x, titleBarHeight + nsViewPoint.y);
- NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 0, 0)].origin;
- QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint();
-
- ulong timestamp = [theEvent timestamp] * 1000;
- QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons);
-}
-
-- (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber
-{
- if ([self isTransparentForUserInput])
- return false;
-
- Qt::MouseButton button = cocoaButton2QtButton(buttonNumber);
-
- QPointF qtWindowPoint;
- QPointF qtScreenPoint;
- [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
- Q_UNUSED(qtScreenPoint);
-
- // Maintain masked state for the button for use by MouseDragged and MouseUp.
- QRegion mask = m_platformWindow->window()->mask();
- const bool masked = !mask.isEmpty() && !mask.contains(qtWindowPoint.toPoint());
- if (masked)
- m_acceptedMouseDowns &= ~button;
- else
- m_acceptedMouseDowns |= button;
-
- // Forward masked out events to the next responder
- if (masked)
- return false;
-
- m_buttons |= button;
-
- [self handleMouseEvent:theEvent];
- return true;
-}
-
-- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent withButton:(int)buttonNumber
-{
- if ([self isTransparentForUserInput])
- return false;
-
- Qt::MouseButton button = cocoaButton2QtButton(buttonNumber);
-
- // Forward the event to the next responder if Qt did not accept the
- // corresponding mouse down for this button
- if (!(m_acceptedMouseDowns & button) == button)
- return false;
-
- [self handleMouseEvent:theEvent];
- return true;
-}
-
-- (bool)handleMouseUpEvent:(NSEvent *)theEvent withButton:(int)buttonNumber
-{
- if ([self isTransparentForUserInput])
- return false;
-
- Qt::MouseButton button = cocoaButton2QtButton(buttonNumber);
-
- // Forward the event to the next responder if Qt did not accept the
- // corresponding mouse down for this button
- if (!(m_acceptedMouseDowns & button) == button)
- return false;
-
- if (m_sendUpAsRightButton && button == Qt::LeftButton)
- button = Qt::RightButton;
- if (button == Qt::RightButton)
- m_sendUpAsRightButton = false;
-
- m_buttons &= ~button;
-
- [self handleMouseEvent:theEvent];
- return true;
-}
-
-- (void)mouseDown:(NSEvent *)theEvent
-{
- if ([self isTransparentForUserInput])
- return [super mouseDown:theEvent];
- m_sendUpAsRightButton = false;
-
- // Handle any active poup windows; clicking outisde them should close them
- // all. Don't do anything or clicks inside one of the menus, let Cocoa
- // handle that case. Note that in practice many windows of the Qt::Popup type
- // will actually close themselves in this case using logic implemented in
- // that particular poup type (for example context menus). However, Qt expects
- // that plain popup QWindows will also be closed, so we implement the logic
- // here as well.
- QList<QCocoaWindow *> *popups = QCocoaIntegration::instance()->popupWindowStack();
- if (!popups->isEmpty()) {
- // Check if the click is outside all popups.
- bool inside = false;
- QPointF qtScreenPoint = QCocoaScreen::mapFromNative([self screenMousePoint:theEvent]);
- for (QList<QCocoaWindow *>::const_iterator it = popups->begin(); it != popups->end(); ++it) {
- if ((*it)->geometry().contains(qtScreenPoint.toPoint())) {
- inside = true;
- break;
- }
- }
- // Close the popups if the click was outside.
- if (!inside) {
- Qt::WindowType type = QCocoaIntegration::instance()->activePopupWindow()->window()->type();
- while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) {
- QWindowSystemInterface::handleCloseEvent(popup->window());
- QWindowSystemInterface::flushWindowSystemEvents();
- }
- // Consume the mouse event when closing the popup, except for tool tips
- // were it's expected that the event is processed normally.
- if (type != Qt::ToolTip)
- return;
- }
- }
-
- QPointF qtWindowPoint;
- QPointF qtScreenPoint;
- [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
- Q_UNUSED(qtScreenPoint);
-
- QRegion mask = m_platformWindow->window()->mask();
- const bool masked = !mask.isEmpty() && !mask.contains(qtWindowPoint.toPoint());
- // Maintain masked state for the button for use by MouseDragged and Up.
- if (masked)
- m_acceptedMouseDowns &= ~Qt::LeftButton;
- else
- m_acceptedMouseDowns |= Qt::LeftButton;
-
- // Forward masked out events to the next responder
- if (masked) {
- [super mouseDown:theEvent];
- return;
- }
-
- if ([self hasMarkedText]) {
- [[NSTextInputContext currentInputContext] handleEvent:theEvent];
- } else {
- auto ctrlOrMetaModifier = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) ? Qt::ControlModifier : Qt::MetaModifier;
- if (!m_dontOverrideCtrlLMB && [QNSView convertKeyModifiers:[theEvent modifierFlags]] & ctrlOrMetaModifier) {
- m_buttons |= Qt::RightButton;
- m_sendUpAsRightButton = true;
- } else {
- m_buttons |= Qt::LeftButton;
- }
- [self handleMouseEvent:theEvent];
- }
-}
-
-- (void)mouseDragged:(NSEvent *)theEvent
-{
- const bool accepted = [self handleMouseDraggedEvent:theEvent withButton:[theEvent buttonNumber]];
- if (!accepted)
- [super mouseDragged:theEvent];
-}
-
-- (void)mouseUp:(NSEvent *)theEvent
-{
- const bool accepted = [self handleMouseUpEvent:theEvent withButton:[theEvent buttonNumber]];
- if (!accepted)
- [super mouseUp:theEvent];
-}
-
-- (void)rightMouseDown:(NSEvent *)theEvent
-{
- // Wacom tablet might not return the correct button number for NSEvent buttonNumber
- // on right clicks. Decide here that the button is the "right" button and forward
- // the button number to the mouse (and tablet) handler.
- const bool accepted = [self handleMouseDownEvent:theEvent withButton:1];
- if (!accepted)
- [super rightMouseDown:theEvent];
-}
-
-- (void)rightMouseDragged:(NSEvent *)theEvent
-{
- const bool accepted = [self handleMouseDraggedEvent:theEvent withButton:1];
- if (!accepted)
- [super rightMouseDragged:theEvent];
-}
-
-- (void)rightMouseUp:(NSEvent *)theEvent
-{
- const bool accepted = [self handleMouseUpEvent:theEvent withButton:1];
- if (!accepted)
- [super rightMouseUp:theEvent];
-}
-
-- (void)otherMouseDown:(NSEvent *)theEvent
-{
- const bool accepted = [self handleMouseDownEvent:theEvent withButton:[theEvent buttonNumber]];
- if (!accepted)
- [super otherMouseDown:theEvent];
-}
-
-- (void)otherMouseDragged:(NSEvent *)theEvent
-{
- const bool accepted = [self handleMouseDraggedEvent:theEvent withButton:[theEvent buttonNumber]];
- if (!accepted)
- [super otherMouseDragged:theEvent];
-}
-
-- (void)otherMouseUp:(NSEvent *)theEvent
-{
- const bool accepted = [self handleMouseUpEvent:theEvent withButton:[theEvent buttonNumber]];
- if (!accepted)
- [super otherMouseUp:theEvent];
-}
-
-- (void)updateTrackingAreas
-{
- [super updateTrackingAreas];
-
- QMacAutoReleasePool pool;
-
- // NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early
- if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea])
- return;
-
- // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should
- // only be turned on if mouseTracking, hover is on or a tool tip is set.
- // Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to
- // turn it on in ALL case. That means EVERY QWindow gets to pay the cost of
- // mouse moves delivered to it (Apple recommends keeping it OFF because there
- // is a performance hit). So it goes.
- NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp
- | NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
- [m_trackingArea release];
- m_trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame]
- options:trackingOptions
- owner:m_mouseMoveHelper
- userInfo:nil];
- [self addTrackingArea:m_trackingArea];
-}
-
-- (void)cursorUpdate:(NSEvent *)theEvent
-{
- qCDebug(lcQpaCocoaMouse) << "[QNSView cursorUpdate:]" << self.cursor;
-
- // Note: We do not get this callback when moving from a subview that
- // uses the legacy cursorRect API, so the cursor is reset to the arrow
- // cursor. See rdar://34183708
-
- if (self.cursor)
- [self.cursor set];
- else
- [super cursorUpdate:theEvent];
-}
-
-- (void)mouseMovedImpl:(NSEvent *)theEvent
-{
- if (!m_platformWindow)
- return;
-
- if ([self isTransparentForUserInput])
- return;
-
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
-
- // Top-level windows generate enter-leave events for sub-windows.
- // Qt wants to know which window (if any) will be entered at the
- // the time of the leave. This is dificult to accomplish by
- // handling mouseEnter and mouseLeave envents, since they are sent
- // individually to different views.
- if (m_platformWindow->isContentView() && childWindow) {
- if (childWindow != m_platformWindow->m_enterLeaveTargetWindow) {
- QWindowSystemInterface::handleEnterLeaveEvent(childWindow, m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
- m_platformWindow->m_enterLeaveTargetWindow = childWindow;
- }
- }
-
- // Cocoa keeps firing mouse move events for obscured parent views. Qt should not
- // send those events so filter them out here.
- if (childWindow != m_platformWindow->window())
- return;
-
- [self handleMouseEvent: theEvent];
-}
-
-- (void)mouseEnteredImpl:(NSEvent *)theEvent
-{
- Q_UNUSED(theEvent)
- if (!m_platformWindow)
- return;
-
- m_platformWindow->m_windowUnderMouse = true;
-
- if ([self isTransparentForUserInput])
- return;
-
- // Top-level windows generate enter events for sub-windows.
- if (!m_platformWindow->isContentView())
- return;
-
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- m_platformWindow->m_enterLeaveTargetWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
- QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
-}
-
-- (void)mouseExitedImpl:(NSEvent *)theEvent
-{
- Q_UNUSED(theEvent);
- if (!m_platformWindow)
- return;
-
- m_platformWindow->m_windowUnderMouse = false;
-
- if ([self isTransparentForUserInput])
- return;
-
- // Top-level windows generate leave events for sub-windows.
- if (!m_platformWindow->isContentView())
- return;
-
- QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_enterLeaveTargetWindow);
- m_platformWindow->m_enterLeaveTargetWindow = 0;
-}
-
-#ifndef QT_NO_TABLETEVENT
-struct QCocoaTabletDeviceData
-{
- QTabletEvent::TabletDevice device;
- QTabletEvent::PointerType pointerType;
- uint capabilityMask;
- qint64 uid;
-};
-
-typedef QHash<uint, QCocoaTabletDeviceData> QCocoaTabletDeviceDataHash;
-Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash)
-
-- (bool)handleTabletEvent: (NSEvent *)theEvent
-{
- static bool ignoreButtonMapping = qEnvironmentVariableIsSet("QT_MAC_TABLET_IGNORE_BUTTON_MAPPING");
-
- if (!m_platformWindow)
- return false;
-
- NSEventType eventType = [theEvent type];
- if (eventType != NSTabletPoint && [theEvent subtype] != NSTabletPointEventSubtype)
- return false; // Not a tablet event.
-
- ulong timestamp = [theEvent timestamp] * 1000;
-
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint: &windowPoint andScreenPoint: &screenPoint];
-
- uint deviceId = [theEvent deviceID];
- if (!tabletDeviceDataHash->contains(deviceId)) {
- // Error: Unknown tablet device. Qt also gets into this state
- // when running on a VM. This appears to be harmless; don't
- // print a warning.
- return false;
- }
- const QCocoaTabletDeviceData &deviceData = tabletDeviceDataHash->value(deviceId);
-
- bool down = (eventType != NSMouseMoved);
-
- qreal pressure;
- if (down) {
- pressure = [theEvent pressure];
- } else {
- pressure = 0.0;
- }
-
- NSPoint tilt = [theEvent tilt];
- int xTilt = qRound(tilt.x * 60.0);
- int yTilt = qRound(tilt.y * -60.0);
- qreal tangentialPressure = 0;
- qreal rotation = 0;
- int z = 0;
- if (deviceData.capabilityMask & 0x0200)
- z = [theEvent absoluteZ];
-
- if (deviceData.capabilityMask & 0x0800)
- tangentialPressure = ([theEvent tangentialPressure] * 2.0) - 1.0;
-
- rotation = 360.0 - [theEvent rotation];
- if (rotation > 180.0)
- rotation -= 360.0;
-
- Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- Qt::MouseButtons buttons = ignoreButtonMapping ? static_cast<Qt::MouseButtons>(static_cast<uint>([theEvent buttonMask])) : m_buttons;
-
- qCDebug(lcQpaTablet, "event on tablet %d with tool %d type %d unique ID %lld pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf",
- deviceId, deviceData.device, deviceData.pointerType, deviceData.uid,
- windowPoint.x(), windowPoint.y(), screenPoint.x(), screenPoint.y(),
- static_cast<uint>(buttons), pressure, xTilt, yTilt, rotation);
-
- QWindowSystemInterface::handleTabletEvent(m_platformWindow->window(), timestamp, windowPoint, screenPoint,
- deviceData.device, deviceData.pointerType, buttons, pressure, xTilt, yTilt,
- tangentialPressure, rotation, z, deviceData.uid,
- keyboardModifiers);
- return true;
-}
-
-- (void)tabletPoint:(NSEvent *)theEvent
-{
- if ([self isTransparentForUserInput])
- return [super tabletPoint:theEvent];
-
- [self handleTabletEvent: theEvent];
-}
-
-static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
-{
- qint64 uid = [theEvent uniqueID];
- uint bits = [theEvent vendorPointingDeviceType];
- if (bits == 0 && uid != 0) {
- // Fallback. It seems that the driver doesn't always include all the information.
- // High-End Wacom devices store their "type" in the uper bits of the Unique ID.
- // I'm not sure how to handle it for consumer devices, but I'll test that in a bit.
- bits = uid >> 32;
- }
-
- QTabletEvent::TabletDevice device;
- // Defined in the "EN0056-NxtGenImpGuideX"
- // on Wacom's Developer Website (www.wacomeng.com)
- if (((bits & 0x0006) == 0x0002) && ((bits & 0x0F06) != 0x0902)) {
- device = QTabletEvent::Stylus;
- } else {
- switch (bits & 0x0F06) {
- case 0x0802:
- device = QTabletEvent::Stylus;
- break;
- case 0x0902:
- device = QTabletEvent::Airbrush;
- break;
- case 0x0004:
- device = QTabletEvent::FourDMouse;
- break;
- case 0x0006:
- device = QTabletEvent::Puck;
- break;
- case 0x0804:
- device = QTabletEvent::RotationStylus;
- break;
- default:
- device = QTabletEvent::NoDevice;
- }
- }
- return device;
-}
-
-- (void)tabletProximity:(NSEvent *)theEvent
-{
- if ([self isTransparentForUserInput])
- return [super tabletProximity:theEvent];
-
- ulong timestamp = [theEvent timestamp] * 1000;
-
- QCocoaTabletDeviceData deviceData;
- deviceData.uid = [theEvent uniqueID];
- deviceData.capabilityMask = [theEvent capabilityMask];
-
- switch ([theEvent pointingDeviceType]) {
- case NSUnknownPointingDevice:
- default:
- deviceData.pointerType = QTabletEvent::UnknownPointer;
- break;
- case NSPenPointingDevice:
- deviceData.pointerType = QTabletEvent::Pen;
- break;
- case NSCursorPointingDevice:
- deviceData.pointerType = QTabletEvent::Cursor;
- break;
- case NSEraserPointingDevice:
- deviceData.pointerType = QTabletEvent::Eraser;
- break;
- }
-
- deviceData.device = wacomTabletDevice(theEvent);
-
- // The deviceID is "unique" while in the proximity, it's a key that we can use for
- // linking up QCocoaTabletDeviceData to an event (especially if there are two devices in action).
- bool entering = [theEvent isEnteringProximity];
- uint deviceId = [theEvent deviceID];
- if (entering) {
- tabletDeviceDataHash->insert(deviceId, deviceData);
- } else {
- tabletDeviceDataHash->remove(deviceId);
- }
-
- qCDebug(lcQpaTablet, "proximity change on tablet %d: current tool %d type %d unique ID %lld",
- deviceId, deviceData.device, deviceData.pointerType, deviceData.uid);
+@end
- if (entering) {
- QWindowSystemInterface::handleTabletEnterProximityEvent(timestamp, deviceData.device, deviceData.pointerType, deviceData.uid);
- } else {
- QWindowSystemInterface::handleTabletLeaveProximityEvent(timestamp, deviceData.device, deviceData.pointerType, deviceData.uid);
- }
-}
+#include "qnsview_drawing.mm"
+#include "qnsview_mouse.mm"
+#include "qnsview_touch.mm"
+#include "qnsview_gestures.mm"
+#include "qnsview_tablet.mm"
+#include "qnsview_dragging.mm"
+#include "qnsview_keys.mm"
+#include "qnsview_complextext.mm"
+#include "qnsview_menus.mm"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qnsview_accessibility.mm"
#endif
-- (bool)shouldSendSingleTouch
-{
- if (!m_platformWindow)
- return true;
-
- // QtWidgets expects single-point touch events, QtDeclarative does not.
- // Until there is an API we solve this by looking at the window class type.
- return m_platformWindow->window()->inherits("QWidgetWindow");
-}
-
-- (void)touchesBeganWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- const NSTimeInterval timestamp = [event timestamp];
- const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
- qCDebug(lcQpaTouch) << "touchesBeganWithEvent" << points << "from device" << hex << [event deviceID];
- QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
-}
-
-- (void)touchesMovedWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- const NSTimeInterval timestamp = [event timestamp];
- const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
- qCDebug(lcQpaTouch) << "touchesMovedWithEvent" << points << "from device" << hex << [event deviceID];
- QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
-}
-
-- (void)touchesEndedWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- const NSTimeInterval timestamp = [event timestamp];
- const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
- qCDebug(lcQpaTouch) << "touchesEndedWithEvent" << points << "from device" << hex << [event deviceID];
- QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
-}
-
-- (void)touchesCancelledWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- const NSTimeInterval timestamp = [event timestamp];
- const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
- qCDebug(lcQpaTouch) << "touchesCancelledWithEvent" << points << "from device" << hex << [event deviceID];
- QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
-}
-
-#ifndef QT_NO_GESTURES
-
-- (bool)handleGestureAsBeginEnd:(NSEvent *)event
-{
- if (QOperatingSystemVersion::current() < QOperatingSystemVersion::OSXElCapitan)
- return false;
-
- if ([event phase] == NSEventPhaseBegan) {
- [self beginGestureWithEvent:event];
- return true;
- }
-
- if ([event phase] == NSEventPhaseEnded) {
- [self endGestureWithEvent:event];
- return true;
- }
-
- return false;
-}
-- (void)magnifyWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- if ([self handleGestureAsBeginEnd:event])
- return;
-
- qCDebug(lcQpaGestures) << "magnifyWithEvent" << [event magnification] << "from device" << hex << [event deviceID];
- const NSTimeInterval timestamp = [event timestamp];
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::ZoomNativeGesture,
- [event magnification], windowPoint, screenPoint);
-}
-
-- (void)smartMagnifyWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- static bool zoomIn = true;
- qCDebug(lcQpaGestures) << "smartMagnifyWithEvent" << zoomIn << "from device" << hex << [event deviceID];
- const NSTimeInterval timestamp = [event timestamp];
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::SmartZoomNativeGesture,
- zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
- zoomIn = !zoomIn;
-}
-
-- (void)rotateWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- if ([self handleGestureAsBeginEnd:event])
- return;
-
- const NSTimeInterval timestamp = [event timestamp];
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::RotateNativeGesture,
- -[event rotation], windowPoint, screenPoint);
-}
-
-- (void)swipeWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- qCDebug(lcQpaGestures) << "swipeWithEvent" << [event deltaX] << [event deltaY] << "from device" << hex << [event deviceID];
- const NSTimeInterval timestamp = [event timestamp];
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
-
- qreal angle = 0.0f;
- if ([event deltaX] == 1)
- angle = 180.0f;
- else if ([event deltaX] == -1)
- angle = 0.0f;
- else if ([event deltaY] == 1)
- angle = 90.0f;
- else if ([event deltaY] == -1)
- angle = 270.0f;
-
- QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::SwipeNativeGesture,
- angle, windowPoint, screenPoint);
-}
-
-- (void)beginGestureWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- const NSTimeInterval timestamp = [event timestamp];
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint << "from device" << hex << [event deviceID];
- QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::BeginNativeGesture,
- windowPoint, screenPoint);
-}
-
-- (void)endGestureWithEvent:(NSEvent *)event
-{
- if (!m_platformWindow)
- return;
-
- qCDebug(lcQpaGestures) << "endGestureWithEvent" << "from device" << hex << [event deviceID];
- const NSTimeInterval timestamp = [event timestamp];
- QPointF windowPoint;
- QPointF screenPoint;
- [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::EndNativeGesture,
- windowPoint, screenPoint);
-}
-#endif // QT_NO_GESTURES
-
-#if QT_CONFIG(wheelevent)
-- (void)scrollWheel:(NSEvent *)theEvent
-{
- if (!m_platformWindow)
- return;
-
- if ([self isTransparentForUserInput])
- return [super scrollWheel:theEvent];
-
- QPoint angleDelta;
- Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
- if ([theEvent hasPreciseScrollingDeltas]) {
- // The mouse device contains pixel scroll wheel support (Mighty Mouse, Trackpad).
- // Since deviceDelta is delivered as pixels rather than degrees, we need to
- // convert from pixels to degrees in a sensible manner.
- // It looks like 1/4 degrees per pixel behaves most native.
- // (NB: Qt expects the unit for delta to be 8 per degree):
- const int pixelsToDegrees = 2; // 8 * 1/4
- angleDelta.setX([theEvent scrollingDeltaX] * pixelsToDegrees);
- angleDelta.setY([theEvent scrollingDeltaY] * pixelsToDegrees);
- source = Qt::MouseEventSynthesizedBySystem;
- } else {
- // Remove acceleration, and use either -120 or 120 as delta:
- angleDelta.setX(qBound(-120, int([theEvent deltaX] * 10000), 120));
- angleDelta.setY(qBound(-120, int([theEvent deltaY] * 10000), 120));
- }
-
- QPoint pixelDelta;
- if ([theEvent hasPreciseScrollingDeltas]) {
- pixelDelta.setX([theEvent scrollingDeltaX]);
- pixelDelta.setY([theEvent scrollingDeltaY]);
- } else {
- // docs: "In the case of !hasPreciseScrollingDeltas, multiply the delta with the line width."
- // scrollingDeltaX seems to return a minimum value of 0.1 in this case, map that to two pixels.
- const CGFloat lineWithEstimate = 20.0;
- pixelDelta.setX([theEvent scrollingDeltaX] * lineWithEstimate);
- pixelDelta.setY([theEvent scrollingDeltaY] * lineWithEstimate);
- }
-
- QPointF qt_windowPoint;
- QPointF qt_screenPoint;
- [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qt_windowPoint andScreenPoint:&qt_screenPoint];
- NSTimeInterval timestamp = [theEvent timestamp];
- ulong qt_timestamp = timestamp * 1000;
-
- // Prevent keyboard modifier state from changing during scroll event streams.
- // A two-finger trackpad flick generates a stream of scroll events. We want
- // the keyboard modifier state to be the state at the beginning of the
- // flick in order to avoid changing the interpretation of the events
- // mid-stream. One example of this happening would be when pressing cmd
- // after scrolling in Qt Creator: not taking the phase into account causes
- // the end of the event stream to be interpreted as font size changes.
- NSEventPhase momentumPhase = [theEvent momentumPhase];
- if (momentumPhase == NSEventPhaseNone) {
- currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- }
-
- NSEventPhase phase = [theEvent phase];
- Qt::ScrollPhase ph = Qt::ScrollUpdate;
-
- // MayBegin is likely to happen. We treat it the same as an actual begin.
- if (phase == NSEventPhaseMayBegin) {
- m_scrolling = true;
- ph = Qt::ScrollBegin;
- } else if (phase == NSEventPhaseBegan) {
- // If MayBegin did not happen, Began is the actual beginning.
- if (!m_scrolling)
- ph = Qt::ScrollBegin;
- m_scrolling = true;
- } else if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled ||
- momentumPhase == NSEventPhaseEnded || momentumPhase == NSEventPhaseCancelled) {
- ph = Qt::ScrollEnd;
- m_scrolling = false;
- } else if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) {
- ph = Qt::NoScrollPhase;
- }
- // "isInverted": natural OS X scrolling, inverted from the Qt/other platform/Jens perspective.
- bool isInverted = [theEvent isDirectionInvertedFromDevice];
-
- qCDebug(lcQpaCocoaMouse) << "scroll wheel @ window pos" << qt_windowPoint << "delta px" << pixelDelta << "angle" << angleDelta << "phase" << ph << (isInverted ? "inverted" : "");
- QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph, source, isInverted);
-}
-#endif // QT_CONFIG(wheelevent)
-
-- (int) convertKeyCode : (QChar)keyChar
-{
- return qt_mac_cocoaKey2QtKey(keyChar);
-}
-
-+ (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags
-{
- const bool dontSwapCtrlAndMeta = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
- Qt::KeyboardModifiers qtMods =Qt::NoModifier;
- if (modifierFlags & NSShiftKeyMask)
- qtMods |= Qt::ShiftModifier;
- if (modifierFlags & NSControlKeyMask)
- qtMods |= dontSwapCtrlAndMeta ? Qt::ControlModifier : Qt::MetaModifier;
- if (modifierFlags & NSAlternateKeyMask)
- qtMods |= Qt::AltModifier;
- if (modifierFlags & NSCommandKeyMask)
- qtMods |= dontSwapCtrlAndMeta ? Qt::MetaModifier : Qt::ControlModifier;
- if (modifierFlags & NSNumericPadKeyMask)
- qtMods |= Qt::KeypadModifier;
- return qtMods;
-}
-
-- (bool)handleKeyEvent:(NSEvent *)nsevent eventType:(int)eventType
-{
- ulong timestamp = [nsevent timestamp] * 1000;
- ulong nativeModifiers = [nsevent modifierFlags];
- Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers];
- NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers];
- NSString *characters = [nsevent characters];
- if (m_inputSource != characters) {
- [m_inputSource release];
- m_inputSource = [characters retain];
- }
-
- // There is no way to get the scan code from carbon/cocoa. But we cannot
- // use the value 0, since it indicates that the event originates from somewhere
- // else than the keyboard.
- quint32 nativeScanCode = 1;
- quint32 nativeVirtualKey = [nsevent keyCode];
-
- QChar ch = QChar::ReplacementCharacter;
- int keyCode = Qt::Key_unknown;
-
- // If a dead key occurs as a result of pressing a key combination then
- // characters will have 0 length, but charactersIgnoringModifiers will
- // have a valid character in it. This enables key combinations such as
- // ALT+E to be used as a shortcut with an English keyboard even though
- // pressing ALT+E will give a dead key while doing normal text input.
- if ([characters length] != 0 || [charactersIgnoringModifiers length] != 0) {
- auto ctrlOrMetaModifier = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) ? Qt::ControlModifier : Qt::MetaModifier;
- if (((modifiers & ctrlOrMetaModifier) || (modifiers & Qt::AltModifier)) && ([charactersIgnoringModifiers length] != 0))
- ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
- else if ([characters length] != 0)
- ch = QChar([characters characterAtIndex:0]);
- keyCode = [self convertKeyCode:ch];
- }
-
- // we will send a key event unless the input method sets m_sendKeyEvent to false
- m_sendKeyEvent = true;
- QString text;
- // ignore text for the U+F700-U+F8FF range. This is used by Cocoa when
- // delivering function keys (e.g. arrow keys, backspace, F1-F35, etc.)
- if (!(modifiers & (Qt::ControlModifier | Qt::MetaModifier)) && (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff))
- text = QString::fromNSString(characters);
-
- QWindow *window = [self topLevelWindow];
-
- // Popups implicitly grab key events; forward to the active popup if there is one.
- // This allows popups to e.g. intercept shortcuts and close the popup in response.
- if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) {
- if (!popup->m_windowFlags.testFlag(Qt::ToolTip))
- window = popup->window();
- }
-
- if (eventType == QEvent::KeyPress) {
-
- if (m_composingText.isEmpty()) {
- m_sendKeyEvent = !QWindowSystemInterface::handleShortcutEvent(window, timestamp, keyCode,
- modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1);
-
- // Handling a shortcut may result in closing the window
- if (!m_platformWindow)
- return true;
- }
-
- QObject *fo = m_platformWindow->window()->focusObject();
- if (m_sendKeyEvent && fo) {
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints);
- if (QCoreApplication::sendEvent(fo, &queryEvent)) {
- bool imEnabled = queryEvent.value(Qt::ImEnabled).toBool();
- Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
- if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) {
- // pass the key event to the input method. note that m_sendKeyEvent may be set to false during this call
- m_currentlyInterpretedKeyEvent = nsevent;
- [self interpretKeyEvents:[NSArray arrayWithObject:nsevent]];
- m_currentlyInterpretedKeyEvent = 0;
- }
- }
- }
- if (m_resendKeyEvent)
- m_sendKeyEvent = true;
- }
-
- bool accepted = true;
- if (m_sendKeyEvent && m_composingText.isEmpty()) {
- QWindowSystemInterface::handleExtendedKeyEvent(window, timestamp, QEvent::Type(eventType), keyCode, modifiers,
- nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1, false);
- accepted = QWindowSystemInterface::flushWindowSystemEvents();
- }
- m_sendKeyEvent = false;
- m_resendKeyEvent = false;
- return accepted;
-}
-
-- (void)keyDown:(NSEvent *)nsevent
-{
- if ([self isTransparentForUserInput])
- return [super keyDown:nsevent];
-
- const bool accepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
-
- // When Qt is used to implement a plugin for a native application we
- // want to propagate unhandled events to other native views. However,
- // Qt does not always set the accepted state correctly (in particular
- // for return key events), so do this for plugin applications only
- // to prevent incorrect forwarding in the general case.
- const bool shouldPropagate = QCoreApplication::testAttribute(Qt::AA_PluginApplication) && !accepted;
-
- // Track keyDown acceptance/forward state for later acceptance of the keyUp.
- if (!shouldPropagate)
- m_acceptedKeyDowns.insert([nsevent keyCode]);
-
- if (shouldPropagate)
- [super keyDown:nsevent];
-}
-
-- (void)keyUp:(NSEvent *)nsevent
-{
- if ([self isTransparentForUserInput])
- return [super keyUp:nsevent];
-
- const bool keyUpAccepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)];
-
- // Propagate the keyUp if neither Qt accepted it nor the corresponding KeyDown was
- // accepted. Qt text controls wil often not use and ignore keyUp events, but we
- // want to avoid propagating unmatched keyUps.
- const bool keyDownAccepted = m_acceptedKeyDowns.remove([nsevent keyCode]);
- if (!keyUpAccepted && !keyDownAccepted)
- [super keyUp:nsevent];
-}
-
-- (void)cancelOperation:(id)sender
-{
- Q_UNUSED(sender);
-
- NSEvent *currentEvent = [NSApp currentEvent];
- if (!currentEvent || currentEvent.type != NSKeyDown)
- return;
-
- // Handling the key event may recurse back here through interpretKeyEvents
- // (when IM is enabled), so we need to guard against that.
- if (currentEvent == m_currentlyInterpretedKeyEvent)
- return;
-
- // Send Command+Key_Period and Escape as normal keypresses so that
- // the key sequence is delivered through Qt. That way clients can
- // intercept the shortcut and override its effect.
- [self handleKeyEvent:currentEvent eventType:int(QEvent::KeyPress)];
-}
-
-- (void)flagsChanged:(NSEvent *)nsevent
-{
- ulong timestamp = [nsevent timestamp] * 1000;
- ulong modifiers = [nsevent modifierFlags];
- Qt::KeyboardModifiers qmodifiers = [QNSView convertKeyModifiers:modifiers];
-
- // calculate the delta and remember the current modifiers for next time
- static ulong m_lastKnownModifiers;
- ulong lastKnownModifiers = m_lastKnownModifiers;
- ulong delta = lastKnownModifiers ^ modifiers;
- m_lastKnownModifiers = modifiers;
-
- struct qt_mac_enum_mapper
- {
- ulong mac_mask;
- Qt::Key qt_code;
- };
- static qt_mac_enum_mapper modifier_key_symbols[] = {
- { NSShiftKeyMask, Qt::Key_Shift },
- { NSControlKeyMask, Qt::Key_Meta },
- { NSCommandKeyMask, Qt::Key_Control },
- { NSAlternateKeyMask, Qt::Key_Alt },
- { NSAlphaShiftKeyMask, Qt::Key_CapsLock },
- { 0ul, Qt::Key_unknown } };
- for (int i = 0; modifier_key_symbols[i].mac_mask != 0u; ++i) {
- uint mac_mask = modifier_key_symbols[i].mac_mask;
- if ((delta & mac_mask) == 0u)
- continue;
-
- Qt::Key qtCode = modifier_key_symbols[i].qt_code;
- if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
- if (qtCode == Qt::Key_Meta)
- qtCode = Qt::Key_Control;
- else if (qtCode == Qt::Key_Control)
- qtCode = Qt::Key_Meta;
- }
- QWindowSystemInterface::handleKeyEvent(m_platformWindow->window(),
- timestamp,
- (lastKnownModifiers & mac_mask) ? QEvent::KeyRelease : QEvent::KeyPress,
- qtCode,
- qmodifiers ^ [QNSView convertKeyModifiers:mac_mask]);
- }
-}
-
-- (void) insertNewline:(id)sender
-{
- Q_UNUSED(sender);
- m_resendKeyEvent = true;
-}
-
-- (void) doCommandBySelector:(SEL)aSelector
-{
- [self tryToPerform:aSelector with:self];
-}
-
-- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
-{
- Q_UNUSED(replacementRange)
-
- if (m_sendKeyEvent && m_composingText.isEmpty() && [aString isEqualToString:m_inputSource]) {
- // don't send input method events for simple text input (let handleKeyEvent send key events instead)
- return;
- }
-
- QString commitString;
- if ([aString length]) {
- if ([aString isKindOfClass:[NSAttributedString class]]) {
- commitString = QString::fromCFString(reinterpret_cast<CFStringRef>([aString string]));
- } else {
- commitString = QString::fromCFString(reinterpret_cast<CFStringRef>(aString));
- };
- }
- if (QObject *fo = m_platformWindow->window()->focusObject()) {
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
- if (QCoreApplication::sendEvent(fo, &queryEvent)) {
- if (queryEvent.value(Qt::ImEnabled).toBool()) {
- QInputMethodEvent e;
- e.setCommitString(commitString);
- QCoreApplication::sendEvent(fo, &e);
- // prevent handleKeyEvent from sending a key event
- m_sendKeyEvent = false;
- }
- }
- }
-
- m_composingText.clear();
- m_composingFocusObject = nullptr;
-}
-
-- (void) setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
-{
- Q_UNUSED(replacementRange)
- QString preeditString;
-
- QList<QInputMethodEvent::Attribute> attrs;
- attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selectedRange.location + selectedRange.length, 1, QVariant());
-
- if ([aString isKindOfClass:[NSAttributedString class]]) {
- // Preedit string has attribution
- preeditString = QString::fromCFString(reinterpret_cast<CFStringRef>([aString string]));
- int composingLength = preeditString.length();
- int index = 0;
- // Create attributes for individual sections of preedit text
- while (index < composingLength) {
- NSRange effectiveRange;
- NSRange range = NSMakeRange(index, composingLength-index);
- NSDictionary *attributes = [aString attributesAtIndex:index
- longestEffectiveRange:&effectiveRange
- inRange:range];
- NSNumber *underlineStyle = [attributes objectForKey:NSUnderlineStyleAttributeName];
- if (underlineStyle) {
- QColor clr (Qt::black);
- NSColor *color = [attributes objectForKey:NSUnderlineColorAttributeName];
- if (color) {
- clr = qt_mac_toQColor(color);
- }
- QTextCharFormat format;
- format.setFontUnderline(true);
- format.setUnderlineColor(clr);
- attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- effectiveRange.location,
- effectiveRange.length,
- format);
- }
- index = effectiveRange.location + effectiveRange.length;
- }
- } else {
- // No attributes specified, take only the preedit text.
- preeditString = QString::fromCFString(reinterpret_cast<CFStringRef>(aString));
- }
-
- if (attrs.isEmpty()) {
- QTextCharFormat format;
- format.setFontUnderline(true);
- attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- 0, preeditString.length(), format);
- }
-
- m_composingText = preeditString;
-
- if (QObject *fo = m_platformWindow->window()->focusObject()) {
- m_composingFocusObject = fo;
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
- if (QCoreApplication::sendEvent(fo, &queryEvent)) {
- if (queryEvent.value(Qt::ImEnabled).toBool()) {
- QInputMethodEvent e(preeditString, attrs);
- QCoreApplication::sendEvent(fo, &e);
- // prevent handleKeyEvent from sending a key event
- m_sendKeyEvent = false;
- }
- }
- }
-}
-
-- (void)cancelComposingText
-{
- if (m_composingText.isEmpty())
- return;
-
- if (m_composingFocusObject) {
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
- if (QCoreApplication::sendEvent(m_composingFocusObject, &queryEvent)) {
- if (queryEvent.value(Qt::ImEnabled).toBool()) {
- QInputMethodEvent e;
- QCoreApplication::sendEvent(m_composingFocusObject, &e);
- }
- }
- }
-
- m_composingText.clear();
- m_composingFocusObject = nullptr;
-}
-
-- (void) unmarkText
-{
- if (!m_composingText.isEmpty()) {
- if (QObject *fo = m_platformWindow->window()->focusObject()) {
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
- if (QCoreApplication::sendEvent(fo, &queryEvent)) {
- if (queryEvent.value(Qt::ImEnabled).toBool()) {
- QInputMethodEvent e;
- e.setCommitString(m_composingText);
- QCoreApplication::sendEvent(fo, &e);
- }
- }
- }
- }
- m_composingText.clear();
- m_composingFocusObject = nullptr;
-}
-
-- (BOOL) hasMarkedText
-{
- return (m_composingText.isEmpty() ? NO: YES);
-}
-
-- (NSAttributedString *) attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
-{
- Q_UNUSED(actualRange)
- QObject *fo = m_platformWindow->window()->focusObject();
- if (!fo)
- return nil;
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection);
- if (!QCoreApplication::sendEvent(fo, &queryEvent))
- return nil;
- if (!queryEvent.value(Qt::ImEnabled).toBool())
- return nil;
-
- QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString();
- if (selectedText.isEmpty())
- return nil;
-
- QCFString string(selectedText.mid(aRange.location, aRange.length));
- const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
- return [[[NSAttributedString alloc] initWithString:const_cast<NSString *>(tmpString)] autorelease];
-}
-
-- (NSRange) markedRange
-{
- NSRange range;
- if (!m_composingText.isEmpty()) {
- range.location = 0;
- range.length = m_composingText.length();
- } else {
- range.location = NSNotFound;
- range.length = 0;
- }
- return range;
-}
-
-- (NSRange) selectedRange
-{
- NSRange selectedRange = {0, 0};
-
- QObject *fo = m_platformWindow->window()->focusObject();
- if (!fo)
- return selectedRange;
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection);
- if (!QCoreApplication::sendEvent(fo, &queryEvent))
- return selectedRange;
- if (!queryEvent.value(Qt::ImEnabled).toBool())
- return selectedRange;
-
- QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString();
-
- if (!selectedText.isEmpty()) {
- selectedRange.location = 0;
- selectedRange.length = selectedText.length();
- }
- return selectedRange;
-}
-
-- (NSRect) firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
-{
- Q_UNUSED(aRange)
- Q_UNUSED(actualRange)
- QObject *fo = m_platformWindow->window()->focusObject();
- if (!fo)
- return NSZeroRect;
-
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
- if (!QCoreApplication::sendEvent(fo, &queryEvent))
- return NSZeroRect;
- if (!queryEvent.value(Qt::ImEnabled).toBool())
- return NSZeroRect;
-
- if (!m_platformWindow->window())
- return NSZeroRect;
-
- // The returned rect is always based on the internal cursor.
- QRect mr = qApp->inputMethod()->cursorRectangle().toRect();
- mr.moveBottomLeft(m_platformWindow->window()->mapToGlobal(mr.bottomLeft()));
- return QCocoaScreen::mapToNative(mr);
-}
-
-- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
-{
- // We don't support cursor movements using mouse while composing.
- Q_UNUSED(aPoint);
- return NSNotFound;
-}
-
-- (NSArray*)validAttributesForMarkedText
-{
- if (!m_platformWindow)
- return nil;
-
- if (m_platformWindow->window() != QGuiApplication::focusWindow())
- return nil;
-
- QObject *fo = m_platformWindow->window()->focusObject();
- if (!fo)
- return nil;
-
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
- if (!QCoreApplication::sendEvent(fo, &queryEvent))
- return nil;
- if (!queryEvent.value(Qt::ImEnabled).toBool())
- return nil;
-
- // Support only underline color/style.
- return [NSArray arrayWithObjects:NSUnderlineColorAttributeName,
- NSUnderlineStyleAttributeName, nil];
-}
-
--(void)registerDragTypes
-{
- QMacAutoReleasePool pool;
- QStringList customTypes = qt_mac_enabledDraggedTypes();
- if (currentCustomDragTypes == 0 || *currentCustomDragTypes != customTypes) {
- if (currentCustomDragTypes == 0)
- currentCustomDragTypes = new QStringList();
- *currentCustomDragTypes = customTypes;
- const NSString* mimeTypeGeneric = @"com.trolltech.qt.MimeTypeName";
- NSMutableArray *supportedTypes = [NSMutableArray arrayWithObjects:NSColorPboardType,
- NSFilenamesPboardType, NSStringPboardType,
- NSFilenamesPboardType, NSPostScriptPboardType, NSTIFFPboardType,
- NSRTFPboardType, NSTabularTextPboardType, NSFontPboardType,
- NSRulerPboardType, NSFileContentsPboardType, NSColorPboardType,
- NSRTFDPboardType, NSHTMLPboardType,
- NSURLPboardType, NSPDFPboardType, NSVCardPboardType,
- NSFilesPromisePboardType, NSInkTextPboardType,
- NSMultipleTextSelectionPboardType, mimeTypeGeneric, nil];
- // Add custom types supported by the application.
- for (int i = 0; i < customTypes.size(); i++) {
- [supportedTypes addObject:customTypes[i].toNSString()];
- }
- [self registerForDraggedTypes:supportedTypes];
- }
-}
-
-static QWindow *findEventTargetWindow(QWindow *candidate)
-{
- while (candidate) {
- if (!(candidate->flags() & Qt::WindowTransparentForInput))
- return candidate;
- candidate = candidate->parent();
- }
- return candidate;
-}
-
-static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint point)
-{
- return target->mapFromGlobal(source->mapToGlobal(point));
-}
-
-- (NSDragOperation)draggingSession:(NSDraggingSession *)session
- sourceOperationMaskForDraggingContext:(NSDraggingContext)context
-{
- Q_UNUSED(session);
- Q_UNUSED(context);
- QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- return qt_mac_mapDropActions(nativeDrag->currentDrag()->supportedActions());
-}
-
-- (BOOL)ignoreModifierKeysForDraggingSession:(NSDraggingSession *)session
-{
- Q_UNUSED(session);
- // According to the "Dragging Sources" chapter on Cocoa DnD Programming
- // (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DragandDrop/Concepts/dragsource.html),
- // if the control, option, or command key is pressed, the source’s
- // operation mask is filtered to only contain a reduced set of operations.
- //
- // Since Qt already takes care of tracking the keyboard modifiers, we
- // don't need (or want) Cocoa to filter anything. Instead, we'll let
- // the application do the actual filtering.
- return YES;
-}
-
-- (BOOL)wantsPeriodicDraggingUpdates
-{
- // From the documentation:
- //
- // "If the destination returns NO, these messages are sent only when the mouse moves
- // or a modifier flag changes. Otherwise the destination gets the default behavior,
- // where it receives periodic dragging-updated messages even if nothing changes."
- //
- // We do not want these constant drag update events while mouse is stationary,
- // since we do all animations (autoscroll) with timers.
- return NO;
-}
-
-
-- (BOOL)wantsPeriodicDraggingUpdates:(void *)dummy
-{
- // This method never gets called. It's a workaround for Apple's
- // bug: they first respondsToSelector : @selector(wantsPeriodicDraggingUpdates:)
- // (note ':') and then call -wantsPeriodicDraggingUpdate (without colon).
- // So, let's make them happy.
- Q_UNUSED(dummy);
-
- return NO;
-}
-
-- (void)updateCursorFromDragResponse:(QPlatformDragQtResponse)response drag:(QCocoaDrag *)drag
-{
- const QPixmap pixmapCursor = drag->currentDrag()->dragCursor(response.acceptedAction());
- NSCursor *nativeCursor = nil;
-
- if (pixmapCursor.isNull()) {
- switch (response.acceptedAction()) {
- case Qt::CopyAction:
- nativeCursor = [NSCursor dragCopyCursor];
- break;
- case Qt::LinkAction:
- nativeCursor = [NSCursor dragLinkCursor];
- break;
- case Qt::IgnoreAction:
- // Uncomment the next lines if forbiden cursor wanted on non droppable targets.
- /*nativeCursor = [NSCursor operationNotAllowedCursor];
- break;*/
- case Qt::MoveAction:
- default:
- nativeCursor = [NSCursor arrowCursor];
- break;
- }
- }
- else {
- NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor);
- nsimage.size = NSSizeFromCGSize((pixmapCursor.size() / pixmapCursor.devicePixelRatioF()).toCGSize());
- nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint];
- [nsimage release];
- }
-
- // change the cursor
- [nativeCursor set];
-
- // Make sure the cursor is updated correctly if the mouse does not move and window is under cursor
- // by creating a fake move event, unless on 10.14 and later where doing so will trigger a security
- // warning dialog. FIXME: Find a way to update the cursor without fake mouse events.
- if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave)
- return;
-
- if (m_updatingDrag)
- return;
-
- const QPoint mousePos(QCursor::pos());
- CGEventRef moveEvent(CGEventCreateMouseEvent(
- NULL, kCGEventMouseMoved,
- CGPointMake(mousePos.x(), mousePos.y()),
- kCGMouseButtonLeft // ignored
- ));
- CGEventPost(kCGHIDEventTap, moveEvent);
- CFRelease(moveEvent);
-}
-
-- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
-{
- return [self handleDrag : sender];
-}
-
-- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
-{
- m_updatingDrag = true;
- const NSDragOperation ret([self handleDrag : sender]);
- m_updatingDrag = false;
-
- return ret;
-}
-
-// Sends drag update to Qt, return the action
-- (NSDragOperation)handleDrag:(id <NSDraggingInfo>)sender
-{
- if (!m_platformWindow)
- return NSDragOperationNone;
-
- NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
- QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
- Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
-
- QWindow *target = findEventTargetWindow(m_platformWindow->window());
- if (!target)
- return NSDragOperationNone;
-
- // update these so selecting move/copy/link works
- QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]];
-
- QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
- QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- if (nativeDrag->currentDrag()) {
- // The drag was started from within the application
- response = QWindowSystemInterface::handleDrag(target, nativeDrag->dragMimeData(), mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed);
- [self updateCursorFromDragResponse:response drag:nativeDrag];
- } else {
- QCocoaDropData mimeData([sender draggingPasteboard]);
- response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed);
- }
-
- return qt_mac_mapDropAction(response.acceptedAction());
-}
-
-- (void)draggingExited:(id <NSDraggingInfo>)sender
-{
- if (!m_platformWindow)
- return;
-
- QWindow *target = findEventTargetWindow(m_platformWindow->window());
- if (!target)
- return;
-
- NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
- QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
-
- // Send 0 mime data to indicate drag exit
- QWindowSystemInterface::handleDrag(target, 0, mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), Qt::IgnoreAction);
-}
-
-// called on drop, send the drop to Qt and return if it was accepted.
-- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
-{
- if (!m_platformWindow)
- return false;
-
- QWindow *target = findEventTargetWindow(m_platformWindow->window());
- if (!target)
- return false;
-
- NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
- QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
- Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
-
- QPlatformDropQtResponse response(false, Qt::IgnoreAction);
- QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- if (nativeDrag->currentDrag()) {
- // The drag was started from within the application
- response = QWindowSystemInterface::handleDrop(target, nativeDrag->dragMimeData(), mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed);
- } else {
- QCocoaDropData mimeData([sender draggingPasteboard]);
- response = QWindowSystemInterface::handleDrop(target, &mimeData, mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint), qtAllowed);
- }
- if (response.isAccepted()) {
- QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- nativeDrag->setAcceptedAction(response.acceptedAction());
- }
- return response.isAccepted();
-}
-
-- (void)draggingSession:(NSDraggingSession *)session
- endedAtPoint:(NSPoint)screenPoint
- operation:(NSDragOperation)operation
-{
- Q_UNUSED(session);
- Q_UNUSED(operation);
-
- if (!m_platformWindow)
- return;
-
- QWindow *target = findEventTargetWindow(m_platformWindow->window());
- if (!target)
- return;
-
- // keep our state, and QGuiApplication state (buttons member) in-sync,
- // or future mouse events will be processed incorrectly
- NSUInteger pmb = [NSEvent pressedMouseButtons];
- for (int buttonNumber = 0; buttonNumber < 32; buttonNumber++) { // see cocoaButton2QtButton() for the 32 value
- if (!(pmb & (1 << buttonNumber)))
- m_buttons &= ~cocoaButton2QtButton(buttonNumber);
- }
-
- NSPoint windowPoint = [self.window convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 1, 1)].origin;
- NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil]; // NSView/QWindow coordinates
- QPoint qtWindowPoint(nsViewPoint.x, nsViewPoint.y);
- QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint();
-
- QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_platformWindow->window(), target, qtWindowPoint), qtScreenPoint, m_buttons);
-}
-
-@end
+// -----------------------------------------------------
@implementation QT_MANGLE_NAMESPACE(QNSView) (QtExtras)
@@ -2089,9 +347,4 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
return m_platformWindow.data();;
}
-- (BOOL)isMenuView
-{
- return m_isMenuView;
-}
-
@end
diff --git a/src/plugins/platforms/cocoa/qnsview_accessibility.mm b/src/plugins/platforms/cocoa/qnsview_accessibility.mm
new file mode 100644
index 0000000000..32ec0b74d4
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_accessibility.mm
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+#include "qcocoaaccessibility.h"
+#include "qcocoaaccessibilityelement.h"
+#include "qcocoaintegration.h"
+
+#include <QtGui/qaccessible.h>
+
+#import <AppKit/NSAccessibility.h>
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Accessibility)
+
+- (id)childAccessibleElement
+{
+ QCocoaWindow *platformWindow = self.platformWindow;
+ if (!platformWindow || !platformWindow->window()->accessibleRoot())
+ return nil;
+
+ QAccessible::Id childId = QAccessible::uniqueId(platformWindow->window()->accessibleRoot());
+ return [QMacAccessibilityElement elementWithId:childId];
+}
+
+// The QNSView is a container that the user does not interact directly with:
+// Remove it from the user-visible accessibility tree.
+- (BOOL)accessibilityIsIgnored
+{
+ return YES;
+}
+
+- (id)accessibilityAttributeValue:(NSString *)attribute
+{
+ // activate accessibility updates
+ QCocoaIntegration::instance()->accessibility()->setActive(true);
+
+ if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
+ return NSAccessibilityUnignoredChildrenForOnlyChild([self childAccessibleElement]);
+ else
+ return [super accessibilityAttributeValue:attribute];
+}
+
+- (id)accessibilityHitTest:(NSPoint)point
+{
+ return [[self childAccessibleElement] accessibilityHitTest:point];
+}
+
+- (id)accessibilityFocusedUIElement
+{
+ return [[self childAccessibleElement] accessibilityFocusedUIElement];
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnsview_complextext.mm b/src/plugins/platforms/cocoa/qnsview_complextext.mm
new file mode 100644
index 0000000000..d357082d33
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_complextext.mm
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (ComplexTextAPI)
+
+- (void)cancelComposingText
+{
+ if (m_composingText.isEmpty())
+ return;
+
+ if (m_composingFocusObject) {
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
+ if (QCoreApplication::sendEvent(m_composingFocusObject, &queryEvent)) {
+ if (queryEvent.value(Qt::ImEnabled).toBool()) {
+ QInputMethodEvent e;
+ QCoreApplication::sendEvent(m_composingFocusObject, &e);
+ }
+ }
+ }
+
+ m_composingText.clear();
+ m_composingFocusObject = nullptr;
+}
+
+- (void)unmarkText
+{
+ if (!m_composingText.isEmpty()) {
+ if (QObject *fo = m_platformWindow->window()->focusObject()) {
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
+ if (QCoreApplication::sendEvent(fo, &queryEvent)) {
+ if (queryEvent.value(Qt::ImEnabled).toBool()) {
+ QInputMethodEvent e;
+ e.setCommitString(m_composingText);
+ QCoreApplication::sendEvent(fo, &e);
+ }
+ }
+ }
+ }
+ m_composingText.clear();
+ m_composingFocusObject = nullptr;
+}
+
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (ComplexText)
+
+- (void)insertNewline:(id)sender
+{
+ Q_UNUSED(sender);
+ m_resendKeyEvent = true;
+}
+
+- (void)doCommandBySelector:(SEL)aSelector
+{
+ [self tryToPerform:aSelector with:self];
+}
+
+- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
+{
+ Q_UNUSED(replacementRange)
+
+ if (m_sendKeyEvent && m_composingText.isEmpty() && [aString isEqualToString:m_inputSource]) {
+ // don't send input method events for simple text input (let handleKeyEvent send key events instead)
+ return;
+ }
+
+ QString commitString;
+ if ([aString length]) {
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ commitString = QString::fromCFString(reinterpret_cast<CFStringRef>([aString string]));
+ } else {
+ commitString = QString::fromCFString(reinterpret_cast<CFStringRef>(aString));
+ };
+ }
+ if (QObject *fo = m_platformWindow->window()->focusObject()) {
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
+ if (QCoreApplication::sendEvent(fo, &queryEvent)) {
+ if (queryEvent.value(Qt::ImEnabled).toBool()) {
+ QInputMethodEvent e;
+ e.setCommitString(commitString);
+ QCoreApplication::sendEvent(fo, &e);
+ // prevent handleKeyEvent from sending a key event
+ m_sendKeyEvent = false;
+ }
+ }
+ }
+
+ m_composingText.clear();
+ m_composingFocusObject = nullptr;
+}
+
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
+{
+ Q_UNUSED(replacementRange)
+ QString preeditString;
+
+ QList<QInputMethodEvent::Attribute> attrs;
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selectedRange.location + selectedRange.length, 1, QVariant());
+
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ // Preedit string has attribution
+ preeditString = QString::fromCFString(reinterpret_cast<CFStringRef>([aString string]));
+ int composingLength = preeditString.length();
+ int index = 0;
+ // Create attributes for individual sections of preedit text
+ while (index < composingLength) {
+ NSRange effectiveRange;
+ NSRange range = NSMakeRange(index, composingLength-index);
+ NSDictionary *attributes = [aString attributesAtIndex:index
+ longestEffectiveRange:&effectiveRange
+ inRange:range];
+ NSNumber *underlineStyle = [attributes objectForKey:NSUnderlineStyleAttributeName];
+ if (underlineStyle) {
+ QColor clr (Qt::black);
+ NSColor *color = [attributes objectForKey:NSUnderlineColorAttributeName];
+ if (color) {
+ clr = qt_mac_toQColor(color);
+ }
+ QTextCharFormat format;
+ format.setFontUnderline(true);
+ format.setUnderlineColor(clr);
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ effectiveRange.location,
+ effectiveRange.length,
+ format);
+ }
+ index = effectiveRange.location + effectiveRange.length;
+ }
+ } else {
+ // No attributes specified, take only the preedit text.
+ preeditString = QString::fromCFString(reinterpret_cast<CFStringRef>(aString));
+ }
+
+ if (attrs.isEmpty()) {
+ QTextCharFormat format;
+ format.setFontUnderline(true);
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ 0, preeditString.length(), format);
+ }
+
+ m_composingText = preeditString;
+
+ if (QObject *fo = m_platformWindow->window()->focusObject()) {
+ m_composingFocusObject = fo;
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
+ if (QCoreApplication::sendEvent(fo, &queryEvent)) {
+ if (queryEvent.value(Qt::ImEnabled).toBool()) {
+ QInputMethodEvent e(preeditString, attrs);
+ QCoreApplication::sendEvent(fo, &e);
+ // prevent handleKeyEvent from sending a key event
+ m_sendKeyEvent = false;
+ }
+ }
+ }
+}
+
+- (BOOL)hasMarkedText
+{
+ return (m_composingText.isEmpty() ? NO: YES);
+}
+
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
+{
+ Q_UNUSED(actualRange)
+ QObject *fo = m_platformWindow->window()->focusObject();
+ if (!fo)
+ return nil;
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return nil;
+ if (!queryEvent.value(Qt::ImEnabled).toBool())
+ return nil;
+
+ QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString();
+ if (selectedText.isEmpty())
+ return nil;
+
+ QCFString string(selectedText.mid(aRange.location, aRange.length));
+ const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
+ return [[[NSAttributedString alloc] initWithString:const_cast<NSString *>(tmpString)] autorelease];
+}
+
+- (NSRange)markedRange
+{
+ NSRange range;
+ if (!m_composingText.isEmpty()) {
+ range.location = 0;
+ range.length = m_composingText.length();
+ } else {
+ range.location = NSNotFound;
+ range.length = 0;
+ }
+ return range;
+}
+
+- (NSRange)selectedRange
+{
+ NSRange selectedRange = {0, 0};
+
+ QObject *fo = m_platformWindow->window()->focusObject();
+ if (!fo)
+ return selectedRange;
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImCurrentSelection);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return selectedRange;
+ if (!queryEvent.value(Qt::ImEnabled).toBool())
+ return selectedRange;
+
+ QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString();
+
+ if (!selectedText.isEmpty()) {
+ selectedRange.location = 0;
+ selectedRange.length = selectedText.length();
+ }
+ return selectedRange;
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
+{
+ Q_UNUSED(aRange)
+ Q_UNUSED(actualRange)
+
+ QObject *fo = m_platformWindow->window()->focusObject();
+ if (!fo)
+ return NSZeroRect;
+
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return NSZeroRect;
+ if (!queryEvent.value(Qt::ImEnabled).toBool())
+ return NSZeroRect;
+
+ // The returned rect is always based on the internal cursor.
+ QRect mr = qApp->inputMethod()->cursorRectangle().toRect();
+ mr.moveBottomLeft(m_platformWindow->window()->mapToGlobal(mr.bottomLeft()));
+ return QCocoaScreen::mapToNative(mr);
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
+{
+ // We don't support cursor movements using mouse while composing.
+ Q_UNUSED(aPoint);
+ return NSNotFound;
+}
+
+- (NSArray<NSString *> *)validAttributesForMarkedText
+{
+ if (!m_platformWindow)
+ return nil;
+
+ if (m_platformWindow->window() != QGuiApplication::focusWindow())
+ return nil;
+
+ QObject *fo = m_platformWindow->window()->focusObject();
+ if (!fo)
+ return nil;
+
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return nil;
+ if (!queryEvent.value(Qt::ImEnabled).toBool())
+ return nil;
+
+ // Support only underline color/style.
+ return @[NSUnderlineColorAttributeName, NSUnderlineStyleAttributeName];
+}
+
+- (void)textInputContextKeyboardSelectionDidChangeNotification:(NSNotification *)textInputContextKeyboardSelectionDidChangeNotification
+{
+ Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification)
+ if (([NSApp keyWindow] == self.window) && self.window.firstResponder == self) {
+ QCocoaInputContext *ic = qobject_cast<QCocoaInputContext *>(QCocoaIntegration::instance()->inputContext());
+ ic->updateLocale();
+ }
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnsview_dragging.mm b/src/plugins/platforms/cocoa/qnsview_dragging.mm
new file mode 100644
index 0000000000..1c38c5326c
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_dragging.mm
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Dragging)
+
+-(void)registerDragTypes
+{
+ QMacAutoReleasePool pool;
+
+ NSString * const mimeTypeGeneric = @"com.trolltech.qt.MimeTypeName";
+ NSMutableArray<NSString *> *supportedTypes = [NSMutableArray<NSString *> arrayWithArray:@[
+ NSColorPboardType,
+ NSFilenamesPboardType, NSStringPboardType,
+ NSFilenamesPboardType, NSPostScriptPboardType, NSTIFFPboardType,
+ NSRTFPboardType, NSTabularTextPboardType, NSFontPboardType,
+ NSRulerPboardType, NSFileContentsPboardType, NSColorPboardType,
+ NSRTFDPboardType, NSHTMLPboardType,
+ NSURLPboardType, NSPDFPboardType, NSVCardPboardType,
+ NSFilesPromisePboardType, NSInkTextPboardType,
+ NSMultipleTextSelectionPboardType, mimeTypeGeneric]];
+
+ // Add custom types supported by the application.
+ for (const QString &customType : qt_mac_enabledDraggedTypes())
+ [supportedTypes addObject:customType.toNSString()];
+
+ [self registerForDraggedTypes:supportedTypes];
+}
+
+static QWindow *findEventTargetWindow(QWindow *candidate)
+{
+ while (candidate) {
+ if (!(candidate->flags() & Qt::WindowTransparentForInput))
+ return candidate;
+ candidate = candidate->parent();
+ }
+ return candidate;
+}
+
+static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint point)
+{
+ return target->mapFromGlobal(source->mapToGlobal(point));
+}
+
+- (NSDragOperation)draggingSession:(NSDraggingSession *)session
+ sourceOperationMaskForDraggingContext:(NSDraggingContext)context
+{
+ Q_UNUSED(session);
+ Q_UNUSED(context);
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
+ return qt_mac_mapDropActions(nativeDrag->currentDrag()->supportedActions());
+}
+
+- (BOOL)ignoreModifierKeysForDraggingSession:(NSDraggingSession *)session
+{
+ Q_UNUSED(session);
+ // According to the "Dragging Sources" chapter on Cocoa DnD Programming
+ // (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DragandDrop/Concepts/dragsource.html),
+ // if the control, option, or command key is pressed, the source’s
+ // operation mask is filtered to only contain a reduced set of operations.
+ //
+ // Since Qt already takes care of tracking the keyboard modifiers, we
+ // don't need (or want) Cocoa to filter anything. Instead, we'll let
+ // the application do the actual filtering.
+ return YES;
+}
+
+- (BOOL)wantsPeriodicDraggingUpdates
+{
+ // From the documentation:
+ //
+ // "If the destination returns NO, these messages are sent only when the mouse moves
+ // or a modifier flag changes. Otherwise the destination gets the default behavior,
+ // where it receives periodic dragging-updated messages even if nothing changes."
+ //
+ // We do not want these constant drag update events while mouse is stationary,
+ // since we do all animations (autoscroll) with timers.
+ return NO;
+}
+
+
+- (BOOL)wantsPeriodicDraggingUpdates:(void *)dummy
+{
+ // This method never gets called. It's a workaround for Apple's
+ // bug: they first respondsToSelector : @selector(wantsPeriodicDraggingUpdates:)
+ // (note ':') and then call -wantsPeriodicDraggingUpdate (without colon).
+ // So, let's make them happy.
+ Q_UNUSED(dummy);
+
+ return NO;
+}
+
+- (void)updateCursorFromDragResponse:(QPlatformDragQtResponse)response drag:(QCocoaDrag *)drag
+{
+ const QPixmap pixmapCursor = drag->currentDrag()->dragCursor(response.acceptedAction());
+ NSCursor *nativeCursor = nil;
+
+ if (pixmapCursor.isNull()) {
+ switch (response.acceptedAction()) {
+ case Qt::CopyAction:
+ nativeCursor = [NSCursor dragCopyCursor];
+ break;
+ case Qt::LinkAction:
+ nativeCursor = [NSCursor dragLinkCursor];
+ break;
+ case Qt::IgnoreAction:
+ // Uncomment the next lines if forbiden cursor wanted on non droppable targets.
+ /*nativeCursor = [NSCursor operationNotAllowedCursor];
+ break;*/
+ case Qt::MoveAction:
+ default:
+ nativeCursor = [NSCursor arrowCursor];
+ break;
+ }
+ }
+ else {
+ NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor);
+ nsimage.size = NSSizeFromCGSize((pixmapCursor.size() / pixmapCursor.devicePixelRatioF()).toCGSize());
+ nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint];
+ [nsimage release];
+ }
+
+ // change the cursor
+ [nativeCursor set];
+
+ // Make sure the cursor is updated correctly if the mouse does not move and window is under cursor
+ // by creating a fake move event, unless on 10.14 and later where doing so will trigger a security
+ // warning dialog. FIXME: Find a way to update the cursor without fake mouse events.
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave)
+ return;
+
+ if (m_updatingDrag)
+ return;
+
+ const QPoint mousePos(QCursor::pos());
+ CGEventRef moveEvent(CGEventCreateMouseEvent(
+ NULL, kCGEventMouseMoved,
+ CGPointMake(mousePos.x(), mousePos.y()),
+ kCGMouseButtonLeft // ignored
+ ));
+ CGEventPost(kCGHIDEventTap, moveEvent);
+ CFRelease(moveEvent);
+}
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+ return [self handleDrag : sender];
+}
+
+- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
+{
+ m_updatingDrag = true;
+ const NSDragOperation ret([self handleDrag : sender]);
+ m_updatingDrag = false;
+
+ return ret;
+}
+
+// Sends drag update to Qt, return the action
+- (NSDragOperation)handleDrag:(id <NSDraggingInfo>)sender
+{
+ if (!m_platformWindow)
+ return NSDragOperationNone;
+
+ NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
+ QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
+ Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
+
+ QWindow *target = findEventTargetWindow(m_platformWindow->window());
+ if (!target)
+ return NSDragOperationNone;
+
+ const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags];
+ const auto buttons = currentlyPressedMouseButtons();
+ const auto point = mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint);
+
+ QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
+ if (nativeDrag->currentDrag()) {
+ // The drag was started from within the application
+ response = QWindowSystemInterface::handleDrag(target, nativeDrag->dragMimeData(),
+ point, qtAllowed, buttons, modifiers);
+ [self updateCursorFromDragResponse:response drag:nativeDrag];
+ } else {
+ QCocoaDropData mimeData([sender draggingPasteboard]);
+ response = QWindowSystemInterface::handleDrag(target, &mimeData,
+ point, qtAllowed, buttons, modifiers);
+ }
+
+ return qt_mac_mapDropAction(response.acceptedAction());
+}
+
+- (void)draggingExited:(id <NSDraggingInfo>)sender
+{
+ if (!m_platformWindow)
+ return;
+
+ QWindow *target = findEventTargetWindow(m_platformWindow->window());
+ if (!target)
+ return;
+
+ NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
+ QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
+
+ // Send 0 mime data to indicate drag exit
+ QWindowSystemInterface::handleDrag(target, nullptr,
+ mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint),
+ Qt::IgnoreAction, Qt::NoButton, Qt::NoModifier);
+}
+
+// called on drop, send the drop to Qt and return if it was accepted.
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+ if (!m_platformWindow)
+ return false;
+
+ QWindow *target = findEventTargetWindow(m_platformWindow->window());
+ if (!target)
+ return false;
+
+ NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
+ QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
+ Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
+
+ QPlatformDropQtResponse response(false, Qt::IgnoreAction);
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
+ const auto modifiers = [QNSView convertKeyModifiers:NSApp.currentEvent.modifierFlags];
+ const auto buttons = currentlyPressedMouseButtons();
+ const auto point = mapWindowCoordinates(m_platformWindow->window(), target, qt_windowPoint);
+
+ if (nativeDrag->currentDrag()) {
+ // The drag was started from within the application
+ response = QWindowSystemInterface::handleDrop(target, nativeDrag->dragMimeData(),
+ point, qtAllowed, buttons, modifiers);
+ } else {
+ QCocoaDropData mimeData([sender draggingPasteboard]);
+ response = QWindowSystemInterface::handleDrop(target, &mimeData,
+ point, qtAllowed, buttons, modifiers);
+ }
+ return response.isAccepted();
+}
+
+- (void)draggingSession:(NSDraggingSession *)session
+ endedAtPoint:(NSPoint)screenPoint
+ operation:(NSDragOperation)operation
+{
+ Q_UNUSED(session);
+ Q_UNUSED(screenPoint);
+
+ if (!m_platformWindow)
+ return;
+
+ QWindow *target = findEventTargetWindow(m_platformWindow->window());
+ if (!target)
+ return;
+
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
+ nativeDrag->setAcceptedAction(qt_mac_mapNSDragOperation(operation));
+
+ m_buttons = currentlyPressedMouseButtons();
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm
new file mode 100644
index 0000000000..4f9d17504d
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Drawing)
+
+- (BOOL)isOpaque
+{
+ if (!m_platformWindow)
+ return true;
+ return m_platformWindow->isOpaque();
+}
+
+- (BOOL)isFlipped
+{
+ return YES;
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+ Q_UNUSED(dirtyRect);
+
+ if (!m_platformWindow)
+ return;
+
+ QRegion exposedRegion;
+ const NSRect *dirtyRects;
+ NSInteger numDirtyRects;
+ [self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects];
+ for (int i = 0; i < numDirtyRects; ++i)
+ exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
+
+ qCDebug(lcQpaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
+ m_platformWindow->handleExposeEvent(exposedRegion);
+}
+
+- (BOOL)shouldUseMetalLayer
+{
+ // MetalSurface needs a layer, and so does VulkanSurface (via MoltenVK)
+ QSurface::SurfaceType surfaceType = m_platformWindow->window()->surfaceType();
+ return surfaceType == QWindow::MetalSurface || surfaceType == QWindow::VulkanSurface;
+}
+
+- (BOOL)wantsLayerHelper
+{
+ Q_ASSERT(m_platformWindow);
+
+ bool wantsLayer = qt_mac_resolveOption(true, m_platformWindow->window(),
+ "_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER");
+
+ bool layerForSurfaceType = [self shouldUseMetalLayer];
+
+ return wantsLayer || layerForSurfaceType;
+}
+
+- (CALayer *)makeBackingLayer
+{
+ if ([self shouldUseMetalLayer]) {
+ // Check if Metal is supported. If it isn't then it's most likely
+ // too late at this point and the QWindow will be non-functional,
+ // but we can at least print a warning.
+ if (![MTLCreateSystemDefaultDevice() autorelease]) {
+ qWarning() << "QWindow initialization error: Metal is not supported";
+ return [super makeBackingLayer];
+ }
+
+ CAMetalLayer *layer = [CAMetalLayer layer];
+
+ // Set the contentsScale for the layer. This is normally done in
+ // viewDidChangeBackingProperties, however on startup that function
+ // is called before the layer is created here. The layer's drawableSize
+ // is updated from layoutSublayersOfLayer as usual.
+ layer.contentsScale = self.window.backingScaleFactor;
+
+ return layer;
+ }
+
+ return [super makeBackingLayer];
+}
+
+- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
+{
+ // We need to set this explicitly since the super implementation
+ // returns LayerContentsRedrawNever for custom layers like CAMetalLayer.
+ return NSViewLayerContentsRedrawDuringViewResize;
+}
+
+- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
+{
+ CGSize drawableSize = layer.bounds.size;
+ drawableSize.width *= layer.contentsScale;
+ drawableSize.height *= layer.contentsScale;
+ layer.drawableSize = drawableSize;
+}
+
+- (void)layoutSublayersOfLayer:(CALayer *)layer
+{
+ if ([layer isKindOfClass:CAMetalLayer.class])
+ [self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)];
+}
+
+- (void)displayLayer:(CALayer *)layer
+{
+ Q_ASSERT(layer == self.layer);
+
+ if (!m_platformWindow)
+ return;
+
+ qCDebug(lcQpaDrawing) << "[QNSView displayLayer]" << m_platformWindow->window();
+
+ // FIXME: Find out if there's a way to resolve the dirty rect like in drawRect:
+ m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect());
+}
+
+- (void)viewDidChangeBackingProperties
+{
+ CALayer *layer = self.layer;
+ if (!layer)
+ return;
+
+ layer.contentsScale = self.window.backingScaleFactor;
+
+ // Metal layers must be manually updated on e.g. screen change
+ if ([layer isKindOfClass:CAMetalLayer.class]) {
+ [self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)];
+ [self setNeedsDisplay:YES];
+ }
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnsview_gestures.mm b/src/plugins/platforms/cocoa/qnsview_gestures.mm
new file mode 100644
index 0000000000..61d551ee0e
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_gestures.mm
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+#ifndef QT_NO_GESTURES
+
+Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Gestures)
+
+- (bool)handleGestureAsBeginEnd:(NSEvent *)event
+{
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::OSXElCapitan)
+ return false;
+
+ if ([event phase] == NSEventPhaseBegan) {
+ [self beginGestureWithEvent:event];
+ return true;
+ }
+
+ if ([event phase] == NSEventPhaseEnded) {
+ [self endGestureWithEvent:event];
+ return true;
+ }
+
+ return false;
+}
+- (void)magnifyWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ if ([self handleGestureAsBeginEnd:event])
+ return;
+
+ qCDebug(lcQpaGestures) << "magnifyWithEvent" << [event magnification] << "from device" << hex << [event deviceID];
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::ZoomNativeGesture,
+ [event magnification], windowPoint, screenPoint);
+}
+
+- (void)smartMagnifyWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ static bool zoomIn = true;
+ qCDebug(lcQpaGestures) << "smartMagnifyWithEvent" << zoomIn << "from device" << hex << [event deviceID];
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::SmartZoomNativeGesture,
+ zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
+ zoomIn = !zoomIn;
+}
+
+- (void)rotateWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ if ([self handleGestureAsBeginEnd:event])
+ return;
+
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::RotateNativeGesture,
+ -[event rotation], windowPoint, screenPoint);
+}
+
+- (void)swipeWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ qCDebug(lcQpaGestures) << "swipeWithEvent" << [event deltaX] << [event deltaY] << "from device" << hex << [event deviceID];
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+
+ qreal angle = 0.0f;
+ if ([event deltaX] == 1)
+ angle = 180.0f;
+ else if ([event deltaX] == -1)
+ angle = 0.0f;
+ else if ([event deltaY] == 1)
+ angle = 90.0f;
+ else if ([event deltaY] == -1)
+ angle = 270.0f;
+
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::SwipeNativeGesture,
+ angle, windowPoint, screenPoint);
+}
+
+- (void)beginGestureWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint << "from device" << hex << [event deviceID];
+ QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::BeginNativeGesture,
+ windowPoint, screenPoint);
+}
+
+- (void)endGestureWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ qCDebug(lcQpaGestures) << "endGestureWithEvent" << "from device" << hex << [event deviceID];
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::EndNativeGesture,
+ windowPoint, screenPoint);
+}
+
+@end
+
+#endif // QT_NO_GESTURES
diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm
new file mode 100644
index 0000000000..28db532ddc
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_keys.mm
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (KeysAPI)
+
++ (Qt::KeyboardModifiers)convertKeyModifiers:(ulong)modifierFlags
+{
+ const bool dontSwapCtrlAndMeta = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
+ Qt::KeyboardModifiers qtMods =Qt::NoModifier;
+ if (modifierFlags & NSEventModifierFlagShift)
+ qtMods |= Qt::ShiftModifier;
+ if (modifierFlags & NSEventModifierFlagControl)
+ qtMods |= dontSwapCtrlAndMeta ? Qt::ControlModifier : Qt::MetaModifier;
+ if (modifierFlags & NSEventModifierFlagOption)
+ qtMods |= Qt::AltModifier;
+ if (modifierFlags & NSEventModifierFlagCommand)
+ qtMods |= dontSwapCtrlAndMeta ? Qt::MetaModifier : Qt::ControlModifier;
+ if (modifierFlags & NSEventModifierFlagCommand)
+ qtMods |= Qt::KeypadModifier;
+ return qtMods;
+}
+
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Keys)
+
+- (int)convertKeyCode:(QChar)keyChar
+{
+ return qt_mac_cocoaKey2QtKey(keyChar);
+}
+
+- (bool)handleKeyEvent:(NSEvent *)nsevent eventType:(int)eventType
+{
+ ulong timestamp = [nsevent timestamp] * 1000;
+ ulong nativeModifiers = [nsevent modifierFlags];
+ Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers];
+ NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers];
+ NSString *characters = [nsevent characters];
+ if (m_inputSource != characters) {
+ [m_inputSource release];
+ m_inputSource = [characters retain];
+ }
+
+ // There is no way to get the scan code from carbon/cocoa. But we cannot
+ // use the value 0, since it indicates that the event originates from somewhere
+ // else than the keyboard.
+ quint32 nativeScanCode = 1;
+ quint32 nativeVirtualKey = [nsevent keyCode];
+
+ QChar ch = QChar::ReplacementCharacter;
+ int keyCode = Qt::Key_unknown;
+
+ // If a dead key occurs as a result of pressing a key combination then
+ // characters will have 0 length, but charactersIgnoringModifiers will
+ // have a valid character in it. This enables key combinations such as
+ // ALT+E to be used as a shortcut with an English keyboard even though
+ // pressing ALT+E will give a dead key while doing normal text input.
+ if ([characters length] != 0 || [charactersIgnoringModifiers length] != 0) {
+ auto ctrlOrMetaModifier = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) ? Qt::ControlModifier : Qt::MetaModifier;
+ if (((modifiers & ctrlOrMetaModifier) || (modifiers & Qt::AltModifier)) && ([charactersIgnoringModifiers length] != 0))
+ ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
+ else if ([characters length] != 0)
+ ch = QChar([characters characterAtIndex:0]);
+ keyCode = [self convertKeyCode:ch];
+ }
+
+ // we will send a key event unless the input method sets m_sendKeyEvent to false
+ m_sendKeyEvent = true;
+ QString text;
+ // ignore text for the U+F700-U+F8FF range. This is used by Cocoa when
+ // delivering function keys (e.g. arrow keys, backspace, F1-F35, etc.)
+ if (!(modifiers & (Qt::ControlModifier | Qt::MetaModifier)) && (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff))
+ text = QString::fromNSString(characters);
+
+ QWindow *window = [self topLevelWindow];
+
+ // Popups implicitly grab key events; forward to the active popup if there is one.
+ // This allows popups to e.g. intercept shortcuts and close the popup in response.
+ if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) {
+ if (!popup->window()->flags().testFlag(Qt::ToolTip))
+ window = popup->window();
+ }
+
+ if (eventType == QEvent::KeyPress) {
+
+ if (m_composingText.isEmpty()) {
+ m_sendKeyEvent = !QWindowSystemInterface::handleShortcutEvent(window, timestamp, keyCode,
+ modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1);
+
+ // Handling a shortcut may result in closing the window
+ if (!m_platformWindow)
+ return true;
+ }
+
+ QObject *fo = m_platformWindow->window()->focusObject();
+ if (m_sendKeyEvent && fo) {
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints);
+ if (QCoreApplication::sendEvent(fo, &queryEvent)) {
+ bool imEnabled = queryEvent.value(Qt::ImEnabled).toBool();
+ Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
+ if (imEnabled && !(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) {
+ // pass the key event to the input method. note that m_sendKeyEvent may be set to false during this call
+ m_currentlyInterpretedKeyEvent = nsevent;
+ [self interpretKeyEvents:@[nsevent]];
+ m_currentlyInterpretedKeyEvent = 0;
+ }
+ }
+ }
+ if (m_resendKeyEvent)
+ m_sendKeyEvent = true;
+ }
+
+ bool accepted = true;
+ if (m_sendKeyEvent && m_composingText.isEmpty()) {
+ QWindowSystemInterface::handleExtendedKeyEvent(window, timestamp, QEvent::Type(eventType), keyCode, modifiers,
+ nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1, false);
+ accepted = QWindowSystemInterface::flushWindowSystemEvents();
+ }
+ m_sendKeyEvent = false;
+ m_resendKeyEvent = false;
+ return accepted;
+}
+
+- (void)keyDown:(NSEvent *)nsevent
+{
+ if ([self isTransparentForUserInput])
+ return [super keyDown:nsevent];
+
+ const bool accepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
+
+ // When Qt is used to implement a plugin for a native application we
+ // want to propagate unhandled events to other native views. However,
+ // Qt does not always set the accepted state correctly (in particular
+ // for return key events), so do this for plugin applications only
+ // to prevent incorrect forwarding in the general case.
+ const bool shouldPropagate = QCoreApplication::testAttribute(Qt::AA_PluginApplication) && !accepted;
+
+ // Track keyDown acceptance/forward state for later acceptance of the keyUp.
+ if (!shouldPropagate)
+ m_acceptedKeyDowns.insert([nsevent keyCode]);
+
+ if (shouldPropagate)
+ [super keyDown:nsevent];
+}
+
+- (void)keyUp:(NSEvent *)nsevent
+{
+ if ([self isTransparentForUserInput])
+ return [super keyUp:nsevent];
+
+ const bool keyUpAccepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyRelease)];
+
+ // Propagate the keyUp if neither Qt accepted it nor the corresponding KeyDown was
+ // accepted. Qt text controls wil often not use and ignore keyUp events, but we
+ // want to avoid propagating unmatched keyUps.
+ const bool keyDownAccepted = m_acceptedKeyDowns.remove([nsevent keyCode]);
+ if (!keyUpAccepted && !keyDownAccepted)
+ [super keyUp:nsevent];
+}
+
+- (void)cancelOperation:(id)sender
+{
+ Q_UNUSED(sender);
+
+ NSEvent *currentEvent = [NSApp currentEvent];
+ if (!currentEvent || currentEvent.type != NSEventTypeKeyDown)
+ return;
+
+ // Handling the key event may recurse back here through interpretKeyEvents
+ // (when IM is enabled), so we need to guard against that.
+ if (currentEvent == m_currentlyInterpretedKeyEvent)
+ return;
+
+ // Send Command+Key_Period and Escape as normal keypresses so that
+ // the key sequence is delivered through Qt. That way clients can
+ // intercept the shortcut and override its effect.
+ [self handleKeyEvent:currentEvent eventType:int(QEvent::KeyPress)];
+}
+
+- (void)flagsChanged:(NSEvent *)nsevent
+{
+ ulong timestamp = [nsevent timestamp] * 1000;
+ ulong modifiers = [nsevent modifierFlags];
+ Qt::KeyboardModifiers qmodifiers = [QNSView convertKeyModifiers:modifiers];
+
+ // calculate the delta and remember the current modifiers for next time
+ static ulong m_lastKnownModifiers;
+ ulong lastKnownModifiers = m_lastKnownModifiers;
+ ulong delta = lastKnownModifiers ^ modifiers;
+ m_lastKnownModifiers = modifiers;
+
+ struct qt_mac_enum_mapper
+ {
+ ulong mac_mask;
+ Qt::Key qt_code;
+ };
+ static qt_mac_enum_mapper modifier_key_symbols[] = {
+ { NSEventModifierFlagShift, Qt::Key_Shift },
+ { NSEventModifierFlagControl, Qt::Key_Meta },
+ { NSEventModifierFlagCommand, Qt::Key_Control },
+ { NSEventModifierFlagOption, Qt::Key_Alt },
+ { NSEventModifierFlagCapsLock, Qt::Key_CapsLock },
+ { 0ul, Qt::Key_unknown } };
+ for (int i = 0; modifier_key_symbols[i].mac_mask != 0u; ++i) {
+ uint mac_mask = modifier_key_symbols[i].mac_mask;
+ if ((delta & mac_mask) == 0u)
+ continue;
+
+ Qt::Key qtCode = modifier_key_symbols[i].qt_code;
+ if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
+ if (qtCode == Qt::Key_Meta)
+ qtCode = Qt::Key_Control;
+ else if (qtCode == Qt::Key_Control)
+ qtCode = Qt::Key_Meta;
+ }
+ QWindowSystemInterface::handleKeyEvent(m_platformWindow->window(),
+ timestamp,
+ (lastKnownModifiers & mac_mask) ? QEvent::KeyRelease : QEvent::KeyPress,
+ qtCode,
+ qmodifiers ^ [QNSView convertKeyModifiers:mac_mask]);
+ }
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnsview_menus.mm b/src/plugins/platforms/cocoa/qnsview_menus.mm
new file mode 100644
index 0000000000..f0489552aa
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_menus.mm
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+#include <qcocoaapplicationdelegate.h>
+#include <qcocoansmenu.h>
+#include <qcocoamenuitem.h>
+#include <qcocoamenu.h>
+#include <qcocoamenubar.h>
+
+static bool selectorIsCutCopyPaste(SEL selector)
+{
+ return (selector == @selector(cut:)
+ || selector == @selector(copy:)
+ || selector == @selector(paste:)
+ || selector == @selector(selectAll:));
+}
+
+@interface QT_MANGLE_NAMESPACE(QNSView) (Menus)
+- (void)qt_itemFired:(QCocoaNSMenuItem *)item;
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Menus)
+
+- (BOOL)validateMenuItem:(NSMenuItem*)item
+{
+ auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(item);
+ if (!nativeItem)
+ return item.enabled; // FIXME Test with with Qt as plugin or embedded QWindow.
+
+ auto *platformItem = nativeItem.platformMenuItem;
+ if (!platformItem)
+ return NO;
+
+ // Menu-holding items are always enabled, as it's conventional in Cocoa
+ if (platformItem->menu())
+ return YES;
+
+ // Check if a modal dialog is active. Validate only menu
+ // items belonging to this view's window own menu bar.
+ if (QGuiApplication::modalWindow()) {
+ QCocoaMenuBar *menubar = nullptr;
+
+ QObject *menuParent = platformItem->menuParent();
+ while (menuParent && !(menubar = qobject_cast<QCocoaMenuBar *>(menuParent))) {
+ auto *menuObject = dynamic_cast<QCocoaMenuObject *>(menuParent);
+ menuParent = menuObject->menuParent();
+ }
+
+ if (menubar && menubar->cocoaWindow() != self.platformWindow)
+ return NO;
+ }
+
+ return platformItem->isEnabled();
+}
+
+- (BOOL)respondsToSelector:(SEL)selector
+{
+ // Not exactly true. Both copy: and selectAll: can work on non key views.
+ if (selectorIsCutCopyPaste(selector))
+ return ([NSApp keyWindow] == self.window) && (self.window.firstResponder == self);
+
+ return [super respondsToSelector:selector];
+}
+
+- (void)qt_itemFired:(QCocoaNSMenuItem *)item
+{
+ auto *appDelegate = [QCocoaApplicationDelegate sharedDelegate];
+ [appDelegate qt_itemFired:item];
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
+{
+ if (selectorIsCutCopyPaste(selector)) {
+ NSMethodSignature *itemFiredSign = [super methodSignatureForSelector:@selector(qt_itemFired:)];
+ return itemFiredSign;
+ }
+
+ return [super methodSignatureForSelector:selector];
+}
+
+- (void)forwardInvocation:(NSInvocation *)invocation
+{
+ if (selectorIsCutCopyPaste(invocation.selector)) {
+ NSObject *sender;
+ [invocation getArgument:&sender atIndex:2];
+ if (auto *nativeItem = qt_objc_cast<QCocoaNSMenuItem *>(sender)) {
+ [self qt_itemFired:nativeItem];
+ return;
+ }
+ }
+
+ [super forwardInvocation:invocation];
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm
new file mode 100644
index 0000000000..3d6471005d
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm
@@ -0,0 +1,624 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+@implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) {
+ QNSView *view;
+}
+
+- (instancetype)initWithView:(QNSView *)theView
+{
+ if ((self = [super init]))
+ view = theView;
+
+ return self;
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ [view mouseMovedImpl:theEvent];
+}
+
+- (void)mouseEntered:(NSEvent *)theEvent
+{
+ [view mouseEnteredImpl:theEvent];
+}
+
+- (void)mouseExited:(NSEvent *)theEvent
+{
+ [view mouseExitedImpl:theEvent];
+}
+
+- (void)cursorUpdate:(NSEvent *)theEvent
+{
+ [view cursorUpdate:theEvent];
+}
+
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (MouseAPI)
+
+- (void)resetMouseButtons
+{
+ m_buttons = Qt::NoButton;
+ m_frameStrutButtons = Qt::NoButton;
+}
+
+- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
+{
+ if (!m_platformWindow)
+ return;
+
+ // get m_buttons in sync
+ // Don't send frme strut events if we are in the middle of a mouse drag.
+ if (m_buttons != Qt::NoButton)
+ return;
+
+ switch (theEvent.type) {
+ case NSEventTypeLeftMouseDown:
+ case NSEventTypeLeftMouseDragged:
+ m_frameStrutButtons |= Qt::LeftButton;
+ break;
+ case NSEventTypeLeftMouseUp:
+ m_frameStrutButtons &= ~Qt::LeftButton;
+ break;
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeRightMouseDragged:
+ m_frameStrutButtons |= Qt::RightButton;
+ break;
+ case NSEventTypeRightMouseUp:
+ m_frameStrutButtons &= ~Qt::RightButton;
+ break;
+ case NSEventTypeOtherMouseDown:
+ m_frameStrutButtons |= cocoaButton2QtButton(theEvent.buttonNumber);
+ break;
+ case NSEventTypeOtherMouseUp:
+ m_frameStrutButtons &= ~cocoaButton2QtButton(theEvent.buttonNumber);
+ default:
+ break;
+ }
+
+ NSWindow *window = [self window];
+ NSPoint windowPoint = [theEvent locationInWindow];
+
+ int windowScreenY = [window frame].origin.y + [window frame].size.height;
+ NSPoint windowCoord = [self convertPoint:[self frame].origin toView:nil];
+ int viewScreenY = [window convertRectToScreen:NSMakeRect(windowCoord.x, windowCoord.y, 0, 0)].origin.y;
+ int titleBarHeight = windowScreenY - viewScreenY;
+
+ NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil];
+ QPoint qtWindowPoint = QPoint(nsViewPoint.x, titleBarHeight + nsViewPoint.y);
+ NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 0, 0)].origin;
+ QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint();
+
+ ulong timestamp = [theEvent timestamp] * 1000;
+ QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons);
+}
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Mouse)
+
+- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
+{
+ Q_UNUSED(theEvent)
+ if (!m_platformWindow)
+ return NO;
+ if ([self isTransparentForUserInput])
+ return NO;
+ return YES;
+}
+
+- (NSPoint)screenMousePoint:(NSEvent *)theEvent
+{
+ NSPoint screenPoint;
+ if (theEvent) {
+ NSPoint windowPoint = [theEvent locationInWindow];
+ if (qIsNaN(windowPoint.x) || qIsNaN(windowPoint.y)) {
+ screenPoint = [NSEvent mouseLocation];
+ } else {
+ NSRect screenRect = [[theEvent window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
+ screenPoint = screenRect.origin;
+ }
+ } else {
+ screenPoint = [NSEvent mouseLocation];
+ }
+ return screenPoint;
+}
+
+- (void)handleMouseEvent:(NSEvent *)theEvent
+{
+ if (!m_platformWindow)
+ return;
+
+#ifndef QT_NO_TABLETEVENT
+ // Tablet events may come in via the mouse event handlers,
+ // check if this is a valid tablet event first.
+ if ([self handleTabletEvent: theEvent])
+ return;
+#endif
+
+ QPointF qtWindowPoint;
+ QPointF qtScreenPoint;
+ QNSView *targetView = self;
+ if (!targetView.platformWindow)
+ return;
+
+ // Popups implicitly grap mouse events; forward to the active popup if there is one
+ if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) {
+ // Tooltips must be transparent for mouse events
+ // The bug reference is QTBUG-46379
+ if (!popup->window()->flags().testFlag(Qt::ToolTip)) {
+ if (QNSView *popupView = qnsview_cast(popup->view()))
+ targetView = popupView;
+ }
+ }
+
+ [targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
+ ulong timestamp = [theEvent timestamp] * 1000;
+
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
+ nativeDrag->setLastMouseEvent(theEvent, self);
+
+ const auto modifiers = [QNSView convertKeyModifiers:theEvent.modifierFlags];
+ const auto buttons = currentlyPressedMouseButtons();
+ auto button = cocoaButton2QtButton(theEvent);
+ if (button == Qt::LeftButton && m_sendUpAsRightButton)
+ button = Qt::RightButton;
+ const auto eventType = cocoaEvent2QtMouseEvent(theEvent);
+
+ QWindowSystemInterface::handleMouseEvent(targetView->m_platformWindow->window(),
+ timestamp, qtWindowPoint, qtScreenPoint,
+ buttons, button, eventType, modifiers);
+}
+
+- (bool)handleMouseDownEvent:(NSEvent *)theEvent
+{
+ if ([self isTransparentForUserInput])
+ return false;
+
+ const auto button = cocoaButton2QtButton(theEvent);
+
+ QPointF qtWindowPoint;
+ QPointF qtScreenPoint;
+ [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
+ Q_UNUSED(qtScreenPoint);
+
+ // Maintain masked state for the button for use by MouseDragged and MouseUp.
+ QRegion mask = m_platformWindow->window()->mask();
+ const bool masked = !mask.isEmpty() && !mask.contains(qtWindowPoint.toPoint());
+ if (masked)
+ m_acceptedMouseDowns &= ~button;
+ else
+ m_acceptedMouseDowns |= button;
+
+ // Forward masked out events to the next responder
+ if (masked)
+ return false;
+
+ m_buttons |= button;
+
+ [self handleMouseEvent:theEvent];
+ return true;
+}
+
+- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent
+{
+ if ([self isTransparentForUserInput])
+ return false;
+
+ const auto button = cocoaButton2QtButton(theEvent);
+
+ // Forward the event to the next responder if Qt did not accept the
+ // corresponding mouse down for this button
+ if (!(m_acceptedMouseDowns & button) == button)
+ return false;
+
+ [self handleMouseEvent:theEvent];
+ return true;
+}
+
+- (bool)handleMouseUpEvent:(NSEvent *)theEvent
+{
+ if ([self isTransparentForUserInput])
+ return false;
+
+ auto button = cocoaButton2QtButton(theEvent);
+
+ // Forward the event to the next responder if Qt did not accept the
+ // corresponding mouse down for this button
+ if (!(m_acceptedMouseDowns & button) == button)
+ return false;
+
+ if (m_sendUpAsRightButton && button == Qt::LeftButton)
+ button = Qt::RightButton;
+
+ m_buttons &= ~button;
+
+ [self handleMouseEvent:theEvent];
+
+ if (button == Qt::RightButton)
+ m_sendUpAsRightButton = false;
+
+ return true;
+}
+
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ if ([self isTransparentForUserInput])
+ return [super mouseDown:theEvent];
+ m_sendUpAsRightButton = false;
+
+ // Handle any active poup windows; clicking outisde them should close them
+ // all. Don't do anything or clicks inside one of the menus, let Cocoa
+ // handle that case. Note that in practice many windows of the Qt::Popup type
+ // will actually close themselves in this case using logic implemented in
+ // that particular poup type (for example context menus). However, Qt expects
+ // that plain popup QWindows will also be closed, so we implement the logic
+ // here as well.
+ QList<QCocoaWindow *> *popups = QCocoaIntegration::instance()->popupWindowStack();
+ if (!popups->isEmpty()) {
+ // Check if the click is outside all popups.
+ bool inside = false;
+ QPointF qtScreenPoint = QCocoaScreen::mapFromNative([self screenMousePoint:theEvent]);
+ for (QList<QCocoaWindow *>::const_iterator it = popups->begin(); it != popups->end(); ++it) {
+ if ((*it)->geometry().contains(qtScreenPoint.toPoint())) {
+ inside = true;
+ break;
+ }
+ }
+ // Close the popups if the click was outside.
+ if (!inside) {
+ Qt::WindowType type = QCocoaIntegration::instance()->activePopupWindow()->window()->type();
+ while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) {
+ QWindowSystemInterface::handleCloseEvent(popup->window());
+ QWindowSystemInterface::flushWindowSystemEvents();
+ }
+ // Consume the mouse event when closing the popup, except for tool tips
+ // were it's expected that the event is processed normally.
+ if (type != Qt::ToolTip)
+ return;
+ }
+ }
+
+ QPointF qtWindowPoint;
+ QPointF qtScreenPoint;
+ [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
+ Q_UNUSED(qtScreenPoint);
+
+ QRegion mask = m_platformWindow->window()->mask();
+ const bool masked = !mask.isEmpty() && !mask.contains(qtWindowPoint.toPoint());
+ // Maintain masked state for the button for use by MouseDragged and Up.
+ if (masked)
+ m_acceptedMouseDowns &= ~Qt::LeftButton;
+ else
+ m_acceptedMouseDowns |= Qt::LeftButton;
+
+ // Forward masked out events to the next responder
+ if (masked) {
+ [super mouseDown:theEvent];
+ return;
+ }
+
+ if ([self hasMarkedText]) {
+ [[NSTextInputContext currentInputContext] handleEvent:theEvent];
+ } else {
+ auto ctrlOrMetaModifier = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) ? Qt::ControlModifier : Qt::MetaModifier;
+ if (!m_dontOverrideCtrlLMB && [QNSView convertKeyModifiers:[theEvent modifierFlags]] & ctrlOrMetaModifier) {
+ m_buttons |= Qt::RightButton;
+ m_sendUpAsRightButton = true;
+ } else {
+ m_buttons |= Qt::LeftButton;
+ }
+ [self handleMouseEvent:theEvent];
+ }
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent
+{
+ const bool accepted = [self handleMouseDraggedEvent:theEvent];
+ if (!accepted)
+ [super mouseDragged:theEvent];
+}
+
+- (void)mouseUp:(NSEvent *)theEvent
+{
+ const bool accepted = [self handleMouseUpEvent:theEvent];
+ if (!accepted)
+ [super mouseUp:theEvent];
+}
+
+- (void)rightMouseDown:(NSEvent *)theEvent
+{
+ const bool accepted = [self handleMouseDownEvent:theEvent];
+ if (!accepted)
+ [super rightMouseDown:theEvent];
+}
+
+- (void)rightMouseDragged:(NSEvent *)theEvent
+{
+ const bool accepted = [self handleMouseDraggedEvent:theEvent];
+ if (!accepted)
+ [super rightMouseDragged:theEvent];
+}
+
+- (void)rightMouseUp:(NSEvent *)theEvent
+{
+ const bool accepted = [self handleMouseUpEvent:theEvent];
+ if (!accepted)
+ [super rightMouseUp:theEvent];
+}
+
+- (void)otherMouseDown:(NSEvent *)theEvent
+{
+ const bool accepted = [self handleMouseDownEvent:theEvent];
+ if (!accepted)
+ [super otherMouseDown:theEvent];
+}
+
+- (void)otherMouseDragged:(NSEvent *)theEvent
+{
+ const bool accepted = [self handleMouseDraggedEvent:theEvent];
+ if (!accepted)
+ [super otherMouseDragged:theEvent];
+}
+
+- (void)otherMouseUp:(NSEvent *)theEvent
+{
+ const bool accepted = [self handleMouseUpEvent:theEvent];
+ if (!accepted)
+ [super otherMouseUp:theEvent];
+}
+
+- (void)updateTrackingAreas
+{
+ [super updateTrackingAreas];
+
+ QMacAutoReleasePool pool;
+
+ // NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early
+ if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea])
+ return;
+
+ // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should
+ // only be turned on if mouseTracking, hover is on or a tool tip is set.
+ // Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to
+ // turn it on in ALL case. That means EVERY QWindow gets to pay the cost of
+ // mouse moves delivered to it (Apple recommends keeping it OFF because there
+ // is a performance hit). So it goes.
+ NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp
+ | NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
+ [m_trackingArea release];
+ m_trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame]
+ options:trackingOptions
+ owner:m_mouseMoveHelper
+ userInfo:nil];
+ [self addTrackingArea:m_trackingArea];
+}
+
+- (void)cursorUpdate:(NSEvent *)theEvent
+{
+ qCDebug(lcQpaMouse) << "[QNSView cursorUpdate:]" << self.cursor;
+
+ // Note: We do not get this callback when moving from a subview that
+ // uses the legacy cursorRect API, so the cursor is reset to the arrow
+ // cursor. See rdar://34183708
+
+ if (self.cursor)
+ [self.cursor set];
+ else
+ [super cursorUpdate:theEvent];
+}
+
+- (void)mouseMovedImpl:(NSEvent *)theEvent
+{
+ if (!m_platformWindow)
+ return;
+
+ if ([self isTransparentForUserInput])
+ return;
+
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
+
+ // Top-level windows generate enter-leave events for sub-windows.
+ // Qt wants to know which window (if any) will be entered at the
+ // the time of the leave. This is dificult to accomplish by
+ // handling mouseEnter and mouseLeave envents, since they are sent
+ // individually to different views.
+ if (m_platformWindow->isContentView() && childWindow) {
+ if (childWindow != m_platformWindow->m_enterLeaveTargetWindow) {
+ QWindowSystemInterface::handleEnterLeaveEvent(childWindow, m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
+ m_platformWindow->m_enterLeaveTargetWindow = childWindow;
+ }
+ }
+
+ // Cocoa keeps firing mouse move events for obscured parent views. Qt should not
+ // send those events so filter them out here.
+ if (childWindow != m_platformWindow->window())
+ return;
+
+ [self handleMouseEvent: theEvent];
+}
+
+- (void)mouseEnteredImpl:(NSEvent *)theEvent
+{
+ Q_UNUSED(theEvent)
+ if (!m_platformWindow)
+ return;
+
+ m_platformWindow->m_windowUnderMouse = true;
+
+ if ([self isTransparentForUserInput])
+ return;
+
+ // Top-level windows generate enter events for sub-windows.
+ if (!m_platformWindow->isContentView())
+ return;
+
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ m_platformWindow->m_enterLeaveTargetWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());
+ QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
+}
+
+- (void)mouseExitedImpl:(NSEvent *)theEvent
+{
+ Q_UNUSED(theEvent);
+ if (!m_platformWindow)
+ return;
+
+ m_platformWindow->m_windowUnderMouse = false;
+
+ if ([self isTransparentForUserInput])
+ return;
+
+ // Top-level windows generate leave events for sub-windows.
+ if (!m_platformWindow->isContentView())
+ return;
+
+ QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_enterLeaveTargetWindow);
+ m_platformWindow->m_enterLeaveTargetWindow = 0;
+}
+
+#if QT_CONFIG(wheelevent)
+- (void)scrollWheel:(NSEvent *)theEvent
+{
+ if (!m_platformWindow)
+ return;
+
+ if ([self isTransparentForUserInput])
+ return [super scrollWheel:theEvent];
+
+ QPoint angleDelta;
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
+ if ([theEvent hasPreciseScrollingDeltas]) {
+ // The mouse device contains pixel scroll wheel support (Mighty Mouse, Trackpad).
+ // Since deviceDelta is delivered as pixels rather than degrees, we need to
+ // convert from pixels to degrees in a sensible manner.
+ // It looks like 1/4 degrees per pixel behaves most native.
+ // (NB: Qt expects the unit for delta to be 8 per degree):
+ const int pixelsToDegrees = 2; // 8 * 1/4
+ angleDelta.setX([theEvent scrollingDeltaX] * pixelsToDegrees);
+ angleDelta.setY([theEvent scrollingDeltaY] * pixelsToDegrees);
+ source = Qt::MouseEventSynthesizedBySystem;
+ } else {
+ // Remove acceleration, and use either -120 or 120 as delta:
+ angleDelta.setX(qBound(-120, int([theEvent deltaX] * 10000), 120));
+ angleDelta.setY(qBound(-120, int([theEvent deltaY] * 10000), 120));
+ }
+
+ QPoint pixelDelta;
+ if ([theEvent hasPreciseScrollingDeltas]) {
+ pixelDelta.setX([theEvent scrollingDeltaX]);
+ pixelDelta.setY([theEvent scrollingDeltaY]);
+ } else {
+ // docs: "In the case of !hasPreciseScrollingDeltas, multiply the delta with the line width."
+ // scrollingDeltaX seems to return a minimum value of 0.1 in this case, map that to two pixels.
+ const CGFloat lineWithEstimate = 20.0;
+ pixelDelta.setX([theEvent scrollingDeltaX] * lineWithEstimate);
+ pixelDelta.setY([theEvent scrollingDeltaY] * lineWithEstimate);
+ }
+
+ QPointF qt_windowPoint;
+ QPointF qt_screenPoint;
+ [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qt_windowPoint andScreenPoint:&qt_screenPoint];
+ NSTimeInterval timestamp = [theEvent timestamp];
+ ulong qt_timestamp = timestamp * 1000;
+
+ Qt::ScrollPhase phase = Qt::NoScrollPhase;
+ if (theEvent.phase == NSEventPhaseMayBegin || theEvent.phase == NSEventPhaseBegan) {
+ // MayBegin is likely to happen. We treat it the same as an actual begin,
+ // and follow it with an update when the actual begin is delivered.
+ phase = m_scrolling ? Qt::ScrollUpdate : Qt::ScrollBegin;
+ m_scrolling = true;
+ } else if (theEvent.phase == NSEventPhaseStationary || theEvent.phase == NSEventPhaseChanged) {
+ phase = Qt::ScrollUpdate;
+ } else if (theEvent.phase == NSEventPhaseEnded) {
+ // A scroll event phase may be followed by a momentum phase after the user releases
+ // the finger, and in that case we don't want to send a Qt::ScrollEnd until after
+ // the momentum phase has ended. Unfortunately there isn't any guaranteed way of
+ // knowing whether or not a NSEventPhaseEnded will be followed by a momentum phase.
+ // The best we can do is to look at the event queue and hope that the system has
+ // had time to emit a momentum phase event.
+ if ([NSApp nextEventMatchingMask:NSEventMaskScrollWheel untilDate:[NSDate distantPast]
+ inMode:@"QtMomementumEventSearchMode" dequeue:NO].momentumPhase == NSEventPhaseBegan) {
+ Q_ASSERT(pixelDelta.isNull() && angleDelta.isNull());
+ return; // Ignore this event, as it has a delta of 0,0
+ }
+ phase = Qt::ScrollEnd;
+ m_scrolling = false;
+ } else if (theEvent.momentumPhase == NSEventPhaseBegan) {
+ Q_ASSERT(!pixelDelta.isNull() && !angleDelta.isNull());
+ phase = Qt::ScrollUpdate; // Send as update, it has a delta
+ } else if (theEvent.momentumPhase == NSEventPhaseChanged) {
+ phase = Qt::ScrollMomentum;
+ } else if (theEvent.phase == NSEventPhaseCancelled
+ || theEvent.momentumPhase == NSEventPhaseEnded
+ || theEvent.momentumPhase == NSEventPhaseCancelled) {
+ phase = Qt::ScrollEnd;
+ m_scrolling = false;
+ } else {
+ Q_ASSERT(theEvent.momentumPhase != NSEventPhaseStationary);
+ }
+
+ // Prevent keyboard modifier state from changing during scroll event streams.
+ // A two-finger trackpad flick generates a stream of scroll events. We want
+ // the keyboard modifier state to be the state at the beginning of the
+ // flick in order to avoid changing the interpretation of the events
+ // mid-stream. One example of this happening would be when pressing cmd
+ // after scrolling in Qt Creator: not taking the phase into account causes
+ // the end of the event stream to be interpreted as font size changes.
+ if (theEvent.momentumPhase == NSEventPhaseNone)
+ m_currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
+
+ // "isInverted": natural OS X scrolling, inverted from the Qt/other platform/Jens perspective.
+ bool isInverted = [theEvent isDirectionInvertedFromDevice];
+
+ qCDebug(lcQpaMouse) << "scroll wheel @ window pos" << qt_windowPoint << "delta px" << pixelDelta
+ << "angle" << angleDelta << "phase" << phase << (isInverted ? "inverted" : "");
+ QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp, qt_windowPoint,
+ qt_screenPoint, pixelDelta, angleDelta, m_currentWheelModifiers, phase, source, isInverted);
+}
+#endif // QT_CONFIG(wheelevent)
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnsview_tablet.mm b/src/plugins/platforms/cocoa/qnsview_tablet.mm
new file mode 100644
index 0000000000..43b0aa0960
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_tablet.mm
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+#ifndef QT_NO_TABLETEVENT
+
+Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
+
+struct QCocoaTabletDeviceData
+{
+ QTabletEvent::TabletDevice device;
+ QTabletEvent::PointerType pointerType;
+ uint capabilityMask;
+ qint64 uid;
+};
+
+typedef QHash<uint, QCocoaTabletDeviceData> QCocoaTabletDeviceDataHash;
+Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash)
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Tablet)
+
+- (bool)handleTabletEvent:(NSEvent *)theEvent
+{
+ static bool ignoreButtonMapping = qEnvironmentVariableIsSet("QT_MAC_TABLET_IGNORE_BUTTON_MAPPING");
+
+ if (!m_platformWindow)
+ return false;
+
+ NSEventType eventType = [theEvent type];
+ if (eventType != NSEventTypeTabletPoint && [theEvent subtype] != NSEventSubtypeTabletPoint)
+ return false; // Not a tablet event.
+
+ ulong timestamp = [theEvent timestamp] * 1000;
+
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint: &windowPoint andScreenPoint: &screenPoint];
+
+ uint deviceId = [theEvent deviceID];
+ if (!tabletDeviceDataHash->contains(deviceId)) {
+ // Error: Unknown tablet device. Qt also gets into this state
+ // when running on a VM. This appears to be harmless; don't
+ // print a warning.
+ return false;
+ }
+ const QCocoaTabletDeviceData &deviceData = tabletDeviceDataHash->value(deviceId);
+
+ bool down = (eventType != NSEventTypeMouseMoved);
+
+ qreal pressure;
+ if (down) {
+ pressure = [theEvent pressure];
+ } else {
+ pressure = 0.0;
+ }
+
+ NSPoint tilt = [theEvent tilt];
+ int xTilt = qRound(tilt.x * 60.0);
+ int yTilt = qRound(tilt.y * -60.0);
+ qreal tangentialPressure = 0;
+ qreal rotation = 0;
+ int z = 0;
+ if (deviceData.capabilityMask & 0x0200)
+ z = [theEvent absoluteZ];
+
+ if (deviceData.capabilityMask & 0x0800)
+ tangentialPressure = ([theEvent tangentialPressure] * 2.0) - 1.0;
+
+ rotation = 360.0 - [theEvent rotation];
+ if (rotation > 180.0)
+ rotation -= 360.0;
+
+ Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
+ Qt::MouseButtons buttons = ignoreButtonMapping ? static_cast<Qt::MouseButtons>(static_cast<uint>([theEvent buttonMask])) : m_buttons;
+
+ qCDebug(lcQpaTablet, "event on tablet %d with tool %d type %d unique ID %lld pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf",
+ deviceId, deviceData.device, deviceData.pointerType, deviceData.uid,
+ windowPoint.x(), windowPoint.y(), screenPoint.x(), screenPoint.y(),
+ static_cast<uint>(buttons), pressure, xTilt, yTilt, rotation);
+
+ QWindowSystemInterface::handleTabletEvent(m_platformWindow->window(), timestamp, windowPoint, screenPoint,
+ deviceData.device, deviceData.pointerType, buttons, pressure, xTilt, yTilt,
+ tangentialPressure, rotation, z, deviceData.uid,
+ keyboardModifiers);
+ return true;
+}
+
+- (void)tabletPoint:(NSEvent *)theEvent
+{
+ if ([self isTransparentForUserInput])
+ return [super tabletPoint:theEvent];
+
+ [self handleTabletEvent: theEvent];
+}
+
+static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
+{
+ qint64 uid = [theEvent uniqueID];
+ uint bits = [theEvent vendorPointingDeviceType];
+ if (bits == 0 && uid != 0) {
+ // Fallback. It seems that the driver doesn't always include all the information.
+ // High-End Wacom devices store their "type" in the uper bits of the Unique ID.
+ // I'm not sure how to handle it for consumer devices, but I'll test that in a bit.
+ bits = uid >> 32;
+ }
+
+ QTabletEvent::TabletDevice device;
+ // Defined in the "EN0056-NxtGenImpGuideX"
+ // on Wacom's Developer Website (www.wacomeng.com)
+ if (((bits & 0x0006) == 0x0002) && ((bits & 0x0F06) != 0x0902)) {
+ device = QTabletEvent::Stylus;
+ } else {
+ switch (bits & 0x0F06) {
+ case 0x0802:
+ device = QTabletEvent::Stylus;
+ break;
+ case 0x0902:
+ device = QTabletEvent::Airbrush;
+ break;
+ case 0x0004:
+ device = QTabletEvent::FourDMouse;
+ break;
+ case 0x0006:
+ device = QTabletEvent::Puck;
+ break;
+ case 0x0804:
+ device = QTabletEvent::RotationStylus;
+ break;
+ default:
+ device = QTabletEvent::NoDevice;
+ }
+ }
+ return device;
+}
+
+- (void)tabletProximity:(NSEvent *)theEvent
+{
+ if ([self isTransparentForUserInput])
+ return [super tabletProximity:theEvent];
+
+ ulong timestamp = [theEvent timestamp] * 1000;
+
+ QCocoaTabletDeviceData deviceData;
+ deviceData.uid = [theEvent uniqueID];
+ deviceData.capabilityMask = [theEvent capabilityMask];
+
+ switch ([theEvent pointingDeviceType]) {
+ case NSPointingDeviceTypeUnknown:
+ default:
+ deviceData.pointerType = QTabletEvent::UnknownPointer;
+ break;
+ case NSPointingDeviceTypePen:
+ deviceData.pointerType = QTabletEvent::Pen;
+ break;
+ case NSPointingDeviceTypeCursor:
+ deviceData.pointerType = QTabletEvent::Cursor;
+ break;
+ case NSPointingDeviceTypeEraser:
+ deviceData.pointerType = QTabletEvent::Eraser;
+ break;
+ }
+
+ deviceData.device = wacomTabletDevice(theEvent);
+
+ // The deviceID is "unique" while in the proximity, it's a key that we can use for
+ // linking up QCocoaTabletDeviceData to an event (especially if there are two devices in action).
+ bool entering = [theEvent isEnteringProximity];
+ uint deviceId = [theEvent deviceID];
+ if (entering) {
+ tabletDeviceDataHash->insert(deviceId, deviceData);
+ } else {
+ tabletDeviceDataHash->remove(deviceId);
+ }
+
+ qCDebug(lcQpaTablet, "proximity change on tablet %d: current tool %d type %d unique ID %lld",
+ deviceId, deviceData.device, deviceData.pointerType, deviceData.uid);
+
+ if (entering) {
+ QWindowSystemInterface::handleTabletEnterProximityEvent(timestamp, deviceData.device, deviceData.pointerType, deviceData.uid);
+ } else {
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(timestamp, deviceData.device, deviceData.pointerType, deviceData.uid);
+ }
+}
+@end
+
+#endif
diff --git a/src/plugins/platforms/cocoa/qnsview_touch.mm b/src/plugins/platforms/cocoa/qnsview_touch.mm
new file mode 100644
index 0000000000..e789213f70
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qnsview_touch.mm
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file is included from qnsview.mm, and only used to organize the code
+
+Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch")
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (Touch)
+
+- (bool)shouldSendSingleTouch
+{
+ if (!m_platformWindow)
+ return true;
+
+ // QtWidgets expects single-point touch events, QtDeclarative does not.
+ // Until there is an API we solve this by looking at the window class type.
+ return m_platformWindow->window()->inherits("QWidgetWindow");
+}
+
+- (void)touchesBeganWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ const NSTimeInterval timestamp = [event timestamp];
+ const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
+ qCDebug(lcQpaTouch) << "touchesBeganWithEvent" << points << "from device" << hex << [event deviceID];
+ QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
+}
+
+- (void)touchesMovedWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ const NSTimeInterval timestamp = [event timestamp];
+ const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
+ qCDebug(lcQpaTouch) << "touchesMovedWithEvent" << points << "from device" << hex << [event deviceID];
+ QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
+}
+
+- (void)touchesEndedWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ const NSTimeInterval timestamp = [event timestamp];
+ const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
+ qCDebug(lcQpaTouch) << "touchesEndedWithEvent" << points << "from device" << hex << [event deviceID];
+ QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
+}
+
+- (void)touchesCancelledWithEvent:(NSEvent *)event
+{
+ if (!m_platformWindow)
+ return;
+
+ const NSTimeInterval timestamp = [event timestamp];
+ const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
+ qCDebug(lcQpaTouch) << "touchesCancelledWithEvent" << points << "from device" << hex << [event deviceID];
+ QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
deleted file mode 100644
index 645a93edf7..0000000000
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qnsview.h"
-#include "qcocoahelpers.h"
-#include "qcocoaaccessibility.h"
-#include "qcocoaaccessibilityelement.h"
-#include "qcocoaintegration.h"
-
-#include <QtGui/qaccessible.h>
-#include <QtCore/QDebug>
-
-#import <AppKit/NSAccessibility.h>
-
-#ifndef QT_NO_ACCESSIBILITY
-
-@implementation QNSView (QNSViewAccessibility)
-
-- (id)childAccessibleElement {
- if (m_platformWindow.isNull())
- return nil;
-
- if (!m_platformWindow->window()->accessibleRoot())
- return nil;
-
- QAccessible::Id childId = QAccessible::uniqueId(m_platformWindow->window()->accessibleRoot());
- return [QMacAccessibilityElement elementWithId: childId];
-}
-
-// The QNSView is a container that the user does not interact directly with:
-// Remove it from the user-visible accessibility tree.
-- (BOOL)accessibilityIsIgnored {
- return YES;
-}
-
-- (id)accessibilityAttributeValue:(NSString *)attribute {
- // activate accessibility updates
- QCocoaIntegration::instance()->accessibility()->setActive(true);
-
- if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
- return NSAccessibilityUnignoredChildrenForOnlyChild([self childAccessibleElement]);
- } else {
- return [super accessibilityAttributeValue:attribute];
- }
-}
-
-- (id)accessibilityHitTest:(NSPoint)point {
- return [[self childAccessibleElement] accessibilityHitTest: point];
-}
-
-- (id)accessibilityFocusedUIElement {
- return [[self childAccessibleElement] accessibilityFocusedUIElement];
-}
-
-@end
-
-#endif // QT_NO_ACCESSIBILITY
diff --git a/src/plugins/platforms/cocoa/qnswindow.h b/src/plugins/platforms/cocoa/qnswindow.h
index ea690b69e3..64f1ed0802 100644
--- a/src/plugins/platforms/cocoa/qnswindow.h
+++ b/src/plugins/platforms/cocoa/qnswindow.h
@@ -67,6 +67,7 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow)
- (void)dealloc;
- (BOOL)isOpaque;
- (NSColor *)backgroundColor;
+- (NSString *)description;
@property (nonatomic, readonly) QCocoaWindow *platformWindow;
@end
diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm
index cb13b7d184..1b9dd95cbc 100644
--- a/src/plugins/platforms/cocoa/qnswindow.mm
+++ b/src/plugins/platforms/cocoa/qnswindow.mm
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qnswindow.h"
-#include "qnswindowdelegate.h"
#include "qcocoawindow.h"
#include "qcocoahelpers.h"
#include "qcocoaeventdispatcher.h"
@@ -46,18 +45,18 @@
#include <qpa/qwindowsysteminterface.h>
#include <qoperatingsystemversion.h>
-Q_LOGGING_CATEGORY(lcCocoaEvents, "qt.qpa.cocoa.events");
+Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events");
static bool isMouseEvent(NSEvent *ev)
{
switch ([ev type]) {
- case NSLeftMouseDown:
- case NSLeftMouseUp:
- case NSRightMouseDown:
- case NSRightMouseUp:
- case NSMouseMoved:
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
+ case NSEventTypeLeftMouseDown:
+ case NSEventTypeLeftMouseUp:
+ case NSEventTypeRightMouseDown:
+ case NSEventTypeRightMouseUp:
+ case NSEventTypeMouseMoved:
+ case NSEventTypeLeftMouseDragged:
+ case NSEventTypeRightMouseDragged:
return true;
default:
return false;
@@ -72,7 +71,7 @@ static bool isMouseEvent(NSEvent *ev)
[center addObserverForName:NSWindowDidEnterFullScreenNotification object:nil queue:nil
usingBlock:^(NSNotification *notification) {
objc_setAssociatedObject(notification.object, @selector(qt_fullScreen),
- [NSNumber numberWithBool:YES], OBJC_ASSOCIATION_RETAIN);
+ @(YES), OBJC_ASSOCIATION_RETAIN);
}
];
[center addObserverForName:NSWindowDidExitFullScreenNotification object:nil queue:nil
@@ -187,22 +186,22 @@ static bool isMouseEvent(NSEvent *ev)
/*!
Borderless windows need a transparent background
- Technically windows with NSTexturedBackgroundWindowMask (such
- as windows with unified toolbars) need to draw the textured
+ Technically windows with NSWindowStyleMaskTexturedBackground
+ (such as windows with unified toolbars) need to draw the textured
background of the NSWindow, and can't have a transparent
- background, but as NSBorderlessWindowMask is 0, you can't
- have a window with NSTexturedBackgroundWindowMask that is
+ background, but as NSWindowStyleMaskBorderless is 0, you can't
+ have a window with NSWindowStyleMaskTexturedBackground that is
also borderless.
*/
- (NSColor *)backgroundColor
{
- return self.styleMask == NSBorderlessWindowMask
+ return self.styleMask == NSWindowStyleMaskBorderless
? [NSColor clearColor] : qt_objcDynamicSuper();
}
- (void)sendEvent:(NSEvent*)theEvent
{
- qCDebug(lcCocoaEvents) << "Sending" << theEvent << "to" << self;
+ qCDebug(lcQpaEvents) << "Sending" << theEvent << "to" << self;
// We might get events for a NSWindow after the corresponding platform
// window has been deleted, as the NSWindow can outlive the QCocoaWindow
@@ -239,7 +238,7 @@ static bool isMouseEvent(NSEvent *ev)
- (void)closeAndRelease
{
- qCDebug(lcQpaCocoaWindow) << "closeAndRelease" << self;
+ qCDebug(lcQpaWindow) << "closeAndRelease" << self;
[self.delegate release];
self.delegate = nil;
@@ -252,7 +251,7 @@ static bool isMouseEvent(NSEvent *ev)
#pragma clang diagnostic ignored "-Wobjc-missing-super-calls"
- (void)dealloc
{
- qCDebug(lcQpaCocoaWindow) << "dealloc" << self;
+ qCDebug(lcQpaWindow) << "dealloc" << self;
qt_objcDynamicSuper();
}
#pragma clang diagnostic pop
@@ -263,29 +262,20 @@ static bool isMouseEvent(NSEvent *ev)
NSEnumerator<NSWindow*> *windowEnumerator = nullptr;
NSApplication *application = [NSApplication sharedApplication];
-#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12)
- if (__builtin_available(macOS 10.12, *)) {
- // Unfortunately there's no NSWindowListOrderedBackToFront,
- // so we have to manually reverse the order using an array.
- NSMutableArray *windows = [[[NSMutableArray alloc] init] autorelease];
- [application enumerateWindowsWithOptions:NSWindowListOrderedFrontToBack
- usingBlock:^(NSWindow *window, BOOL *) {
- // For some reason AppKit will give us nil-windows, skip those
- if (!window)
- return;
-
- [(NSMutableArray*)windows addObject:window];
- }
- ];
-
- windowEnumerator = windows.reverseObjectEnumerator;
- } else
-#endif
- {
- // No way to get ordered list of windows, so fall back to unordered,
- // list, which typically corresponds to window creation order.
- windowEnumerator = application.windows.objectEnumerator;
- }
+ // Unfortunately there's no NSWindowListOrderedBackToFront,
+ // so we have to manually reverse the order using an array.
+ NSMutableArray<NSWindow *> *windows = [NSMutableArray<NSWindow *> new];
+ [application enumerateWindowsWithOptions:NSWindowListOrderedFrontToBack
+ usingBlock:^(NSWindow *window, BOOL *) {
+ // For some reason AppKit will give us nil-windows, skip those
+ if (!window)
+ return;
+
+ [windows addObject:window];
+ }
+ ];
+
+ windowEnumerator = windows.reverseObjectEnumerator;
for (NSWindow *window in windowEnumerator) {
// We're meddling with normal and floating windows, so leave others alone
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index d2078b5786..e71afcbb2a 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -41,20 +41,16 @@
#define QNSWINDOWDELEGATE_H
#include <AppKit/AppKit.h>
+#include <QtCore/private/qcore_mac_p.h>
-#include "qcocoawindow.h"
+QT_BEGIN_NAMESPACE
+class QCocoaWindow;
+QT_END_NAMESPACE
@interface QT_MANGLE_NAMESPACE(QNSWindowDelegate) : NSObject <NSWindowDelegate>
-{
- QCocoaWindow *m_cocoaWindow;
-}
-- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow;
+- (instancetype)initWithQCocoaWindow:(QT_PREPEND_NAMESPACE(QCocoaWindow) *)cocoaWindow;
-- (BOOL)windowShouldClose:(NSNotification *)notification;
-
-- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu;
-- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard;
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindowDelegate);
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 057a4c2943..97309ea990 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -39,21 +39,24 @@
#include "qnswindowdelegate.h"
#include "qcocoahelpers.h"
+#include "qcocoawindow.h"
#include "qcocoascreen.h"
#include <QDebug>
+#include <QtCore/private/qcore_mac_p.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*"));
-@implementation QNSWindowDelegate
+@implementation QNSWindowDelegate {
+ QCocoaWindow *m_cocoaWindow;
+}
-- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow
+- (instancetype)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow
{
- if (self = [super init])
+ if ((self = [self init]))
m_cocoaWindow = cocoaWindow;
-
return self;
}
@@ -103,6 +106,36 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*"));
return QCocoaScreen::mapToNative(maximizedFrame);
}
+#pragma clang diagnostic push
+// NSDisableScreenUpdates and NSEnableScreenUpdates are deprecated, but the
+// NSAnimationContext API that replaces them doesn't handle the use-case of
+// cross-thread screen update synchronization.
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)frameSize
+{
+ qCDebug(lcQpaWindow) << window << "will resize to" << QSizeF::fromCGSize(frameSize)
+ << "- disabling screen updates temporarily";
+
+ // There may be separate threads rendering to CA layers in this window,
+ // and if any of them do a swap while the resize is still in progress,
+ // the visual bounds of that layer will be updated before the visual
+ // bounds of the window frame, resulting in flickering while resizing.
+
+ // To prevent this we disable screen updates for the whole process until
+ // the resize is complete, which makes the whole thing visually atomic.
+ NSDisableScreenUpdates();
+
+ return frameSize;
+}
+
+- (void)windowDidResize:(NSNotification *)notification
+{
+ NSWindow *window = notification.object;
+ qCDebug(lcQpaWindow) << window << "was resized - re-enabling screen updates";
+ NSEnableScreenUpdates();
+}
+#pragma clang diagnostic pop
+
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
{
Q_UNUSED(window);
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
index 3f363b62d5..96506c67fa 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -98,8 +98,8 @@ CGImageRef qt_mac_create_imagemask(const QPixmap &pixmap, const QRectF &sr)
for (int x = sx; x < sw; ++x)
*(dptr+(offset++)) = (*(srow+x) & mask) ? 255 : 0;
}
- QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(0, dptr, nbytes, qt_mac_cgimage_data_free);
- return CGImageMaskCreate(sw, sh, 8, 8, nbytes / sh, provider, 0, 0);
+ QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(nullptr, dptr, nbytes, qt_mac_cgimage_data_free);
+ return CGImageMaskCreate(sw, sh, 8, 8, nbytes / sh, provider, nullptr, false);
}
//conversion
@@ -287,16 +287,16 @@ static void qt_mac_draw_pattern(void *info, CGContextRef c)
Q_ASSERT(pat->data.bytes);
w = h = 8;
#if (QMACPATTERN_MASK_MULTIPLIER == 1)
- CGDataProviderRef provider = CGDataProviderCreateWithData(0, pat->data.bytes, w*h, 0);
- pat->image = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false);
+ CGDataProviderRef provider = CGDataProviderCreateWithData(nullptr, pat->data.bytes, w*h, nullptr);
+ pat->image = CGImageMaskCreate(w, h, 1, 1, 1, provider, nullptr, false);
CGDataProviderRelease(provider);
#else
const int numBytes = (w*h)/sizeof(uchar);
uchar xor_bytes[numBytes];
for (int i = 0; i < numBytes; ++i)
xor_bytes[i] = pat->data.bytes[i] ^ 0xFF;
- CGDataProviderRef provider = CGDataProviderCreateWithData(0, xor_bytes, w*h, 0);
- CGImageRef swatch = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false);
+ CGDataProviderRef provider = CGDataProviderCreateWithData(nullptr, xor_bytes, w*h, nullptr);
+ CGImageRef swatch = CGImageMaskCreate(w, h, 1, 1, 1, provider, nullptr, false);
CGDataProviderRelease(provider);
const QColor c0(0, 0, 0, 0), c1(255, 255, 255, 255);
@@ -399,9 +399,9 @@ QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev)
d->orig_xform = CGContextGetCTM(d->hd);
if (d->shading) {
CGShadingRelease(d->shading);
- d->shading = 0;
+ d->shading = nullptr;
}
- d->setClip(0); //clear the context's clipping
+ d->setClip(nullptr); //clear the context's clipping
}
setActive(true);
@@ -445,12 +445,12 @@ QCoreGraphicsPaintEngine::end()
CGShadingRelease(d->shading);
d->shading = 0;
}
- d->pdev = 0;
+ d->pdev = nullptr;
if (d->hd) {
d->restoreGraphicsState();
CGContextSynchronize(d->hd);
CGContextRelease(d->hd);
- d->hd = 0;
+ d->hd = nullptr;
}
return true;
}
@@ -545,7 +545,7 @@ QCoreGraphicsPaintEngine::updateBrush(const QBrush &brush, const QPointF &brushO
if (d->shading) {
CGShadingRelease(d->shading);
- d->shading = 0;
+ d->shading = nullptr;
}
d->setFillBrush(brushOrigin);
}
@@ -592,7 +592,7 @@ QCoreGraphicsPaintEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperatio
if (d->current.clipEnabled) {
d->current.clipEnabled = false;
d->current.clip = QRegion();
- d->setClip(0);
+ d->setClip(nullptr);
}
} else {
if (!d->current.clipEnabled)
@@ -601,7 +601,7 @@ QCoreGraphicsPaintEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperatio
QRegion clipRegion(p.toFillPolygon().toPolygon(), p.fillRule());
if (op == Qt::ReplaceClip) {
d->current.clip = clipRegion;
- d->setClip(0);
+ d->setClip(nullptr);
if (p.isEmpty()) {
CGRect rect = CGRectMake(0, 0, 0, 0);
CGContextClipToRect(d->hd, rect);
@@ -630,7 +630,7 @@ QCoreGraphicsPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOp
if (op == Qt::NoClip) {
d->current.clipEnabled = false;
d->current.clip = QRegion();
- d->setClip(0);
+ d->setClip(nullptr);
} else {
if (!d->current.clipEnabled)
op = Qt::ReplaceClip;
@@ -676,7 +676,7 @@ QCoreGraphicsPaintEngine::drawRects(const QRectF *rects, int rectCount)
QRectF r = rects[i];
CGMutablePathRef path = CGPathCreateMutable();
- CGPathAddRect(path, 0, qt_mac_compose_rect(r));
+ CGPathAddRect(path, nullptr, qt_mac_compose_rect(r));
d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill|QCoreGraphicsPaintEnginePrivate::CGStroke,
path);
CGPathRelease(path);
@@ -698,8 +698,8 @@ QCoreGraphicsPaintEngine::drawPoints(const QPointF *points, int pointCount)
CGMutablePathRef path = CGPathCreateMutable();
for (int i=0; i < pointCount; i++) {
float x = points[i].x(), y = points[i].y();
- CGPathMoveToPoint(path, 0, x, y);
- CGPathAddLineToPoint(path, 0, x+0.001, y);
+ CGPathMoveToPoint(path, nullptr, x, y);
+ CGPathAddLineToPoint(path, nullptr, x+0.001, y);
}
bool doRestore = false;
@@ -745,11 +745,11 @@ QCoreGraphicsPaintEngine::drawPolygon(const QPointF *points, int pointCount, Pol
return;
CGMutablePathRef path = CGPathCreateMutable();
- CGPathMoveToPoint(path, 0, points[0].x(), points[0].y());
+ CGPathMoveToPoint(path, nullptr, points[0].x(), points[0].y());
for (int x = 1; x < pointCount; ++x)
- CGPathAddLineToPoint(path, 0, points[x].x(), points[x].y());
+ CGPathAddLineToPoint(path, nullptr, points[x].x(), points[x].y());
if (mode != PolylineMode && points[0] != points[pointCount-1])
- CGPathAddLineToPoint(path, 0, points[0].x(), points[0].y());
+ CGPathAddLineToPoint(path, nullptr, points[0].x(), points[0].y());
uint op = QCoreGraphicsPaintEnginePrivate::CGStroke;
if (mode != PolylineMode)
op |= mode == OddEvenMode ? QCoreGraphicsPaintEnginePrivate::CGEOFill
@@ -770,8 +770,8 @@ QCoreGraphicsPaintEngine::drawLines(const QLineF *lines, int lineCount)
CGMutablePathRef path = CGPathCreateMutable();
for (int i = 0; i < lineCount; i++) {
const QPointF start = lines[i].p1(), end = lines[i].p2();
- CGPathMoveToPoint(path, 0, start.x(), start.y());
- CGPathAddLineToPoint(path, 0, end.x(), end.y());
+ CGPathMoveToPoint(path, nullptr, start.x(), start.y());
+ CGPathAddLineToPoint(path, nullptr, end.x(), end.y());
}
d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path);
CGPathRelease(path);
@@ -870,7 +870,7 @@ QCoreGraphicsPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap
CGPatternRef pat = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height),
trans, width, height,
kCGPatternTilingNoDistortion, true, &callbks);
- CGColorSpaceRef cs = CGColorSpaceCreatePattern(0);
+ CGColorSpaceRef cs = CGColorSpaceCreatePattern(nullptr);
CGContextSetFillColorSpace(d->hd, cs);
CGFloat component = 1.0; //just one
CGContextSetFillPattern(d->hd, pat, &component);
@@ -1198,9 +1198,9 @@ void QCoreGraphicsPaintEnginePrivate::setFillBrush(const QPointF &offset)
Q_ASSERT(grad->spread() == QGradient::PadSpread);
static const CGFloat domain[] = { 0.0f, +1.0f };
- static const CGFunctionCallbacks callbacks = { 0, qt_mac_color_gradient_function, 0 };
+ static const CGFunctionCallbacks callbacks = { 0, qt_mac_color_gradient_function, nullptr };
CGFunctionRef fill_func = CGFunctionCreate(reinterpret_cast<void *>(&current.brush),
- 1, domain, 4, 0, &callbacks);
+ 1, domain, 4, nullptr, &callbacks);
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB)
if (bs == Qt::LinearGradientPattern) {
@@ -1233,7 +1233,7 @@ void QCoreGraphicsPaintEnginePrivate::setFillBrush(const QPointF &offset)
QMacPattern *qpattern = new QMacPattern;
qpattern->pdev = pdev;
CGFloat components[4] = { 1.0, 1.0, 1.0, 1.0 };
- CGColorSpaceRef base_colorspace = 0;
+ CGColorSpaceRef base_colorspace = nullptr;
if (bs == Qt::TexturePattern) {
qpattern->data.pixmap = current.brush.texture();
if (qpattern->data.pixmap.isQBitmap()) {
@@ -1291,7 +1291,7 @@ QCoreGraphicsPaintEnginePrivate::setClip(const QRegion *rgn)
if (!sysClip.isEmpty())
qt_mac_clip_cg(hd, sysClip, &orig_xform);
if (rgn)
- qt_mac_clip_cg(hd, *rgn, 0);
+ qt_mac_clip_cg(hd, *rgn, nullptr);
}
}
@@ -1404,7 +1404,7 @@ void QCoreGraphicsPaintEnginePrivate::drawPath(uchar ops, CGMutablePathRef path)
t.transform = qt_mac_convert_transform_to_cg(current.transform);
t.path = CGPathCreateMutable();
CGPathApply(path, &t, qt_mac_cg_transform_path_apply); //transform the path
- setTransform(0); //unset the context transform
+ setTransform(nullptr); //unset the context transform
CGContextSetLineWidth(hd, cosmeticPenSize);
CGContextAddPath(hd, t.path);
CGPathRelease(t.path);
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac_p.h b/src/plugins/platforms/cocoa/qpaintengine_mac_p.h
index c9519ac827..1416386745 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac_p.h
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac_p.h
@@ -135,7 +135,7 @@ class QCoreGraphicsPaintEnginePrivate : public QPaintEnginePrivate
Q_DECLARE_PUBLIC(QCoreGraphicsPaintEngine)
public:
QCoreGraphicsPaintEnginePrivate()
- : hd(0), shading(0), stackCount(0), complexXForm(false), disabledSmoothFonts(false)
+ : hd(nullptr), shading(nullptr), stackCount(0), complexXForm(false), disabledSmoothFonts(false)
{
}
@@ -164,8 +164,8 @@ public:
//internal functions
enum { CGStroke=0x01, CGEOFill=0x02, CGFill=0x04 };
- void drawPath(uchar ops, CGMutablePathRef path = 0);
- void setClip(const QRegion *rgn=0);
+ void drawPath(uchar ops, CGMutablePathRef path = nullptr);
+ void setClip(const QRegion *rgn = nullptr);
void resetClip();
void setFillBrush(const QPointF &origin=QPoint());
void setStrokePen(const QPen &pen);
@@ -174,7 +174,7 @@ public:
float penOffset();
QPointF devicePixelSize(CGContextRef context);
float adjustPenWidth(float penWidth);
- inline void setTransform(const QTransform *matrix=0)
+ inline void setTransform(const QTransform *matrix = nullptr)
{
CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
CGAffineTransform xform = orig_xform;
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index eade407500..f2f29b26ee 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -117,7 +117,7 @@ bool QMacPrintEngine::end()
if (d->paintEngine->type() == QPaintEngine::CoreGraphics) {
// We don't need the paint engine to call restoreGraphicsState()
static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->stackCount = 0;
- static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = 0;
+ static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = nullptr;
}
d->paintEngine->end();
if (d->state != QPrinter::Idle)
@@ -271,7 +271,7 @@ void QMacPrintEnginePrivate::releaseSession()
PMSessionEndPageNoDialog(session());
PMSessionEndDocumentNoDialog(session());
[printInfo release];
- printInfo = 0;
+ printInfo = nil;
}
bool QMacPrintEnginePrivate::newPage_helper()
@@ -291,7 +291,7 @@ bool QMacPrintEnginePrivate::newPage_helper()
while (cgEngine->d_func()->stackCount > 0)
cgEngine->d_func()->restoreGraphicsState();
- OSStatus status = PMSessionBeginPageNoDialog(session(), format(), 0);
+ OSStatus status = PMSessionBeginPageNoDialog(session(), format(), nullptr);
if (status != noErr) {
state = QPrinter::Error;
return false;
@@ -318,7 +318,7 @@ bool QMacPrintEnginePrivate::newPage_helper()
if (m_pageLayout.mode() != QPageLayout::FullPageMode)
CGContextTranslateCTM(cgContext, page.x() - paper.x(), page.y() - paper.y());
cgEngine->d_func()->orig_xform = CGContextGetCTM(cgContext);
- cgEngine->d_func()->setClip(0);
+ cgEngine->d_func()->setClip(nullptr);
cgEngine->state->dirtyFlags = QPaintEngine::DirtyFlag(QPaintEngine::AllDirty
& ~(QPaintEngine::DirtyClipEnabled
| QPaintEngine::DirtyClipRegion
@@ -340,7 +340,7 @@ void QMacPrintEnginePrivate::setPageSize(const QPageSize &pageSize)
// Get the PMPaper and check it is valid
PMPaper macPaper = m_printDevice->macPaper(usePageSize);
- if (macPaper == 0) {
+ if (!macPaper) {
qWarning() << "QMacPrintEngine: Invalid PMPaper returned for " << pageSize;
return;
}
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
index 9514f3e691..3d94227ae4 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h
+++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
@@ -134,7 +134,7 @@ public:
QMacPrintEnginePrivate() : mode(QPrinter::ScreenResolution), state(QPrinter::Idle),
m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0))),
- printInfo(0), paintEngine(0), embedFonts(true) {}
+ printInfo(nullptr), paintEngine(nullptr), embedFonts(true) {}
~QMacPrintEnginePrivate();
void initialize();
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
index 38f2352934..9689d6a89b 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
@@ -48,9 +48,9 @@
#include "qwindowscontext.h"
-#include <QtGui/QPainter>
-#include <QtGui/QWindow>
-#include <QtCore/QDebug>
+#include <QtGui/qpainter.h>
+#include <QtGui/qwindow.h>
+#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
index 38425f8fa1..2151f3ae95 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
@@ -42,8 +42,8 @@
#include "qwindowsdirect2dhelpers.h"
#include "qwindowsdirect2ddevicecontext.h"
-#include <QtGui/QImage>
-#include <QtGui/QColor>
+#include <QtGui/qimage.h>
+#include <QtGui/qcolor.h>
#include <wrl.h>
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
index ef39b6a661..d8a8a49aec 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
@@ -41,8 +41,8 @@
#define QWINDOWSDIRECT2DBITMAP_H
#include <QtCore/qnamespace.h>
-#include <QtCore/QRect>
-#include <QtCore/QScopedPointer>
+#include <QtCore/qrect.h>
+#include <QtCore/qscopedpointer.h>
struct ID2D1DeviceContext;
struct ID2D1Bitmap1;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
index 0d42c65964..5bce056ad1 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
@@ -40,7 +40,7 @@
#ifndef QWINDOWSDIRECT2DCONTEXT_H
#define QWINDOWSDIRECT2DCONTEXT_H
-#include <QtCore/QScopedPointer>
+#include <QtCore/qscopedpointer.h>
struct ID3D11Device;
struct ID2D1Device;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
index 8544f9448b..aee0eb867d 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
@@ -40,7 +40,7 @@
#ifndef QWINDOWSDIRECT2DDEVICECONTEXT_H
#define QWINDOWSDIRECT2DDEVICECONTEXT_H
-#include <QtCore/QScopedPointer>
+#include <QtCore/qscopedpointer.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
index 34225bba9a..babe646fd8 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
@@ -40,11 +40,11 @@
#ifndef QWINDOWSDIRECT2DHELPERS_H
#define QWINDOWSDIRECT2DHELPERS_H
-#include <QtCore/QRectF>
-#include <QtCore/QSizeF>
-#include <QtCore/QPointF>
-#include <QtGui/QColor>
-#include <QtGui/QTransform>
+#include <QtCore/qrect.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qpoint.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qtransform.h>
#ifdef Q_CC_MINGW
# include <qt_windows.h>
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
index 6d98da5be5..173d79cf2b 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -47,8 +47,8 @@
#include "qwindowscontext.h"
#include <qplatformdefs.h>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QVersionNumber>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qversionnumber.h>
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
index 39ca1d0dbf..19c7521eb7 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
@@ -42,7 +42,7 @@
#include "qwindowsintegration.h"
-#include <QtCore/QScopedPointer>
+#include <QtCore/qscopedpointer.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
index 711366a0b5..f763c4f7ab 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
@@ -39,7 +39,7 @@
#include "qwindowsdirect2dnativeinterface.h"
-#include <QtGui/QBackingStore>
+#include <QtGui/qbackingstore.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
index 1f23d604f5..013d7a9b79 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSDIRECT2DPAINTDEVICE_H
#define QWINDOWSDIRECT2DPAINTDEVICE_H
-#include <QtCore/QScopedPointer>
-#include <QtGui/QPaintDevice>
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qpaintdevice.h>
#include "qwindowsdirect2dpaintengine.h"
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index 95fbd37247..d3e1d4dd12 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -49,9 +49,9 @@
#include <QtFontDatabaseSupport/private/qwindowsfontengine_p.h>
#include "qwindowsintegration.h"
-#include <QtCore/QtMath>
-#include <QtCore/QStack>
-#include <QtCore/QSettings>
+#include <QtCore/qmath.h>
+#include <QtCore/qstack.h>
+#include <QtCore/qsettings.h>
#include <QtGui/private/qpaintengine_p.h>
#include <QtGui/private/qtextengine_p.h>
#include <QtGui/private/qfontengine_p.h>
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
index b9616acd6a..6404c60b13 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
@@ -40,7 +40,7 @@
#ifndef QWINDOWSDIRECT2DPAINTENGINE_H
#define QWINDOWSDIRECT2DPAINTENGINE_H
-#include <QtCore/QScopedPointer>
+#include <QtCore/qscopedpointer.h>
#include <QtGui/private/qpaintengineex_p.h>
struct ID2D1Geometry;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
index 65e056d312..fb50e05b3f 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
@@ -43,10 +43,10 @@
#include "qwindowsdirect2dbitmap.h"
#include "qwindowsdirect2dhelpers.h"
-#include <QtGui/QPainter>
-#include <QtGui/QImage>
-#include <QtGui/QPaintDevice>
-#include <QtGui/QPaintEngine>
+#include <QtGui/qpainter.h>
+#include <QtGui/qimage.h>
+#include <QtGui/qpaintdevice.h>
+#include <QtGui/qpaintengine.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
index 0448613a95..6bd7852ae0 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
@@ -42,7 +42,7 @@
#include "qwindowsdirect2dpaintengine.h"
#include <QtGui/qpa/qplatformpixmap.h>
-#include <QtCore/QScopedPointer>
+#include <QtCore/qscopedpointer.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
index 7393c11dda..6c56d356b7 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
@@ -40,7 +40,7 @@
#include "qwindowsdirect2dintegration.h"
#include <QtGui/qpa/qplatformintegrationplugin.h>
-#include <QtCore/QStringList>
+#include <QtCore/qstringlist.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/api/qeglfshooks.cpp b/src/plugins/platforms/eglfs/api/qeglfshooks.cpp
index d8332a94cb..ff5c5deee4 100644
--- a/src/plugins/platforms/eglfs/api/qeglfshooks.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfshooks.cpp
@@ -54,6 +54,7 @@ QEglFSDeviceIntegration *qt_egl_device_integration()
#else
+namespace {
class DeviceIntegration
{
public:
@@ -63,6 +64,7 @@ public:
private:
QEglFSDeviceIntegration *m_integration;
};
+}
Q_GLOBAL_STATIC(DeviceIntegration, deviceIntegration)
diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
index 33878a5f50..43f2e31a49 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
@@ -415,8 +415,7 @@ static void *eglContextForContext(QOpenGLContext *context)
QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
{
#ifndef QT_NO_OPENGL
- QByteArray lowerCaseResource = resource.toLower();
- if (lowerCaseResource == "get_egl_context")
+ if (resource.compare("get_egl_context", Qt::CaseInsensitive) == 0)
return NativeResourceForContextFunction(eglContextForContext);
#else
Q_UNUSED(resource);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index 4742143121..0cbb494c2f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -47,6 +47,7 @@
#include <QtCore/QLoggingCategory>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qtguiglobal_p.h>
#include <QtFbSupport/private/qfbvthandler_p.h>
#include <errno.h>
@@ -210,17 +211,29 @@ void QEglFSKmsGbmScreen::ensureModeSet(uint32_t fb)
if (doModeSet) {
qCDebug(qLcEglfsKmsDebug, "Setting mode for screen %s", qPrintable(name()));
- int ret = drmModeSetCrtc(fd,
- op.crtc_id,
- fb,
- 0, 0,
- &op.connector_id, 1,
- &op.modes[op.mode]);
-
- if (ret == 0)
- setPowerState(PowerStateOn);
- else
- qErrnoWarning(errno, "Could not set DRM mode for screen %s", qPrintable(name()));
+
+ if (device()->hasAtomicSupport()) {
+#if QT_CONFIG(drm_atomic)
+ drmModeAtomicReq *request = device()->atomic_request();
+ if (request) {
+ drmModeAtomicAddProperty(request, op.connector_id, op.crtcIdPropertyId, op.crtc_id);
+ drmModeAtomicAddProperty(request, op.crtc_id, op.modeIdPropertyId, op.mode_blob_id);
+ drmModeAtomicAddProperty(request, op.crtc_id, op.activePropertyId, 1);
+ }
+#endif
+ } else {
+ int ret = drmModeSetCrtc(fd,
+ op.crtc_id,
+ fb,
+ 0, 0,
+ &op.connector_id, 1,
+ &op.modes[op.mode]);
+
+ if (ret == 0)
+ setPowerState(PowerStateOn);
+ else
+ qErrnoWarning(errno, "Could not set DRM mode for screen %s", qPrintable(name()));
+ }
}
}
}
@@ -243,6 +256,11 @@ void QEglFSKmsGbmScreen::waitForFlip()
drmEvent.page_flip_handler = pageFlipHandler;
drmHandleEvent(device()->fd(), &drmEvent);
}
+
+#if QT_CONFIG(drm_atomic)
+ if (device()->hasAtomicSupport())
+ device()->atomicReset();
+#endif
}
void QEglFSKmsGbmScreen::flip()
@@ -274,34 +292,79 @@ void QEglFSKmsGbmScreen::flip()
QKmsOutput &op(output());
const int fd = device()->fd();
m_flipPending = true;
- int ret = drmModePageFlip(fd,
+
+ if (device()->hasAtomicSupport()) {
+#if QT_CONFIG(drm_atomic)
+ drmModeAtomicReq *request = device()->atomic_request();
+ if (request) {
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->framebufferPropertyId, fb->fb);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcPropertyId, op.crtc_id);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcwidthPropertyId,
+ output().size.width() << 16);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcXPropertyId, 0);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcYPropertyId, 0);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->srcheightPropertyId,
+ output().size.height() << 16);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcXPropertyId, 0);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcYPropertyId, 0);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcwidthPropertyId,
+ m_output.modes[m_output.mode].hdisplay);
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->crtcheightPropertyId,
+ m_output.modes[m_output.mode].vdisplay);
+
+ static int zpos = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ZPOS");
+ if (zpos)
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->zposPropertyId, zpos);
+ }
+#endif
+ } else {
+ int ret = drmModePageFlip(fd,
op.crtc_id,
fb->fb,
DRM_MODE_PAGE_FLIP_EVENT,
this);
- if (ret) {
- qErrnoWarning("Could not queue DRM page flip on screen %s", qPrintable(name()));
- m_flipPending = false;
- gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next);
- m_gbm_bo_next = nullptr;
- return;
+ if (ret) {
+ qErrnoWarning("Could not queue DRM page flip on screen %s", qPrintable(name()));
+ m_flipPending = false;
+ gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next);
+ m_gbm_bo_next = nullptr;
+ return;
+ }
}
for (CloneDestination &d : m_cloneDests) {
if (d.screen != this) {
d.screen->ensureModeSet(fb->fb);
d.cloneFlipPending = true;
- int ret = drmModePageFlip(fd,
- d.screen->output().crtc_id,
- fb->fb,
- DRM_MODE_PAGE_FLIP_EVENT,
- d.screen);
- if (ret) {
- qErrnoWarning("Could not queue DRM page flip for clone screen %s", qPrintable(name()));
- d.cloneFlipPending = false;
+
+ if (device()->hasAtomicSupport()) {
+#if QT_CONFIG(drm_atomic)
+ drmModeAtomicReq *request = device()->atomic_request();
+ if (request) {
+ drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id,
+ d.screen->output().eglfs_plane->framebufferPropertyId, fb->fb);
+ drmModeAtomicAddProperty(request, d.screen->output().eglfs_plane->id,
+ d.screen->output().eglfs_plane->crtcPropertyId, op.crtc_id);
+ }
+#endif
+ } else {
+ int ret = drmModePageFlip(fd,
+ d.screen->output().crtc_id,
+ fb->fb,
+ DRM_MODE_PAGE_FLIP_EVENT,
+ d.screen);
+ if (ret) {
+ qErrnoWarning("Could not queue DRM page flip for clone screen %s", qPrintable(name()));
+ d.cloneFlipPending = false;
+ }
}
}
}
+
+#if QT_CONFIG(drm_atomic)
+ if (device()->hasAtomicSupport())
+ device()->atomicCommit(this);
+#endif
}
void QEglFSKmsGbmScreen::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
index 531b73d1dc..1626c86239 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
@@ -112,7 +112,7 @@ void QEglFSKmsEglDeviceScreen::waitForFlip()
qCDebug(qLcEglfsKmsDebug, "Setting plane %u", op.forced_plane_id);
int ret = drmModeSetPlane(fd, op.forced_plane_id, op.crtc_id, uint32_t(-1), 0,
0, 0, w, h,
- 0 << 16, 0 << 16, w << 16, h << 16);
+ 0 << 16, 0 << 16, op.size.width() << 16, op.size.height() << 16);
if (ret == -1)
qErrnoWarning(errno, "drmModeSetPlane failed");
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
index 06bc272050..a6aac61506 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
@@ -138,6 +138,10 @@ void *QEglFSKmsIntegration::nativeResourceForIntegration(const QByteArray &name)
if (name == QByteArrayLiteral("dri_fd") && m_device)
return (void *) (qintptr) m_device->fd();
+#if QT_CONFIG(drm_atomic)
+ if (name == QByteArrayLiteral("dri_atomic_request") && m_device)
+ return (void *) (qintptr) m_device->atomic_request();
+#endif
return nullptr;
}
@@ -147,6 +151,8 @@ void *QEglFSKmsIntegration::nativeResourceForScreen(const QByteArray &resource,
if (s) {
if (resource == QByteArrayLiteral("dri_crtcid"))
return (void *) (qintptr) s->output().crtc_id;
+ if (resource == QByteArrayLiteral("dri_connectorid"))
+ return (void *) (qintptr) s->output().connector_id;
}
return nullptr;
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
index 5e45b42abe..e5354d97bd 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
@@ -113,10 +113,9 @@ QRect QEglFSKmsScreen::rawGeometry() const
if (m_headless)
return QRect(QPoint(0, 0), m_device->screenConfig()->headlessSize());
- const int mode = m_output.mode;
return QRect(m_pos.x(), m_pos.y(),
- m_output.modes[mode].hdisplay,
- m_output.modes[mode].vdisplay);
+ m_output.size.width(),
+ m_output.size.height());
}
int QEglFSKmsScreen::depth() const
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
index c52d498cd4..201b277494 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
@@ -41,8 +41,6 @@
#include "../../qiosfiledialog.h"
-@interface QIOSImagePickerController : UIImagePickerController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
- QIOSFileDialog *m_fileDialog;
-}
-- (id)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog;
+@interface QIOSImagePickerController : UIImagePickerController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
+- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog;
@end
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm
index 78e0f00ab4..79d4ecf83f 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm
@@ -41,15 +41,17 @@
#include "qiosimagepickercontroller.h"
-@implementation QIOSImagePickerController
+@implementation QIOSImagePickerController {
+ QIOSFileDialog *m_fileDialog;
+}
-- (id)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog
+- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog
{
self = [super init];
if (self) {
m_fileDialog = fileDialog;
- [self setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
- [self setDelegate:self];
+ self.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
+ self.delegate = self;
}
return self;
}
@@ -57,8 +59,8 @@
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
Q_UNUSED(picker);
- NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL];
- QUrl fileUrl = QUrl::fromLocalFile(QString::fromNSString([url description]));
+ NSURL *url = info[UIImagePickerControllerReferenceURL];
+ QUrl fileUrl = QUrl::fromLocalFile(QString::fromNSString(url.description));
m_fileDialog->selectedFilesChanged(QList<QUrl>() << fileUrl);
emit m_fileDialog->accept();
}
diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm
index 9a975eadc9..6bdbf94d3f 100644
--- a/src/plugins/platforms/ios/qiosclipboard.mm
+++ b/src/plugins/platforms/ios/qiosclipboard.mm
@@ -46,11 +46,11 @@
#include <QtGui/QGuiApplication>
@interface UIPasteboard (QUIPasteboard)
- + (UIPasteboard *)pasteboardWithQClipboardMode:(QClipboard::Mode)mode;
++ (instancetype)pasteboardWithQClipboardMode:(QClipboard::Mode)mode;
@end
@implementation UIPasteboard (QUIPasteboard)
-+ (UIPasteboard *)pasteboardWithQClipboardMode:(QClipboard::Mode)mode
++ (instancetype)pasteboardWithQClipboardMode:(QClipboard::Mode)mode
{
NSString *name = (mode == QClipboard::Clipboard) ? UIPasteboardNameGeneral : UIPasteboardNameFind;
return [UIPasteboard pasteboardWithName:name create:NO];
@@ -60,17 +60,15 @@
// --------------------------------------------------------------------
@interface QUIClipboard : NSObject
-{
-@public
+@end
+
+@implementation QUIClipboard {
QIOSClipboard *m_qiosClipboard;
NSInteger m_changeCountClipboard;
NSInteger m_changeCountFindBuffer;
}
-@end
-
-@implementation QUIClipboard
-- (id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard
+- (instancetype)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard
{
self = [super init];
if (self) {
@@ -149,7 +147,7 @@ QStringList QIOSMimeData::formats() const
{
QStringList foundMimeTypes;
UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:m_mode];
- NSArray *pasteboardTypes = [pb pasteboardTypes];
+ NSArray<NSString *> *pasteboardTypes = [pb pasteboardTypes];
for (NSUInteger i = 0; i < [pasteboardTypes count]; ++i) {
QString uti = QString::fromNSString([pasteboardTypes objectAtIndex:i]);
@@ -164,7 +162,7 @@ QStringList QIOSMimeData::formats() const
QVariant QIOSMimeData::retrieveData(const QString &mimeType, QVariant::Type) const
{
UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:m_mode];
- NSArray *pasteboardTypes = [pb pasteboardTypes];
+ NSArray<NSString *> *pasteboardTypes = [pb pasteboardTypes];
foreach (QMacInternalPasteboardMime *converter,
QMacInternalPasteboardMime::all(QMacInternalPasteboardMime::MIME_ALL)) {
@@ -213,12 +211,12 @@ void QIOSClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
UIPasteboard *pb = [UIPasteboard pasteboardWithQClipboardMode:mode];
if (!mimeData) {
- pb.items = [NSArray array];
+ pb.items = [NSArray<NSDictionary<NSString *, id> *> array];
return;
}
mimeData->deleteLater();
- NSMutableDictionary *pbItem = [NSMutableDictionary dictionaryWithCapacity:mimeData->formats().size()];
+ NSMutableDictionary<NSString *, id> *pbItem = [NSMutableDictionary<NSString *, id> dictionaryWithCapacity:mimeData->formats().size()];
foreach (const QString &mimeType, mimeData->formats()) {
foreach (QMacInternalPasteboardMime *converter,
@@ -246,7 +244,7 @@ void QIOSClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
}
}
- pb.items = [NSArray arrayWithObject:pbItem];
+ pb.items = @[pbItem];
}
bool QIOSClipboard::supportsMode(QClipboard::Mode mode) const
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index 06e5e6cb80..776343c5aa 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -204,6 +204,11 @@ namespace
jmp_buf applicationWillTerminateJumpPoint;
bool debugStackUsage = false;
+
+ struct {
+ QAppleLogActivity UIApplicationMain;
+ QAppleLogActivity applicationDidFinishLaunching;
+ } logActivity;
}
extern "C" int qt_main_wrapper(int argc, char *argv[])
@@ -228,6 +233,9 @@ extern "C" int qt_main_wrapper(int argc, char *argv[])
}
}
+ logActivity.UIApplicationMain = QT_APPLE_LOG_ACTIVITY(
+ lcEventDispatcher().isDebugEnabled(), "UIApplicationMain").enter();
+
qCDebug(lcEventDispatcher) << "Running UIApplicationMain";
return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class]));
}
@@ -245,7 +253,7 @@ extern "C" int main(int argc, char *argv[]);
static void __attribute__((noinline, noreturn)) user_main_trampoline()
{
- NSArray *arguments = [[NSProcessInfo processInfo] arguments];
+ NSArray<NSString *> *arguments = [[NSProcessInfo processInfo] arguments];
int argc = arguments.count;
char **argv = new char*[argc];
@@ -263,11 +271,14 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline()
int exitCode = main(argc, argv);
delete[] argv;
+ logActivity.applicationDidFinishLaunching.enter();
qCDebug(lcEventDispatcher) << "Returned from main with exit code " << exitCode;
if (Q_UNLIKELY(debugStackUsage))
userMainStack.printUsage();
+ logActivity.applicationDidFinishLaunching.leave();
+
if (applicationAboutToTerminate)
longjmp(applicationWillTerminateJumpPoint, kJumpedFromUserMainTrampoline);
@@ -322,6 +333,9 @@ static bool rootLevelRunLoopIntegration()
+ (void)applicationDidFinishLaunching:(NSNotification *)notification
{
+ logActivity.applicationDidFinishLaunching = QT_APPLE_LOG_ACTIVITY_WITH_PARENT(
+ lcEventDispatcher().isDebugEnabled(), "applicationDidFinishLaunching", logActivity.UIApplicationMain).enter();
+
qCDebug(lcEventDispatcher) << "Application launched with options" << notification.userInfo;
if (!isQtApplication())
@@ -339,10 +353,11 @@ static bool rootLevelRunLoopIntegration()
return;
}
-
switch (setjmp(processEventEnterJumpPoint)) {
- case kJumpPointSetSuccessfully:
+ case kJumpPointSetSuccessfully: {
qCDebug(lcEventDispatcher) << "Running main() on separate stack";
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "main()");
+
// Redirect the stack pointer to the start of the reserved stack. This ensures
// that when we longjmp out of the event dispatcher and continue execution, the
// 'Qt main' call-stack will not be smashed, as it lives in a part of the stack
@@ -357,9 +372,11 @@ static bool rootLevelRunLoopIntegration()
Q_UNREACHABLE();
break;
+ }
case kJumpedFromEventDispatcherProcessEvents:
// We've returned from the longjmp in the event dispatcher,
// and the stack has been restored to its old self.
+ logActivity.UIApplicationMain.enter();
qCDebug(lcEventDispatcher) << "↳ Jumped from processEvents due to exec";
if (Q_UNLIKELY(debugStackUsage))
@@ -378,6 +395,10 @@ static const char kApplicationWillTerminateExitCode = char(SIGTERM | 0x80);
+ (void)applicationWillTerminate
{
+ QAppleLogActivity applicationWillTerminateActivity = QT_APPLE_LOG_ACTIVITY_WITH_PARENT(
+ lcEventDispatcher().isDebugEnabled(), "applicationWillTerminate", logActivity.UIApplicationMain).enter();
+ qCDebug(lcEventDispatcher) << "Application about to be terminated by iOS";
+
if (!isQtApplication())
return;
@@ -403,11 +424,14 @@ static const char kApplicationWillTerminateExitCode = char(SIGTERM | 0x80);
// so we'll never see the exit activity and have a chance to return from
// QEventLoop::exec(). We initiate the return manually as a workaround.
qCDebug(lcEventDispatcher) << "Manually triggering return from event loop exec";
+ applicationWillTerminateActivity.leave();
static_cast<QIOSJumpingEventDispatcher *>(qApp->eventDispatcher())->interruptEventLoopExec();
break;
case kJumpedFromUserMainTrampoline:
+ applicationWillTerminateActivity.enter();
// The user's main has returned, so we're ready to let iOS terminate the application
qCDebug(lcEventDispatcher) << "kJumpedFromUserMainTrampoline, allowing iOS to terminate";
+ applicationWillTerminateActivity.leave();
break;
default:
qFatal("Unexpected jump result in event loop integration");
@@ -446,8 +470,10 @@ bool QIOSEventDispatcher::processPostedEvents()
if (!QEventDispatcherCoreFoundation::processPostedEvents())
return false;
- qCDebug(lcEventDispatcher) << "Sending window system events for" << m_processEvents.flags;
- QWindowSystemInterface::sendWindowSystemEvents(m_processEvents.flags);
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "sendWindowSystemEvents");
+ QEventLoop::ProcessEventsFlags flags = QEventLoop::ProcessEventsFlags(m_processEvents.flags.load());
+ qCDebug(lcEventDispatcher) << "Sending window system events for" << flags;
+ QWindowSystemInterface::sendWindowSystemEvents(flags);
return true;
}
@@ -469,6 +495,7 @@ bool __attribute__((returns_twice)) QIOSJumpingEventDispatcher::processEvents(QE
}
if (!m_processEventLevel && (flags & QEventLoop::EventLoopExec)) {
+ QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processEvents");
qCDebug(lcEventDispatcher) << "Processing events with flags" << flags;
++m_processEventLevel;
@@ -526,10 +553,12 @@ void QIOSJumpingEventDispatcher::interruptEventLoopExec()
switch (setjmp(processEventEnterJumpPoint)) {
case kJumpPointSetSuccessfully:
qCDebug(lcEventDispatcher) << "Jumping into processEvents due to system runloop exit ⇢";
+ logActivity.UIApplicationMain.leave();
longjmp(processEventExitJumpPoint, kJumpedFromEventLoopExecInterrupt);
break;
case kJumpedFromEventDispatcherProcessEvents:
// QEventLoop was re-executed
+ logActivity.UIApplicationMain.enter();
qCDebug(lcEventDispatcher) << "↳ Jumped from processEvents due to re-exec";
break;
default:
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 493c283ec1..d2229df133 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -69,7 +69,7 @@ static QUIView *focusView()
@implementation QIOSLocaleListener
-- (id)init
+- (instancetype)init
{
if (self = [super init]) {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
@@ -97,16 +97,15 @@ static QUIView *focusView()
// -------------------------------------------------------------------------
-@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate> {
- @private
- QT_PREPEND_NAMESPACE(QIOSInputContext) *m_context;
-}
+@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate>
@property BOOL hasDeferredScrollToCursor;
@end
-@implementation QIOSKeyboardListener
+@implementation QIOSKeyboardListener {
+ QT_PREPEND_NAMESPACE(QIOSInputContext) *m_context;
+}
-- (id)initWithQIOSInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context
+- (instancetype)initWithQIOSInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context
{
if (self = [super initWithTarget:self action:@selector(gestureStateChanged:)]) {
@@ -581,7 +580,7 @@ void QIOSInputContext::scroll(int y)
// Raise all known windows to above the status-bar if we're scrolling the screen,
// while keeping the relative window level between the windows the same.
- NSArray *applicationWindows = [qt_apple_sharedApplication() windows];
+ NSArray<UIWindow *> *applicationWindows = [qt_apple_sharedApplication() windows];
static QHash<UIWindow *, UIWindowLevel> originalWindowLevels;
for (UIWindow *window in applicationWindows) {
if (keyboardScrollIsActive && !originalWindowLevels.contains(window))
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index ed2bfbc0d8..bec8354fcc 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -100,7 +100,7 @@ QIOSIntegration::QIOSIntegration()
void QIOSIntegration::initialize()
{
UIScreen *mainScreen = [UIScreen mainScreen];
- NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease];
+ NSMutableArray<UIScreen *> *screens = [[[UIScreen screens] mutableCopy] autorelease];
if (![screens containsObject:mainScreen]) {
// Fallback for iOS 7.1 (QTBUG-42345)
[screens insertObject:mainScreen atIndex:0];
@@ -115,10 +115,8 @@ void QIOSIntegration::initialize()
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition;
- if (__builtin_available(iOS 9, *)) {
- if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
- touchCapabilities |= QTouchDevice::Pressure;
- }
+ if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
+ touchCapabilities |= QTouchDevice::Pressure;
m_touchDevice->setCapabilities(touchCapabilities);
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
#if QT_CONFIG(tabletevent)
diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm
index 6c70676a31..74a77de757 100644
--- a/src/plugins/platforms/ios/qiosmenu.mm
+++ b/src/plugins/platforms/ios/qiosmenu.mm
@@ -60,14 +60,14 @@ QIOSMenu *QIOSMenu::m_currentMenu = 0;
static NSString *const kSelectorPrefix = @"_qtMenuItem_";
-@interface QUIMenuController : UIResponder {
- QIOSMenuItemList m_visibleMenuItems;
-}
+@interface QUIMenuController : UIResponder
@end
-@implementation QUIMenuController
+@implementation QUIMenuController {
+ QIOSMenuItemList m_visibleMenuItems;
+}
-- (id)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems
+- (instancetype)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems
{
if (self = [super init]) {
[self setVisibleMenuItems:visibleMenuItems];
@@ -80,7 +80,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
return self;
}
--(void)dealloc
+- (void)dealloc
{
[[NSNotificationCenter defaultCenter]
removeObserver:self
@@ -91,7 +91,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
- (void)setVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems
{
m_visibleMenuItems = visibleMenuItems;
- NSMutableArray *menuItemArray = [NSMutableArray arrayWithCapacity:m_visibleMenuItems.size()];
+ NSMutableArray<UIMenuItem *> *menuItemArray = [NSMutableArray<UIMenuItem *> arrayWithCapacity:m_visibleMenuItems.size()];
// Create an array of UIMenuItems, one for each visible QIOSMenuItem. Each
// UIMenuItem needs a callback assigned, so we assign one of the placeholder methods
// added to UIWindow (QIOSMenuActionTargets) below. Each method knows its own index, which
@@ -107,7 +107,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
[[UIMenuController sharedMenuController] setMenuVisible:YES animated:NO];
}
--(void)menuClosed
+- (void)menuClosed
{
QIOSMenu::currentMenu()->dismiss();
}
@@ -141,19 +141,19 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
// -------------------------------------------------------------------------
-@interface QUIPickerView : UIPickerView <UIPickerViewDelegate, UIPickerViewDataSource> {
- QIOSMenuItemList m_visibleMenuItems;
- QPointer<QObject> m_focusObjectWithPickerView;
- NSInteger m_selectedRow;
-}
+@interface QUIPickerView : UIPickerView <UIPickerViewDelegate, UIPickerViewDataSource>
@property(retain) UIToolbar *toolbar;
@end
-@implementation QUIPickerView
+@implementation QUIPickerView {
+ QIOSMenuItemList m_visibleMenuItems;
+ QPointer<QObject> m_focusObjectWithPickerView;
+ NSInteger m_selectedRow;
+}
-- (id)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems selectItem:(const QIOSMenuItem *)selectItem
+- (instancetype)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems selectItem:(const QIOSMenuItem *)selectItem
{
if (self = [super init]) {
[self setVisibleMenuItems:visibleMenuItems selectItem:selectItem];
@@ -172,7 +172,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
UIBarButtonItem *doneButton = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self action:@selector(closeMenu)] autorelease];
- [self.toolbar setItems:[NSArray arrayWithObjects:cancelButton, spaceButton, doneButton, nil]];
+ [self.toolbar setItems:@[cancelButton, spaceButton, doneButton]];
[self setDelegate:self];
[self setDataSource:self];
diff --git a/src/plugins/platforms/ios/qiosoptionalplugininterface.h b/src/plugins/platforms/ios/qiosoptionalplugininterface.h
index 660c74e856..bae9e5a0d8 100644
--- a/src/plugins/platforms/ios/qiosoptionalplugininterface.h
+++ b/src/plugins/platforms/ios/qiosoptionalplugininterface.h
@@ -44,10 +44,10 @@
#include "qiosfiledialog.h"
-QT_BEGIN_NAMESPACE
-
Q_FORWARD_DECLARE_OBJC_CLASS(UIViewController);
+QT_BEGIN_NAMESPACE
+
#define QIosOptionalPluginInterface_iid "org.qt-project.Qt.QPA.ios.optional"
class QIosOptionalPluginInterface
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index f367d1e75e..4f753be21a 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -132,16 +132,14 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
// -------------------------------------------------------------------------
-@interface QIOSOrientationListener : NSObject {
- @public
- QIOSScreen *m_screen;
-}
-- (id)initWithQIOSScreen:(QIOSScreen *)screen;
+@interface QIOSOrientationListener : NSObject
@end
-@implementation QIOSOrientationListener
+@implementation QIOSOrientationListener {
+ QIOSScreen *m_screen;
+}
-- (id)initWithQIOSScreen:(QIOSScreen *)screen
+- (instancetype)initWithQIOSScreen:(QIOSScreen *)screen
{
self = [super init];
if (self) {
@@ -195,7 +193,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
@implementation QUIWindow
-- (id)initWithFrame:(CGRect)frame
+- (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
self->_sendingEvent = NO;
@@ -399,17 +397,21 @@ void QIOSScreen::deliverUpdateRequests() const
QList<QWindow*> windows = QGuiApplication::allWindows();
for (int i = 0; i < windows.size(); ++i) {
- if (platformScreenForWindow(windows.at(i)) != this)
+ QWindow *window = windows.at(i);
+ if (platformScreenForWindow(window) != this)
continue;
- QWindowPrivate *wp = static_cast<QWindowPrivate *>(QObjectPrivate::get(windows.at(i)));
- if (!wp->updateRequestPending)
+ QPlatformWindow *platformWindow = window->handle();
+ if (!platformWindow)
continue;
- wp->deliverUpdateRequest();
+ if (!platformWindow->hasPendingUpdateRequest())
+ continue;
+
+ platformWindow->deliverUpdateRequest();
// Another update request was triggered, keep the display link running
- if (wp->updateRequestPending)
+ if (platformWindow->hasPendingUpdateRequest())
pauseUpdates = false;
}
@@ -454,12 +456,7 @@ qreal QIOSScreen::devicePixelRatio() const
qreal QIOSScreen::refreshRate() const
{
-#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 100300, 110000, __WATCHOS_NA)
- if (__builtin_available(iOS 10.3, tvOS 11, *))
- return m_uiScreen.maximumFramesPerSecond;
-#endif
-
- return 60.0;
+ return m_uiScreen.maximumFramesPerSecond;
}
Qt::ScreenOrientation QIOSScreen::nativeOrientation() const
diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm
index 87c282e24a..e5419b1766 100644
--- a/src/plugins/platforms/ios/qiostextinputoverlay.mm
+++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm
@@ -97,7 +97,7 @@ static void executeBlockWithoutAnimation(Block block)
@implementation QIOSEditMenu
-- (id)init
+- (instancetype)init
{
if (self = [super init]) {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
@@ -161,7 +161,13 @@ static void executeBlockWithoutAnimation(Block block)
// -------------------------------------------------------------------------
-@interface QIOSLoupeLayer : CALayer {
+@interface QIOSLoupeLayer : CALayer
+@property (nonatomic, retain) UIView *targetView;
+@property (nonatomic, assign) CGPoint focalPoint;
+@property (nonatomic, assign) BOOL visible;
+@end
+
+@implementation QIOSLoupeLayer {
UIView *_snapshotView;
BOOL _pendingSnapshotUpdate;
UIView *_loupeImageView;
@@ -169,14 +175,8 @@ static void executeBlockWithoutAnimation(Block block)
CGFloat _loupeOffset;
QTimer _updateTimer;
}
-@property (nonatomic, retain) UIView *targetView;
-@property (nonatomic, assign) CGPoint focalPoint;
-@property (nonatomic, assign) BOOL visible;
-@end
-@implementation QIOSLoupeLayer
-
-- (id)initWithSize:(CGSize)size cornerRadius:(CGFloat)cornerRadius bottomOffset:(CGFloat)bottomOffset
+- (instancetype)initWithSize:(CGSize)size cornerRadius:(CGFloat)cornerRadius bottomOffset:(CGFloat)bottomOffset
{
if (self = [super init]) {
_loupeOffset = bottomOffset + (size.height / 2);
@@ -302,26 +302,22 @@ static void executeBlockWithoutAnimation(Block block)
// -------------------------------------------------------------------------
-#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_10_0)
-@interface QIOSHandleLayer : CALayer <CAAnimationDelegate> {
-#else
-@interface QIOSHandleLayer : CALayer {
-#endif
- CALayer *_handleCursorLayer;
- CALayer *_handleKnobLayer;
- Qt::Edge _selectionEdge;
-}
+@interface QIOSHandleLayer : CALayer <CAAnimationDelegate>
@property (nonatomic, assign) CGRect cursorRectangle;
@property (nonatomic, assign) CGFloat handleScale;
@property (nonatomic, assign) BOOL visible;
@property (nonatomic, copy) Block onAnimationDidStop;
@end
-@implementation QIOSHandleLayer
+@implementation QIOSHandleLayer {
+ CALayer *_handleCursorLayer;
+ CALayer *_handleKnobLayer;
+ Qt::Edge _selectionEdge;
+}
@dynamic handleScale;
-- (id)initWithKnobAtEdge:(Qt::Edge)selectionEdge
+- (instancetype)initWithKnobAtEdge:(Qt::Edge)selectionEdge
{
if (self = [super init]) {
CGColorRef bgColor = [UIColor colorWithRed:0.1 green:0.4 blue:0.9 alpha:1].CGColor;
@@ -356,16 +352,8 @@ static void executeBlockWithoutAnimation(Block block)
// The handle should "bounce" in when becoming visible
CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:key];
[animation setDuration:0.5];
- animation.values = [NSArray arrayWithObjects:
- [NSNumber numberWithFloat:0],
- [NSNumber numberWithFloat:1.3],
- [NSNumber numberWithFloat:1.3],
- [NSNumber numberWithFloat:1], nil];
- animation.keyTimes = [NSArray arrayWithObjects:
- [NSNumber numberWithFloat:0],
- [NSNumber numberWithFloat:0.3],
- [NSNumber numberWithFloat:0.9],
- [NSNumber numberWithFloat:1], nil];
+ animation.values = @[@(0.0f), @(1.3f), @(1.3f), @(1.0f)];
+ animation.keyTimes = @[@(0.0f), @(0.3f), @(0.9f), @(1.0f)];
return animation;
} else {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:key];
@@ -437,8 +425,13 @@ static void executeBlockWithoutAnimation(Block block)
below will inherit. It takes care of creating and showing a magnifier
glass depending on the current gesture state.
*/
-@interface QIOSLoupeRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate> {
-@public
+@interface QIOSLoupeRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>
+@property (nonatomic, assign) QPointF focalPoint;
+@property (nonatomic, assign) BOOL dragTriggersGesture;
+@property (nonatomic, readonly) UIView *focusView;
+@end
+
+@implementation QIOSLoupeRecognizer {
QIOSLoupeLayer *_loupeLayer;
UIView *_desktopView;
CGPoint _firstTouchPoint;
@@ -446,14 +439,8 @@ static void executeBlockWithoutAnimation(Block block)
QTimer _triggerStateBeganTimer;
int _originalCursorFlashTime;
}
-@property (nonatomic, assign) QPointF focalPoint;
-@property (nonatomic, assign) BOOL dragTriggersGesture;
-@property (nonatomic, readonly) UIView *focusView;
-@end
-@implementation QIOSLoupeRecognizer
-
-- (id)init
+- (instancetype)init
{
if (self = [super initWithTarget:self action:@selector(gestureStateChanged)]) {
self.enabled = NO;
@@ -658,7 +645,10 @@ static void executeBlockWithoutAnimation(Block block)
on the sides. If the user starts dragging on a handle (or do a press and
hold), it will show a magnifier glass that follows the handle as it moves.
*/
-@interface QIOSSelectionRecognizer : QIOSLoupeRecognizer {
+@interface QIOSSelectionRecognizer : QIOSLoupeRecognizer
+@end
+
+@implementation QIOSSelectionRecognizer {
CALayer *_clipRectLayer;
QIOSHandleLayer *_cursorLayer;
QIOSHandleLayer *_anchorLayer;
@@ -670,11 +660,8 @@ static void executeBlockWithoutAnimation(Block block)
QMetaObject::Connection _anchorConnection;
QMetaObject::Connection _clipRectConnection;
}
-@end
-
-@implementation QIOSSelectionRecognizer
-- (id)init
+- (instancetype)init
{
if (self = [super init]) {
self.delaysTouchesBegan = YES;
@@ -890,15 +877,15 @@ static void executeBlockWithoutAnimation(Block block)
visibility of the edit menu will be toggled. Otherwise, if there's a selection, a
first tap will close the edit menu (if any), and a second tap will remove the selection.
*/
-@interface QIOSTapRecognizer : UITapGestureRecognizer {
+@interface QIOSTapRecognizer : UITapGestureRecognizer
+@end
+
+@implementation QIOSTapRecognizer {
int _cursorPosOnPress;
UIView *_focusView;
}
-@end
-
-@implementation QIOSTapRecognizer
-- (id)init
+- (instancetype)init
{
if (self = [super initWithTarget:self action:@selector(gestureStateChanged)]) {
self.enabled = NO;
diff --git a/src/plugins/platforms/ios/qiostextresponder.h b/src/plugins/platforms/ios/qiostextresponder.h
index 77be2cf2fe..074598c1c3 100644
--- a/src/plugins/platforms/ios/qiostextresponder.h
+++ b/src/plugins/platforms/ios/qiostextresponder.h
@@ -49,16 +49,8 @@ class QIOSInputContext;
QT_END_NAMESPACE
@interface QIOSTextInputResponder : UIResponder <UITextInputTraits, UIKeyInput, UITextInput>
-{
- @private
- QT_PREPEND_NAMESPACE(QIOSInputContext) *m_inputContext;
- QT_PREPEND_NAMESPACE(QInputMethodQueryEvent) *m_configuredImeState;
- QString m_markedText;
- BOOL m_inSendEventToFocusObject;
- BOOL m_inSelectionChange;
-}
-- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context;
+- (instancetype)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)context;
- (BOOL)needsKeyboardReconfigure:(Qt::InputMethodQueries)updatedProperties;
- (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties;
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index b029c49a67..396c769be8 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -55,13 +55,13 @@
@interface QUITextPosition : UITextPosition
@property (nonatomic) NSUInteger index;
-+ (QUITextPosition *)positionWithIndex:(NSUInteger)index;
++ (instancetype)positionWithIndex:(NSUInteger)index;
@end
@implementation QUITextPosition
-+ (QUITextPosition *)positionWithIndex:(NSUInteger)index
++ (instancetype)positionWithIndex:(NSUInteger)index
{
QUITextPosition *pos = [[QUITextPosition alloc] init];
pos.index = index;
@@ -75,15 +75,15 @@
@interface QUITextRange : UITextRange
@property (nonatomic) NSRange range;
-+ (QUITextRange *)rangeWithNSRange:(NSRange)range;
++ (instancetype)rangeWithNSRange:(NSRange)range;
@end
@implementation QUITextRange
-+ (QUITextRange *)rangeWithNSRange:(NSRange)nsrange
++ (instancetype)rangeWithNSRange:(NSRange)nsrange
{
- QUITextRange *range = [[QUITextRange alloc] init];
+ QUITextRange *range = [[self alloc] init];
range.range = nsrange;
return [range autorelease];
}
@@ -117,7 +117,7 @@
@implementation WrapperView
-- (id)initWithView:(UIView *)view
+- (instancetype)initWithView:(UIView *)view
{
if (self = [self init]) {
[self addSubview:view];
@@ -132,7 +132,7 @@
- (void)layoutSubviews
{
- UIView* view = [self.subviews firstObject];
+ UIView *view = [self.subviews firstObject];
view.frame = self.bounds;
// FIXME: During orientation changes the size and position
@@ -161,9 +161,15 @@
// -------------------------------------------------------------------------
-@implementation QIOSTextInputResponder
+@implementation QIOSTextInputResponder {
+ QT_PREPEND_NAMESPACE(QIOSInputContext) *m_inputContext;
+ QT_PREPEND_NAMESPACE(QInputMethodQueryEvent) *m_configuredImeState;
+ QString m_markedText;
+ BOOL m_inSendEventToFocusObject;
+ BOOL m_inSelectionChange;
+}
-- (id)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)inputContext
+- (instancetype)initWithInputContext:(QT_PREPEND_NAMESPACE(QIOSInputContext) *)inputContext
{
if (!(self = [self init]))
return self;
@@ -238,17 +244,15 @@
self.inputAccessoryView = [[[WrapperView alloc] initWithView:accessoryView] autorelease];
#ifndef Q_OS_TVOS
- if (__builtin_available(iOS 9, *)) {
- if (platformData.value(kImePlatformDataHideShortcutsBar).toBool()) {
- // According to the docs, leadingBarButtonGroups/trailingBarButtonGroups should be set to nil to hide the shortcuts bar.
- // However, starting with iOS 10, the API has been surrounded with NS_ASSUME_NONNULL, which contradicts this and causes
- // compiler warnings. Still it is the way to go to really hide the space reserved for that.
+ if (platformData.value(kImePlatformDataHideShortcutsBar).toBool()) {
+ // According to the docs, leadingBarButtonGroups/trailingBarButtonGroups should be set to nil to hide the shortcuts bar.
+ // However, starting with iOS 10, the API has been surrounded with NS_ASSUME_NONNULL, which contradicts this and causes
+ // compiler warnings. Still it is the way to go to really hide the space reserved for that.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
- self.inputAssistantItem.leadingBarButtonGroups = nil;
- self.inputAssistantItem.trailingBarButtonGroups = nil;
+ self.inputAssistantItem.leadingBarButtonGroups = nil;
+ self.inputAssistantItem.trailingBarButtonGroups = nil;
#pragma clang diagnostic pop
- }
}
#endif
@@ -548,7 +552,7 @@
[self sendKeyPressRelease:key modifiers:modifiers];
}
-- (void)addKeyCommandsToArray:(NSMutableArray *)array key:(NSString *)key
+- (void)addKeyCommandsToArray:(NSMutableArray<UIKeyCommand *> *)array key:(NSString *)key
{
SEL s = @selector(keyCommandTriggered:);
[array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:0 action:s]];
@@ -559,19 +563,19 @@
[array addObject:[UIKeyCommand keyCommandWithInput:key modifierFlags:UIKeyModifierCommand|UIKeyModifierShift action:s]];
}
-- (NSArray *)keyCommands
+- (NSArray<UIKeyCommand *> *)keyCommands
{
// Since keyCommands is called for every key
// press/release, we cache the result
static dispatch_once_t once;
- static NSMutableArray *array;
+ static NSMutableArray<UIKeyCommand *> *array;
dispatch_once(&once, ^{
// We let Qt move the cursor around when the arrow keys are being used. This
// is normally implemented through UITextInput, but since IM in Qt have poor
// support for moving the cursor vertically, and even less support for selecting
// text across multiple paragraphs, we do this through key events.
- array = [NSMutableArray new];
+ array = [NSMutableArray<UIKeyCommand *> new];
[self addKeyCommandsToArray:array key:UIKeyInputUpArrow];
[self addKeyCommandsToArray:array key:UIKeyInputDownArrow];
[self addKeyCommandsToArray:array key:UIKeyInputLeftArrow];
@@ -825,13 +829,13 @@
return startRect.united(endRect).toCGRect();
}
-- (NSArray *)selectionRectsForRange:(UITextRange *)range
+- (NSArray<UITextSelectionRect *> *)selectionRectsForRange:(UITextRange *)range
{
Q_UNUSED(range);
// This method is supposed to return a rectangle for each line with selection. Since we don't
// expose an API in Qt/IM for getting this information, and since we never seems to be getting
// a call from UIKit for this, we return an empty array until a need arise.
- return [[NSArray new] autorelease];
+ return [[NSArray<UITextSelectionRect *> new] autorelease];
}
- (CGRect)caretRectForPosition:(UITextPosition *)position
@@ -916,7 +920,7 @@
QObject *focusObject = QGuiApplication::focusObject();
if (!focusObject)
- return [NSDictionary dictionary];
+ return @{};
// Assume position is the same as the cursor for now. QInputMethodQueryEvent with Qt::ImFont
// needs to be extended to take an extra position argument before this can be fully correct.
@@ -925,8 +929,8 @@
QFont qfont = qvariant_cast<QFont>(e.value(Qt::ImFont));
UIFont *uifont = [UIFont fontWithName:qfont.family().toNSString() size:qfont.pointSize()];
if (!uifont)
- return [NSDictionary dictionary];
- return [NSDictionary dictionaryWithObject:uifont forKey:NSFontAttributeName];
+ return @{};
+ return @{NSFontAttributeName: uifont};
}
#endif
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h
index 07d5535e1a..7af4c83b48 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.h
+++ b/src/plugins/platforms/ios/qiosviewcontroller.h
@@ -48,7 +48,7 @@ QT_END_NAMESPACE
@interface QIOSViewController : UIViewController
-- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen;
+- (instancetype)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen;
- (void)updateProperties;
#ifndef Q_OS_TVOS
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index aa909d6f63..ce2aa96ca5 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -57,12 +57,8 @@
// -------------------------------------------------------------------------
-@interface QIOSViewController () {
- @public
- QPointer<QT_PREPEND_NAMESPACE(QIOSScreen)> m_screen;
- BOOL m_updatingProperties;
- QMetaObject::Connection m_focusWindowChangeConnection;
-}
+@interface QIOSViewController ()
+@property (nonatomic, assign) QPointer<QT_PREPEND_NAMESPACE(QIOSScreen)> platformScreen;
@property (nonatomic, assign) BOOL changingOrientation;
@end
@@ -73,7 +69,7 @@
@implementation QIOSDesktopManagerView
-- (id)init
+- (instancetype)init
{
if (!(self = [super init]))
return nil;
@@ -126,7 +122,7 @@
{
Q_UNUSED(subview);
- QT_PREPEND_NAMESPACE(QIOSScreen) *screen = self.qtViewController->m_screen;
+ QT_PREPEND_NAMESPACE(QIOSScreen) *screen = self.qtViewController.platformScreen;
// The 'window' property of our view is not valid until the window
// has been shown, so we have to access it through the QIOSScreen.
@@ -171,7 +167,7 @@
// here. iOS will still use the latest rendered frame to create the
// application switcher thumbnail, but it will be based on the last
// active orientation of the application.
- QIOSScreen *screen = self.qtViewController->m_screen;
+ QIOSScreen *screen = self.qtViewController.platformScreen;
qCDebug(lcQpaWindow) << "ignoring layout of subviews while suspended,"
<< "likely system snapshot of" << screen->screen()->primaryOrientation();
return;
@@ -247,7 +243,10 @@
// -------------------------------------------------------------------------
-@implementation QIOSViewController
+@implementation QIOSViewController {
+ BOOL m_updatingProperties;
+ QMetaObject::Connection m_focusWindowChangeConnection;
+}
#ifndef Q_OS_TVOS
@synthesize prefersStatusBarHidden;
@@ -255,11 +254,10 @@
@synthesize preferredStatusBarStyle;
#endif
-- (id)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen
+- (instancetype)initWithQIOSScreen:(QT_PREPEND_NAMESPACE(QIOSScreen) *)screen
{
if (self = [self init]) {
- m_screen = screen;
-
+ self.platformScreen = screen;
self.changingOrientation = NO;
#ifndef Q_OS_TVOS
@@ -333,7 +331,7 @@
- (BOOL)shouldAutorotate
{
#ifndef Q_OS_TVOS
- return m_screen && m_screen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation;
+ return self.platformScreen && self.platformScreen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation;
#else
return NO;
#endif
@@ -413,8 +411,8 @@
if (!QCoreApplication::instance())
return;
- if (m_screen)
- m_screen->updateProperties();
+ if (self.platformScreen)
+ self.platformScreen->updateProperties();
}
// -------------------------------------------------------------------------
@@ -424,12 +422,12 @@
if (!isQtApplication())
return;
- if (!m_screen || !m_screen->screen())
+ if (!self.platformScreen || !self.platformScreen->screen())
return;
// For now we only care about the main screen, as both the statusbar
// visibility and orientation is only appropriate for the main screen.
- if (m_screen->uiScreen() != [UIScreen mainScreen])
+ if (self.platformScreen->uiScreen() != [UIScreen mainScreen])
return;
// Prevent recursion caused by updating the status bar appearance (position
@@ -451,7 +449,7 @@
return;
// We only care about changes to focusWindow that involves our screen
- if (!focusWindow->screen() || focusWindow->screen()->handle() != m_screen)
+ if (!focusWindow->screen() || focusWindow->screen()->handle() != self.platformScreen)
return;
// All decisions are based on the the top level window
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 6ee258e363..cdec57de71 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -96,7 +96,7 @@ QIOSWindow::~QIOSWindow()
[m_view touchesCancelled:[NSSet set] withEvent:0];
clearAccessibleCache();
- m_view->m_qioswindow = 0;
+ m_view.platformWindow = 0;
[m_view removeFromSuperview];
[m_view release];
}
@@ -139,7 +139,7 @@ void QIOSWindow::setVisible(bool visible)
} else if (!visible && [m_view isActiveWindow]) {
// Our window was active/focus window but now hidden, so relinquish
// focus to the next possible window in the stack.
- NSArray *subviews = m_view.viewController.view.subviews;
+ NSArray<UIView *> *subviews = m_view.viewController.view.subviews;
for (int i = int(subviews.count) - 1; i >= 0; --i) {
UIView *view = [subviews objectAtIndex:i];
if (view.hidden)
@@ -301,7 +301,7 @@ void QIOSWindow::raiseOrLower(bool raise)
if (!isQtApplication())
return;
- NSArray *subviews = m_view.superview.subviews;
+ NSArray<UIView *> *subviews = m_view.superview.subviews;
if (subviews.count == 1)
return;
diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.h b/src/plugins/platforms/ios/quiaccessibilityelement.h
index 03abf5407e..6b8efdcede 100644
--- a/src/plugins/platforms/ios/quiaccessibilityelement.h
+++ b/src/plugins/platforms/ios/quiaccessibilityelement.h
@@ -45,13 +45,12 @@
#ifndef QT_NO_ACCESSIBILITY
-@interface QMacAccessibilityElement : UIAccessibilityElement
-{}
+@interface QT_MANGLE_NAMESPACE(QMacAccessibilityElement) : UIAccessibilityElement
@property (readonly) QAccessible::Id axid;
-- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view;
-+ (QMacAccessibilityElement *)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view;
+- (instancetype)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view;
++ (instancetype)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view;
@end
diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm
index a26ba61b3c..3154536aad 100644
--- a/src/plugins/platforms/ios/quiaccessibilityelement.mm
+++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm
@@ -42,20 +42,23 @@
#ifndef QT_NO_ACCESSIBILITY
#include "private/qaccessiblecache_p.h"
+#include "private/qcore_mac_p.h"
+
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAccessibilityElement);
@implementation QMacAccessibilityElement
-- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view
+- (instancetype)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view
{
Q_ASSERT((int)anId < 0);
- self = [super initWithAccessibilityContainer: view];
+ self = [super initWithAccessibilityContainer:view];
if (self)
_axid = anId;
return self;
}
-+ (id)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view
++ (instancetype)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view
{
Q_ASSERT(anId);
if (!anId)
@@ -63,10 +66,10 @@
QAccessibleCache *cache = QAccessibleCache::instance();
- QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *element = cache->elementForId(anId);
+ QMacAccessibilityElement *element = cache->elementForId(anId);
if (!element) {
Q_ASSERT(QAccessible::accessibleInterface(anId));
- element = [[self alloc] initWithId:anId withAccessibilityContainer: view];
+ element = [[self alloc] initWithId:anId withAccessibilityContainer:view];
cache->insertElement(anId, element);
}
return element;
diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h
index 3e3c579075..e1d5d5af0c 100644
--- a/src/plugins/platforms/ios/quiview.h
+++ b/src/plugins/platforms/ios/quiview.h
@@ -53,21 +53,10 @@ QT_END_NAMESPACE
@class QIOSViewController;
@interface QUIView : UIView
-{
- @public
- QT_PREPEND_NAMESPACE(QIOSWindow) *m_qioswindow;
- @private
- QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches;
- UITouch *m_activePencilTouch;
- int m_nextTouchId;
-
- @private
- NSMutableArray *m_accessibleElements;
-};
-
-- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window;
+- (instancetype)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window;
- (void)sendUpdatedExposeEvent;
- (BOOL)isActiveWindow;
+@property (nonatomic, assign) QT_PREPEND_NAMESPACE(QIOSWindow) *platformWindow;
@end
@interface QUIView (Accessibility)
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 8db36705c0..e64c05d099 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -55,7 +55,12 @@
Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
-@implementation QUIView
+@implementation QUIView {
+ QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches;
+ UITouch *m_activePencilTouch;
+ int m_nextTouchId;
+ NSMutableArray<UIAccessibilityElement *> *m_accessibleElements;
+}
+ (void)load
{
@@ -82,25 +87,26 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return [CAEAGLLayer class];
}
-- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window
+- (instancetype)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window
{
if (self = [self initWithFrame:window->geometry().toCGRect()]) {
- m_qioswindow = window;
- m_accessibleElements = [[NSMutableArray alloc] init];
+ self.platformWindow = window;
+ m_accessibleElements = [[NSMutableArray<UIAccessibilityElement *> alloc] init];
}
return self;
}
-- (id)initWithFrame:(CGRect)frame
+- (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
// Set up EAGL layer
CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer);
eaglLayer.opaque = TRUE;
- eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
- kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
+ eaglLayer.drawableProperties = @{
+ kEAGLDrawablePropertyRetainedBacking: @(YES),
+ kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8
+ };
if (isQtApplication())
self.hidden = YES;
@@ -122,21 +128,17 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
self.layer.borderWidth = 1.0;
}
-#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 110000, 110000, __WATCHOS_NA)
if (qEnvironmentVariableIsSet("QT_IOS_DEBUG_WINDOW_SAFE_AREAS")) {
- if (__builtin_available(iOS 11, tvOS 11, *)) {
- UIView *safeAreaOverlay = [[UIView alloc] initWithFrame:CGRectZero];
- [safeAreaOverlay setBackgroundColor:[UIColor colorWithRed:0.3 green:0.7 blue:0.9 alpha:0.3]];
- [self addSubview:safeAreaOverlay];
-
- safeAreaOverlay.translatesAutoresizingMaskIntoConstraints = NO;
- [safeAreaOverlay.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES;
- [safeAreaOverlay.leftAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.leftAnchor].active = YES;
- [safeAreaOverlay.rightAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.rightAnchor].active = YES;
- [safeAreaOverlay.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor].active = YES;
- }
+ UIView *safeAreaOverlay = [[UIView alloc] initWithFrame:CGRectZero];
+ [safeAreaOverlay setBackgroundColor:[UIColor colorWithRed:0.3 green:0.7 blue:0.9 alpha:0.3]];
+ [self addSubview:safeAreaOverlay];
+
+ safeAreaOverlay.translatesAutoresizingMaskIntoConstraints = NO;
+ [safeAreaOverlay.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES;
+ [safeAreaOverlay.leftAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.leftAnchor].active = YES;
+ [safeAreaOverlay.rightAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.rightAnchor].active = YES;
+ [safeAreaOverlay.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor].active = YES;
}
-#endif
}
return self;
@@ -156,7 +158,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
#ifndef QT_NO_DEBUG_STREAM
QString platformWindowDescription;
QDebug debug(&platformWindowDescription);
- debug.nospace() << "; " << m_qioswindow << ">";
+ debug.nospace() << "; " << self.platformWindow << ">";
NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1];
[description replaceCharactersInRange:lastCharacter withString:platformWindowDescription.toNSString()];
#endif
@@ -210,10 +212,10 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
if (!CGAffineTransformIsIdentity(self.transform))
qWarning() << self << "has a transform set. This is not supported.";
- QWindow *window = m_qioswindow->window();
+ QWindow *window = self.platformWindow->window();
QRect lastReportedGeometry = qt_window_private(window)->geometry;
QRect currentGeometry = QRectF::fromCGRect(self.frame).toRect();
- qCDebug(lcQpaWindow) << m_qioswindow << "new geometry is" << currentGeometry;
+ qCDebug(lcQpaWindow) << self.platformWindow << "new geometry is" << currentGeometry;
QWindowSystemInterface::handleGeometryChange(window, currentGeometry);
if (currentGeometry.size() != lastReportedGeometry.size()) {
@@ -237,29 +239,29 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
{
QRegion region;
- if (m_qioswindow->isExposed()) {
+ if (self.platformWindow->isExposed()) {
QSize bounds = QRectF::fromCGRect(self.layer.bounds).toRect().size();
- Q_ASSERT(m_qioswindow->geometry().size() == bounds);
- Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible());
+ Q_ASSERT(self.platformWindow->geometry().size() == bounds);
+ Q_ASSERT(self.hidden == !self.platformWindow->window()->isVisible());
region = QRect(QPoint(), bounds);
}
- qCDebug(lcQpaWindow) << m_qioswindow << region << "isExposed" << m_qioswindow->isExposed();
- QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
+ qCDebug(lcQpaWindow) << self.platformWindow << region << "isExposed" << self.platformWindow->isExposed();
+ QWindowSystemInterface::handleExposeEvent(self.platformWindow->window(), region);
}
- (void)safeAreaInsetsDidChange
{
- QWindowSystemInterface::handleSafeAreaMarginsChanged(m_qioswindow->window());
+ QWindowSystemInterface::handleSafeAreaMarginsChanged(self.platformWindow->window());
}
// -------------------------------------------------------------------------
- (BOOL)canBecomeFirstResponder
{
- return !(m_qioswindow->window()->flags() & Qt::WindowDoesNotAcceptFocus);
+ return !(self.platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus);
}
- (BOOL)becomeFirstResponder
@@ -280,10 +282,10 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
qImDebug() << self << "became first responder";
}
- if (qGuiApp->focusWindow() != m_qioswindow->window())
- QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
+ if (qGuiApp->focusWindow() != self.platformWindow->window())
+ QWindowSystemInterface::handleWindowActivated(self.platformWindow->window());
else
- qImDebug() << m_qioswindow->window() << "already active, not sending window activation";
+ qImDebug() << self.platformWindow->window() << "already active, not sending window activation";
return YES;
}
@@ -349,19 +351,17 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice();
QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities();
- if (__builtin_available(iOS 9, *)) {
- if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
- touchCapabilities |= QTouchDevice::Pressure;
- else
- touchCapabilities &= ~QTouchDevice::Pressure;
- }
+ if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
+ touchCapabilities |= QTouchDevice::Pressure;
+ else
+ touchCapabilities &= ~QTouchDevice::Pressure;
touchDevice->setCapabilities(touchCapabilities);
}
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
- if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput)
+ if (self.platformWindow->window()->flags() & Qt::WindowTransparentForInput)
return NO;
return [super pointInside:point withEvent:event];
}
@@ -378,7 +378,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
for (UITouch *cTouch in cTouches) {
QPointF localViewPosition = QPointF::fromCGPoint([cTouch preciseLocationInView:self]);
QPoint localViewPositionI = localViewPosition.toPoint();
- QPointF globalScreenPosition = m_qioswindow->mapToGlobal(localViewPositionI) +
+ QPointF globalScreenPosition = self.platformWindow->mapToGlobal(localViewPositionI) +
(localViewPosition - localViewPositionI);
qreal pressure = cTouch.force / cTouch.maximumPossibleForce;
// azimuth unit vector: +x to the right, +y going downwards
@@ -391,7 +391,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
qCDebug(lcQpaTablet) << i << ":" << timeStamp << localViewPosition << pressure << state << "azimuth" << azimuth.dx << azimuth.dy
<< "angle" << azimuthAngle << "altitude" << cTouch.altitudeAngle
<< "xTilt" << qBound(-60.0, altitudeAngle * azimuth.dx, 60.0) << "yTilt" << qBound(-60.0, altitudeAngle * azimuth.dy, 60.0);
- QWindowSystemInterface::handleTabletEvent(m_qioswindow->window(), timeStamp, localViewPosition, globalScreenPosition,
+ QWindowSystemInterface::handleTabletEvent(self.platformWindow->window(), timeStamp, localViewPosition, globalScreenPosition,
// device, pointerType, buttons
QTabletEvent::RotationStylus, QTabletEvent::Pen, state == Qt::TouchPointReleased ? Qt::NoButton : Qt::LeftButton,
// pressure, xTilt, yTilt
@@ -415,12 +415,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
// just map from the local view position to global coordinates.
// tvOS: all touches start at the center of the screen and move from there.
QPoint localViewPosition = QPointF::fromCGPoint([uiTouch locationInView:self]).toPoint();
- QPoint globalScreenPosition = m_qioswindow->mapToGlobal(localViewPosition);
+ QPoint globalScreenPosition = self.platformWindow->mapToGlobal(localViewPosition);
touchPoint.area = QRectF(globalScreenPosition, QSize(0, 0));
// FIXME: Do we really need to support QTouchDevice::NormalizedPosition?
- QSize screenSize = m_qioswindow->screen()->geometry().size();
+ QSize screenSize = self.platformWindow->screen()->geometry().size();
touchPoint.normalPosition = QPointF(globalScreenPosition.x() / screenSize.width(),
globalScreenPosition.y() / screenSize.height());
@@ -451,10 +451,10 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
// alert dialog, will fail to recognize. To be on the safe side, we deliver
// the event asynchronously.
QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::AsynchronousDelivery>(
- m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
+ self.platformWindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
} else {
QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(
- m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
+ self.platformWindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
}
}
@@ -482,8 +482,8 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
#endif
}
- if (m_qioswindow->shouldAutoActivateWindow() && m_activeTouches.size() == 1) {
- QPlatformWindow *topLevel = m_qioswindow;
+ if (self.platformWindow->shouldAutoActivateWindow() && m_activeTouches.size() == 1) {
+ QPlatformWindow *topLevel = self.platformWindow;
while (QPlatformWindow *p = topLevel->parent())
topLevel = p;
if (topLevel->window() != QGuiApplication::focusWindow())
@@ -553,7 +553,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
- QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice());
+ QWindowSystemInterface::handleTouchCancelEvent(self.platformWindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice());
}
- (int)mapPressTypeToKey:(UIPress*)press
@@ -581,7 +581,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
int key = [self mapPressTypeToKey:press];
if (key == Qt::Key_unknown)
continue;
- if (QWindowSystemInterface::handleKeyEvent(m_qioswindow->window(), type, key, Qt::NoModifier))
+ if (QWindowSystemInterface::handleKeyEvent(self.platformWindow->window(), type, key, Qt::NoModifier))
handled = true;
}
@@ -635,7 +635,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
- (QWindow *)qwindow
{
if ([self isKindOfClass:[QUIView class]]) {
- if (QT_PREPEND_NAMESPACE(QIOSWindow) *w = static_cast<QUIView *>(self)->m_qioswindow)
+ if (QT_PREPEND_NAMESPACE(QIOSWindow) *w = static_cast<QUIView *>(self).platformWindow)
return w->window();
}
return nil;
@@ -662,18 +662,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
- (UIEdgeInsets)qt_safeAreaInsets
{
-#if QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, 110000, 110000, __WATCHOS_NA)
- if (__builtin_available(iOS 11, tvOS 11, *))
- return self.safeAreaInsets;
-#endif
-
- // Fallback for iOS < 11
- UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
- CGPoint topInset = [self convertPoint:CGPointMake(0, self.viewController.topLayoutGuide.length) fromView:nil];
- CGPoint bottomInset = [self convertPoint:CGPointMake(0, self.viewController.bottomLayoutGuide.length) fromView:nil];
- safeAreaInsets.top = topInset.y;
- safeAreaInsets.bottom = bottomInset.y;
- return safeAreaInsets;
+ return self.safeAreaInsets;
}
@end
diff --git a/src/plugins/platforms/ios/quiview_accessibility.mm b/src/plugins/platforms/ios/quiview_accessibility.mm
index 69a4d375bd..a3f4156a59 100644
--- a/src/plugins/platforms/ios/quiview_accessibility.mm
+++ b/src/plugins/platforms/ios/quiview_accessibility.mm
@@ -49,8 +49,9 @@
if (!iface || iface->state().invisible || (iface->text(QAccessible::Name).isEmpty() && iface->text(QAccessible::Value).isEmpty() && iface->text(QAccessible::Description).isEmpty()))
return;
QAccessible::Id accessibleId = QAccessible::uniqueId(iface);
- UIAccessibilityElement *elem = [[QMacAccessibilityElement alloc] initWithId: accessibleId withAccessibilityContainer: self];
- [m_accessibleElements addObject:[elem autorelease]];
+ UIAccessibilityElement *elem = [[QT_MANGLE_NAMESPACE(QMacAccessibilityElement) alloc] initWithId:accessibleId withAccessibilityContainer:self];
+ [m_accessibleElements addObject:elem];
+ [elem release];
}
- (void)createAccessibleContainer:(QAccessibleInterface *)iface
@@ -73,7 +74,7 @@
if ([m_accessibleElements count])
return;
- QWindow *win = m_qioswindow->window();
+ QWindow *win = self.platformWindow->window();
QAccessibleInterface *iface = win->accessibleRoot();
if (iface)
[self createAccessibleContainer: iface];
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index e61887618f..5bf2b77421 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -46,6 +46,8 @@ haiku {
SUBDIRS += haiku
}
+wasm: SUBDIRS = wasm
+
qtConfig(mirclient): SUBDIRS += mirclient
qtConfig(integrityfb): SUBDIRS += integrity
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 2031de308c..1d030ba1aa 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -64,7 +64,7 @@ static QEGLPlatformContext::Flags makeFlags()
{
QEGLPlatformContext::Flags result = 0;
- if (!QQnxIntegration::options().testFlag(QQnxIntegration::SurfacelessEGLContext))
+ if (!QQnxIntegration::instance()->options().testFlag(QQnxIntegration::SurfacelessEGLContext))
result |= QEGLPlatformContext::NoSurfaceless;
return result;
diff --git a/src/plugins/platforms/qnx/qqnxglobal.cpp b/src/plugins/platforms/qnx/qqnxglobal.cpp
index 6b3cc6bebf..c17f6a7546 100644
--- a/src/plugins/platforms/qnx/qqnxglobal.cpp
+++ b/src/plugins/platforms/qnx/qqnxglobal.cpp
@@ -45,9 +45,9 @@ QT_BEGIN_NAMESPACE
void qScreenCheckError(int rc, const char *funcInfo, const char *message, bool critical)
{
- if (!rc && (QQnxIntegration::options() & QQnxIntegration::AlwaysFlushScreenContext)
- && QQnxIntegration::screenContext() != 0) {
- rc = screen_flush_context(QQnxIntegration::screenContext(), 0);
+ if (!rc && (QQnxIntegration::instance()->options() & QQnxIntegration::AlwaysFlushScreenContext)
+ && QQnxIntegration::instance()->screenContext() != 0) {
+ rc = screen_flush_context(QQnxIntegration::instance()->screenContext(), 0);
}
if (Q_UNLIKELY(rc)) {
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index dc4ebdf699..8c8521325c 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -99,8 +99,7 @@
QT_BEGIN_NAMESPACE
-QQnxWindowMapper QQnxIntegration::ms_windowMapper;
-QMutex QQnxIntegration::ms_windowMapperMutex;
+QQnxIntegration *QQnxIntegration::ms_instance;
static inline QQnxIntegration::Options parseOptions(const QStringList &paramList)
{
@@ -124,6 +123,22 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
return options;
}
+static inline int getContextCapabilities(const QStringList &paramList)
+{
+ QString contextCapabilitiesPrefix = QStringLiteral("screen-context-capabilities=");
+ int contextCapabilities = SCREEN_APPLICATION_CONTEXT;
+ for (const QString &param : paramList) {
+ if (param.startsWith(contextCapabilitiesPrefix)) {
+ QStringRef value = param.midRef(contextCapabilitiesPrefix.length());
+ bool ok = false;
+ contextCapabilities = value.toInt(&ok, 0);
+ if (!ok)
+ contextCapabilities = SCREEN_APPLICATION_CONTEXT;
+ }
+ }
+ return contextCapabilities;
+}
+
QQnxIntegration::QQnxIntegration(const QStringList &paramList)
: QPlatformIntegration()
, m_screenEventThread(0)
@@ -147,11 +162,15 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
, m_drag(new QSimpleDrag())
#endif
{
- ms_options = parseOptions(paramList);
+ ms_instance = this;
+ m_options = parseOptions(paramList);
qIntegrationDebug();
+
// Open connection to QNX composition manager
- Q_SCREEN_CRITICALERROR(screen_create_context(&ms_screenContext, SCREEN_APPLICATION_CONTEXT),
- "Failed to create screen context");
+ if (screen_create_context(&m_screenContext, getContextCapabilities(paramList))) {
+ qFatal("%s - Screen: Failed to create screen context - Error: %s (%i)",
+ Q_FUNC_INFO, strerror(errno), errno);
+ }
#if QT_CONFIG(qqnx_pps)
// Create/start navigator event notifier
@@ -168,7 +187,8 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#endif
// Create/start event thread
- m_screenEventThread = new QQnxScreenEventThread(ms_screenContext, m_screenEventHandler);
+ m_screenEventThread = new QQnxScreenEventThread(m_screenContext);
+ m_screenEventHandler->setScreenEventThread(m_screenEventThread);
m_screenEventThread->start();
#if QT_CONFIG(qqnx_pps)
@@ -244,7 +264,7 @@ QQnxIntegration::~QQnxIntegration()
destroyDisplays();
// Close connection to QNX composition manager
- screen_destroy_context(ms_screenContext);
+ screen_destroy_context(m_screenContext);
#if !defined(QT_NO_OPENGL)
// Cleanup global OpenGL resources
@@ -268,6 +288,8 @@ QQnxIntegration::~QQnxIntegration()
// Destroy navigator interface
delete m_navigator;
+ ms_instance = nullptr;
+
qIntegrationDebug("platform plugin shutdown end");
}
@@ -296,10 +318,10 @@ QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const
const bool needRootWindow = options() & RootWindow;
switch (surfaceType) {
case QSurface::RasterSurface:
- return new QQnxRasterWindow(window, ms_screenContext, needRootWindow);
+ return new QQnxRasterWindow(window, m_screenContext, needRootWindow);
#if !defined(QT_NO_OPENGL)
case QSurface::OpenGLSurface:
- return new QQnxEglWindow(window, ms_screenContext, needRootWindow);
+ return new QQnxEglWindow(window, m_screenContext, needRootWindow);
#endif
default:
qFatal("QQnxWindow: unsupported window API");
@@ -433,7 +455,7 @@ QPlatformDrag *QQnxIntegration::drag() const
QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
qIntegrationDebug();
- if ((hint == ShowIsFullScreen) && (ms_options & FullScreenApplication))
+ if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication))
return true;
return QPlatformIntegration::styleHint(hint);
@@ -447,25 +469,25 @@ QPlatformServices * QQnxIntegration::services() const
QWindow *QQnxIntegration::window(screen_window_t qnxWindow)
{
qIntegrationDebug();
- QMutexLocker locker(&ms_windowMapperMutex);
+ QMutexLocker locker(&m_windowMapperMutex);
Q_UNUSED(locker);
- return ms_windowMapper.value(qnxWindow, 0);
+ return m_windowMapper.value(qnxWindow, 0);
}
void QQnxIntegration::addWindow(screen_window_t qnxWindow, QWindow *window)
{
qIntegrationDebug();
- QMutexLocker locker(&ms_windowMapperMutex);
+ QMutexLocker locker(&m_windowMapperMutex);
Q_UNUSED(locker);
- ms_windowMapper.insert(qnxWindow, window);
+ m_windowMapper.insert(qnxWindow, window);
}
void QQnxIntegration::removeWindow(screen_window_t qnxWindow)
{
qIntegrationDebug();
- QMutexLocker locker(&ms_windowMapperMutex);
+ QMutexLocker locker(&m_windowMapperMutex);
Q_UNUSED(locker);
- ms_windowMapper.remove(qnxWindow);
+ m_windowMapper.remove(qnxWindow);
}
void QQnxIntegration::createDisplays()
@@ -473,7 +495,7 @@ void QQnxIntegration::createDisplays()
qIntegrationDebug();
// Query number of displays
int displayCount = 0;
- int result = screen_get_context_property_iv(ms_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT,
+ int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT,
&displayCount);
Q_SCREEN_CRITICALERROR(result, "Failed to query display count");
@@ -484,7 +506,7 @@ void QQnxIntegration::createDisplays()
// Get all displays
screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
- result = screen_get_context_property_pv(ms_screenContext, SCREEN_PROPERTY_DISPLAYS,
+ result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS,
(void **)displays);
Q_SCREEN_CRITICALERROR(result, "Failed to query displays");
@@ -510,7 +532,7 @@ void QQnxIntegration::createDisplays()
void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary)
{
- QQnxScreen *screen = new QQnxScreen(ms_screenContext, display, isPrimary);
+ QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary);
m_screens.append(screen);
screenAdded(screen);
screen->adjustOrientation();
@@ -559,14 +581,14 @@ QQnxScreen *QQnxIntegration::primaryDisplay() const
return m_screens.first();
}
-QQnxIntegration::Options QQnxIntegration::options()
+QQnxIntegration::Options QQnxIntegration::options() const
{
- return ms_options;
+ return m_options;
}
screen_context_t QQnxIntegration::screenContext()
{
- return ms_screenContext;
+ return m_screenContext;
}
QQnxNavigatorEventHandler *QQnxIntegration::navigatorEventHandler()
@@ -574,10 +596,6 @@ QQnxNavigatorEventHandler *QQnxIntegration::navigatorEventHandler()
return m_navigatorEventHandler;
}
-screen_context_t QQnxIntegration::ms_screenContext = 0;
-
-QQnxIntegration::Options QQnxIntegration::ms_options = 0;
-
bool QQnxIntegration::supportsNavigatorEvents() const
{
// If QQNX_PPS is defined then we have navigator
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index f844a7508c..2993607489 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -88,6 +88,8 @@ public:
explicit QQnxIntegration(const QStringList &paramList);
~QQnxIntegration();
+ static QQnxIntegration *instance() { return ms_instance; }
+
bool hasCapability(QPlatformIntegration::Capability cap) const override;
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
@@ -121,15 +123,15 @@ public:
QPlatformServices *services() const override;
- static QWindow *window(screen_window_t qnxWindow);
+ QWindow *window(screen_window_t qnxWindow);
QQnxScreen *screenForNative(screen_display_t qnxScreen) const;
void createDisplay(screen_display_t display, bool isPrimary);
void removeDisplay(QQnxScreen *screen);
QQnxScreen *primaryDisplay() const;
- static Options options();
- static screen_context_t screenContext();
+ Options options() const;
+ screen_context_t screenContext();
QQnxNavigatorEventHandler *navigatorEventHandler();
@@ -137,10 +139,10 @@ private:
void createDisplays();
void destroyDisplays();
- static void addWindow(screen_window_t qnxWindow, QWindow *window);
- static void removeWindow(screen_window_t qnxWindow);
+ void addWindow(screen_window_t qnxWindow, QWindow *window);
+ void removeWindow(screen_window_t qnxWindow);
- static screen_context_t ms_screenContext;
+ screen_context_t m_screenContext;
QQnxScreenEventThread *m_screenEventThread;
QQnxNavigatorEventHandler *m_navigatorEventHandler;
QQnxAbstractVirtualKeyboard *m_virtualKeyboard;
@@ -162,10 +164,12 @@ private:
#if QT_CONFIG(draganddrop)
QSimpleDrag *m_drag;
#endif
- static QQnxWindowMapper ms_windowMapper;
- static QMutex ms_windowMapperMutex;
+ QQnxWindowMapper m_windowMapper;
+ QMutex m_windowMapperMutex;
+
+ Options m_options;
- static Options ms_options;
+ static QQnxIntegration *ms_instance;
friend class QQnxWindow;
};
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index ff1133aaa7..e4843cb438 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -218,36 +218,39 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie
void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread)
{
m_eventThread = eventThread;
+ connect(m_eventThread, &QQnxScreenEventThread::eventsPending,
+ this, &QQnxScreenEventHandler::processEvents);
}
-void QQnxScreenEventHandler::processEventsFromScreenThread()
+void QQnxScreenEventHandler::processEvents()
{
if (!m_eventThread)
return;
- QQnxScreenEventArray *events = m_eventThread->lock();
+ screen_event_t event = nullptr;
+ if (screen_create_event(&event) != 0)
+ return;
- for (int i = 0; i < events->size(); ++i) {
- screen_event_t event = events->at(i);
- if (!event)
- continue;
- (*events)[i] = 0;
+ int count = 0;
+ for (;;) {
+ if (screen_get_event(m_eventThread->context(), event, 0) != 0)
+ break;
- m_eventThread->unlock();
+ int type = SCREEN_EVENT_NONE;
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type);
+ if (type == SCREEN_EVENT_NONE)
+ break;
+ ++count;
long result = 0;
QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
bool handled = dispatcher && dispatcher->filterNativeEvent(QByteArrayLiteral("screen_event_t"), event, &result);
if (!handled)
handleEvent(event);
- screen_destroy_event(event);
-
- m_eventThread->lock();
}
- events->clear();
-
- m_eventThread->unlock();
+ m_eventThread->armEventsPending(count);
+ screen_destroy_event(event);
}
void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
@@ -323,11 +326,11 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
"Failed to query event wheel delta");
// Map window handle to top-level QWindow
- QWindow *w = QQnxIntegration::window(qnxWindow);
+ QWindow *w = QQnxIntegration::instance()->window(qnxWindow);
// Generate enter and leave events as needed.
if (qnxWindow != m_lastMouseWindow) {
- QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow);
+ QWindow *wOld = QQnxIntegration::instance()->window(m_lastMouseWindow);
if (wOld) {
QWindowSystemInterface::handleLeaveEvent(wOld);
@@ -435,11 +438,11 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
if (touchId < MaximumTouchPoints) {
// Map window handle to top-level QWindow
- QWindow *w = QQnxIntegration::window(qnxWindow);
+ QWindow *w = QQnxIntegration::instance()->window(qnxWindow);
// Generate enter and leave events as needed.
if (qnxWindow != m_lastMouseWindow) {
- QWindow *wOld = QQnxIntegration::window(m_lastMouseWindow);
+ QWindow *wOld = QQnxIntegration::instance()->window(m_lastMouseWindow);
if (wOld) {
QWindowSystemInterface::handleLeaveEvent(wOld);
@@ -529,7 +532,7 @@ void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event)
Q_EMIT windowClosed(window);
// Map window handle to top-level QWindow
- QWindow *w = QQnxIntegration::window(window);
+ QWindow *w = QQnxIntegration::instance()->window(window);
if (w != 0)
QWindowSystemInterface::handleCloseEvent(w);
}
@@ -629,7 +632,7 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi
if (Q_UNLIKELY(window && screen_get_window_property_iv(window, SCREEN_PROPERTY_FOCUS, &focus) != 0))
qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno);
- QWindow *focusWindow = QQnxIntegration::window(window);
+ QWindow *focusWindow = QQnxIntegration::instance()->window(window);
if (m_focusLostTimer != -1) {
killTimer(m_focusLostTimer);
@@ -655,7 +658,7 @@ void QQnxScreenEventHandler::handleGeometryPropertyEvent(screen_window_t window)
}
QRect rect(pos[0], pos[1], size[0], size[1]);
- QWindow *qtWindow = QQnxIntegration::window(window);
+ QWindow *qtWindow = QQnxIntegration::instance()->window(window);
if (qtWindow) {
qtWindow->setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(qtWindow, rect);
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
index 40697b7a09..b35967610e 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -74,7 +74,7 @@ protected:
void timerEvent(QTimerEvent *event) override;
private Q_SLOTS:
- void processEventsFromScreenThread();
+ void processEvents();
private:
void handleKeyboardEvent(screen_event_t event);
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
index c56d9a8da4..1b5f3b4954 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
@@ -1,5 +1,6 @@
/***************************************************************************
**
+** Copyright (C) 2017 QNX Software Systems. All rights reserved.
** Copyright (C) 2011 - 2012 Research In Motion
** Contact: https://www.qt.io/licensing/
**
@@ -55,116 +56,101 @@
#define qScreenEventThreadDebug QT_NO_QDEBUG_MACRO
#endif
-QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context, QQnxScreenEventHandler *screenEventHandler)
- : QThread(),
- m_screenContext(context),
- m_screenEventHandler(screenEventHandler),
- m_quit(false)
+static const int c_screenCode = _PULSE_CODE_MINAVAIL + 0;
+static const int c_armCode = _PULSE_CODE_MINAVAIL + 1;
+static const int c_quitCode = _PULSE_CODE_MINAVAIL + 2;
+
+QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context)
+ : QThread()
+ , m_screenContext(context)
{
- screenEventHandler->setScreenEventThread(this);
- connect(this, SIGNAL(eventPending()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection);
- connect(this, SIGNAL(finished()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection);
+ m_channelId = ChannelCreate(_NTO_CHF_DISCONNECT | _NTO_CHF_UNBLOCK | _NTO_CHF_PRIVATE);
+ if (m_channelId == -1) {
+ qFatal("QQnxScreenEventThread: Can't continue without a channel");
+ }
+
+ m_connectionId = ConnectAttach(0, 0, m_channelId, _NTO_SIDE_CHANNEL, 0);
+ if (m_connectionId == -1) {
+ ChannelDestroy(m_channelId);
+ qFatal("QQnxScreenEventThread: Can't continue without a channel connection");
+ }
+
+ struct sigevent screenEvent;
+ SIGEV_PULSE_INIT(&screenEvent, m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_screenCode, 0);
+
+ screen_notify(m_screenContext, SCREEN_NOTIFY_EVENT, nullptr, &screenEvent);
}
QQnxScreenEventThread::~QQnxScreenEventThread()
{
// block until thread terminates
shutdown();
-}
-void QQnxScreenEventThread::injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap)
-{
- QQnxScreenEventHandler::injectKeyboardEvent(flags, sym, mod, scan, cap);
-}
-
-QQnxScreenEventArray *QQnxScreenEventThread::lock()
-{
- m_mutex.lock();
- return &m_events;
-}
-
-void QQnxScreenEventThread::unlock()
-{
- m_mutex.unlock();
+ ConnectDetach(m_connectionId);
+ ChannelDestroy(m_channelId);
}
void QQnxScreenEventThread::run()
{
qScreenEventThreadDebug("screen event thread started");
- int errorCounter = 0;
- // loop indefinitely
- while (!m_quit) {
- screen_event_t event;
-
- // create screen event
- Q_SCREEN_CHECKERROR(screen_create_event(&event), "Failed to create screen event");
-
- // block until screen event is available
- const int error = screen_get_event(m_screenContext, event, -1);
- Q_SCREEN_CRITICALERROR(error, "Failed to get screen event");
- // Only allow 50 consecutive errors before we exit the thread
- if (error) {
- errorCounter++;
- if (errorCounter > 50)
- m_quit = true;
-
- screen_destroy_event(event);
- continue;
- } else {
- errorCounter = 0;
- }
-
- // process received event
- // get the event type
- int qnxType;
- Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType),
- "Failed to query screen event type");
-
- if (qnxType == SCREEN_EVENT_USER) {
- // treat all user events as shutdown requests
- qScreenEventThreadDebug("QNX user screen event");
- m_quit = true;
- } else {
- m_mutex.lock();
- m_events << event;
- m_mutex.unlock();
- emit eventPending();
- }
+ while (1) {
+ struct _pulse msg;
+ memset(&msg, 0, sizeof(msg));
+ int receiveId = MsgReceive(m_channelId, &msg, sizeof(msg), nullptr);
+ if (receiveId == 0 && msg.code == c_quitCode)
+ break;
+ else if (receiveId == 0)
+ handlePulse(msg);
+ else if (receiveId > 0)
+ qWarning() << "Unexpected message" << msg.code;
+ else
+ qWarning() << "MsgReceive error" << strerror(errno);
}
qScreenEventThreadDebug("screen event thread stopped");
-
- // cleanup
- m_mutex.lock();
- Q_FOREACH (screen_event_t event, m_events) {
- screen_destroy_event(event);
- }
- m_events.clear();
- m_mutex.unlock();
}
-void QQnxScreenEventThread::shutdown()
+void QQnxScreenEventThread::armEventsPending(int count)
{
- screen_event_t event;
+ MsgSendPulse(m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_armCode, count);
+}
- // create screen event
- Q_SCREEN_CHECKERROR(screen_create_event(&event),
- "Failed to create screen event");
+void QQnxScreenEventThread::handleScreenPulse(const struct _pulse &msg)
+{
+ Q_UNUSED(msg);
- // set the event type as user
- int type = SCREEN_EVENT_USER;
- Q_SCREEN_CHECKERROR(screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type),
- "Failed to set screen type");
+ ++m_screenPulsesSinceLastArmPulse;
+ if (m_emitNeededOnNextScreenPulse) {
+ m_emitNeededOnNextScreenPulse = false;
+ Q_EMIT eventsPending();
+ }
+}
- // NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events
+void QQnxScreenEventThread::handleArmPulse(const struct _pulse &msg)
+{
+ if (msg.value.sival_int == 0 && m_screenPulsesSinceLastArmPulse == 0) {
+ m_emitNeededOnNextScreenPulse = true;
+ } else {
+ m_screenPulsesSinceLastArmPulse = 0;
+ m_emitNeededOnNextScreenPulse = false;
+ Q_EMIT eventsPending();
+ }
+}
- // post event to event loop so it will wake up and die
- Q_SCREEN_CHECKERROR(screen_send_event(m_screenContext, event, getpid()),
- "Failed to set screen event type");
+void QQnxScreenEventThread::handlePulse(const struct _pulse &msg)
+{
+ if (msg.code == c_screenCode)
+ handleScreenPulse(msg);
+ else if (msg.code == c_armCode)
+ handleArmPulse(msg);
+ else
+ qWarning() << "Unexpected pulse" << msg.code;
+}
- // cleanup
- screen_destroy_event(event);
+void QQnxScreenEventThread::shutdown()
+{
+ MsgSendPulse(m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_quitCode, 0);
qScreenEventThreadDebug("screen event thread shutdown begin");
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.h b/src/plugins/platforms/qnx/qqnxscreeneventthread.h
index 140f53aa50..3c8d197545 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.h
@@ -1,5 +1,6 @@
/***************************************************************************
**
+** Copyright (C) 2017 QNX Software Systems. All rights reserved.
** Copyright (C) 2011 - 2012 Research In Motion
** Contact: https://www.qt.io/licensing/
**
@@ -47,37 +48,34 @@
QT_BEGIN_NAMESPACE
-class QQnxScreenEventHandler;
-
-typedef QVarLengthArray<screen_event_t, 64> QQnxScreenEventArray;
-
class QQnxScreenEventThread : public QThread
{
Q_OBJECT
public:
- QQnxScreenEventThread(screen_context_t context, QQnxScreenEventHandler *screenEventHandler);
+ QQnxScreenEventThread(screen_context_t context);
~QQnxScreenEventThread();
- static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
-
- QQnxScreenEventArray *lock();
- void unlock();
+ screen_context_t context() const { return m_screenContext; }
+ void armEventsPending(int count);
protected:
void run() override;
Q_SIGNALS:
- void eventPending();
+ void eventsPending();
private:
+ void handleScreenPulse(const struct _pulse &msg);
+ void handleArmPulse(const struct _pulse &msg);
+ void handlePulse(const struct _pulse &msg);
void shutdown();
+ int m_channelId;
+ int m_connectionId;
screen_context_t m_screenContext;
- QMutex m_mutex;
- QQnxScreenEventArray m_events;
- QQnxScreenEventHandler *m_screenEventHandler;
- bool m_quit;
+ bool m_emitNeededOnNextScreenPulse = true;
+ int m_screenPulsesSinceLastArmPulse = 0;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 4a547aa158..5d9eaaa3ea 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -174,7 +174,9 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
// If a qnxInitialWindowGroup property is set on the window we'll take this as an
// indication that we want to create a child window and join that window group.
- const QVariant windowGroup = window->property("qnxInitialWindowGroup");
+ QVariant windowGroup = window->property("qnxInitialWindowGroup");
+ if (!windowGroup.isValid())
+ windowGroup = window->property("_q_platform_qnxParentGroup");
if (window->type() == Qt::CoverWindow) {
// Cover windows have to be top level to be accessible to window delegate (i.e. navigator)
@@ -194,7 +196,12 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
if (window->type() == Qt::Desktop) // A desktop widget does not need a libscreen window
return;
- if (m_isTopLevel) {
+ QVariant type = window->property("_q_platform_qnxWindowType");
+ if (type.isValid() && type.canConvert<int>()) {
+ Q_SCREEN_CHECKERROR(
+ screen_create_window_type(&m_window, m_screenContext, type.value<int>()),
+ "Could not create window");
+ } else if (m_isTopLevel) {
Q_SCREEN_CRITICALERROR(screen_create_window(&m_window, m_screenContext),
"Could not create top level window"); // Creates an application window
if (window->type() != Qt::CoverWindow) {
@@ -212,7 +219,9 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
// If the window has a qnxWindowId property, set this as the string id property. This generally
// needs to be done prior to joining any group as it might be used by the owner of the
// group to identify the window.
- const QVariant windowId = window->property("qnxWindowId");
+ QVariant windowId = window->property("qnxWindowId");
+ if (!windowId.isValid())
+ windowId = window->property("_q_platform_qnxWindowId");
if (windowId.isValid() && windowId.canConvert<QByteArray>()) {
QByteArray id = windowId.toByteArray();
Q_SCREEN_CHECKERROR(screen_set_window_property_cv(m_window, SCREEN_PROPERTY_ID_STRING,
@@ -262,7 +271,7 @@ QQnxWindow::~QQnxWindow()
Q_ASSERT(m_childWindows.size() == 0);
// Remove from plugin's window mapper
- QQnxIntegration::removeWindow(m_window);
+ QQnxIntegration::instance()->removeWindow(m_window);
// Remove from parent's Hierarchy.
removeFromParent();
@@ -471,7 +480,7 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
qWindowDebug("Moving window to different screen");
m_screen->removeWindow(this);
- if ((QQnxIntegration::options() & QQnxIntegration::RootWindow)) {
+ if ((QQnxIntegration::instance()->options() & QQnxIntegration::RootWindow)) {
screen_leave_window_group(m_window);
}
}
@@ -726,7 +735,7 @@ void QQnxWindow::initWindow()
m_exposed = false;
// Add window to plugin's window mapper
- QQnxIntegration::addWindow(m_window, window());
+ QQnxIntegration::instance()->addWindow(m_window, window());
// Qt never calls these setters after creating the window, so we need to do that ourselves here
setWindowState(window()->windowState());
@@ -823,7 +832,7 @@ void QQnxWindow::windowPosted()
bool QQnxWindow::shouldMakeFullScreen() const
{
return ((static_cast<QQnxScreen *>(screen())->rootWindow() == this)
- && (QQnxIntegration::options() & QQnxIntegration::FullScreenApplication));
+ && (QQnxIntegration::instance()->options() & QQnxIntegration::FullScreenApplication));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/main.cpp b/src/plugins/platforms/wasm/main.cpp
new file mode 100644
index 0000000000..a4d23b4e0d
--- /dev/null
+++ b/src/plugins/platforms/wasm/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpa/qplatformintegrationplugin.h>
+#include "qwasmintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWasmIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "wasm.json")
+public:
+ QPlatformIntegration *create(const QString &, const QStringList &) override;
+};
+
+QPlatformIntegration *QWasmIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (!system.compare(QStringLiteral("wasm"), Qt::CaseInsensitive))
+ return new QWasmIntegration;
+
+ return nullptr;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js
new file mode 100644
index 0000000000..37a5308034
--- /dev/null
+++ b/src/plugins/platforms/wasm/qtloader.js
@@ -0,0 +1,516 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// QtLoader provides javascript API for managing Qt application modules.
+//
+// QtLoader provides API on top of Emscripten which supports common lifecycle
+// tasks such as displaying placeholder content while the module downloads,
+// handing application exits, and checking for browser wasm support.
+//
+// There are two usage modes:
+// * Managed: QtLoader owns and manages the HTML display elements like
+// the loader and canvas.
+// * External: The embedding HTML page owns the display elements. QtLoader
+// provides event callbacks which the page reacts to.
+//
+// Managed mode usage:
+//
+// var config = {
+// containerElements : [$("container-id")];
+// }
+// var qtLoader = QtLoader(config);
+// qtLoader.loadEmscriptenModule("applicationName");
+//
+// External mode.usage:
+//
+// var config = {
+// showLoader: function() {
+// loader.style.display = 'block'
+// canvas.style.display = 'hidden'
+// },
+// showCanvas: function() {
+// loader.style.display = 'hidden'
+// canvas.style.display = 'block'
+// return canvas;
+// }
+// }
+// var qtLoader = QtLoader(config);
+// qtLoader.loadEmscriptenModule("applicationName");
+//
+// Config keys
+//
+// containerElements : [container-element, ...]
+// One or more HTML elements. QtLoader will display loader elements
+// on these while loading the applicaton, and replace the loader with a
+// canvas on load complete.
+// showLoader : function(status, containerElement)
+// Optional loading element constructor function. Implement to create
+// a custom loading screen. This function may be called multiple times,
+// while preparing the application binary. "status" is a string
+// containing the loading sub-status, and may be either "Downloading",
+// or "Compiling". The browser may be using streaming compilation, in
+// which case the wasm module is compiled during downloading and the
+// there is no separate compile step.
+// showCanvas : function(containerElement)
+// Optional canvas constructor function. Implement to create custom
+// canvas elements.
+// showExit : function(crashed, exitCode, containerElement)
+// Optional exited element constructor function.
+// showError : function(crashed, exitCode, containerElement)
+// Optional error element constructor function.
+//
+// path : <string>
+// Prefix path for wasm file, realative to the loading HMTL file.
+// restartMode : "DoNotRestart", "RestartOnExit", "RestartOnCrash"
+// Controls whether the application should be reloaded on exits. The default is "DoNotRestart"
+// restartType : "RestartModule", "ReloadPage"
+// restartLimit : <int>
+// Restart attempts limit. The default is 10.
+// stdoutEnabled : <bool>
+// stderrEnabled : <bool>
+// environment : <object>
+// key-value environment variable pairs.
+//
+// QtLoader object API
+//
+// webAssemblySupported : bool
+// webGLSupported : bool
+// canLoadQt : bool
+// Reports if WebAssembly and WebGL are supported. These are requirements for
+// running Qt applications.
+// loadEmscriptenModule(applicationName)
+// Loads the application from the given emscripten javascript module file and wasm file
+// status
+// One of "Created", "Loading", "Running", "Exited".
+// crashed
+// Set to true if there was an unclean exit.
+// exitCode
+// main()/emscripten_force_exit() return code. Valid on status change to
+// "Exited", iff crashed is false.
+// exitText
+// Abort/exit message.
+
+
+var Module = {}
+
+function QtLoader(config)
+{
+ function webAssemblySupported() {
+ return typeof WebAssembly !== "undefined"
+ }
+
+ function webGLSupported() {
+ // We expect that WebGL is supported if WebAssembly is; however
+ // the GPU may be blacklisted.
+ try {
+ var canvas = document.createElement("canvas");
+ return !!(window.WebGLRenderingContext && (canvas.getContext("webgl") || canvas.getContext("experimental-webgl")));
+ } catch (e) {
+ return false;
+ }
+ }
+
+ function canLoadQt() {
+ // The current Qt implementation requires WebAssembly (asm.js is not in use),
+ // and also WebGL (there is no raster fallback).
+ return webAssemblySupported() && webGLSupported();
+ }
+
+ function removeChildren(element) {
+ while (element.firstChild) element.removeChild(element.firstChild);
+ }
+
+ // Set default state handler functions if needed
+ if (config.containerElements !== undefined) {
+ config.showError = config.showError || function(errorText, container) {
+ removeChildren(container);
+ var errorTextElement = document.createElement("text");
+ errorTextElement.className = "QtError"
+ errorTextElement.innerHTML = errorText;
+ return errorTextElement;
+ }
+
+ config.showLoader = config.showLoader || function(loadingState, container) {
+ removeChildren(container);
+ var loadingText = document.createElement("text");
+ loadingText.className = "QtLoading"
+ loadingText.innerHTML = '<p><center> ${loadingState}...</center><p>';
+ return loadingText;
+ };
+
+ config.showCanvas = config.showCanvas || function(container) {
+ removeChildren(container);
+ var canvas = document.createElement("canvas");
+ canvas.className = "QtCanvas"
+ canvas.style = "height: 100%; width: 100%;"
+ return canvas;
+ }
+
+ config.showExit = config.showExit || function(crashed, exitCode, container) {
+ if (!crashed)
+ return undefined;
+
+ removeChildren(container);
+ var fontSize = 54;
+ var crashSymbols = ["\u{1F615}", "\u{1F614}", "\u{1F644}", "\u{1F928}", "\u{1F62C}",
+ "\u{1F915}", "\u{2639}", "\u{1F62E}", "\u{1F61E}", "\u{1F633}"];
+ var symbolIndex = Math.floor(Math.random() * crashSymbols.length);
+ var errorHtml = `<font size='${fontSize}'> ${crashSymbols[symbolIndex]} </font>`
+ var errorElement = document.createElement("text");
+ errorElement.className = "QtExit"
+ errorElement.innerHTML = errorHtml;
+ return errorElement;
+ }
+ }
+
+ config.restartMode = config.restartMode || "DoNotRestart";
+ config.restartLimit = config.restartLimit || 10;
+
+ if (config.stdoutEnabled === undefined) config.stdoutEnabled = true;
+ if (config.stderrEnabled === undefined) config.stderrEnabled = true;
+
+ // Make sure config.path is defined and ends with "/" if needed
+ if (config.path === undefined)
+ config.path = "";
+ if (config.path.length > 0 && !config.path.endsWith("/"))
+ config.path = config.path.concat("/");
+
+ if (config.environment === undefined)
+ config.environment = {};
+
+ var publicAPI = {};
+ publicAPI.webAssemblySupported = webAssemblySupported();
+ publicAPI.webGLSupported = webGLSupported();
+ publicAPI.canLoadQt = canLoadQt();
+ publicAPI.canLoadApplication = canLoadQt();
+ publicAPI.status = undefined;
+ publicAPI.loadEmscriptenModule = loadEmscriptenModule;
+
+ restartCount = 0;
+
+ function fetchResource(filePath) {
+ var fullPath = config.path + filePath;
+ return fetch(fullPath).then(function(response) {
+ if (!response.ok) {
+ self.error = response.status + " " + response.statusText + " " + response.url;
+ setStatus("Error");
+ return Promise.reject(self.error)
+ } else {
+ return response;
+ }
+ });
+ }
+
+ function fetchText(filePath) {
+ return fetchResource(filePath).then(function(response) {
+ return response.text();
+ });
+ }
+
+ function fetchThenCompileWasm(response) {
+ return response.arrayBuffer().then(function(data) {
+ self.loaderSubState = "Compiling";
+ setStatus("Loading") // trigger loaderSubState udpate
+ return WebAssembly.compile(data);
+ });
+ }
+
+ function fetchCompileWasm(filePath) {
+ return fetchResource(filePath).then(function(response) {
+ if (typeof WebAssembly.compileStreaming !== "undefined") {
+ self.loaderSubState = "Downloading/Compiling";
+ setStatus("Loading");
+ return WebAssembly.compileStreaming(response).catch(function(error) {
+ // compileStreaming may/will fail if the server does not set the correct
+ // mime type (application/wasm) for the wasm file. Fall back to fetch,
+ // then compile in this case.
+ return fetchThenCompileWasm(response);
+ });
+ } else {
+ // Fall back to fetch, then compile if compileStreaming is not supported
+ return fetchThenCompileWasm(response);
+ }
+ });
+ }
+
+ function loadEmscriptenModule(applicationName) {
+
+ // Loading in qtloader.js goes through four steps:
+ // 1) Check prerequisites
+ // 2) Download resources
+ // 3) Configure the emscripten Module object
+ // 4) Start the emcripten runtime, after which emscripten takes over
+
+ // Check for Wasm & WebGL support; set error and return before downloading resources if missing
+ if (!webAssemblySupported()) {
+ self.error = "Error: WebAssembly is not supported"
+ setStatus("Error");
+ return;
+ }
+ if (!webGLSupported()) {
+ self.error = "Error: WebGL is not supported"
+ setStatus("Error");
+ return;
+ }
+
+ // Continue waiting if loadEmscriptenModule() is called again
+ if (publicAPI.status == "Loading")
+ return;
+ self.loaderSubState = "Downloading";
+ setStatus("Loading");
+
+ // Fetch emscripten generated javascript runtime
+ var emscriptenModuleSource = undefined
+ var emscriptenModuleSourcePromise = fetchText(applicationName + ".js").then(function(source) {
+ emscriptenModuleSource = source
+ });
+
+ // Fetch and compile wasm module
+ var wasmModule = undefined;
+ var wasmModulePromise = fetchCompileWasm(applicationName + ".wasm").then(function (module) {
+ wasmModule = module;
+ });
+
+ // Wait for all resources ready
+ Promise.all([emscriptenModuleSourcePromise, wasmModulePromise]).then(function(){
+ completeLoadEmscriptenModule(applicationName, emscriptenModuleSource, wasmModule);
+ }).catch(function(error) {
+ self.error = error;
+ setStatus("Error");
+ });
+ }
+
+ function completeLoadEmscriptenModule(applicationName, emscriptenModuleSource, wasmModule) {
+
+ // The wasm binary has been compiled into a module during resource download,
+ // and is ready to be instantiated. Define the instantiateWasm callback which
+ // emscripten will call to create the instance.
+ Module.instantiateWasm = function(imports, successCallback) {
+ return WebAssembly.instantiate(wasmModule, imports).then(function(instance) {
+ successCallback(instance);
+ return instance;
+ }, function(error) {
+ self.error = error;
+ setStatus("Error");
+ });
+ };
+
+ Module.locateFile = Module.locateFile || function(filename) {
+ return config.path + filename;
+ };
+
+ // Attach status callbacks
+ Module.setStatus = Module.setStatus || function(text) {
+ // Currently the only usable status update from this function
+ // is "Running..."
+ if (text.startsWith("Running"))
+ setStatus("Running");
+ };
+ Module.monitorRunDependencies = Module.monitorRunDependencies || function(left) {
+ // console.log("monitorRunDependencies " + left)
+ };
+
+ // Attach standard out/err callbacks.
+ Module.print = Module.print || function(text) {
+ if (config.stdoutEnabled)
+ console.log(text)
+ };
+ Module.printErr = Module.printErr || function(text) {
+ // Filter out OpenGL getProcAddress warnings. Qt tries to resolve
+ // all possible function/extension names at startup which causes
+ // emscripten to spam the console log with warnings.
+ if (text.startsWith !== undefined && text.startsWith("bad name in getProcAddress:"))
+ return;
+
+ if (config.stderrEnabled)
+ console.log(text)
+ };
+
+ // Error handling: set status to "Exited", update crashed and
+ // exitCode according to exit type.
+ // Emscripten will typically call printErr with the error text
+ // as well. Note that emscripten may also throw exceptions from
+ // async callbacks. These should be handled in window.onerror by user code.
+ Module.onAbort = Module.onAbort || function(text) {
+ publicAPI.crashed = true;
+ publicAPI.exitText = text;
+ setStatus("Exited");
+ };
+ Module.quit = Module.quit || function(code, exception) {
+ if (exception.name == "ExitStatus") {
+ // Clean exit with code
+ publicAPI.exitText = undefined
+ publicAPI.exitCode = code;
+ } else {
+ publicAPI.exitText = exception.toString();
+ publicAPI.crashed = true;
+ }
+ setStatus("Exited");
+ };
+
+ // Set environment variables
+ Module.preRun = Module.preRun || []
+ Module.preRun.push(function() {
+ for (var [key, value] of Object.entries(config.environment)) {
+ Module.ENV[key.toUpperCase()] = value;
+ }
+ });
+
+ config.restart = function() {
+
+ // Restart by reloading the page. This will wipe all state which means
+ // reload loops can't be prevented.
+ if (config.restartType == "ReloadPage") {
+ location.reload();
+ }
+
+ // Restart by readling the emscripten app module.
+ ++self.restartCount;
+ if (self.restartCount > config.restartLimit) {
+ self.error = "Error: This application has crashed too many times and has been disabled. Reload the page to try again."
+ setStatus("Error");
+ return;
+ }
+ loadEmscriptenModule(applicationName);
+ };
+
+ publicAPI.exitCode = undefined;
+ publicAPI.exitText = undefined;
+ publicAPI.crashed = false;
+
+ // Finally evaluate the emscripten application script, which will
+ // reference the global Module object created above.
+ self.eval(emscriptenModuleSource); // ES5 indirect global scope eval
+ }
+
+ function setErrorContent() {
+ if (config.containerElements === undefined) {
+ if (config.showError !== undefined)
+ config.showError(self.error);
+ return;
+ }
+
+ for (container of config.containerElements) {
+ var errorElement = config.showError(self.error, container);
+ container.appendChild(errorElement);
+ }
+ }
+
+ function setLoaderContent() {
+ if (config.containerElements === undefined) {
+ if (config.showLoader !== undefined)
+ config.showLoader(self.loaderSubState);
+ return;
+ }
+
+ for (container of config.containerElements) {
+ var loaderElement = config.showLoader(self.loaderSubState, container);
+ container.appendChild(loaderElement);
+ }
+ }
+
+ function setCanvasContent() {
+ var firstCanvas;
+ if (config.containerElements === undefined) {
+ firstCanvas = config.showCanvas();
+ } else {
+ for (container of config.containerElements) {
+ var canvasElement = config.showCanvas(container);
+ container.appendChild(canvasElement);
+ }
+ firstCanvas = config.containerElements[0].firstChild;
+ }
+
+ if (Module.canvas === undefined) {
+ Module.canvas = firstCanvas;
+ }
+ }
+
+ function setExitContent() {
+
+ // publicAPI.crashed = true;
+
+ if (publicAPI.status != "Exited")
+ return;
+
+ if (config.containerElements === undefined) {
+ if (config.showExit !== undefined)
+ config.showExit(publicAPI.crashed, publicAPI.exitCode);
+ return;
+ }
+
+ if (!publicAPI.crashed)
+ return;
+
+ for (container of config.containerElements) {
+ var loaderElement = config.showExit(publicAPI.crashed, publicAPI.exitCode, container);
+ if (loaderElement !== undefined)
+ container.appendChild(loaderElement);
+ }
+ }
+
+ var committedStatus = undefined;
+ function handleStatusChange() {
+ if (publicAPI.status != "Loading" && committedStatus == publicAPI.status)
+ return;
+ committedStatus = publicAPI.status;
+
+ if (publicAPI.status == "Error") {
+ setErrorContent();
+ } else if (publicAPI.status == "Loading") {
+ setLoaderContent();
+ } else if (publicAPI.status == "Running") {
+ setCanvasContent();
+ } else if (publicAPI.status == "Exited") {
+ if (config.restartMode == "RestartOnExit" ||
+ config.restartMode == "RestartOnCrash" && publicAPI.crashed) {
+ committedStatus = undefined;
+ config.restart();
+ } else {
+ setExitContent();
+ }
+ }
+
+ // Send status change notification
+ if (config.statusChanged)
+ config.statusChanged(publicAPI.status);
+ }
+
+ function setStatus(status) {
+ if (status != "Loading" && publicAPI.status == status)
+ return;
+ publicAPI.status = status;
+
+ window.setTimeout(function() { handleStatusChange(); }, 0);
+ }
+
+ setStatus("Created");
+
+ return publicAPI;
+}
diff --git a/src/plugins/platforms/wasm/qtlogo.svg b/src/plugins/platforms/wasm/qtlogo.svg
new file mode 100644
index 0000000000..cb8989bb79
--- /dev/null
+++ b/src/plugins/platforms/wasm/qtlogo.svg
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="462pt"
+ height="339pt"
+ viewBox="0 0 462 339"
+ version="1.1"
+ id="svg2"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="TheQtCompany_logo_2.svg">
+ <metadata
+ id="metadata20">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs18" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1536"
+ inkscape:window-height="801"
+ id="namedview16"
+ showgrid="false"
+ inkscape:zoom="1.1138643"
+ inkscape:cx="270.58047"
+ inkscape:cy="174.65092"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ fill="#41cd52"
+ d=" M 63.50 0.00 L 462.00 0.00 L 462.00 274.79 C 440.60 296.26 419.13 317.66 397.61 339.00 L 0.00 339.00 L 0.00 63.39 C 21.08 42.18 42.34 21.13 63.50 0.00 Z"
+ id="path6" />
+ <path
+ d=" M 122.37 71.33 C 137.50 61.32 156.21 58.79 174.00 58.95 C 190.94 59.16 208.72 62.13 222.76 72.24 C 232.96 79.41 239.59 90.48 244.01 101.93 C 251.16 120.73 253.26 141.03 253.50 161.01 C 253.53 181.13 252.62 201.69 245.96 220.86 C 241.50 233.90 233.01 245.48 221.81 253.52 C 229.87 266.58 238.09 279.54 246.15 292.60 C 236.02 297.27 225.92 301.97 215.78 306.62 C 207.15 292.38 198.56 278.11 189.90 263.89 C 178.19 265.81 166.21 265.66 154.44 264.36 C 140.34 262.67 125.97 258.37 115.09 248.88 C 106.73 241.64 101.48 231.51 97.89 221.21 C 92.01 203.79 90.43 185.25 90.16 166.97 C 90.02 147.21 91.28 127.14 97.24 108.18 C 101.85 93.92 109.48 79.69 122.37 71.33 Z"
+ id="path8"
+ fill="#ffffff" />
+ <path
+ d=" M 294.13 70.69 C 304.73 70.68 315.33 70.68 325.93 70.69 C 325.96 84.71 325.92 98.72 325.95 112.74 C 339.50 112.76 353.05 112.74 366.60 112.75 C 366.37 121.85 366.12 130.95 365.86 140.05 C 352.32 140.08 338.79 140.04 325.25 140.07 C 325.28 163.05 325.18 186.03 325.30 209.01 C 325.56 215.30 325.42 221.94 328.19 227.75 C 330.21 232.23 335.65 233.38 340.08 233.53 C 348.43 233.50 356.77 233.01 365.12 232.86 C 365.63 241.22 366.12 249.59 366.60 257.95 C 349.99 260.74 332.56 264.08 316.06 258.86 C 309.11 256.80 302.63 252.19 299.81 245.32 C 294.76 233.63 294.35 220.62 294.13 208.07 C 294.11 185.40 294.13 162.74 294.12 140.07 C 286.73 140.05 279.34 140.08 271.95 140.05 C 271.93 130.96 271.93 121.86 271.95 112.76 C 279.34 112.73 286.72 112.77 294.11 112.74 C 294.14 98.72 294.10 84.71 294.13 70.69 Z"
+ id="path10"
+ fill="#ffffff" />
+ <path
+ fill="#41cd52"
+ d=" M 160.51 87.70 C 170.80 86.36 181.60 86.72 191.34 90.61 C 199.23 93.73 205.93 99.84 209.47 107.58 C 214.90 119.31 216.98 132.26 218.03 145.05 C 219.17 162.07 219.01 179.25 216.66 196.17 C 215.01 206.24 212.66 216.85 205.84 224.79 C 198.92 232.76 188.25 236.18 178.01 236.98 C 167.21 237.77 155.82 236.98 146.07 231.87 C 140.38 228.84 135.55 224.09 132.73 218.27 C 129.31 211.30 127.43 203.69 126.11 196.07 C 122.13 171.91 121.17 146.91 126.61 122.89 C 128.85 113.83 132.11 104.53 138.73 97.70 C 144.49 91.85 152.51 88.83 160.51 87.70 Z"
+ id="path12" />
+</svg>
diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.cpp b/src/plugins/platforms/wasm/qwasmbackingstore.cpp
new file mode 100644
index 0000000000..5b40c44807
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmbackingstore.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmbackingstore.h"
+#include "qwasmwindow.h"
+#include "qwasmcompositor.h"
+
+#include <QtGui/qopengltexture.h>
+#include <QtGui/qmatrix4x4.h>
+#include <QtGui/qpainter.h>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformscreen.h>
+
+#include <QtGui/qbackingstore.h>
+
+QT_BEGIN_NAMESPACE
+
+QWasmBackingStore::QWasmBackingStore(QWasmCompositor *compositor, QWindow *window)
+ : QPlatformBackingStore(window)
+ , m_compositor(compositor)
+ , m_texture(new QOpenGLTexture(QOpenGLTexture::Target2D))
+{
+ QWasmWindow *wasmWindow = static_cast<QWasmWindow *>(window->handle());
+ if (wasmWindow)
+ wasmWindow->setBackingStore(this);
+}
+
+QWasmBackingStore::~QWasmBackingStore()
+{
+}
+
+QPaintDevice *QWasmBackingStore::paintDevice()
+{
+ return &m_image;
+}
+
+void QWasmBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+
+ m_dirty |= region;
+ m_compositor->requestRedraw();
+}
+
+void QWasmBackingStore::updateTexture()
+{
+ if (m_dirty.isNull())
+ return;
+
+ if (!m_texture->isCreated()) {
+ m_texture->setMinificationFilter(QOpenGLTexture::Nearest);
+ m_texture->setMagnificationFilter(QOpenGLTexture::Nearest);
+ m_texture->setWrapMode(QOpenGLTexture::ClampToEdge);
+ m_texture->setData(m_image, QOpenGLTexture::DontGenerateMipMaps);
+ m_texture->create();
+ }
+ m_texture->bind();
+
+ QRegion fixed;
+ QRect imageRect = m_image.rect();
+
+ for (const QRect &rect : m_dirty) {
+
+ // Convert device-independent dirty region to device region
+ qreal dpr = m_image.devicePixelRatio();
+ QRect deviceRect = QRect(rect.topLeft() * dpr, rect.size() * dpr);
+
+ // intersect with image rect to be sure
+ QRect r = imageRect & deviceRect;
+ // if the rect is wide enough it is cheaper to just extend it instead of doing an image copy
+ if (r.width() >= imageRect.width() / 2) {
+ r.setX(0);
+ r.setWidth(imageRect.width());
+ }
+
+ fixed |= r;
+ }
+
+ for (const QRect &rect : fixed) {
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there is no gap between scanlines
+ if (rect.width() == imageRect.width()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.constScanLine(rect.y()));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.copy(rect).constBits());
+ }
+ }
+ /* End of code taken from QEGLPlatformBackingStore */
+
+ m_dirty = QRegion();
+}
+
+void QWasmBackingStore::beginPaint(const QRegion &region)
+{
+ m_dirty |= region;
+ // Keep backing store device pixel ratio in sync with window
+ if (m_image.devicePixelRatio() != window()->devicePixelRatio())
+ resize(backingStore()->size(), backingStore()->staticContents());
+
+ QPainter painter(&m_image);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ const QColor blank = Qt::transparent;
+ for (const QRect &rect : region)
+ painter.fillRect(rect, blank);
+}
+
+void QWasmBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents)
+
+ m_image = QImage(size * window()->devicePixelRatio(), QImage::Format_RGB32);
+ m_image.setDevicePixelRatio(window()->devicePixelRatio());
+
+ if (m_texture->isCreated())
+ m_texture->destroy();
+}
+
+QImage QWasmBackingStore::toImage() const
+{
+ // used by QPlatformBackingStore::composeAndFlush
+ return m_image;
+}
+
+const QImage &QWasmBackingStore::getImageRef() const
+{
+ return m_image;
+}
+
+const QOpenGLTexture *QWasmBackingStore::getUpdatedTexture()
+{
+ updateTexture();
+ return m_texture.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.h b/src/plugins/platforms/wasm/qwasmbackingstore.h
new file mode 100644
index 0000000000..6ffa262e3d
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmbackingstore.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMBACKINGSTORE_H
+#define QWASMBACKINGSTORE_H
+
+#include <qpa/qplatformbackingstore.h>
+#include <QtGui/qimage.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLTexture;
+class QRegion;
+class QWasmCompositor;
+
+class QWasmBackingStore : public QPlatformBackingStore
+{
+public:
+ QWasmBackingStore(QWasmCompositor *compositor, QWindow *window);
+ ~QWasmBackingStore();
+
+ QPaintDevice *paintDevice() override;
+
+ void beginPaint(const QRegion &) override;
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) override;
+ void resize(const QSize &size, const QRegion &staticContents) override;
+ QImage toImage() const override;
+ const QImage &getImageRef() const;
+
+ const QOpenGLTexture *getUpdatedTexture();
+
+protected:
+ void updateTexture();
+
+private:
+ QWasmCompositor *m_compositor;
+ QImage m_image;
+ QScopedPointer<QOpenGLTexture> m_texture;
+ QRegion m_dirty;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWASMBACKINGSTORE_H
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp
new file mode 100644
index 0000000000..f3ea013325
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp
@@ -0,0 +1,721 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmcompositor.h"
+#include "qwasmwindow.h"
+#include "qwasmstylepixmaps_p.h"
+
+#include <QtGui/qopengltexture.h>
+
+#include <QtGui/private/qwindow_p.h>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglfunctions.h>
+#include <QtGui/qopengltextureblitter.h>
+#include <QtGui/qpainter.h>
+#include <private/qpixmapcache_p.h>
+
+#include <private/qguiapplication_p.h>
+
+#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtGui/qguiapplication.h>
+
+Q_GUI_EXPORT int qt_defaultDpiX();
+
+QWasmCompositedWindow::QWasmCompositedWindow()
+ : window(nullptr)
+ , parentWindow(nullptr)
+ , flushPending(false)
+ , visible(false)
+{
+}
+
+QWasmCompositor::QWasmCompositor()
+ : m_frameBuffer(nullptr)
+ , m_blitter(new QOpenGLTextureBlitter)
+ , m_needComposit(false)
+ , m_inFlush(false)
+ , m_inResize(false)
+ , m_isEnabled(true)
+ , m_targetDevicePixelRatio(1)
+{
+}
+
+QWasmCompositor::~QWasmCompositor()
+{
+ delete m_frameBuffer;
+}
+
+void QWasmCompositor::setEnabled(bool enabled)
+{
+ m_isEnabled = enabled;
+}
+
+void QWasmCompositor::addWindow(QWasmWindow *window, QWasmWindow *parentWindow)
+{
+ QWasmCompositedWindow compositedWindow;
+ compositedWindow.window = window;
+ compositedWindow.parentWindow = parentWindow;
+ m_compositedWindows.insert(window, compositedWindow);
+
+ if (parentWindow == 0)
+ m_windowStack.append(window);
+ else
+ m_compositedWindows[parentWindow].childWindows.append(window);
+
+ notifyTopWindowChanged(window);
+}
+
+void QWasmCompositor::removeWindow(QWasmWindow *window)
+{
+ QWasmWindow *platformWindow = m_compositedWindows[window].parentWindow;
+
+ if (platformWindow) {
+ QWasmWindow *parentWindow = window;
+ m_compositedWindows[parentWindow].childWindows.removeAll(window);
+ }
+
+ m_windowStack.removeAll(window);
+ m_compositedWindows.remove(window);
+
+ notifyTopWindowChanged(window);
+}
+
+void QWasmCompositor::setScreen(QWasmScreen *screen)
+{
+ m_screen = screen;
+}
+
+void QWasmCompositor::setVisible(QWasmWindow *window, bool visible)
+{
+ QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
+ if (compositedWindow.visible == visible)
+ return;
+
+ compositedWindow.visible = visible;
+ compositedWindow.flushPending = true;
+ if (visible)
+ compositedWindow.damage = compositedWindow.window->geometry();
+ else
+ m_globalDamage = compositedWindow.window->geometry(); // repaint previosly covered area.
+
+ requestRedraw();
+}
+
+void QWasmCompositor::raise(QWasmWindow *window)
+{
+ if (m_compositedWindows.size() <= 1)
+ return;
+
+ QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
+ compositedWindow.damage = compositedWindow.window->geometry();
+ m_windowStack.removeAll(window);
+ m_windowStack.append(window);
+
+ notifyTopWindowChanged(window);
+}
+
+void QWasmCompositor::lower(QWasmWindow *window)
+{
+ if (m_compositedWindows.size() <= 1)
+ return;
+
+ m_windowStack.removeAll(window);
+ m_windowStack.prepend(window);
+ QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
+ m_globalDamage = compositedWindow.window->geometry(); // repaint previosly covered area.
+
+ notifyTopWindowChanged(window);
+}
+
+void QWasmCompositor::setParent(QWasmWindow *window, QWasmWindow *parent)
+{
+ m_compositedWindows[window].parentWindow = parent;
+
+ requestRedraw();
+}
+
+void QWasmCompositor::flush(QWasmWindow *window, const QRegion &region)
+{
+ QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
+ compositedWindow.flushPending = true;
+ compositedWindow.damage = region;
+
+ requestRedraw();
+}
+
+int QWasmCompositor::windowCount() const
+{
+ return m_windowStack.count();
+}
+
+
+void QWasmCompositor::redrawWindowContent()
+{
+ // Redraw window content by sending expose events. This redraw
+ // will cause a backing store flush, which will call requestRedraw()
+ // to composit.
+ for (QWasmWindow *platformWindow : m_windowStack) {
+ QWindow *window = platformWindow->window();
+ QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(
+ window, QRect(QPoint(0, 0), window->geometry().size()));
+ }
+}
+
+void QWasmCompositor::requestRedraw()
+{
+ if (m_needComposit)
+ return;
+
+ m_needComposit = true;
+ QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
+}
+
+QWindow *QWasmCompositor::windowAt(QPoint p, int padding) const
+{
+ int index = m_windowStack.count() - 1;
+ // qDebug() << "window at" << "point" << p << "window count" << index;
+
+ while (index >= 0) {
+ const QWasmCompositedWindow &compositedWindow = m_compositedWindows[m_windowStack.at(index)];
+ //qDebug() << "windwAt testing" << compositedWindow.window <<
+
+ QRect geometry = compositedWindow.window->windowFrameGeometry()
+ .adjusted(-padding, -padding, padding, padding);
+
+ if (compositedWindow.visible && geometry.contains(p))
+ return m_windowStack.at(index)->window();
+ --index;
+ }
+
+ return 0;
+}
+
+QWindow *QWasmCompositor::keyWindow() const
+{
+ return m_windowStack.at(m_windowStack.count() - 1)->window();
+}
+
+bool QWasmCompositor::event(QEvent *ev)
+{
+ if (ev->type() == QEvent::UpdateRequest) {
+ if (m_isEnabled)
+ frame();
+ return true;
+ }
+
+ return QObject::event(ev);
+}
+
+void QWasmCompositor::blit(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QOpenGLTexture *texture, QRect targetGeometry)
+{
+ QMatrix4x4 m;
+ m.translate(-1.0f, -1.0f);
+
+ m.scale(2.0f / (float)screen->geometry().width(),
+ 2.0f / (float)screen->geometry().height());
+
+ m.translate((float)targetGeometry.width() / 2.0f,
+ (float)-targetGeometry.height() / 2.0f);
+
+ m.translate(targetGeometry.x(), screen->geometry().height() - targetGeometry.y());
+
+ m.scale(0.5f * (float)targetGeometry.width(),
+ 0.5f * (float)targetGeometry.height());
+
+ blitter->blit(texture->textureId(), m, QOpenGLTextureBlitter::OriginTopLeft);
+}
+
+void QWasmCompositor::drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window)
+{
+ QWasmBackingStore *backingStore = window->backingStore();
+
+ QOpenGLTexture const *texture = backingStore->getUpdatedTexture();
+
+ blit(blitter, screen, texture, window->geometry());
+}
+
+QPalette QWasmCompositor::makeWindowPalette()
+{
+ QPalette palette;
+ palette.setColor(QPalette::Active, QPalette::Highlight,
+ palette.color(QPalette::Active, QPalette::Highlight));
+ palette.setColor(QPalette::Active, QPalette::Base,
+ palette.color(QPalette::Active, QPalette::Highlight));
+ palette.setColor(QPalette::Inactive, QPalette::Highlight,
+ palette.color(QPalette::Inactive, QPalette::Dark));
+ palette.setColor(QPalette::Inactive, QPalette::Base,
+ palette.color(QPalette::Inactive, QPalette::Dark));
+ palette.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ palette.color(QPalette::Inactive, QPalette::Window));
+
+ return palette;
+}
+
+QRect QWasmCompositor::titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol)
+{
+ QRect ret;
+ const int controlMargin = 2;
+ const int controlHeight = tb.rect.height() - controlMargin *2;
+ const int delta = controlHeight + controlMargin;
+ int offset = 0;
+
+ bool isMinimized = tb.state & Qt::WindowMinimized;
+ bool isMaximized = tb.state & Qt::WindowMaximized;
+
+ ret = tb.rect;
+ switch (subcontrol) {
+ case SC_TitleBarLabel:
+ if (tb.flags & Qt::WindowSystemMenuHint)
+ ret.adjust(delta, 0, -delta, 0);
+ break;
+ case SC_TitleBarCloseButton:
+ if (tb.flags & Qt::WindowSystemMenuHint) {
+ ret.adjust(0, 0, -delta, 0);
+ offset += delta;
+ }
+ break;
+ case SC_TitleBarMaxButton:
+ if (!isMaximized && tb.flags & Qt::WindowMaximizeButtonHint) {
+ ret.adjust(0, 0, -delta*2, 0);
+ offset += (delta +delta);
+ }
+ break;
+ case SC_TitleBarNormalButton:
+ if (isMinimized && (tb.flags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (isMaximized && (tb.flags & Qt::WindowMaximizeButtonHint))
+ ret.adjust(0, 0, -delta*2, 0);
+ offset += (delta +delta);
+ break;
+ case SC_TitleBarSysMenu:
+ if (tb.flags & Qt::WindowSystemMenuHint) {
+ ret.setRect(tb.rect.left() + controlMargin, tb.rect.top() + controlMargin,
+ controlHeight, controlHeight);
+ }
+ break;
+ default:
+ break;
+ };
+
+ if (subcontrol != SC_TitleBarLabel && subcontrol != SC_TitleBarSysMenu) {
+ ret.setRect(tb.rect.right() - offset, tb.rect.top() + controlMargin,
+ controlHeight, controlHeight);
+ }
+
+ if (qApp->layoutDirection() == Qt::LeftToRight)
+ return ret;
+
+ QRect rect = ret;
+ rect.translate(2 * (tb.rect.right() - ret.right()) +
+ ret.width() - tb.rect.width(), 0);
+
+ return rect;
+}
+
+int dpiScaled(qreal value)
+{
+ return value * (qreal(qt_defaultDpiX()) / 96.0);
+}
+
+QWasmCompositor::QWasmTitleBarOptions QWasmCompositor::makeTitleBarOptions(const QWasmWindow *window)
+{
+ int width = window->windowFrameGeometry().width();
+ int border = window->borderWidth();
+
+ QWasmTitleBarOptions titleBarOptions;
+
+ titleBarOptions.rect = QRect(border, border, width - 2 * border, window->titleHeight());
+ titleBarOptions.flags = window->window()->flags();
+ titleBarOptions.state = window->window()->windowState();
+
+ bool isMaximized = titleBarOptions.state & Qt::WindowMaximized; // this gets reset when maximized
+
+ if (titleBarOptions.flags & (Qt::WindowTitleHint))
+ titleBarOptions.subControls |= SC_TitleBarLabel;
+ if (titleBarOptions.flags & Qt::WindowMaximizeButtonHint) {
+ if (isMaximized)
+ titleBarOptions.subControls |= SC_TitleBarNormalButton;
+ else
+ titleBarOptions.subControls |= SC_TitleBarMaxButton;
+ }
+ if (titleBarOptions.flags & Qt::WindowSystemMenuHint) {
+ titleBarOptions.subControls |= SC_TitleBarCloseButton;
+ titleBarOptions.subControls |= SC_TitleBarSysMenu;
+ }
+
+
+ titleBarOptions.palette = QWasmCompositor::makeWindowPalette();
+
+ if (window->window()->isActive())
+ titleBarOptions.palette.setCurrentColorGroup(QPalette::Active);
+ else
+ titleBarOptions.palette.setCurrentColorGroup(QPalette::Inactive);
+
+ if (window->activeSubControl() != QWasmCompositor::SC_None)
+ titleBarOptions.subControls = window->activeSubControl();
+
+ if (!window->window()->title().isEmpty())
+ titleBarOptions.titleBarOptionsString = window->window()->title();
+
+ return titleBarOptions;
+}
+
+void QWasmCompositor::drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window)
+{
+ int width = window->windowFrameGeometry().width();
+ int height = window->windowFrameGeometry().height();
+ qreal dpr = window->devicePixelRatio();
+
+ QImage image(QSize(width * dpr, height * dpr), QImage::Format_RGB32);
+ image.setDevicePixelRatio(dpr);
+ QPainter painter(&image);
+ painter.fillRect(QRect(0, 0, width, height), painter.background());
+
+ QWasmTitleBarOptions titleBarOptions = makeTitleBarOptions(window);
+
+ drawTitlebarWindow(titleBarOptions, &painter);
+
+ QWasmFrameOptions frameOptions;
+ frameOptions.rect = QRect(0, 0, width, height);
+ frameOptions.lineWidth = dpiScaled(4.);
+
+ drawFrameWindow(frameOptions, &painter);
+
+ painter.end();
+
+ QOpenGLTexture texture(QOpenGLTexture::Target2D);
+ texture.setMinificationFilter(QOpenGLTexture::Nearest);
+ texture.setMagnificationFilter(QOpenGLTexture::Nearest);
+ texture.setWrapMode(QOpenGLTexture::ClampToEdge);
+ texture.setData(image, QOpenGLTexture::DontGenerateMipMaps);
+ texture.create();
+ texture.bind();
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width(), image.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ image.constScanLine(0));
+
+ blit(blitter, screen, &texture, QRect(window->windowFrameGeometry().topLeft(), QSize(width, height)));
+}
+
+void QWasmCompositor::drawFrameWindow(QWasmFrameOptions options, QPainter *painter)
+{
+ int x = options.rect.x();
+ int y = options.rect.y();
+ int w = options.rect.width();
+ int h = options.rect.height();
+ const QColor &c1 = options.palette.light().color();
+ const QColor &c2 = options.palette.shadow().color();
+ const QColor &c3 = options.palette.midlight().color();
+ const QColor &c4 = options.palette.dark().color();
+ const QBrush *fill = 0;
+
+ const qreal devicePixelRatio = painter->device()->devicePixelRatioF();
+ if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
+ const qreal inverseScale = qreal(1) / devicePixelRatio;
+ painter->scale(inverseScale, inverseScale);
+ x = qRound(devicePixelRatio * x);
+ y = qRound(devicePixelRatio * y);
+ w = qRound(devicePixelRatio * w);
+ h = qRound(devicePixelRatio * h);
+ }
+
+ QPen oldPen = painter->pen();
+ QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
+ painter->setPen(c1);
+ painter->drawPolyline(a, 3);
+ QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
+ painter->setPen(c2);
+ painter->drawPolyline(b, 3);
+ if (w > 4 && h > 4) {
+ QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
+ painter->setPen(c3);
+ painter->drawPolyline(c, 3);
+ QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
+ painter->setPen(c4);
+ painter->drawPolyline(d, 3);
+ if (fill)
+ painter->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
+ }
+ painter->setPen(oldPen);
+}
+
+//from commonstyle.cpp
+static QPixmap cachedPixmapFromXPM(const char * const *xpm)
+{
+ QPixmap result;
+ const QString tag = QString::asprintf("xpm:0x%p", static_cast<const void*>(xpm));
+ if (!QPixmapCache::find(tag, &result)) {
+ result = QPixmap(xpm);
+ QPixmapCache::insert(tag, result);
+ }
+ return result;
+}
+
+void QWasmCompositor::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
+ const QPixmap &pixmap) const
+{
+ qreal scale = pixmap.devicePixelRatio();
+ QSize size = pixmap.size() / scale;
+ int x = rect.x();
+ int y = rect.y();
+ int w = size.width();
+ int h = size.height();
+ if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
+ y += rect.size().height()/2 - h/2;
+ else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
+ y += rect.size().height() - h;
+ if ((alignment & Qt::AlignRight) == Qt::AlignRight)
+ x += rect.size().width() - w;
+ else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
+ x += rect.size().width()/2 - w/2;
+
+ QRect aligned = QRect(x, y, w, h);
+ QRect inter = aligned.intersected(rect);
+
+ painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width() * scale, inter.height() *scale);
+}
+
+
+void QWasmCompositor::drawTitlebarWindow(QWasmTitleBarOptions tb, QPainter *painter)
+{
+ QRect ir;
+ if (tb.subControls.testFlag(SC_TitleBarLabel)) {
+ QColor left = tb.palette.highlight().color();
+ QColor right = tb.palette.base().color();
+
+ QBrush fillBrush(left);
+ if (left != right) {
+ QPoint p1(tb.rect.x(), tb.rect.top() + tb.rect.height()/2);
+ QPoint p2(tb.rect.right(), tb.rect.top() + tb.rect.height()/2);
+ QLinearGradient lg(p1, p2);
+ lg.setColorAt(0, left);
+ lg.setColorAt(1, right);
+ fillBrush = lg;
+ }
+
+ painter->fillRect(tb.rect, fillBrush);
+ ir = titlebarRect(tb, SC_TitleBarLabel);
+ painter->setPen(tb.palette.highlightedText().color());
+ painter->drawText(ir.x() + 2, ir.y(), ir.width() - 2, ir.height(),
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb.titleBarOptionsString);
+ } // SC_TitleBarLabel
+
+ bool down = false;
+ QPixmap pixmap;
+
+ if (tb.subControls.testFlag(SC_TitleBarCloseButton)
+ && tb.flags & Qt::WindowSystemMenuHint) {
+ ir = titlebarRect(tb, SC_TitleBarCloseButton);
+ down = tb.subControls & SC_TitleBarCloseButton && (tb.state & State_Sunken);
+ pixmap = cachedPixmapFromXPM(qt_close_xpm).scaled(QSize(10, 10));
+ drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap);
+ } //SC_TitleBarCloseButton
+
+ if (tb.subControls.testFlag(SC_TitleBarMaxButton)
+ && tb.flags & Qt::WindowMaximizeButtonHint
+ && !(tb.state & Qt::WindowMaximized)) {
+ ir = titlebarRect(tb, SC_TitleBarMaxButton);
+ down = tb.subControls & SC_TitleBarMaxButton && (tb.state & State_Sunken);
+ pixmap = cachedPixmapFromXPM(qt_maximize_xpm).scaled(QSize(10, 10));
+ drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap);
+ } //SC_TitleBarMaxButton
+
+ bool drawNormalButton = (tb.subControls & SC_TitleBarNormalButton)
+ && (((tb.flags & Qt::WindowMinimizeButtonHint)
+ && (tb.flags & Qt::WindowMinimized))
+ || ((tb.flags & Qt::WindowMaximizeButtonHint)
+ && (tb.flags & Qt::WindowMaximized)));
+
+ if (drawNormalButton) {
+ ir = titlebarRect(tb, SC_TitleBarNormalButton);
+ down = tb.subControls & SC_TitleBarNormalButton && (tb.state & State_Sunken);
+ pixmap = cachedPixmapFromXPM(qt_normalizeup_xpm).scaled( QSize(10, 10));
+
+ drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap);
+ } // SC_TitleBarNormalButton
+
+ if (tb.subControls & SC_TitleBarSysMenu && tb.flags & Qt::WindowSystemMenuHint) {
+ ir = titlebarRect(tb, SC_TitleBarSysMenu);
+ pixmap = cachedPixmapFromXPM(qt_menu_xpm).scaled(QSize(10, 10));
+ drawItemPixmap(painter, ir, Qt::AlignCenter, pixmap);
+ }
+}
+
+void QWasmCompositor::drawShadePanel(QWasmTitleBarOptions options, QPainter *painter)
+{
+ int lineWidth = 1;
+ QPalette palette = options.palette;
+ const QBrush *fill = &options.palette.brush(QPalette::Button);
+
+ int x = options.rect.x();
+ int y = options.rect.y();
+ int w = options.rect.width();
+ int h = options.rect.height();
+
+ const qreal devicePixelRatio = painter->device()->devicePixelRatioF();
+ if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
+ const qreal inverseScale = qreal(1) / devicePixelRatio;
+ painter->scale(inverseScale, inverseScale);
+
+ x = qRound(devicePixelRatio * x);
+ y = qRound(devicePixelRatio * y);
+ w = qRound(devicePixelRatio * w);
+ h = qRound(devicePixelRatio * h);
+ lineWidth = qRound(devicePixelRatio * lineWidth);
+ }
+
+ QColor shade = palette.dark().color();
+ QColor light = palette.light().color();
+
+ if (fill) {
+ if (fill->color() == shade)
+ shade = palette.shadow().color();
+ if (fill->color() == light)
+ light = palette.midlight().color();
+ }
+ QPen oldPen = painter->pen();
+ QVector<QLineF> lines;
+ lines.reserve(2*lineWidth);
+
+ painter->setPen(light);
+ int x1, y1, x2, y2;
+ int i;
+ x1 = x;
+ y1 = y2 = y;
+ x2 = x + w - 2;
+ for (i = 0; i < lineWidth; i++) // top shadow
+ lines << QLineF(x1, y1++, x2--, y2++);
+
+ x2 = x1;
+ y1 = y + h - 2;
+ for (i = 0; i < lineWidth; i++) // left shado
+ lines << QLineF(x1++, y1, x2++, y2--);
+
+ painter->drawLines(lines);
+ lines.clear();
+ painter->setPen(shade);
+ x1 = x;
+ y1 = y2 = y+h-1;
+ x2 = x+w-1;
+ for (i=0; i<lineWidth; i++) { // bottom shadow
+ lines << QLineF(x1++, y1--, x2, y2--);
+ }
+ x1 = x2;
+ y1 = y;
+ y2 = y + h - lineWidth - 1;
+ for (i = 0; i < lineWidth; i++) // right shadow
+ lines << QLineF(x1--, y1++, x2--, y2);
+
+ painter->drawLines(lines);
+ if (fill) // fill with fill color
+ painter->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill);
+ painter->setPen(oldPen); // restore pen
+
+}
+
+void QWasmCompositor::drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window)
+{
+ if (window->window()->type() != Qt::Popup)
+ drawWindowDecorations(blitter, screen, window);
+ drawWindowContent(blitter, screen, window);
+}
+
+void QWasmCompositor::frame()
+{
+ if (!m_needComposit)
+ return;
+
+ m_needComposit = false;
+
+ if (m_windowStack.empty() || !m_screen)
+ return;
+
+ QWasmWindow *someWindow = nullptr;
+
+ foreach (QWasmWindow *window, m_windowStack) {
+ if (window->window()->surfaceClass() == QSurface::Window
+ && qt_window_private(static_cast<QWindow *>(window->window()))->receivedExpose) {
+ someWindow = window;
+ break;
+ }
+ }
+
+ if (!someWindow)
+ return;
+
+ if (m_context.isNull()) {
+ m_context.reset(new QOpenGLContext());
+ //mContext->setFormat(mScreen->format());
+ m_context->setScreen(m_screen->screen());
+ m_context->create();
+ }
+
+ m_context->makeCurrent(someWindow->window());
+
+ if (!m_blitter->isCreated())
+ m_blitter->create();
+
+ qreal dpr = m_screen->devicePixelRatio();
+ glViewport(0, 0, m_screen->geometry().width() * dpr, m_screen->geometry().height() * dpr);
+
+ m_context->functions()->glClearColor(0.2, 0.2, 0.2, 1.0);
+ m_context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ m_blitter->bind();
+ m_blitter->setRedBlueSwizzle(true);
+
+ foreach (QWasmWindow *window, m_windowStack) {
+ QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
+
+ if (!compositedWindow.visible)
+ continue;
+
+ drawWindow(m_blitter.data(), m_screen, window);
+ }
+
+ m_blitter->release();
+
+ if (someWindow && someWindow->window()->surfaceType() == QSurface::OpenGLSurface)
+ m_context->swapBuffers(someWindow->window());
+}
+
+void QWasmCompositor::notifyTopWindowChanged(QWasmWindow *window)
+{
+ QWindow *modalWindow;
+ bool blocked = QGuiApplicationPrivate::instance()->isWindowBlocked(window->window(), &modalWindow);
+
+ if (blocked) {
+ raise(static_cast<QWasmWindow*>(modalWindow->handle()));
+ return;
+ }
+
+ requestRedraw();
+ QWindowSystemInterface::handleWindowActivated(window->window());
+}
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h
new file mode 100644
index 0000000000..4e5ed46cec
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmcompositor.h
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMCOMPOSITOR_H
+#define QWASMCOMPOSITOR_H
+
+#include <QtGui/qregion.h>
+#include <qpa/qplatformwindow.h>
+
+#include <QtGui/qopengltextureblitter.h>
+#include <QtGui/qopengltexture.h>
+#include <QtGui/qpalette.h>
+#include <QtGui/qpainter.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWasmWindow;
+class QWasmScreen;
+class QOpenGLContext;
+class QOpenGLTextureBlitter;
+
+class QWasmCompositedWindow
+{
+public:
+ QWasmCompositedWindow();
+
+ QWasmWindow *window;
+ QWasmWindow *parentWindow;
+ QRegion damage;
+ bool flushPending;
+ bool visible;
+ QList<QWasmWindow *> childWindows;
+};
+
+class QWasmCompositor : public QObject
+{
+ Q_OBJECT
+public:
+ QWasmCompositor();
+ ~QWasmCompositor();
+
+ enum QWasmSubControl {
+ SC_None = 0x00000000,
+ SC_TitleBarSysMenu = 0x00000001,
+ SC_TitleBarMinButton = 0x00000002,
+ SC_TitleBarMaxButton = 0x00000004,
+ SC_TitleBarCloseButton = 0x00000008,
+ SC_TitleBarNormalButton = 0x00000010,
+ SC_TitleBarLabel = 0x00000100
+ };
+ Q_DECLARE_FLAGS(SubControls, QWasmSubControl)
+
+ enum QWasmStateFlag {
+ State_None = 0x00000000,
+ State_Enabled = 0x00000001,
+ State_Raised = 0x00000002,
+ State_Sunken = 0x00000004
+ };
+ Q_DECLARE_FLAGS(StateFlags, QWasmStateFlag)
+
+ struct QWasmTitleBarOptions {
+ QRect rect;
+ Qt::WindowFlags flags;
+ int state;
+ QPalette palette;
+ QString titleBarOptionsString;
+ QWasmCompositor::SubControls subControls;
+ };
+
+ struct QWasmFrameOptions {
+ QRect rect;
+ int lineWidth;
+ QPalette palette;
+ };
+
+ void setEnabled(bool enabled);
+
+ void addWindow(QWasmWindow *window, QWasmWindow *parentWindow = nullptr);
+ void removeWindow(QWasmWindow *window);
+ void setScreen(QWasmScreen *screen);
+
+ void setVisible(QWasmWindow *window, bool visible);
+ void raise(QWasmWindow *window);
+ void lower(QWasmWindow *window);
+ void setParent(QWasmWindow *window, QWasmWindow *parent);
+
+ void flush(QWasmWindow *surface, const QRegion &region);
+
+ int windowCount() const;
+
+ void redrawWindowContent();
+ void requestRedraw();
+
+ QWindow *windowAt(QPoint p, int padding = 0) const;
+ QWindow *keyWindow() const;
+
+ bool event(QEvent *event);
+
+ static QWasmTitleBarOptions makeTitleBarOptions(const QWasmWindow *window);
+ static QRect titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol);
+
+private slots:
+ void frame();
+
+private:
+ void createFrameBuffer();
+ void flushCompletedCallback(int32_t);
+ void notifyTopWindowChanged(QWasmWindow *window);
+ void drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
+ void drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
+ void blit(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QOpenGLTexture *texture, QRect targetGeometry);
+
+ void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
+ void drwPanelButton();
+
+ QImage *m_frameBuffer;
+ QScopedPointer<QOpenGLContext> m_context;
+ QScopedPointer<QOpenGLTextureBlitter> m_blitter;
+ QWasmScreen *m_screen;
+
+ QHash<QWasmWindow *, QWasmCompositedWindow> m_compositedWindows;
+ QList<QWasmWindow *> m_windowStack;
+ QRegion m_globalDamage; // damage caused by expose, window close, etc.
+ bool m_needComposit;
+ bool m_inFlush;
+ bool m_inResize;
+ bool m_isEnabled;
+ QSize m_targetSize;
+ qreal m_targetDevicePixelRatio;
+
+ static QPalette makeWindowPalette();
+
+ void drawFrameWindow(QWasmFrameOptions options, QPainter *painter);
+ void drawTitlebarWindow(QWasmTitleBarOptions options, QPainter *painter);
+ void drawShadePanel(QWasmTitleBarOptions options, QPainter *painter);
+ void drawItemPixmap(QPainter *painter, const QRect &rect,
+ int alignment, const QPixmap &pixmap) const;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWasmCompositor::SubControls)
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wasm/qwasmcursor.cpp b/src/plugins/platforms/wasm/qwasmcursor.cpp
new file mode 100644
index 0000000000..54804a55b3
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmcursor.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmcursor.h"
+
+#include <QtCore/qdebug.h>
+
+#include <emscripten/emscripten.h>
+
+void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
+{
+ if (windowCursor == nullptr)
+ return;
+
+ // FIXME: The HTML5 plugin sets the cursor on the native canvas; when using multiple windows
+ // multiple cursors need to be managed taking mouse postion and stacking into account.
+ Q_UNUSED(window);
+
+ // Bitmap and custom cursors are not implemented (will fall back to "auto")
+ if (windowCursor->shape() == Qt::BitmapCursor || windowCursor->shape() >= Qt::CustomCursor)
+ qWarning() << "QWasmCursor: bitmap and custom cursors are not supported";
+
+ QByteArray htmlCursorName = cursorShapeToHtml(windowCursor->shape());
+
+ if (htmlCursorName.isEmpty())
+ htmlCursorName = "auto";
+
+ // Set cursor on the main canvas
+ EM_ASM_ARGS({
+ if (Module['canvas']) {
+ Module['canvas'].style['cursor'] = Pointer_stringify($0);
+ }
+ }, htmlCursorName.constData());
+}
+
+QByteArray QWasmCursor::cursorShapeToHtml(Qt::CursorShape shape)
+{
+ QByteArray cursorName;
+
+ switch (shape) {
+ case Qt::ArrowCursor:
+ cursorName = "default";
+ break;
+ case Qt::UpArrowCursor:
+ break;
+ case Qt::CrossCursor:
+ cursorName = "crosshair";
+ break;
+ case Qt::WaitCursor:
+ cursorName = "wait";
+ break;
+ case Qt::IBeamCursor:
+ cursorName = "text";
+ break;
+ case Qt::SizeVerCursor:
+ cursorName = "ns-resize";
+ break;
+ case Qt::SizeHorCursor:
+ cursorName = "ew-resize";
+ break;
+ case Qt::SizeBDiagCursor:
+ cursorName = "nesw-resize";
+ break;
+ case Qt::SizeFDiagCursor:
+ cursorName = "nwse-resize";
+ break;
+ case Qt::SizeAllCursor:
+ break; // no equivalent?
+ case Qt::BlankCursor:
+ cursorName = "none";
+ break;
+ case Qt::SplitVCursor:
+ cursorName = "row-resize";
+ break;
+ case Qt::SplitHCursor:
+ cursorName = "col-resize";
+ break;
+ case Qt::PointingHandCursor:
+ cursorName = "pointer";
+ break;
+ case Qt::ForbiddenCursor:
+ cursorName = "not-allowed";
+ break;
+ case Qt::WhatsThisCursor:
+ cursorName = "help";
+ break;
+ case Qt::BusyCursor:
+ cursorName = "wait";
+ break;
+ case Qt::OpenHandCursor:
+ break; // no equivalent?
+ case Qt::ClosedHandCursor:
+ break; // no equivalent?
+ case Qt::DragCopyCursor:
+ break; // no equivalent?
+ case Qt::DragMoveCursor:
+ break; // no equivalent?
+ case Qt::DragLinkCursor:
+ break; // no equivalent?
+ default:
+ break;
+ }
+
+ return cursorName;
+}
diff --git a/src/plugins/platforms/wasm/qwasmcursor.h b/src/plugins/platforms/wasm/qwasmcursor.h
new file mode 100644
index 0000000000..516e07aa31
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmcursor.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMCURSOR_H
+#define QWASMCURSOR_H
+
+#include <qpa/qplatformcursor.h>
+
+class QWasmCursor : public QPlatformCursor
+{
+public:
+ void changeCursor(QCursor *windowCursor, QWindow *window) override;
+
+ QByteArray cursorShapeToHtml(Qt::CursorShape shape);
+};
+
+#endif
diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp
new file mode 100644
index 0000000000..41355d72ae
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmeventdispatcher.h"
+
+#include <QtCore/qcoreapplication.h>
+
+#include <emscripten.h>
+
+class QWasmEventDispatcherPrivate : public QEventDispatcherUNIXPrivate
+{
+
+};
+
+QWasmEventDispatcher *g_htmlEventDispatcher;
+
+QWasmEventDispatcher::QWasmEventDispatcher(QObject *parent)
+ : QUnixEventDispatcherQPA(parent)
+{
+
+ g_htmlEventDispatcher = this;
+}
+
+QWasmEventDispatcher::~QWasmEventDispatcher()
+{
+ g_htmlEventDispatcher = nullptr;
+}
+
+bool QWasmEventDispatcher::registerRequestUpdateCallback(std::function<void(void)> callback)
+{
+ if (!g_htmlEventDispatcher || !g_htmlEventDispatcher->m_hasMainLoop)
+ return false;
+
+ g_htmlEventDispatcher->m_requestUpdateCallbacks.append(callback);
+ emscripten_resume_main_loop();
+ return true;
+}
+
+void QWasmEventDispatcher::maintainTimers()
+{
+ if (!g_htmlEventDispatcher || !g_htmlEventDispatcher->m_hasMainLoop)
+ return;
+
+ g_htmlEventDispatcher->doMaintainTimers();
+}
+
+bool QWasmEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ // WaitForMoreEvents is not supported (except for in combination with EventLoopExec below),
+ // and we don't want the unix event dispatcher base class to attempt to wait either.
+ flags &= ~QEventLoop::WaitForMoreEvents;
+
+ // Handle normal processEvents.
+ if (!(flags & QEventLoop::EventLoopExec))
+ return QUnixEventDispatcherQPA::processEvents(flags);
+
+ // Handle processEvents from QEventLoop::exec():
+ //
+ // At this point the application has created its root objects on
+ // the stack and has called app.exec() which has called into this
+ // function via QEventLoop.
+ //
+ // The application now expects that exec() will not return until
+ // app exit time. However, the browser expects that we return
+ // control to it periodically, also after initial setup in main().
+
+ // EventLoopExec for nested event loops is not supported.
+ Q_ASSERT(!m_hasMainLoop);
+ m_hasMainLoop = true;
+
+ // Call emscripten_set_main_loop_arg() with a callback which processes
+ // events. Also set simulateInfiniteLoop to true which makes emscripten
+ // return control to the browser without unwinding the C++ stack.
+ auto callback = [](void *eventDispatcher) {
+ QWasmEventDispatcher *that = static_cast<QWasmEventDispatcher *>(eventDispatcher);
+
+ // Save and clear updateRequest callbacks so we can register new ones
+ auto requestUpdateCallbacksCopy = that->m_requestUpdateCallbacks;
+ that->m_requestUpdateCallbacks.clear();
+
+ // Repaint all windows
+ for (auto callback : qAsConst(requestUpdateCallbacksCopy))
+ callback();
+
+ // Pause main loop if no updates were requested. Updates will be
+ // restarted again by registerRequestUpdateCallback().
+ if (that->m_requestUpdateCallbacks.isEmpty())
+ emscripten_pause_main_loop();
+
+ that->doMaintainTimers();
+ };
+ int fps = 0; // update using requestAnimationFrame
+ int simulateInfiniteLoop = 1;
+ emscripten_set_main_loop_arg(callback, this, fps, simulateInfiniteLoop);
+
+ // Note: the above call never returns, not even at app exit
+ return false;
+}
+
+void QWasmEventDispatcher::doMaintainTimers()
+{
+ Q_D(QWasmEventDispatcher);
+
+ // This functon schedules native timers in order to wake up to
+ // process events and activate Qt timers. This is done using the
+ // emscripten_async_call() API which schedules a new timer.
+ // There is unfortunately no way to cancel or update a current
+ // native timer.
+
+ // Schedule a zero-timer to continue processing any pending events.
+ if (!m_hasZeroTimer && hasPendingEvents()) {
+ auto callback = [](void *eventDispatcher) {
+ QWasmEventDispatcher *that = static_cast<QWasmEventDispatcher *>(eventDispatcher);
+ that->m_hasZeroTimer = false;
+ that->QUnixEventDispatcherQPA::processEvents(QEventLoop::AllEvents);
+
+ // Processing events may have posted new events or created new timers
+ that->doMaintainTimers();
+ };
+
+ emscripten_async_call(callback, this, 0);
+ m_hasZeroTimer = true;
+ return;
+ }
+
+ auto timespecToNanosec = [](timespec ts) -> uint64_t { return ts.tv_sec * 1000 + ts.tv_nsec / (1000 * 1000); };
+
+ // Get current time and time-to-first-Qt-timer. This polls for system
+ // time, and we use this time as the current time for the duration of this call.
+ timespec toWait;
+ bool hasTimers = d->timerList.timerWait(toWait);
+ if (!hasTimers)
+ return; // no timer needed
+
+ uint64_t currentTime = timespecToNanosec(d->timerList.currentTime);
+ uint64_t toWaitDuration = timespecToNanosec(toWait);
+
+ // The currently scheduled timer target is stored in m_currentTargetTime.
+ // We can re-use it if the new target is equivalent or later.
+ uint64_t newTargetTime = currentTime + toWaitDuration;
+ if (newTargetTime >= m_currentTargetTime)
+ return; // existing timer is good
+
+ // Schedule a native timer with a callback which processes events (and timers)
+ auto callback = [](void *eventDispatcher) {
+ QWasmEventDispatcher *that = static_cast<QWasmEventDispatcher *>(eventDispatcher);
+ that->m_currentTargetTime = std::numeric_limits<uint64_t>::max();
+ that->QUnixEventDispatcherQPA::processEvents(QEventLoop::AllEvents);
+
+ // Processing events may have posted new events or created new timers
+ that->doMaintainTimers();
+ };
+ emscripten_async_call(callback, this, toWaitDuration);
+ m_currentTargetTime = newTargetTime;
+}
diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.h b/src/plugins/platforms/wasm/qwasmeventdispatcher.h
new file mode 100644
index 0000000000..5300b3de73
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMEVENTDISPATCHER_H
+#define QWASMEVENTDISPATCHER_H
+
+#include <QtCore/qhash.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtEventDispatcherSupport/private/qunixeventdispatcher_qpa_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWasmEventDispatcherPrivate;
+
+class QWasmEventDispatcher : public QUnixEventDispatcherQPA
+{
+ Q_DECLARE_PRIVATE(QWasmEventDispatcher)
+public:
+ explicit QWasmEventDispatcher(QObject *parent = nullptr);
+ ~QWasmEventDispatcher();
+
+ static bool registerRequestUpdateCallback(std::function<void(void)> callback);
+ static void maintainTimers();
+
+protected:
+ bool processEvents(QEventLoop::ProcessEventsFlags flags) override;
+ void doMaintainTimers();
+
+private:
+ bool m_hasMainLoop = false;
+ bool m_hasZeroTimer = false;
+ uint64_t m_currentTargetTime = std::numeric_limits<uint64_t>::max();
+ QVector<std::function<void(void)>> m_requestUpdateCallbacks;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
new file mode 100644
index 0000000000..6545eda4e3
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
@@ -0,0 +1,522 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmeventtranslator.h"
+#include "qwasmeventdispatcher.h"
+#include "qwasmcompositor.h"
+#include "qwasmintegration.h"
+
+#include <QtGui/qevent.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qobject.h>
+
+#include <QtCore/qdeadlinetimer.h>
+
+#include <iostream>
+
+QT_BEGIN_NAMESPACE
+
+// macOS CTRL <-> META switching. We most likely want to enable
+// the existing switching code in QtGui, but for now do it here.
+static bool g_usePlatformMacCtrlMetaSwitching = false;
+
+QWasmEventTranslator::QWasmEventTranslator(QObject *parent)
+ : QObject(parent)
+ , draggedWindow(nullptr)
+ , pressedButtons(Qt::NoButton)
+ , resizeMode(QWasmWindow::ResizeNone)
+{
+ emscripten_set_keydown_callback(0, (void *)this, 1, &keyboard_cb);
+ emscripten_set_keyup_callback(0, (void *)this, 1, &keyboard_cb);
+
+ emscripten_set_mousedown_callback(0, (void *)this, 1, &mouse_cb);
+ emscripten_set_mouseup_callback(0, (void *)this, 1, &mouse_cb);
+ emscripten_set_mousemove_callback(0, (void *)this, 1, &mouse_cb);
+
+ emscripten_set_focus_callback(0, (void *)this, 1, &focus_cb);
+
+ emscripten_set_wheel_callback(0, (void *)this, 1, &wheel_cb);
+
+ touchDevice = new QTouchDevice;
+ touchDevice->setType(QTouchDevice::TouchScreen);
+ touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition);
+ QWindowSystemInterface::registerTouchDevice(touchDevice);
+
+ emscripten_set_touchstart_callback("#canvas", (void *)this, 1, &touchCallback);
+ emscripten_set_touchend_callback("#canvas", (void *)this, 1, &touchCallback);
+ emscripten_set_touchmove_callback("#canvas", (void *)this, 1, &touchCallback);
+ emscripten_set_touchcancel_callback("#canvas", (void *)this, 1, &touchCallback);
+
+ // The Platform Detect: expand coverage and move as needed
+ enum Platform {
+ GenericPlatform,
+ MacOSPlatform
+ };
+ Platform platform =
+ Platform(EM_ASM_INT("if (navigator.platform.includes(\"Mac\")) return 1; return 0;"));
+
+ g_usePlatformMacCtrlMetaSwitching = (platform == MacOSPlatform);
+}
+
+template <typename Event>
+QFlags<Qt::KeyboardModifier> QWasmEventTranslator::translatKeyModifier(const Event *event)
+{
+ QFlags<Qt::KeyboardModifier> keyModifier = Qt::NoModifier;
+ if (event->shiftKey)
+ keyModifier |= Qt::ShiftModifier;
+ if (event->ctrlKey) {
+ if (g_usePlatformMacCtrlMetaSwitching)
+ keyModifier |= Qt::MetaModifier;
+ else
+ keyModifier |= Qt::ControlModifier;
+ }
+ if (event->altKey)
+ keyModifier |= Qt::AltModifier;
+ if (event->metaKey) {
+ if (g_usePlatformMacCtrlMetaSwitching)
+ keyModifier |= Qt::ControlModifier;
+ else
+ keyModifier |= Qt::MetaModifier;
+ }
+ return keyModifier;
+}
+
+QFlags<Qt::KeyboardModifier> QWasmEventTranslator::translateKeyboardEventModifier(const EmscriptenKeyboardEvent *keyEvent)
+{
+ QFlags<Qt::KeyboardModifier> keyModifier = translatKeyModifier(keyEvent);
+ if (keyEvent->location == DOM_KEY_LOCATION_NUMPAD) {
+ keyModifier |= Qt::KeypadModifier;
+ }
+
+ return keyModifier;
+}
+
+QFlags<Qt::KeyboardModifier> QWasmEventTranslator::translateMouseEventModifier(const EmscriptenMouseEvent *mouseEvent)
+{
+ return translatKeyModifier(mouseEvent);
+}
+
+int QWasmEventTranslator::keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
+{
+ Q_UNUSED(userData)
+
+ bool alphanumeric;
+ Qt::Key qtKey = translateEmscriptKey(keyEvent, &alphanumeric);
+
+ QEvent::Type keyType = QEvent::None;
+ switch (eventType) {
+ case EMSCRIPTEN_EVENT_KEYPRESS:
+ case EMSCRIPTEN_EVENT_KEYDOWN: //down
+ keyType = QEvent::KeyPress;
+ break;
+ case EMSCRIPTEN_EVENT_KEYUP: //up
+ keyType = QEvent::KeyRelease;
+ break;
+ default:
+ break;
+ };
+
+ if (keyType == QEvent::None)
+ return 0;
+
+ QString keyText = alphanumeric ? QString(keyEvent->key) : QString();
+ bool accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(
+ 0, keyType, qtKey, translateKeyboardEventModifier(keyEvent), keyText);
+ QWasmEventDispatcher::maintainTimers();
+ return accepted ? 1 : 0;
+}
+
+Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey, bool *outAlphanumeric)
+{
+ Qt::Key qtKey;
+ if (outAlphanumeric)
+ *outAlphanumeric = false;
+
+ switch (emscriptKey->keyCode) {
+ case KeyMultiply: qtKey = Qt::Key_Asterisk; *outAlphanumeric = true; break;
+ case KeyAdd: qtKey = Qt::Key_Plus; *outAlphanumeric = true; break;
+ case KeyMinus: qtKey = Qt::Key_Minus; *outAlphanumeric = true; break;
+ case KeySubtract: qtKey = Qt::Key_Minus; *outAlphanumeric = true; break;
+ case KeyDecimal: qtKey = Qt::Key_Period; *outAlphanumeric = true; break;
+ case KeyDivide: qtKey = Qt::Key_Slash; *outAlphanumeric = true; break;
+ case KeyNumPad0: qtKey = Qt::Key_0; *outAlphanumeric = true; break;
+ case KeyNumPad1: qtKey = Qt::Key_1; *outAlphanumeric = true; break;
+ case KeyNumPad2: qtKey = Qt::Key_2; *outAlphanumeric = true; break;
+ case KeyNumPad3: qtKey = Qt::Key_3; *outAlphanumeric = true; break;
+ case KeyNumPad4: qtKey = Qt::Key_4; *outAlphanumeric = true; break;
+ case KeyNumPad5: qtKey = Qt::Key_5; *outAlphanumeric = true; break;
+ case KeyNumPad6: qtKey = Qt::Key_6; *outAlphanumeric = true; break;
+ case KeyNumPad7: qtKey = Qt::Key_7; *outAlphanumeric = true; break;
+ case KeyNumPad8: qtKey = Qt::Key_8; *outAlphanumeric = true; break;
+ case KeyNumPad9: qtKey = Qt::Key_9; *outAlphanumeric = true; break;
+ case KeyComma: qtKey = Qt::Key_Comma; *outAlphanumeric = true; break;
+ case KeyPeriod: qtKey = Qt::Key_Period; *outAlphanumeric = true; break;
+ case KeySlash: qtKey = Qt::Key_Slash; *outAlphanumeric = true; break;
+ case KeySemiColon: qtKey = Qt::Key_Semicolon; *outAlphanumeric = true; break;
+ case KeyEquals: qtKey = Qt::Key_Equal; *outAlphanumeric = true; break;
+ case KeyOpenBracket: qtKey = Qt::Key_BracketLeft; *outAlphanumeric = true; break;
+ case KeyCloseBracket: qtKey = Qt::Key_BracketRight; *outAlphanumeric = true; break;
+ case KeyBackSlash: qtKey = Qt::Key_Backslash; *outAlphanumeric = true; break;
+ case KeyMeta:
+ Q_FALLTHROUGH();
+ case KeyMetaRight:
+ qtKey = Qt::Key_Meta;
+ break;
+ case KeyTab: qtKey = Qt::Key_Tab; break;
+ case KeyClear: qtKey = Qt::Key_Clear; break;
+ case KeyBackSpace: qtKey = Qt::Key_Backspace; break;
+ case KeyEnter: qtKey = Qt::Key_Return; break;
+ case KeyShift: qtKey = Qt::Key_Shift; break;
+ case KeyControl: qtKey = Qt::Key_Control; break;
+ case KeyAlt: qtKey = Qt::Key_Alt; break;
+ case KeyCapsLock: qtKey = Qt::Key_CapsLock; break;
+ case KeyEscape: qtKey = Qt::Key_Escape; break;
+ case KeyPageUp: qtKey = Qt::Key_PageUp; break;
+ case KeyPageDown: qtKey = Qt::Key_PageDown; break;
+ case KeyEnd: qtKey = Qt::Key_End; break;
+ case KeyHome: qtKey = Qt::Key_Home; break;
+ case KeyLeft: qtKey = Qt::Key_Left; break;
+ case KeyUp: qtKey = Qt::Key_Up; break;
+ case KeyRight: qtKey = Qt::Key_Right; break;
+ case KeyDown: qtKey = Qt::Key_Down; break;
+ case KeyBrightnessDown: qtKey = Qt::Key_MonBrightnessDown; break;
+ case KeyBrightnessUp: qtKey = Qt::Key_MonBrightnessUp; break;
+ case KeyMediaTrackPrevious: qtKey = Qt::Key_MediaPrevious; break;
+ case KeyMediaPlayPause: qtKey = Qt::Key_MediaTogglePlayPause; break;
+ case KeyMediaTrackNext: qtKey = Qt::Key_MediaNext; break;
+ case KeyAudioVolumeMute: qtKey = Qt::Key_VolumeMute; break;
+ case KeyAudioVolumeDown: qtKey = Qt::Key_VolumeDown; break;
+ case KeyAudioVolumeUp: qtKey = Qt::Key_VolumeUp; break;
+ case KeyDelete: qtKey = Qt::Key_Delete; break;
+
+ case KeyF1: qtKey = Qt::Key_F1; break;
+ case KeyF2: qtKey = Qt::Key_F2; break;
+ case KeyF3: qtKey = Qt::Key_F3; break;
+ case KeyF4: qtKey = Qt::Key_F4; break;
+ case KeyF5: qtKey = Qt::Key_F5; break;
+ case KeyF6: qtKey = Qt::Key_F6; break;
+ case KeyF7: qtKey = Qt::Key_F7; break;
+ case KeyF8: qtKey = Qt::Key_F8; break;
+ case KeyF9: qtKey = Qt::Key_F9; break;
+ case KeyF10: qtKey = Qt::Key_F10; break;
+ case KeyF11: qtKey = Qt::Key_F11; break;
+ case KeyF12: qtKey = Qt::Key_F12; break;
+ case 124: qtKey = Qt::Key_F13; break;
+ case 125: qtKey = Qt::Key_F14; break;
+
+ case KeySpace:
+ default:
+ if (outAlphanumeric)
+ *outAlphanumeric = true;
+ qtKey = static_cast<Qt::Key>(emscriptKey->keyCode);
+ break;
+ }
+
+ // Handle Mac command key. Using event->keyCode as above is
+ // no reliable since the codes differ between browsers.
+ if (qstrncmp(emscriptKey->key, "Meta", 4) == 0) {
+ qtKey = Qt::Key_Meta;
+ *outAlphanumeric = false;
+ }
+
+ if (g_usePlatformMacCtrlMetaSwitching) {
+ if (qtKey == Qt::Key_Meta)
+ qtKey = Qt::Key_Control;
+ else if (qtKey == Qt::Key_Control)
+ qtKey = Qt::Key_Meta;
+ }
+
+ return qtKey;
+}
+
+Qt::MouseButton QWasmEventTranslator::translateMouseButton(unsigned short button)
+{
+ if (button == 0)
+ return Qt::LeftButton;
+ else if (button == 1)
+ return Qt::MiddleButton;
+ else if (button == 2)
+ return Qt::RightButton;
+
+ return Qt::NoButton;
+}
+
+int QWasmEventTranslator::mouse_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
+{
+ QWasmEventTranslator *translator = (QWasmEventTranslator*)userData;
+ translator->processMouse(eventType,mouseEvent);
+ QWasmEventDispatcher::maintainTimers();
+ return 0;
+}
+
+void resizeWindow(QWindow *window, QWasmWindow::ResizeMode mode,
+ QRect startRect, QPoint amount)
+{
+ if (mode == QWasmWindow::ResizeNone)
+ return;
+
+ bool top = mode == QWasmWindow::ResizeTopLeft ||
+ mode == QWasmWindow::ResizeTop ||
+ mode == QWasmWindow::ResizeTopRight;
+
+ bool bottom = mode == QWasmWindow::ResizeBottomLeft ||
+ mode == QWasmWindow::ResizeBottom ||
+ mode == QWasmWindow::ResizeBottomRight;
+
+ bool left = mode == QWasmWindow::ResizeLeft ||
+ mode == QWasmWindow::ResizeTopLeft ||
+ mode == QWasmWindow::ResizeBottomLeft;
+
+ bool right = mode == QWasmWindow::ResizeRight ||
+ mode == QWasmWindow::ResizeTopRight ||
+ mode == QWasmWindow::ResizeBottomRight;
+
+ int x1 = startRect.left();
+ int y1 = startRect.top();
+ int x2 = startRect.right();
+ int y2 = startRect.bottom();
+
+ if (left)
+ x1 += amount.x();
+ if (top)
+ y1 += amount.y();
+ if (right)
+ x2 += amount.x();
+ if (bottom)
+ y2 += amount.y();
+
+ int w = x2-x1;
+ int h = y2-y1;
+
+ if (w < window->minimumWidth()) {
+ if (left)
+ x1 -= window->minimumWidth() - w;
+
+ w = window->minimumWidth();
+ }
+
+ if (h < window->minimumHeight()) {
+ if (top)
+ y1 -= window->minimumHeight() - h;
+
+ h = window->minimumHeight();
+ }
+
+ window->setGeometry(x1, y1, w, h);
+}
+
+void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent)
+{
+ auto timestamp = mouseEvent->timestamp;
+ QPoint point(mouseEvent->canvasX, mouseEvent->canvasY);
+
+ QEvent::Type buttonEventType = QEvent::None;
+
+ Qt::MouseButton button = translateMouseButton(mouseEvent->button);
+ Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent);
+
+ QWindow *window2 = QWasmIntegration::get()->compositor()->windowAt(point, 5);
+ QWasmWindow *htmlWindow = static_cast<QWasmWindow*>(window2->handle());
+ bool onFrame = false;
+ if (window2 && !window2->geometry().contains(point))
+ onFrame = true;
+
+ QPoint localPoint(point.x() - window2->geometry().x(), point.y() - window2->geometry().y());
+
+ switch (eventType) {
+ case 5: //down
+ {
+ if (window2)
+ window2->raise();
+
+ pressedButtons.setFlag(button);
+
+ if (mouseEvent->button == 0) {
+ pressedWindow = window2;
+ buttonEventType = QEvent::MouseButtonPress;
+ if (htmlWindow && window2->flags().testFlag(Qt::WindowTitleHint) && htmlWindow->isPointOnTitle(point))
+ draggedWindow = window2;
+ else if (htmlWindow && htmlWindow->isPointOnResizeRegion(point)) {
+ draggedWindow = window2;
+ resizeMode = htmlWindow->resizeModeAtPoint(point);
+ resizePoint = point;
+ resizeStartRect = window2->geometry();
+ }
+ }
+
+ htmlWindow->injectMousePressed(localPoint, point, button, modifiers);
+ break;
+ }
+ case 6: //up
+ {
+ pressedButtons.setFlag(translateMouseButton(mouseEvent->button), false);
+ buttonEventType = QEvent::MouseButtonRelease;
+ QWasmWindow *oldWindow = nullptr;
+
+ if (mouseEvent->button == 0 && pressedWindow) {
+ oldWindow = static_cast<QWasmWindow*>(pressedWindow->handle());
+ pressedWindow = nullptr;
+ }
+
+
+ if (mouseEvent->button == 0) {
+ draggedWindow = nullptr;
+ resizeMode = QWasmWindow::ResizeNone;
+ }
+
+ if (oldWindow)
+ oldWindow->injectMouseReleased(localPoint, point, button, modifiers);
+ break;
+ }
+ case 8://move //drag event
+ {
+ buttonEventType = QEvent::MouseMove;
+ if (resizeMode == QWasmWindow::ResizeNone && draggedWindow) {
+ draggedWindow->setX(draggedWindow->x() + mouseEvent->movementX);
+ draggedWindow->setY(draggedWindow->y() + mouseEvent->movementY);
+ }
+
+ if (resizeMode != QWasmWindow::ResizeNone) {
+ QPoint delta = QPoint(mouseEvent->canvasX, mouseEvent->canvasY) - resizePoint;
+ resizeWindow(draggedWindow, resizeMode, resizeStartRect, delta);
+ }
+ break;
+ }
+ default:
+ break;
+ };
+
+ if (window2 && !onFrame) {
+ QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(
+ window2, timestamp, localPoint, point, pressedButtons, button, buttonEventType, modifiers);
+ }
+}
+
+int QWasmEventTranslator::focus_cb(int /*eventType*/, const EmscriptenFocusEvent */*focusEvent*/, void */*userData*/)
+{
+ return 0;
+}
+
+int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData)
+{
+ Q_UNUSED(eventType)
+ Q_UNUSED(userData)
+
+ EmscriptenMouseEvent mouseEvent = wheelEvent->mouse;
+
+ int scrollFactor = 0;
+ switch (wheelEvent->deltaMode) {
+ case DOM_DELTA_PIXEL://chrome safari
+ scrollFactor = 1;
+ break;
+ case DOM_DELTA_LINE: //firefox
+ scrollFactor = 12;
+ break;
+ case DOM_DELTA_PAGE:
+ scrollFactor = 20;
+ break;
+ };
+
+ Qt::KeyboardModifiers modifiers = translateMouseEventModifier(&mouseEvent);
+ auto timestamp = mouseEvent.timestamp;
+ QPoint globalPoint(mouseEvent.canvasX, mouseEvent.canvasY);
+
+ QWindow *window2 = QWasmIntegration::get()->compositor()->windowAt(globalPoint, 5);
+
+ QPoint localPoint(globalPoint.x() - window2->geometry().x(), globalPoint.y() - window2->geometry().y());
+
+ QPoint pixelDelta;
+
+ if (wheelEvent->deltaY != 0) pixelDelta.setY(wheelEvent->deltaY * scrollFactor);
+ if (wheelEvent->deltaX != 0) pixelDelta.setX(wheelEvent->deltaX * scrollFactor);
+
+ QWindowSystemInterface::handleWheelEvent(window2, timestamp, localPoint, globalPoint, QPoint(), pixelDelta, modifiers);
+ return 1;
+}
+
+int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
+{
+ QList<QWindowSystemInterface::TouchPoint> touchPointList;
+ touchPointList.reserve(touchEvent->numTouches);
+ QWindow *window2;
+
+ for (int i = 0; i < touchEvent->numTouches; i++) {
+
+ const EmscriptenTouchPoint *touches = &touchEvent->touches[i];
+
+ QPoint point(touches->canvasX, touches->canvasY);
+ window2 = QWasmIntegration::get()->compositor()->windowAt(point, 5);
+
+ QWindowSystemInterface::TouchPoint touchPoint;
+
+ auto cX = point.x();
+ auto cY = point.y();
+ touchPoint.area = QRect(0, 0, 8, 8);
+ touchPoint.area.moveCenter(QPointF(cX,cY)); // simulate area
+
+ touchPoint.id = touches->identifier;
+ touchPoint.normalPosition = QPointF(cX / window2->width(), cY / window2->height());
+
+ switch (eventType) {
+ case EMSCRIPTEN_EVENT_TOUCHSTART:
+ touchPoint.state = Qt::TouchPointPressed;
+ break;
+ case EMSCRIPTEN_EVENT_TOUCHEND:
+ touchPoint.state = Qt::TouchPointReleased;
+ break;
+ case EMSCRIPTEN_EVENT_TOUCHMOVE:
+ touchPoint.state = Qt::TouchPointMoved;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ touchPointList.append(touchPoint);
+ }
+
+ QWasmEventTranslator *wasmEventTranslator = (QWasmEventTranslator*)userData;
+ QFlags<Qt::KeyboardModifier> keyModifier = translatKeyModifier(touchEvent);
+
+ if (eventType != EMSCRIPTEN_EVENT_TOUCHCANCEL)
+ QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, touchPointList, keyModifier);
+ else
+ QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, keyModifier);
+
+ QCoreApplication::processEvents();
+ return 1;
+}
+
+quint64 QWasmEventTranslator::getTimestamp()
+{
+ return QDeadlineTimer::current().deadlineNSecs() / 1000;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h
new file mode 100644
index 0000000000..11430a57a2
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMEVENTTRANSLATOR_H
+#define QWASMEVENTTRANSLATOR_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qpoint.h>
+#include <emscripten/html5.h>
+#include "qwasmwindow.h"
+#include <QtGui/qtouchdevice.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+
+class QWasmEventTranslator : public QObject
+{
+ Q_OBJECT
+
+ enum KeyCode {
+ // numpad
+ KeyNumPad0 = 0x60,
+ KeyNumPad1 = 0x61,
+ KeyNumPad2 = 0x62,
+ KeyNumPad3 = 0x63,
+ KeyNumPad4 = 0x64,
+ KeyNumPad5 = 0x65,
+ KeyNumPad6 = 0x66,
+ KeyNumPad7 = 0x67,
+ KeyNumPad8 = 0x68,
+ KeyNumPad9 = 0x69,
+ KeyMultiply = 0x6A,
+ KeyAdd = 0x6B,
+ KeySeparator = 0x6C,
+ KeySubtract = 0x6D,
+ KeyDecimal = 0x6E,
+ KeyDivide = 0x6F,
+ KeyMeta = 0x5B,
+ KeyMetaRight = 0x5C,
+ ////////
+ KeyClear = 0x90,
+ KeyEnter = 0xD,
+ KeyBackSpace = 0x08,
+ KeyCancel = 0x03,
+ KeyTab = 0x09,
+ KeyShift = 0x10,
+ KeyControl = 0x11,
+ KeyAlt = 0x12,
+ KeyPause = 0x13,
+ KeyCapsLock = 0x14,
+ KeyEscape = 0x1B,
+ KeySpace = 0x20,
+ KeyPageUp = 0x21,
+ KeyPageDown = 0x22,
+ KeyEnd = 0x23,
+ KeyHome = 0x24,
+ KeyLeft = 0x25,
+ KeyUp = 0x26,
+ KeyRight = 0x27,
+ KeyDown = 0x28,
+ KeyComma = 0xBC,
+ KeyPeriod = 0xBE,
+ KeySlash = 0xBF,
+ KeyZero = 0x30,
+ KeyOne = 0x31,
+ KeyTwo = 0x32,
+ KeyThree = 0x33,
+ KeyFour = 0x34,
+ KeyFive = 0x35,
+ KeySix = 0x36,
+ KeySeven = 0x37,
+ KeyEight = 0x38,
+ KeyNine = 0x39,
+ KeyBrightnessDown = 0xD8,
+ KeyBrightnessUp = 0xD9,
+ KeyMediaTrackPrevious = 0xB1,
+ KeyMediaPlayPause = 0xB3,
+ KeyMediaTrackNext = 0xB0,
+ KeyAudioVolumeMute = 0xAD,
+ KeyAudioVolumeDown = 0xAE,
+ KeyAudioVolumeUp = 0xAF,
+ KeySemiColon = 0xBA,
+ KeyEquals = 0xBB,
+ KeyMinus = 0xBD,
+ KeyA = 0x41,
+ KeyB = 0x42,
+ KeyC = 0x43,
+ KeyD = 0x44,
+ KeyE = 0x45,
+ KeyF = 0x46,
+ KeyG = 0x47,
+ KeyH = 0x48,
+ KeyI = 0x49,
+ KeyJ = 0x4A,
+ KeyK = 0x4B,
+ KeyL = 0x4C,
+ KeyM = 0x4D,
+ KeyN = 0x4E,
+ KeyO = 0x4F,
+ KeyP = 0x50,
+ KeyQ = 0x51,
+ KeyR = 0x52,
+ KeyS = 0x53,
+ KeyT = 0x54,
+ KeyU = 0x55,
+ KeyV = 0x56,
+ KeyW = 0x57,
+ KeyX = 0x58,
+ KeyY = 0x59,
+ KeyZ = 0x5A,
+ KeyOpenBracket = 0xDB,
+ KeyBackSlash = 0xDC,
+ KeyCloseBracket = 0xDD,
+ KeyF1 = 0x70,
+ KeyF2 = 0x71,
+ KeyF3 = 0x72,
+ KeyF4 = 0x73,
+ KeyF5 = 0x74,
+ KeyF6 = 0x75,
+ KeyF7 = 0x76,
+ KeyF8 = 0x77,
+ KeyF9 = 0x78,
+ KeyF10 = 0x79,
+ KeyF11 = 0x7A,
+ KeyF12 = 0x7B,
+ KeyDelete = 0x2E,
+ KeyNumLock = 0x90,
+ KeyScrollLock = 0x91,
+ KeyPrintScreen = 0x9A,
+ KeyInsert = 0x9B,
+ KeyHelp = 0x9C,
+ KeyBackQuote = 0xC0,
+ KeyQuote = 0xDE,
+ KeyFinal = 0x18,
+ KeyConvert = 0x1C,
+ KeyNonConvert = 0x1D,
+ KeyAccept = 0x1E,
+ KeyModeChange = 0x1F,
+ KeyKana = 0x15,
+ KeyKanji = 0x19,
+ KeyUndefined = 0x0
+ };
+
+public:
+
+ explicit QWasmEventTranslator(QObject *parent = 0);
+
+ static int keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData);
+ static int mouse_cb(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
+ static int focus_cb(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData);
+ static int wheel_cb(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData);
+
+ static int touchCallback(int eventType, const EmscriptenTouchEvent *ev, void *userData);
+
+ void processEvents();
+
+Q_SIGNALS:
+ void getWindowAt(const QPoint &point, QWindow **window);
+private:
+ static Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey, bool *outAlphanumretic);
+ template <typename Event>
+ static QFlags<Qt::KeyboardModifier> translatKeyModifier(const Event *event);
+ static QFlags<Qt::KeyboardModifier> translateKeyboardEventModifier(const EmscriptenKeyboardEvent *keyEvent);
+ static QFlags<Qt::KeyboardModifier> translateMouseEventModifier(const EmscriptenMouseEvent *mouseEvent);
+ static Qt::MouseButton translateMouseButton(unsigned short button);
+
+ void processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent);
+
+private:
+ QWindow *draggedWindow;
+ QWindow *pressedWindow;
+ Qt::MouseButtons pressedButtons;
+
+ QWasmWindow::ResizeMode resizeMode;
+ QPoint resizePoint;
+ QRect resizeStartRect;
+ QTouchDevice *touchDevice;
+ quint64 getTimestamp();
+};
+
+QT_END_NAMESPACE
+#endif // QWASMEVENTTRANSLATOR_H
diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp
new file mode 100644
index 0000000000..0c72dfddc4
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmfontdatabase.h"
+
+#include <QtCore/qfile.h>
+
+QT_BEGIN_NAMESPACE
+
+void QWasmFontDatabase::populateFontDatabase()
+{
+ // Load font file from resources. Currently
+ // all fonts needs to be bundled with the nexe
+ // as Qt resources.
+ QStringList fontFileNames = QStringList() << QStringLiteral(":/fonts/Vera.ttf")
+ << QStringLiteral(":/fonts/DejaVuSans.ttf");
+
+ foreach (const QString &fontFileName, fontFileNames) {
+ QFile theFont(fontFileName);
+ if (!theFont.open(QIODevice::ReadOnly))
+ break;
+
+ QFreeTypeFontDatabase::addTTFile(theFont.readAll(), fontFileName.toLatin1());
+ }
+}
+
+QFontEngine *QWasmFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
+{
+ return QFreeTypeFontDatabase::fontEngine(fontDef, handle);
+}
+
+QStringList QWasmFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style,
+ QFont::StyleHint styleHint,
+ QChar::Script script) const
+{
+ QStringList fallbacks
+ = QFreeTypeFontDatabase::fallbacksForFamily(family, style, styleHint, script);
+
+ // Add the vera.ttf font (loaded in populateFontDatabase above) as a falback font
+ // to all other fonts (except itself).
+ const QString veraFontFamily = QStringLiteral("Bitstream Vera Sans");
+ if (family != veraFontFamily)
+ fallbacks.append(veraFontFamily);
+
+ return fallbacks;
+}
+
+QStringList QWasmFontDatabase::addApplicationFont(const QByteArray &fontData,
+ const QString &fileName)
+{
+ return QFreeTypeFontDatabase::addApplicationFont(fontData, fileName);
+}
+
+void QWasmFontDatabase::releaseHandle(void *handle)
+{
+ QFreeTypeFontDatabase::releaseHandle(handle);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.h b/src/plugins/platforms/wasm/qwasmfontdatabase.h
new file mode 100644
index 0000000000..891f12859e
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmfontdatabase.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMFONTDATABASE_H
+#define QWASMFONTDATABASE_H
+
+#include <QtFontDatabaseSupport/private/qfreetypefontdatabase_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWasmFontDatabase : public QFreeTypeFontDatabase
+{
+public:
+ void populateFontDatabase() override;
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
+ QStringList fallbacksForFamily(const QString &family, QFont::Style style,
+ QFont::StyleHint styleHint,
+ QChar::Script script) const override;
+ QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
+ void releaseHandle(void *handle) override;
+};
+QT_END_NAMESPACE
+#endif
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
new file mode 100644
index 0000000000..1be909f0a0
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmintegration.h"
+#include "qwasmeventtranslator.h"
+#include "qwasmeventdispatcher.h"
+#include "qwasmcompositor.h"
+#include "qwasmopenglcontext.h"
+#include "qwasmtheme.h"
+
+#include "qwasmwindow.h"
+#ifndef QT_NO_OPENGL
+# include "qwasmbackingstore.h"
+#endif
+#include "qwasmfontdatabase.h"
+#if defined(Q_OS_UNIX)
+#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
+#endif
+#include <qpa/qplatformwindow.h>
+#include <QtGui/qscreen.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <emscripten/bind.h>
+
+// this is where EGL headers are pulled in, make sure it is last
+#include "qwasmscreen.h"
+
+using namespace emscripten;
+QT_BEGIN_NAMESPACE
+
+void browserBeforeUnload()
+{
+ QWasmIntegration::QWasmBrowserExit();
+}
+
+EMSCRIPTEN_BINDINGS(my_module)
+{
+ function("browserBeforeUnload", &browserBeforeUnload);
+}
+
+static QWasmIntegration *globalHtml5Integration;
+QWasmIntegration *QWasmIntegration::get() { return globalHtml5Integration; }
+
+QWasmIntegration::QWasmIntegration()
+ : m_fontDb(nullptr),
+ m_compositor(new QWasmCompositor),
+ m_screen(new QWasmScreen(m_compositor)),
+ m_eventDispatcher(nullptr)
+{
+
+ globalHtml5Integration = this;
+
+ updateQScreenAndCanvasRenderSize();
+ screenAdded(m_screen);
+ emscripten_set_resize_callback(0, (void *)this, 1, uiEvent_cb);
+
+ m_eventTranslator = new QWasmEventTranslator;
+
+ EM_ASM(// exit app if browser closes
+ window.onbeforeunload = function () {
+ Module.browserBeforeUnload();
+ };
+ );
+}
+
+QWasmIntegration::~QWasmIntegration()
+{
+ delete m_compositor;
+ destroyScreen(m_screen);
+ delete m_fontDb;
+ delete m_eventTranslator;
+}
+
+void QWasmIntegration::QWasmBrowserExit()
+{
+ QCoreApplication *app = QCoreApplication::instance();
+ app->quit();
+}
+
+bool QWasmIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
+ case RasterGLSurface: return false; // to enable this you need to fix qopenglwidget and quickwidget for wasm
+ case MultipleWindows: return true;
+ case WindowManagement: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformWindow *QWasmIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QWasmWindow(window, m_compositor, m_backingStores.value(window));
+}
+
+QPlatformBackingStore *QWasmIntegration::createPlatformBackingStore(QWindow *window) const
+{
+#ifndef QT_NO_OPENGL
+ QWasmBackingStore *backingStore = new QWasmBackingStore(m_compositor, window);
+ m_backingStores.insert(window, backingStore);
+ return backingStore;
+#else
+ return nullptr;
+#endif
+}
+
+#ifndef QT_NO_OPENGL
+QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ return new QWasmOpenGLContext(context->format());
+}
+#endif
+
+QPlatformFontDatabase *QWasmIntegration::fontDatabase() const
+{
+ if (m_fontDb == nullptr)
+ m_fontDb = new QWasmFontDatabase;
+
+ return m_fontDb;
+}
+
+QAbstractEventDispatcher *QWasmIntegration::createEventDispatcher() const
+{
+ return new QWasmEventDispatcher;
+}
+
+QVariant QWasmIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
+{
+ return QPlatformIntegration::styleHint(hint);
+}
+
+QStringList QWasmIntegration::themeNames() const
+{
+ return QStringList() << QLatin1String("webassembly");
+}
+
+QPlatformTheme *QWasmIntegration::createPlatformTheme(const QString &name) const
+{
+ if (name == QLatin1String("webassembly"))
+ return new QWasmTheme;
+ return QPlatformIntegration::createPlatformTheme(name);
+}
+
+int QWasmIntegration::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData)
+{
+ Q_UNUSED(e)
+ Q_UNUSED(userData)
+
+ if (eventType == EMSCRIPTEN_EVENT_RESIZE) {
+ // This resize event is called when the HTML window is resized. Depending
+ // on the page layout the the canvas might also have been resized, so we
+ // update the Qt screen size (and canvas render size).
+ updateQScreenAndCanvasRenderSize();
+ }
+
+ return 0;
+}
+
+static void set_canvas_size(double width, double height)
+{
+ EM_ASM_({
+ var canvas = Module.canvas;
+ canvas.width = $0;
+ canvas.height = $1;
+ }, width, height);
+}
+
+void QWasmIntegration::updateQScreenAndCanvasRenderSize()
+{
+ // The HTML canvas has two sizes: the CSS size and the canvas render size.
+ // The CSS size is determined according to standard CSS rules, while the
+ // render size is set using the "width" and "height" attributes. The render
+ // size must be set manually and is not auto-updated on CSS size change.
+ // Setting the render size to a value larger than the CSS size enables high-dpi
+ // rendering.
+
+ double css_width;
+ double css_height;
+ emscripten_get_element_css_size(0, &css_width, &css_height);
+ QSizeF cssSize(css_width, css_height);
+
+ QWasmScreen *screen = QWasmIntegration::get()->m_screen;
+ QSizeF canvasSize = cssSize * screen->devicePixelRatio();
+
+ set_canvas_size(canvasSize.width(), canvasSize.height());
+ screen->setGeometry(QRect(QPoint(0, 0), cssSize.toSize()));
+ QWasmIntegration::get()->m_compositor->redrawWindowContent();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h
new file mode 100644
index 0000000000..ebc3d9d431
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmintegration.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMINTEGRATION_H
+#define QWASMINTEGRATION_H
+
+#include "qwasmwindow.h"
+
+#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformscreen.h>
+
+#include <QtCore/qhash.h>
+
+#include <emscripten.h>
+#include <emscripten/html5.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWasmEventTranslator;
+class QWasmFontDatabase;
+class QWasmWindow;
+class QWasmEventDispatcher;
+class QWasmScreen;
+class QWasmCompositor;
+class QWasmBackingStore;
+
+class QWasmIntegration : public QObject, public QPlatformIntegration
+{
+ Q_OBJECT
+public:
+ QWasmIntegration();
+ ~QWasmIntegration();
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const override;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
+#ifndef QT_NO_OPENGL
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
+#endif
+ QPlatformFontDatabase *fontDatabase() const override;
+ QAbstractEventDispatcher *createEventDispatcher() const override;
+ QVariant styleHint(QPlatformIntegration::StyleHint hint) const override;
+ QStringList themeNames() const override;
+ QPlatformTheme *createPlatformTheme(const QString &name) const override;
+
+ static QWasmIntegration *get();
+ QWasmScreen *screen() { return m_screen; }
+ QWasmCompositor *compositor() { return m_compositor; }
+ QWasmEventTranslator *eventTranslator() { return m_eventTranslator; }
+
+ static void QWasmBrowserExit();
+ static void updateQScreenAndCanvasRenderSize();
+
+private:
+ mutable QWasmFontDatabase *m_fontDb;
+ QWasmCompositor *m_compositor;
+ mutable QWasmScreen *m_screen;
+ mutable QWasmEventTranslator *m_eventTranslator;
+ mutable QWasmEventDispatcher *m_eventDispatcher;
+ static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData);
+ mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWASMINTEGRATION_H
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
new file mode 100644
index 0000000000..73af3d1878
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmopenglcontext.h"
+
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+QWasmOpenGLContext::QWasmOpenGLContext(const QSurfaceFormat &format)
+ : m_requestedFormat(format)
+{
+ m_requestedFormat.setRenderableType(QSurfaceFormat::OpenGLES);
+}
+
+QWasmOpenGLContext::~QWasmOpenGLContext()
+{
+ if (m_context)
+ emscripten_webgl_destroy_context(m_context);
+}
+
+void QWasmOpenGLContext::maybeRecreateEmscriptenContext(QPlatformSurface *surface)
+{
+ // Native emscripten contexts are tied to a single surface. Recreate
+ // the context if the surface is changed.
+ if (surface != m_surface) {
+ m_surface = surface;
+
+ // Destroy existing context
+ if (m_context)
+ emscripten_webgl_destroy_context(m_context);
+
+ // Create new context
+ const char *canvasId = 0; // (use default canvas) FIXME: get the actual canvas from the surface.
+ m_context = createEmscriptenContext(canvasId, m_requestedFormat);
+
+ // Register context-lost callback.
+ auto callback = [](int eventType, const void *reserved, void *userData) -> EM_BOOL
+ {
+ Q_UNUSED(eventType);
+ Q_UNUSED(reserved);
+ // The application may get contex-lost if e.g. moved to the background. Set
+ // m_contextLost which will make isValid() return false. Application code will
+ // then detect this and recrate the the context, resulting in a new QWasmOpenGLContext
+ // instance.
+ reinterpret_cast<QWasmOpenGLContext *>(userData)->m_contextLost = true;
+ return true;
+ };
+ bool capture = true;
+ emscripten_set_webglcontextlost_callback(canvasId, this, capture, callback);
+ }
+}
+
+EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(const char *canvasId, QSurfaceFormat format)
+{
+ EmscriptenWebGLContextAttributes attributes;
+ emscripten_webgl_init_context_attributes(&attributes); // Populate with default attributes
+
+ attributes.preferLowPowerToHighPerformance = false;
+ attributes.failIfMajorPerformanceCaveat = false;
+ attributes.antialias = true;
+ attributes.enableExtensionsByDefault = true;
+
+ if (format.majorVersion() == 3) {
+ attributes.majorVersion = 2;
+ }
+
+ // WebGL offers enable/disable control but not size control for these
+ attributes.alpha = format.alphaBufferSize() > 0;
+ attributes.depth = format.depthBufferSize() > 0;
+ attributes.stencil = format.stencilBufferSize() > 0;
+
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(canvasId, &attributes);
+
+ return context;
+}
+
+QSurfaceFormat QWasmOpenGLContext::format() const
+{
+ return m_requestedFormat;
+}
+
+GLuint QWasmOpenGLContext::defaultFramebufferObject(QPlatformSurface *surface) const
+{
+ return QPlatformOpenGLContext::defaultFramebufferObject(surface);
+}
+
+bool QWasmOpenGLContext::makeCurrent(QPlatformSurface *surface)
+{
+ maybeRecreateEmscriptenContext(surface);
+
+ return emscripten_webgl_make_context_current(m_context) == EMSCRIPTEN_RESULT_SUCCESS;
+}
+
+void QWasmOpenGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ Q_UNUSED(surface);
+ // No swapbuffers on WebGl
+}
+
+void QWasmOpenGLContext::doneCurrent()
+{
+ // No doneCurrent on WebGl
+}
+
+bool QWasmOpenGLContext::isSharing() const
+{
+ return false;
+}
+
+bool QWasmOpenGLContext::isValid() const
+{
+ return (m_contextLost == false);
+}
+
+QFunctionPointer QWasmOpenGLContext::getProcAddress(const char *procName)
+{
+ return reinterpret_cast<QFunctionPointer>(eglGetProcAddress(procName));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.h b/src/plugins/platforms/wasm/qwasmopenglcontext.h
new file mode 100644
index 0000000000..9123100479
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmopenglcontext.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpa/qplatformopenglcontext.h>
+
+#include <emscripten.h>
+#include <emscripten/html5.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWasmOpenGLContext : public QPlatformOpenGLContext
+{
+public:
+ QWasmOpenGLContext(const QSurfaceFormat &format);
+ ~QWasmOpenGLContext();
+
+ QSurfaceFormat format() const override;
+ void swapBuffers(QPlatformSurface *surface) override;
+ GLuint defaultFramebufferObject(QPlatformSurface *surface) const override;
+ bool makeCurrent(QPlatformSurface *surface) override;
+ void doneCurrent() override;
+ bool isSharing() const override;
+ bool isValid() const override;
+ QFunctionPointer getProcAddress(const char *procName) override;
+
+private:
+ void maybeRecreateEmscriptenContext(QPlatformSurface *surface);
+ static EMSCRIPTEN_WEBGL_CONTEXT_HANDLE createEmscriptenContext(const char *canvasId, QSurfaceFormat format);
+
+ bool m_contextLost = false;
+ QSurfaceFormat m_requestedFormat;
+ QPlatformSurface *m_surface = nullptr;
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE m_context = 0;
+};
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
new file mode 100644
index 0000000000..93e9906ffc
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmscreen.h"
+#include "qwasmwindow.h"
+#include "qwasmcompositor.h"
+
+#include <QtEglSupport/private/qeglconvenience_p.h>
+#ifndef QT_NO_OPENGL
+# include <QtEglSupport/private/qeglplatformcontext_p.h>
+#endif
+#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtGui/qguiapplication.h>
+#include <private/qhighdpiscaling_p.h>
+
+
+QT_BEGIN_NAMESPACE
+
+QWasmScreen::QWasmScreen(QWasmCompositor *compositor)
+ : m_compositor(compositor)
+ , m_depth(32)
+ , m_format(QImage::Format_RGB32)
+{
+ m_compositor->setScreen(this);
+}
+
+QWasmScreen::~QWasmScreen()
+{
+
+}
+
+QRect QWasmScreen::geometry() const
+{
+ return m_geometry;
+}
+
+int QWasmScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QWasmScreen::format() const
+{
+ return m_format;
+}
+
+qreal QWasmScreen::devicePixelRatio() const
+{
+ // FIXME: The effective device pixel ratio may be different from the
+ // HTML window dpr if the OpenGL driver/GPU allocates a less than
+ // full resolution surface. Use emscripten_webgl_get_drawing_buffer_size()
+ // and compute the dpr instead.
+ double htmlWindowDpr = EM_ASM_DOUBLE({
+ return window.devicePixelRatio;
+ });
+ return qreal(htmlWindowDpr);
+}
+
+QPlatformCursor *QWasmScreen::cursor() const
+{
+ return const_cast<QWasmCursor *>(&m_cursor);
+}
+
+void QWasmScreen::resizeMaximizedWindows()
+{
+ QPlatformScreen::resizeMaximizedWindows();
+}
+
+QWindow *QWasmScreen::topWindow() const
+{
+ return m_compositor->keyWindow();
+}
+
+QWindow *QWasmScreen::topLevelAt(const QPoint &p) const
+{
+ return m_compositor->windowAt(p);
+}
+
+void QWasmScreen::invalidateSize()
+{
+ m_geometry = QRect();
+}
+
+void QWasmScreen::setGeometry(const QRect &rect)
+{
+ m_geometry = rect;
+ QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry());
+ resizeMaximizedWindows();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h
new file mode 100644
index 0000000000..3891db77bb
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmscreen.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMSCREEN_H
+#define QWASMSCREEN_H
+
+#include "qwasmcursor.h"
+
+#include <qpa/qplatformscreen.h>
+
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qtextstream.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformOpenGLContext;
+class QWasmWindow;
+class QWasmBackingStore;
+class QWasmCompositor;
+class QOpenGLContext;
+
+class QWasmScreen : public QObject, public QPlatformScreen
+{
+ Q_OBJECT
+public:
+
+ QWasmScreen(QWasmCompositor *compositor);
+ ~QWasmScreen();
+
+ QRect geometry() const override;
+ int depth() const override;
+ QImage::Format format() const override;
+ qreal devicePixelRatio() const override;
+ QPlatformCursor *cursor() const override;
+
+ void resizeMaximizedWindows();
+ QWindow *topWindow() const;
+ QWindow *topLevelAt(const QPoint &p) const override;
+
+ void invalidateSize();
+
+public slots:
+ void setGeometry(const QRect &rect);
+protected:
+
+private:
+ QWasmCompositor *m_compositor;
+
+ QRect m_geometry = QRect(0, 0, 100, 100);
+ int m_depth;
+ QImage::Format m_format;
+ QWasmCursor m_cursor;
+};
+
+QT_END_NAMESPACE
+#endif // QWASMSCREEN_H
diff --git a/src/plugins/platforms/wasm/qwasmstylepixmaps_p.h b/src/plugins/platforms/wasm/qwasmstylepixmaps_p.h
new file mode 100644
index 0000000000..2b5860f42f
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmstylepixmaps_p.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMSTYLEPIXMAPS_P_H
+#define QWASMSTYLEPIXMAPS_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.
+//
+
+/* XPM */
+static const char * const qt_menu_xpm[] = {
+"16 16 72 1",
+" c None",
+". c #65AF36",
+"+ c #66B036",
+"@ c #77B94C",
+"# c #A7D28C",
+"$ c #BADBA4",
+"% c #A4D088",
+"& c #72B646",
+"* c #9ACB7A",
+"= c #7FBD56",
+"- c #85C05F",
+"; c #F4F9F0",
+"> c #FFFFFF",
+", c #E5F1DC",
+"' c #ECF5E7",
+") c #7ABA50",
+"! c #83BF5C",
+"~ c #AED595",
+"{ c #D7EACA",
+"] c #A9D28D",
+"^ c #BCDDA8",
+"/ c #C4E0B1",
+"( c #81BE59",
+"_ c #D0E7C2",
+": c #D4E9C6",
+"< c #6FB542",
+"[ c #6EB440",
+"} c #88C162",
+"| c #98CA78",
+"1 c #F4F9F1",
+"2 c #8FC56C",
+"3 c #F1F8EC",
+"4 c #E8F3E1",
+"5 c #D4E9C7",
+"6 c #74B748",
+"7 c #80BE59",
+"8 c #73B747",
+"9 c #6DB43F",
+"0 c #CBE4BA",
+"a c #80BD58",
+"b c #6DB33F",
+"c c #FEFFFE",
+"d c #68B138",
+"e c #F9FCF7",
+"f c #91C66F",
+"g c #E8F3E0",
+"h c #DCEDD0",
+"i c #91C66E",
+"j c #A3CF86",
+"k c #C9E3B8",
+"l c #B0D697",
+"m c #E3F0DA",
+"n c #95C873",
+"o c #E6F2DE",
+"p c #9ECD80",
+"q c #BEDEAA",
+"r c #C7E2B6",
+"s c #79BA4F",
+"t c #6EB441",
+"u c #BCDCA7",
+"v c #FAFCF8",
+"w c #F6FAF3",
+"x c #84BF5D",
+"y c #EDF6E7",
+"z c #FAFDF9",
+"A c #88C263",
+"B c #98CA77",
+"C c #CDE5BE",
+"D c #67B037",
+"E c #D9EBCD",
+"F c #6AB23C",
+"G c #77B94D",
+" .++++++++++++++",
+".+++++++++++++++",
+"+++@#$%&+++*=+++",
+"++-;>,>')+!>~+++",
+"++{>]+^>/(_>:~<+",
+"+[>>}+|>123>456+",
+"+7>>8+->>90>~+++",
+"+a>>b+a>c[0>~+++",
+"+de>=+f>g+0>~+++",
+"++h>i+j>k+0>~+++",
+"++l>mno>p+q>rst+",
+"++duv>wl++xy>zA+",
+"++++B>Cb++++&D++",
+"+++++0zE++++++++",
+"++++++FG+++++++.",
+"++++++++++++++. "};
+
+static const char * const qt_close_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+".##....##.",
+"..##..##..",
+"...####...",
+"....##....",
+"...####...",
+"..##..##..",
+".##....##.",
+"..........",
+".........."};
+
+static const char * const qt_maximize_xpm[]={
+"10 10 2 1",
+"# c #000000",
+". c None",
+"#########.",
+"#########.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#########.",
+".........."};
+
+
+static const char * const qt_normalizeup_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"...######.",
+"...######.",
+"...#....#.",
+".######.#.",
+".######.#.",
+".#....###.",
+".#....#...",
+".#....#...",
+".######...",
+".........."};
+
+
+#endif // QWASMSTYLEPIXMAPS_P_H
diff --git a/src/plugins/platforms/wasm/qwasmtheme.cpp b/src/plugins/platforms/wasm/qwasmtheme.cpp
new file mode 100644
index 0000000000..a7f2db3bd3
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmtheme.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmtheme.h"
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_NAMESPACE
+
+QWasmTheme::QWasmTheme()
+{
+}
+
+QWasmTheme::~QWasmTheme()
+{
+}
+
+QVariant QWasmTheme::themeHint(ThemeHint hint) const
+{
+ if (hint == QPlatformTheme::StyleNames)
+ return QVariant(QStringList() << QLatin1String("fusion"));
+ return QPlatformTheme::themeHint(hint);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmtheme.h b/src/plugins/platforms/wasm/qwasmtheme.h
new file mode 100644
index 0000000000..e4cc06e049
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmtheme.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMTHEME_H
+#define QWASMTHEME_H
+
+#include <qpa/qplatformtheme.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWasmEventTranslator;
+class QWasmFontDatabase;
+class QWasmWindow;
+class QWasmEventDispatcher;
+class QWasmScreen;
+class QWasmCompositor;
+class QWasmBackingStore;
+
+class QWasmTheme : public QPlatformTheme
+{
+public:
+ QWasmTheme();
+ ~QWasmTheme();
+
+ QVariant themeHint(ThemeHint hint) const override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWASMTHEME_H
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp
new file mode 100644
index 0000000000..0489813929
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmwindow.cpp
@@ -0,0 +1,398 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpa/qwindowsysteminterface.h>
+#include <private/qguiapplication_p.h>
+#include <QtGui/private/qopenglcontext_p.h>
+#include <QtGui/private/qwindow_p.h>
+#include <QtGui/qopenglcontext.h>
+
+#include "qwasmwindow.h"
+#include "qwasmscreen.h"
+#include "qwasmcompositor.h"
+#include "qwasmeventdispatcher.h"
+
+#include <iostream>
+
+Q_GUI_EXPORT int qt_defaultDpiX();
+
+QT_BEGIN_NAMESPACE
+
+QWasmWindow::QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore)
+ : QPlatformWindow(w),
+ m_window(w),
+ m_compositor(compositor),
+ m_backingStore(backingStore)
+{
+ m_needsCompositor = w->surfaceType() != QSurface::OpenGLSurface;
+ static int serialNo = 0;
+ m_winid = ++serialNo;
+ qWarning("QWasmWindow %p: %p 0x%x\n", this, w, uint(m_winid));
+
+ m_compositor->addWindow(this);
+
+ // Pure OpenGL windows draw directly using egl, disable the compositor.
+ m_compositor->setEnabled(w->surfaceType() != QSurface::OpenGLSurface);
+}
+
+QWasmWindow::~QWasmWindow()
+{
+ m_compositor->removeWindow(this);
+}
+
+void QWasmWindow::initialize()
+{
+ QRect rect = windowGeometry();
+
+ QPlatformWindow::setGeometry(rect);
+
+ const QSize minimumSize = windowMinimumSize();
+ if (rect.width() > 0 || rect.height() > 0) {
+ rect.setWidth(qBound(1, rect.width(), 2000));
+ rect.setHeight(qBound(1, rect.height(), 2000));
+ } else if (minimumSize.width() > 0 || minimumSize.height() > 0) {
+ rect.setSize(minimumSize);
+ }
+
+ setWindowState(window()->windowStates());
+ setWindowFlags(window()->flags());
+ setWindowTitle(window()->title());
+ m_hasTitle = window()->flags().testFlag(Qt::WindowTitleHint) && m_needsCompositor;
+
+ if (window()->isTopLevel())
+ setWindowIcon(window()->icon());
+ m_normalGeometry = rect;
+}
+
+QWasmScreen *QWasmWindow::platformScreen() const
+{
+ return static_cast<QWasmScreen *>(window()->screen()->handle());
+}
+
+void QWasmWindow::setGeometry(const QRect &rect)
+{
+ QRect r = rect;
+ if (m_needsCompositor) {
+ int yMin = window()->geometry().top() - window()->frameGeometry().top();
+
+ if (r.y() < yMin)
+ r.moveTop(yMin);
+ }
+ QWindowSystemInterface::handleGeometryChange(window(), r);
+ QPlatformWindow::setGeometry(r);
+
+ QWindowSystemInterface::flushWindowSystemEvents();
+ invalidate();
+}
+
+void QWasmWindow::setVisible(bool visible)
+{
+ QRect newGeom;
+
+ if (visible) {
+ const bool forceFullScreen = !m_needsCompositor;//make gl apps fullscreen for now
+
+ if (forceFullScreen || (m_windowState & Qt::WindowFullScreen))
+ newGeom = platformScreen()->geometry();
+ else if (m_windowState & Qt::WindowMaximized)
+ newGeom = platformScreen()->availableGeometry();
+ }
+ QPlatformWindow::setVisible(visible);
+
+ m_compositor->setVisible(this, visible);
+
+ if (!newGeom.isEmpty())
+ setGeometry(newGeom); // may or may not generate an expose
+
+ invalidate();
+}
+
+QMargins QWasmWindow::frameMargins() const
+{
+ int border = m_hasTitle ? 4. * (qreal(qt_defaultDpiX()) / 96.0) : 0;
+ int titleBarHeight = m_hasTitle ? titleHeight() : 0;
+
+ QMargins margins;
+ margins.setLeft(border);
+ margins.setRight(border);
+ margins.setTop(2*border + titleBarHeight);
+ margins.setBottom(border);
+
+ return margins;
+}
+
+void QWasmWindow::raise()
+{
+ m_compositor->raise(this);
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size()));
+ invalidate();
+}
+
+void QWasmWindow::lower()
+{
+ m_compositor->lower(this);
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size()));
+ invalidate();
+}
+
+WId QWasmWindow::winId() const
+{
+ return m_winid;
+}
+
+void QWasmWindow::propagateSizeHints()
+{
+// get rid of base class warning
+}
+
+void QWasmWindow::injectMousePressed(const QPoint &local, const QPoint &global,
+ Qt::MouseButton button, Qt::KeyboardModifiers mods)
+{
+ Q_UNUSED(local);
+ Q_UNUSED(mods);
+
+ if (!m_hasTitle || button != Qt::LeftButton)
+ return;
+
+ if (maxButtonRect().contains(global))
+ m_activeControl = QWasmCompositor::SC_TitleBarMaxButton;
+ else if (minButtonRect().contains(global))
+ m_activeControl = QWasmCompositor::SC_TitleBarMinButton;
+ else if (closeButtonRect().contains(global))
+ m_activeControl = QWasmCompositor::SC_TitleBarCloseButton;
+ else if (normButtonRect().contains(global))
+ m_activeControl = QWasmCompositor::SC_TitleBarNormalButton;
+
+ invalidate();
+}
+
+void QWasmWindow::injectMouseReleased(const QPoint &local, const QPoint &global,
+ Qt::MouseButton button, Qt::KeyboardModifiers mods)
+{
+ Q_UNUSED(local);
+ Q_UNUSED(mods);
+
+ if (!m_hasTitle || button != Qt::LeftButton)
+ return;
+
+ if (closeButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarCloseButton)
+ window()->close();
+
+ if (maxButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarMaxButton) {
+ window()->setWindowState(Qt::WindowMaximized);
+ platformScreen()->resizeMaximizedWindows();
+ }
+
+ if (normButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarNormalButton) {
+ window()->setWindowState(Qt::WindowNoState);
+ setGeometry(normalGeometry());
+ }
+
+ m_activeControl = QWasmCompositor::SC_None;
+
+ invalidate();
+}
+
+int QWasmWindow::titleHeight() const
+{
+ return 18. * (qreal(qt_defaultDpiX()) / 96.0);//dpiScaled(18.);
+}
+
+int QWasmWindow::borderWidth() const
+{
+ return 4. * (qreal(qt_defaultDpiX()) / 96.0);// dpiScaled(4.);
+}
+
+QRegion QWasmWindow::titleGeometry() const
+{
+ int border = borderWidth();
+
+ QRegion result(window()->frameGeometry().x() + border,
+ window()->frameGeometry().y() + border,
+ window()->frameGeometry().width() - 2*border,
+ titleHeight());
+
+ result -= titleControlRegion();
+
+ return result;
+}
+
+QRegion QWasmWindow::resizeRegion() const
+{
+ int border = borderWidth();
+ QRegion result(window()->frameGeometry().adjusted(-border, -border, border, border));
+ result -= window()->frameGeometry().adjusted(border, border, -border, -border);
+
+ return result;
+}
+
+bool QWasmWindow::isPointOnTitle(QPoint point) const
+{
+ bool ok = titleGeometry().contains(point);
+ return ok;
+}
+
+bool QWasmWindow::isPointOnResizeRegion(QPoint point) const
+{
+ return resizeRegion().contains(point);
+}
+
+QWasmWindow::ResizeMode QWasmWindow::resizeModeAtPoint(QPoint point) const
+{
+ QPoint p1 = window()->frameGeometry().topLeft() - QPoint(5, 5);
+ QPoint p2 = window()->frameGeometry().bottomRight() + QPoint(5, 5);
+ int corner = 20;
+
+ QRect top(p1, QPoint(p2.x(), p1.y() + corner));
+ QRect middle(QPoint(p1.x(), p1.y() + corner), QPoint(p2.x(), p2.y() - corner));
+ QRect bottom(QPoint(p1.x(), p2.y() - corner), p2);
+
+ QRect left(p1, QPoint(p1.x() + corner, p2.y()));
+ QRect center(QPoint(p1.x() + corner, p1.y()), QPoint(p2.x() - corner, p2.y()));
+ QRect right(QPoint(p2.x() - corner, p1.y()), p2);
+
+ if (top.contains(point)) {
+ // Top
+ if (left.contains(point))
+ return ResizeTopLeft;
+ if (center.contains(point))
+ return ResizeTop;
+ if (right.contains(point))
+ return ResizeTopRight;
+ } else if (middle.contains(point)) {
+ // Middle
+ if (left.contains(point))
+ return ResizeLeft;
+ if (right.contains(point))
+ return ResizeRight;
+ } else if (bottom.contains(point)) {
+ // Bottom
+ if (left.contains(point))
+ return ResizeBottomLeft;
+ if (center.contains(point))
+ return ResizeBottom;
+ if (right.contains(point))
+ return ResizeBottomRight;
+ }
+
+ return ResizeNone;
+}
+
+QRect getSubControlRect(const QWasmWindow *window, QWasmCompositor::SubControls subControl)
+{
+ QWasmCompositor::QWasmTitleBarOptions options = QWasmCompositor::makeTitleBarOptions(window);
+
+ QRect r = QWasmCompositor::titlebarRect(options, subControl);
+ r.translate(window->window()->frameGeometry().x(), window->window()->frameGeometry().y());
+
+ return r;
+}
+
+QRect QWasmWindow::maxButtonRect() const
+{
+ return getSubControlRect(this, QWasmCompositor::SC_TitleBarMaxButton);
+}
+
+QRect QWasmWindow::minButtonRect() const
+{
+ return getSubControlRect(this, QWasmCompositor::SC_TitleBarMinButton);
+}
+
+QRect QWasmWindow::closeButtonRect() const
+{
+ return getSubControlRect(this, QWasmCompositor::SC_TitleBarCloseButton);
+}
+
+QRect QWasmWindow::normButtonRect() const
+{
+ return getSubControlRect(this, QWasmCompositor::SC_TitleBarNormalButton);
+}
+
+QRect QWasmWindow::sysMenuRect() const
+{
+ return getSubControlRect(this, QWasmCompositor::SC_TitleBarSysMenu);
+}
+
+QRegion QWasmWindow::titleControlRegion() const
+{
+ QRegion result;
+ result += closeButtonRect();
+ result += minButtonRect();
+ result += maxButtonRect();
+ result += sysMenuRect();
+
+ return result;
+}
+
+void QWasmWindow::invalidate()
+{
+ m_compositor->requestRedraw();
+}
+
+QWasmCompositor::SubControls QWasmWindow::activeSubControl() const
+{
+ return m_activeControl;
+}
+
+void QWasmWindow::setWindowState(Qt::WindowStates states)
+{
+ m_windowState = Qt::WindowNoState;
+ if (states & Qt::WindowMinimized)
+ m_windowState = Qt::WindowMinimized;
+ else if (states & Qt::WindowFullScreen)
+ m_windowState = Qt::WindowFullScreen;
+ else if (states & Qt::WindowMaximized)
+ m_windowState = Qt::WindowMaximized;
+}
+
+QRect QWasmWindow::normalGeometry() const
+{
+ return m_normalGeometry;
+}
+
+qreal QWasmWindow::devicePixelRatio() const
+{
+ return screen()->devicePixelRatio();
+}
+
+void QWasmWindow::requestUpdate()
+{
+ QPointer<QWindow> windowPointer(window());
+ bool registered = QWasmEventDispatcher::registerRequestUpdateCallback([=](){
+ if (windowPointer.isNull())
+ return;
+
+ deliverUpdateRequest();
+ });
+
+ if (!registered)
+ QPlatformWindow::requestUpdate();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h
new file mode 100644
index 0000000000..a0c463e796
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmwindow.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMWINDOW_H
+#define QWASMWINDOW_H
+
+#include "qwasmintegration.h"
+#include <qpa/qplatformwindow.h>
+#include <emscripten/html5.h>
+#include "qwasmbackingstore.h"
+#include "qwasmscreen.h"
+#include "qwasmcompositor.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWasmCompositor;
+
+class QWasmWindow : public QPlatformWindow
+{
+public:
+ enum ResizeMode {
+ ResizeNone,
+ ResizeTopLeft,
+ ResizeTop,
+ ResizeTopRight,
+ ResizeRight,
+ ResizeBottomRight,
+ ResizeBottom,
+ ResizeBottomLeft,
+ ResizeLeft
+ };
+
+ QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore);
+ ~QWasmWindow();
+
+ void initialize() override;
+
+ void setGeometry(const QRect &) override;
+ void setVisible(bool visible) override;
+ QMargins frameMargins() const override;
+
+ WId winId() const override;
+
+ void propagateSizeHints() override;
+ void raise() override;
+ void lower() override;
+ QRect normalGeometry() const override;
+ qreal devicePixelRatio() const override;
+ void requestUpdate() override;
+
+ QWasmScreen *platformScreen() const;
+ void setBackingStore(QWasmBackingStore *store) { m_backingStore = store; }
+ QWasmBackingStore *backingStore() const { return m_backingStore; }
+ QWindow *window() const { return m_window; }
+
+ void injectMousePressed(const QPoint &local, const QPoint &global,
+ Qt::MouseButton button, Qt::KeyboardModifiers mods);
+ void injectMouseReleased(const QPoint &local, const QPoint &global,
+ Qt::MouseButton button, Qt::KeyboardModifiers mods);
+
+ int titleHeight() const;
+ int borderWidth() const;
+ QRegion titleGeometry() const;
+ QRegion resizeRegion() const;
+ bool isPointOnTitle(QPoint point) const;
+ bool isPointOnResizeRegion(QPoint point) const;
+ ResizeMode resizeModeAtPoint(QPoint point) const;
+ QRect maxButtonRect() const;
+ QRect minButtonRect() const;
+ QRect closeButtonRect() const;
+ QRect sysMenuRect() const;
+ QRect normButtonRect() const;
+ QRegion titleControlRegion() const;
+ QWasmCompositor::SubControls activeSubControl() const;
+
+ void setWindowState(Qt::WindowStates state) override;
+ bool setKeyboardGrabEnabled(bool) override { return false; }
+ bool setMouseGrabEnabled(bool) override { return false; }
+
+protected:
+ void invalidate();
+
+protected:
+ friend class QWasmScreen;
+
+ QWindow* m_window = nullptr;
+ QWasmCompositor *m_compositor = nullptr;
+ QWasmBackingStore *m_backingStore = nullptr;
+ QRect m_normalGeometry {0, 0, 0 ,0};
+
+ Qt::WindowState m_windowState = Qt::WindowNoState;
+ QWasmCompositor::SubControls m_activeControl = QWasmCompositor::SC_None;
+ WId m_winid = 0;
+ bool m_hasTitle = false;
+ bool m_needsCompositor = false;
+};
+QT_END_NAMESPACE
+#endif // QWASMWINDOW_H
diff --git a/src/plugins/platforms/wasm/wasm.json b/src/plugins/platforms/wasm/wasm.json
new file mode 100644
index 0000000000..6e700e06b9
--- /dev/null
+++ b/src/plugins/platforms/wasm/wasm.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "wasm" ]
+}
diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro
new file mode 100644
index 0000000000..f1205702ef
--- /dev/null
+++ b/src/plugins/platforms/wasm/wasm.pro
@@ -0,0 +1,65 @@
+TARGET = wasm
+CONFIG += static plugin
+QT += \
+ core-private gui-private \
+ eventdispatcher_support-private fontdatabase_support-private egl_support-private
+
+# Avoid X11 header collision, use generic EGL native types
+DEFINES += QT_EGL_NO_X11
+
+SOURCES = \
+ main.cpp \
+ qwasmintegration.cpp \
+ qwasmwindow.cpp \
+ qwasmscreen.cpp \
+ qwasmfontdatabase.cpp \
+ qwasmeventtranslator.cpp \
+ qwasmeventdispatcher.cpp \
+ qwasmcompositor.cpp \
+ qwasmcursor.cpp \
+ qwasmopenglcontext.cpp \
+ qwasmtheme.cpp
+
+HEADERS = \
+ qwasmintegration.h \
+ qwasmwindow.h \
+ qwasmscreen.h \
+ qwasmfontdatabase.h \
+ qwasmeventtranslator.h \
+ qwasmeventdispatcher.h \
+ qwasmcompositor.h \
+ qwasmstylepixmaps_p.h \
+ qwasmcursor.h \
+ qwasmopenglcontext.h \
+ qwasmtheme.h
+
+wasmfonts.files = \
+ ../../../3rdparty/wasm/Vera.ttf \
+ ../../../3rdparty/wasm/DejaVuSans.ttf
+wasmfonts.prefix = /fonts
+wasmfonts.base = ../../../3rdparty/wasm
+RESOURCES += wasmfonts
+
+qtConfig(opengl) {
+ SOURCES += qwasmbackingstore.cpp
+ HEADERS += qwasmbackingstore.h
+}
+CONFIG += egl
+
+OTHER_FILES += \
+ wasm.json \
+ wasm_shell.html \
+ qtloader.js
+
+shell_files.path = $$[QT_INSTALL_PLUGINS]/platforms
+shell_files.files = \
+ wasm_shell.html \
+ qtloader.js \
+ qtlogo.svg
+
+INSTALLS += shell_files
+
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QWasmIntegrationPlugin
+!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
+load(qt_plugin)
diff --git a/src/plugins/platforms/wasm/wasm_shell.html b/src/plugins/platforms/wasm/wasm_shell.html
new file mode 100644
index 0000000000..67bfcdfbdc
--- /dev/null
+++ b/src/plugins/platforms/wasm/wasm_shell.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<html lang="en-us">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>APPNAME</title>
+ <style>
+ html, body { padding: 0; margin : 0; overflow:hidden; height: 100% }
+ /* the canvas *must not* have any border or padding, or mouse coords will be wrong */
+ canvas { border: 0px none; background-color: white; height:100%; width:100%; }
+ </style>
+ </head>
+ <body onload="init()">
+ <figure style="overflow:visible;" id="spinner">
+ <center style="margin-top:1.5em; line-height:150%">
+ <img src="qtlogo.svg"; width=320; height=200; style="display:block"> </img>
+ <strong>Qt for WebAssembly: APPNAME</strong>
+ <div id="status"></div>
+ <noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
+ </center>
+ </figure>
+ <canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
+
+ <script type='text/javascript'>
+ function init() {
+ var spinner = document.getElementById('spinner');
+ var canvas = document.getElementById('canvas');
+ var status = document.getElementById('status')
+
+ var qtLoader = QtLoader({
+ showLoader: function(loaderStatus) {
+ spinner.style.display = 'block';
+ canvas.style.display = 'none';
+ status.innerHTML = loaderStatus + "...";
+ },
+ showError: function(errorText) {
+ status.innerHTML = errorText;
+ spinner.style.display = 'block';
+ canvas.style.display = 'none';
+ },
+ showExit: function() {
+ status.innerHTML = "Application exit";
+ if (qtLoader.exitCode !== undefined)
+ status.innerHTML += " with code " + qtLoader.exitCode;
+ if (qtLoader.exitText !== undefined)
+ status.innerHTML += " (" + qtLoader.exitText + ")";
+ spinner.style.display = 'block';
+ canvas.style.display = 'none';
+ },
+ showCanvas: function() {
+ spinner.style.display = 'none';
+ canvas.style.display = 'block';
+ return canvas;
+ },
+ });
+ qtLoader.loadEmscriptenModule("APPNAME");
+ }
+ </script>
+ <script type="text/javascript" src="qtloader.js"></script>
+ </body>
+</html>
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp
index 980de88e72..8bde87c975 100644
--- a/src/plugins/platforms/windows/main.cpp
+++ b/src/plugins/platforms/windows/main.cpp
@@ -39,7 +39,7 @@
#include <qpa/qplatformintegrationplugin.h>
-#include <QtCore/QStringList>
+#include <QtCore/qstringlist.h>
#include "qwindowsgdiintegration.h"
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index d1e9f85247..b618d8567a 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -141,6 +141,18 @@
"features": [
"disable_desktopgl", "disable_d3d11", "disable_d3d9"
]
+ },
+ {
+ "id": 12,
+ "description": "Intel HD Graphics 620 crash in conjunction with shader caches (QTBUG-64697)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x5916" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_program_cache"
+ ]
}
]
}
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 6c44541314..985f13bdc5 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -60,6 +60,22 @@
# define WM_DPICHANGED 0x02E0
#endif
+// WM_POINTER support from Windows 8 onwards (WINVER >= 0x0602)
+#ifndef WM_POINTERUPDATE
+# define WM_NCPOINTERUPDATE 0x0241
+# define WM_NCPOINTERDOWN 0x0242
+# define WM_NCPOINTERUP 0x0243
+# define WM_POINTERUPDATE 0x0245
+# define WM_POINTERDOWN 0x0246
+# define WM_POINTERUP 0x0247
+# define WM_POINTERENTER 0x0249
+# define WM_POINTERLEAVE 0x024A
+# define WM_POINTERACTIVATE 0x024B
+# define WM_POINTERCAPTURECHANGED 0x024C
+# define WM_POINTERWHEEL 0x024E
+# define WM_POINTERHWHEEL 0x024F
+#endif // WM_POINTERUPDATE
+
QT_BEGIN_NAMESPACE
namespace QtWindows
@@ -78,6 +94,7 @@ enum
ApplicationEventFlag = 0x1000000,
ThemingEventFlag = 0x2000000,
GenericEventFlag = 0x4000000, // Misc
+ PointerEventFlag = 0x8000000,
};
enum WindowsEventType // Simplify event types
@@ -103,13 +120,16 @@ enum WindowsEventType // Simplify event types
DpiChangedEvent = WindowEventFlag + 21,
EnterSizeMoveEvent = WindowEventFlag + 22,
ExitSizeMoveEvent = WindowEventFlag + 23,
+ PointerActivateWindowEvent = WindowEventFlag + 24,
MouseEvent = MouseEventFlag + 1,
MouseWheelEvent = MouseEventFlag + 2,
CursorEvent = MouseEventFlag + 3,
TouchEvent = TouchEventFlag + 1,
+ PointerEvent = PointerEventFlag + 1,
NonClientMouseEvent = NonClientEventFlag + MouseEventFlag + 1,
NonClientHitTest = NonClientEventFlag + 2,
NonClientCreate = NonClientEventFlag + 3,
+ NonClientPointerEvent = NonClientEventFlag + PointerEventFlag + 4,
KeyEvent = KeyEventFlag + 1,
KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1,
KeyboardLayoutChangeEvent = KeyEventFlag + 2,
@@ -167,6 +187,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
QtWindows::ActivateApplicationEvent : QtWindows::DeactivateApplicationEvent;
case WM_MOUSEACTIVATE:
return QtWindows::MouseActivateWindowEvent;
+ case WM_POINTERACTIVATE:
+ return QtWindows::PointerActivateWindowEvent;
case WM_ACTIVATE:
return LOWORD(wParamIn) == WA_INACTIVE ?
QtWindows::DeactivateWindowEvent : QtWindows::ActivateWindowEvent;
@@ -297,6 +319,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
if ((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST)
|| (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK))
return QtWindows::MouseEvent;
+ if (message >= WM_NCPOINTERUPDATE && message <= WM_NCPOINTERUP)
+ return QtWindows::NonClientPointerEvent;
+ if (message >= WM_POINTERUPDATE && message <= WM_POINTERHWHEEL)
+ return QtWindows::PointerEvent;
return QtWindows::UnknownEvent;
}
diff --git a/src/plugins/platforms/windows/qwin10helpers.cpp b/src/plugins/platforms/windows/qwin10helpers.cpp
index 5976fd23c0..cc17d8798f 100644
--- a/src/plugins/platforms/windows/qwin10helpers.cpp
+++ b/src/plugins/platforms/windows/qwin10helpers.cpp
@@ -39,8 +39,8 @@
#include "qwin10helpers.h"
-#include <QtCore/QDebug>
-#include <QtCore/QOperatingSystemVersion>
+#include <QtCore/qdebug.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/private/qsystemlibrary_p.h>
#if defined(Q_CC_MINGW) || defined(Q_CC_CLANG)
diff --git a/src/plugins/platforms/windows/qwin10helpers.h b/src/plugins/platforms/windows/qwin10helpers.h
index e1485003dd..4f364dfc59 100644
--- a/src/plugins/platforms/windows/qwin10helpers.h
+++ b/src/plugins/platforms/windows/qwin10helpers.h
@@ -40,7 +40,7 @@
#ifndef QWIN10HELPERS_H
#define QWIN10HELPERS_H
-#include <QtCore/QtGlobal>
+#include <QtCore/qglobal.h>
#include <QtCore/qt_windows.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 80872c3ea3..03b44458ac 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -41,13 +41,13 @@
#include "qwindowswindow.h"
#include "qwindowscontext.h"
-#include <QtGui/QWindow>
-#include <QtGui/QPainter>
+#include <QtGui/qwindow.h>
+#include <QtGui/qpainter.h>
#include <QtFontDatabaseSupport/private/qwindowsnativeimage_p.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qimage_p.h>
-#include <QtCore/QDebug>
+#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
index 9e62266697..088ab3b257 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.h
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -43,7 +43,7 @@
#include <QtCore/qt_windows.h>
#include <qpa/qplatformbackingstore.h>
-#include <QtCore/QScopedPointer>
+#include <QtCore/qscopedpointer.h>
QT_BEGIN_NAMESPACE
@@ -55,7 +55,7 @@ class QWindowsBackingStore : public QPlatformBackingStore
Q_DISABLE_COPY(QWindowsBackingStore)
public:
QWindowsBackingStore(QWindow *window);
- ~QWindowsBackingStore();
+ ~QWindowsBackingStore() override;
QPaintDevice *paintDevice() override;
void flush(QWindow *window, const QRegion &region, const QPoint &offset) override;
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 01191a7dc1..53f329422c 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -42,16 +42,16 @@
#include "qwindowsole.h"
#include "qwindowsmime.h"
-#include <QtGui/QGuiApplication>
-#include <QtGui/QClipboard>
-#include <QtGui/QColor>
-#include <QtGui/QImage>
-
-#include <QtCore/QDebug>
-#include <QtCore/QMimeData>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-#include <QtCore/QUrl>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qclipboard.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qimage.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qmimedata.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qurl.h>
#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.h b/src/plugins/platforms/windows/qwindowsclipboard.h
index 4f3e7437f6..469d638b89 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.h
+++ b/src/plugins/platforms/windows/qwindowsclipboard.h
@@ -58,9 +58,10 @@ protected:
class QWindowsClipboard : public QPlatformClipboard
{
+ Q_DISABLE_COPY(QWindowsClipboard)
public:
QWindowsClipboard();
- ~QWindowsClipboard();
+ ~QWindowsClipboard() override;
void registerViewer(); // Call in initialization, when context is up.
void cleanup();
diff --git a/src/plugins/platforms/windows/qwindowscombase.h b/src/plugins/platforms/windows/qwindowscombase.h
index 5e51b6b7b7..6b25d665dc 100644
--- a/src/plugins/platforms/windows/qwindowscombase.h
+++ b/src/plugins/platforms/windows/qwindowscombase.h
@@ -40,7 +40,7 @@
#ifndef QWINDOWSCOMBASE_H
#define QWINDOWSCOMBASE_H
-#include <QtCore/QtGlobal>
+#include <QtCore/qglobal.h>
#include <unknwn.h>
@@ -83,7 +83,7 @@ template <class ComInterface> class QWindowsComBase : public ComInterface
Q_DISABLE_COPY(QWindowsComBase)
public:
explicit QWindowsComBase(ULONG initialRefCount = 1) : m_ref(initialRefCount) {}
- virtual ~QWindowsComBase() {}
+ virtual ~QWindowsComBase() = default;
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface)
{
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 1da39a0516..373758b49e 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -43,6 +43,7 @@
#include "qwindowswindow.h"
#include "qwindowskeymapper.h"
#include "qwindowsmousehandler.h"
+#include "qwindowspointerhandler.h"
#include "qtwindowsglobal.h"
#include "qwindowsmenu.h"
#include "qwindowsmime.h"
@@ -52,7 +53,7 @@
#endif
#include "qwindowstheme.h"
#include <private/qguiapplication_p.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
# include "uiautomation/qwindowsuiaaccessibility.h"
#endif
#if QT_CONFIG(sessionmanager)
@@ -62,20 +63,20 @@
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
-#include <QtGui/qtguiglobal.h>
-#include <QtGui/QWindow>
+#include <QtGui/qwindow.h>
#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qwindowsysteminterface_p.h>
#include <qpa/qplatformnativeinterface.h>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QOpenGLContext>
-
-#include <QtCore/QSet>
-#include <QtCore/QHash>
-#include <QtCore/QStringList>
-#include <QtCore/QDebug>
-#include <QtCore/QOperatingSystemVersion>
-#include <QtCore/QSysInfo>
-#include <QtCore/QScopedArrayPointer>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qopenglcontext.h>
+
+#include <QtCore/qset.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qoperatingsystemversion.h>
+#include <QtCore/qsysinfo.h>
+#include <QtCore/qscopedpointer.h>
#include <QtCore/private/qsystemlibrary_p.h>
#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
@@ -89,7 +90,6 @@
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows")
-Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore")
Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
Q_LOGGING_CATEGORY(lcQpaGl, "qt.qpa.gl")
Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime")
@@ -194,6 +194,19 @@ void QWindowsUser32DLL::init()
getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences");
setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences");
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8) {
+ enableMouseInPointer = (EnableMouseInPointer)library.resolve("EnableMouseInPointer");
+ getPointerType = (GetPointerType)library.resolve("GetPointerType");
+ getPointerInfo = (GetPointerInfo)library.resolve("GetPointerInfo");
+ getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects");
+ getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo");
+ getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo");
+ getPointerFrameTouchInfoHistory = (GetPointerFrameTouchInfoHistory)library.resolve("GetPointerFrameTouchInfoHistory");
+ getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo");
+ getPointerPenInfoHistory = (GetPointerPenInfoHistory)library.resolve("GetPointerPenInfoHistory");
+ skipPointerFrameMessages = (SkipPointerFrameMessages)library.resolve("SkipPointerFrameMessages");
+ }
+
if (QOperatingSystemVersion::current()
>= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 14393)) {
enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling");
@@ -202,6 +215,13 @@ void QWindowsUser32DLL::init()
}
}
+bool QWindowsUser32DLL::supportsPointerApi()
+{
+ return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects
+ && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerFrameTouchInfoHistory
+ && getPointerPenInfo && getPointerPenInfoHistory && skipPointerFrameMessages;
+}
+
void QWindowsShcoreDLL::init()
{
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
@@ -239,6 +259,7 @@ struct QWindowsContextPrivate {
int m_defaultDPI = 96;
QWindowsKeyMapper m_keyMapper;
QWindowsMouseHandler m_mouseHandler;
+ QWindowsPointerHandler m_pointerHandler;
QWindowsMimeConverter m_mimeConverter;
QWindowsScreenManager m_screenManager;
QSharedPointer<QWindowCreationContext> m_creationContext;
@@ -256,7 +277,7 @@ QWindowsContextPrivate::QWindowsContextPrivate()
QWindowsContext::user32dll.init();
QWindowsContext::shcoredll.init();
- if (m_mouseHandler.touchDevice())
+ if (m_pointerHandler.touchDevice() || m_mouseHandler.touchDevice())
m_systemInfo |= QWindowsContext::SI_SupportsTouch;
m_displayContext = GetDC(0);
m_defaultDPI = GetDeviceCaps(m_displayContext, LOGPIXELSY);
@@ -281,10 +302,6 @@ QWindowsContext::QWindowsContext() :
const QByteArray bv = qgetenv("QT_QPA_VERBOSE");
if (!bv.isEmpty())
QLoggingCategory::setFilterRules(QString::fromLocal8Bit(bv));
-#if QT_CONFIG(tabletevent)
- d->m_tabletSupport.reset(QWindowsTabletSupport::create());
- qCDebug(lcQpaTablet) << "Tablet support: " << (d->m_tabletSupport.isNull() ? QStringLiteral("None") : d->m_tabletSupport->description());
-#endif
}
QWindowsContext::~QWindowsContext()
@@ -310,12 +327,17 @@ bool QWindowsContext::initTouch(unsigned integrationOptions)
if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
return true;
- QTouchDevice *touchDevice = d->m_mouseHandler.ensureTouchDevice();
+ QTouchDevice *touchDevice = (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) ?
+ d->m_pointerHandler.ensureTouchDevice() : d->m_mouseHandler.ensureTouchDevice();
if (!touchDevice)
return false;
- if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch))
- touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
+ if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) {
+ QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
+ } else {
+ if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch))
+ touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
+ }
QWindowSystemInterface::registerTouchDevice(touchDevice);
@@ -330,6 +352,33 @@ bool QWindowsContext::initTouch(unsigned integrationOptions)
return true;
}
+bool QWindowsContext::initTablet(unsigned integrationOptions)
+{
+ Q_UNUSED(integrationOptions);
+#if QT_CONFIG(tabletevent)
+ d->m_tabletSupport.reset(QWindowsTabletSupport::create());
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool QWindowsContext::initPointer(unsigned integrationOptions)
+{
+ if (integrationOptions & QWindowsIntegration::DontUseWMPointer)
+ return false;
+
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8)
+ return false;
+
+ if (!QWindowsContext::user32dll.supportsPointerApi())
+ return false;
+
+ QWindowsContext::user32dll.enableMouseInPointer(TRUE);
+ d->m_systemInfo |= QWindowsContext::SI_SupportsPointer;
+ return true;
+}
+
void QWindowsContext::setTabletAbsoluteRange(int a)
{
#if QT_CONFIG(tabletevent)
@@ -340,6 +389,11 @@ void QWindowsContext::setTabletAbsoluteRange(int a)
#endif
}
+void QWindowsContext::setDetectAltGrModifier(bool a)
+{
+ d->m_keyMapper.setDetectAltGrModifier(a);
+}
+
int QWindowsContext::processDpiAwareness()
{
int result;
@@ -548,7 +602,7 @@ void QWindowsContext::unregisterWindowClasses()
{
const HINSTANCE appInstance = static_cast<HINSTANCE>(GetModuleHandle(0));
- foreach (const QString &name, d->m_registeredWindowClassNames) {
+ for (const QString &name : qAsConst(d->m_registeredWindowClassNames)) {
if (!UnregisterClass(reinterpret_cast<LPCWSTR>(name.utf16()), appInstance) && QWindowsContext::verbose)
qErrnoWarning("UnregisterClass failed for '%s'", qPrintable(name));
}
@@ -632,12 +686,16 @@ QWindow *QWindowsContext::findWindow(HWND hwnd) const
QWindow *QWindowsContext::windowUnderMouse() const
{
- return d->m_mouseHandler.windowUnderMouse();
+ return (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) ?
+ d->m_pointerHandler.windowUnderMouse() : d->m_mouseHandler.windowUnderMouse();
}
void QWindowsContext::clearWindowUnderMouse()
{
- d->m_mouseHandler.clearWindowUnderMouse();
+ if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer)
+ d->m_pointerHandler.clearWindowUnderMouse();
+ else
+ d->m_mouseHandler.clearWindowUnderMouse();
}
/*!
@@ -958,7 +1016,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
switch (et) {
case QtWindows::GestureEvent:
- return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateGestureEvent(platformWindow->window(), hwnd, et, msg, result);
+ if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer))
+ return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateGestureEvent(platformWindow->window(), hwnd, et, msg, result);
+ break;
case QtWindows::InputMethodOpenCandidateWindowEvent:
case QtWindows::InputMethodCloseCandidateWindowEvent:
// TODO: Release/regrab mouse if a popup has mouse grab.
@@ -975,7 +1035,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::UnknownEvent:
return false;
case QtWindows::AccessibleObjectFromWindowRequest:
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
return QWindowsUiaAccessibility::handleWmGetObject(hwnd, wParam, lParam, result);
#else
return false;
@@ -1084,18 +1144,25 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::ExposeEvent:
return platformWindow->handleWmPaint(hwnd, message, wParam, lParam);
case QtWindows::NonClientMouseEvent:
- if (platformWindow->frameStrutEventsEnabled())
+ if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled())
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
break;
+ case QtWindows::NonClientPointerEvent:
+ if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled())
+ return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
+ break;
case QtWindows::EnterSizeMoveEvent:
platformWindow->setFlag(QWindowsWindow::ResizeMoveActive);
return true;
case QtWindows::ExitSizeMoveEvent:
platformWindow->clearFlag(QWindowsWindow::ResizeMoveActive);
platformWindow->checkForScreenChanged();
+ handleExitSizeMove(platformWindow->window());
return true;
case QtWindows::ScrollEvent:
- return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result);
+ if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer))
+ return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result);
+ break;
case QtWindows::MouseWheelEvent:
case QtWindows::MouseEvent:
case QtWindows::LeaveEvent:
@@ -1105,10 +1172,20 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
window = window->parent();
if (!window)
return false;
- return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result);
+ if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer))
+ return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result);
+ else
+ return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result);
}
+ break;
case QtWindows::TouchEvent:
- return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result);
+ if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer))
+ return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result);
+ break;
+ case QtWindows::PointerEvent:
+ if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer)
+ return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
+ break;
case QtWindows::FocusInEvent: // see QWindowsWindow::requestActivateWindow().
case QtWindows::FocusOutEvent:
handleFocusEvent(et, platformWindow);
@@ -1151,6 +1228,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
}
break;
case QtWindows::MouseActivateWindowEvent:
+ case QtWindows::PointerActivateWindowEvent:
if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
*result = LRESULT(MA_NOACTIVATE);
return true;
@@ -1295,6 +1373,37 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg)
}
#endif
+void QWindowsContext::handleExitSizeMove(QWindow *window)
+{
+ // Windows can be moved/resized by:
+ // 1) User moving a window by dragging the title bar: Causes a sequence
+ // of WM_NCLBUTTONDOWN, WM_NCMOUSEMOVE but no WM_NCLBUTTONUP,
+ // leaving the left mouse button 'pressed'
+ // 2) User choosing Resize/Move from System menu and using mouse/cursor keys:
+ // No mouse events are received
+ // 3) Programmatically via QSizeGrip calling QPlatformWindow::startSystemResize/Move():
+ // Mouse is left in pressed state after press on size grip (inside window),
+ // no further mouse events are received
+ // For cases 1,3, intercept WM_EXITSIZEMOVE to sync the buttons.
+ const Qt::MouseButtons currentButtons = QWindowsMouseHandler::queryMouseButtons();
+ const Qt::MouseButtons appButtons = QGuiApplication::mouseButtons();
+ if (currentButtons == appButtons)
+ return;
+ const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
+ const QPoint globalPos = QWindowsCursor::mousePosition();
+ const QPlatformWindow *platWin = window->handle();
+ const QPoint localPos = platWin->mapFromGlobal(globalPos);
+ const QEvent::Type type = platWin->geometry().contains(globalPos)
+ ? QEvent::MouseButtonRelease : QEvent::NonClientAreaMouseButtonRelease;
+ for (Qt::MouseButton button : {Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}) {
+ if (appButtons.testFlag(button) && !currentButtons.testFlag(button)) {
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
+ currentButtons, button, type,
+ keyboardModifiers);
+ }
+ }
+}
+
bool QWindowsContext::asyncExpose() const
{
return d->m_asyncExpose;
@@ -1307,7 +1416,8 @@ void QWindowsContext::setAsyncExpose(bool value)
QTouchDevice *QWindowsContext::touchDevice() const
{
- return d->m_mouseHandler.touchDevice();
+ return (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) ?
+ d->m_pointerHandler.touchDevice() : d->m_mouseHandler.touchDevice();
}
static DWORD readDwordRegistrySetting(const wchar_t *regKey, const wchar_t *subKey, DWORD defaultValue)
@@ -1400,7 +1510,7 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR
marginsFromRects(ncCalcSizeFrame, rectFromNcCalcSize(message, wParam, lParam, 0));
if (margins.left() >= 0) {
if (platformWindow) {
- platformWindow->setFrameMargins(margins);
+ platformWindow->setFullFrameMargins(margins);
} else {
const QSharedPointer<QWindowCreationContext> ctx = QWindowsContext::instance()->windowCreationContext();
if (!ctx.isNull())
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 0a7f20ca83..622c729a10 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -43,9 +43,9 @@
#include "qtwindowsglobal.h"
#include <QtCore/qt_windows.h>
-#include <QtCore/QScopedPointer>
-#include <QtCore/QSharedPointer>
-#include <QtCore/QLoggingCategory>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qloggingcategory.h>
#define STRICT_TYPED_ITEMIDS
#include <shlobj.h>
@@ -57,7 +57,6 @@ struct _SHSTOCKICONINFO;
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaWindows)
-Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore)
Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents)
Q_DECLARE_LOGGING_CATEGORY(lcQpaGl)
Q_DECLARE_LOGGING_CATEGORY(lcQpaMime)
@@ -85,7 +84,18 @@ class QTouchDevice;
struct QWindowsUser32DLL
{
inline void init();
-
+ inline bool supportsPointerApi();
+
+ typedef BOOL (WINAPI *EnableMouseInPointer)(BOOL);
+ typedef BOOL (WINAPI *GetPointerType)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerInfo)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *);
+ typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID);
+ typedef BOOL (WINAPI *GetPointerFrameTouchInfoHistory)(UINT32, UINT32 *, UINT32 *, PVOID);
+ typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID);
+ typedef BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32, UINT32 *, PVOID);
+ typedef BOOL (WINAPI *SkipPointerFrameMessages)(UINT32);
typedef BOOL (WINAPI *SetProcessDPIAware)();
typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
@@ -95,6 +105,18 @@ struct QWindowsUser32DLL
typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND);
typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int);
+ // Windows pointer functions (Windows 8 or later).
+ EnableMouseInPointer enableMouseInPointer = nullptr;
+ GetPointerType getPointerType = nullptr;
+ GetPointerInfo getPointerInfo = nullptr;
+ GetPointerDeviceRects getPointerDeviceRects = nullptr;
+ GetPointerTouchInfo getPointerTouchInfo = nullptr;
+ GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr;
+ GetPointerFrameTouchInfoHistory getPointerFrameTouchInfoHistory = nullptr;
+ GetPointerPenInfo getPointerPenInfo = nullptr;
+ GetPointerPenInfoHistory getPointerPenInfoHistory = nullptr;
+ SkipPointerFrameMessages skipPointerFrameMessages = nullptr;
+
// Windows Vista onwards
SetProcessDPIAware setProcessDPIAware = nullptr;
@@ -134,7 +156,8 @@ public:
enum SystemInfoFlags
{
SI_RTL_Extensions = 0x1,
- SI_SupportsTouch = 0x2
+ SI_SupportsTouch = 0x2,
+ SI_SupportsPointer = 0x4,
};
// Verbose flag set by environment variable QT_QPA_VERBOSE
@@ -145,6 +168,8 @@ public:
bool initTouch();
bool initTouch(unsigned integrationOptions); // For calls from QWindowsIntegration::QWindowsIntegration() only.
+ bool initTablet(unsigned integrationOptions);
+ bool initPointer(unsigned integrationOptions);
int defaultDPI() const;
@@ -191,6 +216,8 @@ public:
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
static int processDpiAwareness();
+ void setDetectAltGrModifier(bool a);
+
// Returns a combination of SystemInfoFlags
unsigned systemInfo() const;
@@ -220,6 +247,7 @@ private:
#ifndef QT_NO_CONTEXTMENU
bool handleContextMenuEvent(QWindow *window, const MSG &msg);
#endif
+ void handleExitSizeMove(QWindow *window);
void unregisterWindowClasses();
QScopedPointer<QWindowsContextPrivate> d;
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 72155a1d1b..4f669a5509 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -43,16 +43,16 @@
#include "qwindowswindow.h"
#include "qwindowsscreen.h"
-#include <QtGui/QBitmap>
-#include <QtGui/QImage>
-#include <QtGui/QBitmap>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QScreen>
+#include <QtGui/qbitmap.h>
+#include <QtGui/qimage.h>
+#include <QtGui/qbitmap.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qscreen.h>
#include <QtGui/private/qguiapplication_p.h> // getPixmapCursor()
#include <QtGui/private/qhighdpiscaling_p.h>
-#include <QtCore/QDebug>
-#include <QtCore/QScopedArrayPointer>
+#include <QtCore/qdebug.h>
+#include <QtCore/qscopedpointer.h>
static bool initResources()
{
@@ -524,10 +524,11 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape, const
}
// Load available standard cursors from resources
- const QWindowsStandardCursorMapping *sEnd = standardCursors + sizeof(standardCursors) / sizeof(standardCursors[0]);
- for (const QWindowsStandardCursorMapping *s = standardCursors; s < sEnd; ++s) {
- if (s->shape == cursorShape)
- return static_cast<HCURSOR>(LoadImage(0, s->resource, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED));
+ for (const QWindowsStandardCursorMapping &s : standardCursors) {
+ if (s.shape == cursorShape) {
+ return static_cast<HCURSOR>(LoadImage(nullptr, s.resource, IMAGE_CURSOR,
+ 0, 0, LR_DEFAULTSIZE | LR_SHARED));
+ }
}
qWarning("%s: Invalid cursor shape %d", __FUNCTION__, cursorShape);
@@ -659,18 +660,18 @@ QPoint QWindowsCursor::mousePosition()
return QPoint(p.x, p.y);
}
-QWindowsCursor::CursorState QWindowsCursor::cursorState()
+QWindowsCursor::State QWindowsCursor::cursorState()
{
enum { cursorShowing = 0x1, cursorSuppressed = 0x2 }; // Windows 8: CURSOR_SUPPRESSED
CURSORINFO cursorInfo;
cursorInfo.cbSize = sizeof(CURSORINFO);
if (GetCursorInfo(&cursorInfo)) {
- if (cursorInfo.flags & CursorShowing)
- return CursorShowing;
+ if (cursorInfo.flags & cursorShowing)
+ return State::Showing;
if (cursorInfo.flags & cursorSuppressed)
- return CursorSuppressed;
+ return State::Suppressed;
}
- return CursorHidden;
+ return State::Hidden;
}
QPoint QWindowsCursor::pos() const
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index 345f47597e..8495b51a5a 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -43,8 +43,8 @@
#include <QtCore/qt_windows.h>
#include <qpa/qplatformcursor.h>
-#include <QtCore/QSharedPointer>
-#include <QtCore/QHash>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE
@@ -89,10 +89,10 @@ typedef QSharedPointer<CursorHandle> CursorHandlePtr;
class QWindowsCursor : public QPlatformCursor
{
public:
- enum CursorState {
- CursorShowing,
- CursorHidden,
- CursorSuppressed // Cursor suppressed by touch interaction (Windows 8).
+ enum class State {
+ Showing,
+ Hidden,
+ Suppressed // Cursor suppressed by touch interaction (Windows 8).
};
struct PixmapCursor {
@@ -119,7 +119,7 @@ public:
static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = nullptr);
static QPoint mousePosition();
- static CursorState cursorState();
+ static State cursorState();
CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
CursorHandlePtr pixmapWindowCursor(const QCursor &c);
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 80ee7b2287..681b35eb7c 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -51,24 +51,23 @@
#include "qwindowsintegration.h"
#include "qwindowstheme.h" // Color conversion helpers
-#include <QtGui/QGuiApplication>
-#include <QtGui/QColor>
-
-#include <QtCore/QDebug>
-#include <QtCore/QRegularExpression>
-#include <QtCore/QTimer>
-#include <QtCore/QDir>
-#include <QtCore/QScopedArrayPointer>
-#include <QtCore/QSharedPointer>
-#include <QtCore/QObject>
-#include <QtCore/QThread>
-#include <QtCore/QSysInfo>
-#include <QtCore/QSharedData>
-#include <QtCore/QExplicitlySharedDataPointer>
-#include <QtCore/QMutex>
-#include <QtCore/QMutexLocker>
-#include <QtCore/QUuid>
-#include <QtCore/QTemporaryFile>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qcolor.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qregularexpression.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qsysinfo.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/quuid.h>
+#include <QtCore/qtemporaryfile.h>
#include <QtCore/private/qsystemlibrary_p.h>
#include <algorithm>
@@ -365,7 +364,7 @@ static BOOL QT_WIN_CALLBACK findDialogEnumWindowsProc(HWND hwnd, LPARAM lParam)
wchar_t buf[256];
if (!RealGetWindowClass(hwnd, buf, sizeof(buf)/sizeof(wchar_t)) || buf[0] != L'#')
return TRUE;
- if (!GetWindowTextW(hwnd, buf, sizeof(buf)/sizeof(wchar_t)) || wcscmp(buf, context->title.data()))
+ if (!GetWindowTextW(hwnd, buf, sizeof(buf)/sizeof(wchar_t)) || wcscmp(buf, context->title.data()) != 0)
return TRUE;
context->hwnd = hwnd;
return FALSE;
@@ -508,6 +507,7 @@ class QWindowsNativeFileDialogBase;
class QWindowsNativeFileDialogEventHandler : public QWindowsComBase<IFileDialogEvents>
{
+ Q_DISABLE_COPY(QWindowsNativeFileDialogEventHandler)
public:
static IFileDialogEvents *create(QWindowsNativeFileDialogBase *nativeFileDialog);
@@ -523,7 +523,6 @@ public:
QWindowsNativeFileDialogEventHandler(QWindowsNativeFileDialogBase *nativeFileDialog) :
m_nativeFileDialog(nativeFileDialog) {}
- virtual ~QWindowsNativeFileDialogEventHandler() {}
private:
QWindowsNativeFileDialogBase *m_nativeFileDialog;
@@ -787,7 +786,7 @@ class QWindowsNativeFileDialogBase : public QWindowsNativeDialogBase
Q_OBJECT
Q_PROPERTY(bool hideFiltersDetails READ hideFiltersDetails WRITE setHideFiltersDetails)
public:
- ~QWindowsNativeFileDialogBase();
+ ~QWindowsNativeFileDialogBase() override;
inline static QWindowsNativeFileDialogBase *create(QFileDialogOptions::AcceptMode am, const QWindowsFileDialogSharedData &data);
@@ -1027,7 +1026,7 @@ static QList<FilterSpec> filterSpecs(const QStringList &filters,
Q_ASSERT(filterSeparatorRE.isValid());
// Split filter specification as 'Texts (*.txt[;] *.doc)', '*.txt[;] *.doc'
// into description and filters specification as '*.txt;*.doc'
- foreach (const QString &filterString, filters) {
+ for (const QString &filterString : filters) {
const int openingParenPos = filterString.lastIndexOf(QLatin1Char('('));
const int closingParenPos = openingParenPos != -1 ?
filterString.indexOf(QLatin1Char(')'), openingParenPos + 1) : -1;
@@ -1322,7 +1321,7 @@ void QWindowsNativeSaveFileDialog::setNameFilters(const QStringList &f)
// filter only if a default suffix is set (see docs). Set the first available
// suffix unless we have a defaultSuffix.
if (!hasDefaultSuffix()) {
- foreach (const QString &filter, f) {
+ for (const QString &filter : f) {
const QString suffix = suffixFromFilter(filter);
if (!suffix.isEmpty()) {
setDefaultSuffixSys(suffix);
@@ -1546,8 +1545,8 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
result->updateDirectory();
result->updateSelectedNameFilter();
const QList<QUrl> initialSelection = opts->initiallySelectedFiles();
- if (initialSelection.size() > 0) {
- const QUrl url = initialSelection.front();
+ if (!initialSelection.empty()) {
+ const QUrl &url = initialSelection.constFirst();
if (url.isLocalFile()) {
QFileInfo info(url.toLocalFile());
if (!info.isDir())
@@ -1699,7 +1698,7 @@ void QWindowsXpNativeFileDialog::doExec(HWND owner)
const QStringList nameFilters = m_options->nameFilters();
if (selectedFilterIndex >= 0 && selectedFilterIndex < nameFilters.size())
m_data.setSelectedNameFilter(nameFilters.at(selectedFilterIndex));
- QUrl firstFile = selectedFiles.front();
+ const QUrl &firstFile = selectedFiles.constFirst();
m_data.setDirectory(firstFile.adjusted(QUrl::RemoveFilename));
m_result = QPlatformDialogHelper::Accepted;
emit accepted();
@@ -1728,7 +1727,7 @@ int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM
switch (uMsg) {
case BFFM_INITIALIZED: {
if (!m_title.isEmpty())
- SetWindowText(hwnd, (wchar_t *)m_title.utf16());
+ SetWindowText(hwnd, reinterpret_cast<const wchar_t *>(m_title.utf16()));
const QString initialFile = QDir::toNativeSeparators(m_data.directory().toLocalFile());
if (!initialFile.isEmpty())
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initialFile.utf16()));
@@ -1781,12 +1780,12 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow
// Create a buffer with the filter strings.
int totalStringLength = 0;
- QList<FilterSpec> specs =
+ const QList<FilterSpec> specs =
filterSpecs(m_options->nameFilters(), m_options->options() & QFileDialogOptions::HideNameFilterDetails, &totalStringLength);
const int size = specs.size();
wchar_t *ptr = new wchar_t[totalStringLength + 2 * size + 1];
ofn->lpstrFilter = ptr;
- foreach (const FilterSpec &spec, specs) {
+ for (const FilterSpec &spec : specs) {
ptr += spec.description.toWCharArray(ptr);
*ptr++ = 0;
ptr += spec.filter.toWCharArray(ptr);
@@ -1874,7 +1873,7 @@ QList<QUrl> QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedF
class QWindowsXpFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDialogHelper>
{
public:
- QWindowsXpFileDialogHelper() {}
+ QWindowsXpFileDialogHelper() = default;
bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const override { return false; }
bool defaultNameFilterDisables() const override
{ return true; }
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
index 55f112c57a..6099ea9ac6 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
@@ -43,8 +43,8 @@
#include <QtCore/qt_windows.h>
#include <qpa/qplatformdialoghelper.h>
#include <qpa/qplatformtheme.h>
-#include <QtCore/QStringList>
-#include <QtCore/QSharedPointer>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qsharedpointer.h>
QT_BEGIN_NAMESPACE
@@ -78,7 +78,7 @@ public:
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; }
protected:
- QWindowsDialogHelperBase() {}
+ QWindowsDialogHelperBase() = default;
QWindowsNativeDialogBase *nativeDialog() const;
inline bool hasNativeDialog() const { return m_nativeDialog; }
void timerEvent(QTimerEvent *) override;
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index e427ee162a..b7d225cb00 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -50,19 +50,19 @@
#include "qwindowsmousehandler.h"
#include "qwindowscursor.h"
-#include <QtGui/QMouseEvent>
-#include <QtGui/QPixmap>
-#include <QtGui/QPainter>
-#include <QtGui/QRasterWindow>
-#include <QtGui/QGuiApplication>
+#include <QtGui/qevent.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qrasterwindow.h>
+#include <QtGui/qguiapplication.h>
#include <qpa/qwindowsysteminterface_p.h>
#include <QtGui/private/qdnd_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
-#include <QtCore/QDebug>
-#include <QtCore/QBuffer>
-#include <QtCore/QPoint>
+#include <QtCore/qdebug.h>
+#include <QtCore/qbuffer.h>
+#include <QtCore/qpoint.h>
#include <shlobj.h>
@@ -225,7 +225,7 @@ public:
};
explicit QWindowsOleDropSource(QWindowsDrag *drag);
- virtual ~QWindowsOleDropSource();
+ ~QWindowsOleDropSource() override;
void createCursors();
@@ -260,7 +260,7 @@ private:
};
QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag)
- : m_mode(QWindowsCursor::cursorState() != QWindowsCursor::CursorSuppressed ? MouseDrag : TouchDrag)
+ : m_mode(QWindowsCursor::cursorState() != QWindowsCursor::State::Suppressed ? MouseDrag : TouchDrag)
, m_drag(drag)
, m_windowUnderMouse(QWindowsContext::instance()->windowUnderMouse())
, m_currentButtons(Qt::NoButton)
@@ -402,20 +402,16 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
switch (result) {
case DRAGDROP_S_DROP:
case DRAGDROP_S_CANCEL:
- QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState);
- if (buttons != QGuiApplicationPrivate::mouse_buttons) {
- if (m_windowUnderMouse.isNull() || m_mode == TouchDrag || fEscapePressed == TRUE) {
- QGuiApplicationPrivate::mouse_buttons = buttons;
- } else {
- // QTBUG 66447: Synthesize a mouse release to the window under mouse at
- // start of the DnD operation as Windows does not send any.
- const QPoint globalPos = QWindowsCursor::mousePosition();
- const QPoint localPos = m_windowUnderMouse->handle()->mapFromGlobal(globalPos);
- QWindowSystemInterface::handleMouseEvent(m_windowUnderMouse.data(),
- QPointF(localPos), QPointF(globalPos),
- QWindowsMouseHandler::queryMouseButtons(),
- Qt::LeftButton, QEvent::MouseButtonRelease);
- }
+ if (!m_windowUnderMouse.isNull() && m_mode != TouchDrag && fEscapePressed == FALSE
+ && buttons != QGuiApplicationPrivate::mouse_buttons) {
+ // QTBUG 66447: Synthesize a mouse release to the window under mouse at
+ // start of the DnD operation as Windows does not send any.
+ const QPoint globalPos = QWindowsCursor::mousePosition();
+ const QPoint localPos = m_windowUnderMouse->handle()->mapFromGlobal(globalPos);
+ QWindowSystemInterface::handleMouseEvent(m_windowUnderMouse.data(),
+ QPointF(localPos), QPointF(globalPos),
+ QWindowsMouseHandler::queryMouseButtons(),
+ Qt::LeftButton, QEvent::MouseButtonRelease);
}
m_currentButtons = Qt::NoButton;
break;
@@ -459,7 +455,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
break;
case TouchDrag:
// "Touch drag" with an unsuppressed cursor may happen with RDP (see createCursors())
- if (QWindowsCursor::cursorState() != QWindowsCursor::CursorSuppressed)
+ if (QWindowsCursor::cursorState() != QWindowsCursor::State::Suppressed)
SetCursor(nullptr);
if (!m_touchDragWindow)
m_touchDragWindow = new QWindowsDragCursorWindow;
@@ -507,11 +503,13 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
QWindowsDrag *windowsDrag = QWindowsDrag::instance();
const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
- QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState);
- QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(grfKeyState);
+ const Qt::KeyboardModifiers keyboardModifiers = toQtKeyboardModifiers(grfKeyState);
+ const Qt::MouseButtons mouseButtons = toQtMouseButtons(grfKeyState);
const QPlatformDragQtResponse response =
- QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions);
+ QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(),
+ m_lastPoint, actions,
+ mouseButtons, keyboardModifiers);
m_answerRect = response.answerRect();
const Qt::DropAction action = response.acceptedAction();
@@ -523,8 +521,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
*pdwEffect = m_chosenEffect;
qCDebug(lcQpaMime) << __FUNCTION__ << m_window
<< windowsDrag->dropData() << " supported actions=" << actions
- << " mods=" << QGuiApplicationPrivate::modifier_buttons
- << " mouse=" << QGuiApplicationPrivate::mouse_buttons
+ << " mods=" << keyboardModifiers << " mouse=" << mouseButtons
<< " accepted: " << response.isAccepted() << action
<< m_answerRect << " effect" << *pdwEffect;
}
@@ -575,13 +572,11 @@ QWindowsOleDropTarget::DragLeave()
qCDebug(lcQpaMime) << __FUNCTION__ << ' ' << m_window;
- QWindowSystemInterface::handleDrag(m_window, 0, QPoint(), Qt::IgnoreAction);
+ QWindowSystemInterface::handleDrag(m_window, 0, QPoint(), Qt::IgnoreAction,
+ Qt::NoButton, Qt::NoModifier);
- if (!QDragManager::self()->source()) {
- QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
- QGuiApplicationPrivate::mouse_buttons = Qt::NoButton;
+ if (!QDragManager::self()->source())
m_lastKeyState = 0;
- }
QWindowsDrag::instance()->releaseDropDataObject();
return NOERROR;
@@ -600,18 +595,16 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
<< "keys=" << grfKeyState << "pt=" << pt.x << ',' << pt.y;
m_lastPoint = QWindowsGeometryHint::mapFromGlobal(m_window, QPoint(pt.x,pt.y));
- // grfKeyState does not all ways contain button state in the drop
- QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(m_lastKeyState);
- QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState);
QWindowsDrag *windowsDrag = QWindowsDrag::instance();
const QPlatformDropQtResponse response =
QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(),
m_lastPoint,
- translateToQDragDropActions(*pdwEffect));
+ translateToQDragDropActions(*pdwEffect),
+ toQtMouseButtons(grfKeyState),
+ toQtKeyboardModifiers(grfKeyState));
- QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(grfKeyState);
m_lastKeyState = grfKeyState;
if (response.isAccepted()) {
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index d934679488..f116e50cbf 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -44,8 +44,8 @@
#include "qwindowsinternalmimedata.h"
#include <qpa/qplatformdrag.h>
+#include <QtGui/qpixmap.h>
#include <QtGui/qdrag.h>
-#include <QtGui/QPixmap>
struct IDropTargetHelper;
@@ -55,7 +55,7 @@ class QPlatformScreen;
class QWindowsDropMimeData : public QWindowsInternalMimeData {
public:
- QWindowsDropMimeData() {}
+ QWindowsDropMimeData() = default;
IDataObject *retrieveDataObject() const override;
};
@@ -63,7 +63,7 @@ class QWindowsOleDropTarget : public QWindowsComBase<IDropTarget>
{
public:
explicit QWindowsOleDropTarget(QWindow *w);
- virtual ~QWindowsOleDropTarget();
+ ~QWindowsOleDropTarget() override;
// IDropTarget methods
STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
diff --git a/src/plugins/platforms/windows/qwindowsdropdataobject.cpp b/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
index bd532ab70e..229ff92894 100644
--- a/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
+++ b/src/plugins/platforms/windows/qwindowsdropdataobject.cpp
@@ -39,8 +39,8 @@
#include "qwindowsdropdataobject.h"
-#include <QtCore/QUrl>
-#include <QtCore/QMimeData>
+#include <QtCore/qurl.h>
+#include <QtCore/qmimedata.h>
QT_BEGIN_NAMESPACE
@@ -60,9 +60,7 @@ QWindowsDropDataObject::QWindowsDropDataObject(QMimeData *mimeData) :
{
}
-QWindowsDropDataObject::~QWindowsDropDataObject()
-{
-}
+QWindowsDropDataObject::~QWindowsDropDataObject() = default;
STDMETHODIMP
QWindowsDropDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
diff --git a/src/plugins/platforms/windows/qwindowsdropdataobject.h b/src/plugins/platforms/windows/qwindowsdropdataobject.h
index 5ef72c9336..16ba7b036a 100644
--- a/src/plugins/platforms/windows/qwindowsdropdataobject.h
+++ b/src/plugins/platforms/windows/qwindowsdropdataobject.h
@@ -48,7 +48,7 @@ class QWindowsDropDataObject : public QWindowsOleDataObject
{
public:
explicit QWindowsDropDataObject(QMimeData *mimeData);
- virtual ~QWindowsDropDataObject();
+ ~QWindowsDropDataObject() override;
// overridden IDataObject methods
STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium);
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index 4632c9c157..52f3c56beb 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -41,8 +41,8 @@
#include "qwindowscontext.h"
#include "qwindowswindow.h"
-#include <QtCore/QDebug>
-#include <QtGui/QOpenGLContext>
+#include <QtCore/qdebug.h>
+#include <QtGui/qopenglcontext.h>
#if defined(QT_OPENGL_ES_2_ANGLE) || defined(QT_OPENGL_DYNAMIC)
# include <EGL/eglext.h>
@@ -889,19 +889,19 @@ EGLConfig QWindowsEGLContext::chooseConfig(const QSurfaceFormat &format)
EGLint green = 0;
EGLint blue = 0;
EGLint alpha = 0;
- for (int i = 0; i < configs.size(); ++i) {
+ for (const EGLConfig &config : configs) {
if (confAttrRed)
- QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, configs[i], EGL_RED_SIZE, &red);
+ QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red);
if (confAttrGreen)
- QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, configs[i], EGL_GREEN_SIZE, &green);
+ QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green);
if (confAttrBlue)
- QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, configs[i], EGL_BLUE_SIZE, &blue);
+ QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue);
if (confAttrAlpha)
- QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, configs[i], EGL_ALPHA_SIZE, &alpha);
+ QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha);
if (red == confAttrRed && green == confAttrGreen
&& blue == confAttrBlue && alpha == confAttrAlpha)
- return configs[i];
+ return config;
}
} while (reduceConfigAttributes(&configureAttributes));
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h
index 3e5f2c81d5..8a1e1ddae8 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.h
+++ b/src/plugins/platforms/windows/qwindowseglcontext.h
@@ -113,7 +113,7 @@ class QWindowsEGLStaticContext : public QWindowsStaticOpenGLContext
public:
static QWindowsEGLStaticContext *create(QWindowsOpenGLTester::Renderers preferredType);
- ~QWindowsEGLStaticContext();
+ ~QWindowsEGLStaticContext() override;
EGLDisplay display() const { return m_display; }
@@ -143,7 +143,7 @@ public:
QWindowsEGLContext(QWindowsEGLStaticContext *staticContext,
const QSurfaceFormat &format,
QPlatformOpenGLContext *share);
- ~QWindowsEGLContext();
+ ~QWindowsEGLContext() override;
bool makeCurrent(QPlatformSurface *surface) override;
void doneCurrent() override;
diff --git a/src/plugins/platforms/windows/qwindowsgdiintegration.cpp b/src/plugins/platforms/windows/qwindowsgdiintegration.cpp
index 51f74518f7..c88f669eb5 100644
--- a/src/plugins/platforms/windows/qwindowsgdiintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsgdiintegration.cpp
@@ -42,7 +42,7 @@
#include "qwindowsbackingstore.h"
#include "qwindowsgdinativeinterface.h"
-#include <QtCore/QDebug>
+#include <QtCore/qdebug.h>
#include <QtGui/private/qpixmap_raster_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsgdiintegration.h b/src/plugins/platforms/windows/qwindowsgdiintegration.h
index ec67a99bc9..74ce3ffd49 100644
--- a/src/plugins/platforms/windows/qwindowsgdiintegration.h
+++ b/src/plugins/platforms/windows/qwindowsgdiintegration.h
@@ -49,7 +49,7 @@ class QWindowsGdiIntegration : public QWindowsIntegration
{
public:
explicit QWindowsGdiIntegration(const QStringList &paramList);
- virtual ~QWindowsGdiIntegration();
+ ~QWindowsGdiIntegration() override;
QPlatformNativeInterface *nativeInterface() const override;
QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const override;
diff --git a/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp b/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp
index c7796d959e..4ba7108f45 100644
--- a/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp
@@ -40,7 +40,7 @@
#include "qwindowsgdinativeinterface.h"
#include "qwindowsbackingstore.h"
-#include <QtGui/QBackingStore>
+#include <QtGui/qbackingstore.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index cc8174051a..851a6c961e 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -42,11 +42,11 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
-#include <QtCore/QDebug>
-#include <QtCore/QSysInfo>
-#include <QtGui/QGuiApplication>
+#include <QtCore/qdebug.h>
+#include <QtCore/qsysinfo.h>
+#include <QtGui/qguiapplication.h>
#include <qpa/qplatformnativeinterface.h>
-#include <QtPlatformHeaders/QWGLNativeContext>
+#include <QtPlatformHeaders/qwglnativecontext.h>
#include <algorithm>
@@ -206,18 +206,12 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering)
BOOL QWindowsOpengl32DLL::swapBuffers(HDC dc)
{
- if (moduleIsNotOpengl32())
- return wglSwapBuffers(dc);
- else
- return SwapBuffers(dc);
+ return moduleIsNotOpengl32() ? wglSwapBuffers(dc) : SwapBuffers(dc);
}
BOOL QWindowsOpengl32DLL::setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd)
{
- if (moduleIsNotOpengl32())
- return wglSetPixelFormat(dc, pf, pfd);
- else
- return SetPixelFormat(dc, pf, pfd);
+ return moduleIsNotOpengl32() ? wglSetPixelFormat(dc, pf, pfd) : SetPixelFormat(dc, pf, pfd);
}
QWindowsOpenGLContext *QOpenGLStaticContext::createContext(QOpenGLContext *context)
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 87c3723c26..199f8112e3 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -43,7 +43,7 @@
#include <QtCore/qt_windows.h>
#include "qwindowsopenglcontext.h"
-#include <QtGui/QOpenGLContext>
+#include <QtGui/qopenglcontext.h>
#include <vector>
@@ -170,13 +170,15 @@ public:
static QOpenGLStaticContext *create(bool softwareRendering = false);
static QByteArray getGlString(unsigned int which);
- QWindowsOpenGLContext *createContext(QOpenGLContext *context);
- void *moduleHandle() const { return opengl32.moduleHandle(); }
- QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGL; }
+ QWindowsOpenGLContext *createContext(QOpenGLContext *context) override;
+ void *moduleHandle() const override { return opengl32.moduleHandle(); }
+ QOpenGLContext::OpenGLModuleType moduleType() const override
+ { return QOpenGLContext::LibGL; }
// For a regular opengl32.dll report the ThreadedOpenGL capability.
// For others, which are likely to be software-only, don't.
- bool supportsThreadedOpenGL() const { return !opengl32.moduleIsNotOpengl32(); }
+ bool supportsThreadedOpenGL() const override
+ { return !opengl32.moduleIsNotOpengl32(); }
const QByteArray vendor;
const QByteArray renderer;
@@ -198,7 +200,7 @@ class QWindowsGLContext : public QWindowsOpenGLContext
{
public:
explicit QWindowsGLContext(QOpenGLStaticContext *staticContext, QOpenGLContext *context);
- ~QWindowsGLContext();
+ ~QWindowsGLContext() override;
bool isSharing() const override { return m_context->shareHandle(); }
bool isValid() const override { return m_renderingContext && !m_lost; }
QSurfaceFormat format() const override { return m_obtainedFormat; }
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 261c931f2b..30da0da1de 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -43,16 +43,15 @@
#include "qwindowsintegration.h"
#include "qwindowsmousehandler.h"
-#include <QtCore/QDebug>
-#include <QtCore/QObject>
-#include <QtCore/QRect>
-#include <QtCore/QRectF>
-#include <QtCore/QTextBoundaryFinder>
-
-#include <QtGui/QInputMethodEvent>
-#include <QtGui/QTextCharFormat>
-#include <QtGui/QPalette>
-#include <QtGui/QGuiApplication>
+#include <QtCore/qdebug.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qtextboundaryfinder.h>
+
+#include <QtGui/qevent.h>
+#include <QtGui/qtextformat.h>
+#include <QtGui/qpalette.h>
+#include <QtGui/qguiapplication.h>
#include <private/qhighdpiscaling_p.h>
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h
index d647628ff1..a47585c29e 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.h
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.h
@@ -42,8 +42,8 @@
#include <QtCore/qt_windows.h>
-#include <QtCore/QLocale>
-#include <QtCore/QPointer>
+#include <QtCore/qlocale.h>
+#include <QtCore/qpointer.h>
#include <qpa/qplatforminputcontext.h>
QT_BEGIN_NAMESPACE
@@ -53,6 +53,7 @@ class QWindowsWindow;
class QWindowsInputContext : public QPlatformInputContext
{
+ Q_DISABLE_COPY(QWindowsInputContext)
Q_OBJECT
struct CompositionContext
@@ -65,7 +66,7 @@ class QWindowsInputContext : public QPlatformInputContext
};
public:
explicit QWindowsInputContext();
- ~QWindowsInputContext();
+ ~QWindowsInputContext() override;
static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled);
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 0a9e8b9d91..7d621126b9 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -59,7 +59,7 @@
#endif
#include "qwindowsinputcontext.h"
#include "qwindowskeymapper.h"
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
# include "uiautomation/qwindowsuiaaccessibility.h"
#endif
@@ -76,8 +76,8 @@
#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
-#include <QtCore/QDebug>
-#include <QtCore/QVariant>
+#include <QtCore/qdebug.h>
+#include <QtCore/qvariant.h>
#include <limits.h>
@@ -133,6 +133,7 @@ QT_BEGIN_NAMESPACE
struct QWindowsIntegrationPrivate
{
+ Q_DISABLE_COPY(QWindowsIntegrationPrivate)
explicit QWindowsIntegrationPrivate(const QStringList &paramList);
~QWindowsIntegrationPrivate();
@@ -150,7 +151,7 @@ struct QWindowsIntegrationPrivate
QScopedPointer<QWindowsStaticOpenGLContext> m_staticOpenGLContext;
#endif // QT_NO_OPENGL
QScopedPointer<QPlatformInputContext> m_inputContext;
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QWindowsUiaAccessibility m_accessibility;
#endif
QWindowsServices m_services;
@@ -184,7 +185,7 @@ static inline unsigned parseOptions(const QStringList &paramList,
QtWindows::ProcessDpiAwareness *dpiAwareness)
{
unsigned options = 0;
- foreach (const QString &param, paramList) {
+ for (const QString &param : paramList) {
if (param.startsWith(QLatin1String("fontengine="))) {
if (param.endsWith(QLatin1String("freetype"))) {
options |= QWindowsIntegration::FontDatabaseFreeType;
@@ -197,6 +198,8 @@ static inline unsigned parseOptions(const QStringList &paramList,
} else if (param.endsWith(QLatin1String("none"))) {
options |= QWindowsIntegration::NoNativeDialogs;
}
+ } else if (param == QLatin1String("altgr")) {
+ options |= QWindowsIntegration::DetectAltGrModifier;
} else if (param == QLatin1String("gl=gdi")) {
options |= QWindowsIntegration::DisableArb;
} else if (param == QLatin1String("nodirectwrite")) {
@@ -212,6 +215,8 @@ static inline unsigned parseOptions(const QStringList &paramList,
options |= QWindowsIntegration::AlwaysUseNativeMenus;
} else if (param == QLatin1String("menus=none")) {
options |= QWindowsIntegration::NoNativeMenus;
+ } else if (param == QLatin1String("nowmpointer")) {
+ options |= QWindowsIntegration::DontUseWMPointer;
} else {
qWarning() << "Unknown option" << param;
}
@@ -230,8 +235,15 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
QtWindows::ProcessDpiAwareness dpiAwareness = QtWindows::ProcessPerMonitorDpiAware;
m_options = parseOptions(paramList, &tabletAbsoluteRange, &dpiAwareness);
QWindowsFontDatabase::setFontOptions(m_options);
- if (tabletAbsoluteRange >= 0)
- m_context.setTabletAbsoluteRange(tabletAbsoluteRange);
+
+ if (m_context.initPointer(m_options)) {
+ QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents);
+ } else {
+ m_context.initTablet(m_options);
+ if (tabletAbsoluteRange >= 0)
+ m_context.setTabletAbsoluteRange(tabletAbsoluteRange);
+ }
+
if (!dpiAwarenessSet) { // Set only once in case of repeated instantiations of QGuiApplication.
if (!QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
m_context.setProcessDpiAwareness(dpiAwareness);
@@ -248,8 +260,7 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate()
{
- if (m_fontDatabase)
- delete m_fontDatabase;
+ delete m_fontDatabase;
}
QWindowsIntegration *QWindowsIntegration::m_instance = nullptr;
@@ -262,6 +273,7 @@ QWindowsIntegration::QWindowsIntegration(const QStringList &paramList) :
d->m_clipboard.registerViewer();
#endif
d->m_context.screenManager().handleScreenChanges();
+ d->m_context.setDetectAltGrModifier((d->m_options & DetectAltGrModifier) != 0);
}
QWindowsIntegration::~QWindowsIntegration()
@@ -332,7 +344,7 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
<< "\n Requested: " << requested.geometry << " frame incl.="
<< QWindowsGeometryHint::positionIncludesFrame(window)
<< ' ' << requested.flags
- << "\n Obtained : " << obtained.geometry << " margins=" << obtained.frame
+ << "\n Obtained : " << obtained.geometry << " margins=" << obtained.fullFrameMargins
<< " handle=" << obtained.hwnd << ' ' << obtained.flags << '\n';
if (Q_UNLIKELY(!obtained.hwnd))
@@ -408,6 +420,10 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate()
}
const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers();
+ if (supportedRenderers.testFlag(QWindowsOpenGLTester::DisableProgramCacheFlag)
+ && !QCoreApplication::testAttribute(Qt::AA_DisableShaderDiskCache)) {
+ QCoreApplication::setAttribute(Qt::AA_DisableShaderDiskCache);
+ }
if (supportedRenderers & QWindowsOpenGLTester::DesktopGl) {
if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create()) {
if ((supportedRenderers & QWindowsOpenGLTester::DisableRotationFlag)
@@ -560,7 +576,7 @@ QPlatformInputContext * QWindowsIntegration::inputContext() const
return d->m_inputContext.data();
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QPlatformAccessibility *QWindowsIntegration::accessibility() const
{
return &d->m_accessibility;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 23f3d9ef4e..da86852766 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -42,7 +42,7 @@
#define QWINDOWSINTEGRATION_H
#include <qpa/qplatformintegration.h>
-#include <QtCore/QScopedPointer>
+#include <QtCore/qscopedpointer.h>
#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
QT_BEGIN_NAMESPACE
@@ -54,6 +54,7 @@ class QWindowsStaticOpenGLContext;
class QWindowsIntegration : public QPlatformIntegration
{
+ Q_DISABLE_COPY(QWindowsIntegration)
public:
enum Options { // Options to be passed on command line.
FontDatabaseFreeType = 0x1,
@@ -66,11 +67,13 @@ public:
DontUseDirectWriteFonts = QWindowsFontDatabase::DontUseDirectWriteFonts,
DontUseColorFonts = QWindowsFontDatabase::DontUseColorFonts,
AlwaysUseNativeMenus = 0x100,
- NoNativeMenus = 0x200
+ NoNativeMenus = 0x200,
+ DontUseWMPointer = 0x400,
+ DetectAltGrModifier = 0x800
};
explicit QWindowsIntegration(const QStringList &paramList);
- virtual ~QWindowsIntegration();
+ ~QWindowsIntegration() override;
bool hasCapability(QPlatformIntegration::Capability cap) const override;
@@ -90,7 +93,7 @@ public:
# endif
#endif // !QT_NO_CLIPBOARD
QPlatformInputContext *inputContext() const override;
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QPlatformAccessibility *accessibility() const override;
#endif
QPlatformFontDatabase *fontDatabase() const override;
diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
index 21ebee6262..8f1d8f73d9 100644
--- a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
@@ -40,7 +40,7 @@
#include "qwindowsinternalmimedata.h"
#include "qwindowscontext.h"
#include "qwindowsmime.h"
-#include <QDebug>
+#include <QtCore/qdebug.h>
/*!
\class QWindowsInternalMimeDataBase
\brief Base for implementations of QInternalMimeData using a IDataObject COM object.
diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.h b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
index a44f5b509c..dbc1ea3922 100644
--- a/src/plugins/platforms/windows/qwindowsinternalmimedata.h
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
@@ -43,7 +43,7 @@
#include <QtCore/qt_windows.h>
#include <QtGui/private/qinternalmimedata_p.h>
-#include <QtCore/QVariant>
+#include <QtCore/qvariant.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 950d8ecd36..1209b6c4b4 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -43,13 +43,14 @@
#include "qwindowswindow.h"
#include "qwindowsinputcontext.h"
-#include <QtGui/QGuiApplication>
-#include <QtGui/QWindow>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qwindow.h>
#include <qpa/qwindowsysteminterface.h>
#include <private/qguiapplication_p.h>
#include <private/qhighdpiscaling_p.h>
-#include <QtGui/QKeyEvent>
+#include <QtGui/qevent.h>
#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
+#include <QtCore/private/qdebug_p.h>
#if defined(WM_APPCOMMAND)
# ifndef FAPPCOMMAND_MOUSE
@@ -105,9 +106,7 @@ QWindowsKeyMapper::QWindowsKeyMapper()
changeKeyboard();
}
-QWindowsKeyMapper::~QWindowsKeyMapper()
-{
-}
+QWindowsKeyMapper::~QWindowsKeyMapper()= default;
#ifndef LANG_PASHTO
#define LANG_PASHTO 0x63
@@ -544,6 +543,59 @@ static const Qt::KeyboardModifiers ModsTbl[] = {
static const size_t NumMods = sizeof ModsTbl / sizeof *ModsTbl;
Q_STATIC_ASSERT((NumMods == KeyboardLayoutItem::NumQtKeys));
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const KeyboardLayoutItem &k)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << "KeyboardLayoutItem(";
+ if (k.exists) {
+ for (size_t i = 0; i < NumMods; ++i) {
+ if (const quint32 qtKey = k.qtKey[i]) {
+ d << '[' << i << ' ';
+ QtDebugUtils::formatQFlags(d, ModsTbl[i]);
+ d << ' ' << hex << showbase << qtKey << dec << noshowbase << ' ';
+ QtDebugUtils::formatQEnum(d, Qt::Key(qtKey));
+ if (qtKey >= 32 && qtKey < 128)
+ d << " '" << char(qtKey) << '\'';
+ if (k.deadkeys & (1<<i))
+ d << " deadkey";
+ d << "] ";
+ }
+ }
+ }
+ d << ')';
+ return d;
+}
+
+// Helpers to format a list of int as Qt key sequence
+class formatKeys
+{
+public:
+ explicit formatKeys(const QList<int> &keys) : m_keys(keys) {}
+
+private:
+ friend QDebug operator<<(QDebug d, const formatKeys &keys);
+ const QList<int> &m_keys;
+};
+
+QDebug operator<<(QDebug d, const formatKeys &k)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << '(';
+ for (int i =0, size = k.m_keys.size(); i < size; ++i) {
+ if (i)
+ d << ", ";
+ d << QKeySequence(k.m_keys.at(i));
+ }
+ d << ')';
+ return d;
+}
+#else // !QT_NO_DEBUG_STREAM
+static int formatKeys(const QList<int> &) { return 0; }
+#endif // QT_NO_DEBUG_STREAM
+
/**
Remap return or action key to select key for windows mobile.
*/
@@ -599,8 +651,8 @@ static inline int asciiToKeycode(char a, int state)
void QWindowsKeyMapper::deleteLayouts()
{
- for (size_t i = 0; i < NumKeyboardLayoutItems; ++i)
- keyLayout[i].exists = false;
+ for (KeyboardLayoutItem &k : keyLayout)
+ k.exists = false;
}
void QWindowsKeyMapper::changeKeyboard()
@@ -620,6 +672,7 @@ void QWindowsKeyMapper::changeKeyboard()
bidi = true;
keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight;
+ m_seenAltGr = false;
}
// Helper function that is used when obtaining the list of characters that can be produced by one key and
@@ -722,21 +775,8 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32
::ToAscii(VK_SPACE, 0, emptyBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
}
- if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
- QString message;
- QDebug debug(&message);
- debug <<__FUNCTION__ << " for virtual key = 0x" << hex << vk_key << dec<< '\n';
- for (size_t i = 0; i < NumMods; ++i) {
- const quint32 qtKey = keyLayout[vk_key].qtKey[i];
- debug << " [" << i << "] (" << qtKey << ','
- << hex << showbase << qtKey << noshowbase << dec
- << ",'" << char(qtKey ? qtKey : 0x03) << "')";
- if (keyLayout[vk_key].deadkeys & (1<<i))
- debug << " deadkey";
- debug << '\n';
- }
- qCDebug(lcQpaEvents) << message;
- }
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "for virtual key="
+ << hex << showbase << vk_key << dec << noshowbase << keyLayout[vk_key];
}
static inline QString messageKeyText(const MSG &msg)
@@ -867,8 +907,34 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
#endif
}
-bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &msg, bool /* grab */, LRESULT *lResult)
+// QTBUG-69317: Check for AltGr found on some keyboards
+// which is a sequence of left Ctrl (SYSKEY) + right Menu (Alt).
+static bool isAltGr(MSG *msg)
{
+ enum : LONG_PTR { RightFlag = 0x1000000 };
+ if (msg->wParam != VK_CONTROL || (msg->lParam & RightFlag) != 0
+ || (msg->message != WM_KEYDOWN && msg->message != WM_SYSKEYUP)) {
+ return false;
+ }
+ const UINT expectedMessage = msg->message == WM_SYSKEYUP
+ ? WM_KEYUP : msg->message;
+ MSG peekedMsg;
+ if (PeekMessage(&peekedMsg, msg->hwnd, 0, 0, PM_NOREMOVE) == FALSE
+ || peekedMsg.message != expectedMessage || peekedMsg.wParam != VK_MENU
+ || (peekedMsg.lParam & RightFlag) == 0) {
+ return false;
+ }
+ *msg = peekedMsg;
+ PeekMessage(&peekedMsg, msg->hwnd, 0, 0, PM_REMOVE);
+ return true;
+}
+
+bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg,
+ bool /* grab */, LRESULT *lResult)
+{
+ const bool altGr = m_detectAltGrModifier && isAltGr(&msg);
+ if (altGr)
+ m_seenAltGr = true;
const UINT msgType = msg.message;
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
@@ -897,10 +963,12 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
// Get the modifier states (may be altered later, depending on key code)
int state = 0;
state |= (nModifiers & ShiftAny ? int(Qt::ShiftModifier) : 0);
- state |= (nModifiers & ControlAny ? int(Qt::ControlModifier) : 0);
- state |= (nModifiers & AltAny ? int(Qt::AltModifier) : 0);
+ state |= (nModifiers & AltLeft ? int(Qt::AltModifier) : 0);
+ if ((nModifiers & AltRight) != 0)
+ state |= m_seenAltGr ? Qt::GroupSwitchModifier : Qt::AltModifier;
+ if ((nModifiers & ControlAny) != 0 && (state & Qt::GroupSwitchModifier) == 0)
+ state |= Qt::ControlModifier;
state |= (nModifiers & MetaAny ? int(Qt::MetaModifier) : 0);
-
// A multi-character key or a Input method character
// not found by our look-ahead
if (msgType == WM_CHAR || msgType == WM_IME_CHAR) {
@@ -971,8 +1039,17 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
modifiersIndex |= (nModifiers & ControlAny ? 0x2 : 0);
modifiersIndex |= (nModifiers & AltAny ? 0x4 : 0);
+ // Note: For the resulting key, AltGr is equivalent to Alt + Ctrl (as
+ // opposed to Linux); hence no entry in KeyboardLayoutItem is required
int code = keyLayout[vk_key].qtKey[modifiersIndex];
+ // If the bit 24 of lParm is set you received a enter,
+ // otherwise a Return. (This is the extended key bit)
+ if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
+ code = Qt::Key_Enter;
+ else if (altGr)
+ code = Qt::Key_AltGr;
+
// Invert state logic:
// If the key actually pressed is a modifier key, then we remove its modifier key from the
// state, since a modifier-key can't have itself as a modifier
@@ -982,11 +1059,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
state = state ^ Qt::ShiftModifier;
else if (code == Qt::Key_Alt)
state = state ^ Qt::AltModifier;
-
- // If the bit 24 of lParm is set you received a enter,
- // otherwise a Return. (This is the extended key bit)
- if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
- code = Qt::Key_Enter;
+ else if (code == Qt::Key_AltGr)
+ state = state ^ Qt::GroupSwitchModifier;
// All cursor keys without extended bit
if (!(msg.lParam & 0x1000000)) {
@@ -1070,7 +1144,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
if (uch.isHighSurrogate()) {
m_lastHighSurrogate = uch;
return true;
- } else if (uch.isLowSurrogate() && !m_lastHighSurrogate.isNull()) {
+ }
+ if (uch.isLowSurrogate() && !m_lastHighSurrogate.isNull()) {
if (QObject *focusObject = QGuiApplication::focusObject()) {
const QChar chars[2] = {m_lastHighSurrogate, uch};
QInputMethodEvent event;
@@ -1287,7 +1362,9 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
*it = matchedKey;
}
}
-
+ qCDebug(lcQpaEvents) << __FUNCTION__ << e << "nativeVirtualKey="
+ << showbase << hex << e->nativeVirtualKey() << dec << noshowbase
+ << e->modifiers() << kbItem << "\n returns" << formatKeys(result);
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h
index c6b46b0c30..a454f0f973 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.h
+++ b/src/plugins/platforms/windows/qwindowskeymapper.h
@@ -42,7 +42,7 @@
#include <QtCore/qt_windows.h>
-#include <QtCore/QLocale>
+#include <QtCore/qlocale.h>
QT_BEGIN_NAMESPACE
@@ -81,6 +81,9 @@ public:
void setUseRTLExtensions(bool e) { m_useRTLExtensions = e; }
bool useRTLExtensions() const { return m_useRTLExtensions; }
+ void setDetectAltGrModifier(bool a) { m_detectAltGrModifier = a; }
+ bool detectAltGrModifier() const { return m_detectAltGrModifier; }
+
bool translateKeyEvent(QWindow *widget, HWND hwnd, const MSG &msg, LRESULT *result);
QWindow *keyGrabber() const { return m_keyGrabber; }
@@ -90,7 +93,7 @@ public:
QList<int> possibleKeys(const QKeyEvent *e) const;
private:
- bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab, LRESULT *lResult);
+ bool translateKeyEventInternal(QWindow *receiver, MSG msg, bool grab, LRESULT *lResult);
bool translateMultimediaKeyEventInternal(QWindow *receiver, const MSG &msg);
void updateKeyMap(const MSG &msg);
@@ -106,6 +109,9 @@ private:
QChar m_lastHighSurrogate;
static const size_t NumKeyboardLayoutItems = 256;
KeyboardLayoutItem keyLayout[NumKeyboardLayoutItems];
+ bool m_detectAltGrModifier = false;
+ bool m_seenAltGr = false;
+
};
enum WindowsNativeModifiers {
diff --git a/src/plugins/platforms/windows/qwindowsmenu.h b/src/plugins/platforms/windows/qwindowsmenu.h
index d51a29676e..6de1553f35 100644
--- a/src/plugins/platforms/windows/qwindowsmenu.h
+++ b/src/plugins/platforms/windows/qwindowsmenu.h
@@ -44,8 +44,8 @@
#include <qpa/qplatformmenu.h>
-#include <QtCore/QVector>
-#include <QtCore/QPair>
+#include <QtCore/qvector.h>
+#include <QtCore/qpair.h>
QT_BEGIN_NAMESPACE
@@ -60,7 +60,7 @@ class QWindowsMenuItem : public QPlatformMenuItem
Q_OBJECT
public:
explicit QWindowsMenuItem(QWindowsMenu *parentMenu = nullptr);
- ~QWindowsMenuItem();
+ ~QWindowsMenuItem() override;
void setText(const QString &text) override;
void setIcon(const QIcon &icon) override;
@@ -199,7 +199,7 @@ public:
typedef QVector<QWindowsMenu *> Menus;
QWindowsMenuBar();
- ~QWindowsMenuBar();
+ ~QWindowsMenuBar() override;
void insertMenu(QPlatformMenu *menu, QPlatformMenu *before) override;
void removeMenu(QPlatformMenu *menu) override;
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index 0439797a7d..ff0dccb0d9 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -41,15 +41,15 @@
#include "qwindowscontext.h"
#include <QtGui/private/qinternalmimedata_p.h>
-#include <QtCore/QByteArrayMatcher>
-#include <QtCore/QTextCodec>
-#include <QtCore/QMap>
-#include <QtCore/QUrl>
-#include <QtCore/QDir>
-#include <QtCore/QDebug>
-#include <QtCore/QBuffer>
-#include <QtGui/QImageReader>
-#include <QtGui/QImageWriter>
+#include <QtCore/qbytearraymatcher.h>
+#include <QtCore/qtextcodec.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qbuffer.h>
+#include <QtGui/qimagereader.h>
+#include <QtGui/qimagewriter.h>
#include <shlobj.h>
#include <algorithm>
@@ -107,7 +107,8 @@ static inline QByteArray msgConversionError(const char *func, const char *format
msg += ": Unable to convert DIB image. The image converter plugin for '";
msg += format;
msg += "' is not available. Available formats: ";
- foreach (const QByteArray &af, QImageReader::supportedImageFormats()) {
+ const QList<QByteArray> &formats = QImageReader::supportedImageFormats();
+ for (const QByteArray &af : formats) {
msg += af;
msg += ' ';
}
@@ -487,17 +488,13 @@ QDebug operator<<(QDebug d, IDataObject *dataObj)
Constructs a new conversion object, adding it to the globally accessed
list of available converters.
*/
-QWindowsMime::QWindowsMime()
-{
-}
+QWindowsMime::QWindowsMime() = default;
/*!
Destroys a conversion object, removing it from the global
list of available converters.
*/
-QWindowsMime::~QWindowsMime()
-{
-}
+QWindowsMime::~QWindowsMime() = default;
/*!
Registers the MIME type \a mime, and returns an ID number
@@ -573,12 +570,12 @@ int QWindowsMime::registerMimeType(const QString &mime)
class QWindowsMimeText : public QWindowsMime
{
public:
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
- QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const;
- QString mimeForFormat(const FORMATETC &formatetc) const;
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override;
+ QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const override;
+ QString mimeForFormat(const FORMATETC &formatetc) const override;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const override;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override;
};
bool QWindowsMimeText::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
@@ -627,7 +624,8 @@ bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeDa
}
o[j]=0;
return setData(r, pmedium);
- } else if (cf == CF_UNICODETEXT) {
+ }
+ if (cf == CF_UNICODETEXT) {
QString str = mimeData->text();
const QChar *u = str.unicode();
QString res;
@@ -729,12 +727,12 @@ class QWindowsMimeURI : public QWindowsMime
{
public:
QWindowsMimeURI();
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
- QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const;
- QString mimeForFormat(const FORMATETC &formatetc) const;
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override;
+ QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const override;
+ QString mimeForFormat(const FORMATETC &formatetc) const override;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const override;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override;
private:
int CF_INETURL_W; // wide char version
int CF_INETURL;
@@ -749,9 +747,9 @@ QWindowsMimeURI::QWindowsMimeURI()
bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
{
if (mimeData->hasUrls() && getCf(formatetc) == CF_HDROP) {
- QList<QUrl> urls = mimeData->urls();
- for (int i=0; i<urls.size(); i++) {
- if (!urls.at(i).toLocalFile().isEmpty())
+ const QList<QUrl> urls = mimeData->urls();
+ for (const QUrl &url : urls) {
+ if (url.isLocalFile())
return true;
}
}
@@ -762,11 +760,11 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat
{
if (canConvertFromMime(formatetc, mimeData)) {
if (getCf(formatetc) == CF_HDROP) {
- QList<QUrl> urls = mimeData->urls();
+ const QList<QUrl> &urls = mimeData->urls();
QStringList fileNames;
int size = sizeof(DROPFILES)+2;
- for (int i=0; i<urls.size(); i++) {
- QString fn = QDir::toNativeSeparators(urls.at(i).toLocalFile());
+ for (const QUrl &url : urls) {
+ const QString fn = QDir::toNativeSeparators(url.toLocalFile());
if (!fn.isEmpty()) {
size += sizeof(ushort) * size_t(fn.length() + 1);
fileNames.append(fn);
@@ -791,7 +789,8 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat
*f = 0;
return setData(result, pmedium);
- } else if (getCf(formatetc) == CF_INETURL_W) {
+ }
+ if (getCf(formatetc) == CF_INETURL_W) {
QList<QUrl> urls = mimeData->urls();
QByteArray result;
if (!urls.isEmpty()) {
@@ -802,7 +801,8 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat
result.append('\0');
result.append('\0');
return setData(result, pmedium);
- } else if (getCf(formatetc) == CF_INETURL) {
+ }
+ if (getCf(formatetc) == CF_INETURL) {
QList<QUrl> urls = mimeData->urls();
QByteArray result;
if (!urls.isEmpty())
@@ -872,7 +872,7 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD
if (preferredType == QVariant::Url && urls.size() == 1)
return urls.at(0);
- else if (!urls.isEmpty())
+ if (!urls.isEmpty())
return urls;
} else if (canGetData(CF_INETURL_W, pDataObj)) {
QByteArray data = getData(CF_INETURL_W, pDataObj);
@@ -1075,10 +1075,8 @@ QString QWindowsMimeImage::mimeForFormat(const FORMATETC &formatetc) const
bool QWindowsMimeImage::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
{
- if (mimeType == QLatin1String("application/x-qt-image") &&
- (canGetData(CF_DIB, pDataObj) || canGetData(CF_PNG, pDataObj)))
- return true;
- return false;
+ return mimeType == QLatin1String("application/x-qt-image")
+ && (canGetData(CF_DIB, pDataObj) || canGetData(CF_PNG, pDataObj));
}
bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
@@ -1134,7 +1132,7 @@ bool QWindowsMimeImage::hasOriginalDIBV5(IDataObject *pDataObj) const
CoTaskMemFree(fc.ptd);
if (fc.cfFormat == CF_DIB)
break;
- else if (fc.cfFormat == CF_DIBV5) {
+ if (fc.cfFormat == CF_DIBV5) {
isSynthesized = false;
break;
}
@@ -1328,7 +1326,7 @@ QStringList QLastResortMimes::excludeList;
QLastResortMimes::QLastResortMimes()
{
//MIME Media-Types
- if (!ianaTypes.size()) {
+ if (ianaTypes.isEmpty()) {
ianaTypes.append(QStringLiteral("application/"));
ianaTypes.append(QStringLiteral("audio/"));
ianaTypes.append(QStringLiteral("example/"));
@@ -1340,7 +1338,7 @@ QLastResortMimes::QLastResortMimes()
ianaTypes.append(QStringLiteral("video/"));
}
//Types handled by other classes
- if (!excludeList.size()) {
+ if (excludeList.isEmpty()) {
excludeList.append(QStringLiteral("HTML Format"));
excludeList.append(QStringLiteral("UniformResourceLocator"));
excludeList.append(QStringLiteral("text/html"));
@@ -1598,7 +1596,7 @@ QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
QVariant::Type preferredType,
QString *formatIn /* = 0 */) const
{
- foreach (const QString &format, mimeTypes) {
+ for (const QString &format : mimeTypes) {
if (const QWindowsMime *converter = converterToMime(format, pDataObj)) {
if (converter->canConvertToMime(format, pDataObj)) {
const QVariant dataV = converter->convertToMime(format, pDataObj, preferredType);
diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h
index 1ed2aa933f..6bbbae1a0e 100644
--- a/src/plugins/platforms/windows/qwindowsmime.h
+++ b/src/plugins/platforms/windows/qwindowsmime.h
@@ -42,9 +42,9 @@
#include <QtCore/qt_windows.h>
-#include <QtCore/QVector>
-#include <QtCore/QList>
-#include <QtCore/QVariant>
+#include <QtCore/qvector.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qvariant.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 17851618b4..c1c275144f 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -45,14 +45,14 @@
#include "qwindowsscreen.h"
#include <qpa/qwindowsysteminterface.h>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QScreen>
-#include <QtGui/QTouchDevice>
-#include <QtGui/QWindow>
-#include <QtGui/QCursor>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qtouchdevice.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qcursor.h>
-#include <QtCore/QDebug>
-#include <QtCore/QScopedArrayPointer>
+#include <QtCore/qdebug.h>
+#include <QtCore/qscopedpointer.h>
#include <windowsx.h>
@@ -119,20 +119,16 @@ static inline void compressMouseMove(MSG *msg)
static inline QTouchDevice *createTouchDevice()
{
- enum { QT_SM_TABLETPC = 86, QT_SM_DIGITIZER = 94, QT_SM_MAXIMUMTOUCHES = 95,
- QT_NID_INTEGRATED_TOUCH = 0x1, QT_NID_EXTERNAL_TOUCH = 0x02,
- QT_NID_MULTI_INPUT = 0x40, QT_NID_READY = 0x80 };
-
- const int digitizers = GetSystemMetrics(QT_SM_DIGITIZER);
- if (!(digitizers & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH)))
+ const int digitizers = GetSystemMetrics(SM_DIGITIZER);
+ if (!(digitizers & (NID_INTEGRATED_TOUCH | NID_EXTERNAL_TOUCH)))
return 0;
- const int tabletPc = GetSystemMetrics(QT_SM_TABLETPC);
- const int maxTouchPoints = GetSystemMetrics(QT_SM_MAXIMUMTOUCHES);
- qCDebug(lcQpaEvents) << "Digitizers:" << hex << showbase << (digitizers & ~QT_NID_READY)
- << "Ready:" << (digitizers & QT_NID_READY) << dec << noshowbase
+ const int tabletPc = GetSystemMetrics(SM_TABLETPC);
+ const int maxTouchPoints = GetSystemMetrics(SM_MAXIMUMTOUCHES);
+ qCDebug(lcQpaEvents) << "Digitizers:" << hex << showbase << (digitizers & ~NID_READY)
+ << "Ready:" << (digitizers & NID_READY) << dec << noshowbase
<< "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints;
QTouchDevice *result = new QTouchDevice;
- result->setType(digitizers & QT_NID_INTEGRATED_TOUCH
+ result->setType(digitizers & NID_INTEGRATED_TOUCH
? QTouchDevice::TouchScreen : QTouchDevice::TouchPad);
QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition;
if (result->type() == QTouchDevice::TouchPad)
@@ -178,22 +174,121 @@ Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
return result;
}
+static QPoint lastMouseMovePos;
+
+namespace {
+struct MouseEvent {
+ QEvent::Type type;
+ Qt::MouseButton button;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const MouseEvent &e)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << "MouseEvent(" << e.type << ", " << e.button << ')';
+ return d;
+}
+#endif // QT_NO_DEBUG_STREAM
+} // namespace
+
+static inline Qt::MouseButton extraButton(WPARAM wParam) // for WM_XBUTTON...
+{
+ return GET_XBUTTON_WPARAM(wParam) == XBUTTON1 ? Qt::BackButton : Qt::ForwardButton;
+}
+
+static inline MouseEvent eventFromMsg(const MSG &msg)
+{
+ switch (msg.message) {
+ case WM_MOUSEMOVE:
+ return {QEvent::MouseMove, Qt::NoButton};
+ case WM_LBUTTONDOWN:
+ return {QEvent::MouseButtonPress, Qt::LeftButton};
+ case WM_LBUTTONUP:
+ return {QEvent::MouseButtonRelease, Qt::LeftButton};
+ case WM_LBUTTONDBLCLK:
+ return {QEvent::MouseButtonDblClick, Qt::LeftButton};
+ case WM_MBUTTONDOWN:
+ return {QEvent::MouseButtonPress, Qt::MidButton};
+ case WM_MBUTTONUP:
+ return {QEvent::MouseButtonRelease, Qt::MidButton};
+ case WM_MBUTTONDBLCLK:
+ return {QEvent::MouseButtonDblClick, Qt::MidButton};
+ case WM_RBUTTONDOWN:
+ return {QEvent::MouseButtonPress, Qt::RightButton};
+ case WM_RBUTTONUP:
+ return {QEvent::MouseButtonRelease, Qt::RightButton};
+ case WM_RBUTTONDBLCLK:
+ return {QEvent::MouseButtonDblClick, Qt::RightButton};
+ case WM_XBUTTONDOWN:
+ return {QEvent::MouseButtonPress, extraButton(msg.wParam)};
+ case WM_XBUTTONUP:
+ return {QEvent::MouseButtonRelease, extraButton(msg.wParam)};
+ case WM_XBUTTONDBLCLK:
+ return {QEvent::MouseButtonDblClick, extraButton(msg.wParam)};
+ case WM_NCMOUSEMOVE:
+ return {QEvent::NonClientAreaMouseMove, Qt::NoButton};
+ case WM_NCLBUTTONDOWN:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton};
+ case WM_NCLBUTTONUP:
+ return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton};
+ case WM_NCLBUTTONDBLCLK:
+ return {QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton};
+ case WM_NCMBUTTONDOWN:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton};
+ case WM_NCMBUTTONUP:
+ return {QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton};
+ case WM_NCMBUTTONDBLCLK:
+ return {QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton};
+ case WM_NCRBUTTONDOWN:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton};
+ case WM_NCRBUTTONUP:
+ return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton};
+ case WM_NCRBUTTONDBLCLK:
+ return {QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton};
+ default: // WM_MOUSELEAVE
+ break;
+ }
+ return {QEvent::None, Qt::NoButton};
+}
+
bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
QtWindows::WindowsEventType et,
MSG msg, LRESULT *result)
{
-#ifdef Q_COMPILER_CLASS_ENUM
enum : quint64 { signatureMask = 0xffffff00, miWpSignature = 0xff515700 };
-#else
- static const quint64 signatureMask = 0xffffff00;
- static const quint64 miWpSignature = 0xff515700;
-#endif // !Q_COMPILER_CLASS_ENUM
if (et == QtWindows::MouseWheelEvent)
return translateMouseWheelEvent(window, hwnd, msg, result);
+ const QPoint winEventPosition(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
+ QPoint clientPosition;
+ QPoint globalPosition;
+ if (et & QtWindows::NonClientEventFlag) {
+ globalPosition = winEventPosition;
+ clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition);
+ } else {
+ clientPosition = winEventPosition;
+ globalPosition = QWindowsGeometryHint::mapToGlobal(hwnd, winEventPosition);
+ }
+
+ // Windows sends a mouse move with no buttons pressed to signal "Enter"
+ // when a window is shown over the cursor. Discard the event and only use
+ // it for generating QEvent::Enter to be consistent with other platforms -
+ // X11 and macOS.
+ bool discardEvent = false;
+ if (msg.message == WM_MOUSEMOVE) {
+ const bool samePosition = globalPosition == lastMouseMovePos;
+ lastMouseMovePos = globalPosition;
+ if (msg.wParam == 0 && (m_windowUnderMouse.isNull() || samePosition))
+ discardEvent = true;
+ }
+
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
+ const MouseEvent mouseEvent = eventFromMsg(msg);
+
// Check for events synthesized from touch. Lower byte is touch index, 0 means pen.
static const bool passSynthesizedMouseEvents =
!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch);
@@ -210,13 +305,11 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
}
- const QPoint winEventPosition(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
- if (et & QtWindows::NonClientEventFlag) {
- const QPoint globalPosition = winEventPosition;
- const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition);
+ if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
globalPosition, buttons,
+ mouseEvent.button, mouseEvent.type,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
return false; // Allow further event processing (dragging of windows).
@@ -224,7 +317,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
*result = 0;
if (msg.message == WM_MOUSELEAVE) {
- qCDebug(lcQpaEvents) << "WM_MOUSELEAVE for " << window << " previous window under mouse = " << m_windowUnderMouse << " tracked window =" << m_trackedWindow;
+ qCDebug(lcQpaEvents) << mouseEvent << "for" << window << "previous window under mouse="
+ << m_windowUnderMouse << "tracked window=" << m_trackedWindow;
// When moving out of a window, WM_MOUSEMOVE within the moved-to window is received first,
// so if m_trackedWindow is not the window here, it means the cursor has left the
@@ -264,12 +358,11 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
m_previousCaptureWindow = window;
return true;
- } else if (m_leftButtonDown && !actualLeftDown) {
- m_leftButtonDown = false;
}
+ if (m_leftButtonDown && !actualLeftDown)
+ m_leftButtonDown = false;
}
- const QPoint globalPosition = QWindowsGeometryHint::mapToGlobal(hwnd, winEventPosition);
// In this context, neither an invisible nor a transparent window (transparent regarding mouse
// events, "click-through") can be considered as the window under mouse.
QWindow *currentWindowUnderMouse = platformWindow->hasMouseCapture() ?
@@ -290,10 +383,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
// Qt expects the platform plugin to capture the mouse on
// any button press until release.
if (!platformWindow->hasMouseCapture()
- && (msg.message == WM_LBUTTONDOWN || msg.message == WM_MBUTTONDOWN
- || msg.message == WM_RBUTTONDOWN || msg.message == WM_XBUTTONDOWN
- || msg.message == WM_LBUTTONDBLCLK || msg.message == WM_MBUTTONDBLCLK
- || msg.message == WM_RBUTTONDBLCLK || msg.message == WM_XBUTTONDBLCLK)) {
+ && (mouseEvent.type == QEvent::MouseButtonPress || mouseEvent.type == QEvent::MouseButtonDblClick)) {
platformWindow->setMouseGrabEnabled(true);
platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
qCDebug(lcQpaEvents) << "Automatic mouse capture " << window;
@@ -302,8 +392,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
window->requestActivate();
} else if (platformWindow->hasMouseCapture()
&& platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)
- && (msg.message == WM_LBUTTONUP || msg.message == WM_MBUTTONUP
- || msg.message == WM_RBUTTONUP || msg.message == WM_XBUTTONUP)
+ && mouseEvent.type == QEvent::MouseButtonRelease
&& !buttons) {
platformWindow->setMouseGrabEnabled(false);
qCDebug(lcQpaEvents) << "Releasing automatic mouse capture " << window;
@@ -369,9 +458,12 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
m_windowUnderMouse = currentWindowUnderMouse;
}
- QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
- QWindowsKeyMapper::queryKeyboardModifiers(),
- source);
+ if (!discardEvent && mouseEvent.type != QEvent::None) {
+ QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
+ mouseEvent.button, mouseEvent.type,
+ QWindowsKeyMapper::queryKeyboardModifiers(),
+ source);
+ }
m_previousCaptureWindow = hasCapture ? window : 0;
// QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND
// is sent for unhandled WM_XBUTTONDOWN.
@@ -411,9 +503,10 @@ static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int del
}
if (handleEvent) {
+ const QPoint point = (orientation == Qt::Vertical) ? QPoint(0, delta) : QPoint(delta, 0);
QWindowSystemInterface::handleWheelEvent(receiver,
QWindowsGeometryHint::mapFromGlobal(receiver, globalPos),
- globalPos, delta, orientation, mods);
+ globalPos, QPoint(), point, mods);
}
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
index 86f18a0482..480662c9bf 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.h
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -43,8 +43,8 @@
#include "qtwindowsglobal.h"
#include <QtCore/qt_windows.h>
-#include <QtCore/QPointer>
-#include <QtCore/QHash>
+#include <QtCore/qpointer.h>
+#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index ffa100f824..de11356fd4 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -48,9 +48,9 @@
#include "qwindowsmime.h"
#include "qwin10helpers.h"
-#include <QtGui/QWindow>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QScreen>
+#include <QtGui/qwindow.h>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qscreen.h>
#include <qpa/qplatformscreen.h>
#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
@@ -111,15 +111,14 @@ void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resourc
return 0;
}
break;
- case QWindow::OpenGLSurface:
- case QWindow::OpenVGSurface:
- break;
case QWindow::VulkanSurface:
#if QT_CONFIG(vulkan)
if (type == VkSurface)
return bw->surface(nullptr, nullptr); // returns the address of the VkSurfaceKHR, not the value, as expected
#endif
break;
+ default:
+ break;
}
qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
return 0;
@@ -276,11 +275,11 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun
{
if (function == QWindowsWindowFunctions::setTouchWindowTouchTypeIdentifier())
return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic);
- else if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier())
+ if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier())
return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic);
- else if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier())
+ if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier())
return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior);
- else if (function == QWindowsWindowFunctions::isTabletModeIdentifier())
+ if (function == QWindowsWindowFunctions::isTabletModeIdentifier())
return QFunctionPointer(QWindowsNativeInterface::isTabletMode);
return nullptr;
}
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
index 0ceb0d82fa..ad0442c8bd 100644
--- a/src/plugins/platforms/windows/qwindowsole.cpp
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -41,14 +41,14 @@
#include "qwindowsmime.h"
#include "qwindowscontext.h"
\
-#include <QtGui/QMouseEvent>
-#include <QtGui/QWindow>
-#include <QtGui/QPainter>
-#include <QtGui/QCursor>
-#include <QtGui/QGuiApplication>
+#include <QtGui/qevent.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qcursor.h>
+#include <QtGui/qguiapplication.h>
-#include <QtCore/QMimeData>
-#include <QtCore/QDebug>
+#include <QtCore/qmimedata.h>
+#include <QtCore/qdebug.h>
#include <shlobj.h>
@@ -80,9 +80,7 @@ QWindowsOleDataObject::QWindowsOleDataObject(QMimeData *mimeData) :
qCDebug(lcQpaMime) << __FUNCTION__ << mimeData->formats();
}
-QWindowsOleDataObject::~QWindowsOleDataObject()
-{
-}
+QWindowsOleDataObject::~QWindowsOleDataObject() = default;
void QWindowsOleDataObject::releaseQt()
{
@@ -365,10 +363,9 @@ QWindowsOleEnumFmtEtc::Clone(LPENUMFORMATETC FAR* newEnum)
if (result->isNull()) {
delete result;
return ResultFromScode(E_OUTOFMEMORY);
- } else {
- *newEnum = result;
}
+ *newEnum = result;
return NOERROR;
}
diff --git a/src/plugins/platforms/windows/qwindowsole.h b/src/plugins/platforms/windows/qwindowsole.h
index fc58858f2c..6940657e88 100644
--- a/src/plugins/platforms/windows/qwindowsole.h
+++ b/src/plugins/platforms/windows/qwindowsole.h
@@ -43,9 +43,9 @@
#include "qwindowscombase.h"
#include <QtCore/qt_windows.h>
-#include <QtCore/QMap>
-#include <QtCore/QPointer>
-#include <QtCore/QVector>
+#include <QtCore/qmap.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qvector.h>
#include <objidl.h>
@@ -58,7 +58,7 @@ class QWindowsOleDataObject : public QWindowsComBase<IDataObject>
{
public:
explicit QWindowsOleDataObject(QMimeData *mimeData);
- virtual ~QWindowsOleDataObject();
+ ~QWindowsOleDataObject() override;
void releaseQt();
QMimeData *mimeData() const;
@@ -88,7 +88,7 @@ class QWindowsOleEnumFmtEtc : public QWindowsComBase<IEnumFORMATETC>
public:
explicit QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs);
explicit QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs);
- virtual ~QWindowsOleEnumFmtEtc();
+ ~QWindowsOleEnumFmtEtc() override;
bool isNull() const;
diff --git a/src/plugins/platforms/windows/qwindowsopenglcontext.h b/src/plugins/platforms/windows/qwindowsopenglcontext.h
index 85f4f717f5..cc6d93d35e 100644
--- a/src/plugins/platforms/windows/qwindowsopenglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsopenglcontext.h
@@ -40,7 +40,7 @@
#ifndef QWINDOWSOPENGLCONTEXT_H
#define QWINDOWSOPENGLCONTEXT_H
-#include <QtGui/QOpenGLContext>
+#include <QtGui/qopenglcontext.h>
#include <qpa/qplatformopenglcontext.h>
QT_BEGIN_NAMESPACE
@@ -51,9 +51,10 @@ class QWindowsOpenGLContext;
class QWindowsStaticOpenGLContext
{
+ Q_DISABLE_COPY(QWindowsStaticOpenGLContext)
public:
static QWindowsStaticOpenGLContext *create();
- virtual ~QWindowsStaticOpenGLContext() { }
+ virtual ~QWindowsStaticOpenGLContext() = default;
virtual QWindowsOpenGLContext *createContext(QOpenGLContext *context) = 0;
virtual void *moduleHandle() const = 0;
@@ -65,15 +66,17 @@ public:
virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/, int * /*err*/) { return 0; }
virtual void destroyWindowSurface(void * /*nativeSurface*/) { }
+protected:
+ QWindowsStaticOpenGLContext() = default;
+
private:
static QWindowsStaticOpenGLContext *doCreate();
};
class QWindowsOpenGLContext : public QPlatformOpenGLContext
{
+ Q_DISABLE_COPY(QWindowsOpenGLContext)
public:
- virtual ~QWindowsOpenGLContext() { }
-
// Returns the native context handle (e.g. HGLRC for WGL, EGLContext for EGL).
virtual void *nativeContext() const = 0;
@@ -81,6 +84,9 @@ public:
// For others, like WGL, they are not relevant.
virtual void *nativeDisplay() const { return 0; }
virtual void *nativeConfig() const { return 0; }
+
+protected:
+ QWindowsOpenGLContext() = default;
};
#endif // QT_NO_OPENGL
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index c52e4e612e..9a630aff4f 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -40,15 +40,15 @@
#include "qwindowsopengltester.h"
#include "qwindowscontext.h"
-#include <QtCore/QVariantMap>
-#include <QtCore/QDebug>
-#include <QtCore/QTextStream>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QFile>
-#include <QtCore/QFileInfo>
-#include <QtCore/QStandardPaths>
-#include <QtCore/QLibraryInfo>
-#include <QtCore/QHash>
+#include <QtCore/qvariant.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qtextstream.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qstandardpaths.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtCore/qhash.h>
#ifndef QT_NO_OPENGL
#include <private/qopengl_p.h>
@@ -60,6 +60,8 @@
QT_BEGIN_NAMESPACE
+static const DWORD VENDOR_ID_AMD = 0x1002;
+
GpuDescription GpuDescription::detect()
{
typedef IDirect3D9 * (WINAPI *PtrDirect3DCreate9)(UINT);
@@ -74,9 +76,16 @@ GpuDescription GpuDescription::detect()
IDirect3D9 *direct3D9 = direct3DCreate9(D3D_SDK_VERSION);
if (!direct3D9)
return result;
+
D3DADAPTER_IDENTIFIER9 adapterIdentifier;
- const HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier);
- direct3D9->Release();
+ bool isAMD = false;
+ // Adapter "0" is D3DADAPTER_DEFAULT which returns the default adapter. In
+ // multi-GPU, multi-screen setups this is the GPU that is associated with
+ // the "main display" in the Display Settings, and this is the GPU OpenGL
+ // and D3D uses by default. Therefore querying any additional adapters is
+ // futile and not useful for our purposes in general, except for
+ // identifying a few special cases later on.
+ HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier);
if (SUCCEEDED(hr)) {
result.vendorId = adapterIdentifier.VendorId;
result.deviceId = adapterIdentifier.DeviceId;
@@ -90,7 +99,37 @@ GpuDescription GpuDescription::detect()
result.driverVersion = QVersionNumber(version);
result.driverName = adapterIdentifier.Driver;
result.description = adapterIdentifier.Description;
+ isAMD = result.vendorId == VENDOR_ID_AMD;
+ }
+
+ // Detect QTBUG-50371 (having AMD as the default adapter results in a crash
+ // when starting apps on a screen connected to the Intel card) by looking
+ // for a default AMD adapter and an additional non-AMD one.
+ if (isAMD) {
+ const UINT adapterCount = direct3D9->GetAdapterCount();
+ for (UINT adp = 1; adp < adapterCount; ++adp) {
+ hr = direct3D9->GetAdapterIdentifier(adp, 0, &adapterIdentifier);
+ if (SUCCEEDED(hr)) {
+ if (adapterIdentifier.VendorId != VENDOR_ID_AMD) {
+ // Bingo. Now figure out the display for the AMD card.
+ DISPLAY_DEVICE dd;
+ memset(&dd, 0, sizeof(dd));
+ dd.cb = sizeof(dd);
+ for (int dev = 0; EnumDisplayDevices(nullptr, dev, &dd, 0); ++dev) {
+ if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
+ // DeviceName is something like \\.\DISPLAY1 which can be used to
+ // match with the MONITORINFOEX::szDevice queried by QWindowsScreen.
+ result.gpuSuitableScreen = QString::fromWCharArray(dd.DeviceName);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
}
+
+ direct3D9->Release();
return result;
}
@@ -103,7 +142,8 @@ QDebug operator<<(QDebug d, const GpuDescription &gd)
<< ", deviceId=" << gd.deviceId << ", subSysId=" << gd.subSysId
<< dec << noshowbase << ", revision=" << gd.revision
<< ", driver: " << gd.driverName
- << ", version=" << gd.driverVersion << ", " << gd.description << ')';
+ << ", version=" << gd.driverVersion << ", " << gd.description
+ << gd.gpuSuitableScreen << ')';
return d;
}
#endif // !QT_NO_DEBUG_STREAM
@@ -113,15 +153,17 @@ QString GpuDescription::toString() const
{
QString result;
QTextStream str(&result);
- str << " Card name: " << description
- << "\n Driver Name: " << driverName
- << "\n Driver Version: " << driverVersion.toString()
- << "\n Vendor ID: 0x" << qSetPadChar(QLatin1Char('0'))
+ str << " Card name : " << description
+ << "\n Driver Name : " << driverName
+ << "\n Driver Version : " << driverVersion.toString()
+ << "\n Vendor ID : 0x" << qSetPadChar(QLatin1Char('0'))
<< uppercasedigits << hex << qSetFieldWidth(4) << vendorId
- << "\n Device ID: 0x" << qSetFieldWidth(4) << deviceId
- << "\n SubSys ID: 0x" << qSetFieldWidth(8) << subSysId
- << "\n Revision ID: 0x" << qSetFieldWidth(4) << revision
+ << "\n Device ID : 0x" << qSetFieldWidth(4) << deviceId
+ << "\n SubSys ID : 0x" << qSetFieldWidth(8) << subSysId
+ << "\n Revision ID : 0x" << qSetFieldWidth(4) << revision
<< dec;
+ if (!gpuSuitableScreen.isEmpty())
+ str << "\nGL windows forced to screen: " << gpuSuitableScreen;
return result;
}
@@ -259,6 +301,10 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c
qCDebug(lcQpaGl) << "Disabling rotation: " << gpu;
result |= DisableRotationFlag;
}
+ if (features.contains(QStringLiteral("disable_program_cache"))) {
+ qCDebug(lcQpaGl) << "Disabling program cache: " << gpu;
+ result |= DisableProgramCacheFlag;
+ }
srCache->insert(qgpu, result);
return result;
#endif // !QT_NO_OPENGL
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index e3fec59dd5..bec87c1f86 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSOPENGLTESTER_H
#define QWINDOWSOPENGLTESTER_H
-#include <QtCore/QByteArray>
-#include <QtCore/QFlags>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qflags.h>
#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
@@ -62,6 +62,7 @@ struct GpuDescription
QVersionNumber driverVersion;
QByteArray driverName;
QByteArray description;
+ QString gpuSuitableScreen;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -82,7 +83,8 @@ public:
GlesMask = Gles | AngleBackendMask,
SoftwareRasterizer = 0x0020,
RendererMask = 0x00FF,
- DisableRotationFlag = 0x0100
+ DisableRotationFlag = 0x0100,
+ DisableProgramCacheFlag = 0x0200
};
Q_DECLARE_FLAGS(Renderers, Renderer)
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
new file mode 100644
index 0000000000..7ead14822a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -0,0 +1,641 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if defined(WINVER) && WINVER < 0x0603
+# undef WINVER
+#endif
+#if !defined(WINVER)
+# define WINVER 0x0603 // Enable pointer functions for MinGW
+#endif
+
+#include "qwindowspointerhandler.h"
+#include "qwindowskeymapper.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsintegration.h"
+#include "qwindowsscreen.h"
+
+#include <qpa/qwindowsysteminterface.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qtouchdevice.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qoperatingsystemversion.h>
+
+#include <windowsx.h>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ QT_PT_POINTER = 1,
+ QT_PT_TOUCH = 2,
+ QT_PT_PEN = 3,
+ QT_PT_MOUSE = 4,
+ QT_PT_TOUCHPAD = 5, // MinGW is missing PT_TOUCHPAD
+};
+
+bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
+{
+ *result = 0;
+ const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
+
+ POINTER_INPUT_TYPE pointerType;
+ if (!QWindowsContext::user32dll.getPointerType(pointerId, &pointerType)) {
+ qWarning() << "GetPointerType() failed:" << qt_error_string();
+ return false;
+ }
+
+ switch (pointerType) {
+ case QT_PT_POINTER:
+ case QT_PT_MOUSE:
+ case QT_PT_TOUCHPAD: {
+ POINTER_INFO pointerInfo;
+ if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo)) {
+ qWarning() << "GetPointerInfo() failed:" << qt_error_string();
+ return false;
+ }
+ return translateMouseTouchPadEvent(window, hwnd, et, msg, &pointerInfo);
+ }
+ case QT_PT_TOUCH: {
+ quint32 pointerCount = 0;
+ if (!QWindowsContext::user32dll.getPointerFrameTouchInfo(pointerId, &pointerCount, nullptr)) {
+ qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string();
+ return false;
+ }
+ QVarLengthArray<POINTER_TOUCH_INFO, 10> touchInfo(pointerCount);
+ if (!QWindowsContext::user32dll.getPointerFrameTouchInfo(pointerId, &pointerCount, touchInfo.data())) {
+ qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string();
+ return false;
+ }
+
+ if (!pointerCount)
+ return false;
+
+ // The history count is the same for all the touchpoints in touchInfo
+ quint32 historyCount = touchInfo[0].pointerInfo.historyCount;
+ // dispatch any skipped frames if event compression is disabled by the app
+ if (historyCount > 1 && !QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) {
+ touchInfo.resize(pointerCount * historyCount);
+ if (!QWindowsContext::user32dll.getPointerFrameTouchInfoHistory(pointerId,
+ &historyCount,
+ &pointerCount,
+ touchInfo.data())) {
+ qWarning() << "GetPointerFrameTouchInfoHistory() failed:" << qt_error_string();
+ return false;
+ }
+
+ // history frames are returned with the most recent frame first so we iterate backwards
+ bool result = true;
+ for (auto it = touchInfo.rbegin(), end = touchInfo.rend(); it != end; it += pointerCount) {
+ result &= translateTouchEvent(window, hwnd, et, msg,
+ &(*(it + (pointerCount - 1))), pointerCount);
+ }
+ return result;
+ }
+
+ return translateTouchEvent(window, hwnd, et, msg, touchInfo.data(), pointerCount);
+ }
+ case QT_PT_PEN: {
+ POINTER_PEN_INFO penInfo;
+ if (!QWindowsContext::user32dll.getPointerPenInfo(pointerId, &penInfo)) {
+ qWarning() << "GetPointerPenInfo() failed:" << qt_error_string();
+ return false;
+ }
+
+ quint32 historyCount = penInfo.pointerInfo.historyCount;
+ // dispatch any skipped frames if generic or tablet event compression is disabled by the app
+ if (historyCount > 1
+ && (!QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)
+ || !QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents))) {
+ QVarLengthArray<POINTER_PEN_INFO, 10> penInfoHistory(historyCount);
+
+ if (!QWindowsContext::user32dll.getPointerPenInfoHistory(pointerId,
+ &historyCount,
+ penInfoHistory.data())) {
+ qWarning() << "GetPointerPenInfoHistory() failed:" << qt_error_string();
+ return false;
+ }
+
+ // history frames are returned with the most recent frame first so we iterate backwards
+ bool result = true;
+ for (auto it = penInfoHistory.rbegin(), end = penInfoHistory.rend(); it != end; ++it) {
+ result &= translatePenEvent(window, hwnd, et, msg, &(*(it)));
+ }
+ return result;
+ }
+
+ return translatePenEvent(window, hwnd, et, msg, &penInfo);
+ }
+ }
+ return false;
+}
+
+static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QPoint globalPos, QEvent::Type *eventType, Qt::MouseButton *mouseButton)
+{
+ static const QHash<POINTER_BUTTON_CHANGE_TYPE, Qt::MouseButton> buttonMapping {
+ {POINTER_CHANGE_FIRSTBUTTON_DOWN, Qt::LeftButton},
+ {POINTER_CHANGE_FIRSTBUTTON_UP, Qt::LeftButton},
+ {POINTER_CHANGE_SECONDBUTTON_DOWN, Qt::RightButton},
+ {POINTER_CHANGE_SECONDBUTTON_UP, Qt::RightButton},
+ {POINTER_CHANGE_THIRDBUTTON_DOWN, Qt::MiddleButton},
+ {POINTER_CHANGE_THIRDBUTTON_UP, Qt::MiddleButton},
+ {POINTER_CHANGE_FOURTHBUTTON_DOWN, Qt::XButton1},
+ {POINTER_CHANGE_FOURTHBUTTON_UP, Qt::XButton1},
+ {POINTER_CHANGE_FIFTHBUTTON_DOWN, Qt::XButton2},
+ {POINTER_CHANGE_FIFTHBUTTON_UP, Qt::XButton2},
+ };
+
+ static const QHash<UINT, QEvent::Type> eventMapping {
+ {WM_POINTERUPDATE, QEvent::MouseMove},
+ {WM_POINTERDOWN, QEvent::MouseButtonPress},
+ {WM_POINTERUP, QEvent::MouseButtonRelease},
+ {WM_NCPOINTERUPDATE, QEvent::NonClientAreaMouseMove},
+ {WM_NCPOINTERDOWN, QEvent::NonClientAreaMouseButtonPress},
+ {WM_NCPOINTERUP, QEvent::NonClientAreaMouseButtonRelease},
+ {WM_POINTERWHEEL, QEvent::Wheel},
+ {WM_POINTERHWHEEL, QEvent::Wheel},
+ };
+
+ if (!eventType || !mouseButton)
+ return;
+
+ if (message == WM_POINTERDOWN || message == WM_POINTERUP || message == WM_NCPOINTERDOWN || message == WM_NCPOINTERUP)
+ *mouseButton = buttonMapping.value(changeType, Qt::NoButton);
+ else
+ *mouseButton = Qt::NoButton;
+
+ *eventType = eventMapping.value(message, QEvent::None);
+
+ // Pointer messages lack a double click indicator. Check if this is the case here.
+ if (message == WM_POINTERDOWN) {
+ static LONG lastTime = 0;
+ static Qt::MouseButton lastButton = Qt::NoButton;
+ static QPoint lastPos;
+ LONG messageTime = GetMessageTime();
+ if (*mouseButton == lastButton
+ && messageTime - lastTime < (LONG)GetDoubleClickTime()
+ && qAbs(globalPos.x() - lastPos.x()) < GetSystemMetrics(SM_CXDOUBLECLK)
+ && qAbs(globalPos.y() - lastPos.y()) < GetSystemMetrics(SM_CYDOUBLECLK)) {
+ *eventType = QEvent::MouseButtonDblClick;
+ }
+ lastTime = messageTime;
+ lastButton = *mouseButton;
+ lastPos = globalPos;
+ }
+}
+
+static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos)
+{
+ QWindow *currentWindowUnderPointer = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT);
+
+ while (currentWindowUnderPointer && currentWindowUnderPointer->flags() & Qt::WindowTransparentForInput)
+ currentWindowUnderPointer = currentWindowUnderPointer->parent();
+
+ // QTBUG-44332: When Qt is running at low integrity level and
+ // a Qt Window is parented on a Window of a higher integrity process
+ // using QWindow::fromWinId() (for example, Qt running in a browser plugin)
+ // ChildWindowFromPointEx() may not find the Qt window (failing with ERROR_ACCESS_DENIED)
+ if (!currentWindowUnderPointer) {
+ const QRect clientRect(QPoint(0, 0), window->size());
+ if (clientRect.contains(globalPos))
+ currentWindowUnderPointer = window;
+ }
+ return currentWindowUnderPointer;
+}
+
+static bool trackLeave(HWND hwnd)
+{
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ return TrackMouseEvent(&tme);
+}
+
+static bool isValidWheelReceiver(QWindow *candidate)
+{
+ if (candidate) {
+ const QWindow *toplevel = QWindowsWindow::topLevelOf(candidate);
+ if (toplevel->handle() && toplevel->handle()->isForeignWindow())
+ return true;
+ if (const QWindowsWindow *ww = QWindowsWindow::windowsWindowOf(toplevel))
+ return !ww->testFlag(QWindowsWindow::BlockedByModal);
+ }
+ return false;
+}
+
+static QTouchDevice *createTouchDevice()
+{
+ const int digitizers = GetSystemMetrics(SM_DIGITIZER);
+ if (!(digitizers & (NID_INTEGRATED_TOUCH | NID_EXTERNAL_TOUCH)))
+ return nullptr;
+ const int tabletPc = GetSystemMetrics(SM_TABLETPC);
+ const int maxTouchPoints = GetSystemMetrics(SM_MAXIMUMTOUCHES);
+ qCDebug(lcQpaEvents) << "Digitizers:" << hex << showbase << (digitizers & ~NID_READY)
+ << "Ready:" << (digitizers & NID_READY) << dec << noshowbase
+ << "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints;
+ QTouchDevice *result = new QTouchDevice;
+ result->setType(digitizers & NID_INTEGRATED_TOUCH
+ ? QTouchDevice::TouchScreen : QTouchDevice::TouchPad);
+ QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition;
+ if (result->type() == QTouchDevice::TouchPad)
+ capabilities |= QTouchDevice::MouseEmulation;
+ result->setCapabilities(capabilities);
+ result->setMaximumTouchPoints(maxTouchPoints);
+ return result;
+}
+
+QTouchDevice *QWindowsPointerHandler::ensureTouchDevice()
+{
+ if (!m_touchDevice)
+ m_touchDevice = createTouchDevice();
+ return m_touchDevice;
+}
+
+Qt::MouseButtons QWindowsPointerHandler::queryMouseButtons()
+{
+ Qt::MouseButtons result = 0;
+ const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON);
+ if (GetAsyncKeyState(VK_LBUTTON) < 0)
+ result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton;
+ if (GetAsyncKeyState(VK_RBUTTON) < 0)
+ result |= mouseSwapped ? Qt::LeftButton : Qt::RightButton;
+ if (GetAsyncKeyState(VK_MBUTTON) < 0)
+ result |= Qt::MidButton;
+ if (GetAsyncKeyState(VK_XBUTTON1) < 0)
+ result |= Qt::XButton1;
+ if (GetAsyncKeyState(VK_XBUTTON2) < 0)
+ result |= Qt::XButton2;
+ return result;
+}
+
+bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd,
+ QtWindows::WindowsEventType et,
+ MSG msg, PVOID vPointerInfo)
+{
+ POINTER_INFO *pointerInfo = static_cast<POINTER_INFO *>(vPointerInfo);
+ const QPoint globalPos = QPoint(pointerInfo->ptPixelLocation.x, pointerInfo->ptPixelLocation.y);
+ const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
+ const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
+ const Qt::MouseButtons mouseButtons = queryMouseButtons();
+
+ QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
+ QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
+
+ switch (msg.message) {
+ case WM_NCPOINTERDOWN:
+ case WM_NCPOINTERUP:
+ case WM_NCPOINTERUPDATE:
+ case WM_POINTERDOWN:
+ case WM_POINTERUP:
+ case WM_POINTERUPDATE: {
+
+ QEvent::Type eventType;
+ Qt::MouseButton button;
+ getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, globalPos, &eventType, &button);
+
+ if (et & QtWindows::NonClientEventFlag) {
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType,
+ keyModifiers, Qt::MouseEventNotSynthesized);
+ return false; // To allow window dragging, etc.
+ } else {
+ if (currentWindowUnderPointer != m_windowUnderPointer) {
+ if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) {
+ QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer);
+ m_currentWindow = nullptr;
+ }
+
+ if (currentWindowUnderPointer) {
+ if (currentWindowUnderPointer != m_currentWindow) {
+ QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, localPos, globalPos);
+ m_currentWindow = currentWindowUnderPointer;
+ if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer))
+ wumPlatformWindow->applyCursor();
+ trackLeave(hwnd);
+ }
+ } else {
+ platformWindow->applyCursor();
+ }
+ m_windowUnderPointer = currentWindowUnderPointer;
+ }
+
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType,
+ keyModifiers, Qt::MouseEventNotSynthesized);
+
+ // The initial down click over the QSizeGrip area, which posts a resize WM_SYSCOMMAND
+ // has go to through DefWindowProc() for resizing to work, so we return false here,
+ // unless the mouse is captured, as it would mess with menu processing.
+ return msg.message != WM_POINTERDOWN || GetCapture();
+ }
+ }
+ case WM_POINTERHWHEEL:
+ case WM_POINTERWHEEL: {
+
+ int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam);
+
+ // Qt horizontal wheel rotation orientation is opposite to the one in WM_POINTERHWHEEL
+ if (msg.message == WM_POINTERHWHEEL)
+ delta = -delta;
+
+ const QPoint angleDelta = (msg.message == WM_POINTERHWHEEL || (keyModifiers & Qt::AltModifier)) ?
+ QPoint(delta, 0) : QPoint(0, delta);
+
+ if (isValidWheelReceiver(window))
+ QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
+ return true;
+ }
+ case WM_POINTERLEAVE:
+ return true;
+ }
+ return false;
+}
+
+bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
+ QtWindows::WindowsEventType et,
+ MSG msg, PVOID vTouchInfo, quint32 count)
+{
+ Q_UNUSED(hwnd);
+ Q_UNUSED(et);
+
+ if (et & QtWindows::NonClientEventFlag)
+ return false; // Let DefWindowProc() handle Non Client messages.
+
+ if (count < 1)
+ return false;
+
+ if (msg.message == WM_POINTERCAPTURECHANGED) {
+ QWindowSystemInterface::handleTouchCancelEvent(window, m_touchDevice,
+ QWindowsKeyMapper::queryKeyboardModifiers());
+ m_lastTouchPositions.clear();
+ return true;
+ }
+
+ // Only handle down/up/update, ignore others like WM_POINTERENTER, WM_POINTERLEAVE, etc.
+ if (msg.message > WM_POINTERUP)
+ return false;
+
+ const QScreen *screen = window->screen();
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ if (!screen)
+ return false;
+
+ POINTER_TOUCH_INFO *touchInfo = static_cast<POINTER_TOUCH_INFO *>(vTouchInfo);
+
+ const QRect screenGeometry = screen->geometry();
+
+ QList<QWindowSystemInterface::TouchPoint> touchPoints;
+
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaEvents).noquote().nospace() << showbase
+ << __FUNCTION__
+ << " message=" << hex << msg.message
+ << " count=" << dec << count;
+
+ for (quint32 i = 0; i < count; ++i) {
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaEvents).noquote().nospace() << showbase
+ << " TouchPoint id=" << touchInfo[i].pointerInfo.pointerId
+ << " frame=" << touchInfo[i].pointerInfo.frameId
+ << " flags=" << hex << touchInfo[i].pointerInfo.pointerFlags;
+
+ QWindowSystemInterface::TouchPoint touchPoint;
+ touchPoint.id = touchInfo[i].pointerInfo.pointerId;
+ touchPoint.pressure = (touchInfo[i].touchMask & TOUCH_MASK_PRESSURE) ?
+ touchInfo[i].pressure / 1024.0 : 1.0;
+ if (m_lastTouchPositions.contains(touchPoint.id))
+ touchPoint.normalPosition = m_lastTouchPositions.value(touchPoint.id);
+
+ const QPointF screenPos = QPointF(touchInfo[i].pointerInfo.ptPixelLocation.x,
+ touchInfo[i].pointerInfo.ptPixelLocation.y);
+
+ if (touchInfo[i].touchMask & TOUCH_MASK_CONTACTAREA)
+ touchPoint.area.setSize(QSizeF(touchInfo[i].rcContact.right - touchInfo[i].rcContact.left,
+ touchInfo[i].rcContact.bottom - touchInfo[i].rcContact.top));
+ touchPoint.area.moveCenter(screenPos);
+ QPointF normalPosition = QPointF(screenPos.x() / screenGeometry.width(),
+ screenPos.y() / screenGeometry.height());
+ const bool stationaryTouchPoint = (normalPosition == touchPoint.normalPosition);
+ touchPoint.normalPosition = normalPosition;
+
+ if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_DOWN) {
+ touchPoint.state = Qt::TouchPointPressed;
+ m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition);
+ } else if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_UP) {
+ touchPoint.state = Qt::TouchPointReleased;
+ m_lastTouchPositions.remove(touchPoint.id);
+ } else {
+ touchPoint.state = stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved;
+ m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition);
+ }
+ touchPoints.append(touchPoint);
+
+ // Avoid getting repeated messages for this frame if there are multiple pointerIds
+ QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
+ }
+
+ QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints,
+ QWindowsKeyMapper::queryKeyboardModifiers());
+
+ return true;
+}
+
+bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et,
+ MSG msg, PVOID vPenInfo)
+{
+ if (et & QtWindows::NonClientEventFlag)
+ return false; // Let DefWindowProc() handle Non Client messages.
+
+ POINTER_PEN_INFO *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo);
+
+ RECT pRect, dRect;
+ if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
+ return false;
+
+ const quint32 pointerId = penInfo->pointerInfo.pointerId;
+ const QPoint globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y);
+ const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
+ const QPointF hiResGlobalPos = QPointF(dRect.left + qreal(penInfo->pointerInfo.ptHimetricLocation.x - pRect.left)
+ / (pRect.right - pRect.left) * (dRect.right - dRect.left),
+ dRect.top + qreal(penInfo->pointerInfo.ptHimetricLocation.y - pRect.top)
+ / (pRect.bottom - pRect.top) * (dRect.bottom - dRect.top));
+ const qreal pressure = (penInfo->penMask & PEN_MASK_PRESSURE) ? qreal(penInfo->pressure) / 1024.0 : 0.5;
+ const qreal rotation = (penInfo->penMask & PEN_MASK_ROTATION) ? qreal(penInfo->rotation) : 0.0;
+ const qreal tangentialPressure = 0.0;
+ const int xTilt = (penInfo->penMask & PEN_MASK_TILT_X) ? penInfo->tiltX : 0;
+ const int yTilt = (penInfo->penMask & PEN_MASK_TILT_Y) ? penInfo->tiltY : 0;
+ const int z = 0;
+
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaEvents).noquote().nospace() << showbase
+ << __FUNCTION__ << " pointerId=" << pointerId
+ << " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos
+ << " message=" << hex << msg.message
+ << " flags=" << hex << penInfo->pointerInfo.pointerFlags;
+
+ const QTabletEvent::TabletDevice device = QTabletEvent::Stylus;
+ QTabletEvent::PointerType type;
+ Qt::MouseButtons mouseButtons;
+
+ const bool pointerInContact = IS_POINTER_INCONTACT_WPARAM(msg.wParam);
+ if (pointerInContact)
+ mouseButtons = Qt::LeftButton;
+
+ if (penInfo->penFlags & (PEN_FLAG_ERASER | PEN_FLAG_INVERTED)) {
+ type = QTabletEvent::Eraser;
+ } else {
+ type = QTabletEvent::Pen;
+ if (pointerInContact && penInfo->penFlags & PEN_FLAG_BARREL)
+ mouseButtons = Qt::RightButton; // Either left or right, not both
+ }
+
+ switch (msg.message) {
+ case WM_POINTERENTER: {
+ QWindowSystemInterface::handleTabletEnterProximityEvent(device, type, pointerId);
+ m_windowUnderPointer = window;
+ // The local coordinates may fall outside the window.
+ // Wait until the next update to send the enter event.
+ m_needsEnterOnPointerUpdate = true;
+ break;
+ }
+ case WM_POINTERLEAVE:
+ if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) {
+ QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer);
+ m_windowUnderPointer = nullptr;
+ m_currentWindow = nullptr;
+ }
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, pointerId);
+ break;
+ case WM_POINTERDOWN:
+ case WM_POINTERUP:
+ case WM_POINTERUPDATE: {
+ QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(pointerId).target; // Pass to window that grabbed it.
+ if (!target && m_windowUnderPointer)
+ target = m_windowUnderPointer;
+ if (!target)
+ target = window;
+
+ if (m_needsEnterOnPointerUpdate) {
+ m_needsEnterOnPointerUpdate = false;
+ if (window != m_currentWindow) {
+ QWindowSystemInterface::handleEnterEvent(window, localPos, globalPos);
+ m_currentWindow = window;
+ if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(target))
+ wumPlatformWindow->applyCursor();
+ }
+ }
+ const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
+
+ QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
+ pressure, xTilt, yTilt, tangentialPressure, rotation, z,
+ pointerId, keyModifiers);
+ break;
+ }
+ }
+ return true;
+}
+
+// SetCursorPos()/TrackMouseEvent() will generate old-style WM_MOUSE messages. Handle them here.
+bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
+{
+ Q_UNUSED(et);
+
+ *result = 0;
+ if (msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE)
+ return false;
+
+ const QPoint localPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
+ const QPoint globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, localPos);
+
+ QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
+
+ if (msg.message == WM_MOUSELEAVE) {
+ if (window == m_currentWindow) {
+ QWindowSystemInterface::handleLeaveEvent(window);
+ m_windowUnderPointer = nullptr;
+ m_currentWindow = nullptr;
+ platformWindow->applyCursor();
+ }
+ return false;
+ }
+
+ // Windows sends a mouse move with no buttons pressed to signal "Enter"
+ // when a window is shown over the cursor. Discard the event and only use
+ // it for generating QEvent::Enter to be consistent with other platforms -
+ // X11 and macOS.
+ static QPoint lastMouseMovePos;
+ const bool discardEvent = msg.wParam == 0 && (m_windowUnderPointer.isNull() || globalPos == lastMouseMovePos);
+ lastMouseMovePos = globalPos;
+
+ QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
+
+ if (currentWindowUnderPointer != m_windowUnderPointer) {
+ if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) {
+ QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer);
+ m_currentWindow = nullptr;
+ }
+
+ if (currentWindowUnderPointer) {
+ if (currentWindowUnderPointer != m_currentWindow) {
+ QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, localPos, globalPos);
+ m_currentWindow = currentWindowUnderPointer;
+ if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer))
+ wumPlatformWindow->applyCursor();
+ trackLeave(hwnd);
+ }
+ } else {
+ platformWindow->applyCursor();
+ }
+ m_windowUnderPointer = currentWindowUnderPointer;
+ }
+
+ const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
+ const Qt::MouseButtons mouseButtons = queryMouseButtons();
+
+ if (!discardEvent)
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::NoButton, QEvent::MouseMove,
+ keyModifiers, Qt::MouseEventNotSynthesized);
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h
new file mode 100644
index 0000000000..c4d0e0ce4a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSPOINTERHANDLER_H
+#define QWINDOWSPOINTERHANDLER_H
+
+#include "qtwindowsglobal.h"
+#include <QtCore/qt_windows.h>
+
+#include <QtCore/qpointer.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qhash.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+class QTouchDevice;
+
+class QWindowsPointerHandler
+{
+ Q_DISABLE_COPY(QWindowsPointerHandler)
+public:
+ QWindowsPointerHandler() = default;
+ bool translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result);
+ bool translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result);
+ QTouchDevice *touchDevice() const { return m_touchDevice; }
+ QTouchDevice *ensureTouchDevice();
+ Qt::MouseButtons queryMouseButtons();
+ QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); }
+ void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; }
+
+private:
+ bool translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo);
+ bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count);
+ bool translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPenInfo);
+
+ QTouchDevice *m_touchDevice = nullptr;
+ QHash<int, QPointF> m_lastTouchPositions;
+ QPointer<QWindow> m_windowUnderPointer;
+ QPointer<QWindow> m_currentWindow;
+ bool m_needsEnterOnPointerUpdate = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSPOINTERHANDLER_H
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index d56dc870ea..2eaf386d42 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -45,14 +45,14 @@
#include <QtCore/qt_windows.h>
-#include <QtCore/QSettings>
-#include <QtGui/QPixmap>
-#include <QtGui/QGuiApplication>
+#include <QtCore/qsettings.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qguiapplication.h>
#include <qpa/qwindowsysteminterface.h>
#include <private/qhighdpiscaling_p.h>
-#include <QtGui/QScreen>
+#include <QtGui/qscreen.h>
-#include <QtCore/QDebug>
+#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
@@ -69,7 +69,7 @@ static inline QDpi monitorDPI(HMONITOR hMonitor)
if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, 0, &dpiX, &dpiY)))
return QDpi(dpiX, dpiY);
}
- return QDpi(0, 0);
+ return {0, 0};
}
typedef QList<QWindowsScreenData> WindowsScreenDataList;
@@ -274,9 +274,12 @@ QList<QPlatformScreen *> QWindowsScreen::virtualSiblings() const
{
QList<QPlatformScreen *> result;
if (m_data.flags & QWindowsScreenData::VirtualDesktop) {
- foreach (QWindowsScreen *screen, QWindowsContext::instance()->screenManager().screens())
+ const QWindowsScreenManager::WindowsScreenList screens
+ = QWindowsContext::instance()->screenManager().screens();
+ for (QWindowsScreen *screen : screens) {
if (screen->data().flags & QWindowsScreenData::VirtualDesktop)
result.push_back(screen);
+ }
} else {
result.push_back(const_cast<QWindowsScreen *>(this));
}
@@ -327,10 +330,7 @@ QRect QWindowsScreen::virtualGeometry(const QPlatformScreen *screen) // cf QScre
return result;
}
-enum OrientationPreference // matching Win32 API ORIENTATION_PREFERENCE
-#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC)
- : DWORD
-#endif
+enum OrientationPreference : DWORD // matching Win32 API ORIENTATION_PREFERENCE
{
orientationPreferenceNone = 0,
orientationPreferenceLandscape = 0x1,
@@ -398,7 +398,8 @@ QPlatformScreen::SubpixelAntialiasingType QWindowsScreen::subpixelAntialiasingTy
{
QPlatformScreen::SubpixelAntialiasingType type = QPlatformScreen::subpixelAntialiasingTypeHint();
if (type == QPlatformScreen::Subpixel_None) {
- QSettings settings(QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Avalon.Graphics\\DISPLAY1"), QSettings::NativeFormat);
+ QSettings settings(QLatin1String(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Avalon.Graphics\DISPLAY1)"),
+ QSettings::NativeFormat);
int registryValue = settings.value(QLatin1String("PixelStructure"), -1).toInt();
switch (registryValue) {
case 0:
@@ -505,7 +506,8 @@ void QWindowsScreenManager::removeScreen(int index)
// move those manually.
if (screen != primaryScreen) {
unsigned movedWindowCount = 0;
- foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
+ const QWindowList tlws = QGuiApplication::topLevelWindows();
+ for (QWindow *w : tlws) {
if (w->screen() == screen && w->handle() && w->type() != Qt::Desktop) {
if (w->isVisible() && w->windowState() != Qt::WindowMinimized
&& (QWindowsWindow::baseWindowOf(w)->exStyle() & WS_EX_TOOLWINDOW)) {
@@ -530,9 +532,9 @@ void QWindowsScreenManager::removeScreen(int index)
bool QWindowsScreenManager::handleScreenChanges()
{
// Look for changed monitors, add new ones
- WindowsScreenDataList newDataList = monitorData();
+ const WindowsScreenDataList newDataList = monitorData();
const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen);
- foreach (const QWindowsScreenData &newData, newDataList) {
+ for (const QWindowsScreenData &newData : newDataList) {
const int existingIndex = indexOfMonitor(m_screens, newData.name);
if (existingIndex != -1) {
m_screens.at(existingIndex)->handleChanges(newData);
@@ -564,7 +566,7 @@ void QWindowsScreenManager::clearScreens()
const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
{
- foreach (QWindowsScreen *scr, m_screens) {
+ for (QWindowsScreen *scr : m_screens) {
if (scr->geometry().contains(p))
return scr;
}
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 5753e605da..824bcb1ad6 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -42,10 +42,10 @@
#include "qtwindowsglobal.h"
-#include <QtCore/QList>
-#include <QtCore/QVector>
-#include <QtCore/QPair>
-#include <QtCore/QScopedPointer>
+#include <QtCore/qlist.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qscopedpointer.h>
#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp
index 48332b35f8..b6ed27464e 100644
--- a/src/plugins/platforms/windows/qwindowsservices.cpp
+++ b/src/plugins/platforms/windows/qwindowsservices.cpp
@@ -41,9 +41,9 @@
#include "qwindowsservices.h"
#include <QtCore/qt_windows.h>
-#include <QtCore/QUrl>
-#include <QtCore/QDebug>
-#include <QtCore/QDir>
+#include <QtCore/qurl.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qdir.h>
#include <shlobj.h>
#include <intshcut.h>
diff --git a/src/plugins/platforms/windows/qwindowsservices.h b/src/plugins/platforms/windows/qwindowsservices.h
index 7518a52755..5feb7c8490 100644
--- a/src/plugins/platforms/windows/qwindowsservices.h
+++ b/src/plugins/platforms/windows/qwindowsservices.h
@@ -47,8 +47,8 @@ QT_BEGIN_NAMESPACE
class QWindowsServices : public QPlatformServices
{
public:
- bool openUrl(const QUrl &url);
- bool openDocument(const QUrl &url);
+ bool openUrl(const QUrl &url) override;
+ bool openDocument(const QUrl &url) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.h b/src/plugins/platforms/windows/qwindowssystemtrayicon.h
index 1f696180cd..a8adb9641f 100644
--- a/src/plugins/platforms/windows/qwindowssystemtrayicon.h
+++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.h
@@ -57,7 +57,7 @@ class QWindowsSystemTrayIcon : public QPlatformSystemTrayIcon
{
public:
QWindowsSystemTrayIcon();
- ~QWindowsSystemTrayIcon();
+ ~QWindowsSystemTrayIcon() override;
void init() override;
void cleanup() override;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 6acb62ad8f..fa209f09c4 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -46,13 +46,13 @@
#include <qpa/qwindowsysteminterface.h>
-#include <QtGui/QTabletEvent>
-#include <QtGui/QScreen>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QWindow>
-#include <QtCore/QDebug>
-#include <QtCore/QVarLengthArray>
-#include <QtCore/QtMath>
+#include <QtGui/qevent.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qwindow.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qmath.h>
#include <private/qguiapplication_p.h>
#include <QtCore/private/qsystemlibrary_p.h>
@@ -108,7 +108,7 @@ inline QPointF QWindowsTabletDeviceData::scaleCoordinates(int coordX, int coordY
((coordY - minY) * qAbs(targetHeight) / qAbs(qreal(maxY - minY))) + targetY :
((qAbs(maxY) - (coordY - minY)) * qAbs(targetHeight) / qAbs(qreal(maxY - minY))) + targetY;
- return QPointF(x, y);
+ return {x, y};
}
template <class Stream>
@@ -135,9 +135,9 @@ QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t)
d.nospace();
d << "TabletDevice id:" << t.uniqueId << " pressure: " << t.minPressure
<< ".." << t.maxPressure << " tan pressure: " << t.minTanPressure << ".."
- << t.maxTanPressure << " area:" << t.minX << t.minY <<t.minZ
- << ".." << t.maxX << t.maxY << t.maxZ << " device " << t.currentDevice
- << " pointer " << t.currentPointerType;
+ << t.maxTanPressure << " area: (" << t.minX << ',' << t.minY << ',' << t.minZ
+ << ")..(" << t.maxX << ',' << t.maxY << ',' << t.maxZ << ") device "
+ << t.currentDevice << " pointer " << t.currentPointerType;
return d;
}
@@ -211,9 +211,6 @@ bool QWindowsWinTab32DLL::init()
QWindowsTabletSupport::QWindowsTabletSupport(HWND window, HCTX context)
: m_window(window)
, m_context(context)
- , m_absoluteRange(20)
- , m_tiltSupport(false)
- , m_currentDevice(-1)
{
AXIS orientation[3];
// Some tablets don't support tilt, check if it is possible,
@@ -230,13 +227,13 @@ QWindowsTabletSupport::~QWindowsTabletSupport()
QWindowsTabletSupport *QWindowsTabletSupport::create()
{
if (!m_winTab32DLL.init())
- return 0;
+ return nullptr;
const HWND window = QWindowsContext::instance()->createDummyWindow(QStringLiteral("TabletDummyWindow"),
L"TabletDummyWindow",
qWindowsTabletSupportWndProc);
if (!window) {
qCWarning(lcQpaTablet) << __FUNCTION__ << "Unable to create window for tablet.";
- return 0;
+ return nullptr;
}
LOGCONTEXT lcMine;
// build our context from the default context
@@ -255,7 +252,7 @@ QWindowsTabletSupport *QWindowsTabletSupport::create()
if (!context) {
qCDebug(lcQpaTablet) << __FUNCTION__ << "Unable to open tablet.";
DestroyWindow(window);
- return 0;
+ return nullptr;
}
// Set the size of the Packet Queue to the correct size
@@ -266,7 +263,7 @@ QWindowsTabletSupport *QWindowsTabletSupport::create()
qWarning("Unable to set queue size on tablet. The tablet will not work.");
QWindowsTabletSupport::m_winTab32DLL.wTClose(context);
DestroyWindow(window);
- return 0;
+ return nullptr;
} // cannot restore old size
} // cannot set
} // mismatch
@@ -285,7 +282,7 @@ unsigned QWindowsTabletSupport::options() const
QString QWindowsTabletSupport::description() const
{
- const unsigned size = m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, 0);
+ const unsigned size = m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, nullptr);
if (!size)
return QString();
QVarLengthArray<TCHAR> winTabId(size + 1);
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
index 9379dd72d6..d91701d6a5 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.h
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
@@ -43,8 +43,8 @@
#include "qtwindowsglobal.h"
#include <QtGui/qtguiglobal.h>
-#include <QtCore/QVector>
-#include <QtCore/QPointF>
+#include <QtCore/qvector.h>
+#include <QtCore/qpoint.h>
#include <wintab.h>
@@ -83,22 +83,23 @@ struct QWindowsWinTab32DLL
struct QWindowsTabletDeviceData
{
- QWindowsTabletDeviceData() : minPressure(0), maxPressure(0), minTanPressure(0),
- maxTanPressure(0), minX(0), maxX(0), minY(0), maxY(0), minZ(0), maxZ(0),
- uniqueId(0), currentDevice(0), currentPointerType(0) {}
-
QPointF scaleCoordinates(int coordX, int coordY,const QRect &targetArea) const;
qreal scalePressure(qreal p) const { return p / qreal(maxPressure - minPressure); }
qreal scaleTangentialPressure(qreal p) const { return p / qreal(maxTanPressure - minTanPressure); }
- int minPressure;
- int maxPressure;
- int minTanPressure;
- int maxTanPressure;
- int minX, maxX, minY, maxY, minZ, maxZ;
- qint64 uniqueId;
- int currentDevice;
- int currentPointerType;
+ int minPressure = 0;
+ int maxPressure = 0;
+ int minTanPressure = 0;
+ int maxTanPressure = 0;
+ int minX = 0;
+ int maxX = 0;
+ int minY = 0;
+ int maxY = 0;
+ int minZ = 0;
+ int maxZ = 0;
+ qint64 uniqueId = 0;
+ int currentDevice = 0;
+ int currentPointerType = 0;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -145,10 +146,10 @@ private:
static QWindowsWinTab32DLL m_winTab32DLL;
const HWND m_window;
const HCTX m_context;
- int m_absoluteRange;
- bool m_tiltSupport;
+ int m_absoluteRange = 20;
+ bool m_tiltSupport = false;
QVector<QWindowsTabletDeviceData> m_devices;
- int m_currentDevice;
+ int m_currentDevice = -1;
Mode m_mode = PenMode;
State m_state = PenUp;
};
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 651c661d6b..d01a7b0a8a 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -59,20 +59,20 @@
#endif
#include <shellapi.h>
-#include <QtCore/QVariant>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QDebug>
-#include <QtCore/QTextStream>
-#include <QtCore/QSysInfo>
-#include <QtCore/QCache>
-#include <QtCore/QThread>
-#include <QtCore/QMutex>
-#include <QtCore/QWaitCondition>
-#include <QtGui/QColor>
-#include <QtGui/QPalette>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QPainter>
-#include <QtGui/QPixmapCache>
+#include <QtCore/qvariant.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qtextstream.h>
+#include <QtCore/qsysinfo.h>
+#include <QtCore/qcache.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qwaitcondition.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qpalette.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpixmapcache.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtThemeSupport/private/qabstractfileiconengine_p.h>
#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
@@ -107,7 +107,7 @@ static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue)
{
BOOL result;
if (SystemParametersInfo(what, 0, &result, 0))
- return result ? true : false;
+ return result != FALSE;
return defaultValue;
}
@@ -121,9 +121,9 @@ static inline DWORD dWordSystemParametersInfo(UINT what, DWORD defaultValue)
static inline QColor mixColors(const QColor &c1, const QColor &c2)
{
- return QColor ((c1.red() + c2.red()) / 2,
- (c1.green() + c2.green()) / 2,
- (c1.blue() + c2.blue()) / 2);
+ return {(c1.red() + c2.red()) / 2,
+ (c1.green() + c2.green()) / 2,
+ (c1.blue() + c2.blue()) / 2};
}
static inline QColor getSysColor(int index)
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 237e8158fa..c132f20167 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -42,8 +42,8 @@
#include <qpa/qplatformtheme.h>
-#include <QtCore/QSharedPointer>
-#include <QtCore/QVariant>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qvariant.h>
QT_BEGIN_NAMESPACE
@@ -51,9 +51,10 @@ class QWindow;
class QWindowsTheme : public QPlatformTheme
{
+ Q_DISABLE_COPY(QWindowsTheme)
public:
QWindowsTheme();
- ~QWindowsTheme();
+ ~QWindowsTheme() override;
static QWindowsTheme *instance() { return m_instance; }
diff --git a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h
index 5601cc9305..731e4b5432 100644
--- a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h
+++ b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h
@@ -40,10 +40,10 @@
#ifndef QWINDOWSTHREADPOOLRUNNER_H
#define QWINDOWSTHREADPOOLRUNNER_H
-#include <QtCore/QMutex>
-#include <QtCore/QRunnable>
-#include <QtCore/QThreadPool>
-#include <QtCore/QWaitCondition>
+#include <QtCore/qmutex.h>
+#include <QtCore/qrunnable.h>
+#include <QtCore/qthreadpool.h>
+#include <QtCore/qwaitcondition.h>
QT_BEGIN_NAMESPACE
@@ -61,7 +61,7 @@ class QWindowsThreadPoolRunner
{
Q_DISABLE_COPY(QWindowsThreadPoolRunner)
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
template <class RunnableFunction> // nested class implementing QRunnable to execute a function.
class Runnable : public QRunnable
{
@@ -104,7 +104,7 @@ public:
private:
QMutex m_mutex;
QWaitCondition m_condition;
-#else // !QT_NO_THREAD
+#else // QT_CONFIG(thread)
public:
QWindowsThreadPoolRunner() {}
@@ -114,7 +114,7 @@ public:
f();
return true;
}
-#endif // QT_NO_THREAD
+#endif // QT_CONFIG(thread)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp b/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp
index d81ee8ba29..7a01483abd 100644
--- a/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp
+++ b/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp
@@ -44,20 +44,9 @@ QT_BEGIN_NAMESPACE
QWindowsVulkanInstance::QWindowsVulkanInstance(QVulkanInstance *instance)
: m_instance(instance),
m_getPhysDevPresSupport(nullptr),
- m_createSurface(nullptr),
- m_destroySurface(nullptr)
+ m_createSurface(nullptr)
{
- if (qEnvironmentVariableIsSet("QT_VULKAN_LIB"))
- m_lib.setFileName(QString::fromUtf8(qgetenv("QT_VULKAN_LIB")));
- else
- m_lib.setFileName(QStringLiteral("vulkan-1"));
-
- if (!m_lib.load()) {
- qWarning("Failed to load %s: %s", qPrintable(m_lib.fileName()), qPrintable(m_lib.errorString()));
- return;
- }
-
- init(&m_lib);
+ loadVulkanLibrary(QStringLiteral("vulkan-1"));
}
void QWindowsVulkanInstance::createOrAdoptInstance()
@@ -73,10 +62,6 @@ void QWindowsVulkanInstance::createOrAdoptInstance()
qWarning("Failed to find vkGetPhysicalDeviceWin32PresentationSupportKHR");
}
-QWindowsVulkanInstance::~QWindowsVulkanInstance()
-{
-}
-
bool QWindowsVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
QWindow *window)
@@ -106,14 +91,6 @@ VkSurfaceKHR QWindowsVulkanInstance::createSurface(HWND win)
qWarning("Failed to find vkCreateWin32SurfaceKHR");
return surface;
}
- if (!m_destroySurface) {
- m_destroySurface = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
- m_vkGetInstanceProcAddr(m_vkInst, "vkDestroySurfaceKHR"));
- }
- if (!m_destroySurface) {
- qWarning("Failed to find vkDestroySurfaceKHR");
- return surface;
- }
VkWin32SurfaceCreateInfoKHR surfaceInfo;
memset(&surfaceInfo, 0, sizeof(surfaceInfo));
@@ -127,10 +104,4 @@ VkSurfaceKHR QWindowsVulkanInstance::createSurface(HWND win)
return surface;
}
-void QWindowsVulkanInstance::destroySurface(VkSurfaceKHR surface)
-{
- if (m_destroySurface && surface)
- m_destroySurface(m_vkInst, surface, nullptr);
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsvulkaninstance.h b/src/plugins/platforms/windows/qwindowsvulkaninstance.h
index ca60ab7627..3292137c39 100644
--- a/src/plugins/platforms/windows/qwindowsvulkaninstance.h
+++ b/src/plugins/platforms/windows/qwindowsvulkaninstance.h
@@ -47,28 +47,25 @@
#define VK_USE_PLATFORM_WIN32_KHR
#include <QtVulkanSupport/private/qbasicvulkanplatforminstance_p.h>
-#include <QLibrary>
+#include <QtCore/qlibrary.h>
QT_BEGIN_NAMESPACE
class QWindowsVulkanInstance : public QBasicPlatformVulkanInstance
{
+ Q_DISABLE_COPY(QWindowsVulkanInstance)
public:
QWindowsVulkanInstance(QVulkanInstance *instance);
- ~QWindowsVulkanInstance();
void createOrAdoptInstance() override;
bool supportsPresent(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, QWindow *window) override;
VkSurfaceKHR createSurface(HWND win);
- void destroySurface(VkSurfaceKHR surface);
private:
QVulkanInstance *m_instance;
- QLibrary m_lib;
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR m_getPhysDevPresSupport;
PFN_vkCreateWin32SurfaceKHR m_createSurface;
- PFN_vkDestroySurfaceKHR m_destroySurface;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index ca87f1b6a4..9c31409644 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -58,23 +58,25 @@
#else
# include "qwindowsopenglcontext.h"
#endif
+#include "qwindowsopengltester.h"
#ifdef QT_NO_CURSOR
# include "qwindowscursor.h"
#endif
-#include <QtGui/QGuiApplication>
-#include <QtGui/QScreen>
-#include <QtGui/QWindow>
-#include <QtGui/QRegion>
-#include <QtGui/QOpenGLContext>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qregion.h>
+#include <QtGui/qopenglcontext.h>
#include <private/qsystemlibrary_p.h>
#include <private/qwindow_p.h> // QWINDOWSIZE_MAX
#include <private/qguiapplication_p.h>
#include <private/qhighdpiscaling_p.h>
#include <qpa/qwindowsysteminterface.h>
-#include <QtCore/QDebug>
-#include <QtCore/QLibraryInfo>
+#include <QtCore/qdebug.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <dwmapi.h>
@@ -422,6 +424,31 @@ static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::Windo
}
/*!
+ Calculates the dimensions of the invisible borders within the
+ window frames in Windows 10, using an empirical expression that
+ reproduces the measured values for standard DPI settings.
+*/
+
+static QMargins invisibleMargins(QPoint screenPoint)
+{
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10) {
+ POINT pt = {screenPoint.x(), screenPoint.y()};
+ if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
+ if (QWindowsContext::shcoredll.isValid()) {
+ UINT dpiX;
+ UINT dpiY;
+ if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, 0, &dpiX, &dpiY))) {
+ const qreal sc = (dpiX - 96) / 96.0;
+ const int gap = 7 + qRound(5*sc) - int(sc);
+ return QMargins(gap, 0, gap, gap);
+ }
+ }
+ }
+ }
+ return QMargins();
+}
+
+/*!
\class WindowCreationData
\brief Window creation code.
@@ -515,6 +542,84 @@ static inline void fixTopLevelWindowFlags(Qt::WindowFlags &flags)
flags |= Qt::FramelessWindowHint;
}
+static QScreen *screenForName(const QWindow *w, const QString &name)
+{
+ QScreen *winScreen = w ? w->screen() : QGuiApplication::primaryScreen();
+ if (winScreen && winScreen->name() != name) {
+ const auto screens = winScreen->virtualSiblings();
+ for (QScreen *screen : screens) {
+ if (screen->name() == name)
+ return screen;
+ }
+ }
+ return winScreen;
+}
+
+static QScreen *forcedScreenForGLWindow(const QWindow *w)
+{
+ const QString forceToScreen = GpuDescription::detect().gpuSuitableScreen;
+ return forceToScreen.isEmpty() ? nullptr : screenForName(w, forceToScreen);
+}
+
+static QPoint calcPosition(const QWindow *w, const QWindowCreationContextPtr &context, const QMargins &invMargins)
+{
+ const QPoint orgPos(context->frameX - invMargins.left(), context->frameY - invMargins.top());
+
+ if (!w || (!w->isTopLevel() && w->surfaceType() != QWindow::OpenGLSurface))
+ return orgPos;
+
+ // Workaround for QTBUG-50371
+ const QScreen *screenForGL = forcedScreenForGLWindow(w);
+ if (!screenForGL)
+ return orgPos;
+
+ const QPoint posFrame(context->frameX, context->frameY);
+ const QMargins margins = context->margins;
+ const QRect scrGeo = screenForGL->handle()->availableGeometry();
+
+ // Point is already in the required screen.
+ if (scrGeo.contains(orgPos))
+ return orgPos;
+
+ // If the visible part of the window is already in the
+ // required screen, just ignore the invisible offset.
+ if (scrGeo.contains(posFrame))
+ return posFrame;
+
+ // Find the original screen containing the coordinates.
+ const QList<QScreen *> screens = screenForGL->virtualSiblings();
+ const QScreen *orgScreen = nullptr;
+ for (QScreen *screen : screens) {
+ if (screen->handle()->availableGeometry().contains(posFrame)) {
+ orgScreen = screen;
+ break;
+ }
+ }
+ const QPoint ctPos = QPoint(qMax(scrGeo.left(), scrGeo.center().x()
+ + (margins.right() - margins.left() - context->frameWidth)/2),
+ qMax(scrGeo.top(), scrGeo.center().y()
+ + (margins.bottom() - margins.top() - context->frameHeight)/2));
+
+ // If initial coordinates were outside all screens, center the window on the required screen.
+ if (!orgScreen)
+ return ctPos;
+
+ const QRect orgGeo = orgScreen->handle()->availableGeometry();
+ const QRect orgFrame(QPoint(context->frameX, context->frameY),
+ QSize(context->frameWidth, context->frameHeight));
+
+ // Window would be centered on orgScreen. Center it on the required screen.
+ if (orgGeo.center() == (orgFrame - margins).center())
+ return ctPos;
+
+ // Transform the coordinates to map them into the required screen.
+ const QPoint newPos(scrGeo.left() + ((posFrame.x() - orgGeo.left()) * scrGeo.width()) / orgGeo.width(),
+ scrGeo.top() + ((posFrame.y() - orgGeo.top()) * scrGeo.height()) / orgGeo.height());
+ const QPoint newPosNoMargin(newPos.x() - invMargins.left(), newPos.y() - invMargins.top());
+
+ return scrGeo.contains(newPosNoMargin) ? newPosNoMargin : newPos;
+}
+
void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flagsIn,
unsigned creationFlags)
{
@@ -634,7 +739,7 @@ QWindowsWindowData
WindowData result;
result.flags = flags;
- const HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
+ const auto appinst = reinterpret_cast<HINSTANCE>(GetModuleHandle(nullptr));
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);
@@ -651,16 +756,23 @@ QWindowsWindowData
const QWindowCreationContextPtr context(new QWindowCreationContext(w, data.geometry, rect, data.customMargins, style, exStyle));
QWindowsContext::instance()->setWindowCreationContext(context);
+ QMargins invMargins = topLevel && !(result.flags & Qt::FramelessWindowHint) && QWindowsGeometryHint::positionIncludesFrame(w)
+ ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins();
+
qCDebug(lcQpaWindows).nospace()
<< "CreateWindowEx: " << w << " class=" << windowClassName << " title=" << title
<< '\n' << *this << "\nrequested: " << rect << ": "
<< context->frameWidth << 'x' << context->frameHeight
<< '+' << context->frameX << '+' << context->frameY
- << " custom margins: " << context->customMargins;
+ << " custom margins: " << context->customMargins
+ << " invisible margins: " << invMargins;
+
+
+ QPoint pos = calcPosition(w, context, invMargins);
result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
style,
- context->frameX, context->frameY,
+ pos.x(), pos.y(),
context->frameWidth, context->frameHeight,
parentHandle, NULL, appinst, NULL);
qCDebug(lcQpaWindows).nospace()
@@ -673,7 +785,7 @@ QWindowsWindowData
}
result.geometry = context->obtainedGeometry;
- result.frame = context->margins;
+ result.fullFrameMargins = context->margins;
result.embedded = embedded;
result.customMargins = context->customMargins;
@@ -887,7 +999,7 @@ QRect QWindowsBaseWindow::frameGeometry_sys() const
QRect QWindowsBaseWindow::geometry_sys() const
{
- return frameGeometry_sys().marginsRemoved(frameMargins());
+ return frameGeometry_sys().marginsRemoved(fullFrameMargins());
}
QMargins QWindowsBaseWindow::frameMargins_sys() const
@@ -1344,28 +1456,12 @@ bool QWindowsWindow::isEmbedded() const
QPoint QWindowsWindow::mapToGlobal(const QPoint &pos) const
{
- if (m_data.hwnd)
- return QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos);
- else
- return pos;
+ return m_data.hwnd ? QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos) : pos;
}
QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const
{
- if (m_data.hwnd)
- return QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos);
- else
- return pos;
-}
-
-static inline HWND transientParentHwnd(HWND hwnd)
-{
- if (GetAncestor(hwnd, GA_PARENT) == GetDesktopWindow()) {
- const HWND rootOwnerHwnd = GetAncestor(hwnd, GA_ROOTOWNER);
- if (rootOwnerHwnd != hwnd) // May return itself for toplevels.
- return rootOwnerHwnd;
- }
- return 0;
+ return m_data.hwnd ? QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos) : pos;
}
// Update the transient parent for a toplevel window. The concept does not
@@ -1382,7 +1478,7 @@ void QWindowsWindow::updateTransientParent() const
if (window()->type() == Qt::Popup)
return; // QTBUG-34503, // a popup stays on top, no parent, see also WindowCreationData::fromWindow().
// Update transient parent.
- const HWND oldTransientParent = transientParentHwnd(m_data.hwnd);
+ const HWND oldTransientParent = GetWindow(m_data.hwnd, GW_OWNER);
HWND newTransientParent = 0;
if (const QWindow *tp = window()->transientParent())
if (const QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(tp))
@@ -1560,7 +1656,7 @@ QRect QWindowsWindow::normalGeometry() const
const bool fakeFullScreen =
m_savedFrameGeometry.isValid() && (window()->windowStates() & Qt::WindowFullScreen);
const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
- const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMargins();
+ const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : fullFrameMargins();
return frame.isValid() ? frame.marginsRemoved(margins) : frame;
}
@@ -1592,8 +1688,8 @@ void QWindowsWindow::setGeometry(const QRect &rectIn)
window()->metaObject()->className(), qPrintable(window()->objectName()),
m_data.geometry.width(), m_data.geometry.height(),
m_data.geometry.x(), m_data.geometry.y(),
- m_data.frame.left(), m_data.frame.top(),
- m_data.frame.right(), m_data.frame.bottom(),
+ m_data.fullFrameMargins.left(), m_data.fullFrameMargins.top(),
+ m_data.fullFrameMargins.right(), m_data.fullFrameMargins.bottom(),
m_data.customMargins.left(), m_data.customMargins.top(),
m_data.customMargins.right(), m_data.customMargins.bottom(),
window()->minimumWidth(), window()->minimumHeight(),
@@ -1685,7 +1781,7 @@ void QWindowsWindow::handleGeometryChange()
void QWindowsBaseWindow::setGeometry_sys(const QRect &rect) const
{
- const QMargins margins = frameMargins();
+ const QMargins margins = fullFrameMargins();
const QRect frameGeometry = rect + margins;
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window()
@@ -1856,7 +1952,8 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
fireExpose(QRegion(0, 0, w->width(), w->height()));
exposeEventsSent = true;
}
- foreach (QWindow *child, QGuiApplication::allWindows()) {
+ const QWindowList allWindows = QGuiApplication::allWindows();
+ for (QWindow *child : allWindows) {
if (child != w && child->isVisible() && child->transientParent() == w) {
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child);
if (platformWindow && platformWindow->isLayered()) {
@@ -2048,7 +2145,7 @@ void QWindowsWindow::setExStyle(unsigned s) const
SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
}
-void QWindowsWindow::windowEvent(QEvent *event)
+bool QWindowsWindow::windowEvent(QEvent *event)
{
switch (event->type()) {
case QEvent::WindowBlocked: // Blocked by another modal window.
@@ -2064,6 +2161,8 @@ void QWindowsWindow::windowEvent(QEvent *event)
default:
break;
}
+
+ return QPlatformWindow::windowEvent(event);
}
void QWindowsWindow::propagateSizeHints()
@@ -2106,21 +2205,29 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
bool QWindowsWindow::handleGeometryChanging(MSG *message) const
{
- const QMargins margins = window()->isTopLevel() ? frameMargins() : QMargins();
+ const QMargins margins = window()->isTopLevel() ? fullFrameMargins() : QMargins();
return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
}
-void QWindowsWindow::setFrameMargins(const QMargins &newMargins)
+void QWindowsWindow::setFullFrameMargins(const QMargins &newMargins)
{
- if (m_data.frame != newMargins) {
- qCDebug(lcQpaWindows) << __FUNCTION__ << window() << m_data.frame << "->" << newMargins;
- m_data.frame = newMargins;
+ if (m_data.fullFrameMargins != newMargins) {
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window() << m_data.fullFrameMargins << "->" << newMargins;
+ m_data.fullFrameMargins = newMargins;
}
}
QMargins QWindowsWindow::frameMargins() const
{
- return m_data.frame;
+ QMargins result = fullFrameMargins();
+ if (isTopLevel() && !(m_data.flags & Qt::FramelessWindowHint))
+ result -= invisibleMargins(geometry().topLeft());
+ return result;
+}
+
+QMargins QWindowsWindow::fullFrameMargins() const
+{
+ return m_data.fullFrameMargins;
}
void QWindowsWindow::setOpacity(qreal level)
@@ -2174,7 +2281,7 @@ void QWindowsWindow::setMask(const QRegion &region)
// Mask is in client area coordinates, so offset it in case we have a frame
if (window()->isTopLevel()) {
- const QMargins margins = frameMargins();
+ const QMargins margins = fullFrameMargins();
OffsetRgn(winRegion, margins.left(), margins.top());
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 6d439bce1a..e8c30bd44b 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -41,7 +41,7 @@
#define QWINDOWSWINDOW_H
#include <QtCore/qt_windows.h>
-#include <QtCore/QPointer>
+#include <QtCore/qpointer.h>
#include "qwindowscursor.h"
#include <qpa/qplatformwindow.h>
@@ -59,7 +59,7 @@ class QDebug;
struct QWindowsGeometryHint
{
- QWindowsGeometryHint() {}
+ QWindowsGeometryHint() = default;
explicit QWindowsGeometryHint(const QWindow *w, const QMargins &customMargins);
static QMargins frame(DWORD style, DWORD exStyle);
static bool handleCalculateSize(const QMargins &customMargins, const MSG &msg, LRESULT *result);
@@ -108,8 +108,8 @@ struct QWindowsWindowData
{
Qt::WindowFlags flags;
QRect geometry;
- QMargins frame; // Do not use directly for windows, see FrameDirty.
- QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
+ QMargins fullFrameMargins; // Do not use directly for windows, see FrameDirty.
+ QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
HWND hwnd = 0;
bool embedded = false;
@@ -120,14 +120,16 @@ struct QWindowsWindowData
class QWindowsBaseWindow : public QPlatformWindow
{
+ Q_DISABLE_COPY(QWindowsBaseWindow)
public:
explicit QWindowsBaseWindow(QWindow *window) : QPlatformWindow(window) {}
WId winId() const override { return WId(handle()); }
QRect geometry() const override { return geometry_sys(); }
- QMargins frameMargins() const override { return frameMargins_sys(); }
+ QMargins frameMargins() const override { return fullFrameMargins(); }
QPoint mapToGlobal(const QPoint &pos) const override;
QPoint mapFromGlobal(const QPoint &pos) const override;
+ virtual QMargins fullFrameMargins() const { return frameMargins_sys(); }
using QPlatformWindow::screenForGeometry;
@@ -222,7 +224,7 @@ public:
};
QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
- ~QWindowsWindow();
+ ~QWindowsWindow() override;
void initialize() override;
@@ -251,13 +253,14 @@ public:
void raise() override { raise_sys(); }
void lower() override { lower_sys(); }
- void windowEvent(QEvent *event) override;
+ bool windowEvent(QEvent *event) override;
void propagateSizeHints() override;
static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp);
bool handleGeometryChanging(MSG *message) const;
QMargins frameMargins() const override;
- void setFrameMargins(const QMargins &newMargins);
+ QMargins fullFrameMargins() const override;
+ void setFullFrameMargins(const QMargins &newMargins);
void setOpacity(qreal level) override;
void setMask(const QRegion &region) override;
@@ -428,7 +431,7 @@ inline QWindowsWindow *QWindowsWindow::windowsWindowOf(const QWindow *w)
void *QWindowsWindow::userDataOf(HWND hwnd)
{
- return (void *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ return reinterpret_cast<void *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
}
void QWindowsWindow::setUserDataOf(HWND hwnd, void *ud)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
index 0f0f42fafe..85a931e015 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp
@@ -37,16 +37,16 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiaaccessibility.h"
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiautils.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QWindow>
-#include <QtGui/QGuiApplication>
+#include <QtGui/qaccessible.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qguiapplication.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/qt_windows.h>
#include <qpa/qplatformintegration.h>
@@ -104,19 +104,15 @@ void QWindowsUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event
return;
switch (event->type()) {
-
case QAccessible::Focus:
QWindowsUiaMainProvider::notifyFocusChange(event);
break;
-
case QAccessible::StateChanged:
QWindowsUiaMainProvider::notifyStateChange(static_cast<QAccessibleStateChangeEvent *>(event));
break;
-
case QAccessible::ValueChanged:
QWindowsUiaMainProvider::notifyValueChange(static_cast<QAccessibleValueChangeEvent *>(event));
break;
-
case QAccessible::TextAttributeChanged:
case QAccessible::TextColumnChanged:
case QAccessible::TextInserted:
@@ -126,7 +122,6 @@ void QWindowsUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event
case QAccessible::TextCaretMoved:
QWindowsUiaMainProvider::notifyTextChange(event);
break;
-
default:
break;
}
@@ -134,4 +129,4 @@ void QWindowsUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.h
index bbb81d596b..48b4f9fa6a 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.h
@@ -40,15 +40,15 @@
#ifndef QWINDOWSUIAACCESSIBILITY_H
#define QWINDOWSUIAACCESSIBILITY_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowscontext.h"
#include <qpa/qplatformaccessibility.h>
QT_BEGIN_NAMESPACE
-// Windows plataform accessibility implemented over UI Automation.
+// Windows platform accessibility implemented over UI Automation.
class QWindowsUiaAccessibility : public QPlatformAccessibility
{
public:
@@ -60,6 +60,6 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAACCESSIBILITY_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.cpp
index 1e1fc49c0f..53c647512a 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.cpp
@@ -37,17 +37,15 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -78,4 +76,4 @@ QAccessible::Id QWindowsUiaBaseProvider::id() const
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h
index 3ae403e8c5..9caa7d6898 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h
@@ -40,12 +40,11 @@
#ifndef QWINDOWSUIABASEPROVIDER_H
#define QWINDOWSUIABASEPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QPointer>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qpointer.h>
#include <qwindowscombase.h>
#include <QtWindowsUIAutomationSupport/private/qwindowsuiawrapper_p.h>
@@ -53,7 +52,6 @@
QT_BEGIN_NAMESPACE
class QAccessibleInterface;
-class QDebug;
// Base class for UI Automation providers.
class QWindowsUiaBaseProvider : public QObject
@@ -73,6 +71,6 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIABASEPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.cpp
index e0502c00f3..93d360c40b 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.cpp
@@ -37,18 +37,17 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiagriditemprovider.h"
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -148,7 +147,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_ColumnSpan(int *pRetV
return S_OK;
}
-// Returns the provider for the cointaining table/tree.
+// Returns the provider for the containing table/tree.
HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_ContainingGrid(IRawElementProviderSimple **pRetVal)
{
qCDebug(lcQpaUiAutomation) << __FUNCTION__;
@@ -173,4 +172,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_ContainingGrid(IRawEl
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h
index a93b50ef97..3d17056d38 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIAGRIDITEMPROVIDER_H
#define QWINDOWSUIAGRIDITEMPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,15 +57,15 @@ public:
virtual ~QWindowsUiaGridItemProvider();
// IGridItemProvider
- HRESULT STDMETHODCALLTYPE get_Row(int *pRetVal);
- HRESULT STDMETHODCALLTYPE get_Column(int *pRetVal);
- HRESULT STDMETHODCALLTYPE get_RowSpan(int *pRetVal);
- HRESULT STDMETHODCALLTYPE get_ColumnSpan(int *pRetVal);
- HRESULT STDMETHODCALLTYPE get_ContainingGrid(IRawElementProviderSimple **pRetVal);
+ HRESULT STDMETHODCALLTYPE get_Row(int *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_Column(int *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_RowSpan(int *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_ColumnSpan(int *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_ContainingGrid(IRawElementProviderSimple **pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAGRIDITEMPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.cpp
index 65c2df703b..cce9d8143c 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.cpp
@@ -37,18 +37,17 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiagridprovider.h"
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -133,4 +132,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaGridProvider::get_ColumnCount(int *pRetVal)
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h
index 15521f98b3..b96fc1a93c 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIAGRIDPROVIDER_H
#define QWINDOWSUIAGRIDPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,13 +57,13 @@ public:
virtual ~QWindowsUiaGridProvider();
// IGridProvider
- HRESULT STDMETHODCALLTYPE GetItem(int row, int column, IRawElementProviderSimple **pRetVal);
- HRESULT STDMETHODCALLTYPE get_RowCount(int *pRetVal);
- HRESULT STDMETHODCALLTYPE get_ColumnCount(int *pRetVal);
+ HRESULT STDMETHODCALLTYPE GetItem(int row, int column, IRawElementProviderSimple **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_RowCount(int *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_ColumnCount(int *pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAGRIDPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.cpp
index 2af883c4f6..d09770bc81 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.cpp
@@ -37,17 +37,16 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiainvokeprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -81,4 +80,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaInvokeProvider::Invoke()
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h
index 2b8a646983..5fb509c5f3 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIAINVOKEPROVIDER_H
#define QWINDOWSUIAINVOKEPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,11 +57,11 @@ public:
virtual ~QWindowsUiaInvokeProvider();
// IInvokeProvider
- HRESULT STDMETHODCALLTYPE Invoke();
+ HRESULT STDMETHODCALLTYPE Invoke() override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAINVOKEPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index e36006c103..fad83fb165 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiavalueprovider.h"
@@ -57,10 +57,10 @@
#include "qwindowsuiautils.h"
#include "qwindowsuiaprovidercache.h"
-#include <QtCore/QDebug>
-#include <QtGui/QAccessible>
-#include <QtGui/QGuiApplication>
-#include <QtGui/QWindow>
+#include <QtCore/qloggingcategory.h>
+#include <QtGui/qaccessible.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qwindow.h>
#if !defined(Q_CC_BOR) && !defined (Q_CC_GNU)
#include <comdef.h>
@@ -391,9 +391,8 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
break;
case UIA_NamePropertyId: {
QString name = accessible->text(QAccessible::Name);
- if (name.isEmpty() && clientTopLevel) {
+ if (name.isEmpty() && clientTopLevel)
name = QCoreApplication::applicationName();
- }
setVariantString(name, pRetVal);
break;
}
@@ -658,4 +657,4 @@ HRESULT QWindowsUiaMainProvider::GetFocus(IRawElementProviderFragment **pRetVal)
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
index 893cbf7f8a..325d5b3de4 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h
@@ -40,15 +40,15 @@
#ifndef QWINDOWSUIAMAINPROVIDER_H
#define QWINDOWSUIAMAINPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
-#include <QtCore/QPointer>
-#include <QtCore/QSharedPointer>
+#include <QtCore/qpointer.h>
+#include <QtCore/qsharedpointer.h>
#include <QtCore/qt_windows.h>
-#include <QtGui/QAccessible>
+#include <QtGui/qaccessible.h>
QT_BEGIN_NAMESPACE
@@ -71,27 +71,27 @@ public:
static void notifyTextChange(QAccessibleEvent *event);
// IUnknown
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface) override;
+ ULONG STDMETHODCALLTYPE AddRef() override;
+ ULONG STDMETHODCALLTYPE Release() override;
// IRawElementProviderSimple methods
- HRESULT STDMETHODCALLTYPE get_ProviderOptions(ProviderOptions *pRetVal);
- HRESULT STDMETHODCALLTYPE GetPatternProvider(PATTERNID idPattern, IUnknown **pRetVal);
- HRESULT STDMETHODCALLTYPE GetPropertyValue(PROPERTYID idProp, VARIANT *pRetVal);
- HRESULT STDMETHODCALLTYPE get_HostRawElementProvider(IRawElementProviderSimple **pRetVal);
+ HRESULT STDMETHODCALLTYPE get_ProviderOptions(ProviderOptions *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetPatternProvider(PATTERNID idPattern, IUnknown **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetPropertyValue(PROPERTYID idProp, VARIANT *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_HostRawElementProvider(IRawElementProviderSimple **pRetVal) override;
// IRawElementProviderFragment methods
- HRESULT STDMETHODCALLTYPE Navigate(NavigateDirection direction, IRawElementProviderFragment **pRetVal);
- HRESULT STDMETHODCALLTYPE GetRuntimeId(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE get_BoundingRectangle(UiaRect *pRetVal);
- HRESULT STDMETHODCALLTYPE GetEmbeddedFragmentRoots(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE SetFocus();
- HRESULT STDMETHODCALLTYPE get_FragmentRoot(IRawElementProviderFragmentRoot **pRetVal);
+ HRESULT STDMETHODCALLTYPE Navigate(NavigateDirection direction, IRawElementProviderFragment **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetRuntimeId(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_BoundingRectangle(UiaRect *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetEmbeddedFragmentRoots(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE SetFocus() override;
+ HRESULT STDMETHODCALLTYPE get_FragmentRoot(IRawElementProviderFragmentRoot **pRetVal) override;
// IRawElementProviderFragmentRoot methods
- HRESULT STDMETHODCALLTYPE ElementProviderFromPoint(double x, double y, IRawElementProviderFragment **pRetVal);
- HRESULT STDMETHODCALLTYPE GetFocus(IRawElementProviderFragment **pRetVal);
+ HRESULT STDMETHODCALLTYPE ElementProviderFromPoint(double x, double y, IRawElementProviderFragment **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetFocus(IRawElementProviderFragment **pRetVal) override;
private:
QString automationIdForAccessible(const QAccessibleInterface *accessible);
@@ -100,6 +100,6 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAMAINPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp
index 9f0a1e126f..c55e827a46 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp
@@ -37,15 +37,13 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiaprovidercache.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtCore/QDebug>
-
QT_BEGIN_NAMESPACE
using namespace QWindowsUiAutomation;
@@ -66,7 +64,7 @@ QWindowsUiaProviderCache *QWindowsUiaProviderCache::instance()
// Returns the provider instance associated with the ID, or nullptr.
QWindowsUiaBaseProvider *QWindowsUiaProviderCache::providerForId(QAccessible::Id id) const
{
- return providerTable.value(id);
+ return m_providerTable.value(id);
}
// Inserts a provider in the cache and associates it with an accessibility ID.
@@ -74,8 +72,8 @@ void QWindowsUiaProviderCache::insert(QAccessible::Id id, QWindowsUiaBaseProvide
{
remove(id);
if (provider) {
- providerTable[id] = provider;
- inverseTable[provider] = id;
+ m_providerTable[id] = provider;
+ m_inverseTable[provider] = id;
// Connects the destroyed signal to our slot, to remove deleted objects from the cache.
QObject::connect(provider, &QObject::destroyed, this, &QWindowsUiaProviderCache::objectDestroyed);
}
@@ -87,20 +85,20 @@ void QWindowsUiaProviderCache::objectDestroyed(QObject *obj)
// We have to use the inverse table to map the object address back to its ID,
// since at this point (called from QObject destructor), it has already been
// partially destroyed and we cannot treat it as a provider.
- auto it = inverseTable.find(obj);
- if (it != inverseTable.end()) {
- providerTable.remove(*it);
- inverseTable.remove(obj);
+ auto it = m_inverseTable.find(obj);
+ if (it != m_inverseTable.end()) {
+ m_providerTable.remove(*it);
+ m_inverseTable.remove(obj);
}
}
// Removes a provider with a given id from the cache.
void QWindowsUiaProviderCache::remove(QAccessible::Id id)
{
- inverseTable.remove(providerTable.value(id));
- providerTable.remove(id);
+ m_inverseTable.remove(m_providerTable.value(id));
+ m_providerTable.remove(id);
}
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.h
index 7ad30ac39c..f66dc2c170 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.h
@@ -40,14 +40,13 @@
#ifndef QWINDOWSUIAPROVIDERCACHE_H
#define QWINDOWSUIAPROVIDERCACHE_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
-#include <QtCore/QHash>
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
+#include <QtCore/qhash.h>
+#include <QtGui/qaccessible.h>
QT_BEGIN_NAMESPACE
@@ -66,12 +65,12 @@ private Q_SLOTS:
void objectDestroyed(QObject *obj);
private:
- QHash<QAccessible::Id, QWindowsUiaBaseProvider *> providerTable;
- QHash<QObject *, QAccessible::Id> inverseTable;
+ QHash<QAccessible::Id, QWindowsUiaBaseProvider *> m_providerTable;
+ QHash<QObject *, QAccessible::Id> m_inverseTable;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAPROVIDERCACHE_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.cpp
index 0cd09c3f0a..7c1827387a 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.cpp
@@ -37,17 +37,16 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiarangevalueprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -187,4 +186,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaRangeValueProvider::get_SmallChange(double
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h
index f742ef99c2..c5e0a03ee5 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIARANGEVALUEPROVIDER_H
#define QWINDOWSUIARANGEVALUEPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,17 +57,17 @@ public:
virtual ~QWindowsUiaRangeValueProvider();
// IRangeValueProvider
- HRESULT STDMETHODCALLTYPE SetValue(double val);
- HRESULT STDMETHODCALLTYPE get_Value(double *pRetVal);
- HRESULT STDMETHODCALLTYPE get_IsReadOnly(BOOL *pRetVal);
- HRESULT STDMETHODCALLTYPE get_Maximum(double *pRetVal);
- HRESULT STDMETHODCALLTYPE get_Minimum(double *pRetVal);
- HRESULT STDMETHODCALLTYPE get_LargeChange(double *pRetVal);
- HRESULT STDMETHODCALLTYPE get_SmallChange(double *pRetVal);
+ HRESULT STDMETHODCALLTYPE SetValue(double val) override;
+ HRESULT STDMETHODCALLTYPE get_Value(double *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_IsReadOnly(BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_Maximum(double *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_Minimum(double *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_LargeChange(double *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_SmallChange(double *pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIARANGEVALUEPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp
index 45216a6d1c..a93a05c7bc 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp
@@ -37,18 +37,17 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiaselectionitemprovider.h"
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -198,4 +197,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_SelectionContain
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h
index 6a9b5b1e4b..1f2605188b 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIASELECTIONITEMPROVIDER_H
#define QWINDOWSUIASELECTIONITEMPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,15 +57,15 @@ public:
virtual ~QWindowsUiaSelectionItemProvider();
// ISelectionItemProvider
- HRESULT STDMETHODCALLTYPE Select();
- HRESULT STDMETHODCALLTYPE AddToSelection();
- HRESULT STDMETHODCALLTYPE RemoveFromSelection();
- HRESULT STDMETHODCALLTYPE get_IsSelected(BOOL *pRetVal);
- HRESULT STDMETHODCALLTYPE get_SelectionContainer(IRawElementProviderSimple **pRetVal);
+ HRESULT STDMETHODCALLTYPE Select() override;
+ HRESULT STDMETHODCALLTYPE AddToSelection() override;
+ HRESULT STDMETHODCALLTYPE RemoveFromSelection() override;
+ HRESULT STDMETHODCALLTYPE get_IsSelected(BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_SelectionContainer(IRawElementProviderSimple **pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIASELECTIONITEMPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp
index 1c06503bfc..3305e9c5c4 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp
@@ -37,19 +37,18 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiaselectionprovider.h"
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
-#include <QList>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qlist.h>
QT_BEGIN_NAMESPACE
@@ -144,4 +143,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_IsSelectionRequired(
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h
index 5a07a82ac8..0376d25804 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIASELECTIONPROVIDER_H
#define QWINDOWSUIASELECTIONPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,13 +57,13 @@ public:
virtual ~QWindowsUiaSelectionProvider();
// ISelectionProvider
- HRESULT STDMETHODCALLTYPE GetSelection(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE get_CanSelectMultiple(BOOL *pRetVal);
- HRESULT STDMETHODCALLTYPE get_IsSelectionRequired(BOOL *pRetVal);
+ HRESULT STDMETHODCALLTYPE GetSelection(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_CanSelectMultiple(BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_IsSelectionRequired(BOOL *pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIASELECTIONPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp
index 3ea29fc86c..2a94012590 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp
@@ -37,18 +37,17 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiatableitemprovider.h"
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -126,4 +125,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetColumnHeaderItems(SAF
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h
index 277884c980..bf4b52ee0b 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIATABLEITEMPROVIDER_H
#define QWINDOWSUIATABLEITEMPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,12 +57,12 @@ public:
virtual ~QWindowsUiaTableItemProvider();
// ITableItemProvider
- HRESULT STDMETHODCALLTYPE GetRowHeaderItems(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE GetColumnHeaderItems(SAFEARRAY **pRetVal);
+ HRESULT STDMETHODCALLTYPE GetRowHeaderItems(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetColumnHeaderItems(SAFEARRAY **pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIATABLEITEMPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.cpp
index f79a24536b..80086f1d4f 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.cpp
@@ -37,18 +37,17 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiatableprovider.h"
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -151,4 +150,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTableProvider::get_RowOrColumnMajor(enum Ro
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h
index 8cd0acda03..94c8ab93a7 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIATABLEPROVIDER_H
#define QWINDOWSUIATABLEPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,13 +57,13 @@ public:
virtual ~QWindowsUiaTableProvider();
// ITableProvider
- HRESULT STDMETHODCALLTYPE GetRowHeaders(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE GetColumnHeaders(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE get_RowOrColumnMajor(enum RowOrColumnMajor *pRetVal);
+ HRESULT STDMETHODCALLTYPE GetRowHeaders(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetColumnHeaders(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_RowOrColumnMajor(enum RowOrColumnMajor *pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIATABLEPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp
index e1622933af..9d1e72fb78 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp
@@ -37,17 +37,16 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiatextprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -258,4 +257,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetCaretRange(BOOL *isActive,
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h
index a6d10027fa..a9be70fa16 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIATEXTPROVIDER_H
#define QWINDOWSUIATEXTPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
#include "qwindowsuiatextrangeprovider.h"
@@ -58,23 +58,23 @@ public:
~QWindowsUiaTextProvider();
// IUnknown overrides
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface);
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface) override;
// ITextProvider
- HRESULT STDMETHODCALLTYPE GetSelection(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE GetVisibleRanges(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE RangeFromChild(IRawElementProviderSimple *childElement, ITextRangeProvider **pRetVal);
- HRESULT STDMETHODCALLTYPE RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal);
- HRESULT STDMETHODCALLTYPE get_DocumentRange(ITextRangeProvider **pRetVal);
- HRESULT STDMETHODCALLTYPE get_SupportedTextSelection(SupportedTextSelection *pRetVal);
+ HRESULT STDMETHODCALLTYPE GetSelection(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetVisibleRanges(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE RangeFromChild(IRawElementProviderSimple *childElement, ITextRangeProvider **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_DocumentRange(ITextRangeProvider **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_SupportedTextSelection(SupportedTextSelection *pRetVal) override;
// ITextProvider2
- HRESULT STDMETHODCALLTYPE RangeFromAnnotation(IRawElementProviderSimple *annotationElement, ITextRangeProvider **pRetVal);
- HRESULT STDMETHODCALLTYPE GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal);
+ HRESULT STDMETHODCALLTYPE RangeFromAnnotation(IRawElementProviderSimple *annotationElement, ITextRangeProvider **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIATEXTPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
index dae7cbdd5f..1be186f6b3 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp
@@ -37,18 +37,17 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiatextrangeprovider.h"
#include "qwindowsuiamainprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -238,12 +237,12 @@ HRESULT QWindowsUiaTextRangeProvider::GetBoundingRectangles(SAFEARRAY **pRetVal)
int endRange = qMin(end, m_endOffset);
if (startRange < endRange) {
// Calculates a bounding rectangle for the line and adds it to the list.
- QRect startRect = textInterface->characterRect(startRange);
- QRect endRect = textInterface->characterRect(endRange - 1);
- QRect lineRect(qMin(startRect.x(), endRect.x()),
- qMin(startRect.y(), endRect.y()),
- qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
- qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
+ const QRect startRect = textInterface->characterRect(startRange);
+ const QRect endRect = textInterface->characterRect(endRange - 1);
+ const QRect lineRect(qMin(startRect.x(), endRect.x()),
+ qMin(startRect.y(), endRect.y()),
+ qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
+ qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
rectList.append(lineRect);
}
if (end >= len) break;
@@ -519,9 +518,9 @@ HRESULT QWindowsUiaTextRangeProvider::Select()
}
// Not supported.
-HRESULT QWindowsUiaTextRangeProvider::FindTextW(BSTR /* text */, BOOL /* backward */,
- BOOL /* ignoreCase */,
- ITextRangeProvider **pRetVal)
+HRESULT QWindowsUiaTextRangeProvider::FindText(BSTR /* text */, BOOL /* backward */,
+ BOOL /* ignoreCase */,
+ ITextRangeProvider **pRetVal)
{
if (!pRetVal)
return E_INVALIDARG;
@@ -551,4 +550,4 @@ HRESULT QWindowsUiaTextRangeProvider::unselect()
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h
index 6fe6502c41..39b9069fc0 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIATEXTRANGEPROVIDER_H
#define QWINDOWSUIATEXTRANGEPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -56,24 +56,25 @@ public:
explicit QWindowsUiaTextRangeProvider(QAccessible::Id id, int startOffset, int endOffset);
virtual ~QWindowsUiaTextRangeProvider();
- HRESULT STDMETHODCALLTYPE AddToSelection();
- HRESULT STDMETHODCALLTYPE Clone(ITextRangeProvider **pRetVal);
- HRESULT STDMETHODCALLTYPE Compare(ITextRangeProvider *range, BOOL *pRetVal);
- HRESULT STDMETHODCALLTYPE CompareEndpoints(TextPatternRangeEndpoint endpoint, ITextRangeProvider *targetRange, TextPatternRangeEndpoint targetEndpoint, int *pRetVal);
- HRESULT STDMETHODCALLTYPE ExpandToEnclosingUnit(TextUnit unit);
- HRESULT STDMETHODCALLTYPE FindAttribute(TEXTATTRIBUTEID attributeId, VARIANT val, BOOL backward, ITextRangeProvider **pRetVal);
- HRESULT STDMETHODCALLTYPE FindText(BSTR text, BOOL backward, BOOL ignoreCase, ITextRangeProvider **pRetVal);
- HRESULT STDMETHODCALLTYPE GetAttributeValue(TEXTATTRIBUTEID attributeId, VARIANT *pRetVal);
- HRESULT STDMETHODCALLTYPE GetBoundingRectangles(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE GetChildren(SAFEARRAY **pRetVal);
- HRESULT STDMETHODCALLTYPE GetEnclosingElement(IRawElementProviderSimple **pRetVal);
- HRESULT STDMETHODCALLTYPE GetText(int maxLength, BSTR *pRetVal);
- HRESULT STDMETHODCALLTYPE Move(TextUnit unit, int count, int *pRetVal);
- HRESULT STDMETHODCALLTYPE MoveEndpointByRange(TextPatternRangeEndpoint endpoint, ITextRangeProvider *targetRange, TextPatternRangeEndpoint targetEndpoint);
- HRESULT STDMETHODCALLTYPE MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count, int *pRetVal);
- HRESULT STDMETHODCALLTYPE RemoveFromSelection();
- HRESULT STDMETHODCALLTYPE ScrollIntoView(BOOL alignToTop);
- HRESULT STDMETHODCALLTYPE Select();
+ // ITextRangeProvider
+ HRESULT STDMETHODCALLTYPE AddToSelection() override;
+ HRESULT STDMETHODCALLTYPE Clone(ITextRangeProvider **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE Compare(ITextRangeProvider *range, BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE CompareEndpoints(TextPatternRangeEndpoint endpoint, ITextRangeProvider *targetRange, TextPatternRangeEndpoint targetEndpoint, int *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE ExpandToEnclosingUnit(TextUnit unit) override;
+ HRESULT STDMETHODCALLTYPE FindAttribute(TEXTATTRIBUTEID attributeId, VARIANT val, BOOL backward, ITextRangeProvider **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE FindText(BSTR text, BOOL backward, BOOL ignoreCase, ITextRangeProvider **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetAttributeValue(TEXTATTRIBUTEID attributeId, VARIANT *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetBoundingRectangles(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetChildren(SAFEARRAY **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetEnclosingElement(IRawElementProviderSimple **pRetVal) override;
+ HRESULT STDMETHODCALLTYPE GetText(int maxLength, BSTR *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE Move(TextUnit unit, int count, int *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE MoveEndpointByRange(TextPatternRangeEndpoint endpoint, ITextRangeProvider *targetRange, TextPatternRangeEndpoint targetEndpoint) override;
+ HRESULT STDMETHODCALLTYPE MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count, int *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE RemoveFromSelection() override;
+ HRESULT STDMETHODCALLTYPE ScrollIntoView(BOOL alignToTop) override;
+ HRESULT STDMETHODCALLTYPE Select() override;
private:
HRESULT unselect();
@@ -83,6 +84,6 @@ private:
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIATEXTRANGEPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.cpp
index 01cdfd7e91..32445e4ffb 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.cpp
@@ -37,17 +37,16 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiatoggleprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -102,4 +101,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaToggleProvider::get_ToggleState(ToggleState
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h
index a0df983e40..2bed6f7e36 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIATOGGLEPROVIDER_H
#define QWINDOWSUIATOGGLEPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -57,12 +57,12 @@ public:
virtual ~QWindowsUiaToggleProvider();
// IToggleProvider
- HRESULT STDMETHODCALLTYPE Toggle();
- HRESULT STDMETHODCALLTYPE get_ToggleState(ToggleState *pRetVal);
+ HRESULT STDMETHODCALLTYPE Toggle() override;
+ HRESULT STDMETHODCALLTYPE get_ToggleState(ToggleState *pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIATOGGLEPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
index 89e5aad6a6..fbb5c3b9ec 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
@@ -37,14 +37,14 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
#include "qwindowswindow.h"
-#include <QtGui/QWindow>
+#include <QtGui/qwindow.h>
#include <QtGui/private/qhighdpiscaling_p.h>
#include <cmath>
@@ -232,4 +232,4 @@ bool isTextUnitSeparator(TextUnit unit, const QChar &ch)
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.h
index 15f4d6e8ba..6a482f6c1c 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.h
@@ -40,16 +40,14 @@
#ifndef QWINDOWSUIAUTILS_H
#define QWINDOWSUIAUTILS_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
-#include <QtCore/QString>
+#include <QtCore/qstring.h>
#include <QtCore/qt_windows.h>
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtGui/QWindow>
-#include <QtCore/QDebug>
-#include <QtCore/QRect>
+#include <QtGui/qaccessible.h>
+#include <QtGui/qwindow.h>
+#include <QtCore/qrect.h>
#include <QtWindowsUIAutomationSupport/private/qwindowsuiawrapper_p.h>
QT_BEGIN_NAMESPACE
@@ -84,6 +82,6 @@ void setVariantString(const QString &value, VARIANT *variant);
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAUTILS_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.cpp
index ef7d564e22..8651bcff60 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.cpp
@@ -37,17 +37,16 @@
**
****************************************************************************/
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiavalueprovider.h"
#include "qwindowsuiautils.h"
#include "qwindowscontext.h"
-#include <QtGui/QAccessible>
-#include <QtGui/QAccessibleInterface>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
@@ -129,4 +128,4 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaValueProvider::get_Value(BSTR *pRetVal)
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h
index db54fc0a46..334a17e51d 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h
@@ -40,8 +40,8 @@
#ifndef QWINDOWSUIAVALUEPROVIDER_H
#define QWINDOWSUIAVALUEPROVIDER_H
-#include <QtCore/QtConfig>
-#ifndef QT_NO_ACCESSIBILITY
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
#include "qwindowsuiabaseprovider.h"
@@ -58,13 +58,13 @@ public:
virtual ~QWindowsUiaValueProvider();
// IValueProvider
- HRESULT STDMETHODCALLTYPE SetValue(LPCWSTR val);
- HRESULT STDMETHODCALLTYPE get_IsReadOnly(BOOL *pRetVal);
- HRESULT STDMETHODCALLTYPE get_Value(BSTR *pRetVal);
+ HRESULT STDMETHODCALLTYPE SetValue(LPCWSTR val) override;
+ HRESULT STDMETHODCALLTYPE get_IsReadOnly(BOOL *pRetVal) override;
+ HRESULT STDMETHODCALLTYPE get_Value(BSTR *pRetVal) override;
};
QT_END_NAMESPACE
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
#endif // QWINDOWSUIAVALUEPROVIDER_H
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index f4c396f7c5..c1d4e907d9 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -9,7 +9,7 @@ mingw: LIBS *= -luuid
# For the dialog helpers:
LIBS += -lshlwapi -lshell32 -ladvapi32
-DEFINES *= QT_NO_CAST_FROM_ASCII
+DEFINES *= QT_NO_CAST_FROM_ASCII QT_NO_FOREACH
SOURCES += \
$$PWD/qwindowswindow.cpp \
@@ -18,6 +18,7 @@ SOURCES += \
$$PWD/qwindowsscreen.cpp \
$$PWD/qwindowskeymapper.cpp \
$$PWD/qwindowsmousehandler.cpp \
+ $$PWD/qwindowspointerhandler.cpp \
$$PWD/qwindowsole.cpp \
$$PWD/qwindowsdropdataobject.cpp \
$$PWD/qwindowsmime.cpp \
@@ -40,6 +41,7 @@ HEADERS += \
$$PWD/qwindowsscreen.h \
$$PWD/qwindowskeymapper.h \
$$PWD/qwindowsmousehandler.h \
+ $$PWD/qwindowspointerhandler.h \
$$PWD/qtwindowsglobal.h \
$$PWD/qwindowsole.h \
$$PWD/qwindowsdropdataobject.h \
diff --git a/src/plugins/platforms/winrt/main.cpp b/src/plugins/platforms/winrt/main.cpp
index 222287b3ef..a37bd1e3d8 100644
--- a/src/plugins/platforms/winrt/main.cpp
+++ b/src/plugins/platforms/winrt/main.cpp
@@ -58,7 +58,7 @@ QPlatformIntegration *QWinRTIntegrationPlugin::create(const QString& system, con
if (!system.compare(QLatin1String("winrt"), Qt::CaseInsensitive))
return QWinRTIntegration::create();
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
index 113886f9b4..b3bf52f09b 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
@@ -50,9 +50,6 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore")
-Q_LOGGING_CATEGORY(lcQpaBackingStoreVerbose, "qt.qpa.backingstore.verbose")
-
class QWinRTBackingStorePrivate
{
public:
@@ -68,7 +65,7 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
: QPlatformBackingStore(window), d_ptr(new QWinRTBackingStorePrivate)
{
Q_D(QWinRTBackingStore);
- qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window;
+ qCInfo(lcQpaBackingStore) << __FUNCTION__ << this << window;
d->initialized = false;
d->screen = static_cast<QWinRTScreen*>(window->screen()->handle());
@@ -80,7 +77,7 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
bool QWinRTBackingStore::initialize()
{
Q_D(QWinRTBackingStore);
- qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << d->initialized;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << d->initialized;
if (d->initialized)
return true;
@@ -102,7 +99,7 @@ bool QWinRTBackingStore::initialize()
QWinRTBackingStore::~QWinRTBackingStore()
{
- qCDebug(lcQpaBackingStore) << __FUNCTION__ << this;
+ qCInfo(lcQpaBackingStore) << __FUNCTION__ << this;
}
QPaintDevice *QWinRTBackingStore::paintDevice()
@@ -116,7 +113,7 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
Q_D(QWinRTBackingStore);
Q_UNUSED(offset)
- qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << window << region;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << region;
if (d->size.isEmpty())
return;
@@ -151,7 +148,7 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents
Q_D(QWinRTBackingStore);
Q_UNUSED(staticContents)
- qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << size;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << size;
if (!initialize())
return;
@@ -182,14 +179,14 @@ QImage QWinRTBackingStore::toImage() const
void QWinRTBackingStore::beginPaint(const QRegion &region)
{
- qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this << region;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << region;
resize(window()->size(), region);
}
void QWinRTBackingStore::endPaint()
{
- qCDebug(lcQpaBackingStoreVerbose) << __FUNCTION__ << this;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h
index cd05faa63e..b62d340b82 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.h
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h
@@ -47,9 +47,6 @@
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore)
-Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStoreVerbose)
-
class QWinRTScreen;
class QWinRTBackingStorePrivate;
@@ -57,7 +54,7 @@ class QWinRTBackingStore : public QPlatformBackingStore
{
public:
explicit QWinRTBackingStore(QWindow *window);
- ~QWinRTBackingStore();
+ ~QWinRTBackingStore() override;
QPaintDevice *paintDevice() override;
void beginPaint(const QRegion &) override;
void endPaint() override;
diff --git a/src/plugins/platforms/winrt/qwinrtcanvas.cpp b/src/plugins/platforms/winrt/qwinrtcanvas.cpp
new file mode 100644
index 0000000000..dd6b52d9cd
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcanvas.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcanvas.h"
+#include "uiautomation/qwinrtuiaaccessibility.h"
+#include "uiautomation/qwinrtuiamainprovider.h"
+#include "uiautomation/qwinrtuiametadatacache.h"
+#include "uiautomation/qwinrtuiautils.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/qfunctions_winrt.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::System;
+using namespace ABI::Windows::UI;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::Xaml;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTCanvas::QWinRTCanvas(const std::function<QWindow*()> &delegateWindow)
+{
+ ComPtr<Xaml::Controls::ICanvasFactory> factory;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(), IID_PPV_ARGS(&factory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = factory->CreateInstance(this, &m_base, &m_core);
+ Q_ASSERT_SUCCEEDED(hr);
+
+ delegate = delegateWindow;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::QueryInterface(REFIID iid, LPVOID *iface)
+{
+ if (!iface)
+ return E_POINTER;
+ *iface = nullptr;
+
+ if (iid == IID_IUnknown) {
+ *iface = static_cast<Xaml::IUIElementOverrides *>(this);
+ AddRef();
+ return S_OK;
+ } else if (iid == Xaml::IID_IUIElementOverrides) {
+ *iface = static_cast<Xaml::IUIElementOverrides *>(this);
+ AddRef();
+ return S_OK;
+ } else {
+ return m_base.CopyTo(iid, iface);
+ }
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::GetIids(ULONG *iidCount, IID **iids)
+{
+ *iidCount = 0;
+ *iids = nullptr;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::GetRuntimeClassName(HSTRING *className)
+{
+ const wchar_t *name = L"QWinRTCanvas";
+ return ::WindowsCreateString(name, static_cast<UINT32>(::wcslen(name)), className);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::GetTrustLevel(TrustLevel *trustLevel)
+{
+ *trustLevel = TrustLevel::BaseTrust;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::OnCreateAutomationPeer(Xaml::Automation::Peers::IAutomationPeer **returnValue)
+{
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ if (delegate) {
+ if (QWindow *window = delegate()) {
+ QWinRTUiaAccessibility::activate();
+ if (QAccessibleInterface *accessible = window->accessibleRoot()) {
+ QAccessible::Id accid = QWinRTUiAutomation::idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ if (ComPtr<QWinRTUiaMainProvider> provider = QWinRTUiaMainProvider::providerForAccessibleId(accid))
+ return provider.CopyTo(returnValue);
+ }
+ }
+ }
+ return m_base->OnCreateAutomationPeer(returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::OnDisconnectVisualChildren()
+{
+ return m_base->OnDisconnectVisualChildren();
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTCanvas::FindSubElementsForTouchTargeting(Point point, Rect boundingRect, IIterable<IIterable<ABI::Windows::Foundation::Point>*> **returnValue)
+{
+ return m_base->FindSubElementsForTouchTargeting(point, boundingRect, returnValue);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/winrt/qwinrtcanvas.h b/src/plugins/platforms/winrt/qwinrtcanvas.h
new file mode 100644
index 0000000000..bc3b708ac2
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcanvas.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTCANVAS_H
+#define QWINRTCANVAS_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/QWindow>
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTCanvas:
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::IUIElementOverrides>
+{
+public:
+ QWinRTCanvas(const std::function<QWindow*()> &delegateWindow);
+ ~QWinRTCanvas() override = default;
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *iface) override;
+ HRESULT STDMETHODCALLTYPE GetIids(ULONG *iidCount, IID **iids) override;
+ HRESULT STDMETHODCALLTYPE GetRuntimeClassName(HSTRING *className) override;
+ HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel *trustLevel) override;
+ HRESULT STDMETHODCALLTYPE OnCreateAutomationPeer(ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer **returnValue) override;
+ HRESULT STDMETHODCALLTYPE OnDisconnectVisualChildren() override;
+ HRESULT STDMETHODCALLTYPE FindSubElementsForTouchTargeting(ABI::Windows::Foundation::Point point, ABI::Windows::Foundation::Rect boundingRect, ABI::Windows::Foundation::Collections::IIterable<ABI::Windows::Foundation::Collections::IIterable<ABI::Windows::Foundation::Point>*> **returnValue) override;
+
+private:
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::IUIElementOverrides> m_base;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::Controls::ICanvas> m_core;
+ std::function<QWindow*()> delegate;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCANVAS_H
diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp
index 05c34b82f8..fd0ed8aed2 100644
--- a/src/plugins/platforms/winrt/qwinrtclipboard.cpp
+++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp
@@ -99,7 +99,7 @@ QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode)
quint32 size;
const wchar_t *textStr = result.GetRawBuffer(&size);
- QString text = QString::fromWCharArray(textStr, size);
+ QString text = QString::fromWCharArray(textStr, int(size));
text.replace(QLatin1String("\r\n"), QLatin1String("\n"));
if (m_mimeData) {
@@ -161,7 +161,8 @@ void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
&package);
const QString nativeString = convertToWindowsLineEnding(text);
- HStringReference textRef(reinterpret_cast<LPCWSTR>(nativeString.utf16()), nativeString.length());
+ HStringReference textRef(reinterpret_cast<LPCWSTR>(nativeString.utf16()),
+ uint(nativeString.length()));
hr = package->SetText(textRef.Get());
RETURN_HR_IF_FAILED("Could not set text to clipboard data package.");
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
index 3c918df935..180905945b 100644
--- a/src/plugins/platforms/winrt/qwinrtcursor.cpp
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -56,6 +56,11 @@ using namespace ABI::Windows::Foundation;
QT_BEGIN_NAMESPACE
+static inline bool qIsPointInRect(const Point &p, const Rect &r)
+{
+ return (p.X >= r.X && p.Y >= r.Y && p.X < r.X + r.Width && p.Y < r.Y + r.Height);
+}
+
class QWinRTCursorPrivate
{
public:
@@ -73,10 +78,6 @@ QWinRTCursor::QWinRTCursor()
Q_ASSERT_SUCCEEDED(hr);
}
-QWinRTCursor::~QWinRTCursor()
-{
-}
-
#ifndef QT_NO_CURSOR
void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window)
{
@@ -169,14 +170,60 @@ QPoint QWinRTCursor::pos() const
ICoreWindow *coreWindow = screen->coreWindow();
Q_ASSERT(coreWindow);
Point point;
- HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, &point]() {
- return coreWindow->get_PointerPosition(&point);
+ Rect bounds;
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, &point, &bounds]() {
+ HRESULT hr = coreWindow->get_PointerPosition(&point);
+ RETURN_HR_IF_FAILED("Failed to obtain pointer position.");
+ hr = coreWindow->get_Bounds(&bounds);
+ RETURN_HR_IF_FAILED("Failed to obtain window bounds.");
+ return hr;
});
Q_ASSERT_SUCCEEDED(hr);
- const QPoint position = QPoint(point.X, point.Y) * screen->scaleFactor();
+ QPointF position(qreal(point.X), qreal(point.Y));
// If no cursor get_PointerPosition returns SHRT_MIN for x and y
- return position.x() == SHRT_MIN && position.y() == SHRT_MIN || FAILED(hr) ? QPointF(Q_INFINITY, Q_INFINITY).toPoint()
- : position;
+ if ((int(position.x()) == SHRT_MIN && int(position.y()) == SHRT_MIN)
+ || FAILED(hr))
+ return QPointF(Q_INFINITY, Q_INFINITY).toPoint();
+ position.rx() -= qreal(bounds.X);
+ position.ry() -= qreal(bounds.Y);
+ position *= screen->scaleFactor();
+ return position.toPoint();
+}
+
+void QWinRTCursor::setPos(const QPoint &pos)
+{
+ QWinRTScreen *screen = static_cast<QWinRTScreen *>(QGuiApplication::primaryScreen()->handle());
+ Q_ASSERT(screen);
+ ComPtr<ICoreWindow> coreWindow = screen->coreWindow();
+ Q_ASSERT(coreWindow);
+ const QPointF scaledPos = QPointF(pos) / screen->scaleFactor();
+ QWinRTScreen::MousePositionTransition t;
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, scaledPos, &t]() {
+ ComPtr<ICoreWindow2> coreWindow2;
+ HRESULT hr = coreWindow.As(&coreWindow2);
+ RETURN_HR_IF_FAILED("Failed to cast core window.");
+ Rect bounds;
+ hr = coreWindow->get_Bounds(&bounds);
+ RETURN_HR_IF_FAILED("Failed to obtain window bounds.");
+ Point mousePos;
+ hr = coreWindow->get_PointerPosition(&mousePos);
+ RETURN_HR_IF_FAILED("Failed to obtain mouse position.");
+ const Point p = { FLOAT(scaledPos.x()) + bounds.X,
+ FLOAT(scaledPos.y()) + bounds.Y };
+ const bool wasInWindow = qIsPointInRect(mousePos, bounds);
+ const bool willBeInWindow = qIsPointInRect(p, bounds);
+ if (wasInWindow && willBeInWindow)
+ t = QWinRTScreen::MousePositionTransition::StayedIn;
+ else if (wasInWindow && !willBeInWindow)
+ t = QWinRTScreen::MousePositionTransition::MovedOut;
+ else if (!wasInWindow && willBeInWindow)
+ t = QWinRTScreen::MousePositionTransition::MovedIn;
+ else
+ t = QWinRTScreen::MousePositionTransition::StayedOut;
+ return coreWindow2->put_PointerPosition(p);
+ });
+ RETURN_VOID_IF_FAILED("Failed to set cursor position");
+ screen->emulateMouseMove(scaledPos, t);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.h b/src/plugins/platforms/winrt/qwinrtcursor.h
index 7f579f1531..eca3d8c7ca 100644
--- a/src/plugins/platforms/winrt/qwinrtcursor.h
+++ b/src/plugins/platforms/winrt/qwinrtcursor.h
@@ -49,11 +49,12 @@ class QWinRTCursor : public QPlatformCursor
{
public:
explicit QWinRTCursor();
- ~QWinRTCursor();
+ ~QWinRTCursor() override = default;
#ifndef QT_NO_CURSOR
void changeCursor(QCursor * windowCursor, QWindow *window) override;
#endif
QPoint pos() const override;
+ void setPos(const QPoint &pos) override;
private:
QScopedPointer<QWinRTCursorPrivate> d_ptr;
diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp
index 0c918230b3..3ed4cd692d 100644
--- a/src/plugins/platforms/winrt/qwinrtdrag.cpp
+++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp
@@ -81,7 +81,7 @@ ComPtr<IBuffer> createIBufferFromData(const char *data, qint32 size)
}
ComPtr<IBuffer> buffer;
- const UINT32 length = size;
+ const UINT32 length = UINT32(size);
hr = bufferFactory->Create(length, &buffer);
Q_ASSERT_SUCCEEDED(hr);
hr = buffer->put_Length(length);
@@ -118,13 +118,13 @@ inline QString hStringToQString(const HString &hString)
{
quint32 l;
const wchar_t *raw = hString.GetRawBuffer(&l);
- return (QString::fromWCharArray(raw, l));
+ return (QString::fromWCharArray(raw, int(l)));
}
inline HString qStringToHString(const QString &qString)
{
HString h;
- h.Set(reinterpret_cast<const wchar_t*>(qString.utf16()), qString.size());
+ h.Set(reinterpret_cast<const wchar_t*>(qString.utf16()), uint(qString.size()));
return h;
}
@@ -184,10 +184,6 @@ QWinRTInternalMimeData::QWinRTInternalMimeData()
}
}
-QWinRTInternalMimeData::~QWinRTInternalMimeData()
-{
-}
-
bool QWinRTInternalMimeData::hasFormat_sys(const QString &mimetype) const
{
qCDebug(lcQpaMime) << __FUNCTION__ << mimetype;
@@ -311,7 +307,7 @@ QVariant QWinRTInternalMimeData::retrieveData_sys(const QString &mimetype, QVari
ComPtr<IAsyncOperation<IInspectable*>> op;
ComPtr<IInspectable> res;
HString type;
- type.Set(reinterpret_cast<const wchar_t*>(mimetype.utf16()), mimetype.size());
+ type.Set(reinterpret_cast<const wchar_t*>(mimetype.utf16()), uint(mimetype.size()));
hr = dataView->GetDataAsync(type.Get(), &op);
RETURN_OK_IF_FAILED("Could not query custom drag data.");
hr = QWinRTFunctions::await(op, res.GetAddressOf());
@@ -434,7 +430,7 @@ QVariant QWinRTInternalMimeData::retrieveData_sys(const QString &mimetype, QVari
IID_PPV_ARGS(&bufferFactory));
Q_ASSERT_SUCCEEDED(hr);
- UINT32 length = qBound(quint64(0), quint64(size), quint64(UINT_MAX));
+ UINT32 length = UINT32(qBound(quint64(0), quint64(size), quint64(UINT_MAX)));
ComPtr<IBuffer> buffer;
hr = bufferFactory->Create(length, &buffer);
Q_ASSERT_SUCCEEDED(hr);
@@ -452,7 +448,7 @@ QVariant QWinRTInternalMimeData::retrieveData_sys(const QString &mimetype, QVari
byte *bytes;
hr = byteArrayAccess->Buffer(&bytes);
- QByteArray array((char *)bytes, length);
+ QByteArray array((char *)bytes, int(length));
result.setValue(array);
return S_OK;
}
@@ -559,7 +555,7 @@ extern ComPtr<ABI::Windows::UI::Input::IPointerPoint> qt_winrt_lastPointerPoint;
QWinRTDrag::QWinRTDrag()
: QPlatformDrag()
- , m_dragTarget(0)
+ , m_dragTarget(nullptr)
{
qCDebug(lcQpaMime) << __FUNCTION__;
m_enter = new Q_INST_DRAGHANDLER(Enter);
@@ -612,7 +608,7 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag)
ComPtr<IAsyncOperation<ABI::Windows::ApplicationModel::DataTransfer::DataPackageOperation>> op;
EventRegistrationToken startingToken;
- hr = QEventDispatcherWinRT::runOnXamlThread([drag, &op, &hr, elem3, &startingToken, this]() {
+ hr = QEventDispatcherWinRT::runOnXamlThread([drag, &op, &hr, elem3, &startingToken]() {
hr = elem3->put_CanDrag(true);
Q_ASSERT_SUCCEEDED(hr);
@@ -660,7 +656,8 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag)
const QImage image = image2.convertToFormat(QImage::Format_ARGB32);
if (!image.isNull()) {
// Create IBuffer containing image
- ComPtr<IBuffer> imageBuffer = createIBufferFromData(reinterpret_cast<const char*>(image.bits()), image.byteCount());
+ ComPtr<IBuffer> imageBuffer
+ = createIBufferFromData(reinterpret_cast<const char*>(image.bits()), int(image.sizeInBytes()));
ComPtr<ISoftwareBitmapFactory> bitmapFactory;
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_SoftwareBitmap).Get(),
@@ -697,7 +694,7 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag)
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(), &ras);
Q_ASSERT_SUCCEEDED(hr);
- hr = ras->put_Size(data.size());
+ hr = ras->put_Size(UINT64(data.size()));
ComPtr<IOutputStream> outputStream;
hr = ras->GetOutputStreamAt(0, &outputStream);
Q_ASSERT_SUCCEEDED(hr);
@@ -802,7 +799,7 @@ void QWinRTDrag::handleNativeDragEvent(IInspectable *sender, ABI::Windows::UI::X
Point relativePoint;
hr = e->GetPosition(m_ui.Get(), &relativePoint);
RETURN_VOID_IF_FAILED("Could not query drag position.");
- const QPoint p(relativePoint.X, relativePoint.Y);
+ const QPoint p(int(relativePoint.X), int(relativePoint.Y));
ComPtr<IDragEventArgs2> e2;
hr = e->QueryInterface(IID_PPV_ARGS(&e2));
diff --git a/src/plugins/platforms/winrt/qwinrtdrag.h b/src/plugins/platforms/winrt/qwinrtdrag.h
index 3868c9f015..ab57999bba 100644
--- a/src/plugins/platforms/winrt/qwinrtdrag.h
+++ b/src/plugins/platforms/winrt/qwinrtdrag.h
@@ -77,7 +77,7 @@ class QWinRTInternalMimeData;
class QWinRTInternalMimeData : public QInternalMimeData {
public:
QWinRTInternalMimeData();
- virtual ~QWinRTInternalMimeData();
+ ~QWinRTInternalMimeData() override = default;
bool hasFormat_sys(const QString &mimetype) const override;
QStringList formats_sys() const override;
@@ -92,7 +92,7 @@ private:
class QWinRTDrag : public QPlatformDrag {
public:
QWinRTDrag();
- virtual ~QWinRTDrag();
+ ~QWinRTDrag() override;
static QWinRTDrag *instance();
Qt::DropAction drag(QDrag *) override;
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h
index 325dc82c40..8dbd0fc7d0 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.h
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.h
@@ -50,7 +50,7 @@ class QWinRTEGLContext : public QPlatformOpenGLContext
{
public:
explicit QWinRTEGLContext(QOpenGLContext *context);
- ~QWinRTEGLContext();
+ ~QWinRTEGLContext() override;
void initialize() override;
diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.h b/src/plugins/platforms/winrt/qwinrteventdispatcher.h
index 4c5c19c6b0..61c824f0a9 100644
--- a/src/plugins/platforms/winrt/qwinrteventdispatcher.h
+++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.h
@@ -48,7 +48,7 @@ class QWinRTEventDispatcher : public QEventDispatcherWinRT
{
Q_OBJECT
public:
- explicit QWinRTEventDispatcher(QObject *parent = 0);
+ explicit QWinRTEventDispatcher(QObject *parent = nullptr);
protected:
bool hasPendingEvents() override;
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
index 3c90334c8c..114d6dacd8 100644
--- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
@@ -51,7 +51,7 @@
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.storage.pickers.h>
-#include <Windows.ApplicationModel.activation.h>
+#include <Windows.Applicationmodel.Activation.h>
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@@ -73,12 +73,12 @@ class WindowsStringVector : public RuntimeClass<IVector<HSTRING>>
public:
HRESULT __stdcall GetAt(quint32 index, HSTRING *item)
{
- *item = impl.at(index);
+ *item = impl.at(int(index));
return S_OK;
}
HRESULT __stdcall get_Size(quint32 *size)
{
- *size = impl.size();
+ *size = quint32(impl.size());
return S_OK;
}
HRESULT __stdcall GetView(IVectorView<HSTRING> **view)
@@ -108,7 +108,7 @@ public:
HRESULT hr = WindowsDuplicateString(item, &newItem);
if (FAILED(hr))
return hr;
- impl[index] = newItem;
+ impl[int(index)] = newItem;
return S_OK;
}
HRESULT __stdcall InsertAt(quint32 index, HSTRING item)
@@ -117,12 +117,12 @@ public:
HRESULT hr = WindowsDuplicateString(item, &newItem);
if (FAILED(hr))
return hr;
- impl.insert(index, newItem);
+ impl.insert(int(index), newItem);
return S_OK;
}
HRESULT __stdcall RemoveAt(quint32 index)
{
- WindowsDeleteString(impl.takeAt(index));
+ WindowsDeleteString(impl.takeAt(int(index)));
return S_OK;
}
HRESULT __stdcall Append(HSTRING item)
@@ -164,7 +164,7 @@ static bool initializePicker(HSTRING runtimeId, T **picker, const QSharedPointer
if (options->isLabelExplicitlySet(QFileDialogOptions::Accept)) {
const QString labelText = options->labelText(QFileDialogOptions::Accept);
HStringReference labelTextRef(reinterpret_cast<const wchar_t *>(labelText.utf16()),
- labelText.length());
+ uint(labelText.length()));
hr = (*picker)->put_CommitButtonText(labelTextRef.Get());
RETURN_FALSE_IF_FAILED("Failed to set commit button text");
}
@@ -188,7 +188,7 @@ static bool initializeOpenPickerOptions(T *picker, const QSharedPointer<QFileDia
// Remove leading star
const int offset = (filter.length() > 1 && filter.startsWith(QLatin1Char('*'))) ? 1 : 0;
HStringReference filterRef(reinterpret_cast<const wchar_t *>(filter.utf16() + offset),
- filter.length() - offset);
+ uint(filter.length() - offset));
hr = filters->Append(filterRef.Get());
if (FAILED(hr)) {
qWarning("Failed to add named file filter \"%s\": %s",
@@ -290,16 +290,12 @@ QWinRTFileDialogHelper::QWinRTFileDialogHelper()
d->shown = false;
}
-QWinRTFileDialogHelper::~QWinRTFileDialogHelper()
-{
-}
-
void QWinRTFileDialogHelper::exec()
{
Q_D(QWinRTFileDialogHelper);
if (!d->shown)
- show(Qt::Dialog, Qt::ApplicationModal, 0);
+ show(Qt::Dialog, Qt::ApplicationModal, nullptr);
d->loop.exec();
}
@@ -369,7 +365,7 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
// Remove leading star
const int starOffset = (filter.length() > 1 && filter.startsWith(QLatin1Char('*'))) ? 1 : 0;
HStringReference filterRef(reinterpret_cast<const wchar_t *>(filter.utf16() + starOffset),
- filter.length() - starOffset);
+ uint(filter.length() - starOffset));
hr = entry->Append(filterRef.Get());
if (FAILED(hr)) {
qWarning("Failed to add named file filter \"%s\": %s",
@@ -379,7 +375,7 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
const int offset = namedFilter.indexOf(QLatin1String(" ("));
const QString filterTitle = namedFilter.mid(0, offset);
HStringReference namedFilterRef(reinterpret_cast<const wchar_t *>(filterTitle.utf16()),
- filterTitle.length());
+ uint(filterTitle.length()));
boolean replaced;
hr = choices->Insert(namedFilterRef.Get(), entry.Get(), &replaced);
// Only print a warning as * or *.* is not a valid choice on Windows 10
@@ -396,7 +392,7 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
if (!suffix.startsWith(QLatin1Char('.')))
suffix.prepend(QLatin1Char('.'));
HStringReference nativeSuffix(reinterpret_cast<const wchar_t *>(suffix.utf16()),
- suffix.length());
+ uint(suffix.length()));
hr = picker->put_DefaultFileExtension(nativeSuffix.Get());
RETURN_FALSE_IF_FAILED_WITH_ARGS("Failed to set default file extension \"%s\"", qPrintable(suffix));
}
@@ -404,7 +400,7 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
const QString suggestedName = QFileInfo(d->saveFileName.toLocalFile()).fileName();
if (!suggestedName.isEmpty()) {
HStringReference nativeSuggestedName(reinterpret_cast<const wchar_t *>(suggestedName.utf16()),
- suggestedName.length());
+ uint(suggestedName.length()));
hr = picker->put_SuggestedFileName(nativeSuggestedName.Get());
RETURN_FALSE_IF_FAILED("Failed to set suggested file name");
}
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
index 99239aad3a..994d099dcf 100644
--- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
@@ -70,7 +70,7 @@ class QWinRTFileDialogHelper : public QPlatformFileDialogHelper
Q_OBJECT
public:
explicit QWinRTFileDialogHelper();
- ~QWinRTFileDialogHelper();
+ ~QWinRTFileDialogHelper() override = default;
void exec() override;
bool show(Qt::WindowFlags, Qt::WindowModality, QWindow *) override;
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
index 76efdf6cc8..3014b30c38 100644
--- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
@@ -122,10 +122,6 @@ QWinRTFileEngineHandler::QWinRTFileEngineHandler()
{
}
-QWinRTFileEngineHandler::~QWinRTFileEngineHandler()
-{
-}
-
void QWinRTFileEngineHandler::registerFile(const QString &fileName, IStorageItem *file)
{
handlerInstance->d_func()->files.insert(QDir::cleanPath(fileName), file);
@@ -168,7 +164,7 @@ static HRESULT getDestinationFolder(const QString &fileName, const QString &newF
const QString newFilePath = QDir::toNativeSeparators(newFileInfo.absolutePath());
HStringReference nativeNewFilePath(reinterpret_cast<LPCWSTR>(newFilePath.utf16()),
- newFilePath.length());
+ uint(newFilePath.length()));
hr = folderFactory->GetFolderFromPathAsync(nativeNewFilePath.Get(), &op);
}
if (FAILED(hr))
@@ -181,10 +177,6 @@ QWinRTFileEngine::QWinRTFileEngine(const QString &fileName, IStorageItem *file)
{
}
-QWinRTFileEngine::~QWinRTFileEngine()
-{
-}
-
bool QWinRTFileEngine::open(QIODevice::OpenMode openMode)
{
Q_D(QWinRTFileEngine);
@@ -278,7 +270,7 @@ bool QWinRTFileEngine::seek(qint64 pos)
if (!d->stream)
return false;
- HRESULT hr = d->stream->Seek(pos);
+ HRESULT hr = d->stream->Seek(UINT64(pos));
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::PositionError, false);
d->pos = pos;
return SUCCEEDED(hr);
@@ -311,7 +303,8 @@ bool QWinRTFileEngine::copy(const QString &newName)
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
const QString destinationName = QFileInfo(newName).fileName();
- HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()), destinationName.length());
+ HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()),
+ uint(destinationName.length()));
ComPtr<IAsyncOperation<StorageFile *>> op;
hr = file->CopyOverloadDefaultOptions(destinationFolder.Get(), nativeDestinationName.Get(), &op);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
@@ -332,7 +325,8 @@ bool QWinRTFileEngine::rename(const QString &newName)
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
const QString destinationName = QFileInfo(newName).fileName();
- HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()), destinationName.length());
+ HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()),
+ uint(destinationName.length()));
ComPtr<IAsyncAction> op;
hr = d->file->RenameAsyncOverloadDefaultOptions(nativeDestinationName.Get(), &op);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
@@ -349,7 +343,8 @@ bool QWinRTFileEngine::renameOverwrite(const QString &newName)
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
const QString destinationName = QFileInfo(newName).fileName();
- HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()), destinationName.length());
+ HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()),
+ uint(destinationName.length()));
ComPtr<IAsyncAction> op;
hr = d->file->RenameAsync(nativeDestinationName.Get(), NameCollisionOption_ReplaceExisting, &op);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
@@ -451,7 +446,7 @@ qint64 QWinRTFileEngine::read(char *data, qint64 maxlen)
HRESULT hr = d->stream.As(&stream);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
- UINT32 length = qBound(quint64(0), quint64(maxlen), quint64(UINT_MAX));
+ UINT32 length = UINT32(qBound(quint64(0), quint64(maxlen), quint64(UINT32_MAX)));
ComPtr<IBuffer> buffer;
hr = d->bufferFactory->Create(length, &buffer);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
@@ -494,7 +489,7 @@ qint64 QWinRTFileEngine::write(const char *data, qint64 maxlen)
HRESULT hr = d->stream.As(&stream);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
- UINT32 length = qBound(quint64(0), quint64(maxlen), quint64(UINT_MAX));
+ UINT32 length = UINT32(qBound(quint64(0), quint64(maxlen), quint64(UINT_MAX)));
ComPtr<IBuffer> buffer;
hr = d->bufferFactory->Create(length, &buffer);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.h b/src/plugins/platforms/winrt/qwinrtfileengine.h
index 73ff54b0c8..4485917c9e 100644
--- a/src/plugins/platforms/winrt/qwinrtfileengine.h
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.h
@@ -57,7 +57,7 @@ class QWinRTFileEngineHandler : public QAbstractFileEngineHandler
{
public:
QWinRTFileEngineHandler();
- ~QWinRTFileEngineHandler();
+ ~QWinRTFileEngineHandler() override = default;
QAbstractFileEngine *create(const QString &fileName) const override;
static void registerFile(const QString &fileName, ABI::Windows::Storage::IStorageItem *file);
@@ -73,7 +73,7 @@ class QWinRTFileEngine : public QAbstractFileEngine
{
public:
QWinRTFileEngine(const QString &fileName, ABI::Windows::Storage::IStorageItem *file);
- ~QWinRTFileEngine();
+ ~QWinRTFileEngine() override = default;
bool open(QIODevice::OpenMode openMode) override;
bool close() override;
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
index 63e5b0cf27..f7e91bb047 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -64,8 +64,8 @@ inline QRectF getInputPaneRect(ComPtr<IInputPane> pane, qreal scaleFactor)
{
Rect rect;
pane->get_OccludedRect(&rect);
- return QRectF(qRound(rect.X * scaleFactor), qRound(rect.Y * scaleFactor),
- qRound(rect.Width * scaleFactor), qRound(rect.Height * scaleFactor));
+ return QRectF(qRound(qreal(rect.X) * scaleFactor), qRound(qreal(rect.Y) * scaleFactor),
+ qRound(qreal(rect.Width) * scaleFactor), qRound(qreal(rect.Height) * scaleFactor));
}
/*!
@@ -205,6 +205,8 @@ void QWinRTInputContext::showInputPanel()
void QWinRTInputContext::hideInputPanel()
{
qCDebug(lcQpaInputMethods) << __FUNCTION__;
+ if (!m_isInputPanelVisible)
+ return;
QEventDispatcherWinRT::runOnXamlThread([&]() {
ComPtr<IInputPane2> inputPane;
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index c52207d23b..4f37583bed 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -50,6 +50,9 @@
#if QT_CONFIG(draganddrop)
#include "qwinrtdrag.h"
#endif
+#if QT_CONFIG(accessibility)
+# include "uiautomation/qwinrtuiaaccessibility.h"
+#endif
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>
@@ -119,6 +122,9 @@ public:
QPlatformClipboard *clipboard;
QWinRTScreen *mainScreen;
QScopedPointer<QWinRTInputContext> inputContext;
+#if QT_CONFIG(accessibility)
+ QWinRTUiaAccessibility *accessibility;
+#endif
ComPtr<ICoreApplication> application;
QHash<CoreApplicationCallbackRemover, EventRegistrationToken> applicationTokens;
@@ -198,6 +204,9 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
screenAdded(d->mainScreen);
d->platformServices = new QWinRTServices;
d->clipboard = new QWinRTClipboard;
+#if QT_CONFIG(accessibility)
+ d->accessibility = new QWinRTUiaAccessibility;
+#endif
}
QWinRTIntegration::~QWinRTIntegration()
@@ -315,6 +324,14 @@ QPlatformDrag *QWinRTIntegration::drag() const
}
#endif // QT_CONFIG(draganddrop)
+#if QT_CONFIG(accessibility)
+QPlatformAccessibility *QWinRTIntegration::accessibility() const
+{
+ Q_D(const QWinRTIntegration);
+ return d->accessibility;
+}
+#endif // QT_CONFIG(accessibility)
+
Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
{
Q_D(const QWinRTIntegration);
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h
index d1a9b7edbd..636e594b4b 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.h
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -75,7 +75,7 @@ class QWinRTIntegration : public QPlatformIntegration
private:
explicit QWinRTIntegration();
public:
- ~QWinRTIntegration();
+ ~QWinRTIntegration() override;
static QWinRTIntegration *create()
{
@@ -100,6 +100,9 @@ public:
#if QT_CONFIG(draganddrop)
QPlatformDrag *drag() const override;
#endif
+#if QT_CONFIG(accessibility)
+ QPlatformAccessibility *accessibility() const override;
+#endif
Qt::KeyboardModifiers queryKeyboardModifiers() const override;
diff --git a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp
index d69c63e9a4..7016b47f7e 100644
--- a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp
+++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp
@@ -99,7 +99,7 @@ void QWinRTMessageDialogHelper::exec()
Q_D(QWinRTMessageDialogHelper);
if (!d->shown)
- show(Qt::Dialog, Qt::ApplicationModal, 0);
+ show(Qt::Dialog, Qt::ApplicationModal, nullptr);
d->loop.exec();
}
@@ -134,9 +134,11 @@ bool QWinRTMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModa
RETURN_FALSE_IF_FAILED("Failed to create command factory");
ComPtr<IMessageDialog> dialog;
- HStringReference nativeText(reinterpret_cast<LPCWSTR>(text.utf16()), text.size());
+ HStringReference nativeText(reinterpret_cast<LPCWSTR>(text.utf16()),
+ uint(text.size()));
if (!title.isEmpty()) {
- HStringReference nativeTitle(reinterpret_cast<LPCWSTR>(title.utf16()), title.size());
+ HStringReference nativeTitle(reinterpret_cast<LPCWSTR>(title.utf16()),
+ uint(title.size()));
hr = dialogFactory->CreateWithTitle(nativeText.Get(), nativeTitle.Get(), &dialog);
RETURN_FALSE_IF_FAILED("Failed to create dialog with title");
} else {
@@ -162,7 +164,8 @@ bool QWinRTMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModa
continue;
// Add native command
const QString label = d->theme->standardButtonText(i);
- HStringReference nativeLabel(reinterpret_cast<LPCWSTR>(label.utf16()), label.size());
+ HStringReference nativeLabel(reinterpret_cast<LPCWSTR>(label.utf16()),
+ uint(label.size()));
ComPtr<IUICommand> command;
hr = commandFactory->Create(nativeLabel.Get(), &command);
RETURN_HR_IF_FAILED("Failed to create message box command");
diff --git a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h
index 14b6d4b715..ab704b1c7d 100644
--- a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h
+++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h
@@ -67,7 +67,7 @@ class QWinRTMessageDialogHelper : public QPlatformMessageDialogHelper
Q_OBJECT
public:
explicit QWinRTMessageDialogHelper(const QWinRTTheme *theme);
- ~QWinRTMessageDialogHelper();
+ ~QWinRTMessageDialogHelper() override;
void exec() override;
bool show(Qt::WindowFlags windowFlags,
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index e39a87148a..bd2bbcb81c 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -46,9 +46,11 @@
#include "qwinrtdrag.h"
#endif
#include "qwinrtwindow.h"
+#include "qwinrtcanvas.h"
#include <private/qeventdispatcher_winrt_p.h>
#include <private/qhighdpiscaling_p.h>
+#include <QtCore/qdebug.h>
#include <QtCore/QLoggingCategory>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QGuiApplication>
@@ -99,6 +101,31 @@ typedef ITypedEventHandler<ApplicationView*, IInspectable*> VisibleBoundsChanged
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug dbg, QWinRTScreen::MousePositionTransition transition)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "QWinRTScreen::MousePositionTransition::";
+ switch (transition) {
+ case QWinRTScreen::MousePositionTransition::MovedOut:
+ dbg << "MovedOut";
+ break;
+ case QWinRTScreen::MousePositionTransition::MovedIn:
+ dbg << "MovedIn";
+ break;
+ case QWinRTScreen::MousePositionTransition::StayedOut:
+ dbg << "StayedOut";
+ break;
+ case QWinRTScreen::MousePositionTransition::StayedIn:
+ dbg << "StayedIn";
+ break;
+ }
+ return dbg;
+}
+#endif
+
struct KeyInfo {
KeyInfo()
{
@@ -463,7 +490,7 @@ public:
QTouchDevice *touchDevice;
ComPtr<ICoreWindow> coreWindow;
ComPtr<ICorePointerRedirector> redirect;
- ComPtr<Xaml::IDependencyObject> canvas;
+ ComPtr<QWinRTCanvas> canvas;
ComPtr<IApplicationView> view;
ComPtr<IDisplayInformation> displayInformation;
@@ -490,6 +517,7 @@ public:
QAtomicPointer<QWinRTWindow> keyboardGrabWindow;
QWindow *currentPressWindow = nullptr;
QWindow *currentTargetWindow = nullptr;
+ bool firstMouseMove = true;
};
// To be called from the XAML thread
@@ -553,27 +581,25 @@ QWinRTScreen::QWinRTScreen()
hr = applicationViewStatics->GetForCurrentView(&d->view);
RETURN_VOID_IF_FAILED("Could not access currentView");
- // Create a canvas and set it as the window content. Eventually, this should have its own method so multiple "screens" can be added
- ComPtr<Xaml::Controls::ICanvas> canvas;
- hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(), &canvas);
- Q_ASSERT_SUCCEEDED(hr);
+ d->canvas = Make<QWinRTCanvas>([this]() { return topWindow(); });
+
ComPtr<Xaml::IFrameworkElement> frameworkElement;
- hr = canvas.As(&frameworkElement);
+ hr = d->canvas.As(&frameworkElement);
Q_ASSERT_SUCCEEDED(hr);
hr = frameworkElement->put_Width(d->logicalRect.width());
Q_ASSERT_SUCCEEDED(hr);
hr = frameworkElement->put_Height(d->logicalRect.height());
Q_ASSERT_SUCCEEDED(hr);
+
ComPtr<Xaml::IUIElement> uiElement;
- hr = canvas.As(&uiElement);
+ hr = d->canvas.As(&uiElement);
Q_ASSERT_SUCCEEDED(hr);
+
#if QT_CONFIG(draganddrop)
QWinRTDrag::instance()->setUiElement(uiElement);
#endif
hr = window->put_Content(uiElement.Get());
Q_ASSERT_SUCCEEDED(hr);
- hr = canvas.As(&d->canvas);
- Q_ASSERT_SUCCEEDED(hr);
d->cursor.reset(new QWinRTCursor);
@@ -723,7 +749,10 @@ ICoreWindow *QWinRTScreen::coreWindow() const
Xaml::IDependencyObject *QWinRTScreen::canvas() const
{
Q_D(const QWinRTScreen);
- return d->canvas.Get();
+ Xaml::IDependencyObject *depCanvas;
+ if (SUCCEEDED(d->canvas.CopyTo(&depCanvas)))
+ return depCanvas;
+ return nullptr;
}
void QWinRTScreen::initialize()
@@ -848,6 +877,7 @@ void QWinRTScreen::addWindow(QWindow *window)
}
handleExpose();
+ d->firstMouseMove = true;
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
#if QT_CONFIG(draganddrop)
@@ -860,6 +890,8 @@ void QWinRTScreen::removeWindow(QWindow *window)
Q_D(QWinRTScreen);
qCDebug(lcQpaWindows) << __FUNCTION__ << window;
+ handleExpose();
+
const bool wasTopWindow = window == topWindow();
if (!d->visibleWindows.removeAll(window))
return;
@@ -867,7 +899,6 @@ void QWinRTScreen::removeWindow(QWindow *window)
const Qt::WindowType type = window->type();
if (wasTopWindow && type != Qt::Popup && type != Qt::ToolTip && type != Qt::Tool)
QWindowSystemInterface::handleWindowActivated(nullptr, Qt::OtherFocusReason);
- handleExpose();
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
#if QT_CONFIG(draganddrop)
if (wasTopWindow)
@@ -1075,6 +1106,7 @@ HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *, ICharacterReceivedEvent
HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaEvents) << __FUNCTION__;
ComPtr<IPointerPoint> pointerPoint;
if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) {
@@ -1087,7 +1119,9 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
if (d->mouseGrabWindow)
d->currentTargetWindow = d->mouseGrabWindow.load()->window();
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleEnterEvent" << d->currentTargetWindow << pos;
QWindowSystemInterface::handleEnterEvent(d->currentTargetWindow, pos, pos);
+ d->firstMouseMove = false;
}
return S_OK;
}
@@ -1095,7 +1129,7 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args)
{
Q_D(QWinRTScreen);
-
+ qCDebug(lcQpaEvents) << __FUNCTION__;
ComPtr<IPointerPoint> pointerPoint;
if (FAILED(args->get_CurrentPoint(&pointerPoint)))
return E_INVALIDARG;
@@ -1109,6 +1143,7 @@ HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args)
if (d->mouseGrabWindow)
d->currentTargetWindow = d->mouseGrabWindow.load()->window();
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleLeaveEvent" << d->currentTargetWindow;
QWindowSystemInterface::handleLeaveEvent(d->currentTargetWindow);
d->currentTargetWindow = nullptr;
return S_OK;
@@ -1120,6 +1155,7 @@ ComPtr<IPointerPoint> qt_winrt_lastPointerPoint;
HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
{
Q_D(QWinRTScreen);
+ qCDebug(lcQpaEvents) << __FUNCTION__;
ComPtr<IPointerPoint> pointerPoint;
if (FAILED(args->get_CurrentPoint(&pointerPoint)))
return E_INVALIDARG;
@@ -1175,6 +1211,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
boolean isHorizontal;
properties->get_IsHorizontalMouseWheel(&isHorizontal);
QPoint angleDelta(isHorizontal ? delta : 0, isHorizontal ? 0 : delta);
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleWheelEvent" << d->currentTargetWindow
+ << localPos << pos << angleDelta << mods;
QWindowSystemInterface::handleWheelEvent(d->currentTargetWindow, localPos, pos, QPoint(), angleDelta, mods);
break;
}
@@ -1213,6 +1251,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
const QPointF globalPosDelta = pos - posPoint;
const QPointF localPressPos = d->currentPressWindow->mapFromGlobal(posPoint) + globalPosDelta;
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleMouseEvent" << d->currentPressWindow
+ << localPressPos << pos << buttons << mods;
QWindowSystemInterface::handleMouseEvent(d->currentPressWindow, localPressPos, pos, buttons, mods);
d->currentPressWindow = nullptr;
}
@@ -1224,6 +1264,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
d->currentPressWindow = nullptr;
}
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleMouseEvent" << d->currentTargetWindow
+ << localPos << pos << buttons << mods;
QWindowSystemInterface::handleMouseEvent(d->currentTargetWindow, localPos, pos, buttons, mods);
break;
@@ -1280,6 +1322,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height());
it.value().pressure = pressure;
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleTouchEvent" << d->currentTargetWindow
+ << d->touchDevice << d->touchPoints.values() << mods;
QWindowSystemInterface::handleTouchEvent(d->currentTargetWindow, d->touchDevice, d->touchPoints.values(), mods);
if (wasPressEvent)
it.value().state = Qt::TouchPointStationary;
@@ -1301,6 +1345,9 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
float rotation;
properties->get_Twist(&rotation);
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleTabletEvent" << d->currentTargetWindow
+ << isPressed << pos << pointerType << pressure << xTilt << yTilt
+ << rotation << id << mods;
QWindowSystemInterface::handleTabletEvent(d->currentTargetWindow, isPressed, pos, pos, 0,
pointerType, pressure, xTilt, yTilt,
0, rotation, 0, id, mods);
@@ -1312,6 +1359,70 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
return S_OK;
}
+void QWinRTScreen::emulateMouseMove(const QPointF &point, MousePositionTransition transition)
+{
+ Q_D(QWinRTScreen);
+ qCDebug(lcQpaEvents) << __FUNCTION__ << point << transition;
+ if (transition == MousePositionTransition::StayedOut)
+ return;
+ qt_winrt_lastPointerPoint = nullptr;
+ const QPointF pos(point.x() * d->scaleFactor, point.y() * d->scaleFactor);
+ QPointF localPos = pos;
+
+ const QPoint posPoint = pos.toPoint();
+ QWindow *windowUnderPointer = windowAt(QHighDpiScaling::mapPositionFromNative(posPoint, this));
+ d->currentTargetWindow = windowUnderPointer;
+
+ if (d->mouseGrabWindow)
+ d->currentTargetWindow = d->mouseGrabWindow.load()->window();
+
+ if (d->currentTargetWindow) {
+ const QPointF globalPosDelta = pos - posPoint;
+ localPos = d->currentTargetWindow->mapFromGlobal(posPoint) + globalPosDelta;
+ }
+
+ // In case of a mouse grab we have to store the target of a press event
+ // to be able to send one additional release event to this target when the mouse
+ // button is released. This is a similar approach to AutoMouseCapture in the
+ // windows qpa backend. Otherwise the release might not be propagated and the original
+ // press event receiver considers a button to still be pressed, as in Qt Quick Controls 1
+ // menus.
+ if (d->currentPressWindow && d->mouseGrabWindow) {
+ const QPointF globalPosDelta = pos - posPoint;
+ const QPointF localPressPos = d->currentPressWindow->mapFromGlobal(posPoint) + globalPosDelta;
+
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleMouseEvent" << d->currentPressWindow
+ << localPressPos << pos << Qt::NoButton << Qt::NoModifier;
+ QWindowSystemInterface::handleMouseEvent(d->currentPressWindow, localPressPos, pos,
+ Qt::NoButton, Qt::NoModifier);
+ d->currentPressWindow = nullptr;
+ }
+ // If the mouse button is released outside of a window, targetWindow is 0, but the event
+ // has to be delivered to the window, that initially received the mouse press. Do not reset
+ // d->currentTargetWindow though, as it is used (and reset) in onPointerExited.
+ if (d->currentPressWindow && !d->currentTargetWindow) {
+ d->currentTargetWindow = d->currentPressWindow;
+ d->currentPressWindow = nullptr;
+ }
+
+ if (transition == MousePositionTransition::MovedOut) {
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleLeaveEvent" << d->currentTargetWindow;
+ QWindowSystemInterface::handleLeaveEvent(d->currentTargetWindow);
+ return;
+ }
+
+ if (transition == MousePositionTransition::MovedIn || d->firstMouseMove) {
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleEnterEvent" << d->currentTargetWindow
+ << localPos << pos;
+ QWindowSystemInterface::handleEnterEvent(d->currentTargetWindow, localPos, pos);
+ d->firstMouseMove = false;
+ }
+ qCDebug(lcQpaEvents) << __FUNCTION__ << "handleMouseEvent" << d->currentTargetWindow
+ << localPos << pos << Qt::NoButton << Qt::NoModifier;
+ QWindowSystemInterface::handleMouseEvent(d->currentTargetWindow, localPos, pos, Qt::NoButton,
+ Qt::NoModifier);
+}
+
HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
{
Q_D(QWinRTScreen);
@@ -1413,6 +1524,7 @@ HRESULT QWinRTScreen::onRedirectReleased(ICorePointerRedirector *, IPointerEvent
{
// When dragging ends with a non-mouse input device then onRedirectRelease is invoked.
// QTBUG-58781
+ qCDebug(lcQpaEvents) << __FUNCTION__;
return onPointerUpdated(nullptr, args);
}
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index fd6499c2b9..cde148a638 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -89,7 +89,7 @@ class QWinRTScreen : public QPlatformScreen
{
public:
explicit QWinRTScreen();
- ~QWinRTScreen();
+ ~QWinRTScreen() override;
QRect geometry() const override;
QRect availableGeometry() const override;
@@ -128,6 +128,15 @@ public:
void setCursorRect(const QRectF &cursorRect);
void setKeyboardRect(const QRectF &keyboardRect);
+ enum class MousePositionTransition {
+ MovedOut,
+ MovedIn,
+ StayedIn,
+ StayedOut
+ };
+
+ void emulateMouseMove(const QPointF &point, MousePositionTransition transition);
+
private:
void handleExpose();
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
index 05620ca4c8..b27c408f40 100644
--- a/src/plugins/platforms/winrt/qwinrtservices.cpp
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -83,17 +83,14 @@ QWinRTServices::QWinRTServices()
Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
}
-QWinRTServices::~QWinRTServices()
-{
-}
-
bool QWinRTServices::openUrl(const QUrl &url)
{
Q_D(QWinRTServices);
ComPtr<IUriRuntimeClass> uri;
QString urlString = url.toString();
- HStringReference uriString(reinterpret_cast<LPCWSTR>(urlString.utf16()), urlString.length());
+ HStringReference uriString(reinterpret_cast<LPCWSTR>(urlString.utf16()),
+ uint(urlString.length()));
HRESULT hr = d->uriFactory->CreateUri(uriString.Get(), &uri);
RETURN_FALSE_IF_FAILED("Failed to create URI from QUrl.");
@@ -122,7 +119,8 @@ bool QWinRTServices::openDocument(const QUrl &url)
}
if (!file) {
const QString pathString = QDir::toNativeSeparators(url.toLocalFile());
- HStringReference path(reinterpret_cast<LPCWSTR>(pathString.utf16()), pathString.length());
+ HStringReference path(reinterpret_cast<LPCWSTR>(pathString.utf16()),
+ uint(pathString.length()));
ComPtr<IAsyncOperation<StorageFile *>> op;
hr = d->fileFactory->GetFileFromPathAsync(path.Get(), &op);
RETURN_FALSE_IF_FAILED("Failed to initialize file URI.");
diff --git a/src/plugins/platforms/winrt/qwinrtservices.h b/src/plugins/platforms/winrt/qwinrtservices.h
index 80b9a6c92a..202ce722cf 100644
--- a/src/plugins/platforms/winrt/qwinrtservices.h
+++ b/src/plugins/platforms/winrt/qwinrtservices.h
@@ -50,7 +50,7 @@ class QWinRTServices : public QPlatformServices
{
public:
explicit QWinRTServices();
- ~QWinRTServices();
+ ~QWinRTServices() override = default;
bool openUrl(const QUrl &url) override;
bool openDocument(const QUrl &url) override;
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index cbf0ba36c9..29d234d276 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -126,7 +126,7 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_Canvas).Get(),
IID_PPV_ARGS(&d->canvas));
Q_ASSERT_SUCCEEDED(hr);
- hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
// Create a new swapchain and place it inside the canvas
HRESULT hr;
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Controls_SwapChainPanel).Get(),
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 9604b4bbaa..0445e6bf54 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -54,7 +54,7 @@ class QWinRTWindow : public QPlatformWindow
{
public:
QWinRTWindow(QWindow *window);
- ~QWinRTWindow();
+ ~QWinRTWindow() override;
QSurfaceFormat format() const override;
bool isActive() const override;
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.cpp
new file mode 100644
index 0000000000..40274fb967
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiaaccessibility.h"
+#include "qwinrtuiamainprovider.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QWindow>
+#include <QtGui/QGuiApplication>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtCore/qt_windows.h>
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+QWinRTUiaAccessibility::QWinRTUiaAccessibility()
+{
+}
+
+QWinRTUiaAccessibility::~QWinRTUiaAccessibility()
+{
+}
+
+// Handles UI Automation window messages.
+void QWinRTUiaAccessibility::activate()
+{
+ // Start handling accessibility internally
+ QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true);
+}
+
+// Handles accessibility update notifications.
+void QWinRTUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
+{
+ if (!event)
+ return;
+
+ QAccessibleInterface *accessible = event->accessibleInterface();
+ if (!isActive() || !accessible || !accessible->isValid())
+ return;
+
+ switch (event->type()) {
+ case QAccessible::Focus:
+ QWinRTUiaMainProvider::notifyFocusChange(event);
+ break;
+ case QAccessible::ObjectCreated:
+ case QAccessible::ObjectDestroyed:
+ case QAccessible::ObjectShow:
+ case QAccessible::ObjectHide:
+ case QAccessible::ObjectReorder:
+ QWinRTUiaMainProvider::notifyVisibilityChange(event);
+ break;
+ case QAccessible::StateChanged:
+ QWinRTUiaMainProvider::notifyStateChange(static_cast<QAccessibleStateChangeEvent *>(event));
+ break;
+ case QAccessible::ValueChanged:
+ QWinRTUiaMainProvider::notifyValueChange(static_cast<QAccessibleValueChangeEvent *>(event));
+ break;
+ case QAccessible::TextAttributeChanged:
+ case QAccessible::TextColumnChanged:
+ case QAccessible::TextInserted:
+ case QAccessible::TextRemoved:
+ case QAccessible::TextUpdated:
+ case QAccessible::TextSelectionChanged:
+ case QAccessible::TextCaretMoved:
+ QWinRTUiaMainProvider::notifyTextChange(event);
+ break;
+ default:
+ break;
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.h
new file mode 100644
index 0000000000..b966271e21
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaaccessibility.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAACCESSIBILITY_H
+#define QWINRTUIAACCESSIBILITY_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <qpa/qplatformaccessibility.h>
+
+QT_BEGIN_NAMESPACE
+
+// WinRT platform accessibility implemented over UI Automation.
+class QWinRTUiaAccessibility : public QPlatformAccessibility
+{
+public:
+ explicit QWinRTUiaAccessibility();
+ virtual ~QWinRTUiaAccessibility();
+ static void activate();
+ void notifyAccessibilityUpdate(QAccessibleEvent *event) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAACCESSIBILITY_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.cpp
new file mode 100644
index 0000000000..ee53714caa
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+QWinRTUiaBaseProvider::QWinRTUiaBaseProvider(QAccessible::Id id) :
+ m_id(id)
+{
+}
+
+QWinRTUiaBaseProvider::~QWinRTUiaBaseProvider()
+{
+}
+
+QAccessibleInterface *QWinRTUiaBaseProvider::accessibleInterface() const
+{
+ QAccessibleInterface *accessible = QAccessible::accessibleInterface(m_id);
+ if (accessible && accessible->isValid())
+ return accessible;
+ return nullptr;
+}
+
+QAccessible::Id QWinRTUiaBaseProvider::id() const
+{
+ return m_id;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.h
new file mode 100644
index 0000000000..d8837354dc
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiabaseprovider.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIABASEPROVIDER_H
+#define QWINRTUIABASEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+// Base class for UI Automation providers.
+class QWinRTUiaBaseProvider : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaBaseProvider)
+public:
+ explicit QWinRTUiaBaseProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaBaseProvider();
+
+ QAccessibleInterface *accessibleInterface() const;
+ QAccessible::Id id() const;
+
+private:
+ QAccessible::Id m_id;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIABASEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.cpp
new file mode 100644
index 0000000000..4e406a3545
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiacontrolmetadata.h"
+#include "qwinrtuiautils.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+
+QWinRTUiaControlMetadata::QWinRTUiaControlMetadata()
+{
+}
+
+QWinRTUiaControlMetadata::QWinRTUiaControlMetadata(QAccessible::Id id)
+{
+ update(id);
+}
+
+void QWinRTUiaControlMetadata::update(QAccessible::Id id)
+{
+ if (QAccessibleInterface *accessible = accessibleForId(id)) {
+ m_automationId = generateAutomationId(accessible);
+ m_className = generateClassName(accessible);
+ m_controlName = generateControlName(accessible);
+ m_role = generateRole(accessible);
+ m_state = accessible->state();
+ m_accelerator = accessible->text(QAccessible::Accelerator);
+ m_access = accessible->text(QAccessible::Accelerator);
+ m_help = accessible->text(QAccessible::Help);
+ m_description = accessible->text(QAccessible::Description);
+ m_value = accessible->text(QAccessible::Value);
+ m_boundingRect = accessible->rect();
+ updateValueData(accessible);
+ updateTableData(accessible);
+ updateTextData(accessible);
+ }
+}
+
+QString QWinRTUiaControlMetadata::generateControlName(QAccessibleInterface *accessible)
+{
+ const bool clientTopLevel = (accessible->role() == QAccessible::Client)
+ && accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
+
+ QString name = accessible->text(QAccessible::Name);
+ if (name.isEmpty() && clientTopLevel)
+ name = QCoreApplication::applicationName();
+ return name;
+}
+
+QString QWinRTUiaControlMetadata::generateClassName(QAccessibleInterface *accessible)
+{
+ QString name;
+
+ if (QObject *obj = accessible->object())
+ name = QLatin1String(obj->metaObject()->className());
+ return name;
+}
+
+// Generates an ID based on the name of the controls and their parents.
+QString QWinRTUiaControlMetadata::generateAutomationId(QAccessibleInterface *accessible)
+{
+ QString autid;
+ QObject *obj = accessible->object();
+ while (obj) {
+ QString name = obj->objectName();
+ if (name.isEmpty()) {
+ autid = QStringLiteral("");
+ break;
+ }
+ if (!autid.isEmpty())
+ autid.prepend(QLatin1Char('.'));
+ autid.prepend(name);
+ obj = obj->parent();
+ }
+ return autid;
+}
+
+QAccessible::Role QWinRTUiaControlMetadata::generateRole(QAccessibleInterface *accessible)
+{
+ const bool clientTopLevel = (accessible->role() == QAccessible::Client)
+ && accessible->parent() && (accessible->parent()->role() == QAccessible::Application);
+
+ if (clientTopLevel) {
+ // Reports a top-level widget as a window.
+ return QAccessible::Window;
+ } else {
+ return accessible->role();
+ }
+}
+
+void QWinRTUiaControlMetadata::updateValueData(QAccessibleInterface *accessible)
+{
+ if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
+ m_minimumValue = valueInterface->minimumValue().toDouble();
+ m_maximumValue = valueInterface->maximumValue().toDouble();
+ m_currentValue = valueInterface->currentValue().toDouble();
+ m_minimumStepSize = valueInterface->minimumStepSize().toDouble();
+ } else {
+ m_minimumValue = 0.0;
+ m_maximumValue = 0.0;
+ m_currentValue = 0.0;
+ m_minimumStepSize = 0.0;
+ }
+}
+
+void QWinRTUiaControlMetadata::updateTableData(QAccessibleInterface *accessible)
+{
+ if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
+ m_rowIndex = 0;
+ m_columnIndex = 0;
+ m_rowCount = tableInterface->rowCount();
+ m_columnCount = tableInterface->columnCount();
+ } else if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
+ m_rowIndex = tableCellInterface->rowIndex();
+ m_columnIndex = tableCellInterface->columnIndex();
+ m_rowCount = tableCellInterface->rowExtent();
+ m_columnCount = tableCellInterface->columnExtent();
+ } else {
+ m_rowIndex = 0;
+ m_columnIndex = 0;
+ m_rowCount = 0;
+ m_columnCount = 0;
+ }
+}
+
+void QWinRTUiaControlMetadata::updateTextData(QAccessibleInterface *accessible)
+{
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ m_cursorPosition = textInterface->cursorPosition();
+ m_text = textInterface->text(0, textInterface->characterCount());
+ } else {
+ m_cursorPosition = 0;
+ m_text = QStringLiteral("");
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.h
new file mode 100644
index 0000000000..769f073a1b
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiacontrolmetadata.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIACONTROLMETADATA_H
+#define QWINRTUIACONTROLMETADATA_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <QString>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+
+QT_BEGIN_NAMESPACE
+
+// Cacheable control metadata
+class QWinRTUiaControlMetadata
+{
+public:
+ QWinRTUiaControlMetadata();
+ QWinRTUiaControlMetadata(QAccessible::Id id);
+ void update(QAccessible::Id id);
+ QString automationId() const { return m_automationId; }
+ QString className() const { return m_className; }
+ QString controlName() const { return m_controlName; }
+ QString accelerator() const { return m_accelerator; }
+ QString access() const { return m_access; }
+ QString help() const { return m_help; }
+ QString description() const { return m_description; }
+ QString value() const { return m_value; }
+ QString text() const { return m_text; }
+ QAccessible::Role role() const { return m_role; }
+ QAccessible::State state() const { return m_state; }
+ QRect boundingRect() const { return m_boundingRect; }
+ double minimumValue() const { return m_minimumValue; }
+ double maximumValue() const { return m_maximumValue; }
+ double currentValue() const { return m_currentValue; }
+ double minimumStepSize() const { return m_minimumStepSize; }
+ int rowIndex() const { return m_rowIndex; }
+ int columnIndex() const { return m_columnIndex; }
+ int rowCount() const { return m_rowCount; }
+ int columnCount() const { return m_columnCount; }
+ int characterCount() const { return m_text.length(); }
+ int cursorPosition() const { return m_cursorPosition; }
+
+private:
+ QString generateControlName(QAccessibleInterface *accessible);
+ QString generateClassName(QAccessibleInterface *accessible);
+ QString generateAutomationId(QAccessibleInterface *accessible);
+ QAccessible::Role generateRole(QAccessibleInterface *accessible);
+ void updateValueData(QAccessibleInterface *accessible);
+ void updateTableData(QAccessibleInterface *accessible);
+ void updateTextData(QAccessibleInterface *accessible);
+ QString m_automationId;
+ QString m_className;
+ QString m_controlName;
+ QString m_accelerator;
+ QString m_access;
+ QString m_help;
+ QString m_description;
+ QString m_value;
+ QString m_text;
+ QAccessible::Role m_role = QAccessible::NoRole;
+ QAccessible::State m_state;
+ QRect m_boundingRect;
+ double m_minimumValue = 0.0;
+ double m_maximumValue = 0.0;
+ double m_currentValue = 0.0;
+ double m_minimumStepSize = 0.0;
+ int m_rowIndex = 0;
+ int m_columnIndex = 0;
+ int m_rowCount = 0;
+ int m_columnCount = 0;
+ int m_cursorPosition = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIACONTROLMETADATA_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaemptypropertyvalue.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaemptypropertyvalue.h
new file mode 100644
index 0000000000..35e4df75fc
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaemptypropertyvalue.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAEMPTYPROPERTYVALUE_H
+#define QWINRTUIAEMPTYPROPERTYVALUE_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements an empty property value.
+class QWinRTUiaEmptyPropertyValue :
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::Foundation::IPropertyValue>
+{
+ InspectableClass(L"QWinRTUiaEmptyPropertyValue", BaseTrust);
+public:
+
+ HRESULT STDMETHODCALLTYPE get_Type(ABI::Windows::Foundation::PropertyType *value)
+ {
+ *value = ABI::Windows::Foundation::PropertyType_Empty;
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE get_IsNumericScalar(boolean*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt8(BYTE*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt16(INT16*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt16(UINT16*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt32(INT32*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt32(UINT32*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt64(INT64*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt64(UINT64*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetSingle(FLOAT*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetDouble(DOUBLE*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetChar16(WCHAR*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetBoolean(boolean*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetString(HSTRING*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetGuid(GUID*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetDateTime(ABI::Windows::Foundation::DateTime*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetTimeSpan(ABI::Windows::Foundation::TimeSpan*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetPoint(ABI::Windows::Foundation::Point*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetSize(ABI::Windows::Foundation::Size*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetRect(ABI::Windows::Foundation::Rect*) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt8Array(UINT32*, BYTE**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt16Array(UINT32*, INT16**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt16Array(UINT32*, UINT16**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt32Array(UINT32*, INT32**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt32Array(UINT32*, UINT32**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInt64Array(UINT32*, INT64**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetUInt64Array(UINT32*, UINT64**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetSingleArray(UINT32*, FLOAT**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetDoubleArray(UINT32*, DOUBLE**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetChar16Array(UINT32*, WCHAR**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetBooleanArray(UINT32*, boolean**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetStringArray(UINT32*, HSTRING**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetInspectableArray(UINT32*, IInspectable***) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetGuidArray(UINT32*, GUID**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetDateTimeArray(UINT32*, ABI::Windows::Foundation::DateTime**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetTimeSpanArray(UINT32*, ABI::Windows::Foundation::TimeSpan**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetPointArray(UINT32*, ABI::Windows::Foundation::Point**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetSizeArray(UINT32*, ABI::Windows::Foundation::Size**) { return E_FAIL; }
+ HRESULT STDMETHODCALLTYPE GetRectArray(UINT32*, ABI::Windows::Foundation::Rect**) { return E_FAIL; }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAEMPTYPROPERTYVALUE_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
new file mode 100644
index 0000000000..524000b618
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiagriditemprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaGridItemProvider::QWinRTUiaGridItemProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaGridItemProvider::~QWinRTUiaGridItemProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns the column index of the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_Column(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->columnIndex();
+ return S_OK;
+}
+
+// Returns the number of columns occupied by the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ColumnSpan(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->columnCount();
+ return S_OK;
+}
+
+// Returns the provider for the containing table/tree.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ContainingGrid(IIRawElementProviderSimple **value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ *value = nullptr;
+
+ auto accid = id();
+ auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
+ auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
+ if (QAccessibleInterface *table = tableCellInterface->table()) {
+ **ptrElementId = idForAccessible(table);
+ QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ }
+ }
+ }
+ delete ptrElementId;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ if (!*elementId)
+ return S_OK;
+
+ return QWinRTUiaMainProvider::rawProviderForAccessibleId(*elementId, value);
+}
+
+// Returns the row index of the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_Row(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->rowIndex();
+ return S_OK;
+}
+
+// Returns the number of rows occupied by the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_RowSpan(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->rowCount();
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.h
new file mode 100644
index 0000000000..70504fc555
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAGRIDITEMPROVIDER_H
+#define QWINRTUIAGRIDITEMPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Grid Item control pattern provider. Used by items within a table/tree.
+class QWinRTUiaGridItemProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IGridItemProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaGridItemProvider)
+ InspectableClass(L"QWinRTUiaGridItemProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaGridItemProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaGridItemProvider();
+
+ // IGridItemProvider
+ HRESULT STDMETHODCALLTYPE get_Column(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE get_ColumnSpan(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE get_ContainingGrid(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **value) override;
+ HRESULT STDMETHODCALLTYPE get_Row(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE get_RowSpan(INT32 *value) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAGRIDITEMPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
new file mode 100644
index 0000000000..e469991de2
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiagridprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaGridProvider::QWinRTUiaGridProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaGridProvider::~QWinRTUiaGridProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns the number of columns.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::get_ColumnCount(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->columnCount();
+ return S_OK;
+}
+
+// Returns the number of rows.
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::get_RowCount(INT32 *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->rowCount();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::GetItem(INT32 row, INT32 column, IIRawElementProviderSimple **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
+ auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, ptrElementId]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
+ if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) {
+ if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) {
+ **ptrElementId = idForAccessible(cell);
+ QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ }
+ }
+ }
+ }
+ delete ptrElementId;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ if (!*elementId)
+ return E_FAIL;
+
+ return QWinRTUiaMainProvider::rawProviderForAccessibleId(*elementId, returnValue);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.h
new file mode 100644
index 0000000000..d6dfaed315
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAGRIDPROVIDER_H
+#define QWINRTUIAGRIDPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Grid control pattern provider. Used by tables/trees.
+class QWinRTUiaGridProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IGridProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaGridProvider)
+ InspectableClass(L"QWinRTUiaGridProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaGridProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaGridProvider();
+
+ // IGridProvider
+ HRESULT STDMETHODCALLTYPE get_ColumnCount(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE get_RowCount(INT32 *value) override;
+ HRESULT STDMETHODCALLTYPE GetItem(INT32 row, INT32 column, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAGRIDPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.cpp
new file mode 100644
index 0000000000..e2cf7bc107
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiainvokeprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaInvokeProvider::QWinRTUiaInvokeProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaInvokeProvider::~QWinRTUiaInvokeProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaInvokeProvider::Invoke()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface())
+ actionInterface->doAction(QAccessibleActionInterface::pressAction());
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.h
new file mode 100644
index 0000000000..dfe7917a16
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiainvokeprovider.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAINVOKEPROVIDER_H
+#define QWINRTUIAINVOKEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Invoke control pattern provider.
+class QWinRTUiaInvokeProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IInvokeProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaInvokeProvider)
+ InspectableClass(L"QWinRTUiaInvokeProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaInvokeProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaInvokeProvider();
+
+ // IInvokeProvider
+ HRESULT STDMETHODCALLTYPE Invoke() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAINVOKEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
new file mode 100644
index 0000000000..6f3ad6dcd2
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp
@@ -0,0 +1,789 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiaprovidercache.h"
+#include "qwinrtuiavalueprovider.h"
+#include "qwinrtuiarangevalueprovider.h"
+#include "qwinrtuiatextprovider.h"
+#include "qwinrtuiatoggleprovider.h"
+#include "qwinrtuiainvokeprovider.h"
+#include "qwinrtuiaselectionprovider.h"
+#include "qwinrtuiaselectionitemprovider.h"
+#include "qwinrtuiatableprovider.h"
+#include "qwinrtuiatableitemprovider.h"
+#include "qwinrtuiagridprovider.h"
+#include "qwinrtuiagriditemprovider.h"
+#include "qwinrtuiapeervector.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiaemptypropertyvalue.h"
+#include "qwinrtuiautils.h"
+
+#include <QCoreApplication>
+#include <QSemaphore>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/qfunctions_winrt.h>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+using namespace QWinRTUiAutomation;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::System;
+using namespace ABI::Windows::UI;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::Xaml;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTUiaMainProvider::QWinRTUiaMainProvider(QAccessible::Id id)
+ : QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ ComPtr<IAutomationPeerFactory> factory;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Automation_Peers_AutomationPeer).Get(), IID_PPV_ARGS(&factory));
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = factory->CreateInstance(this, &m_base, &m_core);
+ Q_ASSERT_SUCCEEDED(hr);
+}
+
+QWinRTUiaMainProvider::~QWinRTUiaMainProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::QueryInterface(REFIID iid, LPVOID *iface)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!iface)
+ return E_POINTER;
+ *iface = nullptr;
+
+ if (iid == IID_IUnknown) {
+ *iface = static_cast<IAutomationPeerOverrides *>(this);
+ AddRef();
+ return S_OK;
+ } else if (iid == IID_IAutomationPeerOverrides) {
+ *iface = static_cast<IAutomationPeerOverrides *>(this);
+ AddRef();
+ return S_OK;
+ } else {
+ return m_base.CopyTo(iid, iface);
+ }
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetIids(ULONG *iidCount, IID **iids)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ *iidCount = 0;
+ *iids = nullptr;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetRuntimeClassName(HSTRING *className)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ return qHString(QStringLiteral("QWinRTUiaMainProvider"), className);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetTrustLevel(TrustLevel *trustLevel)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ *trustLevel = TrustLevel::BaseTrust;
+ return S_OK;
+}
+
+// Returns a cached instance of the provider for a specific accessible interface.
+QWinRTUiaMainProvider *QWinRTUiaMainProvider::providerForAccessibleId(QAccessible::Id id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ QWinRTUiaProviderCache *providerCache = QWinRTUiaProviderCache::instance();
+ QWinRTUiaMainProvider *provider = qobject_cast<QWinRTUiaMainProvider *>(providerCache->providerForId(id));
+
+ if (provider) {
+ provider->AddRef();
+ } else {
+ ComPtr<QWinRTUiaMainProvider> p = Make<QWinRTUiaMainProvider>(id);
+ provider = p.Get();
+ provider->AddRef();
+ providerCache->insert(id, provider);
+ }
+ return provider;
+}
+
+// Returns an IIRawElementProviderSimple for a specific accessible interface.
+HRESULT QWinRTUiaMainProvider::rawProviderForAccessibleId(QAccessible::Id elementId,
+ IIRawElementProviderSimple **returnValue)
+{
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(elementId)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider.As(&automationPeer))) {
+ ComPtr<IAutomationPeerProtected> automationPeerProtected;
+ if (SUCCEEDED(provider.As(&automationPeerProtected))) {
+ return automationPeerProtected->ProviderFromPeer(automationPeer.Get(), returnValue);
+ }
+ }
+ }
+ return E_FAIL;
+}
+
+// Returns an array of IIRawElementProviderSimple instances for a list of accessible interface ids.
+HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds,
+ UINT32 *returnValueSize,
+ IIRawElementProviderSimple ***returnValue)
+{
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ QList<IIRawElementProviderSimple *> rawProviderList;
+
+ for (auto elementId : qAsConst(elementIds)) {
+ IIRawElementProviderSimple *rawProvider;
+ if (SUCCEEDED(rawProviderForAccessibleId(elementId, &rawProvider)))
+ rawProviderList.append(rawProvider);
+ }
+
+ if (rawProviderList.size() == 0)
+ return S_OK;
+
+ *returnValue = static_cast<IIRawElementProviderSimple **>(CoTaskMemAlloc(rawProviderList.size() * sizeof(IIRawElementProviderSimple *)));
+ if (!*returnValue) {
+ for (auto rawProvider : qAsConst(rawProviderList))
+ rawProvider->Release();
+ return E_OUTOFMEMORY;
+ }
+
+ int index = 0;
+ for (auto rawProvider : qAsConst(rawProviderList))
+ (*returnValue)[index++] = rawProvider;
+ *returnValueSize = rawProviderList.size();
+ return S_OK;
+}
+
+void QWinRTUiaMainProvider::notifyFocusChange(QAccessibleEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ QEventDispatcherWinRT::runOnXamlThread([accid]() {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(accid)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider->QueryInterface(IID_PPV_ARGS(&automationPeer)))) {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_AutomationFocusChanged);
+ }
+ }
+ return S_OK;
+ }, false);
+ }
+}
+
+void QWinRTUiaMainProvider::notifyVisibilityChange(QAccessibleEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ }
+}
+
+void QWinRTUiaMainProvider::notifyStateChange(QAccessibleStateChangeEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+
+ if (event->changedStates().checked || event->changedStates().checkStateMixed) {
+ // Notifies states changes in checkboxes.
+ if (accessible->role() == QAccessible::CheckBox) {
+ QEventDispatcherWinRT::runOnXamlThread([accid]() {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(accid)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider->QueryInterface(IID_PPV_ARGS(&automationPeer)))) {
+ ComPtr<ITogglePatternIdentifiersStatics> toggleStatics;
+ if (SUCCEEDED(RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Automation_TogglePatternIdentifiers).Get(), IID_PPV_ARGS(&toggleStatics)))) {
+ ComPtr<IAutomationProperty> toggleStateProperty;
+ if (SUCCEEDED(toggleStatics->get_ToggleStateProperty(&toggleStateProperty))) {
+ ComPtr<QWinRTUiaEmptyPropertyValue> emptyValue = Make<QWinRTUiaEmptyPropertyValue>();
+ // by sending an event with an empty value we force ui automation to refresh its state
+ automationPeer->RaisePropertyChangedEvent(toggleStateProperty.Get(), emptyValue.Get(), emptyValue.Get());
+ }
+ }
+ }
+ }
+ return S_OK;
+ }, false);
+ }
+ }
+ if (event->changedStates().active) {
+ if (accessible->role() == QAccessible::Window) {
+ // Notifies window opened/closed.
+ bool active = accessible->state().active;
+ QEventDispatcherWinRT::runOnXamlThread([accid, active]() {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(accid)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider->QueryInterface(IID_PPV_ARGS(&automationPeer)))) {
+ if (active) {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_WindowOpened);
+ } else {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_WindowClosed);
+ }
+ }
+ }
+ return S_OK;
+ }, false);
+ }
+ }
+ }
+}
+
+void QWinRTUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
+ // Notifies changes in values of controls supporting the value interface.
+ double value = valueInterface->currentValue().toDouble();
+ QEventDispatcherWinRT::runOnXamlThread([accid, value]() {
+ // For some reason RaisePropertyChangedEvent() does not seem to be
+ // forwarding notifications for any property types except empty,
+ // which would do nothing here. ToDo: find a workaround.
+ return S_OK;
+ }, false);
+ }
+ }
+}
+
+// Notifies changes in text content and selection state of text controls.
+void QWinRTUiaMainProvider::notifyTextChange(QAccessibleEvent *event)
+{
+ if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ QAccessible::Id accid = idForAccessible(accessible);
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ bool readOnly = accessible->state().readOnly;
+ QAccessible::Event eventType = event->type();
+ if (accessible->textInterface()) {
+ QEventDispatcherWinRT::runOnXamlThread([accid, eventType, readOnly]() {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(accid)) {
+ ComPtr<IAutomationPeer> automationPeer;
+ if (SUCCEEDED(provider->QueryInterface(IID_PPV_ARGS(&automationPeer)))) {
+ if (eventType == QAccessible::TextSelectionChanged) {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_TextPatternOnTextSelectionChanged);
+ } else if (eventType == QAccessible::TextCaretMoved) {
+ if (!readOnly) {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_TextPatternOnTextSelectionChanged);
+ }
+ } else {
+ automationPeer->RaiseAutomationEvent(AutomationEvents_TextPatternOnTextChanged);
+ }
+ }
+ }
+ return S_OK;
+ }, false);
+ }
+ }
+}
+
+// Return providers for specific control patterns
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPatternCore(PatternInterface patternInterface, IInspectable **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__ << patternInterface;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible)
+ return E_FAIL;
+
+ switch (patternInterface) {
+ case PatternInterface_Text:
+ case PatternInterface_Text2: {
+ // All text controls.
+ if (accessible->textInterface()) {
+ ComPtr<QWinRTUiaTextProvider> provider = Make<QWinRTUiaTextProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Value: {
+ // All accessible controls return text(QAccessible::Value) (which may be empty).
+ ComPtr<QWinRTUiaValueProvider> provider = Make<QWinRTUiaValueProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ case PatternInterface_RangeValue: {
+ // Controls providing a numeric value within a range (e.g., sliders, scroll bars, dials).
+ if (accessible->valueInterface()) {
+ ComPtr<QWinRTUiaRangeValueProvider> provider = Make<QWinRTUiaRangeValueProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Toggle: {
+ // Checkbox controls.
+ if (accessible->role() == QAccessible::CheckBox) {
+ ComPtr<QWinRTUiaToggleProvider> provider = Make<QWinRTUiaToggleProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Selection: {
+ // Lists of items.
+ if (accessible->role() == QAccessible::List) {
+ ComPtr<QWinRTUiaSelectionProvider> provider = Make<QWinRTUiaSelectionProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_SelectionItem: {
+ // Items within a list and radio buttons.
+ if ((accessible->role() == QAccessible::RadioButton)
+ || (accessible->role() == QAccessible::ListItem)) {
+ ComPtr<QWinRTUiaSelectionItemProvider> provider = Make<QWinRTUiaSelectionItemProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Table: {
+ // Table/tree.
+ if (accessible->tableInterface()
+ && ((accessible->role() == QAccessible::Table) || (accessible->role() == QAccessible::Tree))) {
+ ComPtr<QWinRTUiaTableProvider> provider = Make<QWinRTUiaTableProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_TableItem: {
+ // Item within a table/tree.
+ if (accessible->tableCellInterface()
+ && ((accessible->role() == QAccessible::Cell) || (accessible->role() == QAccessible::TreeItem))) {
+ ComPtr<QWinRTUiaTableItemProvider> provider = Make<QWinRTUiaTableItemProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Grid: {
+ // Table/tree.
+ if (accessible->tableInterface()
+ && ((accessible->role() == QAccessible::Table) || (accessible->role() == QAccessible::Tree))) {
+ ComPtr<QWinRTUiaGridProvider> provider = Make<QWinRTUiaGridProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_GridItem: {
+ // Item within a table/tree.
+ if (accessible->tableCellInterface()
+ && ((accessible->role() == QAccessible::Cell) || (accessible->role() == QAccessible::TreeItem))) {
+ ComPtr<QWinRTUiaGridItemProvider> provider = Make<QWinRTUiaGridItemProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ case PatternInterface_Invoke: {
+ // Things that have an invokable action (e.g., simple buttons).
+ if (accessible->actionInterface()) {
+ ComPtr<QWinRTUiaInvokeProvider> provider = Make<QWinRTUiaInvokeProvider>(id());
+ return provider.CopyTo(returnValue);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetAcceleratorKeyCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->accelerator(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetAccessKeyCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->access(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetAutomationControlTypeCore(AutomationControlType *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = roleToControlType(metadata->role());
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetAutomationIdCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->automationId(), returnValue);
+}
+
+// Returns the bounding rectangle for the accessible control.
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetBoundingRectangleCore(ABI::Windows::Foundation::Rect *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ QRect rect = metadata->boundingRect();
+ returnValue->X = rect.x();
+ returnValue->Y = rect.y();
+ returnValue->Width = rect.width();
+ returnValue->Height = rect.height();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<AutomationPeer *> **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto children = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrChildren = new QSharedPointer<QList<QAccessible::Id>>(children);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrChildren]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ int childCount = accessible->childCount();
+ for (int i = 0; i < childCount; ++i) {
+ if (QAccessibleInterface *childAcc = accessible->child(i)) {
+ QAccessible::Id childId = idForAccessible(childAcc);
+ QWinRTUiaMetadataCache::instance()->load(childId);
+ if (!childAcc->state().invisible)
+ (*ptrChildren)->append(childId);
+ }
+ }
+ }
+ delete ptrChildren;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ ComPtr<IVector<AutomationPeer *>> peerVector = Make<QWinRTUiaPeerVector>();
+
+ for (auto childId : qAsConst(*children)) {
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(childId)) {
+ IAutomationPeer *peer;
+ if (SUCCEEDED(provider.CopyTo(&peer)))
+ peerVector->Append(peer);
+ }
+ }
+ return peerVector.CopyTo(returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetClassNameCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->className(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetClickablePointCore(ABI::Windows::Foundation::Point *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetHelpTextCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->help(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetItemStatusCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetItemTypeCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetLabeledByCore(IAutomationPeer **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetLocalizedControlTypeCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetNameCore(HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->controlName(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetOrientationCore(AutomationOrientation *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = AutomationOrientation_None;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::HasKeyboardFocusCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->state().focused != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsContentElementCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = true;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsControlElementCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = true;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsEnabledCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->state().disabled == 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsKeyboardFocusableCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->state().focusable != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsOffscreenCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->state().offscreen != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsPasswordCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *returnValue = (metadata->role() == QAccessible::EditableText) && (metadata->state().passwordEdit != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::IsRequiredForFormCore(boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = false;
+ return S_OK;
+}
+
+// Sets focus to the control.
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::SetFocusCore()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible)
+ return E_FAIL;
+
+ QAccessibleActionInterface *actionInterface = accessible->actionInterface();
+ if (!actionInterface)
+ return E_FAIL;
+
+ QEventDispatcherWinRT::runOnMainThread([actionInterface]() {
+ actionInterface->doAction(QAccessibleActionInterface::setFocusAction());
+ return S_OK;
+ });
+ return S_OK;
+}
+
+// Returns a provider for the UI element present at the specified screen coordinates.
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windows::Foundation::Point point, IAutomationPeer **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ // Scale coordinates from High DPI screens?
+
+ auto accid = id();
+ auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
+ auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId, point]() {
+ // Controls can be embedded within grouping elements. By default returns the innermost control.
+ QAccessibleInterface *target = accessibleForId(accid);
+ while (QAccessibleInterface *tmpacc = target->childAt(point.X, point.Y)) {
+ target = tmpacc;
+ // For accessibility tools it may be better to return the text element instead of its subcomponents.
+ if (target->textInterface()) break;
+ }
+ **ptrElementId = idForAccessible(target);
+ QWinRTUiaMetadataCache::instance()->load(**ptrElementId);
+ delete ptrElementId;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(*elementId))
+ return provider.CopyTo(returnValue);
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetLiveSettingCore(AutomationLiveSetting *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ return E_NOTIMPL;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
new file mode 100644
index 0000000000..384a166cf7
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAMAINPROVIDER_H
+#define QWINRTUIAMAINPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/QPointer>
+#include <QtCore/QSharedPointer>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// The main WinRT UI Automation class.
+class QWinRTUiaMainProvider:
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaMainProvider)
+
+public:
+ explicit QWinRTUiaMainProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaMainProvider();
+ static QWinRTUiaMainProvider *providerForAccessibleId(QAccessible::Id id);
+ static HRESULT rawProviderForAccessibleId(QAccessible::Id elementId, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue);
+ static HRESULT rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue);
+ static void notifyFocusChange(QAccessibleEvent *event);
+ static void notifyVisibilityChange(QAccessibleEvent *event);
+ static void notifyStateChange(QAccessibleStateChangeEvent *event);
+ static void notifyValueChange(QAccessibleValueChangeEvent *event);
+ static void notifyTextChange(QAccessibleEvent *event);
+
+ // IUnknown
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface) override;
+
+ // IInspectable
+ HRESULT STDMETHODCALLTYPE GetIids(ULONG *iidCount, IID **iids) override;
+ HRESULT STDMETHODCALLTYPE GetRuntimeClassName(HSTRING *className) override;
+ HRESULT STDMETHODCALLTYPE GetTrustLevel(TrustLevel *trustLevel) override;
+
+ // IAutomationPeerOverrides
+ HRESULT STDMETHODCALLTYPE GetPatternCore(ABI::Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface, IInspectable **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAcceleratorKeyCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAccessKeyCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAutomationControlTypeCore(ABI::Windows::UI::Xaml::Automation::Peers::AutomationControlType *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAutomationIdCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetBoundingRectangleCore(ABI::Windows::Foundation::Rect *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetChildrenCore(ABI::Windows::Foundation::Collections::IVector<ABI::Windows::UI::Xaml::Automation::Peers::AutomationPeer*> **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetClassNameCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetClickablePointCore(ABI::Windows::Foundation::Point *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetHelpTextCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetItemStatusCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetItemTypeCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetLabeledByCore(ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetLocalizedControlTypeCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetNameCore(HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetOrientationCore(ABI::Windows::UI::Xaml::Automation::Peers::AutomationOrientation *returnValue) override;
+ HRESULT STDMETHODCALLTYPE HasKeyboardFocusCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsContentElementCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsControlElementCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsEnabledCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsKeyboardFocusableCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsOffscreenCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsPasswordCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE IsRequiredForFormCore(boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE SetFocusCore() override;
+ HRESULT STDMETHODCALLTYPE GetPeerFromPointCore(ABI::Windows::Foundation::Point point, ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetLiveSettingCore(ABI::Windows::UI::Xaml::Automation::Peers::AutomationLiveSetting *returnValue) override;
+
+private:
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeerOverrides> m_base;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer> m_core;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAMAINPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.cpp
new file mode 100644
index 0000000000..442ff184a8
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+
+// Private constructor
+QWinRTUiaMetadataCache::QWinRTUiaMetadataCache()
+{
+}
+
+// shared instance
+QWinRTUiaMetadataCache *QWinRTUiaMetadataCache::instance()
+{
+ static QWinRTUiaMetadataCache metadataCache;
+ return &metadataCache;
+}
+
+// Returns the cached metadata associated with the ID, or an instance with default values.
+QSharedPointer<QWinRTUiaControlMetadata> QWinRTUiaMetadataCache::metadataForId(QAccessible::Id id)
+{
+ QSharedPointer<QWinRTUiaControlMetadata> metadata;
+
+ m_mutex.lock();
+ if (m_metadataTable.contains(id))
+ metadata = m_metadataTable[id];
+ else
+ metadata = QSharedPointer<QWinRTUiaControlMetadata>(new QWinRTUiaControlMetadata);
+ m_mutex.unlock();
+ return metadata;
+}
+
+// Caches metadata from the accessibility framework within the main thread.
+bool QWinRTUiaMetadataCache::load(QAccessible::Id id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([id]() {
+ QWinRTUiaMetadataCache::instance()->insert(id, QSharedPointer<QWinRTUiaControlMetadata>(new QWinRTUiaControlMetadata(id)));
+ return S_OK;
+ }))) {
+ return false;
+ }
+ return true;
+}
+
+// Inserts metadata in the cache and associates it with an accessibility ID.
+void QWinRTUiaMetadataCache::insert(QAccessible::Id id, const QSharedPointer<QWinRTUiaControlMetadata> &metadata)
+{
+ m_mutex.lock();
+ m_metadataTable[id] = metadata;
+ m_mutex.unlock();
+}
+
+// Removes metadata with a given id from the cache.
+void QWinRTUiaMetadataCache::remove(QAccessible::Id id)
+{
+ m_mutex.lock();
+ m_metadataTable.remove(id);
+ m_mutex.unlock();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.h
new file mode 100644
index 0000000000..2d68d1b654
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiametadatacache.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAMETADATACACHE_H
+#define QWINRTUIAMETADATACACHE_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiacontrolmetadata.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QMutex>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+
+QT_BEGIN_NAMESPACE
+
+// Singleton used to cache metadata using the accessibility ID as the key.
+class QWinRTUiaMetadataCache : public QObject
+{
+ QWinRTUiaMetadataCache();
+ Q_OBJECT
+public:
+ static QWinRTUiaMetadataCache *instance();
+ QSharedPointer<QWinRTUiaControlMetadata> metadataForId(QAccessible::Id id);
+ void insert(QAccessible::Id id, const QSharedPointer<QWinRTUiaControlMetadata> &metadata);
+ void remove(QAccessible::Id id);
+ bool load(QAccessible::Id id);
+
+private:
+ QHash<QAccessible::Id, QSharedPointer<QWinRTUiaControlMetadata>> m_metadataTable;
+ QMutex m_mutex;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAMETADATACACHE_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.cpp
new file mode 100644
index 0000000000..e3d6bcae4b
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiapeervector.h"
+#include "qwinrtuiautils.h"
+
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+using namespace ABI::Windows::Foundation::Collections;
+
+QT_BEGIN_NAMESPACE
+
+HRESULT QWinRTUiaPeerVector::GetAt(quint32 index, IAutomationPeer **item)
+{
+ if (index >= quint32(m_impl.size()))
+ return E_FAIL;
+ if ((*item = m_impl.at(index)))
+ (*item)->AddRef();
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::get_Size(quint32 *size)
+{
+ *size = m_impl.size();
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::GetView(IVectorView<AutomationPeer *> **view)
+{
+ *view = nullptr;
+ return E_NOTIMPL;
+}
+
+HRESULT QWinRTUiaPeerVector::IndexOf(IAutomationPeer *value, quint32 *index, boolean *found)
+{
+ int idx = m_impl.indexOf(value);
+ if (idx > -1) {
+ *index = quint32(idx);
+ *found = true;
+ } else {
+ *found = false;
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::SetAt(quint32 index, IAutomationPeer *item)
+{
+ if (index >= quint32(m_impl.size()))
+ return E_FAIL;
+ if (IAutomationPeer *elem = m_impl.at(index)) {
+ if (elem == item)
+ return S_OK;
+ else
+ elem->Release();
+ }
+ if (item)
+ item->AddRef();
+ m_impl[index] = item;
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::InsertAt(quint32 index, IAutomationPeer *item)
+{
+ if (index >= quint32(m_impl.size()))
+ return E_FAIL;
+ if (item)
+ item->AddRef();
+ m_impl.insert(index, item);
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::RemoveAt(quint32 index)
+{
+ if (index >= quint32(m_impl.size()))
+ return E_FAIL;
+ if (IAutomationPeer *elem = m_impl.at(index))
+ elem->Release();
+ m_impl.remove(index);
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::Append(IAutomationPeer *item)
+{
+ if (item)
+ item->AddRef();
+ m_impl.append(item);
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::RemoveAtEnd()
+{
+ if (m_impl.size() == 0)
+ return E_FAIL;
+ if (IAutomationPeer *elem = m_impl.last())
+ elem->Release();
+ m_impl.removeLast();
+ return S_OK;
+}
+
+HRESULT QWinRTUiaPeerVector::Clear()
+{
+ for (auto elem : qAsConst(m_impl))
+ if (elem)
+ elem->Release();
+ m_impl.clear();
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.h
new file mode 100644
index 0000000000..265526de09
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiapeervector.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAPEERVECTOR_H
+#define QWINRTUIAPEERVECTOR_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <QtCore/QString>
+#include <QtCore/qt_windows.h>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtGui/QWindow>
+#include <QVector>
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements IVector<AutomationPeer *>
+class QWinRTUiaPeerVector : public Microsoft::WRL::RuntimeClass<ABI::Windows::Foundation::Collections::IVector<ABI::Windows::UI::Xaml::Automation::Peers::AutomationPeer *>>
+{
+public:
+ HRESULT STDMETHODCALLTYPE GetAt(quint32 index, ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer **item) override;
+ HRESULT STDMETHODCALLTYPE get_Size(quint32 *size) override;
+ HRESULT STDMETHODCALLTYPE GetView(ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::UI::Xaml::Automation::Peers::AutomationPeer *> **view) override;
+ HRESULT STDMETHODCALLTYPE IndexOf(ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *value, quint32 *index, boolean *found) override;
+ HRESULT STDMETHODCALLTYPE SetAt(quint32 index, ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *item) override;
+ HRESULT STDMETHODCALLTYPE InsertAt(quint32 index, ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *item) override;
+ HRESULT STDMETHODCALLTYPE RemoveAt(quint32 index) override;
+ HRESULT STDMETHODCALLTYPE Append(ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *item) override;
+ HRESULT STDMETHODCALLTYPE RemoveAtEnd() override;
+ HRESULT STDMETHODCALLTYPE Clear() override;
+private:
+ QVector<ABI::Windows::UI::Xaml::Automation::Peers::IAutomationPeer *> m_impl;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAPEERVECTOR_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.cpp
new file mode 100644
index 0000000000..06ff094c45
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiaprovidercache.h"
+
+QT_BEGIN_NAMESPACE
+
+// Private constructor
+QWinRTUiaProviderCache::QWinRTUiaProviderCache()
+{
+}
+
+// shared instance
+QWinRTUiaProviderCache *QWinRTUiaProviderCache::instance()
+{
+ static QWinRTUiaProviderCache providerCache;
+ return &providerCache;
+}
+
+// Returns the provider instance associated with the ID, or nullptr.
+QWinRTUiaBaseProvider *QWinRTUiaProviderCache::providerForId(QAccessible::Id id) const
+{
+ return m_providerTable.value(id);
+}
+
+// Inserts a provider in the cache and associates it with an accessibility ID.
+void QWinRTUiaProviderCache::insert(QAccessible::Id id, QWinRTUiaBaseProvider *provider)
+{
+ remove(id);
+ if (provider) {
+ m_providerTable[id] = provider;
+ m_inverseTable[provider] = id;
+ // Connects the destroyed signal to our slot, to remove deleted objects from the cache.
+ QObject::connect(provider, &QObject::destroyed, this, &QWinRTUiaProviderCache::objectDestroyed);
+ }
+}
+
+// Removes deleted provider objects from the cache.
+void QWinRTUiaProviderCache::objectDestroyed(QObject *obj)
+{
+ // We have to use the inverse table to map the object address back to its ID,
+ // since at this point (called from QObject destructor), it has already been
+ // partially destroyed and we cannot treat it as a provider.
+ auto it = m_inverseTable.find(obj);
+ if (it != m_inverseTable.end()) {
+ m_providerTable.remove(*it);
+ m_inverseTable.remove(obj);
+ }
+}
+
+// Removes a provider with a given id from the cache.
+void QWinRTUiaProviderCache::remove(QAccessible::Id id)
+{
+ m_inverseTable.remove(m_providerTable.value(id));
+ m_providerTable.remove(id);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.h
new file mode 100644
index 0000000000..393ef7d562
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaprovidercache.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAPROVIDERCACHE_H
+#define QWINRTUIAPROVIDERCACHE_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <QtCore/QHash>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+
+QT_BEGIN_NAMESPACE
+
+// Singleton used to cache provider instances using the accessibility ID as the key.
+class QWinRTUiaProviderCache : public QObject
+{
+ QWinRTUiaProviderCache();
+ Q_OBJECT
+public:
+ static QWinRTUiaProviderCache *instance();
+ QWinRTUiaBaseProvider *providerForId(QAccessible::Id id) const;
+ void insert(QAccessible::Id id, QWinRTUiaBaseProvider *provider);
+ void remove(QAccessible::Id id);
+
+private Q_SLOTS:
+ void objectDestroyed(QObject *obj);
+
+private:
+ QHash<QAccessible::Id, QWinRTUiaBaseProvider *> m_providerTable;
+ QHash<QObject *, QAccessible::Id> m_inverseTable;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAPROVIDERCACHE_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.cpp
new file mode 100644
index 0000000000..4ac59c890a
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiarangevalueprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaRangeValueProvider::QWinRTUiaRangeValueProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaRangeValueProvider::~QWinRTUiaRangeValueProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_IsReadOnly(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = (metadata->state().readOnly != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_LargeChange(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->minimumStepSize();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_Maximum(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->maximumValue();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_Minimum(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->minimumValue();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_SmallChange(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->minimumStepSize();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::get_Value(DOUBLE *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = metadata->currentValue();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaRangeValueProvider::SetValue(DOUBLE value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid, value]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
+ double minimum = valueInterface->minimumValue().toDouble();
+ double maximum = valueInterface->maximumValue().toDouble();
+ if ((value >= minimum) && (value <= maximum)) {
+ valueInterface->setCurrentValue(QVariant(value));
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.h
new file mode 100644
index 0000000000..4e98959526
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiarangevalueprovider.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIARANGEVALUEPROVIDER_H
+#define QWINRTUIARANGEVALUEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Range Value control pattern provider.
+class QWinRTUiaRangeValueProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IRangeValueProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaRangeValueProvider)
+ InspectableClass(L"QWinRTUiaRangeValueProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaRangeValueProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaRangeValueProvider();
+
+ // IRangeValueProvider
+ HRESULT STDMETHODCALLTYPE get_IsReadOnly(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE get_LargeChange(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE get_Maximum(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE get_Minimum(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE get_SmallChange(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE get_Value(DOUBLE *value) override;
+ HRESULT STDMETHODCALLTYPE SetValue(DOUBLE value) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIARANGEVALUEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
new file mode 100644
index 0000000000..9bc88272ba
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiaselectionitemprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaSelectionItemProvider::QWinRTUiaSelectionItemProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaSelectionItemProvider::~QWinRTUiaSelectionItemProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns true if element is currently selected.
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_IsSelected(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ if (metadata->role() == QAccessible::RadioButton)
+ *value = metadata->state().checked;
+ else
+ *value = metadata->state().selected;
+ return S_OK;
+}
+
+// Returns the provider for the container element (e.g., the list for the list item).
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_SelectionContainer(IIRawElementProviderSimple **value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ *value = nullptr;
+
+ auto accid = id();
+ auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0));
+ auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ // Radio buttons do not require a container.
+ if (accessible->role() == QAccessible::ListItem) {
+ if (QAccessibleInterface *parent = accessible->parent()) {
+ if (parent->role() == QAccessible::List) {
+ **ptrElementId = idForAccessible(parent);
+ }
+ }
+ }
+ }
+ delete ptrElementId;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ if (!*elementId)
+ return S_OK;
+
+ return QWinRTUiaMainProvider::rawProviderForAccessibleId(*elementId, value);
+}
+
+// Adds the element to the list of selected elements.
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::AddToSelection()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface()) {
+ if (accessible->role() == QAccessible::RadioButton) {
+ // For radio buttons we invoke the selection action.
+ actionInterface->doAction(QAccessibleActionInterface::pressAction());
+ } else {
+ // Toggle list item if not already selected.
+ if (!accessible->state().selected) {
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+// Removes a list item from selection.
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::RemoveFromSelection()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface()) {
+ if (accessible->role() != QAccessible::RadioButton) {
+ if (accessible->state().selected) {
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+// Selects the element (deselecting all others).
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::Select()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface()) {
+ if (accessible->role() == QAccessible::RadioButton) {
+ // For radio buttons we just invoke the selection action; others are automatically deselected.
+ actionInterface->doAction(QAccessibleActionInterface::pressAction());
+ } else {
+ // Toggle list item if not already selected. It must be done first to support all selection modes.
+ if (!accessible->state().selected) {
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ // Toggle selected siblings.
+ if (QAccessibleInterface *parent = accessible->parent()) {
+ for (int i = 0; i < parent->childCount(); ++i) {
+ if (QAccessibleInterface *sibling = parent->child(i)) {
+ if ((sibling != accessible) && (sibling->state().selected)) {
+ if (QAccessibleActionInterface *siblingAction = sibling->actionInterface()) {
+ siblingAction->doAction(QAccessibleActionInterface::toggleAction());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.h
new file mode 100644
index 0000000000..1b3cce7495
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIASELECTIONITEMPROVIDER_H
+#define QWINRTUIASELECTIONITEMPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Selection Item control pattern provider. Used for List items and radio buttons.
+class QWinRTUiaSelectionItemProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ISelectionItemProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaSelectionItemProvider)
+ InspectableClass(L"QWinRTUiaSelectionItemProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaSelectionItemProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaSelectionItemProvider();
+
+ // ISelectionItemProvider
+ HRESULT STDMETHODCALLTYPE get_IsSelected(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE get_SelectionContainer(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **value) override;
+ HRESULT STDMETHODCALLTYPE AddToSelection() override;
+ HRESULT STDMETHODCALLTYPE RemoveFromSelection() override;
+ HRESULT STDMETHODCALLTYPE Select() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIASELECTIONITEMPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
new file mode 100644
index 0000000000..9e61a8df61
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiaselectionprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaSelectionProvider::QWinRTUiaSelectionProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaSelectionProvider::~QWinRTUiaSelectionProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_CanSelectMultiple(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = (metadata->state().multiSelectable != 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ *value = false;
+
+ auto accid = id();
+ auto selectionRequired = QSharedPointer<bool>(new bool(false));
+ auto ptrSelectionRequired = new QSharedPointer<bool>(selectionRequired);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelectionRequired]() {
+ // Initially returns false if none are selected. After the first selection, it may be required.
+ bool anySelected = false;
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ int childCount = accessible->childCount();
+ for (int i = 0; i < childCount; ++i) {
+ if (QAccessibleInterface *childAcc = accessible->child(i)) {
+ if (childAcc->state().selected) {
+ anySelected = true;
+ break;
+ }
+ }
+ }
+ **ptrSelectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
+ }
+ delete ptrSelectionRequired;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ *value = *selectionRequired;
+ return S_OK;
+}
+
+// Returns an array of providers with the selected items.
+HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ int childCount = accessible->childCount();
+ for (int i = 0; i < childCount; ++i) {
+ if (QAccessibleInterface *childAcc = accessible->child(i)) {
+ if (childAcc->state().selected) {
+ QAccessible::Id childId = idForAccessible(childAcc);
+ QWinRTUiaMetadataCache::instance()->load(childId);
+ (*ptrElementIds)->append(childId);
+ }
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.h
new file mode 100644
index 0000000000..dcd286800f
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIASELECTIONPROVIDER_H
+#define QWINRTUIASELECTIONPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Selection control pattern provider. Used for Lists.
+class QWinRTUiaSelectionProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ISelectionProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaSelectionProvider)
+ InspectableClass(L"QWinRTUiaSelectionProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaSelectionProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaSelectionProvider();
+
+ // ISelectionProvider
+ HRESULT STDMETHODCALLTYPE get_CanSelectMultiple(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE get_IsSelectionRequired(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE GetSelection(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIASELECTIONPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
new file mode 100644
index 0000000000..1af74a8b72
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatableitemprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaTableItemProvider::QWinRTUiaTableItemProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaTableItemProvider::~QWinRTUiaTableItemProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns the providers for the column headers associated with the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetColumnHeaderItems(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
+ QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
+ for (auto header : qAsConst(headers)) {
+ QAccessible::Id headerId = idForAccessible(header);
+ QWinRTUiaMetadataCache::instance()->load(headerId);
+ (*ptrElementIds)->append(headerId);
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+// Returns the providers for the row headers associated with the item.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetRowHeaderItems(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) {
+ QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
+ for (auto header : qAsConst(headers)) {
+ QAccessible::Id headerId = idForAccessible(header);
+ QWinRTUiaMetadataCache::instance()->load(headerId);
+ (*ptrElementIds)->append(headerId);
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.h
new file mode 100644
index 0000000000..cb759864ae
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATABLEITEMPROVIDER_H
+#define QWINRTUIATABLEITEMPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Table Item control pattern provider. Used by items within a table/tree.
+class QWinRTUiaTableItemProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ITableItemProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaTableItemProvider)
+ InspectableClass(L"QWinRTUiaTableItemProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaTableItemProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaTableItemProvider();
+
+ // ITableItemProvider
+ HRESULT STDMETHODCALLTYPE GetColumnHeaderItems(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetRowHeaderItems(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATABLEITEMPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
new file mode 100644
index 0000000000..e71ade3c1f
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatableprovider.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+
+QWinRTUiaTableProvider::QWinRTUiaTableProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaTableProvider::~QWinRTUiaTableProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns the primary direction of traversal for the table.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::get_RowOrColumnMajor(RowOrColumnMajor *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ *value = RowOrColumnMajor_Indeterminate;
+ return S_OK;
+}
+
+// Gets the providers for all the column headers in the table.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
+ for (int i = 0; i < tableInterface->columnCount(); ++i) {
+ if (QAccessibleInterface *cell = tableInterface->cellAt(0, i)) {
+ QWinRTUiaMetadataCache::instance()->load(idForAccessible(cell));
+ if (QAccessibleTableCellInterface *tableCellInterface = cell->tableCellInterface()) {
+ QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells();
+ for (auto header : qAsConst(headers)) {
+ QAccessible::Id headerId = idForAccessible(header);
+ QWinRTUiaMetadataCache::instance()->load(headerId);
+ (*ptrElementIds)->append(headerId);
+ }
+ }
+ }
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+// Gets the providers for all the row headers in the table.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>);
+ auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) {
+ for (int i = 0; i < tableInterface->rowCount(); ++i) {
+ if (QAccessibleInterface *cell = tableInterface->cellAt(i, 0)) {
+ QWinRTUiaMetadataCache::instance()->load(idForAccessible(cell));
+ if (QAccessibleTableCellInterface *tableCellInterface = cell->tableCellInterface()) {
+ QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells();
+ for (auto header : qAsConst(headers)) {
+ QAccessible::Id headerId = idForAccessible(header);
+ QWinRTUiaMetadataCache::instance()->load(headerId);
+ (*ptrElementIds)->append(headerId);
+ }
+ }
+ }
+ }
+ }
+ }
+ delete ptrElementIds;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ return QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(*elementIds, returnValueSize, returnValue);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.h
new file mode 100644
index 0000000000..0cd174e401
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATABLEPROVIDER_H
+#define QWINRTUIATABLEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Table control pattern provider. Used by tables/trees.
+class QWinRTUiaTableProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ITableProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaTableProvider)
+ InspectableClass(L"QWinRTUiaTableProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaTableProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaTableProvider();
+
+ // ITableProvider
+ HRESULT STDMETHODCALLTYPE get_RowOrColumnMajor(ABI::Windows::UI::Xaml::Automation::RowOrColumnMajor *value) override;
+ HRESULT STDMETHODCALLTYPE GetColumnHeaders(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetRowHeaders(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATABLEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
new file mode 100644
index 0000000000..aa120377df
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatextprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiatextrangeprovider.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaTextProvider::QWinRTUiaTextProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaTextProvider::~QWinRTUiaTextProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Returns a text range provider for the entire text.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::get_DocumentRange(ITextRangeProvider **value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), 0, metadata->characterCount());
+ return textRangeProvider.CopyTo(value);
+}
+
+// Currently supporting single selection.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::get_SupportedTextSelection(SupportedTextSelection *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!value)
+ return E_INVALIDARG;
+ *value = SupportedTextSelection_Single;
+ return S_OK;
+
+}
+
+// Returns an array of providers for the selected text ranges.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValueSize, ITextRangeProvider ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto selections = QSharedPointer<QList<QPair<int,int>>>(new QList<QPair<int,int>>);
+ auto ptrSelections = new QSharedPointer<QList<QPair<int,int>>>(selections);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelections]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ for (int i = 0; i < textInterface->selectionCount(); ++i) {
+ QPair<int,int> sel;
+ textInterface->selection(i, &sel.first, &sel.second);
+ (*ptrSelections)->append(sel);
+ }
+ if ((*ptrSelections)->size() == 0) {
+ // If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
+ QPair<int,int> sel(textInterface->cursorPosition(), textInterface->cursorPosition());
+ (*ptrSelections)->append(sel);
+ }
+ }
+ }
+ delete ptrSelections;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ int selCount = selections->size();
+ if (selCount < 1)
+ return E_FAIL;
+
+ ITextRangeProvider **providerArray = static_cast<ITextRangeProvider **>(CoTaskMemAlloc(selCount * sizeof(ITextRangeProvider *)));
+ if (!providerArray)
+ return E_OUTOFMEMORY;
+
+ for (int i = 0; i < selCount; ++i) {
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), (*selections)[i].first, (*selections)[i].second);
+ textRangeProvider.CopyTo(&providerArray[i]);
+ }
+ *returnValueSize = selCount;
+ *returnValue = providerArray;
+ return S_OK;
+}
+
+// Returns an array of providers for the visible text ranges.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetVisibleRanges(UINT32 *returnValueSize, ITextRangeProvider ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ // Considering the entire text as visible.
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), 0, metadata->characterCount());
+ textRangeProvider.CopyTo(*returnValue);
+ *returnValueSize = 1;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromChild(IIRawElementProviderSimple *childElement, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!childElement || !returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+ // No children supported.
+ return S_OK;
+}
+
+// Returns a degenerate text range at the specified point.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromPoint(ABI::Windows::Foundation::Point screenLocation, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ const QPoint pt(screenLocation.X, screenLocation.Y);
+ auto accid = id();
+ auto offset = QSharedPointer<int>(new int);
+ auto ptrOffset = new QSharedPointer<int>(offset);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, ptrOffset]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface())
+ **ptrOffset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1);
+ delete ptrOffset;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), *offset, *offset);
+ textRangeProvider.CopyTo(returnValue);
+ return S_OK;
+}
+
+// Not supporting annotations.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromAnnotation(IIRawElementProviderSimple *annotationElement, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!annotationElement || !returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetCaretRange(boolean *isActive, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!isActive || !returnValue)
+ return E_INVALIDARG;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *isActive = metadata->state().focused;
+
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), metadata->cursorPosition(), metadata->cursorPosition());
+ return textRangeProvider.CopyTo(returnValue);
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.h
new file mode 100644
index 0000000000..80d88e4115
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATEXTPROVIDER_H
+#define QWINRTUIATEXTPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Text control pattern provider. Used for text controls.
+class QWinRTUiaTextProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ITextProvider, ABI::Windows::UI::Xaml::Automation::Provider::ITextProvider2>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaTextProvider)
+ InspectableClass(L"QWinRTUiaTextProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaTextProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaTextProvider();
+
+ // ITextProvider
+ HRESULT STDMETHODCALLTYPE get_DocumentRange(ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **value) override;
+ HRESULT STDMETHODCALLTYPE get_SupportedTextSelection(ABI::Windows::UI::Xaml::Automation::SupportedTextSelection *value) override;
+ HRESULT STDMETHODCALLTYPE GetSelection(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider ***returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetVisibleRanges(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider ***returnValue) override;
+ HRESULT STDMETHODCALLTYPE RangeFromChild(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple *childElement, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE RangeFromPoint(ABI::Windows::Foundation::Point screenLocation, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+
+ // ITextProvider2
+ HRESULT STDMETHODCALLTYPE RangeFromAnnotation(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple *annotationElement, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetCaretRange(boolean *isActive, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATEXTPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
new file mode 100644
index 0000000000..fc3778d652
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp
@@ -0,0 +1,497 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatextrangeprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiamainprovider.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::Xaml;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+using namespace ABI::Windows::UI::Xaml::Automation::Text;
+
+QWinRTUiaTextRangeProvider::QWinRTUiaTextRangeProvider(QAccessible::Id id, int startOffset, int endOffset) :
+ QWinRTUiaBaseProvider(id),
+ m_startOffset(startOffset),
+ m_endOffset(endOffset)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__ << startOffset << endOffset;
+}
+
+QWinRTUiaTextRangeProvider::~QWinRTUiaTextRangeProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::Clone(ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+
+ ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), m_startOffset, m_endOffset);
+ textRangeProvider.CopyTo(returnValue);
+ return S_OK;
+}
+
+// Two ranges are considered equal if their start/end points are the same.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::Compare(ITextRangeProvider *textRangeProvider, boolean *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!textRangeProvider || !returnValue)
+ return E_INVALIDARG;
+
+ QWinRTUiaTextRangeProvider *targetProvider = static_cast<QWinRTUiaTextRangeProvider *>(textRangeProvider);
+ *returnValue = ((targetProvider->m_startOffset == m_startOffset) && (targetProvider->m_endOffset == m_endOffset));
+ return S_OK;
+}
+
+// Compare different endpoinds between two providers.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::CompareEndpoints(TextPatternRangeEndpoint endpoint, ITextRangeProvider *textRangeProvider, TextPatternRangeEndpoint targetEndpoint, INT32 *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!textRangeProvider || !returnValue)
+ return E_INVALIDARG;
+
+ QWinRTUiaTextRangeProvider *targetProvider = static_cast<QWinRTUiaTextRangeProvider *>(textRangeProvider);
+
+ int point = (endpoint == TextPatternRangeEndpoint_Start) ? m_startOffset : m_endOffset;
+ int targetPoint = (targetEndpoint == TextPatternRangeEndpoint_Start) ?
+ targetProvider->m_startOffset : targetProvider->m_endOffset;
+ *returnValue = point - targetPoint;
+ return S_OK;
+}
+
+// Expands/normalizes the range for a given text unit.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::ExpandToEnclosingUnit(TextUnit unit)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "unit=" << unit << "this: " << this;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ int len = metadata->characterCount();
+ if (len < 1) {
+ m_startOffset = 0;
+ m_endOffset = 0;
+ } else {
+ if (unit == TextUnit_Character) {
+ m_startOffset = qBound(0, m_startOffset, len - 1);
+ m_endOffset = m_startOffset + 1;
+ } else {
+ QString text = metadata->text();
+ for (int t = m_startOffset; t >= 0; --t) {
+ if (!isTextUnitSeparator(unit, text[t]) && ((t == 0) || isTextUnitSeparator(unit, text[t - 1]))) {
+ m_startOffset = t;
+ break;
+ }
+ }
+ for (int t = m_startOffset; t < len; ++t) {
+ if ((t == len - 1) || (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1])))) {
+ m_endOffset = t + 1;
+ break;
+ }
+ }
+ }
+ }
+ return S_OK;
+}
+
+// Not supported.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::FindAttribute(INT32 /*attributeId*/, IInspectable * /*value*/, boolean /*backward*/, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::FindText(HSTRING /*text*/, boolean /*backward*/, boolean /*ignoreCase*/, ITextRangeProvider **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+ return S_OK;
+}
+
+// Returns the value of a given attribute.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetAttributeValue(INT32 attributeId, IInspectable **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "attributeId=" << attributeId;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ ComPtr<IPropertyValueStatics> propertyValueStatics;
+ if (FAILED(RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), IID_PPV_ARGS(&propertyValueStatics))))
+ return E_FAIL;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ switch (attributeId) {
+ case AutomationTextAttributesEnum_IsReadOnlyAttribute:
+ return propertyValueStatics->CreateBoolean(metadata->state().readOnly, returnValue);
+ case AutomationTextAttributesEnum_CaretPositionAttribute:
+ if (metadata->cursorPosition() == 0)
+ return propertyValueStatics->CreateInt32(AutomationCaretPosition_BeginningOfLine, returnValue);
+ else if (metadata->cursorPosition() == metadata->characterCount())
+ return propertyValueStatics->CreateInt32(AutomationCaretPosition_EndOfLine, returnValue);
+ else
+ return propertyValueStatics->CreateInt32(AutomationCaretPosition_Unknown, returnValue);
+ default:
+ break;
+ }
+ return E_FAIL;
+}
+
+// Returns an array of bounding rectangles for text lines within the range.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT32 *returnValueSize, DOUBLE **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValueSize || !returnValue)
+ return E_INVALIDARG;
+ *returnValueSize = 0;
+ *returnValue = nullptr;
+
+ auto accid = id();
+ auto startOffset = m_startOffset;
+ auto endOffset = m_endOffset;
+ auto rects = QSharedPointer<QList<QRect>>(new QList<QRect>);
+ auto ptrRects = new QSharedPointer<QList<QRect>>(rects);
+
+ if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, ptrRects]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ int len = textInterface->characterCount();
+ if ((startOffset >= 0) && (endOffset <= len) && (startOffset < endOffset)) {
+ int start, end;
+ textInterface->textAtOffset(startOffset, QAccessible::LineBoundary, &start, &end);
+ while ((start >= 0) && (end >= 0)) {
+ int startRange = qMax(start, startOffset);
+ int endRange = qMin(end, endOffset);
+ if (startRange < endRange) {
+ // Calculates a bounding rectangle for the line and adds it to the list.
+ const QRect startRect = textInterface->characterRect(startRange);
+ const QRect endRect = textInterface->characterRect(endRange - 1);
+ const QRect lineRect(qMin(startRect.x(), endRect.x()),
+ qMin(startRect.y(), endRect.y()),
+ qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()),
+ qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y()));
+ (*ptrRects)->append(lineRect);
+ }
+ if (end >= len) break;
+ textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end);
+ }
+ }
+ }
+ }
+ delete ptrRects;
+ return S_OK;
+ }))) {
+ return E_FAIL;
+ }
+
+ DOUBLE *doubleArray = static_cast<DOUBLE *>(CoTaskMemAlloc(4 * rects->size() * sizeof(DOUBLE)));
+ if (!doubleArray)
+ return E_OUTOFMEMORY;
+
+ for (int i = 0; i < rects->size(); ++i) {
+ doubleArray[i*4] = (*rects)[i].left();
+ doubleArray[i*4+1] = (*rects)[i].top();
+ doubleArray[i*4+2] = (*rects)[i].width();
+ doubleArray[i*4+3] = (*rects)[i].height();
+ }
+ *returnValue = doubleArray;
+ *returnValueSize = 4 * rects->size();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetEnclosingElement(IIRawElementProviderSimple **returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ return QWinRTUiaMainProvider::rawProviderForAccessibleId(id(), returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetText(INT32 maxLength, HSTRING *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = nullptr;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ QString rangeText = metadata->text().mid(m_startOffset, m_endOffset - m_startOffset);
+
+ if ((maxLength > -1) && (rangeText.size() > maxLength))
+ rangeText.truncate(maxLength);
+ return qHString(rangeText, returnValue);
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::Move(TextUnit unit, INT32 count, INT32 *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = 0;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ int len = metadata->characterCount();
+ if (len < 1)
+ return S_OK;
+
+ if (unit == TextUnit_Character) {
+ // Moves the start point, ensuring it lies within the bounds.
+ int start = qBound(0, m_startOffset + count, len - 1);
+ // If range was initially empty, leaves it as is; otherwise, normalizes it to one char.
+ m_endOffset = (m_endOffset > m_startOffset) ? start + 1 : start;
+ *returnValue = start - m_startOffset; // Returns the actually moved distance.
+ m_startOffset = start;
+ } else {
+ if (count > 0) {
+ MoveEndpointByUnit(TextPatternRangeEndpoint_End, unit, count, returnValue);
+ MoveEndpointByUnit(TextPatternRangeEndpoint_Start, unit, count, returnValue);
+ } else {
+ MoveEndpointByUnit(TextPatternRangeEndpoint_Start, unit, count, returnValue);
+ MoveEndpointByUnit(TextPatternRangeEndpoint_End, unit, count, returnValue);
+ }
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, INT32 count, INT32 *returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!returnValue)
+ return E_INVALIDARG;
+ *returnValue = 0;
+
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+
+ int len = metadata->characterCount();
+ if (len < 1)
+ return S_OK;
+
+ if (unit == TextUnit_Character) {
+ if (endpoint == TextPatternRangeEndpoint_Start) {
+ int boundedValue = qBound(0, m_startOffset + count, len - 1);
+ *returnValue = boundedValue - m_startOffset;
+ m_startOffset = boundedValue;
+ m_endOffset = qBound(m_startOffset, m_endOffset, len);
+ } else {
+ int boundedValue = qBound(0, m_endOffset + count, len);
+ *returnValue = boundedValue - m_endOffset;
+ m_endOffset = boundedValue;
+ m_startOffset = qBound(0, m_startOffset, m_endOffset);
+ }
+ } else {
+ QString text = metadata->text();
+ int moved = 0;
+
+ if (endpoint == TextPatternRangeEndpoint_Start) {
+ if (count > 0) {
+ for (int t = m_startOffset; (t < len - 1) && (moved < count); ++t) {
+ if (isTextUnitSeparator(unit, text[t]) && !isTextUnitSeparator(unit, text[t + 1])) {
+ m_startOffset = t + 1;
+ ++moved;
+ }
+ }
+ m_endOffset = qBound(m_startOffset, m_endOffset, len);
+ } else {
+ for (int t = m_startOffset - 1; (t >= 0) && (moved > count); --t) {
+ if (!isTextUnitSeparator(unit, text[t]) && ((t == 0) || isTextUnitSeparator(unit, text[t - 1]))) {
+ m_startOffset = t;
+ --moved;
+ }
+ }
+ }
+ } else {
+ if (count > 0) {
+ for (int t = m_endOffset; (t < len) && (moved < count); ++t) {
+ if ((t == len - 1) || (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1])))) {
+ m_endOffset = t + 1;
+ ++moved;
+ }
+ }
+ } else {
+ int end = 0;
+ for (int t = m_endOffset - 2; (t > 0) && (moved > count); --t) {
+ if (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1]))) {
+ end = t + 1;
+ --moved;
+ }
+ }
+ m_endOffset = end;
+ m_startOffset = qBound(0, m_startOffset, m_endOffset);
+ }
+ }
+ *returnValue = moved;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::MoveEndpointByRange(TextPatternRangeEndpoint endpoint, ITextRangeProvider *textRangeProvider, TextPatternRangeEndpoint targetEndpoint)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ if (!textRangeProvider)
+ return E_INVALIDARG;
+
+ QWinRTUiaTextRangeProvider *targetProvider = static_cast<QWinRTUiaTextRangeProvider *>(textRangeProvider);
+
+ int targetPoint = (targetEndpoint == TextPatternRangeEndpoint_Start) ?
+ targetProvider->m_startOffset : targetProvider->m_endOffset;
+
+ // If the moved endpoint crosses the other endpoint, that one is moved too.
+ if (endpoint == TextPatternRangeEndpoint_Start) {
+ m_startOffset = targetPoint;
+ if (m_endOffset < m_startOffset)
+ m_endOffset = m_startOffset;
+ } else {
+ m_endOffset = targetPoint;
+ if (m_endOffset < m_startOffset)
+ m_startOffset = m_endOffset;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::Select()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+ auto startOffset = m_startOffset;
+ auto endOffset = m_endOffset;
+
+ QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ // unselects all and adds a new selection
+ for (int i = textInterface->selectionCount() - 1; i >= 0; --i)
+ textInterface->removeSelection(i);
+ textInterface->addSelection(startOffset, endOffset);
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::AddToSelection()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+ return Select();
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::RemoveFromSelection()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ // unselects all
+ for (int i = textInterface->selectionCount() - 1; i >= 0; --i)
+ textInterface->removeSelection(i);
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::ScrollIntoView(boolean /*alignToTop*/)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+ auto startOffset = m_startOffset;
+ auto endOffset = m_endOffset;
+
+ QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleTextInterface *textInterface = accessible->textInterface()) {
+ textInterface->scrollToSubstring(startOffset, endOffset);
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+// Returns an array of children elements embedded within the range.
+HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetChildren(UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!returnValue)
+ return E_INVALIDARG;
+ // Not supporting any children.
+ returnValueSize = 0;
+ *returnValue = nullptr;
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.h
new file mode 100644
index 0000000000..81b5f0d400
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATEXTRANGEPROVIDER_H
+#define QWINRTUIATEXTRANGEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Text Range control pattern provider. Used for text controls.
+class QWinRTUiaTextRangeProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaTextRangeProvider)
+ InspectableClass(L"QWinRTUiaTextRangeProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaTextRangeProvider(QAccessible::Id id, int startOffset, int endOffset);
+ virtual ~QWinRTUiaTextRangeProvider();
+
+ // ITextRangeProvider
+ HRESULT STDMETHODCALLTYPE Clone(ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE Compare(ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider *textRangeProvider, boolean *returnValue) override;
+ HRESULT STDMETHODCALLTYPE CompareEndpoints(ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider *textRangeProvider, ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint targetEndpoint, INT32 *returnValue) override;
+ HRESULT STDMETHODCALLTYPE ExpandToEnclosingUnit(ABI::Windows::UI::Xaml::Automation::Text::TextUnit unit) override;
+ HRESULT STDMETHODCALLTYPE FindAttribute(INT32 attributeId, IInspectable *value, boolean backward, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE FindText(HSTRING text, boolean backward, boolean ignoreCase, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetAttributeValue(INT32 attributeId, IInspectable **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetBoundingRectangles(UINT32 *returnValueSize, DOUBLE **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetEnclosingElement(ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue) override;
+ HRESULT STDMETHODCALLTYPE GetText(INT32 maxLength, HSTRING *returnValue) override;
+ HRESULT STDMETHODCALLTYPE Move(ABI::Windows::UI::Xaml::Automation::Text::TextUnit unit, INT32 count, INT32 *returnValue) override;
+ HRESULT STDMETHODCALLTYPE MoveEndpointByUnit(ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint, ABI::Windows::UI::Xaml::Automation::Text::TextUnit unit, INT32 count, INT32 *returnValue) override;
+ HRESULT STDMETHODCALLTYPE MoveEndpointByRange(ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint endpoint, ABI::Windows::UI::Xaml::Automation::Provider::ITextRangeProvider *textRangeProvider, ABI::Windows::UI::Xaml::Automation::Text::TextPatternRangeEndpoint targetEndpoint) override;
+ HRESULT STDMETHODCALLTYPE Select() override;
+ HRESULT STDMETHODCALLTYPE AddToSelection() override;
+ HRESULT STDMETHODCALLTYPE RemoveFromSelection() override;
+ HRESULT STDMETHODCALLTYPE ScrollIntoView(boolean alignToTop) override;
+ HRESULT STDMETHODCALLTYPE GetChildren(UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue) override;
+
+private:
+ int m_startOffset;
+ int m_endOffset;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATEXTRANGEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.cpp
new file mode 100644
index 0000000000..59f55eb422
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiatoggleprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaToggleProvider::QWinRTUiaToggleProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaToggleProvider::~QWinRTUiaToggleProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// Gets the current toggle state.
+HRESULT STDMETHODCALLTYPE QWinRTUiaToggleProvider::get_ToggleState(ToggleState *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ if (metadata->state().checked)
+ *value = metadata->state().checkStateMixed ? ToggleState_Indeterminate : ToggleState_On;
+ else
+ *value = ToggleState_Off;
+ return S_OK;
+}
+
+// Toggles the state by invoking the toggle action.
+HRESULT STDMETHODCALLTYPE QWinRTUiaToggleProvider::Toggle()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+
+ QEventDispatcherWinRT::runOnMainThread([accid]() {
+ if (QAccessibleInterface *accessible = accessibleForId(accid))
+ if (QAccessibleActionInterface *actionInterface = accessible->actionInterface())
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ return S_OK;
+ }, 0);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.h
new file mode 100644
index 0000000000..3d1740c0a1
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatoggleprovider.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIATOGGLEPROVIDER_H
+#define QWINRTUIATOGGLEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Toggle control pattern provider. Used for checkboxes.
+class QWinRTUiaToggleProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IToggleProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaToggleProvider)
+ InspectableClass(L"QWinRTUiaToggleProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaToggleProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaToggleProvider();
+
+ // IToggleProvider
+ HRESULT STDMETHODCALLTYPE get_ToggleState(ABI::Windows::UI::Xaml::Automation::ToggleState *value) override;
+ HRESULT STDMETHODCALLTYPE Toggle() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIATOGGLEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.cpp
new file mode 100644
index 0000000000..16197c99b9
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiautils.h"
+
+using namespace ABI::Windows::UI::Xaml::Automation::Peers;
+using namespace ABI::Windows::UI::Xaml::Automation::Text;
+using namespace ABI::Windows::Foundation::Collections;
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcQpaUiAutomation, "qt.qpa.uiautomation")
+
+namespace QWinRTUiAutomation {
+
+// Returns the window containing the element (usually the top window),
+QWindow *windowForAccessible(const QAccessibleInterface *accessible)
+{
+ QWindow *window = accessible->window();
+ if (!window) {
+ QAccessibleInterface *acc = accessible->parent();
+ while (acc && acc->isValid() && !window) {
+ window = acc->window();
+ QAccessibleInterface *par = acc->parent();
+ acc = par;
+ }
+ }
+ return window;
+}
+
+QAccessibleInterface *accessibleForId(QAccessible::Id id)
+{
+ QAccessibleInterface *accessible = QAccessible::accessibleInterface(id);
+ if (!accessible || !accessible->isValid())
+ return nullptr;
+ return accessible;
+}
+
+QAccessible::Id idForAccessible(QAccessibleInterface *accessible)
+{
+ if (!accessible)
+ return QAccessible::Id(0);
+ return QAccessible::uniqueId(accessible);
+}
+
+// Maps an accessibility role ID to an UI Automation control type ID.
+AutomationControlType roleToControlType(QAccessible::Role role)
+{
+ static const QHash<QAccessible::Role, AutomationControlType> mapping {
+ {QAccessible::TitleBar, AutomationControlType::AutomationControlType_TitleBar},
+ {QAccessible::MenuBar, AutomationControlType::AutomationControlType_MenuBar},
+ {QAccessible::ScrollBar, AutomationControlType::AutomationControlType_ScrollBar},
+ {QAccessible::Grip, AutomationControlType::AutomationControlType_Thumb},
+ {QAccessible::Sound, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Cursor, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Caret, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::AlertMessage, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Window, AutomationControlType::AutomationControlType_Window},
+ {QAccessible::Client, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::PopupMenu, AutomationControlType::AutomationControlType_Menu},
+ {QAccessible::MenuItem, AutomationControlType::AutomationControlType_MenuItem},
+ {QAccessible::ToolTip, AutomationControlType::AutomationControlType_ToolTip},
+ {QAccessible::Application, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Document, AutomationControlType::AutomationControlType_Document},
+ {QAccessible::Pane, AutomationControlType::AutomationControlType_Pane},
+ {QAccessible::Chart, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Dialog, AutomationControlType::AutomationControlType_Window},
+ {QAccessible::Border, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Grouping, AutomationControlType::AutomationControlType_Group},
+ {QAccessible::Separator, AutomationControlType::AutomationControlType_Separator},
+ {QAccessible::ToolBar, AutomationControlType::AutomationControlType_ToolBar},
+ {QAccessible::StatusBar, AutomationControlType::AutomationControlType_StatusBar},
+ {QAccessible::Table, AutomationControlType::AutomationControlType_Table},
+ {QAccessible::ColumnHeader, AutomationControlType::AutomationControlType_Header},
+ {QAccessible::RowHeader, AutomationControlType::AutomationControlType_Header},
+ {QAccessible::Column, AutomationControlType::AutomationControlType_HeaderItem},
+ {QAccessible::Row, AutomationControlType::AutomationControlType_HeaderItem},
+ {QAccessible::Cell, AutomationControlType::AutomationControlType_DataItem},
+ {QAccessible::Link, AutomationControlType::AutomationControlType_Hyperlink},
+ {QAccessible::HelpBalloon, AutomationControlType::AutomationControlType_ToolTip},
+ {QAccessible::Assistant, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::List, AutomationControlType::AutomationControlType_List},
+ {QAccessible::ListItem, AutomationControlType::AutomationControlType_ListItem},
+ {QAccessible::Tree, AutomationControlType::AutomationControlType_Tree},
+ {QAccessible::TreeItem, AutomationControlType::AutomationControlType_TreeItem},
+ {QAccessible::PageTab, AutomationControlType::AutomationControlType_TabItem},
+ {QAccessible::PropertyPage, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Indicator, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Graphic, AutomationControlType::AutomationControlType_Image},
+ {QAccessible::StaticText, AutomationControlType::AutomationControlType_Text},
+ {QAccessible::EditableText, AutomationControlType::AutomationControlType_Edit},
+ {QAccessible::Button, AutomationControlType::AutomationControlType_Button},
+ {QAccessible::CheckBox, AutomationControlType::AutomationControlType_CheckBox},
+ {QAccessible::RadioButton, AutomationControlType::AutomationControlType_RadioButton},
+ {QAccessible::ComboBox, AutomationControlType::AutomationControlType_ComboBox},
+ {QAccessible::ProgressBar, AutomationControlType::AutomationControlType_ProgressBar},
+ {QAccessible::Dial, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::HotkeyField, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Slider, AutomationControlType::AutomationControlType_Slider},
+ {QAccessible::SpinBox, AutomationControlType::AutomationControlType_Spinner},
+ {QAccessible::Canvas, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Animation, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Equation, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::ButtonDropDown, AutomationControlType::AutomationControlType_Button},
+ {QAccessible::ButtonMenu, AutomationControlType::AutomationControlType_Button},
+ {QAccessible::ButtonDropGrid, AutomationControlType::AutomationControlType_Button},
+ {QAccessible::Whitespace, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::PageTabList, AutomationControlType::AutomationControlType_Tab},
+ {QAccessible::Clock, AutomationControlType::AutomationControlType_Custom},
+ {QAccessible::Splitter, AutomationControlType::AutomationControlType_Custom},
+ };
+
+ return mapping.value(role, AutomationControlType::AutomationControlType_Custom);
+}
+
+// True if a character can be a separator for a text unit.
+bool isTextUnitSeparator(TextUnit unit, const QChar &ch)
+{
+ return (((unit == TextUnit_Word) || (unit == TextUnit_Format)) && ch.isSpace())
+ || ((unit == TextUnit_Line) && (ch.toLatin1() == '\n'));
+}
+
+HRESULT qHString(const QString &str, HSTRING *returnValue)
+{
+ if (!returnValue)
+ return E_INVALIDARG;
+
+ const wchar_t *wstr = reinterpret_cast<const wchar_t *>(str.utf16());
+ return ::WindowsCreateString(wstr, static_cast<UINT32>(::wcslen(wstr)), returnValue);
+}
+
+QString hStrToQStr(const HSTRING &hStr)
+{
+ quint32 len;
+ const wchar_t *wstr = ::WindowsGetStringRawBuffer(hStr, &len);
+ return QString::fromWCharArray(wstr, len);
+}
+
+} // namespace QWinRTUiAutomation
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.h
new file mode 100644
index 0000000000..9519cb4eb5
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiautils.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAUTILS_H
+#define QWINRTUIAUTILS_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include <QtCore/QString>
+#include <QtCore/qt_windows.h>
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtGui/QWindow>
+#include <QtCore/QLoggingCategory>
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcQpaUiAutomation)
+
+namespace QWinRTUiAutomation {
+
+QWindow *windowForAccessible(const QAccessibleInterface *accessible);
+
+QAccessibleInterface *accessibleForId(QAccessible::Id id);
+
+QAccessible::Id idForAccessible(QAccessibleInterface *accessible);
+
+ABI::Windows::UI::Xaml::Automation::Peers::AutomationControlType roleToControlType(QAccessible::Role role);
+
+bool isTextUnitSeparator(ABI::Windows::UI::Xaml::Automation::Text::TextUnit unit, const QChar &ch);
+
+HRESULT qHString(const QString &str, HSTRING *returnValue);
+
+QString hStrToQStr(const HSTRING &hStr);
+
+} // namespace QWinRTUiAutomation
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAUTILS_H
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
new file mode 100644
index 0000000000..21389b74d2
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiavalueprovider.h"
+#include "qwinrtuiametadatacache.h"
+#include "qwinrtuiautils.h"
+
+#include <QtGui/QAccessible>
+#include <QtGui/QAccessibleInterface>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWinRTUiAutomation;
+using namespace ABI::Windows::UI::Xaml::Automation;
+using namespace ABI::Windows::UI::Xaml::Automation::Provider;
+
+QWinRTUiaValueProvider::QWinRTUiaValueProvider(QAccessible::Id id) :
+ QWinRTUiaBaseProvider(id)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+QWinRTUiaValueProvider::~QWinRTUiaValueProvider()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+}
+
+// True for read-only controls.
+HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::get_IsReadOnly(boolean *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ *value = (metadata->state().readOnly != 0);
+ return S_OK;
+}
+
+// Returns the value in text form.
+HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::get_Value(HSTRING *value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!value)
+ return E_INVALIDARG;
+ QSharedPointer<QWinRTUiaControlMetadata> metadata = QWinRTUiaMetadataCache::instance()->metadataForId(id());
+ return qHString(metadata->value(), value);
+}
+
+// Sets the value associated with the control.
+HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::SetValue(HSTRING value)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ auto accid = id();
+ auto tmpValue = QSharedPointer<QString>(new QString);
+ auto ptrValue = new QSharedPointer<QString>(tmpValue);
+
+ *tmpValue = hStrToQStr(value);
+
+ QEventDispatcherWinRT::runOnMainThread([accid, ptrValue]() {
+
+ if (QAccessibleInterface *accessible = accessibleForId(accid)) {
+
+ // First sets the value as a text.
+ accessible->setText(QAccessible::Value, **ptrValue);
+
+ // Then, if the control supports the value interface (range value)
+ // and the supplied text can be converted to a number, and that number
+ // lies within the min/max limits, sets it as the control's current (numeric) value.
+ if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) {
+ bool ok = false;
+ double numval = (*ptrValue)->toDouble(&ok);
+ if (ok) {
+ double minimum = valueInterface->minimumValue().toDouble();
+ double maximum = valueInterface->maximumValue().toDouble();
+ if ((numval >= minimum) && (numval <= maximum)) {
+ valueInterface->setCurrentValue(QVariant(numval));
+ }
+ }
+ }
+ }
+ QWinRTUiaMetadataCache::instance()->load(accid);
+ delete ptrValue;
+ return S_OK;
+ }, 0);
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.h
new file mode 100644
index 0000000000..d9cd5d200d
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTUIAVALUEPROVIDER_H
+#define QWINRTUIAVALUEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwinrtuiabaseprovider.h"
+
+#include <wrl.h>
+#include <windows.ui.xaml.h>
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Value control pattern provider.
+// Supported for all controls that can return text(QAccessible::Value).
+class QWinRTUiaValueProvider :
+ public QWinRTUiaBaseProvider,
+ public Microsoft::WRL::RuntimeClass<ABI::Windows::UI::Xaml::Automation::Provider::IValueProvider>
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QWinRTUiaValueProvider)
+ InspectableClass(L"QWinRTUiaValueProvider", BaseTrust);
+
+public:
+ explicit QWinRTUiaValueProvider(QAccessible::Id id);
+ virtual ~QWinRTUiaValueProvider();
+
+ // IValueProvider
+ HRESULT STDMETHODCALLTYPE get_IsReadOnly(boolean *value) override;
+ HRESULT STDMETHODCALLTYPE get_Value(HSTRING *value) override;
+ HRESULT STDMETHODCALLTYPE SetValue(HSTRING value) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINRTUIAVALUEPROVIDER_H
diff --git a/src/plugins/platforms/winrt/uiautomation/uiautomation.pri b/src/plugins/platforms/winrt/uiautomation/uiautomation.pri
new file mode 100644
index 0000000000..ca0dfae53f
--- /dev/null
+++ b/src/plugins/platforms/winrt/uiautomation/uiautomation.pri
@@ -0,0 +1,45 @@
+
+SOURCES += \
+ $$PWD/qwinrtuiaaccessibility.cpp \
+ $$PWD/qwinrtuiabaseprovider.cpp \
+ $$PWD/qwinrtuiacontrolmetadata.cpp \
+ $$PWD/qwinrtuiagriditemprovider.cpp \
+ $$PWD/qwinrtuiagridprovider.cpp \
+ $$PWD/qwinrtuiainvokeprovider.cpp \
+ $$PWD/qwinrtuiamainprovider.cpp \
+ $$PWD/qwinrtuiametadatacache.cpp \
+ $$PWD/qwinrtuiapeervector.cpp \
+ $$PWD/qwinrtuiaprovidercache.cpp \
+ $$PWD/qwinrtuiarangevalueprovider.cpp \
+ $$PWD/qwinrtuiaselectionitemprovider.cpp \
+ $$PWD/qwinrtuiaselectionprovider.cpp \
+ $$PWD/qwinrtuiatableitemprovider.cpp \
+ $$PWD/qwinrtuiatableprovider.cpp \
+ $$PWD/qwinrtuiatextprovider.cpp \
+ $$PWD/qwinrtuiatextrangeprovider.cpp \
+ $$PWD/qwinrtuiatoggleprovider.cpp \
+ $$PWD/qwinrtuiautils.cpp \
+ $$PWD/qwinrtuiavalueprovider.cpp
+
+HEADERS += \
+ $$PWD/qwinrtuiaaccessibility.h \
+ $$PWD/qwinrtuiabaseprovider.h \
+ $$PWD/qwinrtuiacontrolmetadata.h \
+ $$PWD/qwinrtuiaemptypropertyvalue.h \
+ $$PWD/qwinrtuiagriditemprovider.h \
+ $$PWD/qwinrtuiagridprovider.h \
+ $$PWD/qwinrtuiainvokeprovider.h \
+ $$PWD/qwinrtuiamainprovider.h \
+ $$PWD/qwinrtuiametadatacache.h \
+ $$PWD/qwinrtuiapeervector.h \
+ $$PWD/qwinrtuiaprovidercache.h \
+ $$PWD/qwinrtuiarangevalueprovider.h \
+ $$PWD/qwinrtuiaselectionitemprovider.h \
+ $$PWD/qwinrtuiaselectionprovider.h \
+ $$PWD/qwinrtuiatableitemprovider.h \
+ $$PWD/qwinrtuiatableprovider.h \
+ $$PWD/qwinrtuiatextprovider.h \
+ $$PWD/qwinrtuiatextrangeprovider.h \
+ $$PWD/qwinrtuiatoggleprovider.h \
+ $$PWD/qwinrtuiautils.h \
+ $$PWD/qwinrtuiavalueprovider.h
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index 46371b4880..6a847465e4 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -13,6 +13,7 @@ LIBS += -lws2_32 -ld3d11
SOURCES = \
main.cpp \
qwinrtbackingstore.cpp \
+ qwinrtcanvas.cpp \
qwinrtclipboard.cpp \
qwinrtcursor.cpp \
qwinrteglcontext.cpp \
@@ -30,6 +31,7 @@ SOURCES = \
HEADERS = \
qwinrtbackingstore.h \
+ qwinrtcanvas.h \
qwinrtclipboard.h \
qwinrtcursor.h \
qwinrteglcontext.h \
@@ -56,6 +58,8 @@ qtConfig(draganddrop) {
HEADERS += qwinrtdrag.h
}
+qtConfig(accessibility): include($$PWD/uiautomation/uiautomation.pri)
+
PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin
!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
index 8308db46dc..5f238ab261 100644
--- a/src/plugins/platforms/xcb/README
+++ b/src/plugins/platforms/xcb/README
@@ -1,32 +1,7 @@
-Requires libxcb >= 1.5.
-
-PACKAGE DEPENDENCIES
-
-Required packages:
-libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev
-
-On Ubuntu 11.10 icccm1 is replaced by icccm4 and xcb-render-util is not available:
-libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev
-The packages for xcb-render-util can be installed manually from http://packages.ubuntu.com/natty/libxcb-render-util0 and http://packages.ubuntu.com/natty/libxcb-render-util0-dev
-
-On Ubuntu 12.04 icccm1 is replaced by icccm4 and xcb-render-util can be installed automatically:
-libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-glx0-dev libxcb-xinerama0-dev
-
-
-On Fedora, the following packages are required:
-libxcb libxcb-devel libXrender libXrender-devel xcb-util-wm xcb-util-wm-devel xcb-util xcb-util-devel xcb-util-image xcb-util-image-devel xcb-util-keysyms xcb-util-keysyms-devel
+Requires libxcb >= 1.9.1.
REDUCING RUNTIME DEPENDENCIES
The '-qt-xcb' configure option can be used to get rid of most xcb- dependencies. Only libxcb will
still be linked dynamically, since it will be most likely be pulled in via other dependencies anyway.
This should allow for binaries that are portable across most modern Linux distributions.
-
-PACKAGE VERSION REQUIREMENTS
-
-When using touch input via XInput 2.2 or higher, there is a potential issue on systems that ship with
-a libXi older than 1.7.5. This is because XIAllowTouchEvents can deadlock with libXi 1.7.4 and earlier.
-When touch events are never received, this is not an issue, so plain mouse/keyboard systems are not affected.
-Qt versions before 5.8 attempted to recognize this scenario based on the pkg-config package version and skip
-the call. This has been removed starting from 5.8 since relying on pkg-config package versions is unsafe given
-that Qt must also support systems with limited or incomplete pkg-config setups.
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
index a7641baea1..b751aaf8a3 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp
@@ -163,9 +163,9 @@ bool QXcbGlxIntegration::handleXcbEvent(xcb_generic_event_t *event, uint respons
// Unlock the display before calling the native event filter
XUnlockDisplay(xdisplay);
locked = false;
- QByteArray genericEventFilterType = m_connection->nativeInterface()->genericEventFilterType();
+ auto eventType = m_connection->nativeInterface()->nativeEventType();
long result = 0;
- handled = dispatcher->filterNativeEvent(genericEventFilterType, &ev, &result);
+ handled = dispatcher->filterNativeEvent(eventType, &ev, &result);
}
#endif
}
diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
index 8b63e5431d..a3e6cedecd 100644
--- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
+++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
@@ -226,7 +226,9 @@ public:
QXRenderGlyphCache(QXcbX11Info x, QFontEngine::GlyphFormat format, const QTransform &matrix);
~QXRenderGlyphCache();
- bool addGlyphs(const QTextItemInt &ti, QVarLengthArray<glyph_t> glyphs, QVarLengthArray<QFixedPoint> positions);
+ bool addGlyphs(const QTextItemInt &ti,
+ const QVarLengthArray<glyph_t> &glyphs,
+ const QVarLengthArray<QFixedPoint> &positions);
bool draw(Drawable src, Drawable dst, const QTransform &matrix, const QTextItemInt &ti);
inline GlyphSet glyphSet();
@@ -2608,7 +2610,9 @@ QXRenderGlyphCache::~QXRenderGlyphCache()
XRenderFreeGlyphSet(xinfo.display(), gset);
}
-bool QXRenderGlyphCache::addGlyphs(const QTextItemInt &ti, QVarLengthArray<glyph_t> glyphs, QVarLengthArray<QFixedPoint> positions)
+bool QXRenderGlyphCache::addGlyphs(const QTextItemInt &ti,
+ const QVarLengthArray<glyph_t> &glyphs,
+ const QVarLengthArray<QFixedPoint> &positions)
{
Q_ASSERT(ti.fontEngine->type() == QFontEngine::Freetype);
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 8ae9d9899e..c29eb29b7e 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -45,6 +45,16 @@
#include <xcb/shm.h>
#include <xcb/xcb_image.h>
+#if QT_CONFIG(xcb_render)
+#include <xcb/render.h>
+// 'template' is used as a function argument name in xcb_renderutil.h
+#define template template_param
+// extern "C" is missing too
+extern "C" {
+#include <xcb/xcb_renderutil.h>
+}
+#undef template
+#endif
#include <sys/ipc.h>
#include <sys/shm.h>
@@ -76,6 +86,7 @@ class QXcbBackingStoreImage : public QXcbObject
{
public:
QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size);
+ QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size, uint depth, QImage::Format format);
~QXcbBackingStoreImage() { destroy(true); }
void resize(const QSize &size);
@@ -99,6 +110,8 @@ public:
xcb_shm_segment_info_t *shm_info = nullptr);
private:
+ void init(const QSize &size, uint depth, QImage::Format format);
+
void createShmSegment(size_t segmentSize);
void destroyShmSegment();
void destroy(bool destroyShm);
@@ -109,8 +122,8 @@ private:
void setClip(const QRegion &region);
xcb_shm_segment_info_t m_shm_info;
- QXcbBackingStore *m_backingStore = nullptr;
size_t m_segmentSize = 0;
+ QXcbBackingStore *m_backingStore = nullptr;
xcb_image_t *m_xcb_image = nullptr;
@@ -185,10 +198,23 @@ QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbBackingStore *backingStore, con
, m_backingStore(backingStore)
{
auto window = static_cast<QXcbWindow *>(m_backingStore->window()->handle());
- m_xcb_format = connection()->formatForDepth(window->depth());
+ init(size, window->depth(), window->imageFormat());
+}
+
+QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size,
+ uint depth, QImage::Format format)
+ : QXcbObject(backingStore->connection())
+ , m_backingStore(backingStore)
+{
+ init(size, depth, format);
+}
+
+void QXcbBackingStoreImage::init(const QSize &size, uint depth, QImage::Format format)
+{
+ m_xcb_format = connection()->formatForDepth(depth);
Q_ASSERT(m_xcb_format);
- m_qimage_format = window->imageFormat();
+ m_qimage_format = format;
m_hasAlpha = QImage::toPixelFormat(m_qimage_format).alphaUsage() == QPixelFormat::UsesAlpha;
if (!m_hasAlpha)
m_qimage_format = qt_maybeAlphaVersionWithSameDepth(m_qimage_format);
@@ -843,7 +869,7 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
return;
}
- m_image->put(platformWindow->xcb_window(), clipped, offset);
+ render(platformWindow->xcb_window(), clipped, offset);
if (platformWindow->needsSync())
platformWindow->updateSyncRequestCounter();
@@ -851,6 +877,11 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
xcb_flush(xcb_connection());
}
+void QXcbBackingStore::render(xcb_window_t window, const QRegion &region, const QPoint &offset)
+{
+ m_image->put(window, region, offset);
+}
+
#ifndef QT_NO_OPENGL
void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
QPlatformTextureList *textures,
@@ -884,6 +915,11 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &)
}
QXcbWindow* win = static_cast<QXcbWindow *>(pw);
+ recreateImage(win, size);
+}
+
+void QXcbBackingStore::recreateImage(QXcbWindow *win, const QSize &size)
+{
if (m_image)
m_image->resize(size);
else
@@ -904,4 +940,167 @@ bool QXcbBackingStore::scroll(const QRegion &area, int dx, int dy)
return false;
}
+QXcbSystemTrayBackingStore::QXcbSystemTrayBackingStore(QWindow *window)
+ : QXcbBackingStore(window)
+{
+ // We need three different behaviors depending on whether the X11 visual
+ // for the system tray supports an alpha channel, i.e. is 32 bits, and
+ // whether XRender can be used:
+ // 1) if the visual has an alpha channel, then render the window's buffer
+ // directly to the X11 window as usual
+ // 2) else if XRender can be used, then render the window's buffer to Pixmap,
+ // then render Pixmap's contents to the cleared X11 window with
+ // xcb_render_composite()
+ // 3) else grab the X11 window's content and paint it first each time as a
+ // background before rendering the window's buffer to the X11 window
+
+ auto *platformWindow = static_cast<QXcbWindow *>(window->handle());
+ quint8 depth = connection()->primaryScreen()->depthOfVisual(platformWindow->visualId());
+
+ if (depth != 32) {
+ platformWindow->setParentRelativeBackPixmap();
+#if QT_CONFIG(xcb_render)
+ initXRenderMode();
+#endif
+ m_useGrabbedBackgound = !m_usingXRenderMode;
+ }
+}
+
+QXcbSystemTrayBackingStore::~QXcbSystemTrayBackingStore()
+{
+#if QT_CONFIG(xcb_render)
+ if (m_xrenderPicture) {
+ xcb_render_free_picture(xcb_connection(), m_xrenderPicture);
+ m_xrenderPicture = XCB_NONE;
+ }
+ if (m_xrenderPixmap) {
+ xcb_free_pixmap(xcb_connection(), m_xrenderPixmap);
+ m_xrenderPixmap = XCB_NONE;
+ }
+ if (m_windowPicture) {
+ xcb_render_free_picture(xcb_connection(), m_windowPicture);
+ m_windowPicture = XCB_NONE;
+ }
+#endif // QT_CONFIG(xcb_render)
+}
+
+void QXcbSystemTrayBackingStore::beginPaint(const QRegion &region)
+{
+ QXcbBackingStore::beginPaint(region);
+
+ if (m_useGrabbedBackgound) {
+ QPainter p(paintDevice());
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ for (const QRect &rect: region)
+ p.drawPixmap(rect, m_grabbedBackground, rect);
+ }
+}
+
+void QXcbSystemTrayBackingStore::render(xcb_window_t window, const QRegion &region, const QPoint &offset)
+{
+ if (!m_usingXRenderMode) {
+ QXcbBackingStore::render(window, region, offset);
+ return;
+ }
+
+#if QT_CONFIG(xcb_render)
+ m_image->put(m_xrenderPixmap, region, offset);
+ const QRect bounds = region.boundingRect();
+ const QPoint target = bounds.topLeft();
+ const QRect source = bounds.translated(offset);
+ xcb_clear_area(xcb_connection(), false, window,
+ target.x(), target.y(), source.width(), source.height());
+ xcb_render_composite(xcb_connection(), XCB_RENDER_PICT_OP_OVER,
+ m_xrenderPicture, 0, m_windowPicture,
+ target.x(), target.y(), 0, 0, target.x(), target.y(),
+ source.width(), source.height());
+#endif // QT_CONFIG(xcb_render)
+}
+
+void QXcbSystemTrayBackingStore::recreateImage(QXcbWindow *win, const QSize &size)
+{
+ if (!m_usingXRenderMode) {
+ QXcbBackingStore::recreateImage(win, size);
+
+ if (m_useGrabbedBackgound) {
+ xcb_clear_area(xcb_connection(), false, win->xcb_window(),
+ 0, 0, size.width(), size.height());
+ m_grabbedBackground = win->xcbScreen()->grabWindow(win->winId(), 0, 0,
+ size.width(), size.height());
+ }
+ return;
+ }
+
+#if QT_CONFIG(xcb_render)
+ if (m_xrenderPicture) {
+ xcb_render_free_picture(xcb_connection(), m_xrenderPicture);
+ m_xrenderPicture = XCB_NONE;
+ }
+ if (m_xrenderPixmap) {
+ xcb_free_pixmap(xcb_connection(), m_xrenderPixmap);
+ m_xrenderPixmap = XCB_NONE;
+ }
+
+ QXcbScreen *screen = win->xcbScreen();
+
+ m_xrenderPixmap = xcb_generate_id(xcb_connection());
+ xcb_create_pixmap(xcb_connection(), 32, m_xrenderPixmap, screen->root(), size.width(), size.height());
+
+ m_xrenderPicture = xcb_generate_id(xcb_connection());
+ xcb_render_create_picture(xcb_connection(), m_xrenderPicture, m_xrenderPixmap, m_xrenderPictFormat, 0, 0);
+
+ // XRender expects premultiplied alpha
+ if (m_image)
+ m_image->resize(size);
+ else
+ m_image = new QXcbBackingStoreImage(this, size, 32, QImage::Format_ARGB32_Premultiplied);
+#endif // QT_CONFIG(xcb_render)
+}
+
+#if QT_CONFIG(xcb_render)
+void QXcbSystemTrayBackingStore::initXRenderMode()
+{
+ if (!connection()->hasXRender())
+ return;
+
+ xcb_connection_t *conn = xcb_connection();
+ auto formatsReply = Q_XCB_REPLY(xcb_render_query_pict_formats, conn);
+
+ if (!formatsReply) {
+ qWarning("QXcbSystemTrayBackingStore: xcb_render_query_pict_formats() failed");
+ return;
+ }
+
+ xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formatsReply.get(),
+ XCB_PICT_STANDARD_ARGB_32);
+ if (!fmt) {
+ qWarning("QXcbSystemTrayBackingStore: Failed to find format PICT_STANDARD_ARGB_32");
+ return;
+ }
+
+ m_xrenderPictFormat = fmt->id;
+
+ auto *platformWindow = static_cast<QXcbWindow *>(window()->handle());
+ xcb_render_pictvisual_t *vfmt = xcb_render_util_find_visual_format(formatsReply.get(), platformWindow->visualId());
+
+ if (!vfmt) {
+ qWarning("QXcbSystemTrayBackingStore: Failed to find format for visual %x", platformWindow->visualId());
+ return;
+ }
+
+ m_windowPicture = xcb_generate_id(conn);
+ xcb_void_cookie_t cookie =
+ xcb_render_create_picture_checked(conn, m_windowPicture, platformWindow->xcb_window(), vfmt->format, 0, 0);
+ xcb_generic_error_t *error = xcb_request_check(conn, cookie);
+ if (error) {
+ qWarning("QXcbSystemTrayBackingStore: Failed to create Picture with format %x for window %x, error code %d",
+ vfmt->format, platformWindow->xcb_window(), error->error_code);
+ free(error);
+ return;
+ }
+
+ m_usingXRenderMode = true;
+}
+#endif // QT_CONFIG(xcb_render)
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h
index 734de1f7d7..39d023cb9d 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.h
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.h
@@ -77,12 +77,41 @@ public:
static bool createSystemVShmSegment(QXcbConnection *c, size_t segmentSize = 1,
void *shmInfo = nullptr);
-private:
+protected:
+ virtual void render(xcb_window_t window, const QRegion &region, const QPoint &offset);
+ virtual void recreateImage(QXcbWindow *win, const QSize &size);
+
QXcbBackingStoreImage *m_image = nullptr;
QStack<QRegion> m_paintRegions;
QImage m_rgbImage;
};
+class QXcbSystemTrayBackingStore : public QXcbBackingStore
+{
+public:
+ QXcbSystemTrayBackingStore(QWindow *window);
+ ~QXcbSystemTrayBackingStore();
+
+ void beginPaint(const QRegion &) override;
+
+protected:
+ void render(xcb_window_t window, const QRegion &region, const QPoint &offset) override;
+ void recreateImage(QXcbWindow *win, const QSize &size) override;
+
+private:
+#if QT_CONFIG(xcb_render)
+ void initXRenderMode();
+
+ xcb_pixmap_t m_xrenderPixmap = XCB_NONE;
+ xcb_render_picture_t m_xrenderPicture = XCB_NONE;
+ xcb_render_pictformat_t m_xrenderPictFormat = XCB_NONE;
+ xcb_render_picture_t m_windowPicture = XCB_NONE;
+#endif
+ bool m_usingXRenderMode = false;
+ bool m_useGrabbedBackgound = false;
+ QPixmap m_grabbedBackground;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index b091928e8c..84831cdbe5 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -42,16 +42,13 @@
#include "qxcbconnection.h"
#include "qxcbscreen.h"
#include "qxcbmime.h"
+#include "qxcbwindow.h"
#include <private/qguiapplication_p.h>
#include <QElapsedTimer>
#include <QtCore/QDebug>
-#define class class_name // Workaround XCB-ICCCM 3.8 breakage
-#include <xcb/xcb_icccm.h>
-#undef class
-
QT_BEGIN_NAMESPACE
#ifndef QT_NO_CLIPBOARD
@@ -156,6 +153,7 @@ private:
QByteArray format_atoms;
};
+namespace {
class INCRTransaction;
typedef QMap<xcb_window_t,INCRTransaction*> TransactionMap;
static TransactionMap *transactions = 0;
@@ -262,6 +260,7 @@ private:
uint offset;
int abort_timer;
};
+} // unnamed namespace
const int QXcbClipboard::clipboard_timeout = 5000;
@@ -276,18 +275,6 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c)
m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME;
m_owner = connection()->getQtSelectionOwner();
-#ifndef QT_NO_DEBUG
- QByteArray ba("Qt clipboard window");
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_owner,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData());
-#endif
-
if (connection()->hasXFixes()) {
const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
@@ -314,7 +301,7 @@ QXcbClipboard::~QXcbClipboard()
connection()->sync();
// waiting until the clipboard manager fetches the content.
- if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, clipboard_timeout, true)) {
+ if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, true)) {
qWarning("QXcbClipboard: Unable to receive an event from the "
"clipboard manager in a reasonable time");
}
@@ -467,17 +454,9 @@ xcb_window_t QXcbClipboard::requestor() const
platformScreen->screen()->root_visual, // visual
0, // value mask
0); // value list
-#ifndef QT_NO_DEBUG
- QByteArray ba("Qt clipboard requestor window");
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- window,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData());
-#endif
+
+ QXcbWindow::setWindowTitle(connection(), window,
+ QStringLiteral("Qt Clipboard Requestor Window"));
uint32_t mask = XCB_EVENT_MASK_PROPERTY_CHANGE;
xcb_change_window_attributes(xcb_connection(), window, XCB_CW_EVENT_MASK, &mask);
@@ -600,7 +579,7 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
return;
}
- Q_DECLARE_XCB_EVENT(event, xcb_selection_notify_event_t);
+ q_padded_xcb_event<xcb_selection_notify_event_t> event = {};
event.response_type = XCB_SELECTION_NOTIFY;
event.requestor = req->requestor;
event.selection = req->selection;
@@ -824,73 +803,44 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property,
return ok;
}
-
-namespace
+xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t window, int type, bool checkManager)
{
- class Notify {
- public:
- Notify(xcb_window_t win, int t)
- : window(win), type(t) {}
- xcb_window_t window;
- int type;
- bool checkEvent(xcb_generic_event_t *event) const {
- if (!event)
- return false;
- int t = event->response_type & 0x7f;
- if (t != type)
+ QElapsedTimer timer;
+ timer.start();
+ do {
+ auto e = connection()->checkEvent([window, type](xcb_generic_event_t *event, int eventType) {
+ if (eventType != type)
return false;
- if (t == XCB_PROPERTY_NOTIFY) {
- xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
- if (pn->window == window)
+ if (eventType == XCB_PROPERTY_NOTIFY) {
+ auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
+ if (propertyNotify->window == window)
return true;
- } else if (t == XCB_SELECTION_NOTIFY) {
- xcb_selection_notify_event_t *sn = (xcb_selection_notify_event_t *)event;
- if (sn->requestor == window)
+ } else if (eventType == XCB_SELECTION_NOTIFY) {
+ auto selectionNotify = reinterpret_cast<xcb_selection_notify_event_t *>(event);
+ if (selectionNotify->requestor == window)
return true;
}
return false;
- }
- };
- class ClipboardEvent {
- public:
- ClipboardEvent(QXcbConnection *c)
- { clipboard = c->internAtom("CLIPBOARD"); }
- xcb_atom_t clipboard;
- bool checkEvent(xcb_generic_event_t *e) const {
- if (!e)
- return false;
- int type = e->response_type & 0x7f;
- if (type == XCB_SELECTION_REQUEST) {
- xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)e;
- return sr->selection == XCB_ATOM_PRIMARY || sr->selection == clipboard;
- } else if (type == XCB_SELECTION_CLEAR) {
- xcb_selection_clear_event_t *sc = (xcb_selection_clear_event_t *)e;
- return sc->selection == XCB_ATOM_PRIMARY || sc->selection == clipboard;
- }
- return false;
- }
- };
-}
-
-xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool checkManager)
-{
- QElapsedTimer timer;
- timer.start();
- do {
- Notify notify(win, type);
- xcb_generic_event_t *e = connection()->checkEvent(notify);
- if (e)
+ });
+ if (e) // found the waited for event
return e;
if (checkManager) {
auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));
if (!reply || reply->owner == XCB_NONE)
- return 0;
+ return nullptr;
}
// process other clipboard events, since someone is probably requesting data from us
- ClipboardEvent clipboard(connection());
- e = connection()->checkEvent(clipboard);
+ auto clipboardAtom = atom(QXcbAtom::CLIPBOARD);
+ e = connection()->checkEvent([clipboardAtom](xcb_generic_event_t *event, int type) {
+ xcb_atom_t selection = XCB_ATOM_NONE;
+ if (type == XCB_SELECTION_REQUEST)
+ selection = reinterpret_cast<xcb_selection_request_event_t *>(event)->selection;
+ else if (type == XCB_SELECTION_CLEAR)
+ selection = reinterpret_cast<xcb_selection_clear_event_t *>(event)->selection;
+ return selection == XCB_ATOM_PRIMARY || selection == clipboardAtom;
+ });
if (e) {
connection()->handleXcbEvent(e);
free(e);
@@ -900,9 +850,9 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int
// sleep 50 ms, so we don't use up CPU cycles all the time.
QThread::msleep(50);
- } while (timer.elapsed() < timeout);
+ } while (timer.elapsed() < clipboard_timeout);
- return 0;
+ return nullptr;
}
QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm)
@@ -924,7 +874,7 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
for (;;) {
connection()->flush();
- xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY, clipboard_timeout);
+ xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY);
if (!ge)
break;
xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge;
@@ -987,7 +937,7 @@ QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target,
connection()->sync();
- xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_SELECTION_NOTIFY, clipboard_timeout);
+ xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_SELECTION_NOTIFY);
bool no_selection = !ge || ((xcb_selection_notify_event_t *)ge)->property == XCB_NONE;
free(ge);
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h
index bfeae13e10..abab42a613 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.h
+++ b/src/plugins/platforms/xcb/qxcbclipboard.h
@@ -89,7 +89,7 @@ public:
QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0);
private:
- xcb_generic_event_t *waitForClipboardEvent(xcb_window_t win, int type, int timeout, bool checkManager = false);
+ xcb_generic_event_t *waitForClipboardEvent(xcb_window_t window, int type, bool checkManager = false);
xcb_atom_t sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property);
xcb_atom_t sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index aca2c347ea..48715e0812 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -55,6 +55,7 @@
#include "qxcbsystemtraytracker.h"
#include "qxcbglintegrationfactory.h"
#include "qxcbglintegration.h"
+#include "qxcbcursor.h"
#include "qxcbbackingstore.h"
#include <QSocketNotifier>
@@ -81,8 +82,8 @@
#undef register
#endif
-#if QT_CONFIG(xinput2)
-#include <X11/extensions/XI2proto.h>
+#if QT_CONFIG(xcb_xinput)
+#include <xcb/xinput.h>
#endif
#if QT_CONFIG(xcb_render)
@@ -118,6 +119,7 @@ Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
Q_LOGGING_CATEGORY(lcQpaXcb, "qt.qpa.xcb") // for general (uncategorized) XCB logging
Q_LOGGING_CATEGORY(lcQpaPeeker, "qt.qpa.peeker")
Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard")
+Q_LOGGING_CATEGORY(lcQpaXDnd, "qt.qpa.xdnd")
// this event type was added in libxcb 1.10,
// but we support also older version
@@ -125,7 +127,7 @@ Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard")
#define XCB_GE_GENERIC 35
#endif
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
// - "pad0" became "extension"
// - "pad1" and "pad" became "pad0"
@@ -143,7 +145,7 @@ static inline bool isXIEvent(xcb_generic_event_t *event, int opCode)
qt_xcb_ge_event_t *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
return e->extension == opCode;
}
-#endif // QT_CONFIG(xinput2)
+#endif // QT_CONFIG(xcb_xinput)
#if QT_CONFIG(xcb_xlib)
static const char * const xcbConnectionErrors[] = {
@@ -542,31 +544,59 @@ void QXcbConnection::initializeScreens()
}
}
-QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
- : m_canGrabServer(canGrabServer)
- , m_defaultVisualId(defaultVisualId)
- , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
- , m_nativeInterface(nativeInterface)
+QXcbConnection *QXcbConnection::create(QXcbNativeInterface *nativeInterface, bool canGrabServer,
+ xcb_visualid_t defaultVisualId,
+ const char *displayNameIn)
{
+ const QByteArray displayName = displayNameIn ? QByteArray(displayNameIn) : qgetenv("DISPLAY");
+ int primaryScreenNumber = 0;
+ void *xlibDisplay = nullptr;
+ xcb_connection_t *connection = nullptr;
#if QT_CONFIG(xcb_xlib)
- Display *dpy = XOpenDisplay(m_displayName.constData());
+ Display *dpy = XOpenDisplay(displayName.constData());
if (dpy) {
- m_primaryScreenNumber = DefaultScreen(dpy);
- m_connection = XGetXCBConnection(dpy);
+ primaryScreenNumber = DefaultScreen(dpy);
+ connection = XGetXCBConnection(dpy);
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
XSetErrorHandler(nullErrorHandler);
XSetIOErrorHandler(ioErrorHandler);
- m_xlib_display = dpy;
+ xlibDisplay = dpy;
}
#else
- m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
+ connection = xcb_connect(displayName.constData(), &primaryScreenNumber);
#endif // QT_CONFIG(xcb_xlib)
-
- if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection))) {
- qCWarning(lcQpaScreen, "QXcbConnection: Could not connect to display %s", m_displayName.constData());
- return;
+ if (Q_UNLIKELY(connection == nullptr)) {
+ qWarning("QXcbConnection: Could not connect to display \"%s\"", displayName.constData());
+ return nullptr;
+ }
+ if (Q_UNLIKELY(xcb_connection_has_error(connection))) {
+#if QT_CONFIG(xcb_xlib)
+ XCloseDisplay(static_cast<Display *>(xlibDisplay));
+#else
+ xcb_disconnect(connection);
+#endif
+ qWarning("QXcbConnection: Errors occurred connecting to display \"%s\"", displayName.constData());
+ return nullptr;
}
+ return new QXcbConnection(connection, primaryScreenNumber, nativeInterface,
+ canGrabServer, defaultVisualId, displayName, xlibDisplay);
+}
+
+QXcbConnection::QXcbConnection(xcb_connection_t *c, int primaryScreenNumber,
+ QXcbNativeInterface *nativeInterface, bool canGrabServer,
+ xcb_visualid_t defaultVisualId, const QByteArray &displayName,
+ void *xlibDisplay)
+ : m_connection(c)
+ , m_canGrabServer(canGrabServer)
+ , m_defaultVisualId(defaultVisualId)
+ , m_primaryScreenNumber(primaryScreenNumber)
+ , m_displayName(displayName)
+ , m_nativeInterface(nativeInterface)
+#if QT_CONFIG(xcb_xlib)
+ , m_xlib_display(xlibDisplay)
+#endif
+{
m_reader = new QXcbEventReader(this);
m_reader->start();
@@ -578,6 +608,9 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
#if QT_CONFIG(xcb_render)
&xcb_render_id,
#endif
+#if QT_CONFIG(xcb_xinput)
+ &xcb_input_id,
+#endif
0
};
@@ -590,6 +623,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeAllAtoms();
+ initializeXSync();
if (!qEnvironmentVariableIsSet("QT_XCB_NO_MITSHM"))
initializeShm();
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XRANDR"))
@@ -600,7 +634,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeScreens();
initializeXRender();
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2"))
initializeXInput2();
#endif
@@ -727,22 +761,22 @@ QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
{ \
- event_t *e = reinterpret_cast<event_t *>(event); \
+ auto e = reinterpret_cast<event_t *>(event); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \
- handled = eventListener->handleGenericEvent(event, &result); \
- if (!handled) \
- eventListener->handler(e); \
+ if (eventListener->handleNativeEvent(event)) \
+ return; \
+ eventListener->handler(e); \
} \
} \
break;
#define HANDLE_KEYBOARD_EVENT(event_t, handler) \
{ \
- event_t *e = reinterpret_cast<event_t *>(event); \
+ auto e = reinterpret_cast<event_t *>(event); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
- handled = eventListener->handleGenericEvent(event, &result); \
- if (!handled) \
- m_keyboard->handler(e); \
+ if (eventListener->handleNativeEvent(event)) \
+ return; \
+ m_keyboard->handler(e); \
} \
} \
break;
@@ -968,7 +1002,7 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
{
long result = 0;
QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
- if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), error, &result))
+ if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), error, &result))
return;
printXcbError("QXcbConnection: XCB error", error);
@@ -1060,197 +1094,206 @@ namespace {
void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
{
- long result = 0;
+ if (Q_UNLIKELY(lcQpaEvents().isDebugEnabled()))
+ printXcbEvent(lcQpaEvents(), "Event", event);
+
+ long result = 0; // Used only by MS Windows
QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance();
- bool handled = dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), event, &result);
+ bool handledByNativeEventFilter = dispatcher && dispatcher->filterNativeEvent(
+ m_nativeInterface->nativeEventType(), event, &result);
+ if (handledByNativeEventFilter)
+ return;
uint response_type = event->response_type & ~0x80;
- if (!handled) {
- switch (response_type) {
- case XCB_EXPOSE:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
-
- case XCB_BUTTON_PRESS: {
- xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event;
- m_keyboard->updateXKBStateFromCore(ev->state);
- // the event explicitly contains the state of the three first buttons,
- // the rest we need to manage ourselves
- m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
- setButtonState(translateMouseButton(ev->detail), true);
- if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
- qCDebug(lcQpaXInputEvents, "legacy mouse press, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttonState));
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
- }
- case XCB_BUTTON_RELEASE: {
- xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event;
- m_keyboard->updateXKBStateFromCore(ev->state);
- m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
- setButtonState(translateMouseButton(ev->detail), false);
- if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
- qCDebug(lcQpaXInputEvents, "legacy mouse release, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttonState));
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
- }
- case XCB_MOTION_NOTIFY: {
- xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event;
- m_keyboard->updateXKBStateFromCore(ev->state);
- m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
- if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
- qCDebug(lcQpaXInputEvents, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y,
- ev->detail, static_cast<unsigned int>(m_buttonState));
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
- }
-
- case XCB_CONFIGURE_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
- case XCB_MAP_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
- case XCB_UNMAP_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
- case XCB_DESTROY_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_destroy_notify_event_t, event, handleDestroyNotifyEvent);
- case XCB_CLIENT_MESSAGE:
- handleClientMessageEvent((xcb_client_message_event_t *)event);
- break;
- case XCB_ENTER_NOTIFY:
-#if QT_CONFIG(xinput2)
- if (hasXInput2() && !xi2MouseEventsDisabled())
- break;
+ bool handled = true;
+ switch (response_type) {
+ case XCB_EXPOSE:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
+ case XCB_BUTTON_PRESS: {
+ auto ev = reinterpret_cast<xcb_button_press_event_t *>(event);
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ // the event explicitly contains the state of the three first buttons,
+ // the rest we need to manage ourselves
+ m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
+ setButtonState(translateMouseButton(ev->detail), true);
+ if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
+ qCDebug(lcQpaXInputEvents, "legacy mouse press, button %d state %X",
+ ev->detail, static_cast<unsigned int>(m_buttonState));
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
+ }
+ case XCB_BUTTON_RELEASE: {
+ auto ev = reinterpret_cast<xcb_button_release_event_t *>(event);
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
+ setButtonState(translateMouseButton(ev->detail), false);
+ if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
+ qCDebug(lcQpaXInputEvents, "legacy mouse release, button %d state %X",
+ ev->detail, static_cast<unsigned int>(m_buttonState));
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
+ }
+ case XCB_MOTION_NOTIFY: {
+ auto ev = reinterpret_cast<xcb_motion_notify_event_t *>(event);
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
+ if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
+ qCDebug(lcQpaXInputEvents, "legacy mouse move %d,%d button %d state %X",
+ ev->event_x, ev->event_y, ev->detail, static_cast<unsigned int>(m_buttonState));
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
+ }
+ case XCB_CONFIGURE_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
+ case XCB_MAP_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
+ case XCB_UNMAP_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
+ case XCB_DESTROY_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_destroy_notify_event_t, event, handleDestroyNotifyEvent);
+ case XCB_CLIENT_MESSAGE: {
+ auto clientMessage = reinterpret_cast<xcb_client_message_event_t *>(event);
+ if (clientMessage->format != 32)
+ return;
+#if QT_CONFIG(draganddrop)
+ if (clientMessage->type == atom(QXcbAtom::XdndStatus))
+ drag()->handleStatus(clientMessage);
+ else if (clientMessage->type == atom(QXcbAtom::XdndFinished))
+ drag()->handleFinished(clientMessage);
#endif
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
- case XCB_LEAVE_NOTIFY:
-#if QT_CONFIG(xinput2)
- if (hasXInput2() && !xi2MouseEventsDisabled())
- break;
+ if (m_systemTrayTracker && clientMessage->type == atom(QXcbAtom::MANAGER))
+ m_systemTrayTracker->notifyManagerClientMessageEvent(clientMessage);
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
+ }
+ case XCB_ENTER_NOTIFY:
+#if QT_CONFIG(xcb_xinput)
+ if (hasXInput2() && !xi2MouseEventsDisabled())
+ break;
#endif
- m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state);
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
- case XCB_FOCUS_IN:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
- case XCB_FOCUS_OUT:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
- case XCB_KEY_PRESS:
- {
- xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
- m_keyboard->updateXKBStateFromCore(kp->state);
- setTime(kp->time);
- HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
- }
- case XCB_KEY_RELEASE:
- m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
- HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
- case XCB_MAPPING_NOTIFY:
- m_keyboard->updateKeymap(reinterpret_cast<xcb_mapping_notify_event_t *>(event));
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
+ case XCB_LEAVE_NOTIFY:
+#if QT_CONFIG(xcb_xinput)
+ if (hasXInput2() && !xi2MouseEventsDisabled())
break;
- case XCB_SELECTION_REQUEST:
- {
+#endif
+ m_keyboard->updateXKBStateFromCore(reinterpret_cast<xcb_leave_notify_event_t *>(event)->state);
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
+ case XCB_FOCUS_IN:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
+ case XCB_FOCUS_OUT:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
+ case XCB_KEY_PRESS:
+ {
+ auto keyPress = reinterpret_cast<xcb_key_press_event_t *>(event);
+ m_keyboard->updateXKBStateFromCore(keyPress->state);
+ setTime(keyPress->time);
+ HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
+ }
+ case XCB_KEY_RELEASE:
+ m_keyboard->updateXKBStateFromCore(reinterpret_cast<xcb_key_release_event_t *>(event)->state);
+ HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
+ case XCB_MAPPING_NOTIFY:
+ m_keyboard->updateKeymap(reinterpret_cast<xcb_mapping_notify_event_t *>(event));
+ break;
+ case XCB_SELECTION_REQUEST:
+ {
#if QT_CONFIG(draganddrop) || QT_CONFIG(clipboard)
- xcb_selection_request_event_t *sr = reinterpret_cast<xcb_selection_request_event_t *>(event);
+ auto selectionRequest = reinterpret_cast<xcb_selection_request_event_t *>(event);
#endif
#if QT_CONFIG(draganddrop)
- if (sr->selection == atom(QXcbAtom::XdndSelection))
- m_drag->handleSelectionRequest(sr);
- else
+ if (selectionRequest->selection == atom(QXcbAtom::XdndSelection))
+ m_drag->handleSelectionRequest(selectionRequest);
+ else
#endif
- {
+ {
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleSelectionRequest(sr);
+ m_clipboard->handleSelectionRequest(selectionRequest);
#endif
- }
- break;
}
- case XCB_SELECTION_CLEAR:
- setTime((reinterpret_cast<xcb_selection_clear_event_t *>(event))->time);
+ break;
+ }
+ case XCB_SELECTION_CLEAR:
+ setTime((reinterpret_cast<xcb_selection_clear_event_t *>(event))->time);
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleSelectionClearRequest(reinterpret_cast<xcb_selection_clear_event_t *>(event));
+ m_clipboard->handleSelectionClearRequest(reinterpret_cast<xcb_selection_clear_event_t *>(event));
#endif
- handled = true;
- break;
- case XCB_SELECTION_NOTIFY:
- setTime((reinterpret_cast<xcb_selection_notify_event_t *>(event))->time);
- handled = false;
- break;
- case XCB_PROPERTY_NOTIFY:
- {
- xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
- if (pn->atom == atom(QXcbAtom::_NET_WORKAREA)) {
- QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(pn->window);
- if (virtualDesktop)
- virtualDesktop->updateWorkArea();
- } else {
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
- }
- break;
+ break;
+ case XCB_SELECTION_NOTIFY:
+ setTime((reinterpret_cast<xcb_selection_notify_event_t *>(event))->time);
+ break;
+ case XCB_PROPERTY_NOTIFY:
+ {
+ auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
+ if (propertyNotify->atom == atom(QXcbAtom::_NET_WORKAREA)) {
+ QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
+ if (virtualDesktop)
+ virtualDesktop->updateWorkArea();
+ } else {
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
}
-#if QT_CONFIG(xinput2)
- case XCB_GE_GENERIC:
- // Here the windowEventListener is invoked from xi2HandleEvent()
- if (hasXInput2() && isXIEvent(event, m_xiOpCode))
- xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
- break;
+ break;
+ }
+#if QT_CONFIG(xcb_xinput)
+ case XCB_GE_GENERIC:
+ // Here the windowEventListener is invoked from xi2HandleEvent()
+ if (hasXInput2() && isXIEvent(event, m_xiOpCode))
+ xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
+ break;
#endif
- default:
- handled = false;
- break;
- }
+ default:
+ handled = false; // event type not recognized
+ break;
}
- if (!handled) {
- if (has_xfixes && response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
- xcb_xfixes_selection_notify_event_t *notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
- setTime(notify_event->timestamp);
+ if (handled)
+ return;
+
+ handled = true;
+ if (has_xfixes && response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
+ auto notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
+ setTime(notify_event->timestamp);
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleXFixesSelectionRequest(notify_event);
+ m_clipboard->handleXFixesSelectionRequest(notify_event);
#endif
- for (QXcbVirtualDesktop *virtualDesktop : qAsConst(m_virtualDesktops))
- virtualDesktop->handleXFixesSelectionNotify(notify_event);
-
- handled = true;
- } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) {
- updateScreens(reinterpret_cast<xcb_randr_notify_event_t *>(event));
- handled = true;
- } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
- xcb_randr_screen_change_notify_event_t *change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
- if (auto *virtualDesktop = virtualDesktopForRootWindow(change_event->root))
- virtualDesktop->handleScreenChange(change_event);
-
- handled = true;
+ for (QXcbVirtualDesktop *virtualDesktop : qAsConst(m_virtualDesktops))
+ virtualDesktop->handleXFixesSelectionNotify(notify_event);
+ } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) {
+ updateScreens(reinterpret_cast<xcb_randr_notify_event_t *>(event));
+ } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
+ auto change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
+ if (auto virtualDesktop = virtualDesktopForRootWindow(change_event->root))
+ virtualDesktop->handleScreenChange(change_event);
#if QT_CONFIG(xkb)
- } else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295
- _xkb_event *xkb_event = reinterpret_cast<_xkb_event *>(event);
- if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
- switch (xkb_event->any.xkbType) {
- // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap
- // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent recompilations.
- case XCB_XKB_STATE_NOTIFY:
- m_keyboard->updateXKBState(&xkb_event->state_notify);
- handled = true;
- break;
- case XCB_XKB_MAP_NOTIFY:
+ } else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295
+ auto xkb_event = reinterpret_cast<_xkb_event *>(event);
+ if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
+ switch (xkb_event->any.xkbType) {
+ // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap
+ // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent recompilations.
+ case XCB_XKB_STATE_NOTIFY:
+ m_keyboard->updateXKBState(&xkb_event->state_notify);
+ break;
+ case XCB_XKB_MAP_NOTIFY:
+ m_keyboard->updateKeymap();
+ break;
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
m_keyboard->updateKeymap();
- handled = true;
- break;
- case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
- xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
- if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
- m_keyboard->updateKeymap();
- break;
- }
- default:
- break;
+ break;
}
+ default:
+ break;
}
-#endif
}
+#endif
+ } else {
+ handled = false; // event type still not recognized
}
- if (!handled && m_glIntegration)
- handled = m_glIntegration->handleXcbEvent(event, response_type);
+ if (handled)
+ return;
-#if 0
- if (Q_UNLIKELY(lcQpaEvents().isDebugEnabled()))
- printXcbEvent(lcQpaEvents(), handled ? "Handled" : "Unhandled", event);
-#endif
+ if (m_glIntegration)
+ m_glIntegration->handleXcbEvent(event, response_type);
}
void QXcbConnection::addPeekFunc(PeekFunc f)
@@ -1478,54 +1521,35 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
xcb_flush(xcb_connection());
}
-namespace
-{
- class PropertyNotifyEvent {
- public:
- PropertyNotifyEvent(xcb_window_t win, xcb_atom_t property)
- : window(win), type(XCB_PROPERTY_NOTIFY), atom(property) {}
- xcb_window_t window;
- int type;
- xcb_atom_t atom;
- bool checkEvent(xcb_generic_event_t *event) const {
- if (!event)
- return false;
- if ((event->response_type & ~0x80) != type) {
- return false;
- } else {
- xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
- if ((pn->window == window) && (pn->atom == atom))
- return true;
- }
- return false;
- }
- };
-}
-
xcb_timestamp_t QXcbConnection::getTimestamp()
{
// send a dummy event to myself to get the timestamp from X server.
- xcb_window_t root_win = rootWindow();
- xcb_change_property(xcb_connection(), XCB_PROP_MODE_APPEND, root_win, atom(QXcbAtom::CLIP_TEMPORARY),
- XCB_ATOM_INTEGER, 32, 0, NULL);
+ xcb_window_t window = rootWindow();
+ xcb_atom_t dummyAtom = atom(QXcbAtom::CLIP_TEMPORARY);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_APPEND, window, dummyAtom,
+ XCB_ATOM_INTEGER, 32, 0, nullptr);
connection()->flush();
- PropertyNotifyEvent checker(root_win, atom(QXcbAtom::CLIP_TEMPORARY));
- xcb_generic_event_t *event = 0;
+ xcb_generic_event_t *event = nullptr;
// lets keep this inside a loop to avoid a possible race condition, where
// reader thread has not yet had the time to acquire the mutex in order
// to add the new set of events to its event queue
while (!event) {
connection()->sync();
- event = checkEvent(checker);
+ event = checkEvent([window, dummyAtom](xcb_generic_event_t *event, int type) {
+ if (type != XCB_PROPERTY_NOTIFY)
+ return false;
+ auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
+ return propertyNotify->window == window && propertyNotify->atom == dummyAtom;
+ });
}
xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
xcb_timestamp_t timestamp = pn->time;
free(event);
- xcb_delete_property(xcb_connection(), root_win, atom(QXcbAtom::CLIP_TEMPORARY));
+ xcb_delete_property(xcb_connection(), window, dummyAtom);
return timestamp;
}
@@ -1552,6 +1576,9 @@ xcb_window_t QXcbConnection::getQtSelectionOwner()
xcbScreen->root_visual, // visual
0, // value mask
0); // value list
+
+ QXcbWindow::setWindowTitle(connection(), m_qtSelectionOwner,
+ QStringLiteral("Qt Selection Window"));
}
return m_qtSelectionOwner;
}
@@ -1576,17 +1603,11 @@ xcb_window_t QXcbConnection::clientLeader()
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->screen()->root_visual,
0, 0);
-#ifndef QT_NO_DEBUG
- QByteArray ba("Qt client leader window");
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_clientLeader,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData());
-#endif
+
+
+ QXcbWindow::setWindowTitle(connection(), m_clientLeader,
+ QStringLiteral("Qt Client Leader Window"));
+
xcb_change_property(xcb_connection(),
XCB_PROP_MODE_REPLACE,
m_clientLeader,
@@ -1614,39 +1635,14 @@ xcb_window_t QXcbConnection::clientLeader()
return m_clientLeader;
}
-#if QT_CONFIG(xcb_xlib)
-void *QXcbConnection::xlib_display() const
-{
- return m_xlib_display;
-}
-
-void *QXcbConnection::createVisualInfoForDefaultVisualId() const
-{
- if (m_defaultVisualId == UINT_MAX)
- return 0;
- XVisualInfo info;
- memset(&info, 0, sizeof info);
- info.visualid = m_defaultVisualId;
-
- int count = 0;
- Display *dpy = static_cast<Display *>(connection()->xlib_display());
- XVisualInfo *retVisual = XGetVisualInfo(dpy, VisualIDMask, &info, &count);
- Q_ASSERT(count < 2);
- return retVisual;
-}
-
-#endif
-
-#if QT_CONFIG(xinput2)
-// it is safe to cast XI_* events here as long as we are only touching the first 32 bytes,
-// after that position event needs memmove, see xi2PrepareXIGenericDeviceEvent
+#if QT_CONFIG(xcb_xinput)
static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type)
{
if (!isXIEvent(event, opCode))
return false;
- xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
- return xiEvent->evtype == type;
+ auto *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
+ return e->event_type == type;
}
#endif
static inline bool isValid(xcb_generic_event_t *event)
@@ -1682,49 +1678,45 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
}
return false;
}
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
// compress XI_* events
if (responseType == XCB_GE_GENERIC) {
if (!hasXInput2())
return false;
// compress XI_Motion
- if (isXIType(event, m_xiOpCode, XI_Motion)) {
+ if (isXIType(event, m_xiOpCode, XCB_INPUT_MOTION)) {
#if QT_CONFIG(tabletevent)
- xXIDeviceEvent *xdev = reinterpret_cast<xXIDeviceEvent *>(event);
- // Xlib's XI2 events need memmove, see xi2PrepareXIGenericDeviceEvent()
- auto sourceId = *reinterpret_cast<uint16_t *>(reinterpret_cast<char *>(&xdev->sourceid) + 4);
+ auto *xdev = reinterpret_cast<xcb_input_motion_event_t *>(event);
if (!QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents) &&
- const_cast<QXcbConnection *>(this)->tabletDataForDevice(sourceId))
+ const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid))
return false;
#endif // QT_CONFIG(tabletevent)
for (int j = nextIndex; j < eventqueue->size(); ++j) {
xcb_generic_event_t *next = eventqueue->at(j);
if (!isValid(next))
continue;
- if (isXIType(next, m_xiOpCode, XI_Motion))
+ if (isXIType(next, m_xiOpCode, XCB_INPUT_MOTION))
return true;
}
return false;
}
-#ifdef XCB_USE_XINPUT22
// compress XI_TouchUpdate for the same touch point id
- if (isXIType(event, m_xiOpCode, XI_TouchUpdate)) {
- xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
- uint32_t id = xiDeviceEvent->detail % INT_MAX;
+ if (isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) {
+ auto *touchUpdateEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(event);
+ uint32_t id = touchUpdateEvent->detail % INT_MAX;
for (int j = nextIndex; j < eventqueue->size(); ++j) {
xcb_generic_event_t *next = eventqueue->at(j);
if (!isValid(next))
continue;
- if (isXIType(next, m_xiOpCode, XI_TouchUpdate)) {
- xXIDeviceEvent *xiDeviceNextEvent = reinterpret_cast<xXIDeviceEvent *>(next);
- if (id == xiDeviceNextEvent->detail % INT_MAX)
+ if (isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) {
+ auto *touchUpdateNextEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(next);
+ if (id == touchUpdateNextEvent->detail % INT_MAX)
return true;
}
}
return false;
}
-#endif
return false;
}
#endif
@@ -1806,28 +1798,6 @@ void QXcbConnection::processXcbEvents()
xcb_flush(xcb_connection());
}
-void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t *event)
-{
- if (event->format != 32)
- return;
-
-#if QT_CONFIG(draganddrop)
- if (event->type == atom(QXcbAtom::XdndStatus)) {
- drag()->handleStatus(event);
- } else if (event->type == atom(QXcbAtom::XdndFinished)) {
- drag()->handleFinished(event);
- }
-#endif
- if (m_systemTrayTracker && event->type == atom(QXcbAtom::MANAGER))
- m_systemTrayTracker->notifyManagerClientMessageEvent(event);
-
- QXcbWindow *window = platformWindowFromId(event->window);
- if (!window)
- return;
-
- window->handleClientMessageEvent(event);
-}
-
static const char * xcb_atomnames = {
// window-manager <-> client protocols
"WM_PROTOCOLS\0"
@@ -1850,6 +1820,7 @@ static const char * xcb_atomnames = {
"WM_CLIENT_LEADER\0"
"WM_WINDOW_ROLE\0"
"SM_CLIENT_ID\0"
+ "WM_CLIENT_MACHINE\0"
// Clipboard
"CLIPBOARD\0"
@@ -2021,6 +1992,10 @@ static const char * xcb_atomnames = {
"_COMPIZ_DECOR_DELETE_PIXMAP\0"
"_COMPIZ_TOOLKIT_ACTION\0"
"_GTK_LOAD_ICONTHEMES\0"
+ "AT_SPI_BUS\0"
+ "EDID\0"
+ "EDID_DATA\0"
+ "XFree86_DDC_EDID1_RAWDATA\0"
// \0\0 terminates loop.
};
@@ -2041,10 +2016,7 @@ void QXcbConnection::initializeAllAtoms() {
++ptr;
}
- Q_ASSERT(i == QXcbAtom::NPredefinedAtoms);
-
- const QByteArray settings_atom_name = "_QT_SETTINGS_TIMESTAMP_" + m_displayName;
- names[i++] = settings_atom_name;
+ Q_ASSERT(i == QXcbAtom::NAtoms);
xcb_intern_atom_cookie_t cookies[QXcbAtom::NAtoms];
@@ -2297,6 +2269,15 @@ void QXcbConnection::initializeXKB()
#endif
}
+void QXcbConnection::initializeXSync()
+{
+ const xcb_query_extension_reply_t *reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id);
+ if (!reply || !reply->present)
+ return;
+
+ has_sync_extension = true;
+}
+
QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const
{
if (!m_systemTrayTracker) {
@@ -2309,20 +2290,18 @@ QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const
return m_systemTrayTracker;
}
-bool QXcbConnection::xEmbedSystemTrayAvailable()
+Qt::MouseButtons QXcbConnection::queryMouseButtons() const
{
- if (!QGuiApplicationPrivate::platformIntegration())
- return false;
- QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection();
- return connection->systemTrayTracker();
+ int stateMask = 0;
+ QXcbCursor::queryPointer(connection(), 0, 0, &stateMask);
+ return translateMouseButtons(stateMask);
}
-bool QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel()
+Qt::KeyboardModifiers QXcbConnection::queryKeyboardModifiers() const
{
- if (!QGuiApplicationPrivate::platformIntegration())
- return false;
- QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection();
- return connection->systemTrayTracker() && connection->systemTrayTracker()->visualHasAlphaChannel();
+ int stateMask = 0;
+ QXcbCursor::queryPointer(connection(), 0, 0, &stateMask);
+ return keyboard()->translateModifiers(stateMask);
}
bool QXcbConnection::event(QEvent *e)
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index c9dde35558..94f8a8876a 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -71,16 +71,6 @@
#include <QTabletEvent>
#endif
-#if QT_CONFIG(xinput2)
-#include <X11/extensions/XI2.h>
-#ifdef XIScrollClass
-#define XCB_USE_XINPUT21 // XI 2.1 adds smooth scrolling support
-#ifdef XI_TouchBeginMask
-#define XCB_USE_XINPUT22 // XI 2.2 adds multi-point touch support
-#endif
-#endif
-#endif // QT_CONFIG(xinput2)
-
struct xcb_randr_get_output_info_reply_t;
QT_BEGIN_NAMESPACE
@@ -93,6 +83,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents)
Q_DECLARE_LOGGING_CATEGORY(lcQpaXcb)
Q_DECLARE_LOGGING_CATEGORY(lcQpaPeeker)
Q_DECLARE_LOGGING_CATEGORY(lcQpaKeyboard)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaXDnd)
class QXcbVirtualDesktop;
class QXcbScreen;
@@ -128,6 +119,7 @@ namespace QXcbAtom {
WM_CLIENT_LEADER,
WM_WINDOW_ROLE,
SM_CLIENT_ID,
+ WM_CLIENT_MACHINE,
// Clipboard
CLIPBOARD,
@@ -303,9 +295,12 @@ namespace QXcbAtom {
_COMPIZ_TOOLKIT_ACTION,
_GTK_LOAD_ICONTHEMES,
- NPredefinedAtoms,
+ AT_SPI_BUS,
+
+ EDID,
+ EDID_DATA,
+ XFree86_DDC_EDID1_RAWDATA,
- _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
NAtoms
};
}
@@ -346,7 +341,7 @@ class QXcbWindowEventListener
{
public:
virtual ~QXcbWindowEventListener() {}
- virtual bool handleGenericEvent(xcb_generic_event_t *, long *) { return false; }
+ virtual bool handleNativeEvent(xcb_generic_event_t *) { return false; }
virtual void handleExposeEvent(const xcb_expose_event_t *) {}
virtual void handleClientMessageEvent(const xcb_client_message_event_t *) {}
@@ -362,7 +357,7 @@ public:
virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {}
virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {}
virtual void handleXIEnterLeave(xcb_ge_event_t *) {}
#endif
@@ -388,9 +383,16 @@ class Q_XCB_EXPORT QXcbConnection : public QObject
{
Q_OBJECT
public:
- QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = 0);
+ explicit QXcbConnection(xcb_connection_t *c, int primaryScreenNumber,
+ QXcbNativeInterface *nativeInterface, bool canGrabServer,
+ xcb_visualid_t defaultVisualId, const QByteArray &displayName,
+ void *xlibDisplay = nullptr);
+
~QXcbConnection();
+ static QXcbConnection *create(QXcbNativeInterface *nativeInterface, bool canGrabServer,
+ xcb_visualid_t defaultVisualId, const char *displayName = nullptr);
+
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
bool isConnected() const;
@@ -438,8 +440,7 @@ public:
xcb_visualid_t defaultVisualId() const { return m_defaultVisualId; }
#if QT_CONFIG(xcb_xlib)
- void *xlib_display() const;
- void *createVisualInfoForDefaultVisualId() const;
+ void *xlib_display() const { return m_xlib_display; }
#endif
void sync();
@@ -454,8 +455,8 @@ public:
QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id);
QXcbWindow *platformWindowFromId(xcb_window_t id);
- template<typename T>
- inline xcb_generic_event_t *checkEvent(T &checker);
+ template<typename Functor>
+ inline xcb_generic_event_t *checkEvent(Functor &&filter, bool removeFromQueue = true);
typedef bool (*PeekFunc)(QXcbConnection *, xcb_generic_event_t *);
void addPeekFunc(PeekFunc f);
@@ -490,6 +491,7 @@ public:
bool hasXInput2() const { return m_xi2Enabled; }
bool hasShm() const { return has_shm; }
bool hasShmFd() const { return has_shm_fd; }
+ bool hasXSync() const { return has_sync_extension; }
bool threadedEventHandling() const { return m_reader->isRunning(); }
@@ -522,10 +524,11 @@ public:
QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; }
QXcbSystemTrayTracker *systemTrayTracker() const;
- static bool xEmbedSystemTrayAvailable();
- static bool xEmbedSystemTrayVisualHasAlphaChannel();
-#if QT_CONFIG(xinput2)
+ Qt::MouseButtons queryMouseButtons() const;
+ Qt::KeyboardModifiers queryKeyboardModifiers() const;
+
+#if QT_CONFIG(xcb_xinput)
void xi2SelectStateEvents();
void xi2SelectDeviceEvents(xcb_window_t window);
void xi2SelectDeviceEventsCompatibility(xcb_window_t window);
@@ -534,15 +537,11 @@ public:
bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; }
bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; }
Qt::MouseButton xiToQtMouseButton(uint32_t b);
-#ifdef XCB_USE_XINPUT21
void xi2UpdateScrollingDevices();
-#endif
-#ifdef XCB_USE_XINPUT22
bool startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner);
void abortSystemMoveResizeForTouch();
bool isTouchScreen(int id);
#endif
-#endif
QXcbEventReader *eventReader() const { return m_reader; }
bool canGrab() const { return m_canGrabServer; }
@@ -568,7 +567,7 @@ private:
void initializeXinerama();
void initializeXShape();
void initializeXKB();
- void handleClientMessageEvent(const xcb_client_message_event_t *event);
+ void initializeXSync();
QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const;
QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const;
QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow) const;
@@ -583,7 +582,7 @@ private:
bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const;
bool m_xi2Enabled = false;
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
int m_xi2Minor = -1;
void initializeXInput2();
void xi2SetupDevice(void *info, bool removeExisting = true);
@@ -611,10 +610,8 @@ private:
void xi2HandleEvent(xcb_ge_event_t *event);
void xi2HandleHierarchyEvent(void *event);
void xi2HandleDeviceChangedEvent(void *event);
- int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
-#ifdef XCB_USE_XINPUT22
+ int m_xiOpCode;
void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow);
-#endif // XCB_USE_XINPUT22
#if QT_CONFIG(tabletevent)
struct TabletData {
int deviceId = 0;
@@ -649,31 +646,28 @@ private:
QPointF lastScrollPosition;
};
QHash<int, ScrollingDevice> m_scrollingDevices;
-#ifdef XCB_USE_XINPUT21
void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
void xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice);
ScrollingDevice *scrollingDeviceForId(int id);
-#endif
static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
- static void xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event);
#endif
- xcb_connection_t *m_connection = nullptr;
+ xcb_connection_t *const m_connection;
const xcb_setup_t *m_setup = nullptr;
const bool m_canGrabServer;
const xcb_visualid_t m_defaultVisualId;
QList<QXcbVirtualDesktop *> m_virtualDesktops;
QList<QXcbScreen *> m_screens;
- int m_primaryScreenNumber = 0;
+ const int m_primaryScreenNumber;
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
xcb_timestamp_t m_time = XCB_CURRENT_TIME;
xcb_timestamp_t m_netWmUserTime = XCB_CURRENT_TIME;
- QByteArray m_displayName;
+ const QByteArray m_displayName;
QXcbKeyboard *m_keyboard = nullptr;
#ifndef QT_NO_CLIPBOARD
@@ -686,13 +680,12 @@ private:
QXcbNativeInterface *m_nativeInterface = nullptr;
#if QT_CONFIG(xcb_xlib)
- void *m_xlib_display = nullptr;
+ void *const m_xlib_display;
#endif
QXcbEventReader *m_reader = nullptr;
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
QHash<int, TouchDeviceData> m_touchDevices;
-#ifdef XCB_USE_XINPUT22
struct StartSystemMoveResizeInfo {
xcb_window_t window = XCB_NONE;
uint16_t deviceid;
@@ -700,7 +693,6 @@ private:
int corner;
} m_startSystemMoveResizeInfo;
#endif
-#endif
WindowMapper m_mapper;
QVector<PeekFunc> m_peekFuncs;
@@ -708,6 +700,9 @@ private:
uint32_t xfixes_first_event = 0;
uint32_t xrandr_first_event = 0;
uint32_t xkb_first_event = 0;
+#if QT_CONFIG(xcb_xinput)
+ uint32_t xinput_first_event = 0;
+#endif
bool has_xfixes = false;
bool has_xinerama_extension = false;
@@ -718,6 +713,7 @@ private:
bool has_render_extension = false;
bool has_shm = false;
bool has_shm_fd = false;
+ bool has_sync_extension = false;
QPair<int, int> m_xrenderVersion;
@@ -745,28 +741,29 @@ private:
QByteArray m_xdgCurrentDesktop;
};
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
#if QT_CONFIG(tabletevent)
Q_DECLARE_TYPEINFO(QXcbConnection::TabletData::ValuatorClassInfo, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_MOVABLE_TYPE);
#endif
#endif
-template<typename T>
-xcb_generic_event_t *QXcbConnection::checkEvent(T &checker)
+template<typename Functor>
+xcb_generic_event_t *QXcbConnection::checkEvent(Functor &&filter, bool removeFromQueue)
{
QXcbEventArray *eventqueue = m_reader->lock();
for (int i = 0; i < eventqueue->size(); ++i) {
xcb_generic_event_t *event = eventqueue->at(i);
- if (checker.checkEvent(event)) {
- (*eventqueue)[i] = 0;
+ if (event && filter(event, event->response_type & ~0x80)) {
+ if (removeFromQueue)
+ (*eventqueue)[i] = nullptr;
m_reader->unlock();
return event;
}
}
m_reader->unlock();
- return 0;
+ return nullptr;
}
class QXcbConnectionGrabber
@@ -795,18 +792,11 @@ struct QStdFreeDeleter {
call##_reply(Q_XCB_REPLY_CONNECTION_ARG(__VA_ARGS__), call##_unchecked(__VA_ARGS__), nullptr) \
)
-template <typename T>
-union q_padded_xcb_event {
- T event;
- char padding[32];
-};
-
// The xcb_send_event() requires all events to have 32 bytes. It calls memcpy() on the
// passed in event. If the passed in event is less than 32 bytes, memcpy() reaches into
// unrelated memory.
-#define Q_DECLARE_XCB_EVENT(event_var, event_type) \
- q_padded_xcb_event<event_type> store = {}; \
- auto &event_var = store.event;
+template <typename T>
+struct alignas(32) q_padded_xcb_event : T { };
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 6a5248b8f1..a3befc7384 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -47,59 +47,51 @@
#include <QDebug>
#include <cmath>
-#include <X11/extensions/XInput2.h>
-#include <X11/extensions/XI2proto.h>
+#include <xcb/xinput.h>
+
+using qt_xcb_input_device_event_t = xcb_input_button_press_event_t;
void QXcbConnection::initializeXInput2()
{
- Display *xDisplay = static_cast<Display *>(m_xlib_display);
- if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
- int xiMajor = 2;
-#if defined(XCB_USE_XINPUT22)
- m_xi2Minor = 2; // for touch support 2.2 is enough
-#elif defined(XCB_USE_XINPUT21)
- m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
-#else
- m_xi2Minor = 0; // for tablet support 2.0 is enough
-#endif
- qCDebug(lcQpaXInput, "Plugin build with support for XInput 2 version up "
- "to %d.%d", xiMajor, m_xi2Minor);
-
- switch (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor)) {
- case Success:
- // Server's supported version can be lower than the version we have
- // announced to support. In this case Qt client will be limited by
- // X server's supported version.
- qCDebug(lcQpaXInput, "Using XInput version %d.%d", xiMajor, m_xi2Minor);
- m_xi2Enabled = true;
- xi2SetupDevices();
- xi2SelectStateEvents();
- break;
- case BadRequest: // Must be an X server with XInput 1
- qCDebug(lcQpaXInput, "X server does not support XInput 2");
- break;
- default: // BadValue
- qCDebug(lcQpaXInput, "Internal error");
- break;
- }
+ const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_input_id);
+ if (!reply || !reply->present) {
+ qCDebug(lcQpaXInput, "XInput extension is not present on the X server");
+ return;
+ }
+
+ m_xiOpCode = reply->major_opcode;
+ xinput_first_event = reply->first_event;
+
+ auto xinput_query = Q_XCB_REPLY(xcb_input_xi_query_version, m_connection, 2, 2);
+
+ if (!xinput_query || xinput_query->major_version != 2) {
+ qCWarning(lcQpaXInput, "X server does not support XInput 2");
+ } else {
+ qCDebug(lcQpaXInput, "Using XInput version %d.%d",
+ xinput_query->major_version, xinput_query->minor_version);
+ m_xi2Minor = xinput_query->minor_version;
+ m_xi2Enabled = true;
+ xi2SetupDevices();
+ xi2SelectStateEvents();
}
}
+struct qt_xcb_input_event_mask_t {
+ xcb_input_event_mask_t header;
+ uint32_t mask;
+};
+
void QXcbConnection::xi2SelectStateEvents()
{
// These state events do not depend on a specific X window, but are global
// for the X client's (application's) state.
- unsigned int bitMask = 0;
- unsigned char *xiBitMask = reinterpret_cast<unsigned char *>(&bitMask);
- XIEventMask xiEventMask;
- bitMask = XI_HierarchyChangedMask;
- bitMask |= XI_DeviceChangedMask;
- bitMask |= XI_PropertyEventMask;
- xiEventMask.deviceid = XIAllDevices;
- xiEventMask.mask_len = sizeof(bitMask);
- xiEventMask.mask = xiBitMask;
- Display *dpy = static_cast<Display *>(m_xlib_display);
- XISelectEvents(dpy, DefaultRootWindow(dpy), &xiEventMask, 1);
+ qt_xcb_input_event_mask_t xiEventMask;
+ xiEventMask.header.deviceid = XCB_INPUT_DEVICE_ALL;
+ xiEventMask.header.mask_len = 1;
+ xiEventMask.mask = XCB_INPUT_XI_EVENT_MASK_HIERARCHY;
+ xiEventMask.mask |= XCB_INPUT_XI_EVENT_MASK_DEVICE_CHANGED;
+ xiEventMask.mask |= XCB_INPUT_XI_EVENT_MASK_PROPERTY;
+ xcb_input_xi_select_events(m_connection, rootWindow(), 1, &xiEventMask.header);
}
void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window)
@@ -107,38 +99,42 @@ void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window)
if (window == rootWindow())
return;
- unsigned int bitMask = 0;
- unsigned char *xiBitMask = reinterpret_cast<unsigned char *>(&bitMask);
- bitMask |= XI_ButtonPressMask;
- bitMask |= XI_ButtonReleaseMask;
- bitMask |= XI_MotionMask;
+ uint32_t bitMask = XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS;
+ bitMask |= XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE;
+ bitMask |= XCB_INPUT_XI_EVENT_MASK_MOTION;
// There is a check for enter/leave events in plain xcb enter/leave event handler,
// core enter/leave events will be ignored in this case.
- bitMask |= XI_EnterMask;
- bitMask |= XI_LeaveMask;
-#ifdef XCB_USE_XINPUT22
+ bitMask |= XCB_INPUT_XI_EVENT_MASK_ENTER;
+ bitMask |= XCB_INPUT_XI_EVENT_MASK_LEAVE;
if (isAtLeastXI22()) {
- bitMask |= XI_TouchBeginMask;
- bitMask |= XI_TouchUpdateMask;
- bitMask |= XI_TouchEndMask;
+ bitMask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN;
+ bitMask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE;
+ bitMask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_END;
}
-#endif
- XIEventMask mask;
- mask.mask_len = sizeof(bitMask);
- mask.mask = xiBitMask;
- mask.deviceid = XIAllMasterDevices;
- Display *dpy = static_cast<Display *>(m_xlib_display);
- Status result = XISelectEvents(dpy, window, &mask, 1);
- if (result == Success)
+ qt_xcb_input_event_mask_t mask;
+ mask.header.deviceid = XCB_INPUT_DEVICE_ALL_MASTER;
+ mask.header.mask_len = 1;
+ mask.mask = bitMask;
+ xcb_void_cookie_t cookie =
+ xcb_input_xi_select_events_checked(m_connection, window, 1, &mask.header);
+ xcb_generic_error_t *error = xcb_request_check(m_connection, cookie);
+ if (error) {
+ qCDebug(lcQpaXInput, "failed to select events, window %x, error code %d", window, error->error_code);
+ free(error);
+ } else {
QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
- else
- qCDebug(lcQpaXInput, "failed to select events, window %x, result %d", window, result);
+ }
+}
+
+static inline qreal fixed3232ToReal(xcb_input_fp3232_t val)
+{
+ return qreal(val.integral) + qreal(val.frac) / (1ULL << 32);
}
void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
{
- XIDeviceInfo *deviceInfo = reinterpret_cast<XIDeviceInfo *>(info);
+ auto *deviceInfo = reinterpret_cast<xcb_input_xi_device_info_t *>(info);
if (removeExisting) {
#if QT_CONFIG(tabletevent)
for (int i = 0; i < m_tabletData.count(); ++i) {
@@ -152,53 +148,54 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
m_touchDevices.remove(deviceInfo->deviceid);
}
- qCDebug(lcQpaXInputDevices) << "input device " << deviceInfo->name << "ID" << deviceInfo->deviceid;
+ qCDebug(lcQpaXInputDevices) << "input device " << xcb_input_xi_device_info_name(deviceInfo) << "ID" << deviceInfo->deviceid;
#if QT_CONFIG(tabletevent)
TabletData tabletData;
#endif
ScrollingDevice scrollingDevice;
- for (int c = 0; c < deviceInfo->num_classes; ++c) {
- XIAnyClassInfo *classinfo = deviceInfo->classes[c];
+ auto classes_it = xcb_input_xi_device_info_classes_iterator(deviceInfo);
+ for (; classes_it.rem; xcb_input_device_class_next(&classes_it)) {
+ xcb_input_device_class_t *classinfo = classes_it.data;
switch (classinfo->type) {
- case XIValuatorClass: {
- XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo);
+ case XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR: {
+ auto *vci = reinterpret_cast<xcb_input_valuator_class_t *>(classinfo);
const int valuatorAtom = qatom(vci->label);
qCDebug(lcQpaXInputDevices) << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
#if QT_CONFIG(tabletevent)
if (valuatorAtom < QXcbAtom::NAtoms) {
TabletData::ValuatorClassInfo info;
- info.minVal = vci->min;
- info.maxVal = vci->max;
+ info.minVal = fixed3232ToReal(vci->min);
+ info.maxVal = fixed3232ToReal(vci->max);
info.number = vci->number;
tabletData.valuatorInfo[valuatorAtom] = info;
}
#endif // QT_CONFIG(tabletevent)
if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
- scrollingDevice.lastScrollPosition.setX(vci->value);
+ scrollingDevice.lastScrollPosition.setX(fixed3232ToReal(vci->value));
else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
- scrollingDevice.lastScrollPosition.setY(vci->value);
+ scrollingDevice.lastScrollPosition.setY(fixed3232ToReal(vci->value));
break;
}
-#ifdef XCB_USE_XINPUT21
- case XIScrollClass: {
- XIScrollClassInfo *sci = reinterpret_cast<XIScrollClassInfo *>(classinfo);
- if (sci->scroll_type == XIScrollTypeVertical) {
+ case XCB_INPUT_DEVICE_CLASS_TYPE_SCROLL: {
+ auto *sci = reinterpret_cast<xcb_input_scroll_class_t *>(classinfo);
+ if (sci->scroll_type == XCB_INPUT_SCROLL_TYPE_VERTICAL) {
scrollingDevice.orientations |= Qt::Vertical;
scrollingDevice.verticalIndex = sci->number;
- scrollingDevice.verticalIncrement = sci->increment;
- }
- else if (sci->scroll_type == XIScrollTypeHorizontal) {
+ scrollingDevice.verticalIncrement = fixed3232ToReal(sci->increment);
+ } else if (sci->scroll_type == XCB_INPUT_SCROLL_TYPE_HORIZONTAL) {
scrollingDevice.orientations |= Qt::Horizontal;
scrollingDevice.horizontalIndex = sci->number;
- scrollingDevice.horizontalIncrement = sci->increment;
+ scrollingDevice.horizontalIncrement = fixed3232ToReal(sci->increment);
}
break;
}
- case XIButtonClass: {
- XIButtonClassInfo *bci = reinterpret_cast<XIButtonClassInfo *>(classinfo);
+ case XCB_INPUT_DEVICE_CLASS_TYPE_BUTTON: {
+ auto *bci = reinterpret_cast<xcb_input_button_class_t *>(classinfo);
+ xcb_atom_t *labels = 0;
if (bci->num_buttons >= 5) {
- Atom label4 = bci->labels[3];
- Atom label5 = bci->labels[4];
+ labels = xcb_input_button_class_labels(bci);
+ xcb_atom_t label4 = labels[3];
+ xcb_atom_t label5 = labels[4];
// Some drivers have no labels on the wheel buttons, some have no label on just one and some have no label on
// button 4 and the wrong one on button 5. So we just check that they are not labelled with unrelated buttons.
if ((!label4 || qatom(label4) == QXcbAtom::ButtonWheelUp || qatom(label4) == QXcbAtom::ButtonWheelDown) &&
@@ -206,23 +203,20 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
scrollingDevice.legacyOrientations |= Qt::Vertical;
}
if (bci->num_buttons >= 7) {
- Atom label6 = bci->labels[5];
- Atom label7 = bci->labels[6];
+ xcb_atom_t label6 = labels[5];
+ xcb_atom_t label7 = labels[6];
if ((!label6 || qatom(label6) == QXcbAtom::ButtonHorizWheelLeft) && (!label7 || qatom(label7) == QXcbAtom::ButtonHorizWheelRight))
scrollingDevice.legacyOrientations |= Qt::Horizontal;
}
qCDebug(lcQpaXInputDevices, " has %d buttons", bci->num_buttons);
break;
}
-#endif
- case XIKeyClass:
+ case XCB_INPUT_DEVICE_CLASS_TYPE_KEY:
qCDebug(lcQpaXInputDevices) << " it's a keyboard";
break;
-#ifdef XCB_USE_XINPUT22
- case XITouchClass:
+ case XCB_INPUT_DEVICE_CLASS_TYPE_TOUCH:
// will be handled in populateTouchDevices()
break;
-#endif
default:
qCDebug(lcQpaXInputDevices) << " has class" << classinfo->type;
break;
@@ -237,7 +231,8 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
isTablet = true;
// But we need to be careful not to take the touch and tablet-button devices as tablets.
- QByteArray name = QByteArray(deviceInfo->name).toLower();
+ QByteArray name = QByteArray(xcb_input_xi_device_info_name(deviceInfo),
+ xcb_input_xi_device_info_name_length(deviceInfo)).toLower();
QString dbgType = QLatin1String("UNKNOWN");
if (name.contains("eraser")) {
isTablet = true;
@@ -281,7 +276,6 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
}
#endif // QT_CONFIG(tabletevent)
-#ifdef XCB_USE_XINPUT21
if (scrollingDevice.orientations || scrollingDevice.legacyOrientations) {
scrollingDevice.deviceId = deviceInfo->deviceid;
// Only use legacy wheel button events when we don't have real scroll valuators.
@@ -289,7 +283,6 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice);
qCDebug(lcQpaXInputDevices) << " it's a scrolling device";
}
-#endif
if (!isTablet) {
TouchDeviceData *dev = populateTouchDevices(deviceInfo);
@@ -315,23 +308,28 @@ void QXcbConnection::xi2SetupDevices()
#endif
m_scrollingDevices.clear();
m_touchDevices.clear();
-
- Display *xDisplay = static_cast<Display *>(m_xlib_display);
- int deviceCount = 0;
- XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
m_xiMasterPointerIds.clear();
- for (int i = 0; i < deviceCount; ++i) {
- XIDeviceInfo deviceInfo = devices[i];
- if (deviceInfo.use == XIMasterPointer) {
- m_xiMasterPointerIds.append(deviceInfo.deviceid);
+
+ auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, m_connection, XCB_INPUT_DEVICE_ALL);
+ if (!reply) {
+ qCDebug(lcQpaXInputDevices) << "failed to query devices";
+ return;
+ }
+
+ auto it = xcb_input_xi_query_device_infos_iterator(reply.get());
+ for (; it.rem; xcb_input_xi_device_info_next(&it)) {
+ xcb_input_xi_device_info_t *deviceInfo = it.data;
+ if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_MASTER_POINTER) {
+ m_xiMasterPointerIds.append(deviceInfo->deviceid);
continue;
}
- if (deviceInfo.use == XISlavePointer) // only slave pointer devices are relevant here
- xi2SetupDevice(&deviceInfo, false);
+ // only slave pointer devices are relevant here
+ if (deviceInfo->type == XCB_INPUT_DEVICE_TYPE_SLAVE_POINTER)
+ xi2SetupDevice(deviceInfo, false);
}
+
if (m_xiMasterPointerIds.size() > 1)
qCDebug(lcQpaXInputDevices) << "multi-pointer X detected";
- XIFreeDeviceInfo(devices);
}
/*! \internal
@@ -376,70 +374,64 @@ void QXcbConnection::xi2SelectDeviceEventsCompatibility(xcb_window_t window)
if (window == rootWindow())
return;
- unsigned int mask = 0;
- unsigned char *bitMask = reinterpret_cast<unsigned char *>(&mask);
- Display *dpy = static_cast<Display *>(m_xlib_display);
+ uint32_t mask = 0;
-#ifdef XCB_USE_XINPUT22
if (isAtLeastXI22()) {
- mask |= XI_TouchBeginMask;
- mask |= XI_TouchUpdateMask;
- mask |= XI_TouchEndMask;
-
- XIEventMask xiMask;
- xiMask.mask_len = sizeof(mask);
- xiMask.mask = bitMask;
- xiMask.deviceid = XIAllMasterDevices;
- Status result = XISelectEvents(dpy, window, &xiMask, 1);
- if (result == Success)
+ mask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN;
+ mask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE;
+ mask |= XCB_INPUT_XI_EVENT_MASK_TOUCH_END;
+
+ qt_xcb_input_event_mask_t xiMask;
+ xiMask.header.deviceid = XCB_INPUT_DEVICE_ALL_MASTER;
+ xiMask.header.mask_len = 1;
+ xiMask.mask = mask;
+
+ xcb_void_cookie_t cookie =
+ xcb_input_xi_select_events_checked(m_connection, window, 1, &xiMask.header);
+ xcb_generic_error_t *error = xcb_request_check(m_connection, cookie);
+ if (error) {
+ qCDebug(lcQpaXInput, "failed to select events, window %x, error code %d", window, error->error_code);
+ free(error);
+ } else {
QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
- else
- qCDebug(lcQpaXInput, "failed to select events, window %x, result %d", window, result);
+ }
}
-#endif
- mask = XI_ButtonPressMask;
- mask |= XI_ButtonReleaseMask;
- mask |= XI_MotionMask;
+ mask = XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS;
+ mask |= XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE;
+ mask |= XCB_INPUT_XI_EVENT_MASK_MOTION;
#if QT_CONFIG(tabletevent)
QSet<int> tabletDevices;
if (!m_tabletData.isEmpty()) {
const int nrTablets = m_tabletData.count();
- QVector<XIEventMask> xiEventMask(nrTablets);
+ QVector<qt_xcb_input_event_mask_t> xiEventMask(nrTablets);
for (int i = 0; i < nrTablets; ++i) {
int deviceId = m_tabletData.at(i).deviceId;
tabletDevices.insert(deviceId);
- xiEventMask[i].deviceid = deviceId;
- xiEventMask[i].mask_len = sizeof(mask);
- xiEventMask[i].mask = bitMask;
+ xiEventMask[i].header.deviceid = deviceId;
+ xiEventMask[i].header.mask_len = 1;
+ xiEventMask[i].mask = mask;
}
- XISelectEvents(dpy, window, xiEventMask.data(), nrTablets);
+ xcb_input_xi_select_events(m_connection, window, nrTablets, &(xiEventMask.data()->header));
}
#endif
-#ifdef XCB_USE_XINPUT21
if (!m_scrollingDevices.isEmpty()) {
- QVector<XIEventMask> xiEventMask(m_scrollingDevices.size());
+ QVector<qt_xcb_input_event_mask_t> xiEventMask(m_scrollingDevices.size());
int i = 0;
for (const ScrollingDevice& scrollingDevice : qAsConst(m_scrollingDevices)) {
#if QT_CONFIG(tabletevent)
if (tabletDevices.contains(scrollingDevice.deviceId))
continue; // All necessary events are already captured.
#endif
- xiEventMask[i].deviceid = scrollingDevice.deviceId;
- xiEventMask[i].mask_len = sizeof(mask);
- xiEventMask[i].mask = bitMask;
+ xiEventMask[i].header.deviceid = scrollingDevice.deviceId;
+ xiEventMask[i].header.mask_len = 1;
+ xiEventMask[i].mask = mask;
i++;
}
- XISelectEvents(dpy, window, xiEventMask.data(), i);
+ xcb_input_xi_select_events(m_connection, window, i, &(xiEventMask.data()->header));
}
-#endif
-
-#if !QT_CONFIG(tabletevent) && !defined(XCB_USE_XINPUT21)
- Q_UNUSED(bitMask);
- Q_UNUSED(dpy);
-#endif
}
QXcbConnection::TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
@@ -452,39 +444,38 @@ QXcbConnection::TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info)
{
- XIDeviceInfo *deviceinfo = reinterpret_cast<XIDeviceInfo *>(info);
+ auto *deviceinfo = reinterpret_cast<xcb_input_xi_device_info_t *>(info);
QTouchDevice::Capabilities caps = 0;
int type = -1;
int maxTouchPoints = 1;
bool isTouchDevice = false;
bool hasRelativeCoords = false;
TouchDeviceData dev;
- for (int i = 0; i < deviceinfo->num_classes; ++i) {
- XIAnyClassInfo *classinfo = deviceinfo->classes[i];
+ auto classes_it = xcb_input_xi_device_info_classes_iterator(deviceinfo);
+ for (; classes_it.rem; xcb_input_device_class_next(&classes_it)) {
+ xcb_input_device_class_t *classinfo = classes_it.data;
switch (classinfo->type) {
-#ifdef XCB_USE_XINPUT22
- case XITouchClass: {
- XITouchClassInfo *tci = reinterpret_cast<XITouchClassInfo *>(classinfo);
+ case XCB_INPUT_DEVICE_CLASS_TYPE_TOUCH: {
+ auto *tci = reinterpret_cast<xcb_input_touch_class_t *>(classinfo);
maxTouchPoints = tci->num_touches;
qCDebug(lcQpaXInputDevices, " has touch class with mode %d", tci->mode);
switch (tci->mode) {
- case XIDependentTouch:
+ case XCB_INPUT_TOUCH_MODE_DEPENDENT:
type = QTouchDevice::TouchPad;
break;
- case XIDirectTouch:
+ case XCB_INPUT_TOUCH_MODE_DIRECT:
type = QTouchDevice::TouchScreen;
break;
}
break;
}
-#endif // XCB_USE_XINPUT22
- case XIValuatorClass: {
- XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo);
+ case XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR: {
+ auto *vci = reinterpret_cast<xcb_input_valuator_class_t *>(classinfo);
const QXcbAtom::Atom valuatorAtom = qatom(vci->label);
if (valuatorAtom < QXcbAtom::NAtoms) {
TouchDeviceData::ValuatorClassInfo info;
- info.min = vci->min;
- info.max = vci->max;
+ info.min = fixed3232ToReal(vci->min);
+ info.max = fixed3232ToReal(vci->max);
info.number = vci->number;
info.label = valuatorAtom;
dev.valuatorInfo.append(info);
@@ -502,16 +493,16 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
caps |= QTouchDevice::Pressure;
else if (valuatorAtom == QXcbAtom::RelX) {
hasRelativeCoords = true;
- dev.size.setWidth((vci->max - vci->min) * 1000.0 / vciResolution);
+ dev.size.setWidth((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
} else if (valuatorAtom == QXcbAtom::RelY) {
hasRelativeCoords = true;
- dev.size.setHeight((vci->max - vci->min) * 1000.0 / vciResolution);
+ dev.size.setHeight((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
} else if (valuatorAtom == QXcbAtom::AbsX) {
caps |= QTouchDevice::Position;
- dev.size.setWidth((vci->max - vci->min) * 1000.0 / vciResolution);
+ dev.size.setWidth((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
} else if (valuatorAtom == QXcbAtom::AbsY) {
caps |= QTouchDevice::Position;
- dev.size.setHeight((vci->max - vci->min) * 1000.0 / vciResolution);
+ dev.size.setHeight((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
}
break;
}
@@ -530,7 +521,8 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) {
dev.qtTouchDevice = new QTouchDevice;
- dev.qtTouchDevice->setName(QString::fromUtf8(deviceinfo->name));
+ dev.qtTouchDevice->setName(QString::fromUtf8(xcb_input_xi_device_info_name(deviceinfo),
+ xcb_input_xi_device_info_name_length(deviceinfo)));
dev.qtTouchDevice->setType((QTouchDevice::DeviceType)type);
dev.qtTouchDevice->setCapabilities(caps);
dev.qtTouchDevice->setMaximumTouchPoints(maxTouchPoints);
@@ -543,89 +535,83 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
return isTouchDevice ? &m_touchDevices[deviceinfo->deviceid] : nullptr;
}
-#if defined(XCB_USE_XINPUT21) || QT_CONFIG(tabletevent)
-static inline qreal fixed1616ToReal(FP1616 val)
+#if QT_CONFIG(tabletevent)
+static inline qreal fixed1616ToReal(xcb_input_fp1616_t val)
{
return qreal(val) / 0x10000;
}
-#endif // defined(XCB_USE_XINPUT21) || QT_CONFIG(tabletevent)
+#endif // QT_CONFIG(tabletevent)
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
- xi2PrepareXIGenericDeviceEvent(event);
- xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
+ auto *xiEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event);
int sourceDeviceId = xiEvent->deviceid; // may be the master id
- xXIDeviceEvent *xiDeviceEvent = 0;
- xXIEnterEvent *xiEnterEvent = 0;
+ qt_xcb_input_device_event_t *xiDeviceEvent = nullptr;
+ xcb_input_enter_event_t *xiEnterEvent = nullptr;
QXcbWindowEventListener *eventListener = 0;
- switch (xiEvent->evtype) {
- case XI_ButtonPress:
- case XI_ButtonRelease:
- case XI_Motion:
-#ifdef XCB_USE_XINPUT22
- case XI_TouchBegin:
- case XI_TouchUpdate:
- case XI_TouchEnd:
-#endif
+ switch (xiEvent->event_type) {
+ case XCB_INPUT_BUTTON_PRESS:
+ case XCB_INPUT_BUTTON_RELEASE:
+ case XCB_INPUT_MOTION:
+ case XCB_INPUT_TOUCH_BEGIN:
+ case XCB_INPUT_TOUCH_UPDATE:
+ case XCB_INPUT_TOUCH_END:
{
- xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ xiDeviceEvent = xiEvent;
eventListener = windowEventListenerFromId(xiDeviceEvent->event);
sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master
break;
}
- case XI_Enter:
- case XI_Leave: {
- xiEnterEvent = reinterpret_cast<xXIEnterEvent *>(event);
+ case XCB_INPUT_ENTER:
+ case XCB_INPUT_LEAVE: {
+ xiEnterEvent = reinterpret_cast<xcb_input_enter_event_t *>(event);
eventListener = windowEventListenerFromId(xiEnterEvent->event);
sourceDeviceId = xiEnterEvent->sourceid; // use the actual device id instead of the master
break;
}
- case XI_HierarchyChanged:
- xi2HandleHierarchyEvent(xiEvent);
+ case XCB_INPUT_HIERARCHY:
+ xi2HandleHierarchyEvent(event);
return;
- case XI_DeviceChanged:
- xi2HandleDeviceChangedEvent(xiEvent);
+ case XCB_INPUT_DEVICE_CHANGED:
+ xi2HandleDeviceChangedEvent(event);
return;
default:
break;
}
if (eventListener) {
- long result = 0;
- if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result))
+ if (eventListener->handleNativeEvent(reinterpret_cast<xcb_generic_event_t *>(event)))
return;
}
#if QT_CONFIG(tabletevent)
if (!xiEnterEvent) {
QXcbConnection::TabletData *tablet = tabletDataForDevice(sourceDeviceId);
- if (tablet && xi2HandleTabletEvent(xiEvent, tablet))
+ if (tablet && xi2HandleTabletEvent(event, tablet))
return;
}
#endif // QT_CONFIG(tabletevent)
-#ifdef XCB_USE_XINPUT21
if (ScrollingDevice *device = scrollingDeviceForId(sourceDeviceId))
- xi2HandleScrollEvent(xiEvent, *device);
-#endif // XCB_USE_XINPUT21
+ xi2HandleScrollEvent(event, *device);
-#ifdef XCB_USE_XINPUT22
if (xiDeviceEvent) {
- switch (xiDeviceEvent->evtype) {
- case XI_ButtonPress:
- case XI_ButtonRelease:
- case XI_Motion:
- if (!xi2MouseEventsDisabled() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated))
+ switch (xiDeviceEvent->event_type) {
+ case XCB_INPUT_BUTTON_PRESS:
+ case XCB_INPUT_BUTTON_RELEASE:
+ case XCB_INPUT_MOTION:
+ if (!xi2MouseEventsDisabled() && eventListener &&
+ !(xiDeviceEvent->flags & XCB_INPUT_POINTER_EVENT_FLAGS_POINTER_EMULATED))
eventListener->handleXIMouseEvent(event);
break;
- case XI_TouchBegin:
- case XI_TouchUpdate:
- case XI_TouchEnd:
+ case XCB_INPUT_TOUCH_BEGIN:
+ case XCB_INPUT_TOUCH_UPDATE:
+ case XCB_INPUT_TOUCH_END:
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x",
- event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail,
+ event->event_type, xiDeviceEvent->sequence, xiDeviceEvent->detail,
fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y),
fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event);
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event))
@@ -633,14 +619,13 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
break;
}
} else if (xiEnterEvent && !xi2MouseEventsDisabled() && eventListener) {
- switch (xiEnterEvent->evtype) {
- case XI_Enter:
- case XI_Leave:
+ switch (xiEnterEvent->event_type) {
+ case XCB_INPUT_ENTER:
+ case XCB_INPUT_LEAVE:
eventListener->handleXIEnterLeave(event);
break;
}
}
-#endif // XCB_USE_XINPUT22
}
bool QXcbConnection::xi2MouseEventsDisabled() const
@@ -651,7 +636,6 @@ bool QXcbConnection::xi2MouseEventsDisabled() const
return xi2MouseDisabled || has_xinerama_extension;
}
-#ifdef XCB_USE_XINPUT22
bool QXcbConnection::isTouchScreen(int id)
{
auto device = touchDeviceForId(id);
@@ -660,11 +644,11 @@ bool QXcbConnection::isTouchScreen(int id)
void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow)
{
- xXIDeviceEvent *xiDeviceEvent = static_cast<xXIDeviceEvent *>(xiDevEvent);
+ auto *xiDeviceEvent = reinterpret_cast<xcb_input_touch_begin_event_t *>(xiDevEvent);
TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid);
Q_ASSERT(dev);
const bool firstTouch = dev->touchPoints.isEmpty();
- if (xiDeviceEvent->evtype == XI_TouchBegin) {
+ if (xiDeviceEvent->event_type == XCB_INPUT_TOUCH_BEGIN) {
QWindowSystemInterface::TouchPoint tp;
tp.id = xiDeviceEvent->detail % INT_MAX;
tp.state = Qt::TouchPointPressed;
@@ -735,7 +719,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
y = touchPoint.area.center().y();
ny = y / screen->geometry().height();
}
- if (xiDeviceEvent->evtype != XI_TouchEnd) {
+ if (xiDeviceEvent->event_type != XCB_INPUT_TOUCH_END) {
if (!dev->providesTouchOrientation) {
if (w == 0.0)
w = touchPoint.area.width();
@@ -750,8 +734,8 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
}
}
- switch (xiDeviceEvent->evtype) {
- case XI_TouchBegin:
+ switch (xiDeviceEvent->event_type) {
+ case XCB_INPUT_TOUCH_BEGIN:
if (firstTouch) {
dev->firstPressedPosition = QPointF(x, y);
dev->firstPressedNormalPosition = QPointF(nx, ny);
@@ -761,14 +745,12 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
// Touches must be accepted when we are grabbing touch events. Otherwise the entire sequence
// will get replayed when the grab ends.
if (m_xiGrab) {
- // Note that XIAllowTouchEvents is known to deadlock with older libXi versions,
- // for details see qtbase/src/plugins/platforms/xcb/README. This has nothing to
- // do with the XInput protocol version, but is a bug in libXi implementation instead.
- XIAllowTouchEvents(static_cast<Display *>(m_xlib_display), xiDeviceEvent->deviceid,
- xiDeviceEvent->detail, xiDeviceEvent->event, XIAcceptTouch);
+ xcb_input_xi_allow_events(m_connection, XCB_CURRENT_TIME, xiDeviceEvent->deviceid,
+ XCB_INPUT_EVENT_MODE_ACCEPT_TOUCH,
+ xiDeviceEvent->detail, xiDeviceEvent->event);
}
break;
- case XI_TouchUpdate:
+ case XCB_INPUT_TOUCH_UPDATE:
if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
@@ -789,14 +771,15 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
xiDeviceEvent->detail == m_startSystemMoveResizeInfo.pointid) {
QXcbWindow *window = platformWindowFromId(m_startSystemMoveResizeInfo.window);
if (window) {
- XIAllowTouchEvents(static_cast<Display *>(m_xlib_display), xiDeviceEvent->deviceid,
- xiDeviceEvent->detail, xiDeviceEvent->event, XIRejectTouch);
+ xcb_input_xi_allow_events(m_connection, XCB_CURRENT_TIME, xiDeviceEvent->deviceid,
+ XCB_INPUT_EVENT_MODE_REJECT_TOUCH,
+ xiDeviceEvent->detail, xiDeviceEvent->event);
window->doStartSystemMoveResize(QPoint(x, y), m_startSystemMoveResizeInfo.corner);
m_startSystemMoveResizeInfo.window = XCB_NONE;
}
}
break;
- case XI_TouchEnd:
+ case XCB_INPUT_TOUCH_END:
touchPoint.state = Qt::TouchPointReleased;
if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
@@ -814,7 +797,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition <<
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
- Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
+ Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective);
QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, dev->touchPoints.values(), modifiers);
if (touchPoint.state == Qt::TouchPointReleased)
// If a touchpoint was released, we can forget it, because the ID won't be reused.
@@ -850,46 +833,46 @@ void QXcbConnection::abortSystemMoveResizeForTouch()
{
m_startSystemMoveResizeInfo.window = XCB_NONE;
}
-#endif // XCB_USE_XINPUT22
bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab)
{
- Display *xDisplay = static_cast<Display *>(xlib_display());
bool ok = false;
if (grab) { // grab
- XIEventMask evmask;
- unsigned char mask[XIMaskLen(XI_LASTEVENT)];
- evmask.mask = mask;
- evmask.mask_len = sizeof(mask);
- memset(mask, 0, sizeof(mask));
- XISetMask(mask, XI_ButtonPress);
- XISetMask(mask, XI_ButtonRelease);
- XISetMask(mask, XI_Motion);
- XISetMask(mask, XI_Enter);
- XISetMask(mask, XI_Leave);
- XISetMask(mask, XI_TouchBegin);
- XISetMask(mask, XI_TouchUpdate);
- XISetMask(mask, XI_TouchEnd);
+ uint32_t mask = XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS
+ | XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE
+ | XCB_INPUT_XI_EVENT_MASK_MOTION
+ | XCB_INPUT_XI_EVENT_MASK_ENTER
+ | XCB_INPUT_XI_EVENT_MASK_LEAVE
+ | XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN
+ | XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE
+ | XCB_INPUT_XI_EVENT_MASK_TOUCH_END;
for (int id : m_xiMasterPointerIds) {
- evmask.deviceid = id;
- Status result = XIGrabDevice(xDisplay, id, w, CurrentTime, None,
- XIGrabModeAsync, XIGrabModeAsync, False, &evmask);
- if (result != Success) {
+ xcb_generic_error_t *error = nullptr;
+ auto cookie = xcb_input_xi_grab_device(m_connection, w, XCB_CURRENT_TIME, XCB_CURSOR_NONE, id,
+ XCB_INPUT_GRAB_MODE_22_ASYNC, XCB_INPUT_GRAB_MODE_22_ASYNC,
+ false, 1, &mask);
+ auto *reply = xcb_input_xi_grab_device_reply(m_connection, cookie, &error);
+ if (error) {
qCDebug(lcQpaXInput, "failed to grab events for device %d on window %x"
- "(result %d)", id, w, result);
+ "(error code %d)", id, w, error->error_code);
+ free(error);
} else {
// Managed to grab at least one of master pointers, that should be enough
// to properly dismiss windows that rely on mouse grabbing.
ok = true;
}
+ free(reply);
}
} else { // ungrab
for (int id : m_xiMasterPointerIds) {
- Status result = XIUngrabDevice(xDisplay, id, CurrentTime);
- if (result != Success)
- qCDebug(lcQpaXInput, "XIUngrabDevice failed - id: %d (result %d)", id, result);
+ auto cookie = xcb_input_xi_ungrab_device_checked(m_connection, XCB_CURRENT_TIME, id);
+ xcb_generic_error_t *error = xcb_request_check(m_connection, cookie);
+ if (error) {
+ qCDebug(lcQpaXInput, "XIUngrabDevice failed - id: %d (error code %d)", id, error->error_code);
+ free(error);
+ }
}
// XIUngrabDevice does not seem to wait for a reply from X server (similar to
// xcb_ungrab_pointer). Ungrabbing won't fail, unless NoSuchExtension error
@@ -906,9 +889,9 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab)
void QXcbConnection::xi2HandleHierarchyEvent(void *event)
{
- xXIHierarchyEvent *xiEvent = reinterpret_cast<xXIHierarchyEvent *>(event);
+ auto *xiEvent = reinterpret_cast<xcb_input_hierarchy_event_t *>(event);
// We only care about hotplugged devices
- if (!(xiEvent->flags & (XISlaveRemoved | XISlaveAdded)))
+ if (!(xiEvent->flags & (XCB_INPUT_HIERARCHY_MASK_SLAVE_REMOVED | XCB_INPUT_HIERARCHY_MASK_SLAVE_ADDED)))
return;
xi2SetupDevices();
@@ -925,23 +908,19 @@ void QXcbConnection::xi2HandleHierarchyEvent(void *event)
void QXcbConnection::xi2HandleDeviceChangedEvent(void *event)
{
- xXIDeviceChangedEvent *xiEvent = reinterpret_cast<xXIDeviceChangedEvent *>(event);
+ auto *xiEvent = reinterpret_cast<xcb_input_device_changed_event_t *>(event);
switch (xiEvent->reason) {
- case XIDeviceChange: {
- int nrDevices = 0;
- Display *dpy = static_cast<Display *>(m_xlib_display);
- XIDeviceInfo* deviceInfo = XIQueryDevice(dpy, xiEvent->sourceid, &nrDevices);
- if (nrDevices <= 0)
+ case XCB_INPUT_CHANGE_REASON_DEVICE_CHANGE: {
+ auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, m_connection, xiEvent->sourceid);
+ if (!reply || reply->num_infos <= 0)
return;
- xi2SetupDevice(deviceInfo);
- XIFreeDeviceInfo(deviceInfo);
+ auto it = xcb_input_xi_query_device_infos_iterator(reply.get());
+ xi2SetupDevice(it.data);
break;
}
- case XISlaveSwitch: {
-#ifdef XCB_USE_XINPUT21
+ case XCB_INPUT_CHANGE_REASON_SLAVE_SWITCH: {
if (ScrollingDevice *scrollingDevice = scrollingDeviceForId(xiEvent->sourceid))
xi2UpdateScrollingDevice(*scrollingDevice);
-#endif
break;
}
default:
@@ -950,28 +929,28 @@ void QXcbConnection::xi2HandleDeviceChangedEvent(void *event)
}
}
-#ifdef XCB_USE_XINPUT21
void QXcbConnection::xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice)
{
- int nrDevices = 0;
- Display *dpy = static_cast<Display *>(m_xlib_display);
- XIDeviceInfo* deviceInfo = XIQueryDevice(dpy, scrollingDevice.deviceId, &nrDevices);
- if (nrDevices <= 0) {
+ auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, m_connection, scrollingDevice.deviceId);
+ if (!reply || reply->num_infos <= 0) {
qCDebug(lcQpaXInputDevices, "scrolling device %d no longer present", scrollingDevice.deviceId);
return;
}
QPointF lastScrollPosition;
if (lcQpaXInputEvents().isDebugEnabled())
lastScrollPosition = scrollingDevice.lastScrollPosition;
- for (int c = 0; c < deviceInfo->num_classes; ++c) {
- XIAnyClassInfo *classInfo = deviceInfo->classes[c];
- if (classInfo->type == XIValuatorClass) {
- XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classInfo);
+
+ xcb_input_xi_device_info_t *deviceInfo = xcb_input_xi_query_device_infos_iterator(reply.get()).data;
+ auto classes_it = xcb_input_xi_device_info_classes_iterator(deviceInfo);
+ for (; classes_it.rem; xcb_input_device_class_next(&classes_it)) {
+ xcb_input_device_class_t *classInfo = classes_it.data;
+ if (classInfo->type == XCB_INPUT_DEVICE_CLASS_TYPE_VALUATOR) {
+ auto *vci = reinterpret_cast<xcb_input_valuator_class_t *>(classInfo);
const int valuatorAtom = qatom(vci->label);
if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
- scrollingDevice.lastScrollPosition.setX(vci->value);
+ scrollingDevice.lastScrollPosition.setX(fixed3232ToReal(vci->value));
else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
- scrollingDevice.lastScrollPosition.setY(vci->value);
+ scrollingDevice.lastScrollPosition.setY(fixed3232ToReal(vci->value));
}
}
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled() && lastScrollPosition != scrollingDevice.lastScrollPosition))
@@ -979,8 +958,6 @@ void QXcbConnection::xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice)
lastScrollPosition.x(), lastScrollPosition.y(),
scrollingDevice.lastScrollPosition.x(),
scrollingDevice.lastScrollPosition.y());
-
- XIFreeDeviceInfo(deviceInfo);
}
void QXcbConnection::xi2UpdateScrollingDevices()
@@ -1003,10 +980,9 @@ QXcbConnection::ScrollingDevice *QXcbConnection::scrollingDeviceForId(int id)
void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice)
{
- xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
+ auto *xiDeviceEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event);
- if (xiEvent->evtype == XI_Motion && scrollingDevice.orientations) {
- xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ if (xiDeviceEvent->event_type == XCB_INPUT_MOTION && scrollingDevice.orientations) {
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
QPoint rawDelta;
QPoint angleDelta;
@@ -1040,17 +1016,16 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
if (!angleDelta.isNull()) {
QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y));
QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y));
- Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
+ Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective);
if (modifiers & Qt::AltModifier) {
std::swap(angleDelta.rx(), angleDelta.ry());
std::swap(rawDelta.rx(), rawDelta.ry());
}
qCDebug(lcQpaXInputEvents) << "scroll wheel @ window pos" << local << "delta px" << rawDelta << "angle" << angleDelta;
- QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers);
+ QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiDeviceEvent->time, local, global, rawDelta, angleDelta, modifiers);
}
}
- } else if (xiEvent->evtype == XI_ButtonRelease && scrollingDevice.legacyOrientations) {
- xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ } else if (xiDeviceEvent->event_type == XCB_INPUT_BUTTON_RELEASE && scrollingDevice.legacyOrientations) {
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
QPoint angleDelta;
if (scrollingDevice.legacyOrientations & Qt::Vertical) {
@@ -1068,16 +1043,15 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
if (!angleDelta.isNull()) {
QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y));
QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y));
- Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
+ Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective);
if (modifiers & Qt::AltModifier)
std::swap(angleDelta.rx(), angleDelta.ry());
qCDebug(lcQpaXInputEvents) << "scroll wheel (button" << xiDeviceEvent->detail << ") @ window pos" << local << "delta angle" << angleDelta;
- QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, QPoint(), angleDelta, modifiers);
+ QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiDeviceEvent->time, local, global, QPoint(), angleDelta, modifiers);
}
}
}
}
-#endif // XCB_USE_XINPUT21
static int xi2ValuatorOffset(const unsigned char *maskPtr, int maskLen, int number)
{
@@ -1100,10 +1074,10 @@ static int xi2ValuatorOffset(const unsigned char *maskPtr, int maskLen, int numb
bool QXcbConnection::xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value)
{
- const xXIDeviceEvent *xideviceevent = static_cast<const xXIDeviceEvent *>(event);
- const unsigned char *buttonsMaskAddr = (const unsigned char*)&xideviceevent[1];
- const unsigned char *valuatorsMaskAddr = buttonsMaskAddr + xideviceevent->buttons_len * 4;
- FP3232 *valuatorsValuesAddr = (FP3232*)(valuatorsMaskAddr + xideviceevent->valuators_len * 4);
+ auto *xideviceevent = static_cast<const qt_xcb_input_device_event_t *>(event);
+ auto *buttonsMaskAddr = reinterpret_cast<const unsigned char *>(&xideviceevent[1]);
+ auto *valuatorsMaskAddr = buttonsMaskAddr + xideviceevent->buttons_len * 4;
+ auto *valuatorsValuesAddr = reinterpret_cast<const xcb_input_fp3232_t *>(valuatorsMaskAddr + xideviceevent->valuators_len * 4);
int valuatorOffset = xi2ValuatorOffset(valuatorsMaskAddr, xideviceevent->valuators_len, valuatorNum);
if (valuatorOffset < 0)
@@ -1114,15 +1088,6 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(const void *event, int valuatorNum
return true;
}
-void QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event)
-{
- // xcb event structs contain stuff that wasn't on the wire, the full_sequence field
- // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes.
- // Move this data back to have the same layout in memory as it was on the wire
- // and allow casting, overwriting the full_sequence field.
- memmove((char*) event + 32, (char*) event + 36, event->length * 4);
-}
-
Qt::MouseButton QXcbConnection::xiToQtMouseButton(uint32_t b)
{
switch (b) {
@@ -1186,31 +1151,29 @@ static const char *pointerTypeName(QTabletEvent::PointerType ptype) {
bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletData)
{
bool handled = true;
- Display *xDisplay = static_cast<Display *>(m_xlib_display);
- const xXIGenericDeviceEvent *xiEvent = static_cast<const xXIGenericDeviceEvent *>(event);
- const xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<const xXIDeviceEvent *>(xiEvent);
+ const auto *xiDeviceEvent = reinterpret_cast<const qt_xcb_input_device_event_t *>(event);
- switch (xiEvent->evtype) {
- case XI_ButtonPress: {
+ switch (xiDeviceEvent->event_type) {
+ case XCB_INPUT_BUTTON_PRESS: {
Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail);
tabletData->buttons |= b;
- xi2ReportTabletEvent(xiEvent, tabletData);
+ xi2ReportTabletEvent(event, tabletData);
break;
}
- case XI_ButtonRelease: {
+ case XCB_INPUT_BUTTON_RELEASE: {
Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail);
tabletData->buttons ^= b;
- xi2ReportTabletEvent(xiEvent, tabletData);
+ xi2ReportTabletEvent(event, tabletData);
break;
}
- case XI_Motion:
- xi2ReportTabletEvent(xiEvent, tabletData);
+ case XCB_INPUT_MOTION:
+ xi2ReportTabletEvent(event, tabletData);
break;
- case XI_PropertyEvent: {
+ case XCB_INPUT_PROPERTY: {
// This is the wacom driver's way of reporting tool proximity.
// The evdev driver doesn't do it this way.
- const xXIPropertyEvent *ev = reinterpret_cast<const xXIPropertyEvent *>(event);
- if (ev->what == XIPropertyModified) {
+ const auto *ev = reinterpret_cast<const xcb_input_property_event_t *>(event);
+ if (ev->what == XCB_INPUT_PROPERTY_FLAG_MODIFIED) {
if (ev->property == atom(QXcbAtom::WacomSerialIDs)) {
enum WacomSerialIndex {
_WACSER_USB_ID = 0,
@@ -1220,15 +1183,12 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
_WACSER_TOOL_ID,
_WACSER_COUNT
};
- Atom propType;
- int propFormat;
- unsigned long numItems, bytesAfter;
- unsigned char *data;
- if (XIGetProperty(xDisplay, tabletData->deviceId, ev->property, 0, 100,
- 0, AnyPropertyType, &propType, &propFormat,
- &numItems, &bytesAfter, &data) == Success) {
- if (propType == atom(QXcbAtom::INTEGER) && propFormat == 32 && numItems == _WACSER_COUNT) {
- quint32 *ptr = reinterpret_cast<quint32 *>(data);
+
+ auto reply = Q_XCB_REPLY(xcb_input_xi_get_property, m_connection, tabletData->deviceId, 0,
+ ev->property, XCB_GET_PROPERTY_TYPE_ANY, 0, 100);
+ if (reply) {
+ if (reply->type == atom(QXcbAtom::INTEGER) && reply->format == 32 && reply->num_items == _WACSER_COUNT) {
+ quint32 *ptr = reinterpret_cast<quint32 *>(xcb_input_xi_get_property_items(reply.get()));
quint32 tool = ptr[_WACSER_TOOL_ID];
// Workaround for http://sourceforge.net/p/linuxwacom/bugs/246/
// e.g. on Thinkpad Helix, tool ID will be 0 and serial will be 1
@@ -1260,7 +1220,6 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
tabletData->deviceId, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID],
ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], toolName(tabletData->tool));
}
- XFree(data);
}
}
}
@@ -1276,12 +1235,12 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletData)
{
- const xXIDeviceEvent *ev = reinterpret_cast<const xXIDeviceEvent *>(event);
+ auto *ev = reinterpret_cast<const qt_xcb_input_device_event_t *>(event);
QXcbWindow *xcbWindow = platformWindowFromId(ev->event);
if (!xcbWindow)
return;
QWindow *window = xcbWindow->window();
- const Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(ev->mods.effective_mods);
+ const Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(ev->mods.effective);
QPointF local(fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y));
QPointF global(fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y));
double pressure = 0, rotation = 0, tangentialPressure = 0;
@@ -1324,7 +1283,7 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
qCDebug(lcQpaXInputEvents, "XI2 event on tablet %d with tool %s type %s seq %d detail %d time %d "
"pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf modifiers 0x%x",
tabletData->deviceId, toolName(tabletData->tool), pointerTypeName(tabletData->pointerType),
- ev->sequenceNumber, ev->detail, ev->time,
+ ev->sequence, ev->detail, ev->time,
local.x(), local.y(), global.x(), global.y(),
(int)tabletData->buttons, pressure, xTilt, yTilt, rotation, (int)modifiers);
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index b401100dd4..57629ac03a 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -628,6 +628,12 @@ xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor)
}
#endif
+/*! \internal
+
+ Note that the logical state of a device (as seen by means of the protocol) may
+ lag the physical state if device event processing is frozen. See QueryPointer
+ in X11 protocol specification.
+*/
void QXcbCursor::queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask)
{
if (pos)
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index c8ba33edf5..2b8e507f30 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -63,19 +63,6 @@
QT_BEGIN_NAMESPACE
-//#define DND_DEBUG
-#ifdef DND_DEBUG
-#define DEBUG qDebug
-#else
-#define DEBUG if(0) qDebug
-#endif
-
-#ifdef DND_DEBUG
-#define DNDDEBUG qDebug()
-#else
-#define DNDDEBUG if(0) qDebug()
-#endif
-
const int xdnd_version = 5;
static inline xcb_window_t xcb_window(QPlatformWindow *w)
@@ -164,8 +151,12 @@ void QXcbDrag::init()
QXcbCursor::queryPointer(connection(), &current_virtual_desktop, 0);
drag_types.clear();
+ //current_embedding_widget = 0;
+
dropped = false;
canceled = false;
+
+ source_sameanswer = QRect();
}
bool QXcbDrag::eventFilter(QObject *o, QEvent *e)
@@ -181,11 +172,10 @@ bool QXcbDrag::eventFilter(QObject *o, QEvent *e)
void QXcbDrag::startDrag()
{
- // #fixme enableEventFilter();
-
init();
#ifndef QT_NO_CLIPBOARD
+ qCDebug(lcQpaXDnd) << "starting drag where source:" << connection()->clipboard()->owner();
xcb_set_selection_owner(xcb_connection(), connection()->clipboard()->owner(),
atom(QXcbAtom::XdndSelection), connection()->time());
#endif
@@ -211,6 +201,9 @@ void QXcbDrag::startDrag()
QBasicDrag::startDrag();
if (connection()->mouseGrabber() == nullptr)
shapedPixmapWindow()->setMouseGrabEnabled(true);
+
+ auto nativePixelPos = QHighDpi::toNativePixels(QCursor::pos(), initiatorWindow);
+ move(nativePixelPos, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
}
void QXcbDrag::endDrag()
@@ -307,34 +300,13 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
return 0;
}
-void QXcbDrag::move(const QPoint &globalPos)
+bool QXcbDrag::findXdndAwareTarget(const QPoint &globalPos, xcb_window_t *target_out)
{
-
- if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
- return;
-
- QXcbVirtualDesktop *virtualDesktop = nullptr;
- QPoint cursorPos;
- QXcbCursor::queryPointer(connection(), &virtualDesktop, &cursorPos);
- QXcbScreen *screen = virtualDesktop->screenAt(cursorPos);
- QPoint deviceIndependentPos = QHighDpiScaling::mapPositionFromNative(globalPos, screen);
-
- if (virtualDesktop != current_virtual_desktop) {
- setUseCompositing(virtualDesktop->compositingActive());
- recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos);
- if (connection()->mouseGrabber() == nullptr)
- shapedPixmapWindow()->setMouseGrabEnabled(true);
-
- current_virtual_desktop = virtualDesktop;
- } else {
- QBasicDrag::moveShapedPixmapWindow(deviceIndependentPos);
- }
-
xcb_window_t rootwin = current_virtual_desktop->root();
- auto translate = Q_XCB_REPLY(xcb_translate_coordinates, connection()->xcb_connection(),
+ auto translate = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
rootwin, rootwin, globalPos.x(), globalPos.y());
if (!translate)
- return;
+ return false;
xcb_window_t target = translate->child;
int lx = translate->dst_x;
@@ -343,10 +315,9 @@ void QXcbDrag::move(const QPoint &globalPos)
if (target && target != rootwin) {
xcb_window_t src = rootwin;
while (target != 0) {
- DNDDEBUG << "checking target for XdndAware" << target << lx << ly;
+ qCDebug(lcQpaXDnd) << "checking target for XdndAware" << target;
- // translate coordinates
- auto translate = Q_XCB_REPLY(xcb_translate_coordinates, connection()->xcb_connection(),
+ auto translate = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
src, target, lx, ly);
if (!translate) {
target = 0;
@@ -357,12 +328,11 @@ void QXcbDrag::move(const QPoint &globalPos)
src = target;
xcb_window_t child = translate->child;
- // check if it has XdndAware
auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, target,
atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0);
bool aware = reply && reply->type != XCB_NONE;
if (aware) {
- DNDDEBUG << "Found XdndAware on " << target;
+ qCDebug(lcQpaXDnd) << "found XdndAware on" << target;
break;
}
@@ -370,14 +340,45 @@ void QXcbDrag::move(const QPoint &globalPos)
}
if (!target || target == shapedPixmapWindow()->handle()->winId()) {
- DNDDEBUG << "need to find real window";
+ qCDebug(lcQpaXDnd) << "need to find real window";
target = findRealWindow(globalPos, rootwin, 6, true);
if (target == 0)
target = findRealWindow(globalPos, rootwin, 6, false);
- DNDDEBUG << "real window found" << target;
+ qCDebug(lcQpaXDnd) << "real window found" << target;
}
}
+ *target_out = target;
+ return true;
+}
+
+void QXcbDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+{
+ // The source sends XdndEnter and XdndPosition to the target.
+ if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
+ return;
+
+ QXcbVirtualDesktop *virtualDesktop = nullptr;
+ QPoint cursorPos;
+ QXcbCursor::queryPointer(connection(), &virtualDesktop, &cursorPos);
+ QXcbScreen *screen = virtualDesktop->screenAt(cursorPos);
+ QPoint deviceIndependentPos = QHighDpiScaling::mapPositionFromNative(globalPos, screen);
+
+ if (virtualDesktop != current_virtual_desktop) {
+ setUseCompositing(virtualDesktop->compositingActive());
+ recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos);
+ if (connection()->mouseGrabber() == nullptr)
+ shapedPixmapWindow()->setMouseGrabEnabled(true);
+
+ current_virtual_desktop = virtualDesktop;
+ } else {
+ QBasicDrag::moveShapedPixmapWindow(deviceIndependentPos);
+ }
+
+ xcb_window_t target;
+ if (!findXdndAwareTarget(globalPos, &target))
+ return;
+
QXcbWindow *w = 0;
if (target) {
w = connection()->platformWindowFromId(target);
@@ -385,7 +386,7 @@ void QXcbDrag::move(const QPoint &globalPos)
w = 0;
} else {
w = 0;
- target = rootwin;
+ target = current_virtual_desktop->root();
}
xcb_window_t proxy_target = xdndProxy(connection(), target);
@@ -427,13 +428,14 @@ void QXcbDrag::move(const QPoint &globalPos)
enter.data.data32[0] = 0;
#endif
enter.data.data32[1] = flags;
- enter.data.data32[2] = drag_types.size()>0 ? drag_types.at(0) : 0;
- enter.data.data32[3] = drag_types.size()>1 ? drag_types.at(1) : 0;
- enter.data.data32[4] = drag_types.size()>2 ? drag_types.at(2) : 0;
+ enter.data.data32[2] = drag_types.size() > 0 ? drag_types.at(0) : 0;
+ enter.data.data32[3] = drag_types.size() > 1 ? drag_types.at(1) : 0;
+ enter.data.data32[4] = drag_types.size() > 2 ? drag_types.at(2) : 0;
// provisionally set the rectangle to 5x5 pixels...
- source_sameanswer = QRect(globalPos.x() - 2, globalPos.y() -2 , 5, 5);
+ source_sameanswer = QRect(globalPos.x() - 2, globalPos.y() - 2 , 5, 5);
+
+ qCDebug(lcQpaXDnd) << "sending XdndEnter to target:" << target;
- DEBUG() << "sending Xdnd enter source=" << enter.data.data32[0];
if (w)
handleEnter(w, &enter, current_proxy_target);
else if (target)
@@ -447,7 +449,8 @@ void QXcbDrag::move(const QPoint &globalPos)
if (target) {
waiting_for_status = true;
-
+ // The source sends a ClientMessage of type XdndPosition. This tells the target the
+ // position of the mouse and the action that the user requested.
xcb_client_message_event_t move;
move.response_type = XCB_CLIENT_MESSAGE;
move.sequence = 0;
@@ -462,21 +465,34 @@ void QXcbDrag::move(const QPoint &globalPos)
move.data.data32[1] = 0; // flags
move.data.data32[2] = (globalPos.x() << 16) + globalPos.y();
move.data.data32[3] = connection()->time();
- move.data.data32[4] = toXdndAction(defaultAction(currentDrag()->supportedActions(), QGuiApplication::keyboardModifiers()));
- DEBUG() << "sending Xdnd position source=" << move.data.data32[0] << "target=" << move.window;
+ move.data.data32[4] = toXdndAction(defaultAction(currentDrag()->supportedActions(), mods));
+
+ qCDebug(lcQpaXDnd) << "sending XdndPosition to target:" << target;
source_time = connection()->time();
if (w)
- handle_xdnd_position(w, &move);
+ handle_xdnd_position(w, &move, b, mods);
else
xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&move);
}
+
+ static const bool isUnity = qgetenv("XDG_CURRENT_DESKTOP").toLower() == "unity";
+ if (isUnity && xdndCollectionWindow == XCB_NONE) {
+ QString name = QXcbWindow::windowTitle(connection(), target);
+ if (name == QStringLiteral("XdndCollectionWindowImp"))
+ xdndCollectionWindow = target;
+ }
+ if (target == xdndCollectionWindow) {
+ setCanDrop(false);
+ updateCursor(Qt::IgnoreAction);
+ }
}
-void QXcbDrag::drop(const QPoint &globalPos)
+void QXcbDrag::drop(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
- QBasicDrag::drop(globalPos);
+ // XdndDrop is sent from source to target to complete the drop.
+ QBasicDrag::drop(globalPos, b, mods);
if (!current_target)
return;
@@ -500,7 +516,7 @@ void QXcbDrag::drop(const QPoint &globalPos)
QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
- if (w && (w->window()->type() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ if (w && w->window()->type() == Qt::Desktop) // && !w->acceptDrops()
w = 0;
Transaction t = {
@@ -519,16 +535,13 @@ void QXcbDrag::drop(const QPoint &globalPos)
cleanup_timer = startTimer(XdndDropTransactionTimeout);
}
+ qCDebug(lcQpaXDnd) << "sending drop to target:" << current_target;
+
if (w) {
- handleDrop(w, &drop);
+ handleDrop(w, &drop, b, mods);
} else {
xcb_send_event(xcb_connection(), false, current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&drop);
}
-
- current_target = 0;
- current_proxy_target = 0;
- source_time = 0;
-// current_embedding_widget = 0;
}
Qt::DropAction QXcbDrag::toDropAction(xcb_atom_t a) const
@@ -586,44 +599,6 @@ int QXcbDrag::findTransactionByTime(xcb_timestamp_t timestamp)
}
#if 0
-
-// find an ancestor with XdndAware on it
-static Window findXdndAwareParent(Window window)
-{
- Window target = 0;
- forever {
- // check if window has XdndAware
- Atom type = 0;
- int f;
- unsigned long n, a;
- unsigned char *data = 0;
- if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
- AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
- if (data)
- XFree(data);
- if (type) {
- target = window;
- break;
- }
- }
-
- // try window's parent
- Window root;
- Window parent;
- Window *children;
- uint unused;
- if (!XQueryTree(X11->display, window, &root, &parent, &children, &unused))
- break;
- if (children)
- XFree(children);
- if (window == root)
- break;
- window = parent;
- }
- return target;
-}
-
-
// for embedding only
static QWidget* current_embedding_widget = 0;
static xcb_client_message_event_t last_enter_event;
@@ -665,11 +640,10 @@ static bool checkEmbedded(QWidget* w, const XEvent* xe)
}
#endif
-
-void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event, xcb_window_t proxy)
+void QXcbDrag::handleEnter(QPlatformWindow *, const xcb_client_message_event_t *event, xcb_window_t proxy)
{
- Q_UNUSED(window);
- DEBUG() << "handleEnter" << window;
+ // The target receives XdndEnter.
+ qCDebug(lcQpaXDnd) << "target:" << event->window << "received XdndEnter";
xdnd_types.clear();
@@ -705,11 +679,16 @@ void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_eve
}
}
for(int i = 0; i < xdnd_types.length(); ++i)
- DEBUG() << " " << connection()->atomName(xdnd_types.at(i));
+ qCDebug(lcQpaXDnd) << " " << connection()->atomName(xdnd_types.at(i));
}
-void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *e)
+void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *e,
+ Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
+ // The target receives XdndPosition. The target window must determine which widget the mouse
+ // is in and ask it whether or not it will accept the drop.
+ qCDebug(lcQpaXDnd) << "target:" << e->window << "received XdndPosition";
+
QPoint p((e->data.data32[2] & 0xffff0000) >> 16, e->data.data32[2] & 0x0000ffff);
Q_ASSERT(w);
QRect geometry = w->geometry();
@@ -718,8 +697,9 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
if (!w || !w->window() || (w->window()->type() == Qt::Desktop))
return;
- if (e->data.data32[0] != xdnd_dragsource) {
- DEBUG("xdnd drag position from unexpected source (%x not %x)", e->data.data32[0], xdnd_dragsource);
+ if (Q_UNLIKELY(e->data.data32[0] != xdnd_dragsource)) {
+ qCDebug(lcQpaXDnd, "xdnd drag position from unexpected source (%x not %x)",
+ e->data.data32[0], xdnd_dragsource);
return;
}
@@ -741,10 +721,19 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
supported_actions = Qt::DropActions(toDropAction(e->data.data32[4]));
}
- QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(w->window(),dropData,p,supported_actions);
+ auto buttons = currentDrag() ? b : connection()->queryMouseButtons();
+ auto modifiers = currentDrag() ? mods : connection()->queryKeyboardModifiers();
+
+ QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(
+ w->window(), dropData, p, supported_actions, buttons, modifiers);
+
+ // ### FIXME ? - answerRect appears to be unused.
QRect answerRect(p + geometry.topLeft(), QSize(1,1));
answerRect = qt_response.answerRect().translated(geometry.topLeft()).intersected(geometry);
+ // The target sends a ClientMessage of type XdndStatus. This tells the source whether or not
+ // it will accept the drop, and, if so, what action will be taken. It also includes a rectangle
+ // that means "don't send another XdndPosition message until the mouse moves out of here".
xcb_client_message_event_t response;
response.response_type = XCB_CLIENT_MESSAGE;
response.sequence = 0;
@@ -775,13 +764,15 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
// reset
target_time = XCB_CURRENT_TIME;
+ qCDebug(lcQpaXDnd) << "sending XdndStatus to source:" << xdnd_dragsource;
+
#ifndef QT_NO_CLIPBOARD
if (xdnd_dragsource == connection()->clipboard()->owner())
handle_xdnd_status(&response);
else
#endif
- xcb_send_event(xcb_connection(), false, current_proxy_target,
- XCB_EVENT_MASK_NO_EVENT, (const char *)&response);
+ xcb_send_event(xcb_connection(), false, current_proxy_target,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&response);
}
namespace
@@ -790,12 +781,11 @@ namespace
public:
ClientMessageScanner(xcb_atom_t a) : atom(a) {}
xcb_atom_t atom;
- bool checkEvent(xcb_generic_event_t *event) const {
- if (!event)
- return false;
- if ((event->response_type & 0x7f) != XCB_CLIENT_MESSAGE)
+ bool operator() (xcb_generic_event_t *event, int type) const {
+ if (type != XCB_CLIENT_MESSAGE)
return false;
- return ((xcb_client_message_event_t *)event)->type == atom;
+ auto clientMessage = reinterpret_cast<xcb_client_message_event_t *>(event);
+ return clientMessage->type == atom;
}
};
}
@@ -803,12 +793,11 @@ namespace
void QXcbDrag::handlePosition(QPlatformWindow * w, const xcb_client_message_event_t *event)
{
xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
- xcb_generic_event_t *nextEvent;
ClientMessageScanner scanner(atom(QXcbAtom::XdndPosition));
- while ((nextEvent = connection()->checkEvent(scanner))) {
+ while (auto nextEvent = connection()->checkEvent(scanner)) {
if (lastEvent != event)
free(lastEvent);
- lastEvent = (xcb_client_message_event_t *)nextEvent;
+ lastEvent = reinterpret_cast<xcb_client_message_event_t *>(nextEvent);
}
handle_xdnd_position(w, lastEvent);
@@ -818,7 +807,9 @@ void QXcbDrag::handlePosition(QPlatformWindow * w, const xcb_client_message_even
void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event)
{
- DEBUG("xdndHandleStatus");
+ // The source receives XdndStatus. It can use the action to change the cursor to indicate
+ // whether or not the user's requested action will be performed.
+ qCDebug(lcQpaXDnd) << "source:" << event->window << "received XdndStatus";
waiting_for_status = false;
// ignore late status messages
if (event->data.data32[0] && event->data.data32[0] != current_target)
@@ -864,12 +855,13 @@ void QXcbDrag::handleStatus(const xcb_client_message_event_t *event)
handle_xdnd_status(lastEvent);
if (lastEvent != event)
free(lastEvent);
- DEBUG("xdndHandleStatus end");
}
void QXcbDrag::handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event)
{
- DEBUG("xdnd leave");
+ // If the target receives XdndLeave, it frees any cached data and forgets the whole incident.
+ qCDebug(lcQpaXDnd) << "target:" << event->window << "received XdndLeave";
+
if (!currentWindow || w != currentWindow.data()->handle())
return; // sanity
@@ -882,22 +874,19 @@ void QXcbDrag::handleLeave(QPlatformWindow *w, const xcb_client_message_event_t
if (event->data.data32[0] != xdnd_dragsource) {
// This often happens - leave other-process window quickly
- DEBUG("xdnd drag leave from unexpected source (%x not %x", event->data.data32[0], xdnd_dragsource);
+ qCDebug(lcQpaXDnd, "xdnd drag leave from unexpected source (%x not %x",
+ event->data.data32[0], xdnd_dragsource);
}
- QWindowSystemInterface::handleDrag(w->window(),0,QPoint(),Qt::IgnoreAction);
-
- xdnd_dragsource = 0;
- xdnd_types.clear();
- currentWindow.clear();
+ QWindowSystemInterface::handleDrag(w->window(), nullptr, QPoint(), Qt::IgnoreAction, 0, 0);
}
void QXcbDrag::send_leave()
{
+ // XdndLeave is sent from the source to the target to cancel the drop.
if (!current_target)
return;
-
xcb_client_message_event_t leave;
leave.response_type = XCB_CLIENT_MESSAGE;
leave.sequence = 0;
@@ -919,21 +908,21 @@ void QXcbDrag::send_leave()
if (w && (w->window()->type() == Qt::Desktop) /*&& !w->acceptDrops()*/)
w = 0;
+ qCDebug(lcQpaXDnd) << "sending XdndLeave to target:" << current_target;
+
if (w)
handleLeave(w, (const xcb_client_message_event_t *)&leave);
else
xcb_send_event(xcb_connection(), false,current_proxy_target,
XCB_EVENT_MASK_NO_EVENT, (const char *)&leave);
-
- current_target = 0;
- current_proxy_target = 0;
- source_time = XCB_CURRENT_TIME;
- waiting_for_status = false;
}
-void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event)
+void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event,
+ Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
- DEBUG("xdndHandleDrop");
+ // Target receives XdndDrop. Once it is finished processing the drop, it sends XdndFinished.
+ qCDebug(lcQpaXDnd) << "target:" << event->window << "received XdndDrop";
+
if (!currentWindow) {
xdnd_dragsource = 0;
return; // sanity
@@ -941,16 +930,14 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
const uint32_t *l = event->data.data32;
- DEBUG("xdnd drop");
-
if (l[0] != xdnd_dragsource) {
- DEBUG("xdnd drop from unexpected source (%x not %x", l[0], xdnd_dragsource);
+ qCDebug(lcQpaXDnd, "xdnd drop from unexpected source (%x not %x", l[0], xdnd_dragsource);
return;
}
// update the "user time" from the timestamp in the event.
if (l[2] != 0)
- target_time = /*X11->userTime =*/ l[2];
+ target_time = l[2];
Qt::DropActions supported_drop_actions;
QMimeData *dropData = 0;
@@ -960,9 +947,6 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
} else {
dropData = m_dropData;
supported_drop_actions = accepted_drop_action;
-
- // Drop coming from another app? Update keyboard modifiers.
- QGuiApplicationPrivate::modifier_buttons = QGuiApplication::queryKeyboardModifiers();
}
if (!dropData)
@@ -973,7 +957,13 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
// dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
// if we can't find it, then use the data in the drag manager
- QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(currentWindow.data(),dropData,currentPosition,supported_drop_actions);
+ auto buttons = currentDrag() ? b : connection()->queryMouseButtons();
+ auto modifiers = currentDrag() ? mods : connection()->queryKeyboardModifiers();
+
+ QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(
+ currentWindow.data(), dropData, currentPosition, supported_drop_actions,
+ buttons, modifiers);
+
setExecutedDropAction(response.acceptedAction());
xcb_client_message_event_t finished;
@@ -985,34 +975,26 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
finished.data.data32[0] = currentWindow ? xcb_window(currentWindow.data()) : XCB_NONE;
finished.data.data32[1] = response.isAccepted(); // flags
finished.data.data32[2] = toXdndAction(response.acceptedAction());
- xcb_send_event(xcb_connection(), false, current_proxy_target,
- XCB_EVENT_MASK_NO_EVENT, (char *)&finished);
- xdnd_dragsource = 0;
- currentWindow.clear();
- waiting_for_status = false;
+ qCDebug(lcQpaXDnd) << "sending XdndFinished to source:" << xdnd_dragsource;
- // reset
- target_time = XCB_CURRENT_TIME;
+ xcb_send_event(xcb_connection(), false, current_proxy_target,
+ XCB_EVENT_MASK_NO_EVENT, (char *)&finished);
dropped = true;
}
-
void QXcbDrag::handleFinished(const xcb_client_message_event_t *event)
{
- DEBUG("xdndHandleFinished");
+ // Source receives XdndFinished when target is done processing the drop data.
+ qCDebug(lcQpaXDnd) << "source:" << event->window << "received XdndFinished";
+
#ifndef QT_NO_CLIPBOARD
if (event->window != connection()->clipboard()->owner())
return;
#endif
const unsigned long *l = (const unsigned long *)event->data.data32;
-
- DNDDEBUG << "xdndHandleFinished, l[0]" << l[0]
- << "current_target" << current_target
- << "qt_xdnd_current_proxy_targe" << current_proxy_target;
-
if (l[0]) {
int at = findTransactionByWindow(l[0]);
if (at != -1) {
@@ -1087,7 +1069,8 @@ void QXcbDrag::timerEvent(QTimerEvent* e)
void QXcbDrag::cancel()
{
- DEBUG("QXcbDrag::cancel");
+ qCDebug(lcQpaXDnd) << "dnd was canceled";
+
QBasicDrag::cancel();
if (current_target)
send_leave();
@@ -1098,7 +1081,6 @@ void QXcbDrag::cancel()
canceled = true;
}
-// find an ancestor with XdndAware on it
static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window)
{
xcb_window_t target = 0;
@@ -1127,7 +1109,8 @@ static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window)
void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
{
- Q_DECLARE_XCB_EVENT(notify, xcb_selection_notify_event_t);
+ qCDebug(lcQpaXDnd) << "handle selection request from target:" << event->requestor;
+ q_padded_xcb_event<xcb_selection_notify_event_t> notify = {};
notify.response_type = XCB_SELECTION_NOTIFY;
notify.requestor = event->requestor;
notify.selection = event->selection;
@@ -1194,10 +1177,10 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
{
- DNDDEBUG << "xdndEnable" << w << on;
+ // Windows announce that they support the XDND protocol by creating a window property XdndAware.
if (on) {
- QXcbWindow *xdnd_widget = 0;
- if ((w->window()->type() == Qt::Desktop)) {
+ QXcbWindow *window = nullptr;
+ if (w->window()->type() == Qt::Desktop) {
if (desktop_proxy) // *WE* already have one.
return false;
@@ -1208,8 +1191,8 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
if (!proxy_id) {
desktop_proxy = new QWindow;
- xdnd_widget = static_cast<QXcbWindow *>(desktop_proxy->handle());
- proxy_id = xdnd_widget->xcb_window();
+ window = static_cast<QXcbWindow *>(desktop_proxy->handle());
+ proxy_id = window->xcb_window();
xcb_atom_t xdnd_proxy = atom(QXcbAtom::XdndProxy);
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, w->xcb_window(), xdnd_proxy,
XCB_ATOM_WINDOW, 32, 1, &proxy_id);
@@ -1218,24 +1201,24 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
}
} else {
- xdnd_widget = w;
+ window = w;
}
- if (xdnd_widget) {
- DNDDEBUG << "setting XdndAware for" << xdnd_widget << xdnd_widget->xcb_window();
+ if (window) {
+ qCDebug(lcQpaXDnd) << "setting XdndAware for" << window->xcb_window();
xcb_atom_t atm = xdnd_version;
- xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, xdnd_widget->xcb_window(),
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window->xcb_window(),
atom(QXcbAtom::XdndAware), XCB_ATOM_ATOM, 32, 1, &atm);
return true;
} else {
return false;
}
} else {
- if ((w->window()->type() == Qt::Desktop)) {
+ if (w->window()->type() == Qt::Desktop) {
xcb_delete_property(xcb_connection(), w->xcb_window(), atom(QXcbAtom::XdndProxy));
delete desktop_proxy;
desktop_proxy = 0;
} else {
- DNDDEBUG << "not deleting XDndAware";
+ qCDebug(lcQpaXDnd) << "not deleting XDndAware";
}
return true;
}
@@ -1293,7 +1276,6 @@ QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QVariant::Type r
return mimeConvertToFormat(c, a, result, QLatin1String(format), requestedType, encoding);
}
-
bool QXcbDropData::hasFormat_sys(const QString &format) const
{
return formats().contains(format);
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 60287b717b..c19008c04b 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -78,14 +78,15 @@ public:
void startDrag() override;
void cancel() override;
- void move(const QPoint &globalPos) override;
- void drop(const QPoint &globalPos) override;
+ void move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override;
+ void drop(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override;
void endDrag() override;
void handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event, xcb_window_t proxy = 0);
void handlePosition(QPlatformWindow *w, const xcb_client_message_event_t *event);
void handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event);
- void handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event);
+ void handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event,
+ Qt::MouseButtons b = 0, Qt::KeyboardModifiers mods = 0);
void handleStatus(const xcb_client_message_event_t *event);
void handleSelectionRequest(const xcb_selection_request_event_t *event);
@@ -100,12 +101,15 @@ public:
protected:
void timerEvent(QTimerEvent* e) override;
+ bool findXdndAwareTarget(const QPoint &globalPos, xcb_window_t *target_out);
+
private:
friend class QXcbDropData;
void init();
- void handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *event);
+ void handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *event,
+ Qt::MouseButtons b = 0, Qt::KeyboardModifiers mods = 0);
void handle_xdnd_status(const xcb_client_message_event_t *event);
void send_leave();
@@ -139,6 +143,9 @@ private:
bool dropped;
bool canceled;
+ // A window from Unity DnD Manager, which does not respect the XDnD spec
+ xcb_window_t xdndCollectionWindow = XCB_NONE;
+
// top-level window we sent position to last.
xcb_window_t current_target;
// window to send events to (always valid if current_target)
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index bf9eaacbb8..1ac5445035 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -69,12 +69,12 @@
#define register /* C++17 deprecated register */
#include <X11/Xlib.h>
#undef register
+#endif
#if QT_CONFIG(xcb_native_painting)
#include "qxcbnativepainting.h"
#include "qpixmap_x11_p.h"
#include "qbackingstore_x11_p.h"
#endif
-#endif
#include <qpa/qplatforminputcontextfactory_p.h>
#include <private/qgenericunixthemes_p.h>
@@ -192,25 +192,15 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
const int numParameters = parameters.size();
m_connections.reserve(1 + numParameters / 2);
- auto conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName);
- if (conn->isConnected())
- m_connections << conn;
- else
- delete conn;
-
- for (int i = 0; i < numParameters - 1; i += 2) {
- qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
- QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
- conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData());
- if (conn->isConnected())
- m_connections << conn;
- else
- delete conn;
- }
- if (m_connections.isEmpty()) {
- qCritical("Could not connect to any X display.");
- exit(1);
+ if (QXcbConnection *defaultConnection = QXcbConnection::create(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName)) {
+ m_connections.append(defaultConnection);
+ for (int i = 0; i < numParameters - 1; i += 2) {
+ qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
+ QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1);
+ if (QXcbConnection *connection = QXcbConnection::create(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()))
+ m_connections.append(connection);
+ }
}
m_fontDatabase.reset(new QGenericUnixFontDatabase());
@@ -243,7 +233,8 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
{
QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle());
QXcbGlIntegration *glIntegration = screen->connection()->glIntegration();
- if (window->type() != Qt::Desktop) {
+ const bool isTrayIconWindow = window->objectName() == QLatin1String("QSystemTrayIconSysWindow");
+ if (window->type() != Qt::Desktop && !isTrayIconWindow) {
if (window->supportsOpenGL()) {
if (glIntegration) {
QXcbWindow *xcbWindow = glIntegration->createWindow(window);
@@ -259,7 +250,7 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
}
}
- Q_ASSERT(window->type() == Qt::Desktop || !window->supportsOpenGL()
+ Q_ASSERT(window->type() == Qt::Desktop || isTrayIconWindow || !window->supportsOpenGL()
|| (!glIntegration && window->surfaceType() == QSurface::RasterGLSurface)); // for VNC
QXcbWindow *xcbWindow = new QXcbWindow(window);
xcbWindow->create();
@@ -286,6 +277,10 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont
QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *window) const
{
+ const bool isTrayIconWindow = window->objectName() == QLatin1String("QSystemTrayIconSysWindow");
+ if (isTrayIconWindow)
+ return new QXcbSystemTrayBackingStore(window);
+
#if QT_CONFIG(xcb_native_painting)
if (nativePaintingEnabled())
return new QXcbNativeBackingStore(window);
@@ -381,8 +376,17 @@ QPlatformClipboard *QXcbIntegration::clipboard() const
#endif
#if QT_CONFIG(draganddrop)
+#include <private/qsimpledrag_p.h>
QPlatformDrag *QXcbIntegration::drag() const
{
+ static const bool useSimpleDrag = qEnvironmentVariableIsSet("QT_XCB_USE_SIMPLE_DRAG");
+ if (Q_UNLIKELY(useSimpleDrag)) { // This is useful for testing purposes
+ static QSimpleDrag *simpleDrag = nullptr;
+ if (!simpleDrag)
+ simpleDrag = new QSimpleDrag();
+ return simpleDrag;
+ }
+
return m_connections.at(0)->drag();
}
#endif
@@ -414,10 +418,7 @@ QPlatformServices *QXcbIntegration::services() const
Qt::KeyboardModifiers QXcbIntegration::queryKeyboardModifiers() const
{
- int keybMask = 0;
- QXcbConnection *conn = m_connections.at(0);
- QXcbCursor::queryPointer(conn, 0, 0, &keybMask);
- return conn->keyboard()->translateModifiers(keybMask);
+ return m_connections.at(0)->queryKeyboardModifiers();
}
QList<int> QXcbIntegration::possibleKeys(const QKeyEvent *e) const
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 69e49cb7f6..a2de22d53d 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -103,6 +103,7 @@ public:
QPlatformTheme *createPlatformTheme(const QString &name) const override;
QVariant styleHint(StyleHint hint) const override;
+ bool hasDefaultConnection() const { return !m_connections.isEmpty(); }
QXcbConnection *defaultConnection() const { return m_connections.first(); }
QByteArray wmClass() const;
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 3733995a0d..20c169fc53 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -49,366 +49,388 @@
#include <QtCore/QMetaEnum>
#include <private/qguiapplication_p.h>
+#include <private/qmakearray_p.h>
#include <xkbcommon/xkbcommon-keysyms.h>
-#if QT_CONFIG(xinput2)
-#include <X11/extensions/XI2proto.h>
-#undef KeyPress
-#undef KeyRelease
+#if QT_CONFIG(xcb_xinput)
+#include <xcb/xinput.h>
#endif
QT_BEGIN_NAMESPACE
-static const unsigned int KeyTbl[] = {
- // misc keys
-
- XKB_KEY_Escape, Qt::Key_Escape,
- XKB_KEY_Tab, Qt::Key_Tab,
- XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab,
- XKB_KEY_BackSpace, Qt::Key_Backspace,
- XKB_KEY_Return, Qt::Key_Return,
- XKB_KEY_Insert, Qt::Key_Insert,
- XKB_KEY_Delete, Qt::Key_Delete,
- XKB_KEY_Clear, Qt::Key_Delete,
- XKB_KEY_Pause, Qt::Key_Pause,
- XKB_KEY_Print, Qt::Key_Print,
- 0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq
- 0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq
-
- // cursor movement
-
- XKB_KEY_Home, Qt::Key_Home,
- XKB_KEY_End, Qt::Key_End,
- XKB_KEY_Left, Qt::Key_Left,
- XKB_KEY_Up, Qt::Key_Up,
- XKB_KEY_Right, Qt::Key_Right,
- XKB_KEY_Down, Qt::Key_Down,
- XKB_KEY_Prior, Qt::Key_PageUp,
- XKB_KEY_Next, Qt::Key_PageDown,
-
- // modifiers
-
- XKB_KEY_Shift_L, Qt::Key_Shift,
- XKB_KEY_Shift_R, Qt::Key_Shift,
- XKB_KEY_Shift_Lock, Qt::Key_Shift,
- XKB_KEY_Control_L, Qt::Key_Control,
- XKB_KEY_Control_R, Qt::Key_Control,
- XKB_KEY_Meta_L, Qt::Key_Meta,
- XKB_KEY_Meta_R, Qt::Key_Meta,
- XKB_KEY_Alt_L, Qt::Key_Alt,
- XKB_KEY_Alt_R, Qt::Key_Alt,
- XKB_KEY_Caps_Lock, Qt::Key_CapsLock,
- XKB_KEY_Num_Lock, Qt::Key_NumLock,
- XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock,
- XKB_KEY_Super_L, Qt::Key_Super_L,
- XKB_KEY_Super_R, Qt::Key_Super_R,
- XKB_KEY_Menu, Qt::Key_Menu,
- XKB_KEY_Hyper_L, Qt::Key_Hyper_L,
- XKB_KEY_Hyper_R, Qt::Key_Hyper_R,
- XKB_KEY_Help, Qt::Key_Help,
- 0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab
- 0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11)
- 0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12)
-
- // numeric and function keypad keys
-
- XKB_KEY_KP_Space, Qt::Key_Space,
- XKB_KEY_KP_Tab, Qt::Key_Tab,
- XKB_KEY_KP_Enter, Qt::Key_Enter,
- //XKB_KEY_KP_F1, Qt::Key_F1,
- //XKB_KEY_KP_F2, Qt::Key_F2,
- //XKB_KEY_KP_F3, Qt::Key_F3,
- //XKB_KEY_KP_F4, Qt::Key_F4,
- XKB_KEY_KP_Home, Qt::Key_Home,
- XKB_KEY_KP_Left, Qt::Key_Left,
- XKB_KEY_KP_Up, Qt::Key_Up,
- XKB_KEY_KP_Right, Qt::Key_Right,
- XKB_KEY_KP_Down, Qt::Key_Down,
- XKB_KEY_KP_Prior, Qt::Key_PageUp,
- XKB_KEY_KP_Next, Qt::Key_PageDown,
- XKB_KEY_KP_End, Qt::Key_End,
- XKB_KEY_KP_Begin, Qt::Key_Clear,
- XKB_KEY_KP_Insert, Qt::Key_Insert,
- XKB_KEY_KP_Delete, Qt::Key_Delete,
- XKB_KEY_KP_Equal, Qt::Key_Equal,
- XKB_KEY_KP_Multiply, Qt::Key_Asterisk,
- XKB_KEY_KP_Add, Qt::Key_Plus,
- XKB_KEY_KP_Separator, Qt::Key_Comma,
- XKB_KEY_KP_Subtract, Qt::Key_Minus,
- XKB_KEY_KP_Decimal, Qt::Key_Period,
- XKB_KEY_KP_Divide, Qt::Key_Slash,
-
- // special non-XF86 function keys
-
- XKB_KEY_Undo, Qt::Key_Undo,
- XKB_KEY_Redo, Qt::Key_Redo,
- XKB_KEY_Find, Qt::Key_Find,
- XKB_KEY_Cancel, Qt::Key_Cancel,
-
- // International input method support keys
-
- // International & multi-key character composition
- XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr,
- XKB_KEY_Multi_key, Qt::Key_Multi_key,
- XKB_KEY_Codeinput, Qt::Key_Codeinput,
- XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate,
- XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate,
- XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate,
-
- // Misc Functions
- XKB_KEY_Mode_switch, Qt::Key_Mode_switch,
- XKB_KEY_script_switch, Qt::Key_Mode_switch,
-
- // Japanese keyboard support
- XKB_KEY_Kanji, Qt::Key_Kanji,
- XKB_KEY_Muhenkan, Qt::Key_Muhenkan,
- //XKB_KEY_Henkan_Mode, Qt::Key_Henkan_Mode,
- XKB_KEY_Henkan_Mode, Qt::Key_Henkan,
- XKB_KEY_Henkan, Qt::Key_Henkan,
- XKB_KEY_Romaji, Qt::Key_Romaji,
- XKB_KEY_Hiragana, Qt::Key_Hiragana,
- XKB_KEY_Katakana, Qt::Key_Katakana,
- XKB_KEY_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
- XKB_KEY_Zenkaku, Qt::Key_Zenkaku,
- XKB_KEY_Hankaku, Qt::Key_Hankaku,
- XKB_KEY_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
- XKB_KEY_Touroku, Qt::Key_Touroku,
- XKB_KEY_Massyo, Qt::Key_Massyo,
- XKB_KEY_Kana_Lock, Qt::Key_Kana_Lock,
- XKB_KEY_Kana_Shift, Qt::Key_Kana_Shift,
- XKB_KEY_Eisu_Shift, Qt::Key_Eisu_Shift,
- XKB_KEY_Eisu_toggle, Qt::Key_Eisu_toggle,
- //XKB_KEY_Kanji_Bangou, Qt::Key_Kanji_Bangou,
- //XKB_KEY_Zen_Koho, Qt::Key_Zen_Koho,
- //XKB_KEY_Mae_Koho, Qt::Key_Mae_Koho,
- XKB_KEY_Kanji_Bangou, Qt::Key_Codeinput,
- XKB_KEY_Zen_Koho, Qt::Key_MultipleCandidate,
- XKB_KEY_Mae_Koho, Qt::Key_PreviousCandidate,
-
- // Korean keyboard support
- XKB_KEY_Hangul, Qt::Key_Hangul,
- XKB_KEY_Hangul_Start, Qt::Key_Hangul_Start,
- XKB_KEY_Hangul_End, Qt::Key_Hangul_End,
- XKB_KEY_Hangul_Hanja, Qt::Key_Hangul_Hanja,
- XKB_KEY_Hangul_Jamo, Qt::Key_Hangul_Jamo,
- XKB_KEY_Hangul_Romaja, Qt::Key_Hangul_Romaja,
- //XKB_KEY_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
- XKB_KEY_Hangul_Codeinput, Qt::Key_Codeinput,
- XKB_KEY_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
- XKB_KEY_Hangul_Banja, Qt::Key_Hangul_Banja,
- XKB_KEY_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
- XKB_KEY_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
- //XKB_KEY_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
- //XKB_KEY_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
- //XKB_KEY_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
- XKB_KEY_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
- XKB_KEY_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
- XKB_KEY_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
- XKB_KEY_Hangul_Special, Qt::Key_Hangul_Special,
- //XKB_KEY_Hangul_switch, Qt::Key_Hangul_switch,
- XKB_KEY_Hangul_switch, Qt::Key_Mode_switch,
-
- // dead keys
- XKB_KEY_dead_grave, Qt::Key_Dead_Grave,
- XKB_KEY_dead_acute, Qt::Key_Dead_Acute,
- XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex,
- XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde,
- XKB_KEY_dead_macron, Qt::Key_Dead_Macron,
- XKB_KEY_dead_breve, Qt::Key_Dead_Breve,
- XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot,
- XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis,
- XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering,
- XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute,
- XKB_KEY_dead_caron, Qt::Key_Dead_Caron,
- XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla,
- XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek,
- XKB_KEY_dead_iota, Qt::Key_Dead_Iota,
- XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound,
- XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound,
- XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot,
- XKB_KEY_dead_hook, Qt::Key_Dead_Hook,
- XKB_KEY_dead_horn, Qt::Key_Dead_Horn,
- XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke,
- XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma,
- XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma,
- XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave,
- XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring,
- XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron,
- XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex,
- XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde,
- XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve,
- XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis,
- XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve,
- XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma,
- XKB_KEY_dead_currency, Qt::Key_Dead_Currency,
- XKB_KEY_dead_a, Qt::Key_Dead_a,
- XKB_KEY_dead_A, Qt::Key_Dead_A,
- XKB_KEY_dead_e, Qt::Key_Dead_e,
- XKB_KEY_dead_E, Qt::Key_Dead_E,
- XKB_KEY_dead_i, Qt::Key_Dead_i,
- XKB_KEY_dead_I, Qt::Key_Dead_I,
- XKB_KEY_dead_o, Qt::Key_Dead_o,
- XKB_KEY_dead_O, Qt::Key_Dead_O,
- XKB_KEY_dead_u, Qt::Key_Dead_u,
- XKB_KEY_dead_U, Qt::Key_Dead_U,
- XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa,
- XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa,
- XKB_KEY_dead_greek, Qt::Key_Dead_Greek,
- XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline,
- XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline,
- XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline,
- XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay,
-
- // Special keys from X.org - This include multimedia keys,
- // wireless/bluetooth/uwb keys, special launcher keys, etc.
- XKB_KEY_XF86Back, Qt::Key_Back,
- XKB_KEY_XF86Forward, Qt::Key_Forward,
- XKB_KEY_XF86Stop, Qt::Key_Stop,
- XKB_KEY_XF86Refresh, Qt::Key_Refresh,
- XKB_KEY_XF86Favorites, Qt::Key_Favorites,
- XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia,
- XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl,
- XKB_KEY_XF86HomePage, Qt::Key_HomePage,
- XKB_KEY_XF86Search, Qt::Key_Search,
- XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown,
- XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute,
- XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp,
- XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay,
- XKB_KEY_XF86AudioStop, Qt::Key_MediaStop,
- XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious,
- XKB_KEY_XF86AudioNext, Qt::Key_MediaNext,
- XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord,
- XKB_KEY_XF86AudioPause, Qt::Key_MediaPause,
- XKB_KEY_XF86Mail, Qt::Key_LaunchMail,
- XKB_KEY_XF86MyComputer, Qt::Key_Launch0, // ### Qt 6: remap properly
- XKB_KEY_XF86Calculator, Qt::Key_Launch1,
- XKB_KEY_XF86Memo, Qt::Key_Memo,
- XKB_KEY_XF86ToDoList, Qt::Key_ToDoList,
- XKB_KEY_XF86Calendar, Qt::Key_Calendar,
- XKB_KEY_XF86PowerDown, Qt::Key_PowerDown,
- XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust,
- XKB_KEY_XF86Standby, Qt::Key_Standby,
- XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp,
- XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown,
- XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff,
- XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp,
- XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown,
- XKB_KEY_XF86PowerOff, Qt::Key_PowerOff,
- XKB_KEY_XF86WakeUp, Qt::Key_WakeUp,
- XKB_KEY_XF86Eject, Qt::Key_Eject,
- XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver,
- XKB_KEY_XF86WWW, Qt::Key_WWW,
- XKB_KEY_XF86Sleep, Qt::Key_Sleep,
- XKB_KEY_XF86LightBulb, Qt::Key_LightBulb,
- XKB_KEY_XF86Shop, Qt::Key_Shop,
- XKB_KEY_XF86History, Qt::Key_History,
- XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite,
- XKB_KEY_XF86HotLinks, Qt::Key_HotLinks,
- XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust,
- XKB_KEY_XF86Finance, Qt::Key_Finance,
- XKB_KEY_XF86Community, Qt::Key_Community,
- XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind,
- XKB_KEY_XF86BackForward, Qt::Key_BackForward,
- XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft,
- XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight,
- XKB_KEY_XF86Book, Qt::Key_Book,
- XKB_KEY_XF86CD, Qt::Key_CD,
- XKB_KEY_XF86Calculater, Qt::Key_Calculator,
- XKB_KEY_XF86Clear, Qt::Key_Clear,
- XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab,
- XKB_KEY_XF86Close, Qt::Key_Close,
- XKB_KEY_XF86Copy, Qt::Key_Copy,
- XKB_KEY_XF86Cut, Qt::Key_Cut,
- XKB_KEY_XF86Display, Qt::Key_Display,
- XKB_KEY_XF86DOS, Qt::Key_DOS,
- XKB_KEY_XF86Documents, Qt::Key_Documents,
- XKB_KEY_XF86Excel, Qt::Key_Excel,
- XKB_KEY_XF86Explorer, Qt::Key_Explorer,
- XKB_KEY_XF86Game, Qt::Key_Game,
- XKB_KEY_XF86Go, Qt::Key_Go,
- XKB_KEY_XF86iTouch, Qt::Key_iTouch,
- XKB_KEY_XF86LogOff, Qt::Key_LogOff,
- XKB_KEY_XF86Market, Qt::Key_Market,
- XKB_KEY_XF86Meeting, Qt::Key_Meeting,
- XKB_KEY_XF86MenuKB, Qt::Key_MenuKB,
- XKB_KEY_XF86MenuPB, Qt::Key_MenuPB,
- XKB_KEY_XF86MySites, Qt::Key_MySites,
- XKB_KEY_XF86New, Qt::Key_New,
- XKB_KEY_XF86News, Qt::Key_News,
- XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome,
- XKB_KEY_XF86Open, Qt::Key_Open,
- XKB_KEY_XF86Option, Qt::Key_Option,
- XKB_KEY_XF86Paste, Qt::Key_Paste,
- XKB_KEY_XF86Phone, Qt::Key_Phone,
- XKB_KEY_XF86Reply, Qt::Key_Reply,
- XKB_KEY_XF86Reload, Qt::Key_Reload,
- XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows,
- XKB_KEY_XF86RotationPB, Qt::Key_RotationPB,
- XKB_KEY_XF86RotationKB, Qt::Key_RotationKB,
- XKB_KEY_XF86Save, Qt::Key_Save,
- XKB_KEY_XF86Send, Qt::Key_Send,
- XKB_KEY_XF86Spell, Qt::Key_Spell,
- XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen,
- XKB_KEY_XF86Support, Qt::Key_Support,
- XKB_KEY_XF86TaskPane, Qt::Key_TaskPane,
- XKB_KEY_XF86Terminal, Qt::Key_Terminal,
- XKB_KEY_XF86Tools, Qt::Key_Tools,
- XKB_KEY_XF86Travel, Qt::Key_Travel,
- XKB_KEY_XF86Video, Qt::Key_Video,
- XKB_KEY_XF86Word, Qt::Key_Word,
- XKB_KEY_XF86Xfer, Qt::Key_Xfer,
- XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn,
- XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut,
- XKB_KEY_XF86Away, Qt::Key_Away,
- XKB_KEY_XF86Messenger, Qt::Key_Messenger,
- XKB_KEY_XF86WebCam, Qt::Key_WebCam,
- XKB_KEY_XF86MailForward, Qt::Key_MailForward,
- XKB_KEY_XF86Pictures, Qt::Key_Pictures,
- XKB_KEY_XF86Music, Qt::Key_Music,
- XKB_KEY_XF86Battery, Qt::Key_Battery,
- XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth,
- XKB_KEY_XF86WLAN, Qt::Key_WLAN,
- XKB_KEY_XF86UWB, Qt::Key_UWB,
- XKB_KEY_XF86AudioForward, Qt::Key_AudioForward,
- XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat,
- XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay,
- XKB_KEY_XF86Subtitle, Qt::Key_Subtitle,
- XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack,
- XKB_KEY_XF86Time, Qt::Key_Time,
- XKB_KEY_XF86Select, Qt::Key_Select,
- XKB_KEY_XF86View, Qt::Key_View,
- XKB_KEY_XF86TopMenu, Qt::Key_TopMenu,
- XKB_KEY_XF86Red, Qt::Key_Red,
- XKB_KEY_XF86Green, Qt::Key_Green,
- XKB_KEY_XF86Yellow, Qt::Key_Yellow,
- XKB_KEY_XF86Blue, Qt::Key_Blue,
- XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth,
- XKB_KEY_XF86Suspend, Qt::Key_Suspend,
- XKB_KEY_XF86Hibernate, Qt::Key_Hibernate,
- XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle,
- XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn,
- XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff,
- XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute,
- XKB_KEY_XF86Launch0, Qt::Key_Launch2, // ### Qt 6: remap properly
- XKB_KEY_XF86Launch1, Qt::Key_Launch3,
- XKB_KEY_XF86Launch2, Qt::Key_Launch4,
- XKB_KEY_XF86Launch3, Qt::Key_Launch5,
- XKB_KEY_XF86Launch4, Qt::Key_Launch6,
- XKB_KEY_XF86Launch5, Qt::Key_Launch7,
- XKB_KEY_XF86Launch6, Qt::Key_Launch8,
- XKB_KEY_XF86Launch7, Qt::Key_Launch9,
- XKB_KEY_XF86Launch8, Qt::Key_LaunchA,
- XKB_KEY_XF86Launch9, Qt::Key_LaunchB,
- XKB_KEY_XF86LaunchA, Qt::Key_LaunchC,
- XKB_KEY_XF86LaunchB, Qt::Key_LaunchD,
- XKB_KEY_XF86LaunchC, Qt::Key_LaunchE,
- XKB_KEY_XF86LaunchD, Qt::Key_LaunchF,
- XKB_KEY_XF86LaunchE, Qt::Key_LaunchG,
- XKB_KEY_XF86LaunchF, Qt::Key_LaunchH,
-
- 0, 0
+typedef struct xkb2qt
+{
+ unsigned int xkb;
+ unsigned int qt;
+
+ constexpr bool operator <=(const xkb2qt &that) const noexcept
+ {
+ return xkb <= that.xkb;
+ }
+
+ constexpr bool operator <(const xkb2qt &that) const noexcept
+ {
+ return xkb < that.xkb;
+ }
+} xkb2qt_t;
+
+template<std::size_t Xkb, std::size_t Qt>
+struct Xkb2Qt
+{
+ using Type = xkb2qt_t;
+ static constexpr Type data() noexcept { return Type{Xkb, Qt}; }
};
+static constexpr const auto KeyTbl = qMakeArray(
+ QSortedData<
+ // misc keys
+
+ Xkb2Qt<XKB_KEY_Escape, Qt::Key_Escape>,
+ Xkb2Qt<XKB_KEY_Tab, Qt::Key_Tab>,
+ Xkb2Qt<XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab>,
+ Xkb2Qt<XKB_KEY_BackSpace, Qt::Key_Backspace>,
+ Xkb2Qt<XKB_KEY_Return, Qt::Key_Return>,
+ Xkb2Qt<XKB_KEY_Insert, Qt::Key_Insert>,
+ Xkb2Qt<XKB_KEY_Delete, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
+
+ // cursor movement
+
+ Xkb2Qt<XKB_KEY_Home, Qt::Key_Home>,
+ Xkb2Qt<XKB_KEY_End, Qt::Key_End>,
+ Xkb2Qt<XKB_KEY_Left, Qt::Key_Left>,
+ Xkb2Qt<XKB_KEY_Up, Qt::Key_Up>,
+ Xkb2Qt<XKB_KEY_Right, Qt::Key_Right>,
+ Xkb2Qt<XKB_KEY_Down, Qt::Key_Down>,
+ Xkb2Qt<XKB_KEY_Prior, Qt::Key_PageUp>,
+ Xkb2Qt<XKB_KEY_Next, Qt::Key_PageDown>,
+
+ // modifiers
+
+ Xkb2Qt<XKB_KEY_Shift_L, Qt::Key_Shift>,
+ Xkb2Qt<XKB_KEY_Shift_R, Qt::Key_Shift>,
+ Xkb2Qt<XKB_KEY_Shift_Lock, Qt::Key_Shift>,
+ Xkb2Qt<XKB_KEY_Control_L, Qt::Key_Control>,
+ Xkb2Qt<XKB_KEY_Control_R, Qt::Key_Control>,
+ Xkb2Qt<XKB_KEY_Meta_L, Qt::Key_Meta>,
+ Xkb2Qt<XKB_KEY_Meta_R, Qt::Key_Meta>,
+ Xkb2Qt<XKB_KEY_Alt_L, Qt::Key_Alt>,
+ Xkb2Qt<XKB_KEY_Alt_R, Qt::Key_Alt>,
+ Xkb2Qt<XKB_KEY_Caps_Lock, Qt::Key_CapsLock>,
+ Xkb2Qt<XKB_KEY_Num_Lock, Qt::Key_NumLock>,
+ Xkb2Qt<XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock>,
+ Xkb2Qt<XKB_KEY_Super_L, Qt::Key_Super_L>,
+ Xkb2Qt<XKB_KEY_Super_R, Qt::Key_Super_R>,
+ Xkb2Qt<XKB_KEY_Menu, Qt::Key_Menu>,
+ Xkb2Qt<XKB_KEY_Hyper_L, Qt::Key_Hyper_L>,
+ Xkb2Qt<XKB_KEY_Hyper_R, Qt::Key_Hyper_R>,
+ Xkb2Qt<XKB_KEY_Help, Qt::Key_Help>,
+ Xkb2Qt<0x1000FF74, Qt::Key_Backtab>, // hardcoded HP backtab
+ Xkb2Qt<0x1005FF10, Qt::Key_F11>, // hardcoded Sun F36 (labeled F11)
+ Xkb2Qt<0x1005FF11, Qt::Key_F12>, // hardcoded Sun F37 (labeled F12)
+
+ // numeric and function keypad keys
+
+ Xkb2Qt<XKB_KEY_KP_Space, Qt::Key_Space>,
+ Xkb2Qt<XKB_KEY_KP_Tab, Qt::Key_Tab>,
+ Xkb2Qt<XKB_KEY_KP_Enter, Qt::Key_Enter>,
+ //Xkb2Qt<XKB_KEY_KP_F1, Qt::Key_F1>,
+ //Xkb2Qt<XKB_KEY_KP_F2, Qt::Key_F2>,
+ //Xkb2Qt<XKB_KEY_KP_F3, Qt::Key_F3>,
+ //Xkb2Qt<XKB_KEY_KP_F4, Qt::Key_F4>,
+ Xkb2Qt<XKB_KEY_KP_Home, Qt::Key_Home>,
+ Xkb2Qt<XKB_KEY_KP_Left, Qt::Key_Left>,
+ Xkb2Qt<XKB_KEY_KP_Up, Qt::Key_Up>,
+ Xkb2Qt<XKB_KEY_KP_Right, Qt::Key_Right>,
+ Xkb2Qt<XKB_KEY_KP_Down, Qt::Key_Down>,
+ Xkb2Qt<XKB_KEY_KP_Prior, Qt::Key_PageUp>,
+ Xkb2Qt<XKB_KEY_KP_Next, Qt::Key_PageDown>,
+ Xkb2Qt<XKB_KEY_KP_End, Qt::Key_End>,
+ Xkb2Qt<XKB_KEY_KP_Begin, Qt::Key_Clear>,
+ Xkb2Qt<XKB_KEY_KP_Insert, Qt::Key_Insert>,
+ Xkb2Qt<XKB_KEY_KP_Delete, Qt::Key_Delete>,
+ Xkb2Qt<XKB_KEY_KP_Equal, Qt::Key_Equal>,
+ Xkb2Qt<XKB_KEY_KP_Multiply, Qt::Key_Asterisk>,
+ Xkb2Qt<XKB_KEY_KP_Add, Qt::Key_Plus>,
+ Xkb2Qt<XKB_KEY_KP_Separator, Qt::Key_Comma>,
+ Xkb2Qt<XKB_KEY_KP_Subtract, Qt::Key_Minus>,
+ Xkb2Qt<XKB_KEY_KP_Decimal, Qt::Key_Period>,
+ Xkb2Qt<XKB_KEY_KP_Divide, Qt::Key_Slash>,
+
+ // special non-XF86 function keys
+
+ Xkb2Qt<XKB_KEY_Undo, Qt::Key_Undo>,
+ Xkb2Qt<XKB_KEY_Redo, Qt::Key_Redo>,
+ Xkb2Qt<XKB_KEY_Find, Qt::Key_Find>,
+ Xkb2Qt<XKB_KEY_Cancel, Qt::Key_Cancel>,
+
+ // International input method support keys
+
+ // International & multi-key character composition
+ Xkb2Qt<XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr>,
+ Xkb2Qt<XKB_KEY_Multi_key, Qt::Key_Multi_key>,
+ Xkb2Qt<XKB_KEY_Codeinput, Qt::Key_Codeinput>,
+ Xkb2Qt<XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate>,
+ Xkb2Qt<XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate>,
+ Xkb2Qt<XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate>,
+
+ // Misc Functions
+ Xkb2Qt<XKB_KEY_Mode_switch, Qt::Key_Mode_switch>,
+ Xkb2Qt<XKB_KEY_script_switch, Qt::Key_Mode_switch>,
+
+ // Japanese keyboard support
+ Xkb2Qt<XKB_KEY_Kanji, Qt::Key_Kanji>,
+ Xkb2Qt<XKB_KEY_Muhenkan, Qt::Key_Muhenkan>,
+ //Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan_Mode>,
+ Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan>,
+ Xkb2Qt<XKB_KEY_Henkan, Qt::Key_Henkan>,
+ Xkb2Qt<XKB_KEY_Romaji, Qt::Key_Romaji>,
+ Xkb2Qt<XKB_KEY_Hiragana, Qt::Key_Hiragana>,
+ Xkb2Qt<XKB_KEY_Katakana, Qt::Key_Katakana>,
+ Xkb2Qt<XKB_KEY_Hiragana_Katakana, Qt::Key_Hiragana_Katakana>,
+ Xkb2Qt<XKB_KEY_Zenkaku, Qt::Key_Zenkaku>,
+ Xkb2Qt<XKB_KEY_Hankaku, Qt::Key_Hankaku>,
+ Xkb2Qt<XKB_KEY_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku>,
+ Xkb2Qt<XKB_KEY_Touroku, Qt::Key_Touroku>,
+ Xkb2Qt<XKB_KEY_Massyo, Qt::Key_Massyo>,
+ Xkb2Qt<XKB_KEY_Kana_Lock, Qt::Key_Kana_Lock>,
+ Xkb2Qt<XKB_KEY_Kana_Shift, Qt::Key_Kana_Shift>,
+ Xkb2Qt<XKB_KEY_Eisu_Shift, Qt::Key_Eisu_Shift>,
+ Xkb2Qt<XKB_KEY_Eisu_toggle, Qt::Key_Eisu_toggle>,
+ //Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Kanji_Bangou>,
+ //Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_Zen_Koho>,
+ //Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_Mae_Koho>,
+ Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Codeinput>,
+ Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_MultipleCandidate>,
+ Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_PreviousCandidate>,
+
+ // Korean keyboard support
+ Xkb2Qt<XKB_KEY_Hangul, Qt::Key_Hangul>,
+ Xkb2Qt<XKB_KEY_Hangul_Start, Qt::Key_Hangul_Start>,
+ Xkb2Qt<XKB_KEY_Hangul_End, Qt::Key_Hangul_End>,
+ Xkb2Qt<XKB_KEY_Hangul_Hanja, Qt::Key_Hangul_Hanja>,
+ Xkb2Qt<XKB_KEY_Hangul_Jamo, Qt::Key_Hangul_Jamo>,
+ Xkb2Qt<XKB_KEY_Hangul_Romaja, Qt::Key_Hangul_Romaja>,
+ //Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Hangul_Codeinput>,
+ Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Codeinput>,
+ Xkb2Qt<XKB_KEY_Hangul_Jeonja, Qt::Key_Hangul_Jeonja>,
+ Xkb2Qt<XKB_KEY_Hangul_Banja, Qt::Key_Hangul_Banja>,
+ Xkb2Qt<XKB_KEY_Hangul_PreHanja, Qt::Key_Hangul_PreHanja>,
+ Xkb2Qt<XKB_KEY_Hangul_PostHanja, Qt::Key_Hangul_PostHanja>,
+ //Xkb2Qt<XKB_KEY_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate>,
+ //Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate>,
+ //Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate>,
+ Xkb2Qt<XKB_KEY_Hangul_SingleCandidate, Qt::Key_SingleCandidate>,
+ Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate>,
+ Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate>,
+ Xkb2Qt<XKB_KEY_Hangul_Special, Qt::Key_Hangul_Special>,
+ //Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Hangul_switch>,
+ Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Mode_switch>,
+
+ // dead keys
+ Xkb2Qt<XKB_KEY_dead_grave, Qt::Key_Dead_Grave>,
+ Xkb2Qt<XKB_KEY_dead_acute, Qt::Key_Dead_Acute>,
+ Xkb2Qt<XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex>,
+ Xkb2Qt<XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde>,
+ Xkb2Qt<XKB_KEY_dead_macron, Qt::Key_Dead_Macron>,
+ Xkb2Qt<XKB_KEY_dead_breve, Qt::Key_Dead_Breve>,
+ Xkb2Qt<XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot>,
+ Xkb2Qt<XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis>,
+ Xkb2Qt<XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering>,
+ Xkb2Qt<XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute>,
+ Xkb2Qt<XKB_KEY_dead_caron, Qt::Key_Dead_Caron>,
+ Xkb2Qt<XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla>,
+ Xkb2Qt<XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek>,
+ Xkb2Qt<XKB_KEY_dead_iota, Qt::Key_Dead_Iota>,
+ Xkb2Qt<XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound>,
+ Xkb2Qt<XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound>,
+ Xkb2Qt<XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot>,
+ Xkb2Qt<XKB_KEY_dead_hook, Qt::Key_Dead_Hook>,
+ Xkb2Qt<XKB_KEY_dead_horn, Qt::Key_Dead_Horn>,
+ Xkb2Qt<XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke>,
+ Xkb2Qt<XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma>,
+ Xkb2Qt<XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma>,
+ Xkb2Qt<XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave>,
+ Xkb2Qt<XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring>,
+ Xkb2Qt<XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron>,
+ Xkb2Qt<XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex>,
+ Xkb2Qt<XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde>,
+ Xkb2Qt<XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve>,
+ Xkb2Qt<XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis>,
+ Xkb2Qt<XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve>,
+ Xkb2Qt<XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma>,
+ Xkb2Qt<XKB_KEY_dead_currency, Qt::Key_Dead_Currency>,
+ Xkb2Qt<XKB_KEY_dead_a, Qt::Key_Dead_a>,
+ Xkb2Qt<XKB_KEY_dead_A, Qt::Key_Dead_A>,
+ Xkb2Qt<XKB_KEY_dead_e, Qt::Key_Dead_e>,
+ Xkb2Qt<XKB_KEY_dead_E, Qt::Key_Dead_E>,
+ Xkb2Qt<XKB_KEY_dead_i, Qt::Key_Dead_i>,
+ Xkb2Qt<XKB_KEY_dead_I, Qt::Key_Dead_I>,
+ Xkb2Qt<XKB_KEY_dead_o, Qt::Key_Dead_o>,
+ Xkb2Qt<XKB_KEY_dead_O, Qt::Key_Dead_O>,
+ Xkb2Qt<XKB_KEY_dead_u, Qt::Key_Dead_u>,
+ Xkb2Qt<XKB_KEY_dead_U, Qt::Key_Dead_U>,
+ Xkb2Qt<XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa>,
+ Xkb2Qt<XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa>,
+ Xkb2Qt<XKB_KEY_dead_greek, Qt::Key_Dead_Greek>,
+ Xkb2Qt<XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline>,
+ Xkb2Qt<XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline>,
+ Xkb2Qt<XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline>,
+ Xkb2Qt<XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay>,
+
+ // Special keys from X.org - This include multimedia keys,
+ // wireless/bluetooth/uwb keys, special launcher keys, etc.
+ Xkb2Qt<XKB_KEY_XF86Back, Qt::Key_Back>,
+ Xkb2Qt<XKB_KEY_XF86Forward, Qt::Key_Forward>,
+ Xkb2Qt<XKB_KEY_XF86Stop, Qt::Key_Stop>,
+ Xkb2Qt<XKB_KEY_XF86Refresh, Qt::Key_Refresh>,
+ Xkb2Qt<XKB_KEY_XF86Favorites, Qt::Key_Favorites>,
+ Xkb2Qt<XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia>,
+ Xkb2Qt<XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl>,
+ Xkb2Qt<XKB_KEY_XF86HomePage, Qt::Key_HomePage>,
+ Xkb2Qt<XKB_KEY_XF86Search, Qt::Key_Search>,
+ Xkb2Qt<XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown>,
+ Xkb2Qt<XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute>,
+ Xkb2Qt<XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp>,
+ Xkb2Qt<XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay>,
+ Xkb2Qt<XKB_KEY_XF86AudioStop, Qt::Key_MediaStop>,
+ Xkb2Qt<XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious>,
+ Xkb2Qt<XKB_KEY_XF86AudioNext, Qt::Key_MediaNext>,
+ Xkb2Qt<XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord>,
+ Xkb2Qt<XKB_KEY_XF86AudioPause, Qt::Key_MediaPause>,
+ Xkb2Qt<XKB_KEY_XF86Mail, Qt::Key_LaunchMail>,
+ Xkb2Qt<XKB_KEY_XF86MyComputer, Qt::Key_Launch0>, // ### Qt 6: remap properly
+ Xkb2Qt<XKB_KEY_XF86Calculator, Qt::Key_Launch1>,
+ Xkb2Qt<XKB_KEY_XF86Memo, Qt::Key_Memo>,
+ Xkb2Qt<XKB_KEY_XF86ToDoList, Qt::Key_ToDoList>,
+ Xkb2Qt<XKB_KEY_XF86Calendar, Qt::Key_Calendar>,
+ Xkb2Qt<XKB_KEY_XF86PowerDown, Qt::Key_PowerDown>,
+ Xkb2Qt<XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust>,
+ Xkb2Qt<XKB_KEY_XF86Standby, Qt::Key_Standby>,
+ Xkb2Qt<XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp>,
+ Xkb2Qt<XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown>,
+ Xkb2Qt<XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff>,
+ Xkb2Qt<XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp>,
+ Xkb2Qt<XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown>,
+ Xkb2Qt<XKB_KEY_XF86PowerOff, Qt::Key_PowerOff>,
+ Xkb2Qt<XKB_KEY_XF86WakeUp, Qt::Key_WakeUp>,
+ Xkb2Qt<XKB_KEY_XF86Eject, Qt::Key_Eject>,
+ Xkb2Qt<XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver>,
+ Xkb2Qt<XKB_KEY_XF86WWW, Qt::Key_WWW>,
+ Xkb2Qt<XKB_KEY_XF86Sleep, Qt::Key_Sleep>,
+ Xkb2Qt<XKB_KEY_XF86LightBulb, Qt::Key_LightBulb>,
+ Xkb2Qt<XKB_KEY_XF86Shop, Qt::Key_Shop>,
+ Xkb2Qt<XKB_KEY_XF86History, Qt::Key_History>,
+ Xkb2Qt<XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite>,
+ Xkb2Qt<XKB_KEY_XF86HotLinks, Qt::Key_HotLinks>,
+ Xkb2Qt<XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust>,
+ Xkb2Qt<XKB_KEY_XF86Finance, Qt::Key_Finance>,
+ Xkb2Qt<XKB_KEY_XF86Community, Qt::Key_Community>,
+ Xkb2Qt<XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind>,
+ Xkb2Qt<XKB_KEY_XF86BackForward, Qt::Key_BackForward>,
+ Xkb2Qt<XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft>,
+ Xkb2Qt<XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight>,
+ Xkb2Qt<XKB_KEY_XF86Book, Qt::Key_Book>,
+ Xkb2Qt<XKB_KEY_XF86CD, Qt::Key_CD>,
+ Xkb2Qt<XKB_KEY_XF86Calculater, Qt::Key_Calculator>,
+ Xkb2Qt<XKB_KEY_XF86Clear, Qt::Key_Clear>,
+ Xkb2Qt<XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab>,
+ Xkb2Qt<XKB_KEY_XF86Close, Qt::Key_Close>,
+ Xkb2Qt<XKB_KEY_XF86Copy, Qt::Key_Copy>,
+ Xkb2Qt<XKB_KEY_XF86Cut, Qt::Key_Cut>,
+ Xkb2Qt<XKB_KEY_XF86Display, Qt::Key_Display>,
+ Xkb2Qt<XKB_KEY_XF86DOS, Qt::Key_DOS>,
+ Xkb2Qt<XKB_KEY_XF86Documents, Qt::Key_Documents>,
+ Xkb2Qt<XKB_KEY_XF86Excel, Qt::Key_Excel>,
+ Xkb2Qt<XKB_KEY_XF86Explorer, Qt::Key_Explorer>,
+ Xkb2Qt<XKB_KEY_XF86Game, Qt::Key_Game>,
+ Xkb2Qt<XKB_KEY_XF86Go, Qt::Key_Go>,
+ Xkb2Qt<XKB_KEY_XF86iTouch, Qt::Key_iTouch>,
+ Xkb2Qt<XKB_KEY_XF86LogOff, Qt::Key_LogOff>,
+ Xkb2Qt<XKB_KEY_XF86Market, Qt::Key_Market>,
+ Xkb2Qt<XKB_KEY_XF86Meeting, Qt::Key_Meeting>,
+ Xkb2Qt<XKB_KEY_XF86MenuKB, Qt::Key_MenuKB>,
+ Xkb2Qt<XKB_KEY_XF86MenuPB, Qt::Key_MenuPB>,
+ Xkb2Qt<XKB_KEY_XF86MySites, Qt::Key_MySites>,
+ Xkb2Qt<XKB_KEY_XF86New, Qt::Key_New>,
+ Xkb2Qt<XKB_KEY_XF86News, Qt::Key_News>,
+ Xkb2Qt<XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome>,
+ Xkb2Qt<XKB_KEY_XF86Open, Qt::Key_Open>,
+ Xkb2Qt<XKB_KEY_XF86Option, Qt::Key_Option>,
+ Xkb2Qt<XKB_KEY_XF86Paste, Qt::Key_Paste>,
+ Xkb2Qt<XKB_KEY_XF86Phone, Qt::Key_Phone>,
+ Xkb2Qt<XKB_KEY_XF86Reply, Qt::Key_Reply>,
+ Xkb2Qt<XKB_KEY_XF86Reload, Qt::Key_Reload>,
+ Xkb2Qt<XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows>,
+ Xkb2Qt<XKB_KEY_XF86RotationPB, Qt::Key_RotationPB>,
+ Xkb2Qt<XKB_KEY_XF86RotationKB, Qt::Key_RotationKB>,
+ Xkb2Qt<XKB_KEY_XF86Save, Qt::Key_Save>,
+ Xkb2Qt<XKB_KEY_XF86Send, Qt::Key_Send>,
+ Xkb2Qt<XKB_KEY_XF86Spell, Qt::Key_Spell>,
+ Xkb2Qt<XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen>,
+ Xkb2Qt<XKB_KEY_XF86Support, Qt::Key_Support>,
+ Xkb2Qt<XKB_KEY_XF86TaskPane, Qt::Key_TaskPane>,
+ Xkb2Qt<XKB_KEY_XF86Terminal, Qt::Key_Terminal>,
+ Xkb2Qt<XKB_KEY_XF86Tools, Qt::Key_Tools>,
+ Xkb2Qt<XKB_KEY_XF86Travel, Qt::Key_Travel>,
+ Xkb2Qt<XKB_KEY_XF86Video, Qt::Key_Video>,
+ Xkb2Qt<XKB_KEY_XF86Word, Qt::Key_Word>,
+ Xkb2Qt<XKB_KEY_XF86Xfer, Qt::Key_Xfer>,
+ Xkb2Qt<XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn>,
+ Xkb2Qt<XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut>,
+ Xkb2Qt<XKB_KEY_XF86Away, Qt::Key_Away>,
+ Xkb2Qt<XKB_KEY_XF86Messenger, Qt::Key_Messenger>,
+ Xkb2Qt<XKB_KEY_XF86WebCam, Qt::Key_WebCam>,
+ Xkb2Qt<XKB_KEY_XF86MailForward, Qt::Key_MailForward>,
+ Xkb2Qt<XKB_KEY_XF86Pictures, Qt::Key_Pictures>,
+ Xkb2Qt<XKB_KEY_XF86Music, Qt::Key_Music>,
+ Xkb2Qt<XKB_KEY_XF86Battery, Qt::Key_Battery>,
+ Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
+ Xkb2Qt<XKB_KEY_XF86WLAN, Qt::Key_WLAN>,
+ Xkb2Qt<XKB_KEY_XF86UWB, Qt::Key_UWB>,
+ Xkb2Qt<XKB_KEY_XF86AudioForward, Qt::Key_AudioForward>,
+ Xkb2Qt<XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat>,
+ Xkb2Qt<XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay>,
+ Xkb2Qt<XKB_KEY_XF86Subtitle, Qt::Key_Subtitle>,
+ Xkb2Qt<XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack>,
+ Xkb2Qt<XKB_KEY_XF86Time, Qt::Key_Time>,
+ Xkb2Qt<XKB_KEY_XF86Select, Qt::Key_Select>,
+ Xkb2Qt<XKB_KEY_XF86View, Qt::Key_View>,
+ Xkb2Qt<XKB_KEY_XF86TopMenu, Qt::Key_TopMenu>,
+ Xkb2Qt<XKB_KEY_XF86Red, Qt::Key_Red>,
+ Xkb2Qt<XKB_KEY_XF86Green, Qt::Key_Green>,
+ Xkb2Qt<XKB_KEY_XF86Yellow, Qt::Key_Yellow>,
+ Xkb2Qt<XKB_KEY_XF86Blue, Qt::Key_Blue>,
+ Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
+ Xkb2Qt<XKB_KEY_XF86Suspend, Qt::Key_Suspend>,
+ Xkb2Qt<XKB_KEY_XF86Hibernate, Qt::Key_Hibernate>,
+ Xkb2Qt<XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle>,
+ Xkb2Qt<XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn>,
+ Xkb2Qt<XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff>,
+ Xkb2Qt<XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute>,
+ Xkb2Qt<XKB_KEY_XF86Launch0, Qt::Key_Launch2>, // ### Qt 6: remap properly
+ Xkb2Qt<XKB_KEY_XF86Launch1, Qt::Key_Launch3>,
+ Xkb2Qt<XKB_KEY_XF86Launch2, Qt::Key_Launch4>,
+ Xkb2Qt<XKB_KEY_XF86Launch3, Qt::Key_Launch5>,
+ Xkb2Qt<XKB_KEY_XF86Launch4, Qt::Key_Launch6>,
+ Xkb2Qt<XKB_KEY_XF86Launch5, Qt::Key_Launch7>,
+ Xkb2Qt<XKB_KEY_XF86Launch6, Qt::Key_Launch8>,
+ Xkb2Qt<XKB_KEY_XF86Launch7, Qt::Key_Launch9>,
+ Xkb2Qt<XKB_KEY_XF86Launch8, Qt::Key_LaunchA>,
+ Xkb2Qt<XKB_KEY_XF86Launch9, Qt::Key_LaunchB>,
+ Xkb2Qt<XKB_KEY_XF86LaunchA, Qt::Key_LaunchC>,
+ Xkb2Qt<XKB_KEY_XF86LaunchB, Qt::Key_LaunchD>,
+ Xkb2Qt<XKB_KEY_XF86LaunchC, Qt::Key_LaunchE>,
+ Xkb2Qt<XKB_KEY_XF86LaunchD, Qt::Key_LaunchF>,
+ Xkb2Qt<XKB_KEY_XF86LaunchE, Qt::Key_LaunchG>,
+ Xkb2Qt<XKB_KEY_XF86LaunchF, Qt::Key_LaunchH>
+ >::Data{}
+);
+
// Possible modifier states.
static const Qt::KeyboardModifiers ModsTbl[] = {
Qt::NoModifier, // 0
@@ -831,20 +853,20 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
}
}
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
{
if (m_config && !connection()->hasXKB()) {
- xXIModifierInfo *mods = static_cast<xXIModifierInfo *>(modInfo);
- xXIGroupInfo *group = static_cast<xXIGroupInfo *>(groupInfo);
+ auto *mods = static_cast<xcb_input_modifier_info_t *>(modInfo);
+ auto *group = static_cast<xcb_input_group_info_t *>(groupInfo);
const xkb_state_component changedComponents
= xkb_state_update_mask(m_xkbState.get(),
- mods->base_mods,
- mods->latched_mods,
- mods->locked_mods,
- group->base_group,
- group->latched_group,
- group->locked_group);
+ mods->base,
+ mods->latched,
+ mods->locked,
+ group->base,
+ group->latched,
+ group->locked);
handleStateChanges(changedComponents);
}
@@ -1105,14 +1127,10 @@ int QXcbKeyboard::keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers modif
qtKey = xkbcommon_xkb_keysym_to_upper(keysym);
} else {
// check if we have a direct mapping
- int i = 0;
- while (KeyTbl[i]) {
- if (keysym == KeyTbl[i]) {
- qtKey = KeyTbl[i + 1];
- break;
- }
- i += 2;
- }
+ xkb2qt_t searchKey{keysym, 0};
+ auto it = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
+ if (it != KeyTbl.end() && !(searchKey < *it))
+ qtKey = it->qt;
}
QString text;
@@ -1461,64 +1479,6 @@ void QXcbKeyboard::resolveMaskConflicts()
}
}
-class KeyChecker
-{
-public:
- KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time, quint16 state)
- : m_window(window)
- , m_code(code)
- , m_time(time)
- , m_state(state)
- , m_error(false)
- , m_release(true)
- {
- }
-
- bool checkEvent(xcb_generic_event_t *ev)
- {
- if (m_error || !ev)
- return false;
-
- int type = ev->response_type & ~0x80;
- if (type != XCB_KEY_PRESS && type != XCB_KEY_RELEASE)
- return false;
-
- xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev;
-
- if (event->event != m_window || event->detail != m_code || event->state != m_state) {
- m_error = true;
- return false;
- }
-
- if (type == XCB_KEY_PRESS) {
- m_error = !m_release || event->time - m_time > 10;
- return !m_error;
- }
-
- if (m_release) {
- m_error = true;
- return false;
- }
-
- m_release = true;
- m_time = event->time;
-
- return false;
- }
-
- bool release() const { return m_release; }
- xcb_timestamp_t time() const { return m_time; }
-
-private:
- xcb_window_t m_window;
- xcb_keycode_t m_code;
- xcb_timestamp_t m_time;
- quint16 m_state;
-
- bool m_error;
- bool m_release;
-};
-
void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code,
quint16 state, xcb_timestamp_t time, bool fromSendEvent)
{
@@ -1532,7 +1492,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
if (type == QEvent::KeyPress)
targetWindow->updateNetWmUserTime(time);
-
ScopedXKBState sendEventState;
if (fromSendEvent) {
// Have a temporary keyboard state filled in from state
@@ -1550,7 +1509,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
struct xkb_state *xkbState = fromSendEvent ? sendEventState.get() : m_xkbState.get();
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code);
- QString string = lookupString(xkbState, code);
+ QString text = lookupString(xkbState, code);
Qt::KeyboardModifiers modifiers = translateModifiers(state);
if (sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9)
@@ -1575,55 +1534,42 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
int qtcode = keysymToQtKey(latinKeysym != XKB_KEY_NoSymbol ? latinKeysym : sym,
modifiers, xkbState, code);
- bool isAutoRepeat = false;
if (type == QEvent::KeyPress) {
- if (m_autorepeat_code == code) {
- isAutoRepeat = true;
- m_autorepeat_code = 0;
- }
+ if (m_isAutoRepeat && m_autoRepeatCode != code)
+ // Some other key was pressed while we are auto-repeating on a different key.
+ m_isAutoRepeat = false;
} else {
- // look ahead for auto-repeat
- KeyChecker checker(source->xcb_window(), code, time, state);
- xcb_generic_event_t *event = connection()->checkEvent(checker);
- if (event) {
- isAutoRepeat = true;
- free(event);
- }
- m_autorepeat_code = isAutoRepeat ? code : 0;
+ m_isAutoRepeat = false;
+ // Look at the next event in the queue to see if we are auto-repeating.
+ connection()->checkEvent([this, time, code](xcb_generic_event_t *event, int type) {
+ if (type == XCB_KEY_PRESS) {
+ auto keyPress = reinterpret_cast<xcb_key_press_event_t *>(event);
+ m_isAutoRepeat = keyPress->time == time && keyPress->detail == code;
+ if (m_isAutoRepeat)
+ m_autoRepeatCode = code;
+ }
+ return true;
+ }, false /* removeFromQueue */);
}
bool filtered = false;
- QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
- if (inputContext) {
- QKeyEvent event(type, qtcode, modifiers, code, sym, state, string, isAutoRepeat, string.length());
+ if (auto inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext()) {
+ QKeyEvent event(type, qtcode, modifiers, code, sym, state, text, m_isAutoRepeat, text.size());
event.setTimestamp(time);
filtered = inputContext->filterEvent(&event);
}
- QWindow *window = targetWindow->window();
if (!filtered) {
+ QWindow *window = targetWindow->window();
#ifndef QT_NO_CONTEXTMENU
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
const QPoint pos = window->mapFromGlobal(globalPos);
QWindowSystemInterface::handleContextMenuEvent(window, false, pos, globalPos, modifiers);
}
-#endif // QT_NO_CONTEXTMENU
+#endif
QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
- code, sym, state, string, isAutoRepeat);
- }
-
- if (isAutoRepeat && type == QEvent::KeyRelease) {
- // since we removed it from the event queue using checkEvent we need to send the key press here
- filtered = false;
- if (inputContext) {
- QKeyEvent event(QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat, string.length());
- event.setTimestamp(time);
- filtered = inputContext->filterEvent(&event);
- }
- if (!filtered)
- QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers,
- code, sym, state, string, isAutoRepeat);
+ code, sym, state, text, m_isAutoRepeat);
}
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index c131d69267..95915fb2e6 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -74,7 +74,7 @@ public:
void updateXKBMods();
xkb_mod_mask_t xkbModMask(quint16 state);
void updateXKBStateFromCore(quint16 state);
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
void updateXKBStateFromXI(void *modInfo, void *groupInfo);
#endif
#if QT_CONFIG(xkb)
@@ -109,7 +109,8 @@ protected:
private:
bool m_config = false;
- xcb_keycode_t m_autorepeat_code = 0;
+ bool m_isAutoRepeat = false;
+ xcb_keycode_t m_autoRepeatCode = 0;
struct _mod_masks {
uint alt;
diff --git a/src/plugins/platforms/xcb/qxcbmain.cpp b/src/plugins/platforms/xcb/qxcbmain.cpp
index f8cb9a9269..539d033ca9 100644
--- a/src/plugins/platforms/xcb/qxcbmain.cpp
+++ b/src/plugins/platforms/xcb/qxcbmain.cpp
@@ -52,10 +52,16 @@ public:
QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters, int &argc, char **argv)
{
- if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive))
- return new QXcbIntegration(parameters, argc, argv);
+ if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive)) {
+ QXcbIntegration *xcbIntegration = new QXcbIntegration(parameters, argc, argv);
+ if (!xcbIntegration->hasDefaultConnection()) {
+ delete xcbIntegration;
+ return nullptr;
+ }
+ return xcbIntegration;
+ }
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index db44e58cbb..98bedea48a 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -54,7 +54,6 @@
#include <QtGui/qscreen.h>
#include <QtPlatformHeaders/qxcbwindowfunctions.h>
-#include <QtPlatformHeaders/qxcbintegrationfunctions.h>
#include <QtPlatformHeaders/qxcbscreenfunctions.h>
#include <stdio.h>
@@ -93,8 +92,7 @@ static int resourceType(const QByteArray &key)
return int(result - names);
}
-QXcbNativeInterface::QXcbNativeInterface() :
- m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t"))
+QXcbNativeInterface::QXcbNativeInterface()
{
}
@@ -106,50 +104,6 @@ static inline QXcbSystemTrayTracker *systemTrayTracker(const QScreen *s)
return static_cast<const QXcbScreen *>(s->handle())->connection()->systemTrayTracker();
}
-bool QXcbNativeInterface::systemTrayAvailable(const QScreen *screen) const
-{
- return systemTrayTracker(screen);
-}
-
-bool QXcbNativeInterface::requestSystemTrayWindowDock(const QWindow *window)
-{
- return QXcbWindow::requestSystemTrayWindowDockStatic(window);
-}
-
-QRect QXcbNativeInterface::systemTrayWindowGlobalGeometry(const QWindow *window)
-{
- return QXcbWindow::systemTrayWindowGlobalGeometryStatic(window);
-}
-
-xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const QXcbScreen *screen)
-{
- if (m_sysTraySelectionAtom == XCB_ATOM_NONE) {
- const QByteArray net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen->screenNumber()).toLatin1();
- auto intern_r = Q_XCB_REPLY_UNCHECKED(xcb_intern_atom, conn,
- true, net_sys_tray.length(), net_sys_tray);
- if (!intern_r)
- return XCB_WINDOW_NONE;
-
- m_sysTraySelectionAtom = intern_r->atom;
- }
-
- auto sel_owner_r = Q_XCB_REPLY_UNCHECKED(xcb_get_selection_owner, conn, m_sysTraySelectionAtom);
- if (!sel_owner_r)
- return XCB_WINDOW_NONE;
-
- return sel_owner_r->owner;
-}
-
-bool QXcbNativeInterface::systrayVisualHasAlphaChannel()
-{
- return QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel();
-}
-
-void QXcbNativeInterface::setParentRelativeBackPixmap(QWindow *window)
-{
- QXcbWindow::setParentRelativeBackPixmapStatic(window);
-}
-
void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
{
QByteArray lowerCaseResource = resourceString.toLower();
@@ -371,18 +325,6 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio
if (function == QXcbWindowFunctions::setWmWindowIconTextIdentifier())
return QFunctionPointer(QXcbWindowFunctions::SetWmWindowIconText(QXcbWindow::setWindowIconTextStatic));
- if (function == QXcbWindowFunctions::setParentRelativeBackPixmapIdentifier())
- return QFunctionPointer(QXcbWindowFunctions::SetParentRelativeBackPixmap(QXcbWindow::setParentRelativeBackPixmapStatic));
-
- if (function == QXcbWindowFunctions::requestSystemTrayWindowDockIdentifier())
- return QFunctionPointer(QXcbWindowFunctions::RequestSystemTrayWindowDock(QXcbWindow::requestSystemTrayWindowDockStatic));
-
- if (function == QXcbWindowFunctions::systemTrayWindowGlobalGeometryIdentifier())
- return QFunctionPointer(QXcbWindowFunctions::SystemTrayWindowGlobalGeometry(QXcbWindow::systemTrayWindowGlobalGeometryStatic));
-
- if (function == QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannelIdentifier())
- return QFunctionPointer(QXcbIntegrationFunctions::XEmbedSystemTrayVisualHasAlphaChannel(QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel));
-
if (function == QXcbWindowFunctions::visualIdIdentifier()) {
return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic));
}
@@ -466,7 +408,7 @@ void *QXcbNativeInterface::atspiBus()
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection) {
- xcb_atom_t atspiBusAtom = defaultConnection->internAtom("AT_SPI_BUS");
+ auto atspiBusAtom = defaultConnection->atom(QXcbAtom::AT_SPI_BUS);
auto reply = Q_XCB_REPLY(xcb_get_property, defaultConnection->xcb_connection(),
false, defaultConnection->rootWindow(),
atspiBusAtom, XCB_ATOM_STRING, 0, 128);
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 6a752c68ca..d1f2747bea 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -98,7 +98,7 @@ public:
QFunctionPointer platformFunction(const QByteArray &function) const override;
- inline const QByteArray &genericEventFilterType() const { return m_genericEventFilterType; }
+ inline const QByteArray &nativeEventType() const { return m_nativeEventType; }
void *displayForWindow(QWindow *window);
void *connectionForWindow(QWindow *window);
@@ -122,11 +122,6 @@ public:
QXcbConnection::PeekOptions option = QXcbConnection::PeekDefault,
qint32 peekerId = -1);
- Q_INVOKABLE bool systemTrayAvailable(const QScreen *screen) const;
- Q_INVOKABLE void setParentRelativeBackPixmap(QWindow *window);
- Q_INVOKABLE bool systrayVisualHasAlphaChannel();
- Q_INVOKABLE bool requestSystemTrayWindowDock(const QWindow *window);
- Q_INVOKABLE QRect systemTrayWindowGlobalGeometry(const QWindow *window);
Q_INVOKABLE QString dumpConnectionNativeWindows(const QXcbConnection *connection, WId root) const;
Q_INVOKABLE QString dumpNativeWindows(WId root = 0) const;
@@ -136,9 +131,7 @@ signals:
void systemTrayWindowChanged(QScreen *screen);
private:
- xcb_window_t locateSystemTray(xcb_connection_t *conn, const QXcbScreen *screen);
-
- const QByteArray m_genericEventFilterType;
+ const QByteArray m_nativeEventType = QByteArrayLiteral("xcb_generic_event_t");
xcb_atom_t m_sysTraySelectionAtom = XCB_ATOM_NONE;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 7f2793b2b7..8c0ce8dd7e 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -95,12 +95,6 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
m_windowManagerName = QXcbWindow::windowTitle(connection, windowManager);
}
- const xcb_query_extension_reply_t *sync_reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id);
- if (!sync_reply || !sync_reply->present)
- m_syncRequestSupported = false;
- else
- m_syncRequestSupported = true;
-
xcb_depth_iterator_t depth_iterator =
xcb_screen_allowed_depths_iterator(screen);
@@ -912,16 +906,12 @@ QByteArray QXcbScreen::getEdid() const
return result;
// Try a bunch of atoms
- xcb_atom_t atom = connection()->internAtom("EDID");
- result = getOutputProperty(atom);
- if (result.isEmpty()) {
- atom = connection()->internAtom("EDID_DATA");
- result = getOutputProperty(atom);
- }
- if (result.isEmpty()) {
- atom = connection()->internAtom("XFree86_DDC_EDID1_RAWDATA");
- result = getOutputProperty(atom);
- }
+ result = getOutputProperty(atom(QXcbAtom::EDID));
+ if (result.isEmpty())
+ result = getOutputProperty(atom(QXcbAtom::EDID_DATA));
+ if (result.isEmpty())
+ result = getOutputProperty(atom(QXcbAtom::XFree86_DDC_EDID1_RAWDATA));
+
return result;
}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 6438669e7a..4404a04f49 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -102,7 +102,6 @@ public:
int antialiasingEnabled() const { return m_antialiasingEnabled; }
QString windowManagerName() const { return m_windowManagerName; }
- bool syncRequestSupported() const { return m_syncRequestSupported; }
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &format) const;
@@ -133,7 +132,6 @@ private:
QFontEngine::SubpixelAntialiasingType m_subpixelType = QFontEngine::SubpixelAntialiasingType(-1);
int m_antialiasingEnabled = -1;
QString m_windowManagerName;
- bool m_syncRequestSupported = false;
QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals;
QMap<xcb_visualid_t, quint8> m_visualDepths;
uint16_t m_rotation = XCB_RANDR_ROTATION_ROTATE_0;
@@ -188,7 +186,6 @@ public:
void windowShown(QXcbWindow *window);
QString windowManagerName() const { return m_virtualDesktop->windowManagerName(); }
- bool syncRequestSupported() const { return m_virtualDesktop->syncRequestSupported(); }
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &format) const;
@@ -220,7 +217,6 @@ private:
xcb_randr_crtc_t m_crtc;
xcb_randr_mode_t m_mode = XCB_NONE;
bool m_primary = false;
- uint8_t m_rotation = XCB_RANDR_ROTATION_ROTATE_0;
QString m_outputName;
QSizeF m_outputSizeMillimeters;
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
index c98879c7df..684e603fab 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -91,8 +91,7 @@ xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *conne
return reply->owner;
}
-// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Request a window
-// to be docked on the tray.
+// Request a window to be docked on the tray.
void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const
{
xcb_client_message_event_t trayRequest;
@@ -122,23 +121,6 @@ xcb_window_t QXcbSystemTrayTracker::trayWindow()
return m_trayWindow;
}
-// API for QPlatformNativeInterface/QPlatformSystemTrayIcon: Return the geometry of a
-// a window parented on the tray. Determines the global geometry via XCB since mapToGlobal
-// does not work for the QWindow parented on the tray.
-QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) const
-{
- xcb_connection_t *conn = m_connection->xcb_connection();
- auto geomReply = Q_XCB_REPLY(xcb_get_geometry, conn, window);
- if (!geomReply)
- return QRect();
-
- auto translateReply = Q_XCB_REPLY(xcb_translate_coordinates, conn, window, m_connection->rootWindow(), 0, 0);
- if (!translateReply)
- return QRect();
-
- return QRect(QPoint(translateReply->dst_x, translateReply->dst_y), QSize(geomReply->width, geomReply->height));
-}
-
inline void QXcbSystemTrayTracker::emitSystemTrayWindowChanged()
{
if (const QPlatformScreen *ps = m_connection->primaryScreen())
@@ -162,10 +144,18 @@ void QXcbSystemTrayTracker::handleDestroyNotifyEvent(const xcb_destroy_notify_ev
}
}
-bool QXcbSystemTrayTracker::visualHasAlphaChannel()
+xcb_visualid_t QXcbSystemTrayTracker::visualId()
+{
+ xcb_visualid_t visual = netSystemTrayVisual();
+ if (visual == XCB_NONE)
+ visual = m_connection->primaryScreen()->screen()->root_visual;
+ return visual;
+}
+
+xcb_visualid_t QXcbSystemTrayTracker::netSystemTrayVisual()
{
if (m_trayWindow == XCB_WINDOW_NONE)
- return false;
+ return XCB_NONE;
xcb_atom_t tray_atom = m_connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL);
@@ -174,7 +164,7 @@ bool QXcbSystemTrayTracker::visualHasAlphaChannel()
false, m_trayWindow,
tray_atom, XCB_ATOM_VISUALID, 0, 1);
if (!systray_atom_reply)
- return false;
+ return XCB_NONE;
xcb_visualid_t systrayVisualId = XCB_NONE;
if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply.get()) > 0) {
@@ -182,12 +172,7 @@ bool QXcbSystemTrayTracker::visualHasAlphaChannel()
systrayVisualId = vids[0];
}
- if (systrayVisualId != XCB_NONE) {
- quint8 depth = m_connection->primaryScreen()->depthOfVisual(systrayVisualId);
- return depth == 32;
- }
-
- return false;
+ return systrayVisualId;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
index a95b9374e9..d2fc24c957 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
@@ -57,13 +57,12 @@ public:
xcb_window_t trayWindow();
void requestSystemTrayWindowDock(xcb_window_t window) const;
- QRect systemTrayWindowGlobalGeometry(xcb_window_t window) const;
void notifyManagerClientMessageEvent(const xcb_client_message_event_t *);
void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *) override;
- bool visualHasAlphaChannel();
+ xcb_visualid_t visualId();
signals:
void systemTrayWindowChanged(QScreen *screen);
@@ -73,6 +72,7 @@ private:
xcb_atom_t selection);
static xcb_window_t locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection);
void emitSystemTrayWindowChanged();
+ xcb_visualid_t netSystemTrayVisual();
const xcb_atom_t m_selection;
const xcb_atom_t m_trayAtom;
diff --git a/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp b/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp
index 4d540defa9..b3f8a5832d 100644
--- a/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp
+++ b/src/plugins/platforms/xcb/qxcbvulkaninstance.cpp
@@ -46,20 +46,9 @@ QT_BEGIN_NAMESPACE
QXcbVulkanInstance::QXcbVulkanInstance(QVulkanInstance *instance)
: m_instance(instance),
m_getPhysDevPresSupport(nullptr),
- m_createSurface(nullptr),
- m_destroySurface(nullptr)
+ m_createSurface(nullptr)
{
- if (qEnvironmentVariableIsSet("QT_VULKAN_LIB"))
- m_lib.setFileName(QString::fromUtf8(qgetenv("QT_VULKAN_LIB")));
- else
- m_lib.setFileName(QStringLiteral("vulkan"));
-
- if (!m_lib.load()) {
- qWarning("Failed to load %s: %s", qPrintable(m_lib.fileName()), qPrintable(m_lib.errorString()));
- return;
- }
-
- init(&m_lib);
+ loadVulkanLibrary(QStringLiteral("vulkan"));
}
QXcbVulkanInstance::~QXcbVulkanInstance()
@@ -114,14 +103,6 @@ VkSurfaceKHR QXcbVulkanInstance::createSurface(QXcbWindow *window)
qWarning("Failed to find vkCreateXcbSurfaceKHR");
return surface;
}
- if (!m_destroySurface) {
- m_destroySurface = reinterpret_cast<PFN_vkDestroySurfaceKHR>(
- m_vkGetInstanceProcAddr(m_vkInst, "vkDestroySurfaceKHR"));
- }
- if (!m_destroySurface) {
- qWarning("Failed to find vkDestroySurfaceKHR");
- return surface;
- }
VkXcbSurfaceCreateInfoKHR surfaceInfo;
memset(&surfaceInfo, 0, sizeof(surfaceInfo));
@@ -135,12 +116,6 @@ VkSurfaceKHR QXcbVulkanInstance::createSurface(QXcbWindow *window)
return surface;
}
-void QXcbVulkanInstance::destroySurface(VkSurfaceKHR surface)
-{
- if (m_destroySurface && surface)
- m_destroySurface(m_vkInst, surface, nullptr);
-}
-
void QXcbVulkanInstance::presentQueued(QWindow *window)
{
QXcbWindow *w = static_cast<QXcbWindow *>(window->handle());
diff --git a/src/plugins/platforms/xcb/qxcbvulkaninstance.h b/src/plugins/platforms/xcb/qxcbvulkaninstance.h
index dbe057d944..53f7345254 100644
--- a/src/plugins/platforms/xcb/qxcbvulkaninstance.h
+++ b/src/plugins/platforms/xcb/qxcbvulkaninstance.h
@@ -64,14 +64,11 @@ public:
void presentQueued(QWindow *window) override;
VkSurfaceKHR createSurface(QXcbWindow *window);
- void destroySurface(VkSurfaceKHR surface);
private:
QVulkanInstance *m_instance;
- QLibrary m_lib;
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR m_getPhysDevPresSupport;
PFN_vkCreateXcbSurfaceKHR m_createSurface;
- PFN_vkDestroySurfaceKHR m_destroySurface;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 59b06d543e..52c87ee8a4 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -70,6 +70,9 @@
#undef class
#include <xcb/xfixes.h>
#include <xcb/shape.h>
+#if QT_CONFIG(xcb_xinput)
+#include <xcb/xinput.h>
+#endif
// xcb-icccm 3.8 support
#ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS
@@ -109,11 +112,6 @@
#undef register
#endif
-#if QT_CONFIG(xinput2)
-#include <X11/extensions/XInput2.h>
-#include <X11/extensions/XI2proto.h>
-#endif
-
#define XCOORD_MAX 16383
enum {
defaultWindowWidth = 160,
@@ -200,11 +198,6 @@ void QXcbWindow::setImageFormatForVisual(const xcb_visualtype_t *visual)
}
}
-static inline bool positionIncludesFrame(QWindow *w)
-{
- return qt_window_private(w)->positionPolicy == QWindowPrivate::WindowFrameInclusive;
-}
-
#if QT_CONFIG(xcb_xlib)
static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
{
@@ -282,11 +275,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
setConnection(xcbScreen()->connection());
}
-#ifdef Q_COMPILER_CLASS_ENUM
enum : quint32 {
-#else
-enum {
-#endif
baseEventMask
= XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY
| XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE,
@@ -308,6 +297,7 @@ void QXcbWindow::create()
destroy();
m_windowState = Qt::WindowNoState;
+ m_trayIconWindow = window()->objectName() == QLatin1String("QSystemTrayIconSysWindow");
Qt::WindowType type = window()->type();
@@ -334,9 +324,6 @@ void QXcbWindow::create()
return;
}
- // Parameters to XCreateWindow() are frame corner + inner size.
- // This fits in case position policy is frame inclusive. There is
- // currently no way to implement it for frame-exclusive geometries.
QPlatformWindow::setGeometry(rect);
if (platformScreen != currentScreen)
@@ -368,7 +355,9 @@ void QXcbWindow::create()
const xcb_visualtype_t *visual = nullptr;
- if (connection()->hasDefaultVisualId()) {
+ if (m_trayIconWindow && connection()->systemTrayTracker()) {
+ visual = platformScreen->visualForId(connection()->systemTrayTracker()->visualId());
+ } else if (connection()->hasDefaultVisualId()) {
visual = platformScreen->visualForId(connection()->defaultVisualId());
if (!visual)
qWarning() << "Failed to use requested visual id.";
@@ -448,8 +437,6 @@ void QXcbWindow::create()
connection()->addWindowEventListener(m_window, this);
- xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
-
propagateSizeHints();
xcb_atom_t properties[5];
@@ -458,9 +445,7 @@ void QXcbWindow::create()
properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
- m_usingSyncProtocol = platformScreen->syncRequestSupported();
-
- if (m_usingSyncProtocol)
+ if (connection()->hasXSync())
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
if (window()->flags() & Qt::WindowContextHelpButtonHint)
@@ -484,7 +469,7 @@ void QXcbWindow::create()
XCB_ATOM_STRING, 8, wmClass.size(), wmClass.constData());
}
- if (m_usingSyncProtocol) {
+ if (connection()->hasXSync()) {
m_syncCounter = xcb_generate_id(xcb_connection());
xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue);
@@ -504,6 +489,13 @@ void QXcbWindow::create()
atom(QXcbAtom::_NET_WM_PID), XCB_ATOM_CARDINAL, 32,
1, &pid);
+ const QByteArray clientMachine = QSysInfo::machineHostName().toLocal8Bit();
+ if (!clientMachine.isEmpty()) {
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ atom(QXcbAtom::WM_CLIENT_MACHINE), XCB_ATOM_STRING, 8,
+ clientMachine.size(), clientMachine.constData());
+ }
+
xcb_wm_hints_t hints;
memset(&hints, 0, sizeof(hints));
xcb_wm_hints_set_normal(&hints);
@@ -524,7 +516,7 @@ void QXcbWindow::create()
atom(QXcbAtom::_XEMBED_INFO),
32, 2, (void *)data);
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
if (connection()->hasXInput2()) {
if (connection()->xi2MouseEventsDisabled())
connection()->xi2SelectDeviceEventsCompatibility(m_window);
@@ -562,6 +554,9 @@ void QXcbWindow::create()
QByteArray wmWindowRole = window()->property(wm_window_role_property_id).toByteArray();
setWmWindowRole(wmWindowRole);
}
+
+ if (m_trayIconWindow)
+ m_embedded = requestSystemTrayWindowDock();
}
QXcbWindow::~QXcbWindow()
@@ -587,7 +582,7 @@ void QXcbWindow::destroy()
if (connection()->mouseGrabber() == this)
connection()->setMouseGrabber(nullptr);
- if (m_syncCounter && m_usingSyncProtocol)
+ if (m_syncCounter && connection()->hasXSync())
xcb_sync_destroy_counter(xcb_connection(), m_syncCounter);
if (m_window) {
if (m_netWmUserTimeWindow) {
@@ -623,25 +618,23 @@ void QXcbWindow::setGeometry(const QRect &rect)
if (!newScreen)
newScreen = xcbScreen();
- const QRect wmGeometry = windowToWmGeometry(rect);
-
if (newScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
if (qt_window_private(window())->positionAutomatic) {
const quint32 mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
const qint32 values[] = {
- qBound<qint32>(1, wmGeometry.width(), XCOORD_MAX),
- qBound<qint32>(1, wmGeometry.height(), XCOORD_MAX),
+ qBound<qint32>(1, rect.width(), XCOORD_MAX),
+ qBound<qint32>(1, rect.height(), XCOORD_MAX),
};
xcb_configure_window(xcb_connection(), m_window, mask, reinterpret_cast<const quint32*>(values));
} else {
const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
const qint32 values[] = {
- qBound<qint32>(-XCOORD_MAX, wmGeometry.x(), XCOORD_MAX),
- qBound<qint32>(-XCOORD_MAX, wmGeometry.y(), XCOORD_MAX),
- qBound<qint32>(1, wmGeometry.width(), XCOORD_MAX),
- qBound<qint32>(1, wmGeometry.height(), XCOORD_MAX),
+ qBound<qint32>(-XCOORD_MAX, rect.x(), XCOORD_MAX),
+ qBound<qint32>(-XCOORD_MAX, rect.y(), XCOORD_MAX),
+ qBound<qint32>(1, rect.width(), XCOORD_MAX),
+ qBound<qint32>(1, rect.height(), XCOORD_MAX),
};
xcb_configure_window(xcb_connection(), m_window, mask, reinterpret_cast<const quint32*>(values));
if (window()->parent() && !window()->transientParent()) {
@@ -739,13 +732,6 @@ void QXcbWindow::setVisible(bool visible)
hide();
}
-static inline bool testShowWithoutActivating(const QWindow *window)
-{
- // QWidget-attribute Qt::WA_ShowWithoutActivating.
- const QVariant showWithoutActivating = window->property("_q_showWithoutActivating");
- return showWithoutActivating.isValid() && showWithoutActivating.toBool();
-}
-
void QXcbWindow::show()
{
if (window()->isTopLevel()) {
@@ -764,9 +750,6 @@ void QXcbWindow::show()
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
- m_gravity = positionIncludesFrame(window()) ?
- XCB_GRAVITY_NORTH_WEST : XCB_GRAVITY_STATIC;
-
// update WM_NORMAL_HINTS
propagateSizeHints();
@@ -796,12 +779,14 @@ void QXcbWindow::show()
updateNetWmStateBeforeMap();
}
- if (testShowWithoutActivating(window()))
+ // QWidget-attribute Qt::WA_ShowWithoutActivating.
+ const auto showWithoutActivating = window()->property("_q_showWithoutActivating");
+ if (showWithoutActivating.isValid() && showWithoutActivating.toBool())
updateNetWmUserTime(0);
else if (connection()->time() != XCB_TIME_CURRENT_TIME)
updateNetWmUserTime(connection()->time());
- if (window()->objectName() == QLatin1String("QSystemTrayIconSysWindow"))
+ if (m_trayIconWindow)
return; // defer showing until XEMBED_EMBEDDED_NOTIFY
xcb_map_window(xcb_connection(), m_window);
@@ -819,7 +804,7 @@ void QXcbWindow::hide()
xcb_unmap_window(xcb_connection(), m_window);
// send synthetic UnmapNotify event according to icccm 4.1.4
- Q_DECLARE_XCB_EVENT(event, xcb_unmap_notify_event_t);
+ q_padded_xcb_event<xcb_unmap_notify_event_t> event = {};
event.response_type = XCB_UNMAP_NOTIFY;
event.event = xcbScreen()->root();
event.window = m_window;
@@ -1364,17 +1349,10 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW),
XCB_ATOM_WINDOW, 32, 1, &m_netWmUserTimeWindow);
xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_USER_TIME));
-#ifndef QT_NO_DEBUG
- QByteArray ba("Qt NET_WM user time window");
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_netWmUserTimeWindow,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData());
-#endif
+
+ QXcbWindow::setWindowTitle(connection(), m_netWmUserTimeWindow,
+ QStringLiteral("Qt NET_WM User Time Window"));
+
} else if (!isSupportedByWM) {
// WM no longer supports it, then we should remove the
// _NET_WM_USER_TIME_WINDOW atom.
@@ -1452,24 +1430,7 @@ void QXcbWindow::setParent(const QPlatformWindow *parent)
void QXcbWindow::setWindowTitle(const QString &title)
{
- QString fullTitle = formatWindowTitle(title, QString::fromUtf8(" \xe2\x80\x94 ")); // unicode character U+2014, EM DASH
- const QByteArray ba = std::move(fullTitle).toUtf8();
- xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData());
-
-#if QT_CONFIG(xcb_xlib)
- Display *dpy = static_cast<Display *>(connection()->xlib_display());
- XTextProperty *text = qstringToXTP(dpy, title);
- if (text)
- XSetWMName(dpy, m_window, text);
-#endif
- xcb_flush(xcb_connection());
+ setWindowTitle(connection(), m_window, title);
}
void QXcbWindow::setWindowIconText(const QString &title)
@@ -1541,38 +1502,28 @@ void QXcbWindow::lower()
xcb_configure_window(xcb_connection(), m_window, mask, values);
}
-// Adapt the geometry to match the WM expection with regards
-// to gravity.
-QRect QXcbWindow::windowToWmGeometry(QRect r) const
-{
- if (m_dirtyFrameMargins || m_frameMargins.isNull())
- return r;
- const bool frameInclusive = positionIncludesFrame(window());
- // XCB_GRAVITY_STATIC requires the inner geometry, whereas
- // XCB_GRAVITY_NORTH_WEST requires the frame geometry
- if (frameInclusive && m_gravity == XCB_GRAVITY_STATIC) {
- r.translate(m_frameMargins.left(), m_frameMargins.top());
- } else if (!frameInclusive && m_gravity == XCB_GRAVITY_NORTH_WEST) {
- r.translate(-m_frameMargins.left(), -m_frameMargins.top());
- }
- return r;
-}
-
void QXcbWindow::propagateSizeHints()
{
// update WM_NORMAL_HINTS
xcb_size_hints_t hints;
memset(&hints, 0, sizeof(hints));
- const QRect xRect = windowToWmGeometry(geometry());
+ const QRect rect = geometry();
+ QWindowPrivate *win = qt_window_private(window());
- QWindow *win = window();
+ if (!win->positionAutomatic)
+ xcb_size_hints_set_position(&hints, true, rect.x(), rect.y());
+ if (rect.width() < QWINDOWSIZE_MAX || rect.height() < QWINDOWSIZE_MAX)
+ xcb_size_hints_set_size(&hints, true, rect.width(), rect.height());
- if (!qt_window_private(win)->positionAutomatic)
- xcb_size_hints_set_position(&hints, true, xRect.x(), xRect.y());
- if (xRect.width() < QWINDOWSIZE_MAX || xRect.height() < QWINDOWSIZE_MAX)
- xcb_size_hints_set_size(&hints, true, xRect.width(), xRect.height());
- xcb_size_hints_set_win_gravity(&hints, m_gravity);
+ /* Gravity describes how to interpret x and y values the next time
+ window needs to be positioned on a screen.
+ XCB_GRAVITY_STATIC : the left top corner of the client window
+ XCB_GRAVITY_NORTH_WEST : the left top corner of the frame window */
+ auto gravity = win->positionPolicy == QWindowPrivate::WindowFrameInclusive
+ ? XCB_GRAVITY_NORTH_WEST : XCB_GRAVITY_STATIC;
+
+ xcb_size_hints_set_win_gravity(&hints, gravity);
QSize minimumSize = windowMinimumSize();
QSize maximumSize = windowMaximumSize();
@@ -1836,12 +1787,6 @@ void QXcbWindow::setWmWindowRole(const QByteArray &role)
role.size(), role.constData());
}
-void QXcbWindow::setParentRelativeBackPixmapStatic(QWindow *window)
-{
- if (window->handle())
- static_cast<QXcbWindow *>(window->handle())->setParentRelativeBackPixmap();
-}
-
void QXcbWindow::setParentRelativeBackPixmap()
{
const quint32 mask = XCB_CW_BACK_PIXMAP;
@@ -1849,14 +1794,7 @@ void QXcbWindow::setParentRelativeBackPixmap()
xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
}
-bool QXcbWindow::requestSystemTrayWindowDockStatic(const QWindow *window)
-{
- if (window->handle())
- return static_cast<QXcbWindow *>(window->handle())->requestSystemTrayWindowDock();
- return false;
-}
-
-bool QXcbWindow::requestSystemTrayWindowDock() const
+bool QXcbWindow::requestSystemTrayWindowDock()
{
if (!connection()->systemTrayTracker())
return false;
@@ -1864,81 +1802,34 @@ bool QXcbWindow::requestSystemTrayWindowDock() const
return true;
}
-QRect QXcbWindow::systemTrayWindowGlobalGeometryStatic(const QWindow *window)
-{
- if (window->handle())
- return static_cast<QXcbWindow *>(window->handle())->systemTrayWindowGlobalGeometry();
- return QRect();
-}
-
-QRect QXcbWindow::systemTrayWindowGlobalGeometry() const
-{
- if (!connection()->systemTrayTracker())
- return QRect();
- return connection()->systemTrayTracker()->systemTrayWindowGlobalGeometry(m_window);
-}
-
-class ExposeCompressor
-{
-public:
- ExposeCompressor(xcb_window_t window, QRegion *region)
- : m_window(window)
- , m_region(region)
- , m_pending(true)
- {
- }
-
- bool checkEvent(xcb_generic_event_t *event)
- {
- if (!event)
- return false;
- if ((event->response_type & ~0x80) != XCB_EXPOSE)
- return false;
- xcb_expose_event_t *expose = (xcb_expose_event_t *)event;
- if (expose->window != m_window)
- return false;
- if (expose->count == 0)
- m_pending = false;
- *m_region |= QRect(expose->x, expose->y, expose->width, expose->height);
- return true;
- }
-
- bool pending() const
- {
- return m_pending;
- }
-
-private:
- xcb_window_t m_window;
- QRegion *m_region;
- bool m_pending;
-};
-
-bool QXcbWindow::compressExposeEvent(QRegion &exposeRegion)
-{
- ExposeCompressor compressor(m_window, &exposeRegion);
- xcb_generic_event_t *filter = 0;
- do {
- filter = connection()->checkEvent(compressor);
- free(filter);
- } while (filter);
- return compressor.pending();
-}
-
-bool QXcbWindow::handleGenericEvent(xcb_generic_event_t *event, long *result)
+bool QXcbWindow::handleNativeEvent(xcb_generic_event_t *event)
{
- return QWindowSystemInterface::handleNativeEvent(window(),
- connection()->nativeInterface()->genericEventFilterType(),
- event,
- result);
+ auto eventType = connection()->nativeInterface()->nativeEventType();
+ long result = 0; // Used only by MS Windows
+ return QWindowSystemInterface::handleNativeEvent(window(), eventType, event, &result);
}
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
QRect rect(event->x, event->y, event->width, event->height);
-
m_exposeRegion |= rect;
- bool pending = compressExposeEvent(m_exposeRegion);
+
+ bool pending = true;
+ xcb_generic_event_t *e = nullptr;
+ do { // compress expose events
+ e = connection()->checkEvent([this, &pending](xcb_generic_event_t *event, int type) {
+ if (type != XCB_EXPOSE)
+ return false;
+ auto expose = reinterpret_cast<xcb_expose_event_t *>(event);
+ if (expose->window != m_window)
+ return false;
+ if (expose->count == 0)
+ pending = false;
+ m_exposeRegion |= QRect(expose->x, expose->y, expose->width, expose->height);
+ return true;
+ });
+ free(e);
+ } while (e);
// if count is non-zero there are more expose events pending
if (event->count == 0 || !pending) {
@@ -1977,7 +1868,7 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
connection()->setTime(event->data.data32[1]);
m_syncValue.lo = event->data.data32[2];
m_syncValue.hi = event->data.data32[3];
- if (m_usingSyncProtocol)
+ if (connection()->hasXSync())
m_syncState = SyncReceived;
#ifndef QT_NO_WHATSTHIS
} else if (protocolAtom == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) {
@@ -2052,7 +1943,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
}
m_oldWindowSize = actualGeometry.size();
- if (m_usingSyncProtocol && m_syncState == SyncReceived)
+ if (connection()->hasXSync() && m_syncState == SyncReceived)
m_syncState = SyncAndConfigureReceived;
m_dirtyFrameMargins = true;
@@ -2137,7 +2028,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
updateNetWmUserTime(timestamp);
- if (m_embedded) {
+ if (m_embedded && !m_trayIconWindow) {
if (window() != QGuiApplication::focusWindow()) {
const QXcbWindow *container = static_cast<const QXcbWindow *>(parent());
Q_ASSERT(container != 0);
@@ -2149,7 +2040,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
QPoint global(root_x, root_y);
if (isWheel) {
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
if (!connection()->isAtLeastXI21()) {
#endif
QPoint angleDelta;
@@ -2164,7 +2055,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
if (modifiers & Qt::AltModifier)
std::swap(angleDelta.rx(), angleDelta.ry());
QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, QPoint(), angleDelta, modifiers);
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
}
#endif
return;
@@ -2204,7 +2095,7 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn)
if (conn) {
const bool mouseButtonsPressed = (conn->buttonState() != Qt::NoButton);
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
return mouseButtonsPressed || (conn->hasXInput2() && !conn->xi2MouseEventsDisabled());
#else
return mouseButtonsPressed;
@@ -2231,24 +2122,6 @@ static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn =
|| detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
}
-class EnterEventChecker
-{
-public:
- bool checkEvent(xcb_generic_event_t *event)
- {
- if (!event)
- return false;
- if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY)
- return false;
-
- xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event;
- if (ignoreEnterEvent(enter->mode, enter->detail))
- return false;
-
- return true;
- }
-};
-
void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y,
quint8 mode, quint8 detail, xcb_timestamp_t timestamp)
{
@@ -2258,7 +2131,7 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in
if (ignoreEnterEvent(mode, detail, connection()) || connection()->mousePressWindow())
return;
-#ifdef XCB_USE_XINPUT21
+#if QT_CONFIG(xcb_xinput)
// Updates scroll valuators, as user might have done some scrolling outside our X client.
connection()->xi2UpdateScrollingDevices();
#endif
@@ -2275,9 +2148,17 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y,
if (ignoreLeaveEvent(mode, detail, connection()) || connection()->mousePressWindow())
return;
- EnterEventChecker checker;
- xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker);
- QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0;
+ // check if enter event is buffered
+ auto event = connection()->checkEvent([](xcb_generic_event_t *event, int type) {
+ if (type != XCB_ENTER_NOTIFY)
+ return false;
+ auto enter = reinterpret_cast<xcb_enter_notify_event_t *>(event);
+ if (ignoreEnterEvent(enter->mode, enter->detail))
+ return false;
+ return true;
+ });
+ auto enter = reinterpret_cast<xcb_enter_notify_event_t *>(event);
+ QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : nullptr;
if (enterWindow) {
QPoint local(enter->event_x, enter->event_y);
@@ -2330,16 +2211,18 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
event->time, QEvent::MouseMove);
}
-#if QT_CONFIG(xinput2)
-static inline int fixed1616ToInt(FP1616 val)
+#if QT_CONFIG(xcb_xinput)
+static inline int fixed1616ToInt(xcb_input_fp1616_t val)
{
return int(qreal(val) / 0x10000);
}
+#define qt_xcb_mask_is_set(ptr, event) (((unsigned char*)(ptr))[(event)>>3] & (1 << ((event) & 7)))
+
void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source)
{
QXcbConnection *conn = connection();
- xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
+ auto *ev = reinterpret_cast<xcb_input_button_press_event_t *>(event);
if (ev->buttons_len > 0) {
unsigned char *buttonMask = (unsigned char *) &ev[1];
@@ -2347,16 +2230,16 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
// XIPointerEmulated being set: https://bugs.freedesktop.org/show_bug.cgi?id=98188
// Filter them out by other attributes: when their source device is a touch screen
// and the LMB is pressed.
- if (XIMaskIsSet(buttonMask, 1) && conn->isTouchScreen(ev->sourceid)) {
+ if (qt_xcb_mask_is_set(buttonMask, 1) && conn->isTouchScreen(ev->sourceid)) {
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInput, "XI2 mouse event from touch device %d was ignored", ev->sourceid);
return;
}
for (int i = 1; i <= 15; ++i)
- conn->setButtonState(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i));
+ conn->setButtonState(conn->translateMouseButton(i), qt_xcb_mask_is_set(buttonMask, i));
}
- const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods);
+ const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective);
const int event_x = fixed1616ToInt(ev->event_x);
const int event_y = fixed1616ToInt(ev->event_y);
const int root_x = fixed1616ToInt(ev->root_x);
@@ -2373,47 +2256,47 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
sourceName = me.valueToKey(source);
}
- switch (ev->evtype) {
- case XI_ButtonPress:
+ switch (ev->event_type) {
+ case XCB_INPUT_BUTTON_PRESS:
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName);
conn->setButtonState(button, true);
handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonPress, source);
break;
- case XI_ButtonRelease:
+ case XCB_INPUT_BUTTON_RELEASE:
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName);
conn->setButtonState(button, false);
handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonRelease, source);
break;
- case XI_Motion:
+ case XCB_INPUT_MOTION:
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName);
handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, QEvent::MouseMove, source);
break;
default:
- qWarning() << "Unrecognized XI2 mouse event" << ev->evtype;
+ qWarning() << "Unrecognized XI2 mouse event" << ev->event_type;
break;
}
}
void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
{
- xXIEnterEvent *ev = reinterpret_cast<xXIEnterEvent *>(event);
+ auto *ev = reinterpret_cast<xcb_input_enter_event_t *>(event);
// Compare the window with current mouse grabber to prevent deliver events to any other windows.
// If leave event occurs and the window is under mouse - allow to deliver the leave event.
QXcbWindow *mouseGrabber = connection()->mouseGrabber();
if (mouseGrabber && mouseGrabber != this
- && (ev->evtype != XI_Leave || QGuiApplicationPrivate::currentMouseWindow != window())) {
+ && (ev->event_type != XCB_INPUT_LEAVE || QGuiApplicationPrivate::currentMouseWindow != window())) {
return;
}
const int root_x = fixed1616ToInt(ev->root_x);
const int root_y = fixed1616ToInt(ev->root_y);
- switch (ev->evtype) {
- case XI_Enter: {
+ switch (ev->event_type) {
+ case XCB_INPUT_ENTER: {
const int event_x = fixed1616ToInt(ev->event_x);
const int event_y = fixed1616ToInt(ev->event_y);
qCDebug(lcQpaXInputEvents, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d",
@@ -2421,7 +2304,7 @@ void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time);
break;
}
- case XI_Leave:
+ case XCB_INPUT_LEAVE:
qCDebug(lcQpaXInputEvents, "XI2 mouse leave, mode %d, detail %d, time %d",
ev->mode, ev->detail, ev->time);
connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group);
@@ -2523,7 +2406,7 @@ void QXcbWindow::updateSyncRequestCounter()
// window manager does not expect a sync event yet.
return;
}
- if (m_usingSyncProtocol && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
+ if (connection()->hasXSync() && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue);
xcb_flush(xcb_connection());
@@ -2563,7 +2446,7 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
if (grab && !connection()->canGrab())
return false;
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
if (connection()->hasXInput2() && !connection()->xi2MouseEventsDisabled()) {
bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab);
if (grab && result)
@@ -2591,11 +2474,11 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
return result;
}
-void QXcbWindow::windowEvent(QEvent *event)
+bool QXcbWindow::windowEvent(QEvent *event)
{
switch (event->type()) {
case QEvent::FocusIn:
- if (m_embedded && !event->spontaneous()) {
+ if (m_embedded && !m_trayIconWindow && !event->spontaneous()) {
QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
switch (focusEvent->reason()) {
case Qt::TabFocusReason:
@@ -2617,7 +2500,7 @@ void QXcbWindow::windowEvent(QEvent *event)
default:
break;
}
- QPlatformWindow::windowEvent(event);
+ return QPlatformWindow::windowEvent(event);
}
bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
@@ -2638,7 +2521,7 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
return false;
const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
-#ifdef XCB_USE_XINPUT22
+#if QT_CONFIG(xcb_xinput)
// ### FIXME QTBUG-53389
bool startedByTouch = connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner);
if (startedByTouch) {
@@ -2659,6 +2542,7 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
return true;
}
+
void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner)
{
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
@@ -2728,11 +2612,6 @@ void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event)
case XEMBED_EMBEDDED_NOTIFY:
xcb_map_window(xcb_connection(), m_window);
xcbScreen()->windowShown(this);
- // Without Qt::WA_TranslucentBackground, we use a ParentRelative BackPixmap.
- // Clear the whole tray icon window to its background color as early as possible
- // so that we can get a clean result from grabWindow() later.
- xcb_clear_area(xcb_connection(), false, m_window, 0, 0, geometry().width(), geometry().height());
- xcb_flush(xcb_connection());
break;
case XEMBED_FOCUS_IN:
Qt::FocusReason reason;
@@ -2846,6 +2725,28 @@ QXcbScreen *QXcbWindow::xcbScreen() const
return static_cast<QXcbScreen *>(screen());
}
+void QXcbWindow::setWindowTitle(const QXcbConnection *conn, xcb_window_t window, const QString &title)
+{
+ QString fullTitle = formatWindowTitle(title, QString::fromUtf8(" \xe2\x80\x94 ")); // unicode character U+2014, EM DASH
+ const QByteArray ba = std::move(fullTitle).toUtf8();
+ xcb_change_property(conn->xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ window,
+ conn->atom(QXcbAtom::_NET_WM_NAME),
+ conn->atom(QXcbAtom::UTF8_STRING),
+ 8,
+ ba.length(),
+ ba.constData());
+
+#if QT_CONFIG(xcb_xlib)
+ Display *dpy = static_cast<Display *>(conn->xlib_display());
+ XTextProperty *text = qstringToXTP(dpy, title);
+ if (text)
+ XSetWMName(dpy, window, text);
+#endif
+ xcb_flush(conn->xcb_connection());
+}
+
QString QXcbWindow::windowTitle(const QXcbConnection *conn, xcb_window_t window)
{
const xcb_atom_t utf8Atom = conn->atom(QXcbAtom::UTF8_STRING);
@@ -2856,6 +2757,15 @@ QString QXcbWindow::windowTitle(const QXcbConnection *conn, xcb_window_t window)
const char *name = reinterpret_cast<const char *>(xcb_get_property_value(reply.get()));
return QString::fromUtf8(name, xcb_get_property_value_length(reply.get()));
}
+
+ reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, conn->xcb_connection(),
+ false, window, conn->atom(QXcbAtom::WM_NAME),
+ XCB_ATOM_STRING, 0, 1024);
+ if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) {
+ const char *name = reinterpret_cast<const char *>(xcb_get_property_value(reply.get()));
+ return QString::fromLatin1(name, xcb_get_property_value_length(reply.get()));
+ }
+
return QString();
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index c4f49c593c..99e8e40725 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -105,7 +105,7 @@ public:
QSurfaceFormat format() const override;
- void windowEvent(QEvent *event) override;
+ bool windowEvent(QEvent *event) override;
bool startSystemResize(const QPoint &pos, Qt::Corner corner) override;
bool startSystemMove(const QPoint &pos) override;
@@ -121,7 +121,7 @@ public:
QImage::Format imageFormat() const { return m_imageFormat; }
bool imageNeedsRgbSwap() const { return m_imageRgbSwap; }
- bool handleGenericEvent(xcb_generic_event_t *event, long *result) override;
+ bool handleNativeEvent(xcb_generic_event_t *event) override;
void handleExposeEvent(const xcb_expose_event_t *event) override;
void handleClientMessageEvent(const xcb_client_message_event_t *event) override;
@@ -137,7 +137,7 @@ public:
void handleFocusInEvent(const xcb_focus_in_event_t *event) override;
void handleFocusOutEvent(const xcb_focus_out_event_t *event) override;
void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override;
-#if QT_CONFIG(xinput2)
+#if QT_CONFIG(xcb_xinput)
void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) override;
void handleXIEnterLeave(xcb_ge_event_t *) override;
#endif
@@ -159,14 +159,8 @@ public:
static void setWindowIconTextStatic(QWindow *window, const QString &text);
- static void setParentRelativeBackPixmapStatic(QWindow *window);
void setParentRelativeBackPixmap();
-
- static bool requestSystemTrayWindowDockStatic(const QWindow *window);
- bool requestSystemTrayWindowDock() const;
-
- static QRect systemTrayWindowGlobalGeometryStatic(const QWindow *window);
- QRect systemTrayWindowGlobalGeometry() const;
+ bool requestSystemTrayWindowDock();
uint visualId() const;
bool needsSync() const;
@@ -179,9 +173,12 @@ public:
bool startSystemMoveResize(const QPoint &pos, int corner);
void doStartSystemMoveResize(const QPoint &globalPos, int corner);
+ bool isTrayIconWindow() const { return m_trayIconWindow; }
+
virtual void create();
virtual void destroy();
+ static void setWindowTitle(const QXcbConnection *conn, xcb_window_t window, const QString &title);
static QString windowTitle(const QXcbConnection *conn, xcb_window_t window);
public Q_SLOTS:
@@ -220,8 +217,6 @@ protected:
void doFocusIn();
void doFocusOut();
- bool compressExposeEvent(QRegion &exposeRegion);
-
void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y,
int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
QEvent::Type type, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
@@ -252,15 +247,13 @@ protected:
Qt::WindowStates m_windowState = Qt::WindowNoState;
- xcb_gravity_t m_gravity = XCB_GRAVITY_STATIC;
-
bool m_mapped = false;
bool m_transparent = false;
- bool m_usingSyncProtocol = false;
bool m_deferredActivation = false;
bool m_embedded = false;
bool m_alertState = false;
bool m_minimized = false;
+ bool m_trayIconWindow = false;
xcb_window_t m_netWmUserTimeWindow = XCB_NONE;
QSurfaceFormat m_format;
diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
index 20d8b83e7c..078b275381 100644
--- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
+++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
@@ -2,7 +2,7 @@
# Statically compile in code for
# libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image,
# libxcb-keysyms, libxcb-icccm, libxcb-renderutil, libxcb-xkb,
-# libxcb-xinerama
+# libxcb-xinerama, libxcb-xinput
#
CONFIG += static
@@ -29,7 +29,8 @@ SOURCES += \
$$LIBXCB_DIR/render.c \
$$LIBXCB_DIR/shape.c \
$$LIBXCB_DIR/xkb.c \
- $$LIBXCB_DIR/xinerama.c
+ $$LIBXCB_DIR/xinerama.c \
+ $$LIBXCB_DIR/xinput.c
#
# xcb-util
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index 9c4797ac26..9390d04983 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -58,11 +58,10 @@ DEFINES += QT_BUILD_XCB_PLUGIN
qtConfig(xcb-xlib) {
QMAKE_USE += xcb_xlib
+}
- qtConfig(xinput2) {
- SOURCES += qxcbconnection_xi2.cpp
- QMAKE_USE += xinput2
- }
+qtConfig(xcb-xinput) {
+ SOURCES += qxcbconnection_xi2.cpp
}
qtConfig(xcb-sm) {
@@ -89,6 +88,7 @@ qtConfig(vulkan) {
} else {
qtConfig(xkb): QMAKE_USE += xcb_xkb
qtConfig(xcb-render): QMAKE_USE += xcb_render
+ qtConfig(xcb-xinput): QMAKE_USE += xcb_xinput
QMAKE_USE += xcb_syslibs
}
diff --git a/src/plugins/platformthemes/flatpak/flatpak.json b/src/plugins/platformthemes/flatpak/flatpak.json
deleted file mode 100644
index 71f834fd08..0000000000
--- a/src/plugins/platformthemes/flatpak/flatpak.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": [ "flatpak" ]
-}
diff --git a/src/plugins/platformthemes/flatpak/flatpak.pro b/src/plugins/platformthemes/flatpak/flatpak.pro
deleted file mode 100644
index 1e5dbb7a6c..0000000000
--- a/src/plugins/platformthemes/flatpak/flatpak.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-TARGET = qflatpak
-
-PLUGIN_TYPE = platformthemes
-PLUGIN_EXTENDS = -
-PLUGIN_CLASS_NAME = QFlatpakThemePlugin
-load(qt_plugin)
-
-QT += core-private dbus gui-private theme_support-private
-
-HEADERS += \
- qflatpaktheme.h \
- qflatpakfiledialog_p.h
-
-SOURCES += \
- main.cpp \
- qflatpaktheme.cpp \
- qflatpakfiledialog.cpp
diff --git a/src/plugins/platformthemes/flatpak/main.cpp b/src/plugins/platformthemes/flatpak/main.cpp
deleted file mode 100644
index 7888eed8b2..0000000000
--- a/src/plugins/platformthemes/flatpak/main.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Red Hat, Inc
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qpa/qplatformthemeplugin.h>
-#include "qflatpaktheme.h"
-
-QT_BEGIN_NAMESPACE
-
-class QFlatpakThemePlugin : public QPlatformThemePlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "flatpak.json")
-
-public:
- QPlatformTheme *create(const QString &key, const QStringList &params) override;
-};
-
-QPlatformTheme *QFlatpakThemePlugin::create(const QString &key, const QStringList &params)
-{
- Q_UNUSED(params);
- if (!key.compare(QLatin1String("flatpak"), Qt::CaseInsensitive))
- return new QFlatpakTheme;
-
- return nullptr;
-}
-
-QT_END_NAMESPACE
-
-#include "main.moc"
diff --git a/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp b/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp
deleted file mode 100644
index c31b326357..0000000000
--- a/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Red Hat, Inc
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qflatpakfiledialog_p.h"
-
-#include <QtCore/qeventloop.h>
-
-#include <QtDBus/QtDBus>
-#include <QDBusConnection>
-#include <QDBusMessage>
-#include <QDBusPendingCall>
-#include <QDBusPendingCallWatcher>
-#include <QDBusPendingReply>
-
-#include <QMetaType>
-#include <QMimeType>
-#include <QMimeDatabase>
-#include <QRandomGenerator>
-#include <QWindow>
-
-QT_BEGIN_NAMESPACE
-
-QDBusArgument &operator <<(QDBusArgument &arg, const QFlatpakFileDialog::FilterCondition &filterCondition)
-{
- arg.beginStructure();
- arg << filterCondition.type << filterCondition.pattern;
- arg.endStructure();
- return arg;
-}
-
-const QDBusArgument &operator >>(const QDBusArgument &arg, QFlatpakFileDialog::FilterCondition &filterCondition)
-{
- uint type;
- QString filterPattern;
- arg.beginStructure();
- arg >> type >> filterPattern;
- filterCondition.type = (QFlatpakFileDialog::ConditionType)type;
- filterCondition.pattern = filterPattern;
- arg.endStructure();
-
- return arg;
-}
-
-QDBusArgument &operator <<(QDBusArgument &arg, const QFlatpakFileDialog::Filter filter)
-{
- arg.beginStructure();
- arg << filter.name << filter.filterConditions;
- arg.endStructure();
- return arg;
-}
-
-const QDBusArgument &operator >>(const QDBusArgument &arg, QFlatpakFileDialog::Filter &filter)
-{
- QString name;
- QFlatpakFileDialog::FilterConditionList filterConditions;
- arg.beginStructure();
- arg >> name >> filterConditions;
- filter.name = name;
- filter.filterConditions = filterConditions;
- arg.endStructure();
-
- return arg;
-}
-
-class QFlatpakFileDialogPrivate
-{
-public:
- WId winId = 0;
- bool modal = false;
- bool multipleFiles = false;
- bool saveFile = false;
- QString acceptLabel;
- QString directory;
- QString title;
- QStringList nameFilters;
- QStringList mimeTypesFilters;
- QStringList selectedFiles;
-};
-
-QFlatpakFileDialog::QFlatpakFileDialog()
- : QPlatformFileDialogHelper()
- , d_ptr(new QFlatpakFileDialogPrivate)
-{
-}
-
-QFlatpakFileDialog::~QFlatpakFileDialog()
-{
-}
-
-void QFlatpakFileDialog::initializeDialog()
-{
- Q_D(QFlatpakFileDialog);
-
- if (options()->fileMode() == QFileDialogOptions::ExistingFiles)
- d->multipleFiles = true;
-
- if (options()->isLabelExplicitlySet(QFileDialogOptions::Accept))
- d->acceptLabel = options()->labelText(QFileDialogOptions::Accept);
-
- if (!options()->windowTitle().isEmpty())
- d->title = options()->windowTitle();
-
- if (options()->acceptMode() == QFileDialogOptions::AcceptSave)
- d->saveFile = true;
-
- if (!options()->nameFilters().isEmpty())
- d->nameFilters = options()->nameFilters();
-
- if (!options()->mimeTypeFilters().isEmpty())
- d->mimeTypesFilters = options()->mimeTypeFilters();
-
- setDirectory(options()->initialDirectory());
-}
-
-void QFlatpakFileDialog::openPortal()
-{
- Q_D(const QFlatpakFileDialog);
-
- QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),
- QLatin1String("/org/freedesktop/portal/desktop"),
- QLatin1String("org.freedesktop.portal.FileChooser"),
- d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
- QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId);
-
- QVariantMap options;
- if (!d->acceptLabel.isEmpty())
- options.insert(QLatin1String("accept_label"), d->acceptLabel);
-
- options.insert(QLatin1String("modal"), d->modal);
- options.insert(QLatin1String("multiple"), d->multipleFiles);
-
- if (d->saveFile) {
- if (!d->directory.isEmpty())
- options.insert(QLatin1String("current_folder"), d->directory.toLatin1());
-
- if (!d->selectedFiles.isEmpty())
- options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1());
- }
-
- // Insert filters
- qDBusRegisterMetaType<FilterCondition>();
- qDBusRegisterMetaType<FilterConditionList>();
- qDBusRegisterMetaType<Filter>();
- qDBusRegisterMetaType<FilterList>();
-
- FilterList filterList;
-
- if (!d->mimeTypesFilters.isEmpty()) {
- for (const QString &mimeTypefilter : d->mimeTypesFilters) {
- QMimeDatabase mimeDatabase;
- QMimeType mimeType = mimeDatabase.mimeTypeForName(mimeTypefilter);
-
- // Creates e.g. (1, "image/png")
- FilterCondition filterCondition;
- filterCondition.type = MimeType;
- filterCondition.pattern = mimeTypefilter;
-
- // Creates e.g. [((1, "image/png"))]
- FilterConditionList filterConditions;
- filterConditions << filterCondition;
-
- // Creates e.g. [("Images", [((1, "image/png"))])]
- Filter filter;
- filter.name = mimeType.comment();
- filter.filterConditions = filterConditions;
-
- filterList << filter;
- }
- } else if (!d->nameFilters.isEmpty()) {
- for (const QString &filter : d->nameFilters) {
- // Do parsing:
- // Supported format is ("Images (*.png *.jpg)")
- QRegularExpression regexp(QPlatformFileDialogHelper::filterRegExp);
- QRegularExpressionMatch match = regexp.match(filter);
- if (match.hasMatch()) {
- QString userVisibleName = match.captured(1);
- QStringList filterStrings = match.captured(2).split(QLatin1Char(' '), QString::SkipEmptyParts);
-
- FilterConditionList filterConditions;
- for (const QString &filterString : filterStrings) {
- FilterCondition filterCondition;
- filterCondition.type = GlobalPattern;
- filterCondition.pattern = filterString;
- filterConditions << filterCondition;
- }
-
- Filter filter;
- filter.name = userVisibleName;
- filter.filterConditions = filterConditions;
-
- filterList << filter;
- }
- }
- }
-
- if (!filterList.isEmpty())
- options.insert(QLatin1String("filters"), QVariant::fromValue(filterList));
-
- options.insert(QLatin1String("handle_token"), QStringLiteral("qt%1").arg(QRandomGenerator::global()->generate()));
-
- // TODO choices a(ssa(ss)s)
- // List of serialized combo boxes to add to the file chooser.
-
- message << parentWindowId << d->title << options;
-
- QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
- connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
- QDBusPendingReply<QDBusObjectPath> reply = *watcher;
- if (reply.isError()) {
- Q_EMIT reject();
- } else {
- QDBusConnection::sessionBus().connect(nullptr,
- reply.value().path(),
- QLatin1String("org.freedesktop.portal.Request"),
- QLatin1String("Response"),
- this,
- SLOT(gotResponse(uint,QVariantMap)));
- }
- });
-}
-
-bool QFlatpakFileDialog::defaultNameFilterDisables() const
-{
- return false;
-}
-
-void QFlatpakFileDialog::setDirectory(const QUrl &directory)
-{
- Q_D(QFlatpakFileDialog);
-
- d->directory = directory.path();
-}
-
-QUrl QFlatpakFileDialog::directory() const
-{
- Q_D(const QFlatpakFileDialog);
-
- return d->directory;
-}
-
-void QFlatpakFileDialog::selectFile(const QUrl &filename)
-{
- Q_D(QFlatpakFileDialog);
-
- d->selectedFiles << filename.path();
-}
-
-QList<QUrl> QFlatpakFileDialog::selectedFiles() const
-{
- Q_D(const QFlatpakFileDialog);
-
- QList<QUrl> files;
- for (const QString &file : d->selectedFiles) {
- files << QUrl(file);
- }
- return files;
-}
-
-void QFlatpakFileDialog::setFilter()
-{
- // TODO
-}
-
-void QFlatpakFileDialog::selectNameFilter(const QString &filter)
-{
- Q_UNUSED(filter);
- // TODO
-}
-
-QString QFlatpakFileDialog::selectedNameFilter() const
-{
- // TODO
- return QString();
-}
-
-void QFlatpakFileDialog::exec()
-{
- // HACK we have to avoid returning until we emit that the dialog was accepted or rejected
- QEventLoop loop;
- loop.connect(this, SIGNAL(accept()), SLOT(quit()));
- loop.connect(this, SIGNAL(reject()), SLOT(quit()));
- loop.exec();
-}
-
-void QFlatpakFileDialog::hide()
-{
-}
-
-bool QFlatpakFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
-{
- Q_D(QFlatpakFileDialog);
- Q_UNUSED(windowFlags);
-
- initializeDialog();
-
- d->modal = windowModality != Qt::NonModal;
- d->winId = parent ? parent->winId() : 0;
-
- openPortal();
-
- return true;
-}
-
-void QFlatpakFileDialog::gotResponse(uint response, const QVariantMap &results)
-{
- Q_D(QFlatpakFileDialog);
-
- if (!response) {
- if (results.contains(QLatin1String("uris")))
- d->selectedFiles = results.value(QLatin1String("uris")).toStringList();
-
- Q_EMIT accept();
- } else {
- Q_EMIT reject();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h b/src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h
deleted file mode 100644
index f3e195faa0..0000000000
--- a/src/plugins/platformthemes/flatpak/qflatpakfiledialog_p.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Red Hat, Inc
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QFLATPAKFILEDIALOG_P_H
-#define QFLATPAKFILEDIALOG_P_H
-
-#include <qpa/qplatformdialoghelper.h>
-#include <QVector>
-
-QT_BEGIN_NAMESPACE
-
-class QFlatpakFileDialogPrivate;
-
-class QFlatpakFileDialog : public QPlatformFileDialogHelper
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QFlatpakFileDialog)
-public:
- enum ConditionType : uint {
- GlobalPattern = 0,
- MimeType = 1
- };
- // Filters a(sa(us))
- // Example: [('Images', [(0, '*.ico'), (1, 'image/png')]), ('Text', [(0, '*.txt')])]
- struct FilterCondition {
- ConditionType type;
- QString pattern; // E.g. '*ico' or 'image/png'
- };
- typedef QVector<FilterCondition> FilterConditionList;
-
- struct Filter {
- QString name; // E.g. 'Images' or 'Text
- FilterConditionList filterConditions;; // E.g. [(0, '*.ico'), (1, 'image/png')] or [(0, '*.txt')]
- };
- typedef QVector<Filter> FilterList;
-
- QFlatpakFileDialog();
- ~QFlatpakFileDialog();
-
- bool defaultNameFilterDisables() const override;
- QUrl directory() const override;
- void setDirectory(const QUrl &directory) override;
- void selectFile(const QUrl &filename) override;
- QList<QUrl> selectedFiles() const override;
- void setFilter() override;
- void selectNameFilter(const QString &filter) override;
- QString selectedNameFilter() const override;
-
- void exec() override;
- bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
- void hide() override;
-
-private Q_SLOTS:
- void gotResponse(uint response, const QVariantMap &results);
-
-private:
- void initializeDialog();
- void openPortal();
-
- QScopedPointer<QFlatpakFileDialogPrivate> d_ptr;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterCondition);
-Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterConditionList);
-Q_DECLARE_METATYPE(QFlatpakFileDialog::Filter);
-Q_DECLARE_METATYPE(QFlatpakFileDialog::FilterList);
-
-#endif // QFLATPAKFILEDIALOG_P_H
-
diff --git a/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp b/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp
deleted file mode 100644
index 6c5e1389cf..0000000000
--- a/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qflatpaktheme.h"
-#include "qflatpakfiledialog_p.h"
-
-#include <private/qguiapplication_p.h>
-#include <qpa/qplatformtheme_p.h>
-#include <qpa/qplatformthemefactory_p.h>
-#include <qpa/qplatformintegration.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFlatpakThemePrivate : public QPlatformThemePrivate
-{
-public:
- QFlatpakThemePrivate()
- : QPlatformThemePrivate()
- { }
-
- ~QFlatpakThemePrivate()
- {
- delete baseTheme;
- }
-
- QPlatformTheme *baseTheme;
-};
-
-QFlatpakTheme::QFlatpakTheme()
- : d_ptr(new QFlatpakThemePrivate)
-{
- Q_D(QFlatpakTheme);
-
- QStringList themeNames;
- themeNames += QGuiApplicationPrivate::platform_integration->themeNames();
- // 1) Look for a theme plugin.
- for (const QString &themeName : qAsConst(themeNames)) {
- d->baseTheme = QPlatformThemeFactory::create(themeName, nullptr);
- if (d->baseTheme)
- break;
- }
-
- // 2) If no theme plugin was found ask the platform integration to
- // create a theme
- if (!d->baseTheme) {
- for (const QString &themeName : qAsConst(themeNames)) {
- d->baseTheme = QGuiApplicationPrivate::platform_integration->createPlatformTheme(themeName);
- if (d->baseTheme)
- break;
- }
- // No error message; not having a theme plugin is allowed.
- }
-
- // 3) Fall back on the built-in "null" platform theme.
- if (!d->baseTheme)
- d->baseTheme = new QPlatformTheme;
-}
-
-QPlatformMenuItem* QFlatpakTheme::createPlatformMenuItem() const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->createPlatformMenuItem();
-}
-
-QPlatformMenu* QFlatpakTheme::createPlatformMenu() const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->createPlatformMenu();
-}
-
-QPlatformMenuBar* QFlatpakTheme::createPlatformMenuBar() const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->createPlatformMenuBar();
-}
-
-void QFlatpakTheme::showPlatformMenuBar()
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->showPlatformMenuBar();
-}
-
-bool QFlatpakTheme::usePlatformNativeDialog(DialogType type) const
-{
- Q_D(const QFlatpakTheme);
-
- if (type == FileDialog)
- return true;
-
- return d->baseTheme->usePlatformNativeDialog(type);
-}
-
-QPlatformDialogHelper* QFlatpakTheme::createPlatformDialogHelper(DialogType type) const
-{
- Q_D(const QFlatpakTheme);
-
- if (type == FileDialog)
- return new QFlatpakFileDialog;
-
- return d->baseTheme->createPlatformDialogHelper(type);
-}
-
-#ifndef QT_NO_SYSTEMTRAYICON
-QPlatformSystemTrayIcon* QFlatpakTheme::createPlatformSystemTrayIcon() const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->createPlatformSystemTrayIcon();
-}
-#endif
-
-const QPalette *QFlatpakTheme::palette(Palette type) const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->palette(type);
-}
-
-const QFont* QFlatpakTheme::font(Font type) const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->font(type);
-}
-
-QVariant QFlatpakTheme::themeHint(ThemeHint hint) const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->themeHint(hint);
-}
-
-QPixmap QFlatpakTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->standardPixmap(sp, size);
-}
-
-QIcon QFlatpakTheme::fileIcon(const QFileInfo &fileInfo,
- QPlatformTheme::IconOptions iconOptions) const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->fileIcon(fileInfo, iconOptions);
-}
-
-QIconEngine * QFlatpakTheme::createIconEngine(const QString &iconName) const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->createIconEngine(iconName);
-}
-
-QList<QKeySequence> QFlatpakTheme::keyBindings(QKeySequence::StandardKey key) const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->keyBindings(key);
-}
-
-QString QFlatpakTheme::standardButtonText(int button) const
-{
- Q_D(const QFlatpakTheme);
- return d->baseTheme->standardButtonText(button);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platformthemes/flatpak/qflatpaktheme.h b/src/plugins/platformthemes/flatpak/qflatpaktheme.h
deleted file mode 100644
index 87f79a2395..0000000000
--- a/src/plugins/platformthemes/flatpak/qflatpaktheme.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFLATPAKTHEME_H
-#define QFLATPAKTHEME_H
-
-#include <qpa/qplatformtheme.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFlatpakThemePrivate;
-
-class QFlatpakTheme : public QPlatformTheme
-{
- Q_DECLARE_PRIVATE(QFlatpakTheme)
-public:
- QFlatpakTheme();
-
- QPlatformMenuItem *createPlatformMenuItem() const override;
- QPlatformMenu *createPlatformMenu() const override;
- QPlatformMenuBar *createPlatformMenuBar() const override;
- void showPlatformMenuBar() override;
-
- bool usePlatformNativeDialog(DialogType type) const override;
- QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
-
-#ifndef QT_NO_SYSTEMTRAYICON
- QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override;
-#endif
-
- const QPalette *palette(Palette type = SystemPalette) const override;
-
- const QFont *font(Font type = SystemFont) const override;
-
- QVariant themeHint(ThemeHint hint) const override;
-
- QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
- QIcon fileIcon(const QFileInfo &fileInfo,
- QPlatformTheme::IconOptions iconOptions = 0) const override;
-
- QIconEngine *createIconEngine(const QString &iconName) const override;
-
- QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const override;
-
- QString standardButtonText(int button) const override;
-
-private:
- QScopedPointer<QFlatpakThemePrivate> d_ptr;
- Q_DISABLE_COPY(QFlatpakTheme)
-};
-
-QT_END_NAMESPACE
-
-#endif // QFLATPAKTHEME_H
diff --git a/src/plugins/platformthemes/platformthemes.pro b/src/plugins/platformthemes/platformthemes.pro
index 17b1d91c6a..06ffc4cc9f 100644
--- a/src/plugins/platformthemes/platformthemes.pro
+++ b/src/plugins/platformthemes/platformthemes.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += widgets-private
-qtConfig(dbus):qtConfig(regularexpression): SUBDIRS += flatpak
+qtConfig(dbus):qtConfig(regularexpression): SUBDIRS += xdgdesktopportal
qtHaveModule(widgets):qtConfig(gtk3): SUBDIRS += gtk3
diff --git a/src/plugins/platformthemes/xdgdesktopportal/main.cpp b/src/plugins/platformthemes/xdgdesktopportal/main.cpp
new file mode 100644
index 0000000000..64a03d479f
--- /dev/null
+++ b/src/plugins/platformthemes/xdgdesktopportal/main.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2017-2018 Red Hat, Inc
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpa/qplatformthemeplugin.h>
+#include "qxdgdesktopportaltheme.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXdgDesktopPortalThemePlugin : public QPlatformThemePlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "xdgdesktopportal.json")
+
+public:
+ QPlatformTheme *create(const QString &key, const QStringList &params) override;
+};
+
+QPlatformTheme *QXdgDesktopPortalThemePlugin::create(const QString &key, const QStringList &params)
+{
+ Q_UNUSED(params);
+ if (!key.compare(QLatin1String("xdgdesktopportal"), Qt::CaseInsensitive) ||
+ !key.compare(QLatin1String("flatpak"), Qt::CaseInsensitive) ||
+ !key.compare(QLatin1String("snap"), Qt::CaseInsensitive))
+ return new QXdgDesktopPortalTheme;
+
+ return nullptr;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
new file mode 100644
index 0000000000..cda267d24b
--- /dev/null
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
@@ -0,0 +1,407 @@
+/****************************************************************************
+**
+** Copyright (C) 2017-2018 Red Hat, Inc
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxdgdesktopportalfiledialog_p.h"
+
+#include <QtCore/qeventloop.h>
+
+#include <QtDBus/QtDBus>
+#include <QDBusConnection>
+#include <QDBusMessage>
+#include <QDBusPendingCall>
+#include <QDBusPendingCallWatcher>
+#include <QDBusPendingReply>
+
+#include <QMetaType>
+#include <QMimeType>
+#include <QMimeDatabase>
+#include <QRandomGenerator>
+#include <QWindow>
+
+QT_BEGIN_NAMESPACE
+
+QDBusArgument &operator <<(QDBusArgument &arg, const QXdgDesktopPortalFileDialog::FilterCondition &filterCondition)
+{
+ arg.beginStructure();
+ arg << filterCondition.type << filterCondition.pattern;
+ arg.endStructure();
+ return arg;
+}
+
+const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFileDialog::FilterCondition &filterCondition)
+{
+ uint type;
+ QString filterPattern;
+ arg.beginStructure();
+ arg >> type >> filterPattern;
+ filterCondition.type = (QXdgDesktopPortalFileDialog::ConditionType)type;
+ filterCondition.pattern = filterPattern;
+ arg.endStructure();
+
+ return arg;
+}
+
+QDBusArgument &operator <<(QDBusArgument &arg, const QXdgDesktopPortalFileDialog::Filter filter)
+{
+ arg.beginStructure();
+ arg << filter.name << filter.filterConditions;
+ arg.endStructure();
+ return arg;
+}
+
+const QDBusArgument &operator >>(const QDBusArgument &arg, QXdgDesktopPortalFileDialog::Filter &filter)
+{
+ QString name;
+ QXdgDesktopPortalFileDialog::FilterConditionList filterConditions;
+ arg.beginStructure();
+ arg >> name >> filterConditions;
+ filter.name = name;
+ filter.filterConditions = filterConditions;
+ arg.endStructure();
+
+ return arg;
+}
+
+class QXdgDesktopPortalFileDialogPrivate
+{
+public:
+ QXdgDesktopPortalFileDialogPrivate(QPlatformFileDialogHelper *nativeFileDialog)
+ : nativeFileDialog(nativeFileDialog)
+ { }
+
+ WId winId = 0;
+ bool modal = false;
+ bool multipleFiles = false;
+ bool saveFile = false;
+ QString acceptLabel;
+ QString directory;
+ QString title;
+ QStringList nameFilters;
+ QStringList mimeTypesFilters;
+ QStringList selectedFiles;
+ QPlatformFileDialogHelper *nativeFileDialog = nullptr;
+};
+
+QXdgDesktopPortalFileDialog::QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog)
+ : QPlatformFileDialogHelper()
+ , d_ptr(new QXdgDesktopPortalFileDialogPrivate(nativeFileDialog))
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+ connect(d->nativeFileDialog, SIGNAL(accept()), this, SIGNAL(accept()));
+ connect(d->nativeFileDialog, SIGNAL(reject()), this, SIGNAL(reject()));
+ }
+}
+
+QXdgDesktopPortalFileDialog::~QXdgDesktopPortalFileDialog()
+{
+}
+
+void QXdgDesktopPortalFileDialog::initializeDialog()
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog)
+ d->nativeFileDialog->setOptions(options());
+
+ if (options()->fileMode() == QFileDialogOptions::ExistingFiles)
+ d->multipleFiles = true;
+
+ if (options()->isLabelExplicitlySet(QFileDialogOptions::Accept))
+ d->acceptLabel = options()->labelText(QFileDialogOptions::Accept);
+
+ if (!options()->windowTitle().isEmpty())
+ d->title = options()->windowTitle();
+
+ if (options()->acceptMode() == QFileDialogOptions::AcceptSave)
+ d->saveFile = true;
+
+ if (!options()->nameFilters().isEmpty())
+ d->nameFilters = options()->nameFilters();
+
+ if (!options()->mimeTypeFilters().isEmpty())
+ d->mimeTypesFilters = options()->mimeTypeFilters();
+
+ setDirectory(options()->initialDirectory());
+}
+
+void QXdgDesktopPortalFileDialog::openPortal()
+{
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+ QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.FileChooser"),
+ d->saveFile ? QLatin1String("SaveFile") : QLatin1String("OpenFile"));
+ QString parentWindowId = QLatin1String("x11:") + QString::number(d->winId);
+
+ QVariantMap options;
+ if (!d->acceptLabel.isEmpty())
+ options.insert(QLatin1String("accept_label"), d->acceptLabel);
+
+ options.insert(QLatin1String("modal"), d->modal);
+ options.insert(QLatin1String("multiple"), d->multipleFiles);
+
+ if (d->saveFile) {
+ if (!d->directory.isEmpty())
+ options.insert(QLatin1String("current_folder"), d->directory.toLatin1());
+
+ if (!d->selectedFiles.isEmpty())
+ options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1());
+ }
+
+ // Insert filters
+ qDBusRegisterMetaType<FilterCondition>();
+ qDBusRegisterMetaType<FilterConditionList>();
+ qDBusRegisterMetaType<Filter>();
+ qDBusRegisterMetaType<FilterList>();
+
+ FilterList filterList;
+
+ if (!d->mimeTypesFilters.isEmpty()) {
+ for (const QString &mimeTypefilter : d->mimeTypesFilters) {
+ QMimeDatabase mimeDatabase;
+ QMimeType mimeType = mimeDatabase.mimeTypeForName(mimeTypefilter);
+
+ // Creates e.g. (1, "image/png")
+ FilterCondition filterCondition;
+ filterCondition.type = MimeType;
+ filterCondition.pattern = mimeTypefilter;
+
+ // Creates e.g. [((1, "image/png"))]
+ FilterConditionList filterConditions;
+ filterConditions << filterCondition;
+
+ // Creates e.g. [("Images", [((1, "image/png"))])]
+ Filter filter;
+ filter.name = mimeType.comment();
+ filter.filterConditions = filterConditions;
+
+ filterList << filter;
+ }
+ } else if (!d->nameFilters.isEmpty()) {
+ for (const QString &filter : d->nameFilters) {
+ // Do parsing:
+ // Supported format is ("Images (*.png *.jpg)")
+ QRegularExpression regexp(QPlatformFileDialogHelper::filterRegExp);
+ QRegularExpressionMatch match = regexp.match(filter);
+ if (match.hasMatch()) {
+ QString userVisibleName = match.captured(1);
+ QStringList filterStrings = match.captured(2).split(QLatin1Char(' '), QString::SkipEmptyParts);
+
+ FilterConditionList filterConditions;
+ for (const QString &filterString : filterStrings) {
+ FilterCondition filterCondition;
+ filterCondition.type = GlobalPattern;
+ filterCondition.pattern = filterString;
+ filterConditions << filterCondition;
+ }
+
+ Filter filter;
+ filter.name = userVisibleName;
+ filter.filterConditions = filterConditions;
+
+ filterList << filter;
+ }
+ }
+ }
+
+ if (!filterList.isEmpty())
+ options.insert(QLatin1String("filters"), QVariant::fromValue(filterList));
+
+ options.insert(QLatin1String("handle_token"), QStringLiteral("qt%1").arg(QRandomGenerator::global()->generate()));
+
+ // TODO choices a(ssa(ss)s)
+ // List of serialized combo boxes to add to the file chooser.
+
+ message << parentWindowId << d->title << options;
+
+ QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);
+ connect(watcher, &QDBusPendingCallWatcher::finished, this, [this] (QDBusPendingCallWatcher *watcher) {
+ QDBusPendingReply<QDBusObjectPath> reply = *watcher;
+ if (reply.isError()) {
+ Q_EMIT reject();
+ } else {
+ QDBusConnection::sessionBus().connect(nullptr,
+ reply.value().path(),
+ QLatin1String("org.freedesktop.portal.Request"),
+ QLatin1String("Response"),
+ this,
+ SLOT(gotResponse(uint,QVariantMap)));
+ }
+ });
+}
+
+bool QXdgDesktopPortalFileDialog::defaultNameFilterDisables() const
+{
+ return false;
+}
+
+void QXdgDesktopPortalFileDialog::setDirectory(const QUrl &directory)
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+ d->nativeFileDialog->setOptions(options());
+ d->nativeFileDialog->setDirectory(directory);
+ }
+
+ d->directory = directory.path();
+}
+
+QUrl QXdgDesktopPortalFileDialog::directory() const
+{
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
+ return d->nativeFileDialog->directory();
+
+ return d->directory;
+}
+
+void QXdgDesktopPortalFileDialog::selectFile(const QUrl &filename)
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+ d->nativeFileDialog->setOptions(options());
+ d->nativeFileDialog->selectFile(filename);
+ }
+
+ d->selectedFiles << filename.path();
+}
+
+QList<QUrl> QXdgDesktopPortalFileDialog::selectedFiles() const
+{
+ Q_D(const QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
+ return d->nativeFileDialog->selectedFiles();
+
+ QList<QUrl> files;
+ for (const QString &file : d->selectedFiles) {
+ files << QUrl(file);
+ }
+ return files;
+}
+
+void QXdgDesktopPortalFileDialog::setFilter()
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+ d->nativeFileDialog->setOptions(options());
+ d->nativeFileDialog->setFilter();
+ }
+}
+
+void QXdgDesktopPortalFileDialog::selectNameFilter(const QString &filter)
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog) {
+ d->nativeFileDialog->setOptions(options());
+ d->nativeFileDialog->selectNameFilter(filter);
+ }
+}
+
+QString QXdgDesktopPortalFileDialog::selectedNameFilter() const
+{
+ // TODO
+ return QString();
+}
+
+void QXdgDesktopPortalFileDialog::exec()
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly)) {
+ d->nativeFileDialog->exec();
+ return;
+ }
+
+ // HACK we have to avoid returning until we emit that the dialog was accepted or rejected
+ QEventLoop loop;
+ loop.connect(this, SIGNAL(accept()), SLOT(quit()));
+ loop.connect(this, SIGNAL(reject()), SLOT(quit()));
+ loop.exec();
+}
+
+void QXdgDesktopPortalFileDialog::hide()
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (d->nativeFileDialog)
+ d->nativeFileDialog->hide();
+}
+
+bool QXdgDesktopPortalFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ initializeDialog();
+
+ d->modal = windowModality != Qt::NonModal;
+ d->winId = parent ? parent->winId() : 0;
+
+ if (d->nativeFileDialog && (options()->fileMode() == QFileDialogOptions::Directory || options()->fileMode() == QFileDialogOptions::DirectoryOnly))
+ return d->nativeFileDialog->show(windowFlags, windowModality, parent);
+
+ openPortal();
+
+ return true;
+}
+
+void QXdgDesktopPortalFileDialog::gotResponse(uint response, const QVariantMap &results)
+{
+ Q_D(QXdgDesktopPortalFileDialog);
+
+ if (!response) {
+ if (results.contains(QLatin1String("uris")))
+ d->selectedFiles = results.value(QLatin1String("uris")).toStringList();
+
+ Q_EMIT accept();
+ } else {
+ Q_EMIT reject();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
new file mode 100644
index 0000000000..c1f1a2c005
--- /dev/null
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2017-2018 Red Hat, Inc
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QXDGDESKTOPPORTALFILEDIALOG_P_H
+#define QXDGDESKTOPPORTALFILEDIALOG_P_H
+
+#include <qpa/qplatformdialoghelper.h>
+#include <QVector>
+
+QT_BEGIN_NAMESPACE
+
+class QXdgDesktopPortalFileDialogPrivate;
+
+class QXdgDesktopPortalFileDialog : public QPlatformFileDialogHelper
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QXdgDesktopPortalFileDialog)
+public:
+ enum ConditionType : uint {
+ GlobalPattern = 0,
+ MimeType = 1
+ };
+ // Filters a(sa(us))
+ // Example: [('Images', [(0, '*.ico'), (1, 'image/png')]), ('Text', [(0, '*.txt')])]
+ struct FilterCondition {
+ ConditionType type;
+ QString pattern; // E.g. '*ico' or 'image/png'
+ };
+ typedef QVector<FilterCondition> FilterConditionList;
+
+ struct Filter {
+ QString name; // E.g. 'Images' or 'Text
+ FilterConditionList filterConditions;; // E.g. [(0, '*.ico'), (1, 'image/png')] or [(0, '*.txt')]
+ };
+ typedef QVector<Filter> FilterList;
+
+ QXdgDesktopPortalFileDialog(QPlatformFileDialogHelper *nativeFileDialog = nullptr);
+ ~QXdgDesktopPortalFileDialog();
+
+ bool defaultNameFilterDisables() const override;
+ QUrl directory() const override;
+ void setDirectory(const QUrl &directory) override;
+ void selectFile(const QUrl &filename) override;
+ QList<QUrl> selectedFiles() const override;
+ void setFilter() override;
+ void selectNameFilter(const QString &filter) override;
+ QString selectedNameFilter() const override;
+
+ void exec() override;
+ bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
+ void hide() override;
+
+private Q_SLOTS:
+ void gotResponse(uint response, const QVariantMap &results);
+
+private:
+ void initializeDialog();
+ void openPortal();
+
+ QScopedPointer<QXdgDesktopPortalFileDialogPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QXdgDesktopPortalFileDialog::FilterCondition);
+Q_DECLARE_METATYPE(QXdgDesktopPortalFileDialog::FilterConditionList);
+Q_DECLARE_METATYPE(QXdgDesktopPortalFileDialog::Filter);
+Q_DECLARE_METATYPE(QXdgDesktopPortalFileDialog::FilterList);
+
+#endif // QXDGDESKTOPPORTALFILEDIALOG_P_H
+
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
new file mode 100644
index 0000000000..f07ca3f098
--- /dev/null
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxdgdesktopportaltheme.h"
+#include "qxdgdesktopportalfiledialog_p.h"
+
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme_p.h>
+#include <qpa/qplatformthemefactory_p.h>
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+class QXdgDesktopPortalThemePrivate : public QPlatformThemePrivate
+{
+public:
+ QXdgDesktopPortalThemePrivate()
+ : QPlatformThemePrivate()
+ { }
+
+ ~QXdgDesktopPortalThemePrivate()
+ {
+ delete baseTheme;
+ }
+
+ QPlatformTheme *baseTheme;
+};
+
+QXdgDesktopPortalTheme::QXdgDesktopPortalTheme()
+ : d_ptr(new QXdgDesktopPortalThemePrivate)
+{
+ Q_D(QXdgDesktopPortalTheme);
+
+ QStringList themeNames;
+ themeNames += QGuiApplicationPrivate::platform_integration->themeNames();
+ // 1) Look for a theme plugin.
+ for (const QString &themeName : qAsConst(themeNames)) {
+ d->baseTheme = QPlatformThemeFactory::create(themeName, nullptr);
+ if (d->baseTheme)
+ break;
+ }
+
+ // 2) If no theme plugin was found ask the platform integration to
+ // create a theme
+ if (!d->baseTheme) {
+ for (const QString &themeName : qAsConst(themeNames)) {
+ d->baseTheme = QGuiApplicationPrivate::platform_integration->createPlatformTheme(themeName);
+ if (d->baseTheme)
+ break;
+ }
+ // No error message; not having a theme plugin is allowed.
+ }
+
+ // 3) Fall back on the built-in "null" platform theme.
+ if (!d->baseTheme)
+ d->baseTheme = new QPlatformTheme;
+}
+
+QPlatformMenuItem* QXdgDesktopPortalTheme::createPlatformMenuItem() const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->createPlatformMenuItem();
+}
+
+QPlatformMenu* QXdgDesktopPortalTheme::createPlatformMenu() const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->createPlatformMenu();
+}
+
+QPlatformMenuBar* QXdgDesktopPortalTheme::createPlatformMenuBar() const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->createPlatformMenuBar();
+}
+
+void QXdgDesktopPortalTheme::showPlatformMenuBar()
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->showPlatformMenuBar();
+}
+
+bool QXdgDesktopPortalTheme::usePlatformNativeDialog(DialogType type) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+
+ if (type == FileDialog)
+ return true;
+
+ return d->baseTheme->usePlatformNativeDialog(type);
+}
+
+QPlatformDialogHelper* QXdgDesktopPortalTheme::createPlatformDialogHelper(DialogType type) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+
+ if (type == FileDialog) {
+ if (d->baseTheme->usePlatformNativeDialog(type))
+ return new QXdgDesktopPortalFileDialog(static_cast<QPlatformFileDialogHelper*>(d->baseTheme->createPlatformDialogHelper(type)));
+
+ return new QXdgDesktopPortalFileDialog;
+ }
+
+ return d->baseTheme->createPlatformDialogHelper(type);
+}
+
+#ifndef QT_NO_SYSTEMTRAYICON
+QPlatformSystemTrayIcon* QXdgDesktopPortalTheme::createPlatformSystemTrayIcon() const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->createPlatformSystemTrayIcon();
+}
+#endif
+
+const QPalette *QXdgDesktopPortalTheme::palette(Palette type) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->palette(type);
+}
+
+const QFont* QXdgDesktopPortalTheme::font(Font type) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->font(type);
+}
+
+QVariant QXdgDesktopPortalTheme::themeHint(ThemeHint hint) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->themeHint(hint);
+}
+
+QPixmap QXdgDesktopPortalTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->standardPixmap(sp, size);
+}
+
+QIcon QXdgDesktopPortalTheme::fileIcon(const QFileInfo &fileInfo,
+ QPlatformTheme::IconOptions iconOptions) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->fileIcon(fileInfo, iconOptions);
+}
+
+QIconEngine * QXdgDesktopPortalTheme::createIconEngine(const QString &iconName) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->createIconEngine(iconName);
+}
+
+QList<QKeySequence> QXdgDesktopPortalTheme::keyBindings(QKeySequence::StandardKey key) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->keyBindings(key);
+}
+
+QString QXdgDesktopPortalTheme::standardButtonText(int button) const
+{
+ Q_D(const QXdgDesktopPortalTheme);
+ return d->baseTheme->standardButtonText(button);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h
new file mode 100644
index 0000000000..b72e676419
--- /dev/null
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXDGDESKTOPPORTALTHEME_H
+#define QXDGDESKTOPPORTALTHEME_H
+
+#include <qpa/qplatformtheme.h>
+
+QT_BEGIN_NAMESPACE
+
+class QXdgDesktopPortalThemePrivate;
+
+class QXdgDesktopPortalTheme : public QPlatformTheme
+{
+ Q_DECLARE_PRIVATE(QXdgDesktopPortalTheme)
+public:
+ QXdgDesktopPortalTheme();
+
+ QPlatformMenuItem *createPlatformMenuItem() const override;
+ QPlatformMenu *createPlatformMenu() const override;
+ QPlatformMenuBar *createPlatformMenuBar() const override;
+ void showPlatformMenuBar() override;
+
+ bool usePlatformNativeDialog(DialogType type) const override;
+ QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
+
+#ifndef QT_NO_SYSTEMTRAYICON
+ QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override;
+#endif
+
+ const QPalette *palette(Palette type = SystemPalette) const override;
+
+ const QFont *font(Font type = SystemFont) const override;
+
+ QVariant themeHint(ThemeHint hint) const override;
+
+ QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
+ QIcon fileIcon(const QFileInfo &fileInfo,
+ QPlatformTheme::IconOptions iconOptions = 0) const override;
+
+ QIconEngine *createIconEngine(const QString &iconName) const override;
+
+ QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const override;
+
+ QString standardButtonText(int button) const override;
+
+private:
+ QScopedPointer<QXdgDesktopPortalThemePrivate> d_ptr;
+ Q_DISABLE_COPY(QXdgDesktopPortalTheme)
+};
+
+QT_END_NAMESPACE
+
+#endif // QXDGDESKTOPPORTALTHEME_H
diff --git a/src/plugins/platformthemes/xdgdesktopportal/xdgdesktopportal.json b/src/plugins/platformthemes/xdgdesktopportal/xdgdesktopportal.json
new file mode 100644
index 0000000000..c69062d9a1
--- /dev/null
+++ b/src/plugins/platformthemes/xdgdesktopportal/xdgdesktopportal.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "xdgdesktopportal", "flatpak", "snap" ]
+}
diff --git a/src/plugins/platformthemes/xdgdesktopportal/xdgdesktopportal.pro b/src/plugins/platformthemes/xdgdesktopportal/xdgdesktopportal.pro
new file mode 100644
index 0000000000..0a71484cf9
--- /dev/null
+++ b/src/plugins/platformthemes/xdgdesktopportal/xdgdesktopportal.pro
@@ -0,0 +1,17 @@
+TARGET = qxdgdesktopportal
+
+PLUGIN_TYPE = platformthemes
+PLUGIN_EXTENDS = -
+PLUGIN_CLASS_NAME = QXdgDesktopPortalThemePlugin
+load(qt_plugin)
+
+QT += core-private dbus gui-private theme_support-private
+
+HEADERS += \
+ qxdgdesktopportaltheme.h \
+ qxdgdesktopportalfiledialog_p.h
+
+SOURCES += \
+ main.cpp \
+ qxdgdesktopportaltheme.cpp \
+ qxdgdesktopportalfiledialog.cpp
diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp
index 6c29a99705..c9683eb99d 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp
@@ -104,7 +104,11 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
break;
case PPK_QPageLayout: {
QPageLayout pageLayout = value.value<QPageLayout>();
- if (pageLayout.isValid() && (d->m_printDevice.isValidPageLayout(pageLayout, d->resolution) || d->m_printDevice.supportsCustomPageSizes())) {
+ if (pageLayout.isValid() && (d->m_printDevice.isValidPageLayout(pageLayout, d->resolution)
+ || d->m_printDevice.supportsCustomPageSizes()
+ || d->m_printDevice.supportedPageSizes().isEmpty())) {
+ // supportedPageSizes().isEmpty() because QPageSetupWidget::initPageSizes says
+ // "If no available printer page sizes, populate with all page sizes"
d->m_pageLayout = pageLayout;
d->setPageSize(pageLayout.pageSize());
}
@@ -132,6 +136,9 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_CupsOptions:
ret = d->cupsOptions;
break;
+ case PPK_Duplex:
+ ret = d->duplex;
+ break;
default:
ret = QPdfPrintEngine::property(key);
break;
@@ -140,7 +147,9 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const
}
-QCupsPrintEnginePrivate::QCupsPrintEnginePrivate(QPrinter::PrinterMode m) : QPdfPrintEnginePrivate(m)
+QCupsPrintEnginePrivate::QCupsPrintEnginePrivate(QPrinter::PrinterMode m)
+ : QPdfPrintEnginePrivate(m)
+ , duplex(QPrint::DuplexNone)
{
}
diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h
index d5363bb8cc..2a1a83b9d7 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h
@@ -99,6 +99,7 @@ private:
QPrintDevice m_printDevice;
QStringList cupsOptions;
QString cupsTempFile;
+ QPrint::DuplexMode duplex;
};
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
index a9c992a2e1..19e1df31f6 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
@@ -47,6 +47,15 @@
#include <QtPrintSupport/QPrinterInfo>
+#if QT_CONFIG(dialogbuttonbox)
+#include <QGuiApplication>
+#include <QDialog>
+#include <QDialogButtonBox>
+#include <QFormLayout>
+#include <QLabel>
+#include <QLineEdit>
+#endif // QT_CONFIG(dialogbuttonbox)
+
#include <cups/ppd.h>
#ifndef QT_LINUXBASE // LSB merges everything into cups.h
# include <cups/language.h>
@@ -54,9 +63,78 @@
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(dialogbuttonbox)
+static const char *getPasswordCB(const char */*prompt*/, http_t *http, const char */*method*/, const char *resource, void */*user_data*/)
+{
+ // cups doesn't free the const char * we return so keep around
+ // the last password so we don't leak memory if called multiple times.
+ static QByteArray password;
+
+ // prompt is always "Password for %s on %s? " but we can't use it since we allow the user to change the user.
+ // That is fine because cups always calls cupsUser after calling this callback.
+ // We build our own prompt with the hostname (if not localhost) and the resource that is being used
+
+ char hostname[HTTP_MAX_HOST];
+ httpGetHostname(http, hostname, HTTP_MAX_HOST);
+
+ const QString username = QString::fromLocal8Bit(cupsUser());
+
+ QDialog dialog;
+ dialog.setWindowTitle(QCoreApplication::translate("QCupsPrinterSupport", "Authentication Needed"));
+
+ QFormLayout *layout = new QFormLayout(&dialog);
+ layout->setSizeConstraint(QLayout::SetFixedSize);
+
+ QLineEdit *usernameLE = new QLineEdit();
+ usernameLE->setText(username);
+
+ QLineEdit *passwordLE = new QLineEdit();
+ passwordLE->setEchoMode(QLineEdit::Password);
+
+ QString resourceString = QString::fromLocal8Bit(resource);
+ if (resourceString.startsWith(QStringLiteral("/printers/")))
+ resourceString = resourceString.mid(QStringLiteral("/printers/").length());
+
+ QLabel *label = new QLabel();
+ if (hostname == QStringLiteral("localhost")) {
+ label->setText(QCoreApplication::translate("QCupsPrinterSupport", "Authentication needed to use %1.").arg(resourceString));
+ } else {
+ label->setText(QCoreApplication::translate("QCupsPrinterSupport", "Authentication needed to use %1 on %2.").arg(resourceString).arg(hostname));
+ label->setWordWrap(true);
+ }
+
+ layout->addRow(label);
+ layout->addRow(new QLabel(QCoreApplication::translate("QCupsPrinterSupport", "Username:")), usernameLE);
+ layout->addRow(new QLabel(QCoreApplication::translate("QCupsPrinterSupport", "Password:")), passwordLE);
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ layout->addRow(buttonBox);
+
+ QObject::connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
+ QObject::connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
+
+ passwordLE->setFocus();
+
+ if (dialog.exec() != QDialog::Accepted)
+ return nullptr;
+
+ if (usernameLE->text() != username)
+ cupsSetUser(usernameLE->text().toLocal8Bit().constData());
+
+ password = passwordLE->text().toLocal8Bit();
+
+ return password.constData();
+}
+#endif // QT_CONFIG(dialogbuttonbox)
+
QCupsPrinterSupport::QCupsPrinterSupport()
: QPlatformPrinterSupport()
{
+#if QT_CONFIG(dialogbuttonbox)
+ // Only show password dialog if GUI application
+ if (qobject_cast<QGuiApplication*>(QCoreApplication::instance()))
+ cupsSetPasswordCB2(getPasswordCB, nullptr /* user_data */ );
+#endif // QT_CONFIG(dialogbuttonbox)
}
QCupsPrinterSupport::~QCupsPrinterSupport()
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp
index 340b1a1ff4..d2ddc4144f 100644
--- a/src/plugins/printsupport/cups/qppdprintdevice.cpp
+++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp
@@ -50,13 +50,6 @@
QT_BEGIN_NAMESPACE
-QPpdPrintDevice::QPpdPrintDevice()
- : QPlatformPrintDevice(),
- m_cupsDest(0),
- m_ppd(0)
-{
-}
-
QPpdPrintDevice::QPpdPrintDevice(const QString &id)
: QPlatformPrintDevice(id),
m_cupsDest(0),
@@ -69,9 +62,26 @@ QPpdPrintDevice::QPpdPrintDevice(const QString &id)
m_cupsName = parts.at(0).toUtf8();
if (parts.size() > 1)
m_cupsInstance = parts.at(1).toUtf8();
- loadPrinter();
- if (m_cupsDest && m_ppd) {
+ // Get the print instance and PPD file
+ m_cupsDest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, m_cupsName, m_cupsInstance.isNull() ? nullptr : m_cupsInstance.constData());
+ if (m_cupsDest) {
+ const char *ppdFile = cupsGetPPD(m_cupsName);
+ if (ppdFile) {
+ m_ppd = ppdOpenFile(ppdFile);
+ unlink(ppdFile);
+ }
+ if (m_ppd) {
+ ppdMarkDefaults(m_ppd);
+ cupsMarkOptions(m_ppd, m_cupsDest->num_options, m_cupsDest->options);
+ ppdLocalize(m_ppd);
+
+ m_minimumPhysicalPageSize = QSize(m_ppd->custom_min[0], m_ppd->custom_min[1]);
+ m_maximumPhysicalPageSize = QSize(m_ppd->custom_max[0], m_ppd->custom_max[1]);
+ m_customMargins = QMarginsF(m_ppd->custom_margins[0], m_ppd->custom_margins[3],
+ m_ppd->custom_margins[2], m_ppd->custom_margins[1]);
+ }
+
m_name = printerOption("printer-info");
m_location = printerOption("printer-location");
m_makeAndModel = printerOption("printer-make-and-model");
@@ -87,10 +97,6 @@ QPpdPrintDevice::QPpdPrintDevice(const QString &id)
// Cups ppd_file_t variable_sizes custom_min custom_max
// PPD MaxMediaWidth MaxMediaHeight
m_supportsCustomPageSizes = type & CUPS_PRINTER_VARIABLE;
- m_minimumPhysicalPageSize = QSize(m_ppd->custom_min[0], m_ppd->custom_min[1]);
- m_maximumPhysicalPageSize = QSize(m_ppd->custom_max[0], m_ppd->custom_max[1]);
- m_customMargins = QMarginsF(m_ppd->custom_margins[0], m_ppd->custom_margins[3],
- m_ppd->custom_margins[2], m_ppd->custom_margins[1]);
}
}
}
@@ -107,7 +113,7 @@ QPpdPrintDevice::~QPpdPrintDevice()
bool QPpdPrintDevice::isValid() const
{
- return m_cupsDest && m_ppd;
+ return m_cupsDest;
}
bool QPpdPrintDevice::isDefault() const
@@ -152,8 +158,8 @@ void QPpdPrintDevice::loadPageSizes() const
}
}
}
- m_havePageSizes = true;
}
+ m_havePageSizes = true;
}
QPageSize QPpdPrintDevice::defaultPageSize() const
@@ -359,14 +365,18 @@ void QPpdPrintDevice::loadDuplexModes() const
ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex");
if (duplexModes) {
m_duplexModes.reserve(duplexModes->num_choices);
- for (int i = 0; i < duplexModes->num_choices; ++i)
- m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice));
+ for (int i = 0; i < duplexModes->num_choices; ++i) {
+ if (ppdInstallableConflict(m_ppd, duplexModes->keyword, duplexModes->choices[i].choice) == 0) {
+ m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice));
+ }
+ }
}
// If no result, try just the default
if (m_duplexModes.size() == 0) {
duplexModes = ppdFindOption(m_ppd, "DefaultDuplex");
- if (duplexModes)
+ if (duplexModes && (ppdInstallableConflict(m_ppd, duplexModes->keyword, duplexModes->choices[0].choice) == 0)) {
m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice));
+ }
}
}
// If still no result, or not added in PPD, then add None
@@ -417,7 +427,7 @@ QPrint::ColorMode QPpdPrintDevice::defaultColorMode() const
ppd_option_t *colorModel = ppdFindOption(m_ppd, "DefaultColorModel");
if (!colorModel)
colorModel = ppdFindOption(m_ppd, "ColorModel");
- if (!colorModel || (colorModel && !qstrcmp(colorModel->defchoice, "Gray")))
+ if (!colorModel || qstrcmp(colorModel->defchoice, "Gray") != 0)
return QPrint::Color;
}
return QPrint::GrayScale;
@@ -481,38 +491,6 @@ void QPpdPrintDevice::loadMimeTypes() const
}
#endif
-void QPpdPrintDevice::loadPrinter()
-{
- // Just to be safe, check if existing printer needs closing
- if (m_ppd) {
- ppdClose(m_ppd);
- m_ppd = 0;
- }
- if (m_cupsDest) {
- cupsFreeDests(1, m_cupsDest);
- m_cupsDest = 0;
- }
-
- // Get the print instance and PPD file
- m_cupsDest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, m_cupsName, m_cupsInstance.isNull() ? nullptr : m_cupsInstance.constData());
- if (m_cupsDest) {
- const char *ppdFile = cupsGetPPD(m_cupsName);
- if (ppdFile) {
- m_ppd = ppdOpenFile(ppdFile);
- unlink(ppdFile);
- }
- if (m_ppd) {
- ppdMarkDefaults(m_ppd);
- cupsMarkOptions(m_ppd, m_cupsDest->num_options, m_cupsDest->options);
- ppdLocalize(m_ppd);
- } else {
- cupsFreeDests(1, m_cupsDest);
- m_cupsDest = 0;
- m_ppd = 0;
- }
- }
-}
-
QString QPpdPrintDevice::printerOption(const QString &key) const
{
return cupsGetOption(key.toUtf8(), m_cupsDest->num_options, m_cupsDest->options);
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h
index 9867083bd7..90f90d6788 100644
--- a/src/plugins/printsupport/cups/qppdprintdevice.h
+++ b/src/plugins/printsupport/cups/qppdprintdevice.h
@@ -65,7 +65,6 @@ QT_BEGIN_NAMESPACE
class QPpdPrintDevice : public QPlatformPrintDevice
{
public:
- QPpdPrintDevice();
explicit QPpdPrintDevice(const QString &id);
virtual ~QPpdPrintDevice();
@@ -105,7 +104,6 @@ protected:
#endif
private:
- void loadPrinter();
QString printerOption(const QString &key) const;
cups_ptype_e printerTypeFlags() const;
diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
index b1589c0738..f01e93d611 100644
--- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
+++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 John Layt <jlayt@kde.org>
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -49,6 +49,8 @@
QT_BEGIN_NAMESPACE
QT_WARNING_DISABLE_GCC("-Wsign-compare")
+typedef QVector<QWindowsPrinterInfo> WindowsPrinterLookup;
+Q_GLOBAL_STATIC(WindowsPrinterLookup, windowsDeviceLookup);
extern qreal qt_pointMultiplier(QPageLayout::Unit unit);
@@ -110,7 +112,7 @@ QWindowsPrintDevice::QWindowsPrintDevice(const QString &id)
{
// First do a fast lookup to see if printer exists, if it does then open it
if (!id.isEmpty() && QWindowsPrintDevice::availablePrintDeviceIds().contains(id)) {
- if (OpenPrinter((LPWSTR)m_id.utf16(), &m_hPrinter, NULL)) {
+ if (OpenPrinter(const_cast<LPWSTR>(wcharId()), &m_hPrinter, nullptr)) {
DWORD needed = 0;
GetPrinter(m_hPrinter, 2, 0, 0, &needed);
QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
@@ -121,15 +123,39 @@ QWindowsPrintDevice::QWindowsPrintDevice(const QString &id)
m_makeAndModel = QString::fromWCharArray(info->pDriverName); // TODO Check is not available elsewhere
m_isRemote = info->Attributes & PRINTER_ATTRIBUTE_NETWORK;
}
- m_supportsMultipleCopies = (DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_COPIES, NULL, NULL) > 1);
- m_supportsCollateCopies = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_COLLATE, NULL, NULL);
- // Min/Max custom size is in tenths of a millimeter
- const qreal multiplier = qt_pointMultiplier(QPageLayout::Millimeter);
- DWORD min = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_MINEXTENT, NULL, NULL);
- m_minimumPhysicalPageSize = QSize((LOWORD(min) / 10.0) * multiplier, (HIWORD(min) / 10.0) * multiplier);
- DWORD max = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_MAXEXTENT, NULL, NULL);
- m_maximumPhysicalPageSize = QSize((LOWORD(max) / 10.0) * multiplier, (HIWORD(max) / 10.0) * multiplier);
- m_supportsCustomPageSizes = (m_maximumPhysicalPageSize.width() > 0 && m_maximumPhysicalPageSize.height() > 0);
+ QWindowsPrinterInfo m_info;
+ m_info.m_id = m_id;
+ m_info.m_name = m_name;
+ m_info.m_location = m_location;
+ m_info.m_makeAndModel = m_makeAndModel;
+ m_info.m_isRemote = m_isRemote;
+ m_infoIndex = windowsDeviceLookup()->indexOf(m_info);
+ if (m_infoIndex != -1) {
+ m_info = windowsDeviceLookup()->at(m_infoIndex);
+ m_havePageSizes = m_info.m_havePageSizes;
+ m_pageSizes = m_info.m_pageSizes;
+ m_haveResolutions = m_info.m_haveResolutions;
+ m_resolutions = m_info.m_resolutions;
+ m_haveCopies = m_info.m_haveCopies;
+ m_supportsMultipleCopies = m_info.m_supportsMultipleCopies;
+ m_supportsCollateCopies = m_info.m_supportsCollateCopies;
+ m_haveMinMaxPageSizes = m_info.m_haveMinMaxPageSizes;
+ m_minimumPhysicalPageSize = m_info.m_minimumPhysicalPageSize;
+ m_maximumPhysicalPageSize = m_info.m_maximumPhysicalPageSize;
+ m_supportsCustomPageSizes = m_info.m_supportsCustomPageSizes;
+ m_haveInputSlots = m_info.m_haveInputSlots;
+ m_inputSlots = m_info.m_inputSlots;
+ m_haveOutputBins = m_info.m_haveOutputBins;
+ m_outputBins = m_info.m_outputBins;
+ m_haveDuplexModes = m_info.m_haveDuplexModes;
+ m_duplexModes = m_info.m_duplexModes;
+ m_haveColorModes = m_info.m_haveColorModes;
+ m_colorModes = m_info.m_colorModes;
+ m_infoIndex = windowsDeviceLookup()->indexOf(m_info);
+ } else {
+ windowsDeviceLookup()->append(m_info);
+ m_infoIndex = windowsDeviceLookup()->count() - 1;
+ }
}
}
}
@@ -184,7 +210,7 @@ void QWindowsPrintDevice::loadPageSizes() const
&& DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERS, NULL, NULL) == paperCount) {
QScopedArrayPointer<wchar_t> paperNames(new wchar_t[paperCount*64]);
- QScopedArrayPointer<POINT> winSizes(new POINT[paperCount*sizeof(POINT)]);
+ QScopedArrayPointer<POINT> winSizes(new POINT[paperCount]);
QScopedArrayPointer<wchar_t> papers(new wchar_t[paperCount]);
// Get the details and match the default paper size
@@ -205,6 +231,9 @@ void QWindowsPrintDevice::loadPageSizes() const
}
m_havePageSizes = true;
+ QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
+ info[m_infoIndex].m_havePageSizes = true;
+ info[m_infoIndex].m_pageSizes = m_pageSizes;
}
QPageSize QWindowsPrintDevice::defaultPageSize() const
@@ -297,6 +326,9 @@ void QWindowsPrintDevice::loadResolutions() const
}
}
m_haveResolutions = true;
+ QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
+ info[m_infoIndex].m_haveResolutions = true;
+ info[m_infoIndex].m_resolutions = m_resolutions;
}
int QWindowsPrintDevice::defaultResolution() const
@@ -319,16 +351,19 @@ int QWindowsPrintDevice::defaultResolution() const
void QWindowsPrintDevice::loadInputSlots() const
{
- DWORD binCount = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_BINS, NULL, NULL);
+ const auto printerId = wcharId();
+ DWORD binCount = DeviceCapabilities(printerId, nullptr, DC_BINS, nullptr, nullptr);
if (int(binCount) > 0
- && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_BINNAMES, NULL, NULL) == binCount) {
+ && DeviceCapabilities(printerId, nullptr, DC_BINNAMES, nullptr, nullptr) == binCount) {
- QScopedArrayPointer<WORD> bins(new WORD[binCount*sizeof(WORD)]);
+ QScopedArrayPointer<WORD> bins(new WORD[binCount]);
QScopedArrayPointer<wchar_t> binNames(new wchar_t[binCount*24]);
// Get the details and match the default paper size
- if (DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_BINS, (LPWSTR)bins.data(), NULL) == binCount
- && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_BINNAMES, binNames.data(), NULL) == binCount) {
+ if (DeviceCapabilities(printerId, nullptr, DC_BINS,
+ reinterpret_cast<LPWSTR>(bins.data()), nullptr) == binCount
+ && DeviceCapabilities(printerId, nullptr, DC_BINNAMES, binNames.data(),
+ nullptr) == binCount) {
for (int i = 0; i < int(binCount); ++i) {
wchar_t *binName = binNames.data() + (i * 24);
@@ -340,6 +375,9 @@ void QWindowsPrintDevice::loadInputSlots() const
}
m_haveInputSlots = true;
+ QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
+ info[m_infoIndex].m_haveInputSlots = true;
+ info[m_infoIndex].m_inputSlots = m_inputSlots;
}
QPrint::InputSlot QWindowsPrintDevice::defaultInputSlot() const
@@ -367,12 +405,15 @@ void QWindowsPrintDevice::loadOutputBins() const
{
m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
m_haveOutputBins = true;
+ QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
+ info[m_infoIndex].m_haveOutputBins = true;
+ info[m_infoIndex].m_outputBins = m_outputBins;
}
void QWindowsPrintDevice::loadDuplexModes() const
{
m_duplexModes.append(QPrint::DuplexNone);
- DWORD duplex = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_DUPLEX, NULL, NULL);
+ DWORD duplex = DeviceCapabilities(wcharId(), nullptr, DC_DUPLEX, nullptr, nullptr);
if (int(duplex) == 1) {
// TODO Assume if duplex flag supports both modes
m_duplexModes.append(QPrint::DuplexAuto);
@@ -380,6 +421,9 @@ void QWindowsPrintDevice::loadDuplexModes() const
m_duplexModes.append(QPrint::DuplexShortSide);
}
m_haveDuplexModes = true;
+ QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
+ info[m_infoIndex].m_haveDuplexModes = true;
+ info[m_infoIndex].m_duplexModes = m_duplexModes;
}
QPrint::DuplexMode QWindowsPrintDevice::defaultDuplexMode() const
@@ -403,10 +447,13 @@ QPrint::DuplexMode QWindowsPrintDevice::defaultDuplexMode() const
void QWindowsPrintDevice::loadColorModes() const
{
m_colorModes.append(QPrint::GrayScale);
- DWORD color = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_COLORDEVICE, NULL, NULL);
+ DWORD color = DeviceCapabilities(wcharId(), nullptr, DC_COLORDEVICE, nullptr, nullptr);
if (int(color) == 1)
m_colorModes.append(QPrint::Color);
m_haveColorModes = true;
+ QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
+ info[m_infoIndex].m_haveColorModes = true;
+ info[m_infoIndex].m_colorModes = m_colorModes;
}
QPrint::ColorMode QWindowsPrintDevice::defaultColorMode() const
@@ -457,4 +504,68 @@ QString QWindowsPrintDevice::defaultPrintDeviceId()
return QString::fromWCharArray(name.data());
}
+void QWindowsPrintDevice::loadCopiesSupport() const
+{
+ auto printerId = wcharId();
+ m_supportsMultipleCopies = (DeviceCapabilities(printerId, NULL, DC_COPIES, NULL, NULL) > 1);
+ m_supportsCollateCopies = DeviceCapabilities(printerId, NULL, DC_COLLATE, NULL, NULL);
+ m_haveCopies = true;
+ QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
+ info[m_infoIndex].m_haveCopies = true;
+ info[m_infoIndex].m_supportsMultipleCopies = m_supportsMultipleCopies;
+ info[m_infoIndex].m_supportsCollateCopies = m_supportsCollateCopies;
+}
+
+bool QWindowsPrintDevice::supportsCollateCopies() const
+{
+ if (!m_haveCopies)
+ loadCopiesSupport();
+ return m_supportsCollateCopies;
+}
+
+bool QWindowsPrintDevice::supportsMultipleCopies() const
+{
+ if (!m_haveCopies)
+ loadCopiesSupport();
+ return m_supportsMultipleCopies;
+}
+
+bool QWindowsPrintDevice::supportsCustomPageSizes() const
+{
+ if (!m_haveMinMaxPageSizes)
+ loadMinMaxPageSizes();
+ return m_supportsCustomPageSizes;
+}
+
+QSize QWindowsPrintDevice::minimumPhysicalPageSize() const
+{
+ if (!m_haveMinMaxPageSizes)
+ loadMinMaxPageSizes();
+ return m_minimumPhysicalPageSize;
+}
+
+QSize QWindowsPrintDevice::maximumPhysicalPageSize() const
+{
+ if (!m_haveMinMaxPageSizes)
+ loadMinMaxPageSizes();
+ return m_maximumPhysicalPageSize;
+}
+
+void QWindowsPrintDevice::loadMinMaxPageSizes() const
+{
+ // Min/Max custom size is in tenths of a millimeter
+ const qreal multiplier = qt_pointMultiplier(QPageLayout::Millimeter);
+ auto printerId = wcharId();
+ DWORD min = DeviceCapabilities(printerId, NULL, DC_MINEXTENT, NULL, NULL);
+ m_minimumPhysicalPageSize = QSize((LOWORD(min) / 10.0) * multiplier, (HIWORD(min) / 10.0) * multiplier);
+ DWORD max = DeviceCapabilities(printerId, NULL, DC_MAXEXTENT, NULL, NULL);
+ m_maximumPhysicalPageSize = QSize((LOWORD(max) / 10.0) * multiplier, (HIWORD(max) / 10.0) * multiplier);
+ m_supportsCustomPageSizes = (m_maximumPhysicalPageSize.width() > 0 && m_maximumPhysicalPageSize.height() > 0);
+ m_haveMinMaxPageSizes = true;
+ QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
+ info[m_infoIndex].m_haveCopies = true;
+ info[m_infoIndex].m_supportsMultipleCopies = m_supportsMultipleCopies;
+ info[m_infoIndex].m_supportsCollateCopies = m_supportsCollateCopies;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.h b/src/plugins/printsupport/windows/qwindowsprintdevice.h
index 6b51ee8785..166f0f65b2 100644
--- a/src/plugins/printsupport/windows/qwindowsprintdevice.h
+++ b/src/plugins/printsupport/windows/qwindowsprintdevice.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -57,6 +58,43 @@
QT_BEGIN_NAMESPACE
+class QWindowsPrinterInfo
+{
+public:
+ bool operator==(const QWindowsPrinterInfo &other) const
+ {
+ // We only need to check if these are the same for matching up
+ return m_id == other.m_id && m_name == other.m_name &&
+ m_location == other.m_location &&
+ m_makeAndModel == other.m_makeAndModel &&
+ m_isRemote == other.m_isRemote;
+ }
+ QString m_id;
+ QString m_name;
+ QString m_location;
+ QString m_makeAndModel;
+ QList<QPageSize> m_pageSizes;
+ QList<int> m_resolutions;
+ QVector<QPrint::InputSlot> m_inputSlots;
+ QVector<QPrint::OutputBin> m_outputBins;
+ QVector<QPrint::DuplexMode> m_duplexModes;
+ QVector<QPrint::ColorMode> m_colorModes;
+ QSize m_minimumPhysicalPageSize;
+ QSize m_maximumPhysicalPageSize;
+ bool m_isRemote = false;
+ bool m_havePageSizes = false;
+ bool m_haveResolutions = false;
+ bool m_haveCopies = false;
+ bool m_supportsMultipleCopies = false;
+ bool m_supportsCollateCopies = false;
+ bool m_haveMinMaxPageSizes = false;
+ bool m_supportsCustomPageSizes = false;
+ bool m_haveInputSlots = false;
+ bool m_haveOutputBins = false;
+ bool m_haveDuplexModes = false;
+ bool m_haveColorModes = false;
+};
+
class QWindowsPrintDevice : public QPlatformPrintDevice
{
public:
@@ -85,6 +123,12 @@ public:
static QStringList availablePrintDeviceIds();
static QString defaultPrintDeviceId();
+ bool supportsCollateCopies() const override;
+ bool supportsMultipleCopies() const override;
+ bool supportsCustomPageSizes() const override;
+ QSize minimumPhysicalPageSize() const override;
+ QSize maximumPhysicalPageSize() const override;
+
protected:
void loadPageSizes() const override;
void loadResolutions() const override;
@@ -92,9 +136,16 @@ protected:
void loadOutputBins() const override;
void loadDuplexModes() const override;
void loadColorModes() const override;
+ void loadCopiesSupport() const;
+ void loadMinMaxPageSizes() const;
private:
+ LPCWSTR wcharId() const { return reinterpret_cast<LPCWSTR>(m_id.utf16()); }
+
HANDLE m_hPrinter;
+ mutable bool m_haveCopies;
+ mutable bool m_haveMinMaxPageSizes;
+ int m_infoIndex;
};
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h
index c42e7aa551..4267701145 100644
--- a/src/plugins/printsupport/windows/qwindowsprintersupport.h
+++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h
@@ -46,9 +46,10 @@ QT_BEGIN_NAMESPACE
class QWindowsPrinterSupport : public QPlatformPrinterSupport
{
+ Q_DISABLE_COPY(QWindowsPrinterSupport)
public:
QWindowsPrinterSupport();
- ~QWindowsPrinterSupport();
+ ~QWindowsPrinterSupport() override;
QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId = QString()) override;
QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode) override;
diff --git a/src/plugins/sqldrivers/configure.json b/src/plugins/sqldrivers/configure.json
index 234f880579..4802d3b04d 100644
--- a/src/plugins/sqldrivers/configure.json
+++ b/src/plugins/sqldrivers/configure.json
@@ -229,7 +229,7 @@ Oracle driver, as the current build will most likely fail."
"summary": [
{
- "section": "Qt Sql",
+ "section": "Qt Sql Drivers",
"entries": [
"sql-db2", "sql-ibase", "sql-mysql", "sql-oci", "sql-odbc", "sql-psql",
"sql-sqlite2", "sql-sqlite", "system-sqlite", "sql-tds"
diff --git a/src/plugins/sqldrivers/configure.pri b/src/plugins/sqldrivers/configure.pri
index b69b51b679..24954e9514 100644
--- a/src/plugins/sqldrivers/configure.pri
+++ b/src/plugins/sqldrivers/configure.pri
@@ -19,9 +19,9 @@ defineTest(qtConfLibrary_psqlConfig) {
libs =
!isEmpty(libdir): libs += "-L$$libdir"
libs += "-lpq"
- $${1}.libs = "$$val_escape(libs)"
+ $${1}.libs = $$libs
includedir -= $$QMAKE_DEFAULT_INCDIRS
- $${1}.includedir = "$$val_escape(includedir)"
+ $${1}.includedir = $$includedir
export($${1}.libs)
export($${1}.includedir)
return(true)
@@ -34,7 +34,7 @@ defineTest(qtConfLibrary_psqlEnv) {
# Respect PSQL_LIBS if set
PSQL_LIBS = $$getenv(PSQL_LIBS)
!isEmpty(PSQL_LIBS) {
- $${1}.libs = $$PSQL_LIBS
+ eval($${1}.libs = $$PSQL_LIBS)
export($${1}.libs)
} else {
!qtConfLibrary_inline($$1, $$2): \
@@ -69,14 +69,14 @@ defineTest(qtConfLibrary_mysqlConfig) {
}
libs = $$cleanlibs
}
- $${1}.libs = "$$val_escape(libs)"
+ $${1}.libs = $$libs
eval(rawincludedir = $$includedir)
rawincludedir ~= s/^-I//g
includedir =
for (id, rawincludedir): \
includedir += $$clean_path($$id)
includedir -= $$QMAKE_DEFAULT_INCDIRS
- $${1}.includedir = "$$val_escape(includedir)"
+ $${1}.includedir = $$includedir
export($${1}.libs)
export($${1}.includedir)
return(true)
@@ -90,9 +90,9 @@ defineTest(qtConfLibrary_sybaseEnv) {
sybase = $$getenv(SYBASE)
!isEmpty(sybase): \
libs += "-L$${sybase}/lib"
- libs += $$getenv(SYBASE_LIBS)
+ eval(libs += $$getenv(SYBASE_LIBS))
!isEmpty(libs) {
- $${1}.libs = "$$val_escape(libs)"
+ $${1}.libs = $$libs
export($${1}.libs)
}
return(true)
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index 5a100b8075..58da2a3c51 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
@@ -74,6 +74,10 @@ Q_DECLARE_METATYPE(MYSQL_STMT*)
# define Q_CLIENT_MULTI_STATEMENTS 0
#endif
+// MySQL above version 8 removed my_bool typedef while MariaDB kept it,
+// by redefining it we can regain source compatibility.
+using my_bool = decltype(mysql_stmt_bind_result(nullptr, nullptr));
+
QT_BEGIN_NAMESPACE
class QMYSQLDriverPrivate : public QSqlDriverPrivate
@@ -305,7 +309,9 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags)
type = QVariant::Date;
break;
case FIELD_TYPE_TIME :
- type = QVariant::Time;
+ // A time field can be within the range '-838:59:59' to '838:59:59' so
+ // use QString instead of QTime since QTime is limited to 24 hour clock
+ type = QVariant::String;
break;
case FIELD_TYPE_DATETIME :
case FIELD_TYPE_TIMESTAMP :
@@ -1448,7 +1454,7 @@ bool QMYSQLDriver::open(const QString& db,
d->preparedQuerysEnabled = false;
#endif
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
mysql_thread_init();
#endif
@@ -1462,7 +1468,7 @@ void QMYSQLDriver::close()
{
Q_D(QMYSQLDriver);
if (isOpen()) {
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
mysql_thread_end();
#endif
mysql_close(d->mysql);
diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
index 547eb2043d..1fbbcd0ef1 100644
--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
@@ -72,6 +72,7 @@ inline static QString fromSQLTCHAR(const QVarLengthArray<SQLTCHAR>& input, int s
{
QString result;
+ // Remove any trailing \0 as some drivers misguidedly append one
int realsize = qMin(size, input.size());
if(realsize > 0 && input[realsize-1] == 0)
realsize--;
@@ -458,7 +459,6 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni
// more data can be fetched, the length indicator does NOT
// contain the number of bytes returned - it contains the
// total number of bytes that CAN be fetched
- // colSize-1: remove 0 termination when there is more data to fetch
int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : int(lengthIndicator / sizeof(SQLTCHAR));
fieldVal += fromSQLTCHAR(buf, rSize);
if (lengthIndicator < SQLLEN(colSize*sizeof(SQLTCHAR))) {
@@ -499,9 +499,12 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni
// more data can be fetched, the length indicator does NOT
// contain the number of bytes returned - it contains the
// total number of bytes that CAN be fetched
- // colSize-1: remove 0 termination when there is more data to fetch
int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator;
- fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize);
+ // Remove any trailing \0 as some drivers misguidedly append one
+ int realsize = qMin(rSize, buf.size());
+ if (realsize > 0 && buf[realsize - 1] == 0)
+ realsize--;
+ fieldVal += QString::fromUtf8(reinterpret_cast<const char *>(buf.constData()), realsize);
if (lengthIndicator < SQLLEN(colSize)) {
// workaround for Drivermanagers that don't return SQL_NO_DATA
break;
@@ -1304,7 +1307,7 @@ QVariant QODBCResult::data(int field)
bool QODBCResult::isNull(int field)
{
Q_D(const QODBCResult);
- if (field < 0 || field > d->fieldCache.size())
+ if (field < 0 || field >= d->fieldCache.size())
return true;
if (field <= d->fieldCacheIdx) {
// since there is no good way to find out whether the value is NULL
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index fe9e098c12..bf0493b0c3 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -1465,8 +1465,11 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
precision = -1;
}
QString defVal = query.value(5).toString();
- if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\''))
- defVal = defVal.mid(1, defVal.length() - 2);
+ if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\'')) {
+ const int end = defVal.lastIndexOf(QLatin1Char('\''));
+ if (end > 0)
+ defVal = defVal.mid(1, end - 1);
+ }
QSqlField f(query.value(0).toString(), qDecodePSQLType(query.value(1).toInt()), tablename);
f.setRequired(query.value(2).toBool());
f.setLength(len);
diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
index 491d903137..f1a003ddcd 100644
--- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
+++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
@@ -55,9 +55,6 @@
#include <qcache.h>
#include <qregularexpression.h>
#endif
-#if QT_CONFIG(timezone)
-#include <QTimeZone>
-#endif
#include <QScopedValueRollback>
#if defined Q_OS_WIN
@@ -421,34 +418,6 @@ bool QSQLiteResult::prepare(const QString &query)
return true;
}
-static QString secondsToOffset(int seconds)
-{
- const QChar sign = ushort(seconds < 0 ? '-' : '+');
- seconds = qAbs(seconds);
- const int hours = seconds / 3600;
- const int minutes = (seconds % 3600) / 60;
-
- return QString(QStringLiteral("%1%2:%3")).arg(sign).arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0'));
-}
-
-static QString timespecToString(const QDateTime &dateTime)
-{
- switch (dateTime.timeSpec()) {
- case Qt::LocalTime:
- return QString();
- case Qt::UTC:
- return QStringLiteral("Z");
- case Qt::OffsetFromUTC:
- return secondsToOffset(dateTime.offsetFromUtc());
-#if QT_CONFIG(timezone)
- case Qt::TimeZone:
- return secondsToOffset(dateTime.timeZone().offsetFromUtc(dateTime));
-#endif
- default:
- return QString();
- }
-}
-
bool QSQLiteResult::execBatch(bool arrayBind)
{
Q_UNUSED(arrayBind);
@@ -555,7 +524,7 @@ bool QSQLiteResult::exec()
break;
case QVariant::DateTime: {
const QDateTime dateTime = value.toDateTime();
- const QString str = dateTime.toString(QLatin1String("yyyy-MM-ddThh:mm:ss.zzz") + timespecToString(dateTime));
+ const QString str = dateTime.toString(Qt::ISODateWithMs);
res = sqlite3_bind_text16(d->stmt, i + 1, str.utf16(),
str.size() * sizeof(ushort), SQLITE_TRANSIENT);
break;
@@ -673,7 +642,7 @@ static void _q_regexp(sqlite3_context* context, int argc, sqlite3_value** argv)
const bool wasCached = regexp;
if (!wasCached)
- regexp = new QRegularExpression(pattern, QRegularExpression::DontCaptureOption | QRegularExpression::OptimizeOnFirstUsageOption);
+ regexp = new QRegularExpression(pattern, QRegularExpression::DontCaptureOption);
const bool found = subject.contains(*regexp);
@@ -953,13 +922,20 @@ static QSqlIndex qGetTableInfo(QSqlQuery &q, const QString &tableName, bool only
if (onlyPIndex && !isPk)
continue;
QString typeName = q.value(2).toString().toLower();
+ QString defVal = q.value(4).toString();
+ if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\'')) {
+ const int end = defVal.lastIndexOf(QLatin1Char('\''));
+ if (end > 0)
+ defVal = defVal.mid(1, end - 1);
+ }
+
QSqlField fld(q.value(1).toString(), qGetColumnType(typeName), tableName);
if (isPk && (typeName == QLatin1String("integer")))
// INTEGER PRIMARY KEY fields are auto-generated in sqlite
// INT PRIMARY KEY is not the same as INTEGER PRIMARY KEY!
fld.setAutoValue(true);
fld.setRequired(q.value(3).toInt() != 0);
- fld.setDefaultValue(q.value(4));
+ fld.setDefaultValue(defVal);
ind.append(fld);
}
return ind;
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 3405f01046..2a21673054 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -143,22 +143,12 @@ static QWindow *qt_getWindow(const QWidget *widget)
return widget ? widget->window()->windowHandle() : 0;
}
-@interface QT_MANGLE_NAMESPACE(NotificationReceiver) : NSObject {
-QMacStylePrivate *mPrivate;
-}
-- (id)initWithPrivate:(QMacStylePrivate *)priv;
-- (void)scrollBarStyleDidChange:(NSNotification *)notification;
+@interface QT_MANGLE_NAMESPACE(NotificationReceiver) : NSObject
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver);
@implementation NotificationReceiver
-- (id)initWithPrivate:(QMacStylePrivate *)priv
-{
- self = [super init];
- mPrivate = priv;
- return self;
-}
- (void)scrollBarStyleDidChange:(NSNotification *)notification
{
@@ -263,33 +253,50 @@ QVector<QPointer<QObject> > QMacStylePrivate::scrollBars;
static QLinearGradient titlebarGradientActive()
{
- static QLinearGradient gradient;
- if (gradient == QLinearGradient()) {
+ static QLinearGradient darkGradient = [](){
+ QLinearGradient gradient;
+ // FIXME: colors are chosen somewhat arbitrarily and could be fine-tuned,
+ // or ideally determined by calling a native API.
+ gradient.setColorAt(0, QColor(47, 47, 47));
+ return gradient;
+ }();
+ static QLinearGradient lightGradient = [](){
+ QLinearGradient gradient;
gradient.setColorAt(0, QColor(235, 235, 235));
gradient.setColorAt(0.5, QColor(210, 210, 210));
gradient.setColorAt(0.75, QColor(195, 195, 195));
gradient.setColorAt(1, QColor(180, 180, 180));
- }
- return gradient;
+ return gradient;
+ }();
+ return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient;
}
static QLinearGradient titlebarGradientInactive()
{
- static QLinearGradient gradient;
- if (gradient == QLinearGradient()) {
+ static QLinearGradient darkGradient = [](){
+ QLinearGradient gradient;
+ gradient.setColorAt(1, QColor(42, 42, 42));
+ return gradient;
+ }();
+ static QLinearGradient lightGradient = [](){
+ QLinearGradient gradient;
gradient.setColorAt(0, QColor(250, 250, 250));
gradient.setColorAt(1, QColor(225, 225, 225));
- }
- return gradient;
+ return gradient;
+ }();
+ return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient;
}
static const QColor titlebarSeparatorLineActive(111, 111, 111);
static const QColor titlebarSeparatorLineInactive(131, 131, 131);
+static const QColor darkModeSeparatorLine(88, 88, 88);
// Gradient colors used for the dock widget title bar and
// non-unifed tool bar bacground.
-static const QColor mainWindowGradientBegin(240, 240, 240);
-static const QColor mainWindowGradientEnd(200, 200, 200);
+static const QColor lightMainWindowGradientBegin(240, 240, 240);
+static const QColor lightMainWindowGradientEnd(200, 200, 200);
+static const QColor darkMainWindowGradientBegin(47, 47, 47);
+static const QColor darkMainWindowGradientEnd(47, 47, 47);
static const int DisclosureOffset = 4;
@@ -404,9 +411,9 @@ static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl)
const bool ticksAbove = sl->tickPosition == QSlider::TicksAbove;
if (sl->orientation == Qt::Horizontal)
- slider.tickMarkPosition = ticksAbove ? NSTickMarkAbove : NSTickMarkBelow;
+ slider.tickMarkPosition = ticksAbove ? NSTickMarkPositionAbove : NSTickMarkPositionBelow;
else
- slider.tickMarkPosition = ticksAbove ? NSTickMarkLeft : NSTickMarkRight;
+ slider.tickMarkPosition = ticksAbove ? NSTickMarkPositionLeading : NSTickMarkPositionTrailing;
} else {
slider.numberOfTickMarks = 0;
}
@@ -1745,17 +1752,10 @@ NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const
}
Q_UNREACHABLE();
} ();
-#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12)
const auto styleMask = NSWindowStyleMaskTitled
| NSWindowStyleMaskClosable
| NSWindowStyleMaskMiniaturizable
| NSWindowStyleMaskResizable;
-#else
- const auto styleMask = NSTitledWindowMask
- | NSClosableWindowMask
- | NSMiniaturizableWindowMask
- | NSResizableWindowMask;
-#endif
bv = [NSWindow standardWindowButton:button forStyleMask:styleMask];
[bv retain];
break;
@@ -1802,10 +1802,10 @@ NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const
auto *ctrl = static_cast<NSControl *>(bv);
switch (widget.size) {
case QStyleHelper::SizeSmall:
- ctrl.controlSize = NSSmallControlSize;
+ ctrl.controlSize = NSControlSizeSmall;
break;
case QStyleHelper::SizeMini:
- ctrl.controlSize = NSMiniControlSize;
+ ctrl.controlSize = NSControlSizeMini;
break;
default:
break;
@@ -1816,10 +1816,10 @@ NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const
pi.indeterminate = (widget.type == ProgressIndicator_Indeterminate);
switch (widget.size) {
case QStyleHelper::SizeSmall:
- pi.controlSize = NSSmallControlSize;
+ pi.controlSize = NSControlSizeSmall;
break;
case QStyleHelper::SizeMini:
- pi.controlSize = NSMiniControlSize;
+ pi.controlSize = NSControlSizeMini;
break;
default:
break;
@@ -1865,10 +1865,10 @@ NSCell *QMacStylePrivate::cocoaCell(CocoaControl widget) const
switch (widget.size) {
case QStyleHelper::SizeSmall:
- cell.controlSize = NSSmallControlSize;
+ cell.controlSize = NSControlSizeSmall;
break;
case QStyleHelper::SizeMini:
- cell.controlSize = NSMiniControlSize;
+ cell.controlSize = NSControlSizeMini;
break;
default:
break;
@@ -1936,7 +1936,7 @@ QMacStyle::QMacStyle()
Q_D(QMacStyle);
QMacAutoReleasePool pool;
- d->receiver = [[NotificationReceiver alloc] initWithPrivate:d];
+ d->receiver = [[NotificationReceiver alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:d->receiver
selector:@selector(scrollBarStyleDidChange:)
name:NSPreferredScrollerStyleDidChangeNotification
@@ -2208,9 +2208,9 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
ret = 0;
break;
case PM_TitleBarHeight: {
- NSUInteger style = NSTitledWindowMask;
+ NSUInteger style = NSWindowStyleMaskTitled;
if (widget && ((widget->windowFlags() & Qt::Tool) == Qt::Tool))
- style |= NSUtilityWindowMask;
+ style |= NSWindowStyleMaskUtilityWindow;
ret = int([NSWindow frameRectForContentRect:NSZeroRect
styleMask:style].size.height);
break; }
@@ -2820,8 +2820,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
{
Q_D(const QMacStyle);
QMacCGContext cg(p);
- QWindow *window = w && w->window() ? w->window()->windowHandle() :
- QStyleHelper::styleObjectWindow(opt->styleObject);
+ QWindow *window = w && w->window() ? w->window()->windowHandle() : nullptr;
d->resolveCurrentNSView(window);
switch (pe) {
case PE_IndicatorArrowUp:
@@ -3136,8 +3135,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
tf.bezeled = YES;
static_cast<NSTextFieldCell *>(tf.cell).bezelStyle = isRounded ? NSTextFieldRoundedBezel : NSTextFieldSquareBezel;
tf.frame = opt->rect.toCGRect();
- d->drawNSViewInRect(tf, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) {
- Q_UNUSED(ctx);
+ d->drawNSViewInRect(tf, opt->rect, p, ^(CGContextRef, const CGRect &rect) {
[tf.cell drawWithFrame:rect inView:tf];
});
} else {
@@ -3266,8 +3264,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
{
Q_D(const QMacStyle);
QMacCGContext cg(p);
- QWindow *window = w && w->window() ? w->window()->windowHandle() :
- QStyleHelper::styleObjectWindow(opt->styleObject);
+ QWindow *window = w && w->window() ? w->window()->windowHandle() : nullptr;
d->resolveCurrentNSView(window);
switch (ce) {
case CE_HeaderSection:
@@ -3468,7 +3465,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
pb.enabled = isEnabled;
[pb highlight:isPressed];
pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState;
- d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) {
+ d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef, const CGRect &r) {
[pb.cell drawBezelWithFrame:r inView:pb.superview];
});
[pb highlight:NO];
@@ -4210,7 +4207,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge);
auto *sv = static_cast<NSSplitView *>(d->cocoaControl(cw));
sv.frame = opt->rect.toCGRect();
- d->drawNSViewInRect(sv, opt->rect, p, ^(CGContextRef __unused ctx, const CGRect &rect) {
+ d->drawNSViewInRect(sv, opt->rect, p, ^(CGContextRef, const CGRect &rect) {
[sv drawDividerInRect:rect];
});
} else {
@@ -4253,12 +4250,13 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
#ifndef QT_NO_TOOLBAR
case CE_ToolBar: {
const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt);
+ const bool isDarkMode = qt_mac_applicationIsInDarkMode();
// Unified title and toolbar drawing. In this mode the cocoa platform plugin will
// fill the top toolbar area part with a background gradient that "unifies" with
// the title bar. The following code fills the toolBar area with transparent pixels
// to make that gradient visible.
- if (w) {
+ if (w) {
#if QT_CONFIG(mainwindow)
if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) {
if (toolBar && toolBar->toolBarArea == Qt::TopToolBarArea && mainWindow->unifiedTitleAndToolBarOnMac()) {
@@ -4268,7 +4266,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
p->fillRect(opt->rect, Qt::transparent);
p->restore();
- // Drow a horizontal separator line at the toolBar bottom if the "unified" area ends here.
+ // Draw a horizontal separator line at the toolBar bottom if the "unified" area ends here.
// There might be additional toolbars or other widgets such as tab bars in document
// mode below. Determine this by making a unified toolbar area test for the row below
// this toolbar.
@@ -4277,7 +4275,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (isEndOfUnifiedArea) {
const int margin = qt_mac_aqua_get_metric(SeparatorSize);
const auto separatorRect = QRect(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
- p->fillRect(separatorRect, opt->palette.dark().color());
+ p->fillRect(separatorRect, isDarkMode ? darkModeSeparatorLine : opt->palette.dark().color());
}
break;
}
@@ -4292,21 +4290,23 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
else
linearGrad = QLinearGradient(opt->rect.left(), 0, opt->rect.right(), 0);
+ QColor mainWindowGradientBegin = isDarkMode ? darkMainWindowGradientBegin : lightMainWindowGradientBegin;
+ QColor mainWindowGradientEnd = isDarkMode ? darkMainWindowGradientEnd : lightMainWindowGradientEnd;
+
linearGrad.setColorAt(0, mainWindowGradientBegin);
linearGrad.setColorAt(1, mainWindowGradientEnd);
p->fillRect(opt->rect, linearGrad);
p->save();
if (opt->state & State_Horizontal) {
- p->setPen(mainWindowGradientBegin.lighter(114));
+ p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114));
p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
- p->setPen(mainWindowGradientEnd.darker(114));
+ p->setPen(isDarkMode ? darkModeSeparatorLine :mainWindowGradientEnd.darker(114));
p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
-
} else {
- p->setPen(mainWindowGradientBegin.lighter(114));
+ p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114));
p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
- p->setPen(mainWindowGradientEnd.darker(114));
+ p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientEnd.darker(114));
p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
}
p->restore();
@@ -4841,8 +4841,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
{
Q_D(const QMacStyle);
QMacCGContext cg(p);
- QWindow *window = widget && widget->window() ? widget->window()->windowHandle() :
- QStyleHelper::styleObjectWindow(opt->styleObject);
+ QWindow *window = widget && widget->window() ? widget->window()->windowHandle() : nullptr;
d->resolveCurrentNSView(window);
switch (cc) {
case CC_ScrollBar:
@@ -5217,7 +5216,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
}
pb.frame = frameRect.toCGRect();
[pb highlight:isPressed];
- d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) {
+ d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef, const CGRect &r) {
[pb.cell drawBezelWithFrame:r inView:pb.superview];
});
} else if (cw.type == QMacStylePrivate::ComboBox) {
@@ -5233,7 +5232,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
// TODO Render to pixmap and darken the button manually
}
- d->drawNSViewInRect(cb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) {
+ d->drawNSViewInRect(cb, frameRect, p, ^(CGContextRef, const CGRect &r) {
// FIXME This is usually drawn in the control's superview, but we wouldn't get inactive look in this case
[cb.cell drawWithFrame:r inView:cb];
});
@@ -5305,13 +5304,10 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
Q_UNUSED(isHovered); // FIXME No public API for this
const auto buttonRect = proxy()->subControlRect(CC_TitleBar, titlebar, sc, widget);
- const auto drawBlock = ^ (CGContextRef ctx, const CGRect &rect) {
- Q_UNUSED(ctx);
- Q_UNUSED(rect);
+ d->drawNSViewInRect(wb, buttonRect, p, ^(CGContextRef, const CGRect &rect) {
auto *wbCell = static_cast<NSButtonCell *>(wb.cell);
[wbCell drawWithFrame:rect inView:wb];
- };
- d->drawNSViewInRect(wb, buttonRect, p, drawBlock);
+ });
}
}
@@ -5376,12 +5372,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
d->drawToolbarButtonArrow(tb, p);
}
if (tb->state & State_On) {
- QWindow *window = 0;
- if (widget && widget->window())
- window = widget->window()->windowHandle();
- else if (opt->styleObject)
- window = opt->styleObject->property("_q_styleObjectWindow").value<QWindow *>();
-
NSView *view = window ? (NSView *)window->winId() : nil;
bool isKey = false;
if (view)
@@ -5420,8 +5410,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
pb.enabled = isEnabled;
[pb highlight:isPressed];
pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState;
- const auto buttonRect = proxy()->subControlRect(cc, tb, SC_ToolButton, widget);
- d->drawNSViewInRect(pb, buttonRect, p, ^(CGContextRef __unused ctx, const CGRect &rect) {
+ const auto buttonRect = proxy()->subControlRect(cc, tb, SC_ToolButton, widget);
+ d->drawNSViewInRect(pb, buttonRect, p, ^(CGContextRef, const CGRect &rect) {
[pb.cell drawBezelWithFrame:rect inView:pb];
});
}
@@ -5904,7 +5894,7 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
switch (ct) {
#if QT_CONFIG(spinbox)
case CT_SpinBox:
- if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ if (qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
const int buttonWidth = 20; // FIXME Use subControlRect()
sz += QSize(buttonWidth, 0);
}
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
index 6add110249..7b35d1b58c 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
@@ -179,9 +179,7 @@ QWindowsVistaStyle::QWindowsVistaStyle()
/*!
Destructor.
*/
-QWindowsVistaStyle::~QWindowsVistaStyle()
-{
-}
+QWindowsVistaStyle::~QWindowsVistaStyle() = default;
//convert Qt state flags to uxtheme button states
static int buttonStateId(int flags, int partId)
@@ -2171,12 +2169,12 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
if (!buttonVisible(subControl, tb))
return rect;
+ const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget);
const bool isToolTitle = false;
const int height = tb->rect.height();
const int width = tb->rect.width();
const int buttonWidth =
- qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)
- - QStyleHelper::dpiScaled(4));
+ qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor - QStyleHelper::dpiScaled(4));
const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
@@ -2190,31 +2188,31 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
if (isToolTitle) {
if (sysmenuHint) {
- rect.adjust(0, 0, -buttonWidth - 3, 0);
+ rect.adjust(0, 0, int(-buttonWidth - 3 * factor), 0);
}
if (minimizeHint || maximizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
+ rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
} else {
if (sysmenuHint) {
- const int leftOffset = height - 8;
- rect.adjust(leftOffset, 0, 0, 4);
+ const int leftOffset = int(height - 8 * factor);
+ rect.adjust(leftOffset, 0, 0, int(4 * factor));
}
if (minimizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
+ rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
if (maximizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
+ rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
if (contextHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
+ rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
if (shadeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
+ rect.adjust(0, 0, int(-buttonWidth - 2 * factor), 0);
}
- rect.translate(0, 2);
+ rect.translate(0, int(2 * factor));
rect = visualRect(option->direction, option->rect, rect);
break;
case SC_TitleBarSysMenu:
{
- const int controlTop = 6;
- const int controlHeight = height - controlTop - 3;
+ const int controlTop = int(6 * factor);
+ const int controlHeight = int(height - controlTop - 3 * factor);
int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
if (tb->icon.isNull())
@@ -2222,7 +2220,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
int hPad = (controlHeight - iconSize.height())/2;
int vPad = (controlHeight - iconSize.width())/2;
rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
- rect.translate(0, 3);
+ rect.translate(0, int(3 * factor));
rect = visualRect(option->direction, option->rect, rect);
}
break;
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h b/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h
index 5ffcbc6aa9..0ebb0eb41a 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h
@@ -62,38 +62,41 @@ class QWindowsVistaStyle : public QWindowsXPStyle
Q_OBJECT
public:
QWindowsVistaStyle();
- ~QWindowsVistaStyle();
+ ~QWindowsVistaStyle() override;
void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
+ QPainter *painter,
+ const QWidget *widget = nullptr) const override;
void drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
+ QPainter *painter, const QWidget *widget) const override;
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const;
+ QPainter *painter, const QWidget *widget) const override;
QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const;
+ const QSize &size, const QWidget *widget) const override;
- QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subElementRect(SubElement element, const QStyleOption *option,
+ const QWidget *widget) const override;
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget) const;
+ SubControl sc, const QWidget *widget) const override;
SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- const QPoint &pos, const QWidget *widget = 0) const;
+ const QPoint &pos, const QWidget *widget = nullptr) const override;
- QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
+ QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override;
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget = 0) const;
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
- int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
+ const QWidget *widget = nullptr) const override;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override;
+ int styleHint(StyleHint hint, const QStyleOption *opt = nullptr,
+ const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override;
- void polish(QWidget *widget);
- void unpolish(QWidget *widget);
- void polish(QPalette &pal);
- void polish(QApplication *app);
- void unpolish(QApplication *app);
- QPalette standardPalette() const;
+ void polish(QWidget *widget) override;
+ void unpolish(QWidget *widget) override;
+ void polish(QPalette &pal) override;
+ void polish(QApplication *app) override;
+ void unpolish(QApplication *app) override;
+ QPalette standardPalette() const override;
private:
Q_DISABLE_COPY(QWindowsVistaStyle)
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
index 36a8afb453..4b583e13d3 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
@@ -494,7 +494,8 @@ bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData)
QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
{
HRGN hRgn = 0;
- RECT rect = themeData.toRECT(themeData.rect);
+ const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(themeData.widget);
+ RECT rect = themeData.toRECT(QRect(themeData.rect.topLeft() / factor, themeData.rect.size() / factor));
if (!SUCCEEDED(GetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
themeData.stateId, &rect, &hRgn))) {
return QRegion();
@@ -523,7 +524,7 @@ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
RECT *r = reinterpret_cast<RECT*>(rd->Buffer);
for (uint i = 0; i < rd->rdh.nCount; ++i) {
QRect rect;
- rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1);
+ rect.setCoords(int(r->left * factor), int(r->top * factor), int((r->right - 1) * factor), int((r->bottom - 1) * factor));
++r;
region |= rect;
}
@@ -1756,9 +1757,9 @@ case PE_Frame:
else
stateId = FS_INACTIVE;
- int fwidth = frm->lineWidth + frm->midLineWidth;
+ int fwidth = int((frm->lineWidth + frm->midLineWidth) / QWindowsStylePrivate::nativeMetricScaleFactor(widget));
- XPThemeData theme(0, p, themeNumber, 0, stateId);
+ XPThemeData theme(widget, p, themeNumber, 0, stateId);
if (!theme.isValid())
break;
@@ -2949,6 +2950,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
{
if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option))
{
+ const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget);
bool isActive = tb->titleBarState & QStyle::State_Active;
XPThemeData theme(widget, p, QWindowsXPStylePrivate::WindowTheme);
if (sub & SC_TitleBarLabel) {
@@ -2975,13 +2977,15 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo
GetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
p->setPen(textShadow);
- p->drawText(ir.x() + 3, ir.y() + 2, ir.width() - 1, ir.height(),
+ p->drawText(int(ir.x() + 3 * factor), int(ir.y() + 2 * factor),
+ int(ir.width() - 1 * factor), ir.height(),
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
}
COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
p->setPen(textColor);
- p->drawText(ir.x() + 2, ir.y() + 1, ir.width() - 2, ir.height(),
+ p->drawText(int(ir.x() + 2 * factor), int(ir.y() + 1 * factor),
+ int(ir.width() - 2 * factor), ir.height(),
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
}
if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h b/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h
index d00620eefa..7e9f4ddda6 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h
@@ -63,35 +63,37 @@ class QWindowsXPStyle : public QWindowsStyle
public:
QWindowsXPStyle();
QWindowsXPStyle(QWindowsXPStylePrivate &dd);
- ~QWindowsXPStyle();
+ ~QWindowsXPStyle() override;
- void unpolish(QApplication*);
- void polish(QApplication*);
- void polish(QWidget*);
- void polish(QPalette&);
- void unpolish(QWidget*);
+ void unpolish(QApplication*) override;
+ void polish(QApplication*) override;
+ void polish(QWidget*) override;
+ void polish(QPalette&) override;
+ void unpolish(QWidget*) override;
void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p,
- const QWidget *widget = 0) const;
+ const QWidget *widget = nullptr) const override;
void drawControl(ControlElement element, const QStyleOption *option, QPainter *p,
- const QWidget *wwidget = 0) const;
- QRect subElementRect(SubElement r, const QStyleOption *option, const QWidget *widget = 0) const;
+ const QWidget *wwidget = nullptr) const override;
+ QRect subElementRect(SubElement r, const QStyleOption *option,
+ const QWidget *widget = nullptr) const override;
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc,
- const QWidget *widget = 0) const;
+ const QWidget *widget = nullptr) const override;
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p,
- const QWidget *widget = 0) const;
+ const QWidget *widget = nullptr) const override;
QSize sizeFromContents(ContentsType ct, const QStyleOption *option, const QSize &contentsSize,
- const QWidget *widget = 0) const;
- int pixelMetric(PixelMetric pm, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
- int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
+ const QWidget *widget = nullptr) const override;
+ int pixelMetric(PixelMetric pm, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override;
+ int styleHint(StyleHint hint, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr,
+ QStyleHintReturn *returnData = nullptr) const override;
- QPalette standardPalette() const;
+ QPalette standardPalette() const override;
QPixmap standardPixmap(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget = 0) const;
- QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
+ const QWidget *widget = nullptr) const override;
+ QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override;
private:
Q_DISABLE_COPY(QWindowsXPStyle)
diff --git a/src/printsupport/dialogs/qpagesetupdialog_mac.mm b/src/printsupport/dialogs/qpagesetupdialog_mac.mm
index 1e398452f7..a3511fe7b6 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_mac.mm
+++ b/src/printsupport/dialogs/qpagesetupdialog_mac.mm
@@ -52,16 +52,13 @@ QT_USE_NAMESPACE
@class QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate);
@interface QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) : NSObject
-{
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) {
NSPrintInfo *printInfo;
}
-- (id)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo;
-- (void)pageLayoutDidEnd:(NSPageLayout *)pageLayout
- returnCode:(int)returnCode contextInfo:(void *)contextInfo;
-@end
-@implementation QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate)
-- (id)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo
+- (instancetype)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo
{
self = [super init];
if (self) {
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
index 7e32f9aa57..d9b4a84aa9 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
@@ -49,6 +49,7 @@
#include "qpainter.h"
#include "qprintdialog.h"
+#include "qtextcodec.h"
#include "qdialogbuttonbox.h"
#include <ui_qpagesetupwidget.h>
@@ -235,6 +236,9 @@ QPageSetupWidget::QPageSetupWidget(QWidget *parent)
m_pagePreview(nullptr),
m_printer(nullptr),
m_printDevice(nullptr),
+#if QT_CONFIG(cups)
+ m_pageSizePpdOption(nullptr),
+#endif
m_outputFormat(QPrinter::PdfFormat),
m_units(QPageLayout::Point),
m_savedUnits(QPageLayout::Point),
@@ -391,6 +395,11 @@ void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice,
m_printer = printer;
m_printDevice = printDevice;
+#if QT_CONFIG(cups)
+ // find the PageSize cups option
+ m_pageSizePpdOption = m_printDevice ? QCUPSSupport::findPpdOption("PageSize", m_printDevice) : nullptr;
+#endif
+
// Initialize the layout to the current QPrinter layout
m_pageLayout = m_printer->pageLayout();
@@ -415,6 +424,12 @@ void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice,
initPageSizes();
updateWidget();
updateSavedValues();
+
+ if (m_ui.pageSizeCombo->currentIndex() == -1) {
+ // This can happen in raw printers that since they don't have a default
+ // page size none will get selected so just default to the first size (A4)
+ m_ui.pageSizeCombo->setCurrentIndex(0);
+ }
}
// Update the widget with the current settings
@@ -547,15 +562,48 @@ void QPageSetupWidget::revertToSavedValues()
m_ui.pagesPerSheetLayoutCombo->setCurrentIndex(m_savedPagesPerSheetLayout);
}
+#if QT_CONFIG(cups)
+bool QPageSetupWidget::hasPpdConflict() const
+{
+ if (m_pageSizePpdOption) {
+ if (m_pageSizePpdOption->conflicted) {
+ const QIcon warning = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr);
+ const int pixmap_size = m_ui.pageSizeCombo->sizeHint().height() * .75;
+ m_ui.pageSizeWarningLabel->setPixmap(warning.pixmap(pixmap_size, pixmap_size));
+ } else {
+ m_ui.pageSizeWarningLabel->setPixmap(QPixmap());
+ }
+ return m_pageSizePpdOption->conflicted;
+ }
+
+ return false;
+}
+#endif
+
// Updates size/preview after the combobox has been changed.
void QPageSetupWidget::pageSizeChanged()
{
- if (m_blockSignals)
- return;
-
QPageSize pageSize;
if (m_ui.pageSizeCombo->currentIndex() != m_realCustomPageSizeIndex) {
pageSize = m_ui.pageSizeCombo->currentData().value<QPageSize>();
+
+#if QT_CONFIG(cups)
+ if (m_pageSizePpdOption) {
+ ppd_file_t *ppd = m_printDevice->property(PDPK_PpdFile).value<ppd_file_t*>();
+ QTextCodec *cupsCodec = QTextCodec::codecForName(ppd->lang_encoding);
+ for (int i = 0; i < m_pageSizePpdOption->num_choices; ++i) {
+ const ppd_choice_t *choice = &m_pageSizePpdOption->choices[i];
+ if (cupsCodec->toUnicode(choice->text) == m_ui.pageSizeCombo->currentText()) {
+ const auto values = QStringList{} << QString::fromLatin1(m_pageSizePpdOption->keyword)
+ << QString::fromLatin1(choice->choice);
+ m_printDevice->setProperty(PDPK_PpdOption, values);
+ emit ppdOptionChanged();
+ break;
+ }
+ }
+ }
+#endif
+
} else {
QSizeF customSize;
if (m_pageLayout.orientation() == QPageLayout::Landscape)
@@ -563,7 +611,22 @@ void QPageSetupWidget::pageSizeChanged()
else
customSize = QSizeF(m_ui.pageWidth->value(), m_ui.pageHeight->value());
pageSize = QPageSize(customSize, QPageSize::Unit(m_units));
+
+#if QT_CONFIG(cups)
+ if (m_pageSizePpdOption) {
+ const auto values = QStringList{} << QString::fromLatin1(m_pageSizePpdOption->keyword)
+ << QStringLiteral("Custom");
+ m_printDevice->setProperty(PDPK_PpdOption, values);
+ emit ppdOptionChanged();
+ }
+#endif
}
+
+ // We always need to update the m_pageSizePpdOption when the page size changes
+ // even if it's from inside updateWidget, so do not move up
+ if (m_blockSignals)
+ return;
+
const QMarginsF printable = m_printDevice ? m_printDevice->printableMargins(pageSize, m_pageLayout.orientation(), m_printer->resolution())
: QMarginsF();
m_pageLayout.setPageSize(pageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units()));
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
index bb33a0f587..7bfdaed740 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
@@ -54,6 +54,7 @@
#include <QtPrintSupport/private/qtprintsupportglobal_p.h>
#include "qprinter.h"
+#include "kernel/qprint_p.h"
#include <QtGui/qpagelayout.h>
@@ -78,6 +79,13 @@ public:
void updateSavedValues();
void revertToSavedValues();
+#if QT_CONFIG(cups)
+ bool hasPpdConflict() const;
+
+signals:
+ void ppdOptionChanged();
+#endif
+
private slots:
void pageSizeChanged();
void pageOrientationChanged();
@@ -100,6 +108,9 @@ private:
QPagePreview *m_pagePreview;
QPrinter *m_printer;
QPrintDevice *m_printDevice;
+#if QT_CONFIG(cups)
+ ppd_option_t *m_pageSizePpdOption;
+#endif
QPrinter::OutputFormat m_outputFormat;
QString m_printerName;
QPageLayout m_pageLayout;
diff --git a/src/printsupport/dialogs/qpagesetupwidget.ui b/src/printsupport/dialogs/qpagesetupwidget.ui
index 960a9dac17..3f24553c76 100644
--- a/src/printsupport/dialogs/qpagesetupwidget.ui
+++ b/src/printsupport/dialogs/qpagesetupwidget.ui
@@ -99,6 +99,9 @@
</property>
</spacer>
</item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="pageSizeWarningLabel"/>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm
index 854779977c..ed2d0908c4 100644
--- a/src/printsupport/dialogs/qprintdialog_mac.mm
+++ b/src/printsupport/dialogs/qprintdialog_mac.mm
@@ -77,22 +77,20 @@ QT_USE_NAMESPACE
@class QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate);
@interface QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) : NSObject
-{
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) {
NSPrintInfo *printInfo;
}
-- (id)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo;
-- (void)printPanelDidEnd:(NSPrintPanel *)printPanel
- returnCode:(int)returnCode contextInfo:(void *)contextInfo;
-@end
-@implementation QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate)
-- (id)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo
+- (instancetype)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo
{
- if (self = [super init]) {
+ if ((self = [self init])) {
printInfo = nsPrintInfo;
}
return self;
}
+
- (void)printPanelDidEnd:(NSPrintPanel *)printPanel
returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
@@ -102,8 +100,8 @@ QT_USE_NAMESPACE
QPrinter *printer = dialog->printer();
if (returnCode == NSModalResponseOK) {
- PMPrintSession session = static_cast<PMPrintSession>([printInfo PMPrintSession]);
- PMPrintSettings settings = static_cast<PMPrintSettings>([printInfo PMPrintSettings]);
+ PMPrintSession session = static_cast<PMPrintSession>(printInfo.PMPrintSession);
+ PMPrintSettings settings = static_cast<PMPrintSettings>(printInfo.PMPrintSettings);
UInt32 frompage, topage;
PMGetFirstPage(settings, &frompage);
@@ -192,6 +190,7 @@ QT_USE_NAMESPACE
dialog->done((returnCode == NSModalResponseOK) ? QDialog::Accepted : QDialog::Rejected);
}
+
@end
QT_BEGIN_NAMESPACE
diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp
index 86daea3b02..5390a8b2f2 100644
--- a/src/printsupport/dialogs/qprintdialog_unix.cpp
+++ b/src/printsupport/dialogs/qprintdialog_unix.cpp
@@ -50,12 +50,14 @@
#endif
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
+#include <QtCore/qglobal.h>
#include <QtCore/qtextcodec.h>
#include <QtGui/qevent.h>
#if QT_CONFIG(filesystemmodel)
#include <QtWidgets/qfilesystemmodel.h>
#endif
#include <QtWidgets/qstyleditemdelegate.h>
+#include <QtWidgets/qformlayout.h>
#include <QtPrintSupport/qprinter.h>
#include <qpa/qplatformprintplugin.h>
@@ -73,6 +75,7 @@
#include "ui_qprintwidget.h"
#if QT_CONFIG(cups)
+Q_DECLARE_METATYPE(const ppd_option_t *)
#include <private/qcups_p.h>
#if QT_CONFIG(cupsjobwidget)
#include "qcupsjobwidget_p.h"
@@ -110,11 +113,6 @@ Print dialog class declarations
allow editing of Page and Advanced tabs.
Layout in qprintpropertieswidget.ui
-
- QPPDOptionsModel: Holds the PPD Options for the printer.
-
- QPPDOptionsEditor: Edits the PPD Options for the printer.
-
*/
static void initResources()
@@ -124,9 +122,6 @@ static void initResources()
QT_BEGIN_NAMESPACE
-class QOptionTreeItem;
-class QPPDOptionsModel;
-
class QPrintPropertiesDialog : public QDialog
{
Q_OBJECT
@@ -138,13 +133,13 @@ public:
void setupPrinter() const;
- void showEvent(QShowEvent *event) override;
-
private slots:
void reject() override;
void accept() override;
private:
+ void showEvent(QShowEvent *event) override;
+
friend class QUnixPrintWidgetPrivate;
#if QT_CONFIG(cups)
QPrinter *m_printer;
@@ -156,9 +151,16 @@ private:
#endif
#if QT_CONFIG(cups)
- void setCupsOptionsFromItems(QOptionTreeItem *parent) const;
+ bool createAdvancedOptionsWidget();
+ void setPrinterAdvancedCupsOptions() const;
+ void revertAdvancedOptionsToSavedValues() const;
+ void advancedOptionsUpdateSavedValues() const;
+ bool anyPpdOptionConflict() const;
+ bool anyAdvancedOptionConflict() const;
- QPPDOptionsModel *m_cupsOptionsModel;
+ QPrintDevice *m_currentPrintDevice;
+ QTextCodec *m_cupsCodec = nullptr;
+ QVector<QComboBox*> m_advancedOptionsCombos;
#endif
};
@@ -174,6 +176,7 @@ public:
void updatePrinter();
private:
+ friend class QPrintDialog;
friend class QPrintDialogPrivate;
friend class QUnixPrintWidgetPrivate;
QUnixPrintWidgetPrivate *d;
@@ -206,6 +209,11 @@ public:
void updateWidget();
+#if QT_CONFIG(cups)
+ void setPpdDuplex(QPrinter::DuplexMode mode);
+ ppd_option_t *m_duplexPpdOption;
+#endif
+
private:
QPrintDialogPrivate *optionsPane;
bool filePrintersAdded;
@@ -229,6 +237,9 @@ public:
#endif
void _q_collapseOrExpandDialog();
+#if QT_CONFIG(cups)
+ void updatePpdDuplexOption(QRadioButton *radio);
+#endif
void setupPrinter();
void updateWidgets();
@@ -240,103 +251,12 @@ public:
QDialogButtonBox *buttons;
QPushButton *collapseButton;
QPrinter::OutputFormat printerOutputFormat;
-};
-
-#if QT_CONFIG(cups)
-class QOptionTreeItem
-{
-public:
- enum ItemType { Root, Group, Option, Choice };
-
- QOptionTreeItem(ItemType t, int i, const void *p, QOptionTreeItem *pi)
- : type(t),
- index(i),
- ptr(p),
- parentItem(pi) {}
-
- ~QOptionTreeItem() {
- qDeleteAll(childItems);
- }
-
- ItemType type;
- int index;
- const void *ptr;
- QOptionTreeItem *parentItem;
- QList<QOptionTreeItem*> childItems;
-};
-
-class QOptionTreeItemOption : public QOptionTreeItem
-{
-public:
- QOptionTreeItemOption (int i, const void *p, QOptionTreeItem *pi)
- : QOptionTreeItem(Option, i, p, pi)
- {
- }
-
- // These indices are related to ppd_option_t::choices not to childItems
- int selected;
- int originallySelected;
-};
-
-class QPPDOptionsModel : public QAbstractItemModel
-{
- Q_OBJECT
-
-public:
- explicit QPPDOptionsModel(QPrintDevice *currentPrintDevice, QObject *parent);
-
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
- QModelIndex parent(const QModelIndex &index) const override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
-
- void setCupsOptionsFromItems(QPrinter *printer) const;
- void reject();
- void updateSavedValues();
- void revertToSavedValues();
-
- QPrintDevice *currentPrintDevice() const;
- QTextCodec *cupsCodec() const;
-
- void emitConflictsChanged();
- bool hasConflicts() const;
-
-signals:
- void hasConflictsChanged(bool conflicts);
-
private:
- void parseGroups(QOptionTreeItem *parent);
- void parseOptions(QOptionTreeItem *parent);
- void parseChoices(QOptionTreeItemOption *parent);
-
- void setCupsOptionsFromItems(QPrinter *printer, QOptionTreeItem *parent) const;
- void reject(QOptionTreeItem *item);
- void updateSavedValues(QOptionTreeItem *item);
- void revertToSavedValues(QOptionTreeItem *item);
- void emitDataChanged(QOptionTreeItem *item, const QModelIndex &itemIndex, bool *conflictsFound);
- bool hasConflicts(QOptionTreeItem *item) const;
-
- QPrintDevice *m_currentPrintDevice;
- QTextCodec *m_cupsCodec;
- QOptionTreeItem *m_rootItem;
+ void setExplicitDuplexMode(QPrint::DuplexMode duplexMode);
+ // duplex mode explicitly set by user, QPrint::DuplexAuto otherwise
+ QPrint::DuplexMode explicitDuplexMode;
};
-class QPPDOptionsEditor : public QStyledItemDelegate
-{
- Q_OBJECT
-public:
- explicit QPPDOptionsEditor(QObject *parent) : QStyledItemDelegate(parent) {}
-
- QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
- void setEditorData(QWidget *editor, const QModelIndex &index) const override;
- void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
-};
-
-#endif
-
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -377,24 +297,15 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QPrinter *printer, QPrintDevice *
const int advancedTabIndex = widget.tabs->indexOf(widget.cupsPropertiesPage);
#if QT_CONFIG(cups)
- m_cupsOptionsModel = new QPPDOptionsModel(currentPrintDevice, this);
-
- widget.treeView->setItemDelegate(new QPPDOptionsEditor(this));
+ m_currentPrintDevice = currentPrintDevice;
+ const bool anyWidgetCreated = createAdvancedOptionsWidget();
- if (m_cupsOptionsModel->rowCount() > 0) {
- widget.treeView->setModel(m_cupsOptionsModel);
+ widget.tabs->setTabEnabled(advancedTabIndex, anyWidgetCreated);
- for (int i = 0; i < m_cupsOptionsModel->rowCount(); ++i)
- widget.treeView->expand(m_cupsOptionsModel->index(i, 0));
+ connect(widget.pageSetup, &QPageSetupWidget::ppdOptionChanged, this, [this] {
+ widget.conflictsLabel->setVisible(anyPpdOptionConflict());
+ });
- widget.tabs->setTabEnabled(advancedTabIndex, true);
- } else {
- widget.treeView->setModel(nullptr);
- widget.tabs->setTabEnabled(advancedTabIndex, false);
- }
-
- widget.conflictsLabel->setVisible(m_cupsOptionsModel->hasConflicts());
- connect(m_cupsOptionsModel, &QPPDOptionsModel::hasConflictsChanged, widget.conflictsLabel, &QLabel::setVisible);
#else
Q_UNUSED(currentPrintDevice)
widget.tabs->setTabEnabled(advancedTabIndex, false);
@@ -420,16 +331,10 @@ void QPrintPropertiesDialog::setupPrinter() const
// Set Color by default, that will change if the "ColorModel" property is available
m_printer->setColorMode(QPrinter::Color);
- m_cupsOptionsModel->setCupsOptionsFromItems(m_printer);
+ setPrinterAdvancedCupsOptions();
#endif
}
-void QPrintPropertiesDialog::showEvent(QShowEvent *event)
-{
- widget.treeView->resizeColumnToContents(0);
- QDialog::showEvent(event);
-}
-
void QPrintPropertiesDialog::reject()
{
widget.pageSetup->revertToSavedValues();
@@ -439,7 +344,7 @@ void QPrintPropertiesDialog::reject()
#endif
#if QT_CONFIG(cups)
- m_cupsOptionsModel->revertToSavedValues();
+ revertAdvancedOptionsToSavedValues();
#endif
QDialog::reject();
}
@@ -447,7 +352,14 @@ void QPrintPropertiesDialog::reject()
void QPrintPropertiesDialog::accept()
{
#if QT_CONFIG(cups)
- if (m_cupsOptionsModel->hasConflicts()) {
+ if (widget.pageSetup->hasPpdConflict()) {
+ widget.tabs->setCurrentWidget(widget.tabPage);
+ const QMessageBox::StandardButton answer = QMessageBox::warning(this, tr("Page Setup Conflicts"),
+ tr("There are conflicts in page setup options. Do you want to fix them?"),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+ if (answer != QMessageBox::No)
+ return;
+ } else if (anyAdvancedOptionConflict()) {
widget.tabs->setCurrentWidget(widget.cupsPropertiesPage);
const QMessageBox::StandardButton answer = QMessageBox::warning(this, tr("Advanced Option Conflicts"),
tr("There are conflicts in some advanced options. Do you want to fix them?"),
@@ -455,7 +367,7 @@ void QPrintPropertiesDialog::accept()
if (answer != QMessageBox::No)
return;
}
- m_cupsOptionsModel->updateSavedValues();
+ advancedOptionsUpdateSavedValues();
#endif
#if QT_CONFIG(cupsjobwidget)
@@ -467,6 +379,224 @@ void QPrintPropertiesDialog::accept()
QDialog::accept();
}
+void QPrintPropertiesDialog::showEvent(QShowEvent *event)
+{
+#if QT_CONFIG(cups)
+ widget.conflictsLabel->setVisible(anyPpdOptionConflict());
+#endif
+ QDialog::showEvent(event);
+}
+
+#if QT_CONFIG(cups)
+
+// Used to store the ppd_option_t for each QComboBox that represents an advanced option
+static const char *ppdOptionProperty = "_q_ppd_option";
+
+// Used to store the originally selected choice index for each QComboBox that represents an advanced option
+static const char *ppdOriginallySelectedChoiceProperty = "_q_ppd_originally_selected_choice";
+
+// Used to store the warning label pointer for each QComboBox that represents an advanced option
+static const char *warningLabelProperty = "_q_warning_label";
+
+static bool isBlacklistedGroup(const ppd_group_t *group) Q_DECL_NOTHROW
+{
+ return qstrcmp(group->name, "InstallableOptions") == 0;
+};
+
+static bool isBlacklistedOption(const char *keyword) Q_DECL_NOTHROW
+{
+ // We already let the user set these options elsewhere
+ const char *cupsOptionBlacklist[] = {
+ "Collate",
+ "Copies",
+ "OutputOrder",
+ "PageRegion",
+ "PageSize",
+ "Duplex" // handled by the main dialog
+ };
+ auto equals = [](const char *keyword) {
+ return [keyword](const char *candidate) {
+ return qstrcmp(keyword, candidate) == 0;
+ };
+ };
+ return std::any_of(std::begin(cupsOptionBlacklist), std::end(cupsOptionBlacklist), equals(keyword));
+};
+
+bool QPrintPropertiesDialog::createAdvancedOptionsWidget()
+{
+ bool anyWidgetCreated = false;
+
+ ppd_file_t *ppd = m_currentPrintDevice->property(PDPK_PpdFile).value<ppd_file_t*>();
+
+ if (ppd) {
+ m_cupsCodec = QTextCodec::codecForName(ppd->lang_encoding);
+
+ QWidget *holdingWidget = new QWidget();
+ QVBoxLayout *layout = new QVBoxLayout(holdingWidget);
+
+ for (int i = 0; i < ppd->num_groups; ++i) {
+ const ppd_group_t *group = &ppd->groups[i];
+
+ if (!isBlacklistedGroup(group)) {
+ QFormLayout *groupLayout = new QFormLayout();
+
+ for (int i = 0; i < group->num_options; ++i) {
+ const ppd_option_t *option = &group->options[i];
+
+ if (!isBlacklistedOption(option->keyword)) {
+ QComboBox *choicesCb = new QComboBox();
+
+ const auto setPpdOptionFromCombo = [this, choicesCb, option] {
+ // We can't use choicesCb->currentIndex() to know the index of the option in the choices[] array
+ // because some of them may not be present in the list because they conflict with the
+ // installable options so use the index passed on addItem
+ const int selectedChoiceIndex = choicesCb->currentData().toInt();
+ const auto values = QStringList{} << QString::fromLatin1(option->keyword)
+ << QString::fromLatin1(option->choices[selectedChoiceIndex].choice);
+ m_currentPrintDevice->setProperty(PDPK_PpdOption, values);
+ widget.conflictsLabel->setVisible(anyPpdOptionConflict());
+ };
+
+ bool foundMarkedChoice = false;
+ bool markedChoiceNotAvailable = false;
+ for (int i = 0; i < option->num_choices; ++i) {
+ const ppd_choice_t *choice = &option->choices[i];
+ const auto values = QStringList{} << QString::fromLatin1(option->keyword) << QString::fromLatin1(choice->choice);
+ const bool choiceIsInstallableConflict = m_currentPrintDevice->isFeatureAvailable(PDPK_PpdChoiceIsInstallableConflict, values);
+ if (choiceIsInstallableConflict && static_cast<int>(choice->marked) == 1) {
+ markedChoiceNotAvailable = true;
+ } else if (!choiceIsInstallableConflict) {
+ choicesCb->addItem(m_cupsCodec->toUnicode(choice->text), i);
+ if (static_cast<int>(choice->marked) == 1) {
+ choicesCb->setCurrentIndex(choicesCb->count() - 1);
+ choicesCb->setProperty(ppdOriginallySelectedChoiceProperty, QVariant(i));
+ foundMarkedChoice = true;
+ } else if (!foundMarkedChoice && qstrcmp(choice->choice, option->defchoice) == 0) {
+ choicesCb->setCurrentIndex(choicesCb->count() - 1);
+ choicesCb->setProperty(ppdOriginallySelectedChoiceProperty, QVariant(i));
+ }
+ }
+ }
+
+ if (markedChoiceNotAvailable) {
+ // If the user default option is not available because of it conflicting with
+ // the installed options, we need to set the internal ppd value to the value
+ // being shown in the combo
+ setPpdOptionFromCombo();
+ }
+
+ if (choicesCb->count() > 1) {
+
+ connect(choicesCb, QOverload<int>::of(&QComboBox::currentIndexChanged), this, setPpdOptionFromCombo);
+
+ // We need an extra label at the end to show the conflict warning
+ QWidget *choicesCbWithLabel = new QWidget();
+ QHBoxLayout *choicesCbWithLabelLayout = new QHBoxLayout(choicesCbWithLabel);
+ choicesCbWithLabelLayout->setContentsMargins(0, 0, 0, 0);
+ QLabel *warningLabel = new QLabel();
+ choicesCbWithLabelLayout->addWidget(choicesCb);
+ choicesCbWithLabelLayout->addWidget(warningLabel);
+
+ QLabel *optionLabel = new QLabel(m_cupsCodec->toUnicode(option->text));
+ groupLayout->addRow(optionLabel, choicesCbWithLabel);
+ anyWidgetCreated = true;
+ choicesCb->setProperty(ppdOptionProperty, QVariant::fromValue(option));
+ choicesCb->setProperty(warningLabelProperty, QVariant::fromValue(warningLabel));
+ m_advancedOptionsCombos << choicesCb;
+ } else {
+ delete choicesCb;
+ }
+ }
+ }
+
+ if (groupLayout->rowCount() > 0) {
+ QGroupBox *groupBox = new QGroupBox(m_cupsCodec->toUnicode(group->text));
+ groupBox->setLayout(groupLayout);
+ layout->addWidget(groupBox);
+ } else {
+ delete groupLayout;
+ }
+ }
+ }
+
+ layout->addStretch();
+ widget.scrollArea->setWidget(holdingWidget);
+ }
+
+ if (!m_cupsCodec)
+ m_cupsCodec = QTextCodec::codecForLocale();
+
+ return anyWidgetCreated;
+}
+
+void QPrintPropertiesDialog::setPrinterAdvancedCupsOptions() const
+{
+ for (const QComboBox *choicesCb : m_advancedOptionsCombos) {
+ const ppd_option_t *option = choicesCb->property(ppdOptionProperty).value<const ppd_option_t *>();
+
+ // We can't use choicesCb->currentIndex() to know the index of the option in the choices[] array
+ // because some of them may not be present in the list because they conflict with the
+ // installable options so use the index passed on addItem
+ const int selectedChoiceIndex = choicesCb->currentData().toInt();
+ const char *selectedChoice = option->choices[selectedChoiceIndex].choice;
+
+ if (qstrcmp(option->keyword, "ColorModel") == 0)
+ m_printer->setColorMode(qstrcmp(selectedChoice, "Gray") == 0 ? QPrinter::GrayScale : QPrinter::Color);
+
+ if (qstrcmp(option->defchoice, selectedChoice) != 0)
+ QCUPSSupport::setCupsOption(m_printer, QString::fromLatin1(option->keyword), QString::fromLatin1(selectedChoice));
+ }
+}
+
+void QPrintPropertiesDialog::revertAdvancedOptionsToSavedValues() const
+{
+ for (QComboBox *choicesCb : m_advancedOptionsCombos) {
+ const int originallySelectedChoice = choicesCb->property(ppdOriginallySelectedChoiceProperty).value<int>();
+ const int newComboIndexToSelect = choicesCb->findData(originallySelectedChoice);
+ choicesCb->setCurrentIndex(newComboIndexToSelect);
+ // The currentIndexChanged lambda takes care of resetting the ppd option
+ }
+ widget.conflictsLabel->setVisible(anyPpdOptionConflict());
+}
+
+void QPrintPropertiesDialog::advancedOptionsUpdateSavedValues() const
+{
+ for (QComboBox *choicesCb : m_advancedOptionsCombos)
+ choicesCb->setProperty(ppdOriginallySelectedChoiceProperty, choicesCb->currentData());
+}
+
+bool QPrintPropertiesDialog::anyPpdOptionConflict() const
+{
+ // we need to execute both since besides returning true/false they update the warning icons
+ const bool pageSetupConflicts = widget.pageSetup->hasPpdConflict();
+ const bool advancedOptionConflicts = anyAdvancedOptionConflict();
+ return pageSetupConflicts || advancedOptionConflicts;
+}
+
+bool QPrintPropertiesDialog::anyAdvancedOptionConflict() const
+{
+ const QIcon warning = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr);
+
+ bool anyConflicted = false;
+
+ for (const QComboBox *choicesCb : m_advancedOptionsCombos) {
+ const ppd_option_t *option = choicesCb->property(ppdOptionProperty).value<const ppd_option_t *>();
+ QLabel *warningLabel = choicesCb->property(warningLabelProperty).value<QLabel *>();
+ if (option->conflicted) {
+ anyConflicted = true;
+ const int pixmap_size = choicesCb->sizeHint().height() * .75;
+ warningLabel->setPixmap(warning.pixmap(pixmap_size, pixmap_size));
+ } else {
+ warningLabel->setPixmap(QPixmap());
+ }
+ }
+
+ return anyConflicted;
+}
+
+#endif
+
+
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -479,7 +609,8 @@ void QPrintPropertiesDialog::accept()
*/
QPrintDialogPrivate::QPrintDialogPrivate()
- : top(nullptr), bottom(nullptr), buttons(nullptr), collapseButton(nullptr)
+ : top(nullptr), bottom(nullptr), buttons(nullptr), collapseButton(nullptr),
+ explicitDuplexMode(QPrint::DuplexAuto)
{
initResources();
}
@@ -540,6 +671,16 @@ void QPrintDialogPrivate::init()
q, SLOT(_q_togglePageSetCombo(bool)));
QObject::connect(collapseButton, SIGNAL(released()), q, SLOT(_q_collapseOrExpandDialog()));
+
+ QObject::connect(options.noDuplex, &QAbstractButton::clicked, q, [this] { setExplicitDuplexMode(QPrint::DuplexNone); });
+ QObject::connect(options.duplexLong, &QAbstractButton::clicked, q, [this] { setExplicitDuplexMode(QPrint::DuplexLongSide); });
+ QObject::connect(options.duplexShort, &QAbstractButton::clicked, q, [this] { setExplicitDuplexMode(QPrint::DuplexShortSide); });
+
+#if QT_CONFIG(cups)
+ QObject::connect(options.noDuplex, &QAbstractButton::toggled, q, [this] { updatePpdDuplexOption(options.noDuplex); });
+ QObject::connect(options.duplexLong, &QAbstractButton::toggled, q, [this] { updatePpdDuplexOption(options.duplexLong); });
+ QObject::connect(options.duplexShort, &QAbstractButton::toggled, q, [this] { updatePpdDuplexOption(options.duplexShort); });
+#endif
}
// initialize printer options
@@ -559,13 +700,20 @@ void QPrintDialogPrivate::selectPrinter(const QPrinter::OutputFormat outputForma
else
options.grayscale->setChecked(true);
- switch (p->duplex()) {
- case QPrinter::DuplexNone:
+ // keep duplex value explicitly set by user, if any, and selected printer supports it;
+ // use device default otherwise
+ QPrint::DuplexMode duplex;
+ if (explicitDuplexMode != QPrint::DuplexAuto && supportedDuplexMode.contains(explicitDuplexMode))
+ duplex = explicitDuplexMode;
+ else
+ duplex = top->d->m_currentPrintDevice.defaultDuplexMode();
+ switch (duplex) {
+ case QPrint::DuplexNone:
options.noDuplex->setChecked(true); break;
- case QPrinter::DuplexLongSide:
- case QPrinter::DuplexAuto:
+ case QPrint::DuplexLongSide:
+ case QPrint::DuplexAuto:
options.duplexLong->setChecked(true); break;
- case QPrinter::DuplexShortSide:
+ case QPrint::DuplexShortSide:
options.duplexShort->setChecked(true); break;
}
options.copies->setValue(p->copyCount());
@@ -665,8 +813,26 @@ static bool isValidPagesString(const QString &pagesString) Q_DECL_NOTHROW
auto pagesRanges = pageRangesFromString(pagesString);
return !pagesRanges.empty();
}
+
+void QPrintDialogPrivate::updatePpdDuplexOption(QRadioButton *radio)
+{
+ const bool checked = radio->isChecked();
+ if (checked) {
+ if (radio == options.noDuplex) top->d->setPpdDuplex(QPrinter::DuplexNone);
+ else if (radio == options.duplexLong) top->d->setPpdDuplex(QPrinter::DuplexLongSide);
+ else if (radio == options.duplexShort) top->d->setPpdDuplex(QPrinter::DuplexShortSide);
+ }
+ const bool conflict = checked && top->d->m_duplexPpdOption && top->d->m_duplexPpdOption->conflicted;
+ radio->setIcon(conflict ? QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr) : QIcon());
+}
+
#endif
+void QPrintDialogPrivate::setExplicitDuplexMode(const QPrint::DuplexMode duplexMode)
+{
+ explicitDuplexMode = duplexMode;
+}
+
void QPrintDialogPrivate::setupPrinter()
{
// First setup the requested OutputFormat, Printer and Page Size first
@@ -931,6 +1097,13 @@ void QPrintDialog::accept()
QMessageBox::Ok, QMessageBox::Ok);
return;
}
+ if (d->top->d->m_duplexPpdOption && d->top->d->m_duplexPpdOption->conflicted) {
+ const QMessageBox::StandardButton answer = QMessageBox::warning(this, tr("Duplex Settings Conflicts"),
+ tr("There are conflicts in duplex settings. Do you want to fix them?"),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+ if (answer != QMessageBox::No)
+ return;
+ }
#endif
d->setupPrinter();
QDialog::accept();
@@ -952,8 +1125,11 @@ void QPrintDialog::accept()
/*! \internal
*/
QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *prn)
- : parent(p), propertiesDialog(nullptr), printer(prn), optionsPane(0),
- filePrintersAdded(false)
+ : parent(p), propertiesDialog(nullptr), printer(prn),
+#if QT_CONFIG(cups)
+ m_duplexPpdOption(nullptr),
+#endif
+ optionsPane(nullptr), filePrintersAdded(false)
{
q = nullptr;
if (parent)
@@ -1043,6 +1219,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
propertiesDialog = nullptr;
}
+#if QT_CONFIG(cups)
+ m_duplexPpdOption = nullptr;
+#endif
+
if (filePrintersAdded) {
Q_ASSERT(index != printerCount - 2); // separator
if (index == printerCount - 1) { // PDF
@@ -1077,6 +1257,10 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
if (optionsPane)
optionsPane->selectPrinter(QPrinter::NativeFormat);
}
+
+#if QT_CONFIG(cups)
+ m_duplexPpdOption = QCUPSSupport::findPpdOption("Duplex", &m_currentPrintDevice);
+#endif
}
void QUnixPrintWidgetPrivate::setOptionsPane(QPrintDialogPrivate *pane)
@@ -1172,11 +1356,30 @@ void QUnixPrintWidgetPrivate::setupPrinterProperties()
propertiesDialog = new QPrintPropertiesDialog(q->printer(), &m_currentPrintDevice, outputFormat, printerName, q);
}
+#if QT_CONFIG(cups)
+void QUnixPrintWidgetPrivate::setPpdDuplex(QPrinter::DuplexMode mode)
+{
+ auto values = QStringList{} << QStringLiteral("Duplex");
+ if (mode == QPrinter::DuplexNone) values << QStringLiteral("None");
+ else if (mode == QPrinter::DuplexLongSide) values << QStringLiteral("DuplexNoTumble");
+ else if (mode == QPrinter::DuplexShortSide) values << QStringLiteral("DuplexTumble");
+
+ m_currentPrintDevice.setProperty(PDPK_PpdOption, values);
+}
+#endif
+
void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked()
{
if (!propertiesDialog)
setupPrinterProperties();
propertiesDialog->exec();
+
+#if QT_CONFIG(cups)
+ // update the warning icon on the duplex options if needed
+ optionsPane->updatePpdDuplexOption(optionsPane->options.noDuplex);
+ optionsPane->updatePpdDuplexOption(optionsPane->options.duplexLong);
+ optionsPane->updatePpdDuplexOption(optionsPane->options.duplexShort);
+#endif
}
void QUnixPrintWidgetPrivate::setupPrinter()
@@ -1262,436 +1465,8 @@ void QUnixPrintWidget::updatePrinter()
d->setupPrinter();
}
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-/*
-
- QPPDOptionsModel
-
- Holds the PPD Options for the printer.
-
-*/
-
#if QT_CONFIG(cups)
-static bool isBlacklistedGroup(ppd_group_t *group) Q_DECL_NOTHROW
-{
- return qstrcmp(group->name, "InstallableOptions") == 0;
-};
-
-QPPDOptionsModel::QPPDOptionsModel(QPrintDevice *currentPrintDevice, QObject *parent)
- : QAbstractItemModel(parent)
- , m_currentPrintDevice(currentPrintDevice)
- , m_cupsCodec(nullptr)
-{
- ppd_file_t *ppd = m_currentPrintDevice->property(PDPK_PpdFile).value<ppd_file_t*>();
- m_rootItem = new QOptionTreeItem(QOptionTreeItem::Root, 0, ppd, nullptr);
-
- if (ppd) {
- m_cupsCodec = QTextCodec::codecForName(ppd->lang_encoding);
- for (int i = 0; i < ppd->num_groups; ++i) {
- if (!isBlacklistedGroup(&ppd->groups[i])) {
- QOptionTreeItem *group = new QOptionTreeItem(QOptionTreeItem::Group, i, &ppd->groups[i], m_rootItem);
- m_rootItem->childItems.append(group);
- parseGroups(group); // parse possible subgroups
- parseOptions(group); // parse options
- }
- }
- }
-
- if (!m_cupsCodec)
- m_cupsCodec = QTextCodec::codecForLocale();
-}
-
-int QPPDOptionsModel::columnCount(const QModelIndex &) const
-{
- return 2;
-}
-
-int QPPDOptionsModel::rowCount(const QModelIndex &parent) const
-{
- QOptionTreeItem *itm;
- if (!parent.isValid())
- itm = m_rootItem;
- else
- itm = static_cast<QOptionTreeItem*>(parent.internalPointer());
-
- if (itm->type == QOptionTreeItem::Option)
- return 0;
-
- return itm->childItems.count();
-}
-
-QVariant QPPDOptionsModel::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- QOptionTreeItem *itm = static_cast<QOptionTreeItem*>(index.internalPointer());
-
- switch (role) {
- case Qt::FontRole: {
- if (itm->type == QOptionTreeItem::Group){
- QFont font;
- font.setBold(true);
- return QVariant(font);
- }
- return QVariant();
- }
- break;
-
- case Qt::DisplayRole: {
- if (index.column() == 0) {
- if (itm->type == QOptionTreeItem::Option) {
- const ppd_option_t *option = static_cast<const ppd_option_t*>(itm->ptr);
- return m_cupsCodec->toUnicode(option->text);
- } else if (itm->type == QOptionTreeItem::Group) {
- const ppd_group_t *group = static_cast<const ppd_group_t*>(itm->ptr);
- return m_cupsCodec->toUnicode(group->text);
- }
- } else if (itm->type == QOptionTreeItem::Option) {
- QOptionTreeItemOption *itmOption = static_cast<QOptionTreeItemOption *>(itm);
- const ppd_option_t *option = static_cast<const ppd_option_t*>(itm->ptr);
- if (itmOption->selected > -1)
- return m_cupsCodec->toUnicode(option->choices[itmOption->selected].text);
- }
-
- return QVariant();
- }
- break;
-
- case Qt::DecorationRole: {
- if (itm->type == QOptionTreeItem::Option && index.column() == 1) {
- const ppd_option_t *option = static_cast<const ppd_option_t*>(itm->ptr);
- if (option->conflicted) {
- const QIcon warning = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr);
- if (!warning.isNull())
- return warning;
-
- qWarning() << "Current application style returned a null icon for SP_MessageBoxWarning.";
- return QColor(Qt::red);
- }
- }
- return QVariant();
- }
- break;
-
- }
-
- return QVariant();
-}
-
-QModelIndex QPPDOptionsModel::index(int row, int column, const QModelIndex &parent) const
-{
- QOptionTreeItem *itm;
- if (!parent.isValid())
- itm = m_rootItem;
- else
- itm = static_cast<QOptionTreeItem*>(parent.internalPointer());
-
- return createIndex(row, column, itm->childItems.at(row));
-}
-
-
-QModelIndex QPPDOptionsModel::parent(const QModelIndex &index) const
-{
- if (!index.isValid())
- return QModelIndex();
-
- QOptionTreeItem *itm = static_cast<QOptionTreeItem*>(index.internalPointer());
-
- if (itm->parentItem && itm->parentItem != m_rootItem)
- return createIndex(itm->parentItem->index, 0, itm->parentItem);
-
- return QModelIndex();
-}
-
-Qt::ItemFlags QPPDOptionsModel::flags(const QModelIndex &index) const
-{
- if (!index.isValid() || static_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Group)
- return Qt::ItemIsEnabled;
-
- if (index.column() == 1)
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
-
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
-}
-
-QPrintDevice *QPPDOptionsModel::currentPrintDevice() const
-{
- return m_currentPrintDevice;
-}
-
-QTextCodec *QPPDOptionsModel::cupsCodec() const
-{
- return m_cupsCodec;
-}
-
-void QPPDOptionsModel::setCupsOptionsFromItems(QPrinter *printer) const
-{
- setCupsOptionsFromItems(printer, m_rootItem);
-}
-
-void QPPDOptionsModel::setCupsOptionsFromItems(QPrinter *printer, QOptionTreeItem *parent) const
-{
- for (QOptionTreeItem *itm : qAsConst(parent->childItems)) {
- if (itm->type == QOptionTreeItem::Option) {
- QOptionTreeItemOption *itmOption = static_cast<QOptionTreeItemOption *>(itm);
- const ppd_option_t *opt = static_cast<const ppd_option_t*>(itm->ptr);
-
- if (qstrcmp(opt->keyword, "ColorModel") == 0)
- printer->setColorMode(qstrcmp(opt->choices[itmOption->selected].choice, "Gray") == 0 ? QPrinter::GrayScale : QPrinter::Color);
-
- if (qstrcmp(opt->defchoice, opt->choices[itmOption->selected].choice) != 0) {
- QCUPSSupport::setCupsOption(printer, QString::fromLatin1(opt->keyword), QString::fromLatin1(opt->choices[itmOption->selected].choice));
- }
- } else {
- setCupsOptionsFromItems(printer, itm);
- }
- }
-}
-
-void QPPDOptionsModel::parseGroups(QOptionTreeItem *parent)
-{
- const ppd_group_t *group = static_cast<const ppd_group_t*>(parent->ptr);
-
- if (group) {
- for (int i = 0; i < group->num_subgroups; ++i) {
- if (!isBlacklistedGroup(&group->subgroups[i])) {
- QOptionTreeItem *subgroup = new QOptionTreeItem(QOptionTreeItem::Group, i, &group->subgroups[i], parent);
- parent->childItems.append(subgroup);
- parseGroups(subgroup); // parse possible subgroups
- parseOptions(subgroup); // parse options
- }
- }
- }
-}
-
-static bool isBlacklistedOption(const char *keyword) Q_DECL_NOTHROW
-{
- // We already let the user set these options elsewhere
- const char *cupsOptionBlacklist[] = {
- "Collate",
- "Copies",
- "OutputOrder",
- "PageRegion",
- "PageSize",
- "Duplex" // handled by the main dialog
- };
- auto equals = [](const char *keyword) {
- return [keyword](const char *candidate) {
- return qstrcmp(keyword, candidate) == 0;
- };
- };
- return std::any_of(std::begin(cupsOptionBlacklist), std::end(cupsOptionBlacklist), equals(keyword));
-};
-
-void QPPDOptionsModel::parseOptions(QOptionTreeItem *parent)
-{
- const ppd_group_t *group = static_cast<const ppd_group_t*>(parent->ptr);
- for (int i = 0; i < group->num_options; ++i) {
- if (!isBlacklistedOption(group->options[i].keyword)) {
- QOptionTreeItemOption *opt = new QOptionTreeItemOption(i, &group->options[i], parent);
- parseChoices(opt);
-
- // Don't show options that are actually not options at all
- // because they don't give the user any choice
- if (opt->childItems.count() > 1)
- parent->childItems.append(opt);
- else
- delete opt;
- }
- }
-}
-
-void QPPDOptionsModel::parseChoices(QOptionTreeItemOption *parent)
-{
- const ppd_option_t *option = static_cast<const ppd_option_t*>(parent->ptr);
- bool marked = false;
- for (int i = 0; i < option->num_choices; ++i) {
- const auto values = QStringList{} << QString::fromLatin1(option->keyword) << QString::fromLatin1(option->choices[i].choice);
- if (!m_currentPrintDevice->isFeatureAvailable(PDPK_PpdChoiceIsInstallableConflict, values)) {
- QOptionTreeItem *choice = new QOptionTreeItem(QOptionTreeItem::Choice, i, &option->choices[i], parent);
- if (static_cast<int>(option->choices[i].marked) == 1) {
- parent->selected = i;
- marked = true;
- } else if (!marked && qstrcmp(option->choices[i].choice, option->defchoice) == 0) {
- parent->selected = i;
- }
- parent->originallySelected = parent->selected;
- parent->childItems.append(choice);
- }
- }
-}
-
-bool QPPDOptionsModel::hasConflicts() const
-{
- return hasConflicts(m_rootItem);
-}
-
-bool QPPDOptionsModel::hasConflicts(QOptionTreeItem *item) const
-{
- if (item->type == QOptionTreeItem::Option) {
- const ppd_option_t *option = static_cast<const ppd_option_t*>(item->ptr);
- return option->conflicted;
- }
-
- for (QOptionTreeItem *child : qAsConst(item->childItems)) {
- if (hasConflicts(child))
- return true;
- }
-
- return false;
-}
-
-void QPPDOptionsModel::emitConflictsChanged()
-{
- bool conflictsFound = false;
- emitDataChanged(m_rootItem, QModelIndex(), &conflictsFound);
-
- emit hasConflictsChanged(conflictsFound);
-}
-
-void QPPDOptionsModel::emitDataChanged(QOptionTreeItem *item, const QModelIndex &itemIndex, bool *conflictsFound)
-{
- if (item->type == QOptionTreeItem::Option) {
- // We just emit DecorationRole dataChanged for all the leaves
- // and let the view requery the value
- const QModelIndex secondColItem = index(itemIndex.row(), 1, itemIndex.parent());
- emit dataChanged(secondColItem, secondColItem, QVector<int>() << Qt::DecorationRole);
-
- if (conflictsFound && *conflictsFound == false) {
- const ppd_option_t *option = static_cast<const ppd_option_t*>(item->ptr);
- if (option->conflicted && conflictsFound)
- *conflictsFound = true;
- }
- }
-
- for (int i = 0; i < item->childItems.count(); ++i) {
- QOptionTreeItem *child = item->childItems.at(i);
- emitDataChanged(child, index(i, 0, itemIndex), conflictsFound);
- }
-}
-
-QVariant QPPDOptionsModel::headerData(int section, Qt::Orientation, int role) const
-{
- if (role != Qt::DisplayRole)
- return QVariant();
-
- switch (section) {
- case 0:
- return QVariant(tr("Name"));
- case 1:
- return QVariant(tr("Value"));
- }
-
- return QVariant();
-}
-
-void QPPDOptionsModel::revertToSavedValues()
-{
- revertToSavedValues(m_rootItem);
- emitConflictsChanged();
-}
-
-void QPPDOptionsModel::revertToSavedValues(QOptionTreeItem *item)
-{
- if (item->type == QOptionTreeItem::Option) {
- QOptionTreeItemOption *itemOption = static_cast<QOptionTreeItemOption *>(item);
-
- const ppd_option_t *option = static_cast<const ppd_option_t*>(item->ptr);
- const char *choice = itemOption->originallySelected != -1 ? option->choices[itemOption->originallySelected].choice
- : option->defchoice;
- const auto values = QStringList{} << QString::fromLatin1(option->keyword) << QString::fromLatin1(choice);
- m_currentPrintDevice->setProperty(PDPK_PpdOption, values);
- itemOption->selected = itemOption->originallySelected;
- }
-
- for (QOptionTreeItem *child : qAsConst(item->childItems))
- revertToSavedValues(child);
-}
-
-void QPPDOptionsModel::updateSavedValues()
-{
- updateSavedValues(m_rootItem);
-}
-
-void QPPDOptionsModel::updateSavedValues(QOptionTreeItem *item)
-{
- if (item->type == QOptionTreeItem::Option) {
- QOptionTreeItemOption *itemOption = static_cast<QOptionTreeItemOption *>(item);
- itemOption->originallySelected = itemOption->selected;
- }
-
- for (QOptionTreeItem *child : qAsConst(item->childItems))
- updateSavedValues(child);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-/*
-
- QPPDOptionsEditor
-
- Edits the PPD Options for the printer.
-
-*/
-
-QWidget *QPPDOptionsEditor::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
-{
- Q_UNUSED(option)
-
- if (index.column() == 1 && static_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Option)
- return new QComboBox(parent);
-
- return nullptr;
-}
-
-void QPPDOptionsEditor::setEditorData(QWidget *editor, const QModelIndex &index) const
-{
- if (index.column() != 1)
- return;
-
- QComboBox *cb = static_cast<QComboBox*>(editor);
- QOptionTreeItemOption *itm = static_cast<QOptionTreeItemOption*>(index.internalPointer());
-
- if (itm->selected == -1)
- cb->addItem(QString());
-
- const QPPDOptionsModel *m = static_cast<const QPPDOptionsModel*>(index.model());
- for (auto *childItem : qAsConst(itm->childItems)) {
- const ppd_choice_t *choice = static_cast<const ppd_choice_t*>(childItem->ptr);
- cb->addItem(m->cupsCodec()->toUnicode(choice->text), childItem->index);
- if (childItem->index == itm->selected)
- cb->setCurrentIndex(cb->count() - 1);
- }
-}
-
-void QPPDOptionsEditor::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
-{
- QComboBox *cb = static_cast<QComboBox*>(editor);
- QOptionTreeItemOption *itm = static_cast<QOptionTreeItemOption*>(index.internalPointer());
-
- // We can't use cb->currentIndex() to know the index of the option in the choices[] array
- // because some of them may not be present in the list because they conflict with the
- // installable options so use the index passed on addItem
- const int selectedChoiceIndex = cb->currentData().toInt();
-
- if (itm->selected == selectedChoiceIndex || selectedChoiceIndex < 0)
- return;
-
- const ppd_option_t *opt = static_cast<const ppd_option_t*>(itm->ptr);
- QPPDOptionsModel *m = static_cast<QPPDOptionsModel*>(model);
-
- const auto values = QStringList{} << QString::fromLatin1(opt->keyword) << QString::fromLatin1(opt->choices[selectedChoiceIndex].choice);
- m->currentPrintDevice()->setProperty(PDPK_PpdOption, values);
- itm->selected = selectedChoiceIndex;
-
- m->emitConflictsChanged();
-}
-
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp
index a4f721fbc8..418bc47a59 100644
--- a/src/printsupport/dialogs/qprintpreviewdialog.cpp
+++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp
@@ -573,8 +573,11 @@ void QPrintPreviewDialogPrivate::_q_print()
if (printer->outputFormat() != QPrinter::NativeFormat) {
QString title = QCoreApplication::translate("QPrintPreviewDialog", "Export to PDF");
QString suffix = QLatin1String(".pdf");
- QString fileName = QFileDialog::getSaveFileName(q, title, printer->outputFileName(),
+ QString fileName;
+#if QT_CONFIG(filedialog)
+ fileName = QFileDialog::getSaveFileName(q, title, printer->outputFileName(),
QLatin1Char('*') + suffix);
+#endif
if (!fileName.isEmpty()) {
if (QFileInfo(fileName).suffix().isEmpty())
fileName.append(suffix);
diff --git a/src/printsupport/dialogs/qprintpropertieswidget.ui b/src/printsupport/dialogs/qprintpropertieswidget.ui
index d8e526139b..c2b4836d26 100644
--- a/src/printsupport/dialogs/qprintpropertieswidget.ui
+++ b/src/printsupport/dialogs/qprintpropertieswidget.ui
@@ -47,60 +47,74 @@
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QTreeView" name="treeView">
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="conflictsLabel">
- <property name="palette">
- <palette>
- <active>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </active>
- <inactive>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </inactive>
- <disabled>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>165</red>
- <green>167</green>
- <blue>169</blue>
- </color>
- </brush>
- </colorrole>
- </disabled>
- </palette>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
</property>
- <property name="text">
- <string>There are conflicts in some options. Please fix them.</string>
+ <property name="widgetResizable">
+ <bool>true</bool>
</property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>376</width>
+ <height>217</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout"/>
+ </widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
+ <item>
+ <widget class="QLabel" name="conflictsLabel">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>165</red>
+ <green>167</green>
+ <blue>169</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="text">
+ <string>There are conflicts in some options. Please fix them.</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<customwidgets>
diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp
index 7e8e1707b2..8505e8356c 100644
--- a/src/printsupport/kernel/qcups.cpp
+++ b/src/printsupport/kernel/qcups.cpp
@@ -39,6 +39,7 @@
#include "qcups_p.h"
+#include "qprintdevice_p.h"
#include "qprintengine.h"
QT_BEGIN_NAMESPACE
@@ -146,6 +147,25 @@ QCUPSSupport::JobHoldUntilWithTime QCUPSSupport::parseJobHoldUntil(const QString
return { QCUPSSupport::NoHold, QTime() };
}
+ppd_option_t *QCUPSSupport::findPpdOption(const char *optionName, QPrintDevice *printDevice)
+{
+ ppd_file_t *ppd = printDevice->property(PDPK_PpdFile).value<ppd_file_t*>();
+
+ if (ppd) {
+ for (int i = 0; i < ppd->num_groups; ++i) {
+ ppd_group_t *group = &ppd->groups[i];
+
+ for (int i = 0; i < group->num_options; ++i) {
+ ppd_option_t *option = &group->options[i];
+
+ if (qstrcmp(option->keyword, optionName) == 0)
+ return option;
+ }
+ }
+ }
+
+ return nullptr;
+}
void QCUPSSupport::setJobHold(QPrinter *printer, const JobHoldUntil jobHold, const QTime &holdUntilTime)
{
diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h
index 9a71483bb9..57ec281383 100644
--- a/src/printsupport/kernel/qcups_p.h
+++ b/src/printsupport/kernel/qcups_p.h
@@ -52,6 +52,7 @@
//
#include <QtPrintSupport/private/qtprintsupportglobal_p.h>
+#include <QtPrintSupport/private/qprint_p.h>
#include "QtCore/qstring.h"
#include "QtCore/qstringlist.h"
#include "QtPrintSupport/qprinter.h"
@@ -61,6 +62,8 @@ QT_REQUIRE_CONFIG(cups);
QT_BEGIN_NAMESPACE
+class QPrintDevice;
+
// HACK! Define these here temporarily so they can be used in the dialogs
// without a circular reference to QCupsPrintEngine in the plugin.
// Move back to qcupsprintengine_p.h in the plugin once all usage
@@ -163,6 +166,8 @@ public:
QTime time;
};
static JobHoldUntilWithTime parseJobHoldUntil(const QString &jobHoldUntil);
+
+ static ppd_option_t *findPpdOption(const char *optionName, QPrintDevice *printDevice);
};
Q_DECLARE_TYPEINFO(QCUPSSupport::JobHoldUntil, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QCUPSSupport::BannerPage, Q_PRIMITIVE_TYPE);
diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp
index 8dba402a6e..23a92fc2a1 100644
--- a/src/printsupport/kernel/qplatformprintdevice.cpp
+++ b/src/printsupport/kernel/qplatformprintdevice.cpp
@@ -50,23 +50,6 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_PRINTER
-QPlatformPrintDevice::QPlatformPrintDevice()
- : m_isRemote(false),
- m_supportsMultipleCopies(false),
- m_supportsCollateCopies(false),
- m_havePageSizes(false),
- m_supportsCustomPageSizes(false),
- m_haveResolutions(false),
- m_haveInputSlots(false),
- m_haveOutputBins(false),
- m_haveDuplexModes(false),
- m_haveColorModes(false)
-#ifndef QT_NO_MIMETYPE
- , m_haveMimeTypes(false)
-#endif
-{
-}
-
QPlatformPrintDevice::QPlatformPrintDevice(const QString &id)
: m_id(id),
m_isRemote(false),
@@ -247,6 +230,10 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QSizeF &size, QPageSize:
QPageSize QPlatformPrintDevice::supportedPageSizeMatch(const QPageSize &pageSize) const
{
+ // If it's a known page size, just return itself
+ if (m_pageSizes.contains(pageSize))
+ return pageSize;
+
// Try to find a supported page size based on point size
for (const QPageSize &ps : m_pageSizes) {
if (ps.sizePoints() == pageSize.sizePoints())
diff --git a/src/printsupport/kernel/qplatformprintdevice.h b/src/printsupport/kernel/qplatformprintdevice.h
index a988518547..d95a5add9b 100644
--- a/src/printsupport/kernel/qplatformprintdevice.h
+++ b/src/printsupport/kernel/qplatformprintdevice.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtPrintSupport module of the Qt Toolkit.
@@ -69,8 +70,7 @@ class Q_PRINTSUPPORT_EXPORT QPlatformPrintDevice
{
Q_DISABLE_COPY(QPlatformPrintDevice)
public:
- QPlatformPrintDevice();
- explicit QPlatformPrintDevice(const QString &id);
+ explicit QPlatformPrintDevice(const QString &id = QString());
virtual ~QPlatformPrintDevice();
virtual QString id() const;
@@ -152,16 +152,16 @@ protected:
bool m_isRemote;
- bool m_supportsMultipleCopies;
- bool m_supportsCollateCopies;
+ mutable bool m_supportsMultipleCopies;
+ mutable bool m_supportsCollateCopies;
mutable bool m_havePageSizes;
mutable QList<QPageSize> m_pageSizes;
- bool m_supportsCustomPageSizes;
+ mutable bool m_supportsCustomPageSizes;
- QSize m_minimumPhysicalPageSize;
- QSize m_maximumPhysicalPageSize;
+ mutable QSize m_minimumPhysicalPageSize;
+ mutable QSize m_maximumPhysicalPageSize;
mutable bool m_haveResolutions;
mutable QList<int> m_resolutions;
diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp
index 0230ebddc8..3c24e5ac69 100644
--- a/src/printsupport/kernel/qprintengine_pdf.cpp
+++ b/src/printsupport/kernel/qprintengine_pdf.cpp
@@ -132,6 +132,8 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
// The following keys are settings that are unsupported by the PDF PrintEngine
case PPK_CustomBase:
break;
+ case PPK_Duplex:
+ break;
// The following keys are properties and settings that are supported by the PDF PrintEngine
case PPK_CollateCopies:
@@ -203,9 +205,6 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
case PPK_FontEmbedding:
d->embedFonts = value.toBool();
break;
- case PPK_Duplex:
- d->duplex = static_cast<QPrint::DuplexMode>(value.toInt());
- break;
case PPK_CustomPaperSize:
d->m_pageLayout.setPageSize(QPageSize(value.toSizeF(), QPageSize::Point));
break;
@@ -249,6 +248,7 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
// The following keys are settings that are unsupported by the PDF PrintEngine
// Return sensible default values to ensure consistent behavior across platforms
case PPK_CustomBase:
+ case PPK_Duplex:
// Special case, leave null
break;
@@ -322,9 +322,6 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_FontEmbedding:
ret = d->embedFonts;
break;
- case PPK_Duplex:
- ret = d->duplex;
- break;
case PPK_CustomPaperSize:
ret = d->m_pageLayout.fullRectPoints().size();
break;
@@ -389,7 +386,6 @@ void QPdfPrintEnginePrivate::closePrintDevice()
QPdfPrintEnginePrivate::QPdfPrintEnginePrivate(QPrinter::PrinterMode m)
: QPdfEnginePrivate(),
- duplex(QPrint::DuplexNone),
collate(true),
copies(1),
pageOrder(QPrinter::FirstPageFirst),
diff --git a/src/printsupport/kernel/qprintengine_pdf_p.h b/src/printsupport/kernel/qprintengine_pdf_p.h
index bb01a2e9e1..e7ae21f260 100644
--- a/src/printsupport/kernel/qprintengine_pdf_p.h
+++ b/src/printsupport/kernel/qprintengine_pdf_p.h
@@ -130,7 +130,6 @@ private:
QString printProgram;
QString selectionOption;
- QPrint::DuplexMode duplex;
bool collate;
int copies;
QPrinter::PageOrder pageOrder;
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index 6f263e5ea8..e3a5c3d2e8 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/kernel/qprintengine_win.cpp
@@ -1556,14 +1556,15 @@ HGLOBAL *QWin32PrintEngine::createGlobalDevNames()
Q_D(QWin32PrintEngine);
int size = sizeof(DEVNAMES) + d->m_printDevice.id().length() * 2 + 2;
- HGLOBAL *hGlobal = (HGLOBAL *) GlobalAlloc(GMEM_MOVEABLE, size);
- DEVNAMES *dn = (DEVNAMES*) GlobalLock(hGlobal);
+ auto hGlobal = reinterpret_cast<HGLOBAL *>(GlobalAlloc(GMEM_MOVEABLE, size));
+ auto dn = reinterpret_cast<DEVNAMES*>(GlobalLock(hGlobal));
dn->wDriverOffset = 0;
dn->wDeviceOffset = sizeof(DEVNAMES) / sizeof(wchar_t);
dn->wOutputOffset = 0;
- memcpy((ushort*)dn + dn->wDeviceOffset, d->m_printDevice.id().utf16(), d->m_printDevice.id().length() * 2 + 2);
+ memcpy(reinterpret_cast<ushort*>(dn) + dn->wDeviceOffset,
+ d->m_printDevice.id().utf16(), d->m_printDevice.id().length() * 2 + 2);
dn->wDefault = 0;
GlobalUnlock(hGlobal);
@@ -1574,8 +1575,9 @@ void QWin32PrintEngine::setGlobalDevMode(HGLOBAL globalDevNames, HGLOBAL globalD
{
Q_D(QWin32PrintEngine);
if (globalDevNames) {
- DEVNAMES *dn = (DEVNAMES*) GlobalLock(globalDevNames);
- QString id = QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset);
+ auto dn = reinterpret_cast<DEVNAMES*>(GlobalLock(globalDevNames));
+ const QString id =
+ QString::fromWCharArray(reinterpret_cast<const wchar_t*>(dn) + dn->wDeviceOffset);
QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
if (ps)
d->m_printDevice = ps->createPrintDevice(id.isEmpty() ? ps->defaultPrintDeviceId() : id);
@@ -1583,7 +1585,7 @@ void QWin32PrintEngine::setGlobalDevMode(HGLOBAL globalDevNames, HGLOBAL globalD
}
if (globalDevMode) {
- DEVMODE *dm = (DEVMODE*) GlobalLock(globalDevMode);
+ auto dm = reinterpret_cast<DEVMODE*>(GlobalLock(globalDevMode));
d->release();
d->globalDevMode = globalDevMode;
if (d->ownsDevMode) {
@@ -1779,39 +1781,26 @@ static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC h
QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y());
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags,
_glyphs, positions);
- if (_glyphs.size() == 0) {
+ if (_glyphs.isEmpty()) {
SelectObject(hdc, old_font);
return;
}
- bool outputEntireItem = _glyphs.size() > 0;
-
- if (outputEntireItem) {
- options |= ETO_PDY;
- QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2);
- QVarLengthArray<wchar_t> g(_glyphs.size());
- for (int i=0; i<_glyphs.size() - 1; ++i) {
- glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x);
- glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y);
- g[i] = _glyphs[i];
- }
- glyphDistances[(_glyphs.size() - 1) * 2] = 0;
- glyphDistances[(_glyphs.size() - 1) * 2 + 1] = 0;
- g[_glyphs.size() - 1] = _glyphs[_glyphs.size() - 1];
- ExtTextOut(hdc, qRound(positions[0].x), qRound(positions[0].y), options, 0,
- g.constData(), _glyphs.size(),
- glyphDistances.data());
- } else {
- int i = 0;
- while(i < _glyphs.size()) {
- wchar_t g = _glyphs[i];
-
- ExtTextOut(hdc, qRound(positions[i].x),
- qRound(positions[i].y), options, 0,
- &g, 1, 0);
- ++i;
- }
+ options |= ETO_PDY;
+ QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2);
+ QVarLengthArray<wchar_t> g(_glyphs.size());
+ const int lastGlyph = _glyphs.size() - 1;
+ for (int i = 0; i < lastGlyph; ++i) {
+ glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x);
+ glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y);
+ g[i] = _glyphs[i];
}
+ glyphDistances[lastGlyph * 2] = 0;
+ glyphDistances[lastGlyph * 2 + 1] = 0;
+ g[lastGlyph] = _glyphs[lastGlyph];
+ ExtTextOut(hdc, qRound(positions[0].x), qRound(positions[0].y), options, nullptr,
+ g.constData(), _glyphs.size(),
+ glyphDistances.data());
}
win_xform.eM11 = win_xform.eM22 = 1.0;
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index 8a2cdcb34f..ed4292ff3d 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -224,8 +224,8 @@ void QPrinterPrivate::setProperty(QPrintEngine::PrintEnginePropertyKey key, cons
class QPrinterPagedPaintDevicePrivate : public QPagedPaintDevicePrivate
{
public:
- QPrinterPagedPaintDevicePrivate(QPrinterPrivate *d)
- : QPagedPaintDevicePrivate(), pd(d)
+ QPrinterPagedPaintDevicePrivate(QPrinter *p)
+ : QPagedPaintDevicePrivate(), m_printer(p)
{}
virtual ~QPrinterPagedPaintDevicePrivate()
@@ -233,6 +233,8 @@ public:
bool setPageLayout(const QPageLayout &newPageLayout) override
{
+ QPrinterPrivate *pd = QPrinterPrivate::get(m_printer);
+
if (pd->paintEngine->type() != QPaintEngine::Pdf
&& pd->printEngine->printerState() == QPrinter::Active) {
qWarning("QPrinter::setPageLayout: Cannot be changed while printer is active");
@@ -242,14 +244,13 @@ public:
// Try to set the print engine page layout
pd->setProperty(QPrintEngine::PPK_QPageLayout, QVariant::fromValue(newPageLayout));
- // Set QPagedPaintDevice layout to match the current print engine value
- m_pageLayout = pageLayout();
-
return pageLayout().isEquivalentTo(newPageLayout);
}
bool setPageSize(const QPageSize &pageSize) override
{
+ QPrinterPrivate *pd = QPrinterPrivate::get(m_printer);
+
if (pd->paintEngine->type() != QPaintEngine::Pdf
&& pd->printEngine->printerState() == QPrinter::Active) {
qWarning("QPrinter::setPageLayout: Cannot be changed while printer is active");
@@ -260,46 +261,38 @@ public:
// Try to set the print engine page size
pd->setProperty(QPrintEngine::PPK_QPageSize, QVariant::fromValue(pageSize));
- // Set QPagedPaintDevice layout to match the current print engine value
- m_pageLayout = pageLayout();
-
return pageLayout().pageSize().isEquivalentTo(pageSize);
}
bool setPageOrientation(QPageLayout::Orientation orientation) override
{
+ QPrinterPrivate *pd = QPrinterPrivate::get(m_printer);
+
// Set the print engine value
pd->setProperty(QPrintEngine::PPK_Orientation, orientation);
- // Set QPagedPaintDevice layout to match the current print engine value
- m_pageLayout = pageLayout();
-
return pageLayout().orientation() == orientation;
}
- bool setPageMargins(const QMarginsF &margins) override
- {
- return setPageMargins(margins, pageLayout().units());
- }
-
bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override
{
+ QPrinterPrivate *pd = QPrinterPrivate::get(m_printer);
+
// Try to set print engine margins
QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(margins, units);
pd->setProperty(QPrintEngine::PPK_QPageMargins, QVariant::fromValue(pair));
- // Set QPagedPaintDevice layout to match the current print engine value
- m_pageLayout = pageLayout();
-
return pageLayout().margins() == margins && pageLayout().units() == units;
}
QPageLayout pageLayout() const override
{
+ QPrinterPrivate *pd = QPrinterPrivate::get(m_printer);
+
return pd->printEngine->property(QPrintEngine::PPK_QPageLayout).value<QPageLayout>();
}
- QPrinterPrivate *pd;
+ QPrinter *m_printer;
};
@@ -554,11 +547,9 @@ public:
Creates a new printer object with the given \a mode.
*/
QPrinter::QPrinter(PrinterMode mode)
- : QPagedPaintDevice(),
+ : QPagedPaintDevice(new QPrinterPagedPaintDevicePrivate(this)),
d_ptr(new QPrinterPrivate(this))
{
- delete d;
- d = new QPrinterPagedPaintDevicePrivate(d_func());
d_ptr->init(QPrinterInfo(), mode);
}
@@ -568,11 +559,9 @@ QPrinter::QPrinter(PrinterMode mode)
Creates a new printer object with the given \a printer and \a mode.
*/
QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode)
- : QPagedPaintDevice(),
+ : QPagedPaintDevice(new QPrinterPagedPaintDevicePrivate(this)),
d_ptr(new QPrinterPrivate(this))
{
- delete d;
- d = new QPrinterPagedPaintDevicePrivate(d_func());
d_ptr->init(printer, mode);
}
@@ -1469,8 +1458,6 @@ void QPrinter::setFullPage(bool fp)
Q_D(QPrinter);
// Set the print engine
d->setProperty(QPrintEngine::PPK_FullPage, fp);
- // Set QPagedPaintDevice layout to match the current print engine value
- devicePageLayout() = pageLayout();
}
diff --git a/src/printsupport/kernel/qprinter_p.h b/src/printsupport/kernel/qprinter_p.h
index 6ced466236..37c9702c17 100644
--- a/src/printsupport/kernel/qprinter_p.h
+++ b/src/printsupport/kernel/qprinter_p.h
@@ -94,6 +94,10 @@ public:
}
+ static QPrinterPrivate *get(QPrinter *printer) {
+ return printer->d_ptr.get();
+ }
+
void init(const QPrinterInfo &printer, QPrinter::PrinterMode mode);
QPrinterInfo findValidPrinter(const QPrinterInfo &printer = QPrinterInfo());
diff --git a/src/sql/configure.json b/src/sql/configure.json
new file mode 100644
index 0000000000..8fdc27e3a2
--- /dev/null
+++ b/src/sql/configure.json
@@ -0,0 +1,22 @@
+{
+ "module": "sql",
+ "depends": [
+ "core"
+ ],
+
+ "features": {
+ "sqlmodel": {
+ "label": "SQL item models",
+ "purpose": "Provides item model classes backed by SQL databases.",
+ "condition": "features.itemmodel",
+ "output": [ "publicFeature" ]
+ }
+ },
+
+ "summary": [
+ {
+ "section": "Qt Sql",
+ "entries": [ "sqlmodel" ]
+ }
+ ]
+}
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index 628bfa1880..daadcb8a0e 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -942,10 +942,12 @@ void QSqlQuery::clear()
query. See the \l{QSqlQuery examples}{Detailed Description} for
examples.
- Portability note: Some databases choose to delay preparing a query
+ Portability notes: Some databases choose to delay preparing a query
until it is executed the first time. In this case, preparing a
syntactically wrong query succeeds, but every consecutive exec()
will fail.
+ When the database does not support named placeholders directly,
+ the placeholder can only contain characters in the range [a-zA-Z0-9_].
For SQLite, the query string can contain only one statement at a time.
If more than one statement is given, the function returns \c false.
diff --git a/src/sql/kernel/qtsqlglobal.h b/src/sql/kernel/qtsqlglobal.h
index d421adc84b..ec79e8da1e 100644
--- a/src/sql/kernel/qtsqlglobal.h
+++ b/src/sql/kernel/qtsqlglobal.h
@@ -41,6 +41,7 @@
#define QTSQLGLOBAL_H
#include <QtCore/qglobal.h>
+#include <QtSql/qtsql-config.h>
QT_BEGIN_NAMESPACE
diff --git a/src/sql/kernel/qtsqlglobal_p.h b/src/sql/kernel/qtsqlglobal_p.h
index ab45f6cd38..78a2461257 100644
--- a/src/sql/kernel/qtsqlglobal_p.h
+++ b/src/sql/kernel/qtsqlglobal_p.h
@@ -53,5 +53,6 @@
#include <QtSql/qtsqlglobal.h>
#include <QtCore/private/qglobal_p.h>
+#include <QtSql/private/qtsql-config_p.h>
#endif // QTSQLGLOBAL_P_H
diff --git a/src/sql/models/qsqlquerymodel.h b/src/sql/models/qsqlquerymodel.h
index 869a5f030c..427b369ae2 100644
--- a/src/sql/models/qsqlquerymodel.h
+++ b/src/sql/models/qsqlquerymodel.h
@@ -44,8 +44,9 @@
#include <QtCore/qabstractitemmodel.h>
#include <QtSql/qsqldatabase.h>
-QT_BEGIN_NAMESPACE
+QT_REQUIRE_CONFIG(sqlmodel);
+QT_BEGIN_NAMESPACE
class QSqlQueryModelPrivate;
class QSqlError;
diff --git a/src/sql/models/qsqlquerymodel_p.h b/src/sql/models/qsqlquerymodel_p.h
index ffc34b9f95..d5ca2f89cb 100644
--- a/src/sql/models/qsqlquerymodel_p.h
+++ b/src/sql/models/qsqlquerymodel_p.h
@@ -60,6 +60,8 @@
#include "QtCore/qvarlengtharray.h"
#include "QtCore/qvector.h"
+QT_REQUIRE_CONFIG(sqlmodel);
+
QT_BEGIN_NAMESPACE
class QSqlQueryModelPrivate: public QAbstractItemModelPrivate
@@ -73,7 +75,7 @@ public:
void initColOffsets(int size);
int columnInQuery(int modelColumn) const;
- mutable QSqlQuery query;
+ mutable QSqlQuery query = { QSqlQuery(0) };
mutable QSqlError error;
QModelIndex bottom;
QSqlRecord rec;
diff --git a/src/sql/models/qsqlrelationaldelegate.h b/src/sql/models/qsqlrelationaldelegate.h
index 53f43a4acb..e8ae5a229d 100644
--- a/src/sql/models/qsqlrelationaldelegate.h
+++ b/src/sql/models/qsqlrelationaldelegate.h
@@ -42,6 +42,8 @@
#include <QtSql/qtsqlglobal.h>
+QT_REQUIRE_CONFIG(sqlmodel);
+
#ifdef QT_WIDGETS_LIB
#include <QtWidgets/qitemdelegate.h>
@@ -53,7 +55,7 @@
#endif
#include <QtSql/qsqldriver.h>
#include <QtSql/qsqlrelationaltablemodel.h>
-
+#include <QtCore/qmetaobject.h>
QT_BEGIN_NAMESPACE
@@ -97,6 +99,27 @@ QWidget *createEditor(QWidget *aParent,
return combo;
}
+ void setEditorData(QWidget *editor, const QModelIndex &index) const override
+ {
+ if (!index.isValid())
+ return;
+
+ if (qobject_cast<QComboBox *>(editor)) {
+ // Taken from QItemDelegate::setEditorData() as we need
+ // to present the DisplayRole and not the EditRole which
+ // is the id reference to the related model
+ QVariant v = index.data(Qt::DisplayRole);
+ QByteArray n = editor->metaObject()->userProperty().name();
+ if (!n.isEmpty()) {
+ if (!v.isValid())
+ v = QVariant(editor->property(n).userType(), nullptr);
+ editor->setProperty(n, v);
+ return;
+ }
+ }
+ QItemDelegate::setEditorData(editor, index);
+ }
+
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
{
if (!index.isValid())
diff --git a/src/sql/models/qsqlrelationaltablemodel.h b/src/sql/models/qsqlrelationaltablemodel.h
index 90b7a6481f..555755009c 100644
--- a/src/sql/models/qsqlrelationaltablemodel.h
+++ b/src/sql/models/qsqlrelationaltablemodel.h
@@ -45,6 +45,8 @@
#include <QtCore/qtypeinfo.h>
+QT_REQUIRE_CONFIG(sqlmodel);
+
QT_BEGIN_NAMESPACE
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 865f76c73a..a33f76838f 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -565,6 +565,10 @@ bool QSqlTableModel::isDirty(const QModelIndex &index) const
Returns \c true if the value could be set or false on error, for
example if \a index is out of bounds.
+ Returns \c false if the role is not Qt::EditRole. To set data
+ for roles other than EditRole, either use a custom proxy model
+ or subclass QSqlTableModel.
+
\sa editStrategy(), data(), submit(), submitAll(), revertRow()
*/
bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
diff --git a/src/sql/models/qsqltablemodel.h b/src/sql/models/qsqltablemodel.h
index 77b0517c74..7acc7dc94d 100644
--- a/src/sql/models/qsqltablemodel.h
+++ b/src/sql/models/qsqltablemodel.h
@@ -44,6 +44,8 @@
#include <QtSql/qsqldatabase.h>
#include <QtSql/qsqlquerymodel.h>
+QT_REQUIRE_CONFIG(sqlmodel);
+
QT_BEGIN_NAMESPACE
diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h
index 490bb48a24..bb568ab444 100644
--- a/src/sql/models/qsqltablemodel_p.h
+++ b/src/sql/models/qsqltablemodel_p.h
@@ -56,6 +56,8 @@
#include "QtSql/qsqlindex.h"
#include "QtCore/qmap.h"
+QT_REQUIRE_CONFIG(sqlmodel);
+
QT_BEGIN_NAMESPACE
class Q_AUTOTEST_EXPORT QSqlTableModelPrivate: public QSqlQueryModelPrivate
@@ -91,7 +93,7 @@ public:
QSqlTableModel::EditStrategy strategy;
bool busyInsertingRows;
- QSqlQuery editQuery;
+ QSqlQuery editQuery = { QSqlQuery(0) };
QSqlIndex primaryIndex;
QString tableName;
QString filter;
diff --git a/src/sql/sql.pro b/src/sql/sql.pro
index 821ae1c9b9..1cd2a05250 100644
--- a/src/sql/sql.pro
+++ b/src/sql/sql.pro
@@ -11,7 +11,7 @@ PRECOMPILED_HEADER = ../corelib/global/qt_pch.h
SQL_P = sql
include(kernel/kernel.pri)
-include(models/models.pri)
+qtConfig(sqlmodel): include(models/models.pri)
MODULE_PLUGIN_TYPES = \
sqldrivers
diff --git a/src/testlib/doc/snippets/code/doc_src_qtestlib.cpp b/src/testlib/doc/snippets/code/doc_src_qtestlib.cpp
index 0dc45bef76..de301b8df9 100644
--- a/src/testlib/doc/snippets/code/doc_src_qtestlib.cpp
+++ b/src/testlib/doc/snippets/code/doc_src_qtestlib.cpp
@@ -48,19 +48,41 @@
**
****************************************************************************/
+#include <QtTest>
+
//! [0]
class MyFirstTest: public QObject
{
Q_OBJECT
+
+private:
+ bool myCondition()
+ {
+ return true;
+ }
+
private slots:
void initTestCase()
- { qDebug("called before everything else"); }
+ {
+ qDebug("Called before everything else.");
+ }
+
void myFirstTest()
- { QVERIFY(1 == 1); }
+ {
+ QVERIFY(true); // check that a condition is satisfied
+ QCOMPARE(1, 1); // compare two values
+ }
+
void mySecondTest()
- { QVERIFY(1 != 2); }
+ {
+ QVERIFY(myCondition());
+ QVERIFY(1 != 2);
+ }
+
void cleanupTestCase()
- { qDebug("called after myFirstTest and mySecondTest"); }
+ {
+ qDebug("Called after myFirstTest and mySecondTest.");
+ }
};
//! [0]
diff --git a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
index 990b7a38d7..202f87af52 100644
--- a/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
+++ b/src/testlib/doc/snippets/code/src_qtestlib_qtestcase.cpp
@@ -177,13 +177,6 @@ namespace MyNamespace {
}
//! [toString-overload]
-//! [17]
-int i = 0;
-while (myNetworkServerNotResponding() && i++ < 50)
- QTest::qWait(250);
-//! [17]
-
-
//! [18]
MyTestObject test1;
QTest::qExec(&test1);
@@ -245,11 +238,6 @@ void MyTestClass::cleanup()
QTest::qSleep(250);
//! [23]
-//! [24]
-QWidget widget;
-widget.show();
-QTest::qWaitForWindowShown(&widget);
-//! [24]
//! [25]
QTouchDevice *dev = QTest::createTouchDevice();
@@ -306,13 +294,5 @@ QTest::keyClick(myWindow, Qt::Key_Escape);
QTest::keyClick(myWindow, Qt::Key_Escape, Qt::ShiftModifier, 200);
//! [29]
-//! [30]
-MyObject obj;
-obj.startup();
-QTest::qWaitFor([&]() {
- return obj.isReady();
-}, 3000);
-//! [30]
-
}
diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc
index 363ec17c6c..71b4541313 100644
--- a/src/testlib/doc/src/qttestlib-manual.qdoc
+++ b/src/testlib/doc/src/qttestlib-manual.qdoc
@@ -69,8 +69,8 @@
\li Qt Test supports benchmarking and provides several measurement back-ends.
\row
\li \b {IDE friendly}
- \li Qt Test outputs messages that can be interpreted by Visual
- Studio and KDevelop.
+ \li Qt Test outputs messages that can be interpreted by Qt Creator, Visual
+ Studio, and KDevelop.
\row
\li \b Thread-safety
\li The error reporting is thread safe and atomic.
@@ -177,7 +177,7 @@
\list
\li \c -o \e{filename,format} \br
Writes output to the specified file, in the specified format (one of
- \c txt, \c xml, \c lightxml or \c xunitxml). The special filename \c -
+ \c txt, \c xml, \c lightxml, \c xunitxml or \c tap). The special filename \c -
may be used to log to standard output.
\li \c -o \e filename \br
Writes output to the specified file.
@@ -194,6 +194,8 @@
benchmarks, since it suppresses normal pass/fail messages.
\li \c -teamcity \br
Outputs results in TeamCity format.
+ \li \c -tap \br
+ Outputs results in Test Anything Protocol (TAP) format.
\endlist
The first version of the \c -o option may be repeated in order to log
@@ -201,8 +203,8 @@
option can log test results to standard output.
If the first version of the \c -o option is used, neither the second version
- of the \c -o option nor the \c -txt, \c -xml, \c -lightxml, \c -teamcity
- or \c -xunitxml options should be used.
+ of the \c -o option nor the \c -txt, \c -xml, \c -lightxml, \c -teamcity,
+ \c -xunitxml or \c -tap options should be used.
If neither version of the \c -o option is used, test results will be logged to
standard output. If no format option is used, test results will be logged in
diff --git a/src/testlib/qabstracttestlogger.cpp b/src/testlib/qabstracttestlogger.cpp
index 63c165b9dc..2b54cd410b 100644
--- a/src/testlib/qabstracttestlogger.cpp
+++ b/src/testlib/qabstracttestlogger.cpp
@@ -39,6 +39,7 @@
#include <QtTest/private/qabstracttestlogger_p.h>
#include <QtTest/qtestassert.h>
+#include <qtestresult_p.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qstring.h>
@@ -189,4 +190,26 @@ int qt_asprintf(QTestCharBuffer *str, const char *format, ...)
}
+namespace QTestPrivate
+{
+
+void generateTestIdentifier(QTestCharBuffer *identifier, int parts)
+{
+ const char *testObject = parts & TestObject ? QTestResult::currentTestObjectName() : "";
+ const char *testFunction = parts & TestFunction ? (QTestResult::currentTestFunction() ? QTestResult::currentTestFunction() : "UnknownTestFunc") : "";
+ const char *objectFunctionFiller = parts & TestObject && parts & (TestFunction | TestDataTag) ? "::" : "";
+ const char *testFuctionStart = parts & TestFunction ? "(" : "";
+ const char *testFuctionEnd = parts & TestFunction ? ")" : "";
+
+ const char *dataTag = (parts & TestDataTag) && QTestResult::currentDataTag() ? QTestResult::currentDataTag() : "";
+ const char *globalDataTag = (parts & TestDataTag) && QTestResult::currentGlobalDataTag() ? QTestResult::currentGlobalDataTag() : "";
+ const char *tagFiller = (dataTag[0] && globalDataTag[0]) ? ":" : "";
+
+ QTest::qt_asprintf(identifier, "%s%s%s%s%s%s%s%s",
+ testObject, objectFunctionFiller, testFunction, testFuctionStart,
+ globalDataTag, tagFiller, dataTag, testFuctionEnd);
+}
+
+}
+
QT_END_NAMESPACE
diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h
index c4083b43f4..018361b81e 100644
--- a/src/testlib/qabstracttestlogger_p.h
+++ b/src/testlib/qabstracttestlogger_p.h
@@ -58,6 +58,7 @@
QT_BEGIN_NAMESPACE
class QBenchmarkResult;
+class QTestData;
class QAbstractTestLogger
{
@@ -91,6 +92,8 @@ public:
virtual void enterTestFunction(const char *function) = 0;
virtual void leaveTestFunction() = 0;
+ virtual void enterTestData(QTestData *) {}
+
virtual void addIncident(IncidentTypes type, const char *description,
const char *file = 0, int line = 0) = 0;
virtual void addBenchmarkResult(const QBenchmarkResult &result) = 0;
@@ -175,6 +178,11 @@ namespace QTest
int qt_asprintf(QTestCharBuffer *buf, const char *format, ...);
}
+namespace QTestPrivate
+{
+ enum IdentifierPart { TestObject = 0x1, TestFunction = 0x2, TestDataTag = 0x4, AllParts = 0xFFFF };
+ void generateTestIdentifier(QTestCharBuffer *identifier, int parts = AllParts);
+}
QT_END_NAMESPACE
diff --git a/src/testlib/qappletestlogger.cpp b/src/testlib/qappletestlogger.cpp
new file mode 100644
index 0000000000..2c1005ad80
--- /dev/null
+++ b/src/testlib/qappletestlogger.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qappletestlogger_p.h"
+
+#include <QPair>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
+
+using namespace QTestPrivate;
+
+bool QAppleTestLogger::debugLoggingEnabled()
+{
+ // Debug-level messages are only captured in memory when debug logging is
+ // enabled through a configuration change, which can happen automatically
+ // when running inside Xcode, or with the Console application open.
+ return os_log_type_enabled(OS_LOG_DEFAULT, OS_LOG_TYPE_DEBUG);
+}
+
+QAppleTestLogger::QAppleTestLogger(QAbstractTestLogger *logger)
+ : QAbstractTestLogger(nullptr)
+ , m_logger(logger)
+{
+}
+
+static QAppleLogActivity testFunctionActivity;
+
+void QAppleTestLogger::enterTestFunction(const char *function)
+{
+ // Re-create activity each time
+ testFunctionActivity = QT_APPLE_LOG_ACTIVITY("Running test function").enter();
+
+ QTestCharBuffer testIdentifier;
+ QTestPrivate::generateTestIdentifier(&testIdentifier);
+ QString identifier = QString::fromLatin1(testIdentifier.data());
+ QMessageLogContext context(nullptr, 0, nullptr, "qt.test.enter");
+ QString message = identifier;
+ if (AppleUnifiedLogger::messageHandler(QtDebugMsg, context, message, identifier))
+ return; // AUL already printed to stderr
+
+ m_logger->enterTestFunction(function);
+}
+
+void QAppleTestLogger::leaveTestFunction()
+{
+ m_logger->leaveTestFunction();
+ testFunctionActivity.leave();
+}
+
+typedef QPair<QtMsgType, const char *> IncidentClassification;
+static IncidentClassification incidentTypeToClassification(QAbstractTestLogger::IncidentTypes type)
+{
+ switch (type) {
+ case QAbstractTestLogger::Pass:
+ return IncidentClassification(QtInfoMsg, "pass");
+ case QAbstractTestLogger::XFail:
+ return IncidentClassification(QtInfoMsg, "xfail");
+ case QAbstractTestLogger::Fail:
+ return IncidentClassification(QtCriticalMsg, "fail");
+ case QAbstractTestLogger::XPass:
+ return IncidentClassification(QtInfoMsg, "xpass");
+ case QAbstractTestLogger::BlacklistedPass:
+ return IncidentClassification(QtWarningMsg, "bpass");
+ case QAbstractTestLogger::BlacklistedFail:
+ return IncidentClassification(QtInfoMsg, "bfail");
+ }
+ return IncidentClassification(QtFatalMsg, nullptr);
+}
+
+void QAppleTestLogger::addIncident(IncidentTypes type, const char *description,
+ const char *file, int line)
+{
+
+ IncidentClassification incidentClassification = incidentTypeToClassification(type);
+
+ QTestCharBuffer category;
+ QTest::qt_asprintf(&category, "qt.test.%s", incidentClassification.second);
+ QMessageLogContext context(file, line, /* function = */ nullptr, category.data());
+
+ QTestCharBuffer subsystemBuffer;
+ // It would be nice to have the data tag as part of the subsystem too, but that
+ // will for some tests results in hundreds of thousands of log objects being
+ // created, so we limit the subsystem to test functions, which we can hope
+ // are reasonably limited.
+ generateTestIdentifier(&subsystemBuffer, TestObject | TestFunction);
+ QString subsystem = QString::fromLatin1(subsystemBuffer.data());
+
+ // We still want the full identifier as part of the message though
+ QTestCharBuffer testIdentifier;
+ generateTestIdentifier(&testIdentifier);
+ QString message = QString::fromLatin1(testIdentifier.data());
+ if (qstrlen(description))
+ message += QLatin1Char('\n') % QString::fromLatin1(description);
+
+ if (AppleUnifiedLogger::messageHandler(incidentClassification.first, context, message, subsystem))
+ return; // AUL already printed to stderr
+
+ m_logger->addIncident(type, description, file, line);
+}
+
+void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message)
+{
+ if (AppleUnifiedLogger::messageHandler(type, context, message))
+ return; // AUL already printed to stderr
+
+ m_logger->addMessage(type, context, message);
+}
+
+#endif // QT_USE_APPLE_UNIFIED_LOGGING
+
+QT_END_NAMESPACE
diff --git a/src/testlib/qappletestlogger_p.h b/src/testlib/qappletestlogger_p.h
new file mode 100644
index 0000000000..5a45fad7a0
--- /dev/null
+++ b/src/testlib/qappletestlogger_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QAPPLETESTLOGGER_P_H
+#define QAPPLETESTLOGGER_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 <QtTest/private/qabstracttestlogger_p.h>
+
+#include <QtCore/private/qcore_mac_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
+class QAppleTestLogger : public QAbstractTestLogger
+{
+public:
+ static bool debugLoggingEnabled();
+
+ QAppleTestLogger(QAbstractTestLogger *logger);
+
+ void startLogging() override
+ { m_logger->startLogging(); }
+ void stopLogging() override
+ { m_logger->stopLogging(); }
+
+ void enterTestFunction(const char *function) override;
+ void leaveTestFunction() override;
+
+ void addIncident(IncidentTypes type, const char *description,
+ const char *file = 0, int line = 0) override;
+ void addMessage(QtMsgType, const QMessageLogContext &,
+ const QString &) override;
+
+ void addBenchmarkResult(const QBenchmarkResult &result) override
+ { m_logger->addBenchmarkResult(result); }
+
+ void addMessage(MessageTypes type, const QString &message,
+ const char *file = 0, int line = 0) override
+ { m_logger->addMessage(type, message, file, line); }
+
+private:
+ QScopedPointer<QAbstractTestLogger> m_logger;
+};
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QAPPLETESTLOGGER_P_H
diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp
index e5226b7820..853515f2d9 100644
--- a/src/testlib/qplaintestlogger.cpp
+++ b/src/testlib/qplaintestlogger.cpp
@@ -221,18 +221,6 @@ void QPlainTestLogger::outputMessage(const char *str)
outputString(str);
}
-static void testIdentifier(QTestCharBuffer *identifier)
-{
- const char *testObject = QTestResult::currentTestObjectName();
- const char *testFunction = QTestResult::currentTestFunction() ? QTestResult::currentTestFunction() : "UnknownTestFunc";
-
- const char *dataTag = QTestResult::currentDataTag() ? QTestResult::currentDataTag() : "";
- const char *globalDataTag = QTestResult::currentGlobalDataTag() ? QTestResult::currentGlobalDataTag() : "";
- const char *tagFiller = (dataTag[0] && globalDataTag[0]) ? ":" : "";
-
- QTest::qt_asprintf(identifier, "%s::%s(%s%s%s)", testObject, testFunction, globalDataTag, tagFiller, dataTag);
-}
-
void QPlainTestLogger::printMessage(const char *type, const char *msg, const char *file, int line)
{
QTEST_ASSERT(type);
@@ -251,10 +239,10 @@ void QPlainTestLogger::printMessage(const char *type, const char *msg, const cha
}
const char *msgFiller = msg[0] ? " " : "";
- QTestCharBuffer testIdent;
- testIdentifier(&testIdent);
+ QTestCharBuffer testIdentifier;
+ QTestPrivate::generateTestIdentifier(&testIdentifier);
QTest::qt_asprintf(&messagePrefix, "%s: %s%s%s%s\n",
- type, testIdent.data(), msgFiller, msg, failureLocation.data());
+ type, testIdentifier.data(), msgFiller, msg, failureLocation.data());
// In colored mode, printf above stripped our nonprintable control characters.
// Put them back.
diff --git a/src/testlib/qsignalspy.h b/src/testlib/qsignalspy.h
index 824dc6aaed..218a26ec5c 100644
--- a/src/testlib/qsignalspy.h
+++ b/src/testlib/qsignalspy.h
@@ -59,11 +59,7 @@ public:
explicit QSignalSpy(const QObject *obj, const char *aSignal)
: m_waiting(false)
{
-#ifdef Q_CC_BOR
- const int memberOffset = QObject::staticMetaObject.methodCount();
-#else
static const int memberOffset = QObject::staticMetaObject.methodCount();
-#endif
if (!obj) {
qWarning("QSignalSpy: Cannot spy on a null object");
return;
@@ -104,11 +100,7 @@ public:
QSignalSpy(const typename QtPrivate::FunctionPointer<Func>::Object *obj, Func signal0)
: m_waiting(false)
{
-#ifdef Q_CC_BOR
- const int memberOffset = QObject::staticMetaObject.methodCount();
-#else
static const int memberOffset = QObject::staticMetaObject.methodCount();
-#endif
if (!obj) {
qWarning("QSignalSpy: Cannot spy on a null object");
return;
diff --git a/src/testlib/qtaptestlogger.cpp b/src/testlib/qtaptestlogger.cpp
new file mode 100644
index 0000000000..37ab89ac91
--- /dev/null
+++ b/src/testlib/qtaptestlogger.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtaptestlogger_p.h"
+
+#include "qtestlog_p.h"
+#include "qtestresult_p.h"
+#include "qtestassert.h"
+
+#include <QtCore/qregularexpression.h>
+
+QT_BEGIN_NAMESPACE
+
+QTapTestLogger::QTapTestLogger(const char *filename)
+ : QAbstractTestLogger(filename)
+ , m_wasExpectedFail(false)
+{
+}
+
+QTapTestLogger::~QTapTestLogger()
+{
+}
+
+void QTapTestLogger::startLogging()
+{
+ QAbstractTestLogger::startLogging();
+
+ QTestCharBuffer preamble;
+ QTest::qt_asprintf(&preamble, "TAP version 13\n"
+ // By convention, test suite names are output as diagnostics lines
+ // This is a pretty poor convention, as consumers will then treat
+ // actual diagnostics, e.g. qDebug, as test suite names o_O
+ "# %s\n", QTestResult::currentTestObjectName());
+ outputString(preamble.data());
+}
+
+void QTapTestLogger::stopLogging()
+{
+ const int total = QTestLog::totalCount();
+
+ QTestCharBuffer testPlanAndStats;
+ QTest::qt_asprintf(&testPlanAndStats,
+ "1..%d\n"
+ "# tests %d\n"
+ "# pass %d\n"
+ "# fail %d\n",
+ total, total, QTestLog::passCount(), QTestLog::failCount());
+ outputString(testPlanAndStats.data());
+
+ QAbstractTestLogger::stopLogging();
+}
+
+void QTapTestLogger::enterTestFunction(const char *function)
+{
+ Q_UNUSED(function);
+ m_wasExpectedFail = false;
+}
+
+void QTapTestLogger::enterTestData(QTestData *data)
+{
+ Q_UNUSED(data);
+ m_wasExpectedFail = false;
+}
+
+using namespace QTestPrivate;
+
+void QTapTestLogger::outputTestLine(bool ok, int testNumber, QTestCharBuffer &directive)
+{
+ QTestCharBuffer testIdentifier;
+ QTestPrivate::generateTestIdentifier(&testIdentifier, TestFunction | TestDataTag);
+
+ QTestCharBuffer testLine;
+ QTest::qt_asprintf(&testLine, "%s %d - %s%s\n",
+ ok ? "ok" : "not ok", testNumber, testIdentifier.data(), directive.data());
+
+ outputString(testLine.data());
+}
+
+void QTapTestLogger::addIncident(IncidentTypes type, const char *description,
+ const char *file, int line)
+{
+ if (m_wasExpectedFail && type == Pass) {
+ // XFail comes with a corresponding Pass incident, but we only want
+ // to emit a single test point for it, so skip the this pass.
+ return;
+ }
+
+ bool ok = type == Pass || type == XPass || type == BlacklistedPass;
+
+ QTestCharBuffer directive;
+ if (type == XFail || type == XPass || type == BlacklistedFail || type == BlacklistedPass)
+ // We treat expected or blacklisted failures/passes as TODO-failures/passes,
+ // which should be treated as soft issues by consumers. Not all do though :/
+ QTest::qt_asprintf(&directive, " # TODO %s", description);
+
+ int testNumber = QTestLog::totalCount();
+ if (type == XFail) {
+ // The global test counter hasn't been updated yet for XFail
+ testNumber += 1;
+ }
+
+ outputTestLine(ok, testNumber, directive);
+
+ if (!ok) {
+ // All failures need a diagnostics sections to not confuse consumers
+
+ // The indent needs to be two spaces for maximum compatibility
+ #define YAML_INDENT " "
+
+ outputString(YAML_INDENT "---\n");
+
+ if (type != XFail) {
+ // This is fragile, but unfortunately testlib doesn't plumb
+ // the expected and actual values to the loggers (yet).
+ static QRegularExpression verifyRegex(
+ QLatin1Literal("^'(?<actualexpression>.*)' returned (?<actual>\\w+).+\\((?<message>.*)\\)$"));
+
+ static QRegularExpression comparRegex(
+ QLatin1Literal("^(?<message>.*)\n"
+ "\\s*Actual\\s+\\((?<actualexpression>.*)\\)\\s*: (?<actual>.*)\n"
+ "\\s*Expected\\s+\\((?<expectedexpresssion>.*)\\)\\s*: (?<expected>.*)$"));
+
+ QString descriptionString = QString::fromUtf8(description);
+ QRegularExpressionMatch match = verifyRegex.match(descriptionString);
+ if (!match.hasMatch())
+ match = comparRegex.match(descriptionString);
+
+ if (match.hasMatch()) {
+ bool isVerify = match.regularExpression() == verifyRegex;
+ QString message = match.captured(QLatin1Literal("message"));
+ QString expected;
+ QString actual;
+
+ if (isVerify) {
+ QString expression = QLatin1Literal(" (")
+ % match.captured(QLatin1Literal("actualexpression")) % QLatin1Char(')') ;
+ actual = match.captured(QLatin1Literal("actual")).toLower() % expression;
+ expected = (actual.startsWith(QLatin1Literal("true")) ? QLatin1Literal("false") : QLatin1Literal("true")) % expression;
+ if (message.isEmpty())
+ message = QLatin1Literal("Verification failed");
+ } else {
+ expected = match.captured(QLatin1Literal("expected"))
+ % QLatin1Literal(" (") % match.captured(QLatin1Literal("expectedexpresssion")) % QLatin1Char(')');
+ actual = match.captured(QLatin1Literal("actual"))
+ % QLatin1Literal(" (") % match.captured(QLatin1Literal("actualexpression")) % QLatin1Char(')');
+ }
+
+ QTestCharBuffer diagnosticsYamlish;
+ QTest::qt_asprintf(&diagnosticsYamlish,
+ YAML_INDENT "type: %s\n"
+ YAML_INDENT "message: %s\n"
+
+ // Some consumers understand 'wanted/found', while others need
+ // 'expected/actual', so we do both for maximum compatibility.
+ YAML_INDENT "wanted: %s\n"
+ YAML_INDENT "found: %s\n"
+ YAML_INDENT "expected: %s\n"
+ YAML_INDENT "actual: %s\n",
+
+ isVerify ? "QVERIFY" : "QCOMPARE",
+ qPrintable(message),
+ qPrintable(expected), qPrintable(actual),
+ qPrintable(expected), qPrintable(actual)
+ );
+
+ outputString(diagnosticsYamlish.data());
+ } else {
+ QTestCharBuffer unparsableDescription;
+ QTest::qt_asprintf(&unparsableDescription,
+ YAML_INDENT "# %s\n", description);
+ outputString(unparsableDescription.data());
+ }
+ }
+
+ if (file) {
+ QTestCharBuffer location;
+ QTest::qt_asprintf(&location,
+ // The generic 'at' key is understood by most consumers.
+ YAML_INDENT "at: %s::%s() (%s:%d)\n"
+
+ // The file and line keys are for consumers that are able
+ // to read more granular location info.
+ YAML_INDENT "file: %s\n"
+ YAML_INDENT "line: %d\n",
+
+ QTestResult::currentTestObjectName(),
+ QTestResult::currentTestFunction(),
+ file, line, file, line
+ );
+ outputString(location.data());
+ }
+
+ outputString(YAML_INDENT "...\n");
+ }
+
+ m_wasExpectedFail = type == XFail;
+}
+
+void QTapTestLogger::addMessage(MessageTypes type, const QString &message,
+ const char *file, int line)
+{
+ Q_UNUSED(file);
+ Q_UNUSED(line);
+
+ if (type == Skip) {
+ QTestCharBuffer directive;
+ QTest::qt_asprintf(&directive, " # SKIP %s", message.toUtf8().constData());
+ outputTestLine(/* ok = */ true, QTestLog::totalCount(), directive);
+ return;
+ }
+
+ QTestCharBuffer diagnostics;
+ QTest::qt_asprintf(&diagnostics, "# %s\n", qPrintable(message));
+ outputString(diagnostics.data());
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/testlib/qtaptestlogger_p.h b/src/testlib/qtaptestlogger_p.h
new file mode 100644
index 0000000000..b51343e4fe
--- /dev/null
+++ b/src/testlib/qtaptestlogger_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTAPTESTLOGGER_P_H
+#define QTAPTESTLOGGER_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 <QtTest/private/qabstracttestlogger_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTapTestLogger : public QAbstractTestLogger
+{
+public:
+ QTapTestLogger(const char *filename);
+ ~QTapTestLogger();
+
+ void startLogging() override;
+ void stopLogging() override;
+
+ void enterTestFunction(const char *) override;
+ void leaveTestFunction() override {}
+
+ void enterTestData(QTestData *data) override;
+
+ void addIncident(IncidentTypes type, const char *description,
+ const char *file = 0, int line = 0) override;
+ void addMessage(MessageTypes type, const QString &message,
+ const char *file = 0, int line = 0) override;
+
+ void addBenchmarkResult(const QBenchmarkResult &) override {};
+private:
+ void outputTestLine(bool ok, int testNumber, QTestCharBuffer &directive);
+ bool m_wasExpectedFail;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTAPTESTLOGGER_P_H
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index 5517b8fd73..2578037946 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -59,6 +59,8 @@
#include <QtCore/qsize.h>
#include <QtCore/qrect.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
@@ -215,6 +217,25 @@ inline char *toString(const std::pair<T1, T2> &pair)
return toString(QString::asprintf("std::pair(%s,%s)", first.data(), second.data()));
}
+template <typename Tuple, int... I>
+inline char *toString(const Tuple & tuple, QtPrivate::IndexesList<I...>) {
+ using UP = std::unique_ptr<char[]>;
+ // Generate a table of N + 1 elements where N is the number of
+ // elements in the tuple.
+ // The last element is needed to support the empty tuple use case.
+ const UP data[] = {
+ UP(toString(std::get<I>(tuple)))..., UP{}
+ };
+ return formatString("std::tuple(", ")", sizeof...(I), data[I].get()...);
+}
+
+template <class... Types>
+inline char *toString(const std::tuple<Types...> &tuple)
+{
+ static const std::size_t params_count = sizeof...(Types);
+ return toString(tuple, typename QtPrivate::Indexes<params_count>::Value());
+}
+
inline char *toString(std::nullptr_t)
{
return toString(QLatin1String("nullptr"));
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index f5668c274e..32facaf12b 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -60,6 +60,8 @@
#include <QtCore/qwaitcondition.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qtestsupport_core.h>
+
#include <QtTest/private/qtestlog_p.h>
#include <QtTest/private/qtesttable_p.h>
#include <QtTest/qtestdata.h>
@@ -85,7 +87,6 @@
#if defined(Q_OS_LINUX)
#include <sys/types.h>
-#include <unistd.h>
#include <fcntl.h>
#endif
@@ -99,6 +100,7 @@
#include <errno.h>
#include <signal.h>
#include <time.h>
+#include <unistd.h>
# if !defined(Q_OS_INTEGRITY)
# include <sys/resource.h>
# endif
@@ -344,7 +346,9 @@ namespace QTest
static int keyDelay = -1;
static int mouseDelay = -1;
static int eventDelay = -1;
+#if QT_CONFIG(thread)
static int timeout = -1;
+#endif
static bool noCrashHandler = false;
/*! \internal
@@ -395,7 +399,7 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
}
return keyDelay;
}
-
+#if QT_CONFIG(thread)
static int defaultTimeout()
{
if (timeout == -1) {
@@ -407,6 +411,7 @@ static int defaultTimeout()
}
return timeout;
}
+#endif
Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
Q_TESTLIB_EXPORT QStringList testFunctions;
@@ -526,6 +531,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
" xml : XML document\n"
" lightxml : A stream of XML tags\n"
" teamcity : TeamCity format\n"
+ " tap : Test Anything Protocol\n"
"\n"
" *** Multiple loggers can be specified, but at most one can log to stdout.\n"
"\n"
@@ -537,6 +543,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
" -xml : Output results as XML document\n"
" -lightxml : Output results as stream of XML tags\n"
" -teamcity : Output results in TeamCity format\n"
+ " -tap : Output results in Test Anything Protocol format\n"
"\n"
" *** If no output file is specified, stdout is assumed.\n"
" *** If no output format is specified, -txt is assumed.\n"
@@ -624,6 +631,8 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
logFormat = QTestLog::LightXML;
} else if (strcmp(argv[i], "-teamcity") == 0) {
logFormat = QTestLog::TeamCity;
+ } else if (strcmp(argv[i], "-tap") == 0) {
+ logFormat = QTestLog::TAP;
} else if (strcmp(argv[i], "-silent") == 0) {
QTestLog::setVerboseLevel(-1);
} else if (strcmp(argv[i], "-v1") == 0) {
@@ -658,8 +667,10 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
logFormat = QTestLog::XunitXML;
else if (strcmp(format, "teamcity") == 0)
logFormat = QTestLog::TeamCity;
+ else if (strcmp(format, "tap") == 0)
+ logFormat = QTestLog::TAP;
else {
- fprintf(stderr, "output format must be one of txt, csv, lightxml, xml, teamcity or xunitxml\n");
+ fprintf(stderr, "output format must be one of txt, csv, lightxml, xml, tap, teamcity or xunitxml\n");
exit(1);
}
if (strcmp(filename, "-") == 0 && QTestLog::loggerUsingStdout()) {
@@ -967,6 +978,8 @@ void TestMethods::invokeTestOnData(int index) const
}
}
+#if QT_CONFIG(thread)
+
class WatchDog : public QThread
{
public:
@@ -1018,6 +1031,17 @@ private:
QWaitCondition waitCondition;
};
+#else // !QT_CONFIG(thread)
+
+class WatchDog : public QObject
+{
+public:
+ void beginTest() {};
+ void testFinished() {};
+};
+
+#endif
+
/*!
\internal
@@ -1141,6 +1165,31 @@ void *fetchData(QTestData *data, const char *tagName, int typeId)
}
/*!
+ * \internal
+ */
+char *formatString(const char *prefix, const char *suffix, size_t numArguments, ...)
+{
+ va_list ap;
+ va_start(ap, numArguments);
+
+ QByteArray arguments;
+ arguments += prefix;
+
+ if (numArguments > 0) {
+ arguments += va_arg(ap, const char *);
+
+ for (size_t i = 1; i < numArguments; ++i) {
+ arguments += ", ";
+ arguments += va_arg(ap, const char *);
+ }
+ }
+
+ va_end(ap);
+ arguments += suffix;
+ return qstrdup(arguments.constData());
+}
+
+/*!
\fn char* QTest::toHexRepresentation(const char *ba, int length)
Returns a pointer to a string that is the string \a ba represented
@@ -1439,8 +1488,13 @@ void FatalSignalHandler::signal(int signum)
{
const int msecsFunctionTime = qRound(QTestLog::msecsFunctionTime());
const int msecsTotalTime = qRound(QTestLog::msecsTotalTime());
- if (signum != SIGINT)
+ if (signum != SIGINT) {
stackTrace();
+ if (qEnvironmentVariableIsSet("QTEST_PAUSE_ON_CRASH")) {
+ fprintf(stderr, "Pausing process %d for debugging\n", getpid());
+ raise(SIGSTOP);
+ }
+ }
qFatal("Received signal %d\n"
" Function time: %dms Total time: %dms",
signum, msecsFunctionTime, msecsTotalTime);
@@ -2380,16 +2434,9 @@ bool QTest::currentTestFailed()
*/
void QTest::qSleep(int ms)
{
+ // ### Qt 6, move to QtCore or remove altogether
QTEST_ASSERT(ms > 0);
-
-#if defined(Q_OS_WINRT)
- WaitForSingleObjectEx(GetCurrentThread(), ms, true);
-#elif defined(Q_OS_WIN)
- Sleep(uint(ms));
-#else
- struct timespec ts = { time_t(ms / 1000), (ms % 1000) * 1000 * 1000 };
- nanosleep(&ts, NULL);
-#endif
+ QTestPrivate::qSleep(ms);
}
/*! \internal
diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h
index 54669c11de..f6891dc941 100644
--- a/src/testlib/qtestcase.h
+++ b/src/testlib/qtestcase.h
@@ -253,6 +253,22 @@ namespace QTest
return nullptr;
}
+ template<typename F> // Output QFlags of registered enumerations
+ inline typename std::enable_if<QtPrivate::IsQEnumHelper<F>::Value, char*>::type toString(QFlags<F> f)
+ {
+ const QMetaEnum me = QMetaEnum::fromType<F>();
+ return qstrdup(me.valueToKeys(int(f)).constData());
+ }
+
+ template <typename F> // Fallback: Output hex value
+ inline typename std::enable_if<!QtPrivate::IsQEnumHelper<F>::Value, char*>::type toString(QFlags<F> f)
+ {
+ const size_t space = 3 + 2 * sizeof(unsigned); // 2 for 0x, two hex digits per byte, 1 for '\0'
+ char *msg = new char[space];
+ qsnprintf(msg, space, "0x%x", unsigned(f));
+ return msg;
+ }
+
} // namespace Internal
template<typename T>
@@ -267,6 +283,9 @@ namespace QTest
template <typename T1, typename T2>
inline char *toString(const std::pair<T1, T2> &pair);
+ template <class... Types>
+ inline char *toString(const std::tuple<Types...> &tuple);
+
Q_TESTLIB_EXPORT char *toHexRepresentation(const char *ba, int length);
Q_TESTLIB_EXPORT char *toPrettyCString(const char *unicode, int length);
Q_TESTLIB_EXPORT char *toPrettyUnicode(QStringView string);
@@ -372,6 +391,8 @@ namespace QTest
Q_TESTLIB_EXPORT bool compare_string_helper(const char *t1, const char *t2, const char *actual,
const char *expected, const char *file, int line);
+ Q_TESTLIB_EXPORT char *formatString(const char *prefix, const char *suffix, size_t numArguments, ...);
+
#ifndef Q_QDOC
QTEST_COMPARE_DECL(short)
QTEST_COMPARE_DECL(ushort)
diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc
index 9a3c770e31..ad9776f7ec 100644
--- a/src/testlib/qtestcase.qdoc
+++ b/src/testlib/qtestcase.qdoc
@@ -1112,105 +1112,6 @@
Returns a textual representation of size policy \a sp.
*/
-/*! \fn void QTest::qWait(int ms)
-
- Waits for \a ms milliseconds. While waiting, events will be processed and
- your test will stay responsive to user interface events or network communication.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 17
-
- The code above will wait until the network server is responding for a
- maximum of about 12.5 seconds.
-
- \sa QTest::qSleep(), QSignalSpy::wait()
-*/
-
-/*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, int timeout)
-
- Waits for \a timeout milliseconds or until the \a predicate returns true.
-
- Returns \c true if the \a predicate returned true at any point, otherwise returns \c false.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 30
-
- The code above will wait for the object to become ready, for a
- maximum of three seconds.
-
- \since 5.10
-*/
-
-/*! \fn bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
- \since 5.0
-
- Waits for \a timeout milliseconds or until the \a window is exposed.
- Returns \c true if \c window is exposed within \a timeout milliseconds, otherwise returns \c false.
-
- This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
- time after being asked to show itself on the screen.
-
- Note that a window that is mapped to screen may still not be considered exposed if the window client
- area is completely covered by other windows, or if the window is otherwise not visible. This function
- will then time out when waiting for such a window.
-
- \sa QTest::qWaitForWindowActive(), QWindow::isExposed()
-*/
-
-/*! \fn bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
- \since 5.0
-
- Waits for \a timeout milliseconds or until the \a window is active.
-
- Returns \c true if \c window is active within \a timeout milliseconds, otherwise returns \c false.
-
- \sa QTest::qWaitForWindowExposed(), QWindow::isActive()
-*/
-
-/*! \fn bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
- \since 5.0
-
- Waits for \a timeout milliseconds or until the \a widget's window is exposed.
- Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
-
- This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
- time after being asked to show itself on the screen.
-
- Note that a window that is mapped to screen may still not be considered exposed if the window client
- area is completely covered by other windows, or if the window is otherwise not visible. This function
- will then time out when waiting for such a window.
-
- A specific configuration where this happens is when using QGLWidget as a viewport widget on macOS:
- The viewport widget gets the expose event, not the parent widget.
-
- \sa QTest::qWaitForWindowActive()
-*/
-
-/*! \fn bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
- \since 5.0
-
- Waits for \a timeout milliseconds or until the \a widget's window is active.
-
- Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false.
-
- \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow()
-*/
-
-/*! \fn bool QTest::qWaitForWindowShown(QWidget *widget, int timeout)
- \since 5.0
- \deprecated
-
- Waits for \a timeout milliseconds or until the \a widget's window is exposed.
- Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
-
- This function does the same as qWaitForWindowExposed().
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 24
-
- \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed()
-*/
-
/*!
\fn QTouchDevice *QTest::createTouchDevice(QTouchDevice::DeviceType devType = QTouchDevice::TouchScreen)
\since 5.8
diff --git a/src/testlib/qtesteventloop.h b/src/testlib/qtesteventloop.h
index 19ad22565e..a77b47cd7f 100644
--- a/src/testlib/qtesteventloop.h
+++ b/src/testlib/qtesteventloop.h
@@ -83,7 +83,7 @@ protected:
inline void timerEvent(QTimerEvent *e) override;
private:
- bool inLoop;
+ Q_DECL_UNUSED_MEMBER bool inLoop; // ### Qt 6: remove
bool _timeout;
int timerId;
@@ -96,7 +96,6 @@ inline void QTestEventLoop::enterLoopMSecs(int ms)
QEventLoop l;
- inLoop = true;
_timeout = false;
timerId = startTimer(ms);
@@ -120,8 +119,6 @@ inline void QTestEventLoop::exitLoop()
if (loop)
loop->exit();
-
- inLoop = false;
}
inline void QTestEventLoop::timerEvent(QTimerEvent *e)
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 6260b9e3fd..1268730cc6 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -47,10 +47,15 @@
#include <QtTest/private/qxunittestlogger_p.h>
#include <QtTest/private/qxmltestlogger_p.h>
#include <QtTest/private/qteamcitylogger_p.h>
+#include <QtTest/private/qtaptestlogger_p.h>
#if defined(HAVE_XCTEST)
#include <QtTest/private/qxctestlogger_p.h>
#endif
+#if defined(Q_OS_DARWIN)
+#include <QtTest/private/qappletestlogger_p.h>
+#endif
+
#include <QtCore/qatomic.h>
#include <QtCore/qbytearray.h>
#include <QtCore/QElapsedTimer>
@@ -211,6 +216,11 @@ namespace QTest {
FOREACH_LOGGER(logger->leaveTestFunction());
}
+ static void enterTestData(QTestData *data)
+ {
+ FOREACH_LOGGER(logger->enterTestData(data));
+ }
+
static void addIncident(QAbstractTestLogger::IncidentTypes type, const char *description,
const char *file = 0, int line = 0)
{
@@ -339,6 +349,12 @@ void QTestLog::enterTestFunction(const char* function)
QTest::TestLoggers::enterTestFunction(function);
}
+void QTestLog::enterTestData(QTestData *data)
+{
+ QTEST_ASSERT(data);
+ QTest::TestLoggers::enterTestData(data);
+}
+
int QTestLog::unhandledIgnoreMessages()
{
int i = 0;
@@ -498,12 +514,24 @@ void QTestLog::addLogger(LogMode mode, const char *filename)
case QTestLog::TeamCity:
logger = new QTeamCityLogger(filename);
break;
+ case QTestLog::TAP:
+ logger = new QTapTestLogger(filename);
+ break;
#if defined(HAVE_XCTEST)
case QTestLog::XCTest:
logger = new QXcodeTestLogger;
break;
#endif
}
+
+#if defined(QT_USE_APPLE_UNIFIED_LOGGING)
+ // Logger that also feeds messages to AUL. It needs to wrap the existing
+ // logger, as it needs to be able to short circuit the existing logger
+ // in case AUL prints to stderr.
+ if (QAppleTestLogger::debugLoggingEnabled())
+ logger = new QAppleTestLogger(logger);
+#endif
+
QTEST_ASSERT(logger);
QTest::TestLoggers::addLogger(logger);
}
@@ -591,6 +619,11 @@ int QTestLog::blacklistCount()
return QTest::blacklists;
}
+int QTestLog::totalCount()
+{
+ return passCount() + failCount() + skipCount() + blacklistCount();
+}
+
void QTestLog::resetCounters()
{
QTest::passes = 0;
diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h
index 3d28795188..600c078ce2 100644
--- a/src/testlib/qtestlog_p.h
+++ b/src/testlib/qtestlog_p.h
@@ -57,12 +57,13 @@ QT_BEGIN_NAMESPACE
class QBenchmarkResult;
class QRegularExpression;
+class QTestData;
class Q_TESTLIB_EXPORT QTestLog
{
public:
enum LogMode {
- Plain = 0, XML, LightXML, XunitXML, CSV, TeamCity,
+ Plain = 0, XML, LightXML, XunitXML, CSV, TeamCity, TAP,
#if defined(HAVE_XCTEST)
XCTest
#endif
@@ -71,6 +72,8 @@ public:
static void enterTestFunction(const char* function);
static void leaveTestFunction();
+ static void enterTestData(QTestData *data);
+
static void addPass(const char *msg);
static void addFail(const char *msg, const char *file, int line);
static void addXFail(const char *msg, const char *file, int line);
@@ -110,6 +113,7 @@ public:
static int failCount();
static int skipCount();
static int blacklistCount();
+ static int totalCount();
static void resetCounters();
diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp
index 219190d5da..88e3407c90 100644
--- a/src/testlib/qtestresult.cpp
+++ b/src/testlib/qtestresult.cpp
@@ -110,6 +110,8 @@ void QTestResult::setCurrentTestData(QTestData *data)
{
QTest::currentTestData = data;
QTest::failed = false;
+ if (data)
+ QTestLog::enterTestData(data);
}
void QTestResult::setCurrentTestFunction(const char *func)
diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h
index daa0d7aea0..7a73bbb5d2 100644
--- a/src/testlib/qtestsystem.h
+++ b/src/testlib/qtestsystem.h
@@ -41,113 +41,16 @@
#define QTESTSYSTEM_H
#include <QtTest/qtestcase.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qdeadlinetimer.h>
-#ifdef QT_GUI_LIB
-# include <QtGui/QWindow>
-#endif
-#ifdef QT_WIDGETS_LIB
-# include <QtWidgets/QWidget>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-namespace QTest
-{
- template <typename Functor>
- Q_REQUIRED_RESULT static bool qWaitFor(Functor predicate, int timeout = 5000)
- {
- // We should not spin the event loop in case the predicate is already true,
- // otherwise we might send new events that invalidate the predicate.
- if (predicate())
- return true;
-
- // qWait() is expected to spin the event loop, even when called with a small
- // timeout like 1ms, so we we can't use a simple while-loop here based on
- // the deadline timer not having timed out. Use do-while instead.
-
- int remaining = timeout;
- QDeadlineTimer deadline(remaining, Qt::PreciseTimer);
-
- do {
- QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
- QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
-
- remaining = deadline.remainingTime();
- if (remaining > 0) {
- QTest::qSleep(qMin(10, remaining));
- remaining = deadline.remainingTime();
- }
-
- if (predicate())
- return true;
-
- remaining = deadline.remainingTime();
- } while (remaining > 0);
-
- return predicate(); // Last chance
- }
-
- Q_DECL_UNUSED inline static void qWait(int ms)
- {
- // Ideally this method would be implemented in terms of qWaitFor, with
- // a predicate that always returns false, but due to a compiler bug in
- // GCC 6 we can't do that.
-
- Q_ASSERT(QCoreApplication::instance());
-
- QDeadlineTimer timer(ms, Qt::PreciseTimer);
- int remaining = ms;
- do {
- QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
- QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete);
- remaining = timer.remainingTime();
- if (remaining <= 0)
- break;
- QTest::qSleep(qMin(10, remaining));
- remaining = timer.remainingTime();
- } while (remaining > 0);
- }
+#include <QtCore/qtestsupport_core.h>
#ifdef QT_GUI_LIB
- Q_REQUIRED_RESULT inline static bool qWaitForWindowActive(QWindow *window, int timeout = 5000)
- {
- return qWaitFor([&]() { return window->isActive(); }, timeout);
- }
-
- Q_REQUIRED_RESULT inline static bool qWaitForWindowExposed(QWindow *window, int timeout = 5000)
- {
- return qWaitFor([&]() { return window->isExposed(); }, timeout);
- }
+# include <QtGui/qtestsupport_gui.h>
#endif
-
#ifdef QT_WIDGETS_LIB
- Q_REQUIRED_RESULT inline static bool qWaitForWindowActive(QWidget *widget, int timeout = 5000)
- {
- if (QWindow *window = widget->window()->windowHandle())
- return qWaitForWindowActive(window, timeout);
- return false;
- }
-
- Q_REQUIRED_RESULT inline static bool qWaitForWindowExposed(QWidget *widget, int timeout = 5000)
- {
- if (QWindow *window = widget->window()->windowHandle())
- return qWaitForWindowExposed(window, timeout);
- return false;
- }
+# include <QtWidgets/qtestsupport_widgets.h>
#endif
-#if QT_DEPRECATED_SINCE(5, 0)
-# ifdef QT_WIDGETS_LIB
-
- QT_DEPRECATED Q_REQUIRED_RESULT inline static bool qWaitForWindowShown(QWidget *widget, int timeout = 5000)
- {
- return qWaitForWindowExposed(widget, timeout);
- }
-# endif // QT_WIDGETS_LIB
-#endif // QT_DEPRECATED_SINCE(5, 0)
-}
-
+QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
#endif
diff --git a/src/testlib/qxctestlogger.mm b/src/testlib/qxctestlogger.mm
index 62fd73070f..9fa9da2fdd 100644
--- a/src/testlib/qxctestlogger.mm
+++ b/src/testlib/qxctestlogger.mm
@@ -200,7 +200,7 @@ private:
[autoreleasepool release];
}
-+ (id)defaultTestSuite
++ (QTestLibTests *)defaultTestSuite
{
return [[QtTestLibTests alloc] initWithName:@"QtTestLib"];
}
@@ -255,7 +255,7 @@ static XCTestSuiteRun *s_qtTestSuiteRun = 0;
@implementation QtTestLibTest
-- (id)initWithInvocation:(NSInvocation *)invocation
+- (instancetype)initWithInvocation:(NSInvocation *)invocation
{
if (self = [super initWithInvocation:invocation]) {
// The test object name and function name are used by XCTest after QtTestLib has
@@ -322,7 +322,7 @@ QXcodeTestLogger *QXcodeTestLogger::s_currentTestLogger = 0;
QXcodeTestLogger::QXcodeTestLogger()
: QAbstractTestLogger(0)
- , m_testRuns([[NSMutableArray arrayWithCapacity:2] retain])
+ , m_testRuns([[NSMutableArray<XCTestRun *> arrayWithCapacity:2] retain])
{
Q_ASSERT(!s_currentTestLogger);
@@ -383,11 +383,11 @@ static bool isTestFunctionInActiveScope(const char *function)
Q_ASSERT(activeScope == Selected);
- static NSArray *forcedTests = [@[ @"initTestCase", @"initTestCase_data", @"cleanupTestCase" ] retain];
+ static NSArray<NSString *> *forcedTests = [@[ @"initTestCase", @"initTestCase_data", @"cleanupTestCase" ] retain];
if ([forcedTests containsObject:[NSString stringWithUTF8String:function]])
return true;
- static NSArray *testsInScope = [[testScope componentsSeparatedByString:@","] retain];
+ static NSArray<NSString *> *testsInScope = [[testScope componentsSeparatedByString:@","] retain];
bool inScope = [testsInScope containsObject:[NSString stringWithFormat:@"%s/%s",
QTestResult::currentTestObjectName(), function]];
diff --git a/src/testlib/qxctestlogger_p.h b/src/testlib/qxctestlogger_p.h
index 1b641f18af..8baa5aa27f 100644
--- a/src/testlib/qxctestlogger_p.h
+++ b/src/testlib/qxctestlogger_p.h
@@ -90,7 +90,7 @@ private:
void pushTestRunForTest(XCTest *test, bool start);
XCTestRun *popTestRun();
- NSMutableArray *m_testRuns;
+ NSMutableArray<XCTestRun *> *m_testRuns;
static QXcodeTestLogger *s_currentTestLogger;
};
diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro
index 06a6f8b8e5..46b61dac07 100644
--- a/src/testlib/testlib.pro
+++ b/src/testlib/testlib.pro
@@ -39,7 +39,8 @@ HEADERS = \
qtesttouch.h \
qtestblacklist_p.h \
qtesthelpers_p.h \
- qttestglobal.h
+ qttestglobal.h \
+ qtaptestlogger_p.h
SOURCES = \
qtestcase.cpp \
@@ -65,7 +66,8 @@ SOURCES = \
qtestmouse.cpp \
qtestxunitstreamer.cpp \
qxunittestlogger.cpp \
- qtestblacklist.cpp
+ qtestblacklist.cpp \
+ qtaptestlogger.cpp
qtConfig(itemmodeltester) {
HEADERS += \
@@ -84,6 +86,9 @@ embedded:QMAKE_CXXFLAGS += -fno-rtti
mac {
LIBS += -framework Security
+ SOURCES += qappletestlogger.cpp
+ HEADERS += qappletestlogger_p.h
+
macos {
HEADERS += qtestutil_macos_p.h
OBJECTIVE_SOURCES += qtestutil_macos.mm
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 57714fc687..3b78d2487f 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -95,6 +95,7 @@ struct Options
, generateAssetsFileList(true)
, build(true)
, gradle(false)
+ , auxMode(false)
, deploymentMechanism(Bundled)
, releasePackage(false)
, digestAlg(QLatin1String("SHA1"))
@@ -126,6 +127,7 @@ struct Options
bool generateAssetsFileList;
bool build;
bool gradle;
+ bool auxMode;
QTime timer;
// External tools
@@ -137,6 +139,7 @@ struct Options
// Build paths
QString qtInstallDirectory;
+ std::vector<QString> extraPrefixDirs;
QString androidSourceDirectory;
QString outputDirectory;
QString inputFileName;
@@ -431,6 +434,8 @@ Options parseOptions()
options.jarSigner = true;
} else if (argument.compare(QLatin1String("--no-generated-assets-cache"), Qt::CaseInsensitive) == 0) {
options.generateAssetsFileList = false;
+ } else if (argument.compare(QLatin1String("--aux-mode"), Qt::CaseInsensitive) == 0) {
+ options.auxMode = true;
}
}
@@ -516,6 +521,9 @@ void printHelp()
" --verbose: Prints out information during processing.\n"
" --no-generated-assets-cache: Do not pregenerate the entry list for\n"
" the assets file engine.\n"
+ " --aux-mode: Operate in auxiliary mode. This will only copy the\n"
+ " dependencies into the build directory and update the XML templates.\n"
+ " The project will not be built or installed.\n"
" --help: Displays this information.\n\n",
qPrintable(QCoreApplication::arguments().at(0))
);
@@ -730,6 +738,14 @@ bool readInputFile(Options *options)
}
{
+ const auto extraPrefixDirs = jsonObject.value(QLatin1String("extraPrefixDirs")).toArray();
+ options->extraPrefixDirs.reserve(extraPrefixDirs.size());
+ for (const auto &prefix : extraPrefixDirs) {
+ options->extraPrefixDirs.push_back(prefix.toString());
+ }
+ }
+
+ {
const QJsonValue androidSourcesDirectory = jsonObject.value(QStringLiteral("android-package-source-directory"));
if (!androidSourcesDirectory.isUndefined())
options->androidSourceDirectory = androidSourcesDirectory.toString();
@@ -1287,6 +1303,9 @@ bool updateAndroidManifest(Options &options)
}
}
+ options.localJars.removeDuplicates();
+ options.initClasses.removeDuplicates();
+
QHash<QString, QString> replacements;
replacements[QLatin1String("-- %%INSERT_APP_NAME%% --")] = QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1);
replacements[QLatin1String("-- %%INSERT_APP_LIB_NAME%% --")] = QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1);
@@ -1380,6 +1399,16 @@ bool updateAndroidFiles(Options &options)
return true;
}
+static QString absoluteFilePath(const Options *options, const QString &relativeFileName)
+{
+ for (const auto &prefix : options->extraPrefixDirs) {
+ const QString path = prefix + QLatin1Char('/') + relativeFileName;
+ if (QFile::exists(path))
+ return path;
+ }
+ return options->qtInstallDirectory + QLatin1Char('/') + relativeFileName;
+}
+
QList<QtDependency> findFilesRecursively(const Options &options, const QFileInfo &info, const QString &rootPath)
{
if (!info.exists())
@@ -1404,6 +1433,11 @@ QList<QtDependency> findFilesRecursively(const Options &options, const QFileInfo
QList<QtDependency> findFilesRecursively(const Options &options, const QString &fileName)
{
+ for (const auto &prefix : options.extraPrefixDirs) {
+ QFileInfo info(prefix + QLatin1Char('/') + fileName);
+ if (info.exists())
+ return findFilesRecursively(options, info, prefix + QLatin1Char('/'));
+ }
QFileInfo info(options.qtInstallDirectory + QLatin1Char('/') + fileName);
return findFilesRecursively(options, info, options.qtInstallDirectory + QLatin1Char('/'));
}
@@ -1413,7 +1447,7 @@ bool readAndroidDependencyXml(Options *options,
QSet<QString> *usedDependencies,
QSet<QString> *remainingDependencies)
{
- QString androidDependencyName = options->qtInstallDirectory + QString::fromLatin1("/lib/%1-android-dependencies.xml").arg(moduleName);
+ QString androidDependencyName = absoluteFilePath(options, QString::fromLatin1("/lib/%1-android-dependencies.xml").arg(moduleName));
QFile androidDependencyFile(androidDependencyName);
if (androidDependencyFile.exists()) {
@@ -1458,7 +1492,7 @@ bool readAndroidDependencyXml(Options *options,
int bundling = reader.attributes().value(QLatin1String("bundling")).toInt();
QString fileName = reader.attributes().value(QLatin1String("file")).toString();
if (bundling == (options->deploymentMechanism == Options::Bundled)) {
- QtDependency dependency(fileName, options->qtInstallDirectory + QLatin1Char('/') + fileName);
+ QtDependency dependency(fileName, absoluteFilePath(options, fileName));
if (!usedDependencies->contains(dependency.absolutePath)) {
options->qtDependencies.append(dependency);
usedDependencies->insert(dependency.absolutePath);
@@ -1545,7 +1579,7 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
if (line.contains("(NEEDED)") && line.contains("Shared library:") ) {
const int pos = line.lastIndexOf('[') + 1;
QString libraryName = QLatin1String("lib/") + QString::fromLatin1(line.mid(pos, line.length() - pos - 2));
- if (QFile::exists(options.qtInstallDirectory + QLatin1Char('/') + libraryName)) {
+ if (QFile::exists(absoluteFilePath(&options, libraryName))) {
ret += libraryName;
}
@@ -1576,7 +1610,7 @@ bool readDependenciesFromElf(Options *options,
if (usedDependencies->contains(dependency))
continue;
- QString absoluteDependencyPath(options->qtInstallDirectory + QLatin1Char('/') + dependency);
+ QString absoluteDependencyPath = absoluteFilePath(options, dependency);
usedDependencies->insert(dependency);
if (!readDependenciesFromElf(options,
absoluteDependencyPath,
@@ -1763,11 +1797,9 @@ bool readDependencies(Options *options)
if (!readDependenciesFromElf(options, options->qtInstallDirectory + QLatin1String("/plugins/platforms/android/libqtforandroid.so"), &usedDependencies, &remainingDependencies))
return false;
- QString qtDir = options->qtInstallDirectory + QLatin1Char('/');
-
while (!remainingDependencies.isEmpty()) {
QSet<QString>::iterator start = remainingDependencies.begin();
- QString fileName = qtDir + *start;
+ QString fileName = absoluteFilePath(options, *start);
remainingDependencies.erase(start);
QStringList unmetDependencies;
@@ -1785,7 +1817,7 @@ bool readDependencies(Options *options)
QStringList::iterator it = options->localLibs.begin();
while (it != options->localLibs.end()) {
QStringList unmetDependencies;
- if (!goodToCopy(options, qtDir + *it, &unmetDependencies)) {
+ if (!goodToCopy(options, absoluteFilePath(options, *it), &unmetDependencies)) {
fprintf(stdout, "Skipping %s due to unmet dependencies: %s\n",
qPrintable(*it),
qPrintable(unmetDependencies.join(QLatin1Char(','))));
@@ -1922,7 +1954,7 @@ bool goodToCopy(const Options *options, const QString &file, QStringList *unmetD
bool ret = true;
const auto libs = getQtLibsFromElf(*options, file);
for (const QString &lib : libs) {
- if (!options->qtDependencies.contains(QtDependency(lib, options->qtInstallDirectory + QLatin1Char('/') + lib))) {
+ if (!options->qtDependencies.contains(QtDependency(lib, absoluteFilePath(options, lib)))) {
ret = false;
unmetDependencies->append(lib);
}
@@ -2801,6 +2833,22 @@ int main(int argc, char *argv[])
: "No"
);
+ if (options.auxMode) {
+ if (!readDependencies(&options))
+ return CannotReadDependencies;
+ if (!copyQtFiles(&options))
+ return CannotCopyQtFiles;
+ if (!copyAndroidExtraResources(options))
+ return CannotCopyAndroidExtraResources;
+ if (!stripLibraries(options))
+ return CannotStripLibraries;
+ if (!updateAndroidFiles(options))
+ return CannotUpdateAndroidFiles;
+ if (options.generateAssetsFileList && !generateAssetsFileList(options))
+ return CannotGenerateAssetsFileList;
+ return 0;
+ }
+
if (options.build) {
if (options.gradle)
cleanAndroidFiles(options);
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index a45382106a..83e44ff9a4 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -2,7 +2,7 @@ option(host_build)
TARGET = QtBootstrap
QT =
-CONFIG += minimal_syncqt internal_module force_bootstrap
+CONFIG += minimal_syncqt internal_module force_bootstrap gc_binaries
MODULE_INCNAME = QtCore QtXml
MODULE_DEFINES = \
@@ -12,6 +12,7 @@ MODULE_DEFINES = \
QT_VERSION_PATCH=$$QT_PATCH_VERSION \
QT_BOOTSTRAPPED \
QT_NO_CAST_TO_ASCII
+MODULE_CONFIG = gc_binaries
DEFINES += \
$$MODULE_DEFINES \
@@ -24,6 +25,7 @@ SOURCES += \
../../corelib/codecs/qlatincodec.cpp \
../../corelib/codecs/qtextcodec.cpp \
../../corelib/codecs/qutfcodec.cpp \
+ ../../corelib/global/qendian.cpp \
../../corelib/global/qglobal.cpp \
../../corelib/global/qlogging.cpp \
../../corelib/global/qmalloc.cpp \
diff --git a/src/tools/moc/cbordevice.h b/src/tools/moc/cbordevice.h
new file mode 100644
index 0000000000..dbfc537dd2
--- /dev/null
+++ b/src/tools/moc/cbordevice.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CBORDEVICE_H
+#define CBORDEVICE_H
+
+#include <memory>
+#include <stdio.h>
+
+#define CBOR_API inline
+#define CBOR_PRIVATE_API inline
+#define CBOR_NO_PARSER_API 1
+#include <cbor.h>
+
+class CborDevice
+{
+public:
+ CborDevice(FILE *out) : out(out) {}
+
+ void nextItem(const char *comment = nullptr)
+ {
+ i = 0;
+ if (comment)
+ fprintf(out, "\n // %s", comment);
+ }
+
+ static CborError callback(void *self, const void *ptr, size_t len, CborEncoderAppendType t)
+ {
+ auto that = static_cast<CborDevice *>(self);
+ auto data = static_cast<const char *>(ptr);
+ if (t == CborEncoderAppendCborData) {
+ while (len--)
+ that->putByte(*data++);
+ } else {
+ while (len--)
+ that->putChar(*data++);
+ }
+ return CborNoError;
+ }
+
+private:
+ FILE *out;
+ int i = 0;
+
+ void putNewline()
+ {
+ if ((i++ % 8) == 0)
+ fputs("\n ", out);
+ }
+
+ void putByte(uint8_t c)
+ {
+ putNewline();
+ fprintf(out, " 0x%02x, ", c);
+ }
+
+ void putChar(char c)
+ {
+ putNewline();
+ if (uchar(c) < 0x20)
+ fprintf(out, " '\\x%x',", uint8_t(c));
+ else if (uchar(c) >= 0x7f)
+ fprintf(out, " uchar('\\x%x'),", uint8_t(c));
+ else if (c == '\'' || c == '\\')
+ fprintf(out, " '\\%c',", c);
+ else
+ fprintf(out, " '%c', ", c);
+ }
+};
+
+#endif // CBORDEVICE_H
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index d299cdad51..9fb980893f 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -2,6 +2,7 @@
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -28,6 +29,7 @@
****************************************************************************/
#include "generator.h"
+#include "cbordevice.h"
#include "outputrevision.h"
#include "utils.h"
#include <QtCore/qmetatype.h>
@@ -36,9 +38,13 @@
#include <QtCore/qjsonvalue.h>
#include <QtCore/qjsonarray.h>
#include <QtCore/qplugin.h>
+#include <QtCore/qstringview.h>
+
+#include <math.h>
#include <stdio.h>
#include <private/qmetaobject_p.h> //for the flags.
+#include <private/qplugin_p.h> //for the flags.
QT_BEGIN_NAMESPACE
@@ -74,7 +80,7 @@ QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING)
return 0;
}
-Generator::Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile)
+Generator::Generator(ClassDef *classDef, const QVector<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile)
: out(outfile), cdef(classDef), metaTypes(metaTypes), knownQObjectClasses(knownQObjectClasses)
, knownGadgets(knownGadgets)
{
@@ -200,6 +206,7 @@ void Generator::generateCode()
if (cdef->enumDeclarations.contains(def.name)) {
enumList += def;
}
+ def.enumName = def.name;
QByteArray alias = cdef->flagAliases.value(def.name);
if (cdef->enumDeclarations.contains(alias)) {
def.name = alias;
@@ -369,7 +376,7 @@ void Generator::generateCode()
int enumsIndex = index;
for (int i = 0; i < cdef->enumList.count(); ++i)
- index += 4 + (cdef->enumList.at(i).values.count() * 2);
+ index += 5 + (cdef->enumList.at(i).values.count() * 2);
fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0,
isConstructible ? index : 0);
@@ -454,7 +461,7 @@ void Generator::generateCode()
//
// Build extra array
//
- QList<QByteArray> extraList;
+ QVector<QByteArray> extraList;
QHash<QByteArray, QByteArray> knownExtraMetaObject = knownGadgets;
knownExtraMetaObject.unite(knownQObjectClasses);
@@ -523,29 +530,29 @@ void Generator::generateCode()
// Finally create and initialize the static meta object
//
if (isQt)
- fprintf(out, "QT_INIT_METAOBJECT const QMetaObject QObject::staticQtMetaObject = {\n");
+ fprintf(out, "QT_INIT_METAOBJECT const QMetaObject QObject::staticQtMetaObject = { {\n");
else
- fprintf(out, "QT_INIT_METAOBJECT const QMetaObject %s::staticMetaObject = {\n", cdef->qualified.constData());
+ fprintf(out, "QT_INIT_METAOBJECT const QMetaObject %s::staticMetaObject = { {\n", cdef->qualified.constData());
if (isQObject)
- fprintf(out, " { nullptr, ");
+ fprintf(out, " nullptr,\n");
else if (cdef->superclassList.size() && (!cdef->hasQGadget || knownGadgets.contains(purestSuperClass)))
- fprintf(out, " { &%s::staticMetaObject, ", purestSuperClass.constData());
+ fprintf(out, " &%s::staticMetaObject,\n", purestSuperClass.constData());
else
- fprintf(out, " { nullptr, ");
- fprintf(out, "qt_meta_stringdata_%s.data,\n"
- " qt_meta_data_%s, ", qualifiedClassNameIdentifier.constData(),
+ fprintf(out, " nullptr,\n");
+ fprintf(out, " qt_meta_stringdata_%s.data,\n"
+ " qt_meta_data_%s,\n", qualifiedClassNameIdentifier.constData(),
qualifiedClassNameIdentifier.constData());
if (hasStaticMetaCall)
- fprintf(out, " qt_static_metacall, ");
+ fprintf(out, " qt_static_metacall,\n");
else
- fprintf(out, " nullptr, ");
+ fprintf(out, " nullptr,\n");
if (extraList.isEmpty())
- fprintf(out, "nullptr, ");
+ fprintf(out, " nullptr,\n");
else
- fprintf(out, "qt_meta_extradata_%s, ", qualifiedClassNameIdentifier.constData());
- fprintf(out, "nullptr}\n};\n\n");
+ fprintf(out, " qt_meta_extradata_%s,\n", qualifiedClassNameIdentifier.constData());
+ fprintf(out, " nullptr\n} };\n\n");
if(isQt)
return;
@@ -887,6 +894,8 @@ void Generator::registerEnumStrings()
for (int i = 0; i < cdef->enumList.count(); ++i) {
const EnumDef &e = cdef->enumList.at(i);
strreg(e.name);
+ if (!e.enumName.isNull())
+ strreg(e.enumName);
for (int j = 0; j < e.values.count(); ++j)
strreg(e.values.at(j));
}
@@ -897,8 +906,8 @@ void Generator::generateEnums(int index)
if (cdef->enumDeclarations.isEmpty())
return;
- fprintf(out, "\n // enums: name, flags, count, data\n");
- index += 4 * cdef->enumList.count();
+ fprintf(out, "\n // enums: name, alias, flags, count, data\n");
+ index += 5 * cdef->enumList.count();
int i;
for (i = 0; i < cdef->enumList.count(); ++i) {
const EnumDef &e = cdef->enumList.at(i);
@@ -907,8 +916,9 @@ void Generator::generateEnums(int index)
flags |= EnumIsFlag;
if (e.isEnumClass)
flags |= EnumIsScoped;
- fprintf(out, " %4d, 0x%.1x, %4d, %4d,\n",
+ fprintf(out, " %4d, %4d, 0x%.1x, %4d, %4d,\n",
stridx(e.name),
+ e.enumName.isNull() ? stridx(e.name) : stridx(e.enumName),
flags,
e.values.count(),
index);
@@ -922,7 +932,7 @@ void Generator::generateEnums(int index)
const QByteArray &val = e.values.at(j);
QByteArray code = cdef->qualified.constData();
if (e.isEnumClass)
- code += "::" + e.name;
+ code += "::" + (e.enumName.isNull() ? e.name : e.enumName);
code += "::" + val;
fprintf(out, " %4d, uint(%s),\n",
stridx(val), code.constData());
@@ -1556,31 +1566,56 @@ void Generator::generateSignal(FunctionDef *def,int index)
fprintf(out, "}\n");
}
-static void writePluginMetaData(FILE *out, const QJsonObject &data)
+static CborError jsonValueToCbor(CborEncoder *parent, const QJsonValue &v);
+static CborError jsonObjectToCbor(CborEncoder *parent, const QJsonObject &o)
{
- const QJsonDocument doc(data);
+ auto it = o.constBegin();
+ auto end = o.constEnd();
+ CborEncoder map;
+ cbor_encoder_create_map(parent, &map, o.size());
+
+ for ( ; it != end; ++it) {
+ QByteArray key = it.key().toUtf8();
+ cbor_encode_text_string(&map, key.constData(), key.size());
+ jsonValueToCbor(&map, it.value());
+ }
+ return cbor_encoder_close_container(parent, &map);
+}
- fputs("\nQT_PLUGIN_METADATA_SECTION\n"
- "static const unsigned char qt_pluginMetaData[] = {\n"
- " 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', ' ',\n ", out);
-#if 0
- fprintf(out, "\"%s\";\n", doc.toJson().constData());
-#else
- const QByteArray binary = doc.toBinaryData();
- const int last = binary.size() - 1;
- for (int i = 0; i < last; ++i) {
- uchar c = (uchar)binary.at(i);
- if (c < 0x20 || c >= 0x7f)
- fprintf(out, " 0x%02x,", c);
- else if (c == '\'' || c == '\\')
- fprintf(out, " '\\%c',", c);
- else
- fprintf(out, " '%c', ", c);
- if (!((i + 1) % 8))
- fputs("\n ", out);
+static CborError jsonArrayToCbor(CborEncoder *parent, const QJsonArray &a)
+{
+ CborEncoder array;
+ cbor_encoder_create_array(parent, &array, a.size());
+ for (const QJsonValue &v : a)
+ jsonValueToCbor(&array, v);
+ return cbor_encoder_close_container(parent, &array);
+}
+
+static CborError jsonValueToCbor(CborEncoder *parent, const QJsonValue &v)
+{
+ switch (v.type()) {
+ case QJsonValue::Null:
+ case QJsonValue::Undefined:
+ return cbor_encode_null(parent);
+ case QJsonValue::Bool:
+ return cbor_encode_boolean(parent, v.toBool());
+ case QJsonValue::Array:
+ return jsonArrayToCbor(parent, v.toArray());
+ case QJsonValue::Object:
+ return jsonObjectToCbor(parent, v.toObject());
+ case QJsonValue::String: {
+ QByteArray s = v.toString().toUtf8();
+ return cbor_encode_text_string(parent, s.constData(), s.size());
}
- fprintf(out, " 0x%02x\n};\n", (uchar)binary.at(last));
-#endif
+ case QJsonValue::Double: {
+ double d = v.toDouble();
+ if (d == floor(d) && fabs(d) <= (Q_INT64_C(1) << std::numeric_limits<double>::digits))
+ return cbor_encode_int(parent, qint64(d));
+ return cbor_encode_double(parent, d);
+ }
+ }
+ Q_UNREACHABLE();
+ return CborUnknownError;
}
void Generator::generatePluginMetaData()
@@ -1588,32 +1623,48 @@ void Generator::generatePluginMetaData()
if (cdef->pluginData.iid.isEmpty())
return;
- // Write plugin meta data #ifdefed QT_NO_DEBUG with debug=false,
- // true, respectively.
+ fputs("\nQT_PLUGIN_METADATA_SECTION\n"
+ "static constexpr unsigned char qt_pluginMetaData[] = {\n"
+ " 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!',\n"
+ " // metadata version, Qt version, architectural requirements\n"
+ " 0, QT_VERSION_MAJOR, QT_VERSION_MINOR, qPluginArchRequirements(),", out);
- QJsonObject data;
- const QString debugKey = QStringLiteral("debug");
- data.insert(QStringLiteral("IID"), QLatin1String(cdef->pluginData.iid.constData()));
- data.insert(QStringLiteral("className"), QLatin1String(cdef->classname.constData()));
- data.insert(QStringLiteral("version"), (int)QT_VERSION);
- data.insert(debugKey, QJsonValue(false));
- data.insert(QStringLiteral("MetaData"), cdef->pluginData.metaData.object());
- // Add -M args from the command line:
- for (auto it = cdef->pluginData.metaArgs.cbegin(), end = cdef->pluginData.metaArgs.cend(); it != end; ++it)
- data.insert(it.key(), it.value());
+ CborDevice dev(out);
+ CborEncoder enc;
+ cbor_encoder_init_writer(&enc, CborDevice::callback, &dev);
- fputs("\nQT_PLUGIN_METADATA_SECTION const uint qt_section_alignment_dummy = 42;\n\n"
- "#ifdef QT_NO_DEBUG\n", out);
- writePluginMetaData(out, data);
+ CborEncoder map;
+ cbor_encoder_create_map(&enc, &map, CborIndefiniteLength);
- fputs("\n#else // QT_NO_DEBUG\n", out);
+ dev.nextItem("\"IID\"");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::IID));
+ cbor_encode_text_string(&map, cdef->pluginData.iid.constData(), cdef->pluginData.iid.size());
- data.remove(debugKey);
- data.insert(debugKey, QJsonValue(true));
- writePluginMetaData(out, data);
+ dev.nextItem("\"className\"");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::ClassName));
+ cbor_encode_text_string(&map, cdef->classname.constData(), cdef->classname.size());
- fputs("#endif // QT_NO_DEBUG\n\n", out);
+ QJsonObject o = cdef->pluginData.metaData.object();
+ if (!o.isEmpty()) {
+ dev.nextItem("\"MetaData\"");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::MetaData));
+ jsonObjectToCbor(&map, o);
+ }
+
+ // Add -M args from the command line:
+ for (auto it = cdef->pluginData.metaArgs.cbegin(), end = cdef->pluginData.metaArgs.cend(); it != end; ++it) {
+ const QJsonArray &a = it.value();
+ QByteArray key = it.key().toUtf8();
+ dev.nextItem(QByteArray("command-line \"" + key + "\"").constData());
+ cbor_encode_text_string(&map, key.constData(), key.size());
+ jsonArrayToCbor(&map, a);
+ }
+
+ // Close the CBOR map manually
+ dev.nextItem();
+ cbor_encoder_close_container(&enc, &map);
+ fputs("\n};\n", out);
// 'Use' all namespaces.
int pos = cdef->qualified.indexOf("::");
@@ -1623,4 +1674,14 @@ void Generator::generatePluginMetaData()
cdef->qualified.constData(), cdef->classname.constData());
}
+QT_WARNING_DISABLE_GCC("-Wunused-function")
+QT_WARNING_DISABLE_CLANG("-Wunused-function")
+QT_WARNING_DISABLE_CLANG("-Wundefined-internal")
+QT_WARNING_DISABLE_MSVC(4334) // '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
+
+#define CBOR_ENCODER_WRITER_CONTROL 1
+#define CBOR_ENCODER_WRITE_FUNCTION CborDevice::callback
+
QT_END_NAMESPACE
+
+#include "cborencoder.c"
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
index 8b80138302..134166580b 100644
--- a/src/tools/moc/generator.h
+++ b/src/tools/moc/generator.h
@@ -39,7 +39,7 @@ class Generator
ClassDef *cdef;
QVector<uint> meta_data;
public:
- Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = 0);
+ Generator(ClassDef *classDef, const QVector<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = 0);
void generateCode();
private:
bool registerableMetaType(const QByteArray &propertyType);
@@ -64,9 +64,9 @@ private:
void strreg(const QByteArray &); // registers a string
int stridx(const QByteArray &); // returns a string's id
- QList<QByteArray> strings;
+ QVector<QByteArray> strings;
QByteArray purestSuperClass;
- QList<QByteArray> metaTypes;
+ QVector<QByteArray> metaTypes;
QHash<QByteArray, QByteArray> knownQObjectClasses;
QHash<QByteArray, QByteArray> knownGadgets;
};
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 5f8cdfcf2c..d98c73e1a0 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -64,7 +64,8 @@ Q_DECLARE_TYPEINFO(Type, Q_MOVABLE_TYPE);
struct EnumDef
{
QByteArray name;
- QList<QByteArray> values;
+ QByteArray enumName;
+ QVector<QByteArray> values;
bool isEnumClass; // c++11 enum class
EnumDef() : isEnumClass(false) {}
};
@@ -206,10 +207,10 @@ public:
bool noInclude;
bool mustIncludeQPluginH;
QByteArray includePath;
- QList<QByteArray> includeFiles;
+ QVector<QByteArray> includeFiles;
QVector<ClassDef> classList;
QMap<QByteArray, QByteArray> interface2IdMap;
- QList<QByteArray> metaTypes;
+ QVector<QByteArray> metaTypes;
// map from class name to fully qualified name
QHash<QByteArray, QByteArray> knownQObjectClasses;
QHash<QByteArray, QByteArray> knownGadgets;
diff --git a/src/tools/moc/moc.pri b/src/tools/moc/moc.pri
index b689a35478..90839a445b 100644
--- a/src/tools/moc/moc.pri
+++ b/src/tools/moc/moc.pri
@@ -1,5 +1,6 @@
-INCLUDEPATH += $$PWD
+INCLUDEPATH += $$PWD \
+ $$PWD/../../3rdparty/tinycbor/src
HEADERS = $$PWD/moc.h \
$$PWD/preprocessor.h \
@@ -8,7 +9,8 @@ HEADERS = $$PWD/moc.h \
$$PWD/token.h \
$$PWD/utils.h \
$$PWD/generator.h \
- $$PWD/outputrevision.h
+ $$PWD/outputrevision.h \
+ $$PWD/cbordevice.h
SOURCES = $$PWD/moc.cpp \
$$PWD/preprocessor.cpp \
$$PWD/generator.cpp \
diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
index c76983200e..2115a14adf 100644
--- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
+++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -62,7 +62,7 @@ static const char docTypeHeader[] =
#define PROGRAMNAME "qdbuscpp2xml"
#define PROGRAMVERSION "0.2"
-#define PROGRAMCOPYRIGHT "Copyright (C) 2017 The Qt Company Ltd."
+#define PROGRAMCOPYRIGHT "Copyright (C) 2018 The Qt Company Ltd."
static QString outputFile;
static int flags;
diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
index bbe738dadb..5b76502c94 100644
--- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -46,7 +46,7 @@
#define PROGRAMNAME "qdbusxml2cpp"
#define PROGRAMVERSION "0.8"
-#define PROGRAMCOPYRIGHT "Copyright (C) 2017 The Qt Company Ltd."
+#define PROGRAMCOPYRIGHT "Copyright (C) 2018 The Qt Company Ltd."
#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp
index fba47b74c3..12f986b1e2 100644
--- a/src/tools/rcc/main.cpp
+++ b/src/tools/rcc/main.cpp
@@ -151,6 +151,10 @@ int runRcc(int argc, char *argv[])
QCommandLineOption listOption(QStringLiteral("list"), QStringLiteral("Only list .qrc file entries, do not generate code."));
parser.addOption(listOption);
+ QCommandLineOption mapOption(QStringLiteral("list-mapping"),
+ QStringLiteral("Only output a mapping of resource paths to file system paths defined in the .qrc file, do not generate code."));
+ parser.addOption(mapOption);
+
QCommandLineOption projectOption(QStringLiteral("project"), QStringLiteral("Output a resource file containing all files from the current directory."));
parser.addOption(projectOption);
@@ -207,6 +211,7 @@ int runRcc(int argc, char *argv[])
library.setVerbose(true);
const bool list = parser.isSet(listOption);
+ const bool map = parser.isSet(mapOption);
const bool projectRequested = parser.isSet(projectOption);
const QStringList filenamesIn = parser.positionalArguments();
@@ -242,7 +247,7 @@ int runRcc(int argc, char *argv[])
library.setInputFiles(filenamesIn);
- if (!library.readFiles(list, errorDevice))
+ if (!library.readFiles(list || map, errorDevice))
return 1;
QFile out;
@@ -294,6 +299,17 @@ int runRcc(int argc, char *argv[])
return 0;
}
+ if (map) {
+ const RCCResourceLibrary::ResourceDataFileMap data = library.resourceDataFileMap();
+ for (auto it = data.begin(), end = data.end(); it != end; ++it) {
+ out.write(qPrintable(it.key()));
+ out.write("\t");
+ out.write(qPrintable(QDir::cleanPath(it.value())));
+ out.write("\n");
+ }
+ return 0;
+ }
+
QFile temp;
if (!tempFilename.isEmpty()) {
temp.setFileName(tempFilename);
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 4c7d095ca3..1a7cab01df 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -377,7 +377,7 @@ enum RCCXmlTag {
Q_DECLARE_TYPEINFO(RCCXmlTag, Q_PRIMITIVE_TYPE);
bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
- const QString &fname, QString currentPath, bool ignoreErrors)
+ const QString &fname, QString currentPath, bool listMode)
{
Q_ASSERT(m_errorDevice);
const QChar slash = QLatin1Char('/');
@@ -527,7 +527,7 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
m_failedResources.push_back(child.fileName());
}
}
- } else if (file.isFile()) {
+ } else if (listMode || file.isFile()) {
const bool arc =
addFile(alias,
RCCFileInfo(alias.section(slash, -1),
@@ -551,8 +551,6 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
const QString msg = QString::fromLatin1("RCC: Error in '%1': Cannot find file '%2'\n")
.arg(fname, fileName);
m_errorDevice->write(msg.toUtf8());
- if (ignoreErrors)
- continue;
return false;
}
}
@@ -564,8 +562,6 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
}
if (reader.hasError()) {
- if (ignoreErrors)
- return true;
int errorLine = reader.lineNumber();
int errorColumn = reader.columnNumber();
QString errorMessage = reader.errorString();
@@ -577,7 +573,7 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
if (m_root == 0) {
const QString msg = QString::fromLatin1("RCC: Warning: No resources in '%1'.\n").arg(fname);
m_errorDevice->write(msg.toUtf8());
- if (!ignoreErrors && m_format == Binary) {
+ if (!listMode && m_format == Binary) {
// create dummy entry, otherwise loading with QResource will crash
m_root = new RCCFileInfo(QString(), QFileInfo(),
QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory);
@@ -645,14 +641,14 @@ void RCCResourceLibrary::reset()
}
-bool RCCResourceLibrary::readFiles(bool ignoreErrors, QIODevice &errorDevice)
+bool RCCResourceLibrary::readFiles(bool listMode, QIODevice &errorDevice)
{
reset();
m_errorDevice = &errorDevice;
//read in data
if (m_verbose) {
- const QString msg = QString::fromLatin1("Processing %1 files [%2]\n")
- .arg(m_fileNames.size()).arg(static_cast<int>(ignoreErrors));
+ const QString msg = QString::fromLatin1("Processing %1 files [listMode=%2]\n")
+ .arg(m_fileNames.size()).arg(static_cast<int>(listMode));
m_errorDevice->write(msg.toUtf8());
}
for (int i = 0; i < m_fileNames.size(); ++i) {
@@ -680,7 +676,7 @@ bool RCCResourceLibrary::readFiles(bool ignoreErrors, QIODevice &errorDevice)
m_errorDevice->write(msg.toUtf8());
}
- if (!interpretResourceFile(&fileIn, fname, pwd, ignoreErrors))
+ if (!interpretResourceFile(&fileIn, fname, pwd, listMode))
return false;
}
return true;
diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h
index 19e04e401d..36984cf38a 100644
--- a/src/tools/rcc/rcc.h
+++ b/src/tools/rcc/rcc.h
@@ -53,7 +53,7 @@ public:
bool output(QIODevice &outDevice, QIODevice &tempDevice, QIODevice &errorDevice);
- bool readFiles(bool ignoreErrors, QIODevice &errorDevice);
+ bool readFiles(bool listMode, QIODevice &errorDevice);
enum Format { Binary, C_Code, Pass1, Pass2 };
void setFormat(Format f) { m_format = f; }
@@ -109,7 +109,7 @@ private:
void reset();
bool addFile(const QString &alias, const RCCFileInfo &file);
bool interpretResourceFile(QIODevice *inputDevice, const QString &file,
- QString currentPath = QString(), bool ignoreErrors = false);
+ QString currentPath = QString(), bool listMode = false);
bool writeHeader();
bool writeDataBlobs();
bool writeDataNames();
diff --git a/src/tools/tracegen/etw.cpp b/src/tools/tracegen/etw.cpp
index 07f2d114b6..8c065f93c9 100644
--- a/src/tools/tracegen/etw.cpp
+++ b/src/tools/tracegen/etw.cpp
@@ -75,6 +75,9 @@ static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
<< "TraceLoggingValue(" << name << ".width(), \"width\"), "
<< "TraceLoggingValue(" << name << ".height(), \"height\")";
return;
+ case Tracepoint::Field::Pointer:
+ stream << "TraceLoggingPointer(" << name << ", \"" << name << "\")";
+ return;
default:
break;
}
diff --git a/src/tools/tracegen/lttng.cpp b/src/tools/tracegen/lttng.cpp
index 6c0d8cc88b..5d41bf5f1f 100644
--- a/src/tools/tracegen/lttng.cpp
+++ b/src/tools/tracegen/lttng.cpp
@@ -69,6 +69,10 @@ static void writeCtfMacro(QTextStream &stream, const Tracepoint::Field &field)
case Tracepoint::Field::Integer:
stream << "ctf_integer(" << paramType << ", " << name << ", " << name << ")";
return;
+ case Tracepoint::Field::IntegerHex:
+ case Tracepoint::Field::Pointer:
+ stream << "ctf_integer_hex(" << paramType << ", " << name << ", " << name << ")";
+ return;
case Tracepoint::Field::Float:
stream << "ctf_float(" << paramType << ", " << name << ", " << name << ")";
return;
diff --git a/src/tools/tracegen/provider.cpp b/src/tools/tracegen/provider.cpp
index 00e105377e..a6523a2e3d 100644
--- a/src/tools/tracegen/provider.cpp
+++ b/src/tools/tracegen/provider.cpp
@@ -157,10 +157,13 @@ static Tracepoint::Field::BackendType backendType(QString rawType)
{ "signed_long_long_int", Tracepoint::Field::Integer },
{ "unsigned_long_long", Tracepoint::Field::Integer },
{ "char", Tracepoint::Field::Integer },
+ { "intptr_t", Tracepoint::Field::IntegerHex },
+ { "uintptr_t", Tracepoint::Field::IntegerHex },
+ { "std::intptr_t", Tracepoint::Field::IntegerHex },
+ { "std::uintptr_t", Tracepoint::Field::IntegerHex },
{ "float", Tracepoint::Field::Float },
{ "double", Tracepoint::Field::Float },
{ "long_double", Tracepoint::Field::Float },
- { "char_ptr", Tracepoint::Field::String },
{ "QString", Tracepoint::Field::QtString },
{ "QByteArray", Tracepoint::Field::QtByteArray },
{ "QUrl", Tracepoint::Field::QtUrl },
@@ -168,7 +171,6 @@ static Tracepoint::Field::BackendType backendType(QString rawType)
};
auto backendType = [](const QString &rawType) {
-
static const size_t tableSize = sizeof (typeTable) / sizeof (typeTable[0]);
for (size_t i = 0; i < tableSize; ++i) {
@@ -194,7 +196,13 @@ static Tracepoint::Field::BackendType backendType(QString rawType)
rawType = rawType.trimmed();
rawType.replace(QStringLiteral(" "), QStringLiteral("_"));
- return backendType(rawType.trimmed());
+ if (rawType == QLatin1String("char_ptr"))
+ return Tracepoint::Field::String;
+
+ if (rawType.endsWith(QLatin1String("_ptr")))
+ return Tracepoint::Field::Pointer;
+
+ return backendType(rawType);
}
static Tracepoint parseTracepoint(const QString &name, const QStringList &args,
@@ -264,35 +272,28 @@ Provider parseProvider(const QString &filename)
static const QRegExp tracedef(QStringLiteral("([A-Za-z][A-Za-z0-9_]*)\\((.*)\\)"));
- int lineNumber = 0;
-
Provider provider;
provider.name = QFileInfo(filename).baseName();
- for (;;) {
+ for (int lineNumber = 1; !s.atEnd(); ++lineNumber) {
QString line = s.readLine().trimmed();
- if (line.isNull())
- break;
-
- if (line.isEmpty() || line.startsWith(QStringLiteral("#"))) {
- ++lineNumber;
+ if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
continue;
- }
if (tracedef.exactMatch(line)) {
const QString name = tracedef.cap(1);
- QStringList args = tracedef.cap(2).split(QStringLiteral(","), QString::SkipEmptyParts);
-
- if (args.at(0).isNull())
- args.clear();
+ const QString argsString = tracedef.cap(2);
+ const QStringList args = argsString.split(QLatin1Char(','),
+ QString::SkipEmptyParts);
provider.tracepoints << parseTracepoint(name, args, filename, lineNumber);
} else {
- panic("Syntax error whilre processing %s on line %d", qPrintable(filename), lineNumber);
+ panic("Syntax error while processing '%s' line %d:\n"
+ " '%s' does not look like a tracepoint definition",
+ qPrintable(filename), lineNumber,
+ qPrintable(line));
}
-
- ++lineNumber;
}
#ifdef TRACEGEN_DEBUG
diff --git a/src/tools/tracegen/provider.h b/src/tools/tracegen/provider.h
index d8cbd2662d..9771e62f4d 100644
--- a/src/tools/tracegen/provider.h
+++ b/src/tools/tracegen/provider.h
@@ -59,8 +59,10 @@ struct Tracepoint
Array,
Sequence,
Integer,
+ IntegerHex,
Float,
String,
+ Pointer,
QtString,
QtByteArray,
QtUrl,
diff --git a/src/tools/uic/cpp/cppwritedeclaration.cpp b/src/tools/uic/cpp/cppwritedeclaration.cpp
index 9e774ad07b..995b99b692 100644
--- a/src/tools/uic/cpp/cppwritedeclaration.cpp
+++ b/src/tools/uic/cpp/cppwritedeclaration.cpp
@@ -40,10 +40,11 @@
QT_BEGIN_NAMESPACE
namespace {
- void openNameSpaces(const QStringList &namespaceList, QTextStream &output) {
- for (auto it = namespaceList.begin(), end = namespaceList.end(); it != end; ++it) {
- if (!it->isEmpty())
- output << "namespace " << *it << " {\n";
+ void openNameSpaces(const QStringList &namespaceList, QTextStream &output)
+ {
+ for (const QString &n : namespaceList) {
+ if (!n.isEmpty())
+ output << "namespace " << n << " {\n";
}
}
@@ -103,13 +104,9 @@ void WriteDeclaration::acceptUI(DomUI *node)
<< "public:\n";
const QStringList connections = m_uic->databaseInfo()->connections();
- for (int i=0; i<connections.size(); ++i) {
- const QString connection = connections.at(i);
-
- if (connection == QLatin1String("(default)"))
- continue;
-
- m_output << m_option.indent << "QSqlDatabase " << connection << "Connection;\n";
+ for (const QString &connection : connections) {
+ if (connection != QLatin1String("(default)"))
+ m_output << m_option.indent << "QSqlDatabase " << connection << "Connection;\n";
}
TreeWalker::acceptWidget(node->elementWidget());
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
index 9ab5fd4eb0..6a0e2f0338 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.cpp
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -475,21 +475,6 @@ WriteInitialization::WriteInitialization(Uic *uic) :
{
}
-QString WriteInitialization::writeString(const QString &s, const QString &indent) const
-{
- unsigned flags = 0;
- const QString ret = fixString(s, indent, &flags);
- if (flags & Utf8String)
- return QLatin1String("QString::fromUtf8(") + ret + QLatin1Char(')');
- // MSVC cannot concat L"foo" "bar" (C2308: concatenating mismatched strings),
- // use QLatin1String instead (all platforms to avoid cross-compiling issues).
- if (flags & MultiLineString)
- return QLatin1String("QLatin1String(") + ret + QLatin1Char(')');
- const QLatin1String stringWrapper = m_uic->option().stringLiteral ?
- QLatin1String("QStringLiteral(") : QLatin1String("QLatin1String(");
- return stringWrapper + ret + QLatin1Char(')');
-}
-
void WriteInitialization::acceptUI(DomUI *node)
{
m_actionGroupChain.push(0);
@@ -529,16 +514,14 @@ void WriteInitialization::acceptUI(DomUI *node)
continue;
const QString varConn = connection + QLatin1String("Connection");
- m_output << m_indent << varConn << " = QSqlDatabase::database(" << writeString(connection, m_dindent) << ");\n";
+ m_output << m_indent << varConn << " = QSqlDatabase::database(" << fixString(connection, m_dindent) << ");\n";
}
acceptWidget(node->elementWidget());
- if (m_buddies.size() > 0)
+ if (!m_buddies.empty())
openIfndef(m_output, QLatin1String(shortcutDefineC));
- for (int i=0; i<m_buddies.size(); ++i) {
- const Buddy &b = m_buddies.at(i);
-
+ for (const Buddy &b : qAsConst(m_buddies)) {
if (!m_registeredWidgets.contains(b.objName)) {
fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
qPrintable(m_option.messagePrefix()),
@@ -553,7 +536,7 @@ void WriteInitialization::acceptUI(DomUI *node)
m_output << m_indent << b.objName << "->setBuddy(" << b.buddy << ");\n";
}
- if (m_buddies.size() > 0)
+ if (!m_buddies.empty())
closeIfndef(m_output, QLatin1String(shortcutDefineC));
if (node->elementTabStops())
@@ -832,9 +815,7 @@ void WriteInitialization::acceptWidget(DomWidget *node)
m_layoutChain.pop();
const QStringList zOrder = node->elementZOrder();
- for (int i = 0; i < zOrder.size(); ++i) {
- const QString name = zOrder.at(i);
-
+ for (const QString &name : zOrder) {
if (!m_registeredWidgets.contains(name)) {
fprintf(stderr, "%s: Warning: Z-order assignment: '%s' is not a valid widget.\n",
qPrintable(m_option.messagePrefix()),
@@ -842,11 +823,8 @@ void WriteInitialization::acceptWidget(DomWidget *node)
continue;
}
- if (name.isEmpty()) {
- continue;
- }
-
- m_output << m_indent << name << "->raise();\n";
+ if (!name.isEmpty())
+ m_output << m_indent << name << "->raise();\n";
}
}
@@ -1141,7 +1119,7 @@ QString WriteInitialization::writeStringListProperty(const DomStringList *list)
str << '\n' << m_indent << " << " << trCall(values.at(i), comment);
} else {
for (int i = 0; i < values.size(); ++i)
- str << " << " << writeString(values.at(i), m_dindent);
+ str << " << QString::fromUtf8(" << fixString(values.at(i), m_dindent) << ')';
}
return propertyValue;
}
@@ -1156,8 +1134,8 @@ void WriteInitialization::writeProperties(const QString &varName,
if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QAxWidget"))) {
DomPropertyMap properties = propertyMap(lst);
if (DomProperty *p = properties.value(QLatin1String("control"))) {
- m_output << m_indent << varName << "->setControl("
- << writeString(toString(p->elementString()), m_dindent) << ");\n";
+ m_output << m_indent << varName << "->setControl(QString::fromUtf8("
+ << fixString(toString(p->elementString()), m_dindent) << "));\n";
}
}
@@ -1168,14 +1146,13 @@ void WriteInitialization::writeProperties(const QString &varName,
}
if (!(flags & WritePropertyIgnoreObjectName))
m_output << m_indent << indent << varName
- << "->setObjectName(" << writeString(varName, m_dindent) << ");\n";
+ << "->setObjectName(QString::fromUtf8(" << fixString(varName, m_dindent) << "));\n";
int leftMargin, topMargin, rightMargin, bottomMargin;
leftMargin = topMargin = rightMargin = bottomMargin = -1;
bool frameShadowEncountered = false;
- for (int i=0; i<lst.size(); ++i) {
- const DomProperty *p = lst.at(i);
+ for (const DomProperty *p : lst) {
if (!checkProperty(m_option.inputFile, p))
continue;
QString propertyName = p->attributeName();
@@ -1187,30 +1164,35 @@ void WriteInitialization::writeProperties(const QString &varName,
const DomRect *r = p->elementRect();
m_output << m_indent << varName << "->resize(" << r->elementWidth() << ", " << r->elementHeight() << ");\n";
continue;
- } else if (propertyName == QLatin1String("currentRow") // QListWidget::currentRow
- && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) {
+ }
+ if (propertyName == QLatin1String("currentRow") // QListWidget::currentRow
+ && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) {
m_delayedOut << m_indent << varName << "->setCurrentRow("
<< p->elementNumber() << ");\n";
continue;
- } else if (propertyName == QLatin1String("currentIndex") // set currentIndex later
- && (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))
- || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget"))
- || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTabWidget"))
- || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox")))) {
+ }
+ if (propertyName == QLatin1String("currentIndex") // set currentIndex later
+ && (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))
+ || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget"))
+ || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTabWidget"))
+ || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox")))) {
m_delayedOut << m_indent << varName << "->setCurrentIndex("
<< p->elementNumber() << ");\n";
continue;
- } else if (propertyName == QLatin1String("tabSpacing")
- && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox"))) {
+ }
+ if (propertyName == QLatin1String("tabSpacing")
+ && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox"))) {
m_delayedOut << m_indent << varName << "->layout()->setSpacing("
<< p->elementNumber() << ");\n";
continue;
- } else if (propertyName == QLatin1String("control") // ActiveQt support
- && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QAxWidget"))) {
+ }
+ if (propertyName == QLatin1String("control") // ActiveQt support
+ && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QAxWidget"))) {
// already done ;)
continue;
- } else if (propertyName == QLatin1String("default")
- && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QPushButton"))) {
+ }
+ if (propertyName == QLatin1String("default")
+ && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QPushButton"))) {
// QTBUG-44406: Setting of QPushButton::default needs to be delayed until the parent is set
delayProperty = true;
} else if (propertyName == QLatin1String("database")
@@ -1467,8 +1449,8 @@ void WriteInitialization::writeProperties(const QString &varName,
case DomProperty::Url: {
const DomUrl* u = p->elementUrl();
- propertyValue = QString::fromLatin1("QUrl(%1)")
- .arg(writeString(u->elementString()->text(), m_dindent));
+ propertyValue = QString::fromLatin1("QUrl(QString::fromUtf8(%1))")
+ .arg(fixString(u->elementString()->text(), m_dindent));
break;
}
case DomProperty::Brush:
@@ -1572,8 +1554,8 @@ QString WriteInitialization::writeFontProperties(const DomFont *f)
m_output << m_indent << "QFont " << fontName << ";\n";
if (f->hasElementFamily() && !f->elementFamily().isEmpty()) {
- m_output << m_indent << fontName << ".setFamily(" << writeString(f->elementFamily(), m_dindent)
- << ");\n";
+ m_output << m_indent << fontName << ".setFamily(QString::fromUtf8("
+ << fixString(f->elementFamily(), m_dindent) << "));\n";
}
if (f->hasElementPointSize() && f->elementPointSize() > 0) {
m_output << m_indent << fontName << ".setPointSize(" << f->elementPointSize()
@@ -1616,27 +1598,98 @@ QString WriteInitialization::writeFontProperties(const DomFont *f)
}
// Post 4.4 write resource icon
-void WriteInitialization::writeResourceIcon(QTextStream &output,
- const QString &iconName,
- const QString &indent,
- const DomResourceIcon *i) const
-{
- if (i->hasElementNormalOff())
- output << indent << iconName << ".addFile(" << writeString(i->elementNormalOff()->text(), indent) << ", QSize(), QIcon::Normal, QIcon::Off);\n";
- if (i->hasElementNormalOn())
- output << indent << iconName << ".addFile(" << writeString(i->elementNormalOn()->text(), indent) << ", QSize(), QIcon::Normal, QIcon::On);\n";
- if (i->hasElementDisabledOff())
- output << indent << iconName << ".addFile(" << writeString(i->elementDisabledOff()->text(), indent) << ", QSize(), QIcon::Disabled, QIcon::Off);\n";
- if (i->hasElementDisabledOn())
- output << indent << iconName << ".addFile(" << writeString(i->elementDisabledOn()->text(), indent) << ", QSize(), QIcon::Disabled, QIcon::On);\n";
- if (i->hasElementActiveOff())
- output << indent << iconName << ".addFile(" << writeString(i->elementActiveOff()->text(), indent) << ", QSize(), QIcon::Active, QIcon::Off);\n";
- if (i->hasElementActiveOn())
- output << indent << iconName << ".addFile(" << writeString(i->elementActiveOn()->text(), indent) << ", QSize(), QIcon::Active, QIcon::On);\n";
- if (i->hasElementSelectedOff())
- output << indent << iconName << ".addFile(" << writeString(i->elementSelectedOff()->text(), indent) << ", QSize(), QIcon::Selected, QIcon::Off);\n";
- if (i->hasElementSelectedOn())
- output << indent << iconName << ".addFile(" << writeString(i->elementSelectedOn()->text(), indent) << ", QSize(), QIcon::Selected, QIcon::On);\n";
+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";
+ }
+}
+
+void WriteInitialization::writePixmapFunctionIcon(QTextStream &output,
+ const QString &iconName,
+ const QString &indent,
+ const DomResourceIcon *i) const
+{
+ if (i->hasElementNormalOff()) {
+ output << indent << iconName << ".addPixmap("
+ << pixCall(QLatin1String("QPixmap"), i->elementNormalOff()->text())
+ << ", QIcon::Normal, QIcon::Off);\n";
+ }
+ if (i->hasElementNormalOn()) {
+ output << indent << iconName << ".addPixmap("
+ << pixCall(QLatin1String("QPixmap"), i->elementNormalOn()->text())
+ << ", QIcon::Normal, QIcon::On);\n";
+ }
+ if (i->hasElementDisabledOff()) {
+ output << indent << iconName << ".addPixmap("
+ << pixCall(QLatin1String("QPixmap"), i->elementDisabledOff()->text())
+ << ", QIcon::Disabled, QIcon::Off);\n";
+ }
+ if (i->hasElementDisabledOn()) {
+ output << indent << iconName << ".addPixmap("
+ << pixCall(QLatin1String("QPixmap"), i->elementDisabledOn()->text())
+ << ", QIcon::Disabled, QIcon::On);\n";
+ }
+ if (i->hasElementActiveOff()) {
+ output << indent << iconName << ".addPixmap("
+ << pixCall(QLatin1String("QPixmap"), i->elementActiveOff()->text())
+ << ", QIcon::Active, QIcon::Off);\n";
+ }
+ if (i->hasElementActiveOn()) {
+ output << indent << iconName << ".addPixmap("
+ << pixCall(QLatin1String("QPixmap"), i->elementActiveOn()->text())
+ << ", QIcon::Active, QIcon::On);\n";
+ }
+ if (i->hasElementSelectedOff()) {
+ output << indent << iconName << ".addPixmap("
+ << pixCall(QLatin1String("QPixmap"), i->elementSelectedOff()->text())
+ << ", QIcon::Selected, QIcon::Off);\n";
+ }
+ if (i->hasElementSelectedOn()) {
+ output << indent << iconName << ".addPixmap("
+ << pixCall(QLatin1String("QPixmap"), i->elementSelectedOn()->text())
+ << ", QIcon::Selected, QIcon::On);\n";
+ }
}
QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
@@ -1655,10 +1708,13 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
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);
+ if (m_uic->pixmapFunction().isEmpty())
+ writeResourceIcon(m_output, iconName, m_indent, i);
+ else
+ writePixmapFunctionIcon(m_output, iconName, m_indent, i);
} else {
// Theme: Generate code to check the theme and default to resource
- const QString themeIconName = writeString(i->attributeTheme(), QString());
+ 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
@@ -1670,20 +1726,23 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
m_output << "QString ";
m_firstThemeIcon = false;
}
- m_output << themeNameStringVariableC << " = "
- << themeIconName << ";\n";
+ 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);
+ if (m_uic->pixmapFunction().isEmpty())
+ writeResourceIcon(m_output, iconName, m_dindent, i);
+ else
+ writePixmapFunctionIcon(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("
- << themeIconName << "));\n";
+ << "(QIcon::fromTheme(QString::fromUtf8("
+ << themeIconName << ")));\n";
} // Theme, but not state
} // >= 4.4
} else { // pre-4.4 legacy
@@ -1841,7 +1900,7 @@ void WriteInitialization::acceptTabStops(DomTabStops *tabStops)
const QStringList l = tabStops->elementTabStop();
for (int i=0; i<l.size(); ++i) {
- const QString name = l.at(i);
+ const QString &name = l.at(i);
if (!m_registeredWidgets.contains(name)) {
fprintf(stderr, "%s: Warning: Tab-stop assignment: '%s' is not a valid widget.\n",
@@ -1853,9 +1912,9 @@ void WriteInitialization::acceptTabStops(DomTabStops *tabStops)
if (i == 0) {
lastName = name;
continue;
- } else if (name.isEmpty() || lastName.isEmpty()) {
- continue;
}
+ if (name.isEmpty() || lastName.isEmpty())
+ continue;
m_output << m_indent << "QWidget::setTabOrder(" << lastName << ", " << name << ");\n";
@@ -2125,7 +2184,7 @@ void WriteInitialization::initializeTreeWidget(DomWidget *w)
if (!itemName.isNull())
m_output << m_indent << varName << "->setHeaderItem(" << itemName << ");\n";
- if (w->elementItem().size() == 0)
+ if (w->elementItem().empty())
return;
QString tempName = disableSorting(w, varName);
@@ -2167,9 +2226,8 @@ QList<WriteInitialization::Item *> WriteInitialization::initializeTreeWidgetItem
int col = -1;
const DomPropertyList properties = domItem->elementProperty();
- for (int j = 0; j < properties.size(); ++j) {
- DomProperty *p = properties.at(j);
- if (p->attributeName() == QLatin1String("text")) {
+ for (DomProperty *p : properties) {
+ if (p->attributeName() == QLatin1String("text")) {
if (!map.isEmpty()) {
addCommonInitializers(item, map, col);
map.clear();
@@ -2196,7 +2254,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
// columns
const auto &columns = w->elementColumn();
- if (columns.size() != 0) {
+ if (!columns.empty()) {
m_output << m_indent << "if (" << varName << "->columnCount() < " << columns.size() << ")\n"
<< m_dindent << varName << "->setColumnCount(" << columns.size() << ");\n";
}
@@ -2218,7 +2276,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
// rows
const auto &rows = w->elementRow();
- if (rows.size() != 0) {
+ if (!rows.isEmpty()) {
m_output << m_indent << "if (" << varName << "->rowCount() < " << rows.size() << ")\n"
<< m_dindent << varName << "->setRowCount(" << rows.size() << ");\n";
}
@@ -2242,8 +2300,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
const auto &items = w->elementItem();
- for (int i = 0; i < items.size(); ++i) {
- const DomItem *cell = items.at(i);
+ for (const DomItem *cell : items) {
if (cell->hasAttributeRow() && cell->hasAttributeColumn() && !cell->elementProperty().isEmpty()) {
const int r = cell->attributeRow();
const int c = cell->attributeColumn();
@@ -2323,7 +2380,10 @@ QString WriteInitialization::noTrCall(DomString *str, const QString &defaultStri
return QString();
if (str)
value = str->text();
- return writeString(value, m_dindent);
+ QString ret = QLatin1String("QString::fromUtf8(");
+ ret += fixString(value, m_dindent);
+ ret += QLatin1Char(')');
+ return ret;
}
QString WriteInitialization::autoTrCall(DomString *str, const QString &defaultString) const
@@ -2448,13 +2508,13 @@ QString WriteInitialization::Item::writeSetupUi(const QString &parent, Item::Emp
return QString();
bool generateMultiDirective = false;
- if (emptyItemPolicy == Item::ConstructItemOnly && m_children.size() == 0) {
+ if (emptyItemPolicy == Item::ConstructItemOnly && m_children.isEmpty()) {
if (m_setupUiData.policy == ItemData::DontGenerate) {
m_setupUiStream << m_indent << "new " << m_itemClassName << '(' << parent << ");\n";
- return QString();
- } else if (m_setupUiData.policy == ItemData::GenerateWithMultiDirective) {
- generateMultiDirective = true;
+ return QString();
}
+ if (m_setupUiData.policy == ItemData::GenerateWithMultiDirective)
+ generateMultiDirective = true;
}
if (generateMultiDirective)
diff --git a/src/tools/uic/cpp/cppwriteinitialization.h b/src/tools/uic/cpp/cppwriteinitialization.h
index 21116057d4..cce83bd677 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.h
+++ b/src/tools/uic/cpp/cppwriteinitialization.h
@@ -139,8 +139,6 @@ struct WriteInitialization : public TreeWalker
private:
static QString domColor2QString(const DomColor *c);
- QString writeString(const QString &s, const QString &indent) const;
-
QString iconCall(const DomProperty *prop);
QString pixCall(const DomProperty *prop) const;
QString pixCall(const QString &type, const QString &text) const;
@@ -163,6 +161,7 @@ private:
// special initialization
//
class Item {
+ Q_DISABLE_COPY(Item)
public:
Item(const QString &itemClassName, const QString &indent, QTextStream &setupUiStream, QTextStream &retranslateUiStream, Driver *driver);
~Item();
@@ -178,15 +177,15 @@ private:
int setupUiCount() const { return m_setupUiData.setters.count(); }
int retranslateUiCount() const { return m_retranslateUiData.setters.count(); }
private:
- struct ItemData {
- ItemData() : policy(DontGenerate) {}
+ struct ItemData
+ {
QMultiMap<QString, QString> setters; // directive to setter
QSet<QString> directives;
enum TemporaryVariableGeneratorPolicy { // policies with priority, number describes the priority
DontGenerate = 1,
GenerateWithMultiDirective = 2,
Generate = 3
- } policy;
+ } policy = DontGenerate;
};
ItemData m_setupUiData;
ItemData m_retranslateUiData;
@@ -230,8 +229,9 @@ private:
private:
QString writeFontProperties(const DomFont *f);
- void writeResourceIcon(QTextStream &output, const QString &iconName, const QString &indent, const DomResourceIcon *i) const;
QString writeIconProperties(const DomResourceIcon *i);
+ void writePixmapFunctionIcon(QTextStream &output, const QString &iconName,
+ const QString &indent, const DomResourceIcon *i) const;
QString writeSizePolicy(const DomSizePolicy *sp);
QString writeBrushInitialization(const DomBrush *brush);
void addButtonGroup(const DomWidget *node, const QString &varName);
diff --git a/src/tools/uic/customwidgetsinfo.cpp b/src/tools/uic/customwidgetsinfo.cpp
index 6883b715ae..0ac0c2b6a3 100644
--- a/src/tools/uic/customwidgetsinfo.cpp
+++ b/src/tools/uic/customwidgetsinfo.cpp
@@ -33,9 +33,7 @@
QT_BEGIN_NAMESPACE
-CustomWidgetsInfo::CustomWidgetsInfo()
-{
-}
+CustomWidgetsInfo::CustomWidgetsInfo() = default;
void CustomWidgetsInfo::acceptUI(DomUI *node)
{
diff --git a/src/tools/uic/driver.cpp b/src/tools/uic/driver.cpp
index 72be667468..6b3a6f8f69 100644
--- a/src/tools/uic/driver.cpp
+++ b/src/tools/uic/driver.cpp
@@ -41,9 +41,7 @@ Driver::Driver()
m_output = &m_stdout;
}
-Driver::~Driver()
-{
-}
+Driver::~Driver() = default;
QString Driver::findOrInsertWidget(DomWidget *ui_widget)
{
diff --git a/src/tools/uic/driver.h b/src/tools/uic/driver.h
index 41c1572860..1563bdbd83 100644
--- a/src/tools/uic/driver.h
+++ b/src/tools/uic/driver.h
@@ -49,6 +49,7 @@ class DomButtonGroup;
class Driver
{
+ Q_DISABLE_COPY(Driver)
public:
Driver();
virtual ~Driver();
diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp
index 46a1e66bcc..0e30bac28e 100644
--- a/src/tools/uic/main.cpp
+++ b/src/tools/uic/main.cpp
@@ -76,7 +76,7 @@ int runUic(int argc, char *argv[])
parser.addOption(noImplicitIncludesOption);
QCommandLineOption noStringLiteralOption(QStringList() << QStringLiteral("s") << QStringLiteral("no-stringliteral"));
- noStringLiteralOption.setDescription(QStringLiteral("Use QLatin1String instead of QStringLiteral in generated code."));
+ noStringLiteralOption.setDescription(QStringLiteral("Deprecated. The use of this option won't take any effect."));
parser.addOption(noStringLiteralOption);
QCommandLineOption postfixOption(QStringLiteral("postfix"));
@@ -111,13 +111,15 @@ int runUic(int argc, char *argv[])
driver.option().outputFile = parser.value(outputOption);
driver.option().headerProtection = !parser.isSet(noProtOption);
driver.option().implicitIncludes = !parser.isSet(noImplicitIncludesOption);
- driver.option().stringLiteral = !parser.isSet(noStringLiteralOption);
driver.option().idBased = parser.isSet(idBasedOption);
driver.option().postfix = parser.value(postfixOption);
driver.option().translateFunction = parser.value(translateOption);
driver.option().includeFile = parser.value(includeOption);
driver.option().generator = (parser.value(generatorOption).toLower() == QLatin1String("java")) ? Option::JavaGenerator : Option::CppGenerator;
+ if (parser.isSet(noStringLiteralOption))
+ fprintf(stderr, "The -s, --no-stringliteral option is deprecated and it won't take any effect.\n");
+
QString inputFile;
if (!parser.positionalArguments().isEmpty())
inputFile = parser.positionalArguments().at(0);
diff --git a/src/tools/uic/option.h b/src/tools/uic/option.h
index c7278393fb..a5b14abc5f 100644
--- a/src/tools/uic/option.h
+++ b/src/tools/uic/option.h
@@ -51,7 +51,6 @@ struct Option
unsigned int limitXPM_LineLength : 1;
unsigned int implicitIncludes: 1;
unsigned int idBased: 1;
- unsigned int stringLiteral: 1;
Generator generator;
QString inputFile;
@@ -77,7 +76,6 @@ struct Option
limitXPM_LineLength(0),
implicitIncludes(1),
idBased(0),
- stringLiteral(1),
generator(CppGenerator),
prefix(QLatin1String("Ui_"))
{ indent.fill(QLatin1Char(' '), 4); }
diff --git a/src/tools/uic/treewalker.h b/src/tools/uic/treewalker.h
index 78da17d628..43d4633d83 100644
--- a/src/tools/uic/treewalker.h
+++ b/src/tools/uic/treewalker.h
@@ -77,7 +77,7 @@ class DomButtonGroup;
struct TreeWalker
{
- inline virtual ~TreeWalker() {}
+ inline virtual ~TreeWalker() = default;
virtual void acceptUI(DomUI *ui);
virtual void acceptLayoutDefault(DomLayoutDefault *layoutDefault);
diff --git a/src/tools/uic/ui4.cpp b/src/tools/uic/ui4.cpp
index 7a1d755bb4..984ef36274 100644
--- a/src/tools/uic/ui4.cpp
+++ b/src/tools/uic/ui4.cpp
@@ -108,19 +108,19 @@ void DomUI::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("widget"), Qt::CaseInsensitive)) {
- DomWidget *v = new DomWidget();
+ auto *v = new DomWidget();
v->read(reader);
setElementWidget(v);
continue;
}
if (!tag.compare(QLatin1String("layoutdefault"), Qt::CaseInsensitive)) {
- DomLayoutDefault *v = new DomLayoutDefault();
+ auto *v = new DomLayoutDefault();
v->read(reader);
setElementLayoutDefault(v);
continue;
}
if (!tag.compare(QLatin1String("layoutfunction"), Qt::CaseInsensitive)) {
- DomLayoutFunction *v = new DomLayoutFunction();
+ auto *v = new DomLayoutFunction();
v->read(reader);
setElementLayoutFunction(v);
continue;
@@ -130,13 +130,13 @@ void DomUI::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("customwidgets"), Qt::CaseInsensitive)) {
- DomCustomWidgets *v = new DomCustomWidgets();
+ auto *v = new DomCustomWidgets();
v->read(reader);
setElementCustomWidgets(v);
continue;
}
if (!tag.compare(QLatin1String("tabstops"), Qt::CaseInsensitive)) {
- DomTabStops *v = new DomTabStops();
+ auto *v = new DomTabStops();
v->read(reader);
setElementTabStops(v);
continue;
@@ -147,37 +147,37 @@ void DomUI::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("includes"), Qt::CaseInsensitive)) {
- DomIncludes *v = new DomIncludes();
+ auto *v = new DomIncludes();
v->read(reader);
setElementIncludes(v);
continue;
}
if (!tag.compare(QLatin1String("resources"), Qt::CaseInsensitive)) {
- DomResources *v = new DomResources();
+ auto *v = new DomResources();
v->read(reader);
setElementResources(v);
continue;
}
if (!tag.compare(QLatin1String("connections"), Qt::CaseInsensitive)) {
- DomConnections *v = new DomConnections();
+ auto *v = new DomConnections();
v->read(reader);
setElementConnections(v);
continue;
}
if (!tag.compare(QLatin1String("designerdata"), Qt::CaseInsensitive)) {
- DomDesignerData *v = new DomDesignerData();
+ auto *v = new DomDesignerData();
v->read(reader);
setElementDesignerdata(v);
continue;
}
if (!tag.compare(QLatin1String("slots"), Qt::CaseInsensitive)) {
- DomSlots *v = new DomSlots();
+ auto *v = new DomSlots();
v->read(reader);
setElementSlots(v);
continue;
}
if (!tag.compare(QLatin1String("buttongroups"), Qt::CaseInsensitive)) {
- DomButtonGroups *v = new DomButtonGroups();
+ auto *v = new DomButtonGroups();
v->read(reader);
setElementButtonGroups(v);
continue;
@@ -293,7 +293,7 @@ void DomUI::setElementClass(const QString &a)
DomWidget *DomUI::takeElementWidget()
{
DomWidget *a = m_widget;
- m_widget = 0;
+ m_widget = nullptr;
m_children ^= Widget;
return a;
}
@@ -308,7 +308,7 @@ void DomUI::setElementWidget(DomWidget *a)
DomLayoutDefault *DomUI::takeElementLayoutDefault()
{
DomLayoutDefault *a = m_layoutDefault;
- m_layoutDefault = 0;
+ m_layoutDefault = nullptr;
m_children ^= LayoutDefault;
return a;
}
@@ -323,7 +323,7 @@ void DomUI::setElementLayoutDefault(DomLayoutDefault *a)
DomLayoutFunction *DomUI::takeElementLayoutFunction()
{
DomLayoutFunction *a = m_layoutFunction;
- m_layoutFunction = 0;
+ m_layoutFunction = nullptr;
m_children ^= LayoutFunction;
return a;
}
@@ -344,7 +344,7 @@ void DomUI::setElementPixmapFunction(const QString &a)
DomCustomWidgets *DomUI::takeElementCustomWidgets()
{
DomCustomWidgets *a = m_customWidgets;
- m_customWidgets = 0;
+ m_customWidgets = nullptr;
m_children ^= CustomWidgets;
return a;
}
@@ -359,7 +359,7 @@ void DomUI::setElementCustomWidgets(DomCustomWidgets *a)
DomTabStops *DomUI::takeElementTabStops()
{
DomTabStops *a = m_tabStops;
- m_tabStops = 0;
+ m_tabStops = nullptr;
m_children ^= TabStops;
return a;
}
@@ -374,7 +374,7 @@ void DomUI::setElementTabStops(DomTabStops *a)
DomIncludes *DomUI::takeElementIncludes()
{
DomIncludes *a = m_includes;
- m_includes = 0;
+ m_includes = nullptr;
m_children ^= Includes;
return a;
}
@@ -389,7 +389,7 @@ void DomUI::setElementIncludes(DomIncludes *a)
DomResources *DomUI::takeElementResources()
{
DomResources *a = m_resources;
- m_resources = 0;
+ m_resources = nullptr;
m_children ^= Resources;
return a;
}
@@ -404,7 +404,7 @@ void DomUI::setElementResources(DomResources *a)
DomConnections *DomUI::takeElementConnections()
{
DomConnections *a = m_connections;
- m_connections = 0;
+ m_connections = nullptr;
m_children ^= Connections;
return a;
}
@@ -419,7 +419,7 @@ void DomUI::setElementConnections(DomConnections *a)
DomDesignerData *DomUI::takeElementDesignerdata()
{
DomDesignerData *a = m_designerdata;
- m_designerdata = 0;
+ m_designerdata = nullptr;
m_children ^= Designerdata;
return a;
}
@@ -434,7 +434,7 @@ void DomUI::setElementDesignerdata(DomDesignerData *a)
DomSlots *DomUI::takeElementSlots()
{
DomSlots *a = m_slots;
- m_slots = 0;
+ m_slots = nullptr;
m_children ^= Slots;
return a;
}
@@ -449,7 +449,7 @@ void DomUI::setElementSlots(DomSlots *a)
DomButtonGroups *DomUI::takeElementButtonGroups()
{
DomButtonGroups *a = m_buttonGroups;
- m_buttonGroups = 0;
+ m_buttonGroups = nullptr;
m_children ^= ButtonGroups;
return a;
}
@@ -484,21 +484,21 @@ void DomUI::clearElementClass()
void DomUI::clearElementWidget()
{
delete m_widget;
- m_widget = 0;
+ m_widget = nullptr;
m_children &= ~Widget;
}
void DomUI::clearElementLayoutDefault()
{
delete m_layoutDefault;
- m_layoutDefault = 0;
+ m_layoutDefault = nullptr;
m_children &= ~LayoutDefault;
}
void DomUI::clearElementLayoutFunction()
{
delete m_layoutFunction;
- m_layoutFunction = 0;
+ m_layoutFunction = nullptr;
m_children &= ~LayoutFunction;
}
@@ -510,56 +510,56 @@ void DomUI::clearElementPixmapFunction()
void DomUI::clearElementCustomWidgets()
{
delete m_customWidgets;
- m_customWidgets = 0;
+ m_customWidgets = nullptr;
m_children &= ~CustomWidgets;
}
void DomUI::clearElementTabStops()
{
delete m_tabStops;
- m_tabStops = 0;
+ m_tabStops = nullptr;
m_children &= ~TabStops;
}
void DomUI::clearElementIncludes()
{
delete m_includes;
- m_includes = 0;
+ m_includes = nullptr;
m_children &= ~Includes;
}
void DomUI::clearElementResources()
{
delete m_resources;
- m_resources = 0;
+ m_resources = nullptr;
m_children &= ~Resources;
}
void DomUI::clearElementConnections()
{
delete m_connections;
- m_connections = 0;
+ m_connections = nullptr;
m_children &= ~Connections;
}
void DomUI::clearElementDesignerdata()
{
delete m_designerdata;
- m_designerdata = 0;
+ m_designerdata = nullptr;
m_children &= ~Designerdata;
}
void DomUI::clearElementSlots()
{
delete m_slots;
- m_slots = 0;
+ m_slots = nullptr;
m_children &= ~Slots;
}
void DomUI::clearElementButtonGroups()
{
delete m_buttonGroups;
- m_buttonGroups = 0;
+ m_buttonGroups = nullptr;
m_children &= ~ButtonGroups;
}
@@ -576,7 +576,7 @@ void DomIncludes::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("include"), Qt::CaseInsensitive)) {
- DomInclude *v = new DomInclude();
+ auto *v = new DomInclude();
v->read(reader);
m_include.append(v);
continue;
@@ -608,9 +608,7 @@ void DomIncludes::setElementInclude(const QVector<DomInclude *> &a)
m_include = a;
}
-DomInclude::~DomInclude()
-{
-}
+DomInclude::~DomInclude() = default;
void DomInclude::read(QXmlStreamReader &reader)
{
@@ -686,7 +684,7 @@ void DomResources::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("include"), Qt::CaseInsensitive)) {
- DomResource *v = new DomResource();
+ auto *v = new DomResource();
v->read(reader);
m_include.append(v);
continue;
@@ -721,9 +719,7 @@ void DomResources::setElementInclude(const QVector<DomResource *> &a)
m_include = a;
}
-DomResource::~DomResource()
-{
-}
+DomResource::~DomResource() = default;
void DomResource::read(QXmlStreamReader &reader)
{
@@ -791,25 +787,25 @@ void DomActionGroup::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("action"), Qt::CaseInsensitive)) {
- DomAction *v = new DomAction();
+ auto *v = new DomAction();
v->read(reader);
m_action.append(v);
continue;
}
if (!tag.compare(QLatin1String("actiongroup"), Qt::CaseInsensitive)) {
- DomActionGroup *v = new DomActionGroup();
+ auto *v = new DomActionGroup();
v->read(reader);
m_actionGroup.append(v);
continue;
}
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
}
if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_attribute.append(v);
continue;
@@ -900,13 +896,13 @@ void DomAction::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
}
if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_attribute.append(v);
continue;
@@ -953,9 +949,7 @@ void DomAction::setElementAttribute(const QList<DomProperty *> &a)
m_attribute = a;
}
-DomActionRef::~DomActionRef()
-{
-}
+DomActionRef::~DomActionRef() = default;
void DomActionRef::read(QXmlStreamReader &reader)
{
@@ -1019,13 +1013,13 @@ void DomButtonGroup::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
}
if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_attribute.append(v);
continue;
@@ -1082,7 +1076,7 @@ void DomButtonGroups::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("buttongroup"), Qt::CaseInsensitive)) {
- DomButtonGroup *v = new DomButtonGroup();
+ auto *v = new DomButtonGroup();
v->read(reader);
m_buttonGroup.append(v);
continue;
@@ -1127,7 +1121,7 @@ void DomCustomWidgets::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("customwidget"), Qt::CaseInsensitive)) {
- DomCustomWidget *v = new DomCustomWidget();
+ auto *v = new DomCustomWidget();
v->read(reader);
m_customWidget.append(v);
continue;
@@ -1159,9 +1153,7 @@ void DomCustomWidgets::setElementCustomWidget(const QVector<DomCustomWidget *> &
m_customWidget = a;
}
-DomHeader::~DomHeader()
-{
-}
+DomHeader::~DomHeader() = default;
void DomHeader::read(QXmlStreamReader &reader)
{
@@ -1230,13 +1222,13 @@ void DomCustomWidget::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("header"), Qt::CaseInsensitive)) {
- DomHeader *v = new DomHeader();
+ auto *v = new DomHeader();
v->read(reader);
setElementHeader(v);
continue;
}
if (!tag.compare(QLatin1String("sizehint"), Qt::CaseInsensitive)) {
- DomSize *v = new DomSize();
+ auto *v = new DomSize();
v->read(reader);
setElementSizeHint(v);
continue;
@@ -1269,13 +1261,13 @@ void DomCustomWidget::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("slots"), Qt::CaseInsensitive)) {
- DomSlots *v = new DomSlots();
+ auto *v = new DomSlots();
v->read(reader);
setElementSlots(v);
continue;
}
if (!tag.compare(QLatin1String("propertyspecifications"), Qt::CaseInsensitive)) {
- DomPropertySpecifications *v = new DomPropertySpecifications();
+ auto *v = new DomPropertySpecifications();
v->read(reader);
setElementPropertyspecifications(v);
continue;
@@ -1340,7 +1332,7 @@ void DomCustomWidget::setElementExtends(const QString &a)
DomHeader *DomCustomWidget::takeElementHeader()
{
DomHeader *a = m_header;
- m_header = 0;
+ m_header = nullptr;
m_children ^= Header;
return a;
}
@@ -1355,7 +1347,7 @@ void DomCustomWidget::setElementHeader(DomHeader *a)
DomSize *DomCustomWidget::takeElementSizeHint()
{
DomSize *a = m_sizeHint;
- m_sizeHint = 0;
+ m_sizeHint = nullptr;
m_children ^= SizeHint;
return a;
}
@@ -1388,7 +1380,7 @@ void DomCustomWidget::setElementPixmap(const QString &a)
DomSlots *DomCustomWidget::takeElementSlots()
{
DomSlots *a = m_slots;
- m_slots = 0;
+ m_slots = nullptr;
m_children ^= Slots;
return a;
}
@@ -1403,7 +1395,7 @@ void DomCustomWidget::setElementSlots(DomSlots *a)
DomPropertySpecifications *DomCustomWidget::takeElementPropertyspecifications()
{
DomPropertySpecifications *a = m_propertyspecifications;
- m_propertyspecifications = 0;
+ m_propertyspecifications = nullptr;
m_children ^= Propertyspecifications;
return a;
}
@@ -1428,14 +1420,14 @@ void DomCustomWidget::clearElementExtends()
void DomCustomWidget::clearElementHeader()
{
delete m_header;
- m_header = 0;
+ m_header = nullptr;
m_children &= ~Header;
}
void DomCustomWidget::clearElementSizeHint()
{
delete m_sizeHint;
- m_sizeHint = 0;
+ m_sizeHint = nullptr;
m_children &= ~SizeHint;
}
@@ -1457,20 +1449,18 @@ void DomCustomWidget::clearElementPixmap()
void DomCustomWidget::clearElementSlots()
{
delete m_slots;
- m_slots = 0;
+ m_slots = nullptr;
m_children &= ~Slots;
}
void DomCustomWidget::clearElementPropertyspecifications()
{
delete m_propertyspecifications;
- m_propertyspecifications = 0;
+ m_propertyspecifications = nullptr;
m_children &= ~Propertyspecifications;
}
-DomLayoutDefault::~DomLayoutDefault()
-{
-}
+DomLayoutDefault::~DomLayoutDefault() = default;
void DomLayoutDefault::read(QXmlStreamReader &reader)
{
@@ -1516,9 +1506,7 @@ void DomLayoutDefault::write(QXmlStreamWriter &writer, const QString &tagName) c
writer.writeEndElement();
}
-DomLayoutFunction::~DomLayoutFunction()
-{
-}
+DomLayoutFunction::~DomLayoutFunction() = default;
void DomLayoutFunction::read(QXmlStreamReader &reader)
{
@@ -1657,19 +1645,19 @@ void DomLayout::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
}
if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_attribute.append(v);
continue;
}
if (!tag.compare(QLatin1String("item"), Qt::CaseInsensitive)) {
- DomLayoutItem *v = new DomLayoutItem();
+ auto *v = new DomLayoutItem();
v->read(reader);
m_item.append(v);
continue;
@@ -1793,19 +1781,19 @@ void DomLayoutItem::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("widget"), Qt::CaseInsensitive)) {
- DomWidget *v = new DomWidget();
+ auto *v = new DomWidget();
v->read(reader);
setElementWidget(v);
continue;
}
if (!tag.compare(QLatin1String("layout"), Qt::CaseInsensitive)) {
- DomLayout *v = new DomLayout();
+ auto *v = new DomLayout();
v->read(reader);
setElementLayout(v);
continue;
}
if (!tag.compare(QLatin1String("spacer"), Qt::CaseInsensitive)) {
- DomSpacer *v = new DomSpacer();
+ auto *v = new DomSpacer();
v->read(reader);
setElementSpacer(v);
continue;
@@ -1841,24 +1829,21 @@ void DomLayoutItem::write(QXmlStreamWriter &writer, const QString &tagName) cons
writer.writeAttribute(QStringLiteral("alignment"), attributeAlignment());
switch (kind()) {
- case Widget: {
- DomWidget *v = elementWidget();
- if (v != 0)
- v->write(writer, QStringLiteral("widget"));
+ case Widget:
+ if (m_widget != nullptr)
+ m_widget->write(writer, QStringLiteral("widget"));
break;
- }
- case Layout: {
- DomLayout *v = elementLayout();
- if (v != 0)
- v->write(writer, QStringLiteral("layout"));
+
+ case Layout:
+ if (m_layout != nullptr)
+ m_layout->write(writer, QStringLiteral("layout"));
break;
- }
- case Spacer: {
- DomSpacer *v = elementSpacer();
- if (v != 0)
- v->write(writer, QStringLiteral("spacer"));
+
+ case Spacer:
+ if (m_spacer != nullptr)
+ m_spacer->write(writer, QStringLiteral("spacer"));
break;
- }
+
default:
break;
}
@@ -1868,7 +1853,7 @@ void DomLayoutItem::write(QXmlStreamWriter &writer, const QString &tagName) cons
DomWidget *DomLayoutItem::takeElementWidget()
{
DomWidget *a = m_widget;
- m_widget = 0;
+ m_widget = nullptr;
return a;
}
@@ -1882,7 +1867,7 @@ void DomLayoutItem::setElementWidget(DomWidget *a)
DomLayout *DomLayoutItem::takeElementLayout()
{
DomLayout *a = m_layout;
- m_layout = 0;
+ m_layout = nullptr;
return a;
}
@@ -1896,7 +1881,7 @@ void DomLayoutItem::setElementLayout(DomLayout *a)
DomSpacer *DomLayoutItem::takeElementSpacer()
{
DomSpacer *a = m_spacer;
- m_spacer = 0;
+ m_spacer = nullptr;
return a;
}
@@ -1920,7 +1905,7 @@ void DomRow::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
@@ -1965,7 +1950,7 @@ void DomColumn::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
@@ -2026,13 +2011,13 @@ void DomItem::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
}
if (!tag.compare(QLatin1String("item"), Qt::CaseInsensitive)) {
- DomItem *v = new DomItem();
+ auto *v = new DomItem();
v->read(reader);
m_item.append(v);
continue;
@@ -2134,7 +2119,7 @@ void DomWidget::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
@@ -2150,55 +2135,55 @@ void DomWidget::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("attribute"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_attribute.append(v);
continue;
}
if (!tag.compare(QLatin1String("row"), Qt::CaseInsensitive)) {
- DomRow *v = new DomRow();
+ auto *v = new DomRow();
v->read(reader);
m_row.append(v);
continue;
}
if (!tag.compare(QLatin1String("column"), Qt::CaseInsensitive)) {
- DomColumn *v = new DomColumn();
+ auto *v = new DomColumn();
v->read(reader);
m_column.append(v);
continue;
}
if (!tag.compare(QLatin1String("item"), Qt::CaseInsensitive)) {
- DomItem *v = new DomItem();
+ auto *v = new DomItem();
v->read(reader);
m_item.append(v);
continue;
}
if (!tag.compare(QLatin1String("layout"), Qt::CaseInsensitive)) {
- DomLayout *v = new DomLayout();
+ auto *v = new DomLayout();
v->read(reader);
m_layout.append(v);
continue;
}
if (!tag.compare(QLatin1String("widget"), Qt::CaseInsensitive)) {
- DomWidget *v = new DomWidget();
+ auto *v = new DomWidget();
v->read(reader);
m_widget.append(v);
continue;
}
if (!tag.compare(QLatin1String("action"), Qt::CaseInsensitive)) {
- DomAction *v = new DomAction();
+ auto *v = new DomAction();
v->read(reader);
m_action.append(v);
continue;
}
if (!tag.compare(QLatin1String("actiongroup"), Qt::CaseInsensitive)) {
- DomActionGroup *v = new DomActionGroup();
+ auto *v = new DomActionGroup();
v->read(reader);
m_actionGroup.append(v);
continue;
}
if (!tag.compare(QLatin1String("addaction"), Qt::CaseInsensitive)) {
- DomActionRef *v = new DomActionRef();
+ auto *v = new DomActionRef();
v->read(reader);
m_addAction.append(v);
continue;
@@ -2365,7 +2350,7 @@ void DomSpacer::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
@@ -2400,9 +2385,7 @@ void DomSpacer::setElementProperty(const QList<DomProperty *> &a)
m_property = a;
}
-DomColor::~DomColor()
-{
-}
+DomColor::~DomColor() = default;
void DomColor::read(QXmlStreamReader &reader)
{
@@ -2517,7 +2500,7 @@ void DomGradientStop::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
- DomColor *v = new DomColor();
+ auto *v = new DomColor();
v->read(reader);
setElementColor(v);
continue;
@@ -2549,7 +2532,7 @@ void DomGradientStop::write(QXmlStreamWriter &writer, const QString &tagName) co
DomColor *DomGradientStop::takeElementColor()
{
DomColor *a = m_color;
- m_color = 0;
+ m_color = nullptr;
m_children ^= Color;
return a;
}
@@ -2564,7 +2547,7 @@ void DomGradientStop::setElementColor(DomColor *a)
void DomGradientStop::clearElementColor()
{
delete m_color;
- m_color = 0;
+ m_color = nullptr;
m_children &= ~Color;
}
@@ -2639,7 +2622,7 @@ void DomGradient::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("gradientstop"), Qt::CaseInsensitive)) {
- DomGradientStop *v = new DomGradientStop();
+ auto *v = new DomGradientStop();
v->read(reader);
m_gradientStop.append(v);
continue;
@@ -2747,19 +2730,19 @@ void DomBrush::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
- DomColor *v = new DomColor();
+ auto *v = new DomColor();
v->read(reader);
setElementColor(v);
continue;
}
if (!tag.compare(QLatin1String("texture"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
setElementTexture(v);
continue;
}
if (!tag.compare(QLatin1String("gradient"), Qt::CaseInsensitive)) {
- DomGradient *v = new DomGradient();
+ auto *v = new DomGradient();
v->read(reader);
setElementGradient(v);
continue;
@@ -2783,24 +2766,21 @@ void DomBrush::write(QXmlStreamWriter &writer, const QString &tagName) const
writer.writeAttribute(QStringLiteral("brushstyle"), attributeBrushStyle());
switch (kind()) {
- case Color: {
- DomColor *v = elementColor();
- if (v != 0)
- v->write(writer, QStringLiteral("color"));
+ case Color:
+ if (m_color != nullptr)
+ m_color->write(writer, QStringLiteral("color"));
break;
- }
- case Texture: {
- DomProperty *v = elementTexture();
- if (v != 0)
- v->write(writer, QStringLiteral("texture"));
+
+ case Texture:
+ if (m_texture != nullptr)
+ m_texture->write(writer, QStringLiteral("texture"));
break;
- }
- case Gradient: {
- DomGradient *v = elementGradient();
- if (v != 0)
- v->write(writer, QStringLiteral("gradient"));
+
+ case Gradient:
+ if (m_gradient != nullptr)
+ m_gradient->write(writer, QStringLiteral("gradient"));
break;
- }
+
default:
break;
}
@@ -2810,7 +2790,7 @@ void DomBrush::write(QXmlStreamWriter &writer, const QString &tagName) const
DomColor *DomBrush::takeElementColor()
{
DomColor *a = m_color;
- m_color = 0;
+ m_color = nullptr;
return a;
}
@@ -2824,7 +2804,7 @@ void DomBrush::setElementColor(DomColor *a)
DomProperty *DomBrush::takeElementTexture()
{
DomProperty *a = m_texture;
- m_texture = 0;
+ m_texture = nullptr;
return a;
}
@@ -2838,7 +2818,7 @@ void DomBrush::setElementTexture(DomProperty *a)
DomGradient *DomBrush::takeElementGradient()
{
DomGradient *a = m_gradient;
- m_gradient = 0;
+ m_gradient = nullptr;
return a;
}
@@ -2871,7 +2851,7 @@ void DomColorRole::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("brush"), Qt::CaseInsensitive)) {
- DomBrush *v = new DomBrush();
+ auto *v = new DomBrush();
v->read(reader);
setElementBrush(v);
continue;
@@ -2903,7 +2883,7 @@ void DomColorRole::write(QXmlStreamWriter &writer, const QString &tagName) const
DomBrush *DomColorRole::takeElementBrush()
{
DomBrush *a = m_brush;
- m_brush = 0;
+ m_brush = nullptr;
m_children ^= Brush;
return a;
}
@@ -2918,7 +2898,7 @@ void DomColorRole::setElementBrush(DomBrush *a)
void DomColorRole::clearElementBrush()
{
delete m_brush;
- m_brush = 0;
+ m_brush = nullptr;
m_children &= ~Brush;
}
@@ -2937,13 +2917,13 @@ void DomColorGroup::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("colorrole"), Qt::CaseInsensitive)) {
- DomColorRole *v = new DomColorRole();
+ auto *v = new DomColorRole();
v->read(reader);
m_colorRole.append(v);
continue;
}
if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
- DomColor *v = new DomColor();
+ auto *v = new DomColor();
v->read(reader);
m_color.append(v);
continue;
@@ -2998,19 +2978,19 @@ void DomPalette::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("active"), Qt::CaseInsensitive)) {
- DomColorGroup *v = new DomColorGroup();
+ auto *v = new DomColorGroup();
v->read(reader);
setElementActive(v);
continue;
}
if (!tag.compare(QLatin1String("inactive"), Qt::CaseInsensitive)) {
- DomColorGroup *v = new DomColorGroup();
+ auto *v = new DomColorGroup();
v->read(reader);
setElementInactive(v);
continue;
}
if (!tag.compare(QLatin1String("disabled"), Qt::CaseInsensitive)) {
- DomColorGroup *v = new DomColorGroup();
+ auto *v = new DomColorGroup();
v->read(reader);
setElementDisabled(v);
continue;
@@ -3045,7 +3025,7 @@ void DomPalette::write(QXmlStreamWriter &writer, const QString &tagName) const
DomColorGroup *DomPalette::takeElementActive()
{
DomColorGroup *a = m_active;
- m_active = 0;
+ m_active = nullptr;
m_children ^= Active;
return a;
}
@@ -3060,7 +3040,7 @@ void DomPalette::setElementActive(DomColorGroup *a)
DomColorGroup *DomPalette::takeElementInactive()
{
DomColorGroup *a = m_inactive;
- m_inactive = 0;
+ m_inactive = nullptr;
m_children ^= Inactive;
return a;
}
@@ -3075,7 +3055,7 @@ void DomPalette::setElementInactive(DomColorGroup *a)
DomColorGroup *DomPalette::takeElementDisabled()
{
DomColorGroup *a = m_disabled;
- m_disabled = 0;
+ m_disabled = nullptr;
m_children ^= Disabled;
return a;
}
@@ -3090,27 +3070,25 @@ void DomPalette::setElementDisabled(DomColorGroup *a)
void DomPalette::clearElementActive()
{
delete m_active;
- m_active = 0;
+ m_active = nullptr;
m_children &= ~Active;
}
void DomPalette::clearElementInactive()
{
delete m_inactive;
- m_inactive = 0;
+ m_inactive = nullptr;
m_children &= ~Inactive;
}
void DomPalette::clearElementDisabled()
{
delete m_disabled;
- m_disabled = 0;
+ m_disabled = nullptr;
m_children &= ~Disabled;
}
-DomFont::~DomFont()
-{
-}
+DomFont::~DomFont() = default;
void DomFont::read(QXmlStreamReader &reader)
{
@@ -3316,9 +3294,7 @@ void DomFont::clearElementKerning()
m_children &= ~Kerning;
}
-DomPoint::~DomPoint()
-{
-}
+DomPoint::~DomPoint() = default;
void DomPoint::read(QXmlStreamReader &reader)
{
@@ -3380,9 +3356,7 @@ void DomPoint::clearElementY()
m_children &= ~Y;
}
-DomRect::~DomRect()
-{
-}
+DomRect::~DomRect() = default;
void DomRect::read(QXmlStreamReader &reader)
{
@@ -3480,9 +3454,7 @@ void DomRect::clearElementHeight()
m_children &= ~Height;
}
-DomLocale::~DomLocale()
-{
-}
+DomLocale::~DomLocale() = default;
void DomLocale::read(QXmlStreamReader &reader)
{
@@ -3528,9 +3500,7 @@ void DomLocale::write(QXmlStreamWriter &writer, const QString &tagName) const
writer.writeEndElement();
}
-DomSizePolicy::~DomSizePolicy()
-{
-}
+DomSizePolicy::~DomSizePolicy() = default;
void DomSizePolicy::read(QXmlStreamReader &reader)
{
@@ -3648,9 +3618,7 @@ void DomSizePolicy::clearElementVerStretch()
m_children &= ~VerStretch;
}
-DomSize::~DomSize()
-{
-}
+DomSize::~DomSize() = default;
void DomSize::read(QXmlStreamReader &reader)
{
@@ -3712,9 +3680,7 @@ void DomSize::clearElementHeight()
m_children &= ~Height;
}
-DomDate::~DomDate()
-{
-}
+DomDate::~DomDate() = default;
void DomDate::read(QXmlStreamReader &reader)
{
@@ -3794,9 +3760,7 @@ void DomDate::clearElementDay()
m_children &= ~Day;
}
-DomTime::~DomTime()
-{
-}
+DomTime::~DomTime() = default;
void DomTime::read(QXmlStreamReader &reader)
{
@@ -3876,9 +3840,7 @@ void DomTime::clearElementSecond()
m_children &= ~Second;
}
-DomDateTime::~DomDateTime()
-{
-}
+DomDateTime::~DomDateTime() = default;
void DomDateTime::read(QXmlStreamReader &reader)
{
@@ -4088,9 +4050,7 @@ void DomStringList::setElementString(const QStringList &a)
m_string = a;
}
-DomResourcePixmap::~DomResourcePixmap()
-{
-}
+DomResourcePixmap::~DomResourcePixmap() = default;
void DomResourcePixmap::read(QXmlStreamReader &reader)
{
@@ -4176,49 +4136,49 @@ void DomResourceIcon::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("normaloff"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementNormalOff(v);
continue;
}
if (!tag.compare(QLatin1String("normalon"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementNormalOn(v);
continue;
}
if (!tag.compare(QLatin1String("disabledoff"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementDisabledOff(v);
continue;
}
if (!tag.compare(QLatin1String("disabledon"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementDisabledOn(v);
continue;
}
if (!tag.compare(QLatin1String("activeoff"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementActiveOff(v);
continue;
}
if (!tag.compare(QLatin1String("activeon"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementActiveOn(v);
continue;
}
if (!tag.compare(QLatin1String("selectedoff"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementSelectedOff(v);
continue;
}
if (!tag.compare(QLatin1String("selectedon"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementSelectedOn(v);
continue;
@@ -4281,7 +4241,7 @@ void DomResourceIcon::write(QXmlStreamWriter &writer, const QString &tagName) co
DomResourcePixmap *DomResourceIcon::takeElementNormalOff()
{
DomResourcePixmap *a = m_normalOff;
- m_normalOff = 0;
+ m_normalOff = nullptr;
m_children ^= NormalOff;
return a;
}
@@ -4296,7 +4256,7 @@ void DomResourceIcon::setElementNormalOff(DomResourcePixmap *a)
DomResourcePixmap *DomResourceIcon::takeElementNormalOn()
{
DomResourcePixmap *a = m_normalOn;
- m_normalOn = 0;
+ m_normalOn = nullptr;
m_children ^= NormalOn;
return a;
}
@@ -4311,7 +4271,7 @@ void DomResourceIcon::setElementNormalOn(DomResourcePixmap *a)
DomResourcePixmap *DomResourceIcon::takeElementDisabledOff()
{
DomResourcePixmap *a = m_disabledOff;
- m_disabledOff = 0;
+ m_disabledOff = nullptr;
m_children ^= DisabledOff;
return a;
}
@@ -4326,7 +4286,7 @@ void DomResourceIcon::setElementDisabledOff(DomResourcePixmap *a)
DomResourcePixmap *DomResourceIcon::takeElementDisabledOn()
{
DomResourcePixmap *a = m_disabledOn;
- m_disabledOn = 0;
+ m_disabledOn = nullptr;
m_children ^= DisabledOn;
return a;
}
@@ -4341,7 +4301,7 @@ void DomResourceIcon::setElementDisabledOn(DomResourcePixmap *a)
DomResourcePixmap *DomResourceIcon::takeElementActiveOff()
{
DomResourcePixmap *a = m_activeOff;
- m_activeOff = 0;
+ m_activeOff = nullptr;
m_children ^= ActiveOff;
return a;
}
@@ -4356,7 +4316,7 @@ void DomResourceIcon::setElementActiveOff(DomResourcePixmap *a)
DomResourcePixmap *DomResourceIcon::takeElementActiveOn()
{
DomResourcePixmap *a = m_activeOn;
- m_activeOn = 0;
+ m_activeOn = nullptr;
m_children ^= ActiveOn;
return a;
}
@@ -4371,7 +4331,7 @@ void DomResourceIcon::setElementActiveOn(DomResourcePixmap *a)
DomResourcePixmap *DomResourceIcon::takeElementSelectedOff()
{
DomResourcePixmap *a = m_selectedOff;
- m_selectedOff = 0;
+ m_selectedOff = nullptr;
m_children ^= SelectedOff;
return a;
}
@@ -4386,7 +4346,7 @@ void DomResourceIcon::setElementSelectedOff(DomResourcePixmap *a)
DomResourcePixmap *DomResourceIcon::takeElementSelectedOn()
{
DomResourcePixmap *a = m_selectedOn;
- m_selectedOn = 0;
+ m_selectedOn = nullptr;
m_children ^= SelectedOn;
return a;
}
@@ -4401,62 +4361,60 @@ void DomResourceIcon::setElementSelectedOn(DomResourcePixmap *a)
void DomResourceIcon::clearElementNormalOff()
{
delete m_normalOff;
- m_normalOff = 0;
+ m_normalOff = nullptr;
m_children &= ~NormalOff;
}
void DomResourceIcon::clearElementNormalOn()
{
delete m_normalOn;
- m_normalOn = 0;
+ m_normalOn = nullptr;
m_children &= ~NormalOn;
}
void DomResourceIcon::clearElementDisabledOff()
{
delete m_disabledOff;
- m_disabledOff = 0;
+ m_disabledOff = nullptr;
m_children &= ~DisabledOff;
}
void DomResourceIcon::clearElementDisabledOn()
{
delete m_disabledOn;
- m_disabledOn = 0;
+ m_disabledOn = nullptr;
m_children &= ~DisabledOn;
}
void DomResourceIcon::clearElementActiveOff()
{
delete m_activeOff;
- m_activeOff = 0;
+ m_activeOff = nullptr;
m_children &= ~ActiveOff;
}
void DomResourceIcon::clearElementActiveOn()
{
delete m_activeOn;
- m_activeOn = 0;
+ m_activeOn = nullptr;
m_children &= ~ActiveOn;
}
void DomResourceIcon::clearElementSelectedOff()
{
delete m_selectedOff;
- m_selectedOff = 0;
+ m_selectedOff = nullptr;
m_children &= ~SelectedOff;
}
void DomResourceIcon::clearElementSelectedOn()
{
delete m_selectedOn;
- m_selectedOn = 0;
+ m_selectedOn = nullptr;
m_children &= ~SelectedOn;
}
-DomString::~DomString()
-{
-}
+DomString::~DomString() = default;
void DomString::read(QXmlStreamReader &reader)
{
@@ -4523,9 +4481,7 @@ void DomString::write(QXmlStreamWriter &writer, const QString &tagName) const
writer.writeEndElement();
}
-DomPointF::~DomPointF()
-{
-}
+DomPointF::~DomPointF() = default;
void DomPointF::read(QXmlStreamReader &reader)
{
@@ -4587,9 +4543,7 @@ void DomPointF::clearElementY()
m_children &= ~Y;
}
-DomRectF::~DomRectF()
-{
-}
+DomRectF::~DomRectF() = default;
void DomRectF::read(QXmlStreamReader &reader)
{
@@ -4687,9 +4641,7 @@ void DomRectF::clearElementHeight()
m_children &= ~Height;
}
-DomSizeF::~DomSizeF()
-{
-}
+DomSizeF::~DomSizeF() = default;
void DomSizeF::read(QXmlStreamReader &reader)
{
@@ -4751,9 +4703,7 @@ void DomSizeF::clearElementHeight()
m_children &= ~Height;
}
-DomChar::~DomChar()
-{
-}
+DomChar::~DomChar() = default;
void DomChar::read(QXmlStreamReader &reader)
{
@@ -4809,7 +4759,7 @@ void DomUrl::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
- DomString *v = new DomString();
+ auto *v = new DomString();
v->read(reader);
setElementString(v);
continue;
@@ -4838,7 +4788,7 @@ void DomUrl::write(QXmlStreamWriter &writer, const QString &tagName) const
DomString *DomUrl::takeElementString()
{
DomString *a = m_string;
- m_string = 0;
+ m_string = nullptr;
m_children ^= String;
return a;
}
@@ -4853,7 +4803,7 @@ void DomUrl::setElementString(DomString *a)
void DomUrl::clearElementString()
{
delete m_string;
- m_string = 0;
+ m_string = nullptr;
m_children &= ~String;
}
@@ -4963,7 +4913,7 @@ void DomProperty::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("color"), Qt::CaseInsensitive)) {
- DomColor *v = new DomColor();
+ auto *v = new DomColor();
v->read(reader);
setElementColor(v);
continue;
@@ -4985,37 +4935,37 @@ void DomProperty::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("font"), Qt::CaseInsensitive)) {
- DomFont *v = new DomFont();
+ auto *v = new DomFont();
v->read(reader);
setElementFont(v);
continue;
}
if (!tag.compare(QLatin1String("iconset"), Qt::CaseInsensitive)) {
- DomResourceIcon *v = new DomResourceIcon();
+ auto *v = new DomResourceIcon();
v->read(reader);
setElementIconSet(v);
continue;
}
if (!tag.compare(QLatin1String("pixmap"), Qt::CaseInsensitive)) {
- DomResourcePixmap *v = new DomResourcePixmap();
+ auto *v = new DomResourcePixmap();
v->read(reader);
setElementPixmap(v);
continue;
}
if (!tag.compare(QLatin1String("palette"), Qt::CaseInsensitive)) {
- DomPalette *v = new DomPalette();
+ auto *v = new DomPalette();
v->read(reader);
setElementPalette(v);
continue;
}
if (!tag.compare(QLatin1String("point"), Qt::CaseInsensitive)) {
- DomPoint *v = new DomPoint();
+ auto *v = new DomPoint();
v->read(reader);
setElementPoint(v);
continue;
}
if (!tag.compare(QLatin1String("rect"), Qt::CaseInsensitive)) {
- DomRect *v = new DomRect();
+ auto *v = new DomRect();
v->read(reader);
setElementRect(v);
continue;
@@ -5025,31 +4975,31 @@ void DomProperty::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("locale"), Qt::CaseInsensitive)) {
- DomLocale *v = new DomLocale();
+ auto *v = new DomLocale();
v->read(reader);
setElementLocale(v);
continue;
}
if (!tag.compare(QLatin1String("sizepolicy"), Qt::CaseInsensitive)) {
- DomSizePolicy *v = new DomSizePolicy();
+ auto *v = new DomSizePolicy();
v->read(reader);
setElementSizePolicy(v);
continue;
}
if (!tag.compare(QLatin1String("size"), Qt::CaseInsensitive)) {
- DomSize *v = new DomSize();
+ auto *v = new DomSize();
v->read(reader);
setElementSize(v);
continue;
}
if (!tag.compare(QLatin1String("string"), Qt::CaseInsensitive)) {
- DomString *v = new DomString();
+ auto *v = new DomString();
v->read(reader);
setElementString(v);
continue;
}
if (!tag.compare(QLatin1String("stringlist"), Qt::CaseInsensitive)) {
- DomStringList *v = new DomStringList();
+ auto *v = new DomStringList();
v->read(reader);
setElementStringList(v);
continue;
@@ -5067,37 +5017,37 @@ void DomProperty::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("date"), Qt::CaseInsensitive)) {
- DomDate *v = new DomDate();
+ auto *v = new DomDate();
v->read(reader);
setElementDate(v);
continue;
}
if (!tag.compare(QLatin1String("time"), Qt::CaseInsensitive)) {
- DomTime *v = new DomTime();
+ auto *v = new DomTime();
v->read(reader);
setElementTime(v);
continue;
}
if (!tag.compare(QLatin1String("datetime"), Qt::CaseInsensitive)) {
- DomDateTime *v = new DomDateTime();
+ auto *v = new DomDateTime();
v->read(reader);
setElementDateTime(v);
continue;
}
if (!tag.compare(QLatin1String("pointf"), Qt::CaseInsensitive)) {
- DomPointF *v = new DomPointF();
+ auto *v = new DomPointF();
v->read(reader);
setElementPointF(v);
continue;
}
if (!tag.compare(QLatin1String("rectf"), Qt::CaseInsensitive)) {
- DomRectF *v = new DomRectF();
+ auto *v = new DomRectF();
v->read(reader);
setElementRectF(v);
continue;
}
if (!tag.compare(QLatin1String("sizef"), Qt::CaseInsensitive)) {
- DomSizeF *v = new DomSizeF();
+ auto *v = new DomSizeF();
v->read(reader);
setElementSizeF(v);
continue;
@@ -5107,13 +5057,13 @@ void DomProperty::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("char"), Qt::CaseInsensitive)) {
- DomChar *v = new DomChar();
+ auto *v = new DomChar();
v->read(reader);
setElementChar(v);
continue;
}
if (!tag.compare(QLatin1String("url"), Qt::CaseInsensitive)) {
- DomUrl *v = new DomUrl();
+ auto *v = new DomUrl();
v->read(reader);
setElementUrl(v);
continue;
@@ -5127,7 +5077,7 @@ void DomProperty::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("brush"), Qt::CaseInsensitive)) {
- DomBrush *v = new DomBrush();
+ auto *v = new DomBrush();
v->read(reader);
setElementBrush(v);
continue;
@@ -5154,180 +5104,159 @@ void DomProperty::write(QXmlStreamWriter &writer, const QString &tagName) const
writer.writeAttribute(QStringLiteral("stdset"), QString::number(attributeStdset()));
switch (kind()) {
- case Bool: {
+ case Bool:
writer.writeTextElement(QStringLiteral("bool"), elementBool());
break;
- }
- case Color: {
- DomColor *v = elementColor();
- if (v != 0)
- v->write(writer, QStringLiteral("color"));
+
+ case Color:
+ if (m_color != nullptr)
+ m_color->write(writer, QStringLiteral("color"));
break;
- }
- case Cstring: {
+
+ case Cstring:
writer.writeTextElement(QStringLiteral("cstring"), elementCstring());
break;
- }
- case Cursor: {
+
+ case Cursor:
writer.writeTextElement(QStringLiteral("cursor"), QString::number(elementCursor()));
break;
- }
- case CursorShape: {
+
+ case CursorShape:
writer.writeTextElement(QStringLiteral("cursorShape"), elementCursorShape());
break;
- }
- case Enum: {
+
+ case Enum:
writer.writeTextElement(QStringLiteral("enum"), elementEnum());
break;
- }
- case Font: {
- DomFont *v = elementFont();
- if (v != 0)
- v->write(writer, QStringLiteral("font"));
+
+ case Font:
+ if (m_font != nullptr)
+ m_font->write(writer, QStringLiteral("font"));
break;
- }
- case IconSet: {
- DomResourceIcon *v = elementIconSet();
- if (v != 0)
- v->write(writer, QStringLiteral("iconset"));
+
+ case IconSet:
+ if (m_iconSet != nullptr)
+ m_iconSet->write(writer, QStringLiteral("iconset"));
break;
- }
- case Pixmap: {
- DomResourcePixmap *v = elementPixmap();
- if (v != 0)
- v->write(writer, QStringLiteral("pixmap"));
+
+ case Pixmap:
+ if (m_pixmap != nullptr)
+ m_pixmap->write(writer, QStringLiteral("pixmap"));
break;
- }
- case Palette: {
- DomPalette *v = elementPalette();
- if (v != 0)
- v->write(writer, QStringLiteral("palette"));
+
+ case Palette:
+ if (m_palette != nullptr)
+ m_palette->write(writer, QStringLiteral("palette"));
break;
- }
- case Point: {
- DomPoint *v = elementPoint();
- if (v != 0)
- v->write(writer, QStringLiteral("point"));
+
+ case Point:
+ if (m_point != nullptr)
+ m_point->write(writer, QStringLiteral("point"));
break;
- }
- case Rect: {
- DomRect *v = elementRect();
- if (v != 0)
- v->write(writer, QStringLiteral("rect"));
+
+ case Rect:
+ if (m_rect != nullptr)
+ m_rect->write(writer, QStringLiteral("rect"));
break;
- }
- case Set: {
+
+ case Set:
writer.writeTextElement(QStringLiteral("set"), elementSet());
break;
- }
- case Locale: {
- DomLocale *v = elementLocale();
- if (v != 0)
- v->write(writer, QStringLiteral("locale"));
+
+ case Locale:
+ if (m_locale != nullptr)
+ m_locale->write(writer, QStringLiteral("locale"));
break;
- }
- case SizePolicy: {
- DomSizePolicy *v = elementSizePolicy();
- if (v != 0)
- v->write(writer, QStringLiteral("sizepolicy"));
+
+ case SizePolicy:
+ if (m_sizePolicy != nullptr)
+ m_sizePolicy->write(writer, QStringLiteral("sizepolicy"));
break;
- }
- case Size: {
- DomSize *v = elementSize();
- if (v != 0)
- v->write(writer, QStringLiteral("size"));
+
+ case Size:
+ if (m_size != nullptr)
+ m_size->write(writer, QStringLiteral("size"));
break;
- }
- case String: {
- DomString *v = elementString();
- if (v != 0)
- v->write(writer, QStringLiteral("string"));
+
+ case String:
+ if (m_string != nullptr)
+ m_string->write(writer, QStringLiteral("string"));
break;
- }
- case StringList: {
- DomStringList *v = elementStringList();
- if (v != 0)
- v->write(writer, QStringLiteral("stringlist"));
+
+ case StringList:
+ if (m_stringList != nullptr)
+ m_stringList->write(writer, QStringLiteral("stringlist"));
break;
- }
- case Number: {
+
+ case Number:
writer.writeTextElement(QStringLiteral("number"), QString::number(elementNumber()));
break;
- }
- case Float: {
+
+ case Float:
writer.writeTextElement(QStringLiteral("float"), QString::number(elementFloat(), 'f', 8));
break;
- }
- case Double: {
+
+ case Double:
writer.writeTextElement(QStringLiteral("double"), QString::number(elementDouble(), 'f', 15));
break;
- }
- case Date: {
- DomDate *v = elementDate();
- if (v != 0)
- v->write(writer, QStringLiteral("date"));
+
+ case Date:
+ if (m_date != nullptr)
+ m_date->write(writer, QStringLiteral("date"));
break;
- }
- case Time: {
- DomTime *v = elementTime();
- if (v != 0)
- v->write(writer, QStringLiteral("time"));
+
+ case Time:
+ if (m_time != nullptr)
+ m_time->write(writer, QStringLiteral("time"));
break;
- }
- case DateTime: {
- DomDateTime *v = elementDateTime();
- if (v != 0)
- v->write(writer, QStringLiteral("datetime"));
+
+ case DateTime:
+ if (m_dateTime != nullptr)
+ m_dateTime->write(writer, QStringLiteral("datetime"));
break;
- }
- case PointF: {
- DomPointF *v = elementPointF();
- if (v != 0)
- v->write(writer, QStringLiteral("pointf"));
+
+ case PointF:
+ if (m_pointF != nullptr)
+ m_pointF->write(writer, QStringLiteral("pointf"));
break;
- }
- case RectF: {
- DomRectF *v = elementRectF();
- if (v != 0)
- v->write(writer, QStringLiteral("rectf"));
+
+ case RectF:
+ if (m_rectF != nullptr)
+ m_rectF->write(writer, QStringLiteral("rectf"));
break;
- }
- case SizeF: {
- DomSizeF *v = elementSizeF();
- if (v != 0)
- v->write(writer, QStringLiteral("sizef"));
+
+ case SizeF:
+ if (m_sizeF != nullptr)
+ m_sizeF->write(writer, QStringLiteral("sizef"));
break;
- }
- case LongLong: {
+
+ case LongLong:
writer.writeTextElement(QStringLiteral("longLong"), QString::number(elementLongLong()));
break;
- }
- case Char: {
- DomChar *v = elementChar();
- if (v != 0)
- v->write(writer, QStringLiteral("char"));
+
+ case Char:
+ if (m_char != nullptr)
+ m_char->write(writer, QStringLiteral("char"));
break;
- }
- case Url: {
- DomUrl *v = elementUrl();
- if (v != 0)
- v->write(writer, QStringLiteral("url"));
+
+ case Url:
+ if (m_url != nullptr)
+ m_url->write(writer, QStringLiteral("url"));
break;
- }
- case UInt: {
+
+ case UInt:
writer.writeTextElement(QStringLiteral("UInt"), QString::number(elementUInt()));
break;
- }
- case ULongLong: {
+
+ case ULongLong:
writer.writeTextElement(QStringLiteral("uLongLong"), QString::number(elementULongLong()));
break;
- }
- case Brush: {
- DomBrush *v = elementBrush();
- if (v != 0)
- v->write(writer, QStringLiteral("brush"));
+
+ case Brush:
+ if (m_brush != nullptr)
+ m_brush->write(writer, QStringLiteral("brush"));
break;
- }
+
default:
break;
}
@@ -5344,7 +5273,7 @@ void DomProperty::setElementBool(const QString &a)
DomColor *DomProperty::takeElementColor()
{
DomColor *a = m_color;
- m_color = 0;
+ m_color = nullptr;
return a;
}
@@ -5386,7 +5315,7 @@ void DomProperty::setElementEnum(const QString &a)
DomFont *DomProperty::takeElementFont()
{
DomFont *a = m_font;
- m_font = 0;
+ m_font = nullptr;
return a;
}
@@ -5400,7 +5329,7 @@ void DomProperty::setElementFont(DomFont *a)
DomResourceIcon *DomProperty::takeElementIconSet()
{
DomResourceIcon *a = m_iconSet;
- m_iconSet = 0;
+ m_iconSet = nullptr;
return a;
}
@@ -5414,7 +5343,7 @@ void DomProperty::setElementIconSet(DomResourceIcon *a)
DomResourcePixmap *DomProperty::takeElementPixmap()
{
DomResourcePixmap *a = m_pixmap;
- m_pixmap = 0;
+ m_pixmap = nullptr;
return a;
}
@@ -5428,7 +5357,7 @@ void DomProperty::setElementPixmap(DomResourcePixmap *a)
DomPalette *DomProperty::takeElementPalette()
{
DomPalette *a = m_palette;
- m_palette = 0;
+ m_palette = nullptr;
return a;
}
@@ -5442,7 +5371,7 @@ void DomProperty::setElementPalette(DomPalette *a)
DomPoint *DomProperty::takeElementPoint()
{
DomPoint *a = m_point;
- m_point = 0;
+ m_point = nullptr;
return a;
}
@@ -5456,7 +5385,7 @@ void DomProperty::setElementPoint(DomPoint *a)
DomRect *DomProperty::takeElementRect()
{
DomRect *a = m_rect;
- m_rect = 0;
+ m_rect = nullptr;
return a;
}
@@ -5477,7 +5406,7 @@ void DomProperty::setElementSet(const QString &a)
DomLocale *DomProperty::takeElementLocale()
{
DomLocale *a = m_locale;
- m_locale = 0;
+ m_locale = nullptr;
return a;
}
@@ -5491,7 +5420,7 @@ void DomProperty::setElementLocale(DomLocale *a)
DomSizePolicy *DomProperty::takeElementSizePolicy()
{
DomSizePolicy *a = m_sizePolicy;
- m_sizePolicy = 0;
+ m_sizePolicy = nullptr;
return a;
}
@@ -5505,7 +5434,7 @@ void DomProperty::setElementSizePolicy(DomSizePolicy *a)
DomSize *DomProperty::takeElementSize()
{
DomSize *a = m_size;
- m_size = 0;
+ m_size = nullptr;
return a;
}
@@ -5519,7 +5448,7 @@ void DomProperty::setElementSize(DomSize *a)
DomString *DomProperty::takeElementString()
{
DomString *a = m_string;
- m_string = 0;
+ m_string = nullptr;
return a;
}
@@ -5533,7 +5462,7 @@ void DomProperty::setElementString(DomString *a)
DomStringList *DomProperty::takeElementStringList()
{
DomStringList *a = m_stringList;
- m_stringList = 0;
+ m_stringList = nullptr;
return a;
}
@@ -5568,7 +5497,7 @@ void DomProperty::setElementDouble(double a)
DomDate *DomProperty::takeElementDate()
{
DomDate *a = m_date;
- m_date = 0;
+ m_date = nullptr;
return a;
}
@@ -5582,7 +5511,7 @@ void DomProperty::setElementDate(DomDate *a)
DomTime *DomProperty::takeElementTime()
{
DomTime *a = m_time;
- m_time = 0;
+ m_time = nullptr;
return a;
}
@@ -5596,7 +5525,7 @@ void DomProperty::setElementTime(DomTime *a)
DomDateTime *DomProperty::takeElementDateTime()
{
DomDateTime *a = m_dateTime;
- m_dateTime = 0;
+ m_dateTime = nullptr;
return a;
}
@@ -5610,7 +5539,7 @@ void DomProperty::setElementDateTime(DomDateTime *a)
DomPointF *DomProperty::takeElementPointF()
{
DomPointF *a = m_pointF;
- m_pointF = 0;
+ m_pointF = nullptr;
return a;
}
@@ -5624,7 +5553,7 @@ void DomProperty::setElementPointF(DomPointF *a)
DomRectF *DomProperty::takeElementRectF()
{
DomRectF *a = m_rectF;
- m_rectF = 0;
+ m_rectF = nullptr;
return a;
}
@@ -5638,7 +5567,7 @@ void DomProperty::setElementRectF(DomRectF *a)
DomSizeF *DomProperty::takeElementSizeF()
{
DomSizeF *a = m_sizeF;
- m_sizeF = 0;
+ m_sizeF = nullptr;
return a;
}
@@ -5659,7 +5588,7 @@ void DomProperty::setElementLongLong(qlonglong a)
DomChar *DomProperty::takeElementChar()
{
DomChar *a = m_char;
- m_char = 0;
+ m_char = nullptr;
return a;
}
@@ -5673,7 +5602,7 @@ void DomProperty::setElementChar(DomChar *a)
DomUrl *DomProperty::takeElementUrl()
{
DomUrl *a = m_url;
- m_url = 0;
+ m_url = nullptr;
return a;
}
@@ -5701,7 +5630,7 @@ void DomProperty::setElementULongLong(qulonglong a)
DomBrush *DomProperty::takeElementBrush()
{
DomBrush *a = m_brush;
- m_brush = 0;
+ m_brush = nullptr;
return a;
}
@@ -5725,7 +5654,7 @@ void DomConnections::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("connection"), Qt::CaseInsensitive)) {
- DomConnection *v = new DomConnection();
+ auto *v = new DomConnection();
v->read(reader);
m_connection.append(v);
continue;
@@ -5785,7 +5714,7 @@ void DomConnection::read(QXmlStreamReader &reader)
continue;
}
if (!tag.compare(QLatin1String("hints"), Qt::CaseInsensitive)) {
- DomConnectionHints *v = new DomConnectionHints();
+ auto *v = new DomConnectionHints();
v->read(reader);
setElementHints(v);
continue;
@@ -5850,7 +5779,7 @@ void DomConnection::setElementSlot(const QString &a)
DomConnectionHints *DomConnection::takeElementHints()
{
DomConnectionHints *a = m_hints;
- m_hints = 0;
+ m_hints = nullptr;
m_children ^= Hints;
return a;
}
@@ -5885,7 +5814,7 @@ void DomConnection::clearElementSlot()
void DomConnection::clearElementHints()
{
delete m_hints;
- m_hints = 0;
+ m_hints = nullptr;
m_children &= ~Hints;
}
@@ -5902,7 +5831,7 @@ void DomConnectionHints::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("hint"), Qt::CaseInsensitive)) {
- DomConnectionHint *v = new DomConnectionHint();
+ auto *v = new DomConnectionHint();
v->read(reader);
m_hint.append(v);
continue;
@@ -5934,9 +5863,7 @@ void DomConnectionHints::setElementHint(const QVector<DomConnectionHint *> &a)
m_hint = a;
}
-DomConnectionHint::~DomConnectionHint()
-{
-}
+DomConnectionHint::~DomConnectionHint() = default;
void DomConnectionHint::read(QXmlStreamReader &reader)
{
@@ -6024,7 +5951,7 @@ void DomDesignerData::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("property"), Qt::CaseInsensitive)) {
- DomProperty *v = new DomProperty();
+ auto *v = new DomProperty();
v->read(reader);
m_property.append(v);
continue;
@@ -6127,13 +6054,13 @@ void DomPropertySpecifications::read(QXmlStreamReader &reader)
case QXmlStreamReader::StartElement : {
const QStringRef tag = reader.name();
if (!tag.compare(QLatin1String("tooltip"), Qt::CaseInsensitive)) {
- DomPropertyToolTip *v = new DomPropertyToolTip();
+ auto *v = new DomPropertyToolTip();
v->read(reader);
m_tooltip.append(v);
continue;
}
if (!tag.compare(QLatin1String("stringpropertyspecification"), Qt::CaseInsensitive)) {
- DomStringPropertySpecification *v = new DomStringPropertySpecification();
+ auto *v = new DomStringPropertySpecification();
v->read(reader);
m_stringpropertyspecification.append(v);
continue;
@@ -6174,9 +6101,7 @@ void DomPropertySpecifications::setElementStringpropertyspecification(const QVec
m_stringpropertyspecification = a;
}
-DomPropertyToolTip::~DomPropertyToolTip()
-{
-}
+DomPropertyToolTip::~DomPropertyToolTip() = default;
void DomPropertyToolTip::read(QXmlStreamReader &reader)
{
@@ -6215,9 +6140,7 @@ void DomPropertyToolTip::write(QXmlStreamWriter &writer, const QString &tagName)
writer.writeEndElement();
}
-DomStringPropertySpecification::~DomStringPropertySpecification()
-{
-}
+DomStringPropertySpecification::~DomStringPropertySpecification() = default;
void DomStringPropertySpecification::read(QXmlStreamReader &reader)
{
diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp
index 8e4709c831..957a50b1d5 100644
--- a/src/tools/uic/uic.cpp
+++ b/src/tools/uic/uic.cpp
@@ -56,9 +56,7 @@ Uic::Uic(Driver *d)
{
}
-Uic::~Uic()
-{
-}
+Uic::~Uic() = default;
bool Uic::printDependencies()
{
diff --git a/src/tools/uic/uic.h b/src/tools/uic/uic.h
index e00dc595bc..1c229bc516 100644
--- a/src/tools/uic/uic.h
+++ b/src/tools/uic/uic.h
@@ -53,6 +53,7 @@ struct Option;
class Uic
{
+ Q_DISABLE_COPY(Uic)
public:
Uic(Driver *driver);
~Uic();
diff --git a/src/tools/uic/utils.h b/src/tools/uic/utils.h
index 18b361fb81..3f32a532ca 100644
--- a/src/tools/uic/utils.h
+++ b/src/tools/uic/utils.h
@@ -42,27 +42,18 @@ inline bool toBool(const QString &str)
inline QString toString(const DomString *str)
{ return str ? str->text() : QString(); }
-enum StringFlags {
- Utf8String = 0x1,
- MultiLineString = 0x2
-};
-
-inline QString fixString(const QString &str, const QString &indent,
- unsigned *stringFlags = 0)
+inline QString fixString(const QString &str, const QString &indent)
{
QString cursegment;
QStringList result;
const QByteArray utf8 = str.toUtf8();
const int utf8Length = utf8.length();
- unsigned flags = 0;
-
for (int i = 0; i < utf8Length; ++i) {
const uchar cbyte = utf8.at(i);
if (cbyte >= 0x80) {
cursegment += QLatin1Char('\\');
cursegment += QString::number(cbyte, 8);
- flags |= Utf8String;
} else {
switch(cbyte) {
case '\\':
@@ -72,7 +63,6 @@ inline QString fixString(const QString &str, const QString &indent,
case '\r':
break;
case '\n':
- flags |= MultiLineString;
cursegment += QLatin1String("\\n\"\n\""); break;
default:
cursegment += QLatin1Char(cbyte);
@@ -98,24 +88,14 @@ inline QString fixString(const QString &str, const QString &indent,
rc += result.join(joinstr);
rc += QLatin1Char('"');
- if (result.size() > 1)
- flags |= MultiLineString;
-
- if (stringFlags)
- *stringFlags = flags;
-
return rc;
}
inline QHash<QString, DomProperty *> propertyMap(const QList<DomProperty *> &properties)
{
QHash<QString, DomProperty *> map;
-
- for (int i=0; i<properties.size(); ++i) {
- DomProperty *p = properties.at(i);
- map.insert(p->attributeName(), p);
- }
-
+ for (DomProperty *p : properties)
+ map.insert(p->attributeName(), p);
return map;
}
diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp
index 6cdc06d702..63c6fbb9bb 100644
--- a/src/widgets/accessible/complexwidgets.cpp
+++ b/src/widgets/accessible/complexwidgets.cpp
@@ -120,7 +120,14 @@ public:
return rec;
}
- bool isValid() const override { return m_parent.data() && m_parent->count() > m_index; }
+ bool isValid() const override {
+ if (m_parent) {
+ if (static_cast<QWidget *>(m_parent.data())->d_func()->data.in_destructor)
+ return false;
+ return m_parent->count() > m_index;
+ }
+ return false;
+ }
QAccessibleInterface *childAt(int, int) const override { return 0; }
int childCount() const override { return 0; }
@@ -199,7 +206,7 @@ QAccessibleTabBar::QAccessibleTabBar(QWidget *w)
QAccessibleTabBar::~QAccessibleTabBar()
{
- foreach (QAccessible::Id id, m_childInterfaces)
+ for (QAccessible::Id id : qAsConst(m_childInterfaces))
QAccessible::deleteAccessibleInterface(id);
}
diff --git a/src/widgets/accessible/complexwidgets_p.h b/src/widgets/accessible/complexwidgets_p.h
index 96db2dab70..e7a32c7264 100644
--- a/src/widgets/accessible/complexwidgets_p.h
+++ b/src/widgets/accessible/complexwidgets_p.h
@@ -90,8 +90,6 @@ public:
int indexOfChild(const QAccessibleInterface *child) const override;
bool isValid() const override;
QAccessibleInterface *childAt(int x, int y) const override;
-
-//protected:
QAbstractScrollArea *abstractScrollArea() const;
private:
diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp
index 4d37400dc9..04a5dcc878 100644
--- a/src/widgets/accessible/itemviews.cpp
+++ b/src/widgets/accessible/itemviews.cpp
@@ -115,7 +115,7 @@ bool QAccessibleTable::isValid() const
QAccessibleTable::~QAccessibleTable()
{
- Q_FOREACH (QAccessible::Id id, childToId)
+ for (QAccessible::Id id : qAsConst(childToId))
QAccessible::deleteAccessibleInterface(id);
}
@@ -221,7 +221,7 @@ QList<QAccessibleInterface *> QAccessibleTable::selectedCells() const
return cells;
const QModelIndexList selectedIndexes = view()->selectionModel()->selectedIndexes();
cells.reserve(selectedIndexes.size());
- Q_FOREACH (const QModelIndex &index, selectedIndexes)
+ for (const QModelIndex &index : selectedIndexes)
cells.append(child(logicalIndex(index)));
return cells;
}
@@ -233,7 +233,7 @@ QList<int> QAccessibleTable::selectedColumns() const
QList<int> columns;
const QModelIndexList selectedColumns = view()->selectionModel()->selectedColumns();
columns.reserve(selectedColumns.size());
- Q_FOREACH (const QModelIndex &index, selectedColumns)
+ for (const QModelIndex &index : selectedColumns)
columns.append(index.column());
return columns;
@@ -246,7 +246,7 @@ QList<int> QAccessibleTable::selectedRows() const
QList<int> rows;
const QModelIndexList selectedRows = view()->selectionModel()->selectedRows();
rows.reserve(selectedRows.size());
- Q_FOREACH (const QModelIndex &index, selectedRows)
+ for (const QModelIndex &index : selectedRows)
rows.append(index.row());
return rows;
@@ -553,7 +553,7 @@ void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event)
switch (event->modelChangeType()) {
case QAccessibleTableModelChangeEvent::ModelReset:
- Q_FOREACH (QAccessible::Id id, childToId)
+ for (QAccessible::Id id : qAsConst(childToId))
QAccessible::deleteAccessibleInterface(id);
childToId.clear();
break;
diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp
index 8b3353f625..507584eb02 100644
--- a/src/widgets/accessible/qaccessiblemenu.cpp
+++ b/src/widgets/accessible/qaccessiblemenu.cpp
@@ -117,10 +117,9 @@ QAccessibleInterface *QAccessibleMenu::child(int index) const
QAccessibleInterface *QAccessibleMenu::parent() const
{
if (QAction *menuAction = menu()->menuAction()) {
- QList<QWidget *> parentCandidates;
- parentCandidates << menu()->parentWidget();
- parentCandidates << menuAction->associatedWidgets();
- foreach (QWidget *w, parentCandidates) {
+ const QList<QWidget*> parentCandidates =
+ QList<QWidget*>() << menu()->parentWidget() << menuAction->associatedWidgets();
+ for (QWidget *w : parentCandidates) {
if (qobject_cast<QMenu*>(w)
#if QT_CONFIG(menubar)
|| qobject_cast<QMenuBar*>(w)
diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp
index 872ddcded5..0d87cc486d 100644
--- a/src/widgets/accessible/qaccessiblewidgets.cpp
+++ b/src/widgets/accessible/qaccessiblewidgets.cpp
@@ -569,7 +569,7 @@ QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const
QAbstractItemView *QAccessibleCalendarWidget::calendarView() const
{
- foreach (QObject *child, calendarWidget()->children()) {
+ for (QObject *child : calendarWidget()->children()) {
if (child->objectName() == QLatin1String("qt_calendar_calendarview"))
return static_cast<QAbstractItemView *>(child);
}
@@ -578,7 +578,7 @@ QAbstractItemView *QAccessibleCalendarWidget::calendarView() const
QWidget *QAccessibleCalendarWidget::navigationBar() const
{
- foreach (QObject *child, calendarWidget()->children()) {
+ for (QObject *child : calendarWidget()->children()) {
if (child->objectName() == QLatin1String("qt_calendar_navigationbar"))
return static_cast<QWidget *>(child);
}
diff --git a/src/widgets/configure.json b/src/widgets/configure.json
index b3a5227d26..0015c9160a 100644
--- a/src/widgets/configure.json
+++ b/src/widgets/configure.json
@@ -81,7 +81,7 @@
"label": "QFileSystemModel",
"purpose": "Provides a data model for the local filesystem.",
"section": "File I/O",
- "condition": "features.itemmodel",
+ "condition": "features.itemmodel && features.thread",
"output": [ "publicFeature", "feature" ]
},
"itemviews": {
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 99946d341d..434cedfdb9 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -2162,6 +2162,7 @@ QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QStr
return dlg.selectedColor();
}
+#if QT_DEPRECATED_SINCE(5, 12)
/*!
\obsolete
@@ -2169,7 +2170,7 @@ QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QStr
and an alpha channel (transparency) value. The color+alpha is
initially set to \a initial. The dialog is a child of \a parent.
- If \a ok is non-null, \e *\a ok is set to true if the user clicked
+ If \a ok is non-null, \e {*ok} is set to true if the user clicked
\uicontrol{OK}, and to false if the user clicked Cancel.
If the user clicks Cancel, the \a initial value is returned.
@@ -2187,6 +2188,7 @@ QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent)
*ok = color.isValid();
return result;
}
+#endif
/*!
Destroys the color dialog.
diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h
index 6451ff9bde..cdbe0e7fb4 100644
--- a/src/widgets/dialogs/qcolordialog.h
+++ b/src/widgets/dialogs/qcolordialog.h
@@ -92,8 +92,9 @@ public:
const QString &title = QString(),
ColorDialogOptions options = ColorDialogOptions());
- // obsolete
- static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = nullptr, QWidget *parent = nullptr);
+#if QT_DEPRECATED_SINCE(5, 12)
+ QT_DEPRECATED_X("Use getColor()") static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = nullptr, QWidget *parent = nullptr);
+#endif
static int customCount();
static QColor customColor(int index);
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index f5db4481ee..06f0393b4c 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -100,6 +100,10 @@ static inline int themeDialogType(const QDialog *dialog)
if (qobject_cast<const QErrorMessage *>(dialog))
return QPlatformTheme::MessageDialog;
#endif
+#if !QT_CONFIG(filedialog) && !QT_CONFIG(colordialog) && !QT_CONFIG(fontdialog) && \
+ !QT_CONFIG(messagebox) && !QT_CONFIG(errormessage)
+ Q_UNUSED(dialog);
+#endif
return -1;
}
@@ -514,6 +518,13 @@ void QDialog::open()
interaction with the parent window is blocked while the dialog is open.
By default, the dialog is application modal.
+ \note Avoid using this function; instead, use \c{open()}. Unlike exec(),
+ open() is asynchronous, and does not spin an additional event loop. This
+ prevents a series of dangerous bugs from happening (e.g. deleting the
+ dialog's parent while the dialog is open via exec()). When using open() you
+ can connect to the finished() signal of QDialog to be notified when the
+ dialog is closed.
+
\sa open(), show(), result(), setWindowModality()
*/
@@ -560,9 +571,12 @@ int QDialog::exec()
}
/*!
- Closes the dialog and sets its result code to \a r. If this dialog
- is shown with exec(), done() causes the local event loop to finish,
- and exec() to return \a r.
+ Closes the dialog and sets its result code to \a r. The finished() signal
+ will emit \a r; if \a r is QDialog::Accepted or QDialog::Rejected, the
+ accepted() or the rejected() signals will also be emitted, respectively.
+
+ If this dialog is shown with exec(), done() also causes the local event loop
+ to finish, and exec() to return \a r.
As with QWidget::close(), done() deletes the dialog if the
Qt::WA_DeleteOnClose flag is set. If the dialog is the application's
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index ecd2ab6776..6b037726a0 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -517,7 +517,7 @@ void QFileDialog::changeEvent(QEvent *e)
QFileDialogPrivate::QFileDialogPrivate()
:
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
proxyModel(0),
#endif
model(0),
@@ -663,7 +663,7 @@ void QFileDialogPrivate::retranslateStrings()
QList<QAction*> actions = qFileDialogUi->treeView->header()->actions();
QAbstractItemModel *abstractModel = model;
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
if (proxyModel)
abstractModel = proxyModel;
#endif
@@ -1047,10 +1047,15 @@ void QFileDialog::selectFile(const QString &filename)
return;
if (!d->usingWidgets()) {
- QUrl url = QUrl::fromLocalFile(filename);
+ QUrl url;
if (QFileInfo(filename).isRelative()) {
- QDir dir(d->options->initialDirectory().toLocalFile());
- url = QUrl::fromLocalFile(dir.absoluteFilePath(filename));
+ url = d->options->initialDirectory();
+ QString path = url.path();
+ if (!path.endsWith(QLatin1Char('/')))
+ path += QLatin1Char('/');
+ url.setPath(path + filename);
+ } else {
+ url = QUrl::fromLocalFile(filename);
}
d->selectFile_sys(url);
d->options->setInitiallySelectedFiles(QList<QUrl>() << url);
@@ -1108,7 +1113,7 @@ Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path)
const QString homePath = QDir::homePath();
#else
const QByteArray userName = path.midRef(1, separatorPosition - 1).toLocal8Bit();
-# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_WASM)
passwd pw;
passwd *tmpPw;
char buf[200];
@@ -2813,7 +2818,7 @@ bool QFileDialogPrivate::restoreWidgetState(QStringList &history, int splitterPo
QList<QAction*> actions = headerView->actions();
QAbstractItemModel *abstractModel = model;
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
if (proxyModel)
abstractModel = proxyModel;
#endif
@@ -2982,7 +2987,7 @@ void QFileDialogPrivate::createWidgets()
q, SLOT(_q_showHeader(QAction*)));;
QAbstractItemModel *abstractModel = model;
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
if (proxyModel)
abstractModel = proxyModel;
#endif
@@ -3063,7 +3068,7 @@ void QFileDialogPrivate::_q_showHeader(QAction *action)
qFileDialogUi->treeView->header()->setSectionHidden(actionGroup->actions().indexOf(action) + 1, !action->isChecked());
}
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
/*!
\since 4.3
@@ -3141,7 +3146,7 @@ QAbstractProxyModel *QFileDialog::proxyModel() const
Q_D(const QFileDialog);
return d->proxyModel;
}
-#endif // QT_NO_PROXYMODEL
+#endif // QT_CONFIG(proxymodel)
/*!
\internal
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
index 1cbd690f24..8646894750 100644
--- a/src/widgets/dialogs/qfiledialog.h
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -178,7 +178,7 @@ public:
void setSupportedSchemes(const QStringList &schemes);
QStringList supportedSchemes() const;
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
void setProxyModel(QAbstractProxyModel *model);
QAbstractProxyModel *proxyModel() const;
#endif
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index 17290381d3..3a93a53911 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -227,7 +227,7 @@ public:
void _q_fileRenamed(const QString &path, const QString &oldName, const QString &newName);
// layout
-#ifndef QT_NO_PROXYMODEL
+#if QT_CONFIG(proxymodel)
QAbstractProxyModel *proxyModel;
#endif
@@ -346,17 +346,17 @@ private:
};
QModelIndex QFileDialogPrivate::mapToSource(const QModelIndex &index) const {
-#ifdef QT_NO_PROXYMODEL
- return index;
-#else
+#if QT_CONFIG(proxymodel)
return proxyModel ? proxyModel->mapToSource(index) : index;
+#else
+ return index;
#endif
}
QModelIndex QFileDialogPrivate::mapFromSource(const QModelIndex &index) const {
-#ifdef QT_NO_PROXYMODEL
- return index;
-#else
+#if QT_CONFIG(proxymodel)
return proxyModel ? proxyModel->mapFromSource(index) : index;
+#else
+ return index;
#endif
}
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 91c8614c30..e54fdc97d4 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -48,6 +48,9 @@
#endif
#include <qapplication.h>
#include <QtCore/qcollator.h>
+#if QT_CONFIG(regularexpression)
+# include <QtCore/qregularexpression.h>
+#endif
#include <algorithm>
@@ -1580,7 +1583,7 @@ bool QFileSystemModel::nameFilterDisables() const
void QFileSystemModel::setNameFilters(const QStringList &filters)
{
// Prep the regexp's ahead of time
-#ifndef QT_NO_REGEXP
+#if QT_CONFIG(regularexpression)
Q_D(QFileSystemModel);
if (!d->bypassFilters.isEmpty()) {
@@ -1601,11 +1604,7 @@ void QFileSystemModel::setNameFilters(const QStringList &filters)
}
}
- d->nameFilters.clear();
- const Qt::CaseSensitivity caseSensitive =
- (filter() & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
- for (const auto &filter : filters)
- d->nameFilters << QRegExp(filter, caseSensitive, QRegExp::Wildcard);
+ d->nameFilters = filters;
d->forceSort = true;
d->delayedSort();
#endif
@@ -1616,16 +1615,12 @@ void QFileSystemModel::setNameFilters(const QStringList &filters)
*/
QStringList QFileSystemModel::nameFilters() const
{
+#if QT_CONFIG(regularexpression)
Q_D(const QFileSystemModel);
- QStringList filters;
-#ifndef QT_NO_REGEXP
- const int numNameFilters = d->nameFilters.size();
- filters.reserve(numNameFilters);
- for (int i = 0; i < numNameFilters; ++i) {
- filters << d->nameFilters.at(i).pattern();
- }
+ return d->nameFilters;
+#else
+ return QStringList();
#endif
- return filters;
}
/*!
@@ -2026,15 +2021,21 @@ bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) co
*/
bool QFileSystemModelPrivate::passNameFilters(const QFileSystemNode *node) const
{
-#ifndef QT_NO_REGEXP
+#if QT_CONFIG(regularexpression)
if (nameFilters.isEmpty())
return true;
// Check the name regularexpression filters
if (!(node->isDir() && (filters & QDir::AllDirs))) {
+ const QRegularExpression::PatternOptions options =
+ (filters & QDir::CaseSensitive) ? QRegularExpression::NoPatternOption
+ : QRegularExpression::CaseInsensitiveOption;
+
for (const auto &nameFilter : nameFilters) {
- QRegExp copy = nameFilter;
- if (copy.exactMatch(node->fileName))
+ const QString wildcard = QRegularExpression::wildcardToRegularExpression(nameFilter);
+ QRegularExpression rx(QRegularExpression::anchoredPattern(wildcard), options);
+ QRegularExpressionMatch match = rx.match(node->fileName);
+ if (match.hasMatch())
return true;
}
return false;
diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h
index a2a02e2d41..9c432e1ae6 100644
--- a/src/widgets/dialogs/qfilesystemmodel_p.h
+++ b/src/widgets/dialogs/qfilesystemmodel_p.h
@@ -294,8 +294,6 @@ public:
void _q_fileSystemChanged(const QString &path, const QVector<QPair<QString, QFileInfo> > &);
void _q_resolvedName(const QString &fileName, const QString &resolvedName);
- static int naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs);
-
QDir rootDir;
#if QT_CONFIG(filesystemwatcher)
# ifdef Q_OS_WIN
@@ -317,8 +315,8 @@ public:
//It enable a sort which is not recursive, it means
//we sort only what we see.
bool disableRecursiveSort;
-#ifndef QT_NO_REGEXP
- QList<QRegExp> nameFilters;
+#if QT_CONFIG(regularexpression)
+ QStringList nameFilters;
#endif
QHash<QString, QString> resolvedSymLinks;
diff --git a/src/widgets/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp
index 5c6e0f45a5..9a9bd173bd 100644
--- a/src/widgets/dialogs/qinputdialog.cpp
+++ b/src/widgets/dialogs/qinputdialog.cpp
@@ -1180,7 +1180,7 @@ void QInputDialog::done(int result)
\a inputMethodHints is the input method hints that will be used in the
edit widget if an input method is active.
- If \a ok is nonnull \e *\a ok will be set to true if the user pressed
+ If \a ok is nonnull \e {*ok} will be set to true if the user pressed
\uicontrol OK and to false if the user pressed \uicontrol Cancel. The dialog's parent
is \a parent. The dialog will be modal and uses the specified widget
\a flags.
@@ -1228,7 +1228,7 @@ QString QInputDialog::getText(QWidget *parent, const QString &title, const QStri
\a inputMethodHints is the input method hints that will be used in the
edit widget if an input method is active.
- If \a ok is nonnull \e *\a ok will be set to true if the user pressed
+ If \a ok is nonnull \e {*ok} will be set to true if the user pressed
\uicontrol OK and to false if the user pressed \uicontrol Cancel. The dialog's parent
is \a parent. The dialog will be modal and uses the specified widget
\a flags.
@@ -1436,7 +1436,7 @@ double QInputDialog::getDouble(QWidget *parent, const QString &title, const QStr
If \a editable is true the user can enter their own text; otherwise, the
user may only select one of the existing items.
- If \a ok is nonnull \e *\a ok will be set to true if the user pressed
+ If \a ok is nonnull \e {*ok} will be set to true if the user pressed
\uicontrol OK and to false if the user pressed \uicontrol Cancel. The dialog's parent
is \a parent. The dialog will be modal and uses the widget \a flags.
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index 6de952a1d3..c9f72da060 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -64,6 +64,7 @@
#include <QtGui/qfont.h>
#include <QtGui/qfontmetrics.h>
#include <QtGui/qclipboard.h>
+#include "private/qabstractbutton_p.h"
#include <private/qdesktopwidget_p.h>
#ifdef Q_OS_WIN
@@ -492,9 +493,17 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
{
- Q_UNUSED(role);
Q_Q(QMessageBox);
- q->done(button);
+ if (button > QPlatformDialogHelper::LastButton) {
+ // It's a custom button, and the QPushButton in options is just a proxy
+ // for the button on the platform dialog. Simulate the user clicking it.
+ clickedButton = static_cast<QAbstractButton *>(options->customButton(button)->button);
+ Q_ASSERT(clickedButton);
+ clickedButton->click();
+ q->done(role);
+ } else {
+ q->done(button);
+ }
}
/*!
@@ -831,6 +840,8 @@ void QMessageBox::addButton(QAbstractButton *button, ButtonRole role)
if (!button)
return;
removeButton(button);
+ d->options->addButton(button->text(), static_cast<QPlatformDialogHelper::ButtonRole>(role),
+ button);
d->buttonBox->addButton(button, (QDialogButtonBox::ButtonRole)role);
d->customButtonList.append(button);
d->autoAddOkButton = false;
@@ -2678,7 +2689,11 @@ void QMessageBoxPrivate::helperPrepareShow(QPlatformDialogHelper *)
void QMessageBoxPrivate::helperDone(QDialog::DialogCode code, QPlatformDialogHelper *)
{
Q_Q(QMessageBox);
- clickedButton = q->button(QMessageBox::StandardButton(code));
+ QAbstractButton *button = q->button(QMessageBox::StandardButton(code));
+ // If it was a custom button, a custom ID was used, so we won't get a valid pointer here.
+ // In that case, clickedButton has already been set in _q_buttonClicked.
+ if (button)
+ clickedButton = button;
}
/*!
diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp
index 5ef304c9f1..aa9ad7f290 100644
--- a/src/widgets/dialogs/qwizard_win.cpp
+++ b/src/widgets/dialogs/qwizard_win.cpp
@@ -606,8 +606,8 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q
// Set up the DC
const LOGFONT captionLogFont = getCaptionLogFont(hTheme);
const HFONT hCaptionFont = CreateFontIndirect(&captionLogFont);
- HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
- HFONT hOldFont = (HFONT)SelectObject(dcMem, (HGDIOBJ) hCaptionFont);
+ auto hOldBmp = reinterpret_cast<HBITMAP>(SelectObject(dcMem, (HGDIOBJ) bmp));
+ auto hOldFont = reinterpret_cast<HFONT>(SelectObject(dcMem, (HGDIOBJ) hCaptionFont));
// Draw the text!
DTTOPTS dto;
@@ -654,7 +654,7 @@ bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc)
dib.bmiHeader.biCompression = BI_RGB;
bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
- HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
+ auto hOldBmp = reinterpret_cast<HBITMAP>(SelectObject(dcMem, (HGDIOBJ) bmp));
BitBlt(hdc, rectDp.left(), rectDp.top(), rectDp.width(), rectDp.height(), dcMem, 0, 0, SRCCOPY);
SelectObject(dcMem, (HGDIOBJ) hOldBmp);
diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h
index 7ca4899a1f..d302dedaa3 100644
--- a/src/widgets/dialogs/qwizard_win_p.h
+++ b/src/widgets/dialogs/qwizard_win_p.h
@@ -71,22 +71,23 @@ class QVistaBackButton : public QAbstractButton
public:
QVistaBackButton(QWidget *widget);
- QSize sizeHint() const;
- inline QSize minimumSizeHint() const
+ QSize sizeHint() const override;
+ inline QSize minimumSizeHint() const override
{ return sizeHint(); }
- void enterEvent(QEvent *event);
- void leaveEvent(QEvent *event);
- void paintEvent(QPaintEvent *event);
+ void enterEvent(QEvent *event) override;
+ void leaveEvent(QEvent *event) override;
+ void paintEvent(QPaintEvent *event) override;
};
class QWizard;
class QVistaHelper : public QObject
{
+ Q_DISABLE_COPY(QVistaHelper)
public:
QVistaHelper(QWizard *wizard);
- ~QVistaHelper();
+ ~QVistaHelper() override;
enum TitleBarChangeType { NormalTitleBar, ExtendedTitleBar };
void updateCustomMargins(bool vistaMargins);
bool setDWMTitleBar(TitleBarChangeType type);
@@ -133,7 +134,7 @@ private:
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
- bool eventFilter(QObject *obj, QEvent *event);
+ bool eventFilter(QObject *obj, QEvent *event) override;
static int instanceCount;
static VistaState cachedVistaState;
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout.h b/src/widgets/graphicsview/qgraphicsanchorlayout.h
index e392be1568..9bea43dd8e 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout.h
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout.h
@@ -70,7 +70,6 @@ private:
Q_DECLARE_PRIVATE(QGraphicsAnchor)
friend class QGraphicsAnchorLayoutPrivate;
- friend struct AnchorData;
};
class Q_WIDGETS_EXPORT QGraphicsAnchorLayout : public QGraphicsLayout
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
index 71027f00a2..008560d856 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -167,7 +167,7 @@ AnchorData::~AnchorData()
if (graphicsAnchor) {
// Remove reference to ourself to avoid double removal in
// QGraphicsAnchorPrivate dtor.
- graphicsAnchor->d_func()->data = 0;
+ QGraphicsAnchorPrivate::get(graphicsAnchor)->data = nullptr;
delete graphicsAnchor;
}
@@ -215,7 +215,7 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
} else {
// It is a user-created anchor, fetch size information from the associated QGraphicsAnchor
Q_ASSERT(graphicsAnchor);
- QGraphicsAnchorPrivate *anchorPrivate = graphicsAnchor->d_func();
+ QGraphicsAnchorPrivate *anchorPrivate = QGraphicsAnchorPrivate::get(graphicsAnchor);
// Policy, min and max sizes are straightforward
policy = anchorPrivate->sizePolicy;
@@ -2526,7 +2526,7 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
// Check if this constraint have some overlap with current
// trunk variables...
- foreach (QSimplexVariable *ad, trunkVariables) {
+ for (QSimplexVariable *ad : qAsConst(trunkVariables)) {
if (c->variables.contains(ad)) {
match = true;
break;
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h
index 6b2408b2eb..699ca32bfe 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h
@@ -73,6 +73,7 @@ QT_BEGIN_NAMESPACE
respectively.
*/
+namespace QtGraphicsAnchorLayout {
/*!
\internal
@@ -326,6 +327,9 @@ public:
QSet<AnchorData *> positives;
QSet<AnchorData *> negatives;
};
+} // namespace QtGraphicsAnchorLayout
+using namespace QtGraphicsAnchorLayout;
+
Q_DECLARE_TYPEINFO(GraphPath, Q_MOVABLE_TYPE);
class QGraphicsAnchorLayoutPrivate;
@@ -346,6 +350,9 @@ public:
void setSizePolicy(QSizePolicy::Policy policy);
+ static QGraphicsAnchorPrivate *get(QGraphicsAnchor *q)
+ { return q->d_func(); }
+
QGraphicsAnchorLayoutPrivate *layoutPrivate;
AnchorData *data;
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index fdf21fb499..203b879020 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -7310,7 +7310,7 @@ void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
selectedItems = d_ptr->scene->selectedItems();
initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
if (initialPositions.isEmpty()) {
- foreach (QGraphicsItem *item, selectedItems)
+ for (QGraphicsItem *item : qAsConst(selectedItems))
initialPositions[item] = item->pos();
initialPositions[this] = pos();
}
diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h
index 9fc6c0794a..d586a22544 100644
--- a/src/widgets/graphicsview/qgraphicsitem_p.h
+++ b/src/widgets/graphicsview/qgraphicsitem_p.h
@@ -500,7 +500,9 @@ public:
quint32 filtersDescendantEvents : 1;
quint32 sceneTransformTranslateOnly : 1;
quint32 notifyBoundingRectChanged : 1;
-
+#ifdef Q_OS_WASM
+ unsigned char :0; //this aligns 64bit field for wasm see QTBUG-65259
+#endif
// New 32 bits
quint32 notifyInvalidated : 1;
quint32 mouseSetsFocus : 1;
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index 37c631483a..7cc694a613 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -4331,7 +4331,8 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &
pix->fill(Qt::transparent);
pixmapPainter.begin(pix);
} else {
- subPix = QPixmap(br.size());
+ subPix = QPixmap(br.size() * pix->devicePixelRatio());
+ subPix.setDevicePixelRatio(pix->devicePixelRatio());
subPix.fill(Qt::transparent);
pixmapPainter.begin(&subPix);
pixmapPainter.translate(-br.topLeft());
@@ -4409,6 +4410,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
return;
}
+ const qreal devicePixelRatio = painter->device()->devicePixelRatio();
const qreal oldPainterOpacity = painter->opacity();
qreal newPainterOpacity = oldPainterOpacity;
QGraphicsProxyWidget *proxy = item->isWidget() ? qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(item)) : 0;
@@ -4428,6 +4430,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Fetch the off-screen transparent buffer and exposed area info.
QPixmapCache::Key pixmapKey;
QPixmap pix;
+
bool pixmapFound;
QGraphicsItemCache *itemCache = itemd->extraItemCache();
if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
@@ -4442,18 +4445,20 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Render using item coordinate cache mode.
if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
QSize pixmapSize;
- bool fixedCacheSize = false;
+ bool fixedCacheSize = itemCache->fixedSize.isValid();
QRect br = brect.toAlignedRect();
- if ((fixedCacheSize = itemCache->fixedSize.isValid())) {
+ if (fixedCacheSize) {
pixmapSize = itemCache->fixedSize;
} else {
pixmapSize = br.size();
}
+ pixmapSize *= devicePixelRatio;
+
// Create or recreate the pixmap.
int adjust = itemCache->fixedSize.isValid() ? 0 : 2;
QSize adjustSize(adjust*2, adjust*2);
- br.adjust(-adjust, -adjust, adjust, adjust);
+ br.adjust(-adjust / devicePixelRatio, -adjust / devicePixelRatio, adjust / devicePixelRatio, adjust / devicePixelRatio);
if (pix.isNull() || (!fixedCacheSize && (pixmapSize + adjustSize) != pix.size())) {
pix = QPixmap(pixmapSize + adjustSize);
itemCache->boundingRect = br;
@@ -4476,7 +4481,8 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Fit the item's bounding rect into the pixmap's coordinates.
QTransform itemToPixmap;
if (fixedCacheSize) {
- const QPointF scale(pixmapSize.width() / brect.width(), pixmapSize.height() / brect.height());
+ const QPointF scale((pixmapSize.width() / devicePixelRatio) / brect.width(),
+ (pixmapSize.height() / devicePixelRatio) / brect.height());
itemToPixmap.scale(scale.x(), scale.y());
}
itemToPixmap.translate(-br.x(), -br.y());
@@ -4498,6 +4504,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
styleOptionTmp.exposedRect = exposedRect;
// Render.
+ pix.setDevicePixelRatio(devicePixelRatio);
_q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
&styleOptionTmp, painterStateProtection);
@@ -4595,21 +4602,22 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
// Copy / "scroll" the old pixmap onto the new ole and calculate
// scrolled exposure.
- if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size()) {
+ if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size() / devicePixelRatio) {
QPoint diff = newCacheIndent - deviceData->cacheIndent;
- QPixmap newPix(deviceRect.size());
+ QPixmap newPix(deviceRect.size() * devicePixelRatio);
// ### Investigate removing this fill (test with Plasma and
// graphicssystem raster).
newPix.fill(Qt::transparent);
if (!pix.isNull()) {
+ newPix.setDevicePixelRatio(devicePixelRatio);
QPainter newPixPainter(&newPix);
newPixPainter.drawPixmap(-diff, pix);
newPixPainter.end();
}
QRegion exposed;
- exposed += newPix.rect();
+ exposed += QRect(QPoint(0,0), newPix.size() / devicePixelRatio);
if (!pix.isNull())
- exposed -= QRect(-diff, pix.size());
+ exposed -= QRect(-diff, pix.size() / devicePixelRatio);
scrollExposure = exposed;
pix = newPix;
@@ -4621,9 +4629,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
deviceData->cacheIndent = QPoint();
// Auto-adjust the pixmap size.
- if (deviceRect.size() != pix.size()) {
+ if (deviceRect.size() != pix.size() / devicePixelRatio) {
// exposed needs to cover the whole pixmap
- pix = QPixmap(deviceRect.size());
+ pix = QPixmap(deviceRect.size() * devicePixelRatio);
pixModified = true;
itemCache->allExposed = true;
itemCache->exposed.clear();
@@ -4667,6 +4675,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
styleOptionTmp.exposedRect = br.adjusted(-1, -1, 1, 1);
// Render the exposed areas.
+ pix.setDevicePixelRatio(devicePixelRatio);
_q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
&styleOptionTmp, painterStateProtection);
@@ -6391,7 +6400,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
ev.setWidget(event->widget());
sendEvent(receiver.data(), &ev);
QSet<QGesture *> ignoredGestures;
- foreach (QGesture *g, gestures) {
+ for (QGesture *g : qAsConst(gestures)) {
if (!ev.isAccepted() && !ev.isAccepted(g)) {
// if the gesture was ignored by its target, we will update the
// targetItems list with a possible target items (items that
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.cpp b/src/widgets/graphicsview/qgraphicssceneevent.cpp
index f7f09486e9..398ef1aaf5 100644
--- a/src/widgets/graphicsview/qgraphicssceneevent.cpp
+++ b/src/widgets/graphicsview/qgraphicssceneevent.cpp
@@ -259,8 +259,9 @@
#include "qgraphicssceneevent.h"
-#ifndef QT_NO_DEBUG
+#ifndef QT_NO_DEBUG_STREAM
#include <QtCore/qdebug.h>
+#include <private/qdebug_p.h>
#endif
#include <QtCore/qmap.h>
#include <QtCore/qpoint.h>
@@ -1730,4 +1731,99 @@ void QGraphicsSceneMoveEvent::setNewPos(const QPointF &pos)
d->newPos = pos;
}
+#ifndef QT_NO_DEBUG_STREAM
+template <class Event>
+static inline void formatPositions(QDebug &debug, const Event *event)
+{
+ debug << ", pos=";
+ QtDebugUtils::formatQPoint(debug, event->pos());
+ debug << ", scenePos=";
+ QtDebugUtils::formatQPoint(debug, event->scenePos());
+ debug << ", screenPos=";
+ QtDebugUtils::formatQPoint(debug, event->screenPos());
+}
+
+QDebug operator<<(QDebug debug, const QGraphicsSceneEvent *event)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ if (!event) {
+ debug << "QGraphicsSceneEvent(0)";
+ return debug;
+ }
+
+ const QEvent::Type type = event->type();
+ switch (type) {
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick: {
+ const QGraphicsSceneMouseEvent *me = static_cast<const QGraphicsSceneMouseEvent *>(event);
+ const Qt::MouseButton button = me->button();
+ const Qt::MouseButtons buttons = me->buttons();
+ debug << "QGraphicsSceneMouseEvent(";
+ QtDebugUtils::formatQEnum(debug, type);
+ if (type != QEvent::GraphicsSceneMouseMove) {
+ debug << ", ";
+ QtDebugUtils::formatQEnum(debug, button);
+ }
+ if (buttons && button != buttons) {
+ debug << ", buttons=";
+ QtDebugUtils::formatQFlags(debug, buttons);
+ }
+ QtDebugUtils::formatNonNullQFlags(debug, ", ", me->modifiers());
+ formatPositions(debug, me);
+ QtDebugUtils::formatNonNullQEnum(debug, ", ", me->source());
+ QtDebugUtils::formatNonNullQFlags(debug, ", flags=", me->flags());
+ debug << ')';
+ }
+ break;
+ case QEvent::GraphicsSceneContextMenu: {
+ const QGraphicsSceneContextMenuEvent *ce = static_cast<const QGraphicsSceneContextMenuEvent *>(event);
+ debug << "QGraphicsSceneContextMenuEvent(reason=" << ce->reason();
+ QtDebugUtils::formatNonNullQFlags(debug, ", ", ce->modifiers());
+ formatPositions(debug, ce);
+ debug << ')';
+ }
+ break;
+ case QEvent::GraphicsSceneHoverEnter:
+ case QEvent::GraphicsSceneHoverMove:
+ case QEvent::GraphicsSceneHoverLeave:
+ debug << "QGraphicsSceneHoverEvent(";
+ formatPositions(debug, static_cast<const QGraphicsSceneHoverEvent *>(event));
+ debug << ')';
+ break;
+ case QEvent::GraphicsSceneHelp:
+ break;
+ case QEvent::GraphicsSceneDragEnter:
+ case QEvent::GraphicsSceneDragMove:
+ case QEvent::GraphicsSceneDragLeave:
+ case QEvent::GraphicsSceneDrop: {
+ const QGraphicsSceneDragDropEvent *de = static_cast<const QGraphicsSceneDragDropEvent *>(event);
+ debug << "QGraphicsSceneDragDropEvent(proposedAction=";
+ QtDebugUtils::formatQEnum(debug, de->proposedAction());
+ debug << ", possibleActions=";
+ QtDebugUtils::formatQFlags(debug, de->possibleActions());
+ debug << ", source=" << de->source();
+ QtDebugUtils::formatNonNullQFlags(debug, ", buttons=", de->buttons());
+ QtDebugUtils::formatNonNullQFlags(debug, ", ", de->modifiers());
+ formatPositions(debug, de);
+ }
+ break;
+ case QEvent::GraphicsSceneWheel: {
+ const QGraphicsSceneWheelEvent *we = static_cast<const QGraphicsSceneWheelEvent *>(event);
+ debug << "QGraphicsSceneWheelEvent(";
+ QtDebugUtils::formatNonNullQFlags(debug, ", buttons=", we->buttons());
+ QtDebugUtils::formatNonNullQFlags(debug, ", ", we->modifiers());
+ formatPositions(debug, we);
+ debug << ')';
+ }
+ break;
+ default:
+ break;
+ }
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
QT_END_NAMESPACE
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.h b/src/widgets/graphicsview/qgraphicssceneevent.h
index 77b53e401d..9d940be2c0 100644
--- a/src/widgets/graphicsview/qgraphicssceneevent.h
+++ b/src/widgets/graphicsview/qgraphicssceneevent.h
@@ -320,6 +320,10 @@ public:
void setNewPos(const QPointF &pos);
};
+#ifndef QT_NO_DEBUG_STREAM
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug, const QGraphicsSceneEvent *);
+#endif
+
QT_END_NAMESPACE
#endif
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index f79ee41e10..24647dd74c 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -2703,7 +2703,7 @@ void QGraphicsView::updateScene(const QList<QRectF> &rects)
dirtyViewportRects << xrect;
}
- foreach (const QRect &rect, dirtyViewportRects) {
+ for (const QRect &rect : qAsConst(dirtyViewportRects)) {
// Add the exposed rect to the update region. In rect update
// mode, we only count the bounding rect of items.
if (!boundingRectUpdate) {
@@ -3483,7 +3483,9 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// Recreate the background pixmap, and flag the whole background as
// exposed.
if (d->mustResizeBackgroundPixmap) {
- d->backgroundPixmap = QPixmap(viewport()->size());
+ const qreal dpr = d->viewport->devicePixelRatioF();
+ d->backgroundPixmap = QPixmap(viewport()->size() * dpr);
+ d->backgroundPixmap.setDevicePixelRatio(dpr);
QBrush bgBrush = viewport()->palette().brush(viewport()->backgroundRole());
if (!bgBrush.isOpaque())
d->backgroundPixmap.fill(Qt::transparent);
@@ -3679,14 +3681,20 @@ void QGraphicsView::scrollContentsBy(int dx, int dy)
&& X11->use_xrender
#endif
) {
+ // Below, QPixmap::scroll() works in device pixels, while the delta values
+ // and backgroundPixmapExposed are in device independent pixels.
+ const qreal dpr = d->backgroundPixmap.devicePixelRatio();
+ const qreal inverseDpr = qreal(1) / dpr;
+
// Scroll the background pixmap
QRegion exposed;
if (!d->backgroundPixmap.isNull())
- d->backgroundPixmap.scroll(dx, dy, d->backgroundPixmap.rect(), &exposed);
+ d->backgroundPixmap.scroll(dx * dpr, dy * dpr, d->backgroundPixmap.rect(), &exposed);
// Invalidate the background pixmap
d->backgroundPixmapExposed.translate(dx, dy);
- d->backgroundPixmapExposed += exposed;
+ const QRegion exposedScaled = QTransform::fromScale(inverseDpr, inverseDpr).map(exposed);
+ d->backgroundPixmapExposed += exposedScaled;
}
// Always replay on scroll.
diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp
index c9f321c3f6..7bc0ece4b3 100644
--- a/src/widgets/itemviews/qabstractitemdelegate.cpp
+++ b/src/widgets/itemviews/qabstractitemdelegate.cpp
@@ -599,18 +599,21 @@ QString QAbstractItemDelegatePrivate::textForRole(Qt::ItemDataRole role, const Q
case QVariant::DateTime:
text = locale.toString(value.toDateTime(), formatType);
break;
- default: {
- if (value.canConvert<QJsonValue>()) {
- const QJsonValue val = value.toJsonValue();
- if (val.isBool())
- text = QVariant(val.toBool()).toString();
- else if (val.isDouble())
- text = locale.toString(val.toDouble(), 'g', precision);
- else if (val.isString())
- text = val.toString();
- } else {
- text = value.toString();
+ case QVariant::Type(QMetaType::QJsonValue): {
+ const QJsonValue val = value.toJsonValue();
+ if (val.isBool()) {
+ text = QVariant(val.toBool()).toString();
+ break;
+ }
+ if (val.isDouble()) {
+ text = locale.toString(val.toDouble(), 'g', precision);
+ break;
}
+ // val is a string (or null) here
+ Q_FALLTHROUGH();
+ }
+ default: {
+ text = value.toString();
if (role == Qt::DisplayRole)
text.replace(QLatin1Char('\n'), QChar::LineSeparator);
break;
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 2d30b2650a..7bfa51337d 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -1853,11 +1853,13 @@ bool QHeaderView::restoreState(const QByteArray &state)
*/
void QHeaderView::reset()
{
+ Q_D(QHeaderView);
QAbstractItemView::reset();
// it would be correct to call clear, but some apps rely
// on the header keeping the sections, even after calling reset
//d->clear();
initializeSections();
+ d->invalidateCachedSizeHint();
}
/*!
@@ -2868,6 +2870,7 @@ bool QHeaderView::viewportEvent(QEvent *e)
}
return true; }
#endif // QT_CONFIG(statustip)
+ case QEvent::Resize:
case QEvent::FontChange:
case QEvent::StyleChange:
d->invalidateCachedSizeHint();
@@ -2962,8 +2965,10 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical
margin += style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this) +
style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
- if (d->textElideMode != Qt::ElideNone)
- opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode , rect.width() - margin);
+ if (d->textElideMode != Qt::ElideNone) {
+ const QRect textRect = style()->subElementRect(QStyle::SE_HeaderLabel, &opt, this);
+ opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode, textRect.width() - margin);
+ }
QVariant foregroundBrush = d->model->headerData(logicalIndex, d->orientation,
Qt::ForegroundRole);
@@ -3363,7 +3368,9 @@ void QHeaderViewPrivate::setupSectionIndicator(int section, int position)
sectionIndicator->resize(w, h);
#endif
- QPixmap pm(w, h);
+ const qreal pixmapDevicePixelRatio = q->devicePixelRatioF();
+ QPixmap pm(QSize(w, h) * pixmapDevicePixelRatio);
+ pm.setDevicePixelRatio(pixmapDevicePixelRatio);
pm.fill(QColor(0, 0, 0, 45));
QRect rect(0, 0, w, h);
@@ -3828,6 +3835,7 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize)
void QHeaderViewPrivate::setDefaultSectionSize(int size)
{
Q_Q(QHeaderView);
+ size = qBound(q->minimumSectionSize(), size, q->maximumSectionSize());
executePostedLayout();
invalidateCachedSizeHint();
defaultSectionSize = size;
@@ -4083,7 +4091,7 @@ bool QHeaderViewPrivate::read(QDataStream &in)
}
int sectionItemsLengthTotal = 0;
- foreach (const SectionItem &section, newSectionItems)
+ for (const SectionItem &section : qAsConst(newSectionItems))
sectionItemsLengthTotal += section.size;
if (sectionItemsLengthTotal != lengthIn)
return false;
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
index 91122283a4..dff4cc4593 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -103,7 +103,10 @@ public:
QItemEditorFactory *f;
bool clipPainting;
- QRect textLayoutBounds(const QStyleOptionViewItem &options) const;
+ QRect displayRect(const QModelIndex &index, const QStyleOptionViewItem &option,
+ const QRect &decorationRect, const QRect &checkRect) const;
+ QRect textLayoutBounds(const QStyleOptionViewItem &option,
+ const QRect &decorationRect, const QRect &checkRect) const;
QSizeF doTextLayout(int lineWidth) const;
mutable QTextLayout textLayout;
mutable QTextOption textOption;
@@ -121,21 +124,53 @@ public:
} tmp;
};
-QRect QItemDelegatePrivate::textLayoutBounds(const QStyleOptionViewItem &option) const
+QRect QItemDelegatePrivate::displayRect(const QModelIndex &index, const QStyleOptionViewItem &option,
+ const QRect &decorationRect, const QRect &checkRect) const
+{
+ Q_Q(const QItemDelegate);
+ const QVariant value = index.data(Qt::DisplayRole);
+ if (!value.isValid() || value.isNull())
+ return QRect();
+
+ const QString text = valueToText(value, option);
+ const QVariant fontVal = index.data(Qt::FontRole);
+ const QFont fnt = qvariant_cast<QFont>(fontVal).resolve(option.font);
+ return q->textRectangle(nullptr,
+ textLayoutBounds(option, decorationRect, checkRect),
+ fnt, text);
+}
+
+// similar to QCommonStylePrivate::viewItemSize(Qt::DisplayRole)
+QRect QItemDelegatePrivate::textLayoutBounds(const QStyleOptionViewItem &option,
+ const QRect &decorationRect, const QRect &checkRect) const
{
QRect rect = option.rect;
+ const QWidget *w = widget(option);
+ QStyle *style = w ? w->style() : QApplication::style();
const bool wrapText = option.features & QStyleOptionViewItem::WrapText;
+ // see QItemDelegate::drawDisplay
+ const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, w) + 1;
switch (option.decorationPosition) {
case QStyleOptionViewItem::Left:
case QStyleOptionViewItem::Right:
- rect.setWidth(wrapText && rect.isValid() ? rect.width() : (QFIXED_MAX));
+ rect.setWidth(wrapText && rect.isValid() ? rect.width() - 2 * textMargin : (QFIXED_MAX));
break;
case QStyleOptionViewItem::Top:
case QStyleOptionViewItem::Bottom:
- rect.setWidth(wrapText ? option.decorationSize.width() : (QFIXED_MAX));
+ rect.setWidth(wrapText ? option.decorationSize.width() - 2 * textMargin : (QFIXED_MAX));
break;
}
+ if (wrapText) {
+ if (!decorationRect.isNull())
+ rect.setWidth(rect.width() - decorationRect.width() - 2 * textMargin);
+ if (!checkRect.isNull())
+ rect.setWidth(rect.width() - checkRect.width() - 2 * textMargin);
+ // adjust height to be sure that the text fits
+ const QSizeF size = doTextLayout(rect.width());
+ rect.setHeight(qCeil(size.height()));
+ }
+
return rect;
}
@@ -395,14 +430,6 @@ void QItemDelegate::paint(QPainter *painter,
decorationRect = QRect();
}
- QString text;
- QRect displayRect;
- value = index.data(Qt::DisplayRole);
- if (value.isValid() && !value.isNull()) {
- text = d->valueToText(value, opt);
- displayRect = textRectangle(painter, d->textLayoutBounds(opt), opt.font, text);
- }
-
QRect checkRect;
Qt::CheckState checkState = Qt::Unchecked;
value = index.data(Qt::CheckStateRole);
@@ -411,6 +438,14 @@ void QItemDelegate::paint(QPainter *painter,
checkRect = doCheck(opt, opt.rect, value);
}
+ QString text;
+ QRect displayRect;
+ value = index.data(Qt::DisplayRole);
+ if (value.isValid() && !value.isNull()) {
+ text = d->valueToText(value, opt);
+ displayRect = d->displayRect(index, opt, decorationRect, checkRect);
+ }
+
// do the layout
doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
@@ -440,12 +475,13 @@ void QItemDelegate::paint(QPainter *painter,
QSize QItemDelegate::sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
+ Q_D(const QItemDelegate);
QVariant value = index.data(Qt::SizeHintRole);
if (value.isValid())
return qvariant_cast<QSize>(value);
QRect decorationRect = rect(option, index, Qt::DecorationRole);
- QRect displayRect = rect(option, index, Qt::DisplayRole);
QRect checkRect = rect(option, index, Qt::CheckStateRole);
+ QRect displayRect = d->displayRect(index, option, decorationRect, checkRect);
doLayout(option, &checkRect, &decorationRect, &displayRect, true);
@@ -1000,8 +1036,8 @@ QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette,
/*!
\internal
+ Only used (and usable) for Qt::DecorationRole and Qt::CheckStateRole
*/
-
QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
const QModelIndex &index, int role) const
{
@@ -1032,7 +1068,9 @@ QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
const QString text = d->valueToText(value, option);
value = index.data(Qt::FontRole);
QFont fnt = qvariant_cast<QFont>(value).resolve(option.font);
- return textRectangle(0, d->textLayoutBounds(option), fnt, text); }
+ return textRectangle(nullptr,
+ d->textLayoutBounds(option, QRect(), QRect()),
+ fnt, text); }
}
}
return QRect();
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index a7174a92e8..e5769940d4 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1631,6 +1631,32 @@ bool QListView::isSelectionRectVisible() const
}
/*!
+ \property QListView::itemAlignment
+ \brief the alignment of each item in its cell
+ \since 5.12
+
+ This is only supported in ListMode with TopToBottom flow
+ and with wrapping enabled.
+ The default alignment is 0, which means that an item fills
+ its cell entirely.
+*/
+void QListView::setItemAlignment(Qt::Alignment alignment)
+{
+ Q_D(QListView);
+ if (d->itemAlignment == alignment)
+ return;
+ d->itemAlignment = alignment;
+ if (viewMode() == ListMode && flow() == QListView::TopToBottom && isWrapping())
+ d->doDelayedItemsLayout();
+}
+
+Qt::Alignment QListView::itemAlignment() const
+{
+ Q_D(const QListView);
+ return d->itemAlignment;
+}
+
+/*!
\reimp
*/
bool QListView::event(QEvent *e)
@@ -1656,7 +1682,8 @@ QListViewPrivate::QListViewPrivate()
column(0),
uniformItemSizes(false),
batchSize(100),
- showElasticBand(false)
+ showElasticBand(false),
+ itemAlignment(Qt::Alignment())
{
}
@@ -2366,6 +2393,7 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
options.rect.setSize(contentsSize);
QSize size = (uniformItemSizes() && cachedItemSize().isValid())
? cachedItemSize() : itemSize(options, index);
+ QSize cellSize = size;
QPoint pos;
if (flow() == QListView::LeftToRight) {
@@ -2378,12 +2406,22 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
int right = (segment + 1 >= segmentPositions.count()
? contentsSize.width()
: segmentPositions.at(segment + 1));
- size.setWidth(right - pos.x());
+ cellSize.setWidth(right - pos.x());
} else { // make the items as wide as the viewport
- size.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing()));
+ cellSize.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing()));
}
}
+ if (dd->itemAlignment & Qt::AlignHorizontal_Mask) {
+ size.setWidth(qMin(size.width(), cellSize.width()));
+ if (dd->itemAlignment & Qt::AlignRight)
+ pos.setX(pos.x() + cellSize.width() - size.width());
+ if (dd->itemAlignment & Qt::AlignHCenter)
+ pos.setX(pos.x() + (cellSize.width() - size.width()) / 2);
+ } else {
+ size.setWidth(cellSize.width());
+ }
+
return QListViewItem(QRect(pos, size), index.row());
}
@@ -2562,8 +2600,18 @@ QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
if (isHidden(row))
continue;
QModelIndex index = modelIndex(row);
- if (index.isValid())
- ret += index;
+ if (index.isValid()) {
+ if (flow() == QListView::LeftToRight || dd->itemAlignment == Qt::Alignment()) {
+ ret += index;
+ } else {
+ const auto viewItem = indexToListViewItem(index);
+ const int iw = viewItem.width();
+ const int startPos = qMax(segStartPosition, segmentPositions.at(seg));
+ const int endPos = qMin(segmentPositions.at(seg + 1), segEndPosition);
+ if (endPos >= viewItem.x && startPos < viewItem.x + iw)
+ ret += index;
+ }
+ }
#if 0 // for debugging
else
qWarning("intersectingSet: row %d was invalid", row);
@@ -2603,7 +2651,7 @@ int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wr
positions = segmentPositions;
else if (!flowPositions.isEmpty()) {
positions.reserve(scrollValueMap.size());
- foreach (int itemShown, scrollValueMap)
+ for (int itemShown : scrollValueMap)
positions.append(flowPositions.at(itemShown));
}
if (positions.isEmpty() || bounds <= length)
@@ -2767,6 +2815,8 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
drag->setHotSpot(dd->pressedPosition - rect.topLeft());
Qt::DropAction action = drag->exec(supportedActions, dd->defaultDropAction);
draggedItems.clear();
+ // for internal moves the action was set to Qt::CopyAction in
+ // filterDropEvent() to avoid the deletion here
if (action == Qt::MoveAction)
dd->clearOrRemove();
}
@@ -2784,7 +2834,7 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
if (qq->acceptDrops()) {
const Qt::ItemFlags dropableFlags = Qt::ItemIsDropEnabled|Qt::ItemIsEnabled;
const QVector<QModelIndex> &dropIndices = intersectingSet(QRect(end, QSize(1, 1)));
- foreach (const QModelIndex &index, dropIndices)
+ for (const QModelIndex &index : dropIndices)
if ((index.flags() & dropableFlags) == dropableFlags)
return false;
}
@@ -2803,6 +2853,8 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
dd->stopAutoScroll();
draggedItems.clear();
dd->emitIndexesMoved(indexes);
+ // do not delete item on internal move, see filterStartDrag()
+ e->setDropAction(Qt::CopyAction);
e->accept(); // we have handled the event
// if the size has not grown, we need to check if it has shrinked
if (contentsSize != contents) {
diff --git a/src/widgets/itemviews/qlistview.h b/src/widgets/itemviews/qlistview.h
index 9fc4035999..8a5d5e02ae 100644
--- a/src/widgets/itemviews/qlistview.h
+++ b/src/widgets/itemviews/qlistview.h
@@ -65,6 +65,7 @@ class Q_WIDGETS_EXPORT QListView : public QAbstractItemView
Q_PROPERTY(int batchSize READ batchSize WRITE setBatchSize)
Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
Q_PROPERTY(bool selectionRectVisible READ isSelectionRectVisible WRITE setSelectionRectVisible)
+ Q_PROPERTY(Qt::Alignment itemAlignment READ itemAlignment WRITE setItemAlignment)
public:
enum Movement { Static, Free, Snap };
@@ -125,6 +126,9 @@ public:
void setSelectionRectVisible(bool show);
bool isSelectionRectVisible() const;
+ void setItemAlignment(Qt::Alignment alignment);
+ Qt::Alignment itemAlignment() const;
+
QRect visualRect(const QModelIndex &index) const override;
void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;
QModelIndex indexAt(const QPoint &p) const override;
diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h
index ca947292e3..181386d4d0 100644
--- a/src/widgets/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
@@ -431,6 +431,8 @@ public:
QRect elasticBand;
bool showElasticBand;
+
+ Qt::Alignment itemAlignment;
};
// inline implementations
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 4f1c7fe80a..72e0a67a64 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -48,9 +48,6 @@
QT_BEGIN_NAMESPACE
-// workaround for VC++ 6.0 linker bug (?)
-typedef bool(*LessThan)(const QPair<QListWidgetItem*,int>&,const QPair<QListWidgetItem*,int>&);
-
class QListWidgetMimeData : public QMimeData
{
Q_OBJECT
@@ -301,7 +298,7 @@ void QListModel::sort(int column, Qt::SortOrder order)
sorting[i].second = i;
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::sort(sorting.begin(), sorting.end(), compare);
QModelIndexList fromIndexes;
QModelIndexList toIndexes;
@@ -338,7 +335,7 @@ void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int en
sorting[i].second = start + i;
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes = persistentIndexList();
@@ -1847,7 +1844,7 @@ QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*> items) const
// if non empty, it's called from the model's own mimeData
if (cachedIndexes.isEmpty()) {
cachedIndexes.reserve(items.count());
- foreach (QListWidgetItem *item, items)
+ for (QListWidgetItem *item : items)
cachedIndexes << indexFromItem(item);
QMimeData *result = d->listModel()->internalMimeData();
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 1938fd8e92..9725a768de 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -74,7 +74,7 @@ void QSpanCollection::addSpan(QSpanCollection::Span *span)
//the previouslist is the list of spans that sarts _before_ the row of the span.
// and which may intersect this row.
const SubIndex previousList = it_y.value();
- foreach(Span *s, previousList) {
+ for (Span *s : previousList) {
//If a subspans intersect the row, we need to split it into subspans
if(s->bottom() >= span->top())
sub_index.insert(-s->left(), s);
@@ -798,6 +798,7 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
const QStyleOptionViewItem &option, QBitArray *drawn,
int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn)
{
+ Q_Q(const QTableView);
bool alternateBase = false;
QRegion region = viewport->rect();
@@ -816,7 +817,7 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
visibleSpans = set.toList();
}
- foreach (QSpanCollection::Span *span, visibleSpans) {
+ for (QSpanCollection::Span *span : qAsConst(visibleSpans)) {
int row = span->top();
int col = span->left();
QModelIndex index = model->index(row, col, root);
@@ -831,6 +832,18 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
alternateBase = alternatingColors && (span->top() & 1);
opt.features.setFlag(QStyleOptionViewItem::Alternate, alternateBase);
drawCell(painter, opt, index);
+ if (showGrid) {
+ // adjust the clip rect to be able to paint the top & left grid lines
+ // if the headers are not visible, see paintEvent()
+ if (horizontalHeader->visualIndex(row) == 0)
+ rect.setTop(rect.top() + 1);
+ if (verticalHeader->visualIndex(row) == 0) {
+ if (q->isLeftToRight())
+ rect.setLeft(rect.left() + 1);
+ else
+ rect.setRight(rect.right() - 1);
+ }
+ }
region -= rect;
for (int r = span->top(); r <= span->bottom(); ++r) {
const int vr = visualRow(r);
@@ -1163,7 +1176,6 @@ void QTableView::doItemsLayout()
{
Q_D(QTableView);
QAbstractItemView::doItemsLayout();
- d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
if (!d->verticalHeader->updatesEnabled())
d->verticalHeader->setUpdatesEnabled(true);
}
@@ -1321,10 +1333,10 @@ void QTableView::scrollContentsBy(int dx, int dy)
//we need to update the first line of the previous top item in the view
//because it has the grid drawn if the header is invisible.
//It is strictly related to what's done at then end of the paintEvent
- if (dy > 0 && d->horizontalHeader->isHidden() && d->verticalScrollMode == ScrollPerItem) {
+ if (dy > 0 && d->horizontalHeader->isHidden()) {
d->viewport->update(0, dy, d->viewport->width(), dy);
}
- if (dx > 0 && d->verticalHeader->isHidden() && d->horizontalScrollMode == ScrollPerItem) {
+ if (dx > 0 && d->verticalHeader->isHidden()) {
d->viewport->update(dx, 0, dx, d->viewport->height());
}
}
@@ -1504,10 +1516,26 @@ void QTableView::paintEvent(QPaintEvent *event)
//draw the top & left grid lines if the headers are not visible.
//We do update this line when subsequent scroll happen (see scrollContentsBy)
- if (horizontalHeader->isHidden() && verticalScrollMode() == ScrollPerItem)
- painter.drawLine(dirtyArea.left(), 0, dirtyArea.right(), 0);
- if (verticalHeader->isHidden() && horizontalScrollMode() == ScrollPerItem)
- painter.drawLine(0, dirtyArea.top(), 0, dirtyArea.bottom());
+ if (horizontalHeader->isHidden() && top == 0) {
+ const int row = verticalHeader->logicalIndex(top);
+ if (!verticalHeader->isSectionHidden(row)) {
+ const int rowY = rowViewportPosition(row) + offset.y();
+ if (rowY == dirtyArea.top())
+ painter.drawLine(dirtyArea.left(), rowY, dirtyArea.right(), rowY);
+ }
+ }
+ if (verticalHeader->isHidden() && left == 0) {
+ const int col = horizontalHeader->logicalIndex(left);
+ if (!horizontalHeader->isSectionHidden(col)) {
+ int colX = columnViewportPosition(col) + offset.x();
+ if (!isLeftToRight())
+ colX += columnWidth(left) - 1;
+ if (isLeftToRight() && colX == dirtyArea.left())
+ painter.drawLine(colX, dirtyArea.top(), colX, dirtyArea.bottom());
+ if (!isLeftToRight() && colX == dirtyArea.right())
+ painter.drawLine(colX, dirtyArea.top(), colX, dirtyArea.bottom());
+ }
+ }
painter.setPen(old);
}
}
@@ -1788,8 +1816,12 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
break;
case MovePageUp: {
int newRow = rowAt(visualRect(current).bottom() - d->viewport->height());
- if (newRow == -1)
- newRow = d->logicalRow(0);
+ if (newRow == -1) {
+ int visualRow = 0;
+ while (visualRow < bottom && isRowHidden(d->logicalRow(visualRow)))
+ ++visualRow;
+ newRow = d->logicalRow(visualRow);
+ }
return d->model->index(newRow, current.column(), d->root);
}
case MovePageDown: {
@@ -2194,6 +2226,7 @@ void QTableView::updateGeometries()
verticalScrollBar()->setRange(0, verticalLength - vsize.height());
verticalScrollBar()->d_func()->itemviewChangeSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));
}
+ d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
d->geometryRecursionBlock = false;
QAbstractItemView::updateGeometries();
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index 9d5a2aa1bd..11925af7a0 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -453,17 +453,20 @@ bool QTableModel::setItemData(const QModelIndex &index, const QMap<int, QVariant
QTableWidget *view = qobject_cast<QTableWidget*>(QObject::parent());
QTableWidgetItem *itm = item(index);
if (itm) {
- itm->view = 0; // prohibits item from calling itemChanged()
- bool changed = false;
+ itm->view = nullptr; // prohibits item from calling itemChanged()
+ QVector<int> rolesVec;
for (QMap<int, QVariant>::ConstIterator it = roles.constBegin(); it != roles.constEnd(); ++it) {
- if (itm->data(it.key()) != it.value()) {
- itm->setData(it.key(), it.value());
- changed = true;
+ const int role = (it.key() == Qt::EditRole ? Qt::DisplayRole : it.key());
+ if (itm->data(role) != it.value()) {
+ itm->setData(role, it.value());
+ rolesVec += role;
+ if (role == Qt::DisplayRole)
+ rolesVec += Qt::EditRole;
}
}
itm->view = view;
- if (changed)
- itemChanged(itm);
+ if (!rolesVec.isEmpty())
+ itemChanged(itm, rolesVec);
return true;
}
@@ -506,7 +509,7 @@ void QTableModel::sort(int column, Qt::SortOrder order)
unsortable.append(row);
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sortable.begin(), sortable.end(), compare);
QVector<QTableWidgetItem*> sorted_table(tableItems.count());
@@ -558,7 +561,7 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order,
sorting.append(QPair<QTableWidgetItem*,int>(itm, row));
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes, newPersistentIndexes;
QVector<QTableWidgetItem*> newTable = tableItems;
@@ -771,7 +774,7 @@ void QTableModel::clearContents()
endResetModel();
}
-void QTableModel::itemChanged(QTableWidgetItem *item)
+void QTableModel::itemChanged(QTableWidgetItem *item, const QVector<int> &roles)
{
if (!item)
return;
@@ -787,7 +790,7 @@ void QTableModel::itemChanged(QTableWidgetItem *item)
} else {
QModelIndex idx = index(item);
if (idx.isValid())
- emit dataChanged(idx, idx);
+ emit dataChanged(idx, idx, roles);
}
}
@@ -1386,8 +1389,13 @@ void QTableWidgetItem::setData(int role, const QVariant &value)
}
if (!found)
values.append(QWidgetItemData(role, value));
- if (QTableModel *model = (view ? qobject_cast<QTableModel*>(view->model()) : 0))
- model->itemChanged(this);
+ if (QTableModel *model = (view ? qobject_cast<QTableModel*>(view->model()) : nullptr))
+ {
+ const QVector<int> roles((role == Qt::DisplayRole) ?
+ QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
+ QVector<int>({role}));
+ model->itemChanged(this, roles);
+ }
}
/*!
@@ -2595,7 +2603,7 @@ QMimeData *QTableWidget::mimeData(const QList<QTableWidgetItem*> items) const
// if non empty, it's called from the model's own mimeData
if (cachedIndexes.isEmpty()) {
cachedIndexes.reserve(items.count());
- foreach (QTableWidgetItem *item, items)
+ for (QTableWidgetItem *item : items)
cachedIndexes << indexFromItem(item);
QMimeData *result = d->tableModel()->internalMimeData();
diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h
index 7322e3aed7..9de27d164f 100644
--- a/src/widgets/itemviews/qtablewidget.h
+++ b/src/widgets/itemviews/qtablewidget.h
@@ -302,6 +302,7 @@ Q_SIGNALS:
void itemActivated(QTableWidgetItem *item);
void itemEntered(QTableWidgetItem *item);
+ // ### Qt 6: add changed roles
void itemChanged(QTableWidgetItem *item);
void currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous);
diff --git a/src/widgets/itemviews/qtablewidget_p.h b/src/widgets/itemviews/qtablewidget_p.h
index 6412477be0..9899272fce 100644
--- a/src/widgets/itemviews/qtablewidget_p.h
+++ b/src/widgets/itemviews/qtablewidget_p.h
@@ -62,9 +62,6 @@ QT_REQUIRE_CONFIG(tablewidget);
QT_BEGIN_NAMESPACE
-// workaround for VC++ 6.0 linker bug
-typedef bool(*LessThan)(const QPair<QTableWidgetItem*,int>&,const QPair<QTableWidgetItem*,int>&);
-
class QTableWidgetMimeData : public QMimeData
{
Q_OBJECT
@@ -160,7 +157,7 @@ public:
void clear();
void clearContents();
- void itemChanged(QTableWidgetItem *item);
+ void itemChanged(QTableWidgetItem *item, const QVector<int> &roles = QVector<int>());
QTableWidgetItem *createItem() const;
const QTableWidgetItem *itemPrototype() const;
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index fbfbe56246..b534de5c6a 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -632,11 +632,8 @@ bool QTreeView::isFirstColumnSpanned(int row, const QModelIndex &parent) const
Q_D(const QTreeView);
if (d->spanningIndexes.isEmpty() || !d->model)
return false;
- QModelIndex index = d->model->index(row, 0, parent);
- for (int i = 0; i < d->spanningIndexes.count(); ++i)
- if (d->spanningIndexes.at(i) == index)
- return true;
- return false;
+ const QModelIndex index = d->model->index(row, 0, parent);
+ return d->spanningIndexes.contains(index);
}
/*!
@@ -653,20 +650,14 @@ void QTreeView::setFirstColumnSpanned(int row, const QModelIndex &parent, bool s
Q_D(QTreeView);
if (!d->model)
return;
- QModelIndex index = d->model->index(row, 0, parent);
+ const QModelIndex index = d->model->index(row, 0, parent);
if (!index.isValid())
return;
- if (span) {
- QPersistentModelIndex persistent(index);
- if (!d->spanningIndexes.contains(persistent))
- d->spanningIndexes.append(persistent);
- } else {
- QPersistentModelIndex persistent(index);
- int i = d->spanningIndexes.indexOf(persistent);
- if (i >= 0)
- d->spanningIndexes.remove(i);
- }
+ if (span)
+ d->spanningIndexes.insert(index);
+ else
+ d->spanningIndexes.remove(index);
d->executePostedLayout();
int i = d->viewIndex(index);
@@ -1420,7 +1411,7 @@ QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList
if (spanningIndexes.isEmpty())
return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r);
QModelIndexList list;
- foreach (const QModelIndex &idx, indexes) {
+ for (const QModelIndex &idx : indexes) {
if (idx.column() > 0 && q->isFirstColumnSpanned(idx.row(), idx.parent()))
continue;
list << idx;
@@ -2000,19 +1991,21 @@ void QTreeView::keyPressEvent(QKeyEvent *event)
if (d->isIndexValid(current) && d->model && d->itemsExpandable) {
switch (event->key()) {
case Qt::Key_Asterisk: {
+ // do layouting only once after expanding is done
+ d->doDelayedItemsLayout();
QStack<QModelIndex> parents;
parents.push(current);
- while (!parents.isEmpty()) {
- QModelIndex parent = parents.pop();
- for (int row = 0; row < d->model->rowCount(parent); ++row) {
- QModelIndex child = d->model->index(row, 0, parent);
- if (!d->isIndexValid(child))
- break;
- parents.push(child);
- expand(child);
- }
+ while (!parents.isEmpty()) {
+ QModelIndex parent = parents.pop();
+ for (int row = 0; row < d->model->rowCount(parent); ++row) {
+ QModelIndex child = d->model->index(row, 0, parent);
+ if (!d->isIndexValid(child))
+ break;
+ parents.push(child);
+ expand(child);
}
- expand(current);
+ }
+ expand(current);
break; }
case Qt::Key_Plus:
expand(current);
@@ -2495,7 +2488,6 @@ void QTreeView::scrollContentsBy(int dx, int dy)
int previousScrollbarValue = currentScrollbarValue + dy; // -(-dy)
int currentViewIndex = currentScrollbarValue; // the first visible item
int previousViewIndex = previousScrollbarValue;
- const QVector<QTreeViewItem> viewItems = d->viewItems;
dy = 0;
if (previousViewIndex < currentViewIndex) { // scrolling down
for (int i = previousViewIndex; i < currentViewIndex; ++i) {
@@ -3732,9 +3724,14 @@ void QTreeViewPrivate::updateScrollBars()
int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const
{
+ Q_Q(const QTreeView);
executePostedLayout();
- int x = pos.x();
- int column = header->logicalIndexAt(x);
+ bool spanned = false;
+ if (!spanningIndexes.isEmpty()) {
+ const QModelIndex index = q->indexAt(pos);
+ spanned = q->isFirstColumnSpanned(index.row(), index.parent());
+ }
+ const int column = spanned ? 0 : header->logicalIndexAt(pos.x());
if (!isTreePosition(column))
return -1; // no logical index at x
diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h
index 9a391ee88a..8b217036a2 100644
--- a/src/widgets/itemviews/qtreeview_p.h
+++ b/src/widgets/itemviews/qtreeview_p.h
@@ -247,7 +247,7 @@ public:
void updateIndentationFromStyle();
// used for spanning rows
- QVector<QPersistentModelIndex> spanningIndexes;
+ QSet<QPersistentModelIndex> spanningIndexes;
// used for updating resized columns
int columnResizeTimerID;
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index 654c241079..a0af27115d 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -52,9 +52,6 @@
QT_BEGIN_NAMESPACE
-// workaround for VC++ 6.0 linker bug (?)
-typedef bool(*LessThan)(const QPair<QTreeWidgetItem*,int>&,const QPair<QTreeWidgetItem*,int>&);
-
class QTreeModelLessThan
{
public:
@@ -610,7 +607,7 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
sorting[i].second = start + i;
}
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList oldPersistentIndexes;
@@ -777,7 +774,7 @@ bool QTreeModel::isChanging() const
if column is -1 then all columns have changed
*/
-void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column)
+void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column, const QVector<int> &roles)
{
if (signalsBlocked())
return;
@@ -800,7 +797,7 @@ void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column)
topLeft = index(item, column);
bottomRight = topLeft;
}
- emit dataChanged(topLeft, bottomRight);
+ emit dataChanged(topLeft, bottomRight, roles);
}
void QTreeModel::beginInsertItems(QTreeWidgetItem *parent, int row, int count)
@@ -850,7 +847,7 @@ void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortO
}
// do the sorting
- LessThan compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
+ const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList fromList;
@@ -1015,6 +1012,14 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
\sa isHidden()
*/
+void QTreeWidgetItem::setHidden(bool ahide)
+{
+ if (view) {
+ view->setItemHidden(this, ahide);
+ d->hidden = ahide;
+ }
+}
+
/*!
\fn bool QTreeWidgetItem::isHidden() const
\since 4.2
@@ -1024,6 +1029,11 @@ void QTreeModel::timerEvent(QTimerEvent *ev)
\sa setHidden()
*/
+bool QTreeWidgetItem::isHidden() const
+{
+ return (view ? d->hidden : false);
+}
+
/*!
\fn void QTreeWidgetItem::setExpanded(bool expand)
\since 4.2
@@ -1651,6 +1661,25 @@ void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
itemChanged();
}
+void QTreeWidgetItemPrivate::updateHiddenStatus(QTreeWidgetItem *item, bool inserting)
+{
+ QTreeModel *model = (item->view ? qobject_cast<QTreeModel*>(item->view->model()) : 0);
+ if (!model)
+ return;
+ QStack<QTreeWidgetItem *> parents;
+ parents.push(item);
+ while (!parents.isEmpty()) {
+ QTreeWidgetItem *parent = parents.pop();
+ QModelIndex index = model->index(parent, 0);
+ if (parent->d->hidden)
+ item->view->setRowHidden(index.row(), index.parent(), inserting);
+ for (int i = 0; i < parent->children.count(); ++i) {
+ QTreeWidgetItem *child = parent->children.at(i);
+ parents.push(child);
+ }
+ }
+}
+
void QTreeWidgetItemPrivate::propagateDisabled(QTreeWidgetItem *item)
{
Q_ASSERT(item);
@@ -1766,11 +1795,14 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
}
if (model) {
- model->emitDataChanged(this, column);
+ const QVector<int> roles((role == Qt::DisplayRole || role == Qt::EditRole) ?
+ QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
+ QVector<int>({role}));
+ model->emitDataChanged(this, column, roles);
if (role == Qt::CheckStateRole) {
QTreeWidgetItem *p;
for (p = par; p && (p->itemFlags & Qt::ItemIsAutoTristate); p = p->par)
- model->emitDataChanged(p, column);
+ model->emitDataChanged(p, column, roles);
}
}
}
@@ -1937,6 +1969,7 @@ void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
stack.push(i->children.at(c));
}
children.insert(index, child);
+ d->updateHiddenStatus(child, true);
model->endInsertItems();
model->skipPendingSort = wasSkipSort;
} else {
@@ -1974,6 +2007,7 @@ QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
}
if (index >= 0 && index < children.count()) {
if (model) model->beginRemoveItems(this, index, 1);
+ d->updateHiddenStatus(children.at(index), false);
QTreeWidgetItem *item = children.takeAt(index);
item->par = 0;
QStack<QTreeWidgetItem*> stack;
@@ -2052,6 +2086,7 @@ void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &c
this->children.insert(index + n, child);
if (child->par)
d->propagateDisabled(child);
+ d->updateHiddenStatus(child, true);
}
if (model) model->endInsertItems();
}
@@ -3099,6 +3134,8 @@ bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const
*/
void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
{
+ if (!item)
+ return;
Q_D(QTreeWidget);
if (item == d->treeModel()->headerItem) {
header()->setHidden(hide);
@@ -3106,6 +3143,7 @@ void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide)
const QModelIndex index = d->index(item);
setRowHidden(index.row(), index.parent(), hide);
}
+ item->d->hidden = hide;
}
/*!
diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h
index a31af0428a..975f208702 100644
--- a/src/widgets/itemviews/qtreewidget.h
+++ b/src/widgets/itemviews/qtreewidget.h
@@ -82,8 +82,8 @@ public:
inline void setSelected(bool select);
inline bool isSelected() const;
- inline void setHidden(bool hide);
- inline bool isHidden() const;
+ void setHidden(bool hide);
+ bool isHidden() const;
inline void setExpanded(bool expand);
inline bool isExpanded() const;
@@ -339,6 +339,7 @@ Q_SIGNALS:
void itemDoubleClicked(QTreeWidgetItem *item, int column);
void itemActivated(QTreeWidgetItem *item, int column);
void itemEntered(QTreeWidgetItem *item, int column);
+ // ### Qt 6: add changed roles
void itemChanged(QTreeWidgetItem *item, int column);
void itemExpanded(QTreeWidgetItem *item);
void itemCollapsed(QTreeWidgetItem *item);
@@ -409,12 +410,6 @@ inline void QTreeWidgetItem::setSelected(bool aselect)
inline bool QTreeWidgetItem::isSelected() const
{ return (view ? view->isItemSelected(this) : false); }
-inline void QTreeWidgetItem::setHidden(bool ahide)
-{ if (view) view->setItemHidden(this, ahide); }
-
-inline bool QTreeWidgetItem::isHidden() const
-{ return (view ? view->isItemHidden(this) : false); }
-
inline void QTreeWidgetItem::setExpanded(bool aexpand)
{ if (view) view->setItemExpanded(this, aexpand); }
diff --git a/src/widgets/itemviews/qtreewidget_p.h b/src/widgets/itemviews/qtreewidget_p.h
index f4625842ef..adc2c2c421 100644
--- a/src/widgets/itemviews/qtreewidget_p.h
+++ b/src/widgets/itemviews/qtreewidget_p.h
@@ -139,7 +139,7 @@ public:
protected:
QTreeModel(QTreeModelPrivate &, QTreeWidget *parent = 0);
- void emitDataChanged(QTreeWidgetItem *item, int column);
+ void emitDataChanged(QTreeWidgetItem *item, int column, const QVector<int> &roles);
void beginInsertItems(QTreeWidgetItem *parent, int row, int count);
void endInsertItems();
void beginRemoveItems(QTreeWidgetItem *parent, int row, int count);
@@ -187,13 +187,16 @@ class QTreeWidgetItemPrivate
{
public:
QTreeWidgetItemPrivate(QTreeWidgetItem *item)
- : q(item), disabled(false), selected(false), rowGuess(-1), policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {}
+ : q(item), disabled(false), selected(false), hidden(false), rowGuess(-1),
+ policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {}
void propagateDisabled(QTreeWidgetItem *item);
+ void updateHiddenStatus(QTreeWidgetItem *item, bool inserting);
void sortChildren(int column, Qt::SortOrder order, bool climb);
QTreeWidgetItem *q;
QVariantList display;
uint disabled : 1;
uint selected : 1;
+ uint hidden : 1;
int rowGuess;
QTreeWidgetItem::ChildIndicatorPolicy policy;
};
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri
index 1bdcecbc81..c2f6e4ce75 100644
--- a/src/widgets/kernel/kernel.pri
+++ b/src/widgets/kernel/kernel.pri
@@ -35,7 +35,8 @@ HEADERS += \
kernel/qgesturemanager_p.h \
kernel/qdesktopwidget_p.h \
kernel/qwidgetwindow_p.h \
- kernel/qwindowcontainer_p.h
+ kernel/qwindowcontainer_p.h \
+ kernel/qtestsupport_widgets.h
SOURCES += \
kernel/qaction.cpp \
@@ -60,7 +61,8 @@ SOURCES += \
kernel/qdesktopwidget.cpp \
kernel/qwidgetsvariant.cpp \
kernel/qwidgetwindow.cpp \
- kernel/qwindowcontainer.cpp
+ kernel/qwindowcontainer.cpp \
+ kernel/qtestsupport_widgets.cpp
macx: {
HEADERS += kernel/qmacgesturerecognizer_p.h
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index ba315d4338..038226c521 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -110,6 +110,8 @@
#include <qpa/qplatformwindow.h>
+#include <qtwidgets_tracepoints_p.h>
+
//#define ALIEN_DEBUG
static void initResources()
@@ -1025,17 +1027,17 @@ QString QApplication::styleSheet() const
void QApplication::setStyleSheet(const QString& styleSheet)
{
QApplicationPrivate::styleSheet = styleSheet;
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
+ QStyleSheetStyle *styleSheetStyle = qt_styleSheet(QApplicationPrivate::app_style);
if (styleSheet.isEmpty()) { // application style sheet removed
- if (!proxy)
+ if (!styleSheetStyle)
return; // there was no stylesheet before
- setStyle(proxy->base);
- } else if (proxy) { // style sheet update, just repolish
- proxy->repolish(qApp);
+ setStyle(styleSheetStyle->base);
+ } else if (styleSheetStyle) { // style sheet update, just repolish
+ styleSheetStyle->repolish(qApp);
} else { // stylesheet set the first time
- QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
- QApplicationPrivate::app_style->setParent(newProxy);
- setStyle(newProxy);
+ QStyleSheetStyle *newStyleSheetStyle = new QStyleSheetStyle(QApplicationPrivate::app_style);
+ QApplicationPrivate::app_style->setParent(newStyleSheetStyle);
+ setStyle(newStyleSheetStyle);
}
}
@@ -1145,11 +1147,11 @@ void QApplication::setStyle(QStyle *style)
QStyle *old = QApplicationPrivate::app_style; // save
#ifndef QT_NO_STYLE_STYLESHEET
- if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
+ if (!QApplicationPrivate::styleSheet.isEmpty() && !qt_styleSheet(style)) {
// we have a stylesheet already and a new style is being set
- QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
- style->setParent(newProxy);
- QApplicationPrivate::app_style = newProxy;
+ QStyleSheetStyle *newStyleSheetStyle = new QStyleSheetStyle(style);
+ style->setParent(newStyleSheetStyle);
+ QApplicationPrivate::app_style = newStyleSheetStyle;
} else
#endif // QT_NO_STYLE_STYLESHEET
QApplicationPrivate::app_style = style;
@@ -1199,8 +1201,8 @@ void QApplication::setStyle(QStyle *style)
}
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
- oldProxy->deref();
+ if (QStyleSheetStyle *oldStyleSheetStyle = qt_styleSheet(old)) {
+ oldStyleSheetStyle->deref();
} else
#endif
if (old && old->parent() == qApp) {
@@ -2627,7 +2629,7 @@ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint
bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
QWidget *alienWidget, QWidget *nativeWidget,
QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
- bool spontaneous)
+ bool spontaneous, bool onlyDispatchEnterLeave)
{
Q_ASSERT(receiver);
Q_ASSERT(event);
@@ -2688,11 +2690,17 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
// We need this quard in case someone opens a modal dialog / popup. If that's the case
// leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
- bool result;
- if (spontaneous)
- result = QApplication::sendSpontaneousEvent(receiver, event);
- else
- result = QApplication::sendEvent(receiver, event);
+ bool result = true;
+ // This code is used for sending the synthetic enter/leave events for cases where it is needed
+ // due to other events causing the widget under the mouse to change. However in those cases
+ // we do not want to send the mouse event associated with this call, so this enables us to
+ // not send the unneeded mouse event
+ if (!onlyDispatchEnterLeave) {
+ if (spontaneous)
+ result = QApplication::sendSpontaneousEvent(receiver, event);
+ else
+ result = QApplication::sendEvent(receiver, event);
+ }
if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
&& !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
@@ -2767,9 +2775,10 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
if (widget->data->in_destructor && qt_button_down == widget)
qt_button_down = 0;
- // Send enter/leave events followed by a mouse move on the entered widget.
+ // A mouse move is not actually sent, but we utilize the sendMouseEvent() call to send the
+ // enter/leave events as appropriate
QMouseEvent e(QEvent::MouseMove, pos, windowPos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
- sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
+ sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver, true, true);
#else // !QT_NO_CURSOR
Q_UNUSED(widget);
#endif // QT_NO_CURSOR
@@ -2947,8 +2956,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
d->checkReceiverThread(receiver);
#endif
- if (receiver->isWindowType())
- QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(receiver), e);
+ if (receiver->isWindowType()) {
+ if (QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(receiver), e))
+ return true; // Platform plugin ate the event
+ }
if(e->spontaneous()) {
// Capture the current mouse and keyboard states. Doing so here is
@@ -3288,6 +3299,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
wheel->modifiers(), phase, wheel->source(), wheel->inverted());
+ we.setTimestamp(wheel->timestamp());
bool eventAccepted;
do {
we.spont = spontaneous && w == receiver;
@@ -3324,6 +3336,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPos());
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
wheel->modifiers(), wheel->phase(), wheel->source());
+ we.setTimestamp(wheel->timestamp());
we.spont = true;
we.ignore();
d->notify_helper(QApplicationPrivate::wheel_widget, &we);
@@ -3375,6 +3388,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
tablet->modifiers(), tablet->uniqueId(), tablet->button(), tablet->buttons());
te.spont = e->spontaneous();
+ te.setAccepted(false);
res = d->notify_helper(w, w == receiver ? tablet : &te);
eventAccepted = ((w == receiver) ? tablet : &te)->isAccepted();
e->spont = false;
@@ -3649,7 +3663,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
break;
w = w->parentWidget();
}
- foreach (QGesture *g, allGestures)
+ for (QGesture *g : qAsConst(allGestures))
gestureEvent->setAccepted(g, false);
gestureEvent->m_accept = false; // to make sure we check individual gestures
} else {
@@ -3696,11 +3710,19 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
{
+ // These tracepoints (and the whole function, actually) are very similar
+ // to the ones in QCoreApplicationPrivate::notify_helper; the reason for their
+ // duplication is because tracepoint symbols are not exported by QtCore.
+ // If you adjust the tracepoints here, consider adjusting QCoreApplicationPrivate too.
+ Q_TRACE(QApplication_notify_entry, receiver, e, e->type());
+
// send to all application event filters
if (threadRequiresCoreApplication()
&& receiver->d_func()->threadData->thread == mainThread()
- && sendThroughApplicationEventFilters(receiver, e))
+ && sendThroughApplicationEventFilters(receiver, e)) {
+ Q_TRACE(QApplication_notify_event_filtered, receiver, e, e->type());
return true;
+ }
if (receiver->isWidgetType()) {
QWidget *widget = static_cast<QWidget *>(receiver);
@@ -3720,11 +3742,18 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
}
// send to all receiver event filters
- if (sendThroughObjectEventFilters(receiver, e))
+ if (sendThroughObjectEventFilters(receiver, e)) {
+ Q_TRACE(QApplication_notify_event_filtered, receiver, e, e->type());
return true;
+ }
+
+ Q_TRACE(QApplication_notify_before_delivery, receiver, e, e->type());
// deliver the event
- bool consumed = receiver->event(e);
+ const bool consumed = receiver->event(e);
+
+ Q_TRACE(QApplication_notify_after_delivery, receiver, e, e->type(), consumed);
+
QCoreApplicationPrivate::setEventSpontaneous(e, false);
return consumed;
}
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 488ca6cbfd..2d9468cc21 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -226,7 +226,7 @@ public:
QWidget *buttonDown, QWidget *alienWidget);
static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget,
QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
- bool spontaneous = true);
+ bool spontaneous = true, bool onlyDispatchEnterLeave = false);
void sendSyntheticEnterLeave(QWidget *widget);
static QWindow *windowForWidget(const QWidget *widget)
diff --git a/src/widgets/kernel/qgesture.cpp b/src/widgets/kernel/qgesture.cpp
index 7f8bf18e90..fc715687c6 100644
--- a/src/widgets/kernel/qgesture.cpp
+++ b/src/widgets/kernel/qgesture.cpp
@@ -916,7 +916,7 @@ QGesture *QGestureEvent::gesture(Qt::GestureType type) const
QList<QGesture *> QGestureEvent::activeGestures() const
{
QList<QGesture *> gestures;
- foreach (QGesture *gesture, m_gestures) {
+ for (QGesture *gesture : m_gestures) {
if (gesture->state() != Qt::GestureCanceled)
gestures.append(gesture);
}
@@ -929,7 +929,7 @@ QList<QGesture *> QGestureEvent::activeGestures() const
QList<QGesture *> QGestureEvent::canceledGestures() const
{
QList<QGesture *> gestures;
- foreach (QGesture *gesture, m_gestures) {
+ for (QGesture *gesture : m_gestures) {
if (gesture->state() == Qt::GestureCanceled)
gestures.append(gesture);
}
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index 9ce1c1c2d4..eac5674161 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -109,10 +109,11 @@ static int menuBarHeightForWidth(QWidget *menubar, int w)
/*!
Constructs a new top-level QLayout, with parent \a parent.
- \a parent may not be 0.
+ \a parent may not be a \c nullptr.
- There can be only one top-level layout for a widget. It is
- returned by QWidget::layout().
+ The layout is set directly as the top-level layout for
+ \a parent. There can be only one top-level layout for a
+ widget. It is returned by QWidget::layout().
*/
QLayout::QLayout(QWidget *parent)
: QObject(*new QLayoutPrivate, parent)
@@ -1246,6 +1247,26 @@ int QLayout::indexOf(QWidget *widget) const
}
/*!
+ \since 5.12
+ Searches for layout item \a layoutItem in this layout (not including child
+ layouts).
+
+ Returns the index of \a layoutItem, or -1 if \a layoutItem is not found.
+*/
+int QLayout::indexOf(QLayoutItem *layoutItem) const
+{
+ int i = 0;
+ QLayoutItem *item = itemAt(i);
+ while (item) {
+ if (item == layoutItem)
+ return i;
+ ++i;
+ item = itemAt(i);
+ }
+ return -1;
+}
+
+/*!
\enum QLayout::SizeConstraint
The possible values are:
diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h
index bcc33a0811..616f4e7164 100644
--- a/src/widgets/kernel/qlayout.h
+++ b/src/widgets/kernel/qlayout.h
@@ -122,6 +122,7 @@ public:
virtual QLayoutItem *itemAt(int index) const = 0;
virtual QLayoutItem *takeAt(int index) = 0;
virtual int indexOf(QWidget *) const;
+ QT6_VIRTUAL int indexOf(QLayoutItem *) const;
virtual int count() const = 0;
bool isEmpty() const override;
QSizePolicy::ControlTypes controlTypes() const override;
diff --git a/src/widgets/kernel/qmacgesturerecognizer_p.h b/src/widgets/kernel/qmacgesturerecognizer_p.h
index e381a6cc2f..739fc201b7 100644
--- a/src/widgets/kernel/qmacgesturerecognizer_p.h
+++ b/src/widgets/kernel/qmacgesturerecognizer_p.h
@@ -66,9 +66,9 @@ class QMacSwipeGestureRecognizer : public QGestureRecognizer
public:
QMacSwipeGestureRecognizer();
- QGesture *create(QObject *target);
- QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
- void reset(QGesture *gesture);
+ QGesture *create(QObject *target) override;
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
+ void reset(QGesture *gesture) override;
};
class QMacPinchGestureRecognizer : public QGestureRecognizer
@@ -76,9 +76,9 @@ class QMacPinchGestureRecognizer : public QGestureRecognizer
public:
QMacPinchGestureRecognizer();
- QGesture *create(QObject *target);
- QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
- void reset(QGesture *gesture);
+ QGesture *create(QObject *target) override;
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
+ void reset(QGesture *gesture) override;
};
class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
@@ -86,9 +86,9 @@ class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
public:
QMacPanGestureRecognizer();
- QGesture *create(QObject *target);
- QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
- void reset(QGesture *gesture);
+ QGesture *create(QObject *target) override;
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
+ void reset(QGesture *gesture) override;
protected:
void timerEvent(QTimerEvent *ev) override;
private:
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index c96b6812c4..ed0fe0ed91 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -906,9 +906,19 @@ void QOpenGLWidgetPrivate::invalidateFbo()
const int gl_color_attachment0 = 0x8CE0; // GL_COLOR_ATTACHMENT0
const int gl_depth_attachment = 0x8D00; // GL_DEPTH_ATTACHMENT
const int gl_stencil_attachment = 0x8D20; // GL_STENCIL_ATTACHMENT
+#ifdef Q_OS_WASM
+ // webgl does not allow separate depth and stencil attachments
+ // QTBUG-69913
+ const int gl_depth_stencil_attachment = 0x821A; // GL_DEPTH_STENCIL_ATTACHMENT
+
+ const GLenum attachments[] = {
+ gl_color_attachment0, gl_depth_attachment, gl_stencil_attachment, gl_depth_stencil_attachment
+ };
+#else
const GLenum attachments[] = {
gl_color_attachment0, gl_depth_attachment, gl_stencil_attachment
};
+#endif
f->glDiscardFramebufferEXT(GL_FRAMEBUFFER, sizeof attachments / sizeof *attachments, attachments);
} else {
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -938,7 +948,8 @@ QImage QOpenGLWidgetPrivate::grabFramebuffer()
q->makeCurrent();
}
- QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatioF(), false, false);
+ const bool hasAlpha = q->format().hasAlpha();
+ QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatioF(), hasAlpha, hasAlpha);
res.setDevicePixelRatio(q->devicePixelRatioF());
// While we give no guarantees of what is going to be left bound, prefer the
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index fde039c75e..a680ff7913 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -149,8 +149,16 @@ static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidge
bool visible = w->isVisible();
#if QT_CONFIG(menubar)
if (QMenuBar *menuBar = qobject_cast<QMenuBar *>(w)) {
- if (menuBar->isNativeMenuBar())
- visible = true;
+ if (auto *pmb = menuBar->platformMenuBar()) {
+ if (menuBar->parentWidget()) {
+ visible = true;
+ } else {
+ if (auto *ww = qobject_cast<QWidgetWindow *>(pmb->parentWindow()))
+ w = ww->widget(); // Good enough since we only care about the window
+ else
+ return false; // This is not a QWidget window. We won't deliver
+ }
+ }
}
#endif
diff --git a/src/widgets/kernel/qtestsupport_widgets.cpp b/src/widgets/kernel/qtestsupport_widgets.cpp
new file mode 100644
index 0000000000..b227e6ff5d
--- /dev/null
+++ b/src/widgets/kernel/qtestsupport_widgets.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtestsupport_widgets.h"
+
+#include "qwidget.h"
+
+#include <QtGui/qwindow.h>
+#include <QtGui/qtestsupport_gui.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \fn bool qWaitForWindowActive(QWidget *widget, int timeout)
+ \relates QTest
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a widget's window is active.
+
+ Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false.
+
+ \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow()
+*/
+Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
+{
+ if (QWindow *window = widget->window()->windowHandle())
+ return QTest::qWaitForWindowActive(window, timeout);
+ return false;
+}
+
+/*! \fn bool qWaitForWindowExposed(QWidget *widget, int timeout)
+ \relates QTest
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a widget's window is exposed.
+ Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
+
+ This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
+ time after being asked to show itself on the screen.
+
+ Note that a window that is mapped to screen may still not be considered exposed if the window client
+ area is completely covered by other windows, or if the window is otherwise not visible. This function
+ will then time out when waiting for such a window.
+
+ A specific configuration where this happens is when using QGLWidget as a viewport widget on macOS:
+ The viewport widget gets the expose event, not the parent widget.
+
+ \sa QTest::qWaitForWindowActive()
+*/
+Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
+{
+ if (QWindow *window = widget->window()->windowHandle())
+ return QTest::qWaitForWindowExposed(window, timeout);
+ return false;
+}
+
+/*! \fn bool qWaitForWindowShown(QWidget *widget, int timeout)
+ \relates QTest
+ \since 5.0
+ \deprecated
+
+ Waits for \a timeout milliseconds or until the \a widget's window is exposed.
+ Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
+
+ This function does the same as qWaitForWindowExposed().
+
+ Example:
+
+ \code
+ QWidget widget;
+ widget.show();
+ QTest::qWaitForWindowShown(&widget);
+ \endcode
+
+ \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qtestsupport_widgets.h b/src/widgets/kernel/qtestsupport_widgets.h
new file mode 100644
index 0000000000..ca1406b0b2
--- /dev/null
+++ b/src/widgets/kernel/qtestsupport_widgets.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTSUPPORT_WIDGETS_H
+#define QTESTSUPPORT_WIDGETS_H
+
+#include "qtwidgetsglobal.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+
+namespace QTest {
+Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool qWaitForWindowActive(QWidget *widget, int timeout = 5000);
+Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool qWaitForWindowExposed(QWidget *widget, int timeout = 5000);
+
+#if QT_DEPRECATED_SINCE(5, 0)
+QT_DEPRECATED Q_REQUIRED_RESULT inline static bool qWaitForWindowShown(QWidget *widget, int timeout = 5000)
+{ return QTest::qWaitForWindowExposed(widget, timeout); }
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index ed7184302a..8c5573d3a3 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -123,11 +123,11 @@ class QTipLabel : public QLabel
{
Q_OBJECT
public:
- QTipLabel(const QString &text, QWidget *w, int msecDisplayTime);
+ QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int msecDisplayTime);
~QTipLabel();
static QTipLabel *instance;
- void updateSize();
+ void updateSize(const QPoint &pos);
bool eventFilter(QObject *, QEvent *) override;
@@ -135,7 +135,7 @@ public:
bool fadingOut;
- void reuseTip(const QString &text, int msecDisplayTime);
+ void reuseTip(const QString &text, int msecDisplayTime, const QPoint &pos);
void hideTip();
void hideTipImmediately();
void setTipRect(QWidget *w, const QRect &r);
@@ -171,7 +171,7 @@ private:
QTipLabel *QTipLabel::instance = 0;
-QTipLabel::QTipLabel(const QString &text, QWidget *w, int msecDisplayTime)
+QTipLabel::QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int msecDisplayTime)
#ifndef QT_NO_STYLE_STYLESHEET
: QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), styleSheetParent(0), widget(0)
#else
@@ -192,7 +192,7 @@ QTipLabel::QTipLabel(const QString &text, QWidget *w, int msecDisplayTime)
setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0);
setMouseTracking(true);
fadingOut = false;
- reuseTip(text, msecDisplayTime);
+ reuseTip(text, msecDisplayTime, pos);
}
void QTipLabel::restartExpireTimer(int msecDisplayTime)
@@ -204,7 +204,7 @@ void QTipLabel::restartExpireTimer(int msecDisplayTime)
hideTimer.stop();
}
-void QTipLabel::reuseTip(const QString &text, int msecDisplayTime)
+void QTipLabel::reuseTip(const QString &text, int msecDisplayTime, const QPoint &pos)
{
#ifndef QT_NO_STYLE_STYLESHEET
if (styleSheetParent){
@@ -214,20 +214,30 @@ void QTipLabel::reuseTip(const QString &text, int msecDisplayTime)
}
#endif
- setWordWrap(Qt::mightBeRichText(text));
+ setWordWrap(true);
setText(text);
- updateSize();
+ updateSize(pos);
restartExpireTimer(msecDisplayTime);
}
-void QTipLabel::updateSize()
+void QTipLabel::updateSize(const QPoint &pos)
{
QFontMetrics fm(font());
QSize extra(1, 0);
// Make it look good with the default ToolTip font on Mac, which has a small descent.
if (fm.descent() == 2 && fm.ascent() >= 11)
++extra.rheight();
- resize(sizeHint() + extra);
+ QSize sh = sizeHint();
+ if (wordWrap()) {
+ const QRect screenRect = QGuiApplication::screenAt(pos)->geometry();
+ if (sh.width() > screenRect.width()) {
+ // Try to use widely accepted 75chars max length or 80% of the screen width else.
+ // See https://en.wikipedia.org/wiki/Line_length
+ sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast<int>(screenRect.width() * .8)));
+ sh.setHeight(heightForWidth(sh.width()));
+ }
+ }
+ resize(sh + extra);
}
void QTipLabel::paintEvent(QPaintEvent *ev)
@@ -254,13 +264,13 @@ void QTipLabel::resizeEvent(QResizeEvent *e)
void QTipLabel::mouseMoveEvent(QMouseEvent *e)
{
- if (rect.isNull())
- return;
- QPoint pos = e->globalPos();
- if (widget)
- pos = widget->mapFromGlobal(pos);
- if (!rect.contains(pos))
- hideTip();
+ if (!rect.isNull()) {
+ QPoint pos = e->globalPos();
+ if (widget)
+ pos = widget->mapFromGlobal(pos);
+ if (!rect.contains(pos))
+ hideTip();
+ }
QLabel::mouseMoveEvent(e);
}
@@ -381,7 +391,7 @@ int QTipLabel::getTipScreen(const QPoint &pos, QWidget *w)
void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
{
#ifndef QT_NO_STYLE_STYLESHEET
- if (testAttribute(Qt::WA_StyleSheet) || (w && qobject_cast<QStyleSheetStyle *>(w->style()))) {
+ if (testAttribute(Qt::WA_StyleSheet) || (w && qt_styleSheet(w->style()))) {
//the stylesheet need to know the real parent
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.
@@ -394,7 +404,7 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
QTipLabel::instance, SLOT(styleSheetParentDestroyed()));
// QTBUG-64550: A font inherited by the style sheet might change the size,
// particular on Windows, where the tip is not parented on a window.
- QTipLabel::instance->updateSize();
+ QTipLabel::instance->updateSize(pos);
}
}
#endif //QT_NO_STYLE_STYLESHEET
@@ -497,7 +507,7 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
if (w)
localPos = w->mapFromGlobal(pos);
if (QTipLabel::instance->tipChanged(localPos, text, w)){
- QTipLabel::instance->reuseTip(text, msecDisplayTime);
+ QTipLabel::instance->reuseTip(text, msecDisplayTime, pos);
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
}
@@ -511,10 +521,10 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
// raised when the tooltip will be shown
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
- new QTipLabel(text, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)), msecDisplayTime);
+ new QTipLabel(text, pos, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)), msecDisplayTime);
QT_WARNING_POP
#else
- new QTipLabel(text, w, msecDisplayTime); // sets QTipLabel::instance to itself
+ new QTipLabel(text, pos, w, msecDisplayTime); // sets QTipLabel::instance to itself
#endif
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp
index 96d0cf61c4..1fa83d3238 100644
--- a/src/widgets/kernel/qwhatsthis.cpp
+++ b/src/widgets/kernel/qwhatsthis.cpp
@@ -48,7 +48,9 @@
#include "qscreen.h"
#include "qpainter.h"
#include "qtimer.h"
+#if QT_CONFIG(action)
#include "qaction.h"
+#endif // QT_CONFIG(action)
#include "qcursor.h"
#include "qbitmap.h"
#include "qtextdocument.h"
@@ -366,7 +368,9 @@ class QWhatsThisPrivate : public QObject
~QWhatsThisPrivate();
static QWhatsThisPrivate *instance;
bool eventFilter(QObject *, QEvent *) override;
+#if QT_CONFIG(action)
QPointer<QAction> action;
+#endif // QT_CONFIG(action)
static void say(QWidget *, const QString &, int x = 0, int y = 0);
static void notifyToplevels(QEvent *e);
bool leaveOnMouseRelease;
@@ -408,8 +412,10 @@ QWhatsThisPrivate::QWhatsThisPrivate()
QWhatsThisPrivate::~QWhatsThisPrivate()
{
+#if QT_CONFIG(action)
if (action)
action->setChecked(false);
+#endif // QT_CONFIG(action)
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
@@ -485,6 +491,7 @@ bool QWhatsThisPrivate::eventFilter(QObject *o, QEvent *e)
return true;
}
+#if QT_CONFIG(action)
class QWhatsThisAction: public QAction
{
Q_OBJECT
@@ -516,6 +523,7 @@ void QWhatsThisAction::actionTriggered()
QWhatsThisPrivate::instance->action = this;
}
}
+#endif // QT_CONFIG(action)
/*!
This function switches the user interface into "What's This?"
@@ -672,10 +680,12 @@ void QWhatsThis::hideText()
The returned QAction provides a convenient way to let users enter
"What's This?" mode.
*/
+#if QT_CONFIG(action)
QAction *QWhatsThis::createAction(QObject *parent)
{
return new QWhatsThisAction(parent);
}
+#endif // QT_CONFIG(action)
QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwhatsthis.h b/src/widgets/kernel/qwhatsthis.h
index 1f0f82b2a2..59c0b01c9b 100644
--- a/src/widgets/kernel/qwhatsthis.h
+++ b/src/widgets/kernel/qwhatsthis.h
@@ -48,7 +48,9 @@ QT_REQUIRE_CONFIG(whatsthis);
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(action)
class QAction;
+#endif // QT_CONFIG(action)
class Q_WIDGETS_EXPORT QWhatsThis
{
@@ -62,7 +64,9 @@ public:
static void showText(const QPoint &pos, const QString &text, QWidget *w = nullptr);
static void hideText();
+#if QT_CONFIG(action)
static QAction *createAction(QObject *parent = nullptr);
+#endif // QT_CONFIG(action)
};
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 1e249dc191..4adccceebb 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1138,7 +1138,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
q->data = &data;
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
if (!parent) {
Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
"Widgets must be created in the GUI thread.");
@@ -1849,7 +1849,7 @@ void QWidgetPrivate::deleteExtra()
deleteSysExtra();
#ifndef QT_NO_STYLE_STYLESHEET
// dereference the stylesheet style
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style))
+ if (QStyleSheetStyle *proxy = qt_styleSheet(extra->style))
proxy->deref();
#endif
if (extra->topextra) {
@@ -1905,19 +1905,21 @@ void QWidgetPrivate::deleteTLSysExtra()
}
/*
- Returns \c true if there are widgets above this which overlap with
+ Returns \c region of widgets above this which overlap with
\a rect, which is in parent's coordinate system (same as crect).
*/
-bool QWidgetPrivate::isOverlapped(const QRect &rect) const
+QRegion QWidgetPrivate::overlappedRegion(const QRect &rect, bool breakAfterFirst) const
{
Q_Q(const QWidget);
const QWidget *w = q;
QRect r = rect;
+ QPoint p;
+ QRegion region;
while (w) {
if (w->isWindow())
- return false;
+ break;
QWidgetPrivate *pd = w->parentWidget()->d_func();
bool above = false;
for (int i = 0; i < pd->children.size(); ++i) {
@@ -1929,19 +1931,23 @@ bool QWidgetPrivate::isOverlapped(const QRect &rect) const
continue;
}
- if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) {
+ const QRect siblingRect = sibling->d_func()->effectiveRectFor(sibling->data->crect);
+ if (qRectIntersects(siblingRect, r)) {
const QWExtra *siblingExtra = sibling->d_func()->extra;
if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
&& !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
continue;
}
- return true;
+ region += siblingRect.translated(-p);
+ if (breakAfterFirst)
+ break;
}
}
w = w->parentWidget();
r.translate(pd->data.crect.topLeft());
+ p += pd->data.crect.topLeft();
}
- return false;
+ return region;
}
void QWidgetPrivate::syncBackingStore()
@@ -2398,7 +2404,8 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrus
#endif
} else if (brush.gradient()
- && brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
+ && (brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode
+ || brush.gradient()->coordinateMode() == QGradient::ObjectMode)) {
painter->save();
painter->setClipRegion(rgn);
painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush);
@@ -2659,7 +2666,7 @@ void QWidget::setStyleSheet(const QString& styleSheet)
return;
d->createExtra();
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style);
+ QStyleSheetStyle *proxy = qt_styleSheet(d->extra->style);
d->extra->styleSheet = styleSheet;
if (styleSheet.isEmpty()) { // stylesheet removed
if (!proxy)
@@ -2724,12 +2731,12 @@ void QWidget::setStyle(QStyle *style)
setAttribute(Qt::WA_SetStyle, style != 0);
d->createExtra();
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(style)) {
+ if (QStyleSheetStyle *styleSheetStyle = qt_styleSheet(style)) {
//if for some reason someone try to set a QStyleSheetStyle, ref it
//(this may happen for exemple in QButtonDialogBox which propagates its style)
- proxy->ref();
+ styleSheetStyle->ref();
d->setStyle_helper(style, false);
- } else if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty()) {
+ } else if (qt_styleSheet(d->extra->style) || !qApp->styleSheet().isEmpty()) {
// if we have an application stylesheet or have a proxy already, propagate
d->setStyle_helper(new QStyleSheetStyle(style), true);
} else
@@ -2737,48 +2744,22 @@ void QWidget::setStyle(QStyle *style)
d->setStyle_helper(style, false);
}
-void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
-#if 0 // Used to be included in Qt4 for Q_WS_MAC
- metalHack
-#endif
- )
+void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate)
{
Q_Q(QWidget);
- QStyle *oldStyle = q->style();
-#ifndef QT_NO_STYLE_STYLESHEET
- QPointer<QStyle> origStyle;
-#endif
+ QStyle *oldStyle = q->style();
-#if 0 // Used to be included in Qt4 for Q_WS_MAC
- // the metalhack boolean allows Qt/Mac to do a proper re-polish depending
- // on how the Qt::WA_MacBrushedMetal attribute is set. It is only ever
- // set when changing that attribute and passes the widget's CURRENT style.
- // therefore no need to do a reassignment.
- if (!metalHack)
-#endif
- {
- createExtra();
+ createExtra();
#ifndef QT_NO_STYLE_STYLESHEET
- origStyle = extra->style.data();
+ QPointer<QStyle> origStyle = extra->style;
#endif
- extra->style = newStyle;
- }
+ extra->style = newStyle;
// repolish
- if (q->windowType() != Qt::Desktop) {
- if (polished) {
- oldStyle->unpolish(q);
-#if 0 // Used to be included in Qt4 for Q_WS_MAC
- if (metalHack)
- macUpdateMetalAttribute();
-#endif
- q->style()->polish(q);
-#if 0 // Used to be included in Qt4 for Q_WS_MAC
- } else if (metalHack) {
- macUpdateMetalAttribute();
-#endif
- }
+ if (polished && q->windowType() != Qt::Desktop) {
+ oldStyle->unpolish(q);
+ q->style()->polish(q);
}
if (propagate) {
@@ -2792,8 +2773,8 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
}
#ifndef QT_NO_STYLE_STYLESHEET
- if (!qobject_cast<QStyleSheetStyle*>(newStyle)) {
- if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) {
+ if (!qt_styleSheet(newStyle)) {
+ if (const QStyleSheetStyle* cssStyle = qt_styleSheet(origStyle)) {
cssStyle->clearWidgetFont(q);
}
}
@@ -2804,7 +2785,7 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
#ifndef QT_NO_STYLE_STYLESHEET
// dereference the old stylesheet style
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data()))
+ if (QStyleSheetStyle *proxy = qt_styleSheet(origStyle))
proxy->deref();
#endif
}
@@ -2815,7 +2796,9 @@ void QWidgetPrivate::inheritStyle()
#ifndef QT_NO_STYLE_STYLESHEET
Q_Q(QWidget);
- QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0;
+ QStyle *extraStyle = extra ? (QStyle*)extra->style : nullptr;
+
+ QStyleSheetStyle *proxy = qt_styleSheet(extraStyle);
if (!q->styleSheet().isEmpty()) {
Q_ASSERT(proxy);
@@ -2823,16 +2806,16 @@ void QWidgetPrivate::inheritStyle()
return;
}
- QStyle *origStyle = proxy ? proxy->base : (extra ? (QStyle*)extra->style : 0);
+ QStyle *origStyle = proxy ? proxy->base : extraStyle;
QWidget *parent = q->parentWidget();
QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : 0;
// If we have stylesheet on app or parent has stylesheet style, we need
// to be running a proxy
- if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) {
+ if (!qApp->styleSheet().isEmpty() || qt_styleSheet(parentStyle)) {
QStyle *newStyle = parentStyle;
if (q->testAttribute(Qt::WA_SetStyle))
newStyle = new QStyleSheetStyle(origStyle);
- else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(parentStyle))
+ else if (QStyleSheetStyle *newProxy = qt_styleSheet(parentStyle))
newProxy->ref();
setStyle_helper(newStyle, true);
@@ -2841,7 +2824,7 @@ void QWidgetPrivate::inheritStyle()
// So, we have no stylesheet on parent/app and we have an empty stylesheet
// we just need our original style back
- if (origStyle == (extra ? (QStyle*)extra->style : 0)) // is it any different?
+ if (origStyle == extraStyle) // is it any different?
return;
// We could have inherited the proxy from our parent (which has a custom style)
@@ -4690,9 +4673,8 @@ void QWidget::setFont(const QFont &font)
#ifndef QT_NO_STYLE_STYLESHEET
const QStyleSheetStyle* style;
- if (d->extra && (style = qobject_cast<const QStyleSheetStyle*>(d->extra->style))) {
+ if (d->extra && (style = qt_styleSheet(d->extra->style)))
style->saveWidgetFont(this, font);
- }
#endif
setAttribute(Qt::WA_SetFont, font.resolve() != 0);
@@ -4788,7 +4770,7 @@ void QWidgetPrivate::updateFont(const QFont &font)
Q_Q(QWidget);
#ifndef QT_NO_STYLE_STYLESHEET
const QStyleSheetStyle* cssStyle;
- cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0;
+ cssStyle = extra ? qt_styleSheet(extra->style) : 0;
const bool useStyleSheetPropagationInWidgetStyles =
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
#endif
@@ -6981,8 +6963,10 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
determineLastFocusChild(second, lastFocusChildOfSecond);
// If the tab order is already correct, exit early
- if (lastFocusChildOfFirst->d_func()->focus_next == second)
+ if (lastFocusChildOfFirst == second ||
+ lastFocusChildOfFirst->d_func()->focus_next == second) {
return;
+ }
// Note that we need to handle two different sections in the tab chain; The section
// that 'first' belongs to (firstSection), where we are about to insert 'second', and
@@ -7381,7 +7365,8 @@ QByteArray QWidget::saveGeometry() const
// Version history:
// - Qt 4.2 - 4.8.6, 5.0 - 5.3 : Version 1.0
// - Qt 4.8.6 - today, 5.4 - today: Version 2.0, save screen width in addition to check for high DPI scaling.
- quint16 majorVersion = 2;
+ // - Qt 5.12 - today : Version 3.0, save QWidget::geometry()
+ quint16 majorVersion = 3;
quint16 minorVersion = 0;
const int screenNumber = QDesktopWidgetPrivate::screenNumber(this);
stream << magicNumber
@@ -7397,7 +7382,8 @@ QByteArray QWidget::saveGeometry() const
<< qint32(screenNumber)
<< quint8(windowState() & Qt::WindowMaximized)
<< quint8(windowState() & Qt::WindowFullScreen)
- << qint32(QDesktopWidgetPrivate::screenGeometry(screenNumber).width()); // 1.1 onwards
+ << qint32(QDesktopWidgetPrivate::screenGeometry(screenNumber).width()) // added in 2.0
+ << geometry(); // added in 3.0
return array;
}
@@ -7437,7 +7423,7 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
if (storedMagicNumber != magicNumber)
return false;
- const quint16 currentMajorVersion = 2;
+ const quint16 currentMajorVersion = 3;
quint16 majorVersion = 0;
quint16 minorVersion = 0;
@@ -7448,7 +7434,8 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
// (Allow all minor versions.)
QRect restoredFrameGeometry;
- QRect restoredNormalGeometry;
+ QRect restoredGeometry;
+ QRect restoredNormalGeometry;
qint32 restoredScreenNumber;
quint8 maximized;
quint8 fullScreen;
@@ -7462,6 +7449,10 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
if (majorVersion > 1)
stream >> restoredScreenWidth;
+ if (majorVersion > 2)
+ stream >> restoredGeometry;
+
+ // ### Qt 6 - Perhaps it makes sense to dumb down the restoreGeometry() logic, see QTBUG-69104
if (restoredScreenNumber >= QDesktopWidgetPrivate::numScreens())
restoredScreenNumber = QDesktopWidgetPrivate::primaryScreen();
@@ -7548,14 +7539,11 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
setWindowState(ws);
d_func()->topData()->normalGeometry = restoredNormalGeometry;
} else {
- QPoint offset;
-#if 0 // Used to be included in Qt4 for Q_WS_X11
- if (isFullScreen())
- offset = d_func()->topData()->fullScreenOffset;
-#endif
setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowFullScreen));
- move(restoredFrameGeometry.topLeft() + offset);
- resize(restoredNormalGeometry.size());
+ if (majorVersion > 2)
+ setGeometry(restoredGeometry);
+ else
+ setGeometry(restoredNormalGeometry);
}
return true;
}
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index 9f9f167002..9d5fe89c70 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -714,6 +714,7 @@ private:
friend class QWidgetWindow;
friend class QAccessibleWidget;
friend class QAccessibleTable;
+ friend class QAccessibleTabButton;
#ifndef QT_NO_GESTURES
friend class QGestureManager;
friend class QWinNativePanGestureRecognizer;
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index e8b550b1cd..20c4a682ed 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -395,7 +395,7 @@ public:
void setLocale_helper(const QLocale &l, bool forceUpdate = false);
void resolveLocale();
- void setStyle_helper(QStyle *newStyle, bool propagate, bool metalHack = false);
+ void setStyle_helper(QStyle *newStyle, bool propagate);
void inheritStyle();
void setUpdatesEnabled_helper(bool );
@@ -453,7 +453,7 @@ public:
// ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
void invalidateBuffer(const QRegion &);
void invalidateBuffer(const QRect &);
- bool isOverlapped(const QRect&) const;
+ QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const;
void syncBackingStore();
void syncBackingStore(const QRegion &region);
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 3b093283cd..53769ef9ed 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -59,6 +59,7 @@
#include <private/qgraphicseffect_p.h>
#endif
#include <QtGui/private/qwindow_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <qpa/qplatformbackingstore.h>
@@ -759,7 +760,7 @@ void QWidgetBackingStore::updateLists(QWidget *cur)
QList<QObject*> children = cur->children();
for (int i = 0; i < children.size(); ++i) {
QWidget *child = qobject_cast<QWidget*>(children.at(i));
- if (!child)
+ if (!child || child->isWindow())
continue;
updateLists(child);
@@ -793,6 +794,25 @@ QWidgetBackingStore::~QWidgetBackingStore()
delete dirtyOnScreenWidgets;
}
+static QVector<QRect> getSortedRectsToScroll(const QRegion &region, int dx, int dy)
+{
+ QVector<QRect> rects;
+ std::copy(region.begin(), region.end(), std::back_inserter(rects));
+ if (rects.count() > 1) {
+ std::sort(rects.begin(), rects.end(), [=](const QRect &r1, const QRect &r2) {
+ if (r1.y() == r2.y()) {
+ if (dx > 0)
+ return r1.x() > r2.x();
+ return r1.x() < r2.x();
+ }
+ if (dy > 0)
+ return r1.y() > r2.y();
+ return r1.y() < r2.y();
+ });
+ }
+ return rects;
+}
+
//parent's coordinates; move whole rect; update parent and widget
//assume the screen blt has already been done, so we don't need to refresh that part
void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
@@ -820,12 +840,12 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
const QRect parentRect(rect & clipR);
const bool nativeWithTextureChild = textureChildSeen && q->internalWinId();
- bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild
+ const bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild
#if QT_CONFIG(graphicsview)
// No accelerate move for proxy widgets.
&& !tlw->d_func()->extra->proxyWidget
#endif
- && !isOverlapped(sourceRect) && !isOverlapped(destRect);
+ ;
if (!accelerateMove) {
QRegion parentR(effectiveRectFor(parentRect));
@@ -841,18 +861,39 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
QWidgetBackingStore *wbs = x->backingStoreTracker.data();
QRegion childExpose(newRect & clipR);
+ QRegion overlappedExpose;
- if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw))
- childExpose -= destRect;
+ if (sourceRect.isValid()) {
+ overlappedExpose = (overlappedRegion(sourceRect) | overlappedRegion(destRect)) & clipR;
+
+ const qreal factor = QHighDpiScaling::factor(q->windowHandle());
+ if (overlappedExpose.isEmpty() || qFloor(factor) == factor) {
+ const QVector<QRect> rectsToScroll
+ = getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy);
+ for (QRect rect : rectsToScroll) {
+ if (wbs->bltRect(rect, dx, dy, pw)) {
+ childExpose -= rect.translated(dx, dy);
+ }
+ }
+ }
+
+ childExpose -= overlappedExpose;
+ }
if (!pw->updatesEnabled())
return;
const bool childUpdatesEnabled = q->updatesEnabled();
- if (childUpdatesEnabled && !childExpose.isEmpty()) {
- childExpose.translate(-data.crect.topLeft());
- wbs->markDirty(childExpose, q);
- isMoved = true;
+ if (childUpdatesEnabled) {
+ if (!overlappedExpose.isEmpty()) {
+ overlappedExpose.translate(-data.crect.topLeft());
+ invalidateBuffer(overlappedExpose);
+ }
+ if (!childExpose.isEmpty()) {
+ childExpose.translate(-data.crect.topLeft());
+ wbs->markDirty(childExpose, q);
+ isMoved = true;
+ }
}
QRegion parentExpose(parentRect);
@@ -888,13 +929,12 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
static const bool accelEnv = qEnvironmentVariableIntValue("QT_NO_FAST_SCROLL") == 0;
- QRect scrollRect = rect & clipRect();
- bool overlapped = false;
- bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent)
- && !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft())));
+ const QRect clipR = clipRect();
+ const QRect scrollRect = rect & clipR;
+ const bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent);
if (!accelerateScroll) {
- if (overlapped) {
+ if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) {
QRegion region(scrollRect);
subtractOpaqueSiblings(region);
invalidateBuffer(region);
@@ -906,12 +946,23 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
const QRect destRect = scrollRect.translated(dx, dy) & scrollRect;
const QRect sourceRect = destRect.translated(-dx, -dy);
+ const QRegion overlappedExpose = (overlappedRegion(scrollRect.translated(data.crect.topLeft())))
+ .translated(-data.crect.topLeft()) & clipR;
QRegion childExpose(scrollRect);
- if (sourceRect.isValid()) {
- if (wbs->bltRect(sourceRect, dx, dy, q))
- childExpose -= destRect;
+
+ const qreal factor = QHighDpiScaling::factor(q->windowHandle());
+ if (overlappedExpose.isEmpty() || qFloor(factor) == factor) {
+ const QVector<QRect> rectsToScroll
+ = getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy);
+ for (const QRect &rect : rectsToScroll) {
+ if (wbs->bltRect(rect, dx, dy, q)) {
+ childExpose -= rect.translated(dx, dy);
+ }
+ }
}
+ childExpose -= overlappedExpose;
+
if (inDirtyList) {
if (rect == q->rect()) {
dirty.translate(dx, dy);
@@ -928,6 +979,8 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
if (!q->updatesEnabled())
return;
+ if (!overlappedExpose.isEmpty())
+ invalidateBuffer(overlappedExpose);
if (!childExpose.isEmpty()) {
wbs->markDirty(childExpose, q);
isScrolled = true;
@@ -991,7 +1044,7 @@ static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget)
}
}
- if (QWidgetPrivate::get(tlw)->textureChildSeen) {
+ if (QWidgetPrivate::get(widget)->textureChildSeen) {
// No render-to-texture widgets in the (sub-)tree due to hidden or native
// children. Returning null results in using the normal backingstore flush path
// without OpenGL-based compositing. This is very desirable normally. However,
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 1f3057b008..7292c795b8 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -311,8 +311,10 @@ bool QWidgetWindow::event(QEvent *event)
#if QT_CONFIG(draganddrop)
case QEvent::DragEnter:
+ handleDragEnterEvent(static_cast<QDragEnterEvent *>(event));
+ return true;
case QEvent::DragMove:
- handleDragEnterMoveEvent(static_cast<QDragMoveEvent *>(event));
+ handleDragMoveEvent(static_cast<QDragMoveEvent *>(event));
return true;
case QEvent::DragLeave:
handleDragLeaveEvent(static_cast<QDragLeaveEvent *>(event));
@@ -841,6 +843,7 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
QPoint mapped = widget->mapFrom(rootWidget, pos);
QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted());
+ translated.setTimestamp(event->timestamp());
QGuiApplication::forwardEvent(widget, &translated, event);
}
@@ -848,62 +851,80 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
#if QT_CONFIG(draganddrop)
-void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event)
+static QWidget *findDnDTarget(QWidget *parent, const QPoint &pos)
{
- Q_ASSERT(event->type() ==QEvent::DragMove || !m_dragTarget);
// Find a target widget under mouse that accepts drops (QTBUG-22987).
- QWidget *widget = m_widget->childAt(event->pos());
+ QWidget *widget = parent->childAt(pos);
if (!widget)
- widget = m_widget;
+ widget = parent;
for ( ; widget && !widget->isWindow() && !widget->acceptDrops(); widget = widget->parentWidget()) ;
if (widget && !widget->acceptDrops())
- widget = 0;
- // Target widget unchanged: DragMove
- if (widget && widget == m_dragTarget.data()) {
- Q_ASSERT(event->type() == QEvent::DragMove);
- const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
- QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
- translated.setDropAction(event->dropAction());
- if (event->isAccepted()) { // Handling 'DragEnter' should suffice for the application.
- translated.accept();
- translated.setDropAction(event->dropAction());
- }
- QGuiApplication::forwardEvent(widget, &translated, event);
- if (translated.isAccepted()) {
- event->accept();
- } else {
- event->ignore();
- }
- event->setDropAction(translated.dropAction());
- return;
- }
- // Target widget changed: Send DragLeave to previous, DragEnter to new if there is any
- if (m_dragTarget.data()) {
- QDragLeaveEvent le;
- QGuiApplication::forwardEvent(m_dragTarget.data(), &le, event);
- m_dragTarget = 0;
- }
+ widget = nullptr;
+ return widget;
+}
+
+void QWidgetWindow::handleDragEnterEvent(QDragEnterEvent *event, QWidget *widget)
+{
+ Q_ASSERT(m_dragTarget == nullptr);
+ if (!widget)
+ widget = findDnDTarget(m_widget, event->pos());
if (!widget) {
- event->ignore();
- return;
+ event->ignore();
+ return;
}
m_dragTarget = widget;
+
const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
- QDragEnterEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
- QGuiApplication::forwardEvent(widget, &translated, event);
- if (translated.isAccepted()) {
- event->accept();
- } else {
+ QDragEnterEvent translated(mapped, event->possibleActions(), event->mimeData(),
+ event->mouseButtons(), event->keyboardModifiers());
+ translated.setDropAction(event->dropAction());
+ translated.setAccepted(event->isAccepted());
+ QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
+ event->setAccepted(translated.isAccepted());
+ event->setDropAction(translated.dropAction());
+}
+
+void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event)
+{
+ auto *widget = findDnDTarget(m_widget, event->pos());
+ if (!widget) {
event->ignore();
+ if (m_dragTarget) { // Send DragLeave to previous
+ QDragLeaveEvent leaveEvent;
+ QGuiApplication::forwardEvent(m_dragTarget, &leaveEvent, event);
+ m_dragTarget = nullptr;
+ }
+ } else {
+ const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
+ QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(),
+ event->mouseButtons(), event->keyboardModifiers());
+ translated.setDropAction(event->dropAction());
+ translated.setAccepted(event->isAccepted());
+
+ if (widget == m_dragTarget) { // Target widget unchanged: Send DragMove
+ QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
+ } else {
+ if (m_dragTarget) { // Send DragLeave to previous
+ QDragLeaveEvent leaveEvent;
+ QGuiApplication::forwardEvent(m_dragTarget, &leaveEvent, event);
+ m_dragTarget = nullptr;
+ }
+ // Send DragEnter to new widget.
+ handleDragEnterEvent(static_cast<QDragEnterEvent*>(event), widget);
+ // The drag enter event is always immediately followed by a drag move event,
+ // see QDragEnterEvent documentation.
+ QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
+ }
+ event->setAccepted(translated.isAccepted());
+ event->setDropAction(translated.dropAction());
}
- event->setDropAction(translated.dropAction());
}
void QWidgetWindow::handleDragLeaveEvent(QDragLeaveEvent *event)
{
if (m_dragTarget)
- QGuiApplication::forwardEvent(m_dragTarget.data(), event);
- m_dragTarget = 0;
+ QGuiApplication::forwardEvent(m_dragTarget, event);
+ m_dragTarget = nullptr;
}
void QWidgetWindow::handleDropEvent(QDropEvent *event)
@@ -913,13 +934,12 @@ void QWidgetWindow::handleDropEvent(QDropEvent *event)
event->ignore();
return;
}
- const QPoint mapped = m_dragTarget.data()->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
+ const QPoint mapped = m_dragTarget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
QDropEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
- QGuiApplication::forwardEvent(m_dragTarget.data(), &translated, event);
- if (translated.isAccepted())
- event->accept();
+ QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
+ event->setAccepted(translated.isAccepted());
event->setDropAction(translated.dropAction());
- m_dragTarget = 0;
+ m_dragTarget = nullptr;
}
#endif // QT_CONFIG(draganddrop)
@@ -957,7 +977,10 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
}
if (exposed) {
+ // QTBUG-39220, QTBUG-58575: set all (potentially fully obscured parent widgets) mapped.
m_widget->setAttribute(Qt::WA_Mapped);
+ for (QWidget *p = m_widget->parentWidget(); p && !p->testAttribute(Qt::WA_Mapped); p = p->parentWidget())
+ p->setAttribute(Qt::WA_Mapped);
if (!event->region().isNull())
wPriv->syncBackingStore(event->region());
} else {
@@ -1021,6 +1044,7 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
event->pressure(), event->xTilt(), event->yTilt(), event->tangentialPressure(),
event->rotation(), event->z(), event->modifiers(), event->uniqueId(), event->button(), event->buttons());
ev.setTimestamp(event->timestamp());
+ ev.setAccepted(false);
QGuiApplication::forwardEvent(widget, &ev, event);
event->setAccepted(ev.isAccepted());
}
diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h
index ead099390e..0728135467 100644
--- a/src/widgets/kernel/qwidgetwindow_p.h
+++ b/src/widgets/kernel/qwidgetwindow_p.h
@@ -96,7 +96,8 @@ protected:
void handleWheelEvent(QWheelEvent *);
#endif
#if QT_CONFIG(draganddrop)
- void handleDragEnterMoveEvent(QDragMoveEvent *);
+ void handleDragEnterEvent(QDragEnterEvent *, QWidget *widget = nullptr);
+ void handleDragMoveEvent(QDragMoveEvent *);
void handleDragLeaveEvent(QDragLeaveEvent *);
void handleDropEvent(QDropEvent *);
#endif
diff --git a/src/widgets/qtwidgets.tracepoints b/src/widgets/qtwidgets.tracepoints
new file mode 100644
index 0000000000..01a1383670
--- /dev/null
+++ b/src/widgets/qtwidgets.tracepoints
@@ -0,0 +1,4 @@
+QApplication_notify_entry(QObject *receiver, QEvent *event, int type)
+QApplication_notify_event_filtered(QObject *receiver, QEvent *event, int type)
+QApplication_notify_before_delivery(QObject *receiver, QEvent *event, int type)
+QApplication_notify_after_delivery(QObject *receiver, QEvent *event, int type, bool consumed)
diff --git a/src/widgets/styles/images/titlebar-contexthelp-16.png b/src/widgets/styles/images/titlebar-contexthelp-16.png
new file mode 100644
index 0000000000..2cead19910
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-contexthelp-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-contexthelp-32.png b/src/widgets/styles/images/titlebar-contexthelp-32.png
new file mode 100644
index 0000000000..1cd4843d5e
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-contexthelp-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-contexthelp-48.png b/src/widgets/styles/images/titlebar-contexthelp-48.png
new file mode 100644
index 0000000000..9b170687be
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-contexthelp-48.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-max-16.png b/src/widgets/styles/images/titlebar-max-16.png
new file mode 100644
index 0000000000..101a7eac2b
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-max-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-max-32.png b/src/widgets/styles/images/titlebar-max-32.png
new file mode 100644
index 0000000000..529c54f61d
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-max-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-max-48.png b/src/widgets/styles/images/titlebar-max-48.png
new file mode 100644
index 0000000000..cfa0b67edf
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-max-48.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-min-16.png b/src/widgets/styles/images/titlebar-min-16.png
new file mode 100644
index 0000000000..95e714b522
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-min-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-min-32.png b/src/widgets/styles/images/titlebar-min-32.png
new file mode 100644
index 0000000000..0b9afedecf
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-min-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-min-48.png b/src/widgets/styles/images/titlebar-min-48.png
new file mode 100644
index 0000000000..b59a336d36
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-min-48.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-shade-16.png b/src/widgets/styles/images/titlebar-shade-16.png
new file mode 100644
index 0000000000..cc870a1e5c
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-shade-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-shade-32.png b/src/widgets/styles/images/titlebar-shade-32.png
new file mode 100644
index 0000000000..b785b8e216
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-shade-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-shade-48.png b/src/widgets/styles/images/titlebar-shade-48.png
new file mode 100644
index 0000000000..42b75b4a0c
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-shade-48.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-unshade-16.png b/src/widgets/styles/images/titlebar-unshade-16.png
new file mode 100644
index 0000000000..ef19de6c2f
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-unshade-16.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-unshade-32.png b/src/widgets/styles/images/titlebar-unshade-32.png
new file mode 100644
index 0000000000..9f74bb0ac7
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-unshade-32.png
Binary files differ
diff --git a/src/widgets/styles/images/titlebar-unshade-48.png b/src/widgets/styles/images/titlebar-unshade-48.png
new file mode 100644
index 0000000000..bd17c3cf48
--- /dev/null
+++ b/src/widgets/styles/images/titlebar-unshade-48.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-16.png b/src/widgets/styles/images/toolbar-ext-h-16.png
new file mode 100644
index 0000000000..c6bd1b1784
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-16.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-32.png b/src/widgets/styles/images/toolbar-ext-h-32.png
new file mode 100644
index 0000000000..99c62698f2
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-32.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-8.png b/src/widgets/styles/images/toolbar-ext-h-8.png
new file mode 100644
index 0000000000..340a374bce
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-8.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-16.png b/src/widgets/styles/images/toolbar-ext-h-rtl-16.png
new file mode 100644
index 0000000000..31c72892b4
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-rtl-16.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-32.png b/src/widgets/styles/images/toolbar-ext-h-rtl-32.png
new file mode 100644
index 0000000000..bfc333daac
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-rtl-32.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-h-rtl-8.png b/src/widgets/styles/images/toolbar-ext-h-rtl-8.png
new file mode 100644
index 0000000000..538e408310
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-h-rtl-8.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext.png b/src/widgets/styles/images/toolbar-ext-macstyle.png
index 37bd403ff8..37bd403ff8 100644
--- a/src/widgets/styles/images/toolbar-ext.png
+++ b/src/widgets/styles/images/toolbar-ext-macstyle.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext@2x.png b/src/widgets/styles/images/toolbar-ext-macstyle@2x.png
index 6fc729efb0..6fc729efb0 100644
--- a/src/widgets/styles/images/toolbar-ext@2x.png
+++ b/src/widgets/styles/images/toolbar-ext-macstyle@2x.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-v-10.png b/src/widgets/styles/images/toolbar-ext-v-10.png
new file mode 100644
index 0000000000..2a6d0e4c70
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-v-10.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-v-20.png b/src/widgets/styles/images/toolbar-ext-v-20.png
new file mode 100644
index 0000000000..adc27f52b5
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-v-20.png
Binary files differ
diff --git a/src/widgets/styles/images/toolbar-ext-v-5.png b/src/widgets/styles/images/toolbar-ext-v-5.png
new file mode 100644
index 0000000000..21c670446c
--- /dev/null
+++ b/src/widgets/styles/images/toolbar-ext-v-5.png
Binary files differ
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 3b9186e61a..3ee3e856bc 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -936,55 +936,53 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt
viewItemTextLayout(textLayout, textRect.width());
- QString elidedText;
- qreal height = 0;
- qreal width = 0;
- int elidedIndex = -1;
- const int lineCount = textLayout.lineCount();
- for (int j = 0; j < lineCount; ++j) {
- const QTextLine line = textLayout.lineAt(j);
- if (j + 1 <= lineCount - 1) {
- const QTextLine nextLine = textLayout.lineAt(j + 1);
- if ((nextLine.y() + nextLine.height()) > textRect.height()) {
- int start = line.textStart();
- int length = line.textLength() + nextLine.textLength();
- const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
- elidedText = engine.elidedText(option->textElideMode, textRect.width());
- height += line.height();
- width = textRect.width();
- elidedIndex = j;
- break;
- }
- }
- if (line.naturalTextWidth() > textRect.width()) {
- int start = line.textStart();
- int length = line.textLength();
- const QStackTextEngine engine(textLayout.text().mid(start, length), option->font);
- elidedText = engine.elidedText(option->textElideMode, textRect.width());
- height += line.height();
- width = textRect.width();
- elidedIndex = j;
- break;
- }
- width = qMax<qreal>(width, line.width());
- height += line.height();
- }
-
+ const QRectF boundingRect = textLayout.boundingRect();
const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment,
- QSize(int(width), int(height)), textRect);
+ boundingRect.size().toSize(), textRect);
const QPointF position = layoutRect.topLeft();
+ const int lineCount = textLayout.lineCount();
+
+ qreal height = 0;
for (int i = 0; i < lineCount; ++i) {
const QTextLine line = textLayout.lineAt(i);
- if (i == elidedIndex) {
- qreal x = position.x() + line.x();
- qreal y = position.y() + line.y() + line.ascent();
+ height += line.height();
+
+ // above visible rect
+ if (height + layoutRect.top() <= textRect.top())
+ continue;
+
+ const int start = line.textStart();
+ const int length = line.textLength();
+
+ const bool drawElided = line.naturalTextWidth() > textRect.width();
+ bool elideLastVisibleLine = false;
+ if (!drawElided && i + 1 < lineCount) {
+ const QTextLine nextLine = textLayout.lineAt(i + 1);
+ const int nextHeight = height + nextLine.height() / 2;
+ // elide when less than the next half line is visible
+ if (nextHeight + layoutRect.top() > textRect.height() + textRect.top())
+ elideLastVisibleLine = true;
+ }
+
+ if (drawElided || elideLastVisibleLine) {
+ QString text = textLayout.text().mid(start, length);
+ if (elideLastVisibleLine)
+ text += QChar(0x2026);
+ const QStackTextEngine engine(text, option->font);
+ const QString elidedText = engine.elidedText(option->textElideMode, textRect.width());
+ const QPointF pos(position.x() + line.x(),
+ position.y() + line.y() + line.ascent());
p->save();
p->setFont(option->font);
- p->drawText(QPointF(x, y), elidedText);
+ p->drawText(pos, elidedText);
p->restore();
- break;
+ } else {
+ line.draw(p, position);
}
- line.draw(p, position);
+
+ // below visible text, can stop
+ if (height + layoutRect.top() >= textRect.bottom())
+ break;
}
}
@@ -1673,8 +1671,9 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
alignment |= Qt::AlignLeft | Qt::AlignVCenter;
}
tr.translate(shiftX, shiftY);
+ const QString text = toolbutton->fontMetrics.elidedText(toolbutton->text, Qt::ElideMiddle, tr.width());
proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette,
- toolbutton->state & State_Enabled, toolbutton->text,
+ toolbutton->state & State_Enabled, text,
QPalette::ButtonText);
} else {
rect.translate(shiftX, shiftY);
@@ -2861,8 +2860,8 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case SE_TabBarScrollLeftButton: {
const bool vertical = opt->rect.width() < opt->rect.height();
const Qt::LayoutDirection ld = widget->layoutDirection();
- const int buttonWidth = qMax(pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
- const int buttonOverlap = pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, widget);
+ const int buttonWidth = qMax(proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
+ const int buttonOverlap = proxy()->pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, widget);
r = vertical ? QRect(0, opt->rect.height() - (buttonWidth * 2) + buttonOverlap, opt->rect.width(), buttonWidth)
: QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - (buttonWidth * 2) + buttonOverlap, 0, buttonWidth, opt->rect.height()));
@@ -2870,7 +2869,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case SE_TabBarScrollRightButton: {
const bool vertical = opt->rect.width() < opt->rect.height();
const Qt::LayoutDirection ld = widget->layoutDirection();
- const int buttonWidth = qMax(pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
+ const int buttonWidth = qMax(proxy()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
r = vertical ? QRect(0, opt->rect.height() - buttonWidth, opt->rect.width(), buttonWidth)
: QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - buttonWidth, 0, buttonWidth, opt->rect.height()));
@@ -3085,7 +3084,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
//have all the information we need (ie. the layout's margin)
const QToolBar *tb = qobject_cast<const QToolBar*>(widget);
const int margin = tb && tb->layout() ? tb->layout()->margin() : 2;
- const int handleExtent = pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb);
+ const int handleExtent = proxy()->pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb);
if (tbopt->state & QStyle::State_Horizontal) {
r = QRect(margin, margin, handleExtent, tbopt->rect.height() - 2*margin);
r = QStyle::visualRect(tbopt->direction, tbopt->rect, r);
@@ -4940,8 +4939,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_SpinBox:
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
// Add button + frame widths
- int buttonWidth = 20;
- int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0;
+ const int buttonWidth = (vopt->subControls & (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown)) != 0 ? 20 : 0;
+ const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0;
sz += QSize(buttonWidth + 2*fw, 2*fw);
}
break;
@@ -5310,6 +5309,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
case SH_SpinBox_ButtonsInsideFrame:
ret = true;
break;
+ case SH_SpinBox_StepModifier:
+ ret = Qt::ControlModifier;
+ break;
default:
ret = 0;
break;
@@ -5722,14 +5724,14 @@ static inline QString iconPngSuffix() { return QStringLiteral(".png"); }
static void addIconFiles(const QString &prefix, const int sizes[], size_t count, QIcon &icon)
{
- for (size_t i = 0; i < count; ++i) {
- const int size = sizes[i];
- icon.addFile(prefix + QString::number(size) + iconPngSuffix(), QSize(size, size));
- }
+ for (size_t i = 0; i < count; ++i)
+ icon.addFile(prefix + QString::number(sizes[i]) + iconPngSuffix());
}
static const int dockTitleIconSizes[] = {10, 16, 20, 32, 48, 64};
-
+static const int titleBarSizes[] = {16, 32, 48};
+static const int toolBarExtHSizes[] = {8, 16, 32};
+static const int toolBarExtVSizes[] = {5, 10, 20};
#endif // imageformat_png
/*!
@@ -6044,6 +6046,27 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
switch (standardIcon) {
#ifndef QT_NO_IMAGEFORMAT_PNG
+ case SP_TitleBarMinButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-min-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+ break;
+ case SP_TitleBarMaxButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-max-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+ break;
+ case SP_TitleBarShadeButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-shade-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+
+ break;
+ case SP_TitleBarUnshadeButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-unshade-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+ break;
+ case SP_TitleBarContextHelpButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("titlebar-contexthelp-"),
+ titleBarSizes, sizeof(titleBarSizes)/sizeof(titleBarSizes[0]), icon);
+ break;
case SP_FileDialogNewFolder:
icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png"), QSize(16, 16));
icon.addFile(QLatin1String(":/qt-project.org/styles/commonstyle/images/newdirectory-32.png"), QSize(32, 32));
@@ -6252,6 +6275,17 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
addIconFiles(iconResourcePrefix() + QStringLiteral("normalizedockup-"),
dockTitleIconSizes, sizeof(dockTitleIconSizes)/sizeof(dockTitleIconSizes[0]), icon);
break;
+ case SP_ToolBarHorizontalExtensionButton: {
+ QString prefix = iconResourcePrefix() + QStringLiteral("toolbar-ext-h-");
+ if (rtl)
+ prefix += QStringLiteral("rtl-");
+ addIconFiles(prefix, toolBarExtHSizes, sizeof(toolBarExtHSizes)/sizeof(toolBarExtHSizes[0]), icon);
+ }
+ break;
+ case SP_ToolBarVerticalExtensionButton:
+ addIconFiles(iconResourcePrefix() + QStringLiteral("toolbar-ext-v-"),
+ toolBarExtVSizes, sizeof(toolBarExtVSizes)/sizeof(toolBarExtVSizes[0]), icon);
+ break;
#endif // QT_NO_IMAGEFORMAT_PNG
default:
icon.addPixmap(proxy()->standardPixmap(standardIcon, option, widget));
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 73a6554f1a..8006be8c27 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -2001,6 +2001,13 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
Determnines if the spin box buttons are inside the line edit frame.
This enum value has been introduced in Qt 5.11.
+ \value SH_SpinBox_StepModifier
+ Determines which Qt::KeyboardModifier increases the step rate of
+ QAbstractSpinBox. Possible values are Qt::NoModifier,
+ Qt::ControlModifier (default) or Qt::ShiftModifier. Qt::NoModifier
+ disables this feature.
+ This enum value has been introduced in Qt 5.12.
+
\sa styleHint()
*/
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index cef569d514..9192dae864 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -741,6 +741,7 @@ public:
SH_Widget_Animation_Duration,
SH_ComboBox_AllowWheelScrolling,
SH_SpinBox_ButtonsInsideFrame,
+ SH_SpinBox_StepModifier,
// Add new style hint values here
SH_CustomBase = 0xf0000000
diff --git a/src/widgets/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc
index 2dc3207e6d..d3511ee754 100644
--- a/src/widgets/styles/qstyle.qrc
+++ b/src/widgets/styles/qstyle.qrc
@@ -140,13 +140,37 @@
<file>images/normalizedockup-32.png</file>
<file>images/normalizedockup-48.png</file>
<file>images/normalizedockup-64.png</file>
+ <file>images/toolbar-ext-h-8.png</file>
+ <file>images/toolbar-ext-h-16.png</file>
+ <file>images/toolbar-ext-h-32.png</file>
+ <file>images/toolbar-ext-h-rtl-8.png</file>
+ <file>images/toolbar-ext-h-rtl-16.png</file>
+ <file>images/toolbar-ext-h-rtl-32.png</file>
+ <file>images/toolbar-ext-v-5.png</file>
+ <file>images/toolbar-ext-v-10.png</file>
+ <file>images/toolbar-ext-v-20.png</file>
+ <file>images/titlebar-contexthelp-16.png</file>
+ <file>images/titlebar-contexthelp-32.png</file>
+ <file>images/titlebar-contexthelp-48.png</file>
+ <file>images/titlebar-max-16.png</file>
+ <file>images/titlebar-max-32.png</file>
+ <file>images/titlebar-max-48.png</file>
+ <file>images/titlebar-min-16.png</file>
+ <file>images/titlebar-min-32.png</file>
+ <file>images/titlebar-min-48.png</file>
+ <file>images/titlebar-shade-16.png</file>
+ <file>images/titlebar-shade-32.png</file>
+ <file>images/titlebar-shade-48.png</file>
+ <file>images/titlebar-unshade-16.png</file>
+ <file>images/titlebar-unshade-32.png</file>
+ <file>images/titlebar-unshade-48.png</file>
</qresource>
<qresource prefix="/qt-project.org/styles/macstyle">
<file alias="images/closedock-16.png">images/closedock-macstyle-16.png</file>
<file alias="images/closedock-down-16.png">images/closedock-down-macstyle-16.png</file>
<file alias="images/dockdock-16.png">images/dockdock-macstyle-16.png</file>
<file alias="images/dockdock-down-16.png">images/dockdock-down-macstyle-16.png</file>
- <file>images/toolbar-ext.png</file>
- <file>images/toolbar-ext@2x.png</file>
+ <file alias="images/toolbar-ext.png">images/toolbar-ext-macstyle.png</file>
+ <file alias="images/toolbar-ext@2x.png">images/toolbar-ext-macstyle@2x.png</file>
</qresource>
</RCC>
diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp
index 8679d96eda..0b910d46df 100644
--- a/src/widgets/styles/qstylehelper.cpp
+++ b/src/widgets/styles/qstylehelper.cpp
@@ -403,14 +403,6 @@ QColor backgroundColor(const QPalette &pal, const QWidget* widget)
return pal.color(QPalette::Base);
}
-QWindow *styleObjectWindow(QObject *so)
-{
- if (so)
- return so->property("_q_styleObjectWindow").value<QWindow *>();
-
- return 0;
-}
-
WidgetSizePolicy widgetSizePolicy(const QWidget *widget, const QStyleOption *opt)
{
while (widget) {
diff --git a/src/widgets/styles/qstylehelper_p.h b/src/widgets/styles/qstylehelper_p.h
index 260860bf4d..d79dfe4288 100644
--- a/src/widgets/styles/qstylehelper_p.h
+++ b/src/widgets/styles/qstylehelper_p.h
@@ -90,7 +90,6 @@ namespace QStyleHelper
Q_WIDGETS_EXPORT bool hasAncestor(QObject *obj, QAccessible::Role role);
#endif
Q_WIDGETS_EXPORT QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0);
- Q_WIDGETS_EXPORT QWindow *styleObjectWindow(QObject *so);
enum WidgetSizePolicy { SizeLarge = 0, SizeSmall = 1, SizeMini = 2, SizeDefault = -1 };
diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index e7fa26e2d4..97631a5841 100644
--- a/src/widgets/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
@@ -1842,10 +1842,12 @@ QStyleOptionMenuItem::QStyleOptionMenuItem(int version)
/*!
\variable QStyleOptionMenuItem::tabWidth
- \brief the tab width for the menu item
+ \brief the reserved width for the menu item's shortcut
- The tab width is the distance between the text of the menu item
- and the shortcut. The default value is 0.
+ QMenu sets it to the width occupied by the widest shortcut among
+ all visible items within the menu.
+
+ The default value is 0.
*/
diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h
index 9fbaf34a86..8ae07efc81 100644
--- a/src/widgets/styles/qstyleoption.h
+++ b/src/widgets/styles/qstyleoption.h
@@ -366,7 +366,7 @@ public:
QString text;
QIcon icon;
int maxIconWidth;
- int tabWidth;
+ int tabWidth; // ### Qt 6: rename to reservedShortcutWidth
QFont font;
QStyleOptionMenuItem();
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index c046ac52f9..c2ffcc82b1 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -530,6 +530,8 @@ public:
const QStyleSheetGeometryData *geometry() const { return geo; }
const QStyleSheetPositionData *position() const { return p; }
+ bool hasModification() const;
+
bool hasPalette() const { return pal != 0; }
bool hasBackground() const { return bg != 0 && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); }
bool hasGradientBackground() const { return bg && bg->brush.style() >= Qt::LinearGradientPattern
@@ -1041,7 +1043,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
if (const QWidget *widget = qobject_cast<const QWidget *>(object)) {
QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle);
if (!style)
- style = qobject_cast<QStyleSheetStyle *>(widget->style());
+ style = qt_styleSheet(widget->style());
if (style)
fixupBorder(style->nativeFrameWidth(widget));
}
@@ -1444,6 +1446,21 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q
p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
}
+bool QRenderRule::hasModification() const
+{
+ return hasPalette() ||
+ hasBackground() ||
+ hasGradientBackground() ||
+ !hasNativeBorder() ||
+ !hasNativeOutline() ||
+ hasBox() ||
+ hasPosition() ||
+ hasGeometry() ||
+ hasImage() ||
+ hasFont ||
+ !styleHints.isEmpty();
+}
+
///////////////////////////////////////////////////////////////////////////////
// Style rules
#define OBJECT_PTR(x) (static_cast<QObject *>(x.ptr))
@@ -1502,7 +1519,7 @@ public:
return className;
} else if (name == QLatin1String("style")) {
QWidget *w = qobject_cast<QWidget *>(obj);
- QStyleSheetStyle *proxy = w ? qobject_cast<QStyleSheetStyle *>(w->style()) : 0;
+ QStyleSheetStyle *proxy = w ? qt_styleSheet(w->style()) : 0;
if (proxy) {
QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className());
cache[name] = styleName;
@@ -1923,11 +1940,11 @@ QRenderRule QStyleSheetStyle::renderRule(const QObject *obj, const QStyleOption
break;
case QTabBar::RoundedEast:
case QTabBar::TriangularEast:
- extraClass |= PseudoClass_Left;
+ extraClass |= PseudoClass_Right;
break;
case QTabBar::RoundedWest:
case QTabBar::TriangularWest:
- extraClass |= PseudoClass_Right;
+ extraClass |= PseudoClass_Left;
break;
default:
break;
@@ -1960,11 +1977,11 @@ QRenderRule QStyleSheetStyle::renderRule(const QObject *obj, const QStyleOption
break;
case QTabBar::RoundedEast:
case QTabBar::TriangularEast:
- extraClass |= PseudoClass_Left;
+ extraClass |= PseudoClass_Right;
break;
case QTabBar::RoundedWest:
case QTabBar::TriangularWest:
- extraClass |= PseudoClass_Right;
+ extraClass |= PseudoClass_Left;
break;
default:
break;
@@ -2734,7 +2751,7 @@ QStyle *QStyleSheetStyle::baseStyle() const
{
if (base)
return base;
- if (QStyleSheetStyle *me = qobject_cast<QStyleSheetStyle *>(QApplication::style()))
+ if (QStyleSheetStyle *me = qt_styleSheet(QApplication::style()))
return me->base;
return QApplication::style();
}
@@ -2823,6 +2840,9 @@ void QStyleSheetStyle::polish(QWidget *w)
#endif
QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Any);
+
+ w->setAttribute(Qt::WA_StyleSheetTarget, rule.hasModification());
+
if (rule.hasDrawable() || rule.hasBox()) {
if (w->metaObject() == &QWidget::staticMetaObject
#if QT_CONFIG(itemviews)
@@ -2906,6 +2926,7 @@ void QStyleSheetStyle::unpolish(QWidget *w)
styleSheetCaches->styleSheetCache.remove(w);
unsetPalette(w);
setGeometry(w);
+ w->setAttribute(Qt::WA_StyleSheetTarget, false);
w->setAttribute(Qt::WA_StyleSheet, false);
QObject::disconnect(w, 0, this, 0);
#if QT_CONFIG(scrollarea)
@@ -3670,6 +3691,17 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
bool dis = !(opt->state & QStyle::State_Enabled),
act = opt->state & QStyle::State_Selected;
+ int checkableOffset = 0;
+ if (checkable) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ QStyleOptionMenuItem newMi = mi;
+ newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
+ checkableOffset = newMi.rect.width();
+ if (subSubRule.hasDrawable() || checked)
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
+ }
+
+ int iconOffset = 0;
if (!mi.icon.isNull()) {
QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
if (act && !dis)
@@ -3689,20 +3721,22 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
iconRule.geo->height = pixh;
}
QRect iconRect = positionRect(w, subRule, iconRule, PseudoElement_MenuIcon, opt->rect, opt->direction);
+ if (opt->direction == Qt::LeftToRight)
+ iconRect.moveLeft(iconRect.left() + checkableOffset);
+ else
+ iconRect.moveRight(iconRect.right() - checkableOffset);
iconRule.drawRule(p, iconRect);
QRect pmr(0, 0, pixw, pixh);
pmr.moveCenter(iconRect.center());
p->drawPixmap(pmr.topLeft(), pixmap);
- } else if (checkable) {
- QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
- if (subSubRule.hasDrawable() || checked) {
- QStyleOptionMenuItem newMi = mi;
- newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
- drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
- }
+ iconOffset = iconRule.geo->width;
}
QRect textRect = subRule.contentsRect(opt->rect);
+ if (opt->direction == Qt::LeftToRight)
+ textRect.setLeft(textRect.left() + checkableOffset + iconOffset);
+ else
+ textRect.setRight(textRect.right() - checkableOffset - iconOffset);
textRect.setWidth(textRect.width() - mi.tabWidth);
QStringRef s(&mi.text);
p->setPen(mi.palette.buttonText().color());
@@ -3836,17 +3870,10 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if(hasStyleRule(w, PseudoElement_HeaderViewSection)) {
QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
if (!subRule.hasNativeBorder() || !subRule.baseStyleCanDraw()
- || subRule.hasBackground() || subRule.hasPalette() || subRule.hasFont) {
+ || subRule.hasBackground() || subRule.hasPalette() || subRule.hasFont || subRule.hasBorder()) {
ParentStyle::drawControl(ce, opt, p, w);
return;
}
- if (subRule.hasFont) {
- const QFont oldFont = p->font();
- p->setFont(subRule.font.resolve(p->font()));
- baseStyle()->drawControl(ce, opt, p, w);
- p->setFont(oldFont);
- return;
- }
}
break;
case CE_HeaderSection:
@@ -4819,13 +4846,12 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
return 0;
break;
- case PM_TabBarScrollButtonWidth: {
+ case PM_TabBarScrollButtonWidth:
subRule = renderRule(w, opt, PseudoElement_TabBarScroller);
if (subRule.hasContentsSize()) {
QSize sz = subRule.size();
- return sz.width() != -1 ? sz.width() : sz.height();
+ return (sz.width() != -1 ? sz.width() : sz.height()) / 2;
}
- }
break;
case PM_TabBarTabShiftHorizontal:
@@ -5048,6 +5074,16 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
int width = csz.width();
if (mi->text.contains(QLatin1Char('\t')))
width += 12; //as in QCommonStyle
+ bool checkable = mi->checkType != QStyleOptionMenuItem::NotCheckable;
+ if (checkable) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ QRect checkmarkRect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
+ width += checkmarkRect.width();
+ }
+ if (!mi->icon.isNull()) {
+ QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize));
+ width += pixmap.width();
+ }
return subRule.boxSize(subRule.adjustSize(QSize(width, csz.height())));
}
}
@@ -5198,7 +5234,7 @@ static QLatin1String propertyNameForStandardPixmap(QStyle::StandardPixmap sp)
case QStyle::SP_DialogCloseButton: return QLatin1String("dialog-close-icon");
case QStyle::SP_DialogApplyButton: return QLatin1String("dialog-apply-icon");
case QStyle::SP_DialogResetButton: return QLatin1String("dialog-reset-icon");
- case QStyle::SP_DialogDiscardButton: return QLatin1String("discard-icon");
+ case QStyle::SP_DialogDiscardButton: return QLatin1String("dialog-discard-icon");
case QStyle::SP_DialogYesButton: return QLatin1String("dialog-yes-icon");
case QStyle::SP_DialogNoButton: return QLatin1String("dialog-no-icon");
case QStyle::SP_ArrowUp: return QLatin1String("uparrow-icon");
@@ -5874,6 +5910,12 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c
}
break;
+ case SE_TabBarScrollLeftButton:
+ case SE_TabBarScrollRightButton:
+ if (hasStyleRule(w, PseudoElement_TabBarScroller))
+ return ParentStyle::subElementRect(se, opt, w);
+ break;
+
case SE_TabBarTearIndicator: {
QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTear);
if (subRule.hasContentsSize()) {
diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h
index 042abf5c22..d1647fb107 100644
--- a/src/widgets/styles/qstylesheetstyle_p.h
+++ b/src/widgets/styles/qstylesheetstyle_p.h
@@ -215,6 +215,13 @@ template <typename T>
class QTypeInfo<QStyleSheetStyleCaches::Tampered<T>>
: QTypeInfoMerger<QStyleSheetStyleCaches::Tampered<T>, T> {};
+
+// Returns a QStyleSheet from the given style.
+inline QStyleSheetStyle* qt_styleSheet(QStyle *style)
+{
+ return qobject_cast<QStyleSheetStyle *>(style);
+}
+
QT_END_NAMESPACE
#endif // QT_NO_STYLE_STYLESHEET
#endif // QSTYLESHEETSTYLE_P_H
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 7c9d917784..611de6991f 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -840,17 +840,19 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
: opt->palette.text().color());
if (opt->state & State_NoChange)
p->setBrush(opt->palette.brush(QPalette::Button));
- p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, 11, 11);
+ p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, opt->rect.width() - 2, opt->rect.height() - 2);
}
#endif // QT_CONFIG(itemviews)
if (!(opt->state & State_Off)) {
QPointF points[6];
- points[0] = { opt->rect.x() + QStyleHelper::dpiScaled(3.5), opt->rect.y() + QStyleHelper::dpiScaled(5.5) };
- points[1] = { points[0].x(), points[0].y() + QStyleHelper::dpiScaled(2) };
- points[2] = { points[1].x() + QStyleHelper::dpiScaled(2), points[1].y() + QStyleHelper::dpiScaled(2) };
- points[3] = { points[2].x() + QStyleHelper::dpiScaled(4), points[2].y() - QStyleHelper::dpiScaled(4) };
- points[4] = { points[3].x(), points[3].y() - QStyleHelper::dpiScaled(2) };
- points[5] = { points[4].x() - QStyleHelper::dpiScaled(4), points[4].y() + QStyleHelper::dpiScaled(4) };
+ qreal scaleh = opt->rect.width() / 12.0;
+ qreal scalev = opt->rect.height() / 12.0;
+ points[0] = { opt->rect.x() + 3.5 * scaleh, opt->rect.y() + 5.5 * scalev };
+ points[1] = { points[0].x(), points[0].y() + 2 * scalev };
+ points[2] = { points[1].x() + 2 * scaleh, points[1].y() + 2 * scalev };
+ points[3] = { points[2].x() + 4 * scaleh, points[2].y() - 4 * scalev };
+ points[4] = { points[3].x(), points[3].y() - 2 * scalev };
+ points[5] = { points[4].x() - 4 * scaleh, points[4].y() + 4 * scalev };
p->setPen(QPen(opt->palette.text().color(), 0));
p->setBrush(opt->palette.text().color());
p->drawPolygon(points, 6);
@@ -1148,9 +1150,6 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode);
const int pixw = pixmap.width() / pixmap.devicePixelRatio();
const int pixh = pixmap.height() / pixmap.devicePixelRatio();
- if (act && !dis && !checked)
- qDrawShadePanel(p, vCheckRect, menuitem->palette, false, 1,
- &menuitem->palette.brush(QPalette::Button));
QRect pmr(0, 0, pixw, pixh);
pmr.moveCenter(vCheckRect.center());
p->setPen(menuitem->palette.text().color());
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 22fb0a511d..0daa4a4b41 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -144,6 +144,7 @@
#include "qcompleter_p.h"
#include "QtWidgets/qscrollbar.h"
+#include "QtCore/qdir.h"
#include "QtCore/qstringlistmodel.h"
#if QT_CONFIG(dirmodel)
#include "QtWidgets/qdirmodel.h"
@@ -181,10 +182,10 @@ int QCompletionModel::columnCount(const QModelIndex &) const
void QCompletionModel::setSourceModel(QAbstractItemModel *source)
{
- bool hadModel = (sourceModel() != 0);
+ bool hadModel = (sourceModel() != nullptr);
if (hadModel)
- QObject::disconnect(sourceModel(), 0, this, 0);
+ QObject::disconnect(sourceModel(), nullptr, this, nullptr);
QAbstractProxyModel::setSourceModel(source);
@@ -401,7 +402,7 @@ QVariant QCompletionModel::data(const QModelIndex& index, int role) const
void QCompletionModel::modelDestroyed()
{
- QAbstractProxyModel::setSourceModel(0); // switch to static empty model
+ QAbstractProxyModel::setSourceModel(nullptr); // switch to static empty model
invalidate();
}
@@ -470,13 +471,13 @@ QMatchData QCompletionEngine::filterHistory()
return QMatchData();
#if QT_CONFIG(dirmodel)
- const bool isDirModel = (qobject_cast<QDirModel *>(source) != 0);
+ const bool isDirModel = (qobject_cast<QDirModel *>(source) != nullptr);
#else
const bool isDirModel = false;
#endif
Q_UNUSED(isDirModel)
#if QT_CONFIG(filesystemmodel)
- const bool isFsModel = (qobject_cast<QFileSystemModel *>(source) != 0);
+ const bool isFsModel = (qobject_cast<QFileSystemModel *>(source) != nullptr);
#else
const bool isFsModel = false;
#endif
@@ -827,9 +828,18 @@ QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex&
///////////////////////////////////////////////////////////////////////////////
QCompleterPrivate::QCompleterPrivate()
-: widget(0), proxy(0), popup(0), filterMode(Qt::MatchStartsWith), cs(Qt::CaseSensitive),
- role(Qt::EditRole), column(0), maxVisibleItems(7), sorting(QCompleter::UnsortedModel),
- wrap(true), eatFocusOut(true), hiddenBecauseNoMatch(false)
+ : widget(nullptr),
+ proxy(nullptr),
+ popup(nullptr),
+ filterMode(Qt::MatchStartsWith),
+ cs(Qt::CaseSensitive),
+ role(Qt::EditRole),
+ column(0),
+ maxVisibleItems(7),
+ sorting(QCompleter::UnsortedModel),
+ wrap(true),
+ eatFocusOut(true),
+ hiddenBecauseNoMatch(false)
{
}
@@ -1000,7 +1010,7 @@ QCompleter::QCompleter(QAbstractItemModel *model, QObject *parent)
d->init(model);
}
-#ifndef QT_NO_STRINGLISTMODEL
+#if QT_CONFIG(stringlistmodel)
/*!
Constructs a QCompleter object with the given \a parent that uses the specified
\a list as a source of possible completions.
@@ -1011,7 +1021,7 @@ QCompleter::QCompleter(const QStringList& list, QObject *parent)
Q_D(QCompleter);
d->init(new QStringListModel(list, this));
}
-#endif // QT_NO_STRINGLISTMODEL
+#endif // QT_CONFIG(stringlistmodel)
/*!
Destroys the completer object.
@@ -1145,7 +1155,7 @@ void QCompleter::setCompletionMode(QCompleter::CompletionMode mode)
d->widget->removeEventFilter(this);
if (d->popup) {
d->popup->deleteLater();
- d->popup = 0;
+ d->popup = nullptr;
}
} else {
if (d->widget)
@@ -1221,8 +1231,8 @@ void QCompleter::setPopup(QAbstractItemView *popup)
Q_D(QCompleter);
Q_ASSERT(popup != 0);
if (d->popup) {
- QObject::disconnect(d->popup->selectionModel(), 0, this, 0);
- QObject::disconnect(d->popup, 0, this, 0);
+ QObject::disconnect(d->popup->selectionModel(), nullptr, this, nullptr);
+ QObject::disconnect(d->popup, nullptr, this, nullptr);
}
if (d->popup != popup)
delete d->popup;
@@ -1494,7 +1504,7 @@ void QCompleter::complete(const QRect& rect)
return;
}
- Q_ASSERT(d->widget != 0);
+ Q_ASSERT(d->widget);
if ((d->mode == QCompleter::PopupCompletion && !idx.isValid())
|| (d->mode == QCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) {
if (d->popup)
@@ -1804,10 +1814,10 @@ QString QCompleter::pathFromIndex(const QModelIndex& index) const
bool isDirModel = false;
bool isFsModel = false;
#if QT_CONFIG(dirmodel)
- isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
+ isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != nullptr;
#endif
#if QT_CONFIG(filesystemmodel)
- isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
+ isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != nullptr;
#endif
if (!isDirModel && !isFsModel)
return sourceModel->data(index, d->role).toString();
@@ -1854,13 +1864,13 @@ QStringList QCompleter::splitPath(const QString& path) const
bool isFsModel = false;
#if QT_CONFIG(dirmodel)
Q_D(const QCompleter);
- isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
+ isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != nullptr;
#endif
#if QT_CONFIG(filesystemmodel)
#if !QT_CONFIG(dirmodel)
Q_D(const QCompleter);
#endif
- isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
+ isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != nullptr;
#endif
if ((!isDirModel && !isFsModel) || path.isEmpty())
diff --git a/src/widgets/util/qcompleter.h b/src/widgets/util/qcompleter.h
index de79302e15..5620b55589 100644
--- a/src/widgets/util/qcompleter.h
+++ b/src/widgets/util/qcompleter.h
@@ -84,10 +84,10 @@ public:
QCompleter(QObject *parent = nullptr);
QCompleter(QAbstractItemModel *model, QObject *parent = nullptr);
-#ifndef QT_NO_STRINGLISTMODEL
+#if QT_CONFIG(stringlistmodel)
QCompleter(const QStringList& completions, QObject *parent = nullptr);
#endif
- ~QCompleter();
+ ~QCompleter() override;
void setWidget(QWidget *widget);
QWidget *widget() const;
diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp
index 903a141e49..28504f5631 100644
--- a/src/widgets/util/qscroller.cpp
+++ b/src/widgets/util/qscroller.cpp
@@ -1894,7 +1894,7 @@ qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientatio
if (orientation == Qt::Horizontal) {
// the snap points in the list
- foreach (qreal snapPos, snapPositionsX) {
+ for (qreal snapPos : snapPositionsX) {
qreal snapPosDist = snapPos - p;
if ((dir > 0 && snapPosDist < 0) ||
(dir < 0 && snapPosDist > 0))
@@ -1941,7 +1941,7 @@ qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientatio
} else { // (orientation == Qt::Vertical)
// the snap points in the list
- foreach (qreal snapPos, snapPositionsY) {
+ for (qreal snapPos : snapPositionsY) {
qreal snapPosDist = snapPos - p;
if ((dir > 0 && snapPosDist < 0) ||
(dir < 0 && snapPosDist > 0))
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 86c824afdb..d15f5e5955 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -523,6 +523,8 @@ QBalloonTip::QBalloonTip(const QIcon &icon, const QString &title,
closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
closeButton->setFixedSize(closeButtonSize, closeButtonSize);
QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
+#else
+ Q_UNUSED(closeButtonSize);
#endif
#if QT_CONFIG(label)
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index df93e15f80..86532456c7 100644
--- a/src/widgets/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
@@ -63,8 +63,6 @@
#include <private/qguiapplication_p.h>
#include <qdebug.h>
-#include <QtPlatformHeaders/qxcbwindowfunctions.h>
-#include <QtPlatformHeaders/qxcbintegrationfunctions.h>
#ifndef QT_NO_SYSTEMTRAYICON
QT_BEGIN_NAMESPACE
@@ -98,10 +96,7 @@ private slots:
void systemTrayWindowChanged(QScreen *screen);
private:
- bool addToTray();
-
QSystemTrayIcon *q;
- QPixmap background;
};
QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
@@ -117,55 +112,13 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
const QSize size(22, 22); // Gnome, standard size
setGeometry(QRect(QPoint(0, 0), size));
setMinimumSize(size);
-
- // We need two different behaviors depending on whether the X11 visual for the system tray
- // (a) exists and (b) supports an alpha channel, i.e. is 32 bits.
- // If we have a visual that has an alpha channel, we can paint this widget with a transparent
- // background and it will work.
- // However, if there's no alpha channel visual, in order for transparent tray icons to work,
- // we do not have a transparent background on the widget, but set the BackPixmap property of our
- // window to ParentRelative (so that it inherits the background of its X11 parent window), call
- // xcb_clear_region before painting (so that the inherited background is visible) and then grab
- // the just-drawn background from the X11 server.
- bool hasAlphaChannel = QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannel();
- setAttribute(Qt::WA_TranslucentBackground, hasAlphaChannel);
- if (!hasAlphaChannel) {
- createWinId();
- QXcbWindowFunctions::setParentRelativeBackPixmap(windowHandle());
-
- // XXX: This is actually required, but breaks things ("QWidget::paintEngine: Should no
- // longer be called"). Why is this needed? When the widget is drawn, we use tricks to grab
- // the tray icon's background from the server. If the tray icon isn't visible (because
- // another window is on top of it), the trick fails and instead uses the content of that
- // other window as the background.
- // setAttribute(Qt::WA_PaintOnScreen);
- }
-
- addToTray();
-}
-
-bool QSystemTrayIconSys::addToTray()
-{
- if (!locateSystemTray())
- return false;
-
- createWinId();
+ setAttribute(Qt::WA_TranslucentBackground);
setMouseTracking(true);
-
- if (!QXcbWindowFunctions::requestSystemTrayWindowDock(windowHandle()))
- return false;
-
- if (!background.isNull())
- background = QPixmap();
- show();
- return true;
}
void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
{
- if (locateSystemTray()) {
- addToTray();
- } else {
+ if (!locateSystemTray()) {
QBalloonTip::hideBalloon();
hide(); // still no luck
destroy();
@@ -174,7 +127,7 @@ void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
QRect QSystemTrayIconSys::globalGeometry() const
{
- return QXcbWindowFunctions::systemTrayWindowGlobalGeometry(windowHandle());
+ return QRect(mapToGlobal(QPoint(0, 0)), size());
}
void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev)
@@ -227,22 +180,6 @@ void QSystemTrayIconSys::paintEvent(QPaintEvent *)
const QRect rect(QPoint(0, 0), geometry().size());
QPainter painter(this);
- // If we have Qt::WA_TranslucentBackground set, during widget creation
- // we detected the systray visual supported an alpha channel
- if (testAttribute(Qt::WA_TranslucentBackground)) {
- painter.setCompositionMode(QPainter::CompositionMode_Source);
- painter.fillRect(rect, Qt::transparent);
- } else {
- // clearRegion() was called on XEMBED_EMBEDDED_NOTIFY, so we hope that got done by now.
- // Grab the tray background pixmap, before rendering the icon for the first time.
- if (background.isNull()) {
- background = QGuiApplication::primaryScreen()->grabWindow(winId(),
- 0, 0, rect.size().width(), rect.size().height());
- }
- // Then paint over the icon area with the background before compositing the icon on top.
- painter.drawPixmap(QPoint(0, 0), background);
- }
- painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
q->icon().paint(&painter, rect);
}
@@ -285,6 +222,7 @@ void QSystemTrayIconPrivate::install_sys()
sys = new QSystemTrayIconSys(q);
QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
sys, SLOT(systemTrayWindowChanged(QScreen*)));
+ sys->show();
}
}
diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp
index b371e903a6..e928b9fe37 100644
--- a/src/widgets/util/qundostack.cpp
+++ b/src/widgets/util/qundostack.cpp
@@ -742,6 +742,17 @@ void QUndoStack::resetClean()
}
/*!
+ \since 5.12
+ \property QUndoStack::clean
+ \brief the clean status of this stack.
+
+ This property indicates whether or not the stack is clean. For example, a
+ stack is clean when a document has been saved.
+
+ \sa isClean(), setClean(), resetClean(), cleanIndex()
+*/
+
+/*!
If the stack is in the clean state, returns \c true; otherwise returns \c false.
\sa setClean(), cleanIndex()
@@ -940,6 +951,17 @@ void QUndoStack::setIndex(int idx)
}
/*!
+ \since 5.12
+ \property QUndoStack::canUndo
+ \brief whether this stack can undo.
+
+ This property indicates whether or not there is a command that can be
+ undone.
+
+ \sa canUndo(), index(), canRedo()
+*/
+
+/*!
Returns \c true if there is a command available for undo; otherwise returns \c false.
This function returns \c false if the stack is empty, or if the bottom command
@@ -959,6 +981,17 @@ bool QUndoStack::canUndo() const
}
/*!
+ \since 5.12
+ \property QUndoStack::canRedo
+ \brief whether this stack can redo.
+
+ This property indicates whether or not there is a command that can be
+ redone.
+
+ \sa canRedo(), index(), canUndo()
+*/
+
+/*!
Returns \c true if there is a command available for redo; otherwise returns \c false.
This function returns \c false if the stack is empty or if the top command
@@ -978,6 +1011,17 @@ bool QUndoStack::canRedo() const
}
/*!
+ \since 5.12
+ \property QUndoStack::undoText
+ \brief the undo text of the next command that is undone.
+
+ This property holds the text of the command which will be undone in the
+ next call to undo().
+
+ \sa undoText(), QUndoCommand::actionText(), redoText()
+*/
+
+/*!
Returns the text of the command which will be undone in the next call to undo().
\sa QUndoCommand::actionText(), redoText()
@@ -994,6 +1038,17 @@ QString QUndoStack::undoText() const
}
/*!
+ \since 5.12
+ \property QUndoStack::redoText
+ \brief the redo text of the next command that is redone.
+
+ This property holds the text of the command which will be redone in the
+ next call to redo().
+
+ \sa redoText(), QUndoCommand::actionText(), undoText()
+*/
+
+/*!
Returns the text of the command which will be redone in the next call to redo().
\sa QUndoCommand::actionText(), undoText()
diff --git a/src/widgets/util/qundostack.h b/src/widgets/util/qundostack.h
index 4be24eadab..b5716b2e9b 100644
--- a/src/widgets/util/qundostack.h
+++ b/src/widgets/util/qundostack.h
@@ -90,6 +90,11 @@ class Q_WIDGETS_EXPORT QUndoStack : public QObject
Q_DECLARE_PRIVATE(QUndoStack)
Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)
+ Q_PROPERTY(bool canUndo READ canUndo NOTIFY canUndoChanged)
+ Q_PROPERTY(bool canRedo READ canRedo NOTIFY canRedoChanged)
+ Q_PROPERTY(QString undoText READ undoText NOTIFY undoTextChanged)
+ Q_PROPERTY(QString redoText READ redoText NOTIFY redoTextChanged)
+ Q_PROPERTY(bool clean READ isClean NOTIFY cleanChanged)
public:
explicit QUndoStack(QObject *parent = nullptr);
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index e028a691c8..e556cb8b10 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -6,6 +6,9 @@ CONFIG += $$MODULE_CONFIG
DEFINES += QT_NO_USING_NAMESPACE
msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x65000000
+TRACEPOINT_PROVIDER = $$PWD/qtwidgets.tracepoints
+CONFIG += qt_tracepoints
+
QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf
#platforms
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index f059980c5c..1eafb73ba8 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -100,6 +100,16 @@ QT_BEGIN_NAMESPACE
integer value to signify how many steps were taken. E.g. Pressing
Qt::Key_Down will trigger a call to stepBy(-1).
+ When the user triggers a step whilst holding the Qt::ControlModifier,
+ QAbstractSpinBox steps by 10 instead of making a single step. This
+ step modifier affects wheel events, key events and interaction with
+ the spinbox buttons. Note that on macOS, Control corresponds to the
+ Command key.
+
+ Since Qt 5.12, QStyle::SH_SpinBox_StepModifier can be used to select
+ which Qt::KeyboardModifier increases the step rate. Qt::NoModifier
+ disables this feature.
+
QAbstractSpinBox also provide a virtual function stepEnabled() to
determine whether stepping up/down is allowed at any point. This
function returns a bitset of StepEnabled.
@@ -117,6 +127,13 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QAbstractSpinBox::StepType
+
+ \value DefaultStepType
+ \value AdaptiveDecimalStepType
+*/
+
+/*!
\fn void QAbstractSpinBox::editingFinished()
This signal is emitted editing is finished. This happens when the
@@ -640,7 +657,15 @@ void QAbstractSpinBox::stepBy(int steps)
e = AlwaysEmit;
}
if (!dontstep) {
- d->setValue(d->bound(d->value + (d->singleStep * steps), old, steps), e);
+ QVariant singleStep;
+ switch (d->stepType) {
+ case QAbstractSpinBox::StepType::AdaptiveDecimalStepType:
+ singleStep = d->calculateAdaptiveDecimalStep(steps);
+ break;
+ default:
+ singleStep = d->singleStep;
+ }
+ d->setValue(d->bound(d->value + (singleStep * steps), old, steps), e);
} else if (e == AlwaysEmit) {
d->emitSignals(e, old);
}
@@ -826,9 +851,13 @@ void QAbstractSpinBox::changeEvent(QEvent *event)
style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, 0, this);
if (d->edit)
d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this));
+ d->stepModifier = static_cast<Qt::KeyboardModifier>(style()->styleHint(QStyle::SH_SpinBox_StepModifier, nullptr, this));
d->reset();
d->updateEditFieldGeometry();
break;
+ case QEvent::LocaleChange:
+ d->updateEdit();
+ break;
case QEvent::EnabledChange:
if (!isEnabled()) {
d->reset();
@@ -1008,6 +1037,8 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
const bool up = (event->key() == Qt::Key_PageUp || event->key() == Qt::Key_Up);
if (!(stepEnabled() & (up ? StepUpEnabled : StepDownEnabled)))
return;
+ if (!isPgUpOrDown && (event->modifiers() & d->stepModifier))
+ steps *= 10;
if (!up)
steps *= -1;
if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
@@ -1134,11 +1165,24 @@ void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *event)
void QAbstractSpinBox::wheelEvent(QWheelEvent *event)
{
Q_D(QAbstractSpinBox);
+#ifdef Q_OS_MACOS
+ // If the event comes from a real mouse wheel, rather than a track pad
+ // (Qt::MouseEventSynthesizedBySystem), the shift modifier changes the
+ // scroll orientation to horizontal.
+ // Convert horizontal events back to vertical whilst shift is held.
+ if ((event->modifiers() & Qt::ShiftModifier)
+ && event->source() == Qt::MouseEventNotSynthesized) {
+ d->wheelDeltaRemainder += event->angleDelta().x();
+ } else {
+ d->wheelDeltaRemainder += event->angleDelta().y();
+ }
+#else
d->wheelDeltaRemainder += event->angleDelta().y();
+#endif
const int steps = d->wheelDeltaRemainder / 120;
d->wheelDeltaRemainder -= steps * 120;
if (stepEnabled() & (steps > 0 ? StepUpEnabled : StepDownEnabled))
- stepBy(event->modifiers() & Qt::ControlModifier ? steps * 10 : steps);
+ stepBy(event->modifiers() & d->stepModifier ? steps * 10 : steps);
event->accept();
}
#endif
@@ -1238,18 +1282,19 @@ void QAbstractSpinBox::timerEvent(QTimerEvent *event)
}
if (doStep) {
+ const bool increaseStepRate = QGuiApplication::keyboardModifiers() & d->stepModifier;
const StepEnabled st = stepEnabled();
if (d->buttonState & Up) {
if (!(st & StepUpEnabled)) {
d->reset();
} else {
- stepBy(1);
+ stepBy(increaseStepRate ? 10 : 1);
}
} else if (d->buttonState & Down) {
if (!(st & StepDownEnabled)) {
d->reset();
} else {
- stepBy(-1);
+ stepBy(increaseStepRate ? -10 : -1);
}
}
return;
@@ -1377,8 +1422,9 @@ QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate()
cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false),
ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
- acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0),
- showGroupSeparator(0), wheelDeltaRemainder(0)
+ stepModifier(Qt::ControlModifier), acceleration(0), hoverControl(QStyle::SC_None),
+ buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0), showGroupSeparator(0),
+ wheelDeltaRemainder(0)
{
}
@@ -1629,7 +1675,10 @@ void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false
: QAbstractSpinBox::StepDownEnabled))) {
spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
- q->stepBy(up ? 1 : -1);
+ int steps = up ? 1 : -1;
+ if (QGuiApplication::keyboardModifiers() & stepModifier)
+ steps *= 10;
+ q->stepBy(steps);
#ifndef QT_NO_ACCESSIBILITY
QAccessibleValueChangeEvent event(q, value);
QAccessible::updateAccessibility(&event);
@@ -1898,6 +1947,11 @@ void QAbstractSpinBoxPrivate::clearCache() const
cachedState = QValidator::Acceptable;
}
+QVariant QAbstractSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ Q_UNUSED(steps)
+ return singleStep;
+}
// --- QSpinBoxValidator ---
diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h
index 83bf83d779..87d46c7326 100644
--- a/src/widgets/widgets/qabstractspinbox.h
+++ b/src/widgets/widgets/qabstractspinbox.h
@@ -127,6 +127,13 @@ public:
virtual void fixup(QString &input) const;
virtual void stepBy(int steps);
+
+ enum StepType {
+ DefaultStepType,
+ AdaptiveDecimalStepType
+ };
+ Q_ENUM(StepType)
+
public Q_SLOTS:
void stepUp();
void stepDown();
diff --git a/src/widgets/widgets/qabstractspinbox_p.h b/src/widgets/widgets/qabstractspinbox_p.h
index 8f312fa900..fce88e43f4 100644
--- a/src/widgets/widgets/qabstractspinbox_p.h
+++ b/src/widgets/widgets/qabstractspinbox_p.h
@@ -122,6 +122,8 @@ public:
static int variantCompare(const QVariant &arg1, const QVariant &arg2);
static QVariant variantBound(const QVariant &min, const QVariant &value, const QVariant &max);
+ virtual QVariant calculateAdaptiveDecimalStep(int steps) const;
+
QLineEdit *edit;
QString prefix, suffix, specialValueText;
QVariant value, minimum, maximum, singleStep;
@@ -143,6 +145,8 @@ public:
uint cleared : 1;
uint ignoreUpdateEdit : 1;
QAbstractSpinBox::CorrectionMode correctionMode;
+ QAbstractSpinBox::StepType stepType = QAbstractSpinBox::StepType::DefaultStepType;
+ Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
int acceleration;
QStyle::SubControl hoverControl;
QRect hoverRect;
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 04a44e1f37..e20a0892b4 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -3160,7 +3160,6 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e)
#endif
// We've restricted the next couple of lines, because by not calling
// viewContainer(), we avoid creating the QComboBoxPrivateContainer.
- viewContainer()->blockMouseReleaseTimer.start(QApplication::doubleClickInterval());
viewContainer()->initialClickPosition = q->mapToGlobal(e->pos());
#ifdef QT_KEYPAD_NAVIGATION
}
@@ -3169,8 +3168,10 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e)
// The code below ensures that regular mousepress and pick item still works
// If it was not called the viewContainer would ignore event since it didn't have
// a mousePressEvent first.
- if (viewContainer())
+ if (viewContainer()) {
+ viewContainer()->blockMouseReleaseTimer.start(QApplication::doubleClickInterval());
viewContainer()->maybeIgnoreMouseButtonRelease = false;
+ }
} else {
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled() && sc == QStyle::SC_ComboBoxEditField && lineEdit) {
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index 75289e9d1f..3026a5b7d6 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -2629,8 +2629,9 @@ void QDockAreaLayout::removePlaceHolder(const QString &name)
QList<int> index = indexOfPlaceHolder(name);
if (!index.isEmpty())
remove(index);
- foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren<QDockWidgetGroupWindow *>(
- QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
index = dwgw->layoutInfo()->indexOfPlaceHolder(name);
if (!index.isEmpty()) {
dwgw->layoutInfo()->remove(index);
@@ -3065,8 +3066,9 @@ QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget)
bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
{
QDockAreaLayoutItem *item = 0;
- foreach (QDockWidgetGroupWindow *dwgw, mainWindow->findChildren<QDockWidgetGroupWindow *>(
- QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
QList<int> index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName());
if (!index.isEmpty()) {
dockWidget->setParent(dwgw);
@@ -3175,7 +3177,7 @@ void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
if (!info->tabbed && info->o == o) {
info->item_list[path.constLast()].size = size;
int totalSize = 0;
- foreach (const QDockAreaLayoutItem &item, info->item_list) {
+ for (const QDockAreaLayoutItem &item : qAsConst(info->item_list)) {
if (!item.skip()) {
if (totalSize != 0)
totalSize += sep;
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index 5d09e14073..60f88df9af 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -288,7 +288,7 @@ void QLabel::setText(const QString &text)
return;
QWidgetTextControl *oldControl = d->control;
- d->control = 0;
+ d->control = nullptr;
d->clearContents();
d->text = text;
@@ -303,7 +303,7 @@ void QLabel::setText(const QString &text)
d->ensureTextControl();
} else {
delete d->control;
- d->control = 0;
+ d->control = nullptr;
}
if (d->isRichText) {
@@ -714,7 +714,7 @@ void QLabel::setTextInteractionFlags(Qt::TextInteractionFlags flags)
d->ensureTextControl();
} else {
delete d->control;
- d->control = 0;
+ d->control = nullptr;
}
if (d->control)
@@ -1021,13 +1021,13 @@ void QLabel::paintEvent(QPaintEvent *)
QStyleOption opt;
opt.initFrom(this);
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
+ if (QStyleSheetStyle* cssStyle = qt_styleSheet(style))
cssStyle->styleSheetPalette(this, &opt, &opt.palette);
- }
#endif
if (d->control) {
#ifndef QT_NO_SHORTCUT
- const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0);
+ const bool underline = static_cast<bool>(style->styleHint(QStyle::SH_UnderlineShortcut,
+ nullptr, this, nullptr));
if (d->shortcutId != 0
&& underline != d->shortcutCursor.charFormat().fontUnderline()) {
QTextCharFormat fmt;
@@ -1294,20 +1294,20 @@ void QLabel::setMovie(QMovie *movie)
void QLabelPrivate::clearContents()
{
delete control;
- control = 0;
+ control = nullptr;
isTextLabel = false;
hasShortcut = false;
#ifndef QT_NO_PICTURE
delete picture;
- picture = 0;
+ picture = nullptr;
#endif
delete scaledpixmap;
- scaledpixmap = 0;
+ scaledpixmap = nullptr;
delete cachedimage;
- cachedimage = 0;
+ cachedimage = nullptr;
delete pixmap;
- pixmap = 0;
+ pixmap = nullptr;
text.clear();
Q_Q(QLabel);
@@ -1321,7 +1321,7 @@ void QLabelPrivate::clearContents()
QObject::disconnect(movie, SIGNAL(resized(QSize)), q, SLOT(_q_movieResized(QSize)));
QObject::disconnect(movie, SIGNAL(updated(QRect)), q, SLOT(_q_movieUpdated(QRect)));
}
- movie = 0;
+ movie = nullptr;
#endif
#ifndef QT_NO_CURSOR
if (onAnchor) {
@@ -1428,9 +1428,9 @@ void QLabel::setScaledContents(bool enable)
d->scaledcontents = enable;
if (!enable) {
delete d->scaledpixmap;
- d->scaledpixmap = 0;
+ d->scaledpixmap = nullptr;
delete d->cachedimage;
- d->cachedimage = 0;
+ d->cachedimage = nullptr;
}
update(contentsRect());
}
@@ -1629,7 +1629,7 @@ QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos)
}
if (linkToCopy.isEmpty() && !control)
- return 0;
+ return nullptr;
return control->createStandardContextMenu(p, q_func());
}
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index ca6aacc16c..190ff8d2c5 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -497,6 +497,8 @@ void QLineEdit::setClearButtonEnabled(bool enable)
d->removeAction(clearAction);
delete clearAction;
}
+#else
+ Q_UNUSED(enable);
#endif // QT_CONFIG(action)
}
@@ -1676,6 +1678,21 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
*/
/*!
+ \fn void QLineEdit::inputRejected()
+
+ This signal is emitted when the user presses a key that is not
+ considered to be acceptable input. For example, if a key press
+ results in a validator's validate() call to return Invalid.
+ Another case is when trying to enter in more characters beyond the
+ maximum length of the line edit.
+
+ Note: This signal will still be emitted in a case where part of
+ the text is accepted but not all of it is. For example, if there
+ is a maximum length set and the clipboard text is longer than the
+ maximum length when it is pasted.
+*/
+
+/*!
Converts the given key press \a event into a line edit action.
If Return or Enter is pressed and the current text is valid (or
@@ -1946,8 +1963,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
if (!d->placeholderText.isEmpty()) {
const Qt::LayoutDirection layoutDir = d->placeholderText.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
const Qt::Alignment alignPhText = QStyle::visualAlignment(layoutDir, QFlag(d->alignment));
- QColor col = pal.text().color();
- col.setAlpha(128);
+ const QColor col = pal.placeholderText().color();
QPen oldpen = p.pen();
p.setPen(col);
Qt::LayoutDirection oldLayoutDir = p.layoutDirection();
@@ -2002,7 +2018,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
// draw text, selections and cursors
#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
+ if (QStyleSheetStyle* cssStyle = qt_styleSheet(style())) {
cssStyle->styleSheetPalette(this, &panel, &pal);
}
#endif
diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h
index 6c70a8f44a..de82927f74 100644
--- a/src/widgets/widgets/qlineedit.h
+++ b/src/widgets/widgets/qlineedit.h
@@ -207,6 +207,7 @@ Q_SIGNALS:
void returnPressed();
void editingFinished();
void selectionChanged();
+ void inputRejected();
protected:
void mousePressEvent(QMouseEvent *) override;
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 0eeff196a8..33d542abc0 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -216,6 +216,7 @@ void QLineEditPrivate::init(const QString& txt)
QObject::connect(control, SIGNAL(updateNeeded(QRect)),
q, SLOT(_q_updateNeeded(QRect)));
+ QObject::connect(control, SIGNAL(inputRejected()), q, SIGNAL(inputRejected()));
QStyleOptionFrame opt;
q->initStyleOption(&opt);
@@ -348,11 +349,9 @@ void QLineEditIconButton::paintEvent(QPaintEvent *)
QWindow *window = nullptr;
if (const QWidget *nativeParent = nativeParentWidget())
window = nativeParent->windowHandle();
- // Note isDown should really use the active state but in most styles
- // this has no proper feedback
QIcon::Mode state = QIcon::Disabled;
if (isEnabled())
- state = isDown() ? QIcon::Selected : QIcon::Normal;
+ state = isDown() ? QIcon::Active : QIcon::Normal;
const QLineEditPrivate *lep = lineEditPrivate();
const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16;
const QSize iconSize(iconWidth, iconWidth);
@@ -466,6 +465,8 @@ void QLineEditPrivate::setClearButtonEnabled(bool enabled)
break;
}
}
+#else
+ Q_UNUSED(enabled);
#endif
}
@@ -483,6 +484,8 @@ void QLineEditPrivate::positionSideWidgets()
#if QT_CONFIG(action)
if (e.action->isVisible())
widgetGeometry.moveLeft(widgetGeometry.left() + delta);
+#else
+ Q_UNUSED(delta);
#endif
}
widgetGeometry.moveLeft(contentRect.width() - p.widgetWidth - p.margin);
@@ -596,6 +599,8 @@ void QLineEditPrivate::removeAction(QAction *action)
if (!hasSideWidgets()) // Last widget, remove connection
QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString)));
q->update();
+#else
+ Q_UNUSED(action);
#endif // QT_CONFIG(action)
}
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 2014bdabf3..aca38884a7 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1312,8 +1312,12 @@ bool QMainWindow::restoreState(const QByteArray &state, int version)
bool QMainWindow::event(QEvent *event)
{
Q_D(QMainWindow);
+
+#if QT_CONFIG(dockwidget)
if (d->layout && d->layout->windowEvent(event))
return true;
+#endif
+
switch (event->type()) {
#if QT_CONFIG(toolbar)
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 43c22910f9..053bfbf024 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -426,7 +426,8 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty()
}
// Make sure to reparent the possibly floating or hidden QDockWidgets to the parent
- foreach (QDockWidget *dw, findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto dockWidgets = findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidget *dw : dockWidgets) {
bool wasFloating = dw->isFloating();
bool wasHidden = dw->isHidden();
dw->setParent(parentWidget());
@@ -445,7 +446,8 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty()
dw->show();
}
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tb, findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly))
+ const auto tabBars = findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly);
+ for (QTabBar *tb : tabBars)
tb->setParent(parentWidget());
#endif
deleteLater();
@@ -1037,10 +1039,10 @@ void QMainWindowLayoutState::saveState(QDataStream &stream) const
#if QT_CONFIG(dockwidget)
dockAreaLayout.saveState(stream);
#if QT_CONFIG(tabbar)
- QList<QDockWidgetGroupWindow *> floatingTabs =
+ const QList<QDockWidgetGroupWindow *> floatingTabs =
mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly);
- foreach (QDockWidgetGroupWindow *floating, floatingTabs) {
+ for (QDockWidgetGroupWindow *floating : floatingTabs) {
if (floating->layoutInfo()->isEmpty())
continue;
stream << uchar(QDockAreaLayout::FloatingDockWidgetTabMarker) << floating->geometry();
@@ -1528,9 +1530,9 @@ void QMainWindowLayout::setDocumentMode(bool enabled)
_documentMode = enabled;
// Update the document mode for all tab bars
- foreach (QTabBar *bar, usedTabBars)
+ for (QTabBar *bar : qAsConst(usedTabBars))
bar->setDocumentMode(_documentMode);
- foreach (QTabBar *bar, unusedTabBars)
+ for (QTabBar *bar : qAsConst(unusedTabBars))
bar->setDocumentMode(_documentMode);
}
#endif // QT_CONFIG(tabbar)
@@ -1809,8 +1811,9 @@ QDockAreaLayoutInfo *QMainWindowLayout::dockInfo(QWidget *widget)
QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget);
if (info)
return info;
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
info = dwgw->layoutInfo()->info(widget);
if (info)
return info;
@@ -2077,8 +2080,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
layoutState.remove(previousPath);
previousPath = currentHoveredFloat->layoutInfo()->indexOf(widget);
// Let's remove the widget from any possible group window
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
if (dwgw == currentHoveredFloat)
continue;
QList<int> path = dwgw->layoutInfo()->indexOf(widget);
@@ -2106,8 +2110,9 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
#if QT_CONFIG(dockwidget)
// Let's remove the widget from any possible group window
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups) {
QList<int> path = dwgw->layoutInfo()->indexOf(widget);
if (!path.isEmpty())
dwgw->layoutInfo()->remove(path);
@@ -2249,7 +2254,8 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
#if QT_CONFIG(dockwidget)
parentWidget()->update(layoutState.dockAreaLayout.separatorRegion());
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tab_bar, usedTabBars)
+ const auto usedTabBarsCopy = usedTabBars; // list potentially modified by animations
+ for (QTabBar *tab_bar : usedTabBarsCopy)
tab_bar->show();
#endif // QT_CONFIG(tabbar)
#endif // QT_CONFIG(dockwidget)
@@ -2533,7 +2539,8 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
// Check if we are over another floating dock widget
QVarLengthArray<QWidget *, 10> candidates;
- foreach (QObject *c, parentWidget()->children()) {
+ const auto siblings = parentWidget()->children();
+ for (QObject *c : siblings) {
QWidget *w = qobject_cast<QWidget*>(c);
if (!w)
continue;
@@ -2543,7 +2550,8 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
candidates << w;
if (QDockWidgetGroupWindow *group = qobject_cast<QDockWidgetGroupWindow *>(w)) {
// Sometimes, there are floating QDockWidget that have a QDockWidgetGroupWindow as a parent.
- foreach (QObject *c, group->children()) {
+ const auto groupChildren = group->children();
+ for (QObject *c : groupChildren) {
if (QDockWidget *dw = qobject_cast<QDockWidget*>(c)) {
if (dw != widget && dw->isFloating() && dw->isVisible() && !dw->isMinimized())
candidates << dw;
@@ -2671,14 +2679,14 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat
{
#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
QSet<QTabBar*> used = newState.dockAreaLayout.usedTabBars();
- foreach (QDockWidgetGroupWindow *dwgw,
- parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) {
+ const auto groups =
+ parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly);
+ for (QDockWidgetGroupWindow *dwgw : groups)
used += dwgw->layoutInfo()->usedTabBars();
- }
- QSet<QTabBar*> retired = usedTabBars - used;
+ const QSet<QTabBar*> retired = usedTabBars - used;
usedTabBars = used;
- foreach (QTabBar *tab_bar, retired) {
+ for (QTabBar *tab_bar : retired) {
tab_bar->hide();
while (tab_bar->count() > 0)
tab_bar->removeTab(0);
@@ -2686,10 +2694,10 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat
}
if (sep == 1) {
- QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets();
- QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps;
+ const QSet<QWidget*> usedSeps = newState.dockAreaLayout.usedSeparatorWidgets();
+ const QSet<QWidget*> retiredSeps = usedSeparatorWidgets - usedSeps;
usedSeparatorWidgets = usedSeps;
- foreach (QWidget *sepWidget, retiredSeps) {
+ for (QWidget *sepWidget : retiredSeps) {
unusedSeparatorWidgets.append(sepWidget);
}
}
@@ -2731,7 +2739,7 @@ bool QMainWindowLayout::restoreState(QDataStream &stream)
#if QT_CONFIG(dockwidget)
if (parentWidget()->isVisible()) {
#if QT_CONFIG(tabbar)
- foreach (QTabBar *tab_bar, usedTabBars)
+ for (QTabBar *tab_bar : qAsConst(usedTabBars))
tab_bar->show();
#endif
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index 4ccfb1786e..72cbec2350 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -92,6 +92,7 @@ public:
QPoint hoverPos;
#if QT_CONFIG(dockwidget)
+
#if QT_CONFIG(cursor)
QCursor separatorCursor(const QList<int> &path);
void adjustCursor(const QPoint &pos);
@@ -108,13 +109,15 @@ public:
bool startSeparatorMove(const QPoint &pos);
bool separatorMove(const QPoint &pos);
bool endSeparatorMove(const QPoint &pos);
+ bool windowEvent(QEvent *e);
#endif // QT_CONFIG(dockwidget)
- bool windowEvent(QEvent *e);
};
-#if QT_CONFIG(dockwidget) && QT_CONFIG(cursor)
+#if QT_CONFIG(dockwidget)
+
+#if QT_CONFIG(cursor)
template <typename Layout>
QCursor QMainWindowLayoutSeparatorHelper<Layout>::separatorCursor(const QList<int> &path)
{
@@ -187,14 +190,13 @@ void QMainWindowLayoutSeparatorHelper<Layout>::adjustCursor(const QPoint &pos)
}
}
}
-#endif // QT_CONFIG(cursor) && QT_CONFIG(dockwidget)
+#endif // QT_CONFIG(cursor)
template <typename Layout>
bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event)
{
QWidget *w = window();
switch (event->type()) {
-#if QT_CONFIG(dockwidget)
case QEvent::Paint: {
QPainter p(w);
QRegion r = static_cast<QPaintEvent *>(event)->region();
@@ -290,14 +292,12 @@ bool QMainWindowLayoutSeparatorHelper<Layout>::windowEvent(QEvent *event)
return true;
}
break;
-#endif // QT_CONFIG(dockwidget)
default:
break;
}
return false;
}
-#if QT_CONFIG(dockwidget)
template <typename Layout>
bool QMainWindowLayoutSeparatorHelper<Layout>::startSeparatorMove(const QPoint &pos)
{
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 45c01dec80..8639f57ea1 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -471,8 +471,8 @@ QVector<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const
ylist.erase(std::unique(ylist.begin(), ylist.end()), ylist.end());
result.reserve(ylist.size() * xlist.size());
- foreach (int y, ylist)
- foreach (int x, xlist)
+ for (int y : qAsConst(ylist))
+ for (int x : qAsConst(xlist))
result << QRect(QPoint(x, y), size);
return result;
}
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 363647aee0..96635ae505 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2433,7 +2433,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
atAction = d->defaultAction;
// TODO: This works for first level menus, not yet sub menus
} else {
- foreach (QAction *action, d->actions)
+ for (QAction *action : qAsConst(d->actions))
if (action->isEnabled()) {
atAction = action;
break;
diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h
index 86d927e919..628f818b5e 100644
--- a/src/widgets/widgets/qmenu.h
+++ b/src/widgets/widgets/qmenu.h
@@ -46,7 +46,7 @@
#include <QtGui/qicon.h>
#include <QtWidgets/qaction.h>
-#ifdef Q_OS_OSX
+#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC)
Q_FORWARD_DECLARE_OBJC_CLASS(NSMenu);
#endif
@@ -81,7 +81,7 @@ public:
QAction *addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0);
QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0);
-#ifdef Q_QDOC
+#ifdef Q_CLANG_QDOC
template<typename PointerToMemberFunction>
QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0);
template<typename Functor>
@@ -151,7 +151,7 @@ public:
connect(result, &QAction::triggered, std::move(slot));
return result;
}
-#endif // !Q_QDOC
+#endif // !Q_CLANG_QDOC
QAction *addMenu(QMenu *menu);
QMenu *addMenu(const QString &title);
@@ -211,7 +211,7 @@ public:
QPlatformMenu *platformMenu();
void setPlatformMenu(QPlatformMenu *platformMenu);
-#ifdef Q_OS_OSX
+#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC)
NSMenu* toNSMenu();
void setAsDockMenu();
#endif
diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm
index 0d680fb4dc..0872da803d 100644
--- a/src/widgets/widgets/qmenu_mac.mm
+++ b/src/widgets/widgets/qmenu_mac.mm
@@ -73,6 +73,7 @@ inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePla
/*!
+ \fn NSMenu *QMenu::toNSMenu()
\since 5.2
Returns the native NSMenu for this menu. Available on \macos only.
@@ -94,6 +95,7 @@ NSMenu *QMenu::toNSMenu()
/*!
+ \fn void QMenu::setAsDockMenu()
\since 5.2
Set this menu to be the dock menu available by option-clicking
@@ -149,6 +151,7 @@ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem*
#if QT_CONFIG(menubar)
/*!
+ \fn NSMenu *QMenuBar::toNSMenu()
\since 5.2
Returns the native NSMenu for this menu bar. Available on \macos only.
diff --git a/src/widgets/widgets/qmenubar.h b/src/widgets/widgets/qmenubar.h
index 2f071e7e3b..cf6663f94a 100644
--- a/src/widgets/widgets/qmenubar.h
+++ b/src/widgets/widgets/qmenubar.h
@@ -67,7 +67,7 @@ public:
QAction *addAction(const QString &text);
QAction *addAction(const QString &text, const QObject *receiver, const char* member);
-#ifdef Q_QDOC
+#ifdef Q_CLANG_QDOC
template<typename Obj, typename PointerToMemberFunctionOrFunctor>
QAction *addAction(const QString &text, const Obj *receiver, PointerToMemberFunctionOrFunctor method);
template<typename Functor>
@@ -91,7 +91,7 @@ public:
connect(result, &QAction::triggered, std::move(slot));
return result;
}
-#endif // !Q_QDOC
+#endif // !Q_CLANG_QDOC
QAction *addMenu(QMenu *menu);
QMenu *addMenu(const QString &title);
@@ -121,7 +121,7 @@ public:
void setCornerWidget(QWidget *w, Qt::Corner corner = Qt::TopRightCorner);
QWidget *cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
-#ifdef Q_OS_OSX
+#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC)
NSMenu* toNSMenu();
#endif
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index a4c463fb5b..252d5a79df 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -48,6 +48,7 @@
#include <qdrag.h>
#endif
#include <qclipboard.h>
+#include <qmath.h>
#if QT_CONFIG(menu)
#include <qmenu.h>
#endif
@@ -382,6 +383,8 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
line.setLineWidth(availableWidth);
line.setPosition(QPointF(margin, height));
height += line.height();
+ if (line.leading() < 0)
+ height += qCeil(line.leading());
blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
}
tl->endLayout();
@@ -1927,8 +1930,7 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e)
painter.setClipRect(er);
if (d->placeholderVisible) {
- QColor col = d->control->palette().text().color();
- col.setAlpha(128);
+ const QColor col = d->control->palette().placeholderText().color();
painter.setPen(col);
painter.setClipRect(e->rect());
const int margin = int(document()->documentMargin());
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 561215ec85..dcf3906dd7 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -45,6 +45,8 @@
#include <qvalidator.h>
#include <qdebug.h>
+#include <algorithm>
+#include <cmath>
#include <float.h>
QT_BEGIN_NAMESPACE
@@ -75,6 +77,8 @@ public:
}
int displayIntegerBase;
+
+ QVariant calculateAdaptiveDecimalStep(int steps) const override;
};
class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate
@@ -100,6 +104,8 @@ public:
// When fiddling with the decimals property, we may lose precision in these properties.
double actualMin;
double actualMax;
+
+ QVariant calculateAdaptiveDecimalStep(int steps) const override;
};
@@ -415,6 +421,47 @@ void QSpinBox::setRange(int minimum, int maximum)
}
/*!
+ Sets the step type for the spin box to \a stepType, which is single
+ step or adaptive decimal step.
+
+ Adaptive decimal step means that the step size will continuously be
+ adjusted to one power of ten below the current \l value. So when
+ the value is 1100, the step is set to 100, so stepping up once
+ increases it to 1200. For 1200 stepping up takes it to 1300. For
+ negative values, stepping down from -1100 goes to -1200.
+
+ Step direction is taken into account to handle edges cases, so
+ that stepping down from 100 takes the value to 99 instead of 90.
+ Thus a step up followed by a step down -- or vice versa -- always
+ lands on the starting value; 99 -> 100 -> 99.
+
+ Setting this will cause the spin box to disregard the value of
+ \l singleStep, although it is preserved so that \l singleStep
+ comes into effect if adaptive decimal step is later turned off.
+
+ \since 5.12
+*/
+
+void QSpinBox::setStepType(QAbstractSpinBox::StepType stepType)
+{
+ Q_D(QSpinBox);
+ d->stepType = stepType;
+}
+
+/*!
+ \property QSpinBox::stepType
+ \brief The step type.
+
+ The step type can be single step or adaptive decimal step.
+*/
+
+QAbstractSpinBox::StepType QSpinBox::stepType() const
+{
+ Q_D(const QSpinBox);
+ return d->stepType;
+}
+
+/*!
\property QSpinBox::displayIntegerBase
\brief the base used to display the value of the spin box
@@ -847,6 +894,50 @@ void QDoubleSpinBox::setRange(double minimum, double maximum)
}
/*!
+ Sets the step type for the spin box to \a stepType, which is single
+ step or adaptive decimal step.
+
+ Adaptive decimal step means that the step size will continuously be
+ adjusted to one power of ten below the current \l value. So when
+ the value is 1100, the step is set to 100, so stepping up once
+ increases it to 1200. For 1200 stepping up takes it to 1300. For
+ negative values, stepping down from -1100 goes to -1200.
+
+ It also works for any decimal values, 0.041 is increased to 0.042
+ by stepping once.
+
+ Step direction is taken into account to handle edges cases, so
+ that stepping down from 100 takes the value to 99 instead of 90.
+ Thus a step up followed by a step down -- or vice versa -- always
+ lands on the starting value; 99 -> 100 -> 99.
+
+ Setting this will cause the spin box to disregard the value of
+ \l singleStep, although it is preserved so that \l singleStep
+ comes into effect if adaptive decimal step is later turned off.
+
+ \since 5.12
+*/
+
+void QDoubleSpinBox::setStepType(StepType stepType)
+{
+ Q_D(QDoubleSpinBox);
+ d->stepType = stepType;
+}
+
+/*!
+ \property QDoubleSpinBox::stepType
+ \brief The step type.
+
+ The step type can be single step or adaptive decimal step.
+*/
+
+QAbstractSpinBox::StepType QDoubleSpinBox::stepType() const
+{
+ Q_D(const QDoubleSpinBox);
+ return d->stepType;
+}
+
+/*!
\property QDoubleSpinBox::decimals
\brief the precision of the spin box, in decimals
@@ -1078,6 +1169,22 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos,
return cachedValue;
}
+QVariant QSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ const int intValue = value.toInt();
+ const int absValue = qAbs(intValue);
+
+ if (absValue < 100)
+ return 1;
+
+ const bool valueNegative = intValue < 0;
+ const bool stepsNegative = steps < 0;
+ const int signCompensation = (valueNegative == stepsNegative) ? 0 : 1;
+
+ const int log = static_cast<int>(std::log10(absValue - signCompensation)) - 1;
+ return static_cast<int>(std::pow(10, log));
+}
+
// --- QDoubleSpinBoxPrivate ---
/*!
@@ -1303,6 +1410,27 @@ QString QDoubleSpinBoxPrivate::textFromValue(const QVariant &f) const
return q->textFromValue(f.toDouble());
}
+QVariant QDoubleSpinBoxPrivate::calculateAdaptiveDecimalStep(int steps) const
+{
+ const double doubleValue = value.toDouble();
+ const double minStep = std::pow(10, -decimals);
+ double absValue = qAbs(doubleValue);
+
+ if (absValue < minStep)
+ return minStep;
+
+ const bool valueNegative = doubleValue < 0;
+ const bool stepsNegative = steps < 0;
+ if (valueNegative != stepsNegative)
+ absValue /= 1.01;
+
+ const double shift = std::pow(10, 1 - std::floor(std::log10(absValue)));
+ const double absRounded = round(absValue * shift) / shift;
+ const double log = floorf(std::log10(absRounded)) - 1;
+
+ return std::max(minStep, std::pow(10, log));
+}
+
/*! \reimp */
bool QSpinBox::event(QEvent *event)
{
diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h
index 73489c9a68..d2eac903fb 100644
--- a/src/widgets/widgets/qspinbox.h
+++ b/src/widgets/widgets/qspinbox.h
@@ -58,6 +58,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox
Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(StepType stepType READ stepType WRITE setStepType)
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase)
@@ -86,6 +87,9 @@ public:
void setRange(int min, int max);
+ StepType stepType() const;
+ void setStepType(StepType stepType);
+
int displayIntegerBase() const;
void setDisplayIntegerBase(int base);
@@ -121,6 +125,7 @@ class Q_WIDGETS_EXPORT QDoubleSpinBox : public QAbstractSpinBox
Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(StepType stepType READ stepType WRITE setStepType)
Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true)
public:
explicit QDoubleSpinBox(QWidget *parent = nullptr);
@@ -147,6 +152,9 @@ public:
void setRange(double min, double max);
+ StepType stepType() const;
+ void setStepType(StepType stepType);
+
int decimals() const;
void setDecimals(int prec);
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index 44b9f7d9a1..277d2fd99f 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -327,7 +327,13 @@ void QSplashScreen::drawContents(QPainter *painter)
cursor.select(QTextCursor::Document);
QTextBlockFormat fmt;
fmt.setAlignment(Qt::Alignment(d->currAlign));
+ fmt.setLayoutDirection(layoutDirection());
cursor.mergeBlockFormat(fmt);
+ const QSizeF txtSize = doc.size();
+ if (d->currAlign & Qt::AlignBottom)
+ r.setTop(r.height() - txtSize.height());
+ else if (d->currAlign & Qt::AlignVCenter)
+ r.setTop(r.height() / 2 - txtSize.height() / 2);
painter->save();
painter->translate(r.topLeft());
doc.drawContents(painter);
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 6ee49aa9f0..9e38c8f18a 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -826,7 +826,7 @@ QSplitterLayoutStruct *QSplitterPrivate::findWidget(QWidget *w) const
if (list.at(i)->widget == w)
return list.at(i);
}
- return 0;
+ return nullptr;
}
@@ -855,7 +855,7 @@ void QSplitterPrivate::insertWidget_helper(int index, QWidget *widget, bool show
QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
{
Q_Q(QSplitter);
- QSplitterLayoutStruct *sls = 0;
+ QSplitterLayoutStruct *sls = nullptr;
int i;
int last = list.count();
for (i = 0; i < list.size(); ++i) {
@@ -872,12 +872,9 @@ QSplitterLayoutStruct *QSplitterPrivate::insertWidget(int index, QWidget *w)
if (sls) {
list.move(i,index);
} else {
- QSplitterHandle *newHandle = 0;
sls = new QSplitterLayoutStruct;
- QString tmp = QLatin1String("qt_splithandle_");
- tmp += w->objectName();
- newHandle = q->createHandle();
- newHandle->setObjectName(tmp);
+ QSplitterHandle *newHandle = q->createHandle();
+ newHandle->setObjectName(QLatin1String("qt_splithandle_") + w->objectName());
sls->handle = newHandle;
sls->widget = w;
w->lower();
@@ -1248,7 +1245,7 @@ QSplitterHandle *QSplitter::handle(int index) const
{
Q_D(const QSplitter);
if (index < 0 || index >= d->list.size())
- return 0;
+ return nullptr;
return d->list.at(index)->handle;
}
@@ -1262,7 +1259,7 @@ QWidget *QSplitter::widget(int index) const
{
Q_D(const QSplitter);
if (index < 0 || index >= d->list.size())
- return 0;
+ return nullptr;
return d->list.at(index)->widget;
}
@@ -1463,7 +1460,7 @@ void QSplitter::moveSplitter(int pos, int index)
void QSplitter::getRange(int index, int *min, int *max) const
{
Q_D(const QSplitter);
- d->getRange(index, min, 0, 0, max);
+ d->getRange(index, min, nullptr, nullptr, max);
}
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 8af70d0f9c..5959dd0ae4 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -74,6 +74,23 @@
QT_BEGIN_NAMESPACE
+namespace {
+class CloseButton : public QAbstractButton
+{
+ Q_OBJECT
+
+public:
+ explicit CloseButton(QWidget *parent = 0);
+
+ QSize sizeHint() const override;
+ QSize minimumSizeHint() const override
+ { return sizeHint(); }
+ void enterEvent(QEvent *event) override;
+ void leaveEvent(QEvent *event) override;
+ void paintEvent(QPaintEvent *event) override;
+};
+}
+
QMovableTabWidget::QMovableTabWidget(QWidget *parent)
: QWidget(parent)
{
@@ -2686,7 +2703,7 @@ void QTabBarPrivate::Tab::TabBarAnimation::updateCurrentValue(const QVariant &cu
priv->moveTab(priv->tabList.indexOf(*tab), current.toInt());
}
-void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State, QAbstractAnimation::State newState)
+void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State)
{
if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab));
}
@@ -2695,5 +2712,4 @@ void QTabBarPrivate::Tab::TabBarAnimation::updateState(QAbstractAnimation::State
QT_END_NAMESPACE
#include "moc_qtabbar.cpp"
-
-#include "moc_qtabbar_p.cpp"
+#include "qtabbar.moc"
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 1092878f2c..3948b42bc1 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -144,7 +144,7 @@ public:
void updateCurrentValue(const QVariant &current) override;
- void updateState(State, State newState) override;
+ void updateState(State newState, State) override;
private:
//these are needed for the callbacks
Tab *tab;
@@ -271,21 +271,6 @@ public:
};
-class CloseButton : public QAbstractButton
-{
- Q_OBJECT
-
-public:
- explicit CloseButton(QWidget *parent = 0);
-
- QSize sizeHint() const override;
- QSize minimumSizeHint() const override
- { return sizeHint(); }
- void enterEvent(QEvent *event) override;
- void leaveEvent(QEvent *event) override;
- void paintEvent(QPaintEvent *event) override;
-};
-
QT_END_NAMESPACE
#endif
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index fa4dd14c92..46b973bae7 100644
--- a/src/widgets/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
@@ -163,10 +163,13 @@ QString QTextBrowserPrivate::findFile(const QUrl &name) const
fileName = name.toLocalFile();
}
+ if (fileName.isEmpty())
+ return fileName;
+
if (QFileInfo(fileName).isAbsolute())
return fileName;
- foreach (QString path, searchPaths) {
+ for (QString path : qAsConst(searchPaths)) {
if (!path.endsWith(QLatin1Char('/')))
path.append(QLatin1Char('/'));
path.append(fileName);
@@ -1089,6 +1092,8 @@ QVariant QTextBrowser::loadResource(int /*type*/, const QUrl &name)
QByteArray data;
QString fileName = d->findFile(d->resolveUrl(name));
+ if (fileName.isEmpty())
+ return QVariant();
QFile f(fileName);
if (f.open(QFile::ReadOnly)) {
data = f.readAll();
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 5790b1e32e..3a368651de 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -1518,8 +1518,7 @@ void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
layout->setViewport(QRect());
if (!placeholderText.isEmpty() && doc->isEmpty() && !control->isPreediting()) {
- QColor col = control->palette().text().color();
- col.setAlpha(128);
+ const QColor col = control->palette().placeholderText().color();
p->setPen(col);
const int margin = int(doc->documentMargin());
p->drawText(viewport->rect().adjusted(margin, margin, -margin, -margin), Qt::AlignTop | Qt::TextWordWrap, placeholderText);
diff --git a/src/widgets/widgets/qtoolbarlayout_p.h b/src/widgets/widgets/qtoolbarlayout_p.h
index b813cd5e2c..a788d30450 100644
--- a/src/widgets/widgets/qtoolbarlayout_p.h
+++ b/src/widgets/widgets/qtoolbarlayout_p.h
@@ -97,7 +97,7 @@ public:
void insertAction(int index, QAction *action);
int indexOf(QAction *action) const;
- int indexOf(QWidget *widget) const override { return QLayout::indexOf(widget); }
+ using QLayout::indexOf; // bring back the hidden members
bool layoutActions(const QSize &size);
QSize expandedSize(const QSize &size) const;
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index c4a928410b..cf2d885b52 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -711,10 +711,12 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e
m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
if (m_validInput) {
if (m_text != textCopy) {
- internalSetText(textCopy, cursorCopy, false);
+ internalSetText(textCopy, cursorCopy, edited);
return true;
}
m_cursor = cursorCopy;
+ } else {
+ emit inputRejected();
}
}
#endif
@@ -762,6 +764,8 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite
if (m_maskData) {
m_text = maskString(0, txt, true);
m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ if (edited && oldText == m_text)
+ emit inputRejected();
} else {
m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
}
@@ -839,6 +843,8 @@ void QWidgetLineControl::internalInsert(const QString &s)
addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
if (m_maskData) {
QString ms = maskString(m_cursor, s);
+ if (ms.isEmpty() && !s.isEmpty())
+ emit inputRejected();
#ifndef QT_NO_ACCESSIBILITY
QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, ms);
QAccessible::updateAccessibility(&insertEvent);
@@ -867,6 +873,8 @@ void QWidgetLineControl::internalInsert(const QString &s)
addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
m_textDirty = true;
}
+ if (s.length() > remaining)
+ emit inputRejected();
}
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index ca70e2c02f..3e33bc0605 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -545,6 +545,7 @@ Q_SIGNALS:
void accepted();
void editingFinished();
void updateNeeded(const QRect &);
+ void inputRejected();
#ifdef QT_KEYPAD_NAVIGATION
void editFocusChange(bool);
diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp
index 45010d1768..7ed6f6d78d 100644
--- a/src/widgets/widgets/qwidgetresizehandler.cpp
+++ b/src/widgets/widgets/qwidgetresizehandler.cpp
@@ -192,6 +192,7 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee)
keyPressEvent(static_cast<QKeyEvent *>(ee));
break;
case QEvent::ShortcutOverride:
+ buttonDown &= ((QGuiApplication::mouseButtons() & Qt::LeftButton) != Qt::NoButton);
if (buttonDown) {
ee->accept();
return true;
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index 79ecf30b70..7cc57f4d46 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -69,6 +69,7 @@ extern "C" {
#include <qstandardpaths.h>
#include <qfunctions_winrt.h>
#include <qcoreapplication.h>
+#include <qmutex.h>
#include <wrl.h>
#include <Windows.ApplicationModel.core.h>
@@ -87,27 +88,68 @@ using namespace Microsoft::WRL::Wrappers;
#define CoreApplicationClass RuntimeClass_Windows_ApplicationModel_Core_CoreApplication
typedef ITypedEventHandler<CoreApplicationView *, Activation::IActivatedEventArgs *> ActivatedHandler;
+const quint32 resizeMessageType = QtInfoMsg + 1;
+
+const PCWSTR shmemName = L"qdebug-shmem";
+const PCWSTR eventName = L"qdebug-event";
+const PCWSTR ackEventName = L"qdebug-event-ack";
+
static QtMessageHandler defaultMessageHandler;
static void devMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
static HANDLE shmem = 0;
static HANDLE event = 0;
+ static HANDLE ackEvent = 0;
+
+ static QMutex messageMutex;
+ QMutexLocker locker(&messageMutex);
+
+ static quint64 mappingSize = 4096;
+ const quint32 copiedMessageLength = message.length() + 1;
+ // Message format is message type + message. We need the message's length + 4 bytes for the type
+ const quint64 copiedMessageSize = copiedMessageLength * sizeof(wchar_t) + sizeof(quint32);
+ if (copiedMessageSize > mappingSize) {
+ if (!shmem)
+ shmem = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, mappingSize, shmemName);
+ Q_ASSERT_X(shmem, Q_FUNC_INFO, "Could not create file mapping");
+
+ quint32 *data = reinterpret_cast<quint32 *>(MapViewOfFileFromApp(shmem, FILE_MAP_WRITE, 0, mappingSize));
+ Q_ASSERT_X(data, Q_FUNC_INFO, "Could not map size file");
+
+ mappingSize = copiedMessageSize;
+
+ memcpy(data, (void *)&resizeMessageType, sizeof(quint32));
+ memcpy(data + 1, (void *)&mappingSize, sizeof(quint64));
+ UnmapViewOfFile(data);
+ SetEvent(event);
+ WaitForSingleObjectEx(ackEvent, INFINITE, false);
+ if (shmem) {
+ if (!CloseHandle(shmem))
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Could not close shared file handle");
+ shmem = 0;
+ }
+ }
+
if (!shmem)
- shmem = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 4096, L"qdebug-shmem");
+ shmem = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, mappingSize, shmemName);
if (!event)
- event = CreateEventEx(NULL, L"qdebug-event", 0, EVENT_ALL_ACCESS);
+ event = CreateEventEx(NULL, eventName, 0, EVENT_ALL_ACCESS);
+ if (!ackEvent)
+ ackEvent = CreateEventEx(NULL, ackEventName, 0, EVENT_ALL_ACCESS);
Q_ASSERT_X(shmem, Q_FUNC_INFO, "Could not create file mapping");
Q_ASSERT_X(event, Q_FUNC_INFO, "Could not create debug event");
- void *data = MapViewOfFileFromApp(shmem, FILE_MAP_WRITE, 0, 4096);
+ void *data = MapViewOfFileFromApp(shmem, FILE_MAP_WRITE, 0, mappingSize);
Q_ASSERT_X(data, Q_FUNC_INFO, "Could not map file");
memset(data, quint32(type), sizeof(quint32));
- memcpy_s(static_cast<quint32 *>(data) + 1, 4096 - sizeof(quint32),
- message.data(), (message.length() + 1) * sizeof(wchar_t));
+ memcpy_s(static_cast<quint32 *>(data) + 1, mappingSize - sizeof(quint32),
+ message.data(), copiedMessageLength * sizeof(wchar_t));
UnmapViewOfFile(data);
SetEvent(event);
+ WaitForSingleObjectEx(ackEvent, INFINITE, false);
+ locker.unlock();
defaultMessageHandler(type, context, message);
}
@@ -149,15 +191,11 @@ public:
{
}
- int exec(int argc, char **argv)
+ int exec()
{
- args.reserve(argc);
- for (int i = 0; i < argc; ++i)
- args.append(argv[i]);
-
mainThread = CreateThread(NULL, 0, [](void *param) -> DWORD {
AppContainer *app = reinterpret_cast<AppContainer *>(param);
- int argc = app->args.count();
+ int argc = app->args.count() - 1;
char **argv = app->args.data();
const int res = main(argc, argv);
if (app->pidFile != INVALID_HANDLE_VALUE) {
@@ -305,6 +343,8 @@ private:
args.remove(i);
}
}
+ args.append(nullptr);
+
if (develMode) {
// Write a PID file to help runner
const QString pidFileName = QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation))
@@ -379,18 +419,9 @@ private:
// Main entry point for Appx containers
int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
- int argc = 0;
- char **argv = 0, **env = 0;
- for (int i = 0; env && env[i]; ++i) {
- QByteArray var(env[i]);
- int split = var.indexOf('=');
- if (split > 0)
- qputenv(var.mid(0, split), var.mid(split + 1));
- }
-
if (FAILED(RoInitialize(RO_INIT_MULTITHREADED)))
return 1;
ComPtr<AppContainer> app = Make<AppContainer>();
- return app->exec(argc, argv);
+ return app->exec();
}
diff --git a/src/xml/doc/src/xml-processing.qdoc b/src/xml/doc/src/xml-processing.qdoc
index 00c73b4465..4dfcbf4722 100644
--- a/src/xml/doc/src/xml-processing.qdoc
+++ b/src/xml/doc/src/xml-processing.qdoc
@@ -376,7 +376,7 @@
reported through the handler.
\endtable
- The \l{SAX Bookmarks example} illustrates how to subclass
+ The \l{SAX Bookmarks Example} illustrates how to subclass
QXmlDefaultHandler to read an XML bookmark file (XBEL) and
how to generate XML by hand.
@@ -606,7 +606,7 @@
DOM implementation.
To get started please refer to the \l QDomDocument documentation.
- You might also want to take a look at the \l{DOM Bookmarks example},
+ You might also want to take a look at the \l{DOM Bookmarks Example},
which illustrates how to read and write an XML bookmark file (XBEL)
using DOM.
*/
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index fbd89e4045..9eb741edac 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -23,12 +23,12 @@ uikit: SUBDIRS = corelib gui
cross_compile: SUBDIRS -= tools cmake installed_cmake
else:!qtConfig(process): SUBDIRS -= tools
-!qtHaveModule(opengl): SUBDIRS -= opengl
+winrt|!qtHaveModule(opengl): SUBDIRS -= opengl
!qtHaveModule(gui): SUBDIRS -= gui
!qtHaveModule(widgets): SUBDIRS -= widgets
!qtHaveModule(printsupport): SUBDIRS -= printsupport
!qtHaveModule(concurrent): SUBDIRS -= concurrent
-!qtHaveModule(network): SUBDIRS -= network
+winrt|!qtHaveModule(network): SUBDIRS -= network
!qtHaveModule(dbus): SUBDIRS -= dbus
!qtHaveModule(xml): SUBDIRS -= xml
!qtHaveModule(sql): SUBDIRS -= sql
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
index 7f685b0338..51d0d2879e 100644
--- a/tests/auto/cmake/CMakeLists.txt
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -146,6 +146,7 @@ endif()
expect_pass(test_interface_link_libraries)
expect_pass(test_moc_macro_target)
+expect_pass(test_add_big_resource)
if (NOT CMAKE_VERSION VERSION_LESS 3.8)
# With earlier CMake versions, this test would simply run moc multiple times and lead to:
diff --git a/tests/auto/cmake/test_add_big_resource/CMakeLists.txt b/tests/auto/cmake/test_add_big_resource/CMakeLists.txt
new file mode 100644
index 0000000000..f928b11278
--- /dev/null
+++ b/tests/auto/cmake/test_add_big_resource/CMakeLists.txt
@@ -0,0 +1,13 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(test_add_big_resource)
+
+find_package(Qt5Core REQUIRED)
+
+qt5_wrap_cpp(moc_files myobject.h)
+
+qt5_add_big_resources(rcc_files "test_add_big_resource.qrc" "test_add_big_resource2.qrc")
+
+add_executable(myobject myobject.cpp ${moc_files} ${rcc_files})
+target_link_libraries(myobject ${Qt5Core_LIBRARIES})
diff --git a/tests/auto/cmake/test_add_big_resource/myobject.cpp b/tests/auto/cmake/test_add_big_resource/myobject.cpp
new file mode 100644
index 0000000000..5d320b8592
--- /dev/null
+++ b/tests/auto/cmake/test_add_big_resource/myobject.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "myobject.h"
+
+MyObject::MyObject(QObject *parent)
+ : QObject(parent)
+{
+ emit someSignal();
+}
+
+int main(int argc, char **argv)
+{
+ MyObject myObject;
+ // Compile error if the resource file was not created.
+ Q_INIT_RESOURCE(test_add_big_resource);
+ Q_INIT_RESOURCE(test_add_big_resource2);
+ return 0;
+}
diff --git a/tests/auto/cmake/test_add_big_resource/myobject.h b/tests/auto/cmake/test_add_big_resource/myobject.h
new file mode 100644
index 0000000000..b6fbce32cd
--- /dev/null
+++ b/tests/auto/cmake/test_add_big_resource/myobject.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MYOBJECT_H
+#define MYOBJECT_H
+
+#include <QObject>
+
+class MyObject : public QObject
+{
+ Q_OBJECT
+public:
+ MyObject(QObject *parent = 0);
+
+signals:
+ void someSignal();
+};
+
+#endif
diff --git a/tests/auto/cmake/test_add_big_resource/resource_file.txt b/tests/auto/cmake/test_add_big_resource/resource_file.txt
new file mode 100644
index 0000000000..2c604a4f18
--- /dev/null
+++ b/tests/auto/cmake/test_add_big_resource/resource_file.txt
@@ -0,0 +1 @@
+Ken sent me.
diff --git a/tests/auto/cmake/test_add_big_resource/resource_file2.txt b/tests/auto/cmake/test_add_big_resource/resource_file2.txt
new file mode 100644
index 0000000000..2c604a4f18
--- /dev/null
+++ b/tests/auto/cmake/test_add_big_resource/resource_file2.txt
@@ -0,0 +1 @@
+Ken sent me.
diff --git a/tests/auto/cmake/test_add_big_resource/test_add_big_resource.qrc b/tests/auto/cmake/test_add_big_resource/test_add_big_resource.qrc
new file mode 100644
index 0000000000..00a17f541f
--- /dev/null
+++ b/tests/auto/cmake/test_add_big_resource/test_add_big_resource.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>resource_file.txt</file>
+</qresource>
+</RCC>
+
diff --git a/tests/auto/cmake/test_add_big_resource/test_add_big_resource2.qrc b/tests/auto/cmake/test_add_big_resource/test_add_big_resource2.qrc
new file mode 100644
index 0000000000..e21cc5e138
--- /dev/null
+++ b/tests/auto/cmake/test_add_big_resource/test_add_big_resource2.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>resource_file2.txt</file>
+</qresource>
+</RCC>
+
diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
index f539f012df..b864b065e6 100644
--- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
+++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
@@ -2379,7 +2379,7 @@ void tst_QtConcurrentMap::stlContainers()
InstanceCounter ic_fn(const InstanceCounter & ic)
{
return InstanceCounter(ic);
-};
+}
// Verify that held results are deleted when a future is
// assigned over with operator ==
diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST b/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST
index fe1d5bd968..b5b37b4498 100644
--- a/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST
+++ b/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST
@@ -1,2 +1,3 @@
[deleteChildrenWithRunningGroup]
osx-10.12
+osx-10.13
diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST
index 2a31afd735..4c999ff88f 100644
--- a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST
+++ b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST
@@ -3,5 +3,6 @@ windows
[finishWithUncontrolledAnimation]
windows
osx-10.12
+osx-10.13
[groupWithZeroDurationAnimations]
osx
diff --git a/tests/auto/corelib/codecs/qtextcodec/echo/echo.pro b/tests/auto/corelib/codecs/qtextcodec/echo/echo.pro
index bf791ffc61..512da8939b 100644
--- a/tests/auto/corelib/codecs/qtextcodec/echo/echo.pro
+++ b/tests/auto/corelib/codecs/qtextcodec/echo/echo.pro
@@ -1,6 +1,4 @@
SOURCES += main.cpp
QT = core
-CONFIG -= app_bundle debug_and_release_target
-CONFIG += console
-
+load(qt_test_helper)
diff --git a/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro b/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro
index 302d887fc7..15de02a42d 100644
--- a/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro
+++ b/tests/auto/corelib/codecs/qtextcodec/qtextcodec.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = test echo
+SUBDIRS = test.pro
+unix: SUBDIRS += echo
diff --git a/tests/auto/corelib/codecs/qtextcodec/test.pro b/tests/auto/corelib/codecs/qtextcodec/test.pro
new file mode 100644
index 0000000000..7505c5ad51
--- /dev/null
+++ b/tests/auto/corelib/codecs/qtextcodec/test.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+QT = core testlib
+SOURCES = tst_qtextcodec.cpp
+
+TARGET = tst_qtextcodec
+TESTDATA += *.txt
diff --git a/tests/auto/corelib/codecs/qtextcodec/test/test.pro b/tests/auto/corelib/codecs/qtextcodec/test/test.pro
deleted file mode 100644
index e0a1bbd88e..0000000000
--- a/tests/auto/corelib/codecs/qtextcodec/test/test.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-CONFIG += testcase
-QT = core testlib
-SOURCES = ../tst_qtextcodec.cpp
-
-TARGET = ../tst_qtextcodec
-win32 {
- CONFIG(debug, debug|release) {
- TARGET = ../../debug/tst_qtextcodec
- } else {
- TARGET = ../../release/tst_qtextcodec
- }
-}
-TESTDATA += ../*.txt
diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
index f8f9387abb..6cadebfd7f 100644
--- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
+++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
@@ -2092,7 +2092,7 @@ void tst_QTextCodec::toLocal8Bit()
QSKIP("No qprocess support", SkipAll);
#else
QProcess process;
- process.start("echo/echo");
+ process.start("echo_helper");
QString string(QChar(0x410));
process.write((const char*)string.utf16(), string.length()*2);
@@ -2429,7 +2429,7 @@ void tst_QTextCodec::userCodec()
QVERIFY(!QTextCodec::availableCodecs().contains("UserCodec"));
QVERIFY(!QTextCodec::codecForName("UserCodec"));
- QTextCodec *codec = new UserCodec;
+ UserCodec *codec = new UserCodec;
executedOnce = true;
QList<QByteArray> availableCodecs = QTextCodec::availableCodecs();
@@ -2448,6 +2448,11 @@ void tst_QTextCodec::userCodec()
pcodec = QTextCodec::codecForMib(5000);
QCOMPARE(pcodec, codec);
+
+ delete codec;
+
+ pcodec = QTextCodec::codecForName("UserCodec");
+ QCOMPARE(pcodec, nullptr);
}
struct DontCrashAtExit {
diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
index 8f78aa937c..9ce1748e72 100644
--- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
+++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -71,7 +71,7 @@ void tst_Utf8::initTestCase()
// is the locale UTF-8?
if (QString(QChar(QChar::ReplacementCharacter)).toLocal8Bit() == "\xEF\xBF\xBD") {
QTest::newRow("localecodec") << true;
- qDebug() << "locale is utf8";
+ qInfo() << "locale is utf8";
}
}
@@ -227,6 +227,15 @@ void tst_Utf8::invalidUtf8()
// GNU libc's iconv is known to accept U+FFFF and U+FFFE encoded as UTF-8
// OS X's iconv is known to accept those, plus surrogates and codepoints above U+10FFFF
if (!useLocale)
+ QVERIFY(decoder->hasFailure() || decoder->needsMoreData());
+ else if (!decoder->hasFailure() && !decoder->needsMoreData())
+ qWarning("System codec does not report failure when it should. Should report bug upstream.");
+
+ // add a continuation character and test that we don't accidentally use it
+ // (buffer overrun)
+ utf8 += char(0x80 | 0x3f);
+ decoder->toUnicode(utf8.constData(), utf8.size() - 1);
+ if (!useLocale)
QVERIFY(decoder->hasFailure());
else if (!decoder->hasFailure())
qWarning("System codec does not report failure when it should. Should report bug upstream.");
diff --git a/tests/auto/corelib/codecs/utf8/utf8data.cpp b/tests/auto/corelib/codecs/utf8/utf8data.cpp
index 2267dc8514..221e1d5579 100644
--- a/tests/auto/corelib/codecs/utf8/utf8data.cpp
+++ b/tests/auto/corelib/codecs/utf8/utf8data.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -29,15 +30,24 @@
void loadInvalidUtf8Rows()
{
- QTest::newRow("1char") << QByteArray("\x80");
- QTest::newRow("2chars-1") << QByteArray("\xC2\xC0");
- QTest::newRow("2chars-2") << QByteArray("\xC3\xDF");
- QTest::newRow("2chars-3") << QByteArray("\xC7\xF0");
- QTest::newRow("3chars-1") << QByteArray("\xE0\xA0\xC0");
- QTest::newRow("3chars-2") << QByteArray("\xE0\xC0\xA0");
- QTest::newRow("4chars-1") << QByteArray("\xF0\x90\x80\xC0");
- QTest::newRow("4chars-2") << QByteArray("\xF0\x90\xC0\x80");
- QTest::newRow("4chars-3") << QByteArray("\xF0\xC0\x80\x80");
+ // Wrong continuations
+ QTest::newRow("bad-continuation-1char") << QByteArray("\x80");
+ QTest::newRow("bad-continuation-2chars-1") << QByteArray("\xC2\xC0");
+ QTest::newRow("bad-continuation-2chars-2") << QByteArray("\xC3\xDF");
+ QTest::newRow("bad-continuation-2chars-3") << QByteArray("\xC7\xF0");
+ QTest::newRow("bad-continuation-3chars-1") << QByteArray("\xE0\xA0\xC0");
+ QTest::newRow("bad-continuation-3chars-2") << QByteArray("\xE0\xC0\xA0");
+ QTest::newRow("bad-continuation-4chars-1") << QByteArray("\xF0\x90\x80\xC0");
+ QTest::newRow("bad-continuation-4chars-2") << QByteArray("\xF0\x90\xC0\x80");
+ QTest::newRow("bad-continuation-4chars-3") << QByteArray("\xF0\xC0\x80\x80");
+
+ // Too short
+ QTest::newRow("too-short-2chars") << QByteArray("\xC2");
+ QTest::newRow("too-short-3chars-1") << QByteArray("\xE0");
+ QTest::newRow("too-short-3chars-2") << QByteArray("\xE0\xA0");
+ QTest::newRow("too-short-4chars-1") << QByteArray("\xF0");
+ QTest::newRow("too-short-4chars-2") << QByteArray("\xF0\x90");
+ QTest::newRow("too-short-4chars-3") << QByteArray("\xF0\x90\x80");
// Surrogate pairs must now be present either
// U+D800: 1101 10 0000 00 0000
diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp
index 2f1b56629a..6129184738 100644
--- a/tests/auto/corelib/global/qflags/tst_qflags.cpp
+++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp
@@ -39,6 +39,7 @@ private slots:
void classEnum();
void initializerLists();
void testSetFlags();
+ void adl();
};
void tst_QFlags::testFlag() const
@@ -304,6 +305,27 @@ void tst_QFlags::testSetFlags()
QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour));
}
+namespace SomeNS {
+enum Foo { Foo_A = 1 << 0, Foo_B = 1 << 1, Foo_C = 1 << 2 };
+
+Q_DECLARE_FLAGS(Foos, Foo)
+Q_DECLARE_OPERATORS_FOR_FLAGS(Foos);
+
+Qt::Alignment alignment()
+{
+ // Checks that the operator| works, despite there is another operator| in this namespace.
+ return Qt::AlignLeft | Qt::AlignTop;
+}
+}
+
+void tst_QFlags::adl()
+{
+ SomeNS::Foos fl = SomeNS::Foo_B | SomeNS::Foo_C;
+ QVERIFY(fl & SomeNS::Foo_B);
+ QVERIFY(!(fl & SomeNS::Foo_A));
+ QCOMPARE(SomeNS::alignment(), Qt::AlignLeft | Qt::AlignTop);
+}
+
// (statically) check QTypeInfo for QFlags instantiations:
enum MyEnum { Zero, One, Two, Four=4 };
Q_DECLARE_FLAGS( MyFlags, MyEnum )
diff --git a/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp b/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
index f02e902468..544cb1bf07 100644
--- a/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
+++ b/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
@@ -160,8 +160,10 @@ void tst_QGetPutEnv::intValue_data()
// some repetition from what is tested in getSetCheck()
QTest::newRow("empty") << QByteArray() << 0 << false;
- QTest::newRow("spaces-heading") << QByteArray(" 1") << 1 << true;
- QTest::newRow("spaces-trailing") << QByteArray("1 ") << 0 << false;
+ QTest::newRow("spaces-heading") << QByteArray(" \n\r\t1") << 1 << true;
+ QTest::newRow("spaces-trailing") << QByteArray("1 \n\r\t") << 1 << true;
+ QTest::newRow("junk-heading") << QByteArray("x1") << 0 << false;
+ QTest::newRow("junk-trailing") << QByteArray("1x") << 0 << false;
#define ROW(x, i, b) \
QTest::newRow(#x) << QByteArray(#x) << (i) << (b)
diff --git a/tests/auto/corelib/global/qlogging/app/app.pro b/tests/auto/corelib/global/qlogging/app/app.pro
index 30751d89ec..b90b685749 100644
--- a/tests/auto/corelib/global/qlogging/app/app.pro
+++ b/tests/auto/corelib/global/qlogging/app/app.pro
@@ -1,6 +1,15 @@
TEMPLATE = app
-TARGET = app
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ TARGET = ../debug/helper
+ } else {
+ TARGET = ../release/helper
+ }
+} else {
+ TARGET = ../helper
+}
+
QT = core
DESTDIR = ./
diff --git a/tests/auto/corelib/global/qlogging/test/test.pro b/tests/auto/corelib/global/qlogging/test/test.pro
index b48bf82cf9..91896d4494 100644
--- a/tests/auto/corelib/global/qlogging/test/test.pro
+++ b/tests/auto/corelib/global/qlogging/test/test.pro
@@ -1,11 +1,21 @@
CONFIG += testcase
-CONFIG -= debug_and_release_target
qtConfig(c++11): CONFIG += c++11
qtConfig(c++14): CONFIG += c++14
-TARGET = ../tst_qlogging
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/tst_qlogging
+ !android:!winrt: TEST_HELPER_INSTALLS = ../debug/helper
+ } else {
+ TARGET = ../../release/tst_qlogging
+ !android:!winrt: TEST_HELPER_INSTALLS = ../release/helper
+ }
+} else {
+ TARGET = ../tst_qlogging
+ !android:!winrt: TEST_HELPER_INSTALLS = ../helper
+}
+
QT = core testlib
SOURCES = ../tst_qlogging.cpp
DEFINES += QT_MESSAGELOGCONTEXT
-!android:!winrt: TEST_HELPER_INSTALLS = ../app/app
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
index e7a3748c30..d3ed1a6d0d 100644
--- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
+++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
@@ -64,7 +64,6 @@ private slots:
void formatLogMessage();
private:
- QString m_appDir;
QStringList m_baseEnvironment;
};
@@ -101,14 +100,6 @@ tst_qmessagehandler::tst_qmessagehandler()
void tst_qmessagehandler::initTestCase()
{
#if QT_CONFIG(process)
-# ifdef Q_OS_ANDROID
- m_appDir = QCoreApplication::applicationDirPath();
-# else // !android
- m_appDir = QFINDTESTDATA("app");
-# endif
- QVERIFY2(!m_appDir.isEmpty(), qPrintable(
- QString::fromLatin1("Couldn't find helper app dir starting from %1.").arg(QDir::currentPath())));
-
m_baseEnvironment = QProcess::systemEnvironment();
for (int i = 0; i < m_baseEnvironment.count(); ++i) {
if (m_baseEnvironment.at(i).startsWith("QT_MESSAGE_PATTERN=")) {
@@ -806,7 +797,7 @@ void tst_qmessagehandler::qMessagePattern_data()
#ifndef QT_NO_DEBUG
QTest::newRow("backtrace") << "[%{backtrace}] %{message}" << true << (QList<QByteArray>()
// MyClass::qt_static_metacall is explicitly marked as hidden in the Q_OBJECT macro
- << "[MyClass::myFunction|MyClass::mySlot1|?app?|" QT_NAMESPACE_STR "QMetaMethod::invoke|" QT_NAMESPACE_STR "QMetaObject::invokeMethod] from_a_function 34");
+ << "[MyClass::myFunction|MyClass::mySlot1|?helper?|" QT_NAMESPACE_STR "QMetaMethod::invoke|" QT_NAMESPACE_STR "QMetaObject::invokeMethod] from_a_function 34");
#endif
QTest::newRow("backtrace depth,separator") << "[%{backtrace depth=2 separator=\"\n\"}] %{message}" << true << (QList<QByteArray>()
@@ -830,10 +821,10 @@ void tst_qmessagehandler::qMessagePattern()
QFETCH(QList<QByteArray>, expected);
QProcess process;
-#ifdef Q_OS_ANDROID
- const QString appExe = m_appDir + "/libapp.so";
-#else // !android
- const QString appExe = m_appDir + "/app";
+#ifndef Q_OS_ANDROID
+ const QString appExe(QLatin1String("helper"));
+#else
+ const QString appExe(QCoreApplication::applicationDirPath() + QLatin1String("/libhelper.so"));
#endif
//
@@ -880,10 +871,10 @@ void tst_qmessagehandler::setMessagePattern()
//
QProcess process;
-#ifdef Q_OS_ANDROID
- const QString appExe = m_appDir + "/libapp.so";
-#else // !android
- const QString appExe = m_appDir + "/app";
+#ifndef Q_OS_ANDROID
+ const QString appExe(QLatin1String("helper"));
+#else
+ const QString appExe(QCoreApplication::applicationDirPath() + QLatin1String("/libhelper.so"));
#endif
// make sure there is no QT_MESSAGE_PATTERN in the environment
diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
index 7a6842d144..7c04611823 100644
--- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
+++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
@@ -52,7 +52,7 @@
// values chosen at random
static const quint32 RandomValue32 = 0x4d1169f1U;
static const quint64 RandomValue64 = Q_UINT64_C(0x3ce63161b998aa91);
-static const double RandomValueFP = double(0.3010463714599609f);
+static const double RandomValueFP = double(0.3010463714599609);
static void setRNGControl(uint v)
{
diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
index 6934818dcf..7043969c2f 100644
--- a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
+++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
@@ -39,9 +39,17 @@ class tst_QtEndian: public QObject
private slots:
void fromBigEndian();
void fromLittleEndian();
+ void fromBigEndianRegion_data();
+ void fromBigEndianRegion();
+ void fromLittleEndianRegion_data() { fromBigEndianRegion_data(); }
+ void fromLittleEndianRegion();
void toBigEndian();
void toLittleEndian();
+ void toBigEndianRegion_data() { fromBigEndianRegion_data(); }
+ void toBigEndianRegion();
+ void toLittleEndianRegion_data() { fromBigEndianRegion_data(); }
+ void toLittleEndianRegion();
void endianIntegers_data();
void endianIntegers();
@@ -59,6 +67,12 @@ struct TestData
quint8 reserved;
};
+template <typename T> T getData(const TestData &d);
+template <> quint8 getData(const TestData &d) { return d.data8; }
+template <> quint16 getData(const TestData &d) { return d.data16; }
+template <> quint32 getData(const TestData &d) { return d.data32; }
+template <> quint64 getData(const TestData &d) { return d.data64; }
+
union RawTestData
{
uchar rawData[sizeof(TestData)];
@@ -108,6 +122,106 @@ void tst_QtEndian::fromLittleEndian()
#undef ENDIAN_TEST
+template <typename T>
+void transformRegion_template(T (*transformOne)(T), void (*transformRegion)(const void *, qsizetype, void *))
+{
+ enum { Size = 64 };
+ T source[Size];
+ T dest[Size];
+ T expected = transformOne(getData<T>(inNativeEndian));
+ std::fill_n(source, +Size, getData<T>(inNativeEndian));
+ memset(dest, 0, sizeof(dest));
+
+ auto checkBounds = [&](int from) {
+ for ( ; from < Size; ++from)
+ QCOMPARE(dest[from], T(0));
+ };
+
+ transformRegion(source, 1, dest);
+ QCOMPARE(dest[0], expected);
+ checkBounds(1);
+ memset(dest, 0, sizeof(T));
+
+ transformRegion(source, 2, dest);
+ QCOMPARE(dest[0], expected);
+ QCOMPARE(dest[1], expected);
+ checkBounds(2);
+ memset(dest, 0, sizeof(T) * 2);
+
+ transformRegion(source, 3, dest);
+ QCOMPARE(dest[0], expected);
+ QCOMPARE(dest[1], expected);
+ QCOMPARE(dest[2], expected);
+ checkBounds(3);
+ memset(dest, 0, sizeof(T) * 3);
+
+ transformRegion(source, 4, dest);
+ QCOMPARE(dest[0], expected);
+ QCOMPARE(dest[1], expected);
+ QCOMPARE(dest[2], expected);
+ QCOMPARE(dest[3], expected);
+ checkBounds(4);
+ memset(dest, 0, sizeof(T) * 4);
+
+ transformRegion(source, 8, dest);
+ for (int i = 0; i < 8; ++i)
+ QCOMPARE(dest[i], expected);
+ checkBounds(8);
+ memset(dest, 0, sizeof(T) * 8);
+
+ transformRegion(source, 16, dest);
+ for (int i = 0; i < 16; ++i)
+ QCOMPARE(dest[i], expected);
+ checkBounds(16);
+ memset(dest, 0, sizeof(T) * 16);
+
+ transformRegion(source, 32, dest);
+ for (int i = 0; i < 32; ++i)
+ QCOMPARE(dest[i], expected);
+ checkBounds(32);
+ memset(dest, 0, sizeof(T) * 32);
+
+ transformRegion(source, 64, dest);
+ for (int i = 0; i < 64; ++i)
+ QCOMPARE(dest[i], expected);
+
+ // check transforming in-place
+ memcpy(dest, source, sizeof(dest));
+ transformRegion(dest, 64, dest);
+ for (int i = 0; i < 64; ++i)
+ QCOMPARE(dest[i], expected);
+}
+
+void tst_QtEndian::fromBigEndianRegion_data()
+{
+ QTest::addColumn<int>("size");
+ QTest::newRow("1") << 1;
+ QTest::newRow("2") << 2;
+ QTest::newRow("4") << 4;
+ QTest::newRow("8") << 8;
+}
+
+void tst_QtEndian::fromBigEndianRegion()
+{
+ QFETCH(int, size);
+ switch (size) {
+ case 1: return transformRegion_template<quint8>(qFromBigEndian<quint8>, qFromBigEndian<quint8>);
+ case 2: return transformRegion_template<quint16>(qFromBigEndian<quint16>, qFromBigEndian<quint16>);
+ case 4: return transformRegion_template<quint32>(qFromBigEndian<quint32>, qFromBigEndian<quint32>);
+ case 8: return transformRegion_template<quint64>(qFromBigEndian<quint64>, qFromBigEndian<quint64>);
+ }
+}
+
+void tst_QtEndian::fromLittleEndianRegion()
+{
+ QFETCH(int, size);
+ switch (size) {
+ case 1: return transformRegion_template<quint8>(qFromLittleEndian<quint8>, qFromLittleEndian<quint8>);
+ case 2: return transformRegion_template<quint16>(qFromLittleEndian<quint16>, qFromLittleEndian<quint16>);
+ case 4: return transformRegion_template<quint32>(qFromLittleEndian<quint32>, qFromLittleEndian<quint32>);
+ case 8: return transformRegion_template<quint64>(qFromLittleEndian<quint64>, qFromLittleEndian<quint64>);
+ }
+}
#define ENDIAN_TEST(endian, type, size) \
do { \
@@ -135,6 +249,28 @@ void tst_QtEndian::toLittleEndian()
#undef ENDIAN_TEST
+void tst_QtEndian::toBigEndianRegion()
+{
+ QFETCH(int, size);
+ switch (size) {
+ case 1: return transformRegion_template<quint8>(qToBigEndian<quint8>, qToBigEndian<quint8>);
+ case 2: return transformRegion_template<quint16>(qToBigEndian<quint16>, qToBigEndian<quint16>);
+ case 4: return transformRegion_template<quint32>(qToBigEndian<quint32>, qToBigEndian<quint32>);
+ case 8: return transformRegion_template<quint64>(qToBigEndian<quint64>, qToBigEndian<quint64>);
+ }
+}
+
+void tst_QtEndian::toLittleEndianRegion()
+{
+ QFETCH(int, size);
+ switch (size) {
+ case 1: return transformRegion_template<quint8>(qToLittleEndian<quint8>, qToLittleEndian<quint8>);
+ case 2: return transformRegion_template<quint16>(qToLittleEndian<quint16>, qToLittleEndian<quint16>);
+ case 4: return transformRegion_template<quint32>(qToLittleEndian<quint32>, qToLittleEndian<quint32>);
+ case 8: return transformRegion_template<quint64>(qToLittleEndian<quint64>, qToLittleEndian<quint64>);
+ }
+}
+
void tst_QtEndian::endianIntegers_data()
{
QTest::addColumn<int>("val");
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index b43ea7cfa5..7b8b1df166 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -38,6 +38,13 @@
class tst_QDebug: public QObject
{
Q_OBJECT
+public:
+ enum EnumType { EnumValue1 = 1, EnumValue2 = 2 };
+ enum FlagType { EnumFlag1 = 1, EnumFlag2 = 2 };
+ Q_ENUM(EnumType)
+ Q_DECLARE_FLAGS(Flags, FlagType)
+ Q_FLAG(Flags)
+
private slots:
void assignment() const;
void warningWithoutDebug() const;
@@ -637,6 +644,15 @@ void tst_QDebug::qDebugQFlags() const
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
+ // Test the output of QFlags with an enum not declared with Q_DECLARE_FLAGS and Q_FLAGS
+ QFlags<EnumType> flags2(EnumValue2);
+ qDebug() << flags2;
+ QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::EnumType>(EnumValue2)"));
+
+ // A now for one that was fully declared
+ tst_QDebug::Flags flags3(EnumFlag1);
+ qDebug() << flags3;
+ QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::FlagType>(EnumFlag1)"));
}
void tst_QDebug::textStreamModifiers() const
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index afa15fe895..30f0e447ad 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -33,7 +33,6 @@
#include <qdebug.h>
#include <qdir.h>
#include <qfileinfo.h>
-#include <qregexp.h>
#include <qstringlist.h>
#if defined(Q_OS_WIN)
diff --git a/tests/auto/corelib/io/qfile/.gitignore b/tests/auto/corelib/io/qfile/.gitignore
index c508239722..615264e4d4 100644
--- a/tests/auto/corelib/io/qfile/.gitignore
+++ b/tests/auto/corelib/io/qfile/.gitignore
@@ -1,6 +1,10 @@
tst_qfile
-stdinprocess/stdinprocess
-stdinprocess/stdinprocess.exe
+stdinprocess_helper
+stdinprocess_helper.exe
+debug/stdinprocess_helper
+debug/stdinprocess_helper.exe
+release/stdinprocess_helper
+release/stdinprocess_helper.exe
readonlyfile
newfile.txt
appendfile.txt
diff --git a/tests/auto/corelib/io/qfile/qfile.pro b/tests/auto/corelib/io/qfile/qfile.pro
index 0735daedb3..91c5c15f66 100644
--- a/tests/auto/corelib/io/qfile/qfile.pro
+++ b/tests/auto/corelib/io/qfile/qfile.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = test stdinprocess
+SUBDIRS = test.pro
+!winrt: SUBDIRS += stdinprocess
diff --git a/tests/auto/corelib/io/qfile/stdinprocess/main.cpp b/tests/auto/corelib/io/qfile/stdinprocess/main.cpp
index 6ff42c2485..77a1932bd5 100644
--- a/tests/auto/corelib/io/qfile/stdinprocess/main.cpp
+++ b/tests/auto/corelib/io/qfile/stdinprocess/main.cpp
@@ -33,7 +33,7 @@
int main(int argc, char *argv[])
{
if (argc < 2) {
- printf("usage: stdinprocess <all|line <0|1>>\n");
+ printf("usage: stdinprocess_helper <all|line <0|1>>\n");
printf("echos all its input to its output.\n");
return 1;
}
diff --git a/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro b/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
index 8e463e4cef..512da8939b 100644
--- a/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
+++ b/tests/auto/corelib/io/qfile/stdinprocess/stdinprocess.pro
@@ -1,8 +1,4 @@
SOURCES += main.cpp
QT = core
-CONFIG -= app_bundle debug_and_release_target
-CONFIG += console
-# This app is testdata for tst_qfile
-target.path = $$[QT_INSTALL_TESTS]/tst_qfile/$$TARGET
-INSTALLS += target
+load(qt_test_helper)
diff --git a/tests/auto/corelib/io/qfile/test.pro b/tests/auto/corelib/io/qfile/test.pro
new file mode 100644
index 0000000000..95389ab3e2
--- /dev/null
+++ b/tests/auto/corelib/io/qfile/test.pro
@@ -0,0 +1,26 @@
+CONFIG += testcase
+QT = core-private testlib
+qtHaveModule(network): QT += network
+else: DEFINES += QT_NO_NETWORK
+
+contains(CONFIG, builtin_testdata) {
+ DEFINES += BUILTIN_TESTDATA
+}
+
+TESTDATA += BLACKLIST
+
+TARGET = tst_qfile
+
+SOURCES = tst_qfile.cpp
+INCLUDEPATH += ../../../../shared/
+HEADERS += ../../../../shared/emulationdetector.h
+
+RESOURCES += qfile.qrc rename-fallback.qrc copy-fallback.qrc
+
+TESTDATA += \
+ dosfile.txt noendofline.txt testfile.txt \
+ testlog.txt two.dots.file tst_qfile.cpp \
+ Makefile forCopying.txt forRenaming.txt \
+ resources/file1.ext1
+
+win32:!winrt: LIBS += -lole32 -luuid
diff --git a/tests/auto/corelib/io/qfile/test/test.pro b/tests/auto/corelib/io/qfile/test/test.pro
deleted file mode 100644
index 1472ddbb83..0000000000
--- a/tests/auto/corelib/io/qfile/test/test.pro
+++ /dev/null
@@ -1,25 +0,0 @@
-CONFIG += testcase
-CONFIG -= debug_and_release_target
-QT = core-private core testlib
-qtHaveModule(network): QT += network
-else: DEFINES += QT_NO_NETWORK
-
-contains(CONFIG, builtin_testdata) {
- DEFINES += BUILTIN_TESTDATA
-}
-
-TESTDATA += ../BLACKLIST
-
-TARGET = ../tst_qfile
-SOURCES = ../tst_qfile.cpp
-INCLUDEPATH += ../../../../../shared/
-HEADERS += ../../../../../shared/emulationdetector.h
-
-RESOURCES += ../qfile.qrc ../rename-fallback.qrc ../copy-fallback.qrc
-
-TESTDATA += ../dosfile.txt ../noendofline.txt ../testfile.txt \
- ../testlog.txt ../two.dots.file ../tst_qfile.cpp \
- ../Makefile ../forCopying.txt ../forRenaming.txt \
- ../resources/file1.ext1
-
-win32:!winrt: LIBS+=-lole32 -luuid
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 6665200585..678a80c3f7 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -367,7 +367,7 @@ private:
QTemporaryDir m_temporaryDir;
const QString m_oldDir;
- QString m_stdinProcessDir;
+ QString m_stdinProcess;
QString m_testSourceFile;
QString m_testLogFile;
QString m_dosFile;
@@ -379,12 +379,6 @@ private:
QString m_noEndOfLineFile;
};
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- #define STDINPROCESS_NAME "libstdinprocess.so"
-#else // !android || android_embedded
- #define STDINPROCESS_NAME "stdinprocess"
-#endif // android && !android_embededd
-
static const char noReadFile[] = "noreadfile";
static const char readOnlyFile[] = "readonlyfile";
@@ -455,11 +449,13 @@ void tst_QFile::initTestCase()
QVERIFY2(m_temporaryDir.isValid(), qPrintable(m_temporaryDir.errorString()));
#if QT_CONFIG(process)
#if defined(Q_OS_ANDROID)
- m_stdinProcessDir = QCoreApplication::applicationDirPath();
+ m_stdinProcess = QCoreApplication::applicationDirPath() + QLatin1String("/libstdinprocess_helper.so");
+#elif defined(Q_OS_WIN)
+ m_stdinProcess = QFINDTESTDATA("stdinprocess_helper.exe");
#else
- m_stdinProcessDir = QFINDTESTDATA("stdinprocess");
+ m_stdinProcess = QFINDTESTDATA("stdinprocess_helper");
#endif
- QVERIFY(!m_stdinProcessDir.isEmpty());
+ QVERIFY(!m_stdinProcess.isEmpty());
#endif
m_testLogFile = QFINDTESTDATA("testlog.txt");
QVERIFY(!m_testLogFile.isEmpty());
@@ -981,7 +977,7 @@ void tst_QFile::readAllStdin()
QProcess process;
StdinReaderProcessGuard processGuard(&process);
- process.start(m_stdinProcessDir + QStringLiteral("/" STDINPROCESS_NAME), QStringList(QStringLiteral("all")));
+ process.start(m_stdinProcess, QStringList(QStringLiteral("all")));
QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
for (int i = 0; i < 5; ++i) {
QTest::qWait(1000);
@@ -1014,7 +1010,7 @@ void tst_QFile::readLineStdin()
for (int i = 0; i < 2; ++i) {
QProcess process;
StdinReaderProcessGuard processGuard(&process);
- process.start(m_stdinProcessDir + QStringLiteral("/" STDINPROCESS_NAME),
+ process.start(m_stdinProcess,
QStringList() << QStringLiteral("line") << QString::number(i),
QIODevice::Text | QIODevice::ReadWrite);
QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
@@ -1050,7 +1046,7 @@ void tst_QFile::readLineStdin_lineByLine()
for (int i = 0; i < 2; ++i) {
QProcess process;
StdinReaderProcessGuard processGuard(&process);
- process.start(m_stdinProcessDir + QStringLiteral("/" STDINPROCESS_NAME),
+ process.start(m_stdinProcess,
QStringList() << QStringLiteral("line") << QString::number(i),
QIODevice::Text | QIODevice::ReadWrite);
QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
@@ -1297,6 +1293,12 @@ void tst_QFile::append()
f.putChar('a');
f.close();
QCOMPARE(int(f.size()), 2);
+
+ QVERIFY2(f.open(QIODevice::Append | QIODevice::Truncate), msgOpenFailed(f).constData());
+ QCOMPARE(f.pos(), 0);
+ f.putChar('a');
+ f.close();
+ QCOMPARE(int(f.size()), 1);
}
void tst_QFile::permissions_data()
@@ -1833,13 +1835,14 @@ void tst_QFile::encodeName()
void tst_QFile::truncate()
{
- for (int i = 0; i < 2; ++i) {
+ const QIODevice::OpenModeFlag modes[] = { QFile::ReadWrite, QIODevice::WriteOnly, QIODevice::Append };
+ for (auto mode : modes) {
QFile file("truncate.txt");
QVERIFY2(file.open(QFile::WriteOnly), msgOpenFailed(file).constData());
file.write(QByteArray(200, '@'));
file.close();
- QVERIFY2(file.open((i ? QFile::WriteOnly : QFile::ReadWrite) | QFile::Truncate), msgOpenFailed(file).constData());
+ QVERIFY2(file.open(mode | QFile::Truncate), msgOpenFailed(file).constData());
file.write(QByteArray(100, '$'));
file.close();
@@ -2210,7 +2213,8 @@ public:
uint ownerId(FileOwner) const { return 0; }
QString owner(FileOwner) const { return QString(); }
QDateTime fileTime(FileTime) const { return QDateTime(); }
- bool setFileTime(const QDateTime &newDate, FileTime time) { return false; }
+ bool setFileTime(const QDateTime &newDate, FileTime time)
+ { Q_UNUSED(newDate) Q_UNUSED(time) return false; }
private:
int number;
@@ -2755,19 +2759,20 @@ void tst_QFile::renameMultiple()
void tst_QFile::appendAndRead()
{
- QFile writeFile(QLatin1String("appendfile.txt"));
- QVERIFY2(writeFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgOpenFailed(writeFile).constData());
+ const QString fileName(QStringLiteral("appendfile.txt"));
+ QFile writeFile(fileName);
+ QVERIFY2(writeFile.open(QIODevice::Append | QIODevice::Truncate), msgOpenFailed(writeFile).constData());
- QFile readFile(QLatin1String("appendfile.txt"));
+ QFile readFile(fileName);
QVERIFY2(readFile.open(QIODevice::ReadOnly), msgOpenFailed(readFile).constData());
// Write to the end of the file, then read that character back, and so on.
for (int i = 0; i < 100; ++i) {
char c = '\0';
- writeFile.putChar(char(i % 256));
+ writeFile.putChar(char(i));
writeFile.flush();
QVERIFY(readFile.getChar(&c));
- QCOMPARE(c, char(i % 256));
+ QCOMPARE(c, char(i));
QCOMPARE(readFile.pos(), writeFile.pos());
}
@@ -2778,8 +2783,6 @@ void tst_QFile::appendAndRead()
writeFile.flush();
QCOMPARE(readFile.read(size).size(), size);
}
-
- readFile.close();
}
void tst_QFile::miscWithUncPathAsCurrentDir()
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index 87d5675e7a..017eebe153 100644
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -199,7 +199,8 @@ private slots:
void fileTimes_data();
void fileTimes();
- void fileTimes_oldFile();
+ void fakeFileTimes_data();
+ void fakeFileTimes();
void isSymLink_data();
void isSymLink();
@@ -629,6 +630,16 @@ void tst_QFileInfo::canonicalFilePath()
info.canonicalFilePath();
#if defined(Q_OS_UNIX)
+ // If this file exists, you can't log in to run this test ...
+ const QString notExtantPath(QStringLiteral("/etc/nologin"));
+ QFileInfo notExtant(notExtantPath);
+ QCOMPARE(notExtant.canonicalFilePath(), QString());
+
+ // A path with a non-directory as a directory component also doesn't exist:
+ const QString badDirPath(QStringLiteral("/dev/null/sub/dir/n'existe.pas"));
+ QFileInfo badDir(badDirPath);
+ QCOMPARE(badDir.canonicalFilePath(), QString());
+
// This used to crash on Mac
QFileInfo dontCrash(QLatin1String("/"));
QCOMPARE(dontCrash.canonicalFilePath(), QLatin1String("/"));
@@ -1212,12 +1223,23 @@ void tst_QFileInfo::fileTimes()
QVERIFY(writeTime < beforeRead);
}
-void tst_QFileInfo::fileTimes_oldFile()
+void tst_QFileInfo::fakeFileTimes_data()
{
+ QTest::addColumn<QDateTime>("when");
+
// This is 2^{31} seconds before 1970-01-01 15:14:8,
// i.e. shortly after the start of time_t, in any time-zone:
- const QDateTime early(QDate(1901, 12, 14), QTime(12, 0));
- QFile file("ancientfile.txt");
+ QTest::newRow("early") << QDateTime(QDate(1901, 12, 14), QTime(12, 0));
+
+ // QTBUG-12006 claims XP handled this (2010-Mar-26 8:46:10) wrong due to an MS API bug:
+ QTest::newRow("XP-bug") << QDateTime::fromTime_t(1269593170);
+}
+
+void tst_QFileInfo::fakeFileTimes()
+{
+ QFETCH(QDateTime, when);
+
+ QFile file("faketimefile.txt");
file.open(QIODevice::WriteOnly);
file.write("\n", 1);
file.close();
@@ -1228,15 +1250,13 @@ void tst_QFileInfo::fileTimes_oldFile()
modification time, so need to re-open for read in order to setFileTime().
*/
file.open(QIODevice::ReadOnly);
- bool ok = file.setFileTime(early, QFileDevice::FileModificationTime);
+ bool ok = file.setFileTime(when, QFileDevice::FileModificationTime);
file.close();
- if (ok) {
- QFileInfo info(file.fileName());
- QCOMPARE(info.lastModified(), early);
- } else {
- QSKIP("Unable to set file metadata to ancient values");
- }
+ if (ok)
+ QCOMPARE(QFileInfo(file.fileName()).lastModified(), when);
+ else
+ QSKIP("Unable to set file metadata to contrived values");
}
void tst_QFileInfo::isSymLink_data()
diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
index 5b61a6007d..a10e706ed7 100644
--- a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
+++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
@@ -187,6 +187,13 @@ private slots:
"default=false");
QCOMPARE(parser.rules().size(), 1);
+ // QSettings escapes * to %2A when writing.
+ parser.setContent("[Rules]\n"
+ "module.%2A=false");
+ QCOMPARE(parser.rules().size(), 1);
+ QCOMPARE(parser.rules().first().category, QString("module."));
+ QCOMPARE(parser.rules().first().flags, QLoggingRule::LeftFilter);
+
parser.setContent("[OtherSection]\n"
"default=false");
QCOMPARE(parser.rules().size(), 0);
diff --git a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
index b78fa29fb6..17c51eaaf4 100644
--- a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
+++ b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
@@ -65,7 +65,7 @@ void tst_QNoDebug::streaming() const
{
QDateTime dt(QDate(1,2,3),QTime(4,5,6));
const QByteArray debugString = dt.toString(QStringViewLiteral("yyyy-MM-dd HH:mm:ss.zzz t")).toLatin1();
- const QByteArray message = "QDateTime(" + debugString + " Qt::TimeSpec(LocalTime))";
+ const QByteArray message = "QDateTime(" + debugString + " Qt::LocalTime)";
QTest::ignoreMessage(QtWarningMsg, message.constData());
qWarning() << dt;
}
diff --git a/tests/auto/corelib/io/qresourceengine/qresourceengine.pro b/tests/auto/corelib/io/qresourceengine/qresourceengine.pro
index e8071297b1..1e12a41dea 100644
--- a/tests/auto/corelib/io/qresourceengine/qresourceengine.pro
+++ b/tests/auto/corelib/io/qresourceengine/qresourceengine.pro
@@ -1,25 +1,2 @@
-CONFIG += testcase
-TARGET = tst_qresourceengine
-
-QT = core testlib
-SOURCES = tst_qresourceengine.cpp
-RESOURCES += testqrc/test.qrc
-
-qtPrepareTool(QMAKE_RCC, rcc, _DEP)
-runtime_resource.target = runtime_resource.rcc
-runtime_resource.depends = $$PWD/testqrc/test.qrc $$QMAKE_RCC_EXE
-runtime_resource.commands = $$QMAKE_RCC -root /runtime_resource/ -binary $$PWD/testqrc/test.qrc -o $${runtime_resource.target}
-QMAKE_EXTRA_TARGETS = runtime_resource
-PRE_TARGETDEPS += $${runtime_resource.target}
-QMAKE_DISTCLEAN += $${runtime_resource.target}
-
-TESTDATA += \
- parentdir.txt \
- testqrc/*
-GENERATED_TESTDATA = $${runtime_resource.target}
-
-android:!android-embedded {
- RESOURCES += android_testdata.qrc
-}
-
-builtin_testdata: DEFINES += BUILTIN_TESTDATA
+TEMPLATE = subdirs
+SUBDIRS = staticplugin qresourceengine_test.pro
diff --git a/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro b/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro
new file mode 100644
index 0000000000..3838a72c21
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/qresourceengine_test.pro
@@ -0,0 +1,33 @@
+CONFIG += testcase
+TARGET = tst_qresourceengine
+
+QT = core testlib
+SOURCES = tst_qresourceengine.cpp
+RESOURCES += testqrc/test.qrc
+
+qtPrepareTool(QMAKE_RCC, rcc, _DEP)
+runtime_resource.target = runtime_resource.rcc
+runtime_resource.depends = $$PWD/testqrc/test.qrc $$QMAKE_RCC_EXE
+runtime_resource.commands = $$QMAKE_RCC -root /runtime_resource/ -binary $$PWD/testqrc/test.qrc -o $${runtime_resource.target}
+QMAKE_EXTRA_TARGETS = runtime_resource
+PRE_TARGETDEPS += $${runtime_resource.target}
+QMAKE_DISTCLEAN += $${runtime_resource.target}
+
+TESTDATA += \
+ parentdir.txt \
+ testqrc/*
+GENERATED_TESTDATA = $${runtime_resource.target}
+
+android:!android-embedded {
+ RESOURCES += android_testdata.qrc
+}
+
+win32 {
+ CONFIG(debug, debug|release): LIBS += -Lstaticplugin/debug
+ else: LIBS += -Lstaticplugin/release
+} else {
+ LIBS += -Lstaticplugin
+}
+LIBS += -lmoctestplugin
+
+builtin_testdata: DEFINES += BUILTIN_TESTDATA
diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/.gitignore b/tests/auto/corelib/io/qresourceengine/staticplugin/.gitignore
new file mode 100644
index 0000000000..c397dde6a5
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/staticplugin/.gitignore
@@ -0,0 +1 @@
+moctestplugin_plugin_resources.cpp
diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp b/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp
new file mode 100644
index 0000000000..39a3a1e012
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp
@@ -0,0 +1,9 @@
+#include <QObject>
+
+class PluginClass : public QObject
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.tests.moc" FILE "staticplugin.json")
+};
+
+#include "main.moc"
diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.json b/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.json
new file mode 100644
index 0000000000..4103ecb18c
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.json
@@ -0,0 +1 @@
+{ "Keys": [ "staticplugin" ] }
diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.pro b/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.pro
new file mode 100644
index 0000000000..e19d884548
--- /dev/null
+++ b/tests/auto/corelib/io/qresourceengine/staticplugin/staticplugin.pro
@@ -0,0 +1,8 @@
+TEMPLATE = lib
+TARGET = moctestplugin
+CONFIG += plugin static
+SOURCES = main.cpp
+plugin_resource.files = main.cpp
+plugin_resource.prefix = /staticplugin
+RESOURCES += plugin_resource
+QT = core
diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
index b7e85e8f05..ab49dea6d8 100644
--- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
+++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp
@@ -57,6 +57,7 @@ private slots:
void doubleSlashInRoot();
void setLocale();
void lastModified();
+ void resourcesInStaticPlugins();
private:
const QString m_runtimeResourceRcc;
@@ -119,6 +120,7 @@ void tst_QResourceEngine::checkStructure_data()
<< QLatin1String("searchpath1")
<< QLatin1String("searchpath2")
<< QLatin1String("secondary_root")
+ << QLatin1String("staticplugin")
<< QLatin1String("test")
<< QLatin1String("withoutslashes");
@@ -127,7 +129,7 @@ void tst_QResourceEngine::checkStructure_data()
#endif
#if defined(BUILTIN_TESTDATA)
- rootContents.insert(8, QLatin1String("testqrc"));
+ rootContents.insert(9, QLatin1String("testqrc"));
#endif
@@ -520,6 +522,16 @@ void tst_QResourceEngine::lastModified()
}
}
+Q_IMPORT_PLUGIN(PluginClass)
+void tst_QResourceEngine::resourcesInStaticPlugins()
+{
+ // We built a separate static plugin and attempted linking against
+ // it. That should successfully register the resources linked into
+ // the plugin via moc generated Q_INIT_RESOURCE calls in a
+ // Q_CONSTRUCTOR_FUNCTION.
+ QVERIFY(QFile::exists(":/staticplugin/main.cpp"));
+}
+
QTEST_MAIN(tst_QResourceEngine)
#include "tst_qresourceengine.moc"
diff --git a/tests/auto/corelib/io/qsettings/qsettings.pro b/tests/auto/corelib/io/qsettings/qsettings.pro
index 5b4cc8a691..79552b62df 100644
--- a/tests/auto/corelib/io/qsettings/qsettings.pro
+++ b/tests/auto/corelib/io/qsettings/qsettings.pro
@@ -6,4 +6,6 @@ RESOURCES += qsettings.qrc
INCLUDEPATH += $$PWD/../../kernel/qmetatype
msvc: LIBS += advapi32.lib
+darwin: LIBS += -framework CoreFoundation
+
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
index db756ada39..5357194406 100644
--- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
+++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
@@ -531,7 +531,7 @@ void tst_QSettings::ctor()
// more details in QMacSettingsPrivate::QMacSettingsPrivate(), organization was comify()-ed
caseSensitive = settings5.fileName().contains("SoftWare.ORG");;
} else {
- caseSensitive = pathconf(QDir::currentPath().toLatin1().constData(), _PC_CASE_SENSITIVE);
+ caseSensitive = pathconf(settings5.fileName().toLatin1().constData(), _PC_CASE_SENSITIVE);
}
#elif defined(Q_OS_WIN32) || defined(Q_OS_WINRT)
caseSensitive = false;
@@ -1186,6 +1186,10 @@ static void testMetaTypesHelper(QSettings::Format format)
F(QJsonArray) \
F(QJsonDocument) \
F(QPersistentModelIndex) \
+ F(QCborSimpleType) \
+ F(QCborValue) \
+ F(QCborArray) \
+ F(QCborMap) \
#define EXCLUDE_NON_SUPPORTED_METATYPES(MetaTypeName) \
template<> void testMetaTypesHelper<QMetaType::MetaTypeName>(QSettings::Format) \
diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
index 3de777653e..5cb130f631 100644
--- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
+++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
@@ -183,12 +183,14 @@ void tst_qstandardpaths::testDefaultLocations()
#endif
}
+#ifdef Q_XDG_PLATFORM
static void createTestFile(const QString &fileName)
{
QFile file(fileName);
QVERIFY(file.open(QIODevice::WriteOnly));
QVERIFY(file.write("Hello"));
}
+#endif
void tst_qstandardpaths::testCustomLocations()
{
diff --git a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
index 8b1aa105de..1317489e2f 100644
--- a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
+++ b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp
@@ -80,7 +80,7 @@ static int qInfoPrinter(const char *format, ...)
// flush
QtMessageHandler qt_message_print = qInstallMessageHandler(0);
qInstallMessageHandler(qt_message_print); // restore the handler
- qt_message_print(QtInfoMsg, QMessageLogContext(), QString::fromLocal8Bit(buf));
+ qt_message_print(QtInfoMsg, QMessageLogContext(), QString::fromLocal8Bit(buf).trimmed());
bufuse = 0;
}
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index 09aefcee91..1aa8984b70 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -180,6 +180,8 @@ private slots:
void testThreading();
void matches_data();
void matches();
+ void ipv6_zoneId_data();
+ void ipv6_zoneId();
private:
void testThreadingHelper();
@@ -1876,6 +1878,24 @@ void tst_QUrl::ipv6_data()
QTest::newRow("encoded-digit") << "//[::%31]" << true << "//[::1]";
QTest::newRow("encoded-colon") << "//[%3A%3A]" << true << "//[::]";
+
+ QTest::newRow("full ipv6 with zone id (decoded %)") << QString::fromLatin1("//[56:56:56:56:56:56:56:56%eth0]") << true
+ << "//[56:56:56:56:56:56:56:56%25eth0]";
+
+ QTest::newRow("full ipv6 with zone id (encoded %)") << QString::fromLatin1("//[56:56:56:56:56:56:56:56%25eth0]") << true
+ << "//[56:56:56:56:56:56:56:56%25eth0]";
+
+ QTest::newRow("full ipv6 with invalid zone id") << QString::fromLatin1("//[56:56:56:56:56:56:56:56%]") << false << "";
+
+ QTest::newRow("full ipv6 with invalid zone id (encoded)") << QString::fromLatin1("//[56:56:56:56:56:56:56:56%25]") << false << "";
+
+ QTest::newRow("full ipv6 with zone id 25 (encoded)") << QString::fromLatin1("//[56:56:56:56:56:56:56:56%2525]") << true << "//[56:56:56:56:56:56:56:56%2525]";
+
+ QTest::newRow("case 4 with less and ip4 and port and useinfo and zone id")
+ << QString::fromLatin1("//user:pass@[56::56:56:56:127.0.0.1%ethernet_1]:99") << true
+ << "//user:pass@[56::56:56:56:7f00:1%25ethernet_1]:99";
+
+ QTest::newRow("encoded-digit including zone id") << "//[::%31%25eth0]" << true << "//[::1%25eth0]";
}
void tst_QUrl::ipv6()
@@ -4137,6 +4157,38 @@ void tst_QUrl::matches()
QCOMPARE(urlOne.matches(urlTwo, QUrl::FormattingOptions(options)), matches);
}
+void tst_QUrl::ipv6_zoneId_data()
+{
+ QTest::addColumn<QUrl>("url");
+ QTest::addColumn<QString>("decodedHost");
+ QTest::addColumn<QString>("prettyHost");
+ QTest::addColumn<QString>("encodedHost");
+
+ QTest::newRow("digit") << QUrl("x://[::%251]") << "::%1" << "::%251" << "::%251";
+ QTest::newRow("eth0") << QUrl("x://[::%25eth0]") << "::%eth0" << "::%25eth0" << "::%25eth0";
+ QTest::newRow("space") << QUrl("x://[::%25%20]") << "::% " << "::%25 " << "::%25%20";
+ QTest::newRow("subdelims") << QUrl("x://[::%25eth%2B]") << "::%eth+" << "::%25eth%2B" << "::%25eth%2B";
+ QTest::newRow("other") << QUrl("x://[::%25^]") << "::%^" << "::%25%5E" << "::%25%5E";
+ QTest::newRow("control") << QUrl("x://[::%25%7F]") << "::%\x7f" << "::%25%7F" << "::%25%7F";
+ QTest::newRow("unicode") << QUrl("x://[::%25wlán0]") << "::%wlán0" << "::%25wlán0" << "::%25wl%C3%A1n0";
+ QTest::newRow("non-utf8") << QUrl("x://[::%25%80]") << QString("::%") + QChar(QChar::ReplacementCharacter) << "::%25%80" << "::%25%80";
+ }
+
+void tst_QUrl::ipv6_zoneId()
+{
+ QFETCH(QUrl, url);
+ QFETCH(QString, decodedHost);
+ QFETCH(QString, prettyHost);
+ QFETCH(QString, encodedHost);
+
+ QVERIFY2(url.isValid(), qPrintable(url.errorString()));
+ QCOMPARE(url.host(QUrl::FullyDecoded), decodedHost);
+ QCOMPARE(url.host(), decodedHost);
+ QCOMPARE(url.host(QUrl::FullyEncoded), encodedHost);
+ QCOMPARE(url.toString(), "x://[" + prettyHost + "]");
+ QCOMPARE(url.toString(QUrl::FullyEncoded), "x://[" + encodedHost + "]");
+}
+
QTEST_MAIN(tst_QUrl)
#include "tst_qurl.moc"
diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro
index a09f03a7b4..bcb6e604f8 100644
--- a/tests/auto/corelib/itemmodels/itemmodels.pro
+++ b/tests/auto/corelib/itemmodels/itemmodels.pro
@@ -11,7 +11,8 @@ qtHaveModule(gui): SUBDIRS += \
qtHaveModule(widgets) {
SUBDIRS += \
- qsortfilterproxymodel
+ qsortfilterproxymodel_regexp \
+ qsortfilterproxymodel_regularexpression
qtHaveModule(sql): SUBDIRS += \
qitemmodel
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/.gitignore b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/.gitignore
deleted file mode 100644
index d3672fe4ae..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-tst_qsortfilterproxymodel
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/qsortfilterproxymodel.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/qsortfilterproxymodel.pro
deleted file mode 100644
index dfa8b9fa1b..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/qsortfilterproxymodel.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsortfilterproxymodel
-
-QT += widgets testlib
-mtdir = ../../../other/qabstractitemmodelutils
-
-INCLUDEPATH += $$PWD/$${mtdir}
-SOURCES += tst_qsortfilterproxymodel.cpp $${mtdir}/dynamictreemodel.cpp
-HEADERS += $${mtdir}/dynamictreemodel.h
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
deleted file mode 100644
index bced3f5790..0000000000
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
+++ /dev/null
@@ -1,4853 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include "dynamictreemodel.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtGui/QStandardItem>
-#include <QtWidgets/QTreeView>
-#include <QtWidgets/QTableView>
-
-#include <qdebug.h>
-
-typedef QList<int> IntList;
-typedef QPair<int, int> IntPair;
-typedef QList<IntPair> IntPairList;
-
-Q_DECLARE_METATYPE(QList<QPersistentModelIndex>)
-
-class tst_QSortFilterProxyModel : public QObject
-{
- Q_OBJECT
-public:
- tst_QSortFilterProxyModel();
-
-public slots:
- void initTestCase();
- void cleanupTestCase();
- void cleanup();
-
-private slots:
- void getSetCheck();
- void sort_data();
- void sort();
- void sortHierarchy_data();
- void sortHierarchy();
-
- void insertRows_data();
- void insertRows();
- void prependRow();
- void removeRows_data();
- void removeRows();
- void removeColumns_data();
- void removeColumns();
- void insertAfterSelect();
- void removeAfterSelect();
- void filter_data();
- void filter();
- void filterHierarchy_data();
- void filterHierarchy();
- void filterColumns_data();
- void filterColumns();
-
- void filterTable();
- void filterCurrent();
- void filter_qtbug30662();
-
- void changeSourceLayout();
- void changeSourceLayoutFilteredOut();
- void removeSourceRows_data();
- void removeSourceRows();
- void insertSourceRows_data();
- void insertSourceRows();
- void changeFilter_data();
- void changeFilter();
- void changeSourceData_data();
- void changeSourceData();
- void changeSourceDataKeepsStableSorting_qtbug1548();
- void changeSourceDataForwardsRoles_qtbug35440();
- void resortingDoesNotBreakTreeModels();
- void dynamicFilterWithoutSort();
- void sortFilterRole();
- void selectionFilteredOut();
- void match_data();
- void match();
- void insertIntoChildrenlessItem();
- void invalidateMappedChildren();
- void insertRowIntoFilteredParent();
- void filterOutParentAndFilterInChild();
-
- void sourceInsertRows();
- void sourceModelDeletion();
-
- void sortColumnTracking1();
- void sortColumnTracking2();
-
- void sortStable();
-
- void hiddenColumns();
- void insertRowsSort();
- void staticSorting();
- void dynamicSorting();
- void fetchMore();
- void hiddenChildren();
- void mapFromToSource();
- void removeRowsRecursive();
- void doubleProxySelectionSetSourceModel();
- void appearsAndSort();
- void unnecessaryDynamicSorting();
- void unnecessaryMapCreation();
- void resetInvalidate_data();
- void resetInvalidate();
-
- void testMultipleProxiesWithSelection();
- void mapSelectionFromSource();
- void testResetInternalData();
- void filteredColumns();
- void headerDataChanged();
-
- void testParentLayoutChanged();
- void moveSourceRows();
-
- void hierarchyFilterInvalidation();
- void simpleFilterInvalidation();
-
- void chainedProxyModelRoleNames();
-
- void noMapAfterSourceDelete();
- void forwardDropApi();
- void canDropMimeData();
- void filterHint();
-
- void sourceLayoutChangeLeavesValidPersistentIndexes();
- void rowMoveLeavesValidPersistentIndexes();
-
- void emitLayoutChangedOnlyIfSortingChanged_data();
- void emitLayoutChangedOnlyIfSortingChanged();
-
- void checkSetNewModel();
- void filterAndInsertRow_data();
- void filterAndInsertRow();
- void filterAndInsertColumn_data();
- void filterAndInsertColumn();
-
-protected:
- void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
- void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
-
-private:
- QStandardItemModel *m_model;
- QSortFilterProxyModel *m_proxy;
-};
-
-Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint)
-
-// Testing get/set functions
-void tst_QSortFilterProxyModel::getSetCheck()
-{
- QSortFilterProxyModel obj1;
- QCOMPARE(obj1.sourceModel(), (QAbstractItemModel *)0);
- // int QSortFilterProxyModel::filterKeyColumn()
- // void QSortFilterProxyModel::setFilterKeyColumn(int)
- obj1.setFilterKeyColumn(0);
- QCOMPARE(0, obj1.filterKeyColumn());
- obj1.setFilterKeyColumn(INT_MIN);
- QCOMPARE(INT_MIN, obj1.filterKeyColumn());
- obj1.setFilterKeyColumn(INT_MAX);
- QCOMPARE(INT_MAX, obj1.filterKeyColumn());
-}
-
-tst_QSortFilterProxyModel::tst_QSortFilterProxyModel()
- : m_model(0), m_proxy(0)
-{
- qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
-}
-
-void tst_QSortFilterProxyModel::initTestCase()
-{
- qRegisterMetaType<QList<QPersistentModelIndex> >();
- m_model = new QStandardItemModel(0, 1);
- m_proxy = new QSortFilterProxyModel();
- m_proxy->setSourceModel(m_model);
-}
-
-void tst_QSortFilterProxyModel::cleanupTestCase()
-{
- delete m_proxy;
- delete m_model;
-}
-
-void tst_QSortFilterProxyModel::cleanup()
-{
- m_proxy->setFilterRegExp(QRegExp());
- m_proxy->sort(-1, Qt::AscendingOrder);
- m_model->clear();
- m_model->insertColumns(0, 1);
-}
-
-/*
- tests
-*/
-
-void tst_QSortFilterProxyModel::sort_data()
-{
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<int>("sortCaseSensitivity");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("flat descending") << static_cast<int>(Qt::DescendingOrder)
- << int(Qt::CaseSensitive)
- << (QStringList()
- << "delta"
- << "yankee"
- << "bravo"
- << "lima"
- << "charlie"
- << "juliet"
- << "tango"
- << "hotel"
- << "uniform"
- << "alpha"
- << "echo"
- << "golf"
- << "quebec"
- << "foxtrot"
- << "india"
- << "romeo"
- << "november"
- << "oskar"
- << "zulu"
- << "kilo"
- << "whiskey"
- << "mike"
- << "papa"
- << "sierra"
- << "xray"
- << "viktor")
- << (QStringList()
- << "zulu"
- << "yankee"
- << "xray"
- << "whiskey"
- << "viktor"
- << "uniform"
- << "tango"
- << "sierra"
- << "romeo"
- << "quebec"
- << "papa"
- << "oskar"
- << "november"
- << "mike"
- << "lima"
- << "kilo"
- << "juliet"
- << "india"
- << "hotel"
- << "golf"
- << "foxtrot"
- << "echo"
- << "delta"
- << "charlie"
- << "bravo"
- << "alpha");
- QTest::newRow("flat ascending") << static_cast<int>(Qt::AscendingOrder)
- << int(Qt::CaseSensitive)
- << (QStringList()
- << "delta"
- << "yankee"
- << "bravo"
- << "lima"
- << "charlie"
- << "juliet"
- << "tango"
- << "hotel"
- << "uniform"
- << "alpha"
- << "echo"
- << "golf"
- << "quebec"
- << "foxtrot"
- << "india"
- << "romeo"
- << "november"
- << "oskar"
- << "zulu"
- << "kilo"
- << "whiskey"
- << "mike"
- << "papa"
- << "sierra"
- << "xray"
- << "viktor")
- << (QStringList()
- << "alpha"
- << "bravo"
- << "charlie"
- << "delta"
- << "echo"
- << "foxtrot"
- << "golf"
- << "hotel"
- << "india"
- << "juliet"
- << "kilo"
- << "lima"
- << "mike"
- << "november"
- << "oskar"
- << "papa"
- << "quebec"
- << "romeo"
- << "sierra"
- << "tango"
- << "uniform"
- << "viktor"
- << "whiskey"
- << "xray"
- << "yankee"
- << "zulu");
- QTest::newRow("case insensitive") << static_cast<int>(Qt::AscendingOrder)
- << int(Qt::CaseInsensitive)
- << (QStringList()
- << "alpha" << "BETA" << "Gamma" << "delta")
- << (QStringList()
- << "alpha" << "BETA" << "delta" << "Gamma");
- QTest::newRow("case sensitive") << static_cast<int>(Qt::AscendingOrder)
- << int(Qt::CaseSensitive)
- << (QStringList()
- << "alpha" << "BETA" << "Gamma" << "delta")
- << (QStringList()
- << "BETA" << "Gamma" << "alpha" << "delta");
-
- QStringList list;
- for (int i = 10000; i < 20000; ++i)
- list.append(QStringLiteral("Number: ") + QString::number(i));
- QTest::newRow("large set ascending") << static_cast<int>(Qt::AscendingOrder) << int(Qt::CaseSensitive) << list << list;
-}
-
-void tst_QSortFilterProxyModel::sort()
-{
- QFETCH(int, sortOrder);
- QFETCH(int, sortCaseSensitivity);
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
-
- // prepare model
- QStandardItem *root = m_model->invisibleRootItem ();
- QList<QStandardItem *> items;
- for (int i = 0; i < initial.count(); ++i) {
- items.append(new QStandardItem(initial.at(i)));
- }
- root->insertRows(0, items);
- QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
- QCOMPARE(m_model->columnCount(QModelIndex()), 1);
-
- // make sure the proxy is unsorted
- QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
- QCOMPARE(m_proxy->rowCount(QModelIndex()), initial.count());
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-
- // sort
- m_proxy->sort(0, static_cast<Qt::SortOrder>(sortOrder));
- m_proxy->setSortCaseSensitivity(static_cast<Qt::CaseSensitivity>(sortCaseSensitivity));
-
- // make sure the model is unchanged
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
- // make sure the proxy is sorted
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- // restore the unsorted order
- m_proxy->sort(-1);
-
- // make sure the proxy is unsorted again
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-}
-
-void tst_QSortFilterProxyModel::sortHierarchy_data()
-{
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("flat ascending")
- << static_cast<int>(Qt::AscendingOrder)
- << (QStringList()
- << "c" << "f" << "d" << "e" << "a" << "b")
- << (QStringList()
- << "a" << "b" << "c" << "d" << "e" << "f");
-
- QTest::newRow("simple hierarchy")
- << static_cast<int>(Qt::AscendingOrder)
- << (QStringList() << "a" << "<" << "b" << "<" << "c" << ">" << ">")
- << (QStringList() << "a" << "<" << "b" << "<" << "c" << ">" << ">");
-
- QTest::newRow("hierarchical ascending")
- << static_cast<int>(Qt::AscendingOrder)
- << (QStringList()
- << "c"
- << "<"
- << "h"
- << "<"
- << "2"
- << "0"
- << "1"
- << ">"
- << "g"
- << "i"
- << ">"
- << "b"
- << "<"
- << "l"
- << "k"
- << "<"
- << "8"
- << "7"
- << "9"
- << ">"
- << "m"
- << ">"
- << "a"
- << "<"
- << "z"
- << "y"
- << "x"
- << ">")
- << (QStringList()
- << "a"
- << "<"
- << "x"
- << "y"
- << "z"
- << ">"
- << "b"
- << "<"
- << "k"
- << "<"
- << "7"
- << "8"
- << "9"
- << ">"
- << "l"
- << "m"
- << ">"
- << "c"
- << "<"
- << "g"
- << "h"
- << "<"
- << "0"
- << "1"
- << "2"
- << ">"
- << "i"
- << ">");
-}
-
-void tst_QSortFilterProxyModel::sortHierarchy()
-{
- QFETCH(int, sortOrder);
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
-
- buildHierarchy(initial, m_model);
- checkHierarchy(initial, m_model);
- checkHierarchy(initial, m_proxy);
- m_proxy->sort(0, static_cast<Qt::SortOrder>(sortOrder));
- checkHierarchy(initial, m_model);
- checkHierarchy(expected, m_proxy);
-}
-
-void tst_QSortFilterProxyModel::insertRows_data()
-{
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
- QTest::addColumn<QStringList>("insert");
- QTest::addColumn<int>("position");
-
- QTest::newRow("insert one row in the middle")
- << (QStringList()
- << "One"
- << "Two"
- << "Four"
- << "Five")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList()
- << "Three")
- << 2;
-
- QTest::newRow("insert one row in the beginning")
- << (QStringList()
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList()
- << "One")
- << 0;
-
- QTest::newRow("insert one row in the end")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList()
- <<"Five")
- << 4;
-}
-
-void tst_QSortFilterProxyModel::insertRows()
-{
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
- QFETCH(QStringList, insert);
- QFETCH(int, position);
- // prepare model
- m_model->insertRows(0, initial.count(), QModelIndex());
- //m_model->insertColumns(0, 1, QModelIndex());
- QCOMPARE(m_model->columnCount(QModelIndex()), 1);
- QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- m_model->setData(index, initial.at(row), Qt::DisplayRole);
- }
- // make sure the model correct before insert
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
- // make sure the proxy is correct before insert
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-
- // insert the row
- m_proxy->insertRows(position, insert.count(), QModelIndex());
- QCOMPARE(m_model->rowCount(QModelIndex()), expected.count());
- QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
-
- // set the data for the inserted row
- for (int i = 0; i < insert.count(); ++i) {
- QModelIndex index = m_proxy->index(position + i, 0, QModelIndex());
- m_proxy->setData(index, insert.at(i), Qt::DisplayRole);
- }
-
- // make sure the model correct after insert
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- // make sure the proxy is correct after insert
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-void tst_QSortFilterProxyModel::prependRow()
-{
- //this tests that data is correctly handled by the sort filter when prepending a row
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QStandardItem item("root");
- model.appendRow(&item);
-
- QStandardItem sub("sub");
- item.appendRow(&sub);
-
- sub.appendRow(new QStandardItem("test1"));
- sub.appendRow(new QStandardItem("test2"));
-
- QStandardItem sub2("sub2");
- sub2.appendRow(new QStandardItem("sub3"));
- item.insertRow(0, &sub2);
-
- QModelIndex index_sub2 = proxy.mapFromSource(model.indexFromItem(&sub2));
-
- QCOMPARE(sub2.rowCount(), proxy.rowCount(index_sub2));
- QCOMPARE(proxy.rowCount(QModelIndex()), 1); //only the "root" item is there
-}
-
-void tst_QSortFilterProxyModel::removeRows_data()
-{
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<int>("position");
- QTest::addColumn<int>("count");
- QTest::addColumn<bool>("success");
- QTest::addColumn<QStringList>("expectedProxy");
- QTest::addColumn<QStringList>("expectedSource");
-
- QTest::newRow("remove one row in the middle [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 2 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "One"
- << "Two"
- << "Four"
- << "Five")
- << (QStringList() // expectedSource
- << "One"
- << "Two"
- << "Four"
- << "Five");
-
- QTest::newRow("remove one row in the beginning [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 0 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList() // expectedSource
- << "Two"
- << "Three"
- << "Four"
- << "Five");
-
- QTest::newRow("remove one row in the end [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 4 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "One"
- << "Two"
- << "Three"
- << "Four")
- << (QStringList() // expectedSource
- << "One"
- << "Two"
- << "Three"
- << "Four");
-
- QTest::newRow("remove all [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 0 // position
- << 5 // count
- << true // success
- << QStringList() // expectedProxy
- << QStringList(); // expectedSource
-
- QTest::newRow("remove one row past the end [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 5 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList() // expectedSource
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five");
-
- QTest::newRow("remove row -1 [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << -1 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << (QStringList() // expectedSource
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five");
-
- QTest::newRow("remove three rows in the middle [no sorting/filter]")
- << (QStringList()
- << "One"
- << "Two"
- << "Three"
- << "Four"
- << "Five")
- << -1 // no sorting
- << QString() // no filter
- << 1 // position
- << 3 // count
- << true // success
- << (QStringList() // expectedProxy
- << "One"
- << "Five")
- << (QStringList() // expectedSource
- << "One"
- << "Five");
-
- QTest::newRow("remove one row in the middle [ascending sorting, no filter]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << static_cast<int>(Qt::AscendingOrder)
- << QString() // no filter
- << 2 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "4"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "5"
- << "2"
- << "4");
-
- QTest::newRow("remove two rows in the middle [ascending sorting, no filter]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << static_cast<int>(Qt::AscendingOrder)
- << QString() // no filter
- << 2 // position
- << 2 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "5"
- << "2");
-
- QTest::newRow("remove two rows in the middle [descending sorting, no filter]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << static_cast<int>(Qt::DescendingOrder)
- << QString() // no filter
- << 2 // position
- << 2 // count
- << true // success
- << (QStringList() // expectedProxy
- << "5"
- << "4"
- << "1")
- << (QStringList() // expectedSource
- << "1"
- << "5"
- << "4");
-
- QTest::newRow("remove one row in the middle [no sorting, filter=5|2|3]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << -1 // no sorting
- << QString("5|2|3")
- << 1 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "5"
- << "3")
- << (QStringList() // expectedSource
- << "1"
- << "5"
- << "4"
- << "3");
-
- QTest::newRow("remove all [ascending sorting, no filter]")
- << (QStringList()
- << "1"
- << "5"
- << "2"
- << "4"
- << "3")
- << static_cast<int>(Qt::AscendingOrder)
- << QString() // no filter
- << 0 // position
- << 5 // count
- << true // success
- << QStringList() // expectedProxy
- << QStringList(); // expectedSource
-}
-
-void tst_QSortFilterProxyModel::removeRows()
-{
- QFETCH(QStringList, initial);
- QFETCH(int, sortOrder);
- QFETCH(QString, filter);
- QFETCH(int, position);
- QFETCH(int, count);
- QFETCH(bool, success);
- QFETCH(QStringList, expectedProxy);
- QFETCH(QStringList, expectedSource);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- // prepare model
- foreach (QString s, initial)
- model.appendRow(new QStandardItem(s));
-
- if (sortOrder != -1)
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- if (!filter.isEmpty())
- proxy.setFilterRegExp(QRegExp(filter));
-
- // remove the rows
- QCOMPARE(proxy.removeRows(position, count, QModelIndex()), success);
- QCOMPARE(model.rowCount(QModelIndex()), expectedSource.count());
- QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxy.count());
-
- // make sure the model is correct after remove
- for (int row = 0; row < model.rowCount(QModelIndex()); ++row)
- QCOMPARE(model.item(row)->text(), expectedSource.at(row));
-
- // make sure the proxy is correct after remove
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expectedProxy.at(row));
- }
-}
-
-class MyFilteredColumnProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- MyFilteredColumnProxyModel(QObject *parent = 0)
- : QSortFilterProxyModel(parent) { }
-protected:
- bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const
- {
- QString key = sourceModel()->headerData(sourceColumn, Qt::Horizontal).toString();
- return key.contains(filterRegExp());
- }
-};
-
-void tst_QSortFilterProxyModel::removeColumns_data()
-{
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<int>("position");
- QTest::addColumn<int>("count");
- QTest::addColumn<bool>("success");
- QTest::addColumn<QStringList>("expectedProxy");
- QTest::addColumn<QStringList>("expectedSource");
-
- QTest::newRow("remove one column in the middle [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << 2 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "4"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "4"
- << "5");
-
- QTest::newRow("remove one column in the end [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << 4 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "3"
- << "4")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4");
-
- QTest::newRow("remove one column past the end [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << 5 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4"
- << "5");
-
- QTest::newRow("remove column -1 [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << -1 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4"
- << "5");
-
- QTest::newRow("remove all columns [no filter]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString() // no filter
- << 0 // position
- << 5 // count
- << true // success
- << QStringList() // expectedProxy
- << QStringList(); // expectedSource
-
- QTest::newRow("remove one column in the middle [filter=1|3|5]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString("1|3|5")
- << 1 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "4"
- << "5");
-
- QTest::newRow("remove one column in the end [filter=1|3|5]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString("1|3|5")
- << 2 // position
- << 1 // count
- << true // success
- << (QStringList() // expectedProxy
- << "1"
- << "3")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4");
-
- QTest::newRow("remove one column past the end [filter=1|3|5]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString("1|3|5")
- << 3 // position
- << 1 // count
- << false // success
- << (QStringList() // expectedProxy
- << "1"
- << "3"
- << "5")
- << (QStringList() // expectedSource
- << "1"
- << "2"
- << "3"
- << "4"
- << "5");
-
- QTest::newRow("remove all columns [filter=1|3|5]")
- << (QStringList()
- << "1"
- << "2"
- << "3"
- << "4"
- << "5")
- << QString("1|3|5")
- << 0 // position
- << 3 // count
- << true // success
- << QStringList() // expectedProxy
- << (QStringList() // expectedSource
- << "2"
- << "4");
-}
-
-void tst_QSortFilterProxyModel::removeColumns()
-{
- QFETCH(QStringList, initial);
- QFETCH(QString, filter);
- QFETCH(int, position);
- QFETCH(int, count);
- QFETCH(bool, success);
- QFETCH(QStringList, expectedProxy);
- QFETCH(QStringList, expectedSource);
-
- QStandardItemModel model;
- MyFilteredColumnProxyModel proxy;
- proxy.setSourceModel(&model);
- if (!filter.isEmpty())
- proxy.setFilterRegExp(QRegExp(filter));
-
- // prepare model
- model.setHorizontalHeaderLabels(initial);
-
- // remove the columns
- QCOMPARE(proxy.removeColumns(position, count, QModelIndex()), success);
- QCOMPARE(model.columnCount(QModelIndex()), expectedSource.count());
- QCOMPARE(proxy.columnCount(QModelIndex()), expectedProxy.count());
-
- // make sure the model is correct after remove
- for (int col = 0; col < model.columnCount(QModelIndex()); ++col)
- QCOMPARE(model.horizontalHeaderItem(col)->text(), expectedSource.at(col));
-
- // make sure the proxy is correct after remove
- for (int col = 0; col < proxy.columnCount(QModelIndex()); ++col) {
- QCOMPARE(proxy.headerData(col, Qt::Horizontal, Qt::DisplayRole).toString(),
- expectedProxy.at(col));
- }
-}
-
-void tst_QSortFilterProxyModel::filterColumns_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<bool>("data");
-
- QTest::newRow("all") << "a"
- << (QStringList()
- << "delta"
- << "yankee"
- << "bravo"
- << "lima")
- << true;
-
- QTest::newRow("some") << "lie"
- << (QStringList()
- << "charlie"
- << "juliet"
- << "tango"
- << "hotel")
- << true;
-
- QTest::newRow("nothing") << "zoo"
- << (QStringList()
- << "foxtrot"
- << "uniform"
- << "alpha"
- << "golf")
- << false;
-}
-
-void tst_QSortFilterProxyModel::filterColumns()
-{
- QFETCH(QString, pattern);
- QFETCH(QStringList, initial);
- QFETCH(bool, data);
- // prepare model
- m_model->setColumnCount(initial.count());
- m_model->setRowCount(1);
- QCOMPARE(m_model->columnCount(QModelIndex()), initial.count());
- QCOMPARE(m_model->rowCount(QModelIndex()), 1);
- // set data
- QCOMPARE(m_model->rowCount(QModelIndex()), 1);
- for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
- QModelIndex index = m_model->index(0, col, QModelIndex());
- m_model->setData(index, initial.at(col), Qt::DisplayRole);
- }
- m_proxy->setFilterRegExp(pattern);
- m_proxy->setFilterKeyColumn(-1);
- // make sure the model is unchanged
- for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
- QModelIndex index = m_model->index(0, col, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(col));
- }
- // make sure the proxy is filtered
- QModelIndex index = m_proxy->index(0, 0, QModelIndex());
- QCOMPARE(index.isValid(), data);
-}
-
-void tst_QSortFilterProxyModel::filter_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("flat") << "e"
- << (QStringList()
- << "delta"
- << "yankee"
- << "bravo"
- << "lima"
- << "charlie"
- << "juliet"
- << "tango"
- << "hotel"
- << "uniform"
- << "alpha"
- << "echo"
- << "golf"
- << "quebec"
- << "foxtrot"
- << "india"
- << "romeo"
- << "november"
- << "oskar"
- << "zulu"
- << "kilo"
- << "whiskey"
- << "mike"
- << "papa"
- << "sierra"
- << "xray"
- << "viktor")
- << (QStringList()
- << "delta"
- << "yankee"
- << "charlie"
- << "juliet"
- << "hotel"
- << "echo"
- << "quebec"
- << "romeo"
- << "november"
- << "whiskey"
- << "mike"
- << "sierra");
-}
-
-void tst_QSortFilterProxyModel::filter()
-{
- QFETCH(QString, pattern);
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
- // prepare model
- QVERIFY(m_model->insertRows(0, initial.count(), QModelIndex()));
- QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
- // set data
- QCOMPARE(m_model->columnCount(QModelIndex()), 1);
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- m_model->setData(index, initial.at(row), Qt::DisplayRole);
- }
- m_proxy->setFilterRegExp(pattern);
- // make sure the proxy is unfiltered
- QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
- QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
- // make sure the model is unchanged
- for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_model->index(row, 0, QModelIndex());
- QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
- // make sure the proxy is filtered
- for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
- QModelIndex index = m_proxy->index(row, 0, QModelIndex());
- QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-void tst_QSortFilterProxyModel::filterHierarchy_data()
-{
- QTest::addColumn<QString>("pattern");
- QTest::addColumn<QStringList>("initial");
- QTest::addColumn<QStringList>("expected");
-
- QTest::newRow("flat") << ".*oo"
- << (QStringList()
- << "foo" << "boo" << "baz" << "moo" << "laa" << "haa")
- << (QStringList()
- << "foo" << "boo" << "moo");
-
- QTest::newRow("simple hierarchy") << "b.*z"
- << (QStringList() << "baz" << "<" << "boz" << "<" << "moo" << ">" << ">")
- << (QStringList() << "baz" << "<" << "boz" << ">");
-}
-
-void tst_QSortFilterProxyModel::filterHierarchy()
-{
- QFETCH(QString, pattern);
- QFETCH(QStringList, initial);
- QFETCH(QStringList, expected);
- buildHierarchy(initial, m_model);
- m_proxy->setFilterRegExp(pattern);
- checkHierarchy(initial, m_model);
- checkHierarchy(expected, m_proxy);
-}
-
-void tst_QSortFilterProxyModel::buildHierarchy(const QStringList &l, QAbstractItemModel *m)
-{
- int ind = 0;
- int row = 0;
- QStack<int> row_stack;
- QModelIndex parent;
- QStack<QModelIndex> parent_stack;
- for (int i = 0; i < l.count(); ++i) {
- QString token = l.at(i);
- if (token == QLatin1String("<")) { // start table
- ++ind;
- parent_stack.push(parent);
- row_stack.push(row);
- parent = m->index(row - 1, 0, parent);
- row = 0;
- QVERIFY(m->insertColumns(0, 1, parent)); // add column
- } else if (token == QLatin1String(">")) { // end table
- --ind;
- parent = parent_stack.pop();
- row = row_stack.pop();
- } else { // append row
- QVERIFY(m->insertRows(row, 1, parent));
- QModelIndex index = m->index(row, 0, parent);
- QVERIFY(index.isValid());
- m->setData(index, token, Qt::DisplayRole);
- ++row;
- }
- }
-}
-
-void tst_QSortFilterProxyModel::checkHierarchy(const QStringList &l, const QAbstractItemModel *m)
-{
- int row = 0;
- int indent = 0;
- QStack<int> row_stack;
- QModelIndex parent;
- QStack<QModelIndex> parent_stack;
- for (int i = 0; i < l.count(); ++i) {
- QString token = l.at(i);
- if (token == QLatin1String("<")) { // start table
- ++indent;
- parent_stack.push(parent);
- row_stack.push(row);
- parent = m->index(row - 1, 0, parent);
- QVERIFY(parent.isValid());
- row = 0;
- } else if (token == QLatin1String(">")) { // end table
- --indent;
- parent = parent_stack.pop();
- row = row_stack.pop();
- } else { // compare row
- QModelIndex index = m->index(row, 0, parent);
- QVERIFY(index.isValid());
- QString str = m->data(index, Qt::DisplayRole).toString();
- QCOMPARE(str, token);
- ++row;
- }
- }
-}
-
-class TestModel: public QAbstractTableModel
-{
-public:
- int rowCount(const QModelIndex &) const { return 10000; }
- int columnCount(const QModelIndex &) const { return 1; }
- QVariant data(const QModelIndex &index, int role) const
- {
- if (role != Qt::DisplayRole)
- return QVariant();
- return QString::number(index.row());
- }
-};
-
-void tst_QSortFilterProxyModel::filterTable()
-{
- TestModel model;
- QSortFilterProxyModel filter;
- filter.setSourceModel(&model);
- filter.setFilterRegExp("9");
-
- for (int i = 0; i < filter.rowCount(); ++i)
- QVERIFY(filter.data(filter.index(i, 0)).toString().contains(QLatin1Char('9')));
-}
-
-void tst_QSortFilterProxyModel::insertAfterSelect()
-{
- QStandardItemModel model(10, 2);
- for (int i = 0; i<10;i++)
- model.setData(model.index(i, 0), QVariant(i));
- QSortFilterProxyModel filter;
- filter.setSourceModel(&model);
- QTreeView view;
- view.setModel(&filter);
- view.show();
- QModelIndex firstIndex = filter.mapFromSource(model.index(0, 0, QModelIndex()));
- QCOMPARE(firstIndex.model(), (const QAbstractItemModel *)view.model());
- QVERIFY(firstIndex.isValid());
- int itemOffset = view.visualRect(firstIndex).width() / 2;
- QPoint p(itemOffset, 1);
- QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
- QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
- model.insertRows(5, 1, QModelIndex());
- QVERIFY(view.selectionModel()->selectedIndexes().size() > 0); // Should still have a selection
-}
-
-void tst_QSortFilterProxyModel::removeAfterSelect()
-{
- QStandardItemModel model(10, 2);
- for (int i = 0; i<10;i++)
- model.setData(model.index(i, 0), QVariant(i));
- QSortFilterProxyModel filter;
- filter.setSourceModel(&model);
- QTreeView view;
- view.setModel(&filter);
- view.show();
- QModelIndex firstIndex = filter.mapFromSource(model.index(0, 0, QModelIndex()));
- QCOMPARE(firstIndex.model(), (const QAbstractItemModel *)view.model());
- QVERIFY(firstIndex.isValid());
- int itemOffset = view.visualRect(firstIndex).width() / 2;
- QPoint p(itemOffset, 1);
- QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
- QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
- model.removeRows(5, 1, QModelIndex());
- QVERIFY(view.selectionModel()->selectedIndexes().size() > 0); // Should still have a selection
-}
-
-void tst_QSortFilterProxyModel::filterCurrent()
-{
- QStandardItemModel model(2, 1);
- model.setData(model.index(0, 0), QString("AAA"));
- model.setData(model.index(1, 0), QString("BBB"));
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- QTreeView view;
-
- view.show();
- view.setModel(&proxy);
- QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged);
- QVERIFY(spy.isValid());
-
- view.setCurrentIndex(proxy.index(0, 0));
- QCOMPARE(spy.count(), 1);
- proxy.setFilterRegExp(QRegExp("^B"));
- QCOMPARE(spy.count(), 2);
-}
-
-void tst_QSortFilterProxyModel::filter_qtbug30662()
-{
- QStringListModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- // make sure the filter does not match any entry
- proxy.setFilterRegExp(QRegExp("[0-9]+"));
-
- QStringList slSource;
- slSource << "z" << "x" << "a" << "b";
-
- proxy.setDynamicSortFilter(true);
- proxy.sort(0);
- model.setStringList(slSource);
-
- // without fix for QTBUG-30662 this will make all entries visible - but unsorted
- proxy.setFilterRegExp(QRegExp("[a-z]+"));
-
- QStringList slResult;
- for (int i = 0; i < proxy.rowCount(); ++i)
- slResult.append(proxy.index(i, 0).data().toString());
-
- slSource.sort();
- QCOMPARE(slResult, slSource);
-}
-
-void tst_QSortFilterProxyModel::changeSourceLayout()
-{
- QStandardItemModel model(2, 1);
- model.setData(model.index(0, 0), QString("b"));
- model.setData(model.index(1, 0), QString("a"));
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QList<QPersistentModelIndex> persistentSourceIndexes;
- QList<QPersistentModelIndex> persistentProxyIndexes;
- for (int row = 0; row < model.rowCount(); ++row) {
- persistentSourceIndexes.append(model.index(row, 0));
- persistentProxyIndexes.append(proxy.index(row, 0));
- }
-
- // change layout of source model
- model.sort(0, Qt::AscendingOrder);
-
- for (int row = 0; row < model.rowCount(); ++row) {
- QCOMPARE(persistentProxyIndexes.at(row).row(),
- persistentSourceIndexes.at(row).row());
- }
-}
-
-void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
-{
- QStandardItemModel model(2, 1);
- model.setData(model.index(0, 0), QString("b"));
- model.setData(model.index(1, 0), QString("a"));
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- int beforeSortFilter = proxy.rowCount();
-
- QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- // Filter everything out
- proxy.setFilterRegExp(QRegExp("c"));
- QCOMPARE(removeSpy.count(), 1);
- QCOMPARE(0, proxy.rowCount());
-
- // change layout of source model
- model.sort(0, Qt::AscendingOrder);
-
- QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
- // Remove filter; we expect an insert
- proxy.setFilterRegExp(QRegExp(""));
- QCOMPARE(insertSpy.count(), 1);
- QCOMPARE(beforeSortFilter, proxy.rowCount());
-}
-
-void tst_QSortFilterProxyModel::removeSourceRows_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("start");
- QTest::addColumn<int>("count");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<IntPairList>("expectedRemovedProxyIntervals");
- QTest::addColumn<QStringList>("expectedProxyItems");
-
- QTest::newRow("remove one, no sorting")
- << (QStringList() << "a" << "b") // sourceItems
- << 0 // start
- << 1 // count
- << -1 // sortOrder (no sorting)
- << (IntPairList() << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b") // expectedProxyItems
- ;
- QTest::newRow("remove one, ascending sort (same order)")
- << (QStringList() << "a" << "b") // sourceItems
- << 0 // start
- << 1 // count
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (IntPairList() << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b") // expectedProxyItems
- ;
- QTest::newRow("remove one, ascending sort (reverse order)")
- << (QStringList() << "b" << "a") // sourceItems
- << 0 // start
- << 1 // count
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (IntPairList() << IntPair(1, 1)) // expectedRemovedIntervals
- << (QStringList() << "a") // expectedProxyItems
- ;
- QTest::newRow("remove two, multiple proxy intervals")
- << (QStringList() << "c" << "d" << "a" << "b") // sourceItems
- << 1 // start
- << 2 // count
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (IntPairList() << IntPair(3, 3) << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b" << "c") // expectedProxyItems
- ;
- QTest::newRow("remove three, multiple proxy intervals")
- << (QStringList() << "b" << "d" << "f" << "a" << "c" << "e") // sourceItems
- << 3 // start
- << 3 // count
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (IntPairList() << IntPair(4, 4) << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
- << (QStringList() << "b" << "d" << "f") // expectedProxyItems
- ;
- QTest::newRow("remove all, single proxy intervals")
- << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
- << 0 // start
- << 6 // count
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << (IntPairList() << IntPair(0, 5)) // expectedRemovedIntervals
- << QStringList() // expectedProxyItems
- ;
-}
-
-// Check that correct proxy model rows are removed when rows are removed
-// from the source model
-void tst_QSortFilterProxyModel::removeSourceRows()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, start);
- QFETCH(int, count);
- QFETCH(int, sortOrder);
- QFETCH(IntPairList, expectedRemovedProxyIntervals);
- QFETCH(QStringList, expectedProxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
-
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex sindex = model.index(i, 0, QModelIndex());
- model.setData(sindex, sourceItems.at(i), Qt::DisplayRole);
- QModelIndex pindex = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(pindex, Qt::DisplayRole), model.data(sindex, Qt::DisplayRole));
- }
-
- if (sortOrder != -1)
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
- QSignalSpy aboutToRemoveSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeRemoved);
- QSignalSpy aboutToInsertSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeInserted);
-
- QVERIFY(removeSpy.isValid());
- QVERIFY(insertSpy.isValid());
- QVERIFY(aboutToRemoveSpy.isValid());
- QVERIFY(aboutToInsertSpy.isValid());
-
- model.removeRows(start, count, QModelIndex());
-
- QCOMPARE(aboutToRemoveSpy.count(), expectedRemovedProxyIntervals.count());
- for (int i = 0; i < aboutToRemoveSpy.count(); ++i) {
- QList<QVariant> args = aboutToRemoveSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
- }
- QCOMPARE(removeSpy.count(), expectedRemovedProxyIntervals.count());
- for (int i = 0; i < removeSpy.count(); ++i) {
- QList<QVariant> args = removeSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
- }
-
- QCOMPARE(insertSpy.count(), 0);
- QCOMPARE(aboutToInsertSpy.count(), 0);
-
- QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxyItems.count());
- for (int i = 0; i < expectedProxyItems.count(); ++i) {
- QModelIndex pindex = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(pindex, Qt::DisplayRole).toString(), expectedProxyItems.at(i));
- }
-}
-
-void tst_QSortFilterProxyModel::insertSourceRows_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("start");
- QTest::addColumn<QStringList>("newItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QStringList>("proxyItems");
-
- QTest::newRow("insert (1)")
- << (QStringList() << "c" << "b") // sourceItems
- << 1 // start
- << (QStringList() << "a") // newItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << (QStringList() << "a" << "b" << "c") // proxyItems
- ;
-
- QTest::newRow("insert (2)")
- << (QStringList() << "d" << "b" << "c") // sourceItems
- << 3 // start
- << (QStringList() << "a") // newItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << (QStringList() << "d" << "c" << "b" << "a") // proxyItems
- ;
-}
-
-// Check that rows are inserted at correct position in proxy model when
-// rows are inserted into the source model
-void tst_QSortFilterProxyModel::insertSourceRows()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, start);
- QFETCH(QStringList, newItems);
- QFETCH(int, sortOrder);
- QFETCH(QStringList, proxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
-
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i), Qt::DisplayRole);
- }
-
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- model.insertRows(start, newItems.size(), QModelIndex());
-
- QCOMPARE(proxy.rowCount(QModelIndex()), proxyItems.count());
- for (int i = 0; i < newItems.count(); ++i) {
- QModelIndex index = model.index(start + i, 0, QModelIndex());
- model.setData(index, newItems.at(i), Qt::DisplayRole);
- }
-
- for (int i = 0; i < proxyItems.count(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), proxyItems.at(i));
- }
-}
-
-void tst_QSortFilterProxyModel::changeFilter_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("initialFilter");
- QTest::addColumn<IntPairList>("initialRemoveIntervals");
- QTest::addColumn<QStringList>("initialProxyItems");
- QTest::addColumn<QString>("finalFilter");
- QTest::addColumn<IntPairList>("finalRemoveIntervals");
- QTest::addColumn<IntPairList>("insertIntervals");
- QTest::addColumn<QStringList>("finalProxyItems");
-
- QTest::newRow("filter (1)")
- << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|b|c" // initialFilter
- << (IntPairList() << IntPair(3, 5)) // initialRemoveIntervals
- << (QStringList() << "a" << "b" << "c") // initialProxyItems
- << "b|d|f" // finalFilter
- << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // finalRemoveIntervals
- << (IntPairList() << IntPair(1, 2)) // insertIntervals
- << (QStringList() << "b" << "d" << "f") // finalProxyItems
- ;
-
- QTest::newRow("filter (2)")
- << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|c|e" // initialFilter
- << (IntPairList() << IntPair(5, 5) << IntPair(3, 3) << IntPair(1, 1)) // initialRemoveIntervals
- << (QStringList() << "a" << "c" << "e") // initialProxyItems
- << "" // finalFilter
- << IntPairList() // finalRemoveIntervals
- << (IntPairList() << IntPair(3, 3) << IntPair(2, 2) << IntPair(1, 1)) // insertIntervals
- << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // finalProxyItems
- ;
-
- QTest::newRow("filter (3)")
- << (QStringList() << "a" << "b" << "c") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a" // initialFilter
- << (IntPairList() << IntPair(1, 2)) // initialRemoveIntervals
- << (QStringList() << "a") // initialProxyItems
- << "a" // finalFilter
- << IntPairList() // finalRemoveIntervals
- << IntPairList() // insertIntervals
- << (QStringList() << "a") // finalProxyItems
- ;
-}
-
-// Check that rows are added/removed when filter changes
-void tst_QSortFilterProxyModel::changeFilter()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, sortOrder);
- QFETCH(QString, initialFilter);
- QFETCH(IntPairList, initialRemoveIntervals);
- QFETCH(QStringList, initialProxyItems);
- QFETCH(QString, finalFilter);
- QFETCH(IntPairList, finalRemoveIntervals);
- QFETCH(IntPairList, insertIntervals);
- QFETCH(QStringList, finalProxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
-
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i), Qt::DisplayRole);
- }
-
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- QSignalSpy initialRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy initialInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
-
- QVERIFY(initialRemoveSpy.isValid());
- QVERIFY(initialInsertSpy.isValid());
-
- proxy.setFilterRegExp(initialFilter);
-
- QCOMPARE(initialRemoveSpy.count(), initialRemoveIntervals.count());
- QCOMPARE(initialInsertSpy.count(), 0);
- for (int i = 0; i < initialRemoveSpy.count(); ++i) {
- QList<QVariant> args = initialRemoveSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), initialRemoveIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), initialRemoveIntervals.at(i).second);
- }
-
- QCOMPARE(proxy.rowCount(QModelIndex()), initialProxyItems.count());
- for (int i = 0; i < initialProxyItems.count(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initialProxyItems.at(i));
- }
-
- QSignalSpy finalRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy finalInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
-
- QVERIFY(finalRemoveSpy.isValid());
- QVERIFY(finalInsertSpy.isValid());
-
- proxy.setFilterRegExp(finalFilter);
-
- QCOMPARE(finalRemoveSpy.count(), finalRemoveIntervals.count());
- for (int i = 0; i < finalRemoveSpy.count(); ++i) {
- QList<QVariant> args = finalRemoveSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), finalRemoveIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), finalRemoveIntervals.at(i).second);
- }
-
- QCOMPARE(finalInsertSpy.count(), insertIntervals.count());
- for (int i = 0; i < finalInsertSpy.count(); ++i) {
- QList<QVariant> args = finalInsertSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), insertIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), insertIntervals.at(i).second);
- }
-
- QCOMPARE(proxy.rowCount(QModelIndex()), finalProxyItems.count());
- for (int i = 0; i < finalProxyItems.count(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), finalProxyItems.at(i));
- }
-}
-
-void tst_QSortFilterProxyModel::changeSourceData_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<QStringList>("expectedInitialProxyItems");
- QTest::addColumn<bool>("dynamic");
- QTest::addColumn<int>("row");
- QTest::addColumn<QString>("newValue");
- QTest::addColumn<IntPairList>("removeIntervals");
- QTest::addColumn<IntPairList>("insertIntervals");
- QTest::addColumn<int>("expectedDataChangedRow"); // -1 if no dataChanged signal expected
- QTest::addColumn<bool>("expectedLayoutChanged");
- QTest::addColumn<QStringList>("proxyItems");
-
- QTest::newRow("move_to_end_ascending")
- << (QStringList() << "c" << "b" << "a") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "a" << "b" << "c") // expectedInitialProxyItems
- << true // dynamic
- << 2 // row
- << "z" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << 2 // dataChanged(row 2) is emitted, see comment "Make sure we also emit dataChanged for the rows" in the source code (unclear why, though)
- << true // layoutChanged
- << (QStringList() << "b" << "c" << "z") // proxyItems
- ;
-
- QTest::newRow("move_to_end_descending")
- << (QStringList() << "b" << "c" << "z") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "z" << "c" << "b") // expectedInitialProxyItems
- << true // dynamic
- << 1 // row
- << "a" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << 2 // dataChanged(row 2) is emitted, see comment "Make sure we also emit dataChanged for the rows" in the source code (unclear why, though)
- << true // layoutChanged
- << (QStringList() << "z" << "b" << "a") // proxyItems
- ;
-
- QTest::newRow("no_op_change")
- << (QStringList() << "a" << "b") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "b" << "a") // expectedInitialProxyItems
- << true // dynamic
- << 0 // row
- << "a" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << -1 // no dataChanged signal
- << false // layoutChanged
- << (QStringList() << "b" << "a") // proxyItems
- ;
-
- QTest::newRow("no_effect_on_filtering")
- << (QStringList() << "a" << "b") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "a" << "b") // expectedInitialProxyItems
- << true // dynamic
- << 1 // row
- << "z" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << 1 // expectedDataChangedRow
- << false // layoutChanged
- << (QStringList() << "a" << "z") // proxyItems
- ;
-
- QTest::newRow("filtered_out_value_stays_out")
- << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|c" // filter
- << (QStringList() << "a" << "c") // expectedInitialProxyItems
- << true // dynamic
- << 1 // row
- << "x" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << -1 // no dataChanged signal
- << false // layoutChanged
- << (QStringList() << "a" << "c") // proxyItems
- ;
-
- QTest::newRow("filtered_out_now_matches")
- << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|c|x" // filter
- << (QStringList() << "a" << "c") // expectedInitialProxyItems
- << true // dynamic
- << 1 // row
- << "x" // newValue
- << IntPairList() // removeIntervals
- << (IntPairList() << IntPair(2, 2)) // insertIntervals
- << -1 // no dataChanged signal
- << false // layoutChanged
- << (QStringList() << "a" << "c" << "x") // proxyItems
- ;
-
- QTest::newRow("value_is_now_filtered_out")
- << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|c" // filter
- << (QStringList() << "a" << "c") // expectedInitialProxyItems
- << true // dynamic
- << 2 // row
- << "x" // newValue
- << (IntPairList() << IntPair(1, 1)) // removeIntervals
- << IntPairList() // insertIntervals
- << -1 // no dataChanged signal
- << false // layoutChanged
- << (QStringList() << "a") // proxyItems
- ;
-
- QTest::newRow("non_dynamic_filter_does_not_update_sort")
- << (QStringList() << "c" << "b" << "a") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << (QStringList() << "a" << "b" << "c") // expectedInitialProxyItems
- << false // dynamic
- << 2 // row
- << "x" // newValue
- << IntPairList() // removeIntervals
- << IntPairList() // insertIntervals
- << 0 // expectedDataChangedRow
- << false // layoutChanged
- << (QStringList() << "x" << "b" << "c") // proxyItems
- ;
-}
-
-void tst_QSortFilterProxyModel::changeSourceData()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, sortOrder);
- QFETCH(QString, filter);
- QFETCH(QStringList, expectedInitialProxyItems);
- QFETCH(bool, dynamic);
- QFETCH(int, row);
- QFETCH(QString, newValue);
- QFETCH(IntPairList, removeIntervals);
- QFETCH(IntPairList, insertIntervals);
- QFETCH(int, expectedDataChangedRow);
- QFETCH(bool, expectedLayoutChanged);
- QFETCH(QStringList, proxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
-
- proxy.setDynamicSortFilter(dynamic);
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i), Qt::DisplayRole);
- }
-
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- (void)proxy.rowCount(QModelIndex()); // force mapping
-
- proxy.setFilterRegExp(filter);
-
- QCOMPARE(proxy.rowCount(), expectedInitialProxyItems.count());
- for (int i = 0; i < expectedInitialProxyItems.count(); ++i) {
- const QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expectedInitialProxyItems.at(i));
- }
-
- QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
- QSignalSpy dataChangedSpy(&proxy, &QSortFilterProxyModel::dataChanged);
- QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(removeSpy.isValid());
- QVERIFY(insertSpy.isValid());
- QVERIFY(dataChangedSpy.isValid());
- QVERIFY(layoutChangedSpy.isValid());
-
- {
- QModelIndex index = model.index(row, 0, QModelIndex());
- model.setData(index, newValue, Qt::DisplayRole);
- }
-
- QCOMPARE(removeSpy.count(), removeIntervals.count());
- for (int i = 0; i < removeSpy.count(); ++i) {
- QList<QVariant> args = removeSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), removeIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), removeIntervals.at(i).second);
- }
-
- QCOMPARE(insertSpy.count(), insertIntervals.count());
- for (int i = 0; i < insertSpy.count(); ++i) {
- QList<QVariant> args = insertSpy.at(i);
- QCOMPARE(args.at(1).type(), QVariant::Int);
- QCOMPARE(args.at(2).type(), QVariant::Int);
- QCOMPARE(args.at(1).toInt(), insertIntervals.at(i).first);
- QCOMPARE(args.at(2).toInt(), insertIntervals.at(i).second);
- }
-
- QCOMPARE(proxy.rowCount(QModelIndex()), proxyItems.count());
- for (int i = 0; i < proxyItems.count(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), proxyItems.at(i));
- }
-
- if (expectedDataChangedRow == -1) {
- QCOMPARE(dataChangedSpy.count(), 0);
- } else {
- QCOMPARE(dataChangedSpy.count(), 1);
- const QModelIndex idx = dataChangedSpy.at(0).at(0).value<QModelIndex>();
- QCOMPARE(idx.row(), expectedDataChangedRow);
- QCOMPARE(idx.column(), 0);
- }
-
- QCOMPARE(layoutChangedSpy.count(), expectedLayoutChanged ? 1 : 0);
-}
-
-// Checks that the model is a table, and that each and every row is like this:
-// i-th row: ( rows.at(i), i )
-static void checkSortedTableModel(const QAbstractItemModel *model, const QStringList &rows)
-{
- QCOMPARE(model->rowCount(), rows.length());
- QCOMPARE(model->columnCount(), 2);
-
- for (int row = 0; row < model->rowCount(); ++row) {
- const QString column0 = model->index(row, 0).data().toString();
- const int column1 = model->index(row, 1).data().toString().toInt();
-
- QCOMPARE(column0, rows.at(row));
- QCOMPARE(column1, row);
- }
-}
-
-void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548()
-{
- // Check that emitting dataChanged from the source model
- // for a change of a role which is not the sorting role
- // doesn't alter the sorting. In this case, we sort on the DisplayRole,
- // and play with other roles.
-
- static const QStringList rows
- = QStringList() << "a" << "b" << "b" << "b" << "c" << "c" << "x";
-
- // Build a table of pairs (string, #row) in each row
- QStandardItemModel model(0, 2);
-
- for (int rowNumber = 0; rowNumber < rows.length(); ++rowNumber) {
- QStandardItem *column0 = new QStandardItem(rows.at(rowNumber));
- column0->setCheckable(true);
- column0->setCheckState(Qt::Unchecked);
-
- QStandardItem *column1 = new QStandardItem(QString::number(rowNumber));
-
- const QList<QStandardItem *> row
- = QList<QStandardItem *>() << column0 << column1;
-
- model.appendRow(row);
- }
-
- checkSortedTableModel(&model, rows);
-
- // Build the proxy model
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.setDynamicSortFilter(true);
- proxy.sort(0);
-
- // The proxy is now sorted by the first column, check that the sorting
- // * is correct (the input is already sorted, so it must not have changed)
- // * was stable (by looking at the second column)
- checkSortedTableModel(&model, rows);
-
- // Change the check status of an item. That must not break the stable sorting
- // changes the middle "b"
- model.item(2)->setCheckState(Qt::Checked);
- checkSortedTableModel(&model, rows);
-
- // changes the starting "a"
- model.item(0)->setCheckState(Qt::Checked);
- checkSortedTableModel(&model, rows);
-
- // change the background color of the first "c"
- model.item(4)->setBackground(Qt::red);
- checkSortedTableModel(&model, rows);
-
- // change the background color of the second "c"
- model.item(5)->setBackground(Qt::red);
- checkSortedTableModel(&model, rows);
-}
-
-void tst_QSortFilterProxyModel::changeSourceDataForwardsRoles_qtbug35440()
-{
- QStringList strings;
- for (int i = 0; i < 100; ++i)
- strings << QString::number(i);
-
- QStringListModel model(strings);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.sort(0, Qt::AscendingOrder);
-
- QSignalSpy spy(&proxy, &QAbstractItemModel::dataChanged);
- QVERIFY(spy.isValid());
- QCOMPARE(spy.length(), 0);
-
- QModelIndex index;
-
- // QStringListModel doesn't distinguish between edit and display roles,
- // so changing one always changes the other, too.
- QVector<int> expectedChangedRoles;
- expectedChangedRoles.append(Qt::DisplayRole);
- expectedChangedRoles.append(Qt::EditRole);
-
- index = model.index(0, 0);
- QVERIFY(index.isValid());
- model.setData(index, QStringLiteral("teststring"), Qt::DisplayRole);
- QCOMPARE(spy.length(), 1);
- QCOMPARE(spy.at(0).at(2).value<QVector<int> >(), expectedChangedRoles);
-
- index = model.index(1, 0);
- QVERIFY(index.isValid());
- model.setData(index, QStringLiteral("teststring2"), Qt::EditRole);
- QCOMPARE(spy.length(), 2);
- QCOMPARE(spy.at(1).at(2).value<QVector<int> >(), expectedChangedRoles);
-}
-
-void tst_QSortFilterProxyModel::sortFilterRole()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
-
- QList<QPair<QVariant, QVariant> > sourceItems;
- sourceItems = QList<QPair<QVariant, QVariant> >()
- << QPair<QVariant, QVariant>("b", 3)
- << QPair<QVariant, QVariant>("c", 2)
- << QPair<QVariant, QVariant>("a", 1);
-
- QList<int> orderedItems;
- orderedItems = QList<int>()
- << 2 << 1;
-
- model.insertRows(0, sourceItems.count());
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i).first, Qt::DisplayRole);
- model.setData(index, sourceItems.at(i).second, Qt::UserRole);
- }
-
- proxy.setFilterRegExp("2");
- QCOMPARE(proxy.rowCount(), 0); // Qt::DisplayRole is default role
-
- proxy.setFilterRole(Qt::UserRole);
- QCOMPARE(proxy.rowCount(), 1);
-
- proxy.setFilterRole(Qt::DisplayRole);
- QCOMPARE(proxy.rowCount(), 0);
-
- proxy.setFilterRegExp("1|2|3");
- QCOMPARE(proxy.rowCount(), 0);
-
- proxy.setFilterRole(Qt::UserRole);
- QCOMPARE(proxy.rowCount(), 3);
-
- proxy.sort(0, Qt::AscendingOrder);
- QCOMPARE(proxy.rowCount(), 3);
-
- proxy.setSortRole(Qt::UserRole);
- proxy.setFilterRole(Qt::DisplayRole);
- proxy.setFilterRegExp("a|c");
- QCOMPARE(proxy.rowCount(), orderedItems.count());
- for (int i = 0; i < proxy.rowCount(); ++i) {
- QModelIndex index = proxy.index(i, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole), sourceItems.at(orderedItems.at(i)).first);
- }
-}
-
-void tst_QSortFilterProxyModel::selectionFilteredOut()
-{
- QStandardItemModel model(2, 1);
- model.setData(model.index(0, 0), QString("AAA"));
- model.setData(model.index(1, 0), QString("BBB"));
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- QTreeView view;
-
- view.show();
- view.setModel(&proxy);
- QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged);
- QVERIFY(spy.isValid());
-
- view.setCurrentIndex(proxy.index(0, 0));
- QCOMPARE(spy.count(), 1);
- proxy.setFilterRegExp(QRegExp("^B"));
- QCOMPARE(spy.count(), 2);
-}
-
-void tst_QSortFilterProxyModel::match_data()
-{
- QTest::addColumn<QStringList>("sourceItems");
- QTest::addColumn<int>("sortOrder");
- QTest::addColumn<QString>("filter");
- QTest::addColumn<int>("proxyStartRow");
- QTest::addColumn<QString>("what");
- QTest::addColumn<int>("matchFlags");
- QTest::addColumn<IntList>("expectedProxyItems");
- QTest::newRow("1")
- << (QStringList() << "a") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << 0 // proxyStartRow
- << "a" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << (IntList() << 0); // expectedProxyItems
- QTest::newRow("2")
- << (QStringList() << "a" << "b") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << 0 // proxyStartRow
- << "b" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << (IntList() << 1); // expectedProxyItems
- QTest::newRow("3")
- << (QStringList() << "a" << "b") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "" // filter
- << 0 // proxyStartRow
- << "a" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << (IntList() << 1); // expectedProxyItems
- QTest::newRow("4")
- << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "" // filter
- << 1 // proxyStartRow
- << "a" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << IntList(); // expectedProxyItems
- QTest::newRow("5")
- << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
- << static_cast<int>(Qt::AscendingOrder) // sortOrder
- << "a|b" // filter
- << 0 // proxyStartRow
- << "c" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << IntList(); // expectedProxyItems
- QTest::newRow("6")
- << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
- << static_cast<int>(Qt::DescendingOrder) // sortOrder
- << "a|b" // filter
- << 0 // proxyStartRow
- << "b" // what
- << static_cast<int>(Qt::MatchExactly) // matchFlags
- << (IntList() << 0); // expectedProxyItems
-}
-
-void tst_QSortFilterProxyModel::match()
-{
- QFETCH(QStringList, sourceItems);
- QFETCH(int, sortOrder);
- QFETCH(QString, filter);
- QFETCH(int, proxyStartRow);
- QFETCH(QString, what);
- QFETCH(int, matchFlags);
- QFETCH(IntList, expectedProxyItems);
-
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
-
- proxy.setSourceModel(&model);
- model.insertColumns(0, 1);
- model.insertRows(0, sourceItems.count());
-
- for (int i = 0; i < sourceItems.count(); ++i) {
- QModelIndex index = model.index(i, 0, QModelIndex());
- model.setData(index, sourceItems.at(i), Qt::DisplayRole);
- }
-
- proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
- proxy.setFilterRegExp(filter);
-
- QModelIndex startIndex = proxy.index(proxyStartRow, 0);
- QModelIndexList indexes = proxy.match(startIndex, Qt::DisplayRole, what,
- expectedProxyItems.count(),
- Qt::MatchFlags(matchFlags));
- QCOMPARE(indexes.count(), expectedProxyItems.count());
- for (int i = 0; i < indexes.count(); ++i)
- QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i));
-}
-
-void tst_QSortFilterProxyModel::insertIntoChildrenlessItem()
-{
- QStandardItemModel model;
- QStandardItem *itemA = new QStandardItem("a");
- model.appendRow(itemA);
- QStandardItem *itemB = new QStandardItem("b");
- model.appendRow(itemB);
- QStandardItem *itemC = new QStandardItem("c");
- model.appendRow(itemC);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QSignalSpy colsInsertedSpy(&proxy, &QSortFilterProxyModel::columnsInserted);
- QSignalSpy rowsInsertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
-
- QVERIFY(colsInsertedSpy.isValid());
- QVERIFY(rowsInsertedSpy.isValid());
-
- (void)proxy.rowCount(QModelIndex()); // force mapping of "a", "b", "c"
- QCOMPARE(colsInsertedSpy.count(), 0);
- QCOMPARE(rowsInsertedSpy.count(), 0);
-
- // now add a child to itemB ==> should get insert notification from the proxy
- itemB->appendRow(new QStandardItem("a.0"));
- QCOMPARE(colsInsertedSpy.count(), 1);
- QCOMPARE(rowsInsertedSpy.count(), 1);
-
- QVariantList args = colsInsertedSpy.takeFirst();
- QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), proxy.mapFromSource(itemB->index()));
- QCOMPARE(qvariant_cast<int>(args.at(1)), 0);
- QCOMPARE(qvariant_cast<int>(args.at(2)), 0);
-
- args = rowsInsertedSpy.takeFirst();
- QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), proxy.mapFromSource(itemB->index()));
- QCOMPARE(qvariant_cast<int>(args.at(1)), 0);
- QCOMPARE(qvariant_cast<int>(args.at(2)), 0);
-}
-
-void tst_QSortFilterProxyModel::invalidateMappedChildren()
-{
- QStandardItemModel model;
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QStandardItem *itemA = new QStandardItem("a");
- model.appendRow(itemA);
- QStandardItem *itemB = new QStandardItem("b");
- itemA->appendRow(itemB);
-
- QStandardItem *itemC = new QStandardItem("c");
- itemB->appendRow(itemC);
- itemC->appendRow(new QStandardItem("d"));
-
- // force mappings
- (void)proxy.hasChildren(QModelIndex());
- (void)proxy.hasChildren(proxy.mapFromSource(itemA->index()));
- (void)proxy.hasChildren(proxy.mapFromSource(itemB->index()));
- (void)proxy.hasChildren(proxy.mapFromSource(itemC->index()));
-
- itemB->removeRow(0); // should invalidate mapping of itemC
- itemC = new QStandardItem("c");
- itemA->appendRow(itemC);
- itemC->appendRow(new QStandardItem("d"));
-
- itemA->removeRow(1); // should invalidate mapping of itemC
- itemC = new QStandardItem("c");
- itemB->appendRow(itemC);
- itemC->appendRow(new QStandardItem("d"));
-
- QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemA->index())), 1);
- QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemB->index())), 1);
- QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemC->index())), 1);
-}
-
-class EvenOddFilterModel : public QSortFilterProxyModel
-{
-public:
- virtual bool filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const
- {
- if (srcParent.isValid())
- return (srcParent.row() % 2) ^ !(srcRow % 2);
- return (srcRow % 2);
- }
-};
-
-void tst_QSortFilterProxyModel::insertRowIntoFilteredParent()
-{
- QStandardItemModel model;
- EvenOddFilterModel proxy;
- proxy.setSourceModel(&model);
-
- QSignalSpy spy(&proxy, &EvenOddFilterModel::rowsInserted);
- QVERIFY(spy.isValid());
-
- QStandardItem *itemA = new QStandardItem();
- model.appendRow(itemA); // A will be filtered
- QStandardItem *itemB = new QStandardItem();
- itemA->appendRow(itemB);
-
- QCOMPARE(spy.count(), 0);
-
- itemA->removeRow(0);
-
- QCOMPARE(spy.count(), 0);
-}
-
-void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- proxy.setFilterRegExp("A|B");
- QStandardItem *itemA = new QStandardItem("A");
- model.appendRow(itemA); // not filtered
- QStandardItem *itemB = new QStandardItem("B");
- itemA->appendRow(itemB); // not filtered
- QStandardItem *itemC = new QStandardItem("C");
- itemA->appendRow(itemC); // filtered
-
- QSignalSpy removedSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
- QSignalSpy insertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
-
- QVERIFY(removedSpy.isValid());
- QVERIFY(insertedSpy.isValid());
-
- proxy.setFilterRegExp("C"); // A and B will be filtered out, C filtered in
-
- // we should now have been notified that the subtree represented by itemA has been removed
- QCOMPARE(removedSpy.count(), 1);
- // we should NOT get any inserts; itemC should be filtered because its parent (itemA) is
- QCOMPARE(insertedSpy.count(), 0);
-}
-
-void tst_QSortFilterProxyModel::sourceInsertRows()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxyModel;
- proxyModel.setSourceModel(&model);
-
- model.insertColumns(0, 1, QModelIndex());
- model.insertRows(0, 2, QModelIndex());
-
- {
- QModelIndex parent = model.index(0, 0, QModelIndex());
- model.insertColumns(0, 1, parent);
- model.insertRows(0, 1, parent);
- }
-
- {
- QModelIndex parent = model.index(1, 0, QModelIndex());
- model.insertColumns(0, 1, parent);
- model.insertRows(0, 1, parent);
- }
-
- model.insertRows(0, 1, QModelIndex());
- model.insertRows(0, 1, QModelIndex());
-
- QVERIFY(true); // if you got here without asserting, it's all good
-}
-
-void tst_QSortFilterProxyModel::sourceModelDeletion()
-{
- QSortFilterProxyModel proxyModel;
- {
- QStandardItemModel model;
- proxyModel.setSourceModel(&model);
- QCOMPARE(proxyModel.sourceModel(), static_cast<QAbstractItemModel*>(&model));
- }
- QCOMPARE(proxyModel.sourceModel(), static_cast<QAbstractItemModel*>(0));
-}
-
-void tst_QSortFilterProxyModel::sortColumnTracking1()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxyModel;
- proxyModel.setSourceModel(&model);
-
- model.insertColumns(0, 10);
- model.insertRows(0, 10);
-
- proxyModel.sort(1);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.insertColumn(8);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.removeColumn(8);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.insertColumn(2);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.removeColumn(2);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.insertColumn(1);
- QCOMPARE(proxyModel.sortColumn(), 2);
-
- model.removeColumn(1);
- QCOMPARE(proxyModel.sortColumn(), 1);
-
- model.removeColumn(1);
- QCOMPARE(proxyModel.sortColumn(), -1);
-}
-
-void tst_QSortFilterProxyModel::sortColumnTracking2()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxyModel;
- proxyModel.setDynamicSortFilter(true);
- proxyModel.setSourceModel(&model);
-
- proxyModel.sort(0);
- QCOMPARE(proxyModel.sortColumn(), 0);
-
- QList<QStandardItem *> items; // Stable sorting: Items with invalid data should move to the end
- items << new QStandardItem << new QStandardItem("foo") << new QStandardItem("bar")
- << new QStandardItem("some") << new QStandardItem("others") << new QStandardItem("item")
- << new QStandardItem("aa") << new QStandardItem("zz") << new QStandardItem;
-
- model.insertColumn(0,items);
- QCOMPARE(proxyModel.sortColumn(), 0);
- QCOMPARE(proxyModel.data(proxyModel.index(0,0)).toString(),QString::fromLatin1("aa"));
- const int zzIndex = items.count() - 3; // 2 invalid at end.
- QCOMPARE(proxyModel.data(proxyModel.index(zzIndex,0)).toString(),QString::fromLatin1("zz"));
-}
-
-void tst_QSortFilterProxyModel::sortStable()
-{
- QStandardItemModel* model = new QStandardItemModel(5, 2);
- for (int r = 0; r < 5; r++) {
- const QString prefix = QLatin1String("Row:") + QString::number(r) + QLatin1String(", Column:");
- for (int c = 0; c < 2; c++) {
- QStandardItem* item = new QStandardItem(prefix + QString::number(c));
- for (int i = 0; i < 3; i++) {
- QStandardItem* child = new QStandardItem(QLatin1String("Item ") + QString::number(i));
- item->appendRow( child );
- }
- model->setItem(r, c, item);
- }
- }
- model->setHorizontalHeaderItem( 0, new QStandardItem( "Name" ));
- model->setHorizontalHeaderItem( 1, new QStandardItem( "Value" ));
-
- QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(model);
- filterModel->setSourceModel(model);
-
- QTreeView *view = new QTreeView;
- view->setModel(filterModel);
- QModelIndex firstRoot = filterModel->index(0,0);
- view->expand(firstRoot);
- view->setSortingEnabled(true);
-
- view->model()->sort(1, Qt::DescendingOrder);
- QVariant lastItemData =filterModel->index(2,0, firstRoot).data();
- view->model()->sort(1, Qt::DescendingOrder);
- QCOMPARE(lastItemData, filterModel->index(2,0, firstRoot).data());
-}
-
-void tst_QSortFilterProxyModel::hiddenColumns()
-{
- class MyStandardItemModel : public QStandardItemModel
- {
- public:
- MyStandardItemModel() : QStandardItemModel(0,5) {}
- void reset()
- { beginResetModel(); endResetModel(); }
- friend class tst_QSortFilterProxyModel;
- } model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
-
- QTableView view;
- view.setModel(&proxy);
-
- view.hideColumn(0);
-
- QVERIFY(view.isColumnHidden(0));
- model.blockSignals(true);
- model.setRowCount(1);
- model.blockSignals(false);
- model.reset();
-
- // In the initial bug report that spawned this test, this would be false
- // because resetting model would also reset the hidden columns.
- QVERIFY(view.isColumnHidden(0));
-}
-
-void tst_QSortFilterProxyModel::insertRowsSort()
-{
- QStandardItemModel model(2,2);
- QSortFilterProxyModel proxyModel;
- proxyModel.setSourceModel(&model);
-
- proxyModel.sort(0);
- QCOMPARE(proxyModel.sortColumn(), 0);
-
- model.insertColumns(0, 3, model.index(0,0));
- QCOMPARE(proxyModel.sortColumn(), 0);
-
- model.removeColumns(0, 3, model.index(0,0));
- QCOMPARE(proxyModel.sortColumn(), 0);
-}
-
-void tst_QSortFilterProxyModel::staticSorting()
-{
- QStandardItemModel model(0, 1);
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.setDynamicSortFilter(false);
- QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(QLatin1Char(' '));
-
- // prepare model
- QStandardItem *root = model.invisibleRootItem ();
- QList<QStandardItem *> items;
- for (int i = 0; i < initial.count(); ++i) {
- items.append(new QStandardItem(initial.at(i)));
- }
- root->insertRows(0, items);
- QCOMPARE(model.rowCount(QModelIndex()), initial.count());
- QCOMPARE(model.columnCount(QModelIndex()), 1);
-
- // make sure the proxy is unsorted
- QCOMPARE(proxy.columnCount(QModelIndex()), 1);
- QCOMPARE(proxy.rowCount(QModelIndex()), initial.count());
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-
- // sort
- proxy.sort(0);
-
- QStringList expected = initial;
- expected.sort();
- // make sure the proxy is sorted
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- //update one item.
- items.first()->setData("girafe", Qt::DisplayRole);
-
- // make sure the proxy is updated but not sorted
- expected.replaceInStrings("bateau", "girafe");
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- // sort again
- proxy.sort(0);
- expected.sort();
-
- // make sure the proxy is sorted
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-void tst_QSortFilterProxyModel::dynamicSorting()
-{
- QStringListModel model1;
- const QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(QLatin1Char(' '));
- model1.setStringList(initial);
- QSortFilterProxyModel proxy1;
- proxy1.setDynamicSortFilter(false);
- proxy1.sort(0);
- proxy1.setSourceModel(&model1);
-
- QCOMPARE(proxy1.columnCount(QModelIndex()), 1);
- //the model should not be sorted because sorting has not been set to dynamic yet.
- QCOMPARE(proxy1.rowCount(QModelIndex()), initial.count());
- for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy1.index(row, 0, QModelIndex());
- QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), initial.at(row));
- }
-
- proxy1.setDynamicSortFilter(true);
-
- //now the model should be sorted.
- QStringList expected = initial;
- expected.sort();
- for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy1.index(row, 0, QModelIndex());
- QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- QStringList initial2 = initial;
- initial2.replaceInStrings("bateau", "girafe");
- model1.setStringList(initial2); //this will cause a reset
-
- QStringList expected2 = initial2;
- expected2.sort();
-
- //now the model should still be sorted.
- for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy1.index(row, 0, QModelIndex());
- QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected2.at(row));
- }
-
- QStringListModel model2(initial);
- proxy1.setSourceModel(&model2);
-
- //the model should again be sorted
- for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy1.index(row, 0, QModelIndex());
- QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-
- //set up the sorting before seting the model up
- QSortFilterProxyModel proxy2;
- proxy2.sort(0);
- proxy2.setSourceModel(&model2);
- for (int row = 0; row < proxy2.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy2.index(row, 0, QModelIndex());
- QCOMPARE(proxy2.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-class QtTestModel: public QAbstractItemModel
-{
-public:
- QtTestModel(int _rows, int _cols, QObject *parent = 0)
- : QAbstractItemModel(parent)
- , rows(_rows)
- , cols(_cols)
- , wrongIndex(false)
- {
- }
-
- bool canFetchMore(const QModelIndex &idx) const
- {
- return !fetched.contains(idx);
- }
-
- void fetchMore(const QModelIndex &idx)
- {
- if (fetched.contains(idx))
- return;
- beginInsertRows(idx, 0, rows-1);
- fetched.insert(idx);
- endInsertRows();
- }
-
- bool hasChildren(const QModelIndex & = QModelIndex()) const
- {
- return true;
- }
-
- int rowCount(const QModelIndex& parent = QModelIndex()) const
- {
- return fetched.contains(parent) ? rows : 0;
- }
-
- int columnCount(const QModelIndex& parent = QModelIndex()) const
- {
- Q_UNUSED(parent);
- return cols;
- }
-
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
- {
- if (row < 0 || column < 0 || column >= cols || row >= rows) {
- return QModelIndex();
- }
- QModelIndex i = createIndex(row, column, int(parent.internalId() + 1));
- parentHash[i] = parent;
- return i;
- }
-
- QModelIndex parent(const QModelIndex &index) const
- {
- if (!parentHash.contains(index))
- return QModelIndex();
- return parentHash[index];
- }
-
- QVariant data(const QModelIndex &idx, int role) const
- {
- if (!idx.isValid())
- return QVariant();
-
- if (role == Qt::DisplayRole) {
- if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
- wrongIndex = true;
- qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(),
- idx.internalPointer());
- }
- return QLatin1Char('[') + QString::number(idx.row()) + QLatin1Char(',')
- + QString::number(idx.column()) + QLatin1Char(']');
- }
- return QVariant();
- }
-
- QSet<QModelIndex> fetched;
- int rows, cols;
- mutable bool wrongIndex;
- mutable QMap<QModelIndex,QModelIndex> parentHash;
-};
-
-void tst_QSortFilterProxyModel::fetchMore()
-{
- QtTestModel model(10,10);
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- QVERIFY(proxy.canFetchMore(QModelIndex()));
- QVERIFY(proxy.hasChildren());
- while (proxy.canFetchMore(QModelIndex()))
- proxy.fetchMore(QModelIndex());
- QCOMPARE(proxy.rowCount(), 10);
- QCOMPARE(proxy.columnCount(), 10);
-
- QModelIndex idx = proxy.index(1,1);
- QVERIFY(idx.isValid());
- QVERIFY(proxy.canFetchMore(idx));
- QVERIFY(proxy.hasChildren(idx));
- while (proxy.canFetchMore(idx))
- proxy.fetchMore(idx);
- QCOMPARE(proxy.rowCount(idx), 10);
- QCOMPARE(proxy.columnCount(idx), 10);
-}
-
-void tst_QSortFilterProxyModel::hiddenChildren()
-{
- QStandardItemModel model;
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model);
- proxy.setDynamicSortFilter(true);
-
- QStandardItem *itemA = new QStandardItem("A VISIBLE");
- model.appendRow(itemA);
- QStandardItem *itemB = new QStandardItem("B VISIBLE");
- itemA->appendRow(itemB);
- QStandardItem *itemC = new QStandardItem("C");
- itemA->appendRow(itemC);
- proxy.setFilterRegExp("VISIBLE");
-
- QCOMPARE(proxy.rowCount(QModelIndex()) , 1);
- QPersistentModelIndex indexA = proxy.index(0,0);
- QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("A VISIBLE"));
-
- QCOMPARE(proxy.rowCount(indexA) , 1);
- QPersistentModelIndex indexB = proxy.index(0, 0, indexA);
- QCOMPARE(proxy.data(indexB).toString(), QString::fromLatin1("B VISIBLE"));
-
- itemA->setText("A");
- QCOMPARE(proxy.rowCount(QModelIndex()), 0);
- QVERIFY(!indexA.isValid());
- QVERIFY(!indexB.isValid());
-
- itemB->setText("B");
- itemA->setText("A VISIBLE");
- itemC->setText("C VISIBLE");
-
- QCOMPARE(proxy.rowCount(QModelIndex()), 1);
- indexA = proxy.index(0,0);
- QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("A VISIBLE"));
-
- QCOMPARE(proxy.rowCount(indexA) , 1);
- QModelIndex indexC = proxy.index(0, 0, indexA);
- QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE"));
-
- proxy.setFilterRegExp("C");
- QCOMPARE(proxy.rowCount(QModelIndex()), 0);
- itemC->setText("invisible");
- itemA->setText("AC");
-
- QCOMPARE(proxy.rowCount(QModelIndex()), 1);
- indexA = proxy.index(0,0);
- QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("AC"));
- QCOMPARE(proxy.rowCount(indexA) , 0);
-}
-
-void tst_QSortFilterProxyModel::mapFromToSource()
-{
- QtTestModel source(10,10);
- source.fetchMore(QModelIndex());
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&source);
- QCOMPARE(proxy.mapFromSource(source.index(5, 4)), proxy.index(5, 4));
- QCOMPARE(proxy.mapToSource(proxy.index(3, 2)), source.index(3, 2));
- QCOMPARE(proxy.mapFromSource(QModelIndex()), QModelIndex());
- QCOMPARE(proxy.mapToSource(QModelIndex()), QModelIndex());
-
-#ifdef QT_NO_DEBUG //if Qt is compiled in debug mode, this will assert
- QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapToSource");
- QCOMPARE(proxy.mapToSource(source.index(2, 3)), QModelIndex());
- QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapFromSource");
- QCOMPARE(proxy.mapFromSource(proxy.index(6, 2)), QModelIndex());
-#endif
-}
-
-static QStandardItem *addEntry(QStandardItem* pParent, const QString &description)
-{
- QStandardItem* pItem = new QStandardItem(description);
- pParent->appendRow(pItem);
- return pItem;
-}
-
-void tst_QSortFilterProxyModel::removeRowsRecursive()
-{
- QStandardItemModel pModel;
- QStandardItem *pItem1 = new QStandardItem("root");
- pModel.appendRow(pItem1);
- QList<QStandardItem *> items;
-
- QStandardItem *pItem11 = addEntry(pItem1,"Sub-heading");
- items << pItem11;
- QStandardItem *pItem111 = addEntry(pItem11,"A");
- items << pItem111;
- items << addEntry(pItem111,"A1");
- items << addEntry(pItem111,"A2");
- QStandardItem *pItem112 = addEntry(pItem11,"B");
- items << pItem112;
- items << addEntry(pItem112,"B1");
- items << addEntry(pItem112,"B2");
- QStandardItem *pItem1123 = addEntry(pItem112,"B3");
- items << pItem1123;
- items << addEntry(pItem1123,"B3-");
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&pModel);
-
- QList<QPersistentModelIndex> sourceIndexes;
- QList<QPersistentModelIndex> proxyIndexes;
- foreach (QStandardItem *item, items) {
- QModelIndex idx = item->index();
- sourceIndexes << idx;
- proxyIndexes << proxy.mapFromSource(idx);
- }
-
- foreach (const QPersistentModelIndex &pidx, sourceIndexes)
- QVERIFY(pidx.isValid());
- foreach (const QPersistentModelIndex &pidx, proxyIndexes)
- QVERIFY(pidx.isValid());
-
- QList<QStandardItem*> itemRow = pItem1->takeRow(0);
-
- QCOMPARE(itemRow.count(), 1);
- QCOMPARE(itemRow.first(), pItem11);
-
- foreach (const QPersistentModelIndex &pidx, sourceIndexes)
- QVERIFY(!pidx.isValid());
- foreach (const QPersistentModelIndex &pidx, proxyIndexes)
- QVERIFY(!pidx.isValid());
-
- delete pItem11;
-}
-
-void tst_QSortFilterProxyModel::doubleProxySelectionSetSourceModel()
-{
- QStandardItemModel *model1 = new QStandardItemModel;
- QStandardItem *parentItem = model1->invisibleRootItem();
- for (int i = 0; i < 4; ++i) {
- QStandardItem *item = new QStandardItem(QLatin1String("model1 item ") + QString::number(i));
- parentItem->appendRow(item);
- parentItem = item;
- }
-
- QStandardItemModel *model2 = new QStandardItemModel;
- QStandardItem *parentItem2 = model2->invisibleRootItem();
- for (int i = 0; i < 4; ++i) {
- QStandardItem *item = new QStandardItem(QLatin1String("model2 item ") + QString::number(i));
- parentItem2->appendRow(item);
- parentItem2 = item;
- }
-
- QSortFilterProxyModel *toggleProxy = new QSortFilterProxyModel;
- toggleProxy->setSourceModel(model1);
-
- QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel;
- proxyModel->setSourceModel(toggleProxy);
-
- QModelIndex mi = proxyModel->index(0, 0, proxyModel->index(0, 0, proxyModel->index(0, 0)));
- QItemSelectionModel ism(proxyModel);
- ism.select(mi, QItemSelectionModel::Select);
- QModelIndexList mil = ism.selectedIndexes();
- QCOMPARE(mil.count(), 1);
- QCOMPARE(mil.first(), mi);
-
- toggleProxy->setSourceModel(model2);
- // No crash, it's good news!
- QVERIFY(ism.selection().isEmpty());
-}
-
-void tst_QSortFilterProxyModel::appearsAndSort()
-{
- class PModel : public QSortFilterProxyModel
- {
- public:
- PModel() : mVisible(false) {};
- protected:
- bool filterAcceptsRow(int, const QModelIndex &) const
- {
- return mVisible;
- }
-
- public:
- void updateXX()
- {
- mVisible = true;
- invalidate();
- }
- private:
- bool mVisible;
- } proxyModel;
-
- QStringListModel sourceModel;
- QStringList list;
- list << "b" << "a" << "c";
- sourceModel.setStringList(list);
-
- proxyModel.setSourceModel(&sourceModel);
- proxyModel.setDynamicSortFilter(true);
- proxyModel.sort(0, Qt::AscendingOrder);
-
- QApplication::processEvents();
- QCOMPARE(sourceModel.rowCount(), 3);
- QCOMPARE(proxyModel.rowCount(), 0); //all rows are hidden at first;
-
- QSignalSpy spyAbout1(&proxyModel, &PModel::layoutAboutToBeChanged);
- QSignalSpy spyChanged1(&proxyModel, &PModel::layoutChanged);
-
- QVERIFY(spyAbout1.isValid());
- QVERIFY(spyChanged1.isValid());
-
- //introducing secondProxyModel to test the layoutChange when many items appears at once
- QSortFilterProxyModel secondProxyModel;
- secondProxyModel.setSourceModel(&proxyModel);
- secondProxyModel.setDynamicSortFilter(true);
- secondProxyModel.sort(0, Qt::DescendingOrder);
- QCOMPARE(secondProxyModel.rowCount(), 0); //all rows are hidden at first;
- QSignalSpy spyAbout2(&secondProxyModel, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy spyChanged2(&secondProxyModel, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(spyAbout2.isValid());
- QVERIFY(spyChanged2.isValid());
-
- proxyModel.updateXX();
- QApplication::processEvents();
- //now rows should be visible, and sorted
- QCOMPARE(proxyModel.rowCount(), 3);
- QCOMPARE(proxyModel.data(proxyModel.index(0,0), Qt::DisplayRole).toString(), QString::fromLatin1("a"));
- QCOMPARE(proxyModel.data(proxyModel.index(1,0), Qt::DisplayRole).toString(), QString::fromLatin1("b"));
- QCOMPARE(proxyModel.data(proxyModel.index(2,0), Qt::DisplayRole).toString(), QString::fromLatin1("c"));
-
- //now rows should be visible, and sorted
- QCOMPARE(secondProxyModel.rowCount(), 3);
- QCOMPARE(secondProxyModel.data(secondProxyModel.index(0,0), Qt::DisplayRole).toString(), QString::fromLatin1("c"));
- QCOMPARE(secondProxyModel.data(secondProxyModel.index(1,0), Qt::DisplayRole).toString(), QString::fromLatin1("b"));
- QCOMPARE(secondProxyModel.data(secondProxyModel.index(2,0), Qt::DisplayRole).toString(), QString::fromLatin1("a"));
-
- QCOMPARE(spyAbout1.count(), 1);
- QCOMPARE(spyChanged1.count(), 1);
- QCOMPARE(spyAbout2.count(), 1);
- QCOMPARE(spyChanged2.count(), 1);
-}
-
-void tst_QSortFilterProxyModel::unnecessaryDynamicSorting()
-{
- QStringListModel model;
- const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
- model.setStringList(initial);
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(false);
- proxy.setSourceModel(&model);
- proxy.sort(Qt::AscendingOrder);
-
- //append two rows
- int maxrows = proxy.rowCount(QModelIndex());
- model.insertRows(maxrows, 2);
- model.setData(model.index(maxrows, 0), QString("alpha"));
- model.setData(model.index(maxrows + 1, 0), QString("fondue"));
-
- //append new items to the initial string list and compare with model
- QStringList expected = initial;
- expected << QString("alpha") << QString("fondue");
-
- //if bug 7716 is present, new rows were prepended, when they should have been appended
- for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
- QModelIndex index = proxy.index(row, 0, QModelIndex());
- QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
- }
-}
-
-class SelectionProxyModel : QAbstractProxyModel
-{
- Q_OBJECT
-public:
- SelectionProxyModel()
- : QAbstractProxyModel(), selectionModel(0)
- {
- }
-
- QModelIndex mapFromSource(QModelIndex const&) const
- { return QModelIndex(); }
-
- QModelIndex mapToSource(QModelIndex const&) const
- { return QModelIndex(); }
-
- QModelIndex index(int, int, const QModelIndex&) const
- { return QModelIndex(); }
-
- QModelIndex parent(const QModelIndex&) const
- { return QModelIndex(); }
-
- int rowCount(const QModelIndex&) const
- { return 0; }
-
- int columnCount(const QModelIndex&) const
- { return 0; }
-
- void setSourceModel( QAbstractItemModel *sourceModel )
- {
- beginResetModel();
- disconnect( sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) );
- QAbstractProxyModel::setSourceModel( sourceModel );
- connect( sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) );
- endResetModel();
- }
-
- void setSelectionModel( QItemSelectionModel *_selectionModel )
- {
- selectionModel = _selectionModel;
- }
-
-private slots:
- void sourceModelAboutToBeReset()
- {
- QVERIFY( selectionModel->selectedIndexes().size() == 1 );
- beginResetModel();
- }
-
- void sourceModelReset()
- {
- endResetModel();
- }
-
-private:
- QItemSelectionModel *selectionModel;
-};
-
-void tst_QSortFilterProxyModel::testMultipleProxiesWithSelection()
-{
- QStringListModel model;
- const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
- model.setStringList(initial);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel( &model );
-
- SelectionProxyModel proxy1;
- QSortFilterProxyModel proxy2;
-
- // Note that the order here matters. The order of the sourceAboutToBeReset
- // exposes the bug in QSortFilterProxyModel.
- proxy2.setSourceModel( &proxy );
- proxy1.setSourceModel( &proxy );
-
- QItemSelectionModel selectionModel(&proxy2);
- proxy1.setSelectionModel( &selectionModel );
-
- selectionModel.select( proxy2.index( 0, 0 ), QItemSelectionModel::Select );
-
- // trick the proxy into emitting begin/end reset signals.
- proxy.setSourceModel(0);
-}
-
-static bool isValid(const QItemSelection &selection)
-{
- foreach (const QItemSelectionRange &range, selection)
- if (!range.isValid())
- return false;
- return true;
-}
-
-void tst_QSortFilterProxyModel::mapSelectionFromSource()
-{
- QStringListModel model;
- const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
- model.setStringList(initial);
-
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
- proxy.setFilterRegExp("d.*");
- proxy.setSourceModel(&model);
-
- // Only "delta" remains.
- QCOMPARE(proxy.rowCount(), 1);
-
- QItemSelection selection;
- QModelIndex charlie = model.index(1, 0);
- selection.append(QItemSelectionRange(charlie, charlie));
- QModelIndex delta = model.index(2, 0);
- selection.append(QItemSelectionRange(delta, delta));
- QModelIndex echo = model.index(3, 0);
- selection.append(QItemSelectionRange(echo, echo));
-
- QVERIFY(isValid(selection));
-
- QItemSelection proxiedSelection = proxy.mapSelectionFromSource(selection);
-
- // Only "delta" is in the mapped result.
- QCOMPARE(proxiedSelection.size(), 1);
- QVERIFY(isValid(proxiedSelection));
-}
-
-class Model10287 : public QStandardItemModel
-{
- Q_OBJECT
-
-public:
- Model10287(QObject *parent = 0)
- : QStandardItemModel(0, 1, parent)
- {
- parentItem = new QStandardItem("parent");
- parentItem->setData(false, Qt::UserRole);
- appendRow(parentItem);
-
- childItem = new QStandardItem("child");
- childItem->setData(true, Qt::UserRole);
- parentItem->appendRow(childItem);
-
- childItem2 = new QStandardItem("child2");
- childItem2->setData(true, Qt::UserRole);
- parentItem->appendRow(childItem2);
- }
-
- void removeChild()
- {
- childItem2->setData(false, Qt::UserRole);
- parentItem->removeRow(0);
- }
-
-private:
- QStandardItem *parentItem, *childItem, *childItem2;
-};
-
-class Proxy10287 : public QSortFilterProxyModel
-{
- Q_OBJECT
-
-public:
- Proxy10287(QAbstractItemModel *model, QObject *parent = 0)
- : QSortFilterProxyModel(parent)
- {
- setSourceModel(model);
- setDynamicSortFilter(true);
- }
-
-protected:
- virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
- {
- // Filter based on UserRole in model
- QModelIndex i = sourceModel()->index(source_row, 0, source_parent);
- return i.data(Qt::UserRole).toBool();
- }
-};
-
-void tst_QSortFilterProxyModel::unnecessaryMapCreation()
-{
- Model10287 m;
- Proxy10287 p(&m);
- m.removeChild();
- // No assert failure, it passes.
-}
-
-class FilteredColumnProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- FilteredColumnProxyModel(QObject *parent = 0)
- : QSortFilterProxyModel(parent)
- {
- }
-
-protected:
- bool filterAcceptsColumn(int column, const QModelIndex & /* source_parent */) const
- {
- return column % 2 != 0;
- }
-};
-
-void tst_QSortFilterProxyModel::filteredColumns()
-{
- DynamicTreeModel *model = new DynamicTreeModel(this);
-
- FilteredColumnProxyModel *proxy = new FilteredColumnProxyModel(this);
- proxy->setSourceModel(model);
-
- new QAbstractItemModelTester(proxy, this);
-
- ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this);
- insertCommand->setNumCols(2);
- insertCommand->setStartRow(0);
- insertCommand->setEndRow(0);
- // Parent is QModelIndex()
- insertCommand->doCommand();
-}
-
-class ChangableHeaderData : public QStringListModel
-{
- Q_OBJECT
-public:
- explicit ChangableHeaderData(QObject *parent = 0)
- : QStringListModel(parent)
- {
-
- }
-
- void emitHeaderDataChanged()
- {
- headerDataChanged(Qt::Vertical, 0, rowCount() - 1);
- }
-};
-
-
-void tst_QSortFilterProxyModel::headerDataChanged()
-{
- ChangableHeaderData *model = new ChangableHeaderData(this);
-
- QStringList numbers;
- for (int i = 0; i < 10; ++i)
- numbers.append(QString::number(i));
- model->setStringList(numbers);
-
- QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
- proxy->setSourceModel(model);
-
- new QAbstractItemModelTester(proxy, this);
-
- model->emitHeaderDataChanged();
-}
-
-void tst_QSortFilterProxyModel::resetInvalidate_data()
-{
- QTest::addColumn<int>("test");
- QTest::addColumn<bool>("works");
-
- QTest::newRow("nothing") << 0 << false;
- QTest::newRow("reset") << 1 << true;
- QTest::newRow("invalidate") << 2 << true;
- QTest::newRow("invalidate_filter") << 3 << true;
-}
-
-void tst_QSortFilterProxyModel::resetInvalidate()
-{
- QFETCH(int, test);
- QFETCH(bool, works);
-
- struct Proxy : QSortFilterProxyModel {
- QString pattern;
- virtual bool filterAcceptsRow(int source_row, const QModelIndex&) const
- {
- return sourceModel()->data(sourceModel()->index(source_row, 0)).toString().contains(pattern);
- }
- void notifyChange(int test)
- {
- switch (test) {
- case 0: break;
- case 1:
- beginResetModel();
- endResetModel();
- break;
- case 2: invalidate(); break;
- case 3: invalidateFilter(); break;
- }
- }
- };
-
- QStringListModel sourceModel(QStringList() << "Poisson" << "Vache" << "Brebis"
- << "Elephant" << "Cochon" << "Serpent"
- << "Mouton" << "Ecureuil" << "Mouche");
- Proxy proxy;
- proxy.pattern = QString::fromLatin1("n");
- proxy.setSourceModel(&sourceModel);
-
- QCOMPARE(proxy.rowCount(), 5);
- for (int i = 0; i < proxy.rowCount(); i++) {
- QVERIFY(proxy.data(proxy.index(i,0)).toString().contains('n'));
- }
-
- proxy.pattern = QString::fromLatin1("o");
- proxy.notifyChange(test);
-
- QCOMPARE(proxy.rowCount(), works ? 4 : 5);
- bool ok = true;
- for (int i = 0; i < proxy.rowCount(); i++) {
- if (!proxy.data(proxy.index(i,0)).toString().contains('o'))
- ok = false;
- }
- QCOMPARE(ok, works);
-}
-
-/**
- * A proxy which changes the background color for items ending in 'y' or 'r'
- */
-class CustomDataProxy : public QSortFilterProxyModel
-{
- Q_OBJECT
-
-public:
- CustomDataProxy(QObject *parent = 0)
- : QSortFilterProxyModel(parent)
- {
- setDynamicSortFilter(true);
- }
-
- void setSourceModel(QAbstractItemModel *sourceModel)
- {
- // It would be possible to use only the modelReset signal of the source model to clear
- // the data in *this, however, this requires that the slot is connected
- // before QSortFilterProxyModel::setSourceModel is called, and even then depends
- // on the order of invocation of slots being the same as the order of connection.
- // ie, not reliable.
-// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
- QSortFilterProxyModel::setSourceModel(sourceModel);
- // Making the connect after the setSourceModel call clears the data too late.
-// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
-
- // This could be done in data(), but the point is to need to cache something in the proxy
- // which needs to be cleared on reset.
- for (int i = 0; i < sourceModel->rowCount(); ++i)
- {
- if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('y')))
- {
- m_backgroundColours.insert(i, Qt::blue);
- } else if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('r')))
- {
- m_backgroundColours.insert(i, Qt::red);
- }
- }
- }
-
- QVariant data(const QModelIndex &index, int role) const
- {
- if (role != Qt::BackgroundRole)
- return QSortFilterProxyModel::data(index, role);
- return m_backgroundColours.value(index.row());
- }
-
-private slots:
- void resetInternalData()
- {
- m_backgroundColours.clear();
- }
-
-private:
- QHash<int, QColor> m_backgroundColours;
-};
-
-class ModelObserver : public QObject
-{
- Q_OBJECT
-public:
- ModelObserver(QAbstractItemModel *model, QObject *parent = 0)
- : QObject(parent), m_model(model)
- {
- connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToBeReset()));
- connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
- }
-
-public slots:
- void modelAboutToBeReset()
- {
- int reds = 0, blues = 0;
- for (int i = 0; i < m_model->rowCount(); ++i)
- {
- QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
- if (color == Qt::blue)
- ++blues;
- if (color == Qt::red)
- ++reds;
- }
- QCOMPARE(blues, 11);
- QCOMPARE(reds, 4);
- }
-
- void modelReset()
- {
- int reds = 0, blues = 0;
- for (int i = 0; i < m_model->rowCount(); ++i)
- {
- QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
- if (color == Qt::blue)
- ++blues;
- if (color == Qt::red)
- ++reds;
- }
- QCOMPARE(reds, 0);
- QCOMPARE(blues, 0);
- }
-
-private:
- QAbstractItemModel * const m_model;
-
-};
-
-void tst_QSortFilterProxyModel::testResetInternalData()
-{
-
- QStringListModel model(QStringList() << "Monday"
- << "Tuesday"
- << "Wednesday"
- << "Thursday"
- << "Friday"
- << "January"
- << "February"
- << "March"
- << "April"
- << "May"
- << "Saturday"
- << "June"
- << "Sunday"
- << "July"
- << "August"
- << "September"
- << "October"
- << "November"
- << "December");
-
- CustomDataProxy proxy;
- proxy.setSourceModel(&model);
-
- ModelObserver observer(&proxy);
-
- // Cause the source model to reset.
- model.setStringList(QStringList() << "Spam" << "Eggs");
-
-}
-
-void tst_QSortFilterProxyModel::testParentLayoutChanged()
-{
- QStandardItemModel model;
- QStandardItem *parentItem = model.invisibleRootItem();
- for (int i = 0; i < 4; ++i) {
- {
- QStandardItem *item = new QStandardItem(QLatin1String("item ") + QString::number(i));
- parentItem->appendRow(item);
- }
- {
- QStandardItem *item = new QStandardItem(QLatin1String("item 1") + QString::number(i));
- parentItem->appendRow(item);
- parentItem = item;
- }
- }
- // item 0
- // item 10
- // - item 1
- // - item 11
- // - item 2
- // - item 12
- // ...
-
- QSortFilterProxyModel proxy;
- proxy.sort(0, Qt::AscendingOrder);
- proxy.setDynamicSortFilter(true);
-
- proxy.setSourceModel(&model);
- proxy.setObjectName("proxy");
-
- // When Proxy1 emits layoutChanged(QList<QPersistentModelIndex>) this
- // one will too, with mapped indexes.
- QSortFilterProxyModel proxy2;
- proxy2.sort(0, Qt::AscendingOrder);
- proxy2.setDynamicSortFilter(true);
-
- proxy2.setSourceModel(&proxy);
- proxy2.setObjectName("proxy2");
-
- QSignalSpy dataChangedSpy(&model, &QSortFilterProxyModel::dataChanged);
-
- QVERIFY(dataChangedSpy.isValid());
-
- // Verify that the no-arg signal is still emitted.
- QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(layoutAboutToBeChangedSpy.isValid());
- QVERIFY(layoutChangedSpy.isValid());
-
- QSignalSpy parentsAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy parentsChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(parentsAboutToBeChangedSpy.isValid());
- QVERIFY(parentsChangedSpy.isValid());
-
- QSignalSpy proxy2ParentsAboutToBeChangedSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy proxy2ParentsChangedSpy(&proxy2, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(proxy2ParentsAboutToBeChangedSpy.isValid());
- QVERIFY(proxy2ParentsChangedSpy.isValid());
-
- QStandardItem *item = model.invisibleRootItem()->child(1)->child(1);
- QCOMPARE(item->text(), QStringLiteral("item 11"));
-
- // Ensure mapped:
- proxy.mapFromSource(model.indexFromItem(item));
-
- item->setText("Changed");
-
- QCOMPARE(dataChangedSpy.size(), 1);
- QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
- QCOMPARE(layoutChangedSpy.size(), 1);
- QCOMPARE(parentsAboutToBeChangedSpy.size(), 1);
- QCOMPARE(parentsChangedSpy.size(), 1);
- QCOMPARE(proxy2ParentsAboutToBeChangedSpy.size(), 1);
- QCOMPARE(proxy2ParentsChangedSpy.size(), 1);
-
- QVariantList beforeSignal = parentsAboutToBeChangedSpy.first();
- QVariantList afterSignal = parentsChangedSpy.first();
-
- QCOMPARE(beforeSignal.size(), 2);
- QCOMPARE(afterSignal.size(), 2);
-
- QList<QPersistentModelIndex> beforeParents = beforeSignal.first().value<QList<QPersistentModelIndex> >();
- QList<QPersistentModelIndex> afterParents = afterSignal.first().value<QList<QPersistentModelIndex> >();
-
- QCOMPARE(beforeParents.size(), 1);
- QCOMPARE(afterParents.size(), 1);
-
- QVERIFY(beforeParents.first().isValid());
- QVERIFY(beforeParents.first() == afterParents.first());
-
- QVERIFY(beforeParents.first() == proxy.mapFromSource(model.indexFromItem(model.invisibleRootItem()->child(1))));
-
- QList<QPersistentModelIndex> proxy2BeforeList = proxy2ParentsAboutToBeChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
- QList<QPersistentModelIndex> proxy2AfterList = proxy2ParentsChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
-
- QCOMPARE(proxy2BeforeList.size(), beforeParents.size());
- QCOMPARE(proxy2AfterList.size(), afterParents.size());
- foreach (const QPersistentModelIndex &idx, proxy2BeforeList)
- QVERIFY(beforeParents.contains(proxy2.mapToSource(idx)));
- foreach (const QPersistentModelIndex &idx, proxy2AfterList)
- QVERIFY(afterParents.contains(proxy2.mapToSource(idx)));
-}
-
-class SignalArgumentChecker : public QObject
-{
- Q_OBJECT
-public:
- SignalArgumentChecker(QAbstractItemModel *model, QAbstractProxyModel *proxy, QObject *parent = 0)
- : QObject(parent), m_proxy(proxy)
- {
- connect(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
- connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
- connect(proxy, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>)), SLOT(layoutAboutToBeChanged(QList<QPersistentModelIndex>)));
- connect(proxy, SIGNAL(layoutChanged(QList<QPersistentModelIndex>)), SLOT(layoutChanged(QList<QPersistentModelIndex>)));
- }
-
-private slots:
- void rowsAboutToBeMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int)
- {
- m_p1PersistentBefore = source;
- m_p2PersistentBefore = destination;
- m_p2FirstProxyChild = m_proxy->index(0, 0, m_proxy->mapFromSource(destination));
- }
-
- void rowsMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int)
- {
- m_p1PersistentAfter = source;
- m_p2PersistentAfter = destination;
- }
-
- void layoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents)
- {
- QVERIFY(m_p1PersistentBefore.isValid());
- QVERIFY(m_p2PersistentBefore.isValid());
- QCOMPARE(parents.size(), 2);
- QVERIFY(parents.first() != parents.at(1));
- QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentBefore)));
- QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentBefore)));
- }
-
- void layoutChanged(const QList<QPersistentModelIndex> &parents)
- {
- QVERIFY(m_p1PersistentAfter.isValid());
- QVERIFY(m_p2PersistentAfter.isValid());
- QCOMPARE(parents.size(), 2);
- QVERIFY(parents.first() != parents.at(1));
- QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentAfter)));
- QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentAfter)));
-
- // In the source model, the rows were moved to row 1 in the parent.
- // m_p2FirstProxyChild was created with row 0 in the proxy.
- // The moved rows in the proxy do not appear at row 1 because of sorting.
- // Sorting causes them to appear at row 0 instead, pushing what used to
- // be row 0 in the proxy down by two rows.
- QCOMPARE(m_p2FirstProxyChild.row(), 2);
- }
-
-private:
- QAbstractProxyModel *m_proxy;
- QPersistentModelIndex m_p1PersistentBefore;
- QPersistentModelIndex m_p2PersistentBefore;
- QPersistentModelIndex m_p1PersistentAfter;
- QPersistentModelIndex m_p2PersistentAfter;
-
- QPersistentModelIndex m_p2FirstProxyChild;
-};
-
-void tst_QSortFilterProxyModel::moveSourceRows()
-{
- DynamicTreeModel model;
-
- {
- ModelInsertCommand insertCommand(&model);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(9);
- insertCommand.doCommand();
- }
- {
- ModelInsertCommand insertCommand(&model);
- insertCommand.setAncestorRowNumbers(QList<int>() << 2);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(9);
- insertCommand.doCommand();
- }
- {
- ModelInsertCommand insertCommand(&model);
- insertCommand.setAncestorRowNumbers(QList<int>() << 5);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(9);
- insertCommand.doCommand();
- }
-
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
- proxy.sort(0, Qt::AscendingOrder);
-
- // We need to check the arguments at emission time
- SignalArgumentChecker checker(&model, &proxy);
-
- proxy.setSourceModel(&model);
-
- QSortFilterProxyModel filterProxy;
- filterProxy.setDynamicSortFilter(true);
- filterProxy.sort(0, Qt::AscendingOrder);
- filterProxy.setSourceModel(&proxy);
- filterProxy.setFilterRegExp("6"); // One of the parents
-
- QSortFilterProxyModel filterBothProxy;
- filterBothProxy.setDynamicSortFilter(true);
- filterBothProxy.sort(0, Qt::AscendingOrder);
- filterBothProxy.setSourceModel(&proxy);
- filterBothProxy.setFilterRegExp("5"); // The parents are 6 and 3. This filters both out.
-
- QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved);
- QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved);
- QSignalSpy proxyBeforeMoveSpy(m_proxy, &QSortFilterProxyModel::rowsAboutToBeMoved);
- QSignalSpy proxyAfterMoveSpy(m_proxy, &QSortFilterProxyModel::rowsMoved);
- QSignalSpy proxyBeforeParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy proxyAfterParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
- QSignalSpy filterBeforeParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy filterAfterParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutChanged);
- QSignalSpy filterBothBeforeParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy filterBothAfterParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutChanged);
-
- QVERIFY(modelBeforeSpy.isValid());
- QVERIFY(modelAfterSpy.isValid());
- QVERIFY(proxyBeforeMoveSpy.isValid());
- QVERIFY(proxyAfterMoveSpy.isValid());
- QVERIFY(proxyBeforeParentLayoutSpy.isValid());
- QVERIFY(proxyAfterParentLayoutSpy.isValid());
- QVERIFY(filterBeforeParentLayoutSpy.isValid());
- QVERIFY(filterAfterParentLayoutSpy.isValid());
- QVERIFY(filterBothBeforeParentLayoutSpy.isValid());
- QVERIFY(filterBothAfterParentLayoutSpy.isValid());
-
- {
- ModelMoveCommand moveCommand(&model, 0);
- moveCommand.setAncestorRowNumbers(QList<int>() << 2);
- moveCommand.setDestAncestors(QList<int>() << 5);
- moveCommand.setStartRow(3);
- moveCommand.setEndRow(4);
- moveCommand.setDestRow(1);
- moveCommand.doCommand();
- }
-
- // Proxy notifies layout change
- QCOMPARE(modelBeforeSpy.size(), 1);
- QCOMPARE(proxyBeforeParentLayoutSpy.size(), 1);
- QCOMPARE(modelAfterSpy.size(), 1);
- QCOMPARE(proxyAfterParentLayoutSpy.size(), 1);
-
- // But it doesn't notify a move.
- QCOMPARE(proxyBeforeMoveSpy.size(), 0);
- QCOMPARE(proxyAfterMoveSpy.size(), 0);
-
- QCOMPARE(filterBeforeParentLayoutSpy.size(), 1);
- QCOMPARE(filterAfterParentLayoutSpy.size(), 1);
-
- QList<QPersistentModelIndex> filterBeforeParents = filterBeforeParentLayoutSpy.first().first().value<QList<QPersistentModelIndex> >();
- QList<QPersistentModelIndex> filterAfterParents = filterAfterParentLayoutSpy.first().first().value<QList<QPersistentModelIndex> >();
-
- QCOMPARE(filterBeforeParents.size(), 1);
- QCOMPARE(filterAfterParents.size(), 1);
-
- QCOMPARE(
- filterBeforeParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::NoLayoutChangeHint);
- QCOMPARE(filterAfterParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::NoLayoutChangeHint);
-
- QCOMPARE(filterBothBeforeParentLayoutSpy.size(), 0);
- QCOMPARE(filterBothAfterParentLayoutSpy.size(), 0);
-}
-
-class FilterProxy : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- FilterProxy(QObject *parent = 0)
- : QSortFilterProxyModel(parent),
- mode(false)
- {
-
- }
-
-public slots:
- void setMode(bool on)
- {
- mode = on;
- invalidateFilter();
- }
-
-protected:
- virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
- {
- if (mode) {
- if (!source_parent.isValid()) {
- return true;
- } else {
- return (source_row % 2) != 0;
- }
- } else {
- if (!source_parent.isValid()) {
- return source_row >= 2 && source_row < 10;
- } else {
- return true;
- }
- }
- }
-
-private:
- bool mode;
-};
-
-void tst_QSortFilterProxyModel::hierarchyFilterInvalidation()
-{
- QStandardItemModel model;
- for (int i = 0; i < 10; ++i) {
- const QString rowText = QLatin1String("Row ") + QString::number(i);
- QStandardItem *child = new QStandardItem(rowText);
- for (int j = 0; j < 1; ++j) {
- child->appendRow(new QStandardItem(rowText + QLatin1Char('/') + QString::number(j)));
- }
- model.appendRow(child);
- }
-
- FilterProxy proxy;
- proxy.setSourceModel(&model);
-
- QTreeView view;
- view.setModel(&proxy);
-
- view.setCurrentIndex(proxy.index(2, 0).child(0, 0));
-
- view.show();
- QVERIFY(QTest::qWaitForWindowExposed(&view));
-
- proxy.setMode(true);
-}
-
-class FilterProxy2 : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- FilterProxy2(QObject *parent = 0)
- : QSortFilterProxyModel(parent),
- mode(false)
- {
-
- }
-
-public slots:
- void setMode(bool on)
- {
- mode = on;
- invalidateFilter();
- }
-
-protected:
- virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
- {
- if (source_parent.isValid()) {
- return true;
- } else {
- if (0 == source_row) {
- return true;
- } else {
- return !mode;
- }
- }
- }
-
-private:
- bool mode;
-};
-
-void tst_QSortFilterProxyModel::simpleFilterInvalidation()
-{
- QStandardItemModel model;
- for (int i = 0; i < 2; ++i) {
- QStandardItem *child = new QStandardItem(QLatin1String("Row ") + QString::number(i));
- child->appendRow(new QStandardItem("child"));
- model.appendRow(child);
- }
-
- FilterProxy2 proxy;
- proxy.setSourceModel(&model);
-
- QTreeView view;
- view.setModel(&proxy);
-
- view.show();
- QVERIFY(QTest::qWaitForWindowExposed(&view));
-
- proxy.setMode(true);
- model.insertRow(0, new QStandardItem("extra"));
-}
-
-class CustomRoleNameModel : public QAbstractListModel
-{
- Q_OBJECT
-public:
- CustomRoleNameModel(QObject *parent = 0) : QAbstractListModel(parent) {}
-
- QVariant data(const QModelIndex &index, int role) const
- {
- Q_UNUSED(index);
- Q_UNUSED(role);
- return QVariant();
- }
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const
- {
- Q_UNUSED(parent);
- return 0;
- }
-
- QHash<int, QByteArray> roleNames() const
- {
- QHash<int, QByteArray> rn = QAbstractListModel::roleNames();
- rn[Qt::UserRole + 1] = "custom";
- return rn;
- }
-};
-
-void tst_QSortFilterProxyModel::chainedProxyModelRoleNames()
-{
- QSortFilterProxyModel proxy1;
- QSortFilterProxyModel proxy2;
- CustomRoleNameModel customModel;
-
- proxy2.setSourceModel(&proxy1);
-
- // changing the sourceModel of proxy1 must also update roleNames of proxy2
- proxy1.setSourceModel(&customModel);
- QVERIFY(proxy2.roleNames().value(Qt::UserRole + 1) == "custom");
-}
-
-// A source model with ABABAB rows, where only A rows accept drops.
-// It will then be sorted by a QSFPM.
-class DropOnOddRows : public QAbstractListModel
-{
- Q_OBJECT
-public:
- DropOnOddRows(QObject *parent = 0) : QAbstractListModel(parent) {}
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
- {
- if (role == Qt::DisplayRole)
- return (index.row() % 2 == 0) ? "A" : "B";
- return QVariant();
- }
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override
- {
- Q_UNUSED(parent);
- return 10;
- }
-
- bool canDropMimeData(const QMimeData *, Qt::DropAction,
- int row, int column, const QModelIndex &parent) const override
- {
- Q_UNUSED(row);
- Q_UNUSED(column);
- return parent.row() % 2 == 0;
- }
-};
-
-class SourceAssertion : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- explicit SourceAssertion(QObject *parent = 0)
- : QSortFilterProxyModel(parent)
- {
-
- }
-
- QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
- {
- Q_ASSERT(sourceModel());
- return QSortFilterProxyModel::mapToSource(proxyIndex);
- }
-};
-
-void tst_QSortFilterProxyModel::noMapAfterSourceDelete()
-{
- SourceAssertion proxy;
- QStringListModel *model = new QStringListModel(QStringList() << "Foo" << "Bar");
-
- proxy.setSourceModel(model);
-
- // Create mappings
- QPersistentModelIndex persistent = proxy.index(0, 0);
-
- QVERIFY(persistent.isValid());
-
- delete model;
-
- QVERIFY(!persistent.isValid());
-}
-
-// QTBUG-39549, test whether canDropMimeData(), dropMimeData() are proxied as well
-// by invoking them on a QSortFilterProxyModel proxying a QStandardItemModel that allows drops
-// on row #1, filtering for that row.
-class DropTestModel : public QStandardItemModel {
-public:
- explicit DropTestModel(QObject *parent = 0) : QStandardItemModel(0, 1, parent)
- {
- appendRow(new QStandardItem(QStringLiteral("Row0")));
- appendRow(new QStandardItem(QStringLiteral("Row1")));
- }
-
- bool canDropMimeData(const QMimeData *, Qt::DropAction,
- int row, int /* column */, const QModelIndex & /* parent */) const override
- { return row == 1; }
-
- bool dropMimeData(const QMimeData *, Qt::DropAction,
- int row, int /* column */, const QModelIndex & /* parent */) override
- { return row == 1; }
-};
-
-void tst_QSortFilterProxyModel::forwardDropApi()
-{
- QSortFilterProxyModel model;
- model.setSourceModel(new DropTestModel(&model));
- model.setFilterFixedString(QStringLiteral("Row1"));
- QCOMPARE(model.rowCount(), 1);
- QVERIFY(model.canDropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex()));
- QVERIFY(model.dropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex()));
-}
-
-static QString rowTexts(QAbstractItemModel *model) {
- QString str;
- for (int row = 0 ; row < model->rowCount(); ++row)
- str += model->index(row, 0).data().toString();
- return str;
-}
-
-void tst_QSortFilterProxyModel::canDropMimeData()
-{
- // Given a source model which only supports dropping on even rows
- DropOnOddRows sourceModel;
- QCOMPARE(rowTexts(&sourceModel), QString("ABABABABAB"));
-
- // and a proxy model that sorts the rows
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&sourceModel);
- proxy.sort(0, Qt::AscendingOrder);
- QCOMPARE(rowTexts(&proxy), QString("AAAAABBBBB"));
-
- // the proxy should correctly map canDropMimeData to the source model,
- // i.e. accept drops on the first 5 rows and refuse drops on the next 5.
- for (int row = 0; row < proxy.rowCount(); ++row)
- QCOMPARE(proxy.canDropMimeData(0, Qt::CopyAction, -1, -1, proxy.index(row, 0)), row < 5);
-}
-
-void tst_QSortFilterProxyModel::resortingDoesNotBreakTreeModels()
-{
- QStandardItemModel *treeModel = new QStandardItemModel(this);
- QStandardItem *e1 = new QStandardItem("Loading...");
- e1->appendRow(new QStandardItem("entry10"));
- treeModel->appendRow(e1);
- QStandardItem *e0 = new QStandardItem("Loading...");
- e0->appendRow(new QStandardItem("entry00"));
- e0->appendRow(new QStandardItem("entry01"));
- treeModel->appendRow(e0);
-
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
- proxy.sort(0);
- proxy.setSourceModel(treeModel);
-
- QAbstractItemModelTester modelTester(&proxy);
-
- QCOMPARE(proxy.rowCount(), 2);
- e1->setText("entry1");
- e0->setText("entry0");
-
- QModelIndex pi0 = proxy.index(0, 0);
- QCOMPARE(pi0.data().toString(), QString("entry0"));
- QCOMPARE(proxy.rowCount(pi0), 2);
-
- QModelIndex pi01 = proxy.index(1, 0, pi0);
- QCOMPARE(pi01.data().toString(), QString("entry01"));
-
- QModelIndex pi1 = proxy.index(1, 0);
- QCOMPARE(pi1.data().toString(), QString("entry1"));
- QCOMPARE(proxy.rowCount(pi1), 1);
-}
-
-void tst_QSortFilterProxyModel::filterHint()
-{
- // test that a filtering model does not emit layoutChanged with a hint
- QStringListModel model(QStringList() << "one"
- << "two"
- << "three"
- << "four"
- << "five"
- << "six");
- QSortFilterProxyModel proxy1;
- proxy1.setSourceModel(&model);
- proxy1.setSortRole(Qt::DisplayRole);
- proxy1.setDynamicSortFilter(true);
- proxy1.sort(0);
-
- QSortFilterProxyModel proxy2;
- proxy2.setSourceModel(&proxy1);
- proxy2.setFilterRole(Qt::DisplayRole);
- proxy2.setFilterRegExp("^[^ ]*$");
- proxy2.setDynamicSortFilter(true);
-
- QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy proxy1AfterSpy(&proxy1, &QSortFilterProxyModel::layoutChanged);
- QSignalSpy proxy2BeforeSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged);
- QSignalSpy proxy2AfterSpy(&proxy2, &QSortFilterProxyModel::layoutChanged);
-
- model.setData(model.index(2), QStringLiteral("modified three"), Qt::DisplayRole);
-
- // The first proxy was re-sorted as one item as changed.
- QCOMPARE(proxy1BeforeSpy.size(), 1);
- QCOMPARE(proxy1BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::VerticalSortHint);
- QCOMPARE(proxy1AfterSpy.size(), 1);
- QCOMPARE(proxy1AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::VerticalSortHint);
-
- // But the second proxy must not have the VerticalSortHint since an item was filtered
- QCOMPARE(proxy2BeforeSpy.size(), 1);
- QCOMPARE(proxy2BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::NoLayoutChangeHint);
- QCOMPARE(proxy2AfterSpy.size(), 1);
- QCOMPARE(proxy2AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
- QAbstractItemModel::NoLayoutChangeHint);
-}
-
-/**
-
- Creates a model where each item has one child, to a set depth,
- and the last item has no children. For a model created with
- setDepth(4):
-
- - 1
- - - 2
- - - - 3
- - - - - 4
-*/
-class StepTreeModel : public QAbstractItemModel
-{
- Q_OBJECT
-public:
- StepTreeModel(QObject * parent = 0)
- : QAbstractItemModel(parent), m_depth(0) {}
-
- int columnCount(const QModelIndex& = QModelIndex()) const override { return 1; }
-
- int rowCount(const QModelIndex& parent = QModelIndex()) const override
- {
- quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
- return (parentId < m_depth) ? 1 : 0;
- }
-
- QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override
- {
- if (role != Qt::DisplayRole)
- return QVariant();
-
- return QString::number(index.internalId());
- }
-
- QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override
- {
- // QTBUG-44962: Would we always expect the parent to belong to the model
- qDebug() << parent.model() << this;
- Q_ASSERT(!parent.isValid() || parent.model() == this);
-
- quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
- if (parentId >= m_depth)
- return QModelIndex();
-
- return createIndex(0, 0, parentId + 1);
- }
-
- QModelIndex parent(const QModelIndex& index) const override
- {
- if (index.internalId() == 0)
- return QModelIndex();
-
- return createIndex(0, 0, index.internalId() - 1);
- }
-
- void setDepth(quintptr depth)
- {
- int parentIdWithLayoutChange = (m_depth < depth) ? m_depth : depth;
-
- QList<QPersistentModelIndex> parentsOfLayoutChange;
- parentsOfLayoutChange.push_back(createIndex(0, 0, parentIdWithLayoutChange));
-
- layoutAboutToBeChanged(parentsOfLayoutChange);
-
- auto existing = persistentIndexList();
-
- QList<QModelIndex> updated;
-
- for (auto idx : existing) {
- if (indexDepth(idx) <= depth)
- updated.push_back(idx);
- else
- updated.push_back({});
- }
-
- m_depth = depth;
-
- changePersistentIndexList(existing, updated);
-
- layoutChanged(parentsOfLayoutChange);
- }
-
-private:
- static quintptr indexDepth(QModelIndex const& index)
- {
- return (index.isValid()) ? 1 + indexDepth(index.parent()) : 0;
- }
-
-private:
- quintptr m_depth;
-};
-
-void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes()
-{
- StepTreeModel model;
- Q_SET_OBJECT_NAME(model);
- model.setDepth(4);
-
- QSortFilterProxyModel proxy1;
- proxy1.setSourceModel(&model);
- Q_SET_OBJECT_NAME(proxy1);
-
- proxy1.setFilterRegExp("1|2");
-
- // The current state of things:
- // model proxy
- // - 1 - 1
- // - - 2 - - 2
- // - - - 3
- // - - - - 4
-
- // The setDepth call below removes '4' with a layoutChanged call.
- // Because the proxy filters that out anyway, the proxy doesn't need
- // to emit any signals or update persistent indexes.
-
- QPersistentModelIndex persistentIndex = proxy1.index(0, 0, proxy1.index(0, 0));
-
- model.setDepth(3);
-
- // Calling parent() causes the internalPointer to be used.
- // Before fixing QTBUG-47711, that could be a dangling pointer.
- // The use of qDebug here makes sufficient use of the heap to
- // cause corruption at runtime with normal use on linux (before
- // the fix). valgrind confirms the fix.
- qDebug() << persistentIndex.parent();
- QVERIFY(persistentIndex.parent().isValid());
-}
-
-void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes()
-{
- DynamicTreeModel model;
- Q_SET_OBJECT_NAME(model);
-
- QList<int> ancestors;
- for (auto i = 0; i < 5; ++i)
- {
- Q_UNUSED(i);
- ModelInsertCommand insertCommand(&model);
- insertCommand.setAncestorRowNumbers(ancestors);
- insertCommand.setStartRow(0);
- insertCommand.setEndRow(0);
- insertCommand.doCommand();
- ancestors.push_back(0);
- }
-
- QSortFilterProxyModel proxy1;
- proxy1.setSourceModel(&model);
- Q_SET_OBJECT_NAME(proxy1);
-
- proxy1.setFilterRegExp("1|2");
-
- auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first();
- auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first();
-
- Q_ASSERT(item5.isValid());
- Q_ASSERT(item3.isValid());
-
- QPersistentModelIndex persistentIndex = proxy1.match(proxy1.index(0, 0), Qt::DisplayRole, "2", 1, Qt::MatchRecursive).first();
-
- ModelMoveCommand moveCommand(&model, 0);
- moveCommand.setAncestorRowNumbers(QList<int>{0, 0, 0, 0});
- moveCommand.setStartRow(0);
- moveCommand.setEndRow(0);
- moveCommand.setDestRow(0);
- moveCommand.setDestAncestors(QList<int>{0, 0, 0});
- moveCommand.doCommand();
-
- // Calling parent() causes the internalPointer to be used.
- // Before fixing QTBUG-47711 (moveRows case), that could be
- // a dangling pointer.
- QVERIFY(persistentIndex.parent().isValid());
-}
-
-void tst_QSortFilterProxyModel::emitLayoutChangedOnlyIfSortingChanged_data()
-{
- QTest::addColumn<int>("changedRow");
- QTest::addColumn<Qt::ItemDataRole>("changedRole");
- QTest::addColumn<QString>("newData");
- QTest::addColumn<QString>("expectedSourceRowTexts");
- QTest::addColumn<QString>("expectedProxyRowTexts");
- QTest::addColumn<int>("expectedLayoutChanged");
-
- // Starting point:
- // a source model with 8,7,6,5,4,3,2,1
- // a proxy model keeping only even rows and sorting them, therefore showing 2,4,6,8
-
- // When setData changes ordering, layoutChanged should be emitted
- QTest::newRow("ordering_change") << 0 << Qt::DisplayRole << "0" << "07654321" << "0246" << 1;
-
- // When setData on visible row doesn't change ordering, layoutChanged should not be emitted
- QTest::newRow("no_ordering_change") << 6 << Qt::DisplayRole << "0" << "87654301" << "0468" << 0;
-
- // When setData happens on a filtered out row, layoutChanged should not be emitted
- QTest::newRow("filtered_out") << 1 << Qt::DisplayRole << "9" << "89654321" << "2468" << 0;
-
- // When setData makes a row visible, layoutChanged should not be emitted (rowsInserted is emitted instead)
- QTest::newRow("make_row_visible") << 7 << Qt::DisplayRole << "0" << "87654320" << "02468" << 0;
-
- // When setData makes a row hidden, layoutChanged should not be emitted (rowsRemoved is emitted instead)
- QTest::newRow("make_row_hidden") << 4 << Qt::DisplayRole << "1" << "87651321" << "268" << 0;
-
- // When setData happens on an unrelated role, layoutChanged should not be emitted
- QTest::newRow("unrelated_role") << 0 << Qt::DecorationRole << "" << "87654321" << "2468" << 0;
-
- // When many changes happen together... and trigger removal, insertion, and layoutChanged
- QTest::newRow("many_changes") << -1 << Qt::DisplayRole << "3,4,2,5,6,0,7,9" << "34256079" << "0246" << 1;
-
- // When many changes happen together... and trigger removal, insertion, but no change in ordering of visible rows => no layoutChanged
- QTest::newRow("many_changes_no_layoutChanged") << -1 << Qt::DisplayRole << "7,5,4,3,2,1,0,8" << "75432108" << "0248" << 0;
-}
-
-void tst_QSortFilterProxyModel::emitLayoutChangedOnlyIfSortingChanged()
-{
- QFETCH(int, changedRow);
- QFETCH(QString, newData);
- QFETCH(Qt::ItemDataRole, changedRole);
- QFETCH(QString, expectedSourceRowTexts);
- QFETCH(QString, expectedProxyRowTexts);
- QFETCH(int, expectedLayoutChanged);
-
- // Custom version of QStringListModel which supports emitting dataChanged for many rows at once
- class CustomStringListModel : public QAbstractListModel
- {
- public:
- bool setData(const QModelIndex &index, const QVariant &value, int role) override
- {
- if (index.row() >= 0 && index.row() < lst.size()
- && (role == Qt::EditRole || role == Qt::DisplayRole)) {
- lst.replace(index.row(), value.toString());
- emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
- return true;
- }
- return false;
- }
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
- {
- if (role == Qt::DisplayRole || role == Qt::EditRole)
- return lst.at(index.row());
- return QVariant();
- }
- int rowCount(const QModelIndex & = QModelIndex()) const override
- {
- return lst.count();
- }
-
- void replaceData(const QStringList &newData)
- {
- lst = newData;
- emit dataChanged(index(0, 0), index(rowCount()-1, 0), {Qt::DisplayRole, Qt::EditRole});
- }
-
- void emitDecorationChangedSignal()
- {
- const QModelIndex idx = index(0, 0);
- emit dataChanged(idx, idx, {Qt::DecorationRole});
- }
- private:
- QStringList lst;
- };
- CustomStringListModel model;
- QStringList strings;
- for (auto i = 8; i >= 1; --i)
- strings.append(QString::number(i));
- model.replaceData(strings);
- QCOMPARE(rowTexts(&model), QStringLiteral("87654321"));
-
- class FilterEvenRowsProxyModel : public QSortFilterProxyModel
- {
- public:
- bool filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const override
- {
- return sourceModel()->index(srcRow, 0, srcParent).data().toInt() % 2 == 0;
- }
- };
-
- FilterEvenRowsProxyModel proxy;
- proxy.sort(0);
- proxy.setSourceModel(&model);
- QCOMPARE(rowTexts(&proxy), QStringLiteral("2468"));
-
- QSignalSpy modelDataChangedSpy(&model, &QAbstractItemModel::dataChanged);
- QSignalSpy proxyLayoutChangedSpy(&proxy, &QAbstractItemModel::layoutChanged);
-
- if (changedRole == Qt::DecorationRole)
- model.emitDecorationChangedSignal();
- else if (changedRow == -1)
- model.replaceData(newData.split(QLatin1Char(',')));
- else
- model.setData(model.index(changedRow, 0), newData, changedRole);
-
- QCOMPARE(rowTexts(&model), expectedSourceRowTexts);
- QCOMPARE(rowTexts(&proxy), expectedProxyRowTexts);
- QCOMPARE(modelDataChangedSpy.size(), 1);
- QCOMPARE(proxyLayoutChangedSpy.size(), expectedLayoutChanged);
-}
-
-void tst_QSortFilterProxyModel::dynamicFilterWithoutSort()
-{
- QStringListModel model;
- const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
- model.setStringList(initial);
- QSortFilterProxyModel proxy;
- proxy.setDynamicSortFilter(true);
- proxy.setSourceModel(&model);
-
- QSignalSpy layoutChangeSpy(&proxy, &QAbstractItemModel::layoutChanged);
- QSignalSpy resetSpy(&proxy, &QAbstractItemModel::modelReset);
-
- QVERIFY(layoutChangeSpy.isValid());
- QVERIFY(resetSpy.isValid());
-
- model.setStringList(QStringList() << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday");
-
- QVERIFY(layoutChangeSpy.isEmpty());
-
- QCOMPARE(model.stringList(), QStringList() << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday");
-
- QCOMPARE(resetSpy.count(), 1);
-}
-
-void tst_QSortFilterProxyModel::checkSetNewModel()
-{
- QTreeView tv;
- StepTreeModel model1;
- model1.setDepth(4);
-
- QSortFilterProxyModel proxy;
- proxy.setSourceModel(&model1);
- tv.setModel(&proxy);
- tv.show();
- QVERIFY(QTest::qWaitForWindowExposed(&tv));
- tv.expandAll();
- {
- StepTreeModel model2;
- model2.setDepth(4);
- proxy.setSourceModel(&model2);
- tv.expandAll();
- proxy.setSourceModel(&model1);
- tv.expandAll();
- // the destruction of model2 here caused a proxy model reset due to
- // missing disconnect in setSourceModel()
- }
- // handle repaint events, will assert when qsortfilterproxymodel is in wrong state
- QCoreApplication::processEvents();
-}
-
-enum ColumnFilterMode {
- FilterNothing,
- FilterOutMiddle,
- FilterOutBeginEnd,
- FilterAll
-};
-Q_DECLARE_METATYPE(ColumnFilterMode)
-
-void tst_QSortFilterProxyModel::filterAndInsertColumn_data()
-{
-
- QTest::addColumn<int>("insertCol");
- QTest::addColumn<ColumnFilterMode>("filterMode");
- QTest::addColumn<QStringList>("expectedModelList");
- QTest::addColumn<QStringList>("expectedProxyModelList");
-
- QTest::newRow("at_beginning_filter_out_middle")
- << 0
- << FilterOutMiddle
- << QStringList{{"", "A1", "B1", "C1", "D1"}}
- << QStringList{{"", "D1"}}
- ;
- QTest::newRow("at_end_filter_out_middle")
- << 2
- << FilterOutMiddle
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- << QStringList{{"A1", ""}}
- ;
- QTest::newRow("in_the_middle_filter_out_middle")
- << 1
- << FilterOutMiddle
- << QStringList{{"A1", "B1", "C1", "", "D1"}}
- << QStringList{{"A1", "D1"}}
- ;
- QTest::newRow("at_beginning_filter_out_begin_and_end")
- << 0
- << FilterOutBeginEnd
- << QStringList{{"A1", "", "B1", "C1", "D1"}}
- << QStringList{{"", "B1", "C1"}}
- ;
- QTest::newRow("at_end_filter_out_begin_and_end")
- << 2
- << FilterOutBeginEnd
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- << QStringList{{"B1", "C1", "D1"}}
- ;
- QTest::newRow("in_the_middle_filter_out_begin_and_end")
- << 1
- << FilterOutBeginEnd
- << QStringList{{"A1", "B1", "", "C1", "D1"}}
- << QStringList{{"B1", "", "C1"}}
- ;
-
- QTest::newRow("at_beginning_filter_nothing")
- << 0
- << FilterAll
- << QStringList{{"", "A1", "B1", "C1", "D1"}}
- << QStringList{{"", "A1", "B1", "C1", "D1"}}
- ;
- QTest::newRow("at_end_filter_nothing")
- << 4
- << FilterAll
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- ;
- QTest::newRow("in_the_middle_nothing")
- << 2
- << FilterAll
- << QStringList{{"A1", "B1", "", "C1", "D1"}}
- << QStringList{{"A1", "B1", "", "C1", "D1"}}
- ;
-
- QTest::newRow("filter_all")
- << 0
- << FilterNothing
- << QStringList{{"A1", "B1", "C1", "D1", ""}}
- << QStringList{}
- ;
-}
-void tst_QSortFilterProxyModel::filterAndInsertColumn()
-{
-
- class ColumnFilterProxy : public QSortFilterProxyModel {
- Q_DISABLE_COPY(ColumnFilterProxy)
- ColumnFilterMode filerMode;
- public:
- ColumnFilterProxy(ColumnFilterMode mode)
- : filerMode(mode)
- {}
- bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override
- {
- Q_UNUSED(source_parent)
- switch (filerMode){
- case FilterAll:
- return true;
- case FilterNothing:
- return false;
- case FilterOutMiddle:
- return source_column == 0 || source_column == sourceModel()->columnCount() - 1;
- case FilterOutBeginEnd:
- return source_column > 0 && source_column< sourceModel()->columnCount() - 1;
- }
- Q_UNREACHABLE();
- }
- };
- QFETCH(int, insertCol);
- QFETCH(ColumnFilterMode, filterMode);
- QFETCH(QStringList, expectedModelList);
- QFETCH(QStringList, expectedProxyModelList);
- QStandardItemModel model;
- model.insertColumns(0, 4);
- model.insertRows(0, 1);
- for (int i = 0; i < model.rowCount(); ++i) {
- for (int j = 0; j < model.columnCount(); ++j)
- model.setData(model.index(i, j), QString('A' + j) + QString::number(i + 1));
- }
- ColumnFilterProxy proxy(filterMode);
- proxy.setSourceModel(&model);
- QVERIFY(proxy.insertColumn(insertCol));
- proxy.invalidate();
- QStringList modelStringList;
- for (int i = 0; i < model.rowCount(); ++i) {
- for (int j = 0; j < model.columnCount(); ++j)
- modelStringList.append(model.index(i, j).data().toString());
- }
- QCOMPARE(expectedModelList, modelStringList);
- modelStringList.clear();
- for (int i = 0; i < proxy.rowCount(); ++i) {
- for (int j = 0; j < proxy.columnCount(); ++j)
- modelStringList.append(proxy.index(i, j).data().toString());
- }
- QCOMPARE(expectedProxyModelList, modelStringList);
-}
-
-void tst_QSortFilterProxyModel::filterAndInsertRow_data()
-{
- QTest::addColumn<QStringList>("initialModelList");
- QTest::addColumn<int>("row");
- QTest::addColumn<QString>("filterRegExp");
- QTest::addColumn<QStringList>("expectedModelList");
- QTest::addColumn<QStringList>("expectedProxyModelList");
-
- QTest::newRow("at_beginning_filter_out_middle")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 0
- << "^A"
- << QStringList{{"", "A5", "B5", "B6", "A7"}}
- << QStringList{{"A5", "A7"}};
- QTest::newRow("at_end_filter_out_middle")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 2
- << "^A"
- << QStringList{{"A5", "B5", "B6", "A7", ""}}
- << QStringList{{"A5", "A7"}};
- QTest::newRow("in_the_middle_filter_out_middle")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 1
- << "^A"
- << QStringList{{"A5", "B5", "B6", "", "A7"}}
- << QStringList{{"A5", "A7"}};
-
- QTest::newRow("at_beginning_filter_out_first_and_last")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 0
- << "^B"
- << QStringList{{"A5", "", "B5", "B6", "A7"}}
- << QStringList{{"B5", "B6"}};
- QTest::newRow("at_end_filter_out_first_and_last")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 2
- << "^B"
- << QStringList{{"A5", "B5", "B6", "A7", ""}}
- << QStringList{{"B5", "B6"}};
- QTest::newRow("in_the_middle_filter_out_first_and_last")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 1
- << "^B"
- << QStringList{{"A5", "B5", "", "B6", "A7"}}
- << QStringList{{"B5", "B6"}};
-
- QTest::newRow("at_beginning_no_filter")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 0
- << ".*"
- << QStringList{{"", "A5", "B5", "B6", "A7"}}
- << QStringList{{"", "A5", "B5", "B6", "A7"}};
- QTest::newRow("at_end_no_filter")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 4
- << ".*"
- << QStringList{{"A5", "B5", "B6", "A7", ""}}
- << QStringList{{"A5", "B5", "B6", "A7", ""}};
- QTest::newRow("in_the_middle_no_filter")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 2
- << ".*"
- << QStringList{{"A5", "B5", "", "B6", "A7"}}
- << QStringList{{"A5", "B5", "", "B6", "A7"}};
-
- QTest::newRow("filter_all")
- << QStringList{{"A5", "B5", "B6", "A7"}}
- << 0
- << "$a"
- << QStringList{{"A5", "B5", "B6", "A7", ""}}
- << QStringList{};
-}
-
-void tst_QSortFilterProxyModel::filterAndInsertRow()
-{
- QFETCH(QStringList, initialModelList);
- QFETCH(int, row);
- QFETCH(QString, filterRegExp);
- QFETCH(QStringList, expectedModelList);
- QFETCH(QStringList, expectedProxyModelList);
- QStringListModel model;
- QSortFilterProxyModel proxyModel;
-
- model.setStringList(initialModelList);
- proxyModel.setSourceModel(&model);
- proxyModel.setDynamicSortFilter(true);
- proxyModel.setFilterRegExp(filterRegExp);
-
- QVERIFY(proxyModel.insertRow(row));
- QCOMPARE(model.stringList(), expectedModelList);
- QCOMPARE(proxyModel.rowCount(), expectedProxyModelList.count());
- for (int r = 0; r < proxyModel.rowCount(); ++r) {
- QModelIndex index = proxyModel.index(r, 0);
- QVERIFY(index.isValid());
- QCOMPARE(proxyModel.data(index).toString(), expectedProxyModelList.at(r));
- }
-}
-
-QTEST_MAIN(tst_QSortFilterProxyModel)
-#include "tst_qsortfilterproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
new file mode 100644
index 0000000000..82cd26971b
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
@@ -0,0 +1,4950 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "tst_qsortfilterproxymodel.h"
+#include "dynamictreemodel.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtGui/QStandardItem>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QTreeView>
+#include <QtWidgets/QTableView>
+
+#include <qdebug.h>
+
+// Testing get/set functions
+void tst_QSortFilterProxyModel::getSetCheck()
+{
+ QSortFilterProxyModel obj1;
+ QCOMPARE(obj1.sourceModel(), (QAbstractItemModel *)0);
+ // int QSortFilterProxyModel::filterKeyColumn()
+ // void QSortFilterProxyModel::setFilterKeyColumn(int)
+ obj1.setFilterKeyColumn(0);
+ QCOMPARE(0, obj1.filterKeyColumn());
+ obj1.setFilterKeyColumn(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.filterKeyColumn());
+ obj1.setFilterKeyColumn(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.filterKeyColumn());
+}
+
+tst_QSortFilterProxyModel::tst_QSortFilterProxyModel()
+ : m_model(0), m_proxy(0)
+{
+ qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
+}
+
+void tst_QSortFilterProxyModel::initTestCase()
+{
+ qRegisterMetaType<QList<QPersistentModelIndex> >();
+ m_model = new QStandardItemModel(0, 1);
+ m_proxy = new QSortFilterProxyModel();
+ m_proxy->setSourceModel(m_model);
+}
+
+void tst_QSortFilterProxyModel::cleanupTestCase()
+{
+ delete m_proxy;
+ delete m_model;
+}
+
+void tst_QSortFilterProxyModel::cleanup()
+{
+ switch (m_filterType) {
+ case FilterType::RegExp:
+ m_proxy->setFilterRegExp(QRegExp());
+ break;
+ case FilterType::RegularExpression:
+ m_proxy->setFilterRegularExpression(QRegularExpression());
+ break;
+ }
+
+ m_proxy->sort(-1, Qt::AscendingOrder);
+ m_model->clear();
+ m_model->insertColumns(0, 1);
+}
+
+/*
+ tests
+*/
+
+void tst_QSortFilterProxyModel::sort_data()
+{
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<int>("sortCaseSensitivity");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("flat descending") << static_cast<int>(Qt::DescendingOrder)
+ << int(Qt::CaseSensitive)
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "bravo"
+ << "lima"
+ << "charlie"
+ << "juliet"
+ << "tango"
+ << "hotel"
+ << "uniform"
+ << "alpha"
+ << "echo"
+ << "golf"
+ << "quebec"
+ << "foxtrot"
+ << "india"
+ << "romeo"
+ << "november"
+ << "oskar"
+ << "zulu"
+ << "kilo"
+ << "whiskey"
+ << "mike"
+ << "papa"
+ << "sierra"
+ << "xray"
+ << "viktor")
+ << (QStringList()
+ << "zulu"
+ << "yankee"
+ << "xray"
+ << "whiskey"
+ << "viktor"
+ << "uniform"
+ << "tango"
+ << "sierra"
+ << "romeo"
+ << "quebec"
+ << "papa"
+ << "oskar"
+ << "november"
+ << "mike"
+ << "lima"
+ << "kilo"
+ << "juliet"
+ << "india"
+ << "hotel"
+ << "golf"
+ << "foxtrot"
+ << "echo"
+ << "delta"
+ << "charlie"
+ << "bravo"
+ << "alpha");
+ QTest::newRow("flat ascending") << static_cast<int>(Qt::AscendingOrder)
+ << int(Qt::CaseSensitive)
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "bravo"
+ << "lima"
+ << "charlie"
+ << "juliet"
+ << "tango"
+ << "hotel"
+ << "uniform"
+ << "alpha"
+ << "echo"
+ << "golf"
+ << "quebec"
+ << "foxtrot"
+ << "india"
+ << "romeo"
+ << "november"
+ << "oskar"
+ << "zulu"
+ << "kilo"
+ << "whiskey"
+ << "mike"
+ << "papa"
+ << "sierra"
+ << "xray"
+ << "viktor")
+ << (QStringList()
+ << "alpha"
+ << "bravo"
+ << "charlie"
+ << "delta"
+ << "echo"
+ << "foxtrot"
+ << "golf"
+ << "hotel"
+ << "india"
+ << "juliet"
+ << "kilo"
+ << "lima"
+ << "mike"
+ << "november"
+ << "oskar"
+ << "papa"
+ << "quebec"
+ << "romeo"
+ << "sierra"
+ << "tango"
+ << "uniform"
+ << "viktor"
+ << "whiskey"
+ << "xray"
+ << "yankee"
+ << "zulu");
+ QTest::newRow("case insensitive") << static_cast<int>(Qt::AscendingOrder)
+ << int(Qt::CaseInsensitive)
+ << (QStringList()
+ << "alpha" << "BETA" << "Gamma" << "delta")
+ << (QStringList()
+ << "alpha" << "BETA" << "delta" << "Gamma");
+ QTest::newRow("case sensitive") << static_cast<int>(Qt::AscendingOrder)
+ << int(Qt::CaseSensitive)
+ << (QStringList()
+ << "alpha" << "BETA" << "Gamma" << "delta")
+ << (QStringList()
+ << "BETA" << "Gamma" << "alpha" << "delta");
+
+ QStringList list;
+ for (int i = 10000; i < 20000; ++i)
+ list.append(QStringLiteral("Number: ") + QString::number(i));
+ QTest::newRow("large set ascending") << static_cast<int>(Qt::AscendingOrder) << int(Qt::CaseSensitive) << list << list;
+}
+
+void tst_QSortFilterProxyModel::sort()
+{
+ QFETCH(int, sortOrder);
+ QFETCH(int, sortCaseSensitivity);
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+
+ // prepare model
+ QStandardItem *root = m_model->invisibleRootItem ();
+ QList<QStandardItem *> items;
+ for (int i = 0; i < initial.count(); ++i) {
+ items.append(new QStandardItem(initial.at(i)));
+ }
+ root->insertRows(0, items);
+ QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
+ QCOMPARE(m_model->columnCount(QModelIndex()), 1);
+
+ // make sure the proxy is unsorted
+ QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
+ QCOMPARE(m_proxy->rowCount(QModelIndex()), initial.count());
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+
+ // sort
+ m_proxy->sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ m_proxy->setSortCaseSensitivity(static_cast<Qt::CaseSensitivity>(sortCaseSensitivity));
+
+ // make sure the model is unchanged
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+ // make sure the proxy is sorted
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ // restore the unsorted order
+ m_proxy->sort(-1);
+
+ // make sure the proxy is unsorted again
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+}
+
+void tst_QSortFilterProxyModel::sortHierarchy_data()
+{
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("flat ascending")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList()
+ << "c" << "f" << "d" << "e" << "a" << "b")
+ << (QStringList()
+ << "a" << "b" << "c" << "d" << "e" << "f");
+
+ QTest::newRow("simple hierarchy")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "<" << "b" << "<" << "c" << ">" << ">")
+ << (QStringList() << "a" << "<" << "b" << "<" << "c" << ">" << ">");
+
+ QTest::newRow("hierarchical ascending")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList()
+ << "c"
+ << "<"
+ << "h"
+ << "<"
+ << "2"
+ << "0"
+ << "1"
+ << ">"
+ << "g"
+ << "i"
+ << ">"
+ << "b"
+ << "<"
+ << "l"
+ << "k"
+ << "<"
+ << "8"
+ << "7"
+ << "9"
+ << ">"
+ << "m"
+ << ">"
+ << "a"
+ << "<"
+ << "z"
+ << "y"
+ << "x"
+ << ">")
+ << (QStringList()
+ << "a"
+ << "<"
+ << "x"
+ << "y"
+ << "z"
+ << ">"
+ << "b"
+ << "<"
+ << "k"
+ << "<"
+ << "7"
+ << "8"
+ << "9"
+ << ">"
+ << "l"
+ << "m"
+ << ">"
+ << "c"
+ << "<"
+ << "g"
+ << "h"
+ << "<"
+ << "0"
+ << "1"
+ << "2"
+ << ">"
+ << "i"
+ << ">");
+}
+
+void tst_QSortFilterProxyModel::sortHierarchy()
+{
+ QFETCH(int, sortOrder);
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+
+ buildHierarchy(initial, m_model);
+ checkHierarchy(initial, m_model);
+ checkHierarchy(initial, m_proxy);
+ m_proxy->sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ checkHierarchy(initial, m_model);
+ checkHierarchy(expected, m_proxy);
+}
+
+void tst_QSortFilterProxyModel::insertRows_data()
+{
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+ QTest::addColumn<QStringList>("insert");
+ QTest::addColumn<int>("position");
+
+ QTest::newRow("insert one row in the middle")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ << "Three")
+ << 2;
+
+ QTest::newRow("insert one row in the beginning")
+ << (QStringList()
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ << "One")
+ << 0;
+
+ QTest::newRow("insert one row in the end")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList()
+ <<"Five")
+ << 4;
+}
+
+void tst_QSortFilterProxyModel::insertRows()
+{
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+ QFETCH(QStringList, insert);
+ QFETCH(int, position);
+ // prepare model
+ m_model->insertRows(0, initial.count(), QModelIndex());
+ //m_model->insertColumns(0, 1, QModelIndex());
+ QCOMPARE(m_model->columnCount(QModelIndex()), 1);
+ QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ m_model->setData(index, initial.at(row), Qt::DisplayRole);
+ }
+ // make sure the model correct before insert
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+ // make sure the proxy is correct before insert
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+
+ // insert the row
+ m_proxy->insertRows(position, insert.count(), QModelIndex());
+ QCOMPARE(m_model->rowCount(QModelIndex()), expected.count());
+ QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
+
+ // set the data for the inserted row
+ for (int i = 0; i < insert.count(); ++i) {
+ QModelIndex index = m_proxy->index(position + i, 0, QModelIndex());
+ m_proxy->setData(index, insert.at(i), Qt::DisplayRole);
+ }
+
+ // make sure the model correct after insert
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ // make sure the proxy is correct after insert
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+void tst_QSortFilterProxyModel::prependRow()
+{
+ //this tests that data is correctly handled by the sort filter when prepending a row
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QStandardItem item("root");
+ model.appendRow(&item);
+
+ QStandardItem sub("sub");
+ item.appendRow(&sub);
+
+ sub.appendRow(new QStandardItem("test1"));
+ sub.appendRow(new QStandardItem("test2"));
+
+ QStandardItem sub2("sub2");
+ sub2.appendRow(new QStandardItem("sub3"));
+ item.insertRow(0, &sub2);
+
+ QModelIndex index_sub2 = proxy.mapFromSource(model.indexFromItem(&sub2));
+
+ QCOMPARE(sub2.rowCount(), proxy.rowCount(index_sub2));
+ QCOMPARE(proxy.rowCount(QModelIndex()), 1); //only the "root" item is there
+}
+
+void tst_QSortFilterProxyModel::appendRowFromCombobox_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QString>("newitem");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("filter_out_second_last_item")
+ << "^[0-9]*$"
+ << (QStringList() << "a" << "1")
+ << "2"
+ << (QStringList() << "a" << "1" << "2");
+
+ QTest::newRow("filter_out_everything")
+ << "^c*$"
+ << (QStringList() << "a" << "b")
+ << "c"
+ << (QStringList() << "a" << "b" << "c");
+
+ QTest::newRow("no_filter")
+ << ""
+ << (QStringList() << "0" << "1")
+ << "2"
+ << (QStringList() << "0" << "1" << "2");
+
+ QTest::newRow("filter_out_last_item")
+ << "^[a-z]*$"
+ << (QStringList() << "a" << "1")
+ << "b"
+ << (QStringList() << "a" << "1" << "b");
+}
+
+void tst_QSortFilterProxyModel::appendRowFromCombobox()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, initial);
+ QFETCH(QString, newitem);
+ QFETCH(QStringList, expected);
+
+ QStringListModel model(initial);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setFilterRegExp(pattern);
+
+ QComboBox comboBox;
+ comboBox.setModel(&proxy);
+ comboBox.addItem(newitem);
+
+ QCOMPARE(model.stringList(), expected);
+}
+
+void tst_QSortFilterProxyModel::removeRows_data()
+{
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<int>("position");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<bool>("success");
+ QTest::addColumn<QStringList>("expectedProxy");
+ QTest::addColumn<QStringList>("expectedSource");
+
+ QTest::newRow("remove one row in the middle [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 2 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Two"
+ << "Four"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Two"
+ << "Four"
+ << "Five");
+
+ QTest::newRow("remove one row in the beginning [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 0 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five");
+
+ QTest::newRow("remove one row in the end [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 4 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four");
+
+ QTest::newRow("remove all [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 0 // position
+ << 5 // count
+ << true // success
+ << QStringList() // expectedProxy
+ << QStringList(); // expectedSource
+
+ QTest::newRow("remove one row past the end [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 5 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five");
+
+ QTest::newRow("remove row -1 [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << -1 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five");
+
+ QTest::newRow("remove three rows in the middle [no sorting/filter]")
+ << (QStringList()
+ << "One"
+ << "Two"
+ << "Three"
+ << "Four"
+ << "Five")
+ << -1 // no sorting
+ << QString() // no filter
+ << 1 // position
+ << 3 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "One"
+ << "Five")
+ << (QStringList() // expectedSource
+ << "One"
+ << "Five");
+
+ QTest::newRow("remove one row in the middle [ascending sorting, no filter]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QString() // no filter
+ << 2 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "4"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "5"
+ << "2"
+ << "4");
+
+ QTest::newRow("remove two rows in the middle [ascending sorting, no filter]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QString() // no filter
+ << 2 // position
+ << 2 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "5"
+ << "2");
+
+ QTest::newRow("remove two rows in the middle [descending sorting, no filter]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << static_cast<int>(Qt::DescendingOrder)
+ << QString() // no filter
+ << 2 // position
+ << 2 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "5"
+ << "4"
+ << "1")
+ << (QStringList() // expectedSource
+ << "1"
+ << "5"
+ << "4");
+
+ QTest::newRow("remove one row in the middle [no sorting, filter=5|2|3]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << -1 // no sorting
+ << QString("5|2|3")
+ << 1 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "5"
+ << "3")
+ << (QStringList() // expectedSource
+ << "1"
+ << "5"
+ << "4"
+ << "3");
+
+ QTest::newRow("remove all [ascending sorting, no filter]")
+ << (QStringList()
+ << "1"
+ << "5"
+ << "2"
+ << "4"
+ << "3")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QString() // no filter
+ << 0 // position
+ << 5 // count
+ << true // success
+ << QStringList() // expectedProxy
+ << QStringList(); // expectedSource
+}
+
+void tst_QSortFilterProxyModel::removeRows()
+{
+ QFETCH(QStringList, initial);
+ QFETCH(int, sortOrder);
+ QFETCH(QString, filter);
+ QFETCH(int, position);
+ QFETCH(int, count);
+ QFETCH(bool, success);
+ QFETCH(QStringList, expectedProxy);
+ QFETCH(QStringList, expectedSource);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ // prepare model
+ foreach (QString s, initial)
+ model.appendRow(new QStandardItem(s));
+
+ if (sortOrder != -1)
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+
+ if (!filter.isEmpty())
+ setupFilter(&proxy, filter);
+
+ // remove the rows
+ QCOMPARE(proxy.removeRows(position, count, QModelIndex()), success);
+ QCOMPARE(model.rowCount(QModelIndex()), expectedSource.count());
+ QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxy.count());
+
+ // make sure the model is correct after remove
+ for (int row = 0; row < model.rowCount(QModelIndex()); ++row)
+ QCOMPARE(model.item(row)->text(), expectedSource.at(row));
+
+ // make sure the proxy is correct after remove
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expectedProxy.at(row));
+ }
+}
+
+class MyFilteredColumnProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ MyFilteredColumnProxyModel(FilterType filterType, QObject *parent = 0) :
+ QSortFilterProxyModel(parent),
+ m_filterType(filterType)
+ { }
+
+protected:
+ bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const
+ {
+ QString key = sourceModel()->headerData(sourceColumn, Qt::Horizontal).toString();
+ bool result = false;
+ switch (m_filterType) {
+ case FilterType::RegExp:
+ result = key.contains(filterRegExp());
+ break;
+ case FilterType::RegularExpression:
+ result = key.contains(filterRegularExpression());
+ break;
+ }
+ return result;
+ }
+
+private:
+ FilterType m_filterType;
+};
+
+void tst_QSortFilterProxyModel::removeColumns_data()
+{
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<int>("position");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<bool>("success");
+ QTest::addColumn<QStringList>("expectedProxy");
+ QTest::addColumn<QStringList>("expectedSource");
+
+ QTest::newRow("remove one column in the middle [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << 2 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "4"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove one column in the end [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << 4 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "3"
+ << "4")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4");
+
+ QTest::newRow("remove one column past the end [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << 5 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove column -1 [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << -1 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove all columns [no filter]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString() // no filter
+ << 0 // position
+ << 5 // count
+ << true // success
+ << QStringList() // expectedProxy
+ << QStringList(); // expectedSource
+
+ QTest::newRow("remove one column in the middle [filter=1|3|5]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString("1|3|5")
+ << 1 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove one column in the end [filter=1|3|5]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString("1|3|5")
+ << 2 // position
+ << 1 // count
+ << true // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "3")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4");
+
+ QTest::newRow("remove one column past the end [filter=1|3|5]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString("1|3|5")
+ << 3 // position
+ << 1 // count
+ << false // success
+ << (QStringList() // expectedProxy
+ << "1"
+ << "3"
+ << "5")
+ << (QStringList() // expectedSource
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5");
+
+ QTest::newRow("remove all columns [filter=1|3|5]")
+ << (QStringList()
+ << "1"
+ << "2"
+ << "3"
+ << "4"
+ << "5")
+ << QString("1|3|5")
+ << 0 // position
+ << 3 // count
+ << true // success
+ << QStringList() // expectedProxy
+ << (QStringList() // expectedSource
+ << "2"
+ << "4");
+}
+
+void tst_QSortFilterProxyModel::removeColumns()
+{
+ QFETCH(QStringList, initial);
+ QFETCH(QString, filter);
+ QFETCH(int, position);
+ QFETCH(int, count);
+ QFETCH(bool, success);
+ QFETCH(QStringList, expectedProxy);
+ QFETCH(QStringList, expectedSource);
+
+ QStandardItemModel model;
+ MyFilteredColumnProxyModel proxy(m_filterType);
+ proxy.setSourceModel(&model);
+ if (!filter.isEmpty())
+ setupFilter(&proxy, filter);
+
+ // prepare model
+ model.setHorizontalHeaderLabels(initial);
+
+ // remove the columns
+ QCOMPARE(proxy.removeColumns(position, count, QModelIndex()), success);
+ QCOMPARE(model.columnCount(QModelIndex()), expectedSource.count());
+ QCOMPARE(proxy.columnCount(QModelIndex()), expectedProxy.count());
+
+ // make sure the model is correct after remove
+ for (int col = 0; col < model.columnCount(QModelIndex()); ++col)
+ QCOMPARE(model.horizontalHeaderItem(col)->text(), expectedSource.at(col));
+
+ // make sure the proxy is correct after remove
+ for (int col = 0; col < proxy.columnCount(QModelIndex()); ++col) {
+ QCOMPARE(proxy.headerData(col, Qt::Horizontal, Qt::DisplayRole).toString(),
+ expectedProxy.at(col));
+ }
+}
+
+void tst_QSortFilterProxyModel::filterColumns_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<bool>("data");
+
+ QTest::newRow("all") << "a"
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "bravo"
+ << "lima")
+ << true;
+
+ QTest::newRow("some") << "lie"
+ << (QStringList()
+ << "charlie"
+ << "juliet"
+ << "tango"
+ << "hotel")
+ << true;
+
+ QTest::newRow("nothing") << "zoo"
+ << (QStringList()
+ << "foxtrot"
+ << "uniform"
+ << "alpha"
+ << "golf")
+ << false;
+}
+
+void tst_QSortFilterProxyModel::filterColumns()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, initial);
+ QFETCH(bool, data);
+ // prepare model
+ m_model->setColumnCount(initial.count());
+ m_model->setRowCount(1);
+ QCOMPARE(m_model->columnCount(QModelIndex()), initial.count());
+ QCOMPARE(m_model->rowCount(QModelIndex()), 1);
+ // set data
+ QCOMPARE(m_model->rowCount(QModelIndex()), 1);
+ for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
+ QModelIndex index = m_model->index(0, col, QModelIndex());
+ m_model->setData(index, initial.at(col), Qt::DisplayRole);
+ }
+ setupFilter(m_proxy, pattern);
+
+ m_proxy->setFilterKeyColumn(-1);
+ // make sure the model is unchanged
+ for (int col = 0; col < m_model->columnCount(QModelIndex()); ++col) {
+ QModelIndex index = m_model->index(0, col, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(col));
+ }
+ // make sure the proxy is filtered
+ QModelIndex index = m_proxy->index(0, 0, QModelIndex());
+ QCOMPARE(index.isValid(), data);
+}
+
+void tst_QSortFilterProxyModel::filter_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("flat") << "e"
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "bravo"
+ << "lima"
+ << "charlie"
+ << "juliet"
+ << "tango"
+ << "hotel"
+ << "uniform"
+ << "alpha"
+ << "echo"
+ << "golf"
+ << "quebec"
+ << "foxtrot"
+ << "india"
+ << "romeo"
+ << "november"
+ << "oskar"
+ << "zulu"
+ << "kilo"
+ << "whiskey"
+ << "mike"
+ << "papa"
+ << "sierra"
+ << "xray"
+ << "viktor")
+ << (QStringList()
+ << "delta"
+ << "yankee"
+ << "charlie"
+ << "juliet"
+ << "hotel"
+ << "echo"
+ << "quebec"
+ << "romeo"
+ << "november"
+ << "whiskey"
+ << "mike"
+ << "sierra");
+}
+
+void tst_QSortFilterProxyModel::filter()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+
+ // prepare model
+ QVERIFY(m_model->insertRows(0, initial.count(), QModelIndex()));
+ QCOMPARE(m_model->rowCount(QModelIndex()), initial.count());
+ // set data
+ QCOMPARE(m_model->columnCount(QModelIndex()), 1);
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ m_model->setData(index, initial.at(row), Qt::DisplayRole);
+ }
+ setupFilter(m_proxy, pattern);
+ // make sure the proxy is unfiltered
+ QCOMPARE(m_proxy->columnCount(QModelIndex()), 1);
+ QCOMPARE(m_proxy->rowCount(QModelIndex()), expected.count());
+ // make sure the model is unchanged
+ for (int row = 0; row < m_model->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_model->index(row, 0, QModelIndex());
+ QCOMPARE(m_model->data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+ // make sure the proxy is filtered
+ for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) {
+ QModelIndex index = m_proxy->index(row, 0, QModelIndex());
+ QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+void tst_QSortFilterProxyModel::filterHierarchy_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QStringList>("initial");
+ QTest::addColumn<QStringList>("expected");
+
+ QTest::newRow("flat") << ".*oo"
+ << (QStringList()
+ << "foo" << "boo" << "baz" << "moo" << "laa" << "haa")
+ << (QStringList()
+ << "foo" << "boo" << "moo");
+
+ QTest::newRow("simple hierarchy") << "b.*z"
+ << (QStringList() << "baz" << "<" << "boz" << "<" << "moo" << ">" << ">")
+ << (QStringList() << "baz" << "<" << "boz" << ">");
+}
+
+void tst_QSortFilterProxyModel::filterHierarchy()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QStringList, initial);
+ QFETCH(QStringList, expected);
+ buildHierarchy(initial, m_model);
+ setupFilter(m_proxy, pattern);
+ checkHierarchy(initial, m_model);
+ checkHierarchy(expected, m_proxy);
+}
+
+void tst_QSortFilterProxyModel::buildHierarchy(const QStringList &l, QAbstractItemModel *m)
+{
+ int ind = 0;
+ int row = 0;
+ QStack<int> row_stack;
+ QModelIndex parent;
+ QStack<QModelIndex> parent_stack;
+ for (int i = 0; i < l.count(); ++i) {
+ QString token = l.at(i);
+ if (token == QLatin1String("<")) { // start table
+ ++ind;
+ parent_stack.push(parent);
+ row_stack.push(row);
+ parent = m->index(row - 1, 0, parent);
+ row = 0;
+ QVERIFY(m->insertColumns(0, 1, parent)); // add column
+ } else if (token == QLatin1String(">")) { // end table
+ --ind;
+ parent = parent_stack.pop();
+ row = row_stack.pop();
+ } else { // append row
+ QVERIFY(m->insertRows(row, 1, parent));
+ QModelIndex index = m->index(row, 0, parent);
+ QVERIFY(index.isValid());
+ m->setData(index, token, Qt::DisplayRole);
+ ++row;
+ }
+ }
+}
+
+void tst_QSortFilterProxyModel::checkHierarchy(const QStringList &l, const QAbstractItemModel *m)
+{
+ int row = 0;
+ int indent = 0;
+ QStack<int> row_stack;
+ QModelIndex parent;
+ QStack<QModelIndex> parent_stack;
+ for (int i = 0; i < l.count(); ++i) {
+ QString token = l.at(i);
+ if (token == QLatin1String("<")) { // start table
+ ++indent;
+ parent_stack.push(parent);
+ row_stack.push(row);
+ parent = m->index(row - 1, 0, parent);
+ QVERIFY(parent.isValid());
+ row = 0;
+ } else if (token == QLatin1String(">")) { // end table
+ --indent;
+ parent = parent_stack.pop();
+ row = row_stack.pop();
+ } else { // compare row
+ QModelIndex index = m->index(row, 0, parent);
+ QVERIFY(index.isValid());
+ QString str = m->data(index, Qt::DisplayRole).toString();
+ QCOMPARE(str, token);
+ ++row;
+ }
+ }
+}
+
+void tst_QSortFilterProxyModel::setupFilter(QSortFilterProxyModel *model, const QString& pattern)
+{
+ switch (m_filterType) {
+ case FilterType::RegExp:
+ model->setFilterRegExp(pattern);
+ break;
+ case FilterType::RegularExpression:
+ model->setFilterRegularExpression(pattern);
+ break;
+ }
+}
+
+class TestModel: public QAbstractTableModel
+{
+public:
+ int rowCount(const QModelIndex &) const { return 10000; }
+ int columnCount(const QModelIndex &) const { return 1; }
+ QVariant data(const QModelIndex &index, int role) const
+ {
+ if (role != Qt::DisplayRole)
+ return QVariant();
+ return QString::number(index.row());
+ }
+};
+
+void tst_QSortFilterProxyModel::filterTable()
+{
+ TestModel model;
+ QSortFilterProxyModel filter;
+ filter.setSourceModel(&model);
+ setupFilter(&filter, QLatin1String("9"));
+
+ for (int i = 0; i < filter.rowCount(); ++i)
+ QVERIFY(filter.data(filter.index(i, 0)).toString().contains(QLatin1Char('9')));
+}
+
+void tst_QSortFilterProxyModel::insertAfterSelect()
+{
+ QStandardItemModel model(10, 2);
+ for (int i = 0; i<10;i++)
+ model.setData(model.index(i, 0), QVariant(i));
+ QSortFilterProxyModel filter;
+ filter.setSourceModel(&model);
+ QTreeView view;
+ view.setModel(&filter);
+ view.show();
+ QModelIndex firstIndex = filter.mapFromSource(model.index(0, 0, QModelIndex()));
+ QCOMPARE(firstIndex.model(), (const QAbstractItemModel *)view.model());
+ QVERIFY(firstIndex.isValid());
+ int itemOffset = view.visualRect(firstIndex).width() / 2;
+ QPoint p(itemOffset, 1);
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
+ model.insertRows(5, 1, QModelIndex());
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0); // Should still have a selection
+}
+
+void tst_QSortFilterProxyModel::removeAfterSelect()
+{
+ QStandardItemModel model(10, 2);
+ for (int i = 0; i<10;i++)
+ model.setData(model.index(i, 0), QVariant(i));
+ QSortFilterProxyModel filter;
+ filter.setSourceModel(&model);
+ QTreeView view;
+ view.setModel(&filter);
+ view.show();
+ QModelIndex firstIndex = filter.mapFromSource(model.index(0, 0, QModelIndex()));
+ QCOMPARE(firstIndex.model(), (const QAbstractItemModel *)view.model());
+ QVERIFY(firstIndex.isValid());
+ int itemOffset = view.visualRect(firstIndex).width() / 2;
+ QPoint p(itemOffset, 1);
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
+ model.removeRows(5, 1, QModelIndex());
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0); // Should still have a selection
+}
+
+void tst_QSortFilterProxyModel::filterCurrent()
+{
+ QStandardItemModel model(2, 1);
+ model.setData(model.index(0, 0), QString("AAA"));
+ model.setData(model.index(1, 0), QString("BBB"));
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ QTreeView view;
+
+ view.show();
+ view.setModel(&proxy);
+ QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged);
+ QVERIFY(spy.isValid());
+
+ view.setCurrentIndex(proxy.index(0, 0));
+ QCOMPARE(spy.count(), 1);
+ setupFilter(&proxy, QLatin1String("^B"));
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_QSortFilterProxyModel::filter_qtbug30662()
+{
+ QStringListModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ // make sure the filter does not match any entry
+ setupFilter(&proxy, QLatin1String("[0-9]+"));
+
+ QStringList slSource;
+ slSource << "z" << "x" << "a" << "b";
+
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0);
+ model.setStringList(slSource);
+
+ // without fix for QTBUG-30662 this will make all entries visible - but unsorted
+ setupFilter(&proxy, QLatin1String("[a-z]+"));
+
+ QStringList slResult;
+ for (int i = 0; i < proxy.rowCount(); ++i)
+ slResult.append(proxy.index(i, 0).data().toString());
+
+ slSource.sort();
+ QCOMPARE(slResult, slSource);
+}
+
+void tst_QSortFilterProxyModel::changeSourceLayout()
+{
+ QStandardItemModel model(2, 1);
+ model.setData(model.index(0, 0), QString("b"));
+ model.setData(model.index(1, 0), QString("a"));
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QList<QPersistentModelIndex> persistentSourceIndexes;
+ QList<QPersistentModelIndex> persistentProxyIndexes;
+ for (int row = 0; row < model.rowCount(); ++row) {
+ persistentSourceIndexes.append(model.index(row, 0));
+ persistentProxyIndexes.append(proxy.index(row, 0));
+ }
+
+ // change layout of source model
+ model.sort(0, Qt::AscendingOrder);
+
+ for (int row = 0; row < model.rowCount(); ++row) {
+ QCOMPARE(persistentProxyIndexes.at(row).row(),
+ persistentSourceIndexes.at(row).row());
+ }
+}
+
+void tst_QSortFilterProxyModel::changeSourceLayoutFilteredOut()
+{
+ QStandardItemModel model(2, 1);
+ model.setData(model.index(0, 0), QString("b"));
+ model.setData(model.index(1, 0), QString("a"));
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ int beforeSortFilter = proxy.rowCount();
+
+ QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ // Filter everything out
+ setupFilter(&proxy, QLatin1String("c"));
+
+ QCOMPARE(removeSpy.count(), 1);
+ QCOMPARE(0, proxy.rowCount());
+
+ // change layout of source model
+ model.sort(0, Qt::AscendingOrder);
+
+ QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+ // Remove filter; we expect an insert
+ setupFilter(&proxy, "");
+
+ QCOMPARE(insertSpy.count(), 1);
+ QCOMPARE(beforeSortFilter, proxy.rowCount());
+}
+
+void tst_QSortFilterProxyModel::removeSourceRows_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<int>("start");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<IntPairList>("expectedRemovedProxyIntervals");
+ QTest::addColumn<QStringList>("expectedProxyItems");
+
+ QTest::newRow("remove one, no sorting")
+ << (QStringList() << "a" << "b") // sourceItems
+ << 0 // start
+ << 1 // count
+ << -1 // sortOrder (no sorting)
+ << (IntPairList() << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b") // expectedProxyItems
+ ;
+ QTest::newRow("remove one, ascending sort (same order)")
+ << (QStringList() << "a" << "b") // sourceItems
+ << 0 // start
+ << 1 // count
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (IntPairList() << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b") // expectedProxyItems
+ ;
+ QTest::newRow("remove one, ascending sort (reverse order)")
+ << (QStringList() << "b" << "a") // sourceItems
+ << 0 // start
+ << 1 // count
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (IntPairList() << IntPair(1, 1)) // expectedRemovedIntervals
+ << (QStringList() << "a") // expectedProxyItems
+ ;
+ QTest::newRow("remove two, multiple proxy intervals")
+ << (QStringList() << "c" << "d" << "a" << "b") // sourceItems
+ << 1 // start
+ << 2 // count
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (IntPairList() << IntPair(3, 3) << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b" << "c") // expectedProxyItems
+ ;
+ QTest::newRow("remove three, multiple proxy intervals")
+ << (QStringList() << "b" << "d" << "f" << "a" << "c" << "e") // sourceItems
+ << 3 // start
+ << 3 // count
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (IntPairList() << IntPair(4, 4) << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b" << "d" << "f") // expectedProxyItems
+ ;
+ QTest::newRow("remove all, single proxy intervals")
+ << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
+ << 0 // start
+ << 6 // count
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << (IntPairList() << IntPair(0, 5)) // expectedRemovedIntervals
+ << QStringList() // expectedProxyItems
+ ;
+}
+
+// Check that correct proxy model rows are removed when rows are removed
+// from the source model
+void tst_QSortFilterProxyModel::removeSourceRows()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(int, start);
+ QFETCH(int, count);
+ QFETCH(int, sortOrder);
+ QFETCH(IntPairList, expectedRemovedProxyIntervals);
+ QFETCH(QStringList, expectedProxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.count());
+
+ for (int i = 0; i < sourceItems.count(); ++i) {
+ QModelIndex sindex = model.index(i, 0, QModelIndex());
+ model.setData(sindex, sourceItems.at(i), Qt::DisplayRole);
+ QModelIndex pindex = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(pindex, Qt::DisplayRole), model.data(sindex, Qt::DisplayRole));
+ }
+
+ if (sortOrder != -1)
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+ QSignalSpy aboutToRemoveSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeRemoved);
+ QSignalSpy aboutToInsertSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeInserted);
+
+ QVERIFY(removeSpy.isValid());
+ QVERIFY(insertSpy.isValid());
+ QVERIFY(aboutToRemoveSpy.isValid());
+ QVERIFY(aboutToInsertSpy.isValid());
+
+ model.removeRows(start, count, QModelIndex());
+
+ QCOMPARE(aboutToRemoveSpy.count(), expectedRemovedProxyIntervals.count());
+ for (int i = 0; i < aboutToRemoveSpy.count(); ++i) {
+ QList<QVariant> args = aboutToRemoveSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
+ }
+ QCOMPARE(removeSpy.count(), expectedRemovedProxyIntervals.count());
+ for (int i = 0; i < removeSpy.count(); ++i) {
+ QList<QVariant> args = removeSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
+ }
+
+ QCOMPARE(insertSpy.count(), 0);
+ QCOMPARE(aboutToInsertSpy.count(), 0);
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxyItems.count());
+ for (int i = 0; i < expectedProxyItems.count(); ++i) {
+ QModelIndex pindex = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(pindex, Qt::DisplayRole).toString(), expectedProxyItems.at(i));
+ }
+}
+
+void tst_QSortFilterProxyModel::insertSourceRows_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<int>("start");
+ QTest::addColumn<QStringList>("newItems");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QStringList>("proxyItems");
+
+ QTest::newRow("insert (1)")
+ << (QStringList() << "c" << "b") // sourceItems
+ << 1 // start
+ << (QStringList() << "a") // newItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << (QStringList() << "a" << "b" << "c") // proxyItems
+ ;
+
+ QTest::newRow("insert (2)")
+ << (QStringList() << "d" << "b" << "c") // sourceItems
+ << 3 // start
+ << (QStringList() << "a") // newItems
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << (QStringList() << "d" << "c" << "b" << "a") // proxyItems
+ ;
+}
+
+// Check that rows are inserted at correct position in proxy model when
+// rows are inserted into the source model
+void tst_QSortFilterProxyModel::insertSourceRows()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(int, start);
+ QFETCH(QStringList, newItems);
+ QFETCH(int, sortOrder);
+ QFETCH(QStringList, proxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.count());
+
+ for (int i = 0; i < sourceItems.count(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i), Qt::DisplayRole);
+ }
+
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ model.insertRows(start, newItems.size(), QModelIndex());
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), proxyItems.count());
+ for (int i = 0; i < newItems.count(); ++i) {
+ QModelIndex index = model.index(start + i, 0, QModelIndex());
+ model.setData(index, newItems.at(i), Qt::DisplayRole);
+ }
+
+ for (int i = 0; i < proxyItems.count(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), proxyItems.at(i));
+ }
+}
+
+void tst_QSortFilterProxyModel::changeFilter_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QString>("initialFilter");
+ QTest::addColumn<IntPairList>("initialRemoveIntervals");
+ QTest::addColumn<QStringList>("initialProxyItems");
+ QTest::addColumn<QString>("finalFilter");
+ QTest::addColumn<IntPairList>("finalRemoveIntervals");
+ QTest::addColumn<IntPairList>("insertIntervals");
+ QTest::addColumn<QStringList>("finalProxyItems");
+
+ QTest::newRow("filter (1)")
+ << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "a|b|c" // initialFilter
+ << (IntPairList() << IntPair(3, 5)) // initialRemoveIntervals
+ << (QStringList() << "a" << "b" << "c") // initialProxyItems
+ << "b|d|f" // finalFilter
+ << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // finalRemoveIntervals
+ << (IntPairList() << IntPair(1, 2)) // insertIntervals
+ << (QStringList() << "b" << "d" << "f") // finalProxyItems
+ ;
+
+ QTest::newRow("filter (2)")
+ << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "a|c|e" // initialFilter
+ << (IntPairList() << IntPair(5, 5) << IntPair(3, 3) << IntPair(1, 1)) // initialRemoveIntervals
+ << (QStringList() << "a" << "c" << "e") // initialProxyItems
+ << "" // finalFilter
+ << IntPairList() // finalRemoveIntervals
+ << (IntPairList() << IntPair(3, 3) << IntPair(2, 2) << IntPair(1, 1)) // insertIntervals
+ << (QStringList() << "a" << "b" << "c" << "d" << "e" << "f") // finalProxyItems
+ ;
+
+ QTest::newRow("filter (3)")
+ << (QStringList() << "a" << "b" << "c") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "a" // initialFilter
+ << (IntPairList() << IntPair(1, 2)) // initialRemoveIntervals
+ << (QStringList() << "a") // initialProxyItems
+ << "a" // finalFilter
+ << IntPairList() // finalRemoveIntervals
+ << IntPairList() // insertIntervals
+ << (QStringList() << "a") // finalProxyItems
+ ;
+}
+
+// Check that rows are added/removed when filter changes
+void tst_QSortFilterProxyModel::changeFilter()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(int, sortOrder);
+ QFETCH(QString, initialFilter);
+ QFETCH(IntPairList, initialRemoveIntervals);
+ QFETCH(QStringList, initialProxyItems);
+ QFETCH(QString, finalFilter);
+ QFETCH(IntPairList, finalRemoveIntervals);
+ QFETCH(IntPairList, insertIntervals);
+ QFETCH(QStringList, finalProxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.count());
+
+ for (int i = 0; i < sourceItems.count(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i), Qt::DisplayRole);
+ }
+
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ QSignalSpy initialRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy initialInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+
+ QVERIFY(initialRemoveSpy.isValid());
+ QVERIFY(initialInsertSpy.isValid());
+
+ setupFilter(&proxy, initialFilter);
+
+ QCOMPARE(initialRemoveSpy.count(), initialRemoveIntervals.count());
+ QCOMPARE(initialInsertSpy.count(), 0);
+ for (int i = 0; i < initialRemoveSpy.count(); ++i) {
+ QList<QVariant> args = initialRemoveSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), initialRemoveIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), initialRemoveIntervals.at(i).second);
+ }
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), initialProxyItems.count());
+ for (int i = 0; i < initialProxyItems.count(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initialProxyItems.at(i));
+ }
+
+ QSignalSpy finalRemoveSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy finalInsertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+
+ QVERIFY(finalRemoveSpy.isValid());
+ QVERIFY(finalInsertSpy.isValid());
+
+ setupFilter(&proxy, finalFilter);
+
+ QCOMPARE(finalRemoveSpy.count(), finalRemoveIntervals.count());
+ for (int i = 0; i < finalRemoveSpy.count(); ++i) {
+ QList<QVariant> args = finalRemoveSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), finalRemoveIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), finalRemoveIntervals.at(i).second);
+ }
+
+ QCOMPARE(finalInsertSpy.count(), insertIntervals.count());
+ for (int i = 0; i < finalInsertSpy.count(); ++i) {
+ QList<QVariant> args = finalInsertSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), insertIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), insertIntervals.at(i).second);
+ }
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), finalProxyItems.count());
+ for (int i = 0; i < finalProxyItems.count(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), finalProxyItems.at(i));
+ }
+}
+
+void tst_QSortFilterProxyModel::changeSourceData_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<QStringList>("expectedInitialProxyItems");
+ QTest::addColumn<bool>("dynamic");
+ QTest::addColumn<int>("row");
+ QTest::addColumn<QString>("newValue");
+ QTest::addColumn<IntPairList>("removeIntervals");
+ QTest::addColumn<IntPairList>("insertIntervals");
+ QTest::addColumn<int>("expectedDataChangedRow"); // -1 if no dataChanged signal expected
+ QTest::addColumn<bool>("expectedLayoutChanged");
+ QTest::addColumn<QStringList>("proxyItems");
+
+ QTest::newRow("move_to_end_ascending")
+ << (QStringList() << "c" << "b" << "a") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "" // filter
+ << (QStringList() << "a" << "b" << "c") // expectedInitialProxyItems
+ << true // dynamic
+ << 2 // row
+ << "z" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << 2 // dataChanged(row 2) is emitted, see comment "Make sure we also emit dataChanged for the rows" in the source code (unclear why, though)
+ << true // layoutChanged
+ << (QStringList() << "b" << "c" << "z") // proxyItems
+ ;
+
+ QTest::newRow("move_to_end_descending")
+ << (QStringList() << "b" << "c" << "z") // sourceItems
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << "" // filter
+ << (QStringList() << "z" << "c" << "b") // expectedInitialProxyItems
+ << true // dynamic
+ << 1 // row
+ << "a" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << 2 // dataChanged(row 2) is emitted, see comment "Make sure we also emit dataChanged for the rows" in the source code (unclear why, though)
+ << true // layoutChanged
+ << (QStringList() << "z" << "b" << "a") // proxyItems
+ ;
+
+ QTest::newRow("no_op_change")
+ << (QStringList() << "a" << "b") // sourceItems
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << "" // filter
+ << (QStringList() << "b" << "a") // expectedInitialProxyItems
+ << true // dynamic
+ << 0 // row
+ << "a" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << -1 // no dataChanged signal
+ << false // layoutChanged
+ << (QStringList() << "b" << "a") // proxyItems
+ ;
+
+ QTest::newRow("no_effect_on_filtering")
+ << (QStringList() << "a" << "b") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "" // filter
+ << (QStringList() << "a" << "b") // expectedInitialProxyItems
+ << true // dynamic
+ << 1 // row
+ << "z" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << 1 // expectedDataChangedRow
+ << false // layoutChanged
+ << (QStringList() << "a" << "z") // proxyItems
+ ;
+
+ QTest::newRow("filtered_out_value_stays_out")
+ << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "a|c" // filter
+ << (QStringList() << "a" << "c") // expectedInitialProxyItems
+ << true // dynamic
+ << 1 // row
+ << "x" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << -1 // no dataChanged signal
+ << false // layoutChanged
+ << (QStringList() << "a" << "c") // proxyItems
+ ;
+
+ QTest::newRow("filtered_out_now_matches")
+ << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "a|c|x" // filter
+ << (QStringList() << "a" << "c") // expectedInitialProxyItems
+ << true // dynamic
+ << 1 // row
+ << "x" // newValue
+ << IntPairList() // removeIntervals
+ << (IntPairList() << IntPair(2, 2)) // insertIntervals
+ << -1 // no dataChanged signal
+ << false // layoutChanged
+ << (QStringList() << "a" << "c" << "x") // proxyItems
+ ;
+
+ QTest::newRow("value_is_now_filtered_out")
+ << (QStringList() << "a" << "b" << "c" << "d") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "a|c" // filter
+ << (QStringList() << "a" << "c") // expectedInitialProxyItems
+ << true // dynamic
+ << 2 // row
+ << "x" // newValue
+ << (IntPairList() << IntPair(1, 1)) // removeIntervals
+ << IntPairList() // insertIntervals
+ << -1 // no dataChanged signal
+ << false // layoutChanged
+ << (QStringList() << "a") // proxyItems
+ ;
+
+ QTest::newRow("non_dynamic_filter_does_not_update_sort")
+ << (QStringList() << "c" << "b" << "a") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "" // filter
+ << (QStringList() << "a" << "b" << "c") // expectedInitialProxyItems
+ << false // dynamic
+ << 2 // row
+ << "x" // newValue
+ << IntPairList() // removeIntervals
+ << IntPairList() // insertIntervals
+ << 0 // expectedDataChangedRow
+ << false // layoutChanged
+ << (QStringList() << "x" << "b" << "c") // proxyItems
+ ;
+}
+
+void tst_QSortFilterProxyModel::changeSourceData()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(int, sortOrder);
+ QFETCH(QString, filter);
+ QFETCH(QStringList, expectedInitialProxyItems);
+ QFETCH(bool, dynamic);
+ QFETCH(int, row);
+ QFETCH(QString, newValue);
+ QFETCH(IntPairList, removeIntervals);
+ QFETCH(IntPairList, insertIntervals);
+ QFETCH(int, expectedDataChangedRow);
+ QFETCH(bool, expectedLayoutChanged);
+ QFETCH(QStringList, proxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+
+ proxy.setDynamicSortFilter(dynamic);
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.count());
+
+ for (int i = 0; i < sourceItems.count(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i), Qt::DisplayRole);
+ }
+
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ setupFilter(&proxy, filter);
+
+ QCOMPARE(proxy.rowCount(), expectedInitialProxyItems.count());
+ for (int i = 0; i < expectedInitialProxyItems.count(); ++i) {
+ const QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expectedInitialProxyItems.at(i));
+ }
+
+ QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+ QSignalSpy dataChangedSpy(&proxy, &QSortFilterProxyModel::dataChanged);
+ QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(removeSpy.isValid());
+ QVERIFY(insertSpy.isValid());
+ QVERIFY(dataChangedSpy.isValid());
+ QVERIFY(layoutChangedSpy.isValid());
+
+ {
+ QModelIndex index = model.index(row, 0, QModelIndex());
+ model.setData(index, newValue, Qt::DisplayRole);
+ }
+
+ QCOMPARE(removeSpy.count(), removeIntervals.count());
+ for (int i = 0; i < removeSpy.count(); ++i) {
+ QList<QVariant> args = removeSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), removeIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), removeIntervals.at(i).second);
+ }
+
+ QCOMPARE(insertSpy.count(), insertIntervals.count());
+ for (int i = 0; i < insertSpy.count(); ++i) {
+ QList<QVariant> args = insertSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), insertIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), insertIntervals.at(i).second);
+ }
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), proxyItems.count());
+ for (int i = 0; i < proxyItems.count(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), proxyItems.at(i));
+ }
+
+ if (expectedDataChangedRow == -1) {
+ QCOMPARE(dataChangedSpy.count(), 0);
+ } else {
+ QCOMPARE(dataChangedSpy.count(), 1);
+ const QModelIndex idx = dataChangedSpy.at(0).at(0).value<QModelIndex>();
+ QCOMPARE(idx.row(), expectedDataChangedRow);
+ QCOMPARE(idx.column(), 0);
+ }
+
+ QCOMPARE(layoutChangedSpy.count(), expectedLayoutChanged ? 1 : 0);
+}
+
+// Checks that the model is a table, and that each and every row is like this:
+// i-th row: ( rows.at(i), i )
+static void checkSortedTableModel(const QAbstractItemModel *model, const QStringList &rows)
+{
+ QCOMPARE(model->rowCount(), rows.length());
+ QCOMPARE(model->columnCount(), 2);
+
+ for (int row = 0; row < model->rowCount(); ++row) {
+ const QString column0 = model->index(row, 0).data().toString();
+ const int column1 = model->index(row, 1).data().toString().toInt();
+
+ QCOMPARE(column0, rows.at(row));
+ QCOMPARE(column1, row);
+ }
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548()
+{
+ // Check that emitting dataChanged from the source model
+ // for a change of a role which is not the sorting role
+ // doesn't alter the sorting. In this case, we sort on the DisplayRole,
+ // and play with other roles.
+
+ static const QStringList rows
+ = QStringList() << "a" << "b" << "b" << "b" << "c" << "c" << "x";
+
+ // Build a table of pairs (string, #row) in each row
+ QStandardItemModel model(0, 2);
+
+ for (int rowNumber = 0; rowNumber < rows.length(); ++rowNumber) {
+ QStandardItem *column0 = new QStandardItem(rows.at(rowNumber));
+ column0->setCheckable(true);
+ column0->setCheckState(Qt::Unchecked);
+
+ QStandardItem *column1 = new QStandardItem(QString::number(rowNumber));
+
+ const QList<QStandardItem *> row
+ = QList<QStandardItem *>() << column0 << column1;
+
+ model.appendRow(row);
+ }
+
+ checkSortedTableModel(&model, rows);
+
+ // Build the proxy model
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0);
+
+ // The proxy is now sorted by the first column, check that the sorting
+ // * is correct (the input is already sorted, so it must not have changed)
+ // * was stable (by looking at the second column)
+ checkSortedTableModel(&model, rows);
+
+ // Change the check status of an item. That must not break the stable sorting
+ // changes the middle "b"
+ model.item(2)->setCheckState(Qt::Checked);
+ checkSortedTableModel(&model, rows);
+
+ // changes the starting "a"
+ model.item(0)->setCheckState(Qt::Checked);
+ checkSortedTableModel(&model, rows);
+
+ // change the background color of the first "c"
+ model.item(4)->setBackground(Qt::red);
+ checkSortedTableModel(&model, rows);
+
+ // change the background color of the second "c"
+ model.item(5)->setBackground(Qt::red);
+ checkSortedTableModel(&model, rows);
+}
+
+void tst_QSortFilterProxyModel::changeSourceDataForwardsRoles_qtbug35440()
+{
+ QStringList strings;
+ for (int i = 0; i < 100; ++i)
+ strings << QString::number(i);
+
+ QStringListModel model(strings);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.sort(0, Qt::AscendingOrder);
+
+ QSignalSpy spy(&proxy, &QAbstractItemModel::dataChanged);
+ QVERIFY(spy.isValid());
+ QCOMPARE(spy.length(), 0);
+
+ QModelIndex index;
+
+ // QStringListModel doesn't distinguish between edit and display roles,
+ // so changing one always changes the other, too.
+ QVector<int> expectedChangedRoles;
+ expectedChangedRoles.append(Qt::DisplayRole);
+ expectedChangedRoles.append(Qt::EditRole);
+
+ index = model.index(0, 0);
+ QVERIFY(index.isValid());
+ model.setData(index, QStringLiteral("teststring"), Qt::DisplayRole);
+ QCOMPARE(spy.length(), 1);
+ QCOMPARE(spy.at(0).at(2).value<QVector<int> >(), expectedChangedRoles);
+
+ index = model.index(1, 0);
+ QVERIFY(index.isValid());
+ model.setData(index, QStringLiteral("teststring2"), Qt::EditRole);
+ QCOMPARE(spy.length(), 2);
+ QCOMPARE(spy.at(1).at(2).value<QVector<int> >(), expectedChangedRoles);
+}
+
+void tst_QSortFilterProxyModel::sortFilterRole()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+
+ QList<QPair<QVariant, QVariant> > sourceItems;
+ sourceItems = QList<QPair<QVariant, QVariant> >()
+ << QPair<QVariant, QVariant>("b", 3)
+ << QPair<QVariant, QVariant>("c", 2)
+ << QPair<QVariant, QVariant>("a", 1);
+
+ QList<int> orderedItems;
+ orderedItems = QList<int>()
+ << 2 << 1;
+
+ model.insertRows(0, sourceItems.count());
+ for (int i = 0; i < sourceItems.count(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i).first, Qt::DisplayRole);
+ model.setData(index, sourceItems.at(i).second, Qt::UserRole);
+ }
+
+ setupFilter(&proxy, QLatin1String("2"));
+
+ QCOMPARE(proxy.rowCount(), 0); // Qt::DisplayRole is default role
+
+ proxy.setFilterRole(Qt::UserRole);
+ QCOMPARE(proxy.rowCount(), 1);
+
+ proxy.setFilterRole(Qt::DisplayRole);
+ QCOMPARE(proxy.rowCount(), 0);
+
+ setupFilter(&proxy, QLatin1String("1|2|3"));
+
+ QCOMPARE(proxy.rowCount(), 0);
+
+ proxy.setFilterRole(Qt::UserRole);
+ QCOMPARE(proxy.rowCount(), 3);
+
+ proxy.sort(0, Qt::AscendingOrder);
+ QCOMPARE(proxy.rowCount(), 3);
+
+ proxy.setSortRole(Qt::UserRole);
+ proxy.setFilterRole(Qt::DisplayRole);
+ setupFilter(&proxy, QLatin1String("a|c"));
+
+ QCOMPARE(proxy.rowCount(), orderedItems.count());
+ for (int i = 0; i < proxy.rowCount(); ++i) {
+ QModelIndex index = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole), sourceItems.at(orderedItems.at(i)).first);
+ }
+}
+
+void tst_QSortFilterProxyModel::selectionFilteredOut()
+{
+ QStandardItemModel model(2, 1);
+ model.setData(model.index(0, 0), QString("AAA"));
+ model.setData(model.index(1, 0), QString("BBB"));
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ QTreeView view;
+
+ view.show();
+ view.setModel(&proxy);
+ QSignalSpy spy(view.selectionModel(), &QItemSelectionModel::currentChanged);
+ QVERIFY(spy.isValid());
+
+ view.setCurrentIndex(proxy.index(0, 0));
+ QCOMPARE(spy.count(), 1);
+
+ setupFilter(&proxy, QLatin1String("^B"));
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_QSortFilterProxyModel::match_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<int>("proxyStartRow");
+ QTest::addColumn<QString>("what");
+ QTest::addColumn<int>("matchFlags");
+ QTest::addColumn<IntList>("expectedProxyItems");
+ QTest::newRow("1")
+ << (QStringList() << "a") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "" // filter
+ << 0 // proxyStartRow
+ << "a" // what
+ << static_cast<int>(Qt::MatchExactly) // matchFlags
+ << (IntList() << 0); // expectedProxyItems
+ QTest::newRow("2")
+ << (QStringList() << "a" << "b") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "" // filter
+ << 0 // proxyStartRow
+ << "b" // what
+ << static_cast<int>(Qt::MatchExactly) // matchFlags
+ << (IntList() << 1); // expectedProxyItems
+ QTest::newRow("3")
+ << (QStringList() << "a" << "b") // sourceItems
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << "" // filter
+ << 0 // proxyStartRow
+ << "a" // what
+ << static_cast<int>(Qt::MatchExactly) // matchFlags
+ << (IntList() << 1); // expectedProxyItems
+ QTest::newRow("4")
+ << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "" // filter
+ << 1 // proxyStartRow
+ << "a" // what
+ << static_cast<int>(Qt::MatchExactly) // matchFlags
+ << IntList(); // expectedProxyItems
+ QTest::newRow("5")
+ << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "a|b" // filter
+ << 0 // proxyStartRow
+ << "c" // what
+ << static_cast<int>(Qt::MatchExactly) // matchFlags
+ << IntList(); // expectedProxyItems
+ QTest::newRow("6")
+ << (QStringList() << "b" << "d" << "a" << "c") // sourceItems
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << "a|b" // filter
+ << 0 // proxyStartRow
+ << "b" // what
+ << static_cast<int>(Qt::MatchExactly) // matchFlags
+ << (IntList() << 0); // expectedProxyItems
+}
+
+void tst_QSortFilterProxyModel::match()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(int, sortOrder);
+ QFETCH(QString, filter);
+ QFETCH(int, proxyStartRow);
+ QFETCH(QString, what);
+ QFETCH(int, matchFlags);
+ QFETCH(IntList, expectedProxyItems);
+
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+
+ proxy.setSourceModel(&model);
+ model.insertColumns(0, 1);
+ model.insertRows(0, sourceItems.count());
+
+ for (int i = 0; i < sourceItems.count(); ++i) {
+ QModelIndex index = model.index(i, 0, QModelIndex());
+ model.setData(index, sourceItems.at(i), Qt::DisplayRole);
+ }
+
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ setupFilter(&proxy, filter);
+
+ QModelIndex startIndex = proxy.index(proxyStartRow, 0);
+ QModelIndexList indexes = proxy.match(startIndex, Qt::DisplayRole, what,
+ expectedProxyItems.count(),
+ Qt::MatchFlags(matchFlags));
+ QCOMPARE(indexes.count(), expectedProxyItems.count());
+ for (int i = 0; i < indexes.count(); ++i)
+ QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i));
+}
+
+void tst_QSortFilterProxyModel::insertIntoChildrenlessItem()
+{
+ QStandardItemModel model;
+ QStandardItem *itemA = new QStandardItem("a");
+ model.appendRow(itemA);
+ QStandardItem *itemB = new QStandardItem("b");
+ model.appendRow(itemB);
+ QStandardItem *itemC = new QStandardItem("c");
+ model.appendRow(itemC);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QSignalSpy colsInsertedSpy(&proxy, &QSortFilterProxyModel::columnsInserted);
+ QSignalSpy rowsInsertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+
+ QVERIFY(colsInsertedSpy.isValid());
+ QVERIFY(rowsInsertedSpy.isValid());
+
+ (void)proxy.rowCount(QModelIndex()); // force mapping of "a", "b", "c"
+ QCOMPARE(colsInsertedSpy.count(), 0);
+ QCOMPARE(rowsInsertedSpy.count(), 0);
+
+ // now add a child to itemB ==> should get insert notification from the proxy
+ itemB->appendRow(new QStandardItem("a.0"));
+ QCOMPARE(colsInsertedSpy.count(), 1);
+ QCOMPARE(rowsInsertedSpy.count(), 1);
+
+ QVariantList args = colsInsertedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), proxy.mapFromSource(itemB->index()));
+ QCOMPARE(qvariant_cast<int>(args.at(1)), 0);
+ QCOMPARE(qvariant_cast<int>(args.at(2)), 0);
+
+ args = rowsInsertedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), proxy.mapFromSource(itemB->index()));
+ QCOMPARE(qvariant_cast<int>(args.at(1)), 0);
+ QCOMPARE(qvariant_cast<int>(args.at(2)), 0);
+}
+
+void tst_QSortFilterProxyModel::invalidateMappedChildren()
+{
+ QStandardItemModel model;
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QStandardItem *itemA = new QStandardItem("a");
+ model.appendRow(itemA);
+ QStandardItem *itemB = new QStandardItem("b");
+ itemA->appendRow(itemB);
+
+ QStandardItem *itemC = new QStandardItem("c");
+ itemB->appendRow(itemC);
+ itemC->appendRow(new QStandardItem("d"));
+
+ // force mappings
+ (void)proxy.hasChildren(QModelIndex());
+ (void)proxy.hasChildren(proxy.mapFromSource(itemA->index()));
+ (void)proxy.hasChildren(proxy.mapFromSource(itemB->index()));
+ (void)proxy.hasChildren(proxy.mapFromSource(itemC->index()));
+
+ itemB->removeRow(0); // should invalidate mapping of itemC
+ itemC = new QStandardItem("c");
+ itemA->appendRow(itemC);
+ itemC->appendRow(new QStandardItem("d"));
+
+ itemA->removeRow(1); // should invalidate mapping of itemC
+ itemC = new QStandardItem("c");
+ itemB->appendRow(itemC);
+ itemC->appendRow(new QStandardItem("d"));
+
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemA->index())), 1);
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemB->index())), 1);
+ QCOMPARE(proxy.rowCount(proxy.mapFromSource(itemC->index())), 1);
+}
+
+class EvenOddFilterModel : public QSortFilterProxyModel
+{
+public:
+ virtual bool filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const
+ {
+ if (srcParent.isValid())
+ return (srcParent.row() % 2) ^ !(srcRow % 2);
+ return (srcRow % 2);
+ }
+};
+
+void tst_QSortFilterProxyModel::insertRowIntoFilteredParent()
+{
+ QStandardItemModel model;
+ EvenOddFilterModel proxy;
+ proxy.setSourceModel(&model);
+
+ QSignalSpy spy(&proxy, &EvenOddFilterModel::rowsInserted);
+ QVERIFY(spy.isValid());
+
+ QStandardItem *itemA = new QStandardItem();
+ model.appendRow(itemA); // A will be filtered
+ QStandardItem *itemB = new QStandardItem();
+ itemA->appendRow(itemB);
+
+ QCOMPARE(spy.count(), 0);
+
+ itemA->removeRow(0);
+
+ QCOMPARE(spy.count(), 0);
+}
+
+void tst_QSortFilterProxyModel::filterOutParentAndFilterInChild()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ setupFilter(&proxy, QLatin1String("A|B"));
+
+ QStandardItem *itemA = new QStandardItem("A");
+ model.appendRow(itemA); // not filtered
+ QStandardItem *itemB = new QStandardItem("B");
+ itemA->appendRow(itemB); // not filtered
+ QStandardItem *itemC = new QStandardItem("C");
+ itemA->appendRow(itemC); // filtered
+
+ QSignalSpy removedSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy insertedSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+
+ QVERIFY(removedSpy.isValid());
+ QVERIFY(insertedSpy.isValid());
+
+ setupFilter(&proxy, QLatin1String("C")); // A and B will be filtered out, C filtered in
+
+ // we should now have been notified that the subtree represented by itemA has been removed
+ QCOMPARE(removedSpy.count(), 1);
+ // we should NOT get any inserts; itemC should be filtered because its parent (itemA) is
+ QCOMPARE(insertedSpy.count(), 0);
+}
+
+void tst_QSortFilterProxyModel::sourceInsertRows()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ model.insertColumns(0, 1, QModelIndex());
+ model.insertRows(0, 2, QModelIndex());
+
+ {
+ QModelIndex parent = model.index(0, 0, QModelIndex());
+ model.insertColumns(0, 1, parent);
+ model.insertRows(0, 1, parent);
+ }
+
+ {
+ QModelIndex parent = model.index(1, 0, QModelIndex());
+ model.insertColumns(0, 1, parent);
+ model.insertRows(0, 1, parent);
+ }
+
+ model.insertRows(0, 1, QModelIndex());
+ model.insertRows(0, 1, QModelIndex());
+
+ QVERIFY(true); // if you got here without asserting, it's all good
+}
+
+void tst_QSortFilterProxyModel::sourceModelDeletion()
+{
+ QSortFilterProxyModel proxyModel;
+ {
+ QStandardItemModel model;
+ proxyModel.setSourceModel(&model);
+ QCOMPARE(proxyModel.sourceModel(), static_cast<QAbstractItemModel*>(&model));
+ }
+ QCOMPARE(proxyModel.sourceModel(), static_cast<QAbstractItemModel*>(0));
+}
+
+void tst_QSortFilterProxyModel::sortColumnTracking1()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ model.insertColumns(0, 10);
+ model.insertRows(0, 10);
+
+ proxyModel.sort(1);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.insertColumn(8);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.removeColumn(8);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.insertColumn(2);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.removeColumn(2);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.insertColumn(1);
+ QCOMPARE(proxyModel.sortColumn(), 2);
+
+ model.removeColumn(1);
+ QCOMPARE(proxyModel.sortColumn(), 1);
+
+ model.removeColumn(1);
+ QCOMPARE(proxyModel.sortColumn(), -1);
+}
+
+void tst_QSortFilterProxyModel::sortColumnTracking2()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setDynamicSortFilter(true);
+ proxyModel.setSourceModel(&model);
+
+ proxyModel.sort(0);
+ QCOMPARE(proxyModel.sortColumn(), 0);
+
+ QList<QStandardItem *> items; // Stable sorting: Items with invalid data should move to the end
+ items << new QStandardItem << new QStandardItem("foo") << new QStandardItem("bar")
+ << new QStandardItem("some") << new QStandardItem("others") << new QStandardItem("item")
+ << new QStandardItem("aa") << new QStandardItem("zz") << new QStandardItem;
+
+ model.insertColumn(0,items);
+ QCOMPARE(proxyModel.sortColumn(), 0);
+ QCOMPARE(proxyModel.data(proxyModel.index(0,0)).toString(),QString::fromLatin1("aa"));
+ const int zzIndex = items.count() - 3; // 2 invalid at end.
+ QCOMPARE(proxyModel.data(proxyModel.index(zzIndex,0)).toString(),QString::fromLatin1("zz"));
+}
+
+void tst_QSortFilterProxyModel::sortStable()
+{
+ QStandardItemModel* model = new QStandardItemModel(5, 2);
+ for (int r = 0; r < 5; r++) {
+ const QString prefix = QLatin1String("Row:") + QString::number(r) + QLatin1String(", Column:");
+ for (int c = 0; c < 2; c++) {
+ QStandardItem* item = new QStandardItem(prefix + QString::number(c));
+ for (int i = 0; i < 3; i++) {
+ QStandardItem* child = new QStandardItem(QLatin1String("Item ") + QString::number(i));
+ item->appendRow( child );
+ }
+ model->setItem(r, c, item);
+ }
+ }
+ model->setHorizontalHeaderItem( 0, new QStandardItem( "Name" ));
+ model->setHorizontalHeaderItem( 1, new QStandardItem( "Value" ));
+
+ QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(model);
+ filterModel->setSourceModel(model);
+
+ QTreeView *view = new QTreeView;
+ view->setModel(filterModel);
+ QModelIndex firstRoot = filterModel->index(0,0);
+ view->expand(firstRoot);
+ view->setSortingEnabled(true);
+
+ view->model()->sort(1, Qt::DescendingOrder);
+ QVariant lastItemData =filterModel->index(2,0, firstRoot).data();
+ view->model()->sort(1, Qt::DescendingOrder);
+ QCOMPARE(lastItemData, filterModel->index(2,0, firstRoot).data());
+}
+
+void tst_QSortFilterProxyModel::hiddenColumns()
+{
+ class MyStandardItemModel : public QStandardItemModel
+ {
+ public:
+ MyStandardItemModel() : QStandardItemModel(0,5) {}
+ void reset()
+ { beginResetModel(); endResetModel(); }
+ friend class tst_QSortFilterProxyModel;
+ } model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+
+ QTableView view;
+ view.setModel(&proxy);
+
+ view.hideColumn(0);
+
+ QVERIFY(view.isColumnHidden(0));
+ model.blockSignals(true);
+ model.setRowCount(1);
+ model.blockSignals(false);
+ model.reset();
+
+ // In the initial bug report that spawned this test, this would be false
+ // because resetting model would also reset the hidden columns.
+ QVERIFY(view.isColumnHidden(0));
+}
+
+void tst_QSortFilterProxyModel::insertRowsSort()
+{
+ QStandardItemModel model(2,2);
+ QSortFilterProxyModel proxyModel;
+ proxyModel.setSourceModel(&model);
+
+ proxyModel.sort(0);
+ QCOMPARE(proxyModel.sortColumn(), 0);
+
+ model.insertColumns(0, 3, model.index(0,0));
+ QCOMPARE(proxyModel.sortColumn(), 0);
+
+ model.removeColumns(0, 3, model.index(0,0));
+ QCOMPARE(proxyModel.sortColumn(), 0);
+}
+
+void tst_QSortFilterProxyModel::staticSorting()
+{
+ QStandardItemModel model(0, 1);
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setDynamicSortFilter(false);
+ QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(QLatin1Char(' '));
+
+ // prepare model
+ QStandardItem *root = model.invisibleRootItem ();
+ QList<QStandardItem *> items;
+ for (int i = 0; i < initial.count(); ++i) {
+ items.append(new QStandardItem(initial.at(i)));
+ }
+ root->insertRows(0, items);
+ QCOMPARE(model.rowCount(QModelIndex()), initial.count());
+ QCOMPARE(model.columnCount(QModelIndex()), 1);
+
+ // make sure the proxy is unsorted
+ QCOMPARE(proxy.columnCount(QModelIndex()), 1);
+ QCOMPARE(proxy.rowCount(QModelIndex()), initial.count());
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+
+ // sort
+ proxy.sort(0);
+
+ QStringList expected = initial;
+ expected.sort();
+ // make sure the proxy is sorted
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ //update one item.
+ items.first()->setData("girafe", Qt::DisplayRole);
+
+ // make sure the proxy is updated but not sorted
+ expected.replaceInStrings("bateau", "girafe");
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ // sort again
+ proxy.sort(0);
+ expected.sort();
+
+ // make sure the proxy is sorted
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+void tst_QSortFilterProxyModel::dynamicSorting()
+{
+ QStringListModel model1;
+ const QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(QLatin1Char(' '));
+ model1.setStringList(initial);
+ QSortFilterProxyModel proxy1;
+ proxy1.setDynamicSortFilter(false);
+ proxy1.sort(0);
+ proxy1.setSourceModel(&model1);
+
+ QCOMPARE(proxy1.columnCount(QModelIndex()), 1);
+ //the model should not be sorted because sorting has not been set to dynamic yet.
+ QCOMPARE(proxy1.rowCount(QModelIndex()), initial.count());
+ for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy1.index(row, 0, QModelIndex());
+ QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), initial.at(row));
+ }
+
+ proxy1.setDynamicSortFilter(true);
+
+ //now the model should be sorted.
+ QStringList expected = initial;
+ expected.sort();
+ for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy1.index(row, 0, QModelIndex());
+ QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ QStringList initial2 = initial;
+ initial2.replaceInStrings("bateau", "girafe");
+ model1.setStringList(initial2); //this will cause a reset
+
+ QStringList expected2 = initial2;
+ expected2.sort();
+
+ //now the model should still be sorted.
+ for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy1.index(row, 0, QModelIndex());
+ QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected2.at(row));
+ }
+
+ QStringListModel model2(initial);
+ proxy1.setSourceModel(&model2);
+
+ //the model should again be sorted
+ for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy1.index(row, 0, QModelIndex());
+ QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+
+ //set up the sorting before seting the model up
+ QSortFilterProxyModel proxy2;
+ proxy2.sort(0);
+ proxy2.setSourceModel(&model2);
+ for (int row = 0; row < proxy2.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy2.index(row, 0, QModelIndex());
+ QCOMPARE(proxy2.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+class QtTestModel: public QAbstractItemModel
+{
+public:
+ QtTestModel(int _rows, int _cols, QObject *parent = 0)
+ : QAbstractItemModel(parent)
+ , rows(_rows)
+ , cols(_cols)
+ , wrongIndex(false)
+ {
+ }
+
+ bool canFetchMore(const QModelIndex &idx) const
+ {
+ return !fetched.contains(idx);
+ }
+
+ void fetchMore(const QModelIndex &idx)
+ {
+ if (fetched.contains(idx))
+ return;
+ beginInsertRows(idx, 0, rows-1);
+ fetched.insert(idx);
+ endInsertRows();
+ }
+
+ bool hasChildren(const QModelIndex & = QModelIndex()) const
+ {
+ return true;
+ }
+
+ int rowCount(const QModelIndex& parent = QModelIndex()) const
+ {
+ return fetched.contains(parent) ? rows : 0;
+ }
+
+ int columnCount(const QModelIndex& parent = QModelIndex()) const
+ {
+ Q_UNUSED(parent);
+ return cols;
+ }
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
+ {
+ if (row < 0 || column < 0 || column >= cols || row >= rows) {
+ return QModelIndex();
+ }
+ QModelIndex i = createIndex(row, column, int(parent.internalId() + 1));
+ parentHash[i] = parent;
+ return i;
+ }
+
+ QModelIndex parent(const QModelIndex &index) const
+ {
+ if (!parentHash.contains(index))
+ return QModelIndex();
+ return parentHash[index];
+ }
+
+ QVariant data(const QModelIndex &idx, int role) const
+ {
+ if (!idx.isValid())
+ return QVariant();
+
+ if (role == Qt::DisplayRole) {
+ if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
+ wrongIndex = true;
+ qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(),
+ idx.internalPointer());
+ }
+ return QLatin1Char('[') + QString::number(idx.row()) + QLatin1Char(',')
+ + QString::number(idx.column()) + QLatin1Char(']');
+ }
+ return QVariant();
+ }
+
+ QSet<QModelIndex> fetched;
+ int rows, cols;
+ mutable bool wrongIndex;
+ mutable QMap<QModelIndex,QModelIndex> parentHash;
+};
+
+void tst_QSortFilterProxyModel::fetchMore()
+{
+ QtTestModel model(10,10);
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ QVERIFY(proxy.canFetchMore(QModelIndex()));
+ QVERIFY(proxy.hasChildren());
+ while (proxy.canFetchMore(QModelIndex()))
+ proxy.fetchMore(QModelIndex());
+ QCOMPARE(proxy.rowCount(), 10);
+ QCOMPARE(proxy.columnCount(), 10);
+
+ QModelIndex idx = proxy.index(1,1);
+ QVERIFY(idx.isValid());
+ QVERIFY(proxy.canFetchMore(idx));
+ QVERIFY(proxy.hasChildren(idx));
+ while (proxy.canFetchMore(idx))
+ proxy.fetchMore(idx);
+ QCOMPARE(proxy.rowCount(idx), 10);
+ QCOMPARE(proxy.columnCount(idx), 10);
+}
+
+void tst_QSortFilterProxyModel::hiddenChildren()
+{
+ QStandardItemModel model;
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model);
+ proxy.setDynamicSortFilter(true);
+
+ QStandardItem *itemA = new QStandardItem("A VISIBLE");
+ model.appendRow(itemA);
+ QStandardItem *itemB = new QStandardItem("B VISIBLE");
+ itemA->appendRow(itemB);
+ QStandardItem *itemC = new QStandardItem("C");
+ itemA->appendRow(itemC);
+ setupFilter(&proxy, QLatin1String("VISIBLE"));
+
+ QCOMPARE(proxy.rowCount(QModelIndex()) , 1);
+ QPersistentModelIndex indexA = proxy.index(0,0);
+ QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("A VISIBLE"));
+
+ QCOMPARE(proxy.rowCount(indexA) , 1);
+ QPersistentModelIndex indexB = proxy.index(0, 0, indexA);
+ QCOMPARE(proxy.data(indexB).toString(), QString::fromLatin1("B VISIBLE"));
+
+ itemA->setText("A");
+ QCOMPARE(proxy.rowCount(QModelIndex()), 0);
+ QVERIFY(!indexA.isValid());
+ QVERIFY(!indexB.isValid());
+
+ itemB->setText("B");
+ itemA->setText("A VISIBLE");
+ itemC->setText("C VISIBLE");
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), 1);
+ indexA = proxy.index(0,0);
+ QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("A VISIBLE"));
+
+ QCOMPARE(proxy.rowCount(indexA) , 1);
+ QModelIndex indexC = proxy.index(0, 0, indexA);
+ QCOMPARE(proxy.data(indexC).toString(), QString::fromLatin1("C VISIBLE"));
+
+ setupFilter(&proxy, QLatin1String("C"));
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), 0);
+ itemC->setText("invisible");
+ itemA->setText("AC");
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), 1);
+ indexA = proxy.index(0,0);
+ QCOMPARE(proxy.data(indexA).toString(), QString::fromLatin1("AC"));
+ QCOMPARE(proxy.rowCount(indexA) , 0);
+}
+
+void tst_QSortFilterProxyModel::mapFromToSource()
+{
+ QtTestModel source(10,10);
+ source.fetchMore(QModelIndex());
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&source);
+ QCOMPARE(proxy.mapFromSource(source.index(5, 4)), proxy.index(5, 4));
+ QCOMPARE(proxy.mapToSource(proxy.index(3, 2)), source.index(3, 2));
+ QCOMPARE(proxy.mapFromSource(QModelIndex()), QModelIndex());
+ QCOMPARE(proxy.mapToSource(QModelIndex()), QModelIndex());
+
+#ifdef QT_NO_DEBUG //if Qt is compiled in debug mode, this will assert
+ QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapToSource");
+ QCOMPARE(proxy.mapToSource(source.index(2, 3)), QModelIndex());
+ QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapFromSource");
+ QCOMPARE(proxy.mapFromSource(proxy.index(6, 2)), QModelIndex());
+#endif
+}
+
+static QStandardItem *addEntry(QStandardItem* pParent, const QString &description)
+{
+ QStandardItem* pItem = new QStandardItem(description);
+ pParent->appendRow(pItem);
+ return pItem;
+}
+
+void tst_QSortFilterProxyModel::removeRowsRecursive()
+{
+ QStandardItemModel pModel;
+ QStandardItem *pItem1 = new QStandardItem("root");
+ pModel.appendRow(pItem1);
+ QList<QStandardItem *> items;
+
+ QStandardItem *pItem11 = addEntry(pItem1,"Sub-heading");
+ items << pItem11;
+ QStandardItem *pItem111 = addEntry(pItem11,"A");
+ items << pItem111;
+ items << addEntry(pItem111,"A1");
+ items << addEntry(pItem111,"A2");
+ QStandardItem *pItem112 = addEntry(pItem11,"B");
+ items << pItem112;
+ items << addEntry(pItem112,"B1");
+ items << addEntry(pItem112,"B2");
+ QStandardItem *pItem1123 = addEntry(pItem112,"B3");
+ items << pItem1123;
+ items << addEntry(pItem1123,"B3-");
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&pModel);
+
+ QList<QPersistentModelIndex> sourceIndexes;
+ QList<QPersistentModelIndex> proxyIndexes;
+ foreach (QStandardItem *item, items) {
+ QModelIndex idx = item->index();
+ sourceIndexes << idx;
+ proxyIndexes << proxy.mapFromSource(idx);
+ }
+
+ foreach (const QPersistentModelIndex &pidx, sourceIndexes)
+ QVERIFY(pidx.isValid());
+ foreach (const QPersistentModelIndex &pidx, proxyIndexes)
+ QVERIFY(pidx.isValid());
+
+ QList<QStandardItem*> itemRow = pItem1->takeRow(0);
+
+ QCOMPARE(itemRow.count(), 1);
+ QCOMPARE(itemRow.first(), pItem11);
+
+ foreach (const QPersistentModelIndex &pidx, sourceIndexes)
+ QVERIFY(!pidx.isValid());
+ foreach (const QPersistentModelIndex &pidx, proxyIndexes)
+ QVERIFY(!pidx.isValid());
+
+ delete pItem11;
+}
+
+void tst_QSortFilterProxyModel::doubleProxySelectionSetSourceModel()
+{
+ QStandardItemModel *model1 = new QStandardItemModel;
+ QStandardItem *parentItem = model1->invisibleRootItem();
+ for (int i = 0; i < 4; ++i) {
+ QStandardItem *item = new QStandardItem(QLatin1String("model1 item ") + QString::number(i));
+ parentItem->appendRow(item);
+ parentItem = item;
+ }
+
+ QStandardItemModel *model2 = new QStandardItemModel;
+ QStandardItem *parentItem2 = model2->invisibleRootItem();
+ for (int i = 0; i < 4; ++i) {
+ QStandardItem *item = new QStandardItem(QLatin1String("model2 item ") + QString::number(i));
+ parentItem2->appendRow(item);
+ parentItem2 = item;
+ }
+
+ QSortFilterProxyModel *toggleProxy = new QSortFilterProxyModel;
+ toggleProxy->setSourceModel(model1);
+
+ QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel;
+ proxyModel->setSourceModel(toggleProxy);
+
+ QModelIndex mi = proxyModel->index(0, 0, proxyModel->index(0, 0, proxyModel->index(0, 0)));
+ QItemSelectionModel ism(proxyModel);
+ ism.select(mi, QItemSelectionModel::Select);
+ QModelIndexList mil = ism.selectedIndexes();
+ QCOMPARE(mil.count(), 1);
+ QCOMPARE(mil.first(), mi);
+
+ toggleProxy->setSourceModel(model2);
+ // No crash, it's good news!
+ QVERIFY(ism.selection().isEmpty());
+}
+
+void tst_QSortFilterProxyModel::appearsAndSort()
+{
+ class PModel : public QSortFilterProxyModel
+ {
+ public:
+ PModel() : mVisible(false) {};
+ protected:
+ bool filterAcceptsRow(int, const QModelIndex &) const
+ {
+ return mVisible;
+ }
+
+ public:
+ void updateXX()
+ {
+ mVisible = true;
+ invalidate();
+ }
+ private:
+ bool mVisible;
+ } proxyModel;
+
+ QStringListModel sourceModel;
+ QStringList list;
+ list << "b" << "a" << "c";
+ sourceModel.setStringList(list);
+
+ proxyModel.setSourceModel(&sourceModel);
+ proxyModel.setDynamicSortFilter(true);
+ proxyModel.sort(0, Qt::AscendingOrder);
+
+ QApplication::processEvents();
+ QCOMPARE(sourceModel.rowCount(), 3);
+ QCOMPARE(proxyModel.rowCount(), 0); //all rows are hidden at first;
+
+ QSignalSpy spyAbout1(&proxyModel, &PModel::layoutAboutToBeChanged);
+ QSignalSpy spyChanged1(&proxyModel, &PModel::layoutChanged);
+
+ QVERIFY(spyAbout1.isValid());
+ QVERIFY(spyChanged1.isValid());
+
+ //introducing secondProxyModel to test the layoutChange when many items appears at once
+ QSortFilterProxyModel secondProxyModel;
+ secondProxyModel.setSourceModel(&proxyModel);
+ secondProxyModel.setDynamicSortFilter(true);
+ secondProxyModel.sort(0, Qt::DescendingOrder);
+ QCOMPARE(secondProxyModel.rowCount(), 0); //all rows are hidden at first;
+ QSignalSpy spyAbout2(&secondProxyModel, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy spyChanged2(&secondProxyModel, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(spyAbout2.isValid());
+ QVERIFY(spyChanged2.isValid());
+
+ proxyModel.updateXX();
+ QApplication::processEvents();
+ //now rows should be visible, and sorted
+ QCOMPARE(proxyModel.rowCount(), 3);
+ QCOMPARE(proxyModel.data(proxyModel.index(0,0), Qt::DisplayRole).toString(), QString::fromLatin1("a"));
+ QCOMPARE(proxyModel.data(proxyModel.index(1,0), Qt::DisplayRole).toString(), QString::fromLatin1("b"));
+ QCOMPARE(proxyModel.data(proxyModel.index(2,0), Qt::DisplayRole).toString(), QString::fromLatin1("c"));
+
+ //now rows should be visible, and sorted
+ QCOMPARE(secondProxyModel.rowCount(), 3);
+ QCOMPARE(secondProxyModel.data(secondProxyModel.index(0,0), Qt::DisplayRole).toString(), QString::fromLatin1("c"));
+ QCOMPARE(secondProxyModel.data(secondProxyModel.index(1,0), Qt::DisplayRole).toString(), QString::fromLatin1("b"));
+ QCOMPARE(secondProxyModel.data(secondProxyModel.index(2,0), Qt::DisplayRole).toString(), QString::fromLatin1("a"));
+
+ QCOMPARE(spyAbout1.count(), 1);
+ QCOMPARE(spyChanged1.count(), 1);
+ QCOMPARE(spyAbout2.count(), 1);
+ QCOMPARE(spyChanged2.count(), 1);
+}
+
+void tst_QSortFilterProxyModel::unnecessaryDynamicSorting()
+{
+ QStringListModel model;
+ const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
+ model.setStringList(initial);
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(false);
+ proxy.setSourceModel(&model);
+ proxy.sort(Qt::AscendingOrder);
+
+ //append two rows
+ int maxrows = proxy.rowCount(QModelIndex());
+ model.insertRows(maxrows, 2);
+ model.setData(model.index(maxrows, 0), QString("alpha"));
+ model.setData(model.index(maxrows + 1, 0), QString("fondue"));
+
+ //append new items to the initial string list and compare with model
+ QStringList expected = initial;
+ expected << QString("alpha") << QString("fondue");
+
+ //if bug 7716 is present, new rows were prepended, when they should have been appended
+ for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) {
+ QModelIndex index = proxy.index(row, 0, QModelIndex());
+ QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row));
+ }
+}
+
+class SelectionProxyModel : QAbstractProxyModel
+{
+ Q_OBJECT
+public:
+ SelectionProxyModel()
+ : QAbstractProxyModel(), selectionModel(0)
+ {
+ }
+
+ QModelIndex mapFromSource(QModelIndex const&) const
+ { return QModelIndex(); }
+
+ QModelIndex mapToSource(QModelIndex const&) const
+ { return QModelIndex(); }
+
+ QModelIndex index(int, int, const QModelIndex&) const
+ { return QModelIndex(); }
+
+ QModelIndex parent(const QModelIndex&) const
+ { return QModelIndex(); }
+
+ int rowCount(const QModelIndex&) const
+ { return 0; }
+
+ int columnCount(const QModelIndex&) const
+ { return 0; }
+
+ void setSourceModel( QAbstractItemModel *sourceModel )
+ {
+ beginResetModel();
+ disconnect( sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) );
+ QAbstractProxyModel::setSourceModel( sourceModel );
+ connect( sourceModel, SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()) );
+ endResetModel();
+ }
+
+ void setSelectionModel( QItemSelectionModel *_selectionModel )
+ {
+ selectionModel = _selectionModel;
+ }
+
+private slots:
+ void sourceModelAboutToBeReset()
+ {
+ QVERIFY( selectionModel->selectedIndexes().size() == 1 );
+ beginResetModel();
+ }
+
+ void sourceModelReset()
+ {
+ endResetModel();
+ }
+
+private:
+ QItemSelectionModel *selectionModel;
+};
+
+void tst_QSortFilterProxyModel::testMultipleProxiesWithSelection()
+{
+ QStringListModel model;
+ const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
+ model.setStringList(initial);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel( &model );
+
+ SelectionProxyModel proxy1;
+ QSortFilterProxyModel proxy2;
+
+ // Note that the order here matters. The order of the sourceAboutToBeReset
+ // exposes the bug in QSortFilterProxyModel.
+ proxy2.setSourceModel( &proxy );
+ proxy1.setSourceModel( &proxy );
+
+ QItemSelectionModel selectionModel(&proxy2);
+ proxy1.setSelectionModel( &selectionModel );
+
+ selectionModel.select( proxy2.index( 0, 0 ), QItemSelectionModel::Select );
+
+ // trick the proxy into emitting begin/end reset signals.
+ proxy.setSourceModel(0);
+}
+
+static bool isValid(const QItemSelection &selection)
+{
+ foreach (const QItemSelectionRange &range, selection)
+ if (!range.isValid())
+ return false;
+ return true;
+}
+
+void tst_QSortFilterProxyModel::mapSelectionFromSource()
+{
+ QStringListModel model;
+ const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
+ model.setStringList(initial);
+
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+ setupFilter(&proxy, QLatin1String("d.*"));
+
+ proxy.setSourceModel(&model);
+
+ // Only "delta" remains.
+ QCOMPARE(proxy.rowCount(), 1);
+
+ QItemSelection selection;
+ QModelIndex charlie = model.index(1, 0);
+ selection.append(QItemSelectionRange(charlie, charlie));
+ QModelIndex delta = model.index(2, 0);
+ selection.append(QItemSelectionRange(delta, delta));
+ QModelIndex echo = model.index(3, 0);
+ selection.append(QItemSelectionRange(echo, echo));
+
+ QVERIFY(isValid(selection));
+
+ QItemSelection proxiedSelection = proxy.mapSelectionFromSource(selection);
+
+ // Only "delta" is in the mapped result.
+ QCOMPARE(proxiedSelection.size(), 1);
+ QVERIFY(isValid(proxiedSelection));
+}
+
+class Model10287 : public QStandardItemModel
+{
+ Q_OBJECT
+
+public:
+ Model10287(QObject *parent = 0)
+ : QStandardItemModel(0, 1, parent)
+ {
+ parentItem = new QStandardItem("parent");
+ parentItem->setData(false, Qt::UserRole);
+ appendRow(parentItem);
+
+ childItem = new QStandardItem("child");
+ childItem->setData(true, Qt::UserRole);
+ parentItem->appendRow(childItem);
+
+ childItem2 = new QStandardItem("child2");
+ childItem2->setData(true, Qt::UserRole);
+ parentItem->appendRow(childItem2);
+ }
+
+ void removeChild()
+ {
+ childItem2->setData(false, Qt::UserRole);
+ parentItem->removeRow(0);
+ }
+
+private:
+ QStandardItem *parentItem, *childItem, *childItem2;
+};
+
+class Proxy10287 : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+public:
+ Proxy10287(QAbstractItemModel *model, QObject *parent = 0)
+ : QSortFilterProxyModel(parent)
+ {
+ setSourceModel(model);
+ setDynamicSortFilter(true);
+ }
+
+protected:
+ virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
+ {
+ // Filter based on UserRole in model
+ QModelIndex i = sourceModel()->index(source_row, 0, source_parent);
+ return i.data(Qt::UserRole).toBool();
+ }
+};
+
+void tst_QSortFilterProxyModel::unnecessaryMapCreation()
+{
+ Model10287 m;
+ Proxy10287 p(&m);
+ m.removeChild();
+ // No assert failure, it passes.
+}
+
+class FilteredColumnProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ FilteredColumnProxyModel(QObject *parent = 0)
+ : QSortFilterProxyModel(parent)
+ {
+ }
+
+protected:
+ bool filterAcceptsColumn(int column, const QModelIndex & /* source_parent */) const
+ {
+ return column % 2 != 0;
+ }
+};
+
+void tst_QSortFilterProxyModel::filteredColumns()
+{
+ DynamicTreeModel *model = new DynamicTreeModel(this);
+
+ FilteredColumnProxyModel *proxy = new FilteredColumnProxyModel(this);
+ proxy->setSourceModel(model);
+
+ new QAbstractItemModelTester(proxy, this);
+
+ ModelInsertCommand *insertCommand = new ModelInsertCommand(model, this);
+ insertCommand->setNumCols(2);
+ insertCommand->setStartRow(0);
+ insertCommand->setEndRow(0);
+ // Parent is QModelIndex()
+ insertCommand->doCommand();
+}
+
+class ChangableHeaderData : public QStringListModel
+{
+ Q_OBJECT
+public:
+ explicit ChangableHeaderData(QObject *parent = 0)
+ : QStringListModel(parent)
+ {
+
+ }
+
+ void emitHeaderDataChanged()
+ {
+ headerDataChanged(Qt::Vertical, 0, rowCount() - 1);
+ }
+};
+
+
+void tst_QSortFilterProxyModel::headerDataChanged()
+{
+ ChangableHeaderData *model = new ChangableHeaderData(this);
+
+ QStringList numbers;
+ for (int i = 0; i < 10; ++i)
+ numbers.append(QString::number(i));
+ model->setStringList(numbers);
+
+ QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
+ proxy->setSourceModel(model);
+
+ new QAbstractItemModelTester(proxy, this);
+
+ model->emitHeaderDataChanged();
+}
+
+void tst_QSortFilterProxyModel::resetInvalidate_data()
+{
+ QTest::addColumn<int>("test");
+ QTest::addColumn<bool>("works");
+
+ QTest::newRow("nothing") << 0 << false;
+ QTest::newRow("reset") << 1 << true;
+ QTest::newRow("invalidate") << 2 << true;
+ QTest::newRow("invalidate_filter") << 3 << true;
+}
+
+void tst_QSortFilterProxyModel::resetInvalidate()
+{
+ QFETCH(int, test);
+ QFETCH(bool, works);
+
+ struct Proxy : QSortFilterProxyModel {
+ QString pattern;
+ virtual bool filterAcceptsRow(int source_row, const QModelIndex&) const
+ {
+ return sourceModel()->data(sourceModel()->index(source_row, 0)).toString().contains(pattern);
+ }
+ void notifyChange(int test)
+ {
+ switch (test) {
+ case 0: break;
+ case 1:
+ beginResetModel();
+ endResetModel();
+ break;
+ case 2: invalidate(); break;
+ case 3: invalidateFilter(); break;
+ }
+ }
+ };
+
+ QStringListModel sourceModel(QStringList() << "Poisson" << "Vache" << "Brebis"
+ << "Elephant" << "Cochon" << "Serpent"
+ << "Mouton" << "Ecureuil" << "Mouche");
+ Proxy proxy;
+ proxy.pattern = QString::fromLatin1("n");
+ proxy.setSourceModel(&sourceModel);
+
+ QCOMPARE(proxy.rowCount(), 5);
+ for (int i = 0; i < proxy.rowCount(); i++) {
+ QVERIFY(proxy.data(proxy.index(i,0)).toString().contains('n'));
+ }
+
+ proxy.pattern = QString::fromLatin1("o");
+ proxy.notifyChange(test);
+
+ QCOMPARE(proxy.rowCount(), works ? 4 : 5);
+ bool ok = true;
+ for (int i = 0; i < proxy.rowCount(); i++) {
+ if (!proxy.data(proxy.index(i,0)).toString().contains('o'))
+ ok = false;
+ }
+ QCOMPARE(ok, works);
+}
+
+/**
+ * A proxy which changes the background color for items ending in 'y' or 'r'
+ */
+class CustomDataProxy : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+public:
+ CustomDataProxy(QObject *parent = 0)
+ : QSortFilterProxyModel(parent)
+ {
+ setDynamicSortFilter(true);
+ }
+
+ void setSourceModel(QAbstractItemModel *sourceModel)
+ {
+ // It would be possible to use only the modelReset signal of the source model to clear
+ // the data in *this, however, this requires that the slot is connected
+ // before QSortFilterProxyModel::setSourceModel is called, and even then depends
+ // on the order of invocation of slots being the same as the order of connection.
+ // ie, not reliable.
+// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
+ QSortFilterProxyModel::setSourceModel(sourceModel);
+ // Making the connect after the setSourceModel call clears the data too late.
+// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
+
+ // This could be done in data(), but the point is to need to cache something in the proxy
+ // which needs to be cleared on reset.
+ for (int i = 0; i < sourceModel->rowCount(); ++i)
+ {
+ if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('y')))
+ {
+ m_backgroundColours.insert(i, Qt::blue);
+ } else if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('r')))
+ {
+ m_backgroundColours.insert(i, Qt::red);
+ }
+ }
+ }
+
+ QVariant data(const QModelIndex &index, int role) const
+ {
+ if (role != Qt::BackgroundRole)
+ return QSortFilterProxyModel::data(index, role);
+ return m_backgroundColours.value(index.row());
+ }
+
+private slots:
+ void resetInternalData()
+ {
+ m_backgroundColours.clear();
+ }
+
+private:
+ QHash<int, QColor> m_backgroundColours;
+};
+
+class ModelObserver : public QObject
+{
+ Q_OBJECT
+public:
+ ModelObserver(QAbstractItemModel *model, QObject *parent = 0)
+ : QObject(parent), m_model(model)
+ {
+ connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToBeReset()));
+ connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
+ }
+
+public slots:
+ void modelAboutToBeReset()
+ {
+ int reds = 0, blues = 0;
+ for (int i = 0; i < m_model->rowCount(); ++i)
+ {
+ QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
+ if (color == Qt::blue)
+ ++blues;
+ if (color == Qt::red)
+ ++reds;
+ }
+ QCOMPARE(blues, 11);
+ QCOMPARE(reds, 4);
+ }
+
+ void modelReset()
+ {
+ int reds = 0, blues = 0;
+ for (int i = 0; i < m_model->rowCount(); ++i)
+ {
+ QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
+ if (color == Qt::blue)
+ ++blues;
+ if (color == Qt::red)
+ ++reds;
+ }
+ QCOMPARE(reds, 0);
+ QCOMPARE(blues, 0);
+ }
+
+private:
+ QAbstractItemModel * const m_model;
+
+};
+
+void tst_QSortFilterProxyModel::testResetInternalData()
+{
+
+ QStringListModel model(QStringList() << "Monday"
+ << "Tuesday"
+ << "Wednesday"
+ << "Thursday"
+ << "Friday"
+ << "January"
+ << "February"
+ << "March"
+ << "April"
+ << "May"
+ << "Saturday"
+ << "June"
+ << "Sunday"
+ << "July"
+ << "August"
+ << "September"
+ << "October"
+ << "November"
+ << "December");
+
+ CustomDataProxy proxy;
+ proxy.setSourceModel(&model);
+
+ ModelObserver observer(&proxy);
+
+ // Cause the source model to reset.
+ model.setStringList(QStringList() << "Spam" << "Eggs");
+
+}
+
+void tst_QSortFilterProxyModel::testParentLayoutChanged()
+{
+ QStandardItemModel model;
+ QStandardItem *parentItem = model.invisibleRootItem();
+ for (int i = 0; i < 4; ++i) {
+ {
+ QStandardItem *item = new QStandardItem(QLatin1String("item ") + QString::number(i));
+ parentItem->appendRow(item);
+ }
+ {
+ QStandardItem *item = new QStandardItem(QLatin1String("item 1") + QString::number(i));
+ parentItem->appendRow(item);
+ parentItem = item;
+ }
+ }
+ // item 0
+ // item 10
+ // - item 1
+ // - item 11
+ // - item 2
+ // - item 12
+ // ...
+
+ QSortFilterProxyModel proxy;
+ proxy.sort(0, Qt::AscendingOrder);
+ proxy.setDynamicSortFilter(true);
+
+ proxy.setSourceModel(&model);
+ proxy.setObjectName("proxy");
+
+ // When Proxy1 emits layoutChanged(QList<QPersistentModelIndex>) this
+ // one will too, with mapped indexes.
+ QSortFilterProxyModel proxy2;
+ proxy2.sort(0, Qt::AscendingOrder);
+ proxy2.setDynamicSortFilter(true);
+
+ proxy2.setSourceModel(&proxy);
+ proxy2.setObjectName("proxy2");
+
+ QSignalSpy dataChangedSpy(&model, &QSortFilterProxyModel::dataChanged);
+
+ QVERIFY(dataChangedSpy.isValid());
+
+ // Verify that the no-arg signal is still emitted.
+ QSignalSpy layoutAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(layoutAboutToBeChangedSpy.isValid());
+ QVERIFY(layoutChangedSpy.isValid());
+
+ QSignalSpy parentsAboutToBeChangedSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy parentsChangedSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(parentsAboutToBeChangedSpy.isValid());
+ QVERIFY(parentsChangedSpy.isValid());
+
+ QSignalSpy proxy2ParentsAboutToBeChangedSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy proxy2ParentsChangedSpy(&proxy2, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(proxy2ParentsAboutToBeChangedSpy.isValid());
+ QVERIFY(proxy2ParentsChangedSpy.isValid());
+
+ QStandardItem *item = model.invisibleRootItem()->child(1)->child(1);
+ QCOMPARE(item->text(), QStringLiteral("item 11"));
+
+ // Ensure mapped:
+ proxy.mapFromSource(model.indexFromItem(item));
+
+ item->setText("Changed");
+
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+ QCOMPARE(parentsAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(parentsChangedSpy.size(), 1);
+ QCOMPARE(proxy2ParentsAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(proxy2ParentsChangedSpy.size(), 1);
+
+ QVariantList beforeSignal = parentsAboutToBeChangedSpy.first();
+ QVariantList afterSignal = parentsChangedSpy.first();
+
+ QCOMPARE(beforeSignal.size(), 2);
+ QCOMPARE(afterSignal.size(), 2);
+
+ QList<QPersistentModelIndex> beforeParents = beforeSignal.first().value<QList<QPersistentModelIndex> >();
+ QList<QPersistentModelIndex> afterParents = afterSignal.first().value<QList<QPersistentModelIndex> >();
+
+ QCOMPARE(beforeParents.size(), 1);
+ QCOMPARE(afterParents.size(), 1);
+
+ QVERIFY(beforeParents.first().isValid());
+ QVERIFY(beforeParents.first() == afterParents.first());
+
+ QVERIFY(beforeParents.first() == proxy.mapFromSource(model.indexFromItem(model.invisibleRootItem()->child(1))));
+
+ QList<QPersistentModelIndex> proxy2BeforeList = proxy2ParentsAboutToBeChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
+ QList<QPersistentModelIndex> proxy2AfterList = proxy2ParentsChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
+
+ QCOMPARE(proxy2BeforeList.size(), beforeParents.size());
+ QCOMPARE(proxy2AfterList.size(), afterParents.size());
+ foreach (const QPersistentModelIndex &idx, proxy2BeforeList)
+ QVERIFY(beforeParents.contains(proxy2.mapToSource(idx)));
+ foreach (const QPersistentModelIndex &idx, proxy2AfterList)
+ QVERIFY(afterParents.contains(proxy2.mapToSource(idx)));
+}
+
+class SignalArgumentChecker : public QObject
+{
+ Q_OBJECT
+public:
+ SignalArgumentChecker(QAbstractItemModel *model, QAbstractProxyModel *proxy, QObject *parent = 0)
+ : QObject(parent), m_proxy(proxy)
+ {
+ connect(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
+ connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
+ connect(proxy, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>)), SLOT(layoutAboutToBeChanged(QList<QPersistentModelIndex>)));
+ connect(proxy, SIGNAL(layoutChanged(QList<QPersistentModelIndex>)), SLOT(layoutChanged(QList<QPersistentModelIndex>)));
+ }
+
+private slots:
+ void rowsAboutToBeMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int)
+ {
+ m_p1PersistentBefore = source;
+ m_p2PersistentBefore = destination;
+ m_p2FirstProxyChild = m_proxy->index(0, 0, m_proxy->mapFromSource(destination));
+ }
+
+ void rowsMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int)
+ {
+ m_p1PersistentAfter = source;
+ m_p2PersistentAfter = destination;
+ }
+
+ void layoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents)
+ {
+ QVERIFY(m_p1PersistentBefore.isValid());
+ QVERIFY(m_p2PersistentBefore.isValid());
+ QCOMPARE(parents.size(), 2);
+ QVERIFY(parents.first() != parents.at(1));
+ QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentBefore)));
+ QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentBefore)));
+ }
+
+ void layoutChanged(const QList<QPersistentModelIndex> &parents)
+ {
+ QVERIFY(m_p1PersistentAfter.isValid());
+ QVERIFY(m_p2PersistentAfter.isValid());
+ QCOMPARE(parents.size(), 2);
+ QVERIFY(parents.first() != parents.at(1));
+ QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentAfter)));
+ QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentAfter)));
+
+ // In the source model, the rows were moved to row 1 in the parent.
+ // m_p2FirstProxyChild was created with row 0 in the proxy.
+ // The moved rows in the proxy do not appear at row 1 because of sorting.
+ // Sorting causes them to appear at row 0 instead, pushing what used to
+ // be row 0 in the proxy down by two rows.
+ QCOMPARE(m_p2FirstProxyChild.row(), 2);
+ }
+
+private:
+ QAbstractProxyModel *m_proxy;
+ QPersistentModelIndex m_p1PersistentBefore;
+ QPersistentModelIndex m_p2PersistentBefore;
+ QPersistentModelIndex m_p1PersistentAfter;
+ QPersistentModelIndex m_p2PersistentAfter;
+
+ QPersistentModelIndex m_p2FirstProxyChild;
+};
+
+void tst_QSortFilterProxyModel::moveSourceRows()
+{
+ DynamicTreeModel model;
+
+ {
+ ModelInsertCommand insertCommand(&model);
+ insertCommand.setStartRow(0);
+ insertCommand.setEndRow(9);
+ insertCommand.doCommand();
+ }
+ {
+ ModelInsertCommand insertCommand(&model);
+ insertCommand.setAncestorRowNumbers(QList<int>() << 2);
+ insertCommand.setStartRow(0);
+ insertCommand.setEndRow(9);
+ insertCommand.doCommand();
+ }
+ {
+ ModelInsertCommand insertCommand(&model);
+ insertCommand.setAncestorRowNumbers(QList<int>() << 5);
+ insertCommand.setStartRow(0);
+ insertCommand.setEndRow(9);
+ insertCommand.doCommand();
+ }
+
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0, Qt::AscendingOrder);
+
+ // We need to check the arguments at emission time
+ SignalArgumentChecker checker(&model, &proxy);
+
+ proxy.setSourceModel(&model);
+
+ QSortFilterProxyModel filterProxy;
+ filterProxy.setDynamicSortFilter(true);
+ filterProxy.sort(0, Qt::AscendingOrder);
+ filterProxy.setSourceModel(&proxy);
+ setupFilter(&filterProxy, QLatin1String("6")); // One of the parents
+
+ QSortFilterProxyModel filterBothProxy;
+ filterBothProxy.setDynamicSortFilter(true);
+ filterBothProxy.sort(0, Qt::AscendingOrder);
+ filterBothProxy.setSourceModel(&proxy);
+ setupFilter(&filterBothProxy, QLatin1String("5")); // The parents are 6 and 3. This filters both out.
+
+ QSignalSpy modelBeforeSpy(&model, &DynamicTreeModel::rowsAboutToBeMoved);
+ QSignalSpy modelAfterSpy(&model, &DynamicTreeModel::rowsMoved);
+ QSignalSpy proxyBeforeMoveSpy(m_proxy, &QSortFilterProxyModel::rowsAboutToBeMoved);
+ QSignalSpy proxyAfterMoveSpy(m_proxy, &QSortFilterProxyModel::rowsMoved);
+ QSignalSpy proxyBeforeParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy proxyAfterParentLayoutSpy(&proxy, &QSortFilterProxyModel::layoutChanged);
+ QSignalSpy filterBeforeParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy filterAfterParentLayoutSpy(&filterProxy, &QSortFilterProxyModel::layoutChanged);
+ QSignalSpy filterBothBeforeParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy filterBothAfterParentLayoutSpy(&filterBothProxy, &QSortFilterProxyModel::layoutChanged);
+
+ QVERIFY(modelBeforeSpy.isValid());
+ QVERIFY(modelAfterSpy.isValid());
+ QVERIFY(proxyBeforeMoveSpy.isValid());
+ QVERIFY(proxyAfterMoveSpy.isValid());
+ QVERIFY(proxyBeforeParentLayoutSpy.isValid());
+ QVERIFY(proxyAfterParentLayoutSpy.isValid());
+ QVERIFY(filterBeforeParentLayoutSpy.isValid());
+ QVERIFY(filterAfterParentLayoutSpy.isValid());
+ QVERIFY(filterBothBeforeParentLayoutSpy.isValid());
+ QVERIFY(filterBothAfterParentLayoutSpy.isValid());
+
+ {
+ ModelMoveCommand moveCommand(&model, 0);
+ moveCommand.setAncestorRowNumbers(QList<int>() << 2);
+ moveCommand.setDestAncestors(QList<int>() << 5);
+ moveCommand.setStartRow(3);
+ moveCommand.setEndRow(4);
+ moveCommand.setDestRow(1);
+ moveCommand.doCommand();
+ }
+
+ // Proxy notifies layout change
+ QCOMPARE(modelBeforeSpy.size(), 1);
+ QCOMPARE(proxyBeforeParentLayoutSpy.size(), 1);
+ QCOMPARE(modelAfterSpy.size(), 1);
+ QCOMPARE(proxyAfterParentLayoutSpy.size(), 1);
+
+ // But it doesn't notify a move.
+ QCOMPARE(proxyBeforeMoveSpy.size(), 0);
+ QCOMPARE(proxyAfterMoveSpy.size(), 0);
+
+ QCOMPARE(filterBeforeParentLayoutSpy.size(), 1);
+ QCOMPARE(filterAfterParentLayoutSpy.size(), 1);
+
+ QList<QPersistentModelIndex> filterBeforeParents = filterBeforeParentLayoutSpy.first().first().value<QList<QPersistentModelIndex> >();
+ QList<QPersistentModelIndex> filterAfterParents = filterAfterParentLayoutSpy.first().first().value<QList<QPersistentModelIndex> >();
+
+ QCOMPARE(filterBeforeParents.size(), 1);
+ QCOMPARE(filterAfterParents.size(), 1);
+
+ QCOMPARE(
+ filterBeforeParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::NoLayoutChangeHint);
+ QCOMPARE(filterAfterParentLayoutSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::NoLayoutChangeHint);
+
+ QCOMPARE(filterBothBeforeParentLayoutSpy.size(), 0);
+ QCOMPARE(filterBothAfterParentLayoutSpy.size(), 0);
+}
+
+class FilterProxy : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ FilterProxy(QObject *parent = 0)
+ : QSortFilterProxyModel(parent),
+ mode(false)
+ {
+
+ }
+
+public slots:
+ void setMode(bool on)
+ {
+ mode = on;
+ invalidateFilter();
+ }
+
+protected:
+ virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
+ {
+ if (mode) {
+ if (!source_parent.isValid()) {
+ return true;
+ } else {
+ return (source_row % 2) != 0;
+ }
+ } else {
+ if (!source_parent.isValid()) {
+ return source_row >= 2 && source_row < 10;
+ } else {
+ return true;
+ }
+ }
+ }
+
+private:
+ bool mode;
+};
+
+void tst_QSortFilterProxyModel::hierarchyFilterInvalidation()
+{
+ QStandardItemModel model;
+ for (int i = 0; i < 10; ++i) {
+ const QString rowText = QLatin1String("Row ") + QString::number(i);
+ QStandardItem *child = new QStandardItem(rowText);
+ for (int j = 0; j < 1; ++j) {
+ child->appendRow(new QStandardItem(rowText + QLatin1Char('/') + QString::number(j)));
+ }
+ model.appendRow(child);
+ }
+
+ FilterProxy proxy;
+ proxy.setSourceModel(&model);
+
+ QTreeView view;
+ view.setModel(&proxy);
+
+ view.setCurrentIndex(proxy.index(2, 0).child(0, 0));
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ proxy.setMode(true);
+}
+
+class FilterProxy2 : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ FilterProxy2(QObject *parent = 0)
+ : QSortFilterProxyModel(parent),
+ mode(false)
+ {
+
+ }
+
+public slots:
+ void setMode(bool on)
+ {
+ mode = on;
+ invalidateFilter();
+ }
+
+protected:
+ virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
+ {
+ if (source_parent.isValid()) {
+ return true;
+ } else {
+ if (0 == source_row) {
+ return true;
+ } else {
+ return !mode;
+ }
+ }
+ }
+
+private:
+ bool mode;
+};
+
+void tst_QSortFilterProxyModel::simpleFilterInvalidation()
+{
+ QStandardItemModel model;
+ for (int i = 0; i < 2; ++i) {
+ QStandardItem *child = new QStandardItem(QLatin1String("Row ") + QString::number(i));
+ child->appendRow(new QStandardItem("child"));
+ model.appendRow(child);
+ }
+
+ FilterProxy2 proxy;
+ proxy.setSourceModel(&model);
+
+ QTreeView view;
+ view.setModel(&proxy);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ proxy.setMode(true);
+ model.insertRow(0, new QStandardItem("extra"));
+}
+
+class CustomRoleNameModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ CustomRoleNameModel(QObject *parent = 0) : QAbstractListModel(parent) {}
+
+ QVariant data(const QModelIndex &index, int role) const
+ {
+ Q_UNUSED(index);
+ Q_UNUSED(role);
+ return QVariant();
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const
+ {
+ Q_UNUSED(parent);
+ return 0;
+ }
+
+ QHash<int, QByteArray> roleNames() const
+ {
+ QHash<int, QByteArray> rn = QAbstractListModel::roleNames();
+ rn[Qt::UserRole + 1] = "custom";
+ return rn;
+ }
+};
+
+void tst_QSortFilterProxyModel::chainedProxyModelRoleNames()
+{
+ QSortFilterProxyModel proxy1;
+ QSortFilterProxyModel proxy2;
+ CustomRoleNameModel customModel;
+
+ proxy2.setSourceModel(&proxy1);
+
+ // changing the sourceModel of proxy1 must also update roleNames of proxy2
+ proxy1.setSourceModel(&customModel);
+ QVERIFY(proxy2.roleNames().value(Qt::UserRole + 1) == "custom");
+}
+
+// A source model with ABABAB rows, where only A rows accept drops.
+// It will then be sorted by a QSFPM.
+class DropOnOddRows : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ DropOnOddRows(QObject *parent = 0) : QAbstractListModel(parent) {}
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ if (role == Qt::DisplayRole)
+ return (index.row() % 2 == 0) ? "A" : "B";
+ return QVariant();
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ Q_UNUSED(parent);
+ return 10;
+ }
+
+ bool canDropMimeData(const QMimeData *, Qt::DropAction,
+ int row, int column, const QModelIndex &parent) const override
+ {
+ Q_UNUSED(row);
+ Q_UNUSED(column);
+ return parent.row() % 2 == 0;
+ }
+};
+
+class SourceAssertion : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ explicit SourceAssertion(QObject *parent = 0)
+ : QSortFilterProxyModel(parent)
+ {
+
+ }
+
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
+ {
+ Q_ASSERT(sourceModel());
+ return QSortFilterProxyModel::mapToSource(proxyIndex);
+ }
+};
+
+void tst_QSortFilterProxyModel::noMapAfterSourceDelete()
+{
+ SourceAssertion proxy;
+ QStringListModel *model = new QStringListModel(QStringList() << "Foo" << "Bar");
+
+ proxy.setSourceModel(model);
+
+ // Create mappings
+ QPersistentModelIndex persistent = proxy.index(0, 0);
+
+ QVERIFY(persistent.isValid());
+
+ delete model;
+
+ QVERIFY(!persistent.isValid());
+}
+
+// QTBUG-39549, test whether canDropMimeData(), dropMimeData() are proxied as well
+// by invoking them on a QSortFilterProxyModel proxying a QStandardItemModel that allows drops
+// on row #1, filtering for that row.
+class DropTestModel : public QStandardItemModel {
+public:
+ explicit DropTestModel(QObject *parent = 0) : QStandardItemModel(0, 1, parent)
+ {
+ appendRow(new QStandardItem(QStringLiteral("Row0")));
+ appendRow(new QStandardItem(QStringLiteral("Row1")));
+ }
+
+ bool canDropMimeData(const QMimeData *, Qt::DropAction,
+ int row, int /* column */, const QModelIndex & /* parent */) const override
+ { return row == 1; }
+
+ bool dropMimeData(const QMimeData *, Qt::DropAction,
+ int row, int /* column */, const QModelIndex & /* parent */) override
+ { return row == 1; }
+};
+
+void tst_QSortFilterProxyModel::forwardDropApi()
+{
+ QSortFilterProxyModel model;
+ model.setSourceModel(new DropTestModel(&model));
+ model.setFilterFixedString(QStringLiteral("Row1"));
+ QCOMPARE(model.rowCount(), 1);
+ QVERIFY(model.canDropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex()));
+ QVERIFY(model.dropMimeData(0, Qt::CopyAction, 0, 0, QModelIndex()));
+}
+
+static QString rowTexts(QAbstractItemModel *model) {
+ QString str;
+ for (int row = 0 ; row < model->rowCount(); ++row)
+ str += model->index(row, 0).data().toString();
+ return str;
+}
+
+void tst_QSortFilterProxyModel::canDropMimeData()
+{
+ // Given a source model which only supports dropping on even rows
+ DropOnOddRows sourceModel;
+ QCOMPARE(rowTexts(&sourceModel), QString("ABABABABAB"));
+
+ // and a proxy model that sorts the rows
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&sourceModel);
+ proxy.sort(0, Qt::AscendingOrder);
+ QCOMPARE(rowTexts(&proxy), QString("AAAAABBBBB"));
+
+ // the proxy should correctly map canDropMimeData to the source model,
+ // i.e. accept drops on the first 5 rows and refuse drops on the next 5.
+ for (int row = 0; row < proxy.rowCount(); ++row)
+ QCOMPARE(proxy.canDropMimeData(0, Qt::CopyAction, -1, -1, proxy.index(row, 0)), row < 5);
+}
+
+void tst_QSortFilterProxyModel::resortingDoesNotBreakTreeModels()
+{
+ QStandardItemModel *treeModel = new QStandardItemModel(this);
+ QStandardItem *e1 = new QStandardItem("Loading...");
+ e1->appendRow(new QStandardItem("entry10"));
+ treeModel->appendRow(e1);
+ QStandardItem *e0 = new QStandardItem("Loading...");
+ e0->appendRow(new QStandardItem("entry00"));
+ e0->appendRow(new QStandardItem("entry01"));
+ treeModel->appendRow(e0);
+
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+ proxy.sort(0);
+ proxy.setSourceModel(treeModel);
+
+ QAbstractItemModelTester modelTester(&proxy);
+
+ QCOMPARE(proxy.rowCount(), 2);
+ e1->setText("entry1");
+ e0->setText("entry0");
+
+ QModelIndex pi0 = proxy.index(0, 0);
+ QCOMPARE(pi0.data().toString(), QString("entry0"));
+ QCOMPARE(proxy.rowCount(pi0), 2);
+
+ QModelIndex pi01 = proxy.index(1, 0, pi0);
+ QCOMPARE(pi01.data().toString(), QString("entry01"));
+
+ QModelIndex pi1 = proxy.index(1, 0);
+ QCOMPARE(pi1.data().toString(), QString("entry1"));
+ QCOMPARE(proxy.rowCount(pi1), 1);
+}
+
+void tst_QSortFilterProxyModel::filterHint()
+{
+ // test that a filtering model does not emit layoutChanged with a hint
+ QStringListModel model(QStringList() << "one"
+ << "two"
+ << "three"
+ << "four"
+ << "five"
+ << "six");
+ QSortFilterProxyModel proxy1;
+ proxy1.setSourceModel(&model);
+ proxy1.setSortRole(Qt::DisplayRole);
+ proxy1.setDynamicSortFilter(true);
+ proxy1.sort(0);
+
+ QSortFilterProxyModel proxy2;
+ proxy2.setSourceModel(&proxy1);
+ proxy2.setFilterRole(Qt::DisplayRole);
+ setupFilter(&proxy2, QLatin1String("^[^ ]*$"));
+ proxy2.setDynamicSortFilter(true);
+
+ QSignalSpy proxy1BeforeSpy(&proxy1, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy proxy1AfterSpy(&proxy1, &QSortFilterProxyModel::layoutChanged);
+ QSignalSpy proxy2BeforeSpy(&proxy2, &QSortFilterProxyModel::layoutAboutToBeChanged);
+ QSignalSpy proxy2AfterSpy(&proxy2, &QSortFilterProxyModel::layoutChanged);
+
+ model.setData(model.index(2), QStringLiteral("modified three"), Qt::DisplayRole);
+
+ // The first proxy was re-sorted as one item as changed.
+ QCOMPARE(proxy1BeforeSpy.size(), 1);
+ QCOMPARE(proxy1BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::VerticalSortHint);
+ QCOMPARE(proxy1AfterSpy.size(), 1);
+ QCOMPARE(proxy1AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::VerticalSortHint);
+
+ // But the second proxy must not have the VerticalSortHint since an item was filtered
+ QCOMPARE(proxy2BeforeSpy.size(), 1);
+ QCOMPARE(proxy2BeforeSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::NoLayoutChangeHint);
+ QCOMPARE(proxy2AfterSpy.size(), 1);
+ QCOMPARE(proxy2AfterSpy.first().at(1).value<QAbstractItemModel::LayoutChangeHint>(),
+ QAbstractItemModel::NoLayoutChangeHint);
+}
+
+/**
+
+ Creates a model where each item has one child, to a set depth,
+ and the last item has no children. For a model created with
+ setDepth(4):
+
+ - 1
+ - - 2
+ - - - 3
+ - - - - 4
+*/
+class StepTreeModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ StepTreeModel(QObject * parent = 0)
+ : QAbstractItemModel(parent), m_depth(0) {}
+
+ int columnCount(const QModelIndex& = QModelIndex()) const override { return 1; }
+
+ int rowCount(const QModelIndex& parent = QModelIndex()) const override
+ {
+ quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
+ return (parentId < m_depth) ? 1 : 0;
+ }
+
+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override
+ {
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ return QString::number(index.internalId());
+ }
+
+ QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override
+ {
+ // QTBUG-44962: Would we always expect the parent to belong to the model
+ qDebug() << parent.model() << this;
+ Q_ASSERT(!parent.isValid() || parent.model() == this);
+
+ quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
+ if (parentId >= m_depth)
+ return QModelIndex();
+
+ return createIndex(0, 0, parentId + 1);
+ }
+
+ QModelIndex parent(const QModelIndex& index) const override
+ {
+ if (index.internalId() == 0)
+ return QModelIndex();
+
+ return createIndex(0, 0, index.internalId() - 1);
+ }
+
+ void setDepth(quintptr depth)
+ {
+ int parentIdWithLayoutChange = (m_depth < depth) ? m_depth : depth;
+
+ QList<QPersistentModelIndex> parentsOfLayoutChange;
+ parentsOfLayoutChange.push_back(createIndex(0, 0, parentIdWithLayoutChange));
+
+ layoutAboutToBeChanged(parentsOfLayoutChange);
+
+ auto existing = persistentIndexList();
+
+ QList<QModelIndex> updated;
+
+ for (auto idx : existing) {
+ if (indexDepth(idx) <= depth)
+ updated.push_back(idx);
+ else
+ updated.push_back({});
+ }
+
+ m_depth = depth;
+
+ changePersistentIndexList(existing, updated);
+
+ layoutChanged(parentsOfLayoutChange);
+ }
+
+private:
+ static quintptr indexDepth(QModelIndex const& index)
+ {
+ return (index.isValid()) ? 1 + indexDepth(index.parent()) : 0;
+ }
+
+private:
+ quintptr m_depth;
+};
+
+void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes()
+{
+ StepTreeModel model;
+ Q_SET_OBJECT_NAME(model);
+ model.setDepth(4);
+
+ QSortFilterProxyModel proxy1;
+ proxy1.setSourceModel(&model);
+ Q_SET_OBJECT_NAME(proxy1);
+ setupFilter(&proxy1, QLatin1String("1|2"));
+
+ // The current state of things:
+ // model proxy
+ // - 1 - 1
+ // - - 2 - - 2
+ // - - - 3
+ // - - - - 4
+
+ // The setDepth call below removes '4' with a layoutChanged call.
+ // Because the proxy filters that out anyway, the proxy doesn't need
+ // to emit any signals or update persistent indexes.
+
+ QPersistentModelIndex persistentIndex = proxy1.index(0, 0, proxy1.index(0, 0));
+
+ model.setDepth(3);
+
+ // Calling parent() causes the internalPointer to be used.
+ // Before fixing QTBUG-47711, that could be a dangling pointer.
+ // The use of qDebug here makes sufficient use of the heap to
+ // cause corruption at runtime with normal use on linux (before
+ // the fix). valgrind confirms the fix.
+ qDebug() << persistentIndex.parent();
+ QVERIFY(persistentIndex.parent().isValid());
+}
+
+void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes()
+{
+ DynamicTreeModel model;
+ Q_SET_OBJECT_NAME(model);
+
+ QList<int> ancestors;
+ for (auto i = 0; i < 5; ++i)
+ {
+ Q_UNUSED(i);
+ ModelInsertCommand insertCommand(&model);
+ insertCommand.setAncestorRowNumbers(ancestors);
+ insertCommand.setStartRow(0);
+ insertCommand.setEndRow(0);
+ insertCommand.doCommand();
+ ancestors.push_back(0);
+ }
+
+ QSortFilterProxyModel proxy1;
+ proxy1.setSourceModel(&model);
+ Q_SET_OBJECT_NAME(proxy1);
+
+ setupFilter(&proxy1, QLatin1String("1|2"));
+
+ auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first();
+ auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first();
+
+ Q_ASSERT(item5.isValid());
+ Q_ASSERT(item3.isValid());
+
+ QPersistentModelIndex persistentIndex = proxy1.match(proxy1.index(0, 0), Qt::DisplayRole, "2", 1, Qt::MatchRecursive).first();
+
+ ModelMoveCommand moveCommand(&model, 0);
+ moveCommand.setAncestorRowNumbers(QList<int>{0, 0, 0, 0});
+ moveCommand.setStartRow(0);
+ moveCommand.setEndRow(0);
+ moveCommand.setDestRow(0);
+ moveCommand.setDestAncestors(QList<int>{0, 0, 0});
+ moveCommand.doCommand();
+
+ // Calling parent() causes the internalPointer to be used.
+ // Before fixing QTBUG-47711 (moveRows case), that could be
+ // a dangling pointer.
+ QVERIFY(persistentIndex.parent().isValid());
+}
+
+void tst_QSortFilterProxyModel::emitLayoutChangedOnlyIfSortingChanged_data()
+{
+ QTest::addColumn<int>("changedRow");
+ QTest::addColumn<Qt::ItemDataRole>("changedRole");
+ QTest::addColumn<QString>("newData");
+ QTest::addColumn<QString>("expectedSourceRowTexts");
+ QTest::addColumn<QString>("expectedProxyRowTexts");
+ QTest::addColumn<int>("expectedLayoutChanged");
+
+ // Starting point:
+ // a source model with 8,7,6,5,4,3,2,1
+ // a proxy model keeping only even rows and sorting them, therefore showing 2,4,6,8
+
+ // When setData changes ordering, layoutChanged should be emitted
+ QTest::newRow("ordering_change") << 0 << Qt::DisplayRole << "0" << "07654321" << "0246" << 1;
+
+ // When setData on visible row doesn't change ordering, layoutChanged should not be emitted
+ QTest::newRow("no_ordering_change") << 6 << Qt::DisplayRole << "0" << "87654301" << "0468" << 0;
+
+ // When setData happens on a filtered out row, layoutChanged should not be emitted
+ QTest::newRow("filtered_out") << 1 << Qt::DisplayRole << "9" << "89654321" << "2468" << 0;
+
+ // When setData makes a row visible, layoutChanged should not be emitted (rowsInserted is emitted instead)
+ QTest::newRow("make_row_visible") << 7 << Qt::DisplayRole << "0" << "87654320" << "02468" << 0;
+
+ // When setData makes a row hidden, layoutChanged should not be emitted (rowsRemoved is emitted instead)
+ QTest::newRow("make_row_hidden") << 4 << Qt::DisplayRole << "1" << "87651321" << "268" << 0;
+
+ // When setData happens on an unrelated role, layoutChanged should not be emitted
+ QTest::newRow("unrelated_role") << 0 << Qt::DecorationRole << "" << "87654321" << "2468" << 0;
+
+ // When many changes happen together... and trigger removal, insertion, and layoutChanged
+ QTest::newRow("many_changes") << -1 << Qt::DisplayRole << "3,4,2,5,6,0,7,9" << "34256079" << "0246" << 1;
+
+ // When many changes happen together... and trigger removal, insertion, but no change in ordering of visible rows => no layoutChanged
+ QTest::newRow("many_changes_no_layoutChanged") << -1 << Qt::DisplayRole << "7,5,4,3,2,1,0,8" << "75432108" << "0248" << 0;
+}
+
+// Custom version of QStringListModel which supports emitting dataChanged for many rows at once
+class CustomStringListModel : public QAbstractListModel
+{
+public:
+ bool setData(const QModelIndex &index, const QVariant &value, int role) override
+ {
+ if (index.row() >= 0 && index.row() < lst.size()
+ && (role == Qt::EditRole || role == Qt::DisplayRole)) {
+ lst.replace(index.row(), value.toString());
+ emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole });
+ return true;
+ }
+ return false;
+ }
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ if (role == Qt::DisplayRole || role == Qt::EditRole)
+ return lst.at(index.row());
+ return QVariant();
+ }
+ int rowCount(const QModelIndex & = QModelIndex()) const override { return lst.count(); }
+
+ void replaceData(const QStringList &newData)
+ {
+ lst = newData;
+ emit dataChanged(index(0, 0), index(rowCount() - 1, 0), { Qt::DisplayRole, Qt::EditRole });
+ }
+
+ void emitDecorationChangedSignal()
+ {
+ const QModelIndex idx = index(0, 0);
+ emit dataChanged(idx, idx, { Qt::DecorationRole });
+ }
+
+private:
+ QStringList lst;
+};
+
+void tst_QSortFilterProxyModel::emitLayoutChangedOnlyIfSortingChanged()
+{
+ QFETCH(int, changedRow);
+ QFETCH(QString, newData);
+ QFETCH(Qt::ItemDataRole, changedRole);
+ QFETCH(QString, expectedSourceRowTexts);
+ QFETCH(QString, expectedProxyRowTexts);
+ QFETCH(int, expectedLayoutChanged);
+
+ CustomStringListModel model;
+ QStringList strings;
+ for (auto i = 8; i >= 1; --i)
+ strings.append(QString::number(i));
+ model.replaceData(strings);
+ QCOMPARE(rowTexts(&model), QStringLiteral("87654321"));
+
+ class FilterEvenRowsProxyModel : public QSortFilterProxyModel
+ {
+ public:
+ bool filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const override
+ {
+ return sourceModel()->index(srcRow, 0, srcParent).data().toInt() % 2 == 0;
+ }
+ };
+
+ FilterEvenRowsProxyModel proxy;
+ proxy.sort(0);
+ proxy.setSourceModel(&model);
+ QCOMPARE(rowTexts(&proxy), QStringLiteral("2468"));
+
+ QSignalSpy modelDataChangedSpy(&model, &QAbstractItemModel::dataChanged);
+ QSignalSpy proxyLayoutChangedSpy(&proxy, &QAbstractItemModel::layoutChanged);
+
+ if (changedRole == Qt::DecorationRole)
+ model.emitDecorationChangedSignal();
+ else if (changedRow == -1)
+ model.replaceData(newData.split(QLatin1Char(',')));
+ else
+ model.setData(model.index(changedRow, 0), newData, changedRole);
+
+ QCOMPARE(rowTexts(&model), expectedSourceRowTexts);
+ QCOMPARE(rowTexts(&proxy), expectedProxyRowTexts);
+ QCOMPARE(modelDataChangedSpy.size(), 1);
+ QCOMPARE(proxyLayoutChangedSpy.size(), expectedLayoutChanged);
+}
+
+void tst_QSortFilterProxyModel::removeIntervals_data()
+{
+ QTest::addColumn<QStringList>("sourceItems");
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QString>("filter");
+ QTest::addColumn<QStringList>("replacementSourceItems");
+ QTest::addColumn<IntPairList>("expectedRemovedProxyIntervals");
+ QTest::addColumn<QStringList>("expectedProxyItems");
+
+ QTest::newRow("filter all, sort ascending")
+ << (QStringList() << "a"
+ << "b"
+ << "c") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "[^x]" // filter
+ << (QStringList() << "x"
+ << "x"
+ << "x") // replacementSourceItems
+ << (IntPairList() << IntPair(0, 2)) // expectedRemovedIntervals
+ << QStringList() // expectedProxyItems
+ ;
+
+ QTest::newRow("filter all, sort descending")
+ << (QStringList() << "a"
+ << "b"
+ << "c") // sourceItems
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << "[^x]" // filter
+ << (QStringList() << "x"
+ << "x"
+ << "x") // replacementSourceItems
+ << (IntPairList() << IntPair(0, 2)) // expectedRemovedIntervals
+ << QStringList() // expectedProxyItems
+ ;
+
+ QTest::newRow("filter first and last, sort ascending")
+ << (QStringList() << "a"
+ << "b"
+ << "c") // sourceItems
+ << static_cast<int>(Qt::AscendingOrder) // sortOrder
+ << "[^x]" // filter
+ << (QStringList() << "x"
+ << "b"
+ << "x") // replacementSourceItems
+ << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b") // expectedProxyItems
+ ;
+
+ QTest::newRow("filter first and last, sort descending")
+ << (QStringList() << "a"
+ << "b"
+ << "c") // sourceItems
+ << static_cast<int>(Qt::DescendingOrder) // sortOrder
+ << "[^x]" // filter
+ << (QStringList() << "x"
+ << "b"
+ << "x") // replacementSourceItems
+ << (IntPairList() << IntPair(2, 2) << IntPair(0, 0)) // expectedRemovedIntervals
+ << (QStringList() << "b") // expectedProxyItems
+ ;
+}
+
+void tst_QSortFilterProxyModel::removeIntervals()
+{
+ QFETCH(QStringList, sourceItems);
+ QFETCH(int, sortOrder);
+ QFETCH(QString, filter);
+ QFETCH(QStringList, replacementSourceItems);
+ QFETCH(IntPairList, expectedRemovedProxyIntervals);
+ QFETCH(QStringList, expectedProxyItems);
+
+ CustomStringListModel model;
+ QSortFilterProxyModel proxy;
+
+ model.replaceData(sourceItems);
+ proxy.setSourceModel(&model);
+
+ for (int i = 0; i < sourceItems.count(); ++i) {
+ QModelIndex sindex = model.index(i, 0, QModelIndex());
+ QModelIndex pindex = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(pindex, Qt::DisplayRole), model.data(sindex, Qt::DisplayRole));
+ }
+
+ proxy.setDynamicSortFilter(true);
+
+ if (sortOrder != -1)
+ proxy.sort(0, static_cast<Qt::SortOrder>(sortOrder));
+ if (!filter.isEmpty())
+ setupFilter(&proxy, filter);
+
+ (void)proxy.rowCount(QModelIndex()); // force mapping
+
+ QSignalSpy removeSpy(&proxy, &QSortFilterProxyModel::rowsRemoved);
+ QSignalSpy insertSpy(&proxy, &QSortFilterProxyModel::rowsInserted);
+ QSignalSpy aboutToRemoveSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeRemoved);
+ QSignalSpy aboutToInsertSpy(&proxy, &QSortFilterProxyModel::rowsAboutToBeInserted);
+
+ QVERIFY(removeSpy.isValid());
+ QVERIFY(insertSpy.isValid());
+ QVERIFY(aboutToRemoveSpy.isValid());
+ QVERIFY(aboutToInsertSpy.isValid());
+
+ model.replaceData(replacementSourceItems);
+
+ QCOMPARE(aboutToRemoveSpy.count(), expectedRemovedProxyIntervals.count());
+ for (int i = 0; i < aboutToRemoveSpy.count(); ++i) {
+ QList<QVariant> args = aboutToRemoveSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
+ }
+ QCOMPARE(removeSpy.count(), expectedRemovedProxyIntervals.count());
+ for (int i = 0; i < removeSpy.count(); ++i) {
+ QList<QVariant> args = removeSpy.at(i);
+ QCOMPARE(args.at(1).type(), QVariant::Int);
+ QCOMPARE(args.at(2).type(), QVariant::Int);
+ QCOMPARE(args.at(1).toInt(), expectedRemovedProxyIntervals.at(i).first);
+ QCOMPARE(args.at(2).toInt(), expectedRemovedProxyIntervals.at(i).second);
+ }
+
+ QCOMPARE(insertSpy.count(), 0);
+ QCOMPARE(aboutToInsertSpy.count(), 0);
+
+ QCOMPARE(proxy.rowCount(QModelIndex()), expectedProxyItems.count());
+ for (int i = 0; i < expectedProxyItems.count(); ++i) {
+ QModelIndex pindex = proxy.index(i, 0, QModelIndex());
+ QCOMPARE(proxy.data(pindex, Qt::DisplayRole).toString(), expectedProxyItems.at(i));
+ }
+}
+
+void tst_QSortFilterProxyModel::dynamicFilterWithoutSort()
+{
+ QStringListModel model;
+ const QStringList initial = QString("bravo charlie delta echo").split(QLatin1Char(' '));
+ model.setStringList(initial);
+ QSortFilterProxyModel proxy;
+ proxy.setDynamicSortFilter(true);
+ proxy.setSourceModel(&model);
+
+ QSignalSpy layoutChangeSpy(&proxy, &QAbstractItemModel::layoutChanged);
+ QSignalSpy resetSpy(&proxy, &QAbstractItemModel::modelReset);
+
+ QVERIFY(layoutChangeSpy.isValid());
+ QVERIFY(resetSpy.isValid());
+
+ model.setStringList(QStringList() << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday");
+
+ QVERIFY(layoutChangeSpy.isEmpty());
+
+ QCOMPARE(model.stringList(), QStringList() << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday");
+
+ QCOMPARE(resetSpy.count(), 1);
+}
+
+void tst_QSortFilterProxyModel::checkSetNewModel()
+{
+ QTreeView tv;
+ StepTreeModel model1;
+ model1.setDepth(4);
+
+ QSortFilterProxyModel proxy;
+ proxy.setSourceModel(&model1);
+ tv.setModel(&proxy);
+ tv.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tv));
+ tv.expandAll();
+ {
+ StepTreeModel model2;
+ model2.setDepth(4);
+ proxy.setSourceModel(&model2);
+ tv.expandAll();
+ proxy.setSourceModel(&model1);
+ tv.expandAll();
+ // the destruction of model2 here caused a proxy model reset due to
+ // missing disconnect in setSourceModel()
+ }
+ // handle repaint events, will assert when qsortfilterproxymodel is in wrong state
+ QCoreApplication::processEvents();
+}
+
+enum ColumnFilterMode {
+ FilterNothing,
+ FilterOutMiddle,
+ FilterOutBeginEnd,
+ FilterAll
+};
+Q_DECLARE_METATYPE(ColumnFilterMode)
+
+void tst_QSortFilterProxyModel::filterAndInsertColumn_data()
+{
+
+ QTest::addColumn<int>("insertCol");
+ QTest::addColumn<ColumnFilterMode>("filterMode");
+ QTest::addColumn<QStringList>("expectedModelList");
+ QTest::addColumn<QStringList>("expectedProxyModelList");
+
+ QTest::newRow("at_beginning_filter_out_middle")
+ << 0
+ << FilterOutMiddle
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ << QStringList{{"", "D1"}}
+ ;
+ QTest::newRow("at_end_filter_out_middle")
+ << 2
+ << FilterOutMiddle
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"A1", ""}}
+ ;
+ QTest::newRow("in_the_middle_filter_out_middle")
+ << 1
+ << FilterOutMiddle
+ << QStringList{{"A1", "B1", "C1", "", "D1"}}
+ << QStringList{{"A1", "D1"}}
+ ;
+ QTest::newRow("at_beginning_filter_out_begin_and_end")
+ << 0
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "", "B1", "C1", "D1"}}
+ << QStringList{{"", "B1", "C1"}}
+ ;
+ QTest::newRow("at_end_filter_out_begin_and_end")
+ << 2
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"B1", "C1", "D1"}}
+ ;
+ QTest::newRow("in_the_middle_filter_out_begin_and_end")
+ << 1
+ << FilterOutBeginEnd
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ << QStringList{{"B1", "", "C1"}}
+ ;
+
+ QTest::newRow("at_beginning_filter_nothing")
+ << 0
+ << FilterAll
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ << QStringList{{"", "A1", "B1", "C1", "D1"}}
+ ;
+ QTest::newRow("at_end_filter_nothing")
+ << 4
+ << FilterAll
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ ;
+ QTest::newRow("in_the_middle_nothing")
+ << 2
+ << FilterAll
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ << QStringList{{"A1", "B1", "", "C1", "D1"}}
+ ;
+
+ QTest::newRow("filter_all")
+ << 0
+ << FilterNothing
+ << QStringList{{"A1", "B1", "C1", "D1", ""}}
+ << QStringList{}
+ ;
+}
+void tst_QSortFilterProxyModel::filterAndInsertColumn()
+{
+
+ class ColumnFilterProxy : public QSortFilterProxyModel {
+ Q_DISABLE_COPY(ColumnFilterProxy)
+ ColumnFilterMode filerMode;
+ public:
+ ColumnFilterProxy(ColumnFilterMode mode)
+ : filerMode(mode)
+ {}
+ bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override
+ {
+ Q_UNUSED(source_parent)
+ switch (filerMode){
+ case FilterAll:
+ return true;
+ case FilterNothing:
+ return false;
+ case FilterOutMiddle:
+ return source_column == 0 || source_column == sourceModel()->columnCount() - 1;
+ case FilterOutBeginEnd:
+ return source_column > 0 && source_column< sourceModel()->columnCount() - 1;
+ }
+ Q_UNREACHABLE();
+ }
+ };
+ QFETCH(int, insertCol);
+ QFETCH(ColumnFilterMode, filterMode);
+ QFETCH(QStringList, expectedModelList);
+ QFETCH(QStringList, expectedProxyModelList);
+ QStandardItemModel model;
+ model.insertColumns(0, 4);
+ model.insertRows(0, 1);
+ for (int i = 0; i < model.rowCount(); ++i) {
+ for (int j = 0; j < model.columnCount(); ++j)
+ model.setData(model.index(i, j), QString('A' + j) + QString::number(i + 1));
+ }
+ ColumnFilterProxy proxy(filterMode);
+ proxy.setSourceModel(&model);
+ QVERIFY(proxy.insertColumn(insertCol));
+ proxy.invalidate();
+ QStringList modelStringList;
+ for (int i = 0; i < model.rowCount(); ++i) {
+ for (int j = 0; j < model.columnCount(); ++j)
+ modelStringList.append(model.index(i, j).data().toString());
+ }
+ QCOMPARE(expectedModelList, modelStringList);
+ modelStringList.clear();
+ for (int i = 0; i < proxy.rowCount(); ++i) {
+ for (int j = 0; j < proxy.columnCount(); ++j)
+ modelStringList.append(proxy.index(i, j).data().toString());
+ }
+ QCOMPARE(expectedProxyModelList, modelStringList);
+}
+
+void tst_QSortFilterProxyModel::filterAndInsertRow_data()
+{
+ QTest::addColumn<QStringList>("initialModelList");
+ QTest::addColumn<int>("row");
+ QTest::addColumn<QString>("filterRegExp");
+ QTest::addColumn<QStringList>("expectedModelList");
+ QTest::addColumn<QStringList>("expectedProxyModelList");
+
+ QTest::newRow("at_beginning_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "^A"
+ << QStringList{{"", "A5", "B5", "B6", "A7"}}
+ << QStringList{{"A5", "A7"}};
+ QTest::newRow("at_end_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << "^A"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"A5", "A7"}};
+ QTest::newRow("in_the_middle_filter_out_middle")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 1
+ << "^A"
+ << QStringList{{"A5", "B5", "B6", "", "A7"}}
+ << QStringList{{"A5", "A7"}};
+
+ QTest::newRow("at_beginning_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "^B"
+ << QStringList{{"A5", "", "B5", "B6", "A7"}}
+ << QStringList{{"B5", "B6"}};
+ QTest::newRow("at_end_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << "^B"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"B5", "B6"}};
+ QTest::newRow("in_the_middle_filter_out_first_and_last")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 1
+ << "^B"
+ << QStringList{{"A5", "B5", "", "B6", "A7"}}
+ << QStringList{{"B5", "B6"}};
+
+ QTest::newRow("at_beginning_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << ".*"
+ << QStringList{{"", "A5", "B5", "B6", "A7"}}
+ << QStringList{{"", "A5", "B5", "B6", "A7"}};
+ QTest::newRow("at_end_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 4
+ << ".*"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{{"A5", "B5", "B6", "A7", ""}};
+ QTest::newRow("in_the_middle_no_filter")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 2
+ << ".*"
+ << QStringList{{"A5", "B5", "", "B6", "A7"}}
+ << QStringList{{"A5", "B5", "", "B6", "A7"}};
+
+ QTest::newRow("filter_all")
+ << QStringList{{"A5", "B5", "B6", "A7"}}
+ << 0
+ << "$a"
+ << QStringList{{"A5", "B5", "B6", "A7", ""}}
+ << QStringList{};
+}
+
+void tst_QSortFilterProxyModel::filterAndInsertRow()
+{
+ QFETCH(QStringList, initialModelList);
+ QFETCH(int, row);
+ QFETCH(QString, filterRegExp);
+ QFETCH(QStringList, expectedModelList);
+ QFETCH(QStringList, expectedProxyModelList);
+ QStringListModel model;
+ QSortFilterProxyModel proxyModel;
+
+ model.setStringList(initialModelList);
+ proxyModel.setSourceModel(&model);
+ proxyModel.setDynamicSortFilter(true);
+ proxyModel.setFilterRegExp(filterRegExp);
+
+ QVERIFY(proxyModel.insertRow(row));
+ QCOMPARE(model.stringList(), expectedModelList);
+ QCOMPARE(proxyModel.rowCount(), expectedProxyModelList.count());
+ for (int r = 0; r < proxyModel.rowCount(); ++r) {
+ QModelIndex index = proxyModel.index(r, 0);
+ QVERIFY(index.isValid());
+ QCOMPARE(proxyModel.data(index).toString(), expectedProxyModelList.at(r));
+ }
+}
+
+#include "tst_qsortfilterproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
new file mode 100644
index 0000000000..82d4b7344e
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TST_QSORTFILTERPROXYMODEL_H
+#define TST_QSORTFILTERPROXYMODEL_H
+
+#include <QtTest/QtTest>
+#include "dynamictreemodel.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtGui/QStandardItem>
+#include <QtWidgets/QTreeView>
+#include <QtWidgets/QTableView>
+
+#include <qdebug.h>
+
+typedef QList<int> IntList;
+typedef QPair<int, int> IntPair;
+typedef QList<IntPair> IntPairList;
+
+enum class FilterType {
+ RegExp,
+ RegularExpression
+};
+
+Q_DECLARE_METATYPE(QList<QPersistentModelIndex>)
+
+class tst_QSortFilterProxyModel : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QSortFilterProxyModel();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void cleanup();
+
+private slots:
+ void getSetCheck();
+ void sort_data();
+ void sort();
+ void sortHierarchy_data();
+ void sortHierarchy();
+
+ void insertRows_data();
+ void insertRows();
+ void prependRow();
+ void appendRowFromCombobox_data();
+ void appendRowFromCombobox();
+ void removeRows_data();
+ void removeRows();
+ void removeColumns_data();
+ void removeColumns();
+ void insertAfterSelect();
+ void removeAfterSelect();
+ void filter_data();
+ void filter();
+ void filterHierarchy_data();
+ void filterHierarchy();
+ void filterColumns_data();
+ void filterColumns();
+
+ void filterTable();
+ void filterCurrent();
+ void filter_qtbug30662();
+
+ void changeSourceLayout();
+ void changeSourceLayoutFilteredOut();
+ void removeSourceRows_data();
+ void removeSourceRows();
+ void insertSourceRows_data();
+ void insertSourceRows();
+ void changeFilter_data();
+ void changeFilter();
+ void changeSourceData_data();
+ void changeSourceData();
+ void changeSourceDataKeepsStableSorting_qtbug1548();
+ void changeSourceDataForwardsRoles_qtbug35440();
+ void resortingDoesNotBreakTreeModels();
+ void dynamicFilterWithoutSort();
+ void sortFilterRole();
+ void selectionFilteredOut();
+ void match_data();
+ void match();
+ void insertIntoChildrenlessItem();
+ void invalidateMappedChildren();
+ void insertRowIntoFilteredParent();
+ void filterOutParentAndFilterInChild();
+
+ void sourceInsertRows();
+ void sourceModelDeletion();
+
+ void sortColumnTracking1();
+ void sortColumnTracking2();
+
+ void sortStable();
+
+ void hiddenColumns();
+ void insertRowsSort();
+ void staticSorting();
+ void dynamicSorting();
+ void fetchMore();
+ void hiddenChildren();
+ void mapFromToSource();
+ void removeRowsRecursive();
+ void doubleProxySelectionSetSourceModel();
+ void appearsAndSort();
+ void unnecessaryDynamicSorting();
+ void unnecessaryMapCreation();
+ void resetInvalidate_data();
+ void resetInvalidate();
+
+ void testMultipleProxiesWithSelection();
+ void mapSelectionFromSource();
+ void testResetInternalData();
+ void filteredColumns();
+ void headerDataChanged();
+
+ void testParentLayoutChanged();
+ void moveSourceRows();
+
+ void hierarchyFilterInvalidation();
+ void simpleFilterInvalidation();
+
+ void chainedProxyModelRoleNames();
+
+ void noMapAfterSourceDelete();
+ void forwardDropApi();
+ void canDropMimeData();
+ void filterHint();
+
+ void sourceLayoutChangeLeavesValidPersistentIndexes();
+ void rowMoveLeavesValidPersistentIndexes();
+
+ void emitLayoutChangedOnlyIfSortingChanged_data();
+ void emitLayoutChangedOnlyIfSortingChanged();
+
+ void checkSetNewModel();
+ void filterAndInsertRow_data();
+ void filterAndInsertRow();
+ void filterAndInsertColumn_data();
+ void filterAndInsertColumn();
+
+ void removeIntervals_data();
+ void removeIntervals();
+
+protected:
+ void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
+ void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
+ void setupFilter(QSortFilterProxyModel *model, const QString& pattern);
+
+protected:
+ FilterType m_filterType;
+
+private:
+ QStandardItemModel *m_model;
+ QSortFilterProxyModel *m_proxy;
+};
+
+Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint)
+
+#endif // TST_QSORTFILTERPROXYMODEL_H
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore
new file mode 100644
index 0000000000..4fdaebc09d
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/.gitignore
@@ -0,0 +1 @@
+tst_qsortfilterproxymodel_regexp
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro
new file mode 100644
index 0000000000..7c510930f4
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/qsortfilterproxymodel_regexp.pro
@@ -0,0 +1,16 @@
+CONFIG += testcase
+TARGET = tst_qsortfilterproxymodel_regexp
+
+QT += widgets testlib
+mtdir = ../../../other/qabstractitemmodelutils
+qsfpmdir = ../qsortfilterproxymodel_common
+
+INCLUDEPATH += $$PWD/$${mtdir} $$PWD/$${qsfpmdir}
+SOURCES += \
+ tst_qsortfilterproxymodel_regexp.cpp \
+ $${qsfpmdir}/tst_qsortfilterproxymodel.cpp \
+ $${mtdir}/dynamictreemodel.cpp
+
+HEADERS += \
+ $${qsfpmdir}/tst_qsortfilterproxymodel.h \
+ $${mtdir}/dynamictreemodel.h
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp
new file mode 100644
index 0000000000..e83738661e
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regexp/tst_qsortfilterproxymodel_regexp.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include "tst_qsortfilterproxymodel.h"
+
+class tst_QSortFilterProxyModelRegExp : public tst_QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ tst_QSortFilterProxyModelRegExp();
+private slots:
+ void tst_invalid();
+};
+
+tst_QSortFilterProxyModelRegExp::tst_QSortFilterProxyModelRegExp() :
+ tst_QSortFilterProxyModel()
+{
+ m_filterType = FilterType::RegExp;
+}
+
+void tst_QSortFilterProxyModelRegExp::tst_invalid()
+{
+ const QLatin1String pattern("test");
+ QSortFilterProxyModel model;
+ model.setFilterRegExp(pattern);
+ QCOMPARE(model.filterRegExp(), QRegExp(pattern));
+ model.setFilterRegularExpression(pattern);
+ QCOMPARE(model.filterRegExp(), QRegExp());
+}
+
+QTEST_MAIN(tst_QSortFilterProxyModelRegExp)
+#include "tst_qsortfilterproxymodel_regexp.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore
new file mode 100644
index 0000000000..286771e250
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/.gitignore
@@ -0,0 +1 @@
+tst_qsortfilterproxymodel_regularexpression
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro
new file mode 100644
index 0000000000..e993d07126
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/qsortfilterproxymodel_regularexpression.pro
@@ -0,0 +1,16 @@
+CONFIG += testcase
+TARGET = tst_qsortfilterproxymodel_regularexpression
+
+QT += widgets testlib
+mtdir = ../../../other/qabstractitemmodelutils
+qsfpmdir = ../qsortfilterproxymodel_common
+
+INCLUDEPATH += $$PWD/$${mtdir} $${qsfpmdir}
+SOURCES += \
+ tst_qsortfilterproxymodel_regularexpression.cpp \
+ $${qsfpmdir}/tst_qsortfilterproxymodel.cpp \
+ $${mtdir}/dynamictreemodel.cpp
+
+HEADERS += \
+ $${qsfpmdir}/tst_qsortfilterproxymodel.h \
+ $${mtdir}/dynamictreemodel.h
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp
new file mode 100644
index 0000000000..821e199bcb
--- /dev/null
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_regularexpression/tst_qsortfilterproxymodel_regularexpression.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include "tst_qsortfilterproxymodel.h"
+
+class tst_QSortFilterProxyModelRegularExpression : public tst_QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ tst_QSortFilterProxyModelRegularExpression();
+private slots:
+ void tst_invalid();
+};
+
+tst_QSortFilterProxyModelRegularExpression::tst_QSortFilterProxyModelRegularExpression() :
+ tst_QSortFilterProxyModel()
+{
+ m_filterType = FilterType::RegularExpression;
+}
+
+void tst_QSortFilterProxyModelRegularExpression::tst_invalid()
+{
+ const QLatin1String pattern("test");
+ QSortFilterProxyModel model;
+ model.setFilterRegularExpression(pattern);
+ QCOMPARE(model.filterRegularExpression(), QRegularExpression(pattern));
+ model.setFilterRegExp(pattern);
+ QCOMPARE(model.filterRegularExpression(), QRegularExpression());
+}
+
+QTEST_MAIN(tst_QSortFilterProxyModelRegularExpression)
+#include "tst_qsortfilterproxymodel_regularexpression.moc"
diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
index 5e9dbdd226..a53501b9dd 100644
--- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
+++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp
@@ -415,7 +415,7 @@ void tst_QCoreApplication::removePostedEvents()
expected.clear();
}
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
class DeliverInDefinedOrderThread : public QThread
{
Q_OBJECT
@@ -532,7 +532,7 @@ void tst_QCoreApplication::deliverInDefinedOrder()
QObject::connect(&obj, SIGNAL(done()), &app, SLOT(quit()));
app.exec();
}
-#endif // QT_NO_QTHREAD
+#endif // QT_CONFIG(thread)
void tst_QCoreApplication::applicationPid()
{
diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
index b6c20a915f..105cca5174 100644
--- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
+++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h
@@ -43,7 +43,7 @@ private slots:
void argc();
void postEvent();
void removePostedEvents();
-#ifndef QT_NO_THREAD
+#if QT_CONFIG(thread)
void deliverInDefinedOrder();
#endif
void applicationPid();
diff --git a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST b/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
index 4cd3c2f0c8..4dd71ca9f4 100644
--- a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
+++ b/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
@@ -1,3 +1,4 @@
[elapsed]
windows
osx-10.12
+osx-10.13
diff --git a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
index 402d87b82f..fb7e025b7c 100644
--- a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
+++ b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST
@@ -4,3 +4,4 @@ osx
[registerTimer]
windows
osx
+winrt
diff --git a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp
index e4aa8b80c0..bb111a9137 100644
--- a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp
+++ b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp
@@ -37,7 +37,10 @@ class tst_QMetaEnum : public QObject
Q_OBJECT
public:
enum SuperEnum { SuperValue1 = 1 , SuperValue2 = 2 };
+ enum Flag { Flag1 = 1 , Flag2 = 2 };
+ Q_DECLARE_FLAGS(Flags, Flag)
Q_ENUM(SuperEnum)
+ Q_FLAG(Flags)
private slots:
void fromType();
@@ -49,7 +52,17 @@ void tst_QMetaEnum::fromType()
{
QMetaEnum meta = QMetaEnum::fromType<SuperEnum>();
QVERIFY(meta.isValid());
+ QVERIFY(!meta.isFlag());
QCOMPARE(meta.name(), "SuperEnum");
+ QCOMPARE(meta.enumName(), "SuperEnum");
+ QCOMPARE(meta.enclosingMetaObject(), &staticMetaObject);
+ QCOMPARE(meta.keyCount(), 2);
+
+ meta = QMetaEnum::fromType<Flags>();
+ QVERIFY(meta.isValid());
+ QVERIFY(meta.isFlag());
+ QCOMPARE(meta.name(), "Flags");
+ QCOMPARE(meta.enumName(), "Flag");
QCOMPARE(meta.enclosingMetaObject(), &staticMetaObject);
QCOMPARE(meta.keyCount(), 2);
}
diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
index 431a9ebdea..9855bec520 100644
--- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
@@ -54,6 +54,11 @@ namespace MyNamespace {
MyEnum2,
MyEnum3
};
+ enum class MyScopedEnum {
+ Enum1,
+ Enum2,
+ Enum3
+ };
enum MyAnotherEnum {
MyAnotherEnum1 = 1,
MyAnotherEnum2 = 2,
@@ -64,7 +69,13 @@ namespace MyNamespace {
MyFlag2 = 0x02,
MyFlag3 = 0x04
};
+ enum class MyScopedFlag {
+ MyFlag1 = 0x10,
+ MyFlag2 = 0x20,
+ MyFlag3 = 0x40
+ };
Q_DECLARE_FLAGS(MyFlags, MyFlag)
+ Q_DECLARE_FLAGS(MyScopedFlags, MyScopedFlag)
MyEnum myEnum() const { return m_enum; }
void setMyEnum(MyEnum val) { m_enum = val; }
@@ -79,8 +90,10 @@ namespace MyNamespace {
{ }
private:
Q_ENUM(MyEnum)
+ Q_ENUM(MyScopedEnum)
Q_ENUM(MyAnotherEnum)
Q_FLAG(MyFlags)
+ Q_FLAG(MyScopedFlags)
MyEnum m_enum;
MyFlags m_flags;
@@ -1730,20 +1743,35 @@ void tst_QMetaObject::signalIndex()
void tst_QMetaObject::enumDebugStream()
{
- QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyEnum(MyEnum2) world ");
- MyNamespace::MyClass::MyEnum e = MyNamespace::MyClass::MyEnum2;
- qDebug() << "hello" << e << "world";
+ QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyEnum2 world ");
+ qDebug() << "hello" << MyNamespace::MyClass::MyEnum2 << "world";
+
+ QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyScopedEnum::Enum3 scoped world ");
+ qDebug() << "hello" << MyNamespace::MyClass::MyScopedEnum::Enum3 << "scoped world";
- QTest::ignoreMessage(QtDebugMsg, "Qt::WindowType(WindowTitleHint) Qt::WindowType(Window) Qt::WindowType(Desktop) Qt::WindowType(WindowSystemMenuHint)");
- qDebug() << Qt::WindowTitleHint << Qt::Window <<Qt::Desktop << Qt::WindowSystemMenuHint;
+ QTest::ignoreMessage(QtDebugMsg, "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint");
+ qDebug() << Qt::WindowTitleHint << Qt::Window << Qt::Desktop << Qt::WindowSystemMenuHint;
- QTest::ignoreMessage(QtDebugMsg, "hello QFlags<MyNamespace::MyClass::MyFlags>(MyFlag1) world");
+ QTest::ignoreMessage(QtDebugMsg, "hello QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) world");
MyNamespace::MyClass::MyFlags f1 = MyNamespace::MyClass::MyFlag1;
qDebug() << "hello" << f1 << "world";
MyNamespace::MyClass::MyFlags f2 = MyNamespace::MyClass::MyFlag2 | MyNamespace::MyClass::MyFlag3;
- QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyFlags>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlags>(MyFlag2|MyFlag3)");
+ QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)");
qDebug() << f1 << f2;
+
+ QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)");
+ MyNamespace::MyClass::MyScopedFlags f3 = MyNamespace::MyClass::MyScopedFlag::MyFlag2;
+ qDebug() << f3;
+
+ QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)");
+ f3 |= MyNamespace::MyClass::MyScopedFlag::MyFlag3;
+ qDebug() << f3;
+
+ // Single flag recognized as enum:
+ QTest::ignoreMessage(QtDebugMsg, "MyNamespace::MyClass::MyFlag1");
+ MyNamespace::MyClass::MyFlag f4 = MyNamespace::MyClass::MyFlag1;
+ qDebug() << f4;
}
void tst_QMetaObject::inherits_data()
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
index 6bb031e357..56623773a2 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
@@ -830,6 +830,7 @@ void tst_QMetaObjectBuilder::enumerator()
// Modify the attributes on enum1.
enum1.setIsFlag(true);
enum1.setIsScoped(true);
+ enum1.setEnumName(QByteArrayLiteral("fooFlag"));
QCOMPARE(enum1.addKey("ABC", 0), 0);
QCOMPARE(enum1.addKey("DEF", 1), 1);
QCOMPARE(enum1.addKey("GHI", -1), 2);
@@ -838,6 +839,7 @@ void tst_QMetaObjectBuilder::enumerator()
QCOMPARE(enum1.name(), QByteArray("foo"));
QVERIFY(enum1.isFlag());
QVERIFY(enum1.isScoped());
+ QCOMPARE(enum1.enumName(), QByteArray("fooFlag"));
QCOMPARE(enum1.keyCount(), 3);
QCOMPARE(enum1.index(), 0);
QCOMPARE(enum1.key(0), QByteArray("ABC"));
diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
index ad148ccc7f..d70befecfd 100644
--- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
+++ b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qmetatype
-QT = core testlib
+QT = core-private testlib
INCLUDEPATH += $$PWD/../../../other/qvariant_common
SOURCES = tst_qmetatype.cpp
TESTDATA=./typeFlags.bin
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index e312199980..5d9b5ca95c 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -29,6 +29,7 @@
#include <QtCore>
#include <QtTest/QtTest>
+#include <QtCore/private/qmetaobjectbuilder_p.h>
#include "tst_qmetatype.h"
#include "tst_qvariant_common.h"
@@ -38,6 +39,7 @@
#endif
#include <algorithm>
+#include <memory>
// mingw gcc 4.8 also takes way too long, letting the CI system abort the test
#if defined(__MINGW32__)
@@ -52,12 +54,19 @@ class tst_QMetaType: public QObject
Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
public:
+ struct GadgetPropertyType {
+ QByteArray type;
+ QByteArray name;
+ QVariant testData;
+ };
+
tst_QMetaType() { propList << 42 << "Hello"; }
QList<QVariant> prop() const { return propList; }
void setProp(const QList<QVariant> &list) { propList = list; }
private:
+ void registerGadget(const char * name, const QVector<GadgetPropertyType> &gadgetProperties);
QList<QVariant> propList;
private slots:
@@ -89,6 +98,7 @@ private slots:
void flagsBinaryCompatibility5_0();
void construct_data();
void construct();
+ void typedConstruct();
void constructCopy_data();
void constructCopy();
void typedefs();
@@ -115,6 +125,128 @@ private slots:
void customDebugStream();
};
+struct BaseGenericType
+{
+ int m_typeId = -1;
+ virtual void *constructor(int typeId, void *where, const void *copy) = 0;
+ virtual void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) = 0;
+ virtual void saveOperator(QDataStream & out) const = 0;
+ virtual void loadOperator(QDataStream &in) = 0;
+ virtual ~BaseGenericType() {}
+};
+
+struct GenericGadgetType : BaseGenericType
+{
+ void *constructor(int typeId, void *where, const void *copy) override
+ {
+ GenericGadgetType *ret = where ? new(where) GenericGadgetType : new GenericGadgetType;
+ ret->m_typeId = typeId;
+ if (copy) {
+ Q_ASSERT(ret->m_typeId == reinterpret_cast<const GenericGadgetType*>(copy)->m_typeId);
+ *ret = *reinterpret_cast<const GenericGadgetType*>(copy);
+ } else {
+ ret->properties = properties;
+ }
+ return ret;
+ }
+
+ void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) override
+ {
+ if (_c == QMetaObject::ReadProperty) {
+ if (_id < properties.size()) {
+ const auto &prop = properties.at(_id);
+ QMetaType::destruct(int(prop.userType()), _a[0]);
+ QMetaType::construct(int(prop.userType()), _a[0], prop.constData());
+ }
+ } else if (_c == QMetaObject::WriteProperty) {
+ if (_id < properties.size()) {
+ auto & prop = properties[_id];
+ prop = QVariant(prop.userType(), _a[0]);
+ }
+ }
+ }
+
+ void saveOperator(QDataStream & out) const override
+ {
+ for (const auto &prop : properties)
+ out << prop;
+ }
+
+ void loadOperator(QDataStream &in) override
+ {
+ for (auto &prop : properties)
+ in >> prop;
+ }
+ QVector<QVariant> properties;
+};
+
+struct GenericPODType : BaseGenericType
+{
+ // BaseGenericType interface
+ void *constructor(int typeId, void *where, const void *copy) override
+ {
+ GenericPODType *ret = where ? new(where) GenericPODType : new GenericPODType;
+ ret->m_typeId = typeId;
+ if (copy) {
+ Q_ASSERT(ret->m_typeId == reinterpret_cast<const GenericPODType*>(copy)->m_typeId);
+ *ret = *reinterpret_cast<const GenericPODType*>(copy);
+ } else {
+ ret->podData = podData;
+ }
+ return ret;
+ }
+
+ void staticMetacallFunction(QMetaObject::Call _c, int _id, void **_a) override
+ {
+ Q_UNUSED(_c);
+ Q_UNUSED(_id);
+ Q_UNUSED(_a);
+ Q_ASSERT(false);
+ }
+
+ void saveOperator(QDataStream &out) const override
+ {
+ out << podData;
+ }
+ void loadOperator(QDataStream &in) override
+ {
+ in >> podData;
+ }
+ QByteArray podData;
+};
+
+using RegisteredType = QPair<std::shared_ptr<BaseGenericType>, std::shared_ptr<QMetaObject>>;
+static QHash<int, RegisteredType> s_managedTypes;
+
+static void GadgetsStaticMetacallFunction(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+ reinterpret_cast<BaseGenericType*>(_o)->staticMetacallFunction(_c, _id, _a);
+}
+
+static void GadgetTypedDestructor(int typeId, void *ptr)
+{
+ QCOMPARE(typeId, reinterpret_cast<BaseGenericType*>(ptr)->m_typeId);
+ reinterpret_cast<BaseGenericType*>(ptr)->~BaseGenericType();
+}
+
+static void *GadgetTypedConstructor(int type, void *where, const void *copy)
+{
+ auto it = s_managedTypes.find(type);
+ if (it == s_managedTypes.end())
+ return nullptr; // crash the test
+ return it->first->constructor(type, where, copy);
+}
+
+static void GadgetSaveOperator(QDataStream & out, const void *data)
+{
+ reinterpret_cast<const BaseGenericType *>(data)->saveOperator(out);
+}
+
+static void GadgetLoadOperator(QDataStream &in, void *data)
+{
+ reinterpret_cast<BaseGenericType *>(data)->loadOperator(in);
+}
+
struct Foo { int i; };
@@ -149,6 +281,34 @@ class GadgetDerivedAndTyped : public CustomGadget {};
Q_DECLARE_METATYPE(GadgetDerivedAndTyped<int>)
Q_DECLARE_METATYPE(GadgetDerivedAndTyped<int>*)
+void tst_QMetaType::registerGadget(const char *name, const QVector<GadgetPropertyType> &gadgetProperties)
+{
+ QMetaObjectBuilder gadgetBuilder;
+ gadgetBuilder.setClassName(name);
+ QMetaObjectBuilder::MetaObjectFlags metaObjectflags = QMetaObjectBuilder::DynamicMetaObject | QMetaObjectBuilder::PropertyAccessInStaticMetaCall;
+ gadgetBuilder.setFlags(metaObjectflags);
+ auto dynamicGadgetProperties = std::make_shared<GenericGadgetType>();
+ for (const auto &prop : gadgetProperties) {
+ int propertyType = QMetaType::type(prop.type);
+ dynamicGadgetProperties->properties.push_back(QVariant(QVariant::Type(propertyType)));
+ auto dynamicPropery = gadgetBuilder.addProperty(prop.name, prop.type);
+ dynamicPropery.setWritable(true);
+ dynamicPropery.setReadable(true);
+ }
+ auto meta = gadgetBuilder.toMetaObject();
+ meta->d.static_metacall = &GadgetsStaticMetacallFunction;
+ meta->d.superdata = nullptr;
+ const auto flags = QMetaType::WasDeclaredAsMetaType | QMetaType::IsGadget | QMetaType::NeedsConstruction | QMetaType::NeedsDestruction;
+ int gadgetTypeId = QMetaType::registerType(name,
+ &GadgetTypedDestructor,
+ &GadgetTypedConstructor,
+ sizeof(GenericGadgetType),
+ flags, meta);
+ QVERIFY(gadgetTypeId > 0);
+ QMetaType::registerStreamOperators(gadgetTypeId, &GadgetSaveOperator, &GadgetLoadOperator);
+ s_managedTypes[gadgetTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{meta, [](QMetaObject *ptr){ ::free(ptr); }});
+}
+
void tst_QMetaType::defined()
{
QCOMPARE(int(QMetaTypeId2<QString>::Defined), 1);
@@ -906,6 +1066,90 @@ FOR_EACH_CORE_METATYPE(RETURN_CONSTRUCT_FUNCTION)
TypeTestFunctionGetter::get(type)();
}
+void tst_QMetaType::typedConstruct()
+{
+ auto testMetaObjectWriteOnGadget = [](QVariant &gadget, const QVector<GadgetPropertyType> &properties)
+ {
+ auto metaObject = QMetaType::metaObjectForType(gadget.userType());
+ QVERIFY(metaObject != nullptr);
+ QCOMPARE(metaObject->methodCount(), 0);
+ QCOMPARE(metaObject->propertyCount(), properties.size());
+ for (int i = 0; i < metaObject->propertyCount(); ++i) {
+ auto prop = metaObject->property(i);
+ QCOMPARE(properties[i].name, prop.name());
+ QCOMPARE(properties[i].type, prop.typeName());
+ prop.writeOnGadget(gadget.data(), properties[i].testData);
+ }
+ };
+
+ auto testMetaObjectReadOnGadget = [](QVariant gadget, const QVector<GadgetPropertyType> &properties)
+ {
+ auto metaObject = QMetaType::metaObjectForType(gadget.userType());
+ QVERIFY(metaObject != nullptr);
+ QCOMPARE(metaObject->methodCount(), 0);
+ QCOMPARE(metaObject->propertyCount(), properties.size());
+ for (int i = 0; i < metaObject->propertyCount(); ++i) {
+ auto prop = metaObject->property(i);
+ QCOMPARE(properties[i].name, prop.name());
+ QCOMPARE(properties[i].type, prop.typeName());
+ if (!QMetaType::typeFlags(prop.userType()).testFlag(QMetaType::IsGadget))
+ QCOMPARE(properties[i].testData, prop.readOnGadget(gadget.constData()));
+ }
+ };
+
+ QVector<GadgetPropertyType> dynamicGadget1 = {
+ {"int", "int_prop", 34526},
+ {"float", "float_prop", 1.23f},
+ {"QString", "string_prop", QString{"Test QString"}}
+ };
+ registerGadget("DynamicGadget1", dynamicGadget1);
+
+ QVariant testGadget1(QVariant::Type(QMetaType::type("DynamicGadget1")));
+ testMetaObjectWriteOnGadget(testGadget1, dynamicGadget1);
+ testMetaObjectReadOnGadget(testGadget1, dynamicGadget1);
+
+
+ QVector<GadgetPropertyType> dynamicGadget2 = {
+ {"int", "int_prop", 512},
+ {"double", "double_prop", 4.56},
+ {"QString", "string_prop", QString{"Another String"}},
+ {"DynamicGadget1", "dynamicGadget1_prop", testGadget1}
+ };
+ registerGadget("DynamicGadget2", dynamicGadget2);
+ QVariant testGadget2(QVariant::Type(QMetaType::type("DynamicGadget2")));
+ testMetaObjectWriteOnGadget(testGadget2, dynamicGadget2);
+ testMetaObjectReadOnGadget(testGadget2, dynamicGadget2);
+ auto g2mo = QMetaType::metaObjectForType(testGadget2.userType());
+ auto dynamicGadget1_prop = g2mo->property(g2mo->indexOfProperty("dynamicGadget1_prop"));
+ testMetaObjectReadOnGadget(dynamicGadget1_prop.readOnGadget(testGadget2.constData()), dynamicGadget1);
+
+
+ // Register POD
+ const QByteArray myPodTesData = "My POD test data";
+ const char podTypeName[] = "DynamicPOD";
+ auto dynamicGadgetProperties = std::make_shared<GenericPODType>();
+ dynamicGadgetProperties->podData = myPodTesData;
+ const auto flags = QMetaType::NeedsConstruction | QMetaType::NeedsDestruction;
+ int podTypeId = QMetaType::registerType(podTypeName,
+ &GadgetTypedDestructor,
+ &GadgetTypedConstructor,
+ sizeof(GenericGadgetType),
+ flags, nullptr);
+ QVERIFY(podTypeId > 0);
+ QMetaType::registerStreamOperators(podTypeId, &GadgetSaveOperator, &GadgetLoadOperator);
+ s_managedTypes[podTypeId] = qMakePair(dynamicGadgetProperties, std::shared_ptr<QMetaObject>{});
+
+ // Test POD
+ QCOMPARE(podTypeId, QMetaType::type(podTypeName));
+ QVariant podVariant{QVariant::Type(podTypeId)};
+ QCOMPARE(myPodTesData, static_cast<const GenericPODType *>(reinterpret_cast<const BaseGenericType *>(podVariant.constData()))->podData);
+
+ QVariant podVariant1{podVariant};
+ podVariant1.detach(); // Test stream operators
+ static_cast<GenericPODType *>(reinterpret_cast<BaseGenericType *>(podVariant.data()))->podData.clear();
+ QCOMPARE(myPodTesData, static_cast<const GenericPODType *>(reinterpret_cast<const BaseGenericType *>(podVariant1.constData()))->podData);
+}
+
template<int ID>
static void testConstructCopyHelper()
{
@@ -1574,6 +1818,9 @@ DECLARE_NONSTREAMABLE(QJsonValue)
DECLARE_NONSTREAMABLE(QJsonObject)
DECLARE_NONSTREAMABLE(QJsonArray)
DECLARE_NONSTREAMABLE(QJsonDocument)
+DECLARE_NONSTREAMABLE(QCborValue)
+DECLARE_NONSTREAMABLE(QCborArray)
+DECLARE_NONSTREAMABLE(QCborMap)
DECLARE_NONSTREAMABLE(QObject*)
DECLARE_NONSTREAMABLE(QWidget*)
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
index 93ff33bb67..6bda9638f7 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
@@ -273,6 +273,24 @@ template<> struct TestValueFactory<QMetaType::QJsonDocument> {
);
}
};
+
+template<> struct TestValueFactory<QMetaType::QCborSimpleType> {
+ static QCborSimpleType *create() { return new QCborSimpleType(QCborSimpleType::True); }
+};
+template<> struct TestValueFactory<QMetaType::QCborValue> {
+ static QCborValue *create() { return new QCborValue(123.); }
+};
+template<> struct TestValueFactory<QMetaType::QCborMap> {
+ static QCborMap *create() {
+ return new QCborMap{{0, 0}, {"Hello", 1}, {1, nullptr}};
+ }
+};
+template<> struct TestValueFactory<QMetaType::QCborArray> {
+ static QCborArray *create() {
+ return new QCborArray{0, 1, -2, 2.5, false, nullptr, "Hello", QByteArray("World") };
+ }
+};
+
template<> struct TestValueFactory<QMetaType::QVariant> {
static QVariant *create() { return new QVariant(QStringList(QStringList() << "Q" << "t")); }
};
diff --git a/tests/auto/corelib/kernel/qobject/.gitignore b/tests/auto/corelib/kernel/qobject/.gitignore
index 7970e32c8f..d609065333 100644
--- a/tests/auto/corelib/kernel/qobject/.gitignore
+++ b/tests/auto/corelib/kernel/qobject/.gitignore
@@ -1,3 +1,7 @@
tst_qobject
-signalbug/signalbug
-signalbug/signalbug.exe
+signalbug_helper
+signalbug_helper.exe
+debug/signalbug_helper
+release/signalbug_helper
+debug/signalbug_helper.exe
+release/signalbug_helper.exe
diff --git a/tests/auto/corelib/kernel/qobject/qobject.pro b/tests/auto/corelib/kernel/qobject/qobject.pro
index 978aab86c1..75ad7b5f14 100644
--- a/tests/auto/corelib/kernel/qobject/qobject.pro
+++ b/tests/auto/corelib/kernel/qobject/qobject.pro
@@ -1,8 +1,4 @@
TEMPLATE = subdirs
-!winrt {
- test.depends = signalbug
- SUBDIRS += signalbug
-}
-
-SUBDIRS += test
+SUBDIRS += test.pro
+!winrt: SUBDIRS += signalbug
diff --git a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro
index cc51b4c661..d21b3a62a9 100644
--- a/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro
+++ b/tests/auto/corelib/kernel/qobject/signalbug/signalbug.pro
@@ -1,11 +1,6 @@
-CONFIG -= app_bundle debug_and_release
-CONFIG += console
-DESTDIR = ./
QT = core
HEADERS += signalbug.h
SOURCES += signalbug.cpp
-# This app is testdata for tst_qobject
-target.path = $$[QT_INSTALL_TESTS]/tst_qobject/$$TARGET
-INSTALLS += target
+load(qt_test_helper)
diff --git a/tests/auto/corelib/kernel/qobject/test.pro b/tests/auto/corelib/kernel/qobject/test.pro
new file mode 100644
index 0000000000..af5203e152
--- /dev/null
+++ b/tests/auto/corelib/kernel/qobject/test.pro
@@ -0,0 +1,10 @@
+CONFIG += testcase console
+
+QT = core-private network testlib
+TARGET = tst_qobject
+SOURCES = tst_qobject.cpp
+
+# Force C++17 if available (needed due to P0012R1)
+contains(QT_CONFIG, c++1z): CONFIG += c++1z
+
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/kernel/qobject/test/test.pro b/tests/auto/corelib/kernel/qobject/test/test.pro
deleted file mode 100644
index 4e77cb48c5..0000000000
--- a/tests/auto/corelib/kernel/qobject/test/test.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-CONFIG += testcase console
-TARGET = ../tst_qobject
-QT = core-private network testlib
-SOURCES = ../tst_qobject.cpp
-
-# Force C++17 if available (needed due to P0012R1)
-contains(QT_CONFIG, c++1z): CONFIG += c++1z
-
-!winrt: TEST_HELPER_INSTALLS = ../signalbug/signalbug
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index ec57522f48..68c6ece583 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -55,7 +55,6 @@ class tst_QObject : public QObject
{
Q_OBJECT
private slots:
- void initTestCase();
void disconnect();
void connectSlotsByName();
void connectSignalsToSignalsWithDefaultArguments();
@@ -145,6 +144,7 @@ private slots:
void disconnectDoesNotLeakFunctor();
void contextDoesNotLeakFunctor();
void connectBase();
+ void connectWarnings();
void qmlConnect();
void exceptions();
void noDeclarativeParentChangedOnDestruction();
@@ -282,14 +282,6 @@ static void playWithObjects()
}
}
-void tst_QObject::initTestCase()
-{
-#if QT_CONFIG(process)
- const QString testDataDir = QFileInfo(QFINDTESTDATA("signalbug")).absolutePath();
- QVERIFY2(QDir::setCurrent(testDataDir), qPrintable("Could not chdir to " + testDataDir));
-#endif
-}
-
void tst_QObject::disconnect()
{
SenderObject *s = new SenderObject;
@@ -3026,7 +3018,7 @@ void tst_QObject::recursiveSignalEmission()
#else
QProcess proc;
// signalbug helper app should always be next to this test binary
- const QString path = QStringLiteral("signalbug/signalbug");
+ const QString path = QStringLiteral("signalbug_helper");
proc.start(path);
QVERIFY2(proc.waitForStarted(), qPrintable(QString::fromLatin1("Cannot start '%1': %2").arg(path, proc.errorString())));
QVERIFY(proc.waitForFinished());
@@ -6697,6 +6689,26 @@ void tst_QObject::connectBase()
QCOMPARE( r1.count_slot3, 1 );
}
+void tst_QObject::connectWarnings()
+{
+ SubSender sub;
+ SenderObject obj;
+ ReceiverObject r1;
+ r1.reset();
+
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid null parameter");
+ connect(nullptr, &SubSender::signal1, &r1, &ReceiverObject::slot1);
+
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SubSender, Unknown): invalid null parameter");
+ connect(&sub, &SubSender::signal1, nullptr, &ReceiverObject::slot1);
+
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid null parameter");
+ connect(nullptr, &SenderObject::signal1, &r1, &ReceiverObject::slot1);
+
+ QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, Unknown): invalid null parameter");
+ connect(&obj, &SenderObject::signal1, nullptr, &ReceiverObject::slot1);
+}
+
struct QmlReceiver : public QtPrivate::QSlotObjectBase
{
int callCount;
diff --git a/tests/auto/corelib/kernel/qsharedmemory/sharedmemoryhelper/main.cpp b/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/main.cpp
index ffbad37d82..ffbad37d82 100644
--- a/tests/auto/corelib/kernel/qsharedmemory/sharedmemoryhelper/main.cpp
+++ b/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/main.cpp
diff --git a/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/producerconsumer.pro b/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/producerconsumer.pro
new file mode 100644
index 0000000000..a6156ed5b6
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsharedmemory/producerconsumer/producerconsumer.pro
@@ -0,0 +1,5 @@
+QT = core testlib
+
+SOURCES += main.cpp
+
+load(qt_test_helper)
diff --git a/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro b/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro
index 3a4697750e..323d5bbd37 100644
--- a/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro
+++ b/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
qtConfig(sharedmemory) {
- !winrt: SUBDIRS = sharedmemoryhelper
- SUBDIRS += test
+ !winrt: SUBDIRS = producerconsumer
+ SUBDIRS += test.pro
}
diff --git a/tests/auto/corelib/kernel/qsharedmemory/sharedmemoryhelper/sharedmemoryhelper.pro b/tests/auto/corelib/kernel/qsharedmemory/sharedmemoryhelper/sharedmemoryhelper.pro
deleted file mode 100644
index 389015d504..0000000000
--- a/tests/auto/corelib/kernel/qsharedmemory/sharedmemoryhelper/sharedmemoryhelper.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-QT = core testlib
-
-win32: CONFIG += console
-mac:CONFIG -= app_bundle
-
-SOURCES += main.cpp
-TARGET = helperbinary
-
-CONFIG(debug_and_release) {
- CONFIG(debug, debug|release) {
- DESTDIR = ../debug
- } else {
- DESTDIR = ../release
- }
-} else {
- DESTDIR = ..
-}
diff --git a/tests/auto/corelib/kernel/qsharedmemory/test.pro b/tests/auto/corelib/kernel/qsharedmemory/test.pro
new file mode 100644
index 0000000000..8b3badadb0
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsharedmemory/test.pro
@@ -0,0 +1,8 @@
+CONFIG += testcase
+
+QT = core-private testlib
+
+TARGET = tst_qsharedmemory
+SOURCES += tst_qsharedmemory.cpp
+
+linux: LIBS += -lrt
diff --git a/tests/auto/corelib/kernel/qsharedmemory/test/test.pro b/tests/auto/corelib/kernel/qsharedmemory/test/test.pro
deleted file mode 100644
index 61124c27ee..0000000000
--- a/tests/auto/corelib/kernel/qsharedmemory/test/test.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-CONFIG += testcase
-
-QT = core-private testlib
-
-linux:LIBS += -lrt
-
-SOURCES += tst_qsharedmemory.cpp
-TARGET = tst_qsharedmemory
-
-CONFIG(debug_and_release) {
- CONFIG(debug, debug|release) {
- DESTDIR = ../debug
- } else {
- DESTDIR = ../release
- }
-} else {
- DESTDIR = ..
-}
diff --git a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp b/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp
deleted file mode 100644
index f81324b894..0000000000
--- a/tests/auto/corelib/kernel/qsharedmemory/test/tst_qsharedmemory.cpp
+++ /dev/null
@@ -1,839 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QDebug>
-#include <QFile>
-#if QT_CONFIG(process)
-# include <QProcess>
-#endif
-#include <QSharedMemory>
-#include <QTest>
-#include <QThread>
-
-#define EXISTING_SHARE "existing"
-#define EXISTING_SIZE 1024
-
-Q_DECLARE_METATYPE(QSharedMemory::SharedMemoryError)
-Q_DECLARE_METATYPE(QSharedMemory::AccessMode)
-
-class tst_QSharedMemory : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QSharedMemory();
- virtual ~tst_QSharedMemory();
-
-public Q_SLOTS:
- void init();
- void initTestCase();
- void cleanup();
-
-
-private slots:
- // basics
- void constructor();
- void key_data();
- void key();
- void create_data();
- void create();
- void attach_data();
- void attach();
- void lock();
-
- // custom edge cases
-#ifndef Q_OS_HPUX
- void removeWhileAttached();
-#endif
- void emptyMemory();
-#if !defined(Q_OS_WIN)
- void readOnly();
-#endif
-
- // basics all together
-#ifndef Q_OS_HPUX
- void simpleProducerConsumer_data();
- void simpleProducerConsumer();
- void simpleDoubleProducerConsumer();
-#endif
-
- // with threads
- void simpleThreadedProducerConsumer_data();
- void simpleThreadedProducerConsumer();
-
- // with processes
- void simpleProcessProducerConsumer_data();
- void simpleProcessProducerConsumer();
-
- // extreme cases
- void useTooMuchMemory();
-#if !defined(Q_OS_HPUX)
- void attachTooMuch();
-#endif
-
- // unique keys
- void uniqueKey_data();
- void uniqueKey();
-
-protected:
- static QString helperBinary();
- int remove(const QString &key);
-
- QString rememberKey(const QString &key)
- {
- if (key == EXISTING_SHARE)
- return key;
- if (!keys.contains(key)) {
- keys.append(key);
- remove(key);
- }
- return key;
- }
-
- QStringList keys;
- QList<QSharedMemory*> jail;
- QSharedMemory *existingSharedMemory;
-
-private:
- const QString m_helperBinary;
-};
-
-tst_QSharedMemory::tst_QSharedMemory()
- : existingSharedMemory(0)
- , m_helperBinary(tst_QSharedMemory::helperBinary())
-{
-}
-
-tst_QSharedMemory::~tst_QSharedMemory()
-{
-}
-
-void tst_QSharedMemory::initTestCase()
-{
-#if QT_CONFIG(process)
- QVERIFY2(!m_helperBinary.isEmpty(), "Could not find helper binary");
-#endif
-}
-
-void tst_QSharedMemory::init()
-{
- existingSharedMemory = new QSharedMemory(EXISTING_SHARE);
- if (!existingSharedMemory->create(EXISTING_SIZE)) {
- QCOMPARE(existingSharedMemory->error(), QSharedMemory::AlreadyExists);
- }
-}
-
-void tst_QSharedMemory::cleanup()
-{
- delete existingSharedMemory;
- qDeleteAll(jail.begin(), jail.end());
- jail.clear();
-
- keys.append(EXISTING_SHARE);
- for (int i = 0; i < keys.count(); ++i) {
- QSharedMemory sm(keys.at(i));
- if (!sm.create(1024)) {
- //if (sm.error() != QSharedMemory::KeyError)
- // qWarning() << "test cleanup: remove failed:" << keys.at(i) << sm.error() << sm.errorString();
- sm.attach();
- sm.detach();
- remove(keys.at(i));
- }
- }
-}
-
-#ifndef Q_OS_WIN
-#include <private/qsharedmemory_p.h>
-#include <sys/types.h>
-#ifndef QT_POSIX_IPC
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#else
-#include <sys/mman.h>
-#endif // QT_POSIX_IPC
-#include <errno.h>
-#endif
-
-QString tst_QSharedMemory::helperBinary()
-{
- QString binary = QStringLiteral("helperbinary");
-#ifdef Q_OS_WIN
- binary += QStringLiteral(".exe");
-#endif
- return QFINDTESTDATA(binary);
-}
-
-int tst_QSharedMemory::remove(const QString &key)
-{
-#ifdef Q_OS_WIN
- Q_UNUSED(key);
- return 0;
-#else
- // On unix the shared memory might exists from a previously failed test
- // or segfault, remove it it does
- if (key.isEmpty())
- return -1;
-
- // ftok requires that an actual file exists somewhere
- QString fileName = QSharedMemoryPrivate::makePlatformSafeKey(key);
- if (!QFile::exists(fileName)) {
- //qDebug() << "exits failed";
- return -2;
- }
-
-#ifndef QT_POSIX_IPC
- int unix_key = ftok(fileName.toLatin1().constData(), 'Q');
- if (-1 == unix_key) {
- qDebug() << "ftok failed";
- return -3;
- }
-
- int id = shmget(unix_key, 0, 0600);
- if (-1 == id) {
- qDebug() << "shmget failed" << strerror(errno);
- return -4;
- }
-
- struct shmid_ds shmid_ds;
- if (-1 == shmctl(id, IPC_RMID, &shmid_ds)) {
- qDebug() << "shmctl failed";
- return -5;
- }
-#else
- if (shm_unlink(QFile::encodeName(fileName).constData()) == -1) {
- qDebug() << "shm_unlink failed";
- return -5;
- }
-#endif // QT_POSIX_IPC
-
- return QFile::remove(fileName);
-#endif // Q_OS_WIN
-}
-
-/*!
- Tests the default values
- */
-void tst_QSharedMemory::constructor()
-{
- QSharedMemory sm;
- QCOMPARE(sm.key(), QString());
- QVERIFY(!sm.isAttached());
- QVERIFY(!sm.data());
- QCOMPARE(sm.size(), 0);
- QCOMPARE(sm.error(), QSharedMemory::NoError);
- QCOMPARE(sm.errorString(), QString());
-}
-
-void tst_QSharedMemory::key_data()
-{
- QTest::addColumn<QString>("constructorKey");
- QTest::addColumn<QString>("setKey");
- QTest::addColumn<QString>("setNativeKey");
-
- QTest::newRow("null, null, null") << QString() << QString() << QString();
- QTest::newRow("one, null, null") << QString("one") << QString() << QString();
- QTest::newRow("null, one, null") << QString() << QString("one") << QString();
- QTest::newRow("null, null, one") << QString() << QString() << QString("one");
- QTest::newRow("one, two, null") << QString("one") << QString("two") << QString();
- QTest::newRow("one, null, two") << QString("one") << QString() << QString("two");
- QTest::newRow("null, one, two") << QString() << QString("one") << QString("two");
- QTest::newRow("one, two, three") << QString("one") << QString("two") << QString("three");
- QTest::newRow("invalid") << QString("o/e") << QString("t/o") << QString("|x");
-}
-
-/*!
- Basic key testing
- */
-void tst_QSharedMemory::key()
-{
- QFETCH(QString, constructorKey);
- QFETCH(QString, setKey);
- QFETCH(QString, setNativeKey);
-
- QSharedMemory sm(constructorKey);
- QCOMPARE(sm.key(), constructorKey);
- QCOMPARE(sm.nativeKey().isEmpty(), constructorKey.isEmpty());
- sm.setKey(setKey);
- QCOMPARE(sm.key(), setKey);
- QCOMPARE(sm.nativeKey().isEmpty(), setKey.isEmpty());
- sm.setNativeKey(setNativeKey);
- QVERIFY(sm.key().isNull());
- QCOMPARE(sm.nativeKey(), setNativeKey);
- QCOMPARE(sm.isAttached(), false);
-
- QCOMPARE(sm.error(), QSharedMemory::NoError);
- QCOMPARE(sm.errorString(), QString());
- QVERIFY(!sm.data());
- QCOMPARE(sm.size(), 0);
-
- QCOMPARE(sm.detach(), false);
-}
-
-void tst_QSharedMemory::create_data()
-{
- QTest::addColumn<QString>("key");
- QTest::addColumn<int>("size");
- QTest::addColumn<bool>("canCreate");
- QTest::addColumn<QSharedMemory::SharedMemoryError>("error");
-
- QTest::newRow("null key") << QString() << 1024
- << false << QSharedMemory::KeyError;
- QTest::newRow("-1 size") << QString("negsize") << -1
- << false << QSharedMemory::InvalidSize;
- QTest::newRow("nor size") << QString("norsize") << 1024
- << true << QSharedMemory::NoError;
- QTest::newRow("already exists") << QString(EXISTING_SHARE) << EXISTING_SIZE
- << false << QSharedMemory::AlreadyExists;
-}
-
-/*!
- Basic create testing
- */
-void tst_QSharedMemory::create()
-{
- QFETCH(QString, key);
- QFETCH(int, size);
- QFETCH(bool, canCreate);
- QFETCH(QSharedMemory::SharedMemoryError, error);
-
- QSharedMemory sm(rememberKey(key));
- QCOMPARE(sm.create(size), canCreate);
- if (sm.error() != error)
- qDebug() << sm.errorString();
- QCOMPARE(sm.key(), key);
- if (canCreate) {
- QCOMPARE(sm.errorString(), QString());
- QVERIFY(sm.data() != 0);
- QVERIFY(sm.size() != 0);
- } else {
- QVERIFY(!sm.data());
- QVERIFY(sm.errorString() != QString());
- }
-}
-
-void tst_QSharedMemory::attach_data()
-{
- QTest::addColumn<QString>("key");
- QTest::addColumn<bool>("exists");
- QTest::addColumn<QSharedMemory::SharedMemoryError>("error");
-
- QTest::newRow("null key") << QString() << false << QSharedMemory::KeyError;
- QTest::newRow("doesn't exists") << QString("doesntexists") << false << QSharedMemory::NotFound;
-
- // HPUX doesn't allow for multiple attaches per process.
-#ifndef Q_OS_HPUX
- QTest::newRow("already exists") << QString(EXISTING_SHARE) << true << QSharedMemory::NoError;
-#endif
-}
-
-/*!
- Basic attach/detach testing
- */
-void tst_QSharedMemory::attach()
-{
- QFETCH(QString, key);
- QFETCH(bool, exists);
- QFETCH(QSharedMemory::SharedMemoryError, error);
-
- QSharedMemory sm(key);
- QCOMPARE(sm.attach(), exists);
- QCOMPARE(sm.isAttached(), exists);
- QCOMPARE(sm.error(), error);
- QCOMPARE(sm.key(), key);
- if (exists) {
- QVERIFY(sm.data() != 0);
- QVERIFY(sm.size() != 0);
- QCOMPARE(sm.errorString(), QString());
- QVERIFY(sm.detach());
- // Make sure detach doesn't screw up something and we can't re-attach.
- QVERIFY(sm.attach());
- QVERIFY(sm.data() != 0);
- QVERIFY(sm.size() != 0);
- QVERIFY(sm.detach());
- QCOMPARE(sm.size(), 0);
- QVERIFY(!sm.data());
- } else {
- QVERIFY(!sm.data());
- QCOMPARE(sm.size(), 0);
- QVERIFY(sm.errorString() != QString());
- QVERIFY(!sm.detach());
- }
-}
-
-void tst_QSharedMemory::lock()
-{
- QSharedMemory shm;
- QVERIFY(!shm.lock());
- QCOMPARE(shm.error(), QSharedMemory::LockError);
-
- shm.setKey(QLatin1String("qsharedmemory"));
-
- QVERIFY(!shm.lock());
- QCOMPARE(shm.error(), QSharedMemory::LockError);
-
- QVERIFY(shm.create(100));
- QVERIFY(shm.lock());
- QTest::ignoreMessage(QtWarningMsg, "QSharedMemory::lock: already locked");
- QVERIFY(shm.lock());
- // we didn't unlock(), so ignore the warning from auto-detach in destructor
- QTest::ignoreMessage(QtWarningMsg, "QSharedMemory::lock: already locked");
-}
-
-/*!
- Other shared memory are allowed to be attached after we remove,
- but new shared memory are not allowed to attach after a remove.
- */
-// HPUX doesn't allow for multiple attaches per process.
-#ifndef Q_OS_HPUX
-void tst_QSharedMemory::removeWhileAttached()
-{
- rememberKey("one");
-
- // attach 1
- QSharedMemory *smOne = new QSharedMemory(QLatin1String("one"));
- QVERIFY(smOne->create(1024));
- QVERIFY(smOne->isAttached());
-
- // attach 2
- QSharedMemory *smTwo = new QSharedMemory(QLatin1String("one"));
- QVERIFY(smTwo->attach());
- QVERIFY(smTwo->isAttached());
-
- // detach 1 and remove, remove one first to catch another error.
- delete smOne;
- delete smTwo;
-
- // three shouldn't be able to attach
- QSharedMemory smThree(QLatin1String("one"));
- QVERIFY(!smThree.attach());
- QCOMPARE(smThree.error(), QSharedMemory::NotFound);
-}
-#endif
-
-/*!
- The memory should be set to 0 after created.
- */
-void tst_QSharedMemory::emptyMemory()
-{
- QSharedMemory sm(rememberKey(QLatin1String("voidland")));
- int size = 1024;
- QVERIFY(sm.create(size, QSharedMemory::ReadOnly));
- char *get = (char*)sm.data();
- char null = 0;
- for (int i = 0; i < size; ++i)
- QCOMPARE(get[i], null);
-}
-
-/*!
- Verify that attach with ReadOnly is actually read only
- by writing to data and causing a segfault.
-*/
-// This test opens a crash dialog on Windows.
-#if !defined(Q_OS_WIN)
-void tst_QSharedMemory::readOnly()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#elif defined(Q_OS_MACOS)
- QSKIP("QTBUG-59936: Times out on macOS", SkipAll);
-#else
- rememberKey("readonly_segfault");
- // ### on windows disable the popup somehow
- QProcess p;
- p.start(m_helperBinary, QStringList("readonly_segfault"));
- p.setProcessChannelMode(QProcess::ForwardedChannels);
- p.waitForFinished();
- QCOMPARE(p.error(), QProcess::Crashed);
-#endif
-}
-#endif
-
-/*!
- Keep making shared memory until the kernel stops us.
- */
-void tst_QSharedMemory::useTooMuchMemory()
-{
-#ifdef Q_OS_LINUX
- bool success = true;
- int count = 0;
- while (success) {
- QString key = QLatin1String("maxmemorytest_") + QString::number(count++);
- QSharedMemory *sm = new QSharedMemory(rememberKey(key));
- QVERIFY(sm);
- jail.append(sm);
- int size = 32768 * 1024;
- success = sm->create(size);
- if (!success && sm->error() == QSharedMemory::AlreadyExists) {
- // left over from a crash, clean it up
- sm->attach();
- sm->detach();
- success = sm->create(size);
- }
-
- if (!success) {
- QVERIFY(!sm->isAttached());
- QCOMPARE(sm->key(), key);
- QCOMPARE(sm->size(), 0);
- QVERIFY(!sm->data());
- if (sm->error() != QSharedMemory::OutOfResources)
- qDebug() << sm->error() << sm->errorString();
- // ### Linux won't return OutOfResources if there are not enough semaphores to use.
- QVERIFY(sm->error() == QSharedMemory::OutOfResources
- || sm->error() == QSharedMemory::LockError);
- QVERIFY(sm->errorString() != QString());
- QVERIFY(!sm->attach());
- QVERIFY(!sm->detach());
- } else {
- QVERIFY(sm->isAttached());
- }
- }
-#endif
-}
-
-/*!
- Create one shared memory (government) and see how many other shared memories (wars) we can
- attach before the system runs out of resources.
- */
-// HPUX doesn't allow for multiple attaches per process.
-#if !defined(Q_OS_HPUX)
-void tst_QSharedMemory::attachTooMuch()
-{
- QSKIP("disabled");
-
- QSharedMemory government(rememberKey("government"));
- QVERIFY(government.create(1024));
- while (true) {
- QSharedMemory *war = new QSharedMemory(government.key());
- QVERIFY(war);
- jail.append(war);
- if (!war->attach()) {
- QVERIFY(!war->isAttached());
- QCOMPARE(war->key(), government.key());
- QCOMPARE(war->size(), 0);
- QVERIFY(!war->data());
- QCOMPARE(war->error(), QSharedMemory::OutOfResources);
- QVERIFY(war->errorString() != QString());
- QVERIFY(!war->detach());
- break;
- } else {
- QVERIFY(war->isAttached());
- }
- }
-}
-#endif
-
-// HPUX doesn't allow for multiple attaches per process.
-#ifndef Q_OS_HPUX
-void tst_QSharedMemory::simpleProducerConsumer_data()
-{
- QTest::addColumn<QSharedMemory::AccessMode>("mode");
-
- QTest::newRow("readonly") << QSharedMemory::ReadOnly;
- QTest::newRow("readwrite") << QSharedMemory::ReadWrite;
-}
-
-/*!
- The basic consumer producer that rounds out the basic testing.
- If this fails then any muli-threading/process might fail (but be
- harder to debug)
-
- This doesn't require nor test any locking system.
- */
-void tst_QSharedMemory::simpleProducerConsumer()
-{
- QFETCH(QSharedMemory::AccessMode, mode);
-
- rememberKey(QLatin1String("market"));
- QSharedMemory producer(QLatin1String("market"));
- QSharedMemory consumer(QLatin1String("market"));
- int size = 512;
- QVERIFY(producer.create(size));
- QVERIFY(consumer.attach(mode));
-
- char *put = (char*)producer.data();
- char *get = (char*)consumer.data();
- // On Windows CE you always have ReadWrite access. Thus
- // ViewMapOfFile returns the same pointer
- QVERIFY(put != get);
- for (int i = 0; i < size; ++i) {
- put[i] = 'Q';
- QCOMPARE(get[i], 'Q');
- }
- QVERIFY(consumer.detach());
-}
-#endif
-
-// HPUX doesn't allow for multiple attaches per process.
-#ifndef Q_OS_HPUX
-void tst_QSharedMemory::simpleDoubleProducerConsumer()
-{
- rememberKey(QLatin1String("market"));
- QSharedMemory producer(QLatin1String("market"));
- int size = 512;
- QVERIFY(producer.create(size));
- QVERIFY(producer.detach());
- QVERIFY(producer.create(size));
-
- {
- QSharedMemory consumer(QLatin1String("market"));
- QVERIFY(consumer.attach());
- }
-}
-#endif
-
-class Consumer : public QThread
-{
-
-public:
- void run()
- {
- QSharedMemory consumer(QLatin1String("market"));
- while (!consumer.attach()) {
- if (consumer.error() != QSharedMemory::NotFound)
- qDebug() << "consumer: failed to connect" << consumer.error() << consumer.errorString();
- QVERIFY(consumer.error() == QSharedMemory::NotFound || consumer.error() == QSharedMemory::KeyError);
- QTest::qWait(1);
- }
-
- char *memory = (char*)consumer.data();
-
- int i = 0;
- while (true) {
- if (!consumer.lock())
- break;
- if (memory[0] == 'Q')
- memory[0] = ++i;
- if (memory[0] == 'E') {
- memory[1]++;
- QVERIFY(consumer.unlock());
- break;
- }
- QVERIFY(consumer.unlock());
- QTest::qWait(1);
- }
-
- QVERIFY(consumer.detach());
- }
-};
-
-class Producer : public QThread
-{
-
-public:
- Producer() : producer(QLatin1String("market"))
- {
- int size = 1024;
- if (!producer.create(size)) {
- // left over from a crash...
- if (producer.error() == QSharedMemory::AlreadyExists) {
- producer.attach();
- producer.detach();
- QVERIFY(producer.create(size));
- }
- }
- }
-
- void run()
- {
-
- char *memory = (char*)producer.data();
- memory[1] = '0';
- QTime timer;
- timer.start();
- int i = 0;
- while (i < 5 && timer.elapsed() < 5000) {
- QVERIFY(producer.lock());
- if (memory[0] == 'Q') {
- QVERIFY(producer.unlock());
- QTest::qWait(1);
- continue;
- }
- ++i;
- memory[0] = 'Q';
- QVERIFY(producer.unlock());
- QTest::qWait(1);
- }
-
- // tell everyone to quit
- QVERIFY(producer.lock());
- memory[0] = 'E';
- QVERIFY(producer.unlock());
-
- }
-
- QSharedMemory producer;
-private:
-
-};
-
-void tst_QSharedMemory::simpleThreadedProducerConsumer_data()
-{
- QTest::addColumn<bool>("producerIsThread");
- QTest::addColumn<int>("threads");
- for (int i = 0; i < 5; ++i) {
- QTest::newRow("1 consumer, producer is thread") << true << 1;
- QTest::newRow("1 consumer, producer is this") << false << 1;
- QTest::newRow("5 consumers, producer is thread") << true << 5;
- QTest::newRow("5 consumers, producer is this") << false << 5;
- }
-}
-
-/*!
- The basic producer/consumer, but this time using threads.
- */
-void tst_QSharedMemory::simpleThreadedProducerConsumer()
-{
- QFETCH(bool, producerIsThread);
- QFETCH(int, threads);
- rememberKey(QLatin1String("market"));
-
-#if defined Q_OS_HPUX && defined __ia64
- QSKIP("This test locks up on gravlaks.troll.no");
-#endif
-
- Producer p;
- QVERIFY(p.producer.isAttached());
- if (producerIsThread)
- p.start();
-
- QList<Consumer*> consumers;
- for (int i = 0; i < threads; ++i) {
- consumers.append(new Consumer());
- consumers.last()->start();
- }
-
- if (!producerIsThread)
- p.run();
-
- p.wait(5000);
- while (!consumers.isEmpty()) {
- Consumer *c = consumers.first();
- QVERIFY(c->isFinished() || c->wait(5000));
- delete consumers.takeFirst();
- }
-}
-
-void tst_QSharedMemory::simpleProcessProducerConsumer_data()
-{
-#if QT_CONFIG(process)
- QTest::addColumn<int>("processes");
- int tries = 5;
- for (int i = 0; i < tries; ++i) {
- QTest::newRow("1 process") << 1;
- QTest::newRow("5 processes") << 5;
- }
-#endif
-}
-
-/*!
- Create external processes that produce and consume.
- */
-void tst_QSharedMemory::simpleProcessProducerConsumer()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QFETCH(int, processes);
-
- QSKIP("This test is unstable: QTBUG-25655");
-
- rememberKey("market");
-
- QProcess producer;
- producer.start(m_helperBinary, QStringList("producer"));
- QVERIFY2(producer.waitForStarted(), "Could not start helper binary");
- QVERIFY2(producer.waitForReadyRead(), "Helper process failed to create shared memory segment: " +
- producer.readAllStandardError());
-
- QList<QProcess*> consumers;
- unsigned int failedProcesses = 0;
- const QStringList consumerArguments = QStringList("consumer");
- for (int i = 0; i < processes; ++i) {
- QProcess *p = new QProcess;
- p->setProcessChannelMode(QProcess::ForwardedChannels);
- p->start(m_helperBinary, consumerArguments);
- if (p->waitForStarted(2000))
- consumers.append(p);
- else
- ++failedProcesses;
- }
-
- bool consumerFailed = false;
-
- while (!consumers.isEmpty()) {
- QVERIFY(consumers.first()->waitForFinished(3000));
- if (consumers.first()->state() == QProcess::Running ||
- consumers.first()->exitStatus() != QProcess::NormalExit ||
- consumers.first()->exitCode() != 0) {
- consumerFailed = true;
- }
- delete consumers.takeFirst();
- }
- QCOMPARE(consumerFailed, false);
- QCOMPARE(failedProcesses, (unsigned int)(0));
-
- // tell the producer to exit now
- producer.write("", 1);
- producer.waitForBytesWritten();
- QVERIFY(producer.waitForFinished(5000));
-#endif
-}
-
-void tst_QSharedMemory::uniqueKey_data()
-{
- QTest::addColumn<QString>("key1");
- QTest::addColumn<QString>("key2");
-
- QTest::newRow("null == null") << QString() << QString();
- QTest::newRow("key == key") << QString("key") << QString("key");
- QTest::newRow("key1 == key1") << QString("key1") << QString("key1");
- QTest::newRow("key != key1") << QString("key") << QString("key1");
- QTest::newRow("ke1y != key1") << QString("ke1y") << QString("key1");
- QTest::newRow("key1 != key2") << QString("key1") << QString("key2");
- QTest::newRow("Noël -> Nol") << QString::fromUtf8("N\xc3\xabl") << QString("Nol");
-}
-
-void tst_QSharedMemory::uniqueKey()
-{
- QFETCH(QString, key1);
- QFETCH(QString, key2);
-
- QSharedMemory sm1(key1);
- QSharedMemory sm2(key2);
-
- bool setEqual = (key1 == key2);
- bool keyEqual = (sm1.key() == sm2.key());
- bool nativeEqual = (sm1.nativeKey() == sm2.nativeKey());
-
- QCOMPARE(keyEqual, setEqual);
- QCOMPARE(nativeEqual, setEqual);
-}
-
-QTEST_MAIN(tst_QSharedMemory)
-#include "tst_qsharedmemory.moc"
-
diff --git a/tests/auto/corelib/kernel/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/corelib/kernel/qsharedmemory/tst_qsharedmemory.cpp
new file mode 100644
index 0000000000..55deb8eb1a
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsharedmemory/tst_qsharedmemory.cpp
@@ -0,0 +1,821 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QFile>
+#if QT_CONFIG(process)
+# include <QProcess>
+#endif
+#include <QSharedMemory>
+#include <QTest>
+#include <QThread>
+
+#define EXISTING_SHARE "existing"
+#define EXISTING_SIZE 1024
+
+Q_DECLARE_METATYPE(QSharedMemory::SharedMemoryError)
+Q_DECLARE_METATYPE(QSharedMemory::AccessMode)
+
+class tst_QSharedMemory : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QSharedMemory();
+ virtual ~tst_QSharedMemory();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+
+private slots:
+ // basics
+ void constructor();
+ void key_data();
+ void key();
+ void create_data();
+ void create();
+ void attach_data();
+ void attach();
+ void lock();
+
+ // custom edge cases
+#ifndef Q_OS_HPUX
+ void removeWhileAttached();
+#endif
+ void emptyMemory();
+#if !defined(Q_OS_WIN)
+ void readOnly();
+#endif
+
+ // basics all together
+#ifndef Q_OS_HPUX
+ void simpleProducerConsumer_data();
+ void simpleProducerConsumer();
+ void simpleDoubleProducerConsumer();
+#endif
+
+ // with threads
+ void simpleThreadedProducerConsumer_data();
+ void simpleThreadedProducerConsumer();
+
+ // with processes
+ void simpleProcessProducerConsumer_data();
+ void simpleProcessProducerConsumer();
+
+ // extreme cases
+ void useTooMuchMemory();
+#if !defined(Q_OS_HPUX)
+ void attachTooMuch();
+#endif
+
+ // unique keys
+ void uniqueKey_data();
+ void uniqueKey();
+
+protected:
+ int remove(const QString &key);
+
+ QString rememberKey(const QString &key)
+ {
+ if (key == EXISTING_SHARE)
+ return key;
+ if (!keys.contains(key)) {
+ keys.append(key);
+ remove(key);
+ }
+ return key;
+ }
+
+ QStringList keys;
+ QList<QSharedMemory*> jail;
+ QSharedMemory *existingSharedMemory;
+
+private:
+ const QString m_helperBinary;
+};
+
+tst_QSharedMemory::tst_QSharedMemory()
+ : existingSharedMemory(0)
+ , m_helperBinary("producerconsumer_helper")
+{
+}
+
+tst_QSharedMemory::~tst_QSharedMemory()
+{
+}
+
+void tst_QSharedMemory::init()
+{
+ existingSharedMemory = new QSharedMemory(EXISTING_SHARE);
+ if (!existingSharedMemory->create(EXISTING_SIZE)) {
+ QCOMPARE(existingSharedMemory->error(), QSharedMemory::AlreadyExists);
+ }
+}
+
+void tst_QSharedMemory::cleanup()
+{
+ delete existingSharedMemory;
+ qDeleteAll(jail.begin(), jail.end());
+ jail.clear();
+
+ keys.append(EXISTING_SHARE);
+ for (int i = 0; i < keys.count(); ++i) {
+ QSharedMemory sm(keys.at(i));
+ if (!sm.create(1024)) {
+ //if (sm.error() != QSharedMemory::KeyError)
+ // qWarning() << "test cleanup: remove failed:" << keys.at(i) << sm.error() << sm.errorString();
+ sm.attach();
+ sm.detach();
+ remove(keys.at(i));
+ }
+ }
+}
+
+#ifndef Q_OS_WIN
+#include <private/qsharedmemory_p.h>
+#include <sys/types.h>
+#ifndef QT_POSIX_IPC
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <sys/mman.h>
+#endif // QT_POSIX_IPC
+#include <errno.h>
+#endif
+
+int tst_QSharedMemory::remove(const QString &key)
+{
+#ifdef Q_OS_WIN
+ Q_UNUSED(key);
+ return 0;
+#else
+ // On unix the shared memory might exists from a previously failed test
+ // or segfault, remove it it does
+ if (key.isEmpty())
+ return -1;
+
+ // ftok requires that an actual file exists somewhere
+ QString fileName = QSharedMemoryPrivate::makePlatformSafeKey(key);
+ if (!QFile::exists(fileName)) {
+ //qDebug() << "exits failed";
+ return -2;
+ }
+
+#ifndef QT_POSIX_IPC
+ int unix_key = ftok(fileName.toLatin1().constData(), 'Q');
+ if (-1 == unix_key) {
+ qDebug() << "ftok failed";
+ return -3;
+ }
+
+ int id = shmget(unix_key, 0, 0600);
+ if (-1 == id) {
+ qDebug() << "shmget failed" << strerror(errno);
+ return -4;
+ }
+
+ struct shmid_ds shmid_ds;
+ if (-1 == shmctl(id, IPC_RMID, &shmid_ds)) {
+ qDebug() << "shmctl failed";
+ return -5;
+ }
+#else
+ if (shm_unlink(QFile::encodeName(fileName).constData()) == -1) {
+ qDebug() << "shm_unlink failed";
+ return -5;
+ }
+#endif // QT_POSIX_IPC
+
+ return QFile::remove(fileName);
+#endif // Q_OS_WIN
+}
+
+/*!
+ Tests the default values
+ */
+void tst_QSharedMemory::constructor()
+{
+ QSharedMemory sm;
+ QCOMPARE(sm.key(), QString());
+ QVERIFY(!sm.isAttached());
+ QVERIFY(!sm.data());
+ QCOMPARE(sm.size(), 0);
+ QCOMPARE(sm.error(), QSharedMemory::NoError);
+ QCOMPARE(sm.errorString(), QString());
+}
+
+void tst_QSharedMemory::key_data()
+{
+ QTest::addColumn<QString>("constructorKey");
+ QTest::addColumn<QString>("setKey");
+ QTest::addColumn<QString>("setNativeKey");
+
+ QTest::newRow("null, null, null") << QString() << QString() << QString();
+ QTest::newRow("one, null, null") << QString("one") << QString() << QString();
+ QTest::newRow("null, one, null") << QString() << QString("one") << QString();
+ QTest::newRow("null, null, one") << QString() << QString() << QString("one");
+ QTest::newRow("one, two, null") << QString("one") << QString("two") << QString();
+ QTest::newRow("one, null, two") << QString("one") << QString() << QString("two");
+ QTest::newRow("null, one, two") << QString() << QString("one") << QString("two");
+ QTest::newRow("one, two, three") << QString("one") << QString("two") << QString("three");
+ QTest::newRow("invalid") << QString("o/e") << QString("t/o") << QString("|x");
+}
+
+/*!
+ Basic key testing
+ */
+void tst_QSharedMemory::key()
+{
+ QFETCH(QString, constructorKey);
+ QFETCH(QString, setKey);
+ QFETCH(QString, setNativeKey);
+
+ QSharedMemory sm(constructorKey);
+ QCOMPARE(sm.key(), constructorKey);
+ QCOMPARE(sm.nativeKey().isEmpty(), constructorKey.isEmpty());
+ sm.setKey(setKey);
+ QCOMPARE(sm.key(), setKey);
+ QCOMPARE(sm.nativeKey().isEmpty(), setKey.isEmpty());
+ sm.setNativeKey(setNativeKey);
+ QVERIFY(sm.key().isNull());
+ QCOMPARE(sm.nativeKey(), setNativeKey);
+ QCOMPARE(sm.isAttached(), false);
+
+ QCOMPARE(sm.error(), QSharedMemory::NoError);
+ QCOMPARE(sm.errorString(), QString());
+ QVERIFY(!sm.data());
+ QCOMPARE(sm.size(), 0);
+
+ QCOMPARE(sm.detach(), false);
+}
+
+void tst_QSharedMemory::create_data()
+{
+ QTest::addColumn<QString>("key");
+ QTest::addColumn<int>("size");
+ QTest::addColumn<bool>("canCreate");
+ QTest::addColumn<QSharedMemory::SharedMemoryError>("error");
+
+ QTest::newRow("null key") << QString() << 1024
+ << false << QSharedMemory::KeyError;
+ QTest::newRow("-1 size") << QString("negsize") << -1
+ << false << QSharedMemory::InvalidSize;
+ QTest::newRow("nor size") << QString("norsize") << 1024
+ << true << QSharedMemory::NoError;
+ QTest::newRow("already exists") << QString(EXISTING_SHARE) << EXISTING_SIZE
+ << false << QSharedMemory::AlreadyExists;
+}
+
+/*!
+ Basic create testing
+ */
+void tst_QSharedMemory::create()
+{
+ QFETCH(QString, key);
+ QFETCH(int, size);
+ QFETCH(bool, canCreate);
+ QFETCH(QSharedMemory::SharedMemoryError, error);
+
+ QSharedMemory sm(rememberKey(key));
+ QCOMPARE(sm.create(size), canCreate);
+ if (sm.error() != error)
+ qDebug() << sm.errorString();
+ QCOMPARE(sm.key(), key);
+ if (canCreate) {
+ QCOMPARE(sm.errorString(), QString());
+ QVERIFY(sm.data() != 0);
+ QVERIFY(sm.size() != 0);
+ } else {
+ QVERIFY(!sm.data());
+ QVERIFY(sm.errorString() != QString());
+ }
+}
+
+void tst_QSharedMemory::attach_data()
+{
+ QTest::addColumn<QString>("key");
+ QTest::addColumn<bool>("exists");
+ QTest::addColumn<QSharedMemory::SharedMemoryError>("error");
+
+ QTest::newRow("null key") << QString() << false << QSharedMemory::KeyError;
+ QTest::newRow("doesn't exists") << QString("doesntexists") << false << QSharedMemory::NotFound;
+
+ // HPUX doesn't allow for multiple attaches per process.
+#ifndef Q_OS_HPUX
+ QTest::newRow("already exists") << QString(EXISTING_SHARE) << true << QSharedMemory::NoError;
+#endif
+}
+
+/*!
+ Basic attach/detach testing
+ */
+void tst_QSharedMemory::attach()
+{
+ QFETCH(QString, key);
+ QFETCH(bool, exists);
+ QFETCH(QSharedMemory::SharedMemoryError, error);
+
+ QSharedMemory sm(key);
+ QCOMPARE(sm.attach(), exists);
+ QCOMPARE(sm.isAttached(), exists);
+ QCOMPARE(sm.error(), error);
+ QCOMPARE(sm.key(), key);
+ if (exists) {
+ QVERIFY(sm.data() != 0);
+ QVERIFY(sm.size() != 0);
+ QCOMPARE(sm.errorString(), QString());
+ QVERIFY(sm.detach());
+ // Make sure detach doesn't screw up something and we can't re-attach.
+ QVERIFY(sm.attach());
+ QVERIFY(sm.data() != 0);
+ QVERIFY(sm.size() != 0);
+ QVERIFY(sm.detach());
+ QCOMPARE(sm.size(), 0);
+ QVERIFY(!sm.data());
+ } else {
+ QVERIFY(!sm.data());
+ QCOMPARE(sm.size(), 0);
+ QVERIFY(sm.errorString() != QString());
+ QVERIFY(!sm.detach());
+ }
+}
+
+void tst_QSharedMemory::lock()
+{
+ QSharedMemory shm;
+ QVERIFY(!shm.lock());
+ QCOMPARE(shm.error(), QSharedMemory::LockError);
+
+ shm.setKey(QLatin1String("qsharedmemory"));
+
+ QVERIFY(!shm.lock());
+ QCOMPARE(shm.error(), QSharedMemory::LockError);
+
+ QVERIFY(shm.create(100));
+ QVERIFY(shm.lock());
+ QTest::ignoreMessage(QtWarningMsg, "QSharedMemory::lock: already locked");
+ QVERIFY(shm.lock());
+ // we didn't unlock(), so ignore the warning from auto-detach in destructor
+ QTest::ignoreMessage(QtWarningMsg, "QSharedMemory::lock: already locked");
+}
+
+/*!
+ Other shared memory are allowed to be attached after we remove,
+ but new shared memory are not allowed to attach after a remove.
+ */
+// HPUX doesn't allow for multiple attaches per process.
+#ifndef Q_OS_HPUX
+void tst_QSharedMemory::removeWhileAttached()
+{
+ rememberKey("one");
+
+ // attach 1
+ QSharedMemory *smOne = new QSharedMemory(QLatin1String("one"));
+ QVERIFY(smOne->create(1024));
+ QVERIFY(smOne->isAttached());
+
+ // attach 2
+ QSharedMemory *smTwo = new QSharedMemory(QLatin1String("one"));
+ QVERIFY(smTwo->attach());
+ QVERIFY(smTwo->isAttached());
+
+ // detach 1 and remove, remove one first to catch another error.
+ delete smOne;
+ delete smTwo;
+
+ // three shouldn't be able to attach
+ QSharedMemory smThree(QLatin1String("one"));
+ QVERIFY(!smThree.attach());
+ QCOMPARE(smThree.error(), QSharedMemory::NotFound);
+}
+#endif
+
+/*!
+ The memory should be set to 0 after created.
+ */
+void tst_QSharedMemory::emptyMemory()
+{
+ QSharedMemory sm(rememberKey(QLatin1String("voidland")));
+ int size = 1024;
+ QVERIFY(sm.create(size, QSharedMemory::ReadOnly));
+ char *get = (char*)sm.data();
+ char null = 0;
+ for (int i = 0; i < size; ++i)
+ QCOMPARE(get[i], null);
+}
+
+/*!
+ Verify that attach with ReadOnly is actually read only
+ by writing to data and causing a segfault.
+*/
+// This test opens a crash dialog on Windows.
+#if !defined(Q_OS_WIN)
+void tst_QSharedMemory::readOnly()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#elif defined(Q_OS_MACOS)
+ QSKIP("QTBUG-59936: Times out on macOS", SkipAll);
+#else
+ rememberKey("readonly_segfault");
+ // ### on windows disable the popup somehow
+ QProcess p;
+ p.start(m_helperBinary, QStringList("readonly_segfault"));
+ p.setProcessChannelMode(QProcess::ForwardedChannels);
+ p.waitForFinished();
+ QCOMPARE(p.error(), QProcess::Crashed);
+#endif
+}
+#endif
+
+/*!
+ Keep making shared memory until the kernel stops us.
+ */
+void tst_QSharedMemory::useTooMuchMemory()
+{
+#ifdef Q_OS_LINUX
+ bool success = true;
+ int count = 0;
+ while (success) {
+ QString key = QLatin1String("maxmemorytest_") + QString::number(count++);
+ QSharedMemory *sm = new QSharedMemory(rememberKey(key));
+ QVERIFY(sm);
+ jail.append(sm);
+ int size = 32768 * 1024;
+ success = sm->create(size);
+ if (!success && sm->error() == QSharedMemory::AlreadyExists) {
+ // left over from a crash, clean it up
+ sm->attach();
+ sm->detach();
+ success = sm->create(size);
+ }
+
+ if (!success) {
+ QVERIFY(!sm->isAttached());
+ QCOMPARE(sm->key(), key);
+ QCOMPARE(sm->size(), 0);
+ QVERIFY(!sm->data());
+ if (sm->error() != QSharedMemory::OutOfResources)
+ qDebug() << sm->error() << sm->errorString();
+ // ### Linux won't return OutOfResources if there are not enough semaphores to use.
+ QVERIFY(sm->error() == QSharedMemory::OutOfResources
+ || sm->error() == QSharedMemory::LockError);
+ QVERIFY(sm->errorString() != QString());
+ QVERIFY(!sm->attach());
+ QVERIFY(!sm->detach());
+ } else {
+ QVERIFY(sm->isAttached());
+ }
+ }
+#endif
+}
+
+/*!
+ Create one shared memory (government) and see how many other shared memories (wars) we can
+ attach before the system runs out of resources.
+ */
+// HPUX doesn't allow for multiple attaches per process.
+#if !defined(Q_OS_HPUX)
+void tst_QSharedMemory::attachTooMuch()
+{
+ QSKIP("disabled");
+
+ QSharedMemory government(rememberKey("government"));
+ QVERIFY(government.create(1024));
+ while (true) {
+ QSharedMemory *war = new QSharedMemory(government.key());
+ QVERIFY(war);
+ jail.append(war);
+ if (!war->attach()) {
+ QVERIFY(!war->isAttached());
+ QCOMPARE(war->key(), government.key());
+ QCOMPARE(war->size(), 0);
+ QVERIFY(!war->data());
+ QCOMPARE(war->error(), QSharedMemory::OutOfResources);
+ QVERIFY(war->errorString() != QString());
+ QVERIFY(!war->detach());
+ break;
+ } else {
+ QVERIFY(war->isAttached());
+ }
+ }
+}
+#endif
+
+// HPUX doesn't allow for multiple attaches per process.
+#ifndef Q_OS_HPUX
+void tst_QSharedMemory::simpleProducerConsumer_data()
+{
+ QTest::addColumn<QSharedMemory::AccessMode>("mode");
+
+ QTest::newRow("readonly") << QSharedMemory::ReadOnly;
+ QTest::newRow("readwrite") << QSharedMemory::ReadWrite;
+}
+
+/*!
+ The basic consumer producer that rounds out the basic testing.
+ If this fails then any muli-threading/process might fail (but be
+ harder to debug)
+
+ This doesn't require nor test any locking system.
+ */
+void tst_QSharedMemory::simpleProducerConsumer()
+{
+ QFETCH(QSharedMemory::AccessMode, mode);
+
+ rememberKey(QLatin1String("market"));
+ QSharedMemory producer(QLatin1String("market"));
+ QSharedMemory consumer(QLatin1String("market"));
+ int size = 512;
+ QVERIFY(producer.create(size));
+ QVERIFY(consumer.attach(mode));
+
+ char *put = (char*)producer.data();
+ char *get = (char*)consumer.data();
+ // On Windows CE you always have ReadWrite access. Thus
+ // ViewMapOfFile returns the same pointer
+ QVERIFY(put != get);
+ for (int i = 0; i < size; ++i) {
+ put[i] = 'Q';
+ QCOMPARE(get[i], 'Q');
+ }
+ QVERIFY(consumer.detach());
+}
+#endif
+
+// HPUX doesn't allow for multiple attaches per process.
+#ifndef Q_OS_HPUX
+void tst_QSharedMemory::simpleDoubleProducerConsumer()
+{
+ rememberKey(QLatin1String("market"));
+ QSharedMemory producer(QLatin1String("market"));
+ int size = 512;
+ QVERIFY(producer.create(size));
+ QVERIFY(producer.detach());
+ QVERIFY(producer.create(size));
+
+ {
+ QSharedMemory consumer(QLatin1String("market"));
+ QVERIFY(consumer.attach());
+ }
+}
+#endif
+
+class Consumer : public QThread
+{
+
+public:
+ void run()
+ {
+ QSharedMemory consumer(QLatin1String("market"));
+ while (!consumer.attach()) {
+ if (consumer.error() != QSharedMemory::NotFound)
+ qDebug() << "consumer: failed to connect" << consumer.error() << consumer.errorString();
+ QVERIFY(consumer.error() == QSharedMemory::NotFound || consumer.error() == QSharedMemory::KeyError);
+ QTest::qWait(1);
+ }
+
+ char *memory = (char*)consumer.data();
+
+ int i = 0;
+ while (true) {
+ if (!consumer.lock())
+ break;
+ if (memory[0] == 'Q')
+ memory[0] = ++i;
+ if (memory[0] == 'E') {
+ memory[1]++;
+ QVERIFY(consumer.unlock());
+ break;
+ }
+ QVERIFY(consumer.unlock());
+ QTest::qWait(1);
+ }
+
+ QVERIFY(consumer.detach());
+ }
+};
+
+class Producer : public QThread
+{
+
+public:
+ Producer() : producer(QLatin1String("market"))
+ {
+ int size = 1024;
+ if (!producer.create(size)) {
+ // left over from a crash...
+ if (producer.error() == QSharedMemory::AlreadyExists) {
+ producer.attach();
+ producer.detach();
+ QVERIFY(producer.create(size));
+ }
+ }
+ }
+
+ void run()
+ {
+
+ char *memory = (char*)producer.data();
+ memory[1] = '0';
+ QTime timer;
+ timer.start();
+ int i = 0;
+ while (i < 5 && timer.elapsed() < 5000) {
+ QVERIFY(producer.lock());
+ if (memory[0] == 'Q') {
+ QVERIFY(producer.unlock());
+ QTest::qWait(1);
+ continue;
+ }
+ ++i;
+ memory[0] = 'Q';
+ QVERIFY(producer.unlock());
+ QTest::qWait(1);
+ }
+
+ // tell everyone to quit
+ QVERIFY(producer.lock());
+ memory[0] = 'E';
+ QVERIFY(producer.unlock());
+
+ }
+
+ QSharedMemory producer;
+private:
+
+};
+
+void tst_QSharedMemory::simpleThreadedProducerConsumer_data()
+{
+ QTest::addColumn<bool>("producerIsThread");
+ QTest::addColumn<int>("threads");
+ for (int i = 0; i < 5; ++i) {
+ QTest::newRow("1 consumer, producer is thread") << true << 1;
+ QTest::newRow("1 consumer, producer is this") << false << 1;
+ QTest::newRow("5 consumers, producer is thread") << true << 5;
+ QTest::newRow("5 consumers, producer is this") << false << 5;
+ }
+}
+
+/*!
+ The basic producer/consumer, but this time using threads.
+ */
+void tst_QSharedMemory::simpleThreadedProducerConsumer()
+{
+ QFETCH(bool, producerIsThread);
+ QFETCH(int, threads);
+ rememberKey(QLatin1String("market"));
+
+#if defined Q_OS_HPUX && defined __ia64
+ QSKIP("This test locks up on gravlaks.troll.no");
+#endif
+
+ Producer p;
+ QVERIFY(p.producer.isAttached());
+ if (producerIsThread)
+ p.start();
+
+ QList<Consumer*> consumers;
+ for (int i = 0; i < threads; ++i) {
+ consumers.append(new Consumer());
+ consumers.last()->start();
+ }
+
+ if (!producerIsThread)
+ p.run();
+
+ p.wait(5000);
+ while (!consumers.isEmpty()) {
+ Consumer *c = consumers.first();
+ QVERIFY(c->isFinished() || c->wait(5000));
+ delete consumers.takeFirst();
+ }
+}
+
+void tst_QSharedMemory::simpleProcessProducerConsumer_data()
+{
+#if QT_CONFIG(process)
+ QTest::addColumn<int>("processes");
+ int tries = 5;
+ for (int i = 0; i < tries; ++i) {
+ QTest::newRow("1 process") << 1;
+ QTest::newRow("5 processes") << 5;
+ }
+#endif
+}
+
+/*!
+ Create external processes that produce and consume.
+ */
+void tst_QSharedMemory::simpleProcessProducerConsumer()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QFETCH(int, processes);
+
+ QSKIP("This test is unstable: QTBUG-25655");
+
+ rememberKey("market");
+
+ QProcess producer;
+ producer.start(m_helperBinary, QStringList("producer"));
+ QVERIFY2(producer.waitForStarted(), "Could not start helper binary");
+ QVERIFY2(producer.waitForReadyRead(), "Helper process failed to create shared memory segment: " +
+ producer.readAllStandardError());
+
+ QList<QProcess*> consumers;
+ unsigned int failedProcesses = 0;
+ const QStringList consumerArguments = QStringList("consumer");
+ for (int i = 0; i < processes; ++i) {
+ QProcess *p = new QProcess;
+ p->setProcessChannelMode(QProcess::ForwardedChannels);
+ p->start(m_helperBinary, consumerArguments);
+ if (p->waitForStarted(2000))
+ consumers.append(p);
+ else
+ ++failedProcesses;
+ }
+
+ bool consumerFailed = false;
+
+ while (!consumers.isEmpty()) {
+ QVERIFY(consumers.first()->waitForFinished(3000));
+ if (consumers.first()->state() == QProcess::Running ||
+ consumers.first()->exitStatus() != QProcess::NormalExit ||
+ consumers.first()->exitCode() != 0) {
+ consumerFailed = true;
+ }
+ delete consumers.takeFirst();
+ }
+ QCOMPARE(consumerFailed, false);
+ QCOMPARE(failedProcesses, (unsigned int)(0));
+
+ // tell the producer to exit now
+ producer.write("", 1);
+ producer.waitForBytesWritten();
+ QVERIFY(producer.waitForFinished(5000));
+#endif
+}
+
+void tst_QSharedMemory::uniqueKey_data()
+{
+ QTest::addColumn<QString>("key1");
+ QTest::addColumn<QString>("key2");
+
+ QTest::newRow("null == null") << QString() << QString();
+ QTest::newRow("key == key") << QString("key") << QString("key");
+ QTest::newRow("key1 == key1") << QString("key1") << QString("key1");
+ QTest::newRow("key != key1") << QString("key") << QString("key1");
+ QTest::newRow("ke1y != key1") << QString("ke1y") << QString("key1");
+ QTest::newRow("key1 != key2") << QString("key1") << QString("key2");
+ QTest::newRow("Noël -> Nol") << QString::fromUtf8("N\xc3\xabl") << QString("Nol");
+}
+
+void tst_QSharedMemory::uniqueKey()
+{
+ QFETCH(QString, key1);
+ QFETCH(QString, key2);
+
+ QSharedMemory sm1(key1);
+ QSharedMemory sm2(key2);
+
+ bool setEqual = (key1 == key2);
+ bool keyEqual = (sm1.key() == sm2.key());
+ bool nativeEqual = (sm1.nativeKey() == sm2.nativeKey());
+
+ QCOMPARE(keyEqual, setEqual);
+ QCOMPARE(nativeEqual, setEqual);
+}
+
+QTEST_MAIN(tst_QSharedMemory)
+#include "tst_qsharedmemory.moc"
+
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/acquirerelease.pro b/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/acquirerelease.pro
new file mode 100644
index 0000000000..a6156ed5b6
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/acquirerelease.pro
@@ -0,0 +1,5 @@
+QT = core testlib
+
+SOURCES += main.cpp
+
+load(qt_test_helper)
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/main.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/main.cpp
index 7bfb6b16cc..7bfb6b16cc 100644
--- a/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/main.cpp
+++ b/tests/auto/corelib/kernel/qsystemsemaphore/acquirerelease/main.cpp
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro b/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro
index f8a49254d2..70526426aa 100644
--- a/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro
+++ b/tests/auto/corelib/kernel/qsystemsemaphore/qsystemsemaphore.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = systemsemaphorehelper test
+SUBDIRS = acquirerelease test.pro
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/systemsemaphorehelper.pro b/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/systemsemaphorehelper.pro
deleted file mode 100644
index 389015d504..0000000000
--- a/tests/auto/corelib/kernel/qsystemsemaphore/systemsemaphorehelper/systemsemaphorehelper.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-QT = core testlib
-
-win32: CONFIG += console
-mac:CONFIG -= app_bundle
-
-SOURCES += main.cpp
-TARGET = helperbinary
-
-CONFIG(debug_and_release) {
- CONFIG(debug, debug|release) {
- DESTDIR = ../debug
- } else {
- DESTDIR = ../release
- }
-} else {
- DESTDIR = ..
-}
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test.pro b/tests/auto/corelib/kernel/qsystemsemaphore/test.pro
new file mode 100644
index 0000000000..13bd1fa270
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsystemsemaphore/test.pro
@@ -0,0 +1,7 @@
+CONFIG += testcase
+QT = core testlib
+
+SOURCES += tst_qsystemsemaphore.cpp
+TARGET = tst_qsystemsemaphore
+
+win32: CONFIG += console
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test/test.pro b/tests/auto/corelib/kernel/qsystemsemaphore/test/test.pro
deleted file mode 100644
index f60207eb01..0000000000
--- a/tests/auto/corelib/kernel/qsystemsemaphore/test/test.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-CONFIG += testcase
-QT = core testlib
-
-win32: CONFIG += console
-
-SOURCES += tst_qsystemsemaphore.cpp
-TARGET = tst_qsystemsemaphore
-
-CONFIG(debug_and_release) {
- CONFIG(debug, debug|release) {
- DESTDIR = ../debug
- } else {
- DESTDIR = ../release
- }
-} else {
- DESTDIR = ..
-}
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp
deleted file mode 100644
index 6ff1e14976..0000000000
--- a/tests/auto/corelib/kernel/qsystemsemaphore/test/tst_qsystemsemaphore.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtCore/QSystemSemaphore>
-#include <QtCore/QVector>
-#include <QtCore/QTemporaryDir>
-
-#define EXISTING_SHARE "existing"
-#define HELPERWAITTIME 10000
-
-class tst_QSystemSemaphore : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QSystemSemaphore();
-
-public Q_SLOTS:
- void initTestCase();
- void init();
- void cleanup();
-
-private slots:
- void key_data();
- void key();
-
- void basicacquire();
- void complexacquire();
- void release();
-
- void basicProcesses();
-
- void processes_data();
- void processes();
-
-#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC)
- void undo();
-#endif
- void initialValue();
-
-private:
- static QString helperBinary();
- QSystemSemaphore *existingLock;
-
- const QString m_helperBinary;
-};
-
-tst_QSystemSemaphore::tst_QSystemSemaphore()
- : m_helperBinary(helperBinary())
-{
-}
-
-void tst_QSystemSemaphore::initTestCase()
-{
- QVERIFY2(!m_helperBinary.isEmpty(), "Could not find helper binary");
-}
-
-void tst_QSystemSemaphore::init()
-{
- existingLock = new QSystemSemaphore(EXISTING_SHARE, 1, QSystemSemaphore::Create);
-}
-
-void tst_QSystemSemaphore::cleanup()
-{
- delete existingLock;
-}
-
-void tst_QSystemSemaphore::key_data()
-{
- QTest::addColumn<QString>("constructorKey");
- QTest::addColumn<QString>("setKey");
-
- QTest::newRow("null, null") << QString() << QString();
- QTest::newRow("null, one") << QString() << QString("one");
- QTest::newRow("one, two") << QString("one") << QString("two");
-}
-
-/*!
- Basic key testing
- */
-void tst_QSystemSemaphore::key()
-{
- QFETCH(QString, constructorKey);
- QFETCH(QString, setKey);
-
- QSystemSemaphore sem(constructorKey);
- QCOMPARE(sem.key(), constructorKey);
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-
- sem.setKey(setKey);
- QCOMPARE(sem.key(), setKey);
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-}
-
-void tst_QSystemSemaphore::basicacquire()
-{
- QSystemSemaphore sem("QSystemSemaphore_basicacquire", 1, QSystemSemaphore::Create);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-}
-
-void tst_QSystemSemaphore::complexacquire()
-{
- QSystemSemaphore sem("QSystemSemaphore_complexacquire", 2, QSystemSemaphore::Create);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-}
-
-void tst_QSystemSemaphore::release()
-{
- QSystemSemaphore sem("QSystemSemaphore_release", 0, QSystemSemaphore::Create);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.acquire());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QVERIFY(sem.release());
- QCOMPARE(sem.error(), QSystemSemaphore::NoError);
- QCOMPARE(sem.errorString(), QString());
-}
-
-void tst_QSystemSemaphore::basicProcesses()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QSystemSemaphore sem("store", 0, QSystemSemaphore::Create);
-
- QProcess acquire;
- acquire.setProcessChannelMode(QProcess::ForwardedChannels);
-
- QProcess release;
- release.setProcessChannelMode(QProcess::ForwardedChannels);
-
- acquire.start(m_helperBinary, QStringList("acquire"));
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QCOMPARE(acquire.state(), QProcess::Running);
- acquire.kill();
- release.start(m_helperBinary, QStringList("release"));
- QVERIFY2(release.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- release.waitForFinished(HELPERWAITTIME);
- QCOMPARE(acquire.state(), QProcess::NotRunning);
-#endif
-}
-
-void tst_QSystemSemaphore::processes_data()
-{
- QTest::addColumn<int>("processes");
- for (int i = 0; i < 5; ++i) {
- QTest::newRow("1 process") << 1;
- QTest::newRow("3 process") << 3;
- QTest::newRow("10 process") << 10;
- }
-}
-
-void tst_QSystemSemaphore::processes()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
-
- QFETCH(int, processes);
- QVector<QString> scripts(processes, "acquirerelease");
-
- QList<QProcess*> consumers;
- for (int i = 0; i < scripts.count(); ++i) {
- QProcess *p = new QProcess;
- p->setProcessChannelMode(QProcess::ForwardedChannels);
- consumers.append(p);
- p->start(m_helperBinary, QStringList(scripts.at(i)));
- }
-
- while (!consumers.isEmpty()) {
- consumers.first()->waitForFinished();
- QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit);
- QCOMPARE(consumers.first()->exitCode(), 0);
- delete consumers.takeFirst();
- }
-#endif
-}
-
-// This test only checks a system v unix behavior.
-#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC)
-void tst_QSystemSemaphore::undo()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
-
- QStringList acquireArguments = QStringList("acquire");
- QProcess acquire;
- acquire.setProcessChannelMode(QProcess::ForwardedChannels);
- acquire.start(m_helperBinary, acquireArguments);
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::NotRunning);
-
- // At process exit the kernel should auto undo
-
- acquire.start(m_helperBinary, acquireArguments);
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::NotRunning);
-#endif
-}
-#endif
-
-void tst_QSystemSemaphore::initialValue()
-{
-#if !QT_CONFIG(process)
- QSKIP("No qprocess support", SkipAll);
-#else
- QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
-
- QStringList acquireArguments = QStringList("acquire");
- QStringList releaseArguments = QStringList("release");
- QProcess acquire;
- acquire.setProcessChannelMode(QProcess::ForwardedChannels);
-
- QProcess release;
- release.setProcessChannelMode(QProcess::ForwardedChannels);
-
- acquire.start(m_helperBinary, acquireArguments);
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::NotRunning);
-
- acquire.start(m_helperBinary, acquireArguments << QLatin1String("2"));
- QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::Running);
- acquire.kill();
-
- release.start(m_helperBinary, releaseArguments);
- QVERIFY2(release.waitForStarted(), "Could not start helper binary");
- acquire.waitForFinished(HELPERWAITTIME);
- release.waitForFinished(HELPERWAITTIME);
- QVERIFY(acquire.state()== QProcess::NotRunning);
-#endif
-}
-
-QString tst_QSystemSemaphore::helperBinary()
-{
- QString binary = QStringLiteral("helperbinary");
-#ifdef Q_OS_WIN
- binary += QStringLiteral(".exe");
-#endif
- return QFINDTESTDATA(binary);
-}
-QTEST_MAIN(tst_QSystemSemaphore)
-#include "tst_qsystemsemaphore.moc"
-
diff --git a/tests/auto/corelib/kernel/qsystemsemaphore/tst_qsystemsemaphore.cpp b/tests/auto/corelib/kernel/qsystemsemaphore/tst_qsystemsemaphore.cpp
new file mode 100644
index 0000000000..5f010ae3d1
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsystemsemaphore/tst_qsystemsemaphore.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtCore/QSystemSemaphore>
+#include <QtCore/QVector>
+#include <QtCore/QTemporaryDir>
+
+#define EXISTING_SHARE "existing"
+#define HELPERWAITTIME 10000
+
+class tst_QSystemSemaphore : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QSystemSemaphore();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private slots:
+ void key_data();
+ void key();
+
+ void basicacquire();
+ void complexacquire();
+ void release();
+
+ void basicProcesses();
+
+ void processes_data();
+ void processes();
+
+#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC)
+ void undo();
+#endif
+ void initialValue();
+
+private:
+ QSystemSemaphore *existingLock;
+
+ const QString m_helperBinary;
+};
+
+tst_QSystemSemaphore::tst_QSystemSemaphore()
+ : m_helperBinary("acquirerelease_helper")
+{
+}
+
+void tst_QSystemSemaphore::init()
+{
+ existingLock = new QSystemSemaphore(EXISTING_SHARE, 1, QSystemSemaphore::Create);
+}
+
+void tst_QSystemSemaphore::cleanup()
+{
+ delete existingLock;
+}
+
+void tst_QSystemSemaphore::key_data()
+{
+ QTest::addColumn<QString>("constructorKey");
+ QTest::addColumn<QString>("setKey");
+
+ QTest::newRow("null, null") << QString() << QString();
+ QTest::newRow("null, one") << QString() << QString("one");
+ QTest::newRow("one, two") << QString("one") << QString("two");
+}
+
+/*!
+ Basic key testing
+ */
+void tst_QSystemSemaphore::key()
+{
+ QFETCH(QString, constructorKey);
+ QFETCH(QString, setKey);
+
+ QSystemSemaphore sem(constructorKey);
+ QCOMPARE(sem.key(), constructorKey);
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+
+ sem.setKey(setKey);
+ QCOMPARE(sem.key(), setKey);
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+}
+
+void tst_QSystemSemaphore::basicacquire()
+{
+ QSystemSemaphore sem("QSystemSemaphore_basicacquire", 1, QSystemSemaphore::Create);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+}
+
+void tst_QSystemSemaphore::complexacquire()
+{
+ QSystemSemaphore sem("QSystemSemaphore_complexacquire", 2, QSystemSemaphore::Create);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+}
+
+void tst_QSystemSemaphore::release()
+{
+ QSystemSemaphore sem("QSystemSemaphore_release", 0, QSystemSemaphore::Create);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.acquire());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QVERIFY(sem.release());
+ QCOMPARE(sem.error(), QSystemSemaphore::NoError);
+ QCOMPARE(sem.errorString(), QString());
+}
+
+void tst_QSystemSemaphore::basicProcesses()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QSystemSemaphore sem("store", 0, QSystemSemaphore::Create);
+
+ QProcess acquire;
+ acquire.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ QProcess release;
+ release.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ acquire.start(m_helperBinary, QStringList("acquire"));
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QCOMPARE(acquire.state(), QProcess::Running);
+ acquire.kill();
+ release.start(m_helperBinary, QStringList("release"));
+ QVERIFY2(release.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ release.waitForFinished(HELPERWAITTIME);
+ QCOMPARE(acquire.state(), QProcess::NotRunning);
+#endif
+}
+
+void tst_QSystemSemaphore::processes_data()
+{
+ QTest::addColumn<int>("processes");
+ for (int i = 0; i < 5; ++i) {
+ QTest::newRow("1 process") << 1;
+ QTest::newRow("3 process") << 3;
+ QTest::newRow("10 process") << 10;
+ }
+}
+
+void tst_QSystemSemaphore::processes()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
+
+ QFETCH(int, processes);
+ QVector<QString> scripts(processes, "acquirerelease");
+
+ QList<QProcess*> consumers;
+ for (int i = 0; i < scripts.count(); ++i) {
+ QProcess *p = new QProcess;
+ p->setProcessChannelMode(QProcess::ForwardedChannels);
+ consumers.append(p);
+ p->start(m_helperBinary, QStringList(scripts.at(i)));
+ }
+
+ while (!consumers.isEmpty()) {
+ consumers.first()->waitForFinished();
+ QCOMPARE(consumers.first()->exitStatus(), QProcess::NormalExit);
+ QCOMPARE(consumers.first()->exitCode(), 0);
+ delete consumers.takeFirst();
+ }
+#endif
+}
+
+// This test only checks a system v unix behavior.
+#if !defined(Q_OS_WIN) && !defined(QT_POSIX_IPC)
+void tst_QSystemSemaphore::undo()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
+
+ QStringList acquireArguments = QStringList("acquire");
+ QProcess acquire;
+ acquire.setProcessChannelMode(QProcess::ForwardedChannels);
+ acquire.start(m_helperBinary, acquireArguments);
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::NotRunning);
+
+ // At process exit the kernel should auto undo
+
+ acquire.start(m_helperBinary, acquireArguments);
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::NotRunning);
+#endif
+}
+#endif
+
+void tst_QSystemSemaphore::initialValue()
+{
+#if !QT_CONFIG(process)
+ QSKIP("No qprocess support", SkipAll);
+#else
+ QSystemSemaphore sem("store", 1, QSystemSemaphore::Create);
+
+ QStringList acquireArguments = QStringList("acquire");
+ QStringList releaseArguments = QStringList("release");
+ QProcess acquire;
+ acquire.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ QProcess release;
+ release.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ acquire.start(m_helperBinary, acquireArguments);
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::NotRunning);
+
+ acquire.start(m_helperBinary, acquireArguments << QLatin1String("2"));
+ QVERIFY2(acquire.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::Running);
+ acquire.kill();
+
+ release.start(m_helperBinary, releaseArguments);
+ QVERIFY2(release.waitForStarted(), "Could not start helper binary");
+ acquire.waitForFinished(HELPERWAITTIME);
+ release.waitForFinished(HELPERWAITTIME);
+ QVERIFY(acquire.state()== QProcess::NotRunning);
+#endif
+}
+
+QTEST_MAIN(tst_QSystemSemaphore)
+#include "tst_qsystemsemaphore.moc"
+
diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
index 5b2d77a02c..8d194dafc1 100644
--- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
+++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
@@ -75,6 +75,7 @@ private slots:
void dontBlockEvents();
void postedEventsShouldNotStarveTimers();
+ void callOnTimeout();
};
void tst_QTimer::zeroTimer()
@@ -455,8 +456,7 @@ void tst_QTimer::moveToThread()
#if defined(Q_OS_WIN32)
QSKIP("Does not work reliably on Windows :(");
#elif defined(Q_OS_MACOS)
- if (__builtin_available(macOS 10.12, *))
- QSKIP("Does not work reliably on macOS 10.12 (QTBUG-59679)");
+ QSKIP("Does not work reliably on macOS 10.12+ (QTBUG-59679)");
#endif
QTimer ti1;
QTimer ti2;
@@ -979,5 +979,30 @@ void tst_QTimer::crossThreadSingleShotToFunctor()
delete o;
}
+void tst_QTimer::callOnTimeout()
+{
+ QTimer timer;
+ QSignalSpy timeoutSpy(&timer, &QTimer::timeout);
+ timer.setInterval(0);
+ timer.start();
+
+ auto context = new QObject();
+
+ int count = 0;
+ timer.callOnTimeout([&count] { count++; });
+ QMetaObject::Connection connection = timer.callOnTimeout(context, [&count] { count++; });
+ timer.callOnTimeout(&timer, &QTimer::stop);
+
+
+ QTest::qWait(100);
+ QCOMPARE(count, 2);
+ QCOMPARE(timeoutSpy.count(), 1);
+
+ // Test that connection is bound to context lifetime
+ QVERIFY(connection);
+ delete context;
+ QVERIFY(!connection);
+}
+
QTEST_MAIN(tst_QTimer)
#include "tst_qtimer.moc"
diff --git a/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc b/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc
index b33995ef21..39b85db664 100644
--- a/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc
+++ b/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc
@@ -1,6 +1,7 @@
<RCC>
<qresource prefix="/android_testdata">
<file>hellotr_la.qm</file>
+ <file>hellotr_empty.qm</file>
<file>msgfmt_from_po.qm</file>
<file>dependencies_la.qm</file>
</qresource>
diff --git a/tests/auto/corelib/kernel/qtranslator/hellotr_empty.qm b/tests/auto/corelib/kernel/qtranslator/hellotr_empty.qm
new file mode 100644
index 0000000000..be651eede2
--- /dev/null
+++ b/tests/auto/corelib/kernel/qtranslator/hellotr_empty.qm
@@ -0,0 +1 @@
+<¸dÊÍ!¿`¡½Ý \ No newline at end of file
diff --git a/tests/auto/corelib/kernel/qtranslator/hellotr_empty.ts b/tests/auto/corelib/kernel/qtranslator/hellotr_empty.ts
new file mode 100644
index 0000000000..85e0d3992b
--- /dev/null
+++ b/tests/auto/corelib/kernel/qtranslator/hellotr_empty.ts
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1"/>
diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro
index d8924c2d5f..a985f35a14 100644
--- a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro
+++ b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro
@@ -5,5 +5,5 @@ SOURCES = tst_qtranslator.cpp
RESOURCES += qtranslator.qrc
android:!android-embedded: RESOURCES += android_testdata.qrc
-else: TESTDATA += dependencies_la.qm hellotr_la.qm msgfmt_from_po.qm
+else: TESTDATA += dependencies_la.qm hellotr_empty.qm hellotr_la.qm msgfmt_from_po.qm
diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc b/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc
index 333dcfaa21..cb82c6cc95 100644
--- a/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc
+++ b/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc
@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/tst_qtranslator">
<file>hellotr_la.qm</file>
+ <file>hellotr_empty.qm</file>
</qresource>
</RCC>
diff --git a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp
index 451f96339e..40a29c723c 100644
--- a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp
+++ b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp
@@ -41,13 +41,12 @@ protected:
private slots:
void initTestCase();
+ void load_data();
void load();
- void load2();
void threadLoad();
void testLanguageChange();
void plural();
void translate_qm_file_generated_with_msgfmt();
- void loadFromResource();
void loadDirectory();
void dependencies();
void translationInThreadWhileInstallingTranslator();
@@ -106,24 +105,45 @@ bool tst_QTranslator::eventFilter(QObject *, QEvent *event)
return false;
}
-void tst_QTranslator::load()
+void tst_QTranslator::load_data()
{
+ QTest::addColumn<QString>("filepath");
+ QTest::addColumn<bool>("isEmpty");
+ QTest::addColumn<QString>("translation");
- QTranslator tor( 0 );
- tor.load("hellotr_la");
- QVERIFY(!tor.isEmpty());
- QCOMPARE(tor.translate("QPushButton", "Hello world!"), QLatin1String("Hallo Welt!"));
+ QTest::newRow("hellotr_la") << "hellotr_la.qm" << false << "Hallo Welt!";
+ QTest::newRow("hellotr_empty") << "hellotr_empty.qm" << true << "";
}
-void tst_QTranslator::load2()
+void tst_QTranslator::load()
{
- QTranslator tor( 0 );
- QFile file("hellotr_la.qm");
- file.open(QFile::ReadOnly);
- QByteArray data = file.readAll();
- tor.load((const uchar *)data.constData(), data.length());
- QVERIFY(!tor.isEmpty());
- QCOMPARE(tor.translate("QPushButton", "Hello world!"), QLatin1String("Hallo Welt!"));
+ QFETCH(QString, filepath);
+ QFETCH(bool, isEmpty);
+ QFETCH(QString, translation);
+
+ {
+ QTranslator tor;
+ QVERIFY(tor.load(QFileInfo(filepath).baseName()));
+ QCOMPARE(tor.isEmpty(), isEmpty);
+ QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation);
+ }
+
+ {
+ QFile file(filepath);
+ file.open(QFile::ReadOnly);
+ QByteArray data = file.readAll();
+ QTranslator tor;
+ QVERIFY(tor.load((const uchar *)data.constData(), data.length()));
+ QCOMPARE(tor.isEmpty(), isEmpty);
+ QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation);
+ }
+
+ {
+ QTranslator tor;
+ QVERIFY(tor.load(QString(":/tst_qtranslator/%1").arg(filepath)));
+ QCOMPARE(tor.isEmpty(), isEmpty);
+ QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation);
+ }
}
class TranslatorThread : public QThread
@@ -240,14 +260,6 @@ void tst_QTranslator::translate_qm_file_generated_with_msgfmt()
qApp->removeTranslator(&translator);
}
-void tst_QTranslator::loadFromResource()
-{
- QTranslator tor;
- tor.load(":/tst_qtranslator/hellotr_la.qm");
- QVERIFY(!tor.isEmpty());
- QCOMPARE(tor.translate("QPushButton", "Hello world!"), QLatin1String("Hallo Welt!"));
-}
-
void tst_QTranslator::loadDirectory()
{
QString current_base = QDir::current().dirName();
diff --git a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
index e2a0c2dad3..ac8aaa1327 100644
--- a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
+++ b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp
@@ -46,6 +46,7 @@ protected slots:
private slots:
void simple_data();
void simple();
+ void blockedWaiting();
void manyNotifiers();
void disableNotifiersInActivatedSlot_data();
void disableNotifiersInActivatedSlot();
@@ -104,6 +105,26 @@ void tst_QWinEventNotifier::simple()
QVERIFY(simpleActivated);
}
+void tst_QWinEventNotifier::blockedWaiting()
+{
+ simpleHEvent = CreateEvent(0, true, false, 0);
+ QWinEventNotifier n(simpleHEvent);
+ QObject::connect(&n, &QWinEventNotifier::activated,
+ this, &tst_QWinEventNotifier::simple_activated);
+ simpleActivated = false;
+
+ SetEvent(simpleHEvent);
+ QCOMPARE(WaitForSingleObject(simpleHEvent, 1000), WAIT_OBJECT_0);
+
+ n.setEnabled(false);
+ ResetEvent(simpleHEvent);
+ n.setEnabled(true);
+
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(QTestEventLoop::instance().timeout());
+ QVERIFY(!simpleActivated);
+}
+
class EventWithNotifier : public QObject
{
Q_OBJECT
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.foo b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.foo
new file mode 100644
index 0000000000..ed5e761417
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.foo
@@ -0,0 +1,3 @@
+<?foo>
+<blah>
+</blah>
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.xml b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.xml
new file mode 100644
index 0000000000..27b5bd7e1f
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+ <!-- The real life example would be that this mime type is a sub class of application/xml
+ which has a magic that matches &lt;?xml .
+ XML files with an early appearing qnx tag are detected as
+ application/vnd.qnx.bar-descriptor. We want that XML files without the qnx tag to be
+ identified as application/xml, independent of the order in which the two are registered. -->
+ <mime-type type="application/vnd.qnx.bar-descriptor">
+ <sub-class-of type="application/foo"/>
+ <glob pattern="*.foo"/>
+ <magic><!-- higher priority than the parent magic -->
+ <match value="&lt;qnx&gt;" type="string" offset="0:200"/>
+ </magic>
+ </mime-type>
+ <mime-type type="application/foo">
+ <glob pattern="*.foo"/>
+ <magic priority="40">
+ <match value="&lt;?foo" type="string" offset="0"/>
+ </magic>
+ </mime-type>
+</mime-info>
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy2.foo b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy2.foo
new file mode 100644
index 0000000000..fd90ed04b3
--- /dev/null
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/magic-and-hierarchy2.foo
@@ -0,0 +1,3 @@
+<?foo>
+<qnx>
+</qnx>
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc b/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc
index 29666627a1..1002d0195d 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/testdata.qrc
@@ -7,5 +7,8 @@
<file>invalid-magic1.xml</file>
<file>invalid-magic2.xml</file>
<file>invalid-magic3.xml</file>
+ <file>magic-and-hierarchy.xml</file>
+ <file>magic-and-hierarchy.foo</file>
+ <file>magic-and-hierarchy2.foo</file>
</qresource>
</RCC>
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
index 3144c3071c..597d51e7e0 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
@@ -52,6 +52,7 @@ static const char *const additionalMimeFiles[] = {
"invalid-magic1.xml",
"invalid-magic2.xml",
"invalid-magic3.xml",
+ "magic-and-hierarchy.xml",
0
};
@@ -985,6 +986,12 @@ void tst_QMimeDatabase::installNewGlobalMimeType()
qDebug() << objcsrc.globPatterns();
}
+ const QString fooTestFile = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy.foo");
+ QCOMPARE(db.mimeTypeForFile(fooTestFile).name(), QString::fromLatin1("application/foo"));
+
+ const QString fooTestFile2 = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy2.foo");
+ QCOMPARE(db.mimeTypeForFile(fooTestFile2).name(), QString::fromLatin1("application/vnd.qnx.bar-descriptor"));
+
// Now test removing the mimetype definitions again
for (int i = 0; i < m_additionalMimeFileNames.size(); ++i)
QFile::remove(destDir + m_additionalMimeFileNames.at(i));
diff --git a/tests/auto/corelib/plugin/plugin.pro b/tests/auto/corelib/plugin/plugin.pro
index b094c24e55..240608fddf 100644
--- a/tests/auto/corelib/plugin/plugin.pro
+++ b/tests/auto/corelib/plugin/plugin.pro
@@ -11,6 +11,5 @@ qtConfig(library): SUBDIRS += \
contains(CONFIG, static) {
message(Disabling tests requiring shared build of Qt)
SUBDIRS -= qfactoryloader \
- qplugin \
- qpluginloader
+ qplugin
}
diff --git a/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp b/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
index d285ed79c0..a290c012df 100644
--- a/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
+++ b/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -30,8 +31,11 @@
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
+#include <qplugin.h>
#include <QPluginLoader>
+#include <private/qplugin_p.h>
+
class tst_QPlugin : public QObject
{
Q_OBJECT
@@ -124,7 +128,10 @@ void tst_QPlugin::scanInvalidPlugin_data()
{
QTest::addColumn<QByteArray>("metadata");
QTest::addColumn<bool>("loads");
+ QTest::addColumn<QString>("errMsg");
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ // Binary JSON metadata
QByteArray prefix = "QTMETADATA ";
{
@@ -138,27 +145,65 @@ void tst_QPlugin::scanInvalidPlugin_data()
obj.insert("debug", true);
#endif
obj.insert("MetaData", QJsonObject());
- QTest::newRow("control") << (prefix + QJsonDocument(obj).toBinaryData()) << true;
+ QTest::newRow("json-control") << (prefix + QJsonDocument(obj).toBinaryData()) << true << "";
}
- QTest::newRow("zeroes") << prefix << false;
+ QTest::newRow("json-zeroes") << prefix << false << " ";
prefix += "qbjs";
- QTest::newRow("bad-json-version0") << prefix << false;
- QTest::newRow("bad-json-version2") << (prefix + QByteArray("\2\0\0\0", 4)) << false;
+ QTest::newRow("bad-json-version0") << prefix << false << " ";
+ QTest::newRow("bad-json-version2") << (prefix + QByteArray("\2\0\0\0", 4)) << false << " ";
// valid qbjs version 1
prefix += QByteArray("\1\0\0\0");
// too large for the file (100 MB)
- QTest::newRow("bad-json-size-large1") << (prefix + QByteArray("\0\0\x40\x06")) << false;
+ QTest::newRow("bad-json-size-large1") << (prefix + QByteArray("\0\0\x40\x06")) << false << " ";
// too large for binary JSON (512 MB)
- QTest::newRow("bad-json-size-large2") << (prefix + QByteArray("\0\0\0\x20")) << false;
+ QTest::newRow("bad-json-size-large2") << (prefix + QByteArray("\0\0\0\x20")) << false << " ";
// could overflow
- QTest::newRow("bad-json-size-large3") << (prefix + "\xff\xff\xff\x7f") << false;
+ QTest::newRow("bad-json-size-large3") << (prefix + "\xff\xff\xff\x7f") << false << " ";
+#endif
+ // CBOR metadata
+ QByteArray cprefix = "QTMETADATA !1234";
+ cprefix[12] = 0; // current version
+ cprefix[13] = QT_VERSION_MAJOR;
+ cprefix[14] = QT_VERSION_MINOR;
+ cprefix[15] = qPluginArchRequirements();
+
+ QByteArray cborValid = [] {
+ QCborMap m;
+ m.insert(int(QtPluginMetaDataKeys::IID), QLatin1String("org.qt-project.tst_qplugin"));
+ m.insert(int(QtPluginMetaDataKeys::ClassName), QLatin1String("tst"));
+ m.insert(int(QtPluginMetaDataKeys::MetaData), QCborMap());
+ return QCborValue(m).toCbor();
+ }();
+ QTest::newRow("cbor-control") << (cprefix + cborValid) << true << "";
+
+ cprefix[12] = 1;
+ QTest::newRow("cbor-major-too-new") << (cprefix + cborValid) << false
+ << " Invalid metadata version";
+
+ cprefix[12] = 0;
+ cprefix[13] = QT_VERSION_MAJOR + 1;
+ QTest::newRow("cbor-major-too-new") << (cprefix + cborValid) << false << "";
+
+ cprefix[13] = QT_VERSION_MAJOR - 1;
+ QTest::newRow("cbor-major-too-old") << (cprefix + cborValid) << false << "";
+
+ cprefix[13] = QT_VERSION_MAJOR;
+ cprefix[14] = QT_VERSION_MINOR + 1;
+ QTest::newRow("cbor-minor-too-new") << (cprefix + cborValid) << false << "";
+
+ QTest::newRow("cbor-invalid") << (cprefix + "\xff") << false
+ << " Metadata parsing error: Invalid CBOR stream: unexpected 'break' byte";
+ QTest::newRow("cbor-not-map1") << (cprefix + "\x01") << false
+ << " Unexpected metadata contents";
+ QTest::newRow("cbor-not-map2") << (cprefix + "\x81\x01") << false
+ << " Unexpected metadata contents";
}
static const char invalidPluginSignature[] = "qplugin testfile";
@@ -214,6 +259,11 @@ void tst_QPlugin::scanInvalidPlugin()
// now try to load this
QFETCH(bool, loads);
+ QFETCH(QString, errMsg);
+ if (!errMsg.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg,
+ "Found invalid metadata in lib " + QFile::encodeName(newName) +
+ ":" + errMsg.toUtf8());
QPluginLoader loader(newName);
QCOMPARE(loader.load(), loads);
if (loads)
diff --git a/tests/auto/corelib/plugin/qplugin/tst_qplugin.pro b/tests/auto/corelib/plugin/qplugin/tst_qplugin.pro
index 8c6540fe87..4432ee20c1 100644
--- a/tests/auto/corelib/plugin/qplugin/tst_qplugin.pro
+++ b/tests/auto/corelib/plugin/qplugin/tst_qplugin.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qplugin
-QT = core testlib
+QT = core-private testlib
SOURCES = tst_qplugin.cpp
TESTDATA += plugins/*
diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h
index 04ce042e24..ac349c2f75 100644
--- a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h
+++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.h
@@ -35,7 +35,7 @@
class ThePlugin : public QObject, public PluginInterface
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.autotests.plugininterface" FILE "../empty.json")
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.autotests.plugininterface" FILE "../utf8_data.json")
Q_INTERFACES(PluginInterface)
public:
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index f34741281c..c517c0809a 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -140,6 +140,10 @@ void tst_QPluginLoader::cleanup()
void tst_QPluginLoader::errorString()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires Qt to create shared libraries.");
+#endif
+
const QString unknown(QLatin1String("Unknown error"));
{
@@ -206,6 +210,14 @@ void tst_QPluginLoader::errorString()
{
QPluginLoader loader( sys_qualifiedLibraryName("theplugin")); //a plugin
+
+ // Check metadata
+ const QJsonObject metaData = loader.metaData();
+ QCOMPARE(metaData.value("IID").toString(), QStringLiteral("org.qt-project.Qt.autotests.plugininterface"));
+ const QJsonObject kpluginObject = metaData.value("MetaData").toObject().value("KPlugin").toObject();
+ QCOMPARE(kpluginObject.value("Name[mr]").toString(), QString::fromUtf8("चौकट भूमिती"));
+
+ // Load
QCOMPARE(loader.load(), true);
QCOMPARE(loader.errorString(), unknown);
@@ -224,6 +236,9 @@ void tst_QPluginLoader::errorString()
void tst_QPluginLoader::loadHints()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires Qt to create shared libraries.");
+#endif
QPluginLoader loader;
QCOMPARE(loader.loadHints(), (QLibrary::LoadHints)0); //Do not crash
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);
@@ -233,6 +248,9 @@ void tst_QPluginLoader::loadHints()
void tst_QPluginLoader::deleteinstanceOnUnload()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires Qt to create shared libraries.");
+#endif
for (int pass = 0; pass < 2; ++pass) {
QPluginLoader loader1;
loader1.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin
@@ -268,6 +286,9 @@ void tst_QPluginLoader::deleteinstanceOnUnload()
void tst_QPluginLoader::loadDebugObj()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires a shared build of Qt, as QPluginLoader::setFileName is a no-op in static builds");
+#endif
#if defined (__ELF__)
QVERIFY(QFile::exists(QFINDTESTDATA("elftest/debugobj.so")));
QPluginLoader lib1(QFINDTESTDATA("elftest/debugobj.so"));
@@ -277,6 +298,9 @@ void tst_QPluginLoader::loadDebugObj()
void tst_QPluginLoader::loadCorruptElf()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires a shared build of Qt, as QPluginLoader::setFileName is a no-op in static builds");
+#endif
#if defined (__ELF__)
if (sizeof(void*) == 8) {
QVERIFY(QFile::exists(QFINDTESTDATA("elftest/corrupt1.elf64.so")));
@@ -377,6 +401,9 @@ void tst_QPluginLoader::loadMachO()
#if defined (Q_OS_UNIX)
void tst_QPluginLoader::loadGarbage()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires a shared build of Qt, as QPluginLoader::setFileName is a no-op in static builds");
+#endif
for (int i=0; i<5; i++) {
const QString name = QLatin1String("elftest/garbage") + QString::number(i + 1) + QLatin1String(".so");
QPluginLoader lib(QFINDTESTDATA(name));
@@ -388,6 +415,9 @@ void tst_QPluginLoader::loadGarbage()
void tst_QPluginLoader::relativePath()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires Qt to create shared libraries.");
+#endif
// Windows binaries run from release and debug subdirs, so we can't rely on the current dir.
const QString binDir = QFINDTESTDATA("bin");
QVERIFY(!binDir.isEmpty());
@@ -402,6 +432,9 @@ void tst_QPluginLoader::relativePath()
void tst_QPluginLoader::absolutePath()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires Qt to create shared libraries.");
+#endif
// Windows binaries run from release and debug subdirs, so we can't rely on the current dir.
const QString binDir = QFINDTESTDATA("bin");
QVERIFY(!binDir.isEmpty());
@@ -416,6 +449,9 @@ void tst_QPluginLoader::absolutePath()
void tst_QPluginLoader::reloadPlugin()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires Qt to create shared libraries.");
+#endif
QPluginLoader loader;
loader.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin
loader.load(); // not recommended, instance() should do the job.
@@ -451,6 +487,9 @@ void tst_QPluginLoader::preloadedPlugin_data()
void tst_QPluginLoader::preloadedPlugin()
{
+#if !defined(QT_SHARED)
+ QSKIP("This test requires Qt to create shared libraries.");
+#endif
// check that using QPluginLoader does not interfere with QLibrary
QFETCH(QString, libname);
QLibrary lib(libname);
diff --git a/tests/auto/corelib/plugin/qpluginloader/utf8_data.json b/tests/auto/corelib/plugin/qpluginloader/utf8_data.json
new file mode 100644
index 0000000000..7763b65178
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/utf8_data.json
@@ -0,0 +1,17 @@
+{
+ "KPlugin": {
+ "Name": "WindowGeometry",
+ "Name[mr]": "चौकट भूमिती",
+ "Name[pa]": "ਵਿੰਡੋਜà©à¨®à©ˆà¨Ÿà¨°à©€",
+ "Name[th]": "มิติขนาดของหน้าต่าง",
+ "Name[uk]": "Розміри вікна",
+ "Name[zh_CN]": "窗å£å½¢çŠ¶",
+ "Name[zh_TW]": "視窗ä½ç½®",
+ "ServiceTypes": [
+ "KCModule"
+ ]
+ },
+ "X-KDE-ParentComponents": [
+ "windowgeometry"
+ ]
+}
diff --git a/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro b/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro
new file mode 100644
index 0000000000..5df331314a
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborstreamreader/qcborstreamreader.pro
@@ -0,0 +1,11 @@
+QT = core testlib
+TARGET = tst_qcborstreamreader
+CONFIG += testcase
+SOURCES += \
+ tst_qcborstreamreader.cpp
+
+INCLUDEPATH += \
+ ../../../../../src/3rdparty/tinycbor/src \
+ ../../../../../src/3rdparty/tinycbor/tests/parser
+
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp
new file mode 100644
index 0000000000..24d9c7409e
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp
@@ -0,0 +1,1091 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qcborstream.h>
+#include <QtTest>
+
+class tst_QCborStreamReader : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase_data();
+ void basics();
+ void clear_data();
+ void clear();
+ void integers_data();
+ void integers();
+ void fixed_data();
+ void fixed();
+ void strings_data();
+ void strings();
+ void tags_data();
+ void tags() { fixed(); }
+ void emptyContainers_data();
+ void emptyContainers();
+
+ void arrays_data();
+ void arrays();
+ void maps_data() { arrays_data(); }
+ void maps();
+ void undefLengthArrays_data() { arrays_data(); }
+ void undefLengthArrays();
+ void undefLengthMaps_data() { arrays_data(); }
+ void undefLengthMaps();
+
+ void next_data() { arrays_data(); }
+ void next();
+ void validation_data();
+ void validation();
+ void recursionLimit_data();
+ void recursionLimit();
+
+ void addData_singleElement_data();
+ void addData_singleElement();
+ void addData_complex_data() { arrays_data(); }
+ void addData_complex();
+};
+
+#define FOR_CBOR_TYPE(F) \
+ F(QCborStreamReader::UnsignedInteger) \
+ F(QCborStreamReader::NegativeInteger) \
+ F(QCborStreamReader::ByteArray) \
+ F(QCborStreamReader::String) \
+ F(QCborStreamReader::Array) \
+ F(QCborStreamReader::Map) \
+ F(QCborStreamReader::Tag) \
+ F(QCborStreamReader::SimpleType) \
+ F(QCborStreamReader::Float16) \
+ F(QCborStreamReader::Float) \
+ F(QCborStreamReader::Double) \
+ F(QCborStreamReader::Invalid)
+
+QT_BEGIN_NAMESPACE
+namespace QTest {
+template<> char *toString<QCborStreamReader::Type>(const QCborStreamReader::Type &t)
+{
+ return qstrdup([=]() {
+ switch (t) {
+#define TYPE(t) \
+ case t: return QT_STRINGIFY(t);
+ FOR_CBOR_TYPE(TYPE)
+#undef TYPE
+ }
+ return "<huh?>";
+ }());
+}
+} // namespace QTest
+QT_END_NAMESPACE
+
+// Get the data from TinyCBOR (see src/3rdparty/tinycbor/tests/parser/data.cpp)
+#include "data.cpp"
+
+void tst_QCborStreamReader::initTestCase_data()
+{
+ QTest::addColumn<bool>("useDevice");
+ QTest::newRow("QByteArray") << false;
+ QTest::newRow("QBuffer") << true;
+}
+
+void tst_QCborStreamReader::basics()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QBuffer buffer;
+ QCborStreamReader reader;
+
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ QVERIFY(reader.device() != nullptr);
+ } else {
+ QCOMPARE(reader.device(), nullptr);
+ }
+
+ QCOMPARE(reader.currentOffset(), 0);
+ QCOMPARE(reader.lastError(), QCborError::EndOfFile);
+
+ QCOMPARE(reader.type(), QCborStreamReader::Invalid);
+ QVERIFY(!reader.isUnsignedInteger());
+ QVERIFY(!reader.isNegativeInteger());
+ QVERIFY(!reader.isByteArray());
+ QVERIFY(!reader.isString());
+ QVERIFY(!reader.isArray());
+ QVERIFY(!reader.isContainer());
+ QVERIFY(!reader.isMap());
+ QVERIFY(!reader.isTag());
+ QVERIFY(!reader.isSimpleType());
+ QVERIFY(!reader.isBool());
+ QVERIFY(!reader.isNull());
+ QVERIFY(!reader.isUndefined());
+ QVERIFY(!reader.isFloat16());
+ QVERIFY(!reader.isFloat());
+ QVERIFY(!reader.isDouble());
+ QVERIFY(!reader.isValid());
+ QVERIFY(reader.isInvalid());
+
+ QCOMPARE(reader.containerDepth(), 0);
+ QCOMPARE(reader.parentContainerType(), QCborStreamReader::Invalid);
+ QVERIFY(!reader.hasNext());
+ QVERIFY(!reader.next());
+ QCOMPARE(reader.lastError(), QCborError::EndOfFile);
+
+ QVERIFY(reader.isLengthKnown()); // well, it's not unknown
+ QCOMPARE(reader.length(), ~0ULL);
+
+ if (useDevice) {
+ reader.reparse();
+ QVERIFY(reader.device() != nullptr);
+ } else {
+ reader.addData(QByteArray());
+ QCOMPARE(reader.device(), nullptr);
+ }
+
+ // nothing changes, we added nothing
+ QCOMPARE(reader.currentOffset(), 0);
+ QCOMPARE(reader.lastError(), QCborError::EndOfFile);
+
+ QCOMPARE(reader.type(), QCborStreamReader::Invalid);
+ QVERIFY(!reader.isUnsignedInteger());
+ QVERIFY(!reader.isNegativeInteger());
+ QVERIFY(!reader.isByteArray());
+ QVERIFY(!reader.isString());
+ QVERIFY(!reader.isArray());
+ QVERIFY(!reader.isContainer());
+ QVERIFY(!reader.isMap());
+ QVERIFY(!reader.isTag());
+ QVERIFY(!reader.isSimpleType());
+ QVERIFY(!reader.isBool());
+ QVERIFY(!reader.isNull());
+ QVERIFY(!reader.isUndefined());
+ QVERIFY(!reader.isFloat16());
+ QVERIFY(!reader.isFloat());
+ QVERIFY(!reader.isDouble());
+ QVERIFY(!reader.isValid());
+ QVERIFY(reader.isInvalid());
+
+ QVERIFY(reader.isLengthKnown()); // well, it's not unknown
+ QCOMPARE(reader.length(), ~0ULL);
+
+ QCOMPARE(reader.containerDepth(), 0);
+ QCOMPARE(reader.parentContainerType(), QCborStreamReader::Invalid);
+ QVERIFY(!reader.hasNext());
+ QVERIFY(!reader.next());
+
+ reader.clear();
+ QCOMPARE(reader.device(), nullptr);
+ QCOMPARE(reader.currentOffset(), 0);
+ QCOMPARE(reader.lastError(), QCborError::EndOfFile);
+}
+
+void tst_QCborStreamReader::clear_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QCborError>("firstError");
+ QTest::addColumn<int>("offsetAfterSkip");
+ QTest::newRow("invalid") << QByteArray(512, '\xff') << QCborError{QCborError::UnexpectedBreak} << 0;
+ QTest::newRow("valid") << QByteArray(512, '\0') << QCborError{QCborError::NoError} << 0;
+ QTest::newRow("skipped") << QByteArray(512, '\0') << QCborError{QCborError::NoError} << 1;
+}
+
+void tst_QCborStreamReader::clear()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+ QFETCH(QCborError, firstError);
+ QFETCH(int, offsetAfterSkip);
+
+ QBuffer buffer(&data);
+ QCborStreamReader reader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ QCOMPARE(reader.isValid(), !firstError);
+ QCOMPARE(reader.currentOffset(), 0);
+ QCOMPARE(reader.lastError(), firstError);
+
+ if (offsetAfterSkip) {
+ reader.next();
+ QVERIFY(!reader.isValid());
+ QCOMPARE(reader.currentOffset(), 1);
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ }
+
+ reader.clear();
+ QCOMPARE(reader.device(), nullptr);
+ QCOMPARE(reader.currentOffset(), 0);
+ QCOMPARE(reader.lastError(), QCborError::EndOfFile);
+}
+
+void tst_QCborStreamReader::integers_data()
+{
+ addIntegers();
+}
+
+void tst_QCborStreamReader::integers()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+ QFETCH(bool, isNegative);
+ QFETCH(quint64, expectedRaw);
+ QFETCH(qint64, expectedValue);
+ QFETCH(bool, inInt64Range);
+ quint64 absolute = (isNegative ? expectedRaw + 1 : expectedRaw);
+
+ QBuffer buffer(&data);
+ QCborStreamReader reader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ QVERIFY(reader.isInteger());
+
+ if (inInt64Range)
+ QCOMPARE(reader.toInteger(), expectedValue);
+ if (isNegative)
+ QCOMPARE(quint64(reader.toNegativeInteger()), absolute);
+ else
+ QCOMPARE(reader.toUnsignedInteger(), absolute);
+}
+
+void escapedAppendTo(QString &result, const QByteArray &data)
+{
+ result += "h'" + QString::fromLatin1(data.toHex()) + '\'';
+}
+
+void escapedAppendTo(QString &result, const QString &data)
+{
+ result += '"';
+ for (int i = 0; i <= data.size(); i += 245) {
+ // hopefully we won't have a surrogate pair split here
+ QScopedArrayPointer<char> escaped(QTest::toPrettyUnicode(data.mid(i, 245)));
+ QLatin1String s(escaped.data() + 1); // skip opening "
+ s.chop(1); // drop the closing "
+ result += s;
+ }
+ result += '"';
+}
+
+template <typename S, QCborStreamReader::StringResult<S> (QCborStreamReader:: *Decoder)()>
+static QString parseOneString_helper(QCborStreamReader &reader)
+{
+ QString result;
+ bool parens = !reader.isLengthKnown();
+ if (parens)
+ result += '(';
+
+ auto r = (reader.*Decoder)();
+ const char *comma = "";
+ while (r.status == QCborStreamReader::Ok) {
+ result += comma;
+ escapedAppendTo(result, r.data);
+
+ r = (reader.*Decoder)();
+ comma = ", ";
+ }
+
+ if (r.status == QCborStreamReader::Error)
+ return QString();
+
+ if (parens)
+ result += ')';
+ return result;
+}
+
+static QString parseOneByteArray(QCborStreamReader &reader)
+{
+ return parseOneString_helper<QByteArray, &QCborStreamReader::readByteArray>(reader);
+}
+
+static QString parseOneString(QCborStreamReader &reader)
+{
+ return parseOneString_helper<QString, &QCborStreamReader::readString>(reader);
+}
+
+static QString makeNegativeString(QCborNegativeInteger n)
+{
+ return n == QCborNegativeInteger(0) ?
+ QString("-18446744073709551616") :
+ QString("-%1").arg(quint64(n));
+}
+
+template <typename T> static inline bool canConvertTo(double v)
+{
+ // The [conv.fpint] (7.10 Floating-integral conversions) section of the
+ // standard says only exact conversions are guaranteed. Converting
+ // integrals to floating-point with loss of precision has implementation-
+ // defined behavior whether the next higher or next lower is returned;
+ // converting FP to integral is UB if it can't be represented.;
+ Q_STATIC_ASSERT(std::numeric_limits<T>::is_integer);
+
+ double supremum = ldexp(1, std::numeric_limits<T>::digits);
+ if (v >= supremum)
+ return false;
+
+ if (v < std::numeric_limits<T>::min()) // either zero or a power of two, so it's exact
+ return false;
+
+ // we're in range
+ return v == floor(v);
+}
+
+static QString makeFpString(double v)
+{
+ if (canConvertTo<qint64>(v))
+ return QString::number(qint64(v)) + '.';
+ if (canConvertTo<quint64>(v))
+ return QString::number(quint64(v)) + '.';
+
+ QString s = QString::number(v, 'g', std::numeric_limits<double>::digits10 + 2);
+ if (!s.contains('.') && !s.contains('e') && !qIsInf(v) && !qIsNaN(v))
+ s += '.';
+ return s;
+}
+
+static QString makeFpString(float v)
+{
+ if (qIsInf(v))
+ return v > 0 ? "inf" : "-inf";
+ if (qIsNaN(v))
+ return "nan";
+ return makeFpString(double(v)) + 'f';
+}
+
+static QString makeFpString(qfloat16 v)
+{
+ if (qIsInf(v))
+ return v > 0 ? "inf" : "-inf";
+ if (qIsNaN(v))
+ return "nan";
+ return makeFpString(double(v)) + "f16";
+}
+
+static QString parseOne(QCborStreamReader &reader)
+{
+ QString result;
+
+ switch (reader.type()) {
+ case QCborStreamReader::UnsignedInteger:
+ result = QString::number(reader.toUnsignedInteger());
+ break;
+ case QCborStreamReader::NegativeInteger:
+ result = makeNegativeString(reader.toNegativeInteger());
+ break;
+ case QCborStreamReader::ByteArray:
+ return parseOneByteArray(reader);
+ case QCborStreamReader::String:
+ return parseOneString(reader);
+ case QCborStreamReader::Array:
+ case QCborStreamReader::Map: {
+ const char *delimiters = (reader.isArray() ? "[]" : "{}");
+ result += delimiters[0];
+ reader.enterContainer();
+
+ QLatin1String comma("");
+ while (reader.lastError() == QCborError::NoError && reader.hasNext()) {
+ result += comma + parseOne(reader);
+ comma = QLatin1String(", ");
+
+ if (reader.parentContainerType() == QCborStreamReader::Map
+ && reader.lastError() == QCborError::NoError)
+ result += ": " + parseOne(reader);
+ }
+
+ if (reader.isValid())
+ return QString();
+ if (reader.lastError() != QCborError::NoError)
+ return QString();
+ reader.leaveContainer();
+ result += delimiters[1];
+ return result;
+ }
+ case QCborStreamReader::Tag: {
+ QCborTag tag = reader.toTag();
+ if (!reader.next())
+ return QString();
+ return QString("%1(%2)").arg(quint64(tag)).arg(parseOne(reader));
+ }
+ case QCborStreamReader::SimpleType:
+ switch (reader.toSimpleType()) {
+ case QCborSimpleType::False:
+ result = QStringLiteral("false");
+ break;
+ case QCborSimpleType::True:
+ result = QStringLiteral("true");
+ break;
+ case QCborSimpleType::Null:
+ result = QStringLiteral("null");
+ break;
+ case QCborSimpleType::Undefined:
+ result = QStringLiteral("undefined");
+ break;
+ default:
+ result = QString("simple(%1)").arg(quint8(reader.toSimpleType()));
+ break;
+ }
+ break;
+ case QCborStreamReader::Float16:
+ result = makeFpString(reader.toFloat16());
+ break;
+ case QCborStreamReader::Float:
+ result = makeFpString(reader.toFloat());
+ break;
+ case QCborStreamReader::Double:
+ result = makeFpString(reader.toDouble());
+ break;
+ case QCborStreamReader::Invalid:
+ return QStringLiteral("<invalid>");
+ }
+
+ if (!reader.next())
+ return QString();
+ return result;
+}
+
+bool parseNonRecursive(QString &result, bool &printingStringChunks, QCborStreamReader &reader)
+{
+ while (reader.lastError() == QCborError::NoError) {
+ if (!reader.hasNext()) {
+ if (result.endsWith(", "))
+ result.chop(2);
+ if (reader.containerDepth() == 0)
+ return true;
+ result += reader.parentContainerType() == QCborStreamReader::Map ? "}, " : "], ";
+ reader.leaveContainer();
+ continue;
+ }
+
+ switch (reader.type()) {
+ case QCborStreamReader::UnsignedInteger:
+ result += QString::number(reader.toUnsignedInteger());
+ break;
+ case QCborStreamReader::NegativeInteger:
+ result += makeNegativeString(reader.toNegativeInteger());
+ break;
+ case QCborStreamReader::ByteArray:
+ case QCborStreamReader::String: {
+ QCborStreamReader::StringResultCode status;
+ if (!printingStringChunks && !reader.isLengthKnown()) {
+ printingStringChunks = true;
+ result += '(';
+ }
+ if (reader.isByteArray()) {
+ auto r = reader.readByteArray();
+ status = r.status;
+ if (r.status == QCborStreamReader::Ok)
+ escapedAppendTo(result, r.data);
+ } else {
+ auto r = reader.readString();
+ status = r.status;
+ if (r.status == QCborStreamReader::Ok)
+ escapedAppendTo(result, r.data);
+ }
+
+ if (status == QCborStreamReader::EndOfString) {
+ if (result.endsWith(", "))
+ result.chop(2);
+ if (printingStringChunks)
+ result += ')';
+ result += ", ";
+ printingStringChunks = false;
+ }
+ if (status == QCborStreamReader::Ok && printingStringChunks)
+ result += ", ";
+
+ continue;
+ }
+ case QCborStreamReader::Array:
+ result += '[';
+ reader.enterContainer();
+ continue;
+ case QCborStreamReader::Map:
+ result += '{';
+ reader.enterContainer();
+ continue;
+ case QCborStreamReader::Tag:
+ result += QString("Tag:%1:").arg(quint64(reader.toTag()));
+ reader.next();
+ continue; // skip the comma
+ case QCborStreamReader::SimpleType:
+ switch (reader.toSimpleType()) {
+ case QCborSimpleType::False:
+ result += QStringLiteral("false");
+ break;
+ case QCborSimpleType::True:
+ result += QStringLiteral("true");
+ break;
+ case QCborSimpleType::Null:
+ result += QStringLiteral("null");
+ break;
+ case QCborSimpleType::Undefined:
+ result += QStringLiteral("undefined");
+ break;
+ default:
+ result += QString("simple(%1)").arg(quint8(reader.toSimpleType()));
+ break;
+ }
+ break;
+ case QCborStreamReader::Float16:
+ result += makeFpString(reader.toFloat16());
+ break;
+ case QCborStreamReader::Float:
+ result += makeFpString(reader.toFloat());
+ break;
+ case QCborStreamReader::Double:
+ result += makeFpString(reader.toDouble());
+ break;
+ case QCborStreamReader::Invalid:
+ break;
+ }
+
+ reader.next();
+ result += ", ";
+ }
+ return false;
+};
+
+
+static QString &removeIndicators(QString &str)
+{
+ // remove any CBOR encoding indicators from the string, since parseOne above
+ // doesn't produce them
+ static QRegularExpression rx("_(\\d+)? ?");
+ return str.replace(rx, QString());
+}
+
+void tst_QCborStreamReader::fixed_data()
+{
+ addColumns();
+ addFixedData();
+}
+
+void tst_QCborStreamReader::fixed()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ QBuffer buffer(&data);
+ QCborStreamReader reader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ QCOMPARE(parseOne(reader), expected);
+
+ // verify that we can re-read
+ reader.reset();
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ QCOMPARE(parseOne(reader), expected);
+}
+
+void tst_QCborStreamReader::strings_data()
+{
+ addColumns();
+ addStringsData();
+}
+
+void tst_QCborStreamReader::strings()
+{
+ fixed();
+ if (QTest::currentTestFailed())
+ return;
+
+ // Extra string checks:
+ // We'll compare the reads using readString() and readByteArray()
+ // (henceforth "control data" because fixed() above tested them) with those
+ // obtained with readStringChunk().
+
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ QFETCH_GLOBAL(bool, useDevice);
+ bool isChunked = expected.startsWith('(');
+
+ QBuffer buffer(&data), controlBuffer(&data);
+ QCborStreamReader reader(data), controlReader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ controlBuffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ controlReader.setDevice(&controlBuffer);
+ }
+ QVERIFY(reader.isString() || reader.isByteArray());
+ QCOMPARE(reader.isLengthKnown(), !isChunked);
+
+ if (!isChunked)
+ QCOMPARE(reader.currentStringChunkSize(), qsizetype(reader.length()));
+
+ int chunks = 0;
+ forever {
+ QCborStreamReader::StringResult<QByteArray> controlData;
+ if (reader.isString()) {
+ auto r = controlReader.readString();
+ controlData.data = r.data.toUtf8();
+ controlData.status = r.status;
+ } else {
+ controlData = controlReader.readByteArray();
+ }
+ QVERIFY(controlData.status != QCborStreamReader::Error);
+
+ for (int i = 0; i < 10; ++i) {
+ // this call must work several times with the same result
+ QCOMPARE(reader.currentStringChunkSize(), controlData.data.size());
+ }
+
+ QByteArray chunk(controlData.data.size(), Qt::Uninitialized);
+ auto r = reader.readStringChunk(chunk.data(), chunk.size());
+ QCOMPARE(r.status, controlData.status);
+ if (r.status == QCborStreamReader::Ok)
+ QCOMPARE(r.data, controlData.data.size());
+ else
+ QCOMPARE(r.data, 0);
+ QCOMPARE(chunk, controlData.data);
+
+ if (r.status == QCborStreamReader::EndOfString)
+ break;
+ ++chunks;
+ }
+
+ if (!isChunked)
+ QCOMPARE(chunks, 1);
+}
+
+void tst_QCborStreamReader::tags_data()
+{
+ addColumns();
+ addTagsData();
+}
+
+void tst_QCborStreamReader::emptyContainers_data()
+{
+ addColumns();
+ addEmptyContainersData();
+}
+
+void tst_QCborStreamReader::emptyContainers()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ QBuffer buffer(&data);
+ QCborStreamReader reader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ if (reader.isLengthKnown())
+ QCOMPARE(reader.length(), 0U);
+ QCOMPARE(parseOne(reader), expected);
+
+ // verify that we can re-read
+ reader.reset();
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ if (reader.isLengthKnown())
+ QCOMPARE(reader.length(), 0U);
+ QCOMPARE(parseOne(reader), expected);
+}
+
+void tst_QCborStreamReader::arrays_data()
+{
+ addColumns();
+ addFixedData();
+ addStringsData();
+ addTagsData();
+ addEmptyContainersData();
+}
+
+static void checkContainer(int len, const QByteArray &data, const QString &expected)
+{
+ QFETCH_GLOBAL(bool, useDevice);
+
+ QByteArray copy = data;
+ QBuffer buffer(&copy);
+ QCborStreamReader reader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ if (len >= 0) {
+ QVERIFY(reader.isLengthKnown());
+ QCOMPARE(reader.length(), uint(len));
+ }
+ QCOMPARE(parseOne(reader), expected);
+
+ // verify that we can re-read
+ reader.reset();
+ QVERIFY(reader.isValid());
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ if (len >= 0) {
+ QVERIFY(reader.isLengthKnown());
+ QCOMPARE(reader.length(), uint(len));
+ }
+ QCOMPARE(parseOne(reader), expected);
+}
+
+void tst_QCborStreamReader::arrays()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ checkContainer(1, '\x81' + data, '[' + expected + ']');
+ if (QTest::currentTestFailed())
+ return;
+
+ checkContainer(2, '\x82' + data + data, '[' + expected + ", " + expected + ']');
+}
+
+void tst_QCborStreamReader::maps()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ // int keys
+ checkContainer(1, "\xa1\1" + data, "{1: " + expected + '}');
+ if (QTest::currentTestFailed())
+ return;
+
+ checkContainer(2, "\xa2\1" + data + '\x20' + data,
+ "{1: " + expected + ", -1: " + expected + '}');
+ if (QTest::currentTestFailed())
+ return;
+
+ // string keys
+ checkContainer(1, "\xa1\x65Hello" + data, "{\"Hello\": " + expected + '}');
+ if (QTest::currentTestFailed())
+ return;
+
+ checkContainer(2, "\xa2\x65World" + data + "\x65Hello" + data,
+ "{\"World\": " + expected + ", \"Hello\": " + expected + '}');
+}
+
+void tst_QCborStreamReader::undefLengthArrays()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ checkContainer(-1, '\x9f' + data + '\xff', '[' + expected + ']');
+ if (QTest::currentTestFailed())
+ return;
+
+ checkContainer(-2, '\x9f' + data + data + '\xff', '[' + expected + ", " + expected + ']');
+}
+
+void tst_QCborStreamReader::undefLengthMaps()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ // int keys
+ checkContainer(-1, "\xbf\1" + data + '\xff', "{1: " + expected + '}');
+ if (QTest::currentTestFailed())
+ return;
+
+ checkContainer(-2, "\xbf\1" + data + '\x20' + data + '\xff',
+ "{1: " + expected + ", -1: " + expected + '}');
+ if (QTest::currentTestFailed())
+ return;
+
+ // string keys
+ checkContainer(-1, "\xbf\x65Hello" + data + '\xff', "{\"Hello\": " + expected + '}');
+ if (QTest::currentTestFailed())
+ return;
+
+ checkContainer(-2, "\xbf\x65World" + data + "\x65Hello" + data + '\xff',
+ "{\"World\": " + expected + ", \"Hello\": " + expected + '}');
+}
+
+void tst_QCborStreamReader::next()
+{
+ QFETCH(QByteArray, data);
+
+ auto doit = [](QByteArray data) {
+ QFETCH_GLOBAL(bool, useDevice);
+
+ QBuffer buffer(&data);
+ QCborStreamReader reader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ return reader.next();
+ };
+
+ QVERIFY(doit('\x81' + data));
+ QVERIFY(doit('\x82' + data + data));
+ QVERIFY(doit('\x9f' + data + '\xff'));
+ QVERIFY(doit("\x81\x9f" + data + '\xff'));
+ QVERIFY(doit("\x9f\x81" + data + '\xff'));
+
+ QVERIFY(doit("\xa1\1" + data));
+ QVERIFY(doit("\xa2\1" + data + '\x20' + data));
+ QVERIFY(doit("\xbf\1" + data + '\xff'));
+ QVERIFY(doit("\xbf\x9f\1\xff\x9f" + data + "\xff\xff"));
+}
+
+void tst_QCborStreamReader::validation_data()
+{
+ addValidationColumns();
+ addValidationData();
+}
+
+void tst_QCborStreamReader::validation()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+
+ QBuffer buffer(&data);
+ QCborStreamReader reader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ parseOne(reader);
+ QVERIFY(reader.lastError() != QCborError::NoError);
+
+ // next() should fail
+ reader.reset();
+ QVERIFY(!reader.next());
+ QVERIFY(reader.lastError() != QCborError::NoError);
+}
+
+static const int Recursions = 3;
+void tst_QCborStreamReader::recursionLimit_data()
+{
+ static const int recursions = Recursions + 2;
+ QTest::addColumn<QByteArray>("data");
+
+ QTest::newRow("array") << QByteArray(recursions, '\x81') + '\x20';
+ QTest::newRow("_array") << QByteArray(recursions, '\x9f') + '\x20' + QByteArray(recursions, '\xff');
+
+ QByteArray data;
+ for (int i = 0; i < recursions; ++i)
+ data += "\xa1\x65Hello";
+ data += '\2';
+ QTest::newRow("map-recursive-values") << data;
+
+ data.clear();
+ for (int i = 0; i < recursions; ++i)
+ data += "\xbf\x65World";
+ data += '\2';
+ for (int i = 0; i < recursions; ++i)
+ data += "\xff";
+ QTest::newRow("_map-recursive-values") << data;
+
+ data = QByteArray(recursions, '\xa1');
+ data += '\2';
+ for (int i = 0; i < recursions; ++i)
+ data += "\x7f\x64quux\xff";
+ QTest::newRow("map-recursive-keys") << data;
+
+ data = QByteArray(recursions, '\xbf');
+ data += '\2';
+ for (int i = 0; i < recursions; ++i)
+ data += "\1\xff";
+ QTest::newRow("_map-recursive-keys") << data;
+
+ data.clear();
+ for (int i = 0; i < recursions / 2; ++i)
+ data += "\x81\xa1\1";
+ data += '\2';
+ QTest::newRow("mixed") << data;
+}
+
+void tst_QCborStreamReader::recursionLimit()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+
+ data.prepend('\x81');
+ QBuffer buffer(&data);
+ QCborStreamReader reader(data);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+
+ // verify that it works normally:
+ QVERIFY(reader.enterContainer());
+ QVERIFY(reader.next());
+ QVERIFY(!reader.hasNext());
+
+ reader.reset();
+ QVERIFY(reader.enterContainer());
+ QVERIFY(!reader.next(Recursions));
+ QCOMPARE(reader.lastError(), QCborError::NestingTooDeep);
+}
+
+void tst_QCborStreamReader::addData_singleElement_data()
+{
+ addColumns();
+ addFixedData();
+ addNonChunkedStringsData();
+}
+
+void tst_QCborStreamReader::addData_singleElement()
+{
+ QFETCH_GLOBAL(bool, useDevice);
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ QByteArray growing;
+ QBuffer buffer(&growing);
+ QCborStreamReader reader;
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+ for (int i = 0; i < data.size() - 1; ++i) {
+ // add one byte from the data
+ if (useDevice) {
+ growing.append(data.at(i));
+ reader.reparse();
+ } else {
+ reader.addData(data.constData() + i, 1);
+ }
+
+ parseOne(reader);
+ QCOMPARE(reader.lastError(), QCborError::EndOfFile);
+ }
+
+ // add the last byte
+ if (useDevice) {
+ growing.append(data.right(1));
+ reader.reparse();
+ } else {
+ reader.addData(data.right(1));
+ }
+ QCOMPARE(reader.lastError(), QCborError::NoError);
+ QCOMPARE(parseOne(reader), expected);
+}
+
+void tst_QCborStreamReader::addData_complex()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QString, expected);
+ removeIndicators(expected);
+
+ // transform tags (parseNonRecursive can't produce the usual form)
+ expected.replace(QRegularExpression(R"/((\d+)\(([^)]+)\))/"), "Tag:\\1:\\2");
+
+ auto doit = [](const QByteArray &data) {
+ QFETCH_GLOBAL(bool, useDevice);
+
+ // start with one byte
+ int added = 1;
+ QByteArray growing = data.left(added);
+ QBuffer buffer(&growing);
+ QCborStreamReader reader(growing);
+ if (useDevice) {
+ buffer.open(QIODevice::ReadOnly);
+ reader.setDevice(&buffer);
+ }
+
+ QString result;
+ bool printingStringChunks = false;
+ forever {
+ if (parseNonRecursive(result, printingStringChunks, reader))
+ return result;
+ if (reader.lastError() != QCborError::EndOfFile)
+ return reader.lastError().toString();
+
+ while (reader.lastError() == QCborError::EndOfFile) {
+ // add more data
+ if (added == data.size())
+ return QStringLiteral("Couldn't parse even with all data");
+
+ if (useDevice) {
+ growing.append(data.at(added));
+ reader.reparse();
+ } else {
+ reader.addData(data.constData() + added, 1);
+ }
+ ++added;
+ }
+ }
+ };
+
+ // plain:
+ QCOMPARE(doit(data), expected);
+
+ // in an array
+ QCOMPARE(doit('\x81' + data), '[' + expected + ']');
+ QCOMPARE(doit('\x82' + data + data), '[' + expected + ", " + expected + ']');
+
+ QCOMPARE(doit('\x9f' + data + '\xff'), '[' + expected + ']');
+ QCOMPARE(doit('\x9f' + data + data + '\xff'), '[' + expected + ", " + expected + ']');
+
+ // in a map
+ QCOMPARE(doit("\xa1\x01" + data), "{1, " + expected + '}');
+ QCOMPARE(doit("\xa1\x65Hello" + data), "{\"Hello\", " + expected + '}');
+ QCOMPARE(doit("\xa1\x7f\x65Hello\x65World\xff" + data), "{(\"Hello\", \"World\"), " + expected + '}');
+ QCOMPARE(doit("\xa2\x01" + data + "\x65Hello" + data),
+ "{1, " + expected + ", \"Hello\", " + expected + '}');
+
+ QCOMPARE(doit("\xbf\x01" + data + '\xff'), "{1, " + expected + '}');
+
+ // mixed
+ QCOMPARE(doit("\xbf\x01\x81" + data + '\xff'), "{1, [" + expected + "]}");
+ QCOMPARE(doit("\xbf\x01\x82" + data + data + '\xff'),
+ "{1, [" + expected + ", " + expected + "]}");
+ QCOMPARE(doit("\xbf\x01\x9f" + data + data + "\xff\xff"),
+ "{1, [" + expected + ", " + expected + "]}");
+}
+
+
+QTEST_MAIN(tst_QCborStreamReader)
+
+#include "tst_qcborstreamreader.moc"
diff --git a/tests/auto/corelib/serialization/qcborstreamwriter/qcborstreamwriter.pro b/tests/auto/corelib/serialization/qcborstreamwriter/qcborstreamwriter.pro
new file mode 100644
index 0000000000..3391b5a296
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborstreamwriter/qcborstreamwriter.pro
@@ -0,0 +1,8 @@
+QT = core testlib
+TARGET = tst_qcborstreamwriter
+CONFIG += testcase
+SOURCES += \
+ tst_qcborstreamwriter.cpp
+
+INCLUDEPATH += ../../../../../src/3rdparty/tinycbor/tests/encoder
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp b/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp
new file mode 100644
index 0000000000..6995b4d08b
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborstreamwriter/tst_qcborstreamwriter.cpp
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest>
+
+class tst_QCborStreamWriter : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase_data();
+ void fixed_data();
+ void fixed();
+ void strings_data();
+ void strings() { fixed(); }
+ void nonAsciiStrings_data();
+ void nonAsciiStrings();
+ void arraysAndMaps_data();
+ void arraysAndMaps() { fixed(); }
+ void tags_data();
+ void tags();
+ void arrays_data() { tags_data(); }
+ void arrays();
+ void maps_data() { tags_data(); }
+ void maps();
+};
+
+// Get the data from TinyCBOR (see src/3rdparty/tinycbor/tests/encoder/data.cpp)
+typedef quint64 CborTag;
+#include "data.cpp"
+
+void encodeVariant(QCborStreamWriter &writer, const QVariant &v)
+{
+ int type = v.userType();
+ switch (type) {
+ case QVariant::Int:
+ case QVariant::LongLong:
+ return writer.append(v.toLongLong());
+
+ case QVariant::UInt:
+ case QVariant::ULongLong:
+ return writer.append(v.toULongLong());
+
+ case QVariant::Bool:
+ return writer.append(v.toBool());
+
+ case QVariant::Invalid:
+ return writer.appendUndefined();
+
+ case QMetaType::VoidStar:
+ return writer.append(nullptr);
+
+ case QVariant::Double:
+ return writer.append(v.toDouble());
+
+ case QMetaType::Float:
+ return writer.append(v.toFloat());
+
+ case QVariant::String:
+ return writer.append(v.toString());
+
+ case QVariant::ByteArray:
+ return writer.append(v.toByteArray());
+
+ default:
+ if (type == qMetaTypeId<NegativeInteger>())
+ return writer.append(QCborNegativeInteger(v.value<NegativeInteger>().abs));
+ if (type == qMetaTypeId<SimpleType>())
+ return writer.append(QCborSimpleType(v.value<SimpleType>().type));
+ if (type == qMetaTypeId<qfloat16>())
+ return writer.append(v.value<qfloat16>());
+ if (type == qMetaTypeId<Tag>()) {
+ writer.append(QCborTag(v.value<Tag>().tag));
+ return encodeVariant(writer, v.value<Tag>().tagged);
+ }
+ if (type == QVariant::List || type == qMetaTypeId<IndeterminateLengthArray>()) {
+ QVariantList list = v.toList();
+ if (type == qMetaTypeId<IndeterminateLengthArray>()) {
+ list = v.value<IndeterminateLengthArray>();
+ writer.startArray();
+ } else {
+ writer.startArray(list.length());
+ }
+ for (const QVariant &v2 : qAsConst(list))
+ encodeVariant(writer, v2);
+ QVERIFY(writer.endArray());
+ return;
+ }
+ if (type == qMetaTypeId<Map>() || type == qMetaTypeId<IndeterminateLengthMap>()) {
+ Map map = v.value<Map>();
+ if (type == qMetaTypeId<IndeterminateLengthMap>()) {
+ map = v.value<IndeterminateLengthMap>();
+ writer.startMap();
+ } else {
+ writer.startMap(map.length());
+ }
+ for (auto pair : qAsConst(map)) {
+ encodeVariant(writer, pair.first);
+ encodeVariant(writer, pair.second);
+ }
+ QVERIFY(writer.endMap());
+ return;
+ }
+ }
+ QFAIL("Shouldn't have got here");
+}
+
+void compare(const QVariant &input, const QByteArray &output)
+{
+ QFETCH_GLOBAL(bool, useDevice);
+
+ if (useDevice) {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ QCborStreamWriter writer(&buffer);
+ encodeVariant(writer, input);
+ QCOMPARE(buffer.data(), output);
+ } else {
+ QByteArray buffer;
+ QCborStreamWriter writer(&buffer);
+ encodeVariant(writer, input);
+ QCOMPARE(buffer, output);
+ }
+}
+
+void tst_QCborStreamWriter::initTestCase_data()
+{
+ QTest::addColumn<bool>("useDevice");
+ QTest::newRow("QByteArray") << false;
+ QTest::newRow("QIODevice") << true;
+}
+
+void tst_QCborStreamWriter::fixed_data()
+{
+ addColumns();
+ addFixedData();
+}
+
+void tst_QCborStreamWriter::fixed()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+ compare(input, output);
+}
+
+void tst_QCborStreamWriter::strings_data()
+{
+ addColumns();
+ addStringsData();
+}
+
+void tst_QCborStreamWriter::nonAsciiStrings_data()
+{
+ QTest::addColumn<QByteArray>("output");
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<bool>("isLatin1");
+
+ QByteArray latin1 = u8"Résumé";
+ QTest::newRow("shortlatin1")
+ << ("\x68" + latin1) << QString::fromUtf8(latin1) << true;
+
+ // replicate it 5 times (total 40 bytes)
+ latin1 += latin1 + latin1 + latin1 + latin1;
+ QTest::newRow("longlatin1")
+ << ("\x78\x28" + latin1) << QString::fromUtf8(latin1) << true;
+
+ QByteArray nonlatin1 = u8"ΧαίÏετε";
+ QTest::newRow("shortnonlatin1")
+ << ("\x6e" + nonlatin1) << QString::fromUtf8(nonlatin1) << false;
+
+ // replicate it 4 times (total 56 bytes)
+ nonlatin1 = nonlatin1 + nonlatin1 + nonlatin1 + nonlatin1;
+ QTest::newRow("longnonlatin1")
+ << ("\x78\x38" + nonlatin1) << QString::fromUtf8(nonlatin1) << false;
+}
+
+void tst_QCborStreamWriter::nonAsciiStrings()
+{
+ QFETCH(QByteArray, output);
+ QFETCH(QString, input);
+ QFETCH(bool, isLatin1);
+ QFETCH_GLOBAL(bool, useDevice);
+
+ // will be wrong if !isLatin1
+ QByteArray latin1 = input.toLatin1();
+
+ if (useDevice) {
+ {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ QCborStreamWriter writer(&buffer);
+ writer.append(input);
+ QCOMPARE(buffer.data(), output);
+ }
+
+ if (isLatin1) {
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ QCborStreamWriter writer(&buffer);
+ writer.append(QLatin1String(latin1.constData(), latin1.size()));
+ QCOMPARE(buffer.data(), output);
+ }
+ } else {
+ {
+ QByteArray buffer;
+ QCborStreamWriter writer(&buffer);
+ encodeVariant(writer, input);
+ QCOMPARE(buffer, output);
+ }
+
+ if (isLatin1) {
+ QByteArray buffer;
+ QCborStreamWriter writer(&buffer);
+ writer.append(QLatin1String(latin1.constData(), latin1.size()));
+ QCOMPARE(buffer, output);
+ }
+ }
+}
+
+void tst_QCborStreamWriter::arraysAndMaps_data()
+{
+ addColumns();
+ addArraysAndMaps();
+}
+
+void tst_QCborStreamWriter::tags_data()
+{
+ addColumns();
+ addFixedData();
+ addStringsData();
+ addArraysAndMaps();
+}
+
+void tst_QCborStreamWriter::tags()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+
+ compare(QVariant::fromValue(Tag{1, input}), "\xc1" + output);
+}
+
+void tst_QCborStreamWriter::arrays()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+
+ compare(make_list(input), "\x81" + output);
+ if (QTest::currentTestFailed())
+ return;
+
+ compare(make_list(input, input), "\x82" + output + output);
+ if (QTest::currentTestFailed())
+ return;
+
+ // nested lists
+ compare(make_list(make_list(input)), "\x81\x81" + output);
+ if (QTest::currentTestFailed())
+ return;
+
+ compare(make_list(make_list(input), make_list(input)), "\x82\x81" + output + "\x81" + output);
+}
+
+void tst_QCborStreamWriter::maps()
+{
+ QFETCH(QVariant, input);
+ QFETCH(QByteArray, output);
+
+ compare(make_map({{1, input}}), "\xa1\1" + output);
+ if (QTest::currentTestFailed())
+ return;
+
+ compare(make_map({{1, input}, {input, 24}}), "\xa2\1" + output + output + "\x18\x18");
+}
+
+QTEST_MAIN(tst_QCborStreamWriter)
+
+#include "tst_qcborstreamwriter.moc"
diff --git a/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro b/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro
new file mode 100644
index 0000000000..9dd67da1f0
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro
@@ -0,0 +1,11 @@
+QT = core testlib
+TARGET = tst_qcborvalue
+CONFIG += testcase
+SOURCES += \
+ tst_qcborvalue.cpp
+
+INCLUDEPATH += \
+ ../../../../../src/3rdparty/tinycbor/src \
+ ../../../../../src/3rdparty/tinycbor/tests/parser
+
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
new file mode 100644
index 0000000000..b69c993efb
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
@@ -0,0 +1,1692 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qcborvalue.h>
+#include <QtTest>
+
+Q_DECLARE_METATYPE(QCborValue)
+Q_DECLARE_METATYPE(QCborValue::EncodingOptions)
+
+class tst_QCborValue : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void basics_data();
+ void basics();
+ void tagged_data() { basics_data(); }
+ void tagged();
+ void extendedTypes_data();
+ void extendedTypes();
+ void copyCompare_data() { basics_data(); }
+ void copyCompare();
+
+ void arrayDefaultInitialization();
+ void arrayEmptyInitializerList();
+ void arrayEmptyDetach();
+ void arrayInitializerList();
+ void arrayMutation();
+ void arrayPrepend();
+ void arrayInsertRemove_data() { basics_data(); }
+ void arrayInsertRemove();
+ void arrayInsertTagged_data() { basics_data(); }
+ void arrayInsertTagged();
+ void arrayStringElements();
+ void arraySelfAssign_data() { basics_data(); }
+ void arraySelfAssign();
+
+ void mapDefaultInitialization();
+ void mapEmptyInitializerList();
+ void mapEmptyDetach();
+ void mapSimpleInitializerList();
+ void mapMutation();
+ void mapStringValues();
+ void mapStringKeys();
+ void mapInsertRemove_data() { basics_data(); }
+ void mapInsertRemove();
+ void mapInsertTagged_data() { basics_data(); }
+ void mapInsertTagged();
+ void mapSelfAssign_data() { basics_data(); }
+ void mapSelfAssign();
+ void mapComplexKeys_data() { basics_data(); }
+ void mapComplexKeys();
+
+ void sorting();
+
+ void toCbor_data();
+ void toCbor();
+ void fromCbor_data();
+ void fromCbor();
+ void validation_data();
+ void validation();
+ void toDiagnosticNotation_data();
+ void toDiagnosticNotation();
+};
+
+// Get the validation data from TinyCBOR (see src/3rdparty/tinycbor/tests/parser/data.cpp)
+#include "data.cpp"
+
+struct SimpleTypeWrapper
+{
+ // QCborSimpleType is an enum, so QVariant knows how to convert it to
+ // integer and we don't want it to do that.
+ SimpleTypeWrapper(QCborSimpleType type = {}) : st(type) {}
+ QCborSimpleType st;
+};
+Q_DECLARE_METATYPE(SimpleTypeWrapper)
+
+void tst_QCborValue::basics_data()
+{
+ QTest::addColumn<QCborValue::Type>("type");
+ QTest::addColumn<QCborValue>("v");
+ QTest::addColumn<QVariant>("expectedValue");
+ QDateTime dt = QDateTime::currentDateTimeUtc();
+ QUuid uuid = QUuid::createUuid();
+
+ QMetaEnum me = QMetaEnum::fromType<QCborValue::Type>();
+ auto add = [me](QCborValue::Type t, const QCborValue &v, const QVariant &exp) {
+ auto addRow = [=]() -> QTestData & {
+ const char *typeString = me.valueToKey(t);
+ if (t == QCborValue::Integer)
+ return QTest::addRow("Integer:%lld", exp.toLongLong());
+ if (t == QCborValue::Double)
+ return QTest::addRow("Double:%g", exp.toDouble());
+ if (t == QCborValue::ByteArray || t == QCborValue::String)
+ return QTest::addRow("%s:%d", typeString, exp.toString().size());
+ return QTest::newRow(typeString);
+ };
+ addRow() << t << v << exp;
+ };
+ auto st = [](QCborSimpleType t) { return QVariant::fromValue<SimpleTypeWrapper>(t); };
+
+ add(QCborValue::Undefined, QCborValue(), st(QCborSimpleType::Undefined));
+ add(QCborValue::Null, QCborValue::Null, st(QCborSimpleType::Null));
+ QTest::newRow("nullptr") << QCborValue::Null << QCborValue(nullptr)
+ << st(QCborSimpleType::Null);
+ add(QCborValue::False, false, st(QCborSimpleType::False));
+ QTest::newRow("false") << QCborValue::False << QCborValue(QCborValue::False)
+ << st(QCborSimpleType::False);
+ add(QCborValue::True, true, st(QCborSimpleType::True));
+ QTest::newRow("true") << QCborValue::True << QCborValue(QCborValue::True)
+ << st(QCborSimpleType::True);
+ QTest::newRow("simpletype") << QCborValue::Type(QCborValue::SimpleType + 255)
+ << QCborValue(QCborSimpleType(255))
+ << st(QCborSimpleType(255));
+ add(QCborValue::Integer, 0, 0);
+ add(QCborValue::Integer, 1, 1);
+ add(QCborValue::Integer, -1, -1);
+ add(QCborValue::Integer, std::numeric_limits<qint64>::min(), std::numeric_limits<qint64>::min());
+ add(QCborValue::Integer, std::numeric_limits<qint64>::max(), std::numeric_limits<qint64>::max());
+ add(QCborValue::Double, 0., 0.);
+ add(QCborValue::Double, 1.25, 1.25);
+ add(QCborValue::Double, -1.25, -1.25);
+ add(QCborValue::Double, qInf(), qInf());
+ add(QCborValue::Double, -qInf(), -qInf());
+ add(QCborValue::Double, qQNaN(), qQNaN());
+ add(QCborValue::ByteArray, QByteArray("Hello"), QByteArray("Hello"));
+ add(QCborValue::ByteArray, QByteArray(), QByteArray());
+ add(QCborValue::String, "Hello", "Hello");
+ add(QCborValue::String, QLatin1String(), QString());
+ add(QCborValue::DateTime, QCborValue(dt), dt);
+ add(QCborValue::Url, QCborValue(QUrl("http://example.com")), QUrl("http://example.com"));
+ add(QCborValue::RegularExpression, QCborValue(QRegularExpression("^.*$")), QRegularExpression("^.*$"));
+ add(QCborValue::Uuid, QCborValue(uuid), uuid);
+
+ // empty arrays and maps
+ add(QCborValue::Array, QCborArray(), QVariantList());
+ add(QCborValue::Map, QCborMap(), QVariantMap());
+}
+
+static void basicTypeCheck(QCborValue::Type type, const QCborValue &v, const QVariant &expectedValue)
+{
+ bool isSimpleType = (expectedValue.userType() == qMetaTypeId<SimpleTypeWrapper>());
+ QCborSimpleType st = expectedValue.value<SimpleTypeWrapper>().st;
+
+ QCOMPARE(v.type(), type);
+ QCOMPARE(v.isInteger(), type == QCborValue::Integer);
+ QCOMPARE(v.isByteArray(), type == QCborValue::ByteArray);
+ QCOMPARE(v.isString(), type == QCborValue::String);
+ QCOMPARE(v.isArray(), type == QCborValue::Array);
+ QCOMPARE(v.isMap(), type == QCborValue::Map);
+ QCOMPARE(v.isFalse(), type == QCborValue::False);
+ QCOMPARE(v.isTrue(), type == QCborValue::True);
+ QCOMPARE(v.isBool(), type == QCborValue::False || type == QCborValue::True);
+ QCOMPARE(v.isNull(), type == QCborValue::Null);
+ QCOMPARE(v.isUndefined(), type == QCborValue::Undefined);
+ QCOMPARE(v.isDouble(), type == QCborValue::Double);
+ QCOMPARE(v.isDateTime(), type == QCborValue::DateTime);
+ QCOMPARE(v.isUrl(), type == QCborValue::Url);
+ QCOMPARE(v.isUuid(), type == QCborValue::Uuid);
+ QCOMPARE(v.isInvalid(), type == QCborValue::Invalid);
+ QCOMPARE(v.isContainer(), type == QCborValue::Array || type == QCborValue::Map);
+ QCOMPARE(v.isSimpleType(), isSimpleType);
+ QCOMPARE(v.isSimpleType(QCborSimpleType::False), st == QCborSimpleType::False);
+ QCOMPARE(v.isSimpleType(QCborSimpleType::True), st == QCborSimpleType::True);
+ QCOMPARE(v.isSimpleType(QCborSimpleType::Null), st == QCborSimpleType::Null);
+ QCOMPARE(v.isSimpleType(QCborSimpleType::Undefined), st == QCborSimpleType::Undefined);
+ QCOMPARE(v.isSimpleType(QCborSimpleType(255)), st == QCborSimpleType(255));
+
+ if (v.isInteger()) {
+ QCOMPARE(v.toInteger(), expectedValue.toLongLong());
+ QCOMPARE(v.toDouble(), 0. + expectedValue.toLongLong());
+ } else {
+ QCOMPARE(v.toInteger(), qint64(expectedValue.toDouble()));
+ QCOMPARE(v.toDouble(), expectedValue.toDouble());
+ }
+ QCOMPARE(v.toBool(true), st != QCborSimpleType::False);
+ QCOMPARE(v.toBool(), st == QCborSimpleType::True);
+ if (st == QCborSimpleType::Undefined)
+ QCOMPARE(v.toSimpleType(QCborSimpleType::Null), QCborSimpleType::Undefined);
+ else if (isSimpleType)
+ QCOMPARE(v.toSimpleType(), st);
+ else
+ QCOMPARE(v.toSimpleType(), QCborSimpleType::Undefined);
+
+#define CMP(expr, T, validexpr) \
+ if (expectedValue.userType() == qMetaTypeId<T>()) \
+ QCOMPARE(expr, expectedValue.value<T>()); \
+ else \
+ QVERIFY(validexpr)
+ CMP(v.toByteArray(), QByteArray, v.toByteArray().isNull());
+ CMP(v.toString(), QString, v.toString().isNull());
+ CMP(v.toDateTime(), QDateTime, !v.toDateTime().isValid());
+ CMP(v.toUrl(), QUrl, !v.toUrl().isValid());
+ CMP(v.toRegularExpression(), QRegularExpression, v.toRegularExpression().pattern().isNull());
+ CMP(v.toUuid(), QUuid, v.toUuid().isNull());
+#undef CMP
+
+ QVERIFY(v.toArray().isEmpty());
+ QVERIFY(v.toMap().isEmpty());
+
+ QVERIFY(v["Hello"].isUndefined());
+ QVERIFY(v[0].isUndefined());
+}
+
+void tst_QCborValue::basics()
+{
+ QFETCH(QCborValue::Type, type);
+ QFETCH(QCborValue, v);
+ QFETCH(QVariant, expectedValue);
+
+ basicTypeCheck(type, v, expectedValue);
+}
+
+void tst_QCborValue::tagged()
+{
+ QFETCH(QCborValue::Type, type);
+ QFETCH(QCborValue, v);
+ QFETCH(QVariant, expectedValue);
+
+ // make it tagged
+ QCborValue tagged(QCborKnownTags::Signature, v);
+ QVERIFY(tagged.isTag());
+ QCOMPARE(tagged.tag(), QCborTag(QCborKnownTags::Signature));
+
+ // shouldn't compare equal
+ QVERIFY(tagged != v);
+ QVERIFY(v != tagged);
+
+ // ensure we can reach the original value
+ basicTypeCheck(type, tagged.taggedValue(), expectedValue);
+ QVERIFY(tagged.taggedValue() == v);
+ QVERIFY(v == tagged.taggedValue());
+
+ // nested tagging should work too
+ QCborValue tagged2(QCborKnownTags::EncodedCbor, tagged);
+ QVERIFY(tagged2.isTag());
+ QCOMPARE(tagged2.tag(), QCborTag(QCborKnownTags::EncodedCbor));
+
+ QVERIFY(tagged2 != tagged);
+ QVERIFY(tagged != tagged2);
+
+ QVERIFY(tagged2.taggedValue() == tagged);
+ QVERIFY(tagged == tagged2.taggedValue());
+ QVERIFY(tagged2.taggedValue().taggedValue() == v);
+ QVERIFY(v == tagged2.taggedValue().taggedValue());
+}
+
+void tst_QCborValue::extendedTypes_data()
+{
+ QTest::addColumn<QCborValue>("extended");
+ QTest::addColumn<QCborValue>("tagged");
+ QDateTime dt = QDateTime::currentDateTimeUtc();
+ QUuid uuid = QUuid::createUuid();
+
+ QTest::newRow("DateTime") << QCborValue(dt)
+ << QCborValue(QCborKnownTags::DateTimeString, dt.toString(Qt::ISODateWithMs));
+ QTest::newRow("Url:Empty") << QCborValue(QUrl())
+ << QCborValue(QCborKnownTags::Url, QString());
+ QTest::newRow("Url:Authority") << QCborValue(QUrl("https://example.com"))
+ << QCborValue(QCborKnownTags::Url, "https://example.com");
+ QTest::newRow("Url:Path") << QCborValue(QUrl("file:///tmp/none"))
+ << QCborValue(QCborKnownTags::Url, "file:///tmp/none");
+ QTest::newRow("Url:QueryFragment") << QCborValue(QUrl("whatever:?a=b&c=d#e"))
+ << QCborValue(QCborKnownTags::Url, "whatever:?a=b&c=d#e");
+ QTest::newRow("Regex:Empty") << QCborValue(QRegularExpression())
+ << QCborValue(QCborKnownTags::RegularExpression, QString());
+ QTest::newRow("Regex") << QCborValue(QRegularExpression("^.*$"))
+ << QCborValue(QCborKnownTags::RegularExpression, QString("^.*$"));
+ QTest::newRow("Uuid") << QCborValue(uuid)
+ << QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122());
+}
+
+void tst_QCborValue::extendedTypes()
+{
+ QFETCH(QCborValue, extended);
+ QFETCH(QCborValue, tagged);
+ QVERIFY(extended.isTag());
+ QVERIFY(tagged.isTag());
+ QVERIFY(extended == tagged);
+ QVERIFY(tagged == extended);
+
+ QCOMPARE(extended.tag(), tagged.tag());
+ QCOMPARE(extended.taggedValue(), tagged.taggedValue());
+}
+
+void tst_QCborValue::copyCompare()
+{
+ QFETCH(QCborValue, v);
+ QCborValue other = v;
+ other = v;
+ v = other;
+
+ QCOMPARE(v.compare(other), 0);
+ QCOMPARE(v, other);
+ QVERIFY(!(v != other));
+ QVERIFY(!(v < other));
+#if QT_HAS_INCLUDE(<compare>)
+ QVERIFY(v <= other);
+ QVERIFY(v >= other);
+ QVERIFY(!(v > other));
+#endif
+
+ if (v.isUndefined())
+ other = nullptr;
+ else
+ other = {};
+ QVERIFY(v.type() != other.type());
+ QVERIFY(!(v == other));
+ QVERIFY(v != other);
+
+ // they're different types, so they can't compare equal
+ QVERIFY(v.compare(other) != 0);
+ QVERIFY((v < other) || (other < v));
+}
+
+void tst_QCborValue::arrayDefaultInitialization()
+{
+ QCborArray a;
+ QVERIFY(a.isEmpty());
+ QCOMPARE(a.size(), 0);
+ QVERIFY(!a.contains(0));
+ QVERIFY(!a.contains(-1));
+ QVERIFY(!a.contains(false));
+ QVERIFY(!a.contains(true));
+ QVERIFY(!a.contains(nullptr));
+ QVERIFY(!a.contains({}));
+ QVERIFY(!a.contains(1.0));
+ QVERIFY(!a.contains(QByteArray("Hello")));
+ QVERIFY(!a.contains("Hello"));
+ QVERIFY(!a.contains(QCborArray()));
+ QVERIFY(!a.contains(QCborMap()));
+ QVERIFY(!a.contains(QCborValue(QDateTime::currentDateTimeUtc())));
+ QVERIFY(!a.contains(QCborValue(QUrl("http://example.com"))));
+ QVERIFY(!a.contains(QCborValue(QUuid::createUuid())));
+
+ QVERIFY(a.at(0).isUndefined());
+ QCOMPARE(a.constBegin(), a.constEnd());
+
+ QVERIFY(a == a);
+ QVERIFY(a == QCborArray());
+ QVERIFY(QCborArray() == a);
+
+ QCborValue v(a);
+ QVERIFY(v.isArray());
+ QVERIFY(!v.isMap());
+ QVERIFY(!v.isTag());
+ QVERIFY(v[0].isUndefined());
+
+ QCborArray a2 = v.toArray();
+ QVERIFY(a2.isEmpty());
+ QCOMPARE(a2, a);
+}
+
+void tst_QCborValue::mapDefaultInitialization()
+{
+ QCborMap m;
+ QVERIFY(m.isEmpty());
+ QCOMPARE(m.size(), 0);
+ QVERIFY(m.keys().isEmpty());
+ QVERIFY(!m.contains(0));
+ QVERIFY(!m.contains(-1));
+ QVERIFY(!m.contains(false));
+ QVERIFY(!m.contains(true));
+ QVERIFY(!m.contains(QCborValue::Null));
+ QVERIFY(!m.contains({}));
+ QVERIFY(!m.contains(1.0));
+ QVERIFY(!m.contains(QLatin1String("Hello")));
+ QVERIFY(!m.contains(QStringLiteral("Hello")));
+ QVERIFY(!m.contains(QCborValue(QByteArray("Hello"))));
+ QVERIFY(!m.contains(QCborArray()));
+ QVERIFY(!m.contains(QCborMap()));
+ QVERIFY(!m.contains(QCborValue(QDateTime::currentDateTimeUtc())));
+ QVERIFY(!m.contains(QCborValue(QUrl("http://example.com"))));
+ QVERIFY(!m.contains(QCborValue(QUuid::createUuid())));
+
+ QVERIFY(m.value(0).isUndefined());
+ QVERIFY(m.value(QLatin1String("Hello")).isUndefined());
+ QVERIFY(m.value(QStringLiteral("Hello")).isUndefined());
+ QVERIFY(m.value(QCborValue()).isUndefined());
+
+ QVERIFY(m == m);
+ QVERIFY(m == QCborMap{});
+ QVERIFY(QCborMap{} == m);
+
+ QCborValue v(m);
+ QVERIFY(v.isMap());
+ QVERIFY(!v.isArray());
+ QVERIFY(!v.isTag());
+ QVERIFY(v[0].isUndefined());
+ QVERIFY(v[QLatin1String("Hello")].isUndefined());
+ QVERIFY(v["Hello"].isUndefined());
+
+ QCborMap m2 = v.toMap();
+ QVERIFY(m2.isEmpty());
+ QCOMPARE(m2.size(), 0);
+ QCOMPARE(m2, m);
+}
+
+void tst_QCborValue::arrayEmptyInitializerList()
+{
+ QCborArray a{};
+ QVERIFY(a.isEmpty());
+ QCOMPARE(a.size(), 0);
+ QVERIFY(a == a);
+ QVERIFY(a == QCborArray());
+ QVERIFY(QCborArray() == a);
+}
+
+void tst_QCborValue::mapEmptyInitializerList()
+{
+ QCborMap m{};
+ QVERIFY(m.isEmpty());
+ QCOMPARE(m.size(), 0);
+ QVERIFY(m == m);
+ QVERIFY(m == QCborMap{});
+ QVERIFY(QCborMap{} == m);
+}
+
+void tst_QCborValue::arrayEmptyDetach()
+{
+ QCborArray a;
+ QCOMPARE(a.begin(), a.end());
+ QVERIFY(a.isEmpty());
+ QCOMPARE(a.size(), 0);
+
+ QVERIFY(a == a);
+ QVERIFY(a == QCborArray());
+ QVERIFY(QCborArray() == a);
+
+ QCborValue v(a);
+ QVERIFY(v.isArray());
+ QVERIFY(!v.isMap());
+ QVERIFY(!v.isTag());
+
+ QCborArray a2 = v.toArray();
+ QVERIFY(a2.isEmpty());
+ QCOMPARE(a2, a);
+}
+
+void tst_QCborValue::mapEmptyDetach()
+{
+ QCborMap m;
+ QCOMPARE(m.begin(), m.end());
+ QVERIFY(m.isEmpty());
+ QCOMPARE(m.size(), 0);
+
+ QVERIFY(m == m);
+ QVERIFY(m == QCborMap{});
+ QVERIFY(QCborMap{} == m);
+
+ QCborValue v(m);
+ QVERIFY(v.isMap());
+ QVERIFY(!v.isArray());
+ QVERIFY(!v.isTag());
+
+ QCborMap m2 = v.toMap();
+ QVERIFY(m2.isEmpty());
+ QCOMPARE(m2, m);
+}
+
+void tst_QCborValue::arrayInitializerList()
+{
+ QCborArray a{0, -1, false, true, nullptr, {}, 1.0};
+ QVERIFY(!a.isEmpty());
+ QCOMPARE(a.size(), 7);
+ QCOMPARE(a.at(0), QCborValue(0));
+ QCOMPARE(a.at(1), QCborValue(-1));
+ QCOMPARE(a.at(2), QCborValue(QCborValue::False));
+ QCOMPARE(a.at(3), QCborValue(QCborValue::True));
+ QCOMPARE(a.at(4), QCborValue(QCborValue::Null));
+ QCOMPARE(a.at(5), QCborValue(QCborValue::Undefined));
+ QCOMPARE(a.at(6), QCborValue(1.0));
+
+ QVERIFY(a == a);
+ QVERIFY(a != QCborArray{});
+ QVERIFY(QCborArray{} != a);
+ QVERIFY(a == QCborArray({0, -1, false, true, nullptr, {}, 1.0}));
+
+ QCborValue v = a;
+ QCOMPARE(v[0], QCborValue(0));
+ QCOMPARE(v[1], QCborValue(-1));
+ QCOMPARE(v[2], QCborValue(QCborValue::False));
+ QCOMPARE(v[3], QCborValue(QCborValue::True));
+ QCOMPARE(v[4], QCborValue(QCborValue::Null));
+ QCOMPARE(v[5], QCborValue(QCborValue::Undefined));
+ QCOMPARE(v[6], QCborValue(1.0));
+
+ QVERIFY(a.contains(0));
+ QVERIFY(a.contains(-1));
+ QVERIFY(a.contains(false));
+ QVERIFY(a.contains(true));
+ QVERIFY(a.contains(nullptr));
+ QVERIFY(a.contains({}));
+ QVERIFY(a.contains(1.0));
+ QVERIFY(!a.contains(QByteArray("Hello")));
+ QVERIFY(!a.contains("Hello"));
+ QVERIFY(!a.contains(QCborArray()));
+ QVERIFY(!a.contains(QCborMap()));
+ QVERIFY(!a.contains(QCborValue(QDateTime::currentDateTimeUtc())));
+ QVERIFY(!a.contains(QCborValue(QUrl("http://example.com"))));
+ QVERIFY(!a.contains(QCborValue(QUuid::createUuid())));
+
+ // iterators
+ auto it = a.constBegin();
+ auto end = a.constEnd();
+ QCOMPARE(end - it, 7);
+ QCOMPARE(it + 7, end);
+ QVERIFY(it->isInteger());
+ QCOMPARE(*it, QCborValue(0));
+ QCOMPARE(it[1], QCborValue(-1));
+ QCOMPARE(*(it + 2), QCborValue(false));
+ it += 3;
+ QCOMPARE(*it, QCborValue(true));
+ ++it;
+ QCOMPARE(*it, QCborValue(nullptr));
+ it++;
+ QCOMPARE(*it, QCborValue());
+ --end;
+ QCOMPARE(*end, QCborValue(1.0));
+ end--;
+ QCOMPARE(it, end);
+
+ // range for
+ int i = 0;
+ for (const QCborValue &v : qAsConst(a)) {
+ QVERIFY(!v.isInvalid());
+ QCOMPARE(v.isUndefined(), i == 5); // 6th element is Undefined
+ ++i;
+ }
+ QCOMPARE(i, a.size());
+}
+
+void tst_QCborValue::mapSimpleInitializerList()
+{
+ QCborMap m{{0, 0}, {1, 0}, {2, "Hello"}, {"Hello", 2}, {3, QLatin1String("World")}, {QLatin1String("World"), 3}};
+ QCOMPARE(m.size(), 6);
+ QVERIFY(m == m);
+ QVERIFY(m != QCborMap{});
+ QVERIFY(QCborMap{} != m);
+ QVERIFY(m == QCborMap({{0, 0}, {1, 0}, {2, "Hello"}, {"Hello", 2}, {3, QLatin1String("World")}, {QLatin1String("World"), 3}}));
+
+ QCborValue vmap = m;
+ {
+ QVERIFY(m.contains(0));
+ QCborValue v = m.value(0);
+ QVERIFY(v.isInteger());
+ QCOMPARE(v.toInteger(), 0);
+ QCOMPARE(vmap[0], v);
+ }
+ {
+ QVERIFY(m.contains(1));
+ QCborValue v = m.value(1);
+ QVERIFY(v.isInteger());
+ QCOMPARE(v.toInteger(), 0);
+ QCOMPARE(vmap[1], v);
+ }
+ {
+ QVERIFY(m.contains(2));
+ QCborValue v = m.value(2);
+ QVERIFY(v.isString());
+ QCOMPARE(v.toString(), "Hello");
+ QCOMPARE(vmap[2], v);
+ }
+ {
+ QVERIFY(m.contains(3));
+ QCborValue v = m.value(3);
+ QVERIFY(v.isString());
+ QCOMPARE(v.toString(), "World");
+ QCOMPARE(vmap[3], v);
+ }
+ {
+ QVERIFY(m.contains(QStringLiteral("Hello")));
+ QCborValue v = m.value(QLatin1String("Hello"));
+ QVERIFY(v.isInteger());
+ QCOMPARE(v.toInteger(), 2);
+ QCOMPARE(vmap[QStringLiteral("Hello")], v);
+ }
+ {
+ QVERIFY(m.contains(QLatin1String("World")));
+ QCborValue v = m.value(QStringLiteral("World"));
+ QVERIFY(v.isInteger());
+ QCOMPARE(v.toInteger(), 3);
+ QCOMPARE(vmap[QLatin1String("World")], v);
+ }
+
+ QVERIFY(!m.contains(QCborValue::Null));
+ QVERIFY(!m.contains(QCborValue()));
+ QVERIFY(!m.contains(QCborValue(1.0))); // Important: 1.0 does not match 1
+ QVERIFY(!m.contains(QCborValue(QByteArray("Hello"))));
+ QVERIFY(!m.contains(QCborArray()));
+ QVERIFY(!m.contains(QCborMap()));
+ QVERIFY(!m.contains(QCborValue(QDateTime::currentDateTimeUtc())));
+ QVERIFY(!m.contains(QCborValue(QUrl("http://example.com"))));
+ QVERIFY(!m.contains(QCborValue(QUuid::createUuid())));
+
+ // iterators (QCborMap is not sorted)
+ auto it = m.constBegin();
+ auto end = m.constEnd();
+ QCOMPARE(end - it, 6);
+ QCOMPARE(it + 6, end);
+ QCOMPARE(it.key(), QCborValue(0));
+ QCOMPARE(it.value(), QCborValue(0));
+ QVERIFY(it->isInteger());
+ ++it;
+ QCOMPARE(it.key(), QCborValue(1));
+ QCOMPARE(it.value(), QCborValue(0));
+ QCOMPARE((it + 1).key(), QCborValue(2));
+ QVERIFY((it + 1)->isString());
+ QCOMPARE((it + 1)->toString(), "Hello");
+ it += 2;
+ QCOMPARE(it.key(), QCborValue("Hello"));
+ QVERIFY(it->isInteger());
+ it++;
+ QCOMPARE(it.key(), QCborValue(3));
+ QVERIFY(it->isString());
+ QCOMPARE(it.value().toString(), "World");
+ --end;
+ QCOMPARE(end.key(), QCborValue("World"));
+ QCOMPARE(end.value(), QCborValue(3));
+ end--;
+ QCOMPARE(it, end);
+
+ // range for
+ int i = 0;
+ for (auto pair : qAsConst(m)) {
+ QVERIFY(!pair.first.isUndefined());
+ QVERIFY(!pair.second.isUndefined());
+ ++i;
+ }
+ QCOMPARE(i, m.size());
+}
+
+void tst_QCborValue::arrayMutation()
+{
+ QCborArray a{42};
+ {
+ QCborValueRef v = a[0];
+ QVERIFY(!a.isEmpty());
+ QVERIFY(v.isInteger());
+ QCOMPARE(v.toInteger(), 42);
+
+ // now mutate the list
+ v = true;
+ QVERIFY(v.isBool());
+ QVERIFY(v.isTrue());
+ QVERIFY(a.at(0).isTrue());
+ QVERIFY(a.at(0) == v);
+ QVERIFY(v == a.at(0));
+ }
+
+ QVERIFY(a == a);
+ QVERIFY(a == QCborArray{true});
+
+ QCborArray a2 = a;
+ a.append(nullptr);
+ QCOMPARE(a.size(), 2);
+ QCOMPARE(a2.size(), 1);
+
+ // self-insertion
+ a2.append(a2);
+ QCOMPARE(a2.size(), 2);
+ QCOMPARE(a2.last().toArray().size(), 1);
+
+ QCborValueRef v = a[0];
+ QVERIFY(v.isTrue());
+ v = 2.5;
+ QVERIFY(v.isDouble());
+ QVERIFY(a.first().isDouble());
+ QVERIFY(a.last().isNull());
+ QVERIFY(a2.first().isTrue());
+
+ a2 = a;
+ auto it = a.begin(); // detaches again
+ auto end = a.end();
+ QCOMPARE(end - it, 2);
+ QCOMPARE(it + 2, end);
+ QCOMPARE(*it, QCborValue(2.5));
+ QCOMPARE(*++it, QCborValue(nullptr));
+ QVERIFY(a2 == a);
+ QVERIFY(a == a2);
+
+ *it = -1;
+ QCOMPARE(*it, QCborValue(-1));
+ QCOMPARE(a.at(1), QCborValue(-1));
+ QCOMPARE(a2.at(1), QCborValue(nullptr));
+ QCOMPARE(++it, end);
+}
+
+void tst_QCborValue::mapMutation()
+{
+ QCborMap m;
+ QVERIFY(m.isEmpty());
+
+ {
+ QCborValueRef v = m[42];
+ QCOMPARE(m.size(), 1);
+ QVERIFY(v.isUndefined());
+
+ // now mutate the list
+ v = true;
+ QVERIFY(v.isBool());
+ QVERIFY(v.isTrue());
+ QVERIFY(m.begin()->isTrue());
+ QVERIFY(m.begin().value() == v);
+ QVERIFY(v == m.begin().value());
+ }
+
+ QVERIFY(m == QCborMap({{42, true}}));
+ QVERIFY(QCborMap({{42, true}}) == m);
+
+ QCborMap m2 = m;
+ m.insert({nullptr, nullptr});
+ QCOMPARE(m.size(), 2);
+ QCOMPARE(m2.size(), 1);
+
+ QCborValueRef v = m[42];
+ QVERIFY(v.isTrue());
+ v = 2.5;
+ QVERIFY(v.isDouble());
+ QVERIFY(m.begin()->isDouble());
+ QVERIFY((m.end() - 1)->isNull());
+ QVERIFY(m2.begin()->isTrue());
+
+ m2 = m;
+ auto it = m.begin(); // detaches again
+ auto end = m.end();
+ QCOMPARE(end - it, 2);
+ QCOMPARE(it + 2, end);
+ QCOMPARE(it.key(), QCborValue(42));
+ QCOMPARE(it.value(), QCborValue(2.5));
+ QCOMPARE((++it).value(), QCborValue(nullptr));
+ QCOMPARE(it.key(), QCborValue(nullptr));
+ QVERIFY(m2 == m);
+ QVERIFY(m == m2);
+
+ it.value() = -1;
+ QCOMPARE(it.key(), QCborValue(nullptr));
+ QCOMPARE(it.value(), QCborValue(-1));
+ QCOMPARE((m.end() - 1)->toInteger(), -1);
+ QVERIFY((m2.end() - 1)->isNull());
+ QCOMPARE(++it, end);
+}
+
+void tst_QCborValue::arrayPrepend()
+{
+ QCborArray a;
+ a.prepend(0);
+ a.prepend(nullptr);
+ QCOMPARE(a.at(1), QCborValue(0));
+ QCOMPARE(a.at(0), QCborValue(nullptr));
+ QCOMPARE(a.size(), 2);
+}
+
+void tst_QCborValue::arrayInsertRemove()
+{
+ QFETCH(QCborValue, v);
+ QCborArray a;
+ a.append(42);
+ a.append(v);
+ a.insert(1, QCborValue(nullptr));
+ QCOMPARE(a.at(0), QCborValue(42));
+ QCOMPARE(a.at(1), QCborValue(nullptr));
+ QCOMPARE(a.at(2), v);
+
+ // remove 42
+ a.removeAt(0);
+ QCOMPARE(a.size(), 2);
+ QCOMPARE(a.at(0), QCborValue(nullptr));
+ QCOMPARE(a.at(1), v);
+
+ auto it = a.begin();
+ it = a.erase(it); // removes nullptr
+ QCOMPARE(a.size(), 1);
+ QCOMPARE(a.at(0), v);
+
+ it = a.erase(it);
+ QVERIFY(a.isEmpty());
+ QCOMPARE(it, a.end());
+
+ // reinsert the element so we can take it
+ a.append(v);
+ QCOMPARE(a.takeAt(0), v);
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QCborValue::arrayStringElements()
+{
+ QCborArray a{"Hello"};
+ a.append(QByteArray("Hello"));
+ a.append(QLatin1String("World"));
+ QVERIFY(a == a);
+ QVERIFY(a == QCborArray({QLatin1String("Hello"),
+ QByteArray("Hello"), QStringLiteral("World")}));
+
+ QCborValueRef r1 = a[0];
+ QCOMPARE(r1.toString(), "Hello");
+ QCOMPARE(r1.operator QCborValue(), QCborValue("Hello"));
+ QVERIFY(r1 == QCborValue("Hello"));
+
+ QCborValue v2 = a.at(1);
+ QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
+ QCOMPARE(v2, QCborValue(QByteArray("Hello")));
+
+ // v2 must continue to be valid after the entry getting removed
+ a.removeAt(1);
+ QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
+ QCOMPARE(v2, QCborValue(QByteArray("Hello")));
+
+ v2 = a.at(1);
+ QCOMPARE(v2.toString(), "World");
+ QCOMPARE(v2, QCborValue("World"));
+
+ QCOMPARE(a.takeAt(1).toString(), "World");
+ QCOMPARE(a.takeAt(0).toString(), "Hello");
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QCborValue::mapStringValues()
+{
+ QCborMap m{{0, "Hello"}};
+ m.insert({1, QByteArray("Hello")});
+ m.insert({2, QLatin1String("World")});
+ QVERIFY(m == m);
+
+ QCborValueRef r1 = m[0];
+ QCOMPARE(r1.toString(), "Hello");
+ QCOMPARE(r1.operator QCborValue(), QCborValue("Hello"));
+ QVERIFY(r1 == QCborValue("Hello"));
+
+ QCborValue v2 = m.value(1);
+ QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
+ QCOMPARE(v2, QCborValue(QByteArray("Hello")));
+
+ // v2 must continue to be valid after the entry getting removed
+ m.erase(m.constFind(1));
+ QCOMPARE(v2.toByteArray(), QByteArray("Hello"));
+ QCOMPARE(v2, QCborValue(QByteArray("Hello")));
+
+ v2 = (m.begin() + 1).value();
+ QCOMPARE(v2.toString(), "World");
+ QCOMPARE(v2, QCborValue("World"));
+
+ QCOMPARE(m.extract(m.begin() + 1).toString(), "World");
+ QCOMPARE(m.take(0).toString(), "Hello");
+ QVERIFY(m.isEmpty());
+}
+
+void tst_QCborValue::mapStringKeys()
+{
+ QCborMap m{{QLatin1String("Hello"), 1}, {QStringLiteral("World"), 2}};
+ QCOMPARE(m.value(QStringLiteral("Hello")), QCborValue(1));
+ QCOMPARE(m.value(QLatin1String("World")), QCborValue(2));
+
+ QCborMap m2 = m;
+ QVERIFY(m2 == m);
+ QVERIFY(m == m2);
+
+ m.insert({QByteArray("foo"), "bar"});
+ QCOMPARE(m.size(), 3);
+ QCOMPARE(m2.size(), 2);
+ QVERIFY(m2 != m);
+ QVERIFY(m != m2);
+
+ QVERIFY(m2.value(QCborValue(QByteArray("foo"))).isUndefined());
+ QVERIFY(m.value(QCborValue(QLatin1String("foo"))).isUndefined());
+ QCOMPARE(m.value(QCborValue(QByteArray("foo"))).toString(), "bar");
+}
+
+void tst_QCborValue::mapInsertRemove()
+{
+ QFETCH(QCborValue, v);
+ QCborMap m{{1, v}};
+
+ m.remove(1);
+ QVERIFY(m.isEmpty());
+ QVERIFY(!m.contains(1));
+
+ m.insert(2, v);
+ QVERIFY(m.contains(2));
+ QVERIFY(m[2] == v);
+ QVERIFY(v == m[2]);
+
+ auto it = m.find(2);
+ it = m.erase(it);
+ QVERIFY(m.isEmpty());
+
+ // creates m[2] and m[42] just by referencing them
+ m[2];
+ QCborValueRef r = m[42];
+ QCOMPARE(m.size(), 2);
+
+ r = v;
+ it = m.find(42);
+ QVERIFY(it.value() == v);
+ QVERIFY(v == it.value());
+ QVERIFY(it.value() == r);
+ QVERIFY(r == it.value());
+
+ QCOMPARE(m.extract(it), v);
+ QVERIFY(!m.contains(42));
+
+ m[2] = v;
+ QCOMPARE(m.take(2), v);
+ QVERIFY(m.take(2).isUndefined());
+ QVERIFY(m.isEmpty());
+}
+
+void tst_QCborValue::arrayInsertTagged()
+{
+ QFETCH(QCborValue, v);
+
+ // make it tagged
+ QCborValue tagged(QCborKnownTags::Signature, v);
+
+ QCborArray a{tagged};
+ a.insert(1, tagged);
+ QCOMPARE(a.size(), 2);
+ QCOMPARE(a.at(0), tagged);
+ QCOMPARE(a.at(1), tagged);
+ QCOMPARE(a.at(0).taggedValue(), v);
+ QCOMPARE(a.at(1).taggedValue(), v);
+ QCOMPARE(a.takeAt(0).taggedValue(), v);
+ QCOMPARE(a.takeAt(0).taggedValue(), v);
+ QVERIFY(a.isEmpty());
+}
+
+void tst_QCborValue::mapInsertTagged()
+{
+ QFETCH(QCborValue, v);
+
+ // make it tagged
+ QCborValue tagged(QCborKnownTags::Signature, v);
+
+ QCborMap m{{11, tagged}};
+ m.insert({-21, tagged});
+ QCOMPARE(m.size(), 2);
+ QCOMPARE(m.constBegin().value(), tagged);
+ QCOMPARE(m.value(-21), tagged);
+ QCOMPARE(m.value(11).taggedValue(), v);
+ QCOMPARE((m.end() - 1).value().taggedValue(), v);
+ QCOMPARE(m.extract(m.end() - 1).taggedValue(), v);
+ QVERIFY(!m.contains(-21));
+ QCOMPARE(m.take(11).taggedValue(), v);
+ QVERIFY(m.isEmpty());
+}
+
+void tst_QCborValue::arraySelfAssign()
+{
+ QFETCH(QCborValue, v);
+ QCborArray a;
+
+ a = {v};
+
+ // Test 1: QCborValue created first, so
+ // QCborArray::insert() detaches
+ {
+ a.append(a);
+ QCOMPARE(a.size(), 2);
+ QCOMPARE(a.last().toArray().size(), 1);
+ }
+
+ a = {v};
+
+ // Test 2: QCborValueRef created first
+ {
+ a.append(36);
+ auto it = a.end() - 1;
+ *it = a;
+
+ QCOMPARE(a.size(), 2);
+ QCOMPARE(it->toArray().size(), 2);
+ QCOMPARE(it->toArray().last(), QCborValue(36));
+ }
+}
+
+void tst_QCborValue::mapSelfAssign()
+{
+ QFETCH(QCborValue, v);
+ QCborMap m;
+
+ m = {{0, v}};
+ QCOMPARE(m.size(), 1);
+
+ // Test 1: create a QCborValue first
+ // in this case, QCborMap::operator[] detaches first
+ {
+ QCborValue vm = m;
+ m[1] = vm; // self-assign
+ QCOMPARE(m.size(), 2);
+ QCOMPARE(m.value(0), v);
+
+ QCborMap m2 = m.value(1).toMap();
+ // there mustn't be an element with key 1
+ QCOMPARE(m2.size(), 1);
+ QCOMPARE(m2.value(0), v);
+ QVERIFY(!m2.contains(1));
+ }
+
+ m = {{0, v}};
+
+ // Test 2: create the QCborValueRef first
+ // in this case, there's no opportunity to detach
+ {
+ QCborValueRef rv = m[1];
+ rv = m; // self-assign (implicit QCborValue creation)
+ QCOMPARE(m.size(), 2);
+ QCOMPARE(m.value(0), v);
+
+ QCborMap m2 = m.value(1).toMap();
+ // there must be an element with key 1
+ QCOMPARE(m2.size(), 2);
+ QCOMPARE(m2.value(0), v);
+ QVERIFY(m2.contains(1));
+ QCOMPARE(m2.value(1), QCborValue());
+ }
+
+ m = {{0, v}};
+
+ // Test 3: don't force creation of either before
+ // in this case, it's up to the compiler to choose
+ {
+ m[1] = m; // self-assign
+ QCOMPARE(m.size(), 2);
+
+ QCborMap m2 = m.value(1).toMap();
+ QVERIFY(m2.size() == 1 || m2.size() == 2);
+ }
+
+ m = {{0, v}};
+
+ // Test 4: self-assign as key
+ // in this scase, QCborMap::operator[] must detach
+ {
+ m[m] = v;
+ QCOMPARE(m.size(), 2);
+
+ auto it = m.constEnd() - 1;
+ QCOMPARE(it.value(), v);
+ QCOMPARE(it.key(), QCborMap({{0, v}}));
+ }
+}
+
+void tst_QCborValue::mapComplexKeys()
+{
+ QFETCH(QCborValue, v);
+ QCborValue tagged(QCborKnownTags::Signature, v);
+
+ QCborMap m{{42, true}, {v, 42}, {-3, nullptr}};
+ QCOMPARE(m.size(), 3);
+ QVERIFY(m.contains(42));
+ QVERIFY(m.contains(-3));
+ QVERIFY(m.contains(v));
+ QVERIFY(!m.contains(tagged));
+
+ auto it = m.constFind(v);
+ QVERIFY(it != m.constEnd());
+ QVERIFY(it.key() == v);
+ QVERIFY(v == it.key());
+ QCOMPARE(it.value().toInteger(), 42);
+
+ QCborArray a{0, 1, 2, 3, v};
+ m[a] = 1;
+ QCOMPARE(m.size(), 4);
+ QCOMPARE((m.constEnd() - 1).value(), QCborValue(1));
+ if (v != QCborValue(QCborValue::Array))
+ QVERIFY(!m.contains(QCborArray{}));
+ QVERIFY(!m.contains(QCborArray{0}));
+ QVERIFY(!m.contains(QCborArray{0, 1}));
+ QVERIFY(!m.contains(QCborArray{0, 1, 2}));
+ QVERIFY(!m.contains(QCborArray{0, 1, 2, 4}));
+ QVERIFY(!m.contains(QCborArray{0, 1, 2, 3, v, 4}));
+
+ it = m.constFind(QCborArray{0, 1, 2, 3, v});
+ QVERIFY(it != m.constEnd());
+ QCOMPARE(it.key(), a);
+ QCOMPARE(it.value(), QCborValue(1));
+
+ m[m] = 1; // assign itself as a key -- this necessarily detaches before
+ QCOMPARE(m.size(), 5);
+ QCOMPARE((m.end() - 1).value(), 1);
+ QCOMPARE((m.end() - 1).key().toMap().size(), 4);
+
+ QCborValue mv(m);
+ if (v.isInteger()) {
+ // we should be able to find using the overloads too
+ QCOMPARE(m[v.toInteger()].toInteger(), 42);
+ QCOMPARE(mv[v.toInteger()].toInteger(), 42);
+ } else if (v.isString()) {
+ // ditto
+ QCOMPARE(m[v.toString()].toInteger(), 42);
+ QCOMPARE(mv[v.toString()].toInteger(), 42);
+
+ // basics_data() strings are Latin1
+ QByteArray latin1 = v.toString().toLatin1();
+ Q_ASSERT(v.toString() == QString::fromLatin1(latin1));
+ QCOMPARE(m[QLatin1String(latin1)].toInteger(), 42);
+ }
+
+ m.remove(v);
+ QVERIFY(!m.contains(v));
+ QVERIFY(!m.contains(tagged));
+
+ QCborValueRef r = m[tagged];
+ QVERIFY(!m.contains(v));
+ QVERIFY(m.contains(tagged));
+ r = 47;
+ QCOMPARE(m[tagged].toInteger(), 47);
+ QCOMPARE(m.take(tagged).toInteger(), 47);
+ QVERIFY(!m.contains(tagged));
+}
+
+void tst_QCborValue::sorting()
+{
+ QCborValue vundef, vnull(nullptr);
+ QCborValue vtrue(true), vfalse(false);
+ QCborValue vint1(1), vint2(2);
+ QCborValue vneg1(-1), vneg2(-2);
+ QCborValue vba2(QByteArray("Hello")), vba3(QByteArray("World")), vba1(QByteArray("foo"));
+ QCborValue vs2("Hello"), vs3("World"), vs1("foo");
+ QCborValue va1(QCborValue::Array), va2(QCborArray{1}), va3(QCborArray{0, 0});
+ QCborValue vm1(QCborValue::Map), vm2(QCborMap{{1, 0}}), vm3(QCborMap{{0, 0}, {1, 0}});
+ QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC)), vdt2(QDateTime::currentDateTimeUtc());
+ QCborValue vtagged1(QCborKnownTags::UnixTime_t, 0), vtagged2(QCborKnownTags::UnixTime_t, 0.0),
+ vtagged3(QCborKnownTags::Signature, 0), vtagged4(QCborTag(-2), 0), vtagged5(QCborTag(-1), 0);
+ QCborValue vurl1(QUrl("https://example.net")), vurl2(QUrl("https://example.com/"));
+ QCborValue vuuid1{QUuid()}, vuuid2(QUuid::createUuid());
+ QCborValue vsimple1(QCborSimpleType(1)), vsimple32(QCborSimpleType(32)), vsimple255(QCborSimpleType(255));
+ QCborValue vdouble1(1.5), vdouble2(qInf());
+ QCborValue vndouble1(-1.5), vndouble2(-qInf());
+
+#define CHECK_ORDER(v1, v2) \
+ QVERIFY(v1 < v2); \
+ QVERIFY(!(v2 < v2))
+
+ // intra-type comparisons
+ CHECK_ORDER(vfalse, vtrue);
+ CHECK_ORDER(vsimple1, vsimple32);
+ CHECK_ORDER(vsimple32, vsimple255);
+ CHECK_ORDER(vint1, vint2);
+ CHECK_ORDER(vdouble1, vdouble2);
+ CHECK_ORDER(vndouble1, vndouble2);
+ // note: shorter length sorts first
+ CHECK_ORDER(vba1, vba2);
+ CHECK_ORDER(vba2, vba3);
+ CHECK_ORDER(vs1, vs2);
+ CHECK_ORDER(vs2, vs3);
+ CHECK_ORDER(va1, va2);
+ CHECK_ORDER(va2, va3);
+ CHECK_ORDER(vm1, vm2);
+ CHECK_ORDER(vm2, vm3);
+ CHECK_ORDER(vdt1, vdt2);
+ CHECK_ORDER(vtagged1, vtagged2);
+ CHECK_ORDER(vtagged2, vtagged3);
+ CHECK_ORDER(vtagged3, vtagged4);
+ CHECK_ORDER(vtagged4, vtagged5);
+ CHECK_ORDER(vurl1, vurl2);
+ CHECK_ORDER(vuuid1, vuuid2);
+
+ // surprise 1: CBOR sorts integrals by absolute value
+ CHECK_ORDER(vneg1, vneg2);
+
+ // surprise 2: CBOR sorts negatives after positives (sign+magnitude)
+ CHECK_ORDER(vint2, vneg1);
+ QVERIFY(vint2.toInteger() > vneg1.toInteger());
+ CHECK_ORDER(vdouble2, vndouble1);
+ QVERIFY(vdouble2.toDouble() > vndouble1.toDouble());
+
+ // inter-type comparisons
+ CHECK_ORDER(vneg2, vba1);
+ CHECK_ORDER(vba3, vs1);
+ CHECK_ORDER(vs3, va1);
+ CHECK_ORDER(va2, vm1);
+ CHECK_ORDER(vm2, vdt1);
+ CHECK_ORDER(vdt2, vtagged1);
+ CHECK_ORDER(vtagged2, vurl1);
+ CHECK_ORDER(vurl1, vuuid1);
+ CHECK_ORDER(vuuid2, vtagged3);
+ CHECK_ORDER(vtagged4, vsimple1);
+ CHECK_ORDER(vsimple1, vfalse);
+ CHECK_ORDER(vtrue, vnull);
+ CHECK_ORDER(vnull, vundef);
+ CHECK_ORDER(vundef, vsimple32);
+ CHECK_ORDER(vsimple255, vdouble1);
+
+ // which shows all doubles sorted after integrals
+ CHECK_ORDER(vint2, vdouble1);
+ QVERIFY(vint2.toInteger() > vdouble1.toDouble());
+#undef CHECK_ORDER
+}
+
+static void addCommonCborData()
+{
+ // valid for both decoding and encoding
+ QTest::addColumn<QCborValue>("v");
+ QTest::addColumn<QByteArray>("result");
+ QTest::addColumn<QCborValue::EncodingOptions>("options");
+ QDateTime dt = QDateTime::currentDateTimeUtc();
+ QUuid uuid = QUuid::createUuid();
+ QCborValue::EncodingOptions noxfrm = QCborValue::NoTransformation;
+
+ // integrals
+ QTest::newRow("Integer:0") << QCborValue(0) << raw("\x00") << noxfrm;
+ QTest::newRow("Integer:1") << QCborValue(1) << raw("\x01") << noxfrm;
+ QTest::newRow("Integer:-1") << QCborValue(-1) << raw("\x20") << noxfrm;
+ QTest::newRow("Integer:INT64_MAX") << QCborValue(std::numeric_limits<qint64>::max())
+ << raw("\x1b\x7f\xff\xff\xff""\xff\xff\xff\xff")
+ << noxfrm;
+ QTest::newRow("Integer:INT64_MIN") << QCborValue(std::numeric_limits<qint64>::min())
+ << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xff")
+ << noxfrm;
+
+ QTest::newRow("simple0") << QCborValue(QCborValue::SimpleType) << raw("\xe0") << noxfrm;
+ QTest::newRow("simple1") << QCborValue(QCborSimpleType(1)) << raw("\xe1") << noxfrm;
+ QTest::newRow("simple255") << QCborValue(QCborSimpleType(255)) << raw("\xf8\xff") << noxfrm;
+ QTest::newRow("Undefined") << QCborValue() << raw("\xf7") << noxfrm;
+ QTest::newRow("Null") << QCborValue(nullptr) << raw("\xf6") << noxfrm;
+ QTest::newRow("True") << QCborValue(true) << raw("\xf5") << noxfrm;
+ QTest::newRow("False") << QCborValue(false) << raw("\xf4") << noxfrm;
+ QTest::newRow("simple32") << QCborValue(QCborSimpleType(32)) << raw("\xf8\x20") << noxfrm;
+ QTest::newRow("simple255") << QCborValue(QCborSimpleType(255)) << raw("\xf8\xff") << noxfrm;
+
+ QTest::newRow("Double:0") << QCborValue(0.) << raw("\xfb\0\0\0\0""\0\0\0\0") << noxfrm;
+ QTest::newRow("Double:1.5") << QCborValue(1.5) << raw("\xfb\x3f\xf8\0\0""\0\0\0\0") << noxfrm;
+ QTest::newRow("Double:-1.5") << QCborValue(-1.5) << raw("\xfb\xbf\xf8\0\0""\0\0\0\0") << noxfrm;
+ QTest::newRow("Double:INT64_MAX+1") << QCborValue(std::numeric_limits<qint64>::max() + 1.)
+ << raw("\xfb\x43\xe0\0\0""\0\0\0\0") << noxfrm;
+ QTest::newRow("Double:maxintegralfp") << QCborValue(18446744073709551616.0 - 2048)
+ << raw("\xfb\x43\xef\xff\xff""\xff\xff\xff\xff")
+ << noxfrm;
+ QTest::newRow("Double:minintegralfp") << QCborValue(-18446744073709551616.0 + 2048)
+ << raw("\xfb\xc3\xef\xff\xff""\xff\xff\xff\xff")
+ << noxfrm;
+ QTest::newRow("Double:inf") << QCborValue(qInf()) << raw("\xfb\x7f\xf0\0\0""\0\0\0\0") << noxfrm;
+ QTest::newRow("Double:-inf") << QCborValue(-qInf()) << raw("\xfb\xff\xf0\0""\0\0\0\0\0") << noxfrm;
+ QTest::newRow("Double:nan") << QCborValue(qQNaN()) << raw("\xfb\x7f\xf8\0\0""\0\0\0\0") << noxfrm;
+
+ QTest::newRow("Float:0") << QCborValue(0.) << raw("\xfa\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
+ QTest::newRow("Float:1.5") << QCborValue(1.5) << raw("\xfa\x3f\xc0\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
+ QTest::newRow("Float:-1.5") << QCborValue(-1.5) << raw("\xfa\xbf\xc0\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
+ QTest::newRow("Float:inf") << QCborValue(qInf()) << raw("\xfa\x7f\x80\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
+ QTest::newRow("Float:-inf") << QCborValue(-qInf()) << raw("\xfa\xff\x80\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
+ QTest::newRow("Float:nan") << QCborValue(qQNaN()) << raw("\xfa\x7f\xc0\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
+
+ QTest::newRow("Float16:0") << QCborValue(0.) << raw("\xf9\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+ QTest::newRow("Float16:1.5") << QCborValue(1.5) << raw("\xf9\x3e\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+ QTest::newRow("Float16:-1.5") << QCborValue(-1.5) << raw("\xf9\xbe\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+ QTest::newRow("Float16:inf") << QCborValue(qInf()) << raw("\xf9\x7c\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+ QTest::newRow("Float16:-inf") << QCborValue(-qInf()) << raw("\xf9\xfc\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+ QTest::newRow("Float16:nan") << QCborValue(qQNaN()) << raw("\xf9\x7e\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+
+ // out of range of qint64, but in range for CBOR, so these do get converted
+ // to integrals on write and back to double on read
+ QTest::newRow("UseInteger:INT64_MAX+1") << QCborValue(std::numeric_limits<qint64>::max() + 1.)
+ << raw("\x1b\x80\0\0\0""\0\0\0\0")
+ << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:maxintegralfp") << QCborValue(18446744073709551616.0 - 2048)
+ << raw("\x1b\xff\xff\xff\xff""\xff\xff\xf8\0")
+ << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:minintegralfp") << QCborValue(-18446744073709551616.0 + 2048)
+ << raw("\x3b\xff\xff\xff\xff""\xff\xff\xf7\xff")
+ << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+
+ QTest::newRow("ByteArray:Empty") << QCborValue(QByteArray()) << raw("\x40") << noxfrm;
+ QTest::newRow("ByteArray") << QCborValue(QByteArray("Hello")) << raw("\x45Hello") << noxfrm;
+ QTest::newRow("ByteArray:WithNull") << QCborValue(raw("\0\1\2\xff")) << raw("\x44\0\1\2\xff") << noxfrm;
+
+ QTest::newRow("String:Empty") << QCborValue(QString()) << raw("\x60") << noxfrm;
+ QTest::newRow("String:UsAscii") << QCborValue("Hello") << raw("\x65Hello") << noxfrm;
+ QTest::newRow("String:Latin1") << QCborValue(QLatin1String("R\xe9sum\xe9"))
+ << raw("\x68R\xc3\xa9sum\xc3\xa9") << noxfrm;
+ QTest::newRow("String:Unicode") << QCborValue(QStringLiteral(u"éś α €"))
+ << raw("\x6b\xc3\xa9\xc5\x9b \xce\xb1 \xe2\x82\xac") << noxfrm;
+
+ QTest::newRow("DateTime") << QCborValue(dt) // this is UTC
+ << "\xc0\x78\x18" + dt.toString(Qt::ISODateWithMs).toLatin1()
+ << noxfrm;
+ QTest::newRow("DateTime-UTC") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::UTC))
+ << raw("\xc0\x78\x18" "2018-01-01T09:00:00.000Z")
+ << noxfrm;
+ QTest::newRow("DateTime-Local") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::LocalTime))
+ << raw("\xc0\x77" "2018-01-01T09:00:00.000")
+ << noxfrm;
+ QTest::newRow("DateTime+01:00") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::OffsetFromUTC, 3600))
+ << raw("\xc0\x78\x1d" "2018-01-01T09:00:00.000+01:00")
+ << noxfrm;
+ QTest::newRow("Url:Empty") << QCborValue(QUrl()) << raw("\xd8\x20\x60") << noxfrm;
+ QTest::newRow("Url") << QCborValue(QUrl("HTTPS://example.com/{%30%31}?q=%3Ca+b%20%C2%A9%3E&%26"))
+ << raw("\xd8\x20\x78\x27" "https://example.com/{01}?q=<a+b \xC2\xA9>&%26")
+ << noxfrm;
+ QTest::newRow("Regex:Empty") << QCborValue(QRegularExpression()) << raw("\xd8\x23\x60") << noxfrm;
+ QTest::newRow("Regex") << QCborValue(QRegularExpression("^.*$"))
+ << raw("\xd8\x23\x64" "^.*$") << noxfrm;
+ QTest::newRow("Uuid") << QCborValue(uuid) << raw("\xd8\x25\x50") + uuid.toRfc4122() << noxfrm;
+
+ // empty arrays and maps
+ QTest::newRow("Array") << QCborValue(QCborArray()) << raw("\x80") << noxfrm;
+ QTest::newRow("Map") << QCborValue(QCborMap()) << raw("\xa0") << noxfrm;
+
+ QTest::newRow("Tagged:ByteArray") << QCborValue(QCborKnownTags::PositiveBignum, raw("\1\0\0\0\0""\0\0\0\0"))
+ << raw("\xc2\x49\1\0\0\0\0""\0\0\0\0") << noxfrm;
+ QTest::newRow("Tagged:Array") << QCborValue(QCborKnownTags::Decimal, QCborArray{-2, 27315})
+ << raw("\xc4\x82\x21\x19\x6a\xb3") << noxfrm;
+}
+
+void tst_QCborValue::toCbor_data()
+{
+ addCommonCborData();
+
+ // The rest of these tests are conversions whose decoding does not yield
+ // back the same QCborValue.
+
+ // Signalling NaN get normalized to quiet ones
+ QTest::newRow("Double:snan") << QCborValue(qSNaN()) << raw("\xfb\x7f\xf8\0""\0\0\0\0\0") << QCborValue::EncodingOptions();
+ QTest::newRow("Float:snan") << QCborValue(qSNaN()) << raw("\xfa\x7f\xc0\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
+ QTest::newRow("Float16:snan") << QCborValue(qSNaN()) << raw("\xf9\x7e\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+
+ // Floating point written as integers are read back as integers
+ QTest::newRow("UseInteger:0") << QCborValue(0.) << raw("\x00") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:1") << QCborValue(1.) << raw("\x01") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:-1") << QCborValue(-1.) << raw("\x20") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:INT64_MIN") << QCborValue(std::numeric_limits<qint64>::min() + 0.)
+ << raw("\x3b\x7f\xff\xff\xff""\xff\xff\xff\xff")
+ << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+
+ // but obviously non-integral or out of range floating point stay FP
+ QTest::newRow("UseInteger:1.5") << QCborValue(1.5) << raw("\xfb\x3f\xf8\0\0""\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:-1.5") << QCborValue(-1.5) << raw("\xfb\xbf\xf8\0\0""\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:inf") << QCborValue(qInf()) << raw("\xfb\x7f\xf0\0\0""\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:-inf") << QCborValue(-qInf()) << raw("\xfb\xff\xf0\0""\0\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:nan") << QCborValue(qQNaN()) << raw("\xfb\x7f\xf8\0\0""\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:2^64") << QCborValue(18446744073709551616.0) << raw("\xfb\x43\xf0\0\0""\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+ QTest::newRow("UseInteger:-2^65") << QCborValue(-2 * 18446744073709551616.0) << raw("\xfb\xc4\0\0\0""\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
+}
+
+void tst_QCborValue::toCbor()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QByteArray, result);
+ QFETCH(QCborValue::EncodingOptions, options);
+
+ QCOMPARE(v.toCbor(options), result);
+
+ // in maps and arrays
+ QCOMPARE(QCborArray{v}.toCborValue().toCbor(options), "\x81" + result);
+ QCOMPARE(QCborArray({v, v}).toCborValue().toCbor(options),
+ "\x82" + result + result);
+ QCOMPARE(QCborMap({{1, v}}).toCborValue().toCbor(options),
+ "\xa1\x01" + result);
+
+ // tagged
+ QCborValue t(QCborKnownTags::Signature, v);
+ QCOMPARE(t.toCbor(options), "\xd9\xd9\xf7" + result);
+ QCOMPARE(QCborArray({t, t}).toCborValue().toCbor(options),
+ "\x82\xd9\xd9\xf7" + result + "\xd9\xd9\xf7" + result);
+ QCOMPARE(QCborMap({{1, t}}).toCborValue().toCbor(options),
+ "\xa1\x01\xd9\xd9\xf7" + result);
+}
+
+void tst_QCborValue::fromCbor_data()
+{
+ addCommonCborData();
+
+ // chunked strings
+ QTest::newRow("ByteArray:Chunked") << QCborValue(QByteArray("Hello"))
+ << raw("\x5f\x43Hel\x42lo\xff");
+ QTest::newRow("ByteArray:Chunked:Empty") << QCborValue(QByteArray()) << raw("\x5f\xff");
+ QTest::newRow("String:Chunked") << QCborValue("Hello")
+ << raw("\x7f\x63Hel\x62lo\xff");
+ QTest::newRow("String:Chunked:Empty") << QCborValue(QString())
+ << raw("\x7f\xff");
+
+ QTest::newRow("DateTime:NoMilli") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC))
+ << raw("\xc0\x74" "2018-01-10T06:24:37Z");
+ QTest::newRow("UnixTime_t:Integer") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC))
+ << raw("\xc1\x1a\x5a\x55\xb1\xa5");
+ QTest::newRow("UnixTime_t:Double") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::UTC))
+ << raw("\xc1\xfb\x41\xd6\x95\x6c""\x69\x48\x00\x00");
+
+ QTest::newRow("Url:NotNormalized") << QCborValue(QUrl("https://example.com/\xc2\xa9 "))
+ << raw("\xd8\x20\x78\x1dHTTPS://EXAMPLE.COM/%c2%a9%20");
+
+ QTest::newRow("Uuid:Zero") << QCborValue(QUuid()) << raw("\xd8\x25\x40");
+ QTest::newRow("Uuid:TooShort") << QCborValue(QUuid::fromRfc4122(raw("\1\2\3\4""\4\3\2\0""\0\0\0\0""\0\0\0\0")))
+ << raw("\xd8\x25\x47" "\1\2\3\4\4\3\2");
+ QTest::newRow("Uuid:TooLong") << QCborValue(QUuid::fromRfc4122(raw("\1\2\3\4""\4\3\2\0""\0\0\0\0""\0\0\0\1")))
+ << raw("\xd8\x25\x51" "\1\2\3\4""\4\3\2\0""\0\0\0\0""\0\0\0\1""\2");
+}
+
+void tst_QCborValue::fromCbor()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QByteArray, result);
+
+ auto doCheck = [](const QCborValue &v, const QByteArray &result) {
+ QCborParserError error;
+ QCborValue decoded = QCborValue::fromCbor(result, &error);
+ QVERIFY2(error.error == QCborError(), qPrintable(error.errorString()));
+ QCOMPARE(error.offset, result.size());
+ QVERIFY(decoded == v);
+ QVERIFY(v == decoded);
+ };
+
+ doCheck(v, result);
+ if (QTest::currentTestFailed())
+ return;
+
+ // in an array
+ doCheck(QCborArray{v}, "\x81" + result);
+ if (QTest::currentTestFailed())
+ return;
+
+ doCheck(QCborArray{v, v}, "\x82" + result + result);
+ if (QTest::currentTestFailed())
+ return;
+
+ // in a map
+ doCheck(QCborMap{{1, v}}, "\xa1\1" + result);
+ if (QTest::currentTestFailed())
+ return;
+
+ // undefined-length arrays and maps
+ doCheck(QCborArray{v}, "\x9f" + result + "\xff");
+ if (QTest::currentTestFailed())
+ return;
+ doCheck(QCborArray{v, v}, "\x9f" + result + result + "\xff");
+ if (QTest::currentTestFailed())
+ return;
+ doCheck(QCborMap{{1, v}}, "\xbf\1" + result + "\xff");
+ if (QTest::currentTestFailed())
+ return;
+
+ // tagged
+ QCborValue t(QCborKnownTags::Signature, v);
+ doCheck(t, "\xd9\xd9\xf7" + result);
+ if (QTest::currentTestFailed())
+ return;
+
+ // in an array
+ doCheck(QCborArray{t}, "\x81\xd9\xd9\xf7" + result);
+ if (QTest::currentTestFailed())
+ return;
+
+ doCheck(QCborArray{t, t}, "\x82\xd9\xd9\xf7" + result + "\xd9\xd9\xf7" + result);
+ if (QTest::currentTestFailed())
+ return;
+
+ // in a map
+ doCheck(QCborMap{{1, t}}, "\xa1\1\xd9\xd9\xf7" + result);
+ if (QTest::currentTestFailed())
+ return;
+}
+
+void tst_QCborValue::validation_data()
+{
+ addValidationColumns();
+ addValidationData();
+
+ // These tests say we have arrays and maps with very large item counts.
+ // They are meant to ensure we don't pre-allocate a lot of memory
+ // unnecessarily and possibly crash the application. The actual number of
+ // elements in the stream is only 2, so we should get an unexpected EOF
+ // error. QCborValue internally uses 16 bytes per element, so we get to
+ // 2 GB at 2^27 elements.
+ QTest::addRow("very-large-array-no-overflow") << raw("\x9a\x07\xff\xff\xff" "\0\0");
+ QTest::addRow("very-large-array-overflow1") << raw("\x9a\x40\0\0\0" "\0\0");
+
+ // this makes sure we don't accidentally clip to 32-bit: sending 2^32+2 elements
+ QTest::addRow("very-large-array-overflow2") << raw("\x9b\0\0\0\1""\0\0\0\2" "\0\0");
+}
+
+void tst_QCborValue::validation()
+{
+ QFETCH(QByteArray, data);
+
+ QCborParserError error;
+ QCborValue decoded = QCborValue::fromCbor(data, &error);
+ QVERIFY(error.error != QCborError{});
+
+ if (data.startsWith('\x81')) {
+ // decode without the array prefix
+ decoded = QCborValue::fromCbor(data.mid(1), &error);
+ QVERIFY(error.error != QCborError{});
+ }
+}
+
+void tst_QCborValue::toDiagnosticNotation_data()
+{
+ QTest::addColumn<QCborValue>("v");
+ QTest::addColumn<int>("opts");
+ QTest::addColumn<QString>("expected");
+ QDateTime dt = QDateTime::currentDateTimeUtc();
+ QUuid uuid = QUuid::createUuid();
+
+ QMetaEnum me = QMetaEnum::fromType<QCborValue::Type>();
+ auto add = [me](const QCborValue &v, const QString &exp) {
+ auto addRow = [=](const char *prefix) -> QTestData & {
+ QCborValue::Type t = v.type();
+ if (t == QCborValue::Integer)
+ return QTest::addRow("%sInteger:%lld", prefix, v.toInteger());
+ if (t == QCborValue::Double)
+ return QTest::addRow("%sDouble:%g", prefix, v.toDouble());
+ if (t == QCborValue::ByteArray)
+ return QTest::addRow("%sByteArray:%d", prefix, v.toByteArray().size());
+ if (t == QCborValue::String)
+ return QTest::addRow("%sString:%d", prefix, v.toString().size());
+
+ QByteArray typeString = me.valueToKey(t);
+ Q_ASSERT(!typeString.isEmpty());
+ return QTest::newRow(prefix + typeString);
+ };
+ addRow("") << v << int(QCborValue::DiagnosticNotationOptions{}) << exp;
+ addRow("LW:") << v << int(QCborValue::LineWrapped) << exp;
+ addRow("Array:") << QCborValue(QCborArray{v}) << int(QCborValue::DiagnosticNotationOptions{}) << '[' + exp + ']';
+ addRow("Mapped:") << QCborValue(QCborMap{{2, v}}) << int(QCborValue::DiagnosticNotationOptions{}) << "{2: " + exp + '}';
+ addRow("Mapping:") << QCborValue(QCborMap{{v, 2}}) << int(QCborValue::DiagnosticNotationOptions{}) << '{' + exp + ": 2}";
+ };
+
+ // empty arrays and maps
+ QTest::newRow("EmptyArray")
+ << QCborValue(QCborArray()) << int(QCborValue::DiagnosticNotationOptions{})
+ << "[]";
+ QTest::newRow("EmptyMap")
+ << QCborValue(QCborMap()) << int(QCborValue::DiagnosticNotationOptions{})
+ << "{}";
+
+ add(QCborValue(), "undefined");
+ add(QCborValue::Null, "null");
+ add(false, "false");
+ add(true, "true");
+ add(QCborSimpleType(0), "simple(0)");
+ QTest::newRow("SimpleType-255")
+ << QCborValue(QCborSimpleType(255)) << int(QCborValue::DiagnosticNotationOptions{})
+ << "simple(255)";
+ add(0, "0");
+ add(1, "1");
+ add(-1, "-1");
+ add(std::numeric_limits<qint64>::min(), QString::number(std::numeric_limits<qint64>::min()));
+ add(std::numeric_limits<qint64>::max(), QString::number(std::numeric_limits<qint64>::max()));
+ add(0., "0.0");
+ add(1.25, "1.25");
+ add(-1.25, "-1.25");
+ add(qInf(), "inf");
+ add(-qInf(), "-inf");
+ add(qQNaN(), "nan");
+ add(QByteArray(), "h''");
+ add(QByteArray("Hello"), "h'48656c6c6f'");
+ add(QLatin1String(), QLatin1String("\"\""));
+ add("Hello", "\"Hello\"");
+ add("\"Hello\\World\"", "\"\\\"Hello\\\\World\\\"\"");
+ add(QCborValue(dt), "0(\"" + dt.toString(Qt::ISODateWithMs) + "\")");
+ add(QCborValue(QUrl("http://example.com")), "32(\"http://example.com\")");
+ add(QCborValue(QRegularExpression("^.*$")), "35(\"^.*$\")");
+ add(QCborValue(uuid), "37(h'" + uuid.toString(QUuid::Id128) + "')");
+
+ // arrays and maps with more than one element
+ QTest::newRow("2Array")
+ << QCborValue(QCborArray{0, 1}) << int(QCborValue::DiagnosticNotationOptions{})
+ << "[0, 1]";
+ QTest::newRow("2Map")
+ << QCborValue(QCborMap{{0, 1}, {"foo", "bar"}}) << int(QCborValue::DiagnosticNotationOptions{})
+ << "{0: 1, \"foo\": \"bar\"}";
+
+ // line wrapping in arrays and maps
+ QTest::newRow("LW:EmptyArray")
+ << QCborValue(QCborArray()) << int(QCborValue::LineWrapped)
+ << "[\n]";
+ QTest::newRow("LW:EmptyMap")
+ << QCborValue(QCborMap()) << int(QCborValue::LineWrapped)
+ << "{\n}";
+ QTest::newRow("LW:Array:Integer:0")
+ << QCborValue(QCborArray{0}) << int(QCborValue::LineWrapped)
+ << "[\n 0\n]";
+ QTest::newRow("LW:Array:String:5")
+ << QCborValue(QCborArray{"Hello"}) << int(QCborValue::LineWrapped)
+ << "[\n \"Hello\"\n]";
+ QTest::newRow("LW:Map:0-0")
+ << QCborValue(QCborMap{{0, 0}}) << int(QCborValue::LineWrapped)
+ << "{\n 0: 0\n}";
+ QTest::newRow("LW:Map:String:5")
+ << QCborValue(QCborMap{{0, "Hello"}}) << int(QCborValue::LineWrapped)
+ << "{\n 0: \"Hello\"\n}";
+ QTest::newRow("LW:2Array")
+ << QCborValue(QCborArray{0, 1}) << int(QCborValue::LineWrapped)
+ << "[\n 0,\n 1\n]";
+ QTest::newRow("LW:2Map")
+ << QCborValue(QCborMap{{0, 0}, {"foo", "bar"}}) << int(QCborValue::LineWrapped)
+ << "{\n 0: 0,\n \"foo\": \"bar\"\n}";
+
+ // nested arrays and maps
+ QTest::newRow("Array:EmptyArray")
+ << QCborValue(QCborArray() << QCborArray()) << int(QCborValue::DiagnosticNotationOptions{})
+ << "[[]]";
+ QTest::newRow("Array:EmptyMap")
+ << QCborValue(QCborArray() << QCborMap()) << int(QCborValue::DiagnosticNotationOptions{})
+ << "[{}]";
+ QTest::newRow("LW:Array:EmptyArray")
+ << QCborValue(QCborArray() << QCborArray()) << int(QCborValue::LineWrapped)
+ << "[\n [\n ]\n]";
+ QTest::newRow("LW:Array:EmptyMap")
+ << QCborValue(QCborArray() << QCborMap()) << int(QCborValue::LineWrapped)
+ << "[\n {\n }\n]";
+ QTest::newRow("LW:Array:2Array")
+ << QCborValue(QCborArray() << QCborArray{0, 1}) << int(QCborValue::LineWrapped)
+ << "[\n [\n 0,\n 1\n ]\n]";
+ QTest::newRow("LW:Map:2Array")
+ << QCborValue(QCborMap{{0, QCborArray{0, 1}}}) << int(QCborValue::LineWrapped)
+ << "{\n 0: [\n 0,\n 1\n ]\n}";
+ QTest::newRow("LW:Map:2Map")
+ << QCborValue(QCborMap{{-1, QCborMap{{0, 0}, {"foo", "bar"}}}}) << int(QCborValue::LineWrapped)
+ << "{\n -1: {\n 0: 0,\n \"foo\": \"bar\"\n }\n}";
+
+ // string escaping
+ QTest::newRow("String:escaping")
+ << QCborValue("\1\a\b\t\f\r\n\v\x1f\x7f \"\xc2\xa0\xe2\x82\xac\xf0\x90\x80\x80\\\"")
+ << int(QCborValue::DiagnosticNotationOptions{})
+ << "\"\\u0001\\a\\b\\t\\f\\r\\n\\v\\u001F\\u007F \\\"\\u00A0\\u20AC\\U00010000\\\\\\\"\"";
+
+ // extended formatting for byte arrays
+ QTest::newRow("Extended:ByteArray:0")
+ << QCborValue(QByteArray()) << int(QCborValue::ExtendedFormat)
+ << "h''";
+ QTest::newRow("Extended:ByteArray:5")
+ << QCborValue(QByteArray("Hello")) << int(QCborValue::ExtendedFormat)
+ << "h'48 65 6c 6c 6f'";
+ QTest::newRow("Extended:ByteArray:Base64url")
+ << QCborValue(QCborKnownTags::ExpectedBase64url, QByteArray("\xff\xef"))
+ << int(QCborValue::ExtendedFormat) << "21(b64'_-8')";
+ QTest::newRow("Extended:ByteArray:Base64")
+ << QCborValue(QCborKnownTags::ExpectedBase64, QByteArray("\xff\xef"))
+ << int(QCborValue::ExtendedFormat) << "22(b64'/+8=')";
+
+ // formatting applies through arrays too
+ QTest::newRow("Extended:Array:ByteArray:Base64url")
+ << QCborValue(QCborKnownTags::ExpectedBase64url, QCborArray{QByteArray("\xff\xef")})
+ << int(QCborValue::ExtendedFormat) << "21([b64'_-8'])";
+ // and only the innermost applies
+ QTest::newRow("ByteArray:multiple-tags")
+ << QCborValue(QCborKnownTags::ExpectedBase64url,
+ QCborArray{QCborValue(QCborKnownTags::ExpectedBase16, QByteArray("Hello")),
+ QByteArray("\xff\xef")})
+ << int(QCborValue::ExtendedFormat) << "21([23(h'48 65 6c 6c 6f'), b64'_-8'])";
+}
+
+void tst_QCborValue::toDiagnosticNotation()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QString, expected);
+ QFETCH(int, opts);
+
+ QString result = v.toDiagnosticNotation(QCborValue::DiagnosticNotationOptions(opts));
+ QCOMPARE(result, expected);
+}
+
+QTEST_MAIN(tst_QCborValue)
+
+#include "tst_qcborvalue.moc"
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/qcborvalue_json.pro b/tests/auto/corelib/serialization/qcborvalue_json/qcborvalue_json.pro
new file mode 100644
index 0000000000..c11000b7c2
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborvalue_json/qcborvalue_json.pro
@@ -0,0 +1,7 @@
+QT = core testlib
+TARGET = tst_qcborvalue_json
+CONFIG += testcase
+SOURCES += \
+ tst_qcborvalue_json.cpp
+
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
new file mode 100644
index 0000000000..56245a7173
--- /dev/null
+++ b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
@@ -0,0 +1,348 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qcborvalue.h>
+#include <QtTest>
+
+Q_DECLARE_METATYPE(QCborValue)
+
+class tst_QCborValue_Json : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void toVariant_data();
+ void toVariant();
+ void toJson_data() { toVariant_data(); }
+ void toJson();
+ void taggedByteArrayToJson_data();
+ void taggedByteArrayToJson();
+
+ void fromVariant_data() { toVariant_data(); }
+ void fromVariant();
+ void fromJson_data();
+ void fromJson();
+
+ void nonStringKeysInMaps_data();
+ void nonStringKeysInMaps();
+};
+
+void tst_QCborValue_Json::toVariant_data()
+{
+ QTest::addColumn<QCborValue>("v");
+ QTest::addColumn<QVariant>("variant");
+ QTest::addColumn<QJsonValue>("json");
+ QDateTime dt = QDateTime::currentDateTimeUtc();
+ QUuid uuid = QUuid::createUuid();
+
+ QMetaEnum me = QMetaEnum::fromType<QCborValue::Type>();
+ auto add = [me](const QCborValue &v, const QVariant &exp, const QJsonValue &json) {
+ auto addRow = [=]() -> QTestData & {
+ const char *typeString = me.valueToKey(v.type());
+ if (v.type() == QCborValue::Integer)
+ return QTest::addRow("Integer:%lld", exp.toLongLong());
+ if (v.type() == QCborValue::Double)
+ return QTest::addRow("Double:%g", exp.toDouble());
+ if (v.type() == QCborValue::ByteArray || v.type() == QCborValue::String)
+ return QTest::addRow("%s:%d", typeString, exp.toString().size());
+ if (v.type() >= 0x10000)
+ return QTest::newRow(exp.typeName());
+ return QTest::newRow(typeString);
+ };
+ addRow() << v << exp << json;
+ };
+
+ // good JSON matching:
+ add(QCborValue(), QVariant(), QJsonValue::Undefined);
+ add(nullptr, QVariant::fromValue(nullptr), QJsonValue::Null);
+ add(false, false, false);
+ add(true, true, true);
+ add(0, 0, 0);
+ add(1, 1, 1);
+ add(-1, -1, -1);
+ add(0., 0., 0.);
+ add(1.25, 1.25, 1.25);
+ add(-1.25, -1.25, -1.25);
+ add("Hello", "Hello", "Hello");
+
+ // converts to string in JSON:
+ add(QByteArray("Hello"), QByteArray("Hello"), "SGVsbG8");
+ add(QCborValue(dt), dt, dt.toString(Qt::ISODateWithMs));
+ add(QCborValue(QUrl("http://example.com/{q}")), QUrl("http://example.com/{q}"),
+ "http://example.com/%7Bq%7D"); // note the encoded form in JSON
+ add(QCborValue(QRegularExpression(".")), QRegularExpression("."), ".");
+ add(QCborValue(uuid), uuid, uuid.toString(QUuid::WithoutBraces));
+
+ // not valid in JSON
+ QTest::newRow("simpletype") << QCborValue(QCborSimpleType(255))
+ << QVariant::fromValue(QCborSimpleType(255))
+ << QJsonValue("simple(255)");
+ QTest::newRow("Double:inf") << QCborValue(qInf())
+ << QVariant(qInf())
+ << QJsonValue();
+ QTest::newRow("Double:-inf") << QCborValue(-qInf())
+ << QVariant(-qInf())
+ << QJsonValue();
+ QTest::newRow("Double:nan") << QCborValue(qQNaN())
+ << QVariant(qQNaN())
+ << QJsonValue();
+
+ // large integral values lose precision in JSON
+ QTest::newRow("Integer:max") << QCborValue(std::numeric_limits<qint64>::max())
+ << QVariant(std::numeric_limits<qint64>::max())
+ << QJsonValue(std::numeric_limits<qint64>::max());
+ QTest::newRow("Integer:min") << QCborValue(std::numeric_limits<qint64>::min())
+ << QVariant(std::numeric_limits<qint64>::min())
+ << QJsonValue(std::numeric_limits<qint64>::min());
+
+ // empty arrays and maps
+ add(QCborArray(), QVariantList(), QJsonArray());
+ add(QCborMap(), QVariantMap(), QJsonObject());
+}
+
+void tst_QCborValue_Json::toVariant()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QVariant, variant);
+
+ if (qIsNaN(variant.toDouble())) {
+ // because NaN != NaN, QVariant(NaN) != QVariant(NaN), so we
+ // only need to compare the classification
+ QVERIFY(qIsNaN(v.toVariant().toDouble()));
+
+ // the rest of this function depends on the variant comparison
+ return;
+ }
+
+ QCOMPARE(v.toVariant(), variant);
+ if (variant.isValid()) {
+ QVariant variant2 = QVariant::fromValue(v);
+ QVERIFY(variant2.canConvert(variant.userType()));
+ QVERIFY(variant2.convert(variant.userType()));
+ QCOMPARE(variant2, variant);
+ }
+
+ // tags get ignored:
+ QCOMPARE(QCborValue(QCborKnownTags::Signature, v).toVariant(), variant);
+
+ // make arrays with this item
+ QCOMPARE(QCborArray({v}).toVariantList(), QVariantList({variant}));
+ QCOMPARE(QCborArray({v, v}).toVariantList(), QVariantList({variant, variant}));
+
+ // and maps
+ QCOMPARE(QCborMap({{"foo", v}}).toVariantMap(), QVariantMap({{"foo", variant}}));
+ QCOMPARE(QCborMap({{"foo", v}}).toVariantHash(), QVariantHash({{"foo", variant}}));
+
+ // finally, mixed
+ QCOMPARE(QCborArray{QCborMap({{"foo", v}})}.toVariantList(),
+ QVariantList{QVariantMap({{"foo", variant}})});
+}
+
+void tst_QCborValue_Json::toJson()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QJsonValue, json);
+
+ QCOMPARE(v.toJsonValue(), json);
+ QCOMPARE(QVariant::fromValue(v).toJsonValue(), json);
+
+ // most tags get ignored:
+ QCOMPARE(QCborValue(QCborKnownTags::Signature, v).toJsonValue(), json);
+
+ // make arrays with this item
+ QCOMPARE(QCborArray({v}).toJsonArray(), QJsonArray({json}));
+ QCOMPARE(QCborArray({v, v}).toJsonArray(), QJsonArray({json, json}));
+
+ // and maps
+ QCOMPARE(QCborMap({{"foo", v}}).toJsonObject(), QJsonObject({{"foo", json}}));
+
+ // finally, mixed
+ QCOMPARE(QCborArray{QCborMap({{"foo", v}})}.toJsonArray(),
+ QJsonArray{QJsonObject({{"foo", json}})});
+}
+
+void tst_QCborValue_Json::taggedByteArrayToJson_data()
+{
+ QTest::addColumn<QCborValue>("v");
+ QTest::addColumn<QJsonValue>("json");
+
+ QByteArray data("\xff\x01");
+ QTest::newRow("base64url") << QCborValue(QCborKnownTags::ExpectedBase64url, data) << QJsonValue("_wE");
+ QTest::newRow("base64") << QCborValue(QCborKnownTags::ExpectedBase64, data) << QJsonValue("/wE=");
+ QTest::newRow("hex") << QCborValue(QCborKnownTags::ExpectedBase16, data) << QJsonValue("ff01");
+}
+
+void tst_QCborValue_Json::taggedByteArrayToJson()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QJsonValue, json);
+
+ QCOMPARE(v.toJsonValue(), json);
+ QCOMPARE(QCborArray({v}).toJsonArray(), QJsonArray({json}));
+}
+
+void tst_QCborValue_Json::fromVariant()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QVariant, variant);
+
+ QCOMPARE(QCborValue::fromVariant(variant), v);
+ QCOMPARE(variant.value<QCborValue>(), v);
+
+ // try arrays
+ QCOMPARE(QCborArray::fromVariantList({variant}), QCborArray{v});
+ QCOMPARE(QCborArray::fromVariantList({variant, variant}), QCborArray({v, v}));
+
+ if (variant.type() == QVariant::String) {
+ QString s = variant.toString();
+ QCOMPARE(QCborArray::fromStringList({s}), QCborArray{v});
+ QCOMPARE(QCborArray::fromStringList({s, s}), QCborArray({v, v}));
+ }
+
+ // maps...
+ QVariantMap map{{"foo", variant}};
+ QCOMPARE(QCborMap::fromVariantMap(map), QCborMap({{"foo", v}}));
+ QCOMPARE(QCborMap::fromVariantHash({{"foo", variant}}), QCborMap({{"foo", v}}));
+
+ // nested
+ QVariantMap outer{{"bar", QVariantList{0, map, true}}};
+ QCOMPARE(QCborMap::fromVariantMap(outer),
+ QCborMap({{"bar", QCborArray{0, QCborMap{{"foo", v}}, true}}}));
+}
+
+void tst_QCborValue_Json::fromJson_data()
+{
+ QTest::addColumn<QCborValue>("v");
+ QTest::addColumn<QJsonValue>("json");
+
+ QTest::newRow("null") << QCborValue(QCborValue::Null) << QJsonValue(QJsonValue::Null);
+ QTest::newRow("false") << QCborValue(false) << QJsonValue(false);
+ QTest::newRow("true") << QCborValue(true) << QJsonValue(true);
+ QTest::newRow("0") << QCborValue(0) << QJsonValue(0.);
+ QTest::newRow("1") << QCborValue(1) << QJsonValue(1);
+ QTest::newRow("1.5") << QCborValue(1.5) << QJsonValue(1.5);
+ QTest::newRow("string") << QCborValue("Hello") << QJsonValue("Hello");
+ QTest::newRow("array") << QCborValue(QCborValue::Array) << QJsonValue(QJsonValue::Array);
+ QTest::newRow("map") << QCborValue(QCborValue::Map) << QJsonValue(QJsonValue::Object);
+}
+
+void tst_QCborValue_Json::fromJson()
+{
+ QFETCH(QCborValue, v);
+ QFETCH(QJsonValue, json);
+
+ QCOMPARE(QCborValue::fromJsonValue(json), v);
+ QCOMPARE(QVariant(json).value<QCborValue>(), v);
+ QCOMPARE(QCborArray::fromJsonArray({json}), QCborArray({v}));
+ QCOMPARE(QCborArray::fromJsonArray({json, json}), QCborArray({v, v}));
+ QCOMPARE(QCborMap::fromJsonObject({{"foo", json}}), QCborMap({{"foo", v}}));
+
+ // confirm we can roundtrip back to JSON
+ QCOMPARE(QCborValue::fromJsonValue(json).toJsonValue(), json);
+}
+
+void tst_QCborValue_Json::nonStringKeysInMaps_data()
+{
+ QTest::addColumn<QCborValue>("key");
+ QTest::addColumn<QString>("converted");
+
+ auto add = [](const char *str, const QCborValue &v) {
+ QTest::newRow(str) << v << str;
+ };
+ add("0", 0);
+ add("-1", -1);
+ add("false", false);
+ add("true", true);
+ add("null", nullptr);
+ add("undefined", {}); // should this be ""?
+ add("simple(255)", QCborSimpleType(255));
+ add("2.5", 2.5);
+
+ QByteArray data("\xff\x01");
+ QTest::newRow("bytearray") << QCborValue(data) << "_wE";
+ QTest::newRow("base64url") << QCborValue(QCborKnownTags::ExpectedBase64url, data) << "_wE";
+ QTest::newRow("base64") << QCborValue(QCborKnownTags::ExpectedBase64, data) << "/wE=";
+ QTest::newRow("hex") << QCborValue(QCborKnownTags::ExpectedBase16, data) << "ff01";
+
+ QTest::newRow("emptyarray") << QCborValue(QCborValue::Array) << "[]";
+ QTest::newRow("emptymap") << QCborValue(QCborValue::Map) << "{}";
+ QTest::newRow("array") << QCborValue(QCborArray{1, true, 2.5, "Hello"})
+ << "[1, true, 2.5, \"Hello\"]";
+ QTest::newRow("map") << QCborValue(QCborMap{{"Hello", 0}, {0, "Hello"}})
+ << "{\"Hello\": 0, 0: \"Hello\"}";
+
+ QDateTime dt = QDateTime::currentDateTimeUtc();
+ QUrl url("https://example.com");
+ QUuid uuid = QUuid::createUuid();
+ QTest::newRow("QDateTime") << QCborValue(dt) << dt.toString(Qt::ISODateWithMs);
+ QTest::newRow("QUrl") << QCborValue(url) << url.toString(QUrl::FullyEncoded);
+ QTest::newRow("QRegularExpression") << QCborValue(QRegularExpression(".*")) << ".*";
+ QTest::newRow("QUuid") << QCborValue(uuid) << uuid.toString(QUuid::WithoutBraces);
+}
+
+void tst_QCborValue_Json::nonStringKeysInMaps()
+{
+ QFETCH(QCborValue, key);
+ QFETCH(QString, converted);
+
+ QCborMap m;
+ m.insert(key, 0);
+
+ {
+ QVariantMap vm = m.toVariantMap();
+ auto it = vm.begin();
+ QVERIFY(it != vm.end());
+ QCOMPARE(it.key(), converted);
+ QCOMPARE(it.value(), 0);
+ QCOMPARE(++it, vm.end());
+ }
+
+ {
+ QJsonObject o = m.toJsonObject();
+ auto it = o.begin();
+ QVERIFY(it != o.end());
+ QCOMPARE(it.key(), converted);
+ QCOMPARE(it.value(), 0);
+ QCOMPARE(++it, o.end());
+ }
+}
+
+QTEST_MAIN(tst_QCborValue_Json)
+
+#include "tst_qcborvalue_json.moc"
diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
index 14a2528cc6..c6faf8c7d5 100644
--- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
+++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp
@@ -260,16 +260,16 @@ static int NColorRoles[] = {
QPalette::HighlightedText + 1, // Qt_4_0, Qt_4_1
QPalette::HighlightedText + 1, // Qt_4_2
QPalette::AlternateBase + 1, // Qt_4_3
- QPalette::ToolTipText + 1, // Qt_4_4
- QPalette::ToolTipText + 1, // Qt_4_5
- QPalette::ToolTipText + 1, // Qt_4_6
- QPalette::ToolTipText + 1, // Qt_5_0
- QPalette::ToolTipText + 1, // Qt_5_1
- QPalette::ToolTipText + 1, // Qt_5_2
- QPalette::ToolTipText + 1, // Qt_5_3
- QPalette::ToolTipText + 1, // Qt_5_4
- QPalette::ToolTipText + 1, // Qt_5_5
- QPalette::ToolTipText + 1, // Qt_5_6
+ QPalette::PlaceholderText + 1, // Qt_4_4
+ QPalette::PlaceholderText + 1, // Qt_4_5
+ QPalette::PlaceholderText + 1, // Qt_4_6
+ QPalette::PlaceholderText + 1, // Qt_5_0
+ QPalette::PlaceholderText + 1, // Qt_5_1
+ QPalette::PlaceholderText + 1, // Qt_5_2
+ QPalette::PlaceholderText + 1, // Qt_5_3
+ QPalette::PlaceholderText + 1, // Qt_5_4
+ QPalette::PlaceholderText + 1, // Qt_5_5
+ QPalette::PlaceholderText + 1, // Qt_5_6
0 // add the correct value for Qt_5_7 here later
};
@@ -2139,7 +2139,7 @@ void tst_QDataStream::setVersion()
*/
// revise the test if new color roles or color groups are added
- QVERIFY(QPalette::NColorRoles == QPalette::ToolTipText + 1);
+ QVERIFY(QPalette::NColorRoles == QPalette::PlaceholderText + 1);
QCOMPARE(int(QPalette::NColorGroups), 3);
QByteArray ba2;
diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
index df8746e518..edea4713a1 100644
--- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp
@@ -161,6 +161,7 @@ private slots:
void string_write_operator_ToDevice();
void latin1String_write_operator_ToDevice();
void stringref_write_operator_ToDevice();
+ void stringview_write_operator_ToDevice();
// other
void skipWhiteSpace_data();
@@ -2573,6 +2574,17 @@ void tst_QTextStream::stringref_write_operator_ToDevice()
QCOMPARE(buf.buffer().constData(), "No explicit lengthExplicit length");
}
+void tst_QTextStream::stringview_write_operator_ToDevice()
+{
+ QBuffer buf;
+ buf.open(QBuffer::WriteOnly);
+ QTextStream stream(&buf);
+ const QStringView expected = QStringViewLiteral("expectedStringView");
+ stream << expected;
+ stream.flush();
+ QCOMPARE(buf.buffer().constData(), "expectedStringView");
+}
+
// ------------------------------------------------------------------------------
void tst_QTextStream::useCase1()
{
diff --git a/tests/auto/corelib/serialization/serialization.pro b/tests/auto/corelib/serialization/serialization.pro
index afb9c5b61c..9187de1bc5 100644
--- a/tests/auto/corelib/serialization/serialization.pro
+++ b/tests/auto/corelib/serialization/serialization.pro
@@ -1,6 +1,10 @@
TEMPLATE = subdirs
SUBDIRS = \
json \
+ qcborstreamreader \
+ qcborstreamwriter \
+ qcborvalue \
+ qcborvalue_json \
qdatastream \
qtextstream \
qxmlstream
diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
index d4a3ee6054..b8c82c2ea0 100644
--- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
+++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
@@ -1021,6 +1021,8 @@ void tst_QFuture::iterators()
QCOMPARE(i2, c2);
QCOMPARE(c2, i2);
QCOMPARE(c2, c2);
+ QCOMPARE(1 + i1, i1 + 1);
+ QCOMPARE(1 + c1, c1 + 1);
QVERIFY(i1 != i2);
QVERIFY(i1 != c2);
@@ -1070,6 +1072,8 @@ void tst_QFuture::iterators()
QCOMPARE(i2, c2);
QCOMPARE(c2, i2);
QCOMPARE(c2, c2);
+ QCOMPARE(1 + i1, i1 + 1);
+ QCOMPARE(1 + c1, c1 + 1);
QVERIFY(i1 != i2);
QVERIFY(i1 != c2);
diff --git a/tests/auto/corelib/thread/qsemaphore/BLACKLIST b/tests/auto/corelib/thread/qsemaphore/BLACKLIST
index eb83b03556..0786f50417 100644
--- a/tests/auto/corelib/thread/qsemaphore/BLACKLIST
+++ b/tests/auto/corelib/thread/qsemaphore/BLACKLIST
@@ -1,6 +1,8 @@
[tryAcquireWithTimeout:0.2s]
windows
osx-10.12
+osx-10.13
[tryAcquireWithTimeout:2s]
windows
osx-10.12
+osx-10.13
diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp b/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp
index 9179750218..d27884197a 100644
--- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp
+++ b/tests/auto/corelib/thread/qthreadonce/qthreadonce.cpp
@@ -30,7 +30,6 @@
#include "qplatformdefs.h"
#include "qthreadonce.h"
-#ifndef QT_NO_THREAD
#include "qmutex.h"
Q_GLOBAL_STATIC_WITH_ARGS(QMutex, onceInitializationMutex, (QMutex::Recursive))
@@ -104,5 +103,3 @@ void QOnceControl::done()
{
extra &= ~MustRunCode;
}
-
-#endif // QT_NO_THREAD
diff --git a/tests/auto/corelib/thread/qthreadonce/qthreadonce.h b/tests/auto/corelib/thread/qthreadonce/qthreadonce.h
index 71e830ca16..e5918b8fa5 100644
--- a/tests/auto/corelib/thread/qthreadonce/qthreadonce.h
+++ b/tests/auto/corelib/thread/qthreadonce/qthreadonce.h
@@ -34,8 +34,6 @@
#include <QtCore/qatomic.h>
-#ifndef QT_NO_THREAD
-
class QOnceControl
{
public:
@@ -91,6 +89,4 @@ public:
inline operator T*() { return value(); }
};
-#endif // QT_NO_THREAD
-
#endif
diff --git a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro
index 94a0a01e94..d5c09ebc84 100644
--- a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro
+++ b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro
@@ -1,5 +1,13 @@
SOURCES += crashOnExit.cpp
-DESTDIR = ./
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/crashOnExit_helper
+ } else {
+ TARGET = ../../release/crashOnExit_helper
+ }
+} else {
+ TARGET = ../crashOnExit_helper
+}
QT = core
CONFIG -= app_bundle
CONFIG += console
diff --git a/tests/auto/corelib/thread/qthreadstorage/test/test.pro b/tests/auto/corelib/thread/qthreadstorage/test/test.pro
index d7190f7e7b..d2f21f48f0 100644
--- a/tests/auto/corelib/thread/qthreadstorage/test/test.pro
+++ b/tests/auto/corelib/thread/qthreadstorage/test/test.pro
@@ -1,9 +1,16 @@
CONFIG += testcase
-TARGET = ../tst_qthreadstorage
-CONFIG -= debug_and_release_target
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/tst_qthreadstorage
+ !android:!winrt: TEST_HELPER_INSTALLS = ../../debug/crashonexit_helper
+ } else {
+ TARGET = ../../release/tst_qthreadstorage
+ !android:!winrt: TEST_HELPER_INSTALLS = ../../release/crashonexit_helper
+ }
+} else {
+ TARGET = ../tst_qthreadstorage
+ !android:!winrt: TEST_HELPER_INSTALLS = ../crashonexit_helper
+}
CONFIG += console
QT = core testlib
SOURCES = ../tst_qthreadstorage.cpp
-
-!android:!winrt: TEST_HELPER_INSTALLS = ../crashonexit/crashonexit
-
diff --git a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
index 403e28b07b..ef5d3452d5 100644
--- a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
+++ b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
@@ -48,7 +48,6 @@ class tst_QThreadStorage : public QObject
{
Q_OBJECT
private slots:
- void initTestCase();
void hasLocalData();
void localData();
void localData_const();
@@ -60,9 +59,6 @@ private slots:
void leakInDestructor();
void resetInDestructor();
void valueBased();
-
-private:
- QString m_crashOnExit;
};
class Pointer
@@ -74,22 +70,6 @@ public:
};
int Pointer::count = 0;
-void tst_QThreadStorage::initTestCase()
-{
-#if QT_CONFIG(process)
- const QString crashOnExitDir = QFINDTESTDATA("crashonexit");
- QVERIFY2(!crashOnExitDir.isEmpty(),
- qPrintable(QString::fromLatin1("Could not find 'crashonexit' starting from '%1'")
- .arg(QDir::toNativeSeparators(QDir::currentPath()))));
- m_crashOnExit = crashOnExitDir + QStringLiteral("/crashonexit");
-#ifdef Q_OS_WIN
- m_crashOnExit += QStringLiteral(".exe");
-#endif
- QVERIFY2(QFileInfo(m_crashOnExit).isExecutable(),
- qPrintable(QDir::toNativeSeparators(m_crashOnExit) + QStringLiteral(" does not exist or is not executable.")));
-#endif
-}
-
void tst_QThreadStorage::hasLocalData()
{
QThreadStorage<Pointer *> pointers;
@@ -329,7 +309,7 @@ void tst_QThreadStorage::crashOnExit()
QSKIP("No qprocess support", SkipAll);
#else
QString errorMessage;
- QVERIFY2(runCrashOnExit(m_crashOnExit, &errorMessage),
+ QVERIFY2(runCrashOnExit("crashOnExit_helper", &errorMessage),
qPrintable(errorMessage));
#endif
}
diff --git a/tests/auto/corelib/thread/thread.pro b/tests/auto/corelib/thread/thread.pro
index d3c669859b..90b8d6806e 100644
--- a/tests/auto/corelib/thread/thread.pro
+++ b/tests/auto/corelib/thread/thread.pro
@@ -1,22 +1,25 @@
TEMPLATE=subdirs
-SUBDIRS=\
- qatomicint \
- qatomicinteger \
- qatomicpointer \
- qresultstore \
- qfuture \
- qfuturesynchronizer \
- qmutex \
- qmutexlocker \
- qreadlocker \
- qreadwritelock \
- qsemaphore \
- qthread \
- qthreadonce \
- qthreadpool \
- qthreadstorage \
- qwaitcondition \
- qwritelocker
+
+qtConfig(thread) {
+ SUBDIRS=\
+ qatomicint \
+ qatomicinteger \
+ qatomicpointer \
+ qresultstore \
+ qfuture \
+ qfuturesynchronizer \
+ qmutex \
+ qmutexlocker \
+ qreadlocker \
+ qreadwritelock \
+ qsemaphore \
+ qthread \
+ qthreadonce \
+ qthreadpool \
+ qthreadstorage \
+ qwaitcondition \
+ qwritelocker
+}
qtHaveModule(concurrent) {
SUBDIRS += \
diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp
index 38366e86ff..b40b1f0624 100644
--- a/tests/auto/corelib/tools/collections/tst_collections.cpp
+++ b/tests/auto/corelib/tools/collections/tst_collections.cpp
@@ -2620,6 +2620,8 @@ void testLinkedListLikeStlIterators()
QVERIFY(i2 == c2);
QVERIFY(c2 == i2);
QVERIFY(c2 == c2);
+ QVERIFY(1 + i1 == i1 + 1);
+ QVERIFY(1 + c1 == c1 + 1);
QVERIFY(i1 != i2);
QVERIFY(i1 != c2);
@@ -2731,6 +2733,8 @@ void testMapLikeStlIterators()
QVERIFY(i2 == c2);
QVERIFY(c2 == i2);
QVERIFY(c2 == c2);
+ QVERIFY(1 + i1 == i1 + 1);
+ QVERIFY(1 + c1 == c1 + 1);
QVERIFY(i1 != i2);
QVERIFY(i1 != c2);
diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
index 338adaabf7..1ed41793dc 100644
--- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
+++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp
@@ -106,6 +106,8 @@ private slots:
void number();
void toInt_data();
void toInt();
+ void toDouble_data();
+ void toDouble();
void blockSizeCalculations();
void resizeAfterFromRawData();
@@ -141,6 +143,8 @@ private slots:
#endif
void toUpperLower_data();
void toUpperLower();
+ void isUpper();
+ void isLower();
void macTypes();
@@ -856,15 +860,38 @@ void tst_QByteArray::qstricmp()
if ( actual != 0 ) {
actual = (actual < 0 ? -1 : 1);
}
- QCOMPARE(expected, actual);
+ QCOMPARE(actual, expected);
+
+ actual = ::qstricmp("012345679abcd" + str1.toLatin1(), "012345679AbCd" + str2.toLatin1());
+ if ( actual != 0 ) {
+ actual = (actual < 0 ? -1 : 1);
+ }
+ QCOMPARE(actual, expected);
+
+ actual = str1.toLatin1().compare(str2.toLatin1(), Qt::CaseInsensitive);
+ if ( actual != 0 ) {
+ actual = (actual < 0 ? -1 : 1);
+ }
+ QCOMPARE(actual, expected);
+
+ actual = str1.toLatin1().compare(str2.toLatin1().constData(), Qt::CaseInsensitive);
+ if ( actual != 0 ) {
+ actual = (actual < 0 ? -1 : 1);
+ }
+ QCOMPARE(actual, expected);
}
void tst_QByteArray::qstricmp_singularities()
{
QCOMPARE(::qstricmp(0, 0), 0);
- QVERIFY(::qstricmp(0, "a") != 0);
- QVERIFY(::qstricmp("a", 0) != 0);
+ QVERIFY(::qstricmp(0, "a") < 0);
+ QVERIFY(::qstricmp("a", 0) > 0);
QCOMPARE(::qstricmp("", ""), 0);
+ QCOMPARE(QByteArray().compare(nullptr, Qt::CaseInsensitive), 0);
+ QCOMPARE(QByteArray().compare("", Qt::CaseInsensitive), 0);
+ QVERIFY(QByteArray("a").compare(nullptr, Qt::CaseInsensitive) > 0);
+ QVERIFY(QByteArray("a").compare("", Qt::CaseInsensitive) > 0);
+ QVERIFY(QByteArray().compare("a", Qt::CaseInsensitive) < 0);
}
void tst_QByteArray::qstrnicmp_singularities()
@@ -874,6 +901,9 @@ void tst_QByteArray::qstrnicmp_singularities()
QVERIFY(::qstrnicmp("a", 0, 123) != 0);
QCOMPARE(::qstrnicmp("", "", 123), 0);
QCOMPARE(::qstrnicmp("a", "B", 0), 0);
+ QCOMPARE(QByteArray().compare(QByteArray(), Qt::CaseInsensitive), 0);
+ QVERIFY(QByteArray().compare(QByteArray("a"), Qt::CaseInsensitive) < 0);
+ QVERIFY(QByteArray("a").compare(QByteArray(), Qt::CaseInsensitive) > 0);
}
void tst_QByteArray::chop_data()
@@ -1289,6 +1319,11 @@ void tst_QByteArray::toInt_data()
QTest::newRow("base 0-3") << QByteArray("010") << 0 << int(8) << true;
QTest::newRow("empty") << QByteArray() << 0 << int(0) << false;
+ QTest::newRow("leading space") << QByteArray(" 100") << 10 << int(100) << true;
+ QTest::newRow("trailing space") << QByteArray("100 ") << 10 << int(100) << true;
+ QTest::newRow("leading junk") << QByteArray("x100") << 10 << int(0) << false;
+ QTest::newRow("trailing junk") << QByteArray("100x") << 10 << int(0) << false;
+
// using fromRawData
QTest::newRow("raw1") << QByteArray::fromRawData("1", 1) << 10 << 1 << true;
QTest::newRow("raw2") << QByteArray::fromRawData("1foo", 1) << 10 << 1 << true;
@@ -1313,6 +1348,34 @@ void tst_QByteArray::toInt()
QCOMPARE( number, expectednumber );
}
+void tst_QByteArray::toDouble_data()
+{
+ QTest::addColumn<QByteArray>("string");
+ QTest::addColumn<double>("expectedNumber");
+ QTest::addColumn<bool>("expectedOk");
+
+ QTest::newRow("decimal") << QByteArray("1.2345") << 1.2345 << true;
+ QTest::newRow("exponent lowercase") << QByteArray("1.2345e+01") << 12.345 << true;
+ QTest::newRow("exponent uppercase") << QByteArray("1.2345E+02") << 123.45 << true;
+ QTest::newRow("leading spaces") << QByteArray(" \n\r\t1.2345") << 1.2345 << true;
+ QTest::newRow("trailing spaces") << QByteArray("1.2345 \n\r\t") << 1.2345 << true;
+ QTest::newRow("leading junk") << QByteArray("x1.2345") << 0.0 << false;
+ QTest::newRow("trailing junk") << QByteArray("1.2345x") << 0.0 << false;
+}
+
+void tst_QByteArray::toDouble()
+{
+ QFETCH(QByteArray, string);
+ QFETCH(double, expectedNumber);
+ QFETCH(bool, expectedOk);
+
+ bool ok;
+ const double number = string.toDouble(&ok);
+
+ QCOMPARE(ok, expectedOk);
+ QCOMPARE(number, expectedNumber);
+}
+
void tst_QByteArray::toULong_data()
{
QTest::addColumn<QByteArray>("str");
@@ -1326,6 +1389,11 @@ void tst_QByteArray::toULong_data()
QTest::newRow("empty") << QByteArray("") << 10 << 0UL << false;
QTest::newRow("ulong1") << QByteArray("3234567890") << 10 << 3234567890UL << true;
QTest::newRow("ulong2") << QByteArray("fFFfFfFf") << 16 << 0xFFFFFFFFUL << true;
+
+ QTest::newRow("leading spaces") << QByteArray(" \n\r\t100") << 10 << 100UL << true;
+ QTest::newRow("trailing spaces") << QByteArray("100 \n\r\t") << 10 << 100UL << true;
+ QTest::newRow("leading junk") << QByteArray("x100") << 10 << 0UL << false;
+ QTest::newRow("trailing junk") << QByteArray("100x") << 10 << 0UL << false;
}
void tst_QByteArray::toULong()
@@ -1351,6 +1419,10 @@ void tst_QByteArray::toULongLong_data()
QTest::newRow("default") << QByteArray() << 10 << (qulonglong)0 << false;
QTest::newRow("out of base bound") << QByteArray("c") << 10 << (qulonglong)0 << false;
+ QTest::newRow("leading spaces") << QByteArray(" \n\r\t100") << 10 << qulonglong(100) << true;
+ QTest::newRow("trailing spaces") << QByteArray("100 \n\r\t") << 10 << qulonglong(100) << true;
+ QTest::newRow("leading junk") << QByteArray("x100") << 10 << qulonglong(0) << false;
+ QTest::newRow("trailing junk") << QByteArray("100x") << 10 << qulonglong(0) << false;
}
void tst_QByteArray::toULongLong()
@@ -1757,6 +1829,12 @@ void tst_QByteArray::compare()
const bool isLess = result < 0;
const bool isGreater = result > 0;
+ int cmp = str1.compare(str2);
+ if (cmp)
+ cmp = (cmp < 0 ? -1 : 1);
+
+ QCOMPARE(cmp, result);
+
// basic tests:
QCOMPARE(str1 == str2, isEqual);
QCOMPARE(str1 < str2, isLess);
@@ -2188,6 +2266,51 @@ void tst_QByteArray::toUpperLower()
QCOMPARE(qMove(copy).toUpper(), upper);
}
+void tst_QByteArray::isUpper()
+{
+ QVERIFY(!QByteArray().isUpper());
+ QVERIFY(!QByteArray("").isUpper());
+ QVERIFY(QByteArray("TEXT").isUpper());
+ QVERIFY(QByteArray("\xD0\xDE").isUpper());
+ QVERIFY(!QByteArray("\xD7").isUpper()); // multiplication sign is not upper
+ QVERIFY(!QByteArray("\xDF").isUpper()); // sz ligature is not upper
+ QVERIFY(!QByteArray("text").isUpper());
+ QVERIFY(!QByteArray("Text").isUpper());
+ QVERIFY(!QByteArray("tExt").isUpper());
+ QVERIFY(!QByteArray("teXt").isUpper());
+ QVERIFY(!QByteArray("texT").isUpper());
+ QVERIFY(!QByteArray("TExt").isUpper());
+ QVERIFY(!QByteArray("teXT").isUpper());
+ QVERIFY(!QByteArray("tEXt").isUpper());
+ QVERIFY(!QByteArray("tExT").isUpper());
+ QVERIFY(!QByteArray("@ABYZ[").isUpper());
+ QVERIFY(!QByteArray("@abyz[").isUpper());
+ QVERIFY(!QByteArray("`ABYZ{").isUpper());
+ QVERIFY(!QByteArray("`abyz{").isUpper());
+}
+
+void tst_QByteArray::isLower()
+{
+ QVERIFY(!QByteArray().isLower());
+ QVERIFY(!QByteArray("").isLower());
+ QVERIFY(QByteArray("text").isLower());
+ QVERIFY(QByteArray("\xE0\xFF").isLower());
+ QVERIFY(!QByteArray("\xF7").isLower()); // division sign is not lower
+ QVERIFY(!QByteArray("Text").isLower());
+ QVERIFY(!QByteArray("tExt").isLower());
+ QVERIFY(!QByteArray("teXt").isLower());
+ QVERIFY(!QByteArray("texT").isLower());
+ QVERIFY(!QByteArray("TExt").isLower());
+ QVERIFY(!QByteArray("teXT").isLower());
+ QVERIFY(!QByteArray("tEXt").isLower());
+ QVERIFY(!QByteArray("tExT").isLower());
+ QVERIFY(!QByteArray("TEXT").isLower());
+ QVERIFY(!QByteArray("@ABYZ[").isLower());
+ QVERIFY(!QByteArray("@abyz[").isLower());
+ QVERIFY(!QByteArray("`ABYZ{").isLower());
+ QVERIFY(!QByteArray("`abyz{").isLower());
+}
+
void tst_QByteArray::macTypes()
{
#ifndef Q_OS_MAC
diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
index 527e07593c..ce3bdc2d9d 100644
--- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
+++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
@@ -100,7 +100,7 @@ void tst_QCommandLineParser::testInvalidOptions()
QCoreApplication app(empty_argc, empty_argv);
QCommandLineParser parser;
QTest::ignoreMessage(QtWarningMsg, "QCommandLineOption: Option names cannot start with a '-'");
- parser.addOption(QCommandLineOption(QStringLiteral("-v"), QStringLiteral("Displays version information.")));
+ QVERIFY(!parser.addOption(QCommandLineOption(QStringLiteral("-v"), QStringLiteral("Displays version information."))));
}
void tst_QCommandLineParser::testPositionalArguments()
@@ -336,7 +336,7 @@ void tst_QCommandLineParser::testDoubleDash()
QCoreApplication app(empty_argc, empty_argv);
QCommandLineParser parser;
- parser.addOption(QCommandLineOption(QStringList() << "o" << "output", QStringLiteral("Output file"), QStringLiteral("filename")));
+ QVERIFY(parser.addOption(QCommandLineOption(QStringList() << "o" << "output", QStringLiteral("Output file"), QStringLiteral("filename"))));
parser.setSingleDashWordOptionMode(parsingMode);
QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "--output" << "foo"));
QCOMPARE(parser.value("output"), QString("foo"));
@@ -382,7 +382,7 @@ void tst_QCommandLineParser::testMissingOptionValue()
{
QCoreApplication app(empty_argc, empty_argv);
QCommandLineParser parser;
- parser.addOption(QCommandLineOption(QStringLiteral("option"), QStringLiteral("An option"), "value"));
+ QVERIFY(parser.addOption(QCommandLineOption(QStringLiteral("option"), QStringLiteral("An option"), "value")));
QVERIFY(!parser.parse(QStringList() << "argv0" << "--option")); // the user forgot to pass a value for --option
QCOMPARE(parser.value("option"), QString());
QCOMPARE(parser.errorText(), QString("Missing value after '--option'."));
@@ -400,8 +400,8 @@ void tst_QCommandLineParser::testStdinArgument()
QCoreApplication app(empty_argc, empty_argv);
QCommandLineParser parser;
parser.setSingleDashWordOptionMode(parsingMode);
- parser.addOption(QCommandLineOption(QStringList() << "i" << "input", QStringLiteral("Input file."), QStringLiteral("filename")));
- parser.addOption(QCommandLineOption("b", QStringLiteral("Boolean option.")));
+ QVERIFY(parser.addOption(QCommandLineOption(QStringList() << "i" << "input", QStringLiteral("Input file."), QStringLiteral("filename"))));
+ QVERIFY(parser.addOption(QCommandLineOption("b", QStringLiteral("Boolean option."))));
QVERIFY(parser.parse(QStringList() << "tst_qcommandlineparser" << "--input" << "-"));
QCOMPARE(parser.value("input"), QString("-"));
QCOMPARE(parser.positionalArguments(), QStringList());
@@ -471,14 +471,14 @@ void tst_QCommandLineParser::testSingleDashWordOptionModes()
QCoreApplication app(empty_argc, empty_argv);
QCommandLineParser parser;
parser.setSingleDashWordOptionMode(parsingMode);
- parser.addOption(QCommandLineOption("a", QStringLiteral("a option.")));
- parser.addOption(QCommandLineOption("b", QStringLiteral("b option.")));
- parser.addOption(QCommandLineOption(QStringList() << "c" << "abc", QStringLiteral("c option."), QStringLiteral("value")));
- parser.addOption(QCommandLineOption("nn", QStringLiteral("nn option.")));
+ QVERIFY(parser.addOption(QCommandLineOption("a", QStringLiteral("a option."))));
+ QVERIFY(parser.addOption(QCommandLineOption("b", QStringLiteral("b option."))));
+ QVERIFY(parser.addOption(QCommandLineOption(QStringList() << "c" << "abc", QStringLiteral("c option."), QStringLiteral("value"))));
+ QVERIFY(parser.addOption(QCommandLineOption("nn", QStringLiteral("nn option."))));
QCommandLineOption forceShort(QStringLiteral("I"), QStringLiteral("always short option"),
QStringLiteral("path"), QStringLiteral("default"));
forceShort.setFlags(QCommandLineOption::ShortOptionStyle);
- parser.addOption(forceShort);
+ QVERIFY(parser.addOption(forceShort));
QVERIFY(parser.parse(commandLine));
QCOMPARE(parser.optionNames(), expectedOptionNames);
for (int i = 0; i < expectedOptionValues.count(); ++i)
@@ -493,11 +493,11 @@ void tst_QCommandLineParser::testCpp11StyleInitialization()
QCommandLineParser parser;
// primarily check that this compiles:
- parser.addOptions({
+ QVERIFY(parser.addOptions({
{ "a", "The A option." },
{ { "v", "verbose" }, "The verbose option." },
{ { "i", "infile" }, "The input file.", "value" },
- });
+ }));
// but do a very basic functionality test, too:
QVERIFY(parser.parse({"tst_QCommandLineParser", "-a", "-vvv", "--infile=in.txt"}));
QCOMPARE(parser.optionNames(), (QStringList{"a", "v", "v", "v", "infile"}));
diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
index 17a0f3edd9..3eef7631c8 100644
--- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
+++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp
@@ -29,6 +29,7 @@
#include <QtCore/QCoreApplication>
#include <QtTest/QtTest>
+#include <QtCore/QMetaEnum>
Q_DECLARE_METATYPE(QCryptographicHash::Algorithm)
@@ -45,6 +46,7 @@ private slots:
void sha3();
void files_data();
void files();
+ void hashLength();
};
void tst_QCryptographicHash::repeated_result_data()
@@ -291,6 +293,15 @@ void tst_QCryptographicHash::files()
}
}
+void tst_QCryptographicHash::hashLength()
+{
+ auto metaEnum = QMetaEnum::fromType<QCryptographicHash::Algorithm>();
+ for (int i = 0, value = metaEnum.value(i); value != -1; value = metaEnum.value(++i)) {
+ auto algorithm = QCryptographicHash::Algorithm(value);
+ QByteArray output = QCryptographicHash::hash(QByteArrayLiteral("test"), algorithm);
+ QCOMPARE(QCryptographicHash::hashLength(algorithm), output.length());
+ }
+}
QTEST_MAIN(tst_QCryptographicHash)
#include "tst_qcryptographichash.moc"
diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
index 79309f960d..0196dd2d23 100644
--- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
+++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
@@ -423,7 +423,12 @@ void tst_QEasingCurve::setCustomType()
QCOMPARE(curve.valueForProgress(0.15), 0.1);
QCOMPARE(curve.valueForProgress(0.20), 0.2);
QCOMPARE(curve.valueForProgress(0.25), 0.2);
+ // QTBUG-69947, MinGW 7.3 returns 0.2
+#if defined(Q_CC_MINGW)
+#if !defined(__GNUC__) || __GNUC__ != 7 || __GNUC_MINOR__ < 3
QCOMPARE(curve.valueForProgress(0.30), 0.3);
+#endif
+#endif
QCOMPARE(curve.valueForProgress(0.35), 0.3);
QCOMPARE(curve.valueForProgress(0.999999), 0.9);
diff --git a/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp b/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
index f545ead1f1..e89e634841 100644
--- a/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
+++ b/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp
@@ -159,6 +159,8 @@ void tst_QExplicitlySharedDataPointer::data() const
{
QExplicitlySharedDataPointer<const MyClass> pointer;
QCOMPARE(pointer.data(), static_cast<const MyClass *>(0));
+ QVERIFY(pointer == nullptr);
+ QVERIFY(nullptr == pointer);
}
/* On const pointer. Must not mutate the pointer. */
@@ -168,6 +170,9 @@ void tst_QExplicitlySharedDataPointer::data() const
/* Check that this cast is possible. */
static_cast<const MyClass *>(pointer.data());
+
+ QVERIFY(! (pointer == nullptr));
+ QVERIFY(! (nullptr == pointer));
}
/* On mutatable pointer. Must not mutate the pointer. */
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index b7cb8a1bdc..261689d401 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -78,6 +78,7 @@ private slots:
#endif
void ctor();
+ void emptyCtor_data();
void emptyCtor();
void consistentC();
void matchingLocales();
@@ -118,8 +119,10 @@ private slots:
void monthName();
void standaloneMonthName();
- void defaultNumeringSystem();
+ void defaultNumberingSystem_data();
+ void defaultNumberingSystem();
+ void ampm_data();
void ampm();
void currency();
void quoteString();
@@ -127,6 +130,7 @@ private slots:
void weekendDays();
void listPatterns();
+ void measurementSystems_data();
void measurementSystems();
void QTBUG_26035_positivesign();
@@ -135,6 +139,7 @@ private slots:
void formattedDataSize_data();
void formattedDataSize();
+ void bcp47Name_data();
void bcp47Name();
void systemLocale_data();
@@ -145,6 +150,7 @@ private slots:
// QLocale::setDefault() *must* appear *after* all other tests !
void defaulted_ctor(); // This one must be the first of these.
void legacyNames();
+ void unixLocaleName_data();
void unixLocaleName();
void testNames_data();
void testNames();
@@ -152,6 +158,7 @@ private slots:
private:
QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
QString m_sysapp;
+ QStringList cleanEnv;
bool europeanTimeZone;
};
@@ -184,6 +191,14 @@ void tst_QLocale::initTestCase()
QVERIFY2(fi.exists() && fi.isExecutable(),
qPrintable(QDir::toNativeSeparators(m_sysapp)
+ QStringLiteral(" does not exist or is not executable.")));
+
+ // Get an environment free of any locale-related variables
+ cleanEnv.clear();
+ foreach (QString const& entry, QProcess::systemEnvironment()) {
+ if (entry.startsWith("LANG=") || entry.startsWith("LC_") || entry.startsWith("LANGUAGE="))
+ continue;
+ cleanEnv << entry;
+ }
#endif // QT_CONFIG(process)
}
@@ -214,32 +229,48 @@ void tst_QLocale::ctor()
}
// Exact matches
- TEST_CTOR(Chinese, SimplifiedHanScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, TraditionalHanScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
- TEST_CTOR(Chinese, TraditionalHanScript, HongKong, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong);
+ TEST_CTOR(Chinese, SimplifiedHanScript, China,
+ QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
+ TEST_CTOR(Chinese, TraditionalHanScript, Taiwan,
+ QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
+ TEST_CTOR(Chinese, TraditionalHanScript, HongKong,
+ QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong);
// Best match for AnyCountry
- TEST_CTOR(Chinese, SimplifiedHanScript, AnyCountry, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, TraditionalHanScript, AnyCountry, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
+ TEST_CTOR(Chinese, SimplifiedHanScript, AnyCountry,
+ QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
+ TEST_CTOR(Chinese, TraditionalHanScript, AnyCountry,
+ QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
// Best match for AnyScript (and change country to supported one, if necessary)
- TEST_CTOR(Chinese, AnyScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, AnyScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
- TEST_CTOR(Chinese, AnyScript, HongKong, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong);
- TEST_CTOR(Chinese, AnyScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
+ TEST_CTOR(Chinese, AnyScript, China,
+ QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
+ TEST_CTOR(Chinese, AnyScript, Taiwan,
+ QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
+ TEST_CTOR(Chinese, AnyScript, HongKong,
+ QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong);
+ TEST_CTOR(Chinese, AnyScript, UnitedStates,
+ QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
// Fully-specified not found; find best alternate country
- TEST_CTOR(Chinese, SimplifiedHanScript, Taiwan, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, SimplifiedHanScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, TraditionalHanScript, China, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
- TEST_CTOR(Chinese, TraditionalHanScript, UnitedStates, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
+ TEST_CTOR(Chinese, SimplifiedHanScript, Taiwan,
+ QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
+ TEST_CTOR(Chinese, SimplifiedHanScript, UnitedStates,
+ QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
+ TEST_CTOR(Chinese, TraditionalHanScript, China,
+ QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
+ TEST_CTOR(Chinese, TraditionalHanScript, UnitedStates,
+ QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
// Fully-specified not found; find best alternate script
- TEST_CTOR(Chinese, LatinScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
- TEST_CTOR(Chinese, LatinScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
+ TEST_CTOR(Chinese, LatinScript, China,
+ QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
+ TEST_CTOR(Chinese, LatinScript, Taiwan,
+ QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan);
// Fully-specified not found; find best alternate country and script
- TEST_CTOR(Chinese, LatinScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
+ TEST_CTOR(Chinese, LatinScript, UnitedStates,
+ QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China);
#undef TEST_CTOR
}
@@ -278,7 +309,8 @@ void tst_QLocale::defaulted_ctor()
TEST_CTOR(French, France, QLocale::French, QLocale::France)
TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry)
- TEST_CTOR(Spanish, LatinAmericaAndTheCaribbean, QLocale::Spanish, QLocale::LatinAmericaAndTheCaribbean)
+ TEST_CTOR(Spanish, LatinAmerica, QLocale::Spanish,
+ QLocale::LatinAmerica)
QLocale::setDefault(QLocale(QLocale::English, QLocale::France));
@@ -370,8 +402,9 @@ void tst_QLocale::defaulted_ctor()
QVERIFY2(l.language() == QLocale::exp_lang \
&& l.country() == QLocale::exp_country, \
QString("requested: \"" + QString(req_lc) + "\", got: " \
- + QLocale::languageToString(l.language()) \
- + QLatin1Char('/') + QLocale::countryToString(l.country())).toLatin1().constData()); \
+ + QLocale::languageToString(l.language()) \
+ + QLatin1Char('/') \
+ + QLocale::countryToString(l.country())).toLatin1().constData()); \
QCOMPARE(l, QLocale(QLocale::exp_lang, QLocale::exp_country)); \
QCOMPARE(qHash(l), qHash(QLocale(QLocale::exp_lang, QLocale::exp_country))); \
}
@@ -405,6 +438,8 @@ void tst_QLocale::defaulted_ctor()
TEST_CTOR("en_GB@bla", English, UnitedKingdom)
TEST_CTOR("en-GB", English, UnitedKingdom)
TEST_CTOR("en-GB@bla", English, UnitedKingdom)
+ TEST_CTOR("eo", Esperanto, World)
+ TEST_CTOR("yi", Yiddish, World)
QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal);
TEST_CTOR("no", Norwegian, Norway)
@@ -414,8 +449,8 @@ void tst_QLocale::defaulted_ctor()
TEST_CTOR("nb_NO", Norwegian, Norway)
TEST_CTOR("nn_NO", NorwegianNynorsk, Norway)
TEST_CTOR("es_ES", Spanish, Spain)
- TEST_CTOR("es_419", Spanish, LatinAmericaAndTheCaribbean)
- TEST_CTOR("es-419", Spanish, LatinAmericaAndTheCaribbean)
+ TEST_CTOR("es_419", Spanish, LatinAmerica)
+ TEST_CTOR("es-419", Spanish, LatinAmerica)
TEST_CTOR("fr_MA", French, Morocco)
// test default countries for languages
@@ -464,7 +499,8 @@ static inline bool runSysApp(const QString &binary,
process.start(binary);
process.closeWriteChannel();
if (!process.waitForStarted()) {
- *errorMessage = QString::fromLatin1("Cannot start '%1': %2").arg(binary, process.errorString());
+ *errorMessage = QLatin1String("Cannot start '") + binary
+ + QLatin1String("': ") + process.errorString();
return false;
}
if (!process.waitForFinished()) {
@@ -488,94 +524,121 @@ static inline bool runSysAppTest(const QString &binary,
return false;
if (output.isEmpty()) {
- *errorMessage = QString::fromLatin1("Empty output received for requested '%1' (expected '%2')").
- arg(requestedLocale, expectedOutput);
+ *errorMessage = QLatin1String("Empty output received for requested '") + requestedLocale
+ + QLatin1String("' (expected '") + expectedOutput + QLatin1String("')");
return false;
}
if (output != expectedOutput) {
- *errorMessage = QString::fromLatin1("Output mismatch for requested '%1': Expected '%2', got '%3'").
- arg(requestedLocale, expectedOutput, output);
+ *errorMessage = QLatin1String("Output mismatch for requested '") + requestedLocale
+ + QLatin1String("': Expected '") + expectedOutput + QLatin1String("', got '")
+ + output + QLatin1String("'");
return false;
}
return true;
}
#endif
-void tst_QLocale::emptyCtor()
+void tst_QLocale::emptyCtor_data()
{
#if !QT_CONFIG(process)
QSKIP("No qprocess support", SkipAll);
-#else
+#endif
#ifdef Q_OS_ANDROID
QSKIP("This test crashes on Android");
#endif
-#define TEST_CTOR(req_lc, exp_str) \
- { \
- /* Test constructor without arguments. Needs separate process */ \
- /* because of caching of the system locale. */ \
- QString errorMessage; \
- QVERIFY2(runSysAppTest(m_sysapp, env, QLatin1String(req_lc), QLatin1String(exp_str), &errorMessage), \
- qPrintable(errorMessage)); \
- }
- // Get an environment free of any locale-related variables
- QStringList env;
- foreach (QString const& entry, QProcess::systemEnvironment()) {
- if (entry.startsWith("LANG=") || entry.startsWith("LC_") || entry.startsWith("LANGUAGE="))
- continue;
- env << entry;
- }
+ QTest::addColumn<QString>("expected");
+
+#define ADD_CTOR_TEST(give, expect) QTest::newRow(give) << QStringLiteral(expect);
+
+ // For format and meaning, see:
+ // http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html
+ // Note that the accepted values for fields are implementation-dependent;
+ // the template is language[_territory][.codeset][@modifier]
+
+ // Vanilla:
+ ADD_CTOR_TEST("C", "C");
+
+ // Standard forms:
+ ADD_CTOR_TEST("en", "en_US");
+ ADD_CTOR_TEST("en_GB", "en_GB");
+ ADD_CTOR_TEST("de", "de_DE");
+ // Norsk has some quirks:
+ ADD_CTOR_TEST("no", "nb_NO");
+ ADD_CTOR_TEST("nb", "nb_NO");
+ ADD_CTOR_TEST("nn", "nn_NO");
+ ADD_CTOR_TEST("no_NO", "nb_NO");
+ ADD_CTOR_TEST("nb_NO", "nb_NO");
+ ADD_CTOR_TEST("nn_NO", "nn_NO");
+
+ // Not too fussy about case:
+ ADD_CTOR_TEST("DE", "de_DE");
+ ADD_CTOR_TEST("EN", "en_US");
+
+ // Invalid fields
+ ADD_CTOR_TEST("bla", "C");
+ ADD_CTOR_TEST("zz", "C");
+ ADD_CTOR_TEST("zz_zz", "C");
+ ADD_CTOR_TEST("zz...", "C");
+ ADD_CTOR_TEST("en.bla", "en_US");
+#if !(defined(Q_OS_DARWIN) && QT_HAS_FEATURE(address_sanitizer))
+ // See QTBUG-69875
+ ADD_CTOR_TEST("en@bla", "en_US");
+#endif
+ ADD_CTOR_TEST("en_blaaa", "en_US");
+ ADD_CTOR_TEST("en_zz", "en_US");
+ ADD_CTOR_TEST("en_GB.bla", "en_GB");
+ ADD_CTOR_TEST("en_GB@.bla", "en_GB");
+ ADD_CTOR_TEST("en_GB@bla", "en_GB");
+
+ // Empty optional fields, but with punctuators supplied
+ ADD_CTOR_TEST("en.", "en_US");
+#if !(defined(Q_OS_DARWIN) && QT_HAS_FEATURE(address_sanitizer))
+ // See QTBUG-69875
+ ADD_CTOR_TEST("en@", "en_US");
+#endif
+ ADD_CTOR_TEST("en.@", "en_US");
+ ADD_CTOR_TEST("en_", "en_US");
+ ADD_CTOR_TEST("en_.", "en_US");
+ ADD_CTOR_TEST("en_.@", "en_US");
+#undef ADD_CTOR_TEST
+#if QT_CONFIG(process) // for runSysApp
// Get default locale.
QString defaultLoc;
QString errorMessage;
- QVERIFY2(runSysApp(m_sysapp, env, &defaultLoc, &errorMessage),
- qPrintable(errorMessage));
-
- TEST_CTOR("C", "C")
- TEST_CTOR("bla", "C")
- TEST_CTOR("zz", "C")
- TEST_CTOR("zz_zz", "C")
- TEST_CTOR("zz...", "C")
- TEST_CTOR("en", "en_US")
- TEST_CTOR("en", "en_US")
- TEST_CTOR("en.", "en_US")
- TEST_CTOR("en@", "en_US")
- TEST_CTOR("en.@", "en_US")
- TEST_CTOR("en_", "en_US")
- TEST_CTOR("en_.", "en_US")
- TEST_CTOR("en_.@", "en_US")
- TEST_CTOR("en.bla", "en_US")
- TEST_CTOR("en@bla", "en_US")
- TEST_CTOR("en_blaaa", "en_US")
- TEST_CTOR("en_zz", "en_US")
- TEST_CTOR("en_GB", "en_GB")
- TEST_CTOR("en_GB.bla", "en_GB")
- TEST_CTOR("en_GB@.bla", "en_GB")
- TEST_CTOR("en_GB@bla", "en_GB")
- TEST_CTOR("de", "de_DE")
-
- QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal);
- TEST_CTOR("no", "nb_NO")
- TEST_CTOR("nb", "nb_NO")
- TEST_CTOR("nn", "nn_NO")
- TEST_CTOR("no_NO", "nb_NO")
- TEST_CTOR("nb_NO", "nb_NO")
- TEST_CTOR("nn_NO", "nn_NO")
+ if (runSysApp(m_sysapp, cleanEnv, &defaultLoc, &errorMessage)) {
+#define ADD_CTOR_TEST(give) QTest::newRow(give) << defaultLoc;
+ ADD_CTOR_TEST("en/");
+ ADD_CTOR_TEST("asdfghj");
+ ADD_CTOR_TEST("123456");
+#undef ADD_CTOR_TEST
+ } else {
+ qDebug() << "Skipping tests based on default locale" << qPrintable(errorMessage);
+ }
+#endif // process
+}
- TEST_CTOR("DE", "de_DE");
- TEST_CTOR("EN", "en_US");
+void tst_QLocale::emptyCtor()
+{
+#if QT_CONFIG(process) // for runSysAppTest
+ QLatin1String request(QTest::currentDataTag());
+ QFETCH(QString, expected);
- TEST_CTOR("en/", defaultLoc.toLatin1())
- TEST_CTOR("asdfghj", defaultLoc.toLatin1());
- TEST_CTOR("123456", defaultLoc.toLatin1());
+ // Test constructor without arguments (see syslocaleapp/syslocaleapp.cpp)
+ // Needs separate process because of caching of the system locale.
+ QString errorMessage;
+ QVERIFY2(runSysAppTest(m_sysapp, cleanEnv, request, expected, &errorMessage),
+ qPrintable(errorMessage));
-#undef TEST_CTOR
-#endif
+#else
+ // This won't be called, as _data() skipped out early.
+#endif // process
}
void tst_QLocale::legacyNames()
{
+ QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal);
QLocale::setDefault(QLocale(QLocale::C));
#define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \
@@ -598,8 +661,9 @@ void tst_QLocale::legacyNames()
QVERIFY2(l.language() == QLocale::exp_lang \
&& l.country() == QLocale::exp_country, \
QString("requested: \"" + QString(req_lc) + "\", got: " \
- + QLocale::languageToString(l.language()) \
- + QLatin1Char('/') + QLocale::countryToString(l.country())).toLatin1().constData()); \
+ + QLocale::languageToString(l.language()) \
+ + QLatin1Char('/') \
+ + QLocale::countryToString(l.country())).toLatin1().constData()); \
}
TEST_CTOR("mo_MD", Romanian, Moldova)
@@ -649,22 +713,32 @@ void tst_QLocale::matchingLocales()
QVERIFY(locales.contains(ru_RU));
}
+void tst_QLocale::unixLocaleName_data()
+{
+ QTest::addColumn<QLocale::Language>("lang");
+ QTest::addColumn<QLocale::Country>("land");
+ QTest::addColumn<QString>("expect");
+
+#define ADDROW(nom, lang, land, name) \
+ QTest::newRow(nom) << QLocale::lang << QLocale::land << QStringLiteral(name)
+
+ ADDROW("C_any", C, AnyCountry, "C");
+ ADDROW("en_any", English, AnyCountry, "en_US");
+ ADDROW("en_GB", English, UnitedKingdom, "en_GB");
+ ADDROW("ay_GB", Aymara, UnitedKingdom, "C");
+#undef ADDROW
+}
+
void tst_QLocale::unixLocaleName()
{
-#define TEST_NAME(req_lang, req_country, exp_name) \
- { \
- QLocale l(QLocale::req_lang, QLocale::req_country); \
- QCOMPARE(l.name(), QString(exp_name)); \
- }
+ QFETCH(QLocale::Language, lang);
+ QFETCH(QLocale::Country, land);
+ QFETCH(QString, expect);
QLocale::setDefault(QLocale(QLocale::C));
- TEST_NAME(C, AnyCountry, "C")
- TEST_NAME(English, AnyCountry, "en_US")
- TEST_NAME(English, UnitedKingdom, "en_GB")
- TEST_NAME(Aymara, UnitedKingdom, "C")
-
-#undef TEST_NAME
+ QLocale locale(lang, land);
+ QCOMPARE(locale.name(), expect);
}
void tst_QLocale::stringToDouble_data()
@@ -1282,7 +1356,8 @@ void tst_QLocale::formatDate_data()
QTest::newRow("26") << QDate(1974, 12, 1) << "\"yy\"" << "\"74\"";
QTest::newRow("27") << QDate(1974, 12, 1) << "'\"yy\"'" << "\"yy\"";
QTest::newRow("28") << QDate() << "'\"yy\"'" << "";
- QTest::newRow("29") << QDate(1974, 12, 1) << "hh:mm:ss.zzz ap d'd'dd/M/yy" << "hh:mm:ss.zzz ap 1d01/12/74";
+ QTest::newRow("29")
+ << QDate(1974, 12, 1) << "hh:mm:ss.zzz ap d'd'dd/M/yy" << "hh:mm:ss.zzz ap 1d01/12/74";
QTest::newRow("dd MMMM yyyy") << QDate(1, 1, 1) << "dd MMMM yyyy" << "01 January 0001";
}
@@ -1298,7 +1373,6 @@ void tst_QLocale::formatDate()
QCOMPARE(l.toString(date, QStringView(format)), result);
}
-
void tst_QLocale::formatTime_data()
{
QTest::addColumn<QTime>("time");
@@ -1577,7 +1651,8 @@ void tst_QLocale::formatTimeZone()
QDateTime::currentDateTime().timeZoneAbbreviation());
// Time on its own will always be current local time zone
- QCOMPARE(enUS.toString(QTime(1, 2, 3), "t"), QDateTime::currentDateTime().timeZoneAbbreviation());
+ QCOMPARE(enUS.toString(QTime(1, 2, 3), "t"),
+ QDateTime::currentDateTime().timeZoneAbbreviation());
}
void tst_QLocale::toDateTime_data()
@@ -1614,7 +1689,8 @@ void tst_QLocale::toDateTime_data()
QTest::newRow("bad-hour-C") << "C" << QDateTime() << "d-MMM-yy hh:m" << "4-Jun-11 1:2";
QTest::newRow("bad-min-C") << "C" << QDateTime() << "d-MMM-yy h:mm" << "4-Jun-11 1:2";
QTest::newRow("bad-sec-C") << "C" << QDateTime() << "d-MMM-yy h:m:ss" << "4-Jun-11 1:2:3";
- QTest::newRow("bad-milli-C") << "C" << QDateTime() << "d-MMM-yy h:m:s.zzz" << "4-Jun-11 1:2:3.4";
+ QTest::newRow("bad-milli-C")
+ << "C" << QDateTime() << "d-MMM-yy h:m:s.zzz" << "4-Jun-11 1:2:3.4";
QTest::newRow("ok-C") << "C" << QDateTime(QDate(1911, 6, 4), QTime(1, 2, 3, 400))
<< "d-MMM-yy h:m:s.z" << "4-Jun-11 1:2:3.4";
@@ -1637,11 +1713,13 @@ void tst_QLocale::toDateTime_data()
QTest::newRow("12no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0))
<< "d'd'dd/M/yyh" << "1d01/12/7415";
- QTest::newRow("RFC-1123") << "C" << QDateTime(QDate(2007, 11, 1), QTime(18, 8, 30))
- << "ddd, dd MMM yyyy hh:mm:ss 'GMT'" << "Thu, 01 Nov 2007 18:08:30 GMT";
+ QTest::newRow("RFC-1123")
+ << "C" << QDateTime(QDate(2007, 11, 1), QTime(18, 8, 30))
+ << "ddd, dd MMM yyyy hh:mm:ss 'GMT'" << "Thu, 01 Nov 2007 18:08:30 GMT";
- QTest::newRow("longFormat") << "en_US" << QDateTime(QDate(2009, 1, 5), QTime(11, 48, 32))
- << "dddd, MMMM d, yyyy h:mm:ss AP " << "Monday, January 5, 2009 11:48:32 AM ";
+ QTest::newRow("longFormat")
+ << "en_US" << QDateTime(QDate(2009, 1, 5), QTime(11, 48, 32))
+ << "dddd, MMMM d, yyyy h:mm:ss AP " << "Monday, January 5, 2009 11:48:32 AM ";
}
void tst_QLocale::toDateTime()
@@ -1716,36 +1794,40 @@ void tst_QLocale::macDefaultLocale()
// To run this test make sure "Curreny" is US Dollar in System Preferences->Language & Region->Advanced.
if (locale.currencySymbol() == QString("$")) {
- QCOMPARE(locale.toCurrencyString(qulonglong(1234)), systemLocaleFormatNumber(QString("$1,234.00")));
- QCOMPARE(locale.toCurrencyString(double(1234.56)), systemLocaleFormatNumber(QString("$1,234.56")));
+ QCOMPARE(locale.toCurrencyString(qulonglong(1234)),
+ systemLocaleFormatNumber(QString("$1,234.00")));
+ QCOMPARE(locale.toCurrencyString(double(1234.56)),
+ systemLocaleFormatNumber(QString("$1,234.56")));
}
// Depending on the configured time zone, the time string might not
// contain a GMT specifier. (Sometimes it just names the zone, like "CEST")
- if (timeString.contains(QString("GMT"))) {
- QString expectedGMTSpecifierBase("GMT");
- if (diff >= 0)
- expectedGMTSpecifierBase.append(QLatin1Char('+'));
- else
- expectedGMTSpecifierBase.append(QLatin1Char('-'));
-
- QString expectedGMTSpecifier = expectedGMTSpecifierBase + QString("%1").arg(qAbs(diff));
- QString expectedGMTSpecifierZeroExtended = expectedGMTSpecifierBase + QString("0%1").arg(qAbs(diff));
-
- QVERIFY2(timeString.contains(expectedGMTSpecifier)
- || timeString.contains(expectedGMTSpecifierZeroExtended),
- qPrintable(QString("timeString `%1', expectedGMTSpecifier `%2' or `%3'")
- .arg(timeString)
- .arg(expectedGMTSpecifier)
- .arg(expectedGMTSpecifierZeroExtended)
- ));
+ QLatin1String gmt("GMT");
+ if (timeString.contains(gmt) && diff) {
+ QLatin1Char sign(diff < 0 ? '-' : '+');
+ QString number(QString::number(qAbs(diff)));
+ const QString expect = gmt + sign + number;
+
+ if (diff < 10) {
+ const QString zeroed = gmt + sign + QLatin1Char('0') + number;
+
+ QVERIFY2(timeString.contains(expect) || timeString.contains(zeroed),
+ qPrintable(QString("timeString `%1', expected GMT specifier `%2' or `%3'")
+ .arg(timeString).arg(expect).arg(zeroed)));
+ } else {
+ QVERIFY2(timeString.contains(expect),
+ qPrintable(QString("timeString `%1', expected GMT specifier `%2'")
+ .arg(timeString).arg(expect)));
+ }
}
QCOMPARE(locale.dayName(1), QString("Monday"));
QCOMPARE(locale.dayName(7), QString("Sunday"));
QCOMPARE(locale.monthName(1), QString("January"));
QCOMPARE(locale.monthName(12), QString("December"));
- QCOMPARE(locale.quoteString("string"), QString::fromUtf8("\xe2\x80\x9c" "string" "\xe2\x80\x9d"));
- QCOMPARE(locale.quoteString("string", QLocale::AlternateQuotation), QString::fromUtf8("\xe2\x80\x98" "string" "\xe2\x80\x99"));
+ QCOMPARE(locale.quoteString("string"),
+ QString::fromUtf8("\xe2\x80\x9c" "string" "\xe2\x80\x9d"));
+ QCOMPARE(locale.quoteString("string", QLocale::AlternateQuotation),
+ QString::fromUtf8("\xe2\x80\x98" "string" "\xe2\x80\x99"));
QList<Qt::DayOfWeek> days;
days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday;
@@ -1787,12 +1869,6 @@ static void setWinLocaleInfo(LCTYPE type, const QString &value)
# define LOCALE_SSHORTTIME 0x00000079
#endif
-static inline LCTYPE shortTimeType()
-{
- return (QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7 ?
- LOCALE_SSHORTTIME : LOCALE_STIMEFORMAT;
-}
-
class RestoreLocaleHelper {
public:
RestoreLocaleHelper() {
@@ -1800,7 +1876,7 @@ public:
m_thousand = getWinLocaleInfo(LOCALE_STHOUSAND);
m_sdate = getWinLocaleInfo(LOCALE_SSHORTDATE);
m_ldate = getWinLocaleInfo(LOCALE_SLONGDATE);
- m_time = getWinLocaleInfo(shortTimeType());
+ m_time = getWinLocaleInfo(LOCALE_SSHORTTIME);
}
~RestoreLocaleHelper() {
@@ -1809,7 +1885,7 @@ public:
setWinLocaleInfo(LOCALE_STHOUSAND, m_thousand);
setWinLocaleInfo(LOCALE_SSHORTDATE, m_sdate);
setWinLocaleInfo(LOCALE_SLONGDATE, m_ldate);
- setWinLocaleInfo(shortTimeType(), m_time);
+ setWinLocaleInfo(LOCALE_SSHORTTIME, m_time);
// make sure QLocale::system() gets updated
QLocalePrivate::updateSystemPrivate();
@@ -1819,14 +1895,9 @@ public:
};
-#endif // Q_OS_WIN
-
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-
void tst_QLocale::windowsDefaultLocale()
{
RestoreLocaleHelper systemLocale;
- const bool win7OrLater = (QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) && QSysInfo::windowsVersion();
// set weird system defaults and make sure we're using them
setWinLocaleInfo(LOCALE_SDECIMAL, QLatin1String("@"));
setWinLocaleInfo(LOCALE_STHOUSAND, QLatin1String("?"));
@@ -1835,7 +1906,7 @@ void tst_QLocale::windowsDefaultLocale()
const QString longDateFormat = QStringLiteral("d@M@yyyy");
setWinLocaleInfo(LOCALE_SLONGDATE, longDateFormat);
const QString shortTimeFormat = QStringLiteral("h^m^s");
- setWinLocaleInfo(shortTimeType(), shortTimeFormat);
+ setWinLocaleInfo(LOCALE_SSHORTTIME, shortTimeFormat);
// make sure QLocale::system() gets updated
QLocalePrivate::updateSystemPrivate();
@@ -1847,21 +1918,24 @@ void tst_QLocale::windowsDefaultLocale()
QCOMPARE(locale.dateFormat(QLocale::ShortFormat), shortDateFormat);
QCOMPARE(locale.dateFormat(QLocale::LongFormat), longDateFormat);
QCOMPARE(locale.timeFormat(QLocale::ShortFormat), shortTimeFormat);
- QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat), shortDateFormat + QLatin1Char(' ') + shortTimeFormat);
- const QString expectedLongDateTimeFormat = longDateFormat + QLatin1Char(' ')
- + (win7OrLater ? QStringLiteral("h:mm:ss AP") : shortTimeFormat);
+ QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat),
+ shortDateFormat + QLatin1Char(' ') + shortTimeFormat);
+ const QString expectedLongDateTimeFormat
+ = longDateFormat + QLatin1Char(' ') + QStringLiteral("h:mm:ss AP");
QCOMPARE(locale.dateTimeFormat(QLocale::LongFormat), expectedLongDateTimeFormat);
// make sure we are using the system to parse them
QCOMPARE(locale.toString(1234.56), QString("1?234@56"));
QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat), QString("1*12*1974"));
- QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::NarrowFormat), locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat));
+ QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::NarrowFormat),
+ locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat));
QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::LongFormat), QString("1@12@1974"));
const QString expectedFormattedShortTimeSeconds = QStringLiteral("1^2^3");
- const QString expectedFormattedShortTime = win7OrLater ? QStringLiteral("1^2") : expectedFormattedShortTimeSeconds;
+ const QString expectedFormattedShortTime = QStringLiteral("1^2");
QCOMPARE(locale.toString(QTime(1,2,3), QLocale::ShortFormat), expectedFormattedShortTime);
- QCOMPARE(locale.toString(QTime(1,2,3), QLocale::NarrowFormat), locale.toString(QTime(1,2,3), QLocale::ShortFormat));
- const QString expectedFormattedLongTime = win7OrLater ? QStringLiteral("1:02:03 AM") : expectedFormattedShortTimeSeconds;
+ QCOMPARE(locale.toString(QTime(1,2,3), QLocale::NarrowFormat),
+ locale.toString(QTime(1,2,3), QLocale::ShortFormat));
+ const QString expectedFormattedLongTime = QStringLiteral("1:02:03 AM");
QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime);
QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat),
QStringLiteral("1*12*1974 ") + expectedFormattedShortTime);
@@ -1871,7 +1945,7 @@ void tst_QLocale::windowsDefaultLocale()
QStringLiteral("1@12@1974 ") + expectedFormattedLongTime);
QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime);
}
-#endif // #ifdef Q_OS_WIN
+#endif // Q_OS_WIN but !Q_OS_WINRT
void tst_QLocale::numberOptions()
{
@@ -2056,17 +2130,23 @@ void tst_QLocale::dayName_data()
QTest::addColumn<int>("day");
QTest::addColumn<QLocale::FormatType>("format");
- QTest::newRow("no_NO") << QString("no_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
- QTest::newRow("nb_NO") << QString("nb_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
- QTest::newRow("nn_NO") << QString("nn_NO") << QString("tysdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("no_NO") << QString("no_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("nb_NO") << QString("nb_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("nn_NO") << QString("nn_NO") << QString("tysdag") << 2 << QLocale::LongFormat;
- QTest::newRow("C long") << QString("C") << QString("Sunday") << 7 << QLocale::LongFormat;
- QTest::newRow("C short") << QString("C") << QString("Sun") << 7 << QLocale::ShortFormat;
- QTest::newRow("C narrow") << QString("C") << QString("7") << 7 << QLocale::NarrowFormat;
+ QTest::newRow("C long") << QString("C") << QString("Sunday") << 7 << QLocale::LongFormat;
+ QTest::newRow("C short") << QString("C") << QString("Sun") << 7 << QLocale::ShortFormat;
+ QTest::newRow("C narrow") << QString("C") << QString("7") << 7 << QLocale::NarrowFormat;
- QTest::newRow("ru_RU long") << QString("ru_RU") << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320\265\321\201\320\265\320\275\321\214\320\265") << 7 << QLocale::LongFormat;
- QTest::newRow("ru_RU short") << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
- QTest::newRow("ru_RU narrow") << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::NarrowFormat;
+ QTest::newRow("ru_RU long")
+ << QString("ru_RU")
+ << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320"
+ "\265\321\201\320\265\320\275\321\214\320\265")
+ << 7 << QLocale::LongFormat;
+ QTest::newRow("ru_RU short")
+ << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
+ QTest::newRow("ru_RU narrow")
+ << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::NarrowFormat;
}
void tst_QLocale::dayName()
@@ -2096,24 +2176,30 @@ void tst_QLocale::standaloneDayName_data()
QTest::addColumn<int>("day");
QTest::addColumn<QLocale::FormatType>("format");
- QTest::newRow("no_NO") << QString("no_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
- QTest::newRow("nb_NO") << QString("nb_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
- QTest::newRow("nn_NO") << QString("nn_NO") << QString("tysdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("no_NO") << QString("no_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("nb_NO") << QString("nb_NO") << QString("tirsdag") << 2 << QLocale::LongFormat;
+ QTest::newRow("nn_NO") << QString("nn_NO") << QString("tysdag") << 2 << QLocale::LongFormat;
- QTest::newRow("C invalid: 0 long") << QString("C") << QString() << 0 << QLocale::LongFormat;
- QTest::newRow("C invalid: 0 short") << QString("C") << QString() << 0 << QLocale::ShortFormat;
- QTest::newRow("C invalid: 0 narrow") << QString("C") << QString() << 0 << QLocale::NarrowFormat;
- QTest::newRow("C invalid: 8 long") << QString("C") << QString() << 8 << QLocale::LongFormat;
- QTest::newRow("C invalid: 8 short") << QString("C") << QString() << 8 << QLocale::ShortFormat;
- QTest::newRow("C invalid: 8 narrow") << QString("C") << QString() << 8 << QLocale::NarrowFormat;
+ QTest::newRow("C invalid: 0 long") << QString("C") << QString() << 0 << QLocale::LongFormat;
+ QTest::newRow("C invalid: 0 short") << QString("C") << QString() << 0 << QLocale::ShortFormat;
+ QTest::newRow("C invalid: 0 narrow") << QString("C") << QString() << 0 << QLocale::NarrowFormat;
+ QTest::newRow("C invalid: 8 long") << QString("C") << QString() << 8 << QLocale::LongFormat;
+ QTest::newRow("C invalid: 8 short") << QString("C") << QString() << 8 << QLocale::ShortFormat;
+ QTest::newRow("C invalid: 8 narrow") << QString("C") << QString() << 8 << QLocale::NarrowFormat;
- QTest::newRow("C long") << QString("C") << QString("Sunday") << 7 << QLocale::LongFormat;
- QTest::newRow("C short") << QString("C") << QString("Sun") << 7 << QLocale::ShortFormat;
- QTest::newRow("C narrow") << QString("C") << QString("S") << 7 << QLocale::NarrowFormat;
+ QTest::newRow("C long") << QString("C") << QString("Sunday") << 7 << QLocale::LongFormat;
+ QTest::newRow("C short") << QString("C") << QString("Sun") << 7 << QLocale::ShortFormat;
+ QTest::newRow("C narrow") << QString("C") << QString("S") << 7 << QLocale::NarrowFormat;
- QTest::newRow("ru_RU long") << QString("ru_RU") << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320\265\321\201\320\265\320\275\321\214\320\265") << 7 << QLocale::LongFormat;
- QTest::newRow("ru_RU short") << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
- QTest::newRow("ru_RU narrow") << QString("ru_RU") << QString::fromUtf8("\320\222") << 7 << QLocale::NarrowFormat;
+ QTest::newRow("ru_RU long")
+ << QString("ru_RU")
+ << QString::fromUtf8("\320\262\320\276\321\201\320\272\321\200\320"
+ "\265\321\201\320\265\320\275\321\214\320\265")
+ << 7 << QLocale::LongFormat;
+ QTest::newRow("ru_RU short")
+ << QString("ru_RU") << QString::fromUtf8("\320\262\321\201") << 7 << QLocale::ShortFormat;
+ QTest::newRow("ru_RU narrow")
+ << QString("ru_RU") << QString::fromUtf8("\320\222") << 7 << QLocale::NarrowFormat;
}
void tst_QLocale::standaloneDayName()
@@ -2129,9 +2215,7 @@ void tst_QLocale::standaloneDayName()
void tst_QLocale::underflowOverflow()
{
- QString
-a(QLatin1String("0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e10"));
-
+ QString a(QLatin1String("0.") + QString(546, QLatin1Char('0')) + QLatin1String("1e10"));
bool ok = false;
double d = a.toDouble(&ok);
QVERIFY(!ok);
@@ -2160,75 +2244,56 @@ a(QLatin1String("0.0000000000000000000000000000000000000000000000000000000000000
QVERIFY(!ok);
}
-void tst_QLocale::defaultNumeringSystem()
+void tst_QLocale::defaultNumberingSystem_data()
{
- QLocale sk("sk_SK");
- QCOMPARE(sk.toString(123), QLatin1String("123"));
+ QTest::addColumn<QString>("expect");
- QLocale ta("ta_IN");
- QCOMPARE(ta.toString(123), QLatin1String("123"));
-
- QLocale te("te_IN");
- QCOMPARE(te.toString(123), QLatin1String("123"));
-
- QLocale hi("hi_IN");
- QCOMPARE(hi.toString(123), QLatin1String("123"));
-
- QLocale gu("gu_IN");
- QCOMPARE(gu.toString(123), QLatin1String("123"));
-
- QLocale kn("kn_IN");
- QCOMPARE(kn.toString(123), QLatin1String("123"));
-
- QLocale pa("pa_IN");
- QCOMPARE(pa.toString(123), QLatin1String("123"));
-
- QLocale ne("ne_IN");
- QCOMPARE(ne.toString(123), QString::fromUtf8("१२३"));
+ QTest::newRow("sk_SK") << QStringLiteral("123");
+ QTest::newRow("ta_IN") << QStringLiteral("123");
+ QTest::newRow("te_IN") << QStringLiteral("123");
+ QTest::newRow("hi_IN") << QStringLiteral("123");
+ QTest::newRow("gu_IN") << QStringLiteral("123");
+ QTest::newRow("kn_IN") << QStringLiteral("123");
+ QTest::newRow("pa_IN") << QStringLiteral("123");
+ QTest::newRow("ne_IN") << QString::fromUtf8("१२३");
+ QTest::newRow("mr_IN") << QString::fromUtf8("१२३");
+ QTest::newRow("ml_IN") << QStringLiteral("123");
+ QTest::newRow("kok_IN") << QStringLiteral("123");
+}
- QLocale mr("mr_IN");
- QCOMPARE(mr.toString(123), QString::fromUtf8("१२३"));
+void tst_QLocale::defaultNumberingSystem()
+{
+ QFETCH(QString, expect);
+ QLatin1String name(QTest::currentDataTag());
+ QLocale locale(name);
+ QCOMPARE(locale.toString(123), expect);
+}
- QLocale ml("ml_IN");
- QCOMPARE(ml.toString(123), QLatin1String("123"));
+void tst_QLocale::ampm_data()
+{
+ QTest::addColumn<QString>("morn");
+ QTest::addColumn<QString>("even");
- QLocale kok("kok_IN");
- QCOMPARE(kok.toString(123), QLatin1String("123"));
+ QTest::newRow("C") << QStringLiteral("AM") << QStringLiteral("PM");
+ QTest::newRow("de_DE") << QStringLiteral("AM") << QStringLiteral("PM");
+ QTest::newRow("sv_SE") << QStringLiteral("fm") << QStringLiteral("em");
+ QTest::newRow("nl_NL") << QStringLiteral("a.m.") << QStringLiteral("p.m.");
+ QTest::newRow("uk_UA") << QString::fromUtf8("\320\264\320\277")
+ << QString::fromUtf8("\320\277\320\277");
+ QTest::newRow("tr_TR") << QString::fromUtf8("\303\226\303\226")
+ << QString::fromUtf8("\303\226\123");
+ QTest::newRow("id_ID") << QStringLiteral("AM") << QStringLiteral("PM");
+ QTest::newRow("ta_LK") << QString::fromUtf8("à®®à¯à®±à¯à®ªà®•à®²à¯") << QString::fromUtf8("பிறà¯à®ªà®•à®²à¯");
}
void tst_QLocale::ampm()
{
- QLocale c(QLocale::C);
- QCOMPARE(c.amText(), QLatin1String("AM"));
- QCOMPARE(c.pmText(), QLatin1String("PM"));
-
- QLocale de("de_DE");
- QCOMPARE(de.amText(), QLatin1String("vorm."));
- QCOMPARE(de.pmText(), QLatin1String("nachm."));
-
- QLocale sv("sv_SE");
- QCOMPARE(sv.amText(), QLatin1String("fm"));
- QCOMPARE(sv.pmText(), QLatin1String("em"));
-
- QLocale nn("nl_NL");
- QCOMPARE(nn.amText(), QLatin1String("a.m."));
- QCOMPARE(nn.pmText(), QLatin1String("p.m."));
-
- QLocale ua("uk_UA");
- QCOMPARE(ua.amText(), QString::fromUtf8("\320\264\320\277"));
- QCOMPARE(ua.pmText(), QString::fromUtf8("\320\277\320\277"));
-
- QLocale tr("tr_TR");
- QCOMPARE(tr.amText(), QString::fromUtf8("\303\226\303\226"));
- QCOMPARE(tr.pmText(), QString::fromUtf8("\303\226\123"));
-
- QLocale id("id_ID");
- QCOMPARE(id.amText(), QLatin1String("AM"));
- QCOMPARE(id.pmText(), QLatin1String("PM"));
-
- QLocale ta("ta_LK");
- QCOMPARE(ta.amText(), QString::fromUtf8("à®®à¯à®±à¯à®ªà®•à®²à¯"));
- QCOMPARE(ta.pmText(), QString::fromUtf8("பிறà¯à®ªà®•à®²à¯"));
+ QFETCH(QString, morn);
+ QFETCH(QString, even);
+ QLatin1String name(QTest::currentDataTag());
+ QLocale locale(name == QLatin1String("C") ? QLocale(QLocale::C) : QLocale(name));
+ QCOMPARE(locale.amText(), morn);
+ QCOMPARE(locale.pmText(), even);
}
void tst_QLocale::dateFormat()
@@ -2310,8 +2375,10 @@ void tst_QLocale::monthName()
QCOMPARE(de.monthName(12, QLocale::NarrowFormat), QLatin1String("D"));
QLocale ru("ru_RU");
- QCOMPARE(ru.monthName(1, QLocale::LongFormat), QString::fromUtf8("\321\217\320\275\320\262\320\260\321\200\321\217"));
- QCOMPARE(ru.monthName(1, QLocale::ShortFormat), QString::fromUtf8("\321\217\320\275\320\262\56"));
+ QCOMPARE(ru.monthName(1, QLocale::LongFormat),
+ QString::fromUtf8("\321\217\320\275\320\262\320\260\321\200\321\217"));
+ QCOMPARE(ru.monthName(1, QLocale::ShortFormat),
+ QString::fromUtf8("\321\217\320\275\320\262\56"));
QCOMPARE(ru.monthName(1, QLocale::NarrowFormat), QString::fromUtf8("\320\257"));
QLocale ir("ga_IE");
@@ -2340,13 +2407,16 @@ void tst_QLocale::standaloneMonthName()
// For de_DE locale Unicode CLDR database doesn't contain standalone long months
// so just checking if the return value is the same as in monthName().
QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat), QLatin1String("Dezember"));
- QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat), de.monthName(12, QLocale::LongFormat));
+ QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat),
+ de.monthName(12, QLocale::LongFormat));
QCOMPARE(de.standaloneMonthName(12, QLocale::ShortFormat), QLatin1String("Dez"));
QCOMPARE(de.standaloneMonthName(12, QLocale::NarrowFormat), QLatin1String("D"));
QLocale ru("ru_RU");
- QCOMPARE(ru.standaloneMonthName(1, QLocale::LongFormat), QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8c"));
- QCOMPARE(ru.standaloneMonthName(1, QLocale::ShortFormat), QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2."));
+ QCOMPARE(ru.standaloneMonthName(1, QLocale::LongFormat),
+ QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8c"));
+ QCOMPARE(ru.standaloneMonthName(1, QLocale::ShortFormat),
+ QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2."));
QCOMPARE(ru.standaloneMonthName(1, QLocale::NarrowFormat), QString::fromUtf8("\xd0\xaf"));
}
@@ -2371,19 +2441,30 @@ void tst_QLocale::currency()
QCOMPARE(en_US.toCurrencyString(double(-1234.56), NULL, 4), QString("$-1,234.5600"));
const QLocale ru_RU("ru_RU");
- QCOMPARE(ru_RU.toCurrencyString(qulonglong(1234)), QString::fromUtf8("1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd"));
- QCOMPARE(ru_RU.toCurrencyString(qlonglong(-1234)), QString::fromUtf8("-1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd"));
- QCOMPARE(ru_RU.toCurrencyString(double(1234.56)), QString::fromUtf8("1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd"));
- QCOMPARE(ru_RU.toCurrencyString(double(-1234.56)), QString::fromUtf8("-1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd"));
+ QCOMPARE(ru_RU.toCurrencyString(qulonglong(1234)),
+ QString::fromUtf8("1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd"));
+ QCOMPARE(ru_RU.toCurrencyString(qlonglong(-1234)),
+ QString::fromUtf8("-1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd"));
+ QCOMPARE(ru_RU.toCurrencyString(double(1234.56)),
+ QString::fromUtf8("1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd"));
+ QCOMPARE(ru_RU.toCurrencyString(double(-1234.56)),
+ QString::fromUtf8("-1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd"));
const QLocale de_DE("de_DE");
- QCOMPARE(de_DE.toCurrencyString(qulonglong(1234)), QString::fromUtf8("1.234\xc2\xa0\xe2\x82\xac"));
- QCOMPARE(de_DE.toCurrencyString(qulonglong(1234), QLatin1String("BAZ")), QString::fromUtf8("1.234\xc2\xa0" "BAZ"));
- QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234)), QString::fromUtf8("-1.234\xc2\xa0\xe2\x82\xac"));
- QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234), QLatin1String("BAZ")), QString::fromUtf8("-1.234\xc2\xa0" "BAZ"));
- QCOMPARE(de_DE.toCurrencyString(double(1234.56)), QString::fromUtf8("1.234,56\xc2\xa0\xe2\x82\xac"));
- QCOMPARE(de_DE.toCurrencyString(double(-1234.56)), QString::fromUtf8("-1.234,56\xc2\xa0\xe2\x82\xac"));
- QCOMPARE(de_DE.toCurrencyString(double(-1234.56), QLatin1String("BAZ")), QString::fromUtf8("-1.234,56\xc2\xa0" "BAZ"));
+ QCOMPARE(de_DE.toCurrencyString(qulonglong(1234)),
+ QString::fromUtf8("1.234\xc2\xa0\xe2\x82\xac"));
+ QCOMPARE(de_DE.toCurrencyString(qulonglong(1234), QLatin1String("BAZ")),
+ QString::fromUtf8("1.234\xc2\xa0" "BAZ"));
+ QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234)),
+ QString::fromUtf8("-1.234\xc2\xa0\xe2\x82\xac"));
+ QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234), QLatin1String("BAZ")),
+ QString::fromUtf8("-1.234\xc2\xa0" "BAZ"));
+ QCOMPARE(de_DE.toCurrencyString(double(1234.56)),
+ QString::fromUtf8("1.234,56\xc2\xa0\xe2\x82\xac"));
+ QCOMPARE(de_DE.toCurrencyString(double(-1234.56)),
+ QString::fromUtf8("-1.234,56\xc2\xa0\xe2\x82\xac"));
+ QCOMPARE(de_DE.toCurrencyString(double(-1234.56), QLatin1String("BAZ")),
+ QString::fromUtf8("-1.234,56\xc2\xa0" "BAZ"));
const QLocale es_CR(QLocale::Spanish, QLocale::CostaRica);
QCOMPARE(es_CR.toCurrencyString(double(1565.25)),
@@ -2398,11 +2479,13 @@ void tst_QLocale::quoteString()
const QString someText("text");
const QLocale c(QLocale::C);
QCOMPARE(c.quoteString(someText), QString::fromUtf8("\x22" "text" "\x22"));
- QCOMPARE(c.quoteString(someText, QLocale::AlternateQuotation), QString::fromUtf8("\x27" "text" "\x27"));
+ QCOMPARE(c.quoteString(someText, QLocale::AlternateQuotation),
+ QString::fromUtf8("\x27" "text" "\x27"));
const QLocale de_CH("de_CH");
QCOMPARE(de_CH.quoteString(someText), QString::fromUtf8("\xe2\x80\x9e" "text" "\xe2\x80\x9c"));
- QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation), QString::fromUtf8("\xe2\x80\x9a" "text" "\xe2\x80\x98"));
+ QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation),
+ QString::fromUtf8("\xe2\x80\x9a" "text" "\xe2\x80\x98"));
}
@@ -2484,23 +2567,28 @@ void tst_QLocale::listPatterns()
QCOMPARE(zh_CN.createSeparatedList(sl1), QString(""));
QCOMPARE(zh_CN.createSeparatedList(sl2), QString("aaa"));
QCOMPARE(zh_CN.createSeparatedList(sl3), QString::fromUtf8("aaa" "\xe5\x92\x8c" "bbb"));
- QCOMPARE(zh_CN.createSeparatedList(sl4), QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe5\x92\x8c" "ccc"));
- QCOMPARE(zh_CN.createSeparatedList(sl5), QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe3\x80\x81" "ccc" "\xe5\x92\x8c" "ddd"));
+ QCOMPARE(zh_CN.createSeparatedList(sl4),
+ QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe5\x92\x8c" "ccc"));
+ QCOMPARE(zh_CN.createSeparatedList(sl5),
+ QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe3\x80\x81"
+ "ccc" "\xe5\x92\x8c" "ddd"));
}
-void tst_QLocale::measurementSystems()
+void tst_QLocale::measurementSystems_data()
{
- QLocale locale(QLocale::English, QLocale::UnitedStates);
- QCOMPARE(locale.measurementSystem(), QLocale::ImperialUSSystem);
-
- locale = QLocale(QLocale::English, QLocale::UnitedKingdom);
- QCOMPARE(locale.measurementSystem(), QLocale::ImperialUKSystem);
-
- locale = QLocale(QLocale::English, QLocale::Australia);
- QCOMPARE(locale.measurementSystem(), QLocale::MetricSystem);
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<QLocale::MeasurementSystem>("system");
+ QTest::newRow("en_US") << QLocale(QLocale::English, QLocale::UnitedStates) << QLocale::ImperialUSSystem;
+ QTest::newRow("en_GB") << QLocale(QLocale::English, QLocale::UnitedKingdom) << QLocale::ImperialUKSystem;
+ QTest::newRow("en_AU") << QLocale(QLocale::English, QLocale::Australia) << QLocale::MetricSystem;
+ QTest::newRow("de") << QLocale(QLocale::German) << QLocale::MetricSystem;
+}
- locale = QLocale(QLocale::German);
- QCOMPARE(locale.measurementSystem(), QLocale::MetricSystem);
+void tst_QLocale::measurementSystems()
+{
+ QFETCH(QLocale, locale);
+ QFETCH(QLocale::MeasurementSystem, system);
+ QCOMPARE(locale.measurementSystem(), system);
}
void tst_QLocale::QTBUG_26035_positivesign()
@@ -2566,7 +2654,9 @@ void tst_QLocale::textDirection_data()
case QLocale::Uighur:
case QLocale::Urdu:
case QLocale::Yiddish:
- rightToLeft = QLocale(QLocale::Language(language)).language() == QLocale::Language(language); // false if there is no locale data for language
+ // false if there is no locale data for language:
+ rightToLeft = (QLocale(QLocale::Language(language)).language()
+ == QLocale::Language(language));
break;
default:
break;
@@ -2651,6 +2741,37 @@ void tst_QLocale::formattedDataSize_data()
#undef ROWQ
#undef ROWB
}
+
+ // Languages which don't use a Latin alphabet
+
+ const QLocale::DataSizeFormats iecFormat = QLocale::DataSizeIecFormat;
+ const QLocale::DataSizeFormats traditionalFormat = QLocale::DataSizeTraditionalFormat;
+ const QLocale::DataSizeFormats siFormat = QLocale::DataSizeSIFormat;
+ const QLocale::Language lang = QLocale::Russian;
+
+ QTest::newRow("Russian-IEC-0") << lang << 2 << iecFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-IEC-10") << lang << 2 << iecFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
+ // CLDR doesn't provide IEC prefixes (yet?) so they aren't getting translated
+ QTest::newRow("Russian-IEC-12Ki") << lang << 2 << iecFormat << 12345 << QString("12,06 KiB");
+ QTest::newRow("Russian-IEC-16Ki") << lang << 2 << iecFormat << 16384 << QString("16,00 KiB");
+ QTest::newRow("Russian-IEC-1235k") << lang << 2 << iecFormat << 1234567 << QString("1,18 MiB");
+ QTest::newRow("Russian-IEC-1374k") << lang << 2 << iecFormat << 1374744 << QString("1,31 MiB");
+ QTest::newRow("Russian-IEC-1234M") << lang << 2 << iecFormat << 1234567890 << QString("1,15 GiB");
+
+ QTest::newRow("Russian-Trad-0") << lang << 2 << traditionalFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-Trad-10") << lang << 2 << traditionalFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-Trad-12Ki") << lang << 2 << traditionalFormat << 12345 << QString("12,06 \u043A\u0411");
+ QTest::newRow("Russian-Trad-16Ki") << lang << 2 << traditionalFormat << 16384 << QString("16,00 \u043A\u0411");
+ QTest::newRow("Russian-Trad-1235k") << lang << 2 << traditionalFormat << 1234567 << QString("1,18 \u041C\u0411");
+ QTest::newRow("Russian-Trad-1374k") << lang << 2 << traditionalFormat << 1374744 << QString("1,31 \u041C\u0411");
+ QTest::newRow("Russian-Trad-1234M") << lang << 2 << traditionalFormat << 1234567890 << QString("1,15 \u0413\u0411");
+
+ QTest::newRow("Russian-Decimal-0") << lang << 2 << siFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-Decimal-10") << lang << 2 << siFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
+ QTest::newRow("Russian-Decimal-16Ki") << lang << 2 << siFormat << 16384 << QString("16,38 \u043A\u0411");
+ QTest::newRow("Russian-Decimal-1234k") << lang << 2 << siFormat << 1234567 << QString("1,23 \u041C\u0411");
+ QTest::newRow("Russian-Decimal-1374k") << lang << 2 << siFormat << 1374744 << QString("1,37 \u041C\u0411");
+ QTest::newRow("Russian-Decimal-1234M") << lang << 2 << siFormat << 1234567890 << QString("1,23 \u0413\u0411");
}
void tst_QLocale::formattedDataSize()
@@ -2663,25 +2784,33 @@ void tst_QLocale::formattedDataSize()
QCOMPARE(QLocale(language).formattedDataSize(bytes, decimalPlaces, units), output);
}
-void tst_QLocale::bcp47Name()
+void tst_QLocale::bcp47Name_data()
{
- QCOMPARE(QLocale("C").bcp47Name(), QStringLiteral("en"));
- QCOMPARE(QLocale("en").bcp47Name(), QStringLiteral("en"));
- QCOMPARE(QLocale("en_US").bcp47Name(), QStringLiteral("en"));
- QCOMPARE(QLocale("en_GB").bcp47Name(), QStringLiteral("en-GB"));
- QCOMPARE(QLocale("en_DE").bcp47Name(), QStringLiteral("en-DE"));
- QCOMPARE(QLocale("de_DE").bcp47Name(), QStringLiteral("de"));
- QCOMPARE(QLocale("sr_RS").bcp47Name(), QStringLiteral("sr"));
- QCOMPARE(QLocale("sr_Cyrl_RS").bcp47Name(), QStringLiteral("sr"));
- QCOMPARE(QLocale("sr_Latn_RS").bcp47Name(), QStringLiteral("sr-Latn"));
- QCOMPARE(QLocale("sr_ME").bcp47Name(), QStringLiteral("sr-ME"));
- QCOMPARE(QLocale("sr_Cyrl_ME").bcp47Name(), QStringLiteral("sr-Cyrl-ME"));
- QCOMPARE(QLocale("sr_Latn_ME").bcp47Name(), QStringLiteral("sr-ME"));
+ QTest::addColumn<QString>("expect");
+
+ QTest::newRow("C") << QStringLiteral("en");
+ QTest::newRow("en") << QStringLiteral("en");
+ QTest::newRow("en_US") << QStringLiteral("en");
+ QTest::newRow("en_GB") << QStringLiteral("en-GB");
+ QTest::newRow("en_DE") << QStringLiteral("en-DE");
+ QTest::newRow("de_DE") << QStringLiteral("de");
+ QTest::newRow("sr_RS") << QStringLiteral("sr");
+ QTest::newRow("sr_Cyrl_RS") << QStringLiteral("sr");
+ QTest::newRow("sr_Latn_RS") << QStringLiteral("sr-Latn");
+ QTest::newRow("sr_ME") << QStringLiteral("sr-ME");
+ QTest::newRow("sr_Cyrl_ME") << QStringLiteral("sr-Cyrl-ME");
+ QTest::newRow("sr_Latn_ME") << QStringLiteral("sr-ME");
// Fall back to defaults when country isn't in CLDR for this language:
- QCOMPARE(QLocale("sr_HR").bcp47Name(), QStringLiteral("sr"));
- QCOMPARE(QLocale("sr_Cyrl_HR").bcp47Name(), QStringLiteral("sr"));
- QCOMPARE(QLocale("sr_Latn_HR").bcp47Name(), QStringLiteral("sr-Latn"));
+ QTest::newRow("sr_HR") << QStringLiteral("sr");
+ QTest::newRow("sr_Cyrl_HR") << QStringLiteral("sr");
+ QTest::newRow("sr_Latn_HR") << QStringLiteral("sr-Latn");
+}
+
+void tst_QLocale::bcp47Name()
+{
+ QFETCH(QString, expect);
+ QCOMPARE(QLocale(QLatin1String(QTest::currentDataTag())).bcp47Name(), expect);
}
class MySystemLocale : public QSystemLocale
diff --git a/tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro b/tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro
index 26b3a47472..8599596344 100644
--- a/tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro
+++ b/tests/auto/corelib/tools/qmacautoreleasepool/qmacautoreleasepool.pro
@@ -2,3 +2,4 @@ CONFIG += testcase
TARGET = tst_qmacautoreleasepool
QT = core testlib
SOURCES = tst_qmacautoreleasepool.mm
+LIBS += -framework Foundation
diff --git a/tests/auto/corelib/tools/qmakearray/qmakearray.pro b/tests/auto/corelib/tools/qmakearray/qmakearray.pro
new file mode 100644
index 0000000000..abb3d9fdbc
--- /dev/null
+++ b/tests/auto/corelib/tools/qmakearray/qmakearray.pro
@@ -0,0 +1,4 @@
+CONFIG += testcase
+TARGET = tst_qmakearray
+QT = core testlib core-private
+SOURCES = $$PWD/tst_qmakearray.cpp
diff --git a/tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp b/tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp
new file mode 100644
index 0000000000..e0d3f52719
--- /dev/null
+++ b/tests/auto/corelib/tools/qmakearray/tst_qmakearray.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <private/qmakearray_p.h>
+
+
+class tst_QMakeArray : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void quicksort();
+};
+
+struct Pair {
+ unsigned int key;
+ unsigned int val;
+
+ constexpr bool operator <=(const Pair &that) const noexcept
+ {
+ return key <= that.key;
+ }
+
+ constexpr bool operator<(const Pair &that) const noexcept
+ {
+ return key < that.key;
+ }
+
+ constexpr bool operator==(const Pair &that) const noexcept
+ {
+ return key == that.key;
+ }
+};
+
+template<std::size_t Key, std::size_t Val>
+struct PairQuickSortElem
+{
+ using Type = Pair;
+ static constexpr Type data() noexcept { return Type{Key, Val}; }
+};
+
+void tst_QMakeArray::quicksort()
+{
+ constexpr const auto sorted_array = qMakeArray(
+ QSortedData<
+ PairQuickSortElem<10, 0>,
+ PairQuickSortElem<5, 0>,
+ PairQuickSortElem<7, 0>,
+ PairQuickSortElem<1, 0>,
+ PairQuickSortElem<8, 0>,
+ PairQuickSortElem<6, 0>,
+ PairQuickSortElem<4, 0>,
+ PairQuickSortElem<3, 0>,
+ PairQuickSortElem<1, 0>,
+ PairQuickSortElem<2, 0>,
+ PairQuickSortElem<10, 0>,
+ PairQuickSortElem<5, 0>
+ >::Data{});
+ static_assert(sorted_array.size() == 12, "sorted_array.size() != 12");
+ QCOMPARE(sorted_array[0].key, 1u);
+ QCOMPARE(sorted_array[1].key, 1u);
+ QCOMPARE(sorted_array[2].key, 2u);
+ QCOMPARE(sorted_array[3].key, 3u);
+ QCOMPARE(sorted_array[4].key, 4u);
+ QCOMPARE(sorted_array[5].key, 5u);
+ QCOMPARE(sorted_array[6].key, 5u);
+ QCOMPARE(sorted_array[7].key, 6u);
+ QCOMPARE(sorted_array[8].key, 7u);
+ QCOMPARE(sorted_array[9].key, 8u);
+ QCOMPARE(sorted_array[10].key, 10u);
+ QCOMPARE(sorted_array[11].key, 10u);
+}
+
+
+QTEST_APPLESS_MAIN(tst_QMakeArray)
+#include "tst_qmakearray.moc"
diff --git a/tests/auto/corelib/tools/qregularexpression/alwaysoptimize/alwaysoptimize.pro b/tests/auto/corelib/tools/qregularexpression/alwaysoptimize/alwaysoptimize.pro
deleted file mode 100644
index a27286ff20..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/alwaysoptimize/alwaysoptimize.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qregularexpression_alwaysoptimize
-QT = core testlib
-HEADERS = ../tst_qregularexpression.h
-SOURCES = \
- tst_qregularexpression_alwaysoptimize.cpp \
- ../tst_qregularexpression.cpp
diff --git a/tests/auto/corelib/tools/qregularexpression/alwaysoptimize/tst_qregularexpression_alwaysoptimize.cpp b/tests/auto/corelib/tools/qregularexpression/alwaysoptimize/tst_qregularexpression_alwaysoptimize.cpp
deleted file mode 100644
index 6d2ae48235..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/alwaysoptimize/tst_qregularexpression_alwaysoptimize.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include "../tst_qregularexpression.h"
-
-class tst_QRegularExpression_AlwaysOptimize : public tst_QRegularExpression
-{
- Q_OBJECT
-
-private slots:
- void initTestCase();
-};
-
-QT_BEGIN_NAMESPACE
-extern Q_CORE_EXPORT unsigned int qt_qregularexpression_optimize_after_use_count; // from qregularexpression.cpp
-QT_END_NAMESPACE
-
-void tst_QRegularExpression_AlwaysOptimize::initTestCase()
-{
- qt_qregularexpression_optimize_after_use_count = 1;
-}
-
-QTEST_APPLESS_MAIN(tst_QRegularExpression_AlwaysOptimize)
-
-#include "tst_qregularexpression_alwaysoptimize.moc"
diff --git a/tests/auto/corelib/tools/qregularexpression/defaultoptimize/defaultoptimize.pro b/tests/auto/corelib/tools/qregularexpression/defaultoptimize/defaultoptimize.pro
deleted file mode 100644
index 0b36c79c1b..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/defaultoptimize/defaultoptimize.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qregularexpression_defaultoptimize
-QT = core testlib
-HEADERS = ../tst_qregularexpression.h
-SOURCES = \
- tst_qregularexpression_defaultoptimize.cpp \
- ../tst_qregularexpression.cpp
diff --git a/tests/auto/corelib/tools/qregularexpression/defaultoptimize/tst_qregularexpression_defaultoptimize.cpp b/tests/auto/corelib/tools/qregularexpression/defaultoptimize/tst_qregularexpression_defaultoptimize.cpp
deleted file mode 100644
index a815c6cab9..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/defaultoptimize/tst_qregularexpression_defaultoptimize.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include "../tst_qregularexpression.h"
-
-class tst_QRegularExpression_DefaultOptimize : public tst_QRegularExpression
-{
- Q_OBJECT
-};
-
-QTEST_APPLESS_MAIN(tst_QRegularExpression_DefaultOptimize)
-
-#include "tst_qregularexpression_defaultoptimize.moc"
diff --git a/tests/auto/corelib/tools/qregularexpression/forceoptimize/forceoptimize.pro b/tests/auto/corelib/tools/qregularexpression/forceoptimize/forceoptimize.pro
deleted file mode 100644
index 1db77781dd..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/forceoptimize/forceoptimize.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qregularexpression_forceoptimize
-QT = core testlib
-HEADERS = ../tst_qregularexpression.h
-SOURCES = \
- tst_qregularexpression_forceoptimize.cpp \
- ../tst_qregularexpression.cpp
-DEFINES += forceOptimize=true
diff --git a/tests/auto/corelib/tools/qregularexpression/forceoptimize/tst_qregularexpression_forceoptimize.cpp b/tests/auto/corelib/tools/qregularexpression/forceoptimize/tst_qregularexpression_forceoptimize.cpp
deleted file mode 100644
index 38a3a64fa3..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/forceoptimize/tst_qregularexpression_forceoptimize.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include "../tst_qregularexpression.h"
-
-class tst_QRegularExpression_ForceOptimize : public tst_QRegularExpression
-{
- Q_OBJECT
-};
-
-QTEST_APPLESS_MAIN(tst_QRegularExpression_ForceOptimize)
-
-#include "tst_qregularexpression_forceoptimize.moc"
diff --git a/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro b/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro
index e1840808ff..ec8189717e 100644
--- a/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro
+++ b/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro
@@ -1,3 +1,4 @@
-TEMPLATE = subdirs
-SUBDIRS = defaultoptimize forceoptimize
-qtConfig(private_tests): SUBDIRS += alwaysoptimize
+CONFIG += testcase
+TARGET = tst_qregularexpression
+QT = core testlib
+SOURCES = tst_qregularexpression.cpp
diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
index c828551e44..f520e9742a 100644
--- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
+++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
@@ -33,11 +33,60 @@
#include <qstringlist.h>
#include <qhash.h>
-#include "tst_qregularexpression.h"
+#include <qobject.h>
+#include <qregularexpression.h>
+#include <qthread.h>
-#ifndef forceOptimize
-#define forceOptimize false
-#endif
+Q_DECLARE_METATYPE(QRegularExpression::PatternOptions)
+Q_DECLARE_METATYPE(QRegularExpression::MatchType)
+Q_DECLARE_METATYPE(QRegularExpression::MatchOptions)
+
+class tst_QRegularExpression : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void defaultConstructors();
+ void gettersSetters_data();
+ void gettersSetters();
+ void escape_data();
+ void escape();
+ void validity_data();
+ void validity();
+ void patternOptions_data();
+ void patternOptions();
+ void normalMatch_data();
+ void normalMatch();
+ void partialMatch_data();
+ void partialMatch();
+ void globalMatch_data();
+ void globalMatch();
+ void serialize_data();
+ void serialize();
+ void operatoreq_data();
+ void operatoreq();
+ void captureCount_data();
+ void captureCount();
+ void captureNames_data();
+ void captureNames();
+ void pcreJitStackUsage_data();
+ void pcreJitStackUsage();
+ void regularExpressionMatch_data();
+ void regularExpressionMatch();
+ void JOptionUsage_data();
+ void JOptionUsage();
+ void QStringAndQStringRefEquivalence();
+ void threadSafety_data();
+ void threadSafety();
+
+ void wildcard_data();
+ void wildcard();
+ void testInvalidWildcard_data();
+ void testInvalidWildcard();
+
+private:
+ void provideRegularExpressions();
+};
struct Match
{
@@ -292,9 +341,6 @@ static void testMatch(const QRegularExpression &regexp,
QRegularExpression::MatchOptions matchOptions,
const Result &result)
{
- if (forceOptimize)
- regexp.optimize();
-
// test with QString as subject type
testMatchImpl<QREMatch>(regexp, matchingMethodForString, subject, offset, matchType, matchOptions, result);
@@ -401,30 +447,22 @@ void tst_QRegularExpression::gettersSetters()
{
QRegularExpression re;
re.setPattern(pattern);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.pattern(), pattern);
QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
}
{
QRegularExpression re;
re.setPatternOptions(patternOptions);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.pattern(), QString());
QCOMPARE(re.patternOptions(), patternOptions);
}
{
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.pattern(), pattern);
QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
}
{
QRegularExpression re(pattern, patternOptions);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.pattern(), pattern);
QCOMPARE(re.patternOptions(), patternOptions);
}
@@ -465,8 +503,6 @@ void tst_QRegularExpression::escape()
QFETCH(QString, escaped);
QCOMPARE(QRegularExpression::escape(string), escaped);
QRegularExpression re(escaped);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.isValid(), true);
}
@@ -497,8 +533,6 @@ void tst_QRegularExpression::validity()
QFETCH(QString, pattern);
QFETCH(bool, validity);
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.isValid(), validity);
if (!validity)
QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object");
@@ -585,9 +619,6 @@ void tst_QRegularExpression::patternOptions()
QFETCH(QString, subject);
QFETCH(Match, match);
- if (forceOptimize)
- regexp.optimize();
-
QRegularExpressionMatch m = regexp.match(subject);
consistencyCheck(m);
QVERIFY(m == match);
@@ -1403,9 +1434,6 @@ void tst_QRegularExpression::serialize()
QFETCH(QRegularExpression::PatternOptions, patternOptions);
QRegularExpression outRe(pattern, patternOptions);
- if (forceOptimize)
- outRe.optimize();
-
QByteArray buffer;
{
QDataStream out(&buffer, QIODevice::WriteOnly);
@@ -1468,33 +1496,18 @@ void tst_QRegularExpression::operatoreq()
QRegularExpression re1(pattern);
QRegularExpression re2(pattern);
- if (forceOptimize)
- re1.optimize();
- if (forceOptimize)
- re2.optimize();
-
verifyEquality(re1, re2);
}
{
QRegularExpression re1(QString(), patternOptions);
QRegularExpression re2(QString(), patternOptions);
- if (forceOptimize)
- re1.optimize();
- if (forceOptimize)
- re2.optimize();
-
verifyEquality(re1, re2);
}
{
QRegularExpression re1(pattern, patternOptions);
QRegularExpression re2(pattern, patternOptions);
- if (forceOptimize)
- re1.optimize();
- if (forceOptimize)
- re2.optimize();
-
verifyEquality(re1, re2);
}
}
@@ -1524,9 +1537,6 @@ void tst_QRegularExpression::captureCount()
QFETCH(QString, pattern);
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
-
QTEST(re.captureCount(), "captureCount");
if (!re.isValid())
QCOMPARE(re.captureCount(), -1);
@@ -1595,9 +1605,6 @@ void tst_QRegularExpression::captureNames()
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
-
QStringList namedCaptureGroups = re.namedCaptureGroups();
int namedCaptureGroupsCount = namedCaptureGroups.size();
@@ -1633,9 +1640,6 @@ void tst_QRegularExpression::pcreJitStackUsage()
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
-
QVERIFY(re.isValid());
QRegularExpressionMatch match = re.match(subject);
consistencyCheck(match);
@@ -1663,9 +1667,6 @@ void tst_QRegularExpression::regularExpressionMatch()
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
-
QVERIFY(re.isValid());
QRegularExpressionMatch match = re.match(subject);
consistencyCheck(match);
@@ -1705,8 +1706,6 @@ void tst_QRegularExpression::JOptionUsage()
QRegularExpression re(pattern);
if (isValid && JOptionUsed)
QTest::ignoreMessage(QtWarningMsg, qPrintable(warningMessage.arg(pattern)));
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.isValid(), isValid);
}
@@ -2066,3 +2065,185 @@ void tst_QRegularExpression::QStringAndQStringRefEquivalence()
}
}
}
+
+class MatcherThread : public QThread
+{
+public:
+ explicit MatcherThread(const QRegularExpression &re, const QString &subject, QObject *parent = nullptr)
+ : QThread(parent),
+ m_re(re),
+ m_subject(subject)
+ {
+ }
+
+private:
+ static const int MATCH_ITERATIONS = 50;
+
+ void run() override
+ {
+ yieldCurrentThread();
+ for (int i = 0; i < MATCH_ITERATIONS; ++i)
+ m_re.match(m_subject);
+ }
+
+ const QRegularExpression &m_re;
+ const QString &m_subject;
+};
+
+void tst_QRegularExpression::threadSafety_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("subject");
+
+ int i = 0;
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abbbbcccd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abababcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abcabcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abccccccababd";
+
+ {
+ QString subject(512*1024, QLatin1Char('x'));
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ {
+ QString subject = "ab";
+ subject.append(QString(512*1024, QLatin1Char('x')));
+ subject.append("c");
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ {
+ QString subject = "ab";
+ subject.append(QString(512*1024, QLatin1Char('x')));
+ subject.append("cd");
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ QTest::addRow("pattern%d", ++i) << "(?(R)a*(?1)|((?R))b)" << "aaaabcde";
+ QTest::addRow("pattern%d", ++i) << "(?(R)a*(?1)|((?R))b)" << "aaaaaaabcde";
+}
+
+void tst_QRegularExpression::threadSafety()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, subject);
+
+ static const int THREAD_SAFETY_ITERATIONS = 50;
+
+ const int threadCount = qMax(QThread::idealThreadCount(), 4);
+
+ for (int threadSafetyIteration = 0; threadSafetyIteration < THREAD_SAFETY_ITERATIONS; ++threadSafetyIteration) {
+ QRegularExpression re(pattern);
+
+ QVector<MatcherThread *> threads;
+ for (int i = 0; i < threadCount; ++i) {
+ MatcherThread *thread = new MatcherThread(re, subject);
+ thread->start();
+ threads.push_back(thread);
+ }
+
+ for (int i = 0; i < threadCount; ++i)
+ threads[i]->wait();
+
+ qDeleteAll(threads);
+ }
+}
+
+void tst_QRegularExpression::wildcard_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<int>("foundIndex");
+
+ auto addRow = [](const char *pattern, const char *string, int foundIndex) {
+ QTest::newRow(pattern) << pattern << string << foundIndex;
+ };
+
+ addRow("*.html", "test.html", 0);
+ addRow("*.html", "test.htm", -1);
+ addRow("bar*", "foobarbaz", 3);
+ addRow("*", "Qt Rocks!", 0);
+ addRow(".html", "test.html", 4);
+ addRow(".h", "test.cpp", -1);
+ addRow(".???l", "test.html", 4);
+ addRow("?", "test.html", 0);
+ addRow("?m", "test.html", 6);
+ addRow("[*]", "test.html", -1);
+ addRow("[?]","test.html", -1);
+ addRow("[?]","test.h?ml", 6);
+ addRow("[[]","test.h[ml", 6);
+ addRow("[]]","test.h]ml", 6);
+ addRow(".h[a-z]ml", "test.html", 4);
+ addRow(".h[A-Z]ml", "test.html", -1);
+ addRow(".h[A-Z]ml", "test.hTml", 4);
+ addRow(".h[!A-Z]ml", "test.hTml", -1);
+ addRow(".h[!A-Z]ml", "test.html", 4);
+ addRow(".h[!T]ml", "test.hTml", -1);
+ addRow(".h[!T]ml", "test.html", 4);
+ addRow(".h[!T]m[!L]", "test.htmL", -1);
+ addRow(".h[!T]m[!L]", "test.html", 4);
+ addRow(".h[][!]", "test.h]ml", 4);
+ addRow(".h[][!]", "test.h[ml", 4);
+ addRow(".h[][!]", "test.h!ml", 4);
+
+ addRow("foo/*/bar", "Qt/foo/baz/bar", 3);
+ addRow("foo/(*)/bar", "Qt/foo/baz/bar", -1);
+ addRow("foo/(*)/bar", "Qt/foo/(baz)/bar", 3);
+ addRow("foo/?/bar", "Qt/foo/Q/bar", 3);
+ addRow("foo/?/bar", "Qt/foo/Qt/bar", -1);
+ addRow("foo/(?)/bar", "Qt/foo/Q/bar", -1);
+ addRow("foo/(?)/bar", "Qt/foo/(Q)/bar", 3);
+
+#ifdef Q_OS_WIN
+ addRow("foo\\*\\bar", "Qt\\foo\\baz\\bar", 3);
+ addRow("foo\\(*)\\bar", "Qt\\foo\\baz\\bar", -1);
+ addRow("foo\\(*)\\bar", "Qt\\foo\\(baz)\\bar", 3);
+ addRow("foo\\?\\bar", "Qt\\foo\\Q\\bar", 3);
+ addRow("foo\\?\\bar", "Qt\\foo\\Qt\\bar", -1);
+ addRow("foo\\(?)\\bar", "Qt\\foo\\Q\\bar", -1);
+ addRow("foo\\(?)\\bar", "Qt\\foo\\(Q)\\bar", 3);
+#endif
+}
+
+void tst_QRegularExpression::wildcard()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, string);
+ QFETCH(int, foundIndex);
+
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
+ QRegularExpressionMatch match = re.match(string);
+
+ QCOMPARE(match.capturedStart(), foundIndex);
+}
+
+void tst_QRegularExpression::testInvalidWildcard_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<bool>("isValid");
+
+ QTest::newRow("valid []") << "[abc]" << true;
+ QTest::newRow("valid ending ]") << "abc]" << true;
+ QTest::newRow("invalid [") << "[abc" << false;
+ QTest::newRow("ending [") << "abc[" << false;
+ QTest::newRow("ending [^") << "abc[^" << false;
+ QTest::newRow("ending [\\") << "abc[\\" << false;
+ QTest::newRow("ending []") << "abc[]" << false;
+ QTest::newRow("ending [[") << "abc[[" << false;
+}
+
+void tst_QRegularExpression::testInvalidWildcard()
+{
+ QFETCH(QString, pattern);
+ QFETCH(bool, isValid);
+
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
+ QCOMPARE(re.isValid(), isValid);
+}
+
+QTEST_APPLESS_MAIN(tst_QRegularExpression)
+
+#include "tst_qregularexpression.moc"
diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.h b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.h
deleted file mode 100644
index 8bb4aa0cce..0000000000
--- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qobject.h>
-#include <qregularexpression.h>
-
-Q_DECLARE_METATYPE(QRegularExpression::PatternOptions)
-Q_DECLARE_METATYPE(QRegularExpression::MatchType)
-Q_DECLARE_METATYPE(QRegularExpression::MatchOptions)
-
-class tst_QRegularExpression : public QObject
-{
- Q_OBJECT
-
-private slots:
- void defaultConstructors();
- void gettersSetters_data();
- void gettersSetters();
- void escape_data();
- void escape();
- void validity_data();
- void validity();
- void patternOptions_data();
- void patternOptions();
- void normalMatch_data();
- void normalMatch();
- void partialMatch_data();
- void partialMatch();
- void globalMatch_data();
- void globalMatch();
- void serialize_data();
- void serialize();
- void operatoreq_data();
- void operatoreq();
- void captureCount_data();
- void captureCount();
- void captureNames_data();
- void captureNames();
- void pcreJitStackUsage_data();
- void pcreJitStackUsage();
- void regularExpressionMatch_data();
- void regularExpressionMatch();
- void JOptionUsage_data();
- void JOptionUsage();
- void QStringAndQStringRefEquivalence();
-
-private:
- void provideRegularExpressions();
-};
diff --git a/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro b/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro
new file mode 100644
index 0000000000..070d4b077c
--- /dev/null
+++ b/tests/auto/corelib/tools/qscopeguard/qscopeguard.pro
@@ -0,0 +1,4 @@
+CONFIG += testcase
+TARGET = tst_qscopeguard
+QT = core testlib
+SOURCES = tst_qscopeguard.cpp
diff --git a/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp
new file mode 100644
index 0000000000..f95d48f042
--- /dev/null
+++ b/tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtCore/QScopeGuard>
+
+/*!
+ \class tst_QScopedGuard
+ \internal
+ \since 5.11
+ \brief Tests class QScopedCleanup and function qScopeGuard
+
+ */
+class tst_QScopedGuard : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void leavingScope();
+ void exceptions();
+};
+
+static int s_globalState = 0;
+
+void tst_QScopedGuard::leavingScope()
+{
+ auto cleanup = qScopeGuard([] { s_globalState++; QCOMPARE(s_globalState, 3); });
+ QCOMPARE(s_globalState, 0);
+
+ {
+ auto cleanup = qScopeGuard([] { s_globalState++; });
+ QCOMPARE(s_globalState, 0);
+ }
+
+ QCOMPARE(s_globalState, 1);
+ s_globalState++;
+}
+
+void tst_QScopedGuard::exceptions()
+{
+ s_globalState = 0;
+ bool caught = false;
+ QT_TRY
+ {
+ auto cleanup = qScopeGuard([&caught] { s_globalState++; });
+ QT_THROW(std::bad_alloc()); //if Qt compiled without exceptions this is noop
+ s_globalState = 100;
+ }
+ QT_CATCH(...)
+ {
+ caught = true;
+ QCOMPARE(s_globalState, 1);
+ }
+
+ QVERIFY((caught && s_globalState == 1) || (!caught && s_globalState == 101));
+
+}
+
+QTEST_MAIN(tst_QScopedGuard)
+#include "tst_qscopeguard.moc"
diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
index 3e1668522e..4dc620e6ab 100644
--- a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
@@ -53,6 +53,12 @@
# include <unistd.h>
#endif
+enum {
+ QMakeTimeout = 300000, // 5 minutes
+ CompileTimeout = 600000, // 10 minutes
+ RunTimeout = 300000 // 5 minutes
+};
+
static QString makespec()
{
static const char default_makespec[] = DEFAULT_MAKESPEC;
@@ -143,7 +149,7 @@ namespace QTest {
bool prepareSourceCode(const QByteArray &body);
bool createProjectFile();
bool runQmake();
- bool runMake(Target target);
+ bool runMake(Target target, int timeout);
bool commonSetup(const QByteArray &body);
};
@@ -602,7 +608,7 @@ namespace QTest {
std_err += "qmake: ";
std_err += qmake.errorString().toLocal8Bit();
} else {
- ok = qmake.waitForFinished();
+ ok = qmake.waitForFinished(QMakeTimeout);
exitCode = qmake.exitCode();
if (!ok)
QTest::ensureStopped(qmake);
@@ -617,7 +623,7 @@ namespace QTest {
#endif // QT_CONFIG(process)
}
- bool QExternalTestPrivate::runMake(Target target)
+ bool QExternalTestPrivate::runMake(Target target, int timeout)
{
#if !QT_CONFIG(process)
return false;
@@ -670,7 +676,7 @@ namespace QTest {
}
make.closeWriteChannel();
- bool ok = make.waitForFinished(channelMode == QProcess::ForwardedChannels ? -1 : 60000);
+ bool ok = make.waitForFinished(channelMode == QProcess::ForwardedChannels ? -1 : timeout);
if (!ok)
QTest::ensureStopped(make);
exitCode = make.exitCode();
@@ -705,7 +711,7 @@ namespace QTest {
failedStage = QExternalTest::CompilationStage;
std_out += "\n### --- stdout from make (compilation) --- ###\n";
std_err += "\n### --- stderr from make (compilation) --- ###\n";
- return runMake(Compile);
+ return runMake(Compile, CompileTimeout);
}
bool QExternalTestPrivate::tryLink(const QByteArray &body)
@@ -717,7 +723,7 @@ namespace QTest {
failedStage = QExternalTest::LinkStage;
std_out += "\n### --- stdout from make (linking) --- ###\n";
std_err += "\n### --- stderr from make (linking) --- ###\n";
- return runMake(Link);
+ return runMake(Link, CompileTimeout);
}
bool QExternalTestPrivate::tryRun(const QByteArray &body)
@@ -729,7 +735,7 @@ namespace QTest {
failedStage = QExternalTest::RunStage;
std_out += "\n### --- stdout from process --- ###\n";
std_err += "\n### --- stderr from process --- ###\n";
- return runMake(Run);
+ return runMake(Run, RunTimeout);
}
}
QT_END_NAMESPACE
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index 2074c9789a..f429bda804 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -450,6 +450,8 @@ private slots:
void trimmed();
void toUpper();
void toLower();
+ void isUpper();
+ void isLower();
void toCaseFolded();
void rightJustified();
void leftJustified();
@@ -529,10 +531,8 @@ private slots:
void integer_conversion();
void tortureSprintfDouble();
void toNum();
-#if !defined(Q_OS_WIN)
void localeAwareCompare_data();
void localeAwareCompare();
-#endif
void reverseIterators();
void split_data();
void split();
@@ -2315,6 +2315,46 @@ void tst_QString::toLower()
#endif
}
+void tst_QString::isUpper()
+{
+ QVERIFY(!QString().isUpper());
+ QVERIFY(!QString("").isUpper());
+ QVERIFY(QString("TEXT").isUpper());
+ QVERIFY(!QString("text").isUpper());
+ QVERIFY(!QString("Text").isUpper());
+ QVERIFY(!QString("tExt").isUpper());
+ QVERIFY(!QString("teXt").isUpper());
+ QVERIFY(!QString("texT").isUpper());
+ QVERIFY(!QString("TExt").isUpper());
+ QVERIFY(!QString("teXT").isUpper());
+ QVERIFY(!QString("tEXt").isUpper());
+ QVERIFY(!QString("tExT").isUpper());
+ QVERIFY(!QString("@ABYZ[").isUpper());
+ QVERIFY(!QString("@abyz[").isUpper());
+ QVERIFY(!QString("`ABYZ{").isUpper());
+ QVERIFY(!QString("`abyz{").isUpper());
+}
+
+void tst_QString::isLower()
+{
+ QVERIFY(!QString().isLower());
+ QVERIFY(!QString("").isLower());
+ QVERIFY(QString("text").isLower());
+ QVERIFY(!QString("Text").isLower());
+ QVERIFY(!QString("tExt").isLower());
+ QVERIFY(!QString("teXt").isLower());
+ QVERIFY(!QString("texT").isLower());
+ QVERIFY(!QString("TExt").isLower());
+ QVERIFY(!QString("teXT").isLower());
+ QVERIFY(!QString("tEXt").isLower());
+ QVERIFY(!QString("tExT").isLower());
+ QVERIFY(!QString("TEXT").isLower());
+ QVERIFY(!QString("@ABYZ[").isLower());
+ QVERIFY(!QString("@abyz[").isLower());
+ QVERIFY(!QString("`ABYZ{").isLower());
+ QVERIFY(!QString("`abyz{").isLower());
+}
+
void tst_QString::toCaseFolded()
{
QCOMPARE( QString().toCaseFolded(), QString() );
@@ -5468,8 +5508,6 @@ void tst_QString::tortureSprintfDouble()
#include <locale.h>
-#if !defined(Q_OS_WIN)
-// On Q_OS_WIN, we cannot set the system or user locale
void tst_QString::localeAwareCompare_data()
{
QTest::addColumn<QString>("locale");
@@ -5477,6 +5515,46 @@ void tst_QString::localeAwareCompare_data()
QTest::addColumn<QString>("s2");
QTest::addColumn<int>("result");
+ // Compare decomposed and composed form
+ {
+ // From ES6 test262 test suite (built-ins/String/prototype/localeCompare/15.5.4.9_CE.js). The test cases boil down to code like this:
+ // console.log("\u1111\u1171\u11B6".localeCompare("\ud4db")
+
+ // example from Unicode 5.0, section 3.7, definition D70
+ QTest::newRow("normalize1") << QString() << QString::fromUtf8("o\xCC\x88") << QString::fromUtf8("\xC3\xB6") << 0;
+ // examples from Unicode 5.0, chapter 3.11
+ QTest::newRow("normalize2") << QString() << QString::fromUtf8("\xC3\xA4\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
+ QTest::newRow("normalize3") << QString() << QString::fromUtf8("a\xCC\x88\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
+ QTest::newRow("normalize4") << QString() << QString::fromUtf8("\xE1\xBA\xA1\xCC\x88") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0;
+ QTest::newRow("normalize5") << QString() << QString::fromUtf8("\xC3\xA4\xCC\x86") << QString::fromUtf8("a\xCC\x88\xCC\x86") << 0;
+ QTest::newRow("normalize6") << QString() << QString::fromUtf8("\xC4\x83\xCC\x88") << QString::fromUtf8("a\xCC\x86\xCC\x88") << 0;
+ // example from Unicode 5.0, chapter 3.12
+ QTest::newRow("normalize7") << QString() << QString::fromUtf8("\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6") << QString::fromUtf8("\xED\x93\x9B") << 0;
+ // examples from UTS 10, Unicode Collation Algorithm
+ QTest::newRow("normalize8") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("\xC3\x85") << 0;
+ QTest::newRow("normalize9") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0;
+ QTest::newRow("normalize10") << QString() << QString::fromUtf8("x\xCC\x9B\xCC\xA3") << QString::fromUtf8("x\xCC\xA3\xCC\x9B") << 0;
+ QTest::newRow("normalize11") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xE1\xBB\xA5\xCC\x9B") << 0;
+ QTest::newRow("normalize12") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\x9B\xCC\xA3") << 0;
+ QTest::newRow("normalize13") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xC6\xB0\xCC\xA3") << 0;
+ QTest::newRow("normalize14") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\xA3\xCC\x9B") << 0;
+ // examples from UAX 15, Unicode Normalization Forms
+ QTest::newRow("normalize15") << QString() << QString::fromUtf8("\xC3\x87") << QString::fromUtf8("C\xCC\xA7") << 0;
+ QTest::newRow("normalize16") << QString() << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0;
+ QTest::newRow("normalize17") << QString() << QString::fromUtf8("\xEA\xB0\x80") << QString::fromUtf8("\xE1\x84\x80\xE1\x85\xA1") << 0;
+ QTest::newRow("normalize18") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0;
+ QTest::newRow("normalize19") << QString() << QString::fromUtf8("\xE2\x84\xA6") << QString::fromUtf8("\xCE\xA9") << 0;
+ QTest::newRow("normalize20") << QString() << QString::fromUtf8("\xC3\x85") << QString::fromUtf8("A\xCC\x8A") << 0;
+ QTest::newRow("normalize21") << QString() << QString::fromUtf8("\xC3\xB4") << QString::fromUtf8("o\xCC\x82") << 0;
+ QTest::newRow("normalize22") << QString() << QString::fromUtf8("\xE1\xB9\xA9") << QString::fromUtf8("s\xCC\xA3\xCC\x87") << 0;
+ QTest::newRow("normalize23") << QString() << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("d\xCC\xA3\xCC\x87") << 0;
+ QTest::newRow("normalize24") << QString() << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("\xE1\xB8\x8D\xCC\x87") << 0;
+ QTest::newRow("normalize25") << QString() << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0;
+
+ }
+
+#if !defined(Q_OS_WIN)
+// On Q_OS_WIN, we cannot set the system or user locale
/*
The C locale performs pure byte comparisons for
Latin-1-specific characters (I think). Compare with Swedish
@@ -5537,6 +5615,7 @@ void tst_QString::localeAwareCompare_data()
QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1;
QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1;
#endif
+#endif //!defined(Q_OS_WIN)
}
void tst_QString::localeAwareCompare()
@@ -5549,17 +5628,17 @@ void tst_QString::localeAwareCompare()
QStringRef r1(&s1, 0, s1.length());
QStringRef r2(&s2, 0, s2.length());
+ if (!locale.isEmpty()) {
#if defined (Q_OS_DARWIN) || defined(QT_USE_ICU)
- QSKIP("Setting the locale is not supported on OS X or ICU (you can set the C locale, but that won't affect localeAwareCompare)");
+ QSKIP("Setting the locale is not supported on OS X or ICU (you can set the C locale, but that won't affect localeAwareCompare)");
#else
- if (!locale.isEmpty()) {
const char *newLocale = setlocale(LC_ALL, locale.toLatin1());
if (!newLocale) {
setlocale(LC_ALL, "");
QSKIP("Please install the proper locale on this machine to test properly");
}
- }
#endif
+ }
#ifdef QT_USE_ICU
// ### for c1, ICU disagrees with libc on how to compare
@@ -5614,7 +5693,6 @@ void tst_QString::localeAwareCompare()
if (!locale.isEmpty())
setlocale(LC_ALL, "");
}
-#endif //!defined(Q_OS_WIN)
void tst_QString::reverseIterators()
{
@@ -6160,11 +6238,14 @@ void tst_QString::compare()
QStringRef r1(&s1, 0, s1.length());
QStringRef r2(&s2, 0, s2.length());
+ const QStringView v2(s2);
+
QCOMPARE(sign(QString::compare(s1, s2)), csr);
QCOMPARE(sign(QStringRef::compare(r1, r2)), csr);
QCOMPARE(sign(s1.compare(s2)), csr);
QCOMPARE(sign(s1.compare(r2)), csr);
QCOMPARE(sign(r1.compare(r2)), csr);
+ QCOMPARE(sign(s1.compare(v2)), csr);
QCOMPARE(sign(s1.compare(s2, Qt::CaseSensitive)), csr);
QCOMPARE(sign(s1.compare(s2, Qt::CaseInsensitive)), cir);
@@ -6172,6 +6253,8 @@ void tst_QString::compare()
QCOMPARE(sign(s1.compare(r2, Qt::CaseInsensitive)), cir);
QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr);
QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir);
+ QCOMPARE(sign(s1.compare(v2, Qt::CaseSensitive)), csr);
+ QCOMPARE(sign(s1.compare(v2, Qt::CaseInsensitive)), cir);
QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseSensitive)), csr);
QCOMPARE(sign(QString::compare(s1, s2, Qt::CaseInsensitive)), cir);
diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp
index 9f054190e5..a3aec4c299 100644
--- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp
+++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp
@@ -273,6 +273,15 @@ void tst_QStringList::contains()
QVERIFY(list.contains(QLatin1String("ARTHUR"), Qt::CaseInsensitive));
QVERIFY(list.contains(QLatin1String("dent"), Qt::CaseInsensitive));
QVERIFY(!list.contains(QLatin1String("hans"), Qt::CaseInsensitive));
+
+ QVERIFY(list.contains(QStringView(QString("arthur"))));
+ QVERIFY(!list.contains(QStringView(QString("ArthuR"))));
+ QVERIFY(!list.contains(QStringView(QString("Hans"))));
+ QVERIFY(list.contains(QStringView(QString("arthur")), Qt::CaseInsensitive));
+ QVERIFY(list.contains(QStringView(QString("ArthuR")), Qt::CaseInsensitive));
+ QVERIFY(list.contains(QStringView(QString("ARTHUR")), Qt::CaseInsensitive));
+ QVERIFY(list.contains(QStringView(QString("dent")), Qt::CaseInsensitive));
+ QVERIFY(!list.contains(QStringView(QString("hans")), Qt::CaseInsensitive));
}
void tst_QStringList::removeDuplicates_data()
diff --git a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp b/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp
index 4ae96005d0..e800a0d794 100644
--- a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp
+++ b/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp
@@ -217,6 +217,8 @@ private Q_SLOTS:
#endif
}
+ void comparison();
+
private:
template <typename String>
void conversion_tests(String arg) const;
@@ -615,5 +617,23 @@ void tst_QStringView::conversion_tests(String string) const
}
}
+void tst_QStringView::comparison()
+{
+ const QStringView aa = QStringViewLiteral("aa");
+ const QStringView upperAa = QStringViewLiteral("AA");
+ const QStringView bb = QStringViewLiteral("bb");
+
+ QVERIFY(aa == aa);
+ QVERIFY(aa != bb);
+ QVERIFY(aa < bb);
+ QVERIFY(bb > aa);
+
+ QCOMPARE(aa.compare(aa), 0);
+ QVERIFY(aa.compare(upperAa) != 0);
+ QCOMPARE(aa.compare(upperAa, Qt::CaseInsensitive), 0);
+ QVERIFY(aa.compare(bb) < 0);
+ QVERIFY(bb.compare(aa) > 0);
+}
+
QTEST_APPLESS_MAIN(tst_QStringView)
#include "tst_qstringview.moc"
diff --git a/tests/auto/corelib/tools/qtimeline/BLACKLIST b/tests/auto/corelib/tools/qtimeline/BLACKLIST
index 74f84a4a6d..5611969b4d 100644
--- a/tests/auto/corelib/tools/qtimeline/BLACKLIST
+++ b/tests/auto/corelib/tools/qtimeline/BLACKLIST
@@ -1,7 +1,9 @@
[interpolation]
windows
osx-10.12
+osx-10.13
[duration]
windows
[frameRate]
osx-10.12
+osx-10.13
diff --git a/tests/auto/corelib/tools/qtimezone/qtimezone.pro b/tests/auto/corelib/tools/qtimezone/qtimezone.pro
index 19ebc13306..5ec8d008e7 100644
--- a/tests/auto/corelib/tools/qtimezone/qtimezone.pro
+++ b/tests/auto/corelib/tools/qtimezone/qtimezone.pro
@@ -3,7 +3,7 @@ TARGET = tst_qtimezone
QT = core-private testlib
SOURCES = tst_qtimezone.cpp
qtConfig(icu) {
- DEFINES += QT_USE_ICU
+ QMAKE_USE_PRIVATE += icu
}
darwin {
diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
index ed80d4528d..d335dae7bc 100644
--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
+++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
@@ -31,6 +31,10 @@
#include <private/qtimezoneprivate_p.h>
#include <qlocale.h>
+#if defined(Q_OS_WIN) && !QT_CONFIG(icu)
+# define USING_WIN_TZ
+#endif
+
class tst_QTimeZone : public QObject
{
Q_OBJECT
@@ -413,7 +417,7 @@ void tst_QTimeZone::specificTransition_data()
QTest::addColumn<int>("dstoff");
// Moscow ditched DST on 2010-10-31 but has since changed standard offset twice.
-#ifdef Q_OS_WIN
+#ifdef USING_WIN_TZ
// Win7 is too old to know about this transition:
if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7)
#endif
@@ -477,8 +481,9 @@ void tst_QTimeZone::transitionEachZone_data()
};
QString name;
+ const auto zones = QTimeZone::availableTimeZoneIds();
for (int k = sizeof(table) / sizeof(table[0]); k-- > 0; ) {
- foreach (QByteArray zone, QTimeZone::availableTimeZoneIds()) {
+ for (const QByteArray &zone : zones) {
name.sprintf("%s@%d", zone.constData(), table[k].year);
QTest::newRow(name.toUtf8().constData())
<< zone
@@ -500,7 +505,7 @@ void tst_QTimeZone::transitionEachZone()
QTimeZone named(zone);
for (int i = start; i < stop; i++) {
-#ifdef Q_OS_WIN
+#ifdef USING_WIN_TZ
// See QTBUG-64985: MS's TZ APIs' misdescription of Europe/Samara leads
// to mis-disambiguation of its fall-back here.
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7
@@ -833,7 +838,7 @@ void tst_QTimeZone::utcTest()
void tst_QTimeZone::icuTest()
{
-#if defined(QT_BUILD_INTERNAL) && defined(QT_USE_ICU)
+#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu)
// Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
@@ -881,7 +886,7 @@ void tst_QTimeZone::icuTest()
testCetPrivate(tzp);
testEpochTranPrivate(QIcuTimeZonePrivate("America/Toronto"));
-#endif // QT_USE_ICU
+#endif // icu
}
void tst_QTimeZone::tzTest()
@@ -907,7 +912,7 @@ void tst_QTimeZone::tzTest()
QLocale enUS("en_US");
// Only test names in debug mode, names used can vary by ICU version installed
if (debug) {
-#ifdef QT_USE_ICU
+#if QT_CONFIG(icu)
QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
QString("Central European Standard Time"));
QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
@@ -946,7 +951,7 @@ void tst_QTimeZone::tzTest()
QString("CET"));
QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
QString("CET"));
-#endif // QT_USE_ICU
+#endif // icu
// Test Abbreviations
QCOMPARE(tzp.abbreviation(std), QString("CET"));
@@ -1123,7 +1128,7 @@ void tst_QTimeZone::darwinTypes()
void tst_QTimeZone::winTest()
{
-#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN)
+#if defined(QT_BUILD_INTERNAL) && defined(USING_WIN_TZ)
// Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
@@ -1174,7 +1179,7 @@ void tst_QTimeZone::winTest()
testCetPrivate(tzp);
testEpochTranPrivate(QWinTimeZonePrivate("America/Toronto"));
-#endif // Q_OS_WIN
+#endif // QT_BUILD_INTERNAL && USING_WIN_TZ
}
#ifdef QT_BUILD_INTERNAL
@@ -1286,7 +1291,7 @@ void tst_QTimeZone::testEpochTranPrivate(const QTimeZonePrivate &tzp)
// 1970-04-26 02:00 EST, -5 -> -4
const QDateTime after = QDateTime(QDate(1970, 4, 26), QTime(2, 0), Qt::OffsetFromUTC, -5 * 3600);
const QDateTime found = QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC);
-#ifdef Q_OS_WIN // MS gets the date wrong: 5th April instead of 26th.
+#ifdef USING_WIN_TZ // MS gets the date wrong: 5th April instead of 26th.
QCOMPARE(found.toOffsetFromUtc(-5 * 3600).time(), after.time());
#else
QCOMPARE(found, after);
diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro
index f35ed026ac..f28cf21b8b 100644
--- a/tests/auto/corelib/tools/tools.pro
+++ b/tests/auto/corelib/tools/tools.pro
@@ -30,6 +30,7 @@ SUBDIRS=\
qlist \
qlist_strictiterators \
qlocale \
+ qmakearray \
qmap \
qmap_strictiterators \
qmargins \
diff --git a/tests/auto/dbus/qdbusinterface/qdbusinterface/qdbusinterface.pro b/tests/auto/dbus/qdbusinterface/qdbusinterface/qdbusinterface.pro
index b7dedad133..67709105a6 100644
--- a/tests/auto/dbus/qdbusinterface/qdbusinterface/qdbusinterface.pro
+++ b/tests/auto/dbus/qdbusinterface/qdbusinterface/qdbusinterface.pro
@@ -4,4 +4,11 @@ HEADERS += ../myobject.h
TARGET = ../tst_qdbusinterface
DESTDIR = ./
-QT = core core-private dbus testlib
+QT = core core-private dbus dbus-private testlib
+
+qtConfig(dbus-linked) {
+ DEFINES += QT_LINKED_LIBDBUS
+ QMAKE_USE += dbus
+} else {
+ SOURCES += ../../../../../src/dbus/qdbus_symbols.cpp
+}
diff --git a/tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp b/tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp
index da24429b9e..535d2f756b 100644
--- a/tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp
+++ b/tests/auto/dbus/qdbusinterface/qmyserver/qmyserver.cpp
@@ -115,6 +115,16 @@ public slots:
return obj.m_complexProp;
}
+ bool interactiveAuthorization()
+ {
+ if (message().isInteractiveAuthorizationAllowed())
+ return true;
+
+ sendErrorReply(QStringLiteral("org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"),
+ QStringLiteral("Interactive authentication required."));
+ return false;
+ }
+
void quit()
{
qApp->quit();
diff --git a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
index 5494959aaf..05480c6dd2 100644
--- a/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
+++ b/tests/auto/dbus/qdbusinterface/tst_qdbusinterface.cpp
@@ -33,6 +33,7 @@
#include <QtTest/QtTest>
#include <QtCore/qvariant.h>
#include <QtDBus/QtDBus>
+#include <QtDBus/private/qdbus_symbols_p.h>
#include <qdebug.h>
#include "../qdbusmarshall/common.h"
#include "myobject.h"
@@ -213,6 +214,8 @@ private slots:
void propertyWritePeer();
void complexPropertyReadPeer();
void complexPropertyWritePeer();
+
+ void interactiveAuthorizationRequired();
private:
QProcess proc;
};
@@ -1127,6 +1130,30 @@ void tst_QDBusInterface::complexPropertyWritePeer()
QCOMPARE(complexPropPeer(), arg);
}
+void tst_QDBusInterface::interactiveAuthorizationRequired()
+{
+ int major;
+ int minor;
+ int micro;
+ q_dbus_get_version(&major, &minor, &micro);
+
+ QVersionNumber dbusVersion(major, minor, micro);
+ if (dbusVersion < QVersionNumber(1, 9, 2))
+ QSKIP("Your DBus library is too old to support interactive authorization");
+
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "interactiveAuthorization");
+ QDBusMessage reply = QDBusConnection::sessionBus().call(req);
+
+ QCOMPARE(reply.type(), QDBusMessage::ErrorMessage);
+ QCOMPARE(reply.errorName(), QStringLiteral("org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"));
+
+ req.setInteractiveAuthorizationAllowed(true);
+ reply = QDBusConnection::sessionBus().call(req);
+
+ QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
+ QVERIFY(reply.arguments().at(0).toBool());
+}
+
QTEST_MAIN(tst_QDBusInterface)
#include "tst_qdbusinterface.moc"
diff --git a/tests/auto/gui/gui.pro b/tests/auto/gui/gui.pro
index d7cda11513..e0c8123f26 100644
--- a/tests/auto/gui/gui.pro
+++ b/tests/auto/gui/gui.pro
@@ -14,6 +14,6 @@ SUBDIRS = \
util \
itemmodels \
-!qtConfig(opengl): SUBDIRS -= qopengl qopenglconfig
+!qtConfig(opengl)|winrt: SUBDIRS -= qopengl qopenglconfig
!qtConfig(vulkan): SUBDIRS -= qvulkan
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_utf8_comment.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_utf8_comment.jpg
new file mode 100644
index 0000000000..42b305f5b8
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_utf8_comment.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/qimage.pro b/tests/auto/gui/image/qimage/qimage.pro
index 56618e0bfa..b40866892e 100644
--- a/tests/auto/gui/image/qimage/qimage.pro
+++ b/tests/auto/gui/image/qimage/qimage.pro
@@ -7,4 +7,7 @@ qtConfig(c++11): CONFIG += c++11
android:!android-embedded: RESOURCES += qimage.qrc
+win32:!winrt: LIBS += -lgdi32 -luser32
+darwin: LIBS += -framework CoreGraphics
+
TESTDATA += images/*
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 34b20a5cca..5ffd75f931 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -44,6 +44,10 @@
#include <CoreGraphics/CoreGraphics.h>
#endif
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+# include <qt_windows.h>
+#endif
+
Q_DECLARE_METATYPE(QImage::Format)
Q_DECLARE_METATYPE(Qt::GlobalColor)
@@ -116,6 +120,7 @@ private slots:
void smoothScale2();
void smoothScale3_data();
void smoothScale3();
+ void smoothScale4_data();
void smoothScale4();
void smoothScaleBig();
@@ -192,6 +197,7 @@ private slots:
void exif_QTBUG45865();
void exifInvalidData_data();
void exifInvalidData();
+ void exifReadComments();
void cleanupFunctions();
@@ -224,6 +230,11 @@ private slots:
void convertColorTable();
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+ void toWinHBITMAP_data();
+ void toWinHBITMAP();
+#endif // Q_OS_WIN && !Q_OS_WINRT
+
private:
const QString m_prefix;
};
@@ -281,6 +292,12 @@ static QLatin1String formatToString(QImage::Format format)
return QLatin1String("Alpha8");
case QImage::Format_Grayscale8:
return QLatin1String("Grayscale8");
+ case QImage::Format_RGBX64:
+ return QLatin1String("RGBx64");
+ case QImage::Format_RGBA64:
+ return QLatin1String("RGBA64");
+ case QImage::Format_RGBA64_Premultiplied:
+ return QLatin1String("RGBA64pm");
default:
break;
};
@@ -1665,29 +1682,30 @@ void tst_QImage::smoothScale()
// test area sampling
void tst_QImage::smoothScale2_data()
{
- QTest::addColumn<int>("format");
+ QTest::addColumn<QImage::Format>("format");
QTest::addColumn<int>("size");
int sizes[] = { 2, 3, 4, 6, 7, 8, 10, 16, 20, 32, 40, 64, 100, 101, 128, 0 };
- QImage::Format formats[] = { QImage::Format_RGB32, QImage::Format_ARGB32_Premultiplied, QImage::Format_Invalid };
+ QImage::Format formats[] = { QImage::Format_RGB32, QImage::Format_ARGB32_Premultiplied, QImage::Format_RGBX64, QImage::Format_RGBA64_Premultiplied, QImage::Format_Invalid };
for (int j = 0; formats[j] != QImage::Format_Invalid; ++j) {
- QByteArray formatstr = formats[j] == QImage::Format_RGB32 ? QByteArrayLiteral("rgb32") : QByteArrayLiteral("argb32pm");
+ QString formatstr = formatToString(formats[j]);
for (int i = 0; sizes[i] != 0; ++i) {
const QByteArray sizeB = QByteArray::number(sizes[i]);
- QTest::newRow((formatstr + ' ' + sizeB + 'x' + sizeB).constData())
- << (int)formats[j] << sizes[i];
+ QTest::newRow(QString("%1 %2x%2").arg(formatstr).arg(sizes[i]).toUtf8()) << formats[j] << sizes[i];
}
}
}
void tst_QImage::smoothScale2()
{
- QFETCH(int, format);
+ QFETCH(QImage::Format, format);
QFETCH(int, size);
- QRgb expected = format == QImage::Format_RGB32 ? qRgb(63, 127, 255) : qRgba(31, 63, 127, 127);
+ bool opaque = (format == QImage::Format_RGB32 || format == QImage::Format_RGBX64);
- QImage img(size, size, (QImage::Format)format);
+ QRgb expected = opaque ? qRgb(63, 127, 255) : qRgba(31, 63, 127, 127);
+
+ QImage img(size, size, format);
img.fill(expected);
// scale x down, y down
@@ -1824,21 +1842,31 @@ void tst_QImage::smoothScale3()
}
// Tests smooth upscale is smooth
+void tst_QImage::smoothScale4_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+
+ QTest::newRow("RGB32") << QImage::Format_RGB32;
+ QTest::newRow("RGBx64") << QImage::Format_RGBX64;
+}
+
void tst_QImage::smoothScale4()
{
- QImage img(4, 4, QImage::Format_RGB32);
+ QFETCH(QImage::Format, format);
+ QImage img(4, 4, format);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
img.setPixel(x, y, qRgb(x * 255 / 3, y * 255 / 3, 0));
}
}
QImage scaled = img.scaled(37, 23, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ QCOMPARE(scaled.format(), format);
for (int y = 0; y < scaled.height(); ++y) {
for (int x = 0; x < scaled.width(); ++x) {
if (x > 0)
- QVERIFY(qRed(scaled.pixel(x, y)) >= qRed(scaled.pixel(x - 1, y)));
+ QVERIFY(scaled.pixelColor(x, y).redF() >= scaled.pixelColor(x - 1, y).redF());
if (y > 0)
- QVERIFY(qGreen(scaled.pixel(x, y)) >= qGreen(scaled.pixel(x, y - 1)));
+ QVERIFY(scaled.pixelColor(x, y).greenF() >= scaled.pixelColor(x, y - 1).greenF());
}
}
}
@@ -2337,7 +2365,9 @@ void tst_QImage::rgbSwapped_data()
{
QTest::addColumn<QImage::Format>("format");
- for (int i = QImage::Format_Indexed8; i < QImage::Format_Alpha8; ++i) {
+ for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; ++i) {
+ if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8)
+ continue;
QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i);
}
}
@@ -2505,14 +2535,7 @@ void tst_QImage::mirrored()
void tst_QImage::inplaceRgbSwapped_data()
{
- QTest::addColumn<QImage::Format>("format");
-
- QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied;
- QTest::newRow("Format_RGBA8888") << QImage::Format_RGBA8888;
- QTest::newRow("Format_A2RGB30_Premultiplied") << QImage::Format_A2RGB30_Premultiplied;
- QTest::newRow("Format_RGB888") << QImage::Format_RGB888;
- QTest::newRow("Format_RGB16") << QImage::Format_RGB16;
- QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8;
+ rgbSwapped_data();
}
void tst_QImage::inplaceRgbSwapped()
@@ -2543,9 +2566,9 @@ void tst_QImage::inplaceRgbSwapped()
for (int i = 0; i < imageSwapped.width(); ++i) {
QRgb referenceColor = testColor[i];
QRgb swappedColor = imageSwapped.pixel(i, 0);
- QCOMPARE(qRed(swappedColor) & 0xf8, qBlue(referenceColor) & 0xf8);
- QCOMPARE(qGreen(swappedColor) & 0xf8, qGreen(referenceColor) & 0xf8);
- QCOMPARE(qBlue(swappedColor) & 0xf8, qRed(referenceColor) & 0xf8);
+ QCOMPARE(qRed(swappedColor) & 0xf0, qBlue(referenceColor) & 0xf0);
+ QCOMPARE(qGreen(swappedColor) & 0xf0, qGreen(referenceColor) & 0xf0);
+ QCOMPARE(qBlue(swappedColor) & 0xf0, qRed(referenceColor) & 0xf0);
}
QCOMPARE(imageSwapped.constScanLine(0), orginalPtr);
@@ -2761,9 +2784,13 @@ void tst_QImage::genericRgbConversion_data()
QTest::addColumn<QImage::Format>("format");
QTest::addColumn<QImage::Format>("dest_format");
- for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) {
+ for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
+ if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8)
+ continue;
const QLatin1String formatI = formatToString(QImage::Format(i));
- for (int j = QImage::Format_RGB32; j < QImage::Format_Alpha8; ++j) {
+ for (int j = QImage::Format_RGB32; j < QImage::NImageFormats; ++j) {
+ if (j == QImage::Format_Alpha8 || j == QImage::Format_Grayscale8)
+ continue;
if (i == j)
continue;
QTest::addRow("%s -> %s", formatI.data(), formatToString(QImage::Format(j)).data())
@@ -2800,8 +2827,12 @@ void tst_QImage::inplaceRgbConversion_data()
QTest::addColumn<QImage::Format>("format");
QTest::addColumn<QImage::Format>("dest_format");
- for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) {
- for (int j = QImage::Format_RGB32; j < QImage::Format_Alpha8; ++j) {
+ for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
+ if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8)
+ continue;
+ for (int j = QImage::Format_RGB32; j < QImage::NImageFormats; ++j) {
+ if (j == QImage::Format_Alpha8 || j == QImage::Format_Grayscale8)
+ continue;
if (i == j)
continue;
QTest::addRow("%s -> %s", formatToString(QImage::Format(i)).data(), formatToString(QImage::Format(j)).data())
@@ -2834,10 +2865,10 @@ void tst_QImage::inplaceRgbConversion()
QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16);
}
}
- if (image.depth() == imageConverted.depth())
+ if (qt_depthForFormat(format) == qt_depthForFormat(dest_format))
QCOMPARE(imageConverted.constScanLine(0), originalPtr);
- {
+ if (qt_depthForFormat(format) <= 32) {
// Test attempted inplace conversion of images created on existing buffer
static const quint32 readOnlyData[] = { 0xff0102ffU, 0xff0506ffU, 0xff0910ffU, 0xff1314ffU };
quint32 readWriteData[] = { 0xff0102ffU, 0xff0506ffU, 0xff0910ffU, 0xff1314ffU };
@@ -2970,7 +3001,9 @@ void tst_QImage::invertPixelsRGB_data()
{
QTest::addColumn<QImage::Format>("image_format");
- for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) {
+ for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
+ if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8)
+ continue;
QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i);
}
}
@@ -3068,6 +3101,34 @@ void tst_QImage::exifInvalidData()
QVERIFY(!image.isNull());
}
+void tst_QImage::exifReadComments()
+{
+ QImage image;
+ QVERIFY(image.load(m_prefix + "jpeg_exif_utf8_comment.jpg"));
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.textKeys().size(), 1);
+ QCOMPARE(image.textKeys().first(), "Description");
+ // check if exif comment is read as utf-8
+ QCOMPARE(image.text("Description"), QString::fromUtf8("some unicode chars: ÖÄÜ€@"));
+
+ QByteArray ba;
+ {
+ QBuffer buf(&ba);
+ QVERIFY(buf.open(QIODevice::WriteOnly));
+ QVERIFY(image.save(&buf, "JPG"));
+ }
+ QVERIFY(!ba.isEmpty());
+ image = QImage();
+ QCOMPARE(image.textKeys().size(), 0);
+ {
+ QBuffer buf(&ba);
+ QVERIFY(buf.open(QIODevice::ReadOnly));
+ QVERIFY(image.load(&buf, "JPG"));
+ }
+ // compare written (and reread) description text
+ QCOMPARE(image.text("Description"), QString::fromUtf8("some unicode chars: ÖÄÜ€@"));
+}
+
static void cleanupFunction(void* info)
{
bool *called = static_cast<bool*>(info);
@@ -3473,5 +3534,108 @@ void tst_QImage::convertColorTable()
QCOMPARE(rgb32.pixel(0,0), 0xffffffff);
}
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &p, int hbitmapFormat = 0);
+Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
+QT_END_NAMESPACE
+
+static inline QColor COLORREFToQColor(COLORREF cr)
+{
+ return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr));
+}
+
+void tst_QImage::toWinHBITMAP_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<QColor>("color");
+ QTest::addColumn<QColor>("bottomRightColor");
+
+ const QColor red(Qt::red);
+ const QColor green(Qt::green);
+ const QColor blue(Qt::blue);
+ const QColor gray(Qt::gray);
+ const QColor gray555(0x5a, 0x5a, 0x5a); // Note: Interpolation 8<->5 bit occurs.
+ const QColor white(Qt::white);
+ const QColor black(Qt::black);
+
+ QTest::newRow("argb32p-red") << QImage::Format_ARGB32_Premultiplied << red << gray;
+ QTest::newRow("argb32p-green") << QImage::Format_ARGB32_Premultiplied << green << gray;
+ QTest::newRow("argb32p-blue") << QImage::Format_ARGB32_Premultiplied << blue << gray;
+ QTest::newRow("rgb888-red") << QImage::Format_RGB888 << red << gray;
+ QTest::newRow("rgb888-green") << QImage::Format_RGB888 << green << gray;
+ QTest::newRow("rgb888-blue") << QImage::Format_RGB888 << blue << gray;
+ QTest::newRow("indexed8-red") << QImage::Format_Indexed8 << red << gray;
+ QTest::newRow("indexed8-green") << QImage::Format_Indexed8 << green << gray;
+ QTest::newRow("indexed8-blue") << QImage::Format_Indexed8 << blue << gray;
+ QTest::newRow("rgb555-red") << QImage::Format_RGB555 << red << gray555;
+ QTest::newRow("rgb555-green") << QImage::Format_RGB555 << green << gray555;
+ QTest::newRow("rgb555-blue") << QImage::Format_RGB555 << blue << gray555;
+ QTest::newRow("mono") << QImage::Format_Mono << white << black;
+}
+
+// Test image filled with color, black pixel at botttom right corner.
+static inline QImage createTestImage(QImage::Format format, int width, int height,
+ const QColor &fillColor, const QColor &bottomRightColor)
+{
+ QImage image(QSize(width, height), format);
+ image.fill(fillColor);
+ QPainter painter(&image);
+ QPen pen = painter.pen();
+ pen.setColor(bottomRightColor);
+ painter.setPen(pen);
+ painter.drawPoint(width -1, height - 1);
+ return image;
+}
+
+void tst_QImage::toWinHBITMAP()
+{
+ static const int width = 73;
+ static const int height = 57;
+
+ QFETCH(QImage::Format, format);
+ QFETCH(QColor, color);
+ QFETCH(QColor, bottomRightColor);
+
+ // Cannot paint on indexed/mono images.
+ const QImage image = format == QImage::Format_Indexed8 || format == QImage::Format_Mono
+ ? createTestImage(QImage::Format_RGB32, width, height, color, bottomRightColor).convertToFormat(format)
+ : createTestImage(format, width, height, color, bottomRightColor);
+
+ const HBITMAP bitmap = qt_imageToWinHBITMAP(image);
+
+ QVERIFY(bitmap != 0);
+
+ // Verify size
+ BITMAP bitmapInfo;
+ memset(&bitmapInfo, 0, sizeof(BITMAP));
+
+ const int res = GetObject(bitmap, sizeof(BITMAP), &bitmapInfo);
+ QVERIFY(res);
+ QCOMPARE(width, int(bitmapInfo.bmWidth));
+ QCOMPARE(height, int(bitmapInfo.bmHeight));
+
+ const HDC displayDc = GetDC(0);
+ const HDC bitmapDc = CreateCompatibleDC(displayDc);
+
+ const HBITMAP nullBitmap = static_cast<HBITMAP>(SelectObject(bitmapDc, bitmap));
+
+ QCOMPARE(COLORREFToQColor(GetPixel(bitmapDc, 0, 0)), color);
+ QCOMPARE(COLORREFToQColor(GetPixel(bitmapDc, width - 1, 3)), color);
+ QCOMPARE(COLORREFToQColor(GetPixel(bitmapDc, 3, height - 1)), color);
+ QCOMPARE(COLORREFToQColor(GetPixel(bitmapDc, width - 1, height - 1)), bottomRightColor);
+
+ const QImage convertedBack = qt_imageFromWinHBITMAP(bitmap);
+ QCOMPARE(convertedBack.convertToFormat(QImage::Format_ARGB32_Premultiplied),
+ image.convertToFormat(QImage::Format_ARGB32_Premultiplied));
+
+ // Clean up
+ SelectObject(bitmapDc, nullBitmap);
+ DeleteObject(bitmap);
+ DeleteDC(bitmapDc);
+ ReleaseDC(0, displayDc);
+}
+#endif // Q_OS_WIN && !Q_OS_WINRT
+
QTEST_GUILESS_MAIN(tst_QImage)
#include "tst_qimage.moc"
diff --git a/tests/auto/gui/image/qimagereader/images/basn0g16.png b/tests/auto/gui/image/qimagereader/images/basn0g16.png
new file mode 100644
index 0000000000..318ebcadf4
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/basn0g16.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/images/basn2c16.png b/tests/auto/gui/image/qimagereader/images/basn2c16.png
new file mode 100644
index 0000000000..1bd4a4d0e2
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/basn2c16.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/images/basn4a16.png b/tests/auto/gui/image/qimagereader/images/basn4a16.png
new file mode 100644
index 0000000000..6dbee9fbdb
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/basn4a16.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/images/basn6a16.png b/tests/auto/gui/image/qimagereader/images/basn6a16.png
new file mode 100644
index 0000000000..a9bf3cb461
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/basn6a16.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/images/kollada-16bpc.png b/tests/auto/gui/image/qimagereader/images/kollada-16bpc.png
new file mode 100644
index 0000000000..b99d5f8a6f
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/kollada-16bpc.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/images/tbwn0g16.png b/tests/auto/gui/image/qimagereader/images/tbwn0g16.png
new file mode 100644
index 0000000000..99bdeed2b3
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/tbwn0g16.png
Binary files differ
diff --git a/tests/auto/gui/image/qimagereader/qimagereader.pro b/tests/auto/gui/image/qimagereader/qimagereader.pro
index b06f56dddf..623d45ffe2 100644
--- a/tests/auto/gui/image/qimagereader/qimagereader.pro
+++ b/tests/auto/gui/image/qimagereader/qimagereader.pro
@@ -3,7 +3,8 @@ TARGET = tst_qimagereader
SOURCES += tst_qimagereader.cpp
MOC_DIR=tmp
QT += core-private gui-private network testlib
-RESOURCES += qimagereader.qrc
+
+RESOURCES += $$files(images/*)
android:!android-embedded {
RESOURCES += android_testdata.qrc
diff --git a/tests/auto/gui/image/qimagereader/qimagereader.qrc b/tests/auto/gui/image/qimagereader/qimagereader.qrc
deleted file mode 100644
index 2522154b1f..0000000000
--- a/tests/auto/gui/image/qimagereader/qimagereader.qrc
+++ /dev/null
@@ -1,69 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>images/16bpp.bmp</file>
- <file>images/4bpp-rle.bmp</file>
- <file>images/YCbCr_cmyk.jpg</file>
- <file>images/YCbCr_cmyk.png</file>
- <file>images/YCbCr_rgb.jpg</file>
- <file>images/away.png</file>
- <file>images/bat1.gif</file>
- <file>images/bat2.gif</file>
- <file>images/beavis.jpg</file>
- <file>images/black.png</file>
- <file>images/black.xpm</file>
- <file>images/colorful.bmp</file>
- <file>images/corrupt-colors.xpm</file>
- <file>images/corrupt-pixels.xpm</file>
- <file>images/corrupt.bmp</file>
- <file>images/corrupt.gif</file>
- <file>images/corrupt.jpg</file>
- <file>images/corrupt.png</file>
- <file>images/corrupt.xbm</file>
- <file>images/crash-signed-char.bmp</file>
- <file>images/earth.gif</file>
- <file>images/font.bmp</file>
- <file>images/gnus.xbm</file>
- <file>images/image.pbm</file>
- <file>images/image.pgm</file>
- <file>images/image.png</file>
- <file>images/image.ppm</file>
- <file>images/kollada.png</file>
- <file>images/marble.xpm</file>
- <file>images/namedcolors.xpm</file>
- <file>images/negativeheight.bmp</file>
- <file>images/noclearcode.bmp</file>
- <file>images/noclearcode.gif</file>
- <file>images/nontransparent.xpm</file>
- <file>images/rgb32bf.bmp</file>
- <file>images/runners.ppm</file>
- <file>images/teapot.ppm</file>
- <file>images/test.ppm</file>
- <file>images/test.xpm</file>
- <file>images/test32bfv4.bmp</file>
- <file>images/test32v5.bmp</file>
- <file>images/tst7.bmp</file>
- <file>images/tst7.png</file>
- <file>images/transparent.xpm</file>
- <file>images/trolltech.gif</file>
- <file>images/qt.gif</file>
- <file>images/qt1.gif</file>
- <file>images/qt2.gif</file>
- <file>images/qt3.gif</file>
- <file>images/qt4.gif</file>
- <file>images/qt5.gif</file>
- <file>images/qt6.gif</file>
- <file>images/qt7.gif</file>
- <file>images/qt8.gif</file>
- <file>images/endless-anim.gif</file>
- <file>images/four-frames.gif</file>
- <file>images/qt-gif-anim.gif</file>
- <file>images/qt-gif-noanim.gif</file>
- <file>images/rect.svg</file>
- <file>images/rect.svgz</file>
- <file>images/corrupt.svg</file>
- <file>images/corrupt.svgz</file>
- <file>images/qtbug13653-no_eoi.jpg</file>
- <file>images/txts.jpg</file>
- <file>images/txts.png</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 170f551dbf..aa9a990fef 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -234,6 +234,7 @@ void tst_QImageReader::readImage_data()
QTest::newRow("BMP: high mask bit set") << QString("rgb32bf.bmp") << true << QByteArray("bmp");
QTest::newRow("XPM: marble") << QString("marble.xpm") << true << QByteArray("xpm");
QTest::newRow("PNG: kollada") << QString("kollada.png") << true << QByteArray("png");
+ QTest::newRow("PNG: kollada 16bpc") << QString("kollada-16bpc.png") << true << QByteArray("png");
QTest::newRow("PPM: teapot") << QString("teapot.ppm") << true << QByteArray("ppm");
QTest::newRow("PPM: runners") << QString("runners.ppm") << true << QByteArray("ppm");
QTest::newRow("PPM: test") << QString("test.ppm") << true << QByteArray("ppm");
@@ -523,6 +524,12 @@ void tst_QImageReader::imageFormat_data()
QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp") << QImage::Format_RGB32;
QTest::newRow("png") << QString("kollada.png") << QByteArray("png") << QImage::Format_ARGB32;
QTest::newRow("png-2") << QString("YCbCr_cmyk.png") << QByteArray("png") << QImage::Format_RGB32;
+ QTest::newRow("png-3") << QString("kollada-16bpc.png") << QByteArray("png") << QImage::Format_RGBA64;
+ QTest::newRow("png-4") << QString("basn0g16.png") << QByteArray("png") << QImage::Format_RGBX64; // Grayscale16
+ QTest::newRow("png-5") << QString("basn2c16.png") << QByteArray("png") << QImage::Format_RGBX64;
+ QTest::newRow("png-6") << QString("basn4a16.png") << QByteArray("png") << QImage::Format_RGBA64; // Grayscale16Alpha16
+ QTest::newRow("png-7") << QString("basn6a16.png") << QByteArray("png") << QImage::Format_RGBA64;
+ QTest::newRow("png-8") << QString("tbwn0g16.png") << QByteArray("png") << QImage::Format_RGBA64; // Grayscale16+tRNS
QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg") << QImage::Format_ARGB32_Premultiplied;
QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz") << QImage::Format_ARGB32_Premultiplied;
}
@@ -1850,6 +1857,8 @@ void tst_QImageReader::saveFormat_data()
QTest::newRow("Format_RGB888") << QImage::Format_RGB888;
QTest::newRow("Format_RGB444") << QImage::Format_RGB444;
QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied;
+ QTest::newRow("Format_RGBA64") << QImage::Format_RGBA64;
+ QTest::newRow("Format_RGBA64_Premultiplied") << QImage::Format_RGBA64_Premultiplied;
}
void tst_QImageReader::saveFormat()
diff --git a/tests/auto/gui/image/qpicture/qpicture.pro b/tests/auto/gui/image/qpicture/qpicture.pro
index 0fc851ce11..7f967f33b9 100644
--- a/tests/auto/gui/image/qpicture/qpicture.pro
+++ b/tests/auto/gui/image/qpicture/qpicture.pro
@@ -1,7 +1,6 @@
CONFIG += testcase
TARGET = tst_qpicture
QT += testlib
-qtHaveModule(widgets): QT += widgets
SOURCES += tst_qpicture.cpp
diff --git a/tests/auto/gui/image/qpicture/tst_qpicture.cpp b/tests/auto/gui/image/qpicture/tst_qpicture.cpp
index 5c812fd1b2..ec6bb8dcee 100644
--- a/tests/auto/gui/image/qpicture/tst_qpicture.cpp
+++ b/tests/auto/gui/image/qpicture/tst_qpicture.cpp
@@ -33,10 +33,8 @@
#include <qpainter.h>
#include <qimage.h>
#include <qpaintengine.h>
-#ifndef QT_NO_WIDGETS
-#include <qdesktopwidget.h>
-#include <qapplication.h>
-#endif
+#include <qguiapplication.h>
+#include <qscreen.h>
#include <limits.h>
class tst_QPicture : public QObject
@@ -53,11 +51,7 @@ private slots:
void boundingRect();
void swap();
void serialization();
-
-#ifndef QT_NO_WIDGETS
void save_restore();
-#endif
-
void boundaryValues_data();
void boundaryValues();
};
@@ -244,30 +238,23 @@ void tst_QPicture::serialization()
}
}
-
-#ifndef QT_NO_WIDGETS
-static QPointF scalePoint(const QPointF &point, QPaintDevice *sourceDevice, QPaintDevice *destDevice)
-{
- return QPointF(point.x() * qreal(destDevice->logicalDpiX()) / qreal(sourceDevice->logicalDpiX()),
- point.y() * qreal(destDevice->logicalDpiY()) / qreal(sourceDevice->logicalDpiY()));
-}
-
-static QRectF scaleRect(const QRectF &rect, QPaintDevice *sourceDevice, QPaintDevice *destDevice)
+static QRectF scaleRect(const QRectF &rect, qreal xf, qreal yf)
{
- return QRectF(rect.left() * qreal(destDevice->logicalDpiX()) / qreal(sourceDevice->logicalDpiX()),
- rect.top() * qreal(destDevice->logicalDpiY()) / qreal(sourceDevice->logicalDpiY()),
- rect.width() * qreal(destDevice->logicalDpiX()) / qreal(sourceDevice->logicalDpiX()),
- rect.height() * qreal(destDevice->logicalDpiY()) / qreal(sourceDevice->logicalDpiY()));
+ return QRectF(rect.left() * xf, rect.top() * yf, rect.width() * xf, rect.height() * yf);
}
static void paintStuff(QPainter *p)
{
- QPaintDevice *screenDevice = QApplication::desktop();
- p->drawRect(scaleRect(QRectF(100, 100, 100, 100), screenDevice, p->device()));
+ const QScreen *screen = QGuiApplication::primaryScreen();
+ // Calculate factors from the screen resolution against QPicture's 96DPI
+ // (enforced by Qt::AA_Use96Dpi as set by QTEST_MAIN).
+ const qreal xf = qreal(p->device()->logicalDpiX()) / screen->logicalDotsPerInchX();
+ const qreal yf = qreal(p->device()->logicalDpiY()) / screen->logicalDotsPerInchY();
+ p->drawRect(scaleRect(QRectF(100, 100, 100, 100), xf, yf));
p->save();
- p->translate(scalePoint(QPointF(10, 10), screenDevice, p->device()));
+ p->translate(10 * xf, 10 * yf);
p->restore();
- p->drawRect(scaleRect(QRectF(100, 100, 100, 100), screenDevice, p->device()));
+ p->drawRect(scaleRect(QRectF(100, 100, 100, 100), xf, yf));
}
/* See task: 41469
@@ -298,7 +285,6 @@ void tst_QPicture::save_restore()
QVERIFY( pix1.toImage() == pix2.toImage() );
}
-#endif
void tst_QPicture::boundaryValues_data()
{
diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
index e3bda6c2df..9a338ad55a 100644
--- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
@@ -90,6 +90,7 @@ private slots:
void mask();
void bitmapMask();
+ void bitmapFromImageRvalue();
void setGetMask_data();
void setGetMask();
void cacheKey();
@@ -596,6 +597,27 @@ void tst_QPixmap::bitmapMask()
QVERIFY(image.pixel(1, 1));
}
+void tst_QPixmap::bitmapFromImageRvalue()
+{
+ auto makeImage = [](){
+ QImage image(3, 3, QImage::Format_MonoLSB);
+ image.setColor(0, Qt::color0);
+ image.setColor(1, Qt::color1);
+ image.fill(Qt::color0);
+ image.setPixel(1, 1, Qt::color1);
+ image.setPixel(0, 0, Qt::color1);
+ return image;
+ };
+
+ auto image1 = makeImage();
+ auto image2 = makeImage();
+ auto bitmap1 = QBitmap::fromImage(image1);
+ auto bitmap2 = QBitmap::fromImage(std::move(image2));
+ QCOMPARE(bitmap1.toImage(), bitmap2.toImage());
+ QVERIFY(!image1.isNull());
+ QVERIFY(image2.isNull());
+}
+
void tst_QPixmap::setGetMask_data()
{
QTest::addColumn<QPixmap>("pixmap");
diff --git a/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp
index 8a2a35f86c..158530428d 100644
--- a/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp
+++ b/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp
@@ -92,6 +92,9 @@ void tst_QPixmapCache::cacheLimit()
// it was between 2048 and 10240 last time I looked at it
QVERIFY(originalCacheLimit >= 1024 && originalCacheLimit <= 20480);
+ QPixmapCache::setCacheLimit(std::numeric_limits<int>::max());
+ QCOMPARE(QPixmapCache::cacheLimit(), std::numeric_limits<int>::max());
+
QPixmapCache::setCacheLimit(100);
QCOMPARE(QPixmapCache::cacheLimit(), 100);
diff --git a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp
index a45539a041..d19aa9b54f 100644
--- a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp
+++ b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp
@@ -69,8 +69,20 @@ private slots:
void sortChildren();
void subclassing();
void lessThan();
+ void clearData();
};
+void tst_QStandardItem::clearData()
+{
+ QStandardItem item;
+ item.setData(QStringLiteral("Test"), Qt::EditRole);
+ item.setData(5, Qt::UserRole);
+ item.clearData();
+ QCOMPARE(item.data(Qt::EditRole), QVariant());
+ QCOMPARE(item.data(Qt::UserRole), QVariant());
+ QCOMPARE(item.data(Qt::DisplayRole), QVariant());
+}
+
void tst_QStandardItem::ctor()
{
QStandardItem item;
diff --git a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
index 9399ebce34..e2d7a41bd1 100644
--- a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
+++ b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
@@ -98,6 +98,7 @@ private slots:
void checkChildren();
void data();
void clear();
+ void clearItemData();
void sort_data();
void sort();
void sortRole_data();
@@ -749,7 +750,32 @@ void tst_QStandardItemModel::data()
QCOMPARE(m_model->data(m_model->index(0, 0), Qt::DisplayRole).toString(), QLatin1String("initialitem"));
QCOMPARE(m_model->data(m_model->index(0, 0), Qt::ToolTipRole).toString(), QLatin1String("tooltip"));
+ const QMap<int, QVariant> itmData = m_model->itemData(m_model->index(0, 0));
+ QCOMPARE(itmData.value(Qt::DisplayRole), QLatin1String("initialitem"));
+ QCOMPARE(itmData.value(Qt::ToolTipRole), QLatin1String("tooltip"));
+ QVERIFY(!itmData.contains(Qt::UserRole - 1));
+ QVERIFY(m_model->itemData(QModelIndex()).isEmpty());
+}
+void tst_QStandardItemModel::clearItemData()
+{
+ currentRoles.clear();
+ QVERIFY(!m_model->clearItemData(QModelIndex()));
+ QCOMPARE(currentRoles, {});
+ const QModelIndex idx = m_model->index(0, 0);
+ const QMap<int, QVariant> oldData = m_model->itemData(idx);
+ m_model->setData(idx, QLatin1String("initialitem"), Qt::DisplayRole);
+ m_model->setData(idx, QLatin1String("tooltip"), Qt::ToolTipRole);
+ m_model->setData(idx, 5, Qt::UserRole);
+ currentRoles.clear();
+ QVERIFY(m_model->clearItemData(idx));
+ QCOMPARE(idx.data(Qt::UserRole), QVariant());
+ QCOMPARE(idx.data(Qt::ToolTipRole), QVariant());
+ QCOMPARE(idx.data(Qt::DisplayRole), QVariant());
+ QCOMPARE(idx.data(Qt::EditRole), QVariant());
+ QCOMPARE(currentRoles, {});
+ m_model->setItemData(idx, oldData);
+ currentRoles.clear();
}
void tst_QStandardItemModel::clear()
diff --git a/tests/auto/gui/kernel/qguiapplication/BLACKLIST b/tests/auto/gui/kernel/qguiapplication/BLACKLIST
new file mode 100644
index 0000000000..9a670237b7
--- /dev/null
+++ b/tests/auto/gui/kernel/qguiapplication/BLACKLIST
@@ -0,0 +1,4 @@
+[focusObject]
+opensuse
+opensuse-leap
+ubuntu
diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
index fc011d726d..a304981cd1 100644
--- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
+++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
@@ -374,6 +374,9 @@ public:
void tst_QGuiApplication::changeFocusWindow()
{
+#ifdef Q_OS_WINRT
+ QSKIP("WinRt does not support multiple native windows.");
+#endif
int argc = 0;
QGuiApplication app(argc, 0);
@@ -594,6 +597,9 @@ public:
void tst_QGuiApplication::modalWindow()
{
+#ifdef Q_OS_WINRT
+ QSKIP("WinRt does not support multiple native windows.");
+#endif
int argc = 0;
QGuiApplication app(argc, 0);
const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry();
diff --git a/tests/auto/gui/kernel/qpalette/tst_qpalette.cpp b/tests/auto/gui/kernel/qpalette/tst_qpalette.cpp
index ca6f677ba6..a0ac1b3631 100644
--- a/tests/auto/gui/kernel/qpalette/tst_qpalette.cpp
+++ b/tests/auto/gui/kernel/qpalette/tst_qpalette.cpp
@@ -67,9 +67,10 @@ void tst_QPalette::roleValues_data()
QTest::newRow("QPalette::NoRole") << int(QPalette::NoRole) << 17;
QTest::newRow("QPalette::ToolTipBase") << int(QPalette::ToolTipBase) << 18;
QTest::newRow("QPalette::ToolTipText") << int(QPalette::ToolTipText) << 19;
+ QTest::newRow("QPalette::PlaceholderText") << int(QPalette::PlaceholderText) << 20;
// Change this value as you add more roles.
- QTest::newRow("QPalette::NColorRoles") << int(QPalette::NColorRoles) << 20;
+ QTest::newRow("QPalette::NColorRoles") << int(QPalette::NColorRoles) << 21;
}
void tst_QPalette::roleValues()
diff --git a/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro b/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro
index b1e3c10724..8506a005bc 100644
--- a/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro
+++ b/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro
@@ -1,5 +1,4 @@
CONFIG += testcase
-osx: CONFIG += insignificant_test # QTBUG-46266, crashes
SOURCES=tst_qtouchevent.cpp
TARGET=tst_qtouchevent
QT += testlib widgets gui-private
diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST
index df02b5b33e..e9a0d44ba7 100644
--- a/tests/auto/gui/kernel/qwindow/BLACKLIST
+++ b/tests/auto/gui/kernel/qwindow/BLACKLIST
@@ -1,12 +1,14 @@
[positioning:default]
linux
osx-10.12 ci
+winrt
[positioning:fake]
osx-10.12 ci
[modalWithChildWindow]
ubuntu-16.04
# QTBUG-66851
opensuse
+opensuse-leap
# QTBUG-69160
android
[setVisible]
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index 722405377e..7c24bbaadd 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -48,6 +48,12 @@
Q_DECLARE_METATYPE(Qt::ScreenOrientation)
Q_DECLARE_METATYPE(QWindow::Visibility)
+static bool isPlatformWinRT()
+{
+ static const bool isWinRT = !QGuiApplication::platformName().compare(QLatin1String("winrt"), Qt::CaseInsensitive);
+ return isWinRT;
+}
+
class tst_QWindow: public QObject
{
Q_OBJECT
@@ -97,6 +103,7 @@ private slots:
void modalWindowPosition();
#ifndef QT_NO_CURSOR
void modalWindowEnterEventOnHide_QTBUG35109();
+ void spuriousMouseMove();
#endif
void windowsTransientChildren();
void requestUpdate();
@@ -234,6 +241,8 @@ void tst_QWindow::setVisible()
QVERIFY(h.handle());
i.setParent(&h);
QVERIFY2(i.handle(), "Making a visible but not created child window child of a created window should create it");
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "Child windows are unsupported on winrt", Continue);
QVERIFY(QTest::qWaitForWindowExposed(&i));
}
@@ -398,11 +407,15 @@ void tst_QWindow::resizeEventAfterResize()
// Make sure we get a resizeEvent after calling resize
window.resize(m_testWindowSize);
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "Winrt windows are fullscreen by default.", Continue);
QTRY_COMPARE(window.received(QEvent::Resize), 2);
}
void tst_QWindow::exposeEventOnShrink_QTBUG54040()
{
+ if (isPlatformWinRT())
+ QSKIP("", "WinRT does not support non-maximized/non-fullscreen top level windows. QTBUG-54528", Continue);
Window window;
window.setGeometry(QRect(m_availableTopLeft + QPoint(80, 80), m_testWindowSize));
window.setTitle(QTest::currentTestFunction());
@@ -479,7 +492,7 @@ void tst_QWindow::positioning()
}
if (isPlatformWayland())
- QSKIP("Wayland: This fails. Figure out why.");
+ QSKIP("Wayland: This fails. See QTBUG-68660.");
// Some platforms enforce minimum widths for windows, which can cause extra resize
// events, so set the width to suitably large value to avoid those.
@@ -590,6 +603,8 @@ void tst_QWindow::childWindowPositioning()
{
if (isPlatformWayland())
QSKIP("Wayland: This is flaky (protocol errors for xdg-shell v6). See QTBUG-67648.");
+ else if (isPlatformWinRT())
+ QSKIP("WinRT does not support child windows.");
const QPoint topLeftOrigin(0, 0);
@@ -787,11 +802,10 @@ void tst_QWindow::isExposed()
window.hide();
- if (isPlatformWayland())
- QSKIP("Wayland: This is flaky. Figure out why.");
-
QCoreApplication::processEvents();
QTRY_VERIFY(window.received(QEvent::Expose) > 1);
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT does not destroy the window. Figure out why. QTBUG-68297", Continue);
QTRY_VERIFY(!window.isExposed());
}
@@ -825,6 +839,8 @@ void tst_QWindow::isActive()
child.setGeometry(10, 10, 20, 20);
child.show();
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT does not support native child windows.", Abort);
QTRY_VERIFY(child.isExposed());
child.requestActivate();
@@ -895,7 +911,7 @@ void tst_QWindow::isActive()
QVERIFY(child.isActive());
}
-class InputTestWindow : public QWindow
+class InputTestWindow : public ColoredWindow
{
public:
void keyPressEvent(QKeyEvent *event) {
@@ -989,7 +1005,9 @@ public:
enterEventCount = leaveEventCount = 0;
}
- InputTestWindow() {
+ explicit InputTestWindow(const QColor &color = Qt::white, QWindow *parent = nullptr)
+ : ColoredWindow(color, parent)
+ {
keyPressCode = keyReleaseCode = 0;
mousePressButton = mouseReleaseButton = mouseMoveButton = 0;
ignoreMouse = ignoreTouch = false;
@@ -1843,7 +1861,7 @@ void tst_QWindow::mask()
void tst_QWindow::initialSize()
{
if (isPlatformWayland())
- QSKIP("Wayland: This fails. Figure out why.");
+ QSKIP("Wayland: This fails. See QTBUG-66818.");
QSize defaultSize(0,0);
{
@@ -1857,6 +1875,8 @@ void tst_QWindow::initialSize()
Window w;
w.setWidth(m_testWindowSize.width());
w.showNormal();
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT shows windows as fullscreen by default.", Continue);
QTRY_COMPARE(w.width(), m_testWindowSize.width());
QTRY_VERIFY(w.height() > 0);
}
@@ -1867,6 +1887,8 @@ void tst_QWindow::initialSize()
w.showNormal();
const QSize expectedSize = testSize;
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT shows windows as fullscreen by default.", Continue);
QTRY_COMPARE(w.size(), expectedSize);
}
}
@@ -1910,13 +1932,15 @@ void tst_QWindow::modalDialog()
return;
}
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT only support one native window.", Continue);
QTRY_COMPARE(QGuiApplication::focusWindow(), &dialog);
}
void tst_QWindow::modalDialogClosingOneOfTwoModal()
{
- if (isPlatformWayland())
- QSKIP("Wayland: This fails. Figure out why.");
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("QWindow::requestActivate() is not supported.");
QWindow normalWindow;
normalWindow.setFramePosition(m_availableTopLeft + QPoint(80, 80));
@@ -1955,6 +1979,8 @@ void tst_QWindow::modalDialogClosingOneOfTwoModal()
return;
}
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT only support one native window.", Continue);
QTRY_COMPARE(QGuiApplication::focusWindow(), &first_dialog);
}
@@ -1982,6 +2008,8 @@ void tst_QWindow::modalWithChildWindow()
tlw_dialog.show();
QVERIFY(QTest::qWaitForWindowExposed(&tlw_dialog));
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT only support one native window.", Abort);
QVERIFY(QTest::qWaitForWindowExposed(&sub_window));
QTRY_COMPARE(QGuiApplication::focusWindow(), &tlw_dialog);
@@ -2034,6 +2062,8 @@ void tst_QWindow::modalWindowPosition()
window.setModality(Qt::WindowModal);
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT windows are fullscreen by default.", Continue);
QCOMPARE(window.geometry(), origGeo);
}
@@ -2094,6 +2124,9 @@ void tst_QWindow::modalWindowEnterEventOnHide_QTBUG35109()
root.resetCounters();
modal.close();
+ if (isPlatformWinRT())
+ QEXPECT_FAIL("", "WinRT does not trigger the enter event correctly"
+ "- QTBUG-68297.", Abort);
// Check for the enter event
QTRY_COMPARE(root.enterEventCount, 1);
}
@@ -2213,7 +2246,53 @@ void tst_QWindow::modalWindowEnterEventOnHide_QTBUG35109()
QTRY_COMPARE(root.enterEventCount, 1);
}
}
-#endif
+
+// Verify that no spurious mouse move events are received. On Windows, there is
+// no enter event, the OS sends mouse move events instead. Test that the QPA
+// plugin properly suppresses those since they can interfere with tests.
+// Simulate a main window setup with a modal dialog on top, keep the cursor
+// in the center and check that no mouse events are recorded.
+void tst_QWindow::spuriousMouseMove()
+{
+ const QString &platformName = QGuiApplication::platformName();
+ if (platformName == QLatin1String("offscreen") || platformName == QLatin1String("cocoa"))
+ QSKIP("No enter events sent");
+ if (isPlatformWayland() || isPlatformWinRT())
+ QSKIP("QCursor::setPos() is not supported on this platform");
+ const QRect screenGeometry = QGuiApplication::primaryScreen()->geometry();
+ const QPoint center = screenGeometry.center();
+ QCursor::setPos(center);
+ QRect windowGeometry(QPoint(), 2 * m_testWindowSize);
+ windowGeometry.moveCenter(center);
+ QTRY_COMPARE(QCursor::pos(), center);
+ InputTestWindow topLevel;
+ topLevel.setTitle(QTest::currentTestFunction());
+ topLevel.setGeometry(windowGeometry);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ QTRY_VERIFY(topLevel.enterEventCount > 0);
+ InputTestWindow dialog(Qt::yellow);
+ dialog.setTransientParent(&topLevel);
+ dialog.setTitle("Dialog " + topLevel.title());
+ dialog.setModality(Qt::ApplicationModal);
+ windowGeometry.setSize(m_testWindowSize);
+ windowGeometry.moveCenter(center);
+ dialog.setGeometry(windowGeometry);
+ dialog.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&dialog));
+ QTRY_VERIFY(dialog.enterEventCount > 0);
+ dialog.setVisible(false);
+ QCOMPARE(dialog.mousePressedCount, 0);
+ QCOMPARE(dialog.mouseReleasedCount, 0);
+ QCOMPARE(dialog.mouseMovedCount, 0);
+ QCOMPARE(dialog.mouseDoubleClickedCount, 0);
+ topLevel.setVisible(false);
+ QCOMPARE(topLevel.mousePressedCount, 0);
+ QCOMPARE(topLevel.mouseReleasedCount, 0);
+ QCOMPARE(topLevel.mouseMovedCount, 0);
+ QCOMPARE(topLevel.mouseDoubleClickedCount, 0);
+}
+#endif // !QT_NO_CURSOR
static bool isNativeWindowVisible(const QWindow *window)
{
diff --git a/tests/auto/gui/painting/qbrush/tst_qbrush.cpp b/tests/auto/gui/painting/qbrush/tst_qbrush.cpp
index 9098bb0f6e..cd3eaa1478 100644
--- a/tests/auto/gui/painting/qbrush/tst_qbrush.cpp
+++ b/tests/auto/gui/painting/qbrush/tst_qbrush.cpp
@@ -58,6 +58,7 @@ private slots:
void testQGradientCopyConstructor();
void gradientStops();
+ void gradientPresets();
void textures();
@@ -326,6 +327,26 @@ void tst_QBrush::gradientStops()
QCOMPARE(gradient.stops().at(0).second, QColor());
}
+void tst_QBrush::gradientPresets()
+{
+ QGradient gradient(QGradient::WarmFlame);
+ QCOMPARE(gradient.type(), QGradient::LinearGradient);
+ QCOMPARE(gradient.coordinateMode(), QGradient::ObjectMode);
+
+ QLinearGradient *lg = static_cast<QLinearGradient *>(&gradient);
+ QCOMPARE(lg->start(), QPointF(0, 1));
+ QCOMPARE(lg->finalStop(), QPointF(1, 0));
+
+ QCOMPARE(lg->stops().size(), 3);
+ QCOMPARE(lg->stops().at(0), QGradientStop(0, QColor(QLatin1Literal("#ff9a9e"))));
+ QCOMPARE(lg->stops().at(1), QGradientStop(0.99, QColor(QLatin1Literal("#fad0c4"))));
+ QCOMPARE(lg->stops().at(2), QGradientStop(1, QColor(QLatin1Literal("#fad0c4"))));
+
+
+ QGradient invalidPreset(QGradient::Preset(-1));
+ QCOMPARE(invalidPreset.type(), QGradient::NoGradient);
+}
+
void fill(QPaintDevice *pd) {
QPainter p(pd);
diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
index 67d30d7c9a..ece7a30830 100644
--- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
+++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
@@ -1492,10 +1492,28 @@ void tst_QColor::unpremultiply_sse4()
// Tests that qUnpremultiply_sse4 returns the same as qUnpremultiply.
#if QT_COMPILER_SUPPORTS_HERE(SSE4_1)
if (qCpuHasFeature(SSE4_1)) {
+ int minorDifferences = 0;
+ for (uint a = 0; a < 256; a++) {
+ for (uint c = 0; c <= a; c++) {
+ const QRgb p = qRgba(c, a-c, c/2, a);
+ const uint u = qUnpremultiply(p);
+ const uint usse4 = qUnpremultiply_sse4(p);
+ if (u != usse4) {
+ QCOMPARE(qAlpha(u), qAlpha(usse4));
+ QVERIFY(qAbs(qRed(u) - qRed(usse4)) <= 1);
+ QVERIFY(qAbs(qGreen(u) - qGreen(usse4)) <= 1);
+ QVERIFY(qAbs(qBlue(u) - qBlue(usse4)) <= 1);
+ ++minorDifferences;
+ }
+ }
+ }
+ // Allow a few rounding differences as long as it still obeys
+ // the qPremultiply(qUnpremultiply(x)) == x invariant
+ QVERIFY(minorDifferences <= 16 * 255);
for (uint a = 0; a < 256; a++) {
for (uint c = 0; c <= a; c++) {
QRgb p = qRgba(c, a-c, c, a);
- QCOMPARE(qUnpremultiply(p), qUnpremultiply_sse4(p));
+ QCOMPARE(p, qPremultiply(qUnpremultiply_sse4(p)));
}
}
return;
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index 181c609c6e..9bf9e99bf9 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -31,9 +31,9 @@
#include <qpainter.h>
#ifndef QT_NO_WIDGETS
#include <qdrawutil.h>
-#include <qapplication.h>
#include <qwidget.h>
#endif
+#include <qguiapplication.h>
#include <qfontmetrics.h>
#include <qbitmap.h>
#include <qimage.h>
@@ -41,26 +41,18 @@
#include <limits.h>
#include <math.h>
#include <qpaintengine.h>
-#ifndef QT_NO_WIDGETS
-#include <qdesktopwidget.h>
-#endif
#include <qpixmap.h>
#include <qrandom.h>
#include <private/qdrawhelper_p.h>
#include <qpainter.h>
-
-#ifndef QT_NO_WIDGETS
-#include <qlabel.h>
-#endif
-
#include <qqueue.h>
+#include <qscreen.h>
#ifndef QT_NO_WIDGETS
#include <qgraphicsview.h>
#include <qgraphicsscene.h>
#include <qgraphicsproxywidget.h>
-#include <qlayout.h>
#endif
#include <qfontdatabase.h>
@@ -404,7 +396,7 @@ void tst_QPainter::cleanupTestCase()
#ifndef QT_NO_WIDGETS
void tst_QPainter::drawPixmap_comp_data()
{
- if (qApp->desktop()->depth() < 24)
+ if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("Test only works on 32 bit displays");
QTest::addColumn<uint>("dest");
@@ -1099,6 +1091,7 @@ void tst_QPainter::fillRect_data()
QTest::newRow("argb32pm") << QImage::Format_ARGB32_Premultiplied;
QTest::newRow("rgba8888pm") << QImage::Format_RGBA8888_Premultiplied;
+ QTest::newRow("rgba64pm") << QImage::Format_RGBA64_Premultiplied;
}
void tst_QPainter::fillRect()
@@ -2451,6 +2444,24 @@ void tst_QPainter::setOpacity_data()
QTest::newRow("A2RGB30P on RGB30") << QImage::Format_RGB30
<< QImage::Format_A2RGB30_Premultiplied;
+ QTest::newRow("RGBA64P on RGBA64P") << QImage::Format_RGBA64_Premultiplied
+ << QImage::Format_RGBA64_Premultiplied;
+
+ QTest::newRow("RGBA64 on RGBA64") << QImage::Format_RGBA64
+ << QImage::Format_RGBA64;
+
+ QTest::newRow("RGBx64 on RGBx64") << QImage::Format_RGBX64
+ << QImage::Format_RGBX64;
+
+ QTest::newRow("RGBA64P on ARGB32P") << QImage::Format_ARGB32_Premultiplied
+ << QImage::Format_RGBA64_Premultiplied;
+
+ QTest::newRow("RGBx64 on ARGB32P") << QImage::Format_ARGB32_Premultiplied
+ << QImage::Format_RGBX64;
+
+ QTest::newRow("ARGB32P on RGBA64P") << QImage::Format_RGBA64_Premultiplied
+ << QImage::Format_ARGB32_Premultiplied;
+
}
void tst_QPainter::setOpacity()
@@ -3855,6 +3866,8 @@ void tst_QPainter::gradientPixelFormat_data()
QTest::newRow("rgbx8888") << QImage::Format_RGBX8888;
QTest::newRow("rgba8888") << QImage::Format_RGBA8888;
QTest::newRow("rgba8888_pm") << QImage::Format_RGBA8888_Premultiplied;
+ QTest::newRow("rgbx64") << QImage::Format_RGBX64;
+ QTest::newRow("rgba64_pm") << QImage::Format_RGBA64_Premultiplied;
}
void tst_QPainter::gradientPixelFormat()
@@ -4792,7 +4805,19 @@ void tst_QPainter::blendARGBonRGB_data()
<< QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 255 ;
QTest::newRow("ARGB_PM source-in ARGB32") << QImage::Format_ARGB32 << QImage::Format_ARGB32_Premultiplied
<< QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 255;
- // Only ARGB does inverse premultiply, on the rest over and source gives similar results:
+ QTest::newRow("ARGB over RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM over RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB source RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 255;
+ QTest::newRow("ARGB_PM source RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 255;
+ QTest::newRow("ARGB source-in RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 255;
+ QTest::newRow("ARGB_PM source-in RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 255;
+ // Only ARGB32 and RGBA8888 does inverse premultiply, on the rest over and source gives similar results:
QTest::newRow("ARGB over RGB32") << QImage::Format_RGB32 << QImage::Format_ARGB32
<< QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127;
QTest::newRow("ARGB_PM over RGB32") << QImage::Format_RGB32 << QImage::Format_ARGB32_Premultiplied
@@ -4829,18 +4854,6 @@ void tst_QPainter::blendARGBonRGB_data()
<< QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 127;
QTest::newRow("ARGB_PM source-in RGBx8888") << QImage::Format_RGBX8888 << QImage::Format_ARGB32_Premultiplied
<< QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 127;
- QTest::newRow("ARGB over RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32
- << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127;
- QTest::newRow("ARGB_PM over RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied
- << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 127;
- QTest::newRow("ARGB source RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32
- << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 255;
- QTest::newRow("ARGB_PM source RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied
- << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 255;
- QTest::newRow("ARGB source-in RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32
- << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 255;
- QTest::newRow("ARGB_PM source-in RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied
- << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 255;
QTest::newRow("ARGB over RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32
<< QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 123;
QTest::newRow("ARGB_PM over RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32_Premultiplied
@@ -5011,7 +5024,7 @@ void tst_QPainter::drawPolyline_data()
{
QTest::addColumn< QVector<QPointF> >("points");
- QTest::newRow("basic") << (QVector<QPointF>() << QPointF(10, 10) << QPointF(20, 10) << QPointF(20, 20) << QPointF(10, 20));
+ QTest::newRow("basic") << (QVector<QPointF>() << QPointF(10, 10) << QPointF(20, 10) << QPointF(20, 20));
QTest::newRow("clipped") << (QVector<QPointF>() << QPoint(-10, 100) << QPoint(-1, 100) << QPoint(-1, -2) << QPoint(100, -2) << QPoint(100, 40)); // QTBUG-31579
QTest::newRow("shortsegment") << (QVector<QPointF>() << QPoint(20, 100) << QPoint(20, 99) << QPoint(21, 99) << QPoint(21, 104)); // QTBUG-42398
QTest::newRow("edge") << (QVector<QPointF>() << QPointF(4.5, 121.6) << QPointF(9.4, 150.9) << QPointF(14.2, 184.8) << QPointF(19.1, 130.4));
diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp
index 5b1af9b6c9..f1360b9efe 100644
--- a/tests/auto/gui/qopengl/tst_qopengl.cpp
+++ b/tests/auto/gui/qopengl/tst_qopengl.cpp
@@ -82,6 +82,8 @@ private slots:
void fboRendering();
void fboRenderingRGB30_data();
void fboRenderingRGB30();
+ void fboRenderingRGB64_data();
+ void fboRenderingRGB64();
void fboHandleNulledAfterContextDestroyed();
void fboMRT();
void fboMRT_differentFormats();
@@ -614,6 +616,10 @@ void tst_QOpenGL::fboRenderingRGB30_data()
#define GL_RGB10_A2 0x8059
#endif
+#ifndef GL_RGBA16
+#define GL_RGBA16 0x805B
+#endif
+
#ifndef GL_FRAMEBUFFER_RENDERABLE
#define GL_FRAMEBUFFER_RENDERABLE 0x8289
#endif
@@ -622,7 +628,7 @@ void tst_QOpenGL::fboRenderingRGB30_data()
#define GL_FULL_SUPPORT 0x82B7
#endif
-static bool hasRGB10A2(QOpenGLContext *ctx)
+static bool supportsInternalFboFormat(QOpenGLContext *ctx, int glFormat)
{
if (ctx->format().majorVersion() < 3)
return false;
@@ -631,7 +637,7 @@ static bool hasRGB10A2(QOpenGLContext *ctx)
GLint value = -1;
QOpenGLFunctions_4_2_Core* vFuncs = ctx->versionFunctions<QOpenGLFunctions_4_2_Core>();
if (vFuncs && vFuncs->initializeOpenGLFunctions()) {
- vFuncs->glGetInternalformativ(GL_TEXTURE_2D, GL_RGB10_A2, GL_FRAMEBUFFER_RENDERABLE, 1, &value);
+ vFuncs->glGetInternalformativ(GL_TEXTURE_2D, glFormat, GL_FRAMEBUFFER_RENDERABLE, 1, &value);
if (value != GL_FULL_SUPPORT)
return false;
}
@@ -657,7 +663,7 @@ void tst_QOpenGL::fboRenderingRGB30()
if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects())
QSKIP("QOpenGLFramebufferObject not supported on this platform");
- if (!hasRGB10A2(&ctx))
+ if (!supportsInternalFboFormat(&ctx, GL_RGB10_A2))
QSKIP("An internal RGB30_A2 format is not guaranteed on this platform");
// No multisample with combined depth/stencil attachment:
@@ -713,6 +719,71 @@ void tst_QOpenGL::fboRenderingRGB30()
QVERIFY(((pixel >> 20) & 0x3f) > 0);
}
+void tst_QOpenGL::fboRenderingRGB64_data()
+{
+ common_data();
+}
+
+void tst_QOpenGL::fboRenderingRGB64()
+{
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__)
+ QSKIP("QTBUG-22617");
+#endif
+
+ QFETCH(int, surfaceClass);
+ QScopedPointer<QSurface> surface(createSurface(surfaceClass));
+
+ QOpenGLContext ctx;
+ QVERIFY(ctx.create());
+
+ QVERIFY(ctx.makeCurrent(surface.data()));
+
+ if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects())
+ QSKIP("QOpenGLFramebufferObject not supported on this platform");
+
+ if (!supportsInternalFboFormat(&ctx, GL_RGBA16))
+ QSKIP("An internal RGBA16 format is not guaranteed on this platform");
+
+ // No multisample with combined depth/stencil attachment:
+ QOpenGLFramebufferObjectFormat fboFormat;
+ fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ fboFormat.setInternalTextureFormat(GL_RGBA16);
+
+ // Uncomplicate things by using POT:
+ const QSize size(256, 128);
+ QOpenGLFramebufferObject fbo(size, fboFormat);
+
+ if (fbo.attachment() != QOpenGLFramebufferObject::CombinedDepthStencil)
+ QSKIP("FBOs missing combined depth~stencil support");
+
+ QVERIFY(fbo.bind());
+
+ QPainter fboPainter;
+ QOpenGLPaintDevice device(fbo.width(), fbo.height());
+ bool painterBegun = fboPainter.begin(&device);
+ QVERIFY(painterBegun);
+
+ qt_opengl_draw_test_pattern(&fboPainter, fbo.width(), fbo.height());
+
+ fboPainter.end();
+
+ QImage fb = fbo.toImage();
+ QCOMPARE(fb.format(), QImage::Format_RGBA64_Premultiplied);
+ QCOMPARE(fb.size(), size);
+
+ qt_opengl_check_test_pattern(fb);
+
+ // Check rendering can handle precise 16 bit color values.
+ fboPainter.begin(&device);
+ fboPainter.fillRect(QRect(0, 0, 256, 128), QColor::fromRgba64(5, 1002, 8001, 65535));
+ fboPainter.end();
+ fb = fbo.toImage();
+ QRgba64 pixel = ((QRgba64*)fb.bits())[0];
+ QCOMPARE(pixel.red(), 5);
+ QCOMPARE(pixel.green(), 1002);
+ QCOMPARE(pixel.blue(), 8001);
+}
+
void tst_QOpenGL::fboHandleNulledAfterContextDestroyed()
{
QWindow window;
@@ -844,7 +915,7 @@ void tst_QOpenGL::fboMRT_differentFormats()
if (!f->hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets))
QSKIP("Multiple render targets not supported on this platform");
- if (!hasRGB10A2(&ctx))
+ if (!supportsInternalFboFormat(&ctx, GL_RGB10_A2))
QSKIP("RGB10_A2 not supported on this platform");
// 3 color attachments, same size, different internal format, depth/stencil.
diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
index 79058e5073..da2f100c0b 100644
--- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
@@ -65,6 +65,7 @@ private slots:
void fallbackFonts();
void condensedFontWidth();
+ void condensedFontWidthNoFontMerging();
void condensedFontMatching();
void rasterFonts();
@@ -297,6 +298,29 @@ static QString testString()
return QStringLiteral("foo bar");
}
+void tst_QFontDatabase::condensedFontWidthNoFontMerging()
+{
+ int regularFontId = QFontDatabase::addApplicationFont(m_testFont);
+ int condensedFontId = QFontDatabase::addApplicationFont(m_testFontCondensed);
+
+ QVERIFY(!QFontDatabase::applicationFontFamilies(regularFontId).isEmpty());
+ QVERIFY(!QFontDatabase::applicationFontFamilies(condensedFontId).isEmpty());
+
+ QString regularFontName = QFontDatabase::applicationFontFamilies(regularFontId).first();
+ QString condensedFontName = QFontDatabase::applicationFontFamilies(condensedFontId).first();
+
+ QFont condensedFont1(condensedFontName);
+ if (regularFontName == condensedFontName)
+ condensedFont1.setStyleName(QStringLiteral("Condensed"));
+ condensedFont1.setStyleStrategy(QFont::PreferMatch);
+
+ QFont condensedFont2 = condensedFont1;
+ condensedFont2.setStyleStrategy(QFont::StyleStrategy(QFont::NoFontMerging | QFont::PreferMatch));
+
+ QCOMPARE(QFontMetricsF(condensedFont2).horizontalAdvance(QStringLiteral("foobar")),
+ QFontMetricsF(condensedFont1).horizontalAdvance(QStringLiteral("foobar")));
+ }
+
void tst_QFontDatabase::condensedFontWidth()
{
QFontDatabase db;
diff --git a/tests/auto/gui/text/qglyphrun/BLACKLIST b/tests/auto/gui/text/qglyphrun/BLACKLIST
new file mode 100644
index 0000000000..57f32c683d
--- /dev/null
+++ b/tests/auto/gui/text/qglyphrun/BLACKLIST
@@ -0,0 +1,3 @@
+[mixedScripts]
+ubuntu-18.04
+b2qt
diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
index 21b2697b90..b7f014d0e2 100644
--- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
+++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
@@ -731,6 +731,9 @@ void tst_QGlyphRun::mixedScripts()
layout.endLayout();
QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Hangul character not rendered on winrt", Continue);
+#endif
QCOMPARE(glyphRuns.size(), 2);
}
diff --git a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp
index 0089aeb43e..d00dc251d8 100644
--- a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp
+++ b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp
@@ -61,6 +61,8 @@ private slots:
void drawToPoint();
void drawToRect_data();
void drawToRect();
+ void compareToDrawText_data();
+ void compareToDrawText();
void setFont();
void setTextWidth();
void prepareToCorrectData();
@@ -212,6 +214,66 @@ void tst_QStaticText::drawToRect()
QCOMPARE(imageDrawStaticText, imageDrawText);
}
+void tst_QStaticText::compareToDrawText_data()
+{
+ QTest::addColumn<QFont>("font");
+
+ QTest::newRow("default") << QFont();
+ QFont sansserif; sansserif.setStyleHint(QFont::SansSerif);
+ QFont serif; serif.setStyleHint(QFont::Serif);
+ QFont monospace; monospace.setStyleHint(QFont::Monospace);
+ QTest::newRow("sans-serif") << QFont(sansserif.defaultFamily());
+ QTest::newRow("serif") << QFont(serif.defaultFamily());
+ QTest::newRow("monospace") << QFont(monospace.defaultFamily());
+}
+
+void tst_QStaticText::compareToDrawText()
+{
+ QFETCH(QFont, font);
+
+ QPixmap imageDrawText(1000, 1000);
+ imageDrawText.fill(Qt::white);
+ {
+ QPainter p(&imageDrawText);
+ p.setFont(font);
+ p.drawText(QRectF(11, 12, 30, 500), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ }
+
+ QPixmap imageDrawStaticPlainText(1000, 1000);
+ imageDrawStaticPlainText.fill(Qt::white);
+ {
+ QPainter p(&imageDrawStaticPlainText);
+ p.setFont(font);
+ QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ text.setTextWidth(10),
+ p.setClipRect(QRectF(11, 12, 30, 500));
+ text.setTextFormat(Qt::PlainText);
+ p.drawStaticText(QPointF(11, 12), text);
+ }
+
+ QPixmap imageDrawStaticRichText(1000, 1000);
+ imageDrawStaticRichText.fill(Qt::white);
+ {
+ QPainter p(&imageDrawStaticRichText);
+ p.setFont(font);
+ QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ text.setTextWidth(10),
+ p.setClipRect(QRectF(11, 12, 30, 500));
+ text.setTextFormat(Qt::RichText);
+ p.drawStaticText(QPointF(11, 12), text);
+ }
+
+#if defined(DEBUG_SAVE_IMAGE)
+ imageDrawText.save("compareToDrawText_imageDrawText.png");
+ imageDrawStaticText.save("compareToDrawText_imageDrawStaticPlainText.png");
+ imageDrawStaticText.save("compareToDrawText_imageDrawStaticRichText.png");
+#endif
+
+ QVERIFY(imageDrawText.toImage() != m_whiteSquare);
+ QCOMPARE(imageDrawStaticPlainText, imageDrawText);
+ QCOMPARE(imageDrawStaticRichText, imageDrawText);
+}
+
void tst_QStaticText::prepareToCorrectData()
{
QTransform transform;
diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
index ed69802d95..3e354b7523 100644
--- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
+++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
@@ -1692,6 +1692,9 @@ void tst_QTextDocumentFragment::html_bodyBackground()
const char html[] = "<body background=\"foo.png\">Foo</body>";
doc->setHtml(html);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on winrt. Investigate - QTBUG-68297", Continue);
+#endif
QCOMPARE(doc->rootFrame()->frameFormat().background().style(), Qt::TexturePattern);
}
@@ -1706,6 +1709,9 @@ void tst_QTextDocumentFragment::html_tableCellBackground()
QVERIFY(table);
QTextTableCell cell = table->cellAt(0, 0);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on winrt. Investigate - QTBUG-68297", Continue);
+#endif
QCOMPARE(cell.format().background().style(), Qt::TexturePattern);
}
@@ -1714,6 +1720,9 @@ void tst_QTextDocumentFragment::css_bodyBackground()
const char html[] = "<body style=\"background-image:url('foo.png')\">Foo</body>";
doc->setHtml(html);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on winrt. Investigate - QTBUG-68297", Continue);
+#endif
QCOMPARE(doc->rootFrame()->frameFormat().background().style(), Qt::TexturePattern);
}
@@ -1728,6 +1737,9 @@ void tst_QTextDocumentFragment::css_tableCellBackground()
QVERIFY(table);
QTextTableCell cell = table->cellAt(0, 0);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on winrt. Investigate - QTBUG-68297", Continue);
+#endif
QCOMPARE(cell.format().background().style(), Qt::TexturePattern);
}
diff --git a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp
index 082d16f62d..c79f787547 100644
--- a/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp
+++ b/tests/auto/gui/text/qtextdocumentlayout/tst_qtextdocumentlayout.cpp
@@ -299,8 +299,11 @@ void tst_QTextDocumentLayout::imageAtRightAlignedTab()
imgFormat.setName(name);
cursor.insertImage(imgFormat);
- // Everything should fit into the 300 pixels
- QCOMPARE(doc->idealWidth(), 300.0);
+ // Everything should fit into the 300 pixels
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on winrt. Figure out why - QTBUG-68297", Continue);
+#endif
+ QCOMPARE(doc->idealWidth(), 300.0);
}
void tst_QTextDocumentLayout::blockVisibility()
diff --git a/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp b/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp
index fb92b5a20f..bbb90ec82a 100644
--- a/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp
+++ b/tests/auto/gui/text/qtextodfwriter/tst_qtextodfwriter.cpp
@@ -131,7 +131,7 @@ void tst_QTextOdfWriter::testWriteParagraph_data()
QTest::newRow("misc2") << "\t \tFoo" <<
"<text:p text:style-name=\"p1\"><text:span text:style-name=\"c0\"><text:tab/> <text:s text:c=\"4\"/><text:tab/>Foo</text:span></text:p>";
QTest::newRow("linefeed") << (QStringLiteral("line1") + QChar(0x2028) + QStringLiteral("line2")) <<
- "<text:p text:style-name=\"p1\"><text:span text:style-name=\"c0\">line1<text:line-break/>line2</text:span></text:p>";
+ "<text:p text:style-name=\"p1\"><text:span text:style-name=\"c0\">line1<text:tab/><text:line-break/>line2</text:span></text:p>";
QTest::newRow("spaces") << "The quick brown fox jumped over the lazy dog" <<
"<text:p text:style-name=\"p1\"><text:span text:style-name=\"c0\">The quick brown fox jumped over the lazy dog</text:span></text:p>";
}
@@ -378,7 +378,7 @@ void tst_QTextOdfWriter::testWriteTable()
odfWriter->writeFrame(*xmlWriter, document->rootFrame());
QString xml = QString::fromLatin1(
"<text:p text:style-name=\"p1\"/>"
- "<table:table>"
+ "<table:table table:style-name=\"Table2\">"
"<table:table-column table:number-columns-repeated=\"3\"/>"
"<table:table-row>"
"<table:table-cell table:style-name=\"T3\">"
diff --git a/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp b/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp
index 4705fc3ed7..012a7e2ce3 100644
--- a/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp
+++ b/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp
@@ -155,6 +155,10 @@ void tst_QDoubleValidator::validate_data()
QTest::newRow("data48") << "C" << 0.0 << 100.0 << 1 << QString("0.0") << ACC << ACC;
QTest::newRow("data49") << "C" << 0.0 << 100.0 << 0 << QString(".") << ITM << ITM;
QTest::newRow("data50") << "C" << 0.0 << 100.0 << 1 << QString(".") << ITM << ITM;
+ QTest::newRow("data51") << "C" << 0.0 << 2.0 << 2 << QString("9.99") << ITM << ITM;
+ QTest::newRow("data52") << "C" << 100.0 << 200.0 << 4 << QString("999.9999") << ITM << ITM;
+ QTest::newRow("data53") << "C" << 0.0 << 2.0 << 2 << QString("9.9999") << INV << INV;
+ QTest::newRow("data54") << "C" << 100.0 << 200.0 << 4 << QString("9999.9999") << ITM << INV;
QTest::newRow("data_de0") << "de" << 0.0 << 100.0 << 1 << QString("50,0") << ACC << ACC;
QTest::newRow("data_de1") << "de" << 00.0 << 100.0 << 1 << QString("500,0") << ITM << ITM;
@@ -206,6 +210,10 @@ void tst_QDoubleValidator::validate_data()
QTest::newRow("data_de43") << "de" << 0.01 << 0.09 << 2 << QString("0") << ITM << ITM;
QTest::newRow("data_de44") << "de" << 0.0 << 10.0 << 1 << QString("11") << ITM << ITM;
QTest::newRow("data_de45") << "de" << 0.0 << 10.0 << 2 << QString("11") << ITM << ITM;
+ QTest::newRow("data_de46") << "de" << 0.0 << 2.0 << 2 << QString("9,99") << ITM << ITM;
+ QTest::newRow("data_de47") << "de" << 100.0 << 200.0 << 4 << QString("999,9999") << ITM << ITM;
+ QTest::newRow("data_de48") << "de" << 0.0 << 2.0 << 2 << QString("9,9999") << INV << INV;
+ QTest::newRow("data_de49") << "de" << 100.0 << 200.0 << 4 << QString("9999,9999") << ITM << INV;
QString arabicNum;
arabicNum += QChar(1633); // "18.4" in arabic
diff --git a/tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp b/tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp
index 57f55c3121..ec0d63f67c 100644
--- a/tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp
+++ b/tests/auto/gui/util/qintvalidator/tst_qintvalidator.cpp
@@ -54,7 +54,7 @@ void tst_QIntValidator::validate_data()
QTest::addColumn<QValidator::State>("state");
QTest::newRow("data0") << 0 << 100 << QString("50") << ACC;
- QTest::newRow("data1") << 0 << 100 << QString("500") << INV;
+ QTest::newRow("data1") << 0 << 100 << QString("500") << INT;
QTest::newRow("data1a") << 0 << 100 << QString("5000") << INV;
QTest::newRow("data1b") << -100 << 0 << QString("50") << INT;
QTest::newRow("data1c") << -100 << 0 << QString("500") << INV;
@@ -121,7 +121,7 @@ void tst_QIntValidator::validate_data()
QTest::newRow("5.1") << 6 << 8 << QString("5") << INT;
QTest::newRow("5.2") << 6 << 8 << QString("7") << ACC;
- QTest::newRow("5.3") << 6 << 8 << QString("9") << INV;
+ QTest::newRow("5.3") << 6 << 8 << QString("9") << INT;
QTest::newRow("5.3a") << 6 << 8 << QString("19") << INV;
QTest::newRow("5.4") << -8 << -6 << QString("-5") << INT;
QTest::newRow("5.5") << -8 << -6 << QString("-7") << ACC;
@@ -129,13 +129,13 @@ void tst_QIntValidator::validate_data()
QTest::newRow("5.6a") << -8 << -6 << QString("-19") << INV;
QTest::newRow("5.7") << -8 << -6 << QString("5") << INT;
QTest::newRow("5.8") << -8 << -6 << QString("7") << INT;
- QTest::newRow("5.9") << -8 << -6 << QString("9") << INV;
+ QTest::newRow("5.9") << -8 << -6 << QString("9") << INT;
QTest::newRow("5.10") << -6 << 8 << QString("-5") << ACC;
QTest::newRow("5.11") << -6 << 8 << QString("5") << ACC;
QTest::newRow("5.12") << -6 << 8 << QString("-7") << INV;
QTest::newRow("5.13") << -6 << 8 << QString("7") << ACC;
QTest::newRow("5.14") << -6 << 8 << QString("-9") << INV;
- QTest::newRow("5.15") << -6 << 8 << QString("9") << INV;
+ QTest::newRow("5.15") << -6 << 8 << QString("9") << INT;
QTest::newRow("6.1") << 100 << 102 << QString("11") << INT;
QTest::newRow("6.2") << 100 << 102 << QString("-11") << INV;
diff --git a/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.pro b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.pro
new file mode 100644
index 0000000000..43951fe722
--- /dev/null
+++ b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+QT += testlib gui-private
+SOURCES += tst_qtexturefilereader.cpp
+TARGET = tst_qtexturefilereader
+RESOURCES += qtexturefilereader.qrc
diff --git a/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc
new file mode 100644
index 0000000000..ab882b5db2
--- /dev/null
+++ b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file>texturefiles/car.ktx</file>
+ <file>texturefiles/pattern.pkm</file>
+ <file>texturefiles/car_mips.ktx</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/gui/util/qtexturefilereader/texturefiles/car.ktx b/tests/auto/gui/util/qtexturefilereader/texturefiles/car.ktx
new file mode 100644
index 0000000000..2aefdd306b
--- /dev/null
+++ b/tests/auto/gui/util/qtexturefilereader/texturefiles/car.ktx
Binary files differ
diff --git a/tests/auto/gui/util/qtexturefilereader/texturefiles/car_mips.ktx b/tests/auto/gui/util/qtexturefilereader/texturefiles/car_mips.ktx
new file mode 100644
index 0000000000..82822e6c0b
--- /dev/null
+++ b/tests/auto/gui/util/qtexturefilereader/texturefiles/car_mips.ktx
Binary files differ
diff --git a/tests/auto/gui/util/qtexturefilereader/texturefiles/pattern.pkm b/tests/auto/gui/util/qtexturefilereader/texturefiles/pattern.pkm
new file mode 100644
index 0000000000..d986e89b2d
--- /dev/null
+++ b/tests/auto/gui/util/qtexturefilereader/texturefiles/pattern.pkm
Binary files differ
diff --git a/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp b/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp
new file mode 100644
index 0000000000..9ff4f0ccf2
--- /dev/null
+++ b/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qtexturefilereader_p.h>
+#include <QtTest>
+
+class tst_qtexturefilereader : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void checkHandlers_data();
+ void checkHandlers();
+};
+
+void tst_qtexturefilereader::checkHandlers_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QSize>("size");
+ QTest::addColumn<quint32>("glFormat");
+ QTest::addColumn<quint32>("glInternalFormat");
+ QTest::addColumn<quint32>("glBaseInternalFormat");
+ QTest::addColumn<int>("levels");
+ QTest::addColumn<QList<int>>("dataOffsets");
+ QTest::addColumn<QList<int>>("dataLengths");
+
+ QTest::addRow("pattern.pkm") << QStringLiteral(":/texturefiles/pattern.pkm")
+ << QSize(64, 64)
+ << quint32(0x0)
+ << quint32(0x8d64)
+ << quint32(0x0)
+ << 1
+ << (QList<int>() << 16)
+ << (QList<int>() << 2048);
+
+ QTest::addRow("car.ktx") << QStringLiteral(":/texturefiles/car.ktx")
+ << QSize(146, 80)
+ << quint32(0x0)
+ << quint32(0x9278)
+ << quint32(0x1908)
+ << 1
+ << (QList<int>() << 68)
+ << (QList<int>() << 11840);
+
+ QTest::addRow("car_mips.ktx") << QStringLiteral(":/texturefiles/car_mips.ktx")
+ << QSize(146, 80)
+ << quint32(0x0)
+ << quint32(0x9274)
+ << quint32(0x1907)
+ << 8
+ << (QList<int>() << 68 << 5992 << 7516 << 7880 << 8004 << 8056 << 8068 << 8080)
+ << (QList<int>() << 5920 << 1520 << 360 << 120 << 48 << 8 << 8 << 8);
+
+}
+
+void tst_qtexturefilereader::checkHandlers()
+{
+ QFETCH(QString, fileName);
+ QFETCH(QSize, size);
+ QFETCH(quint32, glFormat);
+ QFETCH(quint32, glInternalFormat);
+ QFETCH(int, levels);
+ QFETCH(QList<int>, dataOffsets);
+ QFETCH(QList<int>, dataLengths);
+
+ QFile f(fileName);
+ QVERIFY(f.open(QIODevice::ReadOnly));
+ QTextureFileReader r(&f, fileName);
+ QVERIFY(r.canRead());
+
+ QTextureFileData tex = r.read();
+ QVERIFY(!tex.isNull());
+ QVERIFY(tex.isValid());
+ QCOMPARE(tex.size(), size);
+ QCOMPARE(tex.glFormat(), glFormat);
+ QCOMPARE(tex.glInternalFormat(), glInternalFormat);
+ QCOMPARE(tex.numLevels(), levels);
+ for (int i = 0; i < tex.numLevels(); i++) {
+ QCOMPARE(tex.dataOffset(i), dataOffsets.at(i));
+ QCOMPARE(tex.dataLength(i), dataLengths.at(i));
+ }
+}
+
+QTEST_MAIN(tst_qtexturefilereader)
+
+#include "tst_qtexturefilereader.moc"
diff --git a/tests/auto/gui/util/util.pro b/tests/auto/gui/util/util.pro
index 940e892e5f..2789ffb55d 100644
--- a/tests/auto/gui/util/util.pro
+++ b/tests/auto/gui/util/util.pro
@@ -10,4 +10,4 @@ SUBDIRS= \
qshadergraphloader \
qshadernodes \
qshadernodesloader \
-
+ qtexturefilereader
diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h
index 16966ced4e..a3c318420f 100644
--- a/tests/auto/network-settings.h
+++ b/tests/auto/network-settings.h
@@ -27,10 +27,12 @@
****************************************************************************/
#include <QString>
+#include <QtTest/QtTest>
#ifdef QT_NETWORK_LIB
#include <QtNetwork/QHostInfo>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QAbstractSocket>
+#include <QtNetwork/QTcpSocket>
#endif
#ifdef Q_OS_UNIX
@@ -50,7 +52,11 @@ public:
}
static QString serverDomainName()
{
+#ifdef QT_TEST_SERVER_DOMAIN
+ return QString(QT_TEST_SERVER_DOMAIN); // Defined in testserver feature
+#else
return QString("qt-test-net");
+#endif
}
static QString serverName()
{
@@ -137,6 +143,20 @@ public:
return true;
}
+ static bool verifyConnection(QString serverName, quint16 port, quint32 retry = 10)
+ {
+ QTcpSocket socket;
+ for (quint32 i = 1; i < retry; i++) {
+ socket.connectToHost(serverName, port);
+ if (socket.waitForConnected(1000))
+ return true;
+ // Wait for service to start up
+ QTest::qWait(1000);
+ }
+ socket.connectToHost(serverName, port);
+ return socket.waitForConnected(1000);
+ }
+
// Helper function for usage with QVERIFY2 on sockets.
static QByteArray msgSocketError(const QAbstractSocket &s)
{
@@ -153,4 +173,45 @@ public:
return result.toLocal8Bit();
}
#endif // QT_NETWORK_LIB
+
+ static QString ftpServerName()
+ {
+#ifdef QT_TEST_SERVER
+ return QString("vsftpd.") % serverDomainName();
+#else
+ return serverName();
+#endif
+ }
+ static QString ftpProxyServerName()
+ {
+#ifdef QT_TEST_SERVER
+ return QString("ftp-proxy.") % serverDomainName();
+#else
+ return serverName();
+#endif
+ }
+ static QString httpServerName()
+ {
+#ifdef QT_TEST_SERVER
+ return QString("apache2.") % serverDomainName();
+#else
+ return serverName();
+#endif
+ }
+ static QString httpProxyServerName()
+ {
+#ifdef QT_TEST_SERVER
+ return QString("squid.") % serverDomainName();
+#else
+ return serverName();
+#endif
+ }
+ static QString socksProxyServerName()
+ {
+#ifdef QT_TEST_SERVER
+ return QString("danted.") % serverDomainName();
+#else
+ return serverName();
+#endif
+ }
};
diff --git a/tests/auto/network/access/hpack/hpack.pro b/tests/auto/network/access/hpack/hpack.pro
index 3c8b8e7944..2823ae4d0c 100644
--- a/tests/auto/network/access/hpack/hpack.pro
+++ b/tests/auto/network/access/hpack/hpack.pro
@@ -1,5 +1,5 @@
-QT += core core-private network network-private testlib
-CONFIG += testcase parallel_test c++14
+QT = core core-private network network-private testlib
+CONFIG += testcase parallel_test c++11
TEMPLATE = app
TARGET = tst_hpack
diff --git a/tests/auto/network/access/hsts/hsts.pro b/tests/auto/network/access/hsts/hsts.pro
index 07bdea5f62..dad6638364 100644
--- a/tests/auto/network/access/hsts/hsts.pro
+++ b/tests/auto/network/access/hsts/hsts.pro
@@ -1,4 +1,4 @@
-QT += core core-private network network-private testlib
+QT = core core-private network network-private testlib
CONFIG += testcase parallel_test c++11
TEMPLATE = app
TARGET = tst_qhsts
diff --git a/tests/auto/network/access/http2/http2.pro b/tests/auto/network/access/http2/http2.pro
index e130f30784..62b685e556 100644
--- a/tests/auto/network/access/http2/http2.pro
+++ b/tests/auto/network/access/http2/http2.pro
@@ -1,4 +1,4 @@
-QT += core core-private network network-private testlib
+QT = core core-private network network-private testlib
CONFIG += testcase parallel_test c++11
TARGET = tst_http2
diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp
index b0bae13bad..1f9ffb8985 100644
--- a/tests/auto/network/access/http2/http2srv.cpp
+++ b/tests/auto/network/access/http2/http2srv.cpp
@@ -212,13 +212,30 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize)
const quint32 offset = it->second;
Q_ASSERT(offset < quint32(responseBody.size()));
- const quint32 bytes = std::min<quint32>(windowSize, responseBody.size() - offset);
+ quint32 bytesToSend = std::min<quint32>(windowSize, responseBody.size() - offset);
+ quint32 bytesSent = 0;
const quint32 frameSizeLimit(clientSetting(Settings::MAX_FRAME_SIZE_ID, Http2::maxFrameSize));
const uchar *src = reinterpret_cast<const uchar *>(responseBody.constData() + offset);
- const bool last = offset + bytes == quint32(responseBody.size());
+ const bool last = offset + bytesToSend == quint32(responseBody.size());
+
+ // The payload can significantly exceed frameSizeLimit. Internally, writer
+ // will do needed fragmentation, but if some test failed, there is no need
+ // to wait for writer to send all DATA frames, we check 'interrupted' and
+ // stop early instead.
+ const quint32 framesInChunk = 10;
+ while (bytesToSend) {
+ if (interrupted.loadAcquire())
+ return;
+ const quint32 chunkSize = std::min<quint32>(framesInChunk * frameSizeLimit, bytesToSend);
+ writer.start(FrameType::DATA, FrameFlag::EMPTY, streamID);
+ writer.writeDATA(*socket, frameSizeLimit, src, chunkSize);
+ src += chunkSize;
+ bytesToSend -= chunkSize;
+ bytesSent += chunkSize;
+ }
- writer.start(FrameType::DATA, FrameFlag::EMPTY, streamID);
- writer.writeDATA(*socket, frameSizeLimit, src, bytes);
+ if (interrupted.loadAcquire())
+ return;
if (last) {
writer.start(FrameType::DATA, FrameFlag::END_STREAM, streamID);
@@ -230,7 +247,7 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize)
Q_ASSERT(closedStreams.find(streamID) == closedStreams.end());
closedStreams.insert(streamID);
} else {
- it->second += bytes;
+ it->second += bytesSent;
}
}
@@ -819,6 +836,11 @@ void Http2Server::sendResponse(quint32 streamID, bool emptyBody)
}
}
+void Http2Server::stopSendingDATAFrames()
+{
+ interrupted.storeRelease(1);
+}
+
void Http2Server::processRequest()
{
Q_ASSERT(continuedRequest.size());
diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h
index 14b41cc67d..87a17ced8b 100644
--- a/tests/auto/network/access/http2/http2srv.h
+++ b/tests/auto/network/access/http2/http2srv.h
@@ -40,6 +40,7 @@
#include <QtCore/qscopedpointer.h>
#include <QtNetwork/qtcpserver.h>
#include <QtCore/qbytearray.h>
+#include <QtCore/qatomic.h>
#include <QtCore/qglobal.h>
#include <vector>
@@ -96,6 +97,8 @@ public:
Q_INVOKABLE void sendResponse(quint32 streamID, bool emptyBody);
+ void stopSendingDATAFrames();
+
private:
void processRequest();
@@ -191,6 +194,7 @@ private:
// may still be sending DATA frames. See tst_Http2::earlyResponse().
bool redirectWhileReading = false;
quint16 targetPort = 0;
+ QAtomicInt interrupted;
protected slots:
void ignoreErrorSlot();
};
diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp
index ecf4c5814a..49daedf32c 100644
--- a/tests/auto/network/access/http2/tst_http2.cpp
+++ b/tests/auto/network/access/http2/tst_http2.cpp
@@ -110,8 +110,7 @@ private:
QThread *workerThread = nullptr;
QNetworkAccessManager manager;
- QEventLoop eventLoop;
- QTimer timer;
+ QTestEventLoop eventLoop;
int nRequests = 0;
int nSentRequests = 0;
@@ -133,8 +132,10 @@ struct ServerDeleter
{
static void cleanup(Http2Server *srv)
{
- if (srv)
+ if (srv) {
+ srv->stopSendingDATAFrames();
QMetaObject::invokeMethod(srv, "deleteLater", Qt::QueuedConnection);
+ }
}
};
@@ -146,11 +147,6 @@ tst_Http2::tst_Http2()
: workerThread(new QThread)
{
workerThread->start();
-
- timer.setInterval(10000);
- timer.setSingleShot(true);
-
- connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
}
tst_Http2::~tst_Http2()
@@ -497,15 +493,12 @@ void tst_Http2::clearHTTP2State()
void tst_Http2::runEventLoop(int ms)
{
- timer.setInterval(ms);
- timer.start();
- eventLoop.exec();
+ eventLoop.enterLoopMSecs(ms);
}
void tst_Http2::stopEventLoop()
{
- timer.stop();
- eventLoop.quit();
+ eventLoop.exitLoop();
}
Http2Server *tst_Http2::newServer(const Http2::RawSettings &serverSettings,
diff --git a/tests/auto/network/access/qnetworkreply/certs/qt-test-net-cacert.pem b/tests/auto/network/access/qnetworkreply/certs/qt-test-net-cacert.pem
new file mode 100644
index 0000000000..43c8794ce2
--- /dev/null
+++ b/tests/auto/network/access/qnetworkreply/certs/qt-test-net-cacert.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIIClTCCAf4CCQC2xMhNhwvATDANBgkqhkiG9w0BAQQFADCBjjELMAkGA1UEChMC
+UXQxGTAXBgNVBAsTEENvcmUgQW5kIE5ldHdvcmsxGzAZBgkqhkiG9w0BCQEWDG5v
+Ym9keS5xdC5pbzENMAsGA1UEBxMET3NsbzENMAsGA1UECBMET3NsbzELMAkGA1UE
+BhMCTk8xHDAaBgNVBAMUEyoudGVzdC1uZXQucXQubG9jYWwwHhcNMTgwNzAxMTgz
+NjI3WhcNNDgwNjIzMTgzNjI3WjCBjjELMAkGA1UEChMCUXQxGTAXBgNVBAsTEENv
+cmUgQW5kIE5ldHdvcmsxGzAZBgkqhkiG9w0BCQEWDG5vYm9keS5xdC5pbzENMAsG
+A1UEBxMET3NsbzENMAsGA1UECBMET3NsbzELMAkGA1UEBhMCTk8xHDAaBgNVBAMU
+EyoudGVzdC1uZXQucXQubG9jYWwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
+AM2q22/WNMmn8cC+5EEYGeICySLmp9W6Ay6eKHr0Xxp3X3epETuPfvAuxp7rOtkS
+18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt93CxGBXMIChiMPAsFeYzGa/D6xzAkfcR
+aJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJrgsgBfWrwHdxzAgMBAAEwDQYJKoZIhvcN
+AQEEBQADgYEAZu/lQPy8PXeyyYGamOVms/FZKJ48BH1y8KC3BeBU5FYnhvgG7pz8
+Wz9JKvt2t/r45wQeAkNL6HnGUBhPJsHMjPHl5KktqN+db3D+FQygBeS2V1+zmC0X
+UZNRE4aWiHvt1Lq+pTx89SOMOpfqWfh4qTQKiE5jC2V4DeCNQ3u7uI8=
+-----END CERTIFICATE-----
diff --git a/tests/auto/network/access/qnetworkreply/test/test.pro b/tests/auto/network/access/qnetworkreply/test/test.pro
index e8464e81af..9d36352abc 100644
--- a/tests/auto/network/access/qnetworkreply/test/test.pro
+++ b/tests/auto/network/access/qnetworkreply/test/test.pro
@@ -14,3 +14,6 @@ TESTDATA += ../empty ../rfc3252.txt ../resource ../bigfile ../*.jpg ../certs \
../index.html ../smb-file.txt
!android:!winrt: TEST_HELPER_INSTALLS = ../echo/echo
+
+QT_TEST_SERVER_LIST = vsftpd apache2 ftp-proxy danted squid
+include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri)
diff --git a/tests/auto/network/access/qnetworkreply/testserver_index.html b/tests/auto/network/access/qnetworkreply/testserver_index.html
new file mode 100644
index 0000000000..abc1df188d
--- /dev/null
+++ b/tests/auto/network/access/qnetworkreply/testserver_index.html
@@ -0,0 +1,3 @@
+<h1>Welcome to qt-test-server</h1>
+<img src="fluke.gif" alt="fluke">
+<p>This is a network test server. It serves as a caching ftp and http proxy, transparent http/socks5 proxy, imap, ftp and http server, and more.</p>
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 9c77e156d7..30b41da515 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -156,6 +156,7 @@ class tst_QNetworkReply: public QObject
#ifndef QT_NO_SSL
QSslConfiguration storedSslConfiguration;
QList<QSslError> storedExpectedSslErrors;
+ static const QString certsFilePath;
#endif
#ifndef QT_NO_BEARERMANAGEMENT
QNetworkConfigurationManager *netConfMan;
@@ -547,8 +548,15 @@ static void setupSslServer(QSslSocket* serverSocket)
serverSocket->setPrivateKey(testDataDir + "/certs/server.key");
serverSocket->startServerEncryption();
}
+
+#ifdef QT_TEST_SERVER
+const QString tst_QNetworkReply::certsFilePath = "/certs/qt-test-net-cacert.pem";
+#else
+const QString tst_QNetworkReply::certsFilePath = "/certs/qt-test-server-cacert.pem";
#endif
+#endif // !QT_NO_SSL
+
// NOTE: MiniHttpServer has a very limited support of PUT/POST requests! Make
// sure you understand the server's code before PUTting/POSTing data (and
// probably you'll have to update the logic).
@@ -1270,18 +1278,23 @@ tst_QNetworkReply::tst_QNetworkReply()
manager.setCookieJar(cookieJar);
#ifndef QT_NO_NETWORKPROXY
- QHostInfo hostInfo = QHostInfo::fromName(QtNetworkSettings::serverName());
+ QHostInfo hostInfo = QHostInfo::fromName(QtNetworkSettings::httpProxyServerName());
proxies << ProxyData(QNetworkProxy::NoProxy, "", false);
if (hostInfo.error() == QHostInfo::NoError && !hostInfo.addresses().isEmpty()) {
- QString proxyserver = hostInfo.addresses().first().toString();
- proxies << ProxyData(QNetworkProxy(QNetworkProxy::HttpProxy, proxyserver, 3128), "+proxy", false)
- << ProxyData(QNetworkProxy(QNetworkProxy::HttpProxy, proxyserver, 3129), "+proxyauth", true)
+ QString httpProxy = QtNetworkSettings::httpProxyServerName();
+ QString socksProxy = QtNetworkSettings::socksProxyServerName();
+ proxies << ProxyData(QNetworkProxy(QNetworkProxy::HttpProxy, httpProxy, 3128),
+ "+proxy", false)
+ << ProxyData(QNetworkProxy(QNetworkProxy::HttpProxy, httpProxy, 3129),
+ "+proxyauth", true)
// currently unsupported
// << ProxyData(QNetworkProxy(QNetworkProxy::HttpProxy, proxyserver, 3130), "+proxyauth-ntlm", true);
- << ProxyData(QNetworkProxy(QNetworkProxy::Socks5Proxy, proxyserver, 1080), "+socks", false)
- << ProxyData(QNetworkProxy(QNetworkProxy::Socks5Proxy, proxyserver, 1081), "+socksauth", true);
+ << ProxyData(QNetworkProxy(QNetworkProxy::Socks5Proxy, socksProxy, 1080),
+ "+socks", false)
+ << ProxyData(QNetworkProxy(QNetworkProxy::Socks5Proxy, socksProxy, 1081),
+ "+socksauth", true);
} else {
#endif // !QT_NO_NETWORKPROXY
printf("==================================================================\n");
@@ -1508,8 +1521,20 @@ void tst_QNetworkReply::initTestCase()
if (testDataDir.isEmpty())
testDataDir = QCoreApplication::applicationDirPath();
+#if defined(QT_TEST_SERVER)
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::ftpServerName(), 21));
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::ftpProxyServerName(), 2121));
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80));
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 443));
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3128));
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3129));
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3130));
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080));
+ QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1081));
+#else
if (!QtNetworkSettings::verifyTestNetworkSettings())
QSKIP("No network test server available");
+#endif
#if !defined Q_OS_WIN
wronlyFileName = testDataDir + "/write-only" + uniqueExtension;
QFile wr(wronlyFileName);
@@ -1808,8 +1833,13 @@ void tst_QNetworkReply::getFromFtp_data()
QTest::addColumn<QString>("referenceName");
QTest::addColumn<QString>("url");
- QTest::newRow("rfc3252.txt") << (testDataDir + "/rfc3252.txt") << "ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt";
- QTest::newRow("bigfile") << (testDataDir + "/bigfile") << "ftp://" + QtNetworkSettings::serverName() + "/qtest/bigfile";
+ QTest::newRow("rfc3252.txt")
+ << testDataDir + "/rfc3252.txt"
+ << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt";
+
+ QTest::newRow("bigfile")
+ << testDataDir + "/bigfile"
+ << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/bigfile";
}
void tst_QNetworkReply::getFromFtp()
@@ -1833,7 +1863,7 @@ void tst_QNetworkReply::getFromFtp()
void tst_QNetworkReply::getFromFtpAfterError()
{
- QNetworkRequest invalidRequest(QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/invalid.txt"));
+ QNetworkRequest invalidRequest(QUrl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/invalid.txt"));
QNetworkReplyPtr invalidReply;
invalidReply.reset(manager.get(invalidRequest));
QSignalSpy spy(invalidReply.data(), SIGNAL(error(QNetworkReply::NetworkError)));
@@ -1842,7 +1872,7 @@ void tst_QNetworkReply::getFromFtpAfterError()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkRequest validRequest(QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkRequest validRequest(QUrl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"));
QNetworkReplyPtr validReply;
RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::GetOperation, validRequest, validReply));
QCOMPARE(validReply->url(), validRequest.url());
@@ -1856,9 +1886,17 @@ void tst_QNetworkReply::getFromHttp_data()
QTest::addColumn<QString>("referenceName");
QTest::addColumn<QString>("url");
- QTest::newRow("success-internal") << (testDataDir + "/rfc3252.txt") << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt";
- QTest::newRow("success-external") << (testDataDir + "/rfc3252.txt") << "http://www.ietf.org/rfc/rfc3252.txt";
- QTest::newRow("bigfile-internal") << (testDataDir + "/bigfile") << "http://" + QtNetworkSettings::serverName() + "/qtest/bigfile";
+ QTest::newRow("success-internal")
+ << testDataDir + "/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt";
+
+ QTest::newRow("success-external")
+ << testDataDir + "/rfc3252.txt"
+ << "http://www.ietf.org/rfc/rfc3252.txt";
+
+ QTest::newRow("bigfile-internal")
+ << testDataDir + "/bigfile"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/bigfile";
}
void tst_QNetworkReply::getFromHttp()
@@ -1898,15 +1936,45 @@ void tst_QNetworkReply::headFromHttp_data()
qint64 rfcsize = QFileInfo(testDataDir + "/rfc3252.txt").size();
qint64 bigfilesize = QFileInfo(testDataDir + "/bigfile").size();
+
+#if defined(QT_TEST_SERVER)
+ qint64 indexsize = QFileInfo(testDataDir + "/testserver_index.html").size();
+#else
qint64 indexsize = QFileInfo(testDataDir + "/index.html").size();
+#endif
+ QString httpServer = QtNetworkSettings::httpServerName();
//testing proxies, mainly for the 407 response from http proxy
for (int i = 0; i < proxies.count(); ++i) {
- QTest::newRow("rfc" + proxies.at(i).tag) << rfcsize << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") << "text/plain" << proxies.at(i).proxy;
- QTest::newRow("bigfile" + proxies.at(i).tag) << bigfilesize << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile") << "text/plain" << proxies.at(i).proxy;
- QTest::newRow("index" + proxies.at(i).tag) << indexsize << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/") << "text/html" << proxies.at(i).proxy;
- QTest::newRow("with-authentication" + proxies.at(i).tag) << rfcsize << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << "text/plain" << proxies.at(i).proxy;
- QTest::newRow("cgi" + proxies.at(i).tag) << (qint64)-1 << QUrl("http://qt-test-server/qtest/cgi-bin/httpcachetest_expires500.cgi") << "text/html" << proxies.at(i).proxy;
+ QTest::newRow("rfc" + proxies.at(i).tag)
+ << rfcsize
+ << QUrl("http://" + httpServer + "/qtest/rfc3252.txt")
+ << "text/plain"
+ << proxies.at(i).proxy;
+
+ QTest::newRow("bigfile" + proxies.at(i).tag)
+ << bigfilesize
+ << QUrl("http://" + httpServer + "/qtest/bigfile")
+ << "text/plain"
+ << proxies.at(i).proxy;
+
+ QTest::newRow("index" + proxies.at(i).tag)
+ << indexsize
+ << QUrl("http://" + httpServer + "/qtest/")
+ << "text/html"
+ << proxies.at(i).proxy;
+
+ QTest::newRow("with-authentication" + proxies.at(i).tag)
+ << rfcsize
+ << QUrl("http://" + httpServer + "/qtest/rfcs-auth/rfc3252.txt")
+ << "text/plain"
+ << proxies.at(i).proxy;
+
+ QTest::newRow("cgi" + proxies.at(i).tag)
+ << (qint64)-1
+ << QUrl("http://" + httpServer + "/qtest/cgi-bin/httpcachetest_expires500.cgi")
+ << "text/html"
+ << proxies.at(i).proxy;
}
}
@@ -1988,23 +2056,23 @@ void tst_QNetworkReply::getErrors_data()
// ftp: errors
QTest::newRow("ftp-host") << "ftp://invalid.test.qt-project.org/foo.txt"
<< int(QNetworkReply::HostNotFoundError) << 0 << true;
- QTest::newRow("ftp-no-path") << "ftp://" + QtNetworkSettings::serverName()
+ QTest::newRow("ftp-no-path") << "ftp://" + QtNetworkSettings::ftpServerName()
<< int(QNetworkReply::ContentOperationNotPermittedError) << 0 << true;
- QTest::newRow("ftp-is-dir") << "ftp://" + QtNetworkSettings::serverName() + "/qtest"
+ QTest::newRow("ftp-is-dir") << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest"
<< int(QNetworkReply::ContentOperationNotPermittedError) << 0 << true;
- QTest::newRow("ftp-dir-not-readable") << "ftp://" + QtNetworkSettings::serverName() + "/pub/dir-not-readable/foo.txt"
+ QTest::newRow("ftp-dir-not-readable") << "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/dir-not-readable/foo.txt"
<< int(QNetworkReply::ContentAccessDenied) << 0 << true;
- QTest::newRow("ftp-file-not-readable") << "ftp://" + QtNetworkSettings::serverName() + "/pub/file-not-readable.txt"
+ QTest::newRow("ftp-file-not-readable") << "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/file-not-readable.txt"
<< int(QNetworkReply::ContentAccessDenied) << 0 << true;
- QTest::newRow("ftp-exist") << "ftp://" + QtNetworkSettings::serverName() + "/pub/this-file-doesnt-exist.txt"
+ QTest::newRow("ftp-exist") << "ftp://" + QtNetworkSettings::ftpServerName() + "/pub/this-file-doesnt-exist.txt"
<< int(QNetworkReply::ContentNotFoundError) << 0 << true;
// http: errors
QTest::newRow("http-host") << "http://invalid.test.qt-project.org/"
<< int(QNetworkReply::HostNotFoundError) << 0 << true;
- QTest::newRow("http-exist") << "http://" + QtNetworkSettings::serverName() + "/this-file-doesnt-exist.txt"
+ QTest::newRow("http-exist") << "http://" + QtNetworkSettings::httpServerName() + "/this-file-doesnt-exist.txt"
<< int(QNetworkReply::ContentNotFoundError) << 404 << false;
- QTest::newRow("http-authentication") << "http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth"
+ QTest::newRow("http-authentication") << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfcs-auth"
<< int(QNetworkReply::AuthenticationRequiredError) << 401 << false;
}
@@ -2130,7 +2198,7 @@ void tst_QNetworkReply::putToFtp_data()
void tst_QNetworkReply::putToFtp()
{
- QUrl url("ftp://" + QtNetworkSettings::serverName());
+ QUrl url("ftp://" + QtNetworkSettings::ftpServerName());
url.setPath(QString("/qtest/upload/qnetworkaccess-putToFtp-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
@@ -2176,7 +2244,7 @@ void tst_QNetworkReply::putToFtp()
void tst_QNetworkReply::putToFtpWithInvalidCredentials()
{
- QUrl url("ftp://" + QtNetworkSettings::serverName());
+ QUrl url("ftp://" + QtNetworkSettings::ftpServerName());
url.setPath(QString("/qtest/upload/qnetworkaccess-putToFtp-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
@@ -2203,7 +2271,7 @@ void tst_QNetworkReply::putToHttp_data()
void tst_QNetworkReply::putToHttp()
{
- QUrl url("http://" + QtNetworkSettings::serverName());
+ QUrl url("http://" + QtNetworkSettings::httpServerName());
url.setPath(QString("/dav/qnetworkaccess-putToHttp-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
@@ -2223,7 +2291,7 @@ void tst_QNetworkReply::putToHttp()
// download the file again from HTTP to make sure it was uploaded
// correctly. HTTP/0.9 is enough
QTcpSocket socket;
- socket.connectToHost(QtNetworkSettings::serverName(), 80);
+ socket.connectToHost(QtNetworkSettings::httpServerName(), 80);
socket.write("GET " + url.toEncoded(QUrl::RemoveScheme | QUrl::RemoveAuthority) + "\r\n");
if (!socket.waitForDisconnected(10000))
QFAIL("Network timeout");
@@ -2240,7 +2308,7 @@ void tst_QNetworkReply::putToHttpSynchronous_data()
void tst_QNetworkReply::putToHttpSynchronous()
{
- QUrl url("http://" + QtNetworkSettings::serverName());
+ QUrl url("http://" + QtNetworkSettings::httpServerName());
url.setPath(QString("/dav/qnetworkaccess-putToHttp-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
@@ -2264,7 +2332,7 @@ void tst_QNetworkReply::putToHttpSynchronous()
// download the file again from HTTP to make sure it was uploaded
// correctly. HTTP/0.9 is enough
QTcpSocket socket;
- socket.connectToHost(QtNetworkSettings::serverName(), 80);
+ socket.connectToHost(QtNetworkSettings::httpServerName(), 80);
socket.write("GET " + url.toEncoded(QUrl::RemoveScheme | QUrl::RemoveAuthority) + "\r\n");
if (!socket.waitForDisconnected(10000))
QFAIL("Network timeout");
@@ -2280,7 +2348,7 @@ void tst_QNetworkReply::postToHttp_data()
void tst_QNetworkReply::postToHttp()
{
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi");
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
@@ -2307,7 +2375,7 @@ void tst_QNetworkReply::postToHttpSynchronous_data()
void tst_QNetworkReply::postToHttpSynchronous()
{
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi");
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
@@ -2339,7 +2407,7 @@ void tst_QNetworkReply::postToHttpMultipart_data()
QTest::addColumn<QByteArray>("expectedReplyData");
QTest::addColumn<QByteArray>("contentType");
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/multipart.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/multipart.cgi");
QByteArray expectedData;
@@ -2388,8 +2456,13 @@ void tst_QNetworkReply::postToHttpMultipart_data()
multiPart2->setContentType(QHttpMultiPart::FormDataType);
multiPart2->append(textPart);
multiPart2->append(textPart2);
+#ifdef QT_TEST_SERVER
+ expectedData = "key: text, value: 7 bytes\n"
+ "key: text2, value: some more bytes\n";
+#else
expectedData = "key: text2, value: some more bytes\n"
"key: text, value: 7 bytes\n";
+#endif
QTest::newRow("text-text") << url << multiPart2 << expectedData << QByteArray("form-data");
@@ -2457,9 +2530,15 @@ void tst_QNetworkReply::postToHttpMultipart_data()
imagePart22.setBodyDevice(file22);
imageMultiPart2->append(imagePart22);
file22->setParent(imageMultiPart2);
+#ifdef QT_TEST_SERVER
+ expectedData = "key: text, value: 7 bytes\n"
+ "key: testImage1, value: 87ef3bb319b004ba9e5e9c9fa713776e\n"
+ "key: testImage2, value: 483761b893f7fb1bd2414344cd1f3dfb\n";
+#else
expectedData = "key: testImage1, value: 87ef3bb319b004ba9e5e9c9fa713776e\n"
"key: text, value: 7 bytes\n"
"key: testImage2, value: 483761b893f7fb1bd2414344cd1f3dfb\n";
+#endif
QTest::newRow("text-image-image") << url << imageMultiPart2 << expectedData << QByteArray("form-data");
@@ -2591,7 +2670,7 @@ void tst_QNetworkReply::postToHttpMultipart()
void tst_QNetworkReply::multipartSkipIndices() // QTBUG-32534
{
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::MixedType);
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/multipart.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/multipart.cgi");
QNetworkRequest request(url);
QList<QByteArray> parts;
parts << QByteArray(56083, 'X') << QByteArray(468, 'X') << QByteArray(24952, 'X');
@@ -2685,13 +2764,13 @@ void tst_QNetworkReply::putToHttps_data()
void tst_QNetworkReply::putToHttps()
{
- QUrl url("https://" + QtNetworkSettings::serverName());
+ QUrl url("https://" + QtNetworkSettings::httpServerName());
url.setPath(QString("/dav/qnetworkaccess-putToHttp-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
QNetworkRequest request(url);
- QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + certsFilePath);
QSslConfiguration conf;
conf.setCaCertificates(certs);
request.setSslConfiguration(conf);
@@ -2709,7 +2788,7 @@ void tst_QNetworkReply::putToHttps()
// download the file again from HTTP to make sure it was uploaded
// correctly. HTTP/0.9 is enough
QTcpSocket socket;
- socket.connectToHost(QtNetworkSettings::serverName(), 80);
+ socket.connectToHost(QtNetworkSettings::httpServerName(), 80);
socket.write("GET " + url.toEncoded(QUrl::RemoveScheme | QUrl::RemoveAuthority) + "\r\n");
if (!socket.waitForDisconnected(10000))
QFAIL("Network timeout");
@@ -2726,13 +2805,13 @@ void tst_QNetworkReply::putToHttpsSynchronous_data()
void tst_QNetworkReply::putToHttpsSynchronous()
{
- QUrl url("https://" + QtNetworkSettings::serverName());
+ QUrl url("https://" + QtNetworkSettings::httpServerName());
url.setPath(QString("/dav/qnetworkaccess-putToHttp-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
QNetworkRequest request(url);
- QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + certsFilePath);
QSslConfiguration conf;
conf.setCaCertificates(certs);
request.setSslConfiguration(conf);
@@ -2754,7 +2833,7 @@ void tst_QNetworkReply::putToHttpsSynchronous()
// download the file again from HTTP to make sure it was uploaded
// correctly. HTTP/0.9 is enough
QTcpSocket socket;
- socket.connectToHost(QtNetworkSettings::serverName(), 80);
+ socket.connectToHost(QtNetworkSettings::httpServerName(), 80);
socket.write("GET " + url.toEncoded(QUrl::RemoveScheme | QUrl::RemoveAuthority) + "\r\n");
if (!socket.waitForDisconnected(10000))
QFAIL("Network timeout");
@@ -2770,10 +2849,10 @@ void tst_QNetworkReply::postToHttps_data()
void tst_QNetworkReply::postToHttps()
{
- QUrl url("https://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi");
+ QUrl url("https://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi");
QNetworkRequest request(url);
- QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + certsFilePath);
QSslConfiguration conf;
conf.setCaCertificates(certs);
request.setSslConfiguration(conf);
@@ -2801,10 +2880,10 @@ void tst_QNetworkReply::postToHttpsSynchronous_data()
void tst_QNetworkReply::postToHttpsSynchronous()
{
- QUrl url("https://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi");
+ QUrl url("https://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi");
QNetworkRequest request(url);
- QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + certsFilePath);
QSslConfiguration conf;
conf.setCaCertificates(certs);
request.setSslConfiguration(conf);
@@ -2843,7 +2922,7 @@ void tst_QNetworkReply::postToHttpsMultipart()
static QSet<QByteArray> boundaries;
QNetworkRequest request(url);
- QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + certsFilePath);
QSslConfiguration conf;
conf.setCaCertificates(certs);
request.setSslConfiguration(conf);
@@ -2888,11 +2967,26 @@ void tst_QNetworkReply::deleteFromHttp_data()
// for status codes to expect, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
- QTest::newRow("405-method-not-allowed") << QUrl("http://" + QtNetworkSettings::serverName() + "/index.html") << 405 << QNetworkReply::ContentOperationNotPermittedError;
- QTest::newRow("200-ok") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/http-delete.cgi?200-ok") << 200 << QNetworkReply::NoError;
- QTest::newRow("202-accepted") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/http-delete.cgi?202-accepted") << 202 << QNetworkReply::NoError;
- QTest::newRow("204-no-content") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/http-delete.cgi?204-no-content") << 204 << QNetworkReply::NoError;
- QTest::newRow("404-not-found") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/http-delete.cgi?404-not-found") << 404 << QNetworkReply::ContentNotFoundError;
+ QString httpServer = QtNetworkSettings::httpServerName();
+ QTest::newRow("405-method-not-allowed")
+ << QUrl("http://" + httpServer + "/index.html")
+ << 405 << QNetworkReply::ContentOperationNotPermittedError;
+
+ QTest::newRow("200-ok")
+ << QUrl("http://" + httpServer + "/qtest/cgi-bin/http-delete.cgi?200-ok")
+ << 200 << QNetworkReply::NoError;
+
+ QTest::newRow("202-accepted")
+ << QUrl("http://" + httpServer + "/qtest/cgi-bin/http-delete.cgi?202-accepted")
+ << 202 << QNetworkReply::NoError;
+
+ QTest::newRow("204-no-content")
+ << QUrl("http://" + httpServer + "/qtest/cgi-bin/http-delete.cgi?204-no-content")
+ << 204 << QNetworkReply::NoError;
+
+ QTest::newRow("404-not-found")
+ << QUrl("http://" + httpServer + "/qtest/cgi-bin/http-delete.cgi?404-not-found")
+ << 404 << QNetworkReply::ContentNotFoundError;
}
void tst_QNetworkReply::deleteFromHttp()
@@ -2920,7 +3014,7 @@ void tst_QNetworkReply::putGetDeleteGetFromHttp_data()
QTest::addColumn<int>("get2ResultCode");
QTest::addColumn<QNetworkReply::NetworkError>("get2Error");
- QUrl url("http://" + QtNetworkSettings::serverName());
+ QUrl url("http://" + QtNetworkSettings::httpServerName());
url.setPath(QString("/dav/qnetworkaccess-putToHttp-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
@@ -2928,7 +3022,7 @@ void tst_QNetworkReply::putGetDeleteGetFromHttp_data()
// first use case: put, get (to check it is there), delete, get (to check it is not there anymore)
QTest::newRow("success") << url << 201 << QNetworkReply::NoError << url << 204 << QNetworkReply::NoError << url << 404 << QNetworkReply::ContentNotFoundError;
- QUrl wrongUrl("http://" + QtNetworkSettings::serverName());
+ QUrl wrongUrl("http://" + QtNetworkSettings::httpServerName());
wrongUrl.setPath(QString("/dav/qnetworkaccess-thisURLisNotAvailable"));
// second use case: put, get (to check it is there), delete wrong URL, get (to check it is still there)
@@ -3023,27 +3117,27 @@ void tst_QNetworkReply::sendCustomRequestToHttp_data()
QTest::addColumn<QNetworkReply::NetworkError>("error");
QTest::addColumn<QByteArray>("expectedContent");
- QTest::newRow("options") << QUrl("http://" + QtNetworkSettings::serverName()) <<
+ QTest::newRow("options") << QUrl("http://" + QtNetworkSettings::httpServerName()) <<
QByteArray("OPTIONS") << (QBuffer *) 0 << 200 << QNetworkReply::NoError << QByteArray();
- QTest::newRow("trace") << QUrl("http://" + QtNetworkSettings::serverName()) <<
+ QTest::newRow("trace") << QUrl("http://" + QtNetworkSettings::httpServerName()) <<
QByteArray("TRACE") << (QBuffer *) 0 << 200 << QNetworkReply::NoError << QByteArray();
- QTest::newRow("connect") << QUrl("http://" + QtNetworkSettings::serverName()) <<
+ QTest::newRow("connect") << QUrl("http://" + QtNetworkSettings::httpServerName()) <<
QByteArray("CONNECT") << (QBuffer *) 0 << 400 << QNetworkReply::ProtocolInvalidOperationError << QByteArray(); // 400 = Bad Request
- QTest::newRow("nonsense") << QUrl("http://" + QtNetworkSettings::serverName()) <<
+ QTest::newRow("nonsense") << QUrl("http://" + QtNetworkSettings::httpServerName()) <<
QByteArray("NONSENSE") << (QBuffer *) 0 << 501 << QNetworkReply::OperationNotImplementedError << QByteArray(); // 501 = Method Not Implemented
QByteArray ba("test");
QBuffer *buffer = new QBuffer;
buffer->setData(ba);
buffer->open(QIODevice::ReadOnly);
- QTest::newRow("post") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi") << QByteArray("POST")
+ QTest::newRow("post") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi") << QByteArray("POST")
<< buffer << 200 << QNetworkReply::NoError << QByteArray("098f6bcd4621d373cade4e832627b4f6\n");
QByteArray ba2("test");
QBuffer *buffer2 = new QBuffer;
buffer2->setData(ba2);
buffer2->open(QIODevice::ReadOnly);
- QTest::newRow("put") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi") << QByteArray("PUT")
+ QTest::newRow("put") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi") << QByteArray("PUT")
<< buffer2 << 200 << QNetworkReply::NoError << QByteArray("098f6bcd4621d373cade4e832627b4f6\n");
}
@@ -3181,7 +3275,7 @@ void tst_QNetworkReply::ioGetFromFtp()
QFile reference(fileName);
reference.open(QIODevice::ReadOnly); // will fail for bigfile
- QNetworkRequest request("ftp://" + QtNetworkSettings::serverName() + "/qtest/" + fileName);
+ QNetworkRequest request("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/" + fileName);
QNetworkReplyPtr reply(manager.get(request));
DataReader reader(reply);
@@ -3204,7 +3298,7 @@ void tst_QNetworkReply::ioGetFromFtpWithReuse()
QFile reference(fileName);
reference.open(QIODevice::ReadOnly);
- QNetworkRequest request(QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkRequest request(QUrl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"));
// two concurrent (actually, consecutive) gets:
QNetworkReplyPtr reply1(manager.get(request));
@@ -3236,7 +3330,7 @@ void tst_QNetworkReply::ioGetFromHttp()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
QNetworkReplyPtr reply(manager.get(request));
DataReader reader(reply);
@@ -3257,7 +3351,7 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseParallel()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
QNetworkReplyPtr reply1(manager.get(request));
QNetworkReplyPtr reply2(manager.get(request));
DataReader reader1(reply1);
@@ -3289,7 +3383,7 @@ void tst_QNetworkReply::ioGetFromHttpWithReuseSequential()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
{
QNetworkReplyPtr reply(manager.get(request));
DataReader reader(reply);
@@ -3334,16 +3428,40 @@ void tst_QNetworkReply::ioGetFromHttpWithAuth_data()
QFile reference(testDataDir + "/rfc3252.txt");
reference.open(QIODevice::ReadOnly);
QByteArray referenceData = reference.readAll();
- QTest::newRow("basic") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData << 1;
- QTest::newRow("digest") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n") << 1;
+ QString httpServer = QtNetworkSettings::httpServerName();
+ QTest::newRow("basic")
+ << QUrl("http://" + httpServer + "/qtest/rfcs-auth/rfc3252.txt")
+ << referenceData << 1;
+
+ QTest::newRow("digest")
+ << QUrl("http://" + httpServer + "/qtest/auth-digest/")
+ << QByteArray("digest authentication successful\n") << 1;
+
//if url contains username & password, then it should be used
- QTest::newRow("basic-in-url") << QUrl("http://httptest:httptest@" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData << 0;
- QTest::newRow("digest-in-url") << QUrl("http://httptest:httptest@" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n") << 0;
+ QTest::newRow("basic-in-url")
+ << QUrl("http://httptest:httptest@" + httpServer + "/qtest/rfcs-auth/rfc3252.txt")
+ << referenceData << 0;
+
+ QTest::newRow("digest-in-url")
+ << QUrl("http://httptest:httptest@" + httpServer + "/qtest/auth-digest/")
+ << QByteArray("digest authentication successful\n") << 0;
+
// if url contains incorrect credentials, expect QNAM to ask for good ones (even if cached - matches behaviour of browsers)
- QTest::newRow("basic-bad-user-in-url") << QUrl("http://baduser:httptest@" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData << 3;
- QTest::newRow("basic-bad-password-in-url") << QUrl("http://httptest:wrong@" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt") << referenceData << 3;
- QTest::newRow("digest-bad-user-in-url") << QUrl("http://baduser:httptest@" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n") << 3;
- QTest::newRow("digest-bad-password-in-url") << QUrl("http://httptest:wrong@" + QtNetworkSettings::serverName() + "/qtest/auth-digest/") << QByteArray("digest authentication successful\n") << 3;
+ QTest::newRow("basic-bad-user-in-url")
+ << QUrl("http://baduser:httptest@" + httpServer + "/qtest/rfcs-auth/rfc3252.txt")
+ << referenceData << 3;
+
+ QTest::newRow("basic-bad-password-in-url")
+ << QUrl("http://httptest:wrong@" + httpServer + "/qtest/rfcs-auth/rfc3252.txt")
+ << referenceData << 3;
+
+ QTest::newRow("digest-bad-user-in-url")
+ << QUrl("http://baduser:httptest@" + httpServer + "/qtest/auth-digest/")
+ << QByteArray("digest authentication successful\n") << 3;
+
+ QTest::newRow("digest-bad-password-in-url")
+ << QUrl("http://httptest:wrong@" + httpServer + "/qtest/auth-digest/")
+ << QByteArray("digest authentication successful\n") << 3;
}
void tst_QNetworkReply::ioGetFromHttpWithAuth()
@@ -3459,7 +3577,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuthSynchronous()
// verify that we do not enter an endless loop with synchronous calls and wrong credentials
// the case when we succeed with the login is tested in ioGetFromHttpWithAuth()
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt"));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfcs-auth/rfc3252.txt"));
request.setAttribute(
QNetworkRequest::SynchronousRequestAttribute,
true);
@@ -3481,8 +3599,8 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuth()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkProxy proxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkProxy proxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129);
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
{
manager.setProxy(proxy);
QNetworkReplyPtr reply1(manager.get(request));
@@ -3561,8 +3679,8 @@ void tst_QNetworkReply::ioGetFromHttpWithProxyAuthSynchronous()
// verify that we do not enter an endless loop with synchronous calls and wrong credentials
// the case when we succeed with the login is tested in ioGetFromHttpWithAuth()
- QNetworkProxy proxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkProxy proxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129);
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
manager.setProxy(proxy);
request.setAttribute(
QNetworkRequest::SynchronousRequestAttribute,
@@ -3585,8 +3703,8 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080);
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080);
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
{
manager.setProxy(proxy);
QNetworkReplyPtr reply(manager.get(request));
@@ -3609,7 +3727,7 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy()
}
// set an invalid proxy just to make sure that we can't load
- proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1079);
+ proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1079);
{
manager.setProxy(proxy);
QNetworkReplyPtr reply(manager.get(request));
@@ -3643,7 +3761,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslErrors()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkRequest request(QUrl("https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
QNetworkReplyPtr reply(manager.get(request));
DataReader reader(reply);
@@ -3674,7 +3792,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithIgnoreSslErrors()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkRequest request(QUrl("https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
QNetworkReplyPtr reply(manager.get(request));
reply->ignoreSslErrors();
@@ -3699,7 +3817,7 @@ void tst_QNetworkReply::ioGetFromHttpsWithSslHandshakeError()
QFile reference(testDataDir + "/rfc3252.txt");
QVERIFY(reference.open(QIODevice::ReadOnly));
- QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + ":80"));
+ QNetworkRequest request(QUrl("https://" + QtNetworkSettings::httpServerName() + ":80"));
QNetworkReplyPtr reply(manager.get(request));
reply->ignoreSslErrors();
@@ -4013,34 +4131,34 @@ void tst_QNetworkReply::ioGetWithManyProxies_data()
// Simple tests that work:
// HTTP request with HTTP caching proxy
- proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("http-on-http")
<< proxyList << proxyList.at(0)
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// HTTP request with HTTP transparent proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("http-on-http2")
<< proxyList << proxyList.at(0)
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// HTTP request with SOCKS transparent proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
+ proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081);
QTest::newRow("http-on-socks")
<< proxyList << proxyList.at(0)
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// FTP request with FTP caching proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121);
+ proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121);
QTest::newRow("ftp-on-ftp")
<< proxyList << proxyList.at(0)
- << "ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// The following test doesn't work because QFtp is too limited
@@ -4048,27 +4166,27 @@ void tst_QNetworkReply::ioGetWithManyProxies_data()
// FTP request with SOCKSv5 transparent proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
+ proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081);
QTest::newRow("ftp-on-socks")
<< proxyList << proxyList.at(0)
- << "ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
#ifndef QT_NO_SSL
// HTTPS with HTTP transparent proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("https-on-http")
<< proxyList << proxyList.at(0)
- << "https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// HTTPS request with SOCKS transparent proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
+ proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081);
QTest::newRow("https-on-socks")
<< proxyList << proxyList.at(0)
- << "https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
#endif
@@ -4076,44 +4194,44 @@ void tst_QNetworkReply::ioGetWithManyProxies_data()
// HTTP request with FTP caching proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121);
+ proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121);
QTest::newRow("http-on-ftp")
<< proxyList << QNetworkProxy()
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
// FTP request with HTTP caching proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("ftp-on-http")
<< proxyList << QNetworkProxy()
- << "ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
// FTP request with HTTP caching proxies
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
- << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3130);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
+ << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3130);
QTest::newRow("ftp-on-multiple-http")
<< proxyList << QNetworkProxy()
- << "ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
#ifndef QT_NO_SSL
// HTTPS with HTTP caching proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("https-on-httptransparent")
<< proxyList << QNetworkProxy()
- << "https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
// HTTPS with FTP caching proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121);
+ proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121);
QTest::newRow("https-on-ftp")
<< proxyList << QNetworkProxy()
- << "https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::ProxyNotFoundError;
#endif
@@ -4121,77 +4239,77 @@ void tst_QNetworkReply::ioGetWithManyProxies_data()
// HTTP request with more than one HTTP proxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
- << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3130);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
+ << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3130);
QTest::newRow("http-on-multiple-http")
<< proxyList << proxyList.at(0)
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// HTTP request with HTTP + SOCKS
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
- << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
+ << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081);
QTest::newRow("http-on-http+socks")
<< proxyList << proxyList.at(0)
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// HTTP request with FTP + HTTP + SOCKS
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
- << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
- << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081);
+ proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121)
+ << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
+ << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081);
QTest::newRow("http-on-ftp+http+socks")
<< proxyList << proxyList.at(1) // second proxy should be used
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// HTTP request with NoProxy + HTTP
proxyList.clear();
proxyList << QNetworkProxy(QNetworkProxy::NoProxy)
- << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129);
+ << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("http-on-noproxy+http")
<< proxyList << proxyList.at(0)
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// HTTP request with FTP + NoProxy
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
+ proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121)
<< QNetworkProxy(QNetworkProxy::NoProxy);
QTest::newRow("http-on-ftp+noproxy")
<< proxyList << proxyList.at(1) // second proxy should be used
- << "http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// FTP request with HTTP Caching + FTP
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
- << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
+ << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121);
QTest::newRow("ftp-on-http+ftp")
<< proxyList << proxyList.at(1) // second proxy should be used
- << "ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
#ifndef QT_NO_SSL
// HTTPS request with HTTP Caching + HTTP transparent
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
- << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129);
+ proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
+ << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("https-on-httpcaching+http")
<< proxyList << proxyList.at(1) // second proxy should be used
- << "https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
// HTTPS request with FTP + HTTP C + HTTP T
proxyList.clear();
- proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121)
- << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)
- << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129);
+ proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121)
+ << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129)
+ << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3129);
QTest::newRow("https-on-ftp+httpcaching+http")
<< proxyList << proxyList.at(2) // skip the first two
- << "https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"
+ << "https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"
<< QNetworkReply::NoError;
#endif
}
@@ -4442,7 +4560,7 @@ void tst_QNetworkReply::ioPutToFtpFromFile()
QFile sourceFile(fileName);
QVERIFY(sourceFile.open(QIODevice::ReadOnly));
- QUrl url("ftp://" + QtNetworkSettings::serverName());
+ QUrl url("ftp://" + QtNetworkSettings::ftpServerName());
url.setPath(QString("/qtest/upload/qnetworkaccess-ioPutToFtpFromFile-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
@@ -4491,7 +4609,7 @@ void tst_QNetworkReply::ioPutToHttpFromFile()
QFile sourceFile(fileName);
QVERIFY(sourceFile.open(QIODevice::ReadOnly));
- QUrl url("http://" + QtNetworkSettings::serverName());
+ QUrl url("http://" + QtNetworkSettings::httpServerName());
url.setPath(QString("/dav/qnetworkaccess-ioPutToHttpFromFile-%1-%2")
.arg(QTest::currentDataTag())
.arg(uniqueExtension));
@@ -4534,7 +4652,7 @@ void tst_QNetworkReply::ioPostToHttpFromFile()
QFile sourceFile(fileName);
QVERIFY(sourceFile.open(QIODevice::ReadOnly));
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi");
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
@@ -4568,9 +4686,9 @@ void tst_QNetworkReply::ioPostToHttpFromSocket_data()
for (int auth = 0; auth < 2; ++auth) {
QUrl url;
if (auth)
- url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi";
+ url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi";
else
- url = "http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi";
+ url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi";
QNetworkProxy proxy = proxies.at(i).proxy;
QByteArray testsuffix = QByteArray(auth ? "+auth" : "") + proxies.at(i).tag;
@@ -4685,7 +4803,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous()
// ### for 4.8: make the socket pair unbuffered, to not read everything in one go in QNetworkReplyImplPrivate::setup()
QTestEventLoop::instance().enterLoop(3);
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi");
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
request.setAttribute(
@@ -4716,7 +4834,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileToEnd()
// seeking to the middle
sourceFile.seek(sourceFile.size() / 2);
- QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi";
+ QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi";
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
QNetworkReplyPtr reply(manager.post(request, &sourceFile));
@@ -4742,7 +4860,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfFileFiveBytes()
// seeking to the middle
sourceFile.seek(sourceFile.size() / 2);
- QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi";
+ QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi";
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
// only send 5 bytes
@@ -4773,7 +4891,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfQBufferFiveBytes()
uploadBuffer.write("1234567890");
uploadBuffer.seek(5);
- QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi";
+ QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi";
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
QNetworkReplyPtr reply(manager.post(request, &uploadBuffer));
@@ -4801,7 +4919,7 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag()
QTRY_VERIFY(socketpair.create()); //QTRY_VERIFY as a workaround for QTBUG-24451
socketpair.endPoints[0]->write(data);
- QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi";
+ QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi";
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
// disallow buffering
@@ -5216,7 +5334,7 @@ void tst_QNetworkReply::lastModifiedHeaderForFile()
void tst_QNetworkReply::lastModifiedHeaderForHttp()
{
// Tue, 22 May 2007 12:04:57 GMT according to webserver
- QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/fluke.gif";
+ QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/fluke.gif";
QNetworkRequest request(url);
QNetworkReplyPtr reply(manager.head(request));
@@ -5232,7 +5350,7 @@ void tst_QNetworkReply::lastModifiedHeaderForHttp()
void tst_QNetworkReply::httpCanReadLine()
{
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"));
QNetworkReplyPtr reply(manager.get(request));
QVERIFY2(waitForFinish(reply) == Success, msgWaitForFinished(reply));
@@ -5312,11 +5430,11 @@ void tst_QNetworkReply::downloadProgress_data()
QTest::addColumn<int>("expectedSize");
QTest::newRow("empty") << QUrl::fromLocalFile(QFINDTESTDATA("empty")) << 0;
- QTest::newRow("http:small") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") << 25962;
- QTest::newRow("http:big") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile") << 519240;
- QTest::newRow("http:no-length") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/deflate/rfc2616.html") << -1;
- QTest::newRow("ftp:small") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") << 25962;
- QTest::newRow("ftp:big") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile") << 519240;
+ QTest::newRow("http:small") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt") << 25962;
+ QTest::newRow("http:big") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/bigfile") << 519240;
+ QTest::newRow("http:no-length") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/deflate/rfc2616.html") << -1;
+ QTest::newRow("ftp:small") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt") << 25962;
+ QTest::newRow("ftp:big") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/bigfile") << 519240;
}
class SlowReader : public QObject
@@ -5473,7 +5591,7 @@ void tst_QNetworkReply::receiveCookiesFromHttp_data()
QList<QNetworkCookie> header, jar;
QNetworkCookie cookie("a", "b");
header << cookie;
- cookie.setDomain(QtNetworkSettings::serverName());
+ cookie.setDomain(QtNetworkSettings::httpServerName());
cookie.setPath("/qtest/cgi-bin/");
jar << cookie;
QTest::newRow("simple-cookie") << "a=b" << header << jar;
@@ -5497,7 +5615,7 @@ void tst_QNetworkReply::receiveCookiesFromHttp_data()
cookie = QNetworkCookie("a", "b");
cookie.setPath("/not/part-of-path");
header << cookie;
- cookie.setDomain(QtNetworkSettings::serverName());
+ cookie.setDomain(QtNetworkSettings::httpServerName());
jar << cookie;
QTest::newRow("invalid-cookie-path") << "a=b; path=/not/part-of-path" << header << jar;
@@ -5514,7 +5632,7 @@ void tst_QNetworkReply::receiveCookiesFromHttp()
QFETCH(QString, cookieString);
QByteArray data = cookieString.toLatin1() + '\n';
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/set-cookie.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/set-cookie.cgi");
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
QNetworkReplyPtr reply;
@@ -5541,7 +5659,7 @@ void tst_QNetworkReply::receiveCookiesFromHttpSynchronous()
QFETCH(QString, cookieString);
QByteArray data = cookieString.toLatin1() + '\n';
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/set-cookie.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/set-cookie.cgi");
QNetworkRequest request(url);
request.setRawHeader("Content-Type", "application/octet-stream");
@@ -5577,7 +5695,7 @@ void tst_QNetworkReply::sendCookies_data()
list << cookie;
QTest::newRow("no-match-domain") << list << "";
- cookie.setDomain(QtNetworkSettings::serverName());
+ cookie.setDomain(QtNetworkSettings::httpServerName());
cookie.setPath("/something/else");
list << cookie;
QTest::newRow("no-match-path") << list << "";
@@ -5610,7 +5728,7 @@ void tst_QNetworkReply::sendCookies()
QFETCH(QList<QNetworkCookie>, cookiesToSet);
cookieJar->setAllCookies(cookiesToSet);
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/get-cookie.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/get-cookie.cgi");
QNetworkRequest request(url);
QNetworkReplyPtr reply;
RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::GetOperation, request, reply));
@@ -5634,7 +5752,7 @@ void tst_QNetworkReply::sendCookiesSynchronous()
QFETCH(QList<QNetworkCookie>, cookiesToSet);
cookieJar->setAllCookies(cookiesToSet);
- QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/get-cookie.cgi");
+ QUrl url("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/get-cookie.cgi");
QNetworkRequest request(url);
request.setAttribute(
@@ -5682,7 +5800,7 @@ void tst_QNetworkReply::nestedEventLoops()
qDebug("Takes 16 seconds to run, please wait");
- QUrl url("http://" + QtNetworkSettings::serverName());
+ QUrl url("http://" + QtNetworkSettings::httpServerName());
QNetworkRequest request(url);
QNetworkReplyPtr reply(manager.get(request));
@@ -5840,7 +5958,7 @@ void tst_QNetworkReply::proxyChange()
"HTTP/1.0 200 OK\r\nProxy-Connection: keep-alive\r\n"
"Content-Length: 1\r\n\r\n1");
QNetworkProxy dummyProxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer.serverPort());
- QNetworkRequest req(QUrl("http://" + QtNetworkSettings::serverName()));
+ QNetworkRequest req(QUrl("http://" + QtNetworkSettings::httpServerName()));
proxyServer.doClose = false;
{
@@ -5899,13 +6017,17 @@ void tst_QNetworkReply::authorizationError_data()
QTest::addColumn<int>("httpStatusCode");
QTest::addColumn<QString>("httpBody");
- QTest::newRow("unknown-authorization-method") << "http://" + QtNetworkSettings::serverName() +
- "/qtest/cgi-bin/http-unknown-authentication-method.cgi?401-authorization-required" << 1 << 1
- << int(QNetworkReply::AuthenticationRequiredError) << 401 << "authorization required";
- QTest::newRow("unknown-proxy-authorization-method") << "http://" + QtNetworkSettings::serverName() +
- "/qtest/cgi-bin/http-unknown-authentication-method.cgi?407-proxy-authorization-required" << 1 << 1
- << int(QNetworkReply::ProxyAuthenticationRequiredError) << 407
- << "authorization required";
+ QTest::newRow("unknown-authorization-method")
+ << "http://" + QtNetworkSettings::httpServerName()
+ + "/qtest/cgi-bin/http-unknown-authentication-method.cgi?401-authorization-required"
+ << 1 << 1 << int(QNetworkReply::AuthenticationRequiredError)
+ << 401 << "authorization required";
+
+ QTest::newRow("unknown-proxy-authorization-method")
+ << "http://" + QtNetworkSettings::httpServerName()
+ + "/qtest/cgi-bin/http-unknown-authentication-method.cgi?407-proxy-authorization-required"
+ << 1 << 1 << int(QNetworkReply::ProxyAuthenticationRequiredError)
+ << 407 << "authorization required";
}
void tst_QNetworkReply::authorizationError()
@@ -6124,7 +6246,7 @@ public slots:
}
void startOne()
{
- QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/fluke.gif";
+ QUrl url = "http://" + QtNetworkSettings::httpServerName() + "/qtest/fluke.gif";
QNetworkRequest request(url);
QNetworkReply *reply = manager.get(request);
reply->setParent(this);
@@ -6146,29 +6268,28 @@ void tst_QNetworkReply::httpRecursiveCreation()
#ifndef QT_NO_SSL
void tst_QNetworkReply::ignoreSslErrorsList_data()
{
- QTest::addColumn<QString>("url");
QTest::addColumn<QList<QSslError> >("expectedSslErrors");
QTest::addColumn<QNetworkReply::NetworkError>("expectedNetworkError");
QList<QSslError> expectedSslErrors;
- QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + certsFilePath);
QSslError rightError(FLUKE_CERTIFICATE_ERROR, certs.at(0));
QSslError wrongError(FLUKE_CERTIFICATE_ERROR);
- QTest::newRow("SSL-failure-empty-list") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::SslHandshakeFailedError;
+ QTest::newRow("SSL-failure-empty-list") << expectedSslErrors << QNetworkReply::SslHandshakeFailedError;
expectedSslErrors.append(wrongError);
- QTest::newRow("SSL-failure-wrong-error") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::SslHandshakeFailedError;
+ QTest::newRow("SSL-failure-wrong-error") << expectedSslErrors << QNetworkReply::SslHandshakeFailedError;
expectedSslErrors.append(rightError);
- QTest::newRow("allErrorsInExpectedList1") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::NoError;
+ QTest::newRow("allErrorsInExpectedList1") << expectedSslErrors << QNetworkReply::NoError;
expectedSslErrors.removeAll(wrongError);
- QTest::newRow("allErrorsInExpectedList2") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::NoError;
+ QTest::newRow("allErrorsInExpectedList2") << expectedSslErrors << QNetworkReply::NoError;
expectedSslErrors.removeAll(rightError);
- QTest::newRow("SSL-failure-empty-list-again") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::SslHandshakeFailedError;
+ QTest::newRow("SSL-failure-empty-list-again") << expectedSslErrors << QNetworkReply::SslHandshakeFailedError;
}
void tst_QNetworkReply::ignoreSslErrorsList()
{
- QFETCH(QString, url);
+ QString url(QLatin1String("https://") + QtNetworkSettings::httpServerName() + QLatin1String("/index.html"));
QNetworkRequest request(url);
QNetworkReplyPtr reply(manager.get(request));
@@ -6195,7 +6316,7 @@ void tst_QNetworkReply::ignoreSslErrorListSlot(QNetworkReply *reply, const QList
// do the same as in ignoreSslErrorsList, but ignore the errors in the slot
void tst_QNetworkReply::ignoreSslErrorsListWithSlot()
{
- QFETCH(QString, url);
+ QString url(QLatin1String("https://") + QtNetworkSettings::httpServerName() + QLatin1String("/index.html"));
QNetworkRequest request(url);
QNetworkReplyPtr reply(manager.get(request));
@@ -6220,7 +6341,7 @@ void tst_QNetworkReply::sslConfiguration_data()
QTest::newRow("empty") << QSslConfiguration() << false;
QSslConfiguration conf = QSslConfiguration::defaultConfiguration();
QTest::newRow("default") << conf << false; // does not contain test server cert
- QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(testDataDir + certsFilePath);
conf.setCaCertificates(testServerCert);
QTest::newRow("set-root-cert") << conf << true;
conf.setProtocol(QSsl::SecureProtocols);
@@ -6229,8 +6350,8 @@ void tst_QNetworkReply::sslConfiguration_data()
void tst_QNetworkReply::encrypted()
{
- qDebug() << QtNetworkSettings::serverName();
- QUrl url("https://" + QtNetworkSettings::serverName());
+ qDebug() << QtNetworkSettings::httpServerName();
+ QUrl url("https://" + QtNetworkSettings::httpServerName());
QNetworkRequest request(url);
QNetworkReply *reply = manager.get(request);
reply->ignoreSslErrors();
@@ -6278,7 +6399,7 @@ void tst_QNetworkReply::abortOnEncrypted()
void tst_QNetworkReply::sslConfiguration()
{
- QNetworkRequest request(QUrl("https://" + QtNetworkSettings::serverName() + "/index.html"));
+ QNetworkRequest request(QUrl("https://" + QtNetworkSettings::httpServerName() + "/index.html"));
QFETCH(QSslConfiguration, configuration);
request.setSslConfiguration(configuration);
QNetworkReplyPtr reply(manager.get(request));
@@ -6305,7 +6426,7 @@ void tst_QNetworkReply::sslSessionSharing()
QSKIP("Not implemented with SecureTransport");
#endif
- QString urlString("https://" + QtNetworkSettings::serverName());
+ QString urlString("https://" + QtNetworkSettings::httpServerName());
QList<QNetworkReplyPtr> replies;
// warm up SSL session cache
@@ -6373,7 +6494,7 @@ void tst_QNetworkReply::sslSessionSharingFromPersistentSession()
QSKIP("Not implemented with SecureTransport");
#endif
- QString urlString("https://" + QtNetworkSettings::serverName());
+ QString urlString("https://" + QtNetworkSettings::httpServerName());
// warm up SSL session cache to get a working session
QNetworkRequest warmupRequest(urlString);
@@ -6439,7 +6560,7 @@ void tst_QNetworkReply::getAndThenDeleteObject()
QSKIP("unstable test - reply may be finished too early");
// yes, this will leak if the testcase fails. I don't care. It must not fail then :P
QNetworkAccessManager *manager = new QNetworkAccessManager();
- QNetworkRequest request("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile");
+ QNetworkRequest request("http://" + QtNetworkSettings::httpServerName() + "/qtest/bigfile");
QNetworkReply *reply = manager->get(request);
reply->setReadBufferSize(1);
reply->setParent((QObject*)0); // must be 0 because else it is the manager
@@ -6479,7 +6600,7 @@ void tst_QNetworkReply::getFromHttpIntoBuffer_data()
{
QTest::addColumn<QUrl>("url");
- QTest::newRow("rfc-internal") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt");
+ QTest::newRow("rfc-internal") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt");
}
// Please note that the whole "zero copy" download buffer API is private right now. Do not use it.
@@ -6892,9 +7013,15 @@ void tst_QNetworkReply::authenticationCacheAfterCancel_data()
QTest::addColumn<bool>("proxyAuth");
QTest::addColumn<QUrl>("url");
for (int i = 0; i < proxies.count(); ++i) {
- QTest::newRow("http" + proxies.at(i).tag) << proxies.at(i).proxy << proxies.at(i).requiresAuthentication << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt");
+ QTest::newRow("http" + proxies.at(i).tag)
+ << proxies.at(i).proxy
+ << proxies.at(i).requiresAuthentication
+ << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfcs-auth/rfc3252.txt");
#ifndef QT_NO_SSL
- QTest::newRow("https" + proxies.at(i).tag) << proxies.at(i).proxy << proxies.at(i).requiresAuthentication << QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt");
+ QTest::newRow("https" + proxies.at(i).tag)
+ << proxies.at(i).proxy
+ << proxies.at(i).requiresAuthentication
+ << QUrl("https://" + QtNetworkSettings::httpServerName() + "/qtest/rfcs-auth/rfc3252.txt");
#endif
}
}
@@ -7083,7 +7210,7 @@ void tst_QNetworkReply::authenticationWithDifferentRealm()
helper.httpUserName = "httptest";
helper.httpPassword = "httptest";
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt"));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfcs-auth/rfc3252.txt"));
QNetworkReply* reply = manager.get(request);
connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
QTestEventLoop::instance().enterLoop(10);
@@ -7093,7 +7220,7 @@ void tst_QNetworkReply::authenticationWithDifferentRealm()
helper.httpUserName = "httptest";
helper.httpPassword = "httptest";
- request.setUrl(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/auth-digest/"));
+ request.setUrl(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/auth-digest/"));
reply = manager.get(request);
connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
QTestEventLoop::instance().enterLoop(10);
@@ -7135,7 +7262,7 @@ void tst_QNetworkReply::qtbug13431replyThrottling()
connect(&nam, SIGNAL(finished(QNetworkReply*)), &helper, SLOT(replyFinished(QNetworkReply*)));
// Download a bigger file
- QNetworkRequest netRequest(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile"));
+ QNetworkRequest netRequest(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/bigfile"));
helper.m_reply = nam.get(netRequest);
// Set the throttle
helper.m_reply->setReadBufferSize(36000);
@@ -7161,7 +7288,7 @@ void tst_QNetworkReply::httpWithNoCredentialUsage()
// Get with credentials, to preload authentication cache
{
- QNetworkRequest request(QUrl("http://httptest:httptest@" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"));
+ QNetworkRequest request(QUrl("http://httptest:httptest@" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi"));
QNetworkReplyPtr reply(manager.get(request));
QVERIFY2(waitForFinish(reply) == Success, msgWaitForFinished(reply));
// credentials in URL, so don't expect authentication signal
@@ -7172,7 +7299,7 @@ void tst_QNetworkReply::httpWithNoCredentialUsage()
// Get with cached credentials (normal usage)
{
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi"));
QNetworkReplyPtr reply(manager.get(request));
QVERIFY2(waitForFinish(reply) == Success, msgWaitForFinished(reply));
// credentials in cache, so don't expect authentication signal
@@ -7183,7 +7310,7 @@ void tst_QNetworkReply::httpWithNoCredentialUsage()
// Do not use cached credentials (webkit cross origin usage)
{
- QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/protected/cgi-bin/md5sum.cgi"));
request.setAttribute(QNetworkRequest::AuthenticationReuseAttribute, QNetworkRequest::Manual);
QNetworkReplyPtr reply(manager.get(request));
@@ -7502,13 +7629,13 @@ void tst_QNetworkReply::synchronousRequest_data()
// ### cache, auth, proxies
QTest::newRow("http")
- << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")
+ << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt")
<< QString("file:" + testDataDir + "/rfc3252.txt")
<< true
<< QString("text/plain");
QTest::newRow("http-gzip")
- << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/deflate/rfc3252.txt")
+ << QUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/deflate/rfc3252.txt")
<< QString("file:" + testDataDir + "/rfc3252.txt")
<< false // don't check content length, because it's gzip encoded
// ### we would need to enflate (un-deflate) the file content and compare the sizes
@@ -7516,7 +7643,7 @@ void tst_QNetworkReply::synchronousRequest_data()
#ifndef QT_NO_SSL
QTest::newRow("https")
- << QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")
+ << QUrl("https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt")
<< QString("file:" + testDataDir + "/rfc3252.txt")
<< true
<< QString("text/plain");
@@ -7552,7 +7679,7 @@ void tst_QNetworkReply::synchronousRequest()
// QNetworkRequest, see QTBUG-14774
if (url.scheme() == "https") {
QSslConfiguration sslConf;
- QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + "/certs/qt-test-server-cacert.pem");
+ QList<QSslCertificate> certs = QSslCertificate::fromPath(testDataDir + certsFilePath);
sslConf.setCaCertificates(certs);
request.setSslConfiguration(sslConf);
}
@@ -7597,7 +7724,7 @@ void tst_QNetworkReply::synchronousRequestSslFailure()
// and that we do not emit the sslError signal (in the manager that is,
// in the reply we don't care)
- QUrl url("https://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt");
+ QUrl url("https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt");
QNetworkRequest request(url);
request.setAttribute(
QNetworkRequest::SynchronousRequestAttribute,
@@ -7643,7 +7770,7 @@ void tst_QNetworkReply::httpAbort()
// It must not crash either.
// Abort after the first readyRead()
- QNetworkRequest request("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile");
+ QNetworkRequest request("http://" + QtNetworkSettings::httpServerName() + "/qtest/bigfile");
QNetworkReplyPtr reply(manager.get(request));
HttpAbortHelper replyHolder(reply.data());
QTestEventLoop::instance().enterLoop(10);
@@ -7659,7 +7786,7 @@ void tst_QNetworkReply::httpAbort()
QVERIFY(reply2->isFinished());
// Abort after the finished()
- QNetworkRequest request3("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt");
+ QNetworkRequest request3("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt");
QNetworkReplyPtr reply3(manager.get(request3));
QCOMPARE(waitForFinish(reply3), int(Success));
@@ -7795,7 +7922,7 @@ void tst_QNetworkReply::synchronousAuthenticationCache()
void tst_QNetworkReply::pipelining()
{
- QString urlString("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/echo.cgi?");
+ QString urlString("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/echo.cgi?");
QList<QNetworkReplyPtr> replies;
for (int a = 0; a < 20; a++) {
QNetworkRequest request(urlString + QString::number(a));
@@ -7839,8 +7966,8 @@ void tst_QNetworkReply::emitErrorForAllRepliesSlot() {
void tst_QNetworkReply::closeDuringDownload_data()
{
QTest::addColumn<QUrl>("url");
- QTest::newRow("http") << QUrl("http://" + QtNetworkSettings::serverName() + "/bigfile");
- QTest::newRow("ftp") << QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/bigfile");
+ QTest::newRow("http") << QUrl("http://" + QtNetworkSettings::httpServerName() + "/bigfile");
+ QTest::newRow("ftp") << QUrl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/bigfile");
}
void tst_QNetworkReply::closeDuringDownload()
@@ -7864,8 +7991,8 @@ void tst_QNetworkReply::ftpAuthentication_data()
QTest::addColumn<QString>("url");
QTest::addColumn<int>("error");
- QTest::newRow("invalidPassword") << (testDataDir + "/rfc3252.txt") << "ftp://ftptest:invalid@" + QtNetworkSettings::serverName() + "/home/qt-test-server/ftp/qtest/rfc3252.txt" << int(QNetworkReply::AuthenticationRequiredError);
- QTest::newRow("validPassword") << (testDataDir + "/rfc3252.txt") << "ftp://ftptest:password@" + QtNetworkSettings::serverName() + "/home/qt-test-server/ftp/qtest/rfc3252.txt" << int(QNetworkReply::NoError);
+ QTest::newRow("invalidPassword") << (testDataDir + "/rfc3252.txt") << "ftp://ftptest:invalid@" + QtNetworkSettings::ftpServerName() + "/home/qt-test-server/ftp/qtest/rfc3252.txt" << int(QNetworkReply::AuthenticationRequiredError);
+ QTest::newRow("validPassword") << (testDataDir + "/rfc3252.txt") << "ftp://ftptest:password@" + QtNetworkSettings::ftpServerName() + "/home/qt-test-server/ftp/qtest/rfc3252.txt" << int(QNetworkReply::NoError);
}
void tst_QNetworkReply::ftpAuthentication()
@@ -7925,9 +8052,9 @@ void tst_QNetworkReply::backgroundRequest_data()
QTest::addColumn<int>("policy");
QTest::addColumn<QNetworkReply::NetworkError>("error");
- QUrl httpurl("http://" + QtNetworkSettings::serverName());
- QUrl httpsurl("https://" + QtNetworkSettings::serverName());
- QUrl ftpurl("ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt");
+ QUrl httpurl("http://" + QtNetworkSettings::httpServerName());
+ QUrl httpsurl("https://" + QtNetworkSettings::httpServerName());
+ QUrl ftpurl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt");
QTest::newRow("http, fg, normal") << httpurl << false << (int)QNetworkSession::NoPolicy << QNetworkReply::NoError;
QTest::newRow("http, bg, normal") << httpurl << true << (int)QNetworkSession::NoPolicy << QNetworkReply::NoError;
@@ -7996,9 +8123,9 @@ void tst_QNetworkReply::backgroundRequestInterruption_data()
QTest::addColumn<bool>("background");
QTest::addColumn<QNetworkReply::NetworkError>("error");
- QUrl httpurl("http://" + QtNetworkSettings::serverName() + "/qtest/mediumfile");
- QUrl httpsurl("https://" + QtNetworkSettings::serverName() + "/qtest/mediumfile");
- QUrl ftpurl("ftp://" + QtNetworkSettings::serverName() + "/qtest/bigfile");
+ QUrl httpurl("http://" + QtNetworkSettings::httpServerName() + "/qtest/mediumfile");
+ QUrl httpsurl("https://" + QtNetworkSettings::httpServerName() + "/qtest/mediumfile");
+ QUrl ftpurl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/bigfile");
QTest::newRow("http, fg, nobg") << httpurl << false << QNetworkReply::NoError;
QTest::newRow("http, bg, nobg") << httpurl << true << QNetworkReply::BackgroundRequestNotAllowedError;
@@ -8069,8 +8196,8 @@ void tst_QNetworkReply::backgroundRequestConnectInBackground_data()
QTest::addColumn<QUrl>("url");
QTest::addColumn<bool>("background");
- QUrl httpurl("http://" + QtNetworkSettings::serverName());
- QUrl ftpurl("ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt");
+ QUrl httpurl("http://" + QtNetworkSettings::httpServerName());
+ QUrl ftpurl("ftp://" + QtNetworkSettings::ftpServerName() + "/qtest/rfc3252.txt");
QTest::newRow("http, fg") << httpurl << false;
QTest::newRow("http, bg") << httpurl << true;
@@ -8196,7 +8323,7 @@ void tst_QNetworkReply::putWithRateLimiting()
QByteArray data = reference.readAll();
QVERIFY(data.length() > 0);
- QUrl url = QUrl::fromUserInput("http://" + QtNetworkSettings::serverName()+ "/qtest/cgi-bin/echo.cgi?");
+ QUrl url = QUrl::fromUserInput("http://" + QtNetworkSettings::httpServerName()+ "/qtest/cgi-bin/echo.cgi?");
QNetworkRequest request(url);
QNetworkReplyPtr reply;
@@ -8641,7 +8768,7 @@ void tst_QNetworkReply::ioHttpRedirect()
void tst_QNetworkReply::ioHttpRedirectFromLocalToRemote()
{
- QUrl targetUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt");
+ QUrl targetUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt");
QString redirectReply = tempRedirectReplyStr().arg(targetUrl.toString());
MiniHttpServer redirectServer(redirectReply.toLatin1(), false);
@@ -8710,7 +8837,7 @@ void tst_QNetworkReply::ioHttpRedirectPostPut()
QFETCH(QByteArray, data);
QFETCH(QString, contentType);
- QUrl targetUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi");
+ QUrl targetUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/cgi-bin/md5sum.cgi");
QString redirectReply = QStringLiteral("HTTP/1.1 %1\r\n"
"Content-Type: text/plain\r\n"
@@ -8999,7 +9126,7 @@ void tst_QNetworkReply::putWithServerClosingConnectionImmediately()
// NOTE: This test must be last testcase in tst_qnetworkreply!
void tst_QNetworkReply::parentingRepliesToTheApp()
{
- QNetworkRequest request (QUrl("http://" + QtNetworkSettings::serverName()));
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::httpServerName()));
manager.get(request)->setParent(this); // parent to this object
manager.get(request)->setParent(qApp); // parent to the app
}
diff --git a/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp b/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp
index 50c7ddb0b6..7a3def410a 100644
--- a/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp
+++ b/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp
@@ -236,6 +236,46 @@ void tst_QNetworkRequest::setHeader_data()
<< true << "Last-Modified"
<< "Thu, 01 Nov 2007 18:08:30 GMT";
+ QTest::newRow("If-Modified-Since-Date") << QNetworkRequest::IfModifiedSinceHeader
+ << QVariant(QDate(2017, 7, 01))
+ << true << "If-Modified-Since"
+ << "Sat, 01 Jul 2017 00:00:00 GMT";
+ QTest::newRow("If-Modified-Since-DateTime") << QNetworkRequest::IfModifiedSinceHeader
+ << QVariant(QDateTime(QDate(2017, 7, 01),
+ QTime(3, 14, 15),
+ Qt::UTC))
+ << true << "If-Modified-Since"
+ << "Sat, 01 Jul 2017 03:14:15 GMT";
+
+ QTest::newRow("Etag-strong") << QNetworkRequest::ETagHeader << QVariant(R"("xyzzy")")
+ << true << "ETag" << R"("xyzzy")";
+ QTest::newRow("Etag-weak") << QNetworkRequest::ETagHeader << QVariant(R"(W/"xyzzy")")
+ << true << "ETag" << R"(W/"xyzzy")";
+ QTest::newRow("Etag-empty") << QNetworkRequest::ETagHeader << QVariant(R"("")")
+ << true << "ETag" << R"("")";
+
+ QTest::newRow("If-Match-empty") << QNetworkRequest::IfMatchHeader << QVariant(R"("")")
+ << true << "If-Match" << R"("")";
+ QTest::newRow("If-Match-any") << QNetworkRequest::IfMatchHeader << QVariant(R"("*")")
+ << true << "If-Match" << R"("*")";
+ QTest::newRow("If-Match-single") << QNetworkRequest::IfMatchHeader << QVariant(R"("xyzzy")")
+ << true << "If-Match" << R"("xyzzy")";
+ QTest::newRow("If-Match-multiple") << QNetworkRequest::IfMatchHeader
+ << QVariant(R"("xyzzy", "r2d2xxxx", "c3piozzzz")")
+ << true << "If-Match"
+ << R"("xyzzy", "r2d2xxxx", "c3piozzzz")";
+
+ QTest::newRow("If-None-Match-empty") << QNetworkRequest::IfNoneMatchHeader << QVariant(R"("")")
+ << true << "If-None-Match" << R"("")";
+ QTest::newRow("If-None-Match-any") << QNetworkRequest::IfNoneMatchHeader << QVariant(R"("*")")
+ << true << "If-None-Match" << R"("*")";
+ QTest::newRow("If-None-Match-single") << QNetworkRequest::IfNoneMatchHeader << QVariant(R"("xyzzy")")
+ << true << "If-None-Match" << R"("xyzzy")";
+ QTest::newRow("If-None-Match-multiple") << QNetworkRequest::IfNoneMatchHeader
+ << QVariant(R"("xyzzy", W/"r2d2xxxx", "c3piozzzz")")
+ << true << "If-None-Match"
+ << R"("xyzzy", W/"r2d2xxxx", "c3piozzzz")";
+
QNetworkCookie cookie;
cookie.setName("a");
cookie.setValue("b");
@@ -327,6 +367,62 @@ void tst_QNetworkRequest::rawHeaderParsing_data()
<< true << "Last-Modified"
<< "Sun Nov 6 08:49:37 1994";
+ QTest::newRow("If-Modified-Since-RFC1123") << QNetworkRequest::IfModifiedSinceHeader
+ << QVariant(QDateTime(QDate(1994, 8, 06),
+ QTime(8, 49, 37),
+ Qt::UTC))
+ << true << "If-Modified-Since"
+ << "Sun, 06 Aug 1994 08:49:37 GMT";
+ QTest::newRow("If-Modified-Since-RFC850") << QNetworkRequest::IfModifiedSinceHeader
+ << QVariant(QDateTime(QDate(1994, 8, 06),
+ QTime(8, 49, 37),
+ Qt::UTC))
+ << true << "If-Modified-Since"
+ << "Sunday, 06-Aug-94 08:49:37 GMT";
+ QTest::newRow("If-Modified-Since-asctime") << QNetworkRequest::IfModifiedSinceHeader
+ << QVariant(QDateTime(QDate(1994, 8, 06),
+ QTime(8, 49, 37),
+ Qt::UTC))
+ << true << "If-Modified-Since"
+ << "Sun Aug 6 08:49:37 1994";
+
+ QTest::newRow("Etag-strong") << QNetworkRequest::ETagHeader << QVariant(R"("xyzzy")")
+ << true << "ETag" << R"("xyzzy")";
+ QTest::newRow("Etag-weak") << QNetworkRequest::ETagHeader << QVariant(R"(W/"xyzzy")")
+ << true << "ETag" << R"(W/"xyzzy")";
+ QTest::newRow("Etag-empty") << QNetworkRequest::ETagHeader << QVariant(R"("")")
+ << true << "ETag" << R"("")";
+
+ QTest::newRow("If-Match-empty") << QNetworkRequest::IfMatchHeader << QVariant(QStringList(R"("")"))
+ << true << "If-Match" << R"("")";
+ QTest::newRow("If-Match-any") << QNetworkRequest::IfMatchHeader << QVariant(QStringList(R"("*")"))
+ << true << "If-Match" << R"("*")";
+ QTest::newRow("If-Match-single") << QNetworkRequest::IfMatchHeader
+ << QVariant(QStringList(R"("xyzzy")"))
+ << true << "If-Match" << R"("xyzzy")";
+ QTest::newRow("If-Match-multiple") << QNetworkRequest::IfMatchHeader
+ << QVariant(QStringList({R"("xyzzy")",
+ R"("r2d2xxxx")",
+ R"("c3piozzzz")"}))
+ << true << "If-Match"
+ << R"("xyzzy", "r2d2xxxx", "c3piozzzz")";
+
+ QTest::newRow("If-None-Match-empty") << QNetworkRequest::IfNoneMatchHeader
+ << QVariant(QStringList(R"("")"))
+ << true << "If-None-Match" << R"("")";
+ QTest::newRow("If-None-Match-any") << QNetworkRequest::IfNoneMatchHeader
+ << QVariant(QStringList(R"("*")"))
+ << true << "If-None-Match" << R"("*")";
+ QTest::newRow("If-None-Match-single") << QNetworkRequest::IfNoneMatchHeader
+ << QVariant(QStringList(R"("xyzzy")"))
+ << true << "If-None-Match" << R"("xyzzy")";
+ QTest::newRow("If-None-Match-multiple") << QNetworkRequest::IfNoneMatchHeader
+ << QVariant(QStringList({R"("xyzzy")",
+ R"(W/"r2d2xxxx")",
+ R"("c3piozzzz")"}))
+ << true << "If-None-Match"
+ << R"("xyzzy", W/"r2d2xxxx", "c3piozzzz")";
+
QTest::newRow("Content-Length-invalid1") << QNetworkRequest::ContentLengthHeader << QVariant()
<< false << "Content-Length" << "1a";
QTest::newRow("Content-Length-invalid2") << QNetworkRequest::ContentLengthHeader << QVariant()
diff --git a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
index bc53faf106..01168cc0d6 100644
--- a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
+++ b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
@@ -29,10 +29,6 @@
#include <QtTest/QTest>
-#ifdef Q_OS_WIN
-#include <winsock2.h>
-#endif
-
#include <qcoreapplication.h>
#include <qdatastream.h>
#include <qhostaddress.h>
diff --git a/tests/auto/network/ssl/qdtls/certs/bogus-ca.crt b/tests/auto/network/ssl/qdtls/certs/bogus-ca.crt
new file mode 100644
index 0000000000..cf5893e98d
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/bogus-ca.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDMzCCAhugAwIBAgIJAJBdFtmKuuELMA0GCSqGSIb3DQEBCwUAMC8xGjAYBgNV
+BAoMEUJvZ3VzIENvcnBvcmF0aW9uMREwDwYDVQQDDAhCb2d1cyBDQTAgFw0xNTAx
+MzAxNzM0NDdaGA8yMTE1MDEwNjE3MzQ0N1owLzEaMBgGA1UECgwRQm9ndXMgQ29y
+cG9yYXRpb24xETAPBgNVBAMMCEJvZ3VzIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAnXt/X69lmfvWampP88f20yNs1VZroG9VjdR4GaJM6pbWu5Wn
+SYBfS81osnHC7dTW2FvKZUGnz7KX+ImkbE2qUvj6yTeFu6ILj3o+8ws7A4iOTkiH
+84CHb6T/HxWO5fW6mS5v+tvPDp3rQ7JpPVYvoh7dSv8X1+JCdDmkepRveN6Pzo47
+9VFVC0oscc5I4Y0wPwnaXZ4X26vmRfbhqtoKL57lz1lJ0R6bvLC9mf4DGFPx7WXQ
+eOtlKX2dtuKj+Cl3vyHff6gHNMKM0bq3KfsT+vDO6eIs/ayqVRdd0XBIMj+bZYd9
+7QI/+3XTNR3TwTisrjo71XZtHdA1DkcMaSGoJwIDAQABo1AwTjAdBgNVHQ4EFgQU
+xVZK4BIjBgmluCLIespCbne4BIUwHwYDVR0jBBgwFoAUxVZK4BIjBgmluCLIespC
+bne4BIUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAgZn6odHr2y1G
+1OStblBdsXNxmsW7WzhLUYFUhSzBw9KS/O7uG2HAFLwJNM4sQHeuc0JjxqXG5n7s
+mGbmWpUYt8+KJDRnUssmKwwg2u6Rqp+0I9leCk9KTtYpXX7d9wprSsgwjQKhTEeQ
+fNImbNR6Br7GDO7Om2MnOALvZmp0KJgUFIH0J630LJTrsrTvwfX7wKhYb1wgud5N
+SXdGjBuJxKK3Y0VBMsbqwI0y+wHIYE+qLzlFWNRHmKaYeGtg0T8CVK6XWUrLcjcr
+rQINqW3rb1OlWF7YZ5dg7vXoZrza6YSQLWha6/FQMCaKtJHxIE1NBw0ZXK6txnkI
+f4HXoPvSGg==
+-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qdtls/certs/bogus-ca.key b/tests/auto/network/ssl/qdtls/certs/bogus-ca.key
new file mode 100644
index 0000000000..1c2db7932e
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/bogus-ca.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAnXt/X69lmfvWampP88f20yNs1VZroG9VjdR4GaJM6pbWu5Wn
+SYBfS81osnHC7dTW2FvKZUGnz7KX+ImkbE2qUvj6yTeFu6ILj3o+8ws7A4iOTkiH
+84CHb6T/HxWO5fW6mS5v+tvPDp3rQ7JpPVYvoh7dSv8X1+JCdDmkepRveN6Pzo47
+9VFVC0oscc5I4Y0wPwnaXZ4X26vmRfbhqtoKL57lz1lJ0R6bvLC9mf4DGFPx7WXQ
+eOtlKX2dtuKj+Cl3vyHff6gHNMKM0bq3KfsT+vDO6eIs/ayqVRdd0XBIMj+bZYd9
+7QI/+3XTNR3TwTisrjo71XZtHdA1DkcMaSGoJwIDAQABAoIBAGKkKmJq4L8UyXca
+ZD4UcHxL4i221e9GDVarURbtXDRMivAwivo1GHvIi93J+Ak0meYniJzoBQ7JlPsu
+a/kSpK8YGS3UQ0YF+CvErI1b6XkLHefW8qEJTswVk1+LB1jvFBRCzA1bhVRogiaD
+J/wtceSgZIhHRE4LAQj/2hCVzUTtV6Zr0GIJGjB7hdF9MHGlTwkPrkjvERlK/PTc
+dVjyNbinYGJNA2i701u/atplH2eSBUresMhHu3AZUUXZKfFQ2m07FDBNAtsoYNnO
+d17EXDaoQRDVWSP83GN4b/hpmngvHl1fuFBZ1ms375FNPQo/K33QBaUsLsqiIS/v
+k3LBkeECgYEAyqv5dkgte9c2mxT5zUQySr1fDms4nwZTth8477jRnOZND1M9VoIv
+1EjBfxq3y7gJVd34VWYeCxNBYwK8C45SDXtlU9X2hLeKWU6yfdegyxv950P5AahT
+J80YtYSez+mTLPOC42GeTg7l01NXlTHmPpraIkdNniHc8bqyAEK9w+kCgYEAxuuO
+Ln84GkAm1gr6gyFkOMVwVEfszKjRGIqp4BnSwM9bFgWvhyj4jpr+bpe4gQKQQE5q
+E/GoxYOtdZ3yYupd2Ki0irGhhm3u0ywgmbomurOw46AInONWcHTU6kZY/dd8wfvW
+8YcmFq/LNupwFOEw18mKaQXygMnUYci+uOSw0Y8CgYEAkcX0XjE4FdUL/6usqQme
+KsfesR5J0YfZeism5rXGftXfI2C5w5lMEaJrGqL7A9pRTKOlVLdocIrfAvoaiy1I
+s03H6e8Bqx/gsK+8DmujybNOgqMPXTPW68/HL/g9ykm0hCZ6RFYYaQiqIb/WRQdp
+FiqHLxSeLVkp8+xWz30xxNECgYAA7P23Z64qKRxFKL3ruE8QGJMiQUdv2GVIuPR7
+b4NUlGJ3IsWjWmR1vXDrsNcR+qITOoox15ESgj9facHEBhUzue1FK/h1eLOA1ha8
+wGoHumhbVtZTbJdtZI3NHVCytbsF6Bci/p8FwgGvGr40yquAhZaYUIfFY6sSXW3N
+zHqqLwKBgQCUGrePDhjjUZZNQya0TQZ95HL8OQB2e9bx8RwypYdC3pAZ6uDfl+Ne
+IZoA8EoDHVbsxDXmLTGil/kyvmYBnzvkVz/yMyFm/7I0zXEOr8bTgqE5wJ8BMGSp
+yil5jDoN28KL6D+HsDsWUEOvvHieDYP3cxfpZWiQuWIZ6gfDDVjIwQ==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qdtls/certs/bogus-client.crt b/tests/auto/network/ssl/qdtls/certs/bogus-client.crt
new file mode 100644
index 0000000000..c9d43ce662
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/bogus-client.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIC/zCCAeegAwIBAgIBADANBgkqhkiG9w0BAQsFADAvMRowGAYDVQQKDBFCb2d1
+cyBDb3Jwb3JhdGlvbjERMA8GA1UEAwwIQm9ndXMgQ0EwIBcNMTUwMTMwMTczNTI0
+WhgPMjExNTAxMDYxNzM1MjRaMDMxGjAYBgNVBAoMEUJvZ3VzIENvcnBvcmF0aW9u
+MRUwEwYDVQQDDAxCb2d1cyBDbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDa28y3b2qcrFTjr3GIgjx78qlbRZomBt/A//ZW5qx00+QXT30bu8F0
+jCfHaBTDSnabP86856C/kL1d6oRtc7jmaxNoj39uRh3NcV3VmFEiLI9XmJ0gOIBN
+vMQ0voi4gvRBzjFMnVOFML8FePV4OUX1QUZK4eAvZCsDhaJv1cCEERsfcttv7X31
+CT3+a3geZsb0cMDqicq/uaX2IONhqoNYwGlmgF+bWICIxJmEnaK3e/LnKKpvvfTt
+n2M0Fx0W4150HSZxQ9Iz6fQQ8oLNn3qNL5i9377XKpck2uxC39yt5WXK2d5m8xBF
+5+qwMMqlEW4LoE/dTU9mJ1lZLwV7m7QJAgMBAAGjIDAeMAkGA1UdEwQCMAAwEQYJ
+YIZIAYb4QgEBBAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IBAQBBeGwXbU/WRLkfxDoI
+Js2nPqzpfEXAcrJhurHKlm/wMIHnHHhTM69O7yTl/VUdKIXPzC1bGkAiSBQo+51B
+SJkyWo3vt47g8rqAnUs4oM+bPD2t1YkJVeGLu+Nfw5SHlc+HdojdAcpKtnCbqtrd
+vnV4QyB70nxKXC3jmWVBu/jeim0RzUacO+lF9vRPqwnlDINopx8ZpEjaXxABtaQA
+cVUosFGEPRjOYAbw9j4fK7J7EXh/124j81OfawkfaMMDt2EedmSdlhPy+Io7VaBo
+ho+39cX/oO3Ek+C9v+4aGF7rgp3VyKOGtC5rIy+YiwjcI09pRVPuqEqXC6C4nQcS
+SjjF
+-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qdtls/certs/bogus-client.key b/tests/auto/network/ssl/qdtls/certs/bogus-client.key
new file mode 100644
index 0000000000..f676af73d4
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/bogus-client.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA2tvMt29qnKxU469xiII8e/KpW0WaJgbfwP/2VuasdNPkF099
+G7vBdIwnx2gUw0p2mz/OvOegv5C9XeqEbXO45msTaI9/bkYdzXFd1ZhRIiyPV5id
+IDiATbzENL6IuIL0Qc4xTJ1ThTC/BXj1eDlF9UFGSuHgL2QrA4Wib9XAhBEbH3Lb
+b+199Qk9/mt4HmbG9HDA6onKv7ml9iDjYaqDWMBpZoBfm1iAiMSZhJ2it3vy5yiq
+b7307Z9jNBcdFuNedB0mcUPSM+n0EPKCzZ96jS+Yvd++1yqXJNrsQt/creVlytne
+ZvMQRefqsDDKpRFuC6BP3U1PZidZWS8Fe5u0CQIDAQABAoIBAQDOzZlA0CgWiYTh
+bLvEOQQ8Pw0msLs7KY2vCm7UqL3W2w4RtMvMM/tWTMWd2EyeSLOQeZe5ysmLmpJF
+tz+RSSMzn4REbiwEoH6yzWfUWEx6FU8Rf6UheCJM0o04Jb59U0jJEbRl59eu6GPo
+IOcaxkvDtv1b7tnvDiDTACiAsqNqZhs54QlqwpadSYe4QgK9KH0WxqBzLpXr8eEq
+ZV1uuuNpaf+mitVaJhXHyVt7Od1yPfohbTYaXjko3xt3BcStt4tzRZkGQk2kjMWd
+d53wqcFlc+zxSW9/ogLr+TCDttTEa1oV+JLpXLkV5J0/saf/LYw96r6f98XhLrd1
+5otsbQ+dAoGBAP0nCzd6otnuUsLX+dz0ed61zDzyTVBXLxuOOvDpuPItVUKPI8yZ
+mwveIm97/4u50HGSWUgLR5v+ABfMVG/DqkEP50dDbIhQ2uBhkR5xVgSlZSiZ7S03
+1AErADaeViphKjfAuHraGgC6SRv8HBZadbYW+ZQRVTF6IRJmstiLNJIDAoGBAN1S
+AYtYhH0tJSQxyL+sdeuPGhY5RDdlSeLRAStpoGjmaOC4Rc8uDsts2xuInkCcTW2y
+nogoR5YxFvcly3vGL5kOzLuscLbueqkz/rbTlZPruqL7fMyPI7Y3YgGER5XNwPpE
++DlW1fu2aE42WUU49mkUNaT2WBtOLnbZKShAWKoDAoGAOGZfeF/JMnaHV8OYdmK9
+WCH2u8lb8j9KToBUn2HjA4mYCjkrx6SdR3qY/2+H0pB2YScy3vssXBOt3591XGUi
+ZFZvt4/M+V3SNdVm6HplqKlUrUQF9GIQyKXU6VZDajO1nTBBqZU339ug+Cwl8dD7
+krLxrcxix6AnCBt7UwVIlBMCgYEAydQADogxgknKJiC0Vn86pg9BFeUxXWckIxDA
+hUt0+lSsbcn993qkCUUC5zAGSRuAzLnoMnixF7k6nTW9Q+mu/GBvufH+dAQ0ndsJ
+vMZlEJkXAYxf+dfLFF+bI5DzCxywkEqXJwsWZs6ofjK35BWXOKoyZXY1UOlSHBXb
+n5ZWhOsCgYBRLqEjUehkZfqjZj8VClyPQ/6bAgtfjMRqpgsLgvqG9gBraDs4DXJr
+K8Ac3+vCP8rqVwIUC0iu/5MFX75WJ7Go7wbAg7m91P9tmzSiLEm5H1toXJpla6nv
+oLZW+jN9O1BaVow8f2qIEJMjHnDbuZnMPQlMGUD+g2tNgczfxT3MOA==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qdtls/certs/bogus-server.crt b/tests/auto/network/ssl/qdtls/certs/bogus-server.crt
new file mode 100644
index 0000000000..7e59f6128d
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/bogus-server.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQsFADAvMRowGAYDVQQKDBFCb2d1
+cyBDb3Jwb3JhdGlvbjERMA8GA1UEAwwIQm9ndXMgQ0EwIBcNMTUwMTMxMTc0MjI3
+WhgPMjExNTAxMDcxNzQyMjdaMDMxGjAYBgNVBAoMEUJvZ3VzIENvcnBvcmF0aW9u
+MRUwEwYDVQQDDAxCb2d1cyBTZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCv899JQxy/mpaQzscopmoKOkgbmwGwty1KiTpT09MU1+gtMHCfhmVp
+nAiNIlQlDa+5mjhvyy1fSf+mgdjnvT5pdUAro633gfCv318EViwYsvA7/0ZumFqU
+UyPWw4/2of/ZfJv2ewzMLoYEDKiLcXxInBsMlt5Lr7IBS8SNitDU+TAM7HLEIkMz
+c0JpxY09H707tO8G3e93yfB5l8H+JdeEdPe+7PDfnsZZuMmaImiNYRByPTTuGvrN
+I9I+OxcE4ZOMMNb3mzAoEFnyfHiCO2ehHl58y0a49ayAKJdP/FV3n2LtL/Zc5Ilq
+b3VJgaShevrfIiItURjOAjDA9B95hYuZAgMBAAGjIDAeMAkGA1UdEwQCMAAwEQYJ
+YIZIAYb4QgEBBAQDAgZAMA0GCSqGSIb3DQEBCwUAA4IBAQBhTqwD3HxamZGopq0K
+r8KUdtliiPwo4GBFp0zg6VdSxo01WfpwFGOaeKNmV0JadtJ1DhcsdIUv2OvrxiWQ
+1n0IGHULeazQnst1q1t/Vlup3IggKTGCLi8yd3acY8tr2wj9lGjWhsR+BcrCUTEB
+BCpIsQiFA8+PTf/8SHuzMokDBP+j02fWCqwR749H4NDQgqrFsgzxLDA69XgvkNM3
++HOsOR/QxeYIp54mqPnsNVhzV0JbpQpF4j9R5kMI/bsPmWH6W0GbSSyA07o8iVw7
+eqPbwHnIlHXzafvaGmF0QituAzU0nPgMc9OMxuoqacBSmSvmSdMmh///vr7O2KHO
+7s+g
+-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qdtls/certs/bogus-server.key b/tests/auto/network/ssl/qdtls/certs/bogus-server.key
new file mode 100644
index 0000000000..bda8dae678
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/bogus-server.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAr/PfSUMcv5qWkM7HKKZqCjpIG5sBsLctSok6U9PTFNfoLTBw
+n4ZlaZwIjSJUJQ2vuZo4b8stX0n/poHY570+aXVAK6Ot94Hwr99fBFYsGLLwO/9G
+bphalFMj1sOP9qH/2Xyb9nsMzC6GBAyoi3F8SJwbDJbeS6+yAUvEjYrQ1PkwDOxy
+xCJDM3NCacWNPR+9O7TvBt3vd8nweZfB/iXXhHT3vuzw357GWbjJmiJojWEQcj00
+7hr6zSPSPjsXBOGTjDDW95swKBBZ8nx4gjtnoR5efMtGuPWsgCiXT/xVd59i7S/2
+XOSJam91SYGkoXr63yIiLVEYzgIwwPQfeYWLmQIDAQABAoIBAHVRJJLjpZp3h2a8
+CHypIND69TM60hCywgcNoo9cEES4hL0ErEMhSCL3f5giyHoAOyeElZasoO8FFuk9
+cJNrUd7c59FxDECYKhQJ2n+4uSQqwxUt6xc4jESTfrTmpemrMD0h4ZehifHmH0M5
+8XMwUs7TDxIA0e0jE4vbqg05/m3RMHoeJ4W5K4dMxkJbjmyjjCr8aT8WP/KSTABS
+YQPql0rs6WL5Q2s1I/i3I4qIS4CKk8Ym7O5/Wk1fxbCh2ABL2PhW8PZDzvsFYo2T
+cwX0cc0EILBc3tOG11Iua6mK8y9Zz1BpUT02ZvGaPf9R6vI0Shk1yWbZ0NYLx0MH
+Zu8HIYECgYEA5awzjNcnDYQY9f6C/0TNj54Z8I7UFmGJX7XhPVVMceNieUiLvrsH
+Zmf4Q51PLM1iz0S2qGA/c7lngHDXwFe++MANIK7KNwL2LtPF/83mYgBUxBKJaNHD
+4B/6CCitjSwAfMNBnE70zg0F9chqy+9p+fTEwUFW6Y4y9U5jO4kw5HECgYEAxB8+
+YYMUGeIt9TnMKrC2YK/o8jo+5ZEOpEIPwleeAIUMujVVonu3TX2nKos2MgaZg/F0
+OpvDlcQZqb4Em73ctf3ZgBYEs9tt2qdB5qGlg4Hs2wyfgKUPQGLX2RseUQCYsOWT
+cPPKvYDTZ6yhW6gGBd5ufl5tnG93CsIpcNV1DakCgYEAwByZhi6V4Q1k36eDpcjE
+dWRW6ExghVQS17dIb8hAyGbeAPs4wVKqbvN6y/vytVQbWapta0wO51rng51gKuh6
+upHSqUrrpLZafHLyBPYSxljmjpe+zqnfwUKeH2L/QL3UroeZAwlcZlqoaJ27D1j0
++XrPdaOU8onagCyQfsVT21ECgYAafW3blezdIiO6/7eH/J5lqNz5+swMDe/AV/vw
+8AyzXUU+0X1jmPpFSTePE4aaczHBFJfyYp+kVvxwZO4Say6olkUOe+resEDCS90m
+3aaRgLcRTz8sDR9mPvOQq40Iu9/j5N5pX0R/HCtx0WtqCePmXwjloLOFcbjOhzM5
+vls1IQKBgEF8DEk8T4ycjwBXC3U7Duj9jPL815417BAHdGstLP1yNcI05ubN2T56
+ITbf625YS7OdtYfrf1/jBnUVXsJspsQqkOUB97M224CVWI+vJiv8jPX+KCnR7/Zh
+A/7OrtZ6FCzLyBeu/2p1NHAttqSUqu9t6wCeeBcelnAUcrjfLmlw
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qdtls/certs/fake-login.live.com.key b/tests/auto/network/ssl/qdtls/certs/fake-login.live.com.key
new file mode 100644
index 0000000000..692a7bd85d
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/fake-login.live.com.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDOtxdvMa0VHUQYG5q7Tsi1Jj4qKEJppyZEkmuRXOi0fDbd1SwE
+bwHrLGMvDO6OMrYBbq3WDNrtnIfF9CvzUOEch+gjr4hEVQqecU5fb45Wor7yNel3
+/C/gxfbzuXHrsj/gUjNghL2i10+c2NW+hUo/sWO6OusaBT6d6s7ee+YBcQIDAQAB
+AoGAb8cVhu0HuLkgjyCuJMbPRRUu3ED02Iin6sB6JhplQuNAD+grayJTmUVhRJnr
+jTziqhedLHe7Em1oBaSo92MutfMpXvWiccSlbNygI61VgmrJpVB+qIN5H9cQc9ql
+Zymc+nIPa1+i5rsrOzlpUytTh7AsbZ27QG4tQXR/kQejEiECQQD6BgTxBeT8D7x9
+DuukoBaSCkLwx7U7P1NXx15EI3lA1nO51t6UHfvk/jGPp8Sl4wv4alJ7AQxr5uQ/
+vC3kzA/1AkEA06gNu10se8pe3n8qL2RRt+FmVjHkQdD9Mm2Dx9oWCs2A4wOSOrlo
+6/nKYF1CaQNYn9HgsNbHVEUpnICVO18qDQJBALEw/uOJ1+TDikPfBSWgxx4s45Ad
+GNWqZXh6NNZ5hX9r/IwiOZAjR9fcRmeW8IjYRi2BvH6sGY+HDRAWXzgdXtkCQCma
+dOiJTf8fLjqp4E7kdzOfuI/kyqstOze4Uxjrgz2oW1dEEnA8laUcumzqp+0gXUE8
+7d+UuCWWWrGKjMrYz9kCQQDh5E5+b6Djn082Jo6gvyuXWC5eXju6IdmihlJ2SMzD
+s2y3IDjOUtTeQQRDymLneteMz0ha79KeUp6VnAvZCOVe
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qdtls/certs/fake-login.live.com.pem b/tests/auto/network/ssl/qdtls/certs/fake-login.live.com.pem
new file mode 100644
index 0000000000..429f95187c
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/fake-login.live.com.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDDjCCAnegAwIBAgIRALC3Ez7Qlvm1b66RyHS9OsAwDQYJKoZIhvcNAQEFBQAw
+XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu
+dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMObG9naW4ubGl2ZS5jb20w
+HhcNMTEwMzI1MTMyODUwWhcNMTEwNDI0MTMyODUwWjBeMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMRcwFQYDVQQDEw5sb2dpbi5saXZlLmNvbTCBnzANBgkqhkiG9w0BAQEF
+AAOBjQAwgYkCgYEAzrcXbzGtFR1EGBuau07ItSY+KihCaacmRJJrkVzotHw23dUs
+BG8B6yxjLwzujjK2AW6t1gza7ZyHxfQr81DhHIfoI6+IRFUKnnFOX2+OVqK+8jXp
+d/wv4MX287lx67I/4FIzYIS9otdPnNjVvoVKP7FjujrrGgU+nerO3nvmAXECAwEA
+AaOByzCByDAdBgNVHQ4EFgQUpSOEcmtkQITvBdM2IDfcXnJ0FCAwgZgGA1UdIwSB
+kDCBjYAUpSOEcmtkQITvBdM2IDfcXnJ0FCChYqRgMF4xCzAJBgNVBAYTAkFVMRMw
+EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQxFzAVBgNVBAMTDmxvZ2luLmxpdmUuY29tghEAsLcTPtCW+bVvrpHIdL06
+wDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAD+2HT4GSHHKCdbl9VkX
+zsl+D+drMm2b0ksxz9SgPihP7aW50EEIJDEEihNMTa27mhpeOXHc/sLqDi4ECUao
+/0Ns/5uoVuAIrAKCydmtPsonVFh9XWjyrfUzPOHAc9p2bmJ1i9a3kTsLB6jlrVDO
+VufGzsowHlHZ0TtKf5omojU5
+-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qdtls/certs/fluke.cert b/tests/auto/network/ssl/qdtls/certs/fluke.cert
new file mode 100644
index 0000000000..ace4e4f0eb
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/fluke.cert
@@ -0,0 +1,75 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 0 (0x0)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=NO, ST=Oslo, L=Nydalen, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+ Validity
+ Not Before: Dec 4 01:10:32 2007 GMT
+ Not After : Apr 21 01:10:32 2035 GMT
+ Subject: C=NO, ST=Oslo, O=Nokia Corporation and/or its subsidiary(-ies), OU=Development, CN=fluke.troll.no
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (1024 bit)
+ Modulus (1024 bit):
+ 00:a7:c8:a0:4a:c4:19:05:1b:66:ba:32:e2:d2:f1:
+ 1c:6f:17:82:e4:39:2e:01:51:90:db:04:34:32:11:
+ 21:c2:0d:6f:59:d8:53:90:54:3f:83:8f:a9:d3:b3:
+ d5:ee:1a:9b:80:ae:c3:25:c9:5e:a5:af:4b:60:05:
+ aa:a0:d1:91:01:1f:ca:04:83:e3:58:1c:99:32:45:
+ 84:70:72:58:03:98:4a:63:8b:41:f5:08:49:d2:91:
+ 02:60:6b:e4:64:fe:dd:a0:aa:74:08:e9:34:4c:91:
+ 5f:12:3d:37:4d:54:2c:ad:7f:5b:98:60:36:02:8c:
+ 3b:f6:45:f3:27:6a:9b:94:9d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 21:85:04:3D:23:01:66:E5:F7:9F:1A:84:24:8A:AF:0A:79:F4:E5:AC
+ X509v3 Authority Key Identifier:
+ DirName:/C=NO/ST=Oslo/L=Nydalen/O=Nokia Corporation and/or its subsidiary(-ies)/OU=Development/CN=fluke.troll.no/emailAddress=ahanssen@trolltech.com
+ serial:8E:A8:B4:E8:91:B7:54:2E
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 6d:57:5f:d1:05:43:f0:62:05:ec:2a:71:a5:dc:19:08:f2:c4:
+ a6:bd:bb:25:d9:ca:89:01:0e:e4:cf:1f:c1:8c:c8:24:18:35:
+ 53:59:7b:c0:43:b4:32:e6:98:b2:a6:ef:15:05:0b:48:5f:e1:
+ a0:0c:97:a9:a1:77:d8:35:18:30:bc:a9:8f:d3:b7:54:c7:f1:
+ a9:9e:5d:e6:19:bf:f6:3c:5b:2b:d8:e4:3e:62:18:88:8b:d3:
+ 24:e1:40:9b:0c:e6:29:16:62:ab:ea:05:24:70:36:aa:55:93:
+ ef:02:81:1b:23:10:a2:04:eb:56:95:75:fc:f8:94:b1:5d:42:
+ c5:3f:36:44:85:5d:3a:2e:90:46:8a:a2:b9:6f:87:ae:0c:15:
+ 40:19:31:90:fc:3b:25:bb:ae:f1:66:13:0d:85:90:d9:49:34:
+ 8f:f2:5d:f9:7a:db:4d:5d:27:f6:76:9d:35:8c:06:a6:4c:a3:
+ b1:b2:b6:6f:1d:d7:a3:00:fd:72:eb:9e:ea:44:a1:af:21:34:
+ 7d:c7:42:e2:49:91:19:8b:c0:ad:ba:82:80:a8:71:70:f4:35:
+ 31:91:63:84:20:95:e9:60:af:64:8b:cc:ff:3d:8a:76:74:3d:
+ c8:55:6d:e4:8e:c3:2b:1c:e8:42:18:ae:9f:e6:6b:9c:34:06:
+ ec:6a:f2:c3
+-----BEGIN CERTIFICATE-----
+MIIEEzCCAvugAwIBAgIBADANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMCTk8x
+DTALBgNVBAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xs
+dGVjaCBBU0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50
+cm9sbC5ubzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbTAe
+Fw0wNzEyMDQwMTEwMzJaFw0zNTA0MjEwMTEwMzJaMGMxCzAJBgNVBAYTAk5PMQ0w
+CwYDVQQIEwRPc2xvMRYwFAYDVQQKEw1Ucm9sbHRlY2ggQVNBMRQwEgYDVQQLEwtE
+ZXZlbG9wbWVudDEXMBUGA1UEAxMOZmx1a2UudHJvbGwubm8wgZ8wDQYJKoZIhvcN
+AQEBBQADgY0AMIGJAoGBAKfIoErEGQUbZroy4tLxHG8XguQ5LgFRkNsENDIRIcIN
+b1nYU5BUP4OPqdOz1e4am4CuwyXJXqWvS2AFqqDRkQEfygSD41gcmTJFhHByWAOY
+SmOLQfUISdKRAmBr5GT+3aCqdAjpNEyRXxI9N01ULK1/W5hgNgKMO/ZF8ydqm5Sd
+AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIYUEPSMBZuX3nxqEJIqv
+Cnn05awwgbsGA1UdIwSBszCBsKGBoqSBnzCBnDELMAkGA1UEBhMCTk8xDTALBgNV
+BAgTBE9zbG8xEDAOBgNVBAcTB055ZGFsZW4xFjAUBgNVBAoTDVRyb2xsdGVjaCBB
+U0ExFDASBgNVBAsTC0RldmVsb3BtZW50MRcwFQYDVQQDEw5mbHVrZS50cm9sbC5u
+bzElMCMGCSqGSIb3DQEJARYWYWhhbnNzZW5AdHJvbGx0ZWNoLmNvbYIJAI6otOiR
+t1QuMA0GCSqGSIb3DQEBBQUAA4IBAQBtV1/RBUPwYgXsKnGl3BkI8sSmvbsl2cqJ
+AQ7kzx/BjMgkGDVTWXvAQ7Qy5piypu8VBQtIX+GgDJepoXfYNRgwvKmP07dUx/Gp
+nl3mGb/2PFsr2OQ+YhiIi9Mk4UCbDOYpFmKr6gUkcDaqVZPvAoEbIxCiBOtWlXX8
++JSxXULFPzZEhV06LpBGiqK5b4euDBVAGTGQ/Dslu67xZhMNhZDZSTSP8l35ettN
+XSf2dp01jAamTKOxsrZvHdejAP1y657qRKGvITR9x0LiSZEZi8CtuoKAqHFw9DUx
+kWOEIJXpYK9ki8z/PYp2dD3IVW3kjsMrHOhCGK6f5mucNAbsavLD
+-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qdtls/certs/fluke.key b/tests/auto/network/ssl/qdtls/certs/fluke.key
new file mode 100644
index 0000000000..9d1664d609
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/fluke.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQCnyKBKxBkFG2a6MuLS8RxvF4LkOS4BUZDbBDQyESHCDW9Z2FOQ
+VD+Dj6nTs9XuGpuArsMlyV6lr0tgBaqg0ZEBH8oEg+NYHJkyRYRwclgDmEpji0H1
+CEnSkQJga+Rk/t2gqnQI6TRMkV8SPTdNVCytf1uYYDYCjDv2RfMnapuUnQIDAQAB
+AoGANFzLkanTeSGNFM0uttBipFT9F4a00dqHz6JnO7zXAT26I5r8sU1pqQBb6uLz
+/+Qz5Zwk8RUAQcsMRgJetuPQUb0JZjF6Duv24hNazqXBCu7AZzUenjafwmKC/8ri
+KpX3fTwqzfzi//FKGgbXQ80yykSSliDL3kn/drATxsLCgQECQQDXhEFWLJ0vVZ1s
+1Ekf+3NITE+DR16X+LQ4W6vyEHAjTbaNWtcTKdAWLA2l6N4WAAPYSi6awm+zMxx4
+VomVTsjdAkEAx0z+e7natLeFcrrq8pbU+wa6SAP1VfhQWKitxL1e7u/QO90NCpxE
+oQYKzMkmmpOOFjQwEMAy1dvFMbm4LHlewQJAC/ksDBaUcQHHqjktCtrUb8rVjAyW
+A8lscckeB2fEYyG5J6dJVaY4ClNOOs5yMDS2Afk1F6H/xKvtQ/5CzInA/QJATDub
+K+BPU8jO9q+gpuIi3VIZdupssVGmCgObVCHLakG4uO04y9IyPhV9lA9tALtoIf4c
+VIvv5fWGXBrZ48kZAQJBAJmVCdzQxd9LZI5vxijUCj5EI4e+x5DRqVUvyP8KCZrC
+AiNyoDP85T+hBZaSXK3aYGpVwelyj3bvo1GrTNwNWLw=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qdtls/certs/ss-srv-cert.pem b/tests/auto/network/ssl/qdtls/certs/ss-srv-cert.pem
new file mode 100644
index 0000000000..2c3d2e180d
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/ss-srv-cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC5TCCAk6gAwIBAgIJAP0E+KApnERsMA0GCSqGSIb3DQEBCwUAMIGJMQswCQYD
+VQQGEwJOTzENMAsGA1UECAwET3NsbzENMAsGA1UEBwwET3NsbzELMAkGA1UECgwC
+UXQxHzAdBgNVBAsMFlImRCAoQ29yZSBhbmQgTmV0d29yaykxEDAOBgNVBAMMB2Jv
+Yi5vcmcxHDAaBgkqhkiG9w0BCQEWDWJvYkBnbWFpbC5jb20wHhcNMTgwNDI2MDgw
+NDAxWhcNMjgwNDIzMDgwNDAxWjCBiTELMAkGA1UEBhMCTk8xDTALBgNVBAgMBE9z
+bG8xDTALBgNVBAcMBE9zbG8xCzAJBgNVBAoMAlF0MR8wHQYDVQQLDBZSJkQgKENv
+cmUgYW5kIE5ldHdvcmspMRAwDgYDVQQDDAdib2Iub3JnMRwwGgYJKoZIhvcNAQkB
+Fg1ib2JAZ21haWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWSh+1
+Xp5l3MgpzfTtiiuT4jMh8uQug/N7fyZlo+obMarT51dYWt1L5yFYyPw92FCtWgTi
+rWFUh6Z8O/wIRkLRd/meKAqQsqRMnEVt4WSE9fA41XecWw1FJl2Ehwnl2C3Nj3GF
+XonG+4Wg5EzH7JGEUUQIGQnuUTj06BkHLq0R8QIDAQABo1MwUTAdBgNVHQ4EFgQU
+TRydf45RdKVcjhzNUYgfNq4f/W8wHwYDVR0jBBgwFoAUTRydf45RdKVcjhzNUYgf
+Nq4f/W8wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAsn1aZTcZU
+4qD+ciziSYFM0Qk1GTCHtWf5nufB35AyuUqOK3h6QgRHovvNm+IMJIPMlnnwj5gF
+G8UZ6mCYBUQPBuofZz8+XEL+N0QtvzUXA2/jVKn2TkcSvFXV90juC9KfhGhM93kQ
+1R3qNPgxkuQqteffCbUyWnugv3/axNCjsQ==
+-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qdtls/certs/ss-srv-key.pem b/tests/auto/network/ssl/qdtls/certs/ss-srv-key.pem
new file mode 100644
index 0000000000..c2d912bf4d
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/certs/ss-srv-key.pem
@@ -0,0 +1,18 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIC1DBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIBoCUfXYbG50CAggA
+MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECHsb5ejBIDukBIICgFiMs6LbW0L4
+fxGDVNQWEbWf+1h4HJZsetWVqX5kh+9R3yfvK6vMVI5EQZ3mm8t5NDIKRFON6dN/
+uKGvZA+4vR6Vc5yeOOzL6sC8NsIU6eJOzkxXdyBahBHORm51dJCRtCdsoaWnx00I
+jEAIvdv/dWh+kx9iMF6cZeOvIXbdVPuadjeh62cjPU/zyZSKCFd59zqWRMvIMIIM
+kUOy2In5dVBb8/W9Zz0S8OG7KRJ+KdxxR5ev324L70XtRbb/tDVnGuMz+K83xbQC
+ySJgIEvaz9lmhFeWiJ9HPGqcYtMAUUk4XgF5mcQDete8uCndDnxCy3uCyNxWtIm3
+dXRYzWZh+nbsbjYQWT3Lo3z3zkchB8vNDBfVcp6m0nx7spaUFlptrXujYKU9VQTK
+2vAMhT9uUstLaHm+TEI1SuDBeugbvxy1DNI5lEQ3SG50L8r0m/OuQkV9zPVreHLX
+nJdx7POS69WW+yac2SJX9mMSXICksLvaSGxSnFf1hMyozIp3xM4jGsxV+ckGw2I/
+CNUW2QHMuJ2/AvZo8cJY5iwbRgCaewAKkUiPZbGMDLeRapm9nrRFyTkLGyjI+4wG
+wByzJ8ZZ2IlnZexXbcs0o8qoFmUxgA2R5Q3AvDYAg9/XGWtRcbIOhly4gRv4B/OF
+pWfqYrCK6ZbTNSNZNifMDJfjx5T9qSnnLbAZRjuVwOgvqWTcBZpzpn97YS7XnsrU
+5qMOiaP+VgpWeO2Fcf5zq9CJaBLO8sBUWWJW7mPgrOpxbBOio6x1GbRMT2niOiPN
+wSXWPfw5Kp/P43ORJEttudEGJYpIMAzZ88hmF2j8n3hGC9FHAw5RGaV+3vsonsZq
+iwE2rYxs3RI=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qdtls/qdtls.pro b/tests/auto/network/ssl/qdtls/qdtls.pro
new file mode 100644
index 0000000000..19e13a965c
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/qdtls.pro
@@ -0,0 +1,16 @@
+CONFIG += testcase
+
+SOURCES += tst_qdtls.cpp
+QT = core network-private testlib
+
+TARGET = tst_qdtls
+
+win32 {
+ CONFIG(debug, debug|release) {
+ DESTDIR = debug
+ } else {
+ DESTDIR = release
+ }
+}
+
+TESTDATA += certs
diff --git a/tests/auto/network/ssl/qdtls/tst_qdtls.cpp b/tests/auto/network/ssl/qdtls/tst_qdtls.cpp
new file mode 100644
index 0000000000..6a94eee389
--- /dev/null
+++ b/tests/auto/network/ssl/qdtls/tst_qdtls.cpp
@@ -0,0 +1,1324 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <QtNetwork/qsslpresharedkeyauthenticator.h>
+#include <QtNetwork/qsslconfiguration.h>
+#include <QtNetwork/qhostaddress.h>
+#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qsslcipher.h>
+#include <QtNetwork/qudpsocket.h>
+#include <QtNetwork/qsslerror.h>
+#include <QtNetwork/qsslkey.h>
+#include <QtNetwork/qdtls.h>
+#include <QtNetwork/qssl.h>
+
+#include <QtCore/qcryptographichash.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qobject.h>
+
+#include <algorithm>
+
+QT_BEGIN_NAMESPACE
+
+namespace
+{
+
+bool dtlsErrorIsCleared(const QDtls &dtls)
+{
+ return dtls.dtlsError() == QDtlsError::NoError && dtls.dtlsErrorString().isEmpty();
+}
+
+using DtlsPtr = QScopedPointer<QDtls>;
+
+bool dtlsErrorIsCleared(DtlsPtr &dtls)
+{
+ return dtlsErrorIsCleared(*dtls);
+}
+
+} // unnamed namespace
+
+#define QDTLS_VERIFY_NO_ERROR(obj) QVERIFY(dtlsErrorIsCleared(obj))
+
+#define QDTLS_VERIFY_HANDSHAKE_SUCCESS(obj) \
+ QVERIFY(obj->isConnectionEncrypted()); \
+ QCOMPARE(obj->handshakeState(), QDtls::HandshakeComplete); \
+ QDTLS_VERIFY_NO_ERROR(obj); \
+ QCOMPARE(obj->peerVerificationErrors().size(), 0)
+
+class tst_QDtls : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void init();
+
+private slots:
+ // Tests:
+ void construction_data();
+ void construction();
+ void configuration_data();
+ void configuration();
+ void invalidConfiguration();
+ void setPeer_data();
+ void setPeer();
+ void handshake_data();
+ void handshake();
+ void handshakeWithRetransmission();
+ void sessionCipher();
+ void cipherPreferences_data();
+ void cipherPreferences();
+ void protocolVersionMatching_data();
+ void protocolVersionMatching();
+ void verificationErrors_data();
+ void verificationErrors();
+ void presetExpectedErrors_data();
+ void presetExpectedErrors();
+ void verifyServerCertificate_data();
+ void verifyServerCertificate();
+ void verifyClientCertificate_data();
+ void verifyClientCertificate();
+ void blacklistedCerificate();
+ void readWriteEncrypted_data();
+ void readWriteEncrypted();
+ void datagramFragmentation();
+
+protected slots:
+ void handshakeReadyRead();
+ void encryptedReadyRead();
+ void pskRequested(QSslPreSharedKeyAuthenticator *auth);
+ void handleHandshakeTimeout();
+
+private:
+ void clientServerData();
+ void connectHandshakeReadingSlots();
+ void connectEncryptedReadingSlots();
+ bool verificationErrorDetected(QSslError::SslError code) const;
+
+ static QHostAddress toNonAny(const QHostAddress &addr);
+
+ QUdpSocket serverSocket;
+ QHostAddress serverAddress;
+ quint16 serverPort = 0;
+ QSslConfiguration defaultServerConfig;
+ QSslCertificate selfSignedCert;
+ QString hostName;
+ QSslKey serverKeySS;
+ bool serverDropDgram = false;
+ const QByteArray serverExpectedPlainText = "Hello W ... hmm, I mean DTLS server!";
+ QByteArray serverReceivedPlainText;
+
+ QUdpSocket clientSocket;
+ QHostAddress clientAddress;
+ quint16 clientPort = 0;
+ bool clientDropDgram = false;
+ const QByteArray clientExpectedPlainText = "Hello DTLS client.";
+ QByteArray clientReceivedPlainText;
+
+ DtlsPtr serverCrypto;
+ DtlsPtr clientCrypto;
+
+ QTestEventLoop testLoop;
+ const int handshakeTimeoutMS = 5000;
+ const int dataExchangeTimeoutMS = 1000;
+
+ const QByteArray presharedKey = "DEADBEEFDEADBEEF";
+ QString certDirPath;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QSsl::SslProtocol)
+Q_DECLARE_METATYPE(QSslSocket::SslMode)
+Q_DECLARE_METATYPE(QSslSocket::PeerVerifyMode)
+Q_DECLARE_METATYPE(QList<QSslCertificate>)
+Q_DECLARE_METATYPE(QSslKey)
+Q_DECLARE_METATYPE(QVector<QSslError>)
+
+QT_BEGIN_NAMESPACE
+
+void tst_QDtls::initTestCase()
+{
+ certDirPath = QFileInfo(QFINDTESTDATA("certs")).absolutePath();
+ QVERIFY(certDirPath.size() > 0);
+ certDirPath += QDir::separator() + QStringLiteral("certs") + QDir::separator();
+
+ QVERIFY(QSslSocket::supportsSsl());
+
+ QFile keyFile(certDirPath + QStringLiteral("ss-srv-key.pem"));
+ QVERIFY(keyFile.open(QIODevice::ReadOnly));
+ serverKeySS = QSslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "foobar");
+ QVERIFY(!serverKeySS.isNull());
+
+ QList<QSslCertificate> certificates = QSslCertificate::fromPath(certDirPath + QStringLiteral("ss-srv-cert.pem"));
+ QVERIFY(!certificates.isEmpty());
+ QVERIFY(!certificates.first().isNull());
+ selfSignedCert = certificates.first();
+
+ defaultServerConfig = QSslConfiguration::defaultDtlsConfiguration();
+ defaultServerConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
+ defaultServerConfig.setDtlsCookieVerificationEnabled(false);
+
+ hostName = QStringLiteral("bob.org");
+}
+
+void tst_QDtls::init()
+{
+ if (serverSocket.state() != QAbstractSocket::UnconnectedState) {
+ serverSocket.close();
+ // disconnect signals/slots:
+ serverSocket.disconnect();
+ }
+
+ QVERIFY(serverSocket.bind());
+ serverAddress = toNonAny(serverSocket.localAddress());
+ serverPort = serverSocket.localPort();
+
+ if (clientSocket.localPort()) {
+ clientSocket.close();
+ // disconnect signals/slots:
+ clientSocket.disconnect();
+ }
+
+ clientAddress = {};
+ clientPort = 0;
+
+ serverCrypto.reset(new QDtls(QSslSocket::SslServerMode));
+ serverDropDgram = false;
+ serverReceivedPlainText.clear();
+
+ clientCrypto.reset(new QDtls(QSslSocket::SslClientMode));
+ clientDropDgram = false;
+ clientReceivedPlainText.clear();
+
+ connect(clientCrypto.data(), &QDtls::handshakeTimeout,
+ this, &tst_QDtls::handleHandshakeTimeout);
+ connect(serverCrypto.data(), &QDtls::handshakeTimeout,
+ this, &tst_QDtls::handleHandshakeTimeout);
+}
+
+void tst_QDtls::construction_data()
+{
+ clientServerData();
+}
+
+void tst_QDtls::construction()
+{
+ QFETCH(const QSslSocket::SslMode, mode);
+
+ QDtls dtls(mode);
+ QCOMPARE(dtls.peerAddress(), QHostAddress());
+ QCOMPARE(dtls.peerPort(), quint16());
+ QCOMPARE(dtls.peerVerificationName(), QString());
+ QCOMPARE(dtls.sslMode(), mode);
+
+ QCOMPARE(dtls.mtuHint(), quint16());
+
+ const auto params = dtls.cookieGeneratorParameters();
+ QVERIFY(params.secret.size() > 0);
+#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ QCOMPARE(params.hash, QCryptographicHash::Sha1);
+#else
+ QCOMPARE(params.hash, QCryptographicHash::Sha256);
+#endif
+
+ QCOMPARE(dtls.dtlsConfiguration(), QSslConfiguration::defaultDtlsConfiguration());
+
+ QCOMPARE(dtls.handshakeState(), QDtls::HandshakeNotStarted);
+ QCOMPARE(dtls.isConnectionEncrypted(), false);
+ QCOMPARE(dtls.sessionCipher(), QSslCipher());
+ QCOMPARE(dtls.sessionProtocol(), QSsl::UnknownProtocol);
+
+ QCOMPARE(dtls.dtlsError(), QDtlsError::NoError);
+ QCOMPARE(dtls.dtlsErrorString(), QString());
+ QCOMPARE(dtls.peerVerificationErrors().size(), 0);
+}
+
+void tst_QDtls::configuration_data()
+{
+ clientServerData();
+}
+
+void tst_QDtls::configuration()
+{
+ // There is a proper auto-test for QSslConfiguration in our TLS test suite,
+ // here we only test several DTLS-related details.
+ auto config = QSslConfiguration::defaultDtlsConfiguration();
+ QCOMPARE(config.protocol(), QSsl::DtlsV1_2OrLater);
+
+ const QList<QSslCipher> ciphers = config.ciphers();
+ QVERIFY(ciphers.size() > 0);
+ for (const auto &cipher : ciphers)
+ QVERIFY(cipher.usedBits() >= 128);
+
+ QCOMPARE(config.dtlsCookieVerificationEnabled(), true);
+
+ QFETCH(const QSslSocket::SslMode, mode);
+ QDtls dtls(mode);
+ QCOMPARE(dtls.dtlsConfiguration(), config);
+ config.setProtocol(QSsl::DtlsV1_0OrLater);
+ config.setDtlsCookieVerificationEnabled(false);
+ QCOMPARE(config.dtlsCookieVerificationEnabled(), false);
+
+ QVERIFY(dtls.setDtlsConfiguration(config));
+ QDTLS_VERIFY_NO_ERROR(dtls);
+ QCOMPARE(dtls.dtlsConfiguration(), config);
+
+ if (mode == QSslSocket::SslClientMode) {
+ // Testing a DTLS server would be more complicated, we'd need a DTLS
+ // client sending ClientHello(s), running an event loop etc. - way too
+ // much dancing for a simple setter/getter test.
+ QVERIFY(dtls.setPeer(serverAddress, serverPort));
+ QDTLS_VERIFY_NO_ERROR(dtls);
+
+ QUdpSocket clientSocket;
+ QVERIFY(dtls.doHandshake(&clientSocket));
+ QDTLS_VERIFY_NO_ERROR(dtls);
+ QCOMPARE(dtls.handshakeState(), QDtls::HandshakeInProgress);
+ // As soon as handshake started, it's not allowed to change configuration:
+ QVERIFY(!dtls.setDtlsConfiguration(QSslConfiguration::defaultDtlsConfiguration()));
+ QCOMPARE(dtls.dtlsError(), QDtlsError::InvalidOperation);
+ QCOMPARE(dtls.dtlsConfiguration(), config);
+ }
+}
+
+void tst_QDtls::invalidConfiguration()
+{
+ QUdpSocket socket;
+ QDtls crypto(QSslSocket::SslClientMode);
+ QVERIFY(crypto.setPeer(serverAddress, serverPort));
+ // Note: not defaultDtlsConfiguration(), so the protocol is TLS (without D):
+ QVERIFY(crypto.setDtlsConfiguration(QSslConfiguration::defaultConfiguration()));
+ QDTLS_VERIFY_NO_ERROR(crypto);
+ QCOMPARE(crypto.dtlsConfiguration(), QSslConfiguration::defaultConfiguration());
+ // Try to start the handshake:
+ QCOMPARE(crypto.doHandshake(&socket), false);
+ QCOMPARE(crypto.dtlsError(), QDtlsError::TlsInitializationError);
+}
+
+void tst_QDtls::setPeer_data()
+{
+ clientServerData();
+}
+
+void tst_QDtls::setPeer()
+{
+ static const QHostAddress invalid[] = {QHostAddress(),
+ QHostAddress(QHostAddress::Broadcast),
+ QHostAddress(QStringLiteral("224.0.0.0"))};
+ static const QString peerName = QStringLiteral("does not matter actually");
+
+ QFETCH(const QSslSocket::SslMode, mode);
+ QDtls dtls(mode);
+
+ for (const auto &addr : invalid) {
+ QCOMPARE(dtls.setPeer(addr, 100, peerName), false);
+ QCOMPARE(dtls.dtlsError(), QDtlsError::InvalidInputParameters);
+ QCOMPARE(dtls.peerAddress(), QHostAddress());
+ QCOMPARE(dtls.peerPort(), quint16());
+ QCOMPARE(dtls.peerVerificationName(), QString());
+ }
+
+ QVERIFY(dtls.setPeer(serverAddress, serverPort, peerName));
+ QDTLS_VERIFY_NO_ERROR(dtls);
+ QCOMPARE(dtls.peerAddress(), serverAddress);
+ QCOMPARE(dtls.peerPort(), serverPort);
+ QCOMPARE(dtls.peerVerificationName(), peerName);
+
+ if (mode == QSslSocket::SslClientMode) {
+ // We test for client mode only, for server mode we'd have to run event
+ // loop etc. too much work for a simple setter/getter test.
+ QUdpSocket clientSocket;
+ QVERIFY(dtls.doHandshake(&clientSocket));
+ QDTLS_VERIFY_NO_ERROR(dtls);
+ QCOMPARE(dtls.handshakeState(), QDtls::HandshakeInProgress);
+ QCOMPARE(dtls.setPeer(serverAddress, serverPort), false);
+ QCOMPARE(dtls.dtlsError(), QDtlsError::InvalidOperation);
+ }
+}
+
+void tst_QDtls::handshake_data()
+{
+ QTest::addColumn<bool>("withCertificate");
+
+ QTest::addRow("no-cert") << false;
+ QTest::addRow("with-cert") << true;
+}
+
+void tst_QDtls::handshake()
+{
+ connectHandshakeReadingSlots();
+
+ QFETCH(const bool, withCertificate);
+
+ auto serverConfig = defaultServerConfig;
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+
+ if (!withCertificate) {
+ connect(serverCrypto.data(), &QDtls::pskRequired, this, &tst_QDtls::pskRequested);
+ connect(clientCrypto.data(), &QDtls::pskRequired, this, &tst_QDtls::pskRequested);
+ clientConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
+ QVERIFY(clientConfig.peerCertificate().isNull());
+ } else {
+ serverConfig.setPrivateKey(serverKeySS);
+ serverConfig.setLocalCertificate(selfSignedCert);
+ clientConfig.setCaCertificates({selfSignedCert});
+ }
+
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+
+ // Some early checks before we run event loop.
+ // Remote was not set yet:
+ QVERIFY(!clientCrypto->doHandshake(&clientSocket));
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidOperation);
+ QVERIFY(!serverCrypto->doHandshake(&serverSocket, QByteArray("ClientHello")));
+ QCOMPARE(serverCrypto->dtlsError(), QDtlsError::InvalidOperation);
+
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort, hostName));
+
+ // Invalid socket:
+ QVERIFY(!clientCrypto->doHandshake(nullptr));
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidInputParameters);
+
+ // Now we are ready for handshake:
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeInProgress);
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+
+ QVERIFY(!testLoop.timeout());
+
+ QVERIFY(serverCrypto->isConnectionEncrypted());
+ QDTLS_VERIFY_NO_ERROR(serverCrypto);
+ QCOMPARE(serverCrypto->handshakeState(), QDtls::HandshakeComplete);
+ QCOMPARE(serverCrypto->peerVerificationErrors().size(), 0);
+
+ QVERIFY(clientCrypto->isConnectionEncrypted());
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeComplete);
+ QCOMPARE(clientCrypto->peerVerificationErrors().size(), 0);
+
+ if (withCertificate) {
+ const auto serverCert = clientCrypto->dtlsConfiguration().peerCertificate();
+ QVERIFY(!serverCert.isNull());
+ QCOMPARE(serverCert, selfSignedCert);
+ }
+
+ // Already in 'HandshakeComplete' state/encrypted.
+ QVERIFY(!clientCrypto->doHandshake(&clientSocket));
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidOperation);
+ QVERIFY(!serverCrypto->doHandshake(&serverSocket, {"ServerHello"}));
+ QCOMPARE(serverCrypto->dtlsError(), QDtlsError::InvalidOperation);
+ // Cannot change a remote without calling shutdown first.
+ QVERIFY(!clientCrypto->setPeer(serverAddress, serverPort));
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidOperation);
+ QVERIFY(!serverCrypto->setPeer(clientAddress, clientPort));
+ QCOMPARE(serverCrypto->dtlsError(), QDtlsError::InvalidOperation);
+}
+
+void tst_QDtls::handshakeWithRetransmission()
+{
+ connectHandshakeReadingSlots();
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setPrivateKey(serverKeySS);
+ serverConfig.setLocalCertificate(selfSignedCert);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+ clientConfig.setCaCertificates({selfSignedCert});
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort, hostName));
+
+ // Now we are ready for handshake:
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeInProgress);
+
+ serverDropDgram = true;
+ clientDropDgram = true;
+ // Every failed re-transmission doubles the next timeout. We don't want to
+ // slow down the test just to check the re-transmission ability, so we'll
+ // drop only the first 'ClientHello' and 'ServerHello' datagrams. The
+ // arithmetic is approximately this: the first ClientHello to be dropped -
+ // client will re-transmit in 1s., the first part of 'ServerHello' to be
+ // dropped, the client then will re-transmit after another 2 s. Thus it's ~3.
+ // We err on safe side and double our (already quite generous) 5s.
+ testLoop.enterLoopMSecs(handshakeTimeoutMS * 2);
+
+ QVERIFY(!testLoop.timeout());
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+}
+
+void tst_QDtls::sessionCipher()
+{
+ connectHandshakeReadingSlots();
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setPrivateKey(serverKeySS);
+ serverConfig.setLocalCertificate(selfSignedCert);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+ clientConfig.setCaCertificates({selfSignedCert});
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort, hostName));
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+
+ QVERIFY(!testLoop.timeout());
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+
+ const auto defaultDtlsConfig = QSslConfiguration::defaultDtlsConfiguration();
+
+ const auto clCipher = clientCrypto->sessionCipher();
+ QVERIFY(!clCipher.isNull());
+ QVERIFY(defaultDtlsConfig.ciphers().contains(clCipher));
+
+ const auto srvCipher = serverCrypto->sessionCipher();
+ QVERIFY(!srvCipher.isNull());
+ QVERIFY(defaultDtlsConfig.ciphers().contains(srvCipher));
+
+ QCOMPARE(clCipher, srvCipher);
+}
+
+void tst_QDtls::cipherPreferences_data()
+{
+ QTest::addColumn<bool>("preferClient");
+
+ QTest::addRow("prefer-server") << true;
+ QTest::addRow("prefer-client") << false;
+}
+
+void tst_QDtls::cipherPreferences()
+{
+ // This test is based on the similar case in tst_QSslSocket. We test it for QDtls
+ // because it's possible to set ciphers and corresponding ('server preferred')
+ // options via QSslConfiguration.
+ const QSslCipher aes128(QStringLiteral("AES128-SHA"));
+ const QSslCipher aes256(QStringLiteral("AES256-SHA"));
+
+ auto serverConfig = defaultServerConfig;
+ const QList<QSslCipher> ciphers = serverConfig.ciphers();
+ if (!ciphers.contains(aes128) || !ciphers.contains(aes256))
+ QSKIP("The ciphers needed by this test were not found in the default DTLS configuration");
+
+ serverConfig.setCiphers({aes128, aes256});
+ serverConfig.setLocalCertificate(selfSignedCert);
+ serverConfig.setPrivateKey(serverKeySS);
+
+ QFETCH(const bool, preferClient);
+ if (preferClient)
+ serverConfig.setSslOption(QSsl::SslOptionDisableServerCipherPreference, true);
+
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+ QDTLS_VERIFY_NO_ERROR(serverCrypto);
+
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+ clientConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
+ clientConfig.setCiphers({aes256, aes128});
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort));
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+
+ connectHandshakeReadingSlots();
+
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+ QVERIFY(!testLoop.timeout());
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+
+ if (preferClient) {
+ QCOMPARE(clientCrypto->sessionCipher(), aes256);
+ QCOMPARE(serverCrypto->sessionCipher(), aes256);
+ } else {
+ QCOMPARE(clientCrypto->sessionCipher(), aes128);
+ QCOMPARE(serverCrypto->sessionCipher(), aes128);
+ }
+}
+
+void tst_QDtls::protocolVersionMatching_data()
+{
+ QTest::addColumn<QSsl::SslProtocol>("serverProtocol");
+ QTest::addColumn<QSsl::SslProtocol>("clientProtocol");
+ QTest::addColumn<bool>("works");
+
+ QTest::addRow("DtlsV1_0 <-> DtlsV1_0") << QSsl::DtlsV1_0 << QSsl::DtlsV1_0 << true;
+ QTest::addRow("DtlsV1_0OrLater <-> DtlsV1_0") << QSsl::DtlsV1_0OrLater << QSsl::DtlsV1_0 << true;
+ QTest::addRow("DtlsV1_0 <-> DtlsV1_0OrLater") << QSsl::DtlsV1_0 << QSsl::DtlsV1_0OrLater << true;
+ QTest::addRow("DtlsV1_0OrLater <-> DtlsV1_0OrLater") << QSsl::DtlsV1_0OrLater << QSsl::DtlsV1_0OrLater << true;
+
+ QTest::addRow("DtlsV1_2 <-> DtlsV1_2") << QSsl::DtlsV1_2 << QSsl::DtlsV1_2 << true;
+ QTest::addRow("DtlsV1_2OrLater <-> DtlsV1_2") << QSsl::DtlsV1_2OrLater << QSsl::DtlsV1_2 << true;
+ QTest::addRow("DtlsV1_2 <-> DtlsV1_2OrLater") << QSsl::DtlsV1_2 << QSsl::DtlsV1_2OrLater << true;
+ QTest::addRow("DtlsV1_2OrLater <-> DtlsV1_2OrLater") << QSsl::DtlsV1_2OrLater << QSsl::DtlsV1_2OrLater << true;
+
+ QTest::addRow("DtlsV1_0 <-> DtlsV1_2") << QSsl::DtlsV1_0 << QSsl::DtlsV1_2 << false;
+ QTest::addRow("DtlsV1_0 <-> DtlsV1_2OrLater") << QSsl::DtlsV1_0 << QSsl::DtlsV1_2OrLater << false;
+ QTest::addRow("DtlsV1_2 <-> DtlsV1_0") << QSsl::DtlsV1_2 << QSsl::DtlsV1_0 << false;
+ QTest::addRow("DtlsV1_2OrLater <-> DtlsV1_0") << QSsl::DtlsV1_2OrLater << QSsl::DtlsV1_0 << false;
+}
+
+void tst_QDtls::protocolVersionMatching()
+{
+ QFETCH(const QSsl::SslProtocol, serverProtocol);
+ QFETCH(const QSsl::SslProtocol, clientProtocol);
+ QFETCH(const bool, works);
+
+ connectHandshakeReadingSlots();
+
+ connect(serverCrypto.data(), &QDtls::pskRequired, this, &tst_QDtls::pskRequested);
+ connect(clientCrypto.data(), &QDtls::pskRequired, this, &tst_QDtls::pskRequested);
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setProtocol(serverProtocol);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+ clientConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
+ clientConfig.setProtocol(clientProtocol);
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort));
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+
+ if (works) {
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+ } else {
+ QCOMPARE(serverCrypto->isConnectionEncrypted(), false);
+ QVERIFY(serverCrypto->handshakeState() != QDtls::HandshakeComplete);
+ QCOMPARE(clientCrypto->isConnectionEncrypted(), false);
+ QVERIFY(clientCrypto->handshakeState() != QDtls::HandshakeComplete);
+ }
+}
+
+void tst_QDtls::verificationErrors_data()
+{
+ QTest::addColumn<bool>("abortHandshake");
+
+ QTest::addRow("abort-handshake") << true;
+ QTest::addRow("ignore-errors") << false;
+}
+
+void tst_QDtls::verificationErrors()
+{
+ connectHandshakeReadingSlots();
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setPrivateKey(serverKeySS);
+ serverConfig.setLocalCertificate(selfSignedCert);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+ // And our client already has the default DTLS configuration.
+
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort));
+ // Now we are ready for handshake:
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+
+ QVERIFY(!testLoop.timeout());
+ QDTLS_VERIFY_NO_ERROR(serverCrypto);
+
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::PeerVerificationError);
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::PeerVerificationFailed);
+ QVERIFY(!clientCrypto->isConnectionEncrypted());
+
+ QVERIFY(verificationErrorDetected(QSslError::HostNameMismatch));
+ QVERIFY(verificationErrorDetected(QSslError::SelfSignedCertificate));
+
+ const auto serverCert = clientCrypto->dtlsConfiguration().peerCertificate();
+ QVERIFY(!serverCert.isNull());
+ QCOMPARE(selfSignedCert, serverCert);
+
+ QFETCH(const bool, abortHandshake);
+
+ if (abortHandshake) {
+ QVERIFY(!clientCrypto->abortHandshake(nullptr));
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidInputParameters);
+ QVERIFY(clientCrypto->abortHandshake(&clientSocket));
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ QVERIFY(!clientCrypto->isConnectionEncrypted());
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeNotStarted);
+ QCOMPARE(clientCrypto->sessionCipher(), QSslCipher());
+ QCOMPARE(clientCrypto->sessionProtocol(), QSsl::UnknownProtocol);
+ const auto config = clientCrypto->dtlsConfiguration();
+ QVERIFY(config.peerCertificate().isNull());
+ QCOMPARE(config.peerCertificateChain().size(), 0);
+ QCOMPARE(clientCrypto->peerVerificationErrors().size(), 0);
+ } else {
+ clientCrypto->ignoreVerificationErrors(clientCrypto->peerVerificationErrors());
+ QVERIFY(!clientCrypto->resumeHandshake(nullptr));
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidInputParameters);
+ QVERIFY(clientCrypto->resumeHandshake(&clientSocket));
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+ QVERIFY(clientCrypto->isConnectionEncrypted());
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeComplete);
+ QCOMPARE(clientCrypto->peerVerificationErrors().size(), 0);
+ }
+}
+
+void tst_QDtls::presetExpectedErrors_data()
+{
+ QTest::addColumn<QVector<QSslError>>("expectedTlsErrors");
+ QTest::addColumn<bool>("works");
+
+ QVector<QSslError> expectedErrors{{QSslError::HostNameMismatch, selfSignedCert}};
+ QTest::addRow("unexpected-self-signed") << expectedErrors << false;
+ expectedErrors.push_back({QSslError::SelfSignedCertificate, selfSignedCert});
+ QTest::addRow("all-errors-ignored") << expectedErrors << true;
+}
+
+void tst_QDtls::presetExpectedErrors()
+{
+ QFETCH(const QVector<QSslError>, expectedTlsErrors);
+ QFETCH(const bool, works);
+
+ connectHandshakeReadingSlots();
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setPrivateKey(serverKeySS);
+ serverConfig.setLocalCertificate(selfSignedCert);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+
+ clientCrypto->ignoreVerificationErrors(expectedTlsErrors);
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort));
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+
+ QVERIFY(!testLoop.timeout());
+
+ if (works) {
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeComplete);
+ QVERIFY(clientCrypto->isConnectionEncrypted());
+ } else {
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::PeerVerificationError);
+ QVERIFY(!clientCrypto->isConnectionEncrypted());
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::PeerVerificationFailed);
+ }
+}
+
+void tst_QDtls::verifyServerCertificate_data()
+{
+ QTest::addColumn<QSslSocket::PeerVerifyMode>("verifyMode");
+ QTest::addColumn<QList<QSslCertificate>>("serverCerts");
+ QTest::addColumn<QSslKey>("serverKey");
+ QTest::addColumn<QString>("peerName");
+ QTest::addColumn<bool>("encrypted");
+
+ {
+ // A special case - null key (but with certificate):
+ const auto chain = QSslCertificate::fromPath(certDirPath + QStringLiteral("bogus-server.crt"));
+ QCOMPARE(chain.size(), 1);
+
+ QSslKey nullKey;
+ // Only one row - server must fail to start handshake immediately.
+ QTest::newRow("valid-server-cert-no-key : VerifyPeer") << QSslSocket::VerifyPeer << chain << nullKey << QString() << false;
+ }
+ {
+ // Valid certificate:
+ auto chain = QSslCertificate::fromPath(certDirPath + QStringLiteral("bogus-server.crt"));
+ QCOMPARE(chain.size(), 1);
+
+ const auto caCert = QSslCertificate::fromPath(certDirPath + QStringLiteral("bogus-ca.crt"));
+ QCOMPARE(caCert.size(), 1);
+ chain += caCert;
+
+ QFile keyFile(certDirPath + QStringLiteral("bogus-server.key"));
+ QVERIFY(keyFile.open(QIODevice::ReadOnly));
+ const QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ QVERIFY(!key.isNull());
+
+ auto cert = chain.first();
+ const QString name(cert.subjectInfo(QSslCertificate::CommonName).first());
+ QTest::newRow("valid-server-cert : AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << chain << key << name << true;
+ QTest::newRow("valid-server-cert : QueryPeer") << QSslSocket::QueryPeer << chain << key << name << true;
+ QTest::newRow("valid-server-cert : VerifyNone") << QSslSocket::VerifyNone << chain << key << name << true;
+ QTest::newRow("valid-server-cert : VerifyPeer (add CA)") << QSslSocket::VerifyPeer << chain << key << name << true;
+ QTest::newRow("valid-server-cert : VerifyPeer (no CA)") << QSslSocket::VerifyPeer << chain << key << name << false;
+ QTest::newRow("valid-server-cert : VerifyPeer (name mismatch)") << QSslSocket::VerifyPeer << chain << key << QString() << false;
+ }
+}
+
+void tst_QDtls::verifyServerCertificate()
+{
+ QFETCH(const QSslSocket::PeerVerifyMode, verifyMode);
+ QFETCH(const QList<QSslCertificate>, serverCerts);
+ QFETCH(const QSslKey, serverKey);
+ QFETCH(const QString, peerName);
+ QFETCH(const bool, encrypted);
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setLocalCertificateChain(serverCerts);
+ serverConfig.setPrivateKey(serverKey);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+
+ if (serverCerts.size() == 2 && encrypted) {
+ auto caCerts = clientConfig.caCertificates();
+ caCerts.append(serverCerts.at(1));
+ clientConfig.setCaCertificates(caCerts);
+ }
+
+ clientConfig.setPeerVerifyMode(verifyMode);
+
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort, peerName));
+
+ connectHandshakeReadingSlots();
+
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+ QVERIFY(!testLoop.timeout());
+
+ if (serverKey.isNull() && !serverCerts.isEmpty()) {
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeInProgress);
+ QCOMPARE(serverCrypto->dtlsError(), QDtlsError::TlsInitializationError);
+ QCOMPARE(serverCrypto->handshakeState(), QDtls::HandshakeNotStarted);
+ return;
+ }
+
+ if (encrypted) {
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+ } else {
+ QVERIFY(!clientCrypto->isConnectionEncrypted());
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::PeerVerificationFailed);
+ QVERIFY(clientCrypto->peerVerificationErrors().size());
+ QVERIFY(clientCrypto->writeDatagramEncrypted(&clientSocket, "something") < 0);
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidOperation);
+ }
+}
+
+void tst_QDtls::verifyClientCertificate_data()
+{
+#if !QT_CONFIG(opensslv11)
+ QSKIP("This test is not supposed to work with OpenSSL version below 1.1");
+#endif
+
+ QTest::addColumn<QSslSocket::PeerVerifyMode>("verifyMode");
+ QTest::addColumn<QList<QSslCertificate>>("clientCerts");
+ QTest::addColumn<QSslKey>("clientKey");
+ QTest::addColumn<bool>("encrypted");
+ {
+ // No certficates, no key:
+ QList<QSslCertificate> chain;
+ QSslKey key;
+ QTest::newRow("no-cert : AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << chain << key << true;
+ QTest::newRow("no-cert : QueryPeer") << QSslSocket::QueryPeer << chain << key << true;
+ QTest::newRow("no-cert : VerifyNone") << QSslSocket::VerifyNone << chain << key << true;
+ QTest::newRow("no-cert : VerifyPeer") << QSslSocket::VerifyPeer << chain << key << false;
+ }
+ {
+ const auto chain = QSslCertificate::fromPath(certDirPath + QStringLiteral("fluke.cert"));
+ QCOMPARE(chain.size(), 1);
+
+ QFile keyFile(certDirPath + QStringLiteral("fluke.key"));
+ QVERIFY(keyFile.open(QIODevice::ReadOnly));
+ const QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ QVERIFY(!key.isNull());
+
+ QTest::newRow("self-signed-cert : AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << chain << key << true;
+ QTest::newRow("self-signed-cert : QueryPeer") << QSslSocket::QueryPeer << chain << key << true;
+ QTest::newRow("self-signed-cert : VerifyNone") << QSslSocket::VerifyNone << chain << key << true;
+ QTest::newRow("self-signed-cert : VerifyPeer") << QSslSocket::VerifyPeer << chain << key << false;
+ }
+ {
+ // Valid certificate, but wrong usage (server certificate):
+ const auto chain = QSslCertificate::fromPath(certDirPath + QStringLiteral("bogus-server.crt"));
+ QCOMPARE(chain.size(), 1);
+
+ QFile keyFile(certDirPath + QStringLiteral("bogus-server.key"));
+ QVERIFY(keyFile.open(QIODevice::ReadOnly));
+ const QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ QVERIFY(!key.isNull());
+
+ QTest::newRow("valid-server-cert : AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << chain << key << true;
+ QTest::newRow("valid-server-cert : QueryPeer") << QSslSocket::QueryPeer << chain << key << true;
+ QTest::newRow("valid-server-cert : VerifyNone") << QSslSocket::VerifyNone << chain << key << true;
+ QTest::newRow("valid-server-cert : VerifyPeer") << QSslSocket::VerifyPeer << chain << key << false;
+ }
+ {
+ // Valid certificate, correct usage (client certificate):
+ auto chain = QSslCertificate::fromPath(certDirPath + QStringLiteral("bogus-client.crt"));
+ QCOMPARE(chain.size(), 1);
+
+ QFile keyFile(certDirPath + QStringLiteral("bogus-client.key"));
+ QVERIFY(keyFile.open(QIODevice::ReadOnly));
+ const QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ QVERIFY(!key.isNull());
+
+ QTest::newRow("valid-client-cert : AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << chain << key << true;
+ QTest::newRow("valid-client-cert : QueryPeer") << QSslSocket::QueryPeer << chain << key << true;
+ QTest::newRow("valid-client-cert : VerifyNone") << QSslSocket::VerifyNone << chain << key << true;
+ QTest::newRow("valid-client-cert : VerifyPeer") << QSslSocket::VerifyPeer << chain << key << true;
+
+ // Valid certificate, correct usage (client certificate), with chain:
+ chain += QSslCertificate::fromPath(certDirPath + QStringLiteral("bogus-ca.crt"));
+ QCOMPARE(chain.size(), 2);
+
+ QTest::newRow("valid-client-chain : AutoVerifyPeer") << QSslSocket::AutoVerifyPeer << chain << key << true;
+ QTest::newRow("valid-client-chain : QueryPeer") << QSslSocket::QueryPeer << chain << key << true;
+ QTest::newRow("valid-client-chain : VerifyNone") << QSslSocket::VerifyNone << chain << key << true;
+ QTest::newRow("valid-client-chain : VerifyPeer") << QSslSocket::VerifyPeer << chain << key << true;
+ }
+}
+
+void tst_QDtls::verifyClientCertificate()
+{
+ connectHandshakeReadingSlots();
+
+ QFETCH(const QSslSocket::PeerVerifyMode, verifyMode);
+ QFETCH(const QList<QSslCertificate>, clientCerts);
+ QFETCH(const QSslKey, clientKey);
+ QFETCH(const bool, encrypted);
+
+ QSslConfiguration serverConfig = defaultServerConfig;
+ serverConfig.setLocalCertificate(selfSignedCert);
+ serverConfig.setPrivateKey(serverKeySS);
+ serverConfig.setPeerVerifyMode(verifyMode);
+
+ if (verifyMode == QSslSocket::VerifyPeer && clientCerts.size()) {
+ // Not always needed even if these conditions met, but does not hurt
+ // either.
+ const auto certs = QSslCertificate::fromPath(certDirPath + QStringLiteral("bogus-ca.crt"));
+ QCOMPARE(certs.size(), 1);
+ serverConfig.setCaCertificates(serverConfig.caCertificates() + certs);
+ }
+
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+ serverConfig = serverCrypto->dtlsConfiguration();
+ QVERIFY(serverConfig.peerCertificate().isNull());
+ QCOMPARE(serverConfig.peerCertificateChain().size(), 0);
+
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+ clientConfig.setLocalCertificateChain(clientCerts);
+ clientConfig.setPrivateKey(clientKey);
+ clientConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort));
+
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+
+ serverConfig = serverCrypto->dtlsConfiguration();
+
+ if (verifyMode == QSslSocket::VerifyNone || clientCerts.isEmpty()) {
+ QVERIFY(serverConfig.peerCertificate().isNull());
+ QCOMPARE(serverConfig.peerCertificateChain().size(), 0);
+ } else {
+ QCOMPARE(serverConfig.peerCertificate(), clientCerts.first());
+ QCOMPARE(serverConfig.peerCertificateChain(), clientCerts);
+ }
+
+ if (encrypted) {
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+ } else {
+ QVERIFY(!serverCrypto->isConnectionEncrypted());
+ QCOMPARE(serverCrypto->handshakeState(), QDtls::PeerVerificationFailed);
+ QVERIFY(serverCrypto->dtlsErrorString().size() > 0);
+ QVERIFY(serverCrypto->peerVerificationErrors().size() > 0);
+
+ QVERIFY(!clientCrypto->isConnectionEncrypted());
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeInProgress);
+ }
+}
+
+void tst_QDtls::blacklistedCerificate()
+{
+ const auto serverChain = QSslCertificate::fromPath(certDirPath + QStringLiteral("fake-login.live.com.pem"));
+ QCOMPARE(serverChain.size(), 1);
+
+ QFile keyFile(certDirPath + QStringLiteral("fake-login.live.com.key"));
+ QVERIFY(keyFile.open(QIODevice::ReadOnly));
+ const QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
+ QVERIFY(!key.isNull());
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setLocalCertificateChain(serverChain);
+ serverConfig.setPrivateKey(key);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+
+ connectHandshakeReadingSlots();
+ const QString name(serverChain.first().subjectInfo(QSslCertificate::CommonName).first());
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort, name));
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+ QVERIFY(!testLoop.timeout());
+ QCOMPARE(clientCrypto->handshakeState(), QDtls::PeerVerificationFailed);
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::PeerVerificationError);
+ QVERIFY(!clientCrypto->isConnectionEncrypted());
+ QVERIFY(verificationErrorDetected(QSslError::CertificateBlacklisted));
+}
+
+void tst_QDtls::readWriteEncrypted_data()
+{
+ QTest::addColumn<bool>("serverSideShutdown");
+
+ QTest::addRow("client-shutdown") << false;
+ QTest::addRow("server-shutdown") << true;
+}
+
+void tst_QDtls::readWriteEncrypted()
+{
+ connectHandshakeReadingSlots();
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setLocalCertificate(selfSignedCert);
+ serverConfig.setPrivateKey(serverKeySS);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+ clientConfig.setCaCertificates({selfSignedCert});
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort, hostName));
+
+ // 0. Verify we cannot write any encrypted message without handshake done
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ QVERIFY(clientCrypto->writeDatagramEncrypted(&clientSocket, serverExpectedPlainText) <= 0);
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidOperation);
+ QVERIFY(!clientCrypto->shutdown(&clientSocket));
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidOperation);
+ QDTLS_VERIFY_NO_ERROR(serverCrypto);
+ QVERIFY(serverCrypto->writeDatagramEncrypted(&serverSocket, clientExpectedPlainText) <= 0);
+ QCOMPARE(serverCrypto->dtlsError(), QDtlsError::InvalidOperation);
+ QVERIFY(!serverCrypto->shutdown(&serverSocket));
+ QCOMPARE(serverCrypto->dtlsError(), QDtlsError::InvalidOperation);
+
+ // 1. Initiate a handshake:
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ // 1.1 Verify we cannot read yet. What the datagram is - not really important,
+ // invalid state/operation - is what we verify:
+ const QByteArray dummy = clientCrypto->decryptDatagram(&clientSocket, "BS dgram");
+ QCOMPARE(dummy.size(), 0);
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidOperation);
+
+ // 1.2 Finish the handshake:
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+ QVERIFY(!testLoop.timeout());
+
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+
+ // 2. Change reading slots:
+ connectEncryptedReadingSlots();
+
+ // 3. Test parameter validation:
+ QVERIFY(clientCrypto->writeDatagramEncrypted(nullptr, serverExpectedPlainText) <= 0);
+ QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidInputParameters);
+ // 4. Write the client's message:
+ qint64 clientBytesWritten = clientCrypto->writeDatagramEncrypted(&clientSocket, serverExpectedPlainText);
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+ QVERIFY(clientBytesWritten > 0);
+
+ // 5. Exchange client/server messages:
+ testLoop.enterLoopMSecs(dataExchangeTimeoutMS);
+ QVERIFY(!testLoop.timeout());
+
+ QCOMPARE(serverExpectedPlainText, serverReceivedPlainText);
+ QCOMPARE(clientExpectedPlainText, clientReceivedPlainText);
+
+ QFETCH(const bool, serverSideShutdown);
+ DtlsPtr &crypto = serverSideShutdown ? serverCrypto : clientCrypto;
+ QUdpSocket *socket = serverSideShutdown ? &serverSocket : &clientSocket;
+ // 6. Parameter validation:
+ QVERIFY(!crypto->shutdown(nullptr));
+ QCOMPARE(crypto->dtlsError(), QDtlsError::InvalidInputParameters);
+ // 7. Send shutdown alert:
+ QVERIFY(crypto->shutdown(socket));
+ QDTLS_VERIFY_NO_ERROR(crypto);
+ QCOMPARE(crypto->handshakeState(), QDtls::HandshakeNotStarted);
+ QVERIFY(!crypto->isConnectionEncrypted());
+ // 8. Receive this read notification and handle it:
+ testLoop.enterLoopMSecs(dataExchangeTimeoutMS);
+ QVERIFY(!testLoop.timeout());
+
+ DtlsPtr &peerCrypto = serverSideShutdown ? clientCrypto : serverCrypto;
+ QVERIFY(!peerCrypto->isConnectionEncrypted());
+ QCOMPARE(peerCrypto->handshakeState(), QDtls::HandshakeNotStarted);
+ QCOMPARE(peerCrypto->dtlsError(), QDtlsError::RemoteClosedConnectionError);
+}
+
+void tst_QDtls::datagramFragmentation()
+{
+ connectHandshakeReadingSlots();
+
+ auto serverConfig = defaultServerConfig;
+ serverConfig.setLocalCertificate(selfSignedCert);
+ serverConfig.setPrivateKey(serverKeySS);
+ QVERIFY(serverCrypto->setDtlsConfiguration(serverConfig));
+
+ auto clientConfig = QSslConfiguration::defaultDtlsConfiguration();
+ clientConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
+ QVERIFY(clientCrypto->setDtlsConfiguration(clientConfig));
+ QVERIFY(clientCrypto->setPeer(serverAddress, serverPort));
+
+ QVERIFY(clientCrypto->doHandshake(&clientSocket));
+
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+ QVERIFY(!testLoop.timeout());
+
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
+ QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
+
+ // Done with handshake, reconnect readyRead:
+ connectEncryptedReadingSlots();
+
+ // Verify our dgram is not fragmented and some error set (either UnderlyingSocketError
+ // if OpenSSL somehow had attempted a write or TlsFatalError in case OpenSSL
+ // noticed how big the chunk is).
+ QVERIFY(clientCrypto->writeDatagramEncrypted(&clientSocket, QByteArray(1024 * 17, Qt::Uninitialized)) <= 0);
+ QVERIFY(clientCrypto->dtlsError() != QDtlsError::NoError);
+ // Error to write does not mean QDtls is broken:
+ QVERIFY(clientCrypto->isConnectionEncrypted());
+ QVERIFY(clientCrypto->writeDatagramEncrypted(&clientSocket, "Hello, I'm a tiny datagram") > 0);
+ QDTLS_VERIFY_NO_ERROR(clientCrypto);
+}
+
+void tst_QDtls::handshakeReadyRead()
+{
+ QUdpSocket *socket = qobject_cast<QUdpSocket *>(sender());
+ Q_ASSERT(socket);
+
+ if (!socket->pendingDatagramSize())
+ return;
+
+ const bool isServer = socket == &serverSocket;
+ DtlsPtr &crypto = isServer ? serverCrypto : clientCrypto;
+ DtlsPtr &peerCrypto = isServer ? clientCrypto : serverCrypto;
+ QHostAddress addr;
+ quint16 port = 0;
+
+ QByteArray dgram(socket->pendingDatagramSize(), Qt::Uninitialized);
+ const qint64 size = socket->readDatagram(dgram.data(), dgram.size(), &addr, &port);
+ if (size != dgram.size())
+ return;
+
+ if (isServer) {
+ if (!clientPort) {
+ // It's probably an initial 'ClientHello' message. Let's set remote's
+ // address/port. But first we make sure it is, indeed, 'ClientHello'.
+ if (int(dgram.constData()[0]) != 22)
+ return;
+
+ if (addr.isNull() || addr.isBroadcast()) // Could never be us (client), bail out
+ return;
+
+ if (!crypto->setPeer(addr, port))
+ return testLoop.exitLoop();
+
+ // Check parameter validation:
+ if (crypto->doHandshake(nullptr, dgram) || crypto->dtlsError() != QDtlsError::InvalidInputParameters)
+ return testLoop.exitLoop();
+
+ if (crypto->doHandshake(&serverSocket, {}) || crypto->dtlsError() != QDtlsError::InvalidInputParameters)
+ return testLoop.exitLoop();
+
+ // Make sure we cannot decrypt yet:
+ const QByteArray dummyDgram = crypto->decryptDatagram(&serverSocket, dgram);
+ if (dummyDgram.size() > 0 || crypto->dtlsError() != QDtlsError::InvalidOperation)
+ return testLoop.exitLoop();
+
+ clientAddress = addr;
+ clientPort = port;
+ } else if (clientPort != port || clientAddress != addr) {
+ return;
+ }
+
+ if (serverDropDgram) {
+ serverDropDgram = false;
+ return;
+ }
+ } else if (clientDropDgram) {
+ clientDropDgram = false;
+ return;
+ }
+
+ if (!crypto->doHandshake(socket, dgram))
+ return testLoop.exitLoop();
+
+ const auto state = crypto->handshakeState();
+ if (state != QDtls::HandshakeInProgress && state != QDtls::HandshakeComplete)
+ return testLoop.exitLoop();
+
+ if (state == QDtls::HandshakeComplete && peerCrypto->handshakeState() == QDtls::HandshakeComplete)
+ testLoop.exitLoop();
+}
+
+void tst_QDtls::encryptedReadyRead()
+{
+ QUdpSocket *socket = qobject_cast<QUdpSocket *>(sender());
+ Q_ASSERT(socket);
+
+ if (socket->pendingDatagramSize() <= 0)
+ return;
+
+ QByteArray dtlsMessage(int(socket->pendingDatagramSize()), Qt::Uninitialized);
+ QHostAddress addr;
+ quint16 port = 0;
+ const qint64 bytesRead = socket->readDatagram(dtlsMessage.data(), dtlsMessage.size(), &addr, &port);
+ if (bytesRead <= 0)
+ return;
+
+ dtlsMessage.resize(int(bytesRead));
+
+ if (socket == &serverSocket) {
+ if (addr != clientAddress || port != clientPort)
+ return;
+
+ if (serverExpectedPlainText == dtlsMessage) // No way it can happen!
+ return testLoop.exitLoop();
+
+ serverReceivedPlainText = serverCrypto->decryptDatagram(nullptr, dtlsMessage);
+ if (serverReceivedPlainText.size() > 0 || serverCrypto->dtlsError() != QDtlsError::InvalidInputParameters)
+ return testLoop.exitLoop();
+
+ serverReceivedPlainText = serverCrypto->decryptDatagram(&serverSocket, dtlsMessage);
+
+ const int messageType = dtlsMessage.data()[0];
+ if (serverReceivedPlainText != serverExpectedPlainText
+ && (messageType == 23 || messageType == 21)) {
+ // Type 23 is for application data, 21 is shutdown alert. Here we test
+ // write/read operations and shutdown alerts, not expecting and thus
+ // ignoring any other types of messages.
+ return testLoop.exitLoop();
+ }
+
+ if (serverCrypto->dtlsError() != QDtlsError::NoError)
+ return testLoop.exitLoop();
+
+ // Verify it cannot be done twice:
+ const QByteArray replayed = serverCrypto->decryptDatagram(&serverSocket, dtlsMessage);
+ if (replayed.size() > 0)
+ return testLoop.exitLoop();
+
+ if (serverCrypto->writeDatagramEncrypted(&serverSocket, clientExpectedPlainText) <= 0)
+ testLoop.exitLoop();
+ } else {
+ if (port != serverPort)
+ return;
+
+ if (clientExpectedPlainText == dtlsMessage) // What a disaster!
+ return testLoop.exitLoop();
+
+ clientReceivedPlainText = clientCrypto->decryptDatagram(&clientSocket, dtlsMessage);
+ testLoop.exitLoop();
+ }
+}
+
+void tst_QDtls::pskRequested(QSslPreSharedKeyAuthenticator *auth)
+{
+ Q_ASSERT(auth);
+
+ auth->setPreSharedKey(presharedKey);
+}
+
+void tst_QDtls::handleHandshakeTimeout()
+{
+ auto crypto = qobject_cast<QDtls *>(sender());
+ Q_ASSERT(crypto);
+
+ if (!crypto->handleTimeout(&clientSocket))
+ testLoop.exitLoop();
+}
+
+void tst_QDtls::clientServerData()
+{
+ QTest::addColumn<QSslSocket::SslMode>("mode");
+
+ QTest::addRow("client") << QSslSocket::SslClientMode;
+ QTest::addRow("server") << QSslSocket::SslServerMode;
+}
+
+void tst_QDtls::connectHandshakeReadingSlots()
+{
+ connect(&serverSocket, &QUdpSocket::readyRead, this, &tst_QDtls::handshakeReadyRead);
+ connect(&clientSocket, &QUdpSocket::readyRead, this, &tst_QDtls::handshakeReadyRead);
+}
+
+void tst_QDtls::connectEncryptedReadingSlots()
+{
+ serverSocket.disconnect();
+ clientSocket.disconnect();
+ connect(&serverSocket, &QUdpSocket::readyRead, this, &tst_QDtls::encryptedReadyRead);
+ connect(&clientSocket, &QUdpSocket::readyRead, this, &tst_QDtls::encryptedReadyRead);
+}
+
+bool tst_QDtls::verificationErrorDetected(QSslError::SslError code) const
+{
+ Q_ASSERT(clientCrypto.data());
+
+ const auto errors = clientCrypto->peerVerificationErrors();
+ for (const QSslError &error : errors) {
+ if (error.error() == code)
+ return true;
+ }
+
+ return false;
+}
+
+QHostAddress tst_QDtls::toNonAny(const QHostAddress &addr)
+{
+ if (addr == QHostAddress::Any || addr == QHostAddress::AnyIPv4)
+ return QHostAddress::LocalHost;
+ if (addr == QHostAddress::AnyIPv6)
+ return QHostAddress::LocalHostIPv6;
+ return addr;
+}
+
+QT_END_NAMESPACE
+
+QTEST_MAIN(tst_QDtls)
+
+#include "tst_qdtls.moc"
diff --git a/tests/auto/network/ssl/qdtlscookie/qdtlscookie.pro b/tests/auto/network/ssl/qdtlscookie/qdtlscookie.pro
new file mode 100644
index 0000000000..4caa89fe49
--- /dev/null
+++ b/tests/auto/network/ssl/qdtlscookie/qdtlscookie.pro
@@ -0,0 +1,15 @@
+CONFIG += testcase
+
+SOURCES += tst_qdtlscookie.cpp
+QT = core network-private testlib
+
+TARGET = tst_qdtlscookie
+
+win32 {
+ CONFIG(debug, debug|release) {
+ DESTDIR = debug
+ } else {
+ DESTDIR = release
+ }
+}
+
diff --git a/tests/auto/network/ssl/qdtlscookie/tst_qdtlscookie.cpp b/tests/auto/network/ssl/qdtlscookie/tst_qdtlscookie.cpp
new file mode 100644
index 0000000000..c90e9cb2c8
--- /dev/null
+++ b/tests/auto/network/ssl/qdtlscookie/tst_qdtlscookie.cpp
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <QtNetwork/qhostaddress.h>
+#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qudpsocket.h>
+#include <QtNetwork/qdtls.h>
+
+#include <QtCore/qcryptographichash.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+
+#include <utility>
+#include <vector>
+
+QT_BEGIN_NAMESPACE
+
+#define STOP_ON_FAILURE \
+ if (QTest::currentTestFailed()) \
+ return;
+
+class tst_QDtlsCookie : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void init();
+
+private slots:
+ // Tests:
+ void construction();
+ void validateParameters_data();
+ void validateParameters();
+ void verifyClient();
+ void cookieGeneratorParameters();
+ void verifyMultipleClients();
+
+protected slots:
+ // Aux. functions:
+ void stopLoopOnMessage();
+ void serverReadyRead();
+ void clientReadyRead();
+ void handleClientTimeout();
+ void makeNoise();
+ void spawnClients();
+
+private:
+ void sendClientHello(QUdpSocket *socket, QDtls *handshake,
+ const QByteArray &serverMessage = {});
+ void receiveMessage(QUdpSocket *socket, QByteArray *message,
+ QHostAddress *address = nullptr,
+ quint16 *port = nullptr);
+
+ static QHostAddress toNonAny(const QHostAddress &addr);
+
+ enum AddressType
+ {
+ ValidAddress,
+ NullAddress,
+ BroadcastAddress,
+ MulticastAddress
+ };
+
+ QUdpSocket serverSocket;
+ QHostAddress serverAddress;
+ quint16 serverPort = 0;
+
+ QTestEventLoop testLoop;
+ int handshakeTimeoutMS = 500;
+
+ QDtlsClientVerifier listener;
+ using HandshakePtr = QSharedPointer<QDtls>;
+ HandshakePtr dtls;
+
+ const QCryptographicHash::Algorithm defaultHash =
+#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ QCryptographicHash::Sha1;
+#else
+ QCryptographicHash::Sha256;
+#endif
+
+ using CookieParams = QDtlsClientVerifier::GeneratorParameters;
+
+ QUdpSocket noiseMaker;
+ QHostAddress spammerAddress;
+ QTimer noiseTimer;
+ quint16 spammerPort = 0;
+ const int noiseTimeoutMS = 5;
+
+ using SocketPtr = QSharedPointer<QUdpSocket>;
+ using ValidClient = QPair<SocketPtr, HandshakePtr>;
+ unsigned clientsToWait = 0;
+ unsigned clientsToAdd = 0;
+ std::vector<ValidClient> dtlsClients;
+ QTimer spawnTimer;
+};
+
+QHostAddress tst_QDtlsCookie::toNonAny(const QHostAddress &addr)
+{
+ if (addr == QHostAddress::Any || addr == QHostAddress::AnyIPv4)
+ return QHostAddress::LocalHost;
+ if (addr == QHostAddress::AnyIPv6)
+ return QHostAddress::LocalHostIPv6;
+ return addr;
+}
+
+void tst_QDtlsCookie::initTestCase()
+{
+ QVERIFY(noiseMaker.bind());
+ spammerAddress = toNonAny(noiseMaker.localAddress());
+ spammerPort = noiseMaker.localPort();
+}
+
+void tst_QDtlsCookie::init()
+{
+ if (serverSocket.state() != QAbstractSocket::UnconnectedState) {
+ serverSocket.close();
+ // Disconnect stopLoopOnMessage or serverReadyRead slots:
+ serverSocket.disconnect();
+ }
+
+ QCOMPARE(serverSocket.state(), QAbstractSocket::UnconnectedState);
+ QVERIFY(serverSocket.bind());
+
+ serverAddress = toNonAny(serverSocket.localAddress());
+ serverPort = serverSocket.localPort();
+
+ dtls.reset(new QDtls(QSslSocket::SslClientMode));
+ dtls->setPeer(serverAddress, serverPort);
+}
+
+void tst_QDtlsCookie::construction()
+{
+ QDtlsClientVerifier verifier;
+
+ QCOMPARE(verifier.dtlsError(), QDtlsError::NoError);
+ QCOMPARE(verifier.dtlsErrorString(), QString());
+ QCOMPARE(verifier.verifiedHello(), QByteArray());
+
+ const auto params = verifier.cookieGeneratorParameters();
+ QCOMPARE(params.hash, defaultHash);
+ QVERIFY(params.secret.size() > 0);
+}
+
+void tst_QDtlsCookie::validateParameters_data()
+{
+ QTest::addColumn<bool>("invalidSocket");
+ QTest::addColumn<bool>("emptyDatagram");
+ QTest::addColumn<int>("addressType");
+
+ QTest::addRow("socket") << true << false << int(ValidAddress);
+ QTest::addRow("dgram") << false << true << int(ValidAddress);
+ QTest::addRow("addr(invalid)") << false << false << int(NullAddress);
+ QTest::addRow("addr(broadcast)") << false << false << int(BroadcastAddress);
+ QTest::addRow("addr(multicast)") << false << false << int(MulticastAddress);
+
+ QTest::addRow("socket-dgram") << true << true << int(ValidAddress);
+ QTest::addRow("socket-dgram-addr(invalid)") << true << true << int(NullAddress);
+ QTest::addRow("socket-dgram-addr(broadcast)") << true << true << int(BroadcastAddress);
+ QTest::addRow("socket-dgram-addr(multicast)") << true << true << int(MulticastAddress);
+
+ QTest::addRow("dgram-addr(invalid)") << false << true << int(NullAddress);
+ QTest::addRow("dgram-addr(broadcast)") << false << true << int(BroadcastAddress);
+ QTest::addRow("dgram-addr(multicast)") << false << true << int(MulticastAddress);
+
+ QTest::addRow("socket-addr(invalid)") << true << false << int(NullAddress);
+ QTest::addRow("socket-addr(broadcast)") << true << false << int(BroadcastAddress);
+ QTest::addRow("socket-addr(multicast)") << true << false << int(MulticastAddress);
+}
+
+void tst_QDtlsCookie::validateParameters()
+{
+ connect(&serverSocket, &QUdpSocket::readyRead, this,
+ &tst_QDtlsCookie::stopLoopOnMessage);
+
+ QFETCH(const bool, invalidSocket);
+ QFETCH(const bool, emptyDatagram);
+ QFETCH(const int, addressType);
+
+ QUdpSocket clientSocket;
+ QByteArray hello;
+ QHostAddress clientAddress;
+ quint16 clientPort = 0;
+
+ sendClientHello(&clientSocket, dtls.data());
+ STOP_ON_FAILURE
+ receiveMessage(&serverSocket, &hello, &clientAddress, &clientPort);
+ STOP_ON_FAILURE
+
+ switch (addressType) {
+ case MulticastAddress:
+ clientAddress.setAddress(QStringLiteral("224.0.0.0"));
+ break;
+ case BroadcastAddress:
+ clientAddress = QHostAddress::Broadcast;
+ break;
+ case NullAddress:
+ clientAddress = {};
+ break;
+ }
+
+ if (emptyDatagram)
+ hello.clear();
+
+ QUdpSocket *socket = invalidSocket ? nullptr : &serverSocket;
+ QCOMPARE(listener.verifyClient(socket, hello, clientAddress, clientPort), false);
+ QCOMPARE(listener.verifiedHello(), QByteArray());
+ QCOMPARE(listener.dtlsError(), QDtlsError::InvalidInputParameters);
+}
+
+void tst_QDtlsCookie::verifyClient()
+{
+ connect(&serverSocket, &QUdpSocket::readyRead, this,
+ &tst_QDtlsCookie::stopLoopOnMessage);
+
+ QUdpSocket clientSocket;
+ connect(&clientSocket, &QUdpSocket::readyRead, this,
+ &tst_QDtlsCookie::stopLoopOnMessage);
+
+ // Client: send an initial ClientHello message without any cookie:
+ sendClientHello(&clientSocket, dtls.data());
+ STOP_ON_FAILURE
+ // Server: read the first ClientHello message:
+ QByteArray dgram;
+ QHostAddress clientAddress;
+ quint16 clientPort = 0;
+ receiveMessage(&serverSocket, &dgram, &clientAddress, &clientPort);
+ STOP_ON_FAILURE
+ // Server: reply with a verify hello request (the client is not verified yet):
+ QCOMPARE(listener.verifyClient(&serverSocket, dgram, clientAddress, clientPort), false);
+ QCOMPARE(listener.verifiedHello(), QByteArray());
+ QCOMPARE(listener.dtlsError(), QDtlsError::NoError);
+ // Client: read hello verify request:
+ receiveMessage(&clientSocket, &dgram);
+ STOP_ON_FAILURE
+ // Client: send a new hello message, this time with a cookie attached:
+ sendClientHello(&clientSocket, dtls.data(), dgram);
+ STOP_ON_FAILURE
+ // Server: read a client-verified message:
+ receiveMessage(&serverSocket, &dgram, &clientAddress, &clientPort);
+ STOP_ON_FAILURE
+ // Client's readyRead is not interesting anymore:
+ clientSocket.close();
+
+ // Verify with the address and port we extracted, do it twice (DTLS "listen"
+ // must be stateless and work as many times as needed):
+ for (int i = 0; i < 2; ++i) {
+ QCOMPARE(listener.verifyClient(&serverSocket, dgram, clientAddress, clientPort), true);
+ QCOMPARE(listener.verifiedHello(), dgram);
+ QCOMPARE(listener.dtlsError(), QDtlsError::NoError);
+ }
+
+ // Test that another freshly created (stateless) verifier can verify:
+ QDtlsClientVerifier anotherListener;
+ QCOMPARE(anotherListener.verifyClient(&serverSocket, dgram, clientAddress,
+ clientPort), true);
+ QCOMPARE(anotherListener.verifiedHello(), dgram);
+ QCOMPARE(anotherListener.dtlsError(), QDtlsError::NoError);
+ // Now let's use a wrong port:
+ QCOMPARE(listener.verifyClient(&serverSocket, dgram, clientAddress, serverPort), false);
+ // Invalid cookie, no verified hello message:
+ QCOMPARE(listener.verifiedHello(), QByteArray());
+ // But it's UDP so we ignore this "fishy datagram", no error expected:
+ QCOMPARE(listener.dtlsError(), QDtlsError::NoError);
+}
+
+void tst_QDtlsCookie::cookieGeneratorParameters()
+{
+ CookieParams params;// By defualt, 'secret' is empty.
+ QCOMPARE(listener.setCookieGeneratorParameters(params), false);
+ QCOMPARE(listener.dtlsError(), QDtlsError::InvalidInputParameters);
+ params.secret = "abcdefghijklmnopqrstuvwxyz";
+ QCOMPARE(listener.setCookieGeneratorParameters(params), true);
+ QCOMPARE(listener.dtlsError(), QDtlsError::NoError);
+}
+
+void tst_QDtlsCookie::verifyMultipleClients()
+{
+ // 'verifyClient' above was quite simple - it's like working with blocking
+ // sockets, step by step - we write, then make sure we read a datagram back
+ // etc. This test is more asynchronous - we are running an event loop and don't
+ // stop on the first datagram received, instead, we spawn many clients
+ // with which to exchange handshake messages and verify requests, while at
+ // the same time dealing with a 'noise maker' - a fake DTLS client, who keeps
+ // spamming our server with non-DTLS datagrams and initial ClientHello
+ // messages, but never replies to client verify requests.
+ connect(&serverSocket, &QUdpSocket::readyRead, this, &tst_QDtlsCookie::serverReadyRead);
+
+ noiseTimer.setInterval(noiseTimeoutMS);
+ connect(&noiseTimer, &QTimer::timeout, this, &tst_QDtlsCookie::makeNoise);
+
+ spawnTimer.setInterval(noiseTimeoutMS * 10);
+ connect(&spawnTimer, &QTimer::timeout, this, &tst_QDtlsCookie::spawnClients);
+
+ noiseTimer.start();
+ spawnTimer.start();
+
+ clientsToAdd = clientsToWait = 100;
+
+ testLoop.enterLoop(handshakeTimeoutMS * clientsToWait);
+ QVERIFY(!testLoop.timeout());
+ QVERIFY(clientsToWait == 0);
+}
+
+void tst_QDtlsCookie::sendClientHello(QUdpSocket *socket, QDtls *dtls,
+ const QByteArray &serverMessage)
+{
+ Q_ASSERT(socket && dtls);
+ dtls->doHandshake(socket, serverMessage);
+ // We don't really care about QDtls in this auto-test, but must be
+ // sure that we, indeed, sent our hello and if not - stop early without
+ // running event loop:
+ QCOMPARE(dtls->dtlsError(), QDtlsError::NoError);
+ // We never complete a handshake, so it must be 'HandshakeInProgress':
+ QCOMPARE(dtls->handshakeState(), QDtls::HandshakeInProgress);
+}
+
+void tst_QDtlsCookie::receiveMessage(QUdpSocket *socket, QByteArray *message,
+ QHostAddress *address, quint16 *port)
+{
+ Q_ASSERT(socket && message);
+
+ if (!socket->pendingDatagramSize())
+ testLoop.enterLoopMSecs(handshakeTimeoutMS);
+
+ QVERIFY(!testLoop.timeout());
+ QVERIFY(socket->pendingDatagramSize());
+
+ message->resize(socket->pendingDatagramSize());
+ const qint64 read = socket->readDatagram(message->data(), message->size(),
+ address, port);
+ QVERIFY(read > 0);
+
+ message->resize(read);
+ if (address)
+ QVERIFY(!address->isNull());
+}
+
+void tst_QDtlsCookie::stopLoopOnMessage()
+{
+ testLoop.exitLoop();
+}
+
+void tst_QDtlsCookie::serverReadyRead()
+{
+ Q_ASSERT(clientsToWait);
+
+ if (!serverSocket.pendingDatagramSize())
+ return;
+
+ QByteArray hello;
+ QHostAddress clientAddress;
+ quint16 clientPort = 0;
+
+ receiveMessage(&serverSocket, &hello, &clientAddress, &clientPort);
+ if (QTest::currentTestFailed())
+ return testLoop.exitLoop();
+
+ const bool ok = listener.verifyClient(&serverSocket, hello, clientAddress, clientPort);
+ if (listener.dtlsError() != QDtlsError::NoError) {
+ // exit early, let the test fail.
+ return testLoop.exitLoop();
+ }
+
+ if (!ok) // not verified yet.
+ return;
+
+ if (clientAddress == spammerAddress && clientPort == spammerPort) // should never happen
+ return testLoop.exitLoop();
+
+ --clientsToWait;
+ if (!clientsToWait) // done, success.
+ testLoop.exitLoop();
+}
+
+void tst_QDtlsCookie::clientReadyRead()
+{
+ QUdpSocket *clientSocket = qobject_cast<QUdpSocket *>(sender());
+ Q_ASSERT(clientSocket);
+
+ if (!clientSocket->pendingDatagramSize())
+ return;
+
+ QDtls *handshake = nullptr;
+ for (ValidClient &client : dtlsClients) {
+ if (client.first.data() == clientSocket) {
+ handshake = client.second.data();
+ break;
+ }
+ }
+
+ Q_ASSERT(handshake);
+
+ QByteArray response;
+ receiveMessage(clientSocket, &response);
+ if (QTest::currentTestFailed() || !handshake->doHandshake(clientSocket, response))
+ testLoop.exitLoop();
+}
+
+void tst_QDtlsCookie::makeNoise()
+{
+ noiseMaker.writeDatagram({"Hello, my little DTLS server, take this useless dgram!"},
+ serverAddress, serverPort);
+ QDtls fakeHandshake(QSslSocket::SslClientMode);
+ fakeHandshake.setPeer(serverAddress, serverPort);
+ fakeHandshake.doHandshake(&noiseMaker, {});
+}
+
+void tst_QDtlsCookie::spawnClients()
+{
+ for (int i = 0; i < 10 && clientsToAdd; ++i, --clientsToAdd) {
+ ValidClient newClient;
+ newClient.first.reset(new QUdpSocket);
+ connect(newClient.first.data(), &QUdpSocket::readyRead,
+ this, &tst_QDtlsCookie::clientReadyRead);
+ newClient.second.reset(new QDtls(QSslSocket::SslClientMode));
+ newClient.second->setPeer(serverAddress, serverPort);
+ connect(newClient.second.data(), &QDtls::handshakeTimeout,
+ this, &tst_QDtlsCookie::handleClientTimeout);
+ newClient.second->doHandshake(newClient.first.data(), {});
+ dtlsClients.push_back(std::move(newClient));
+ }
+}
+
+void tst_QDtlsCookie::handleClientTimeout()
+{
+ QDtls *handshake = qobject_cast<QDtls *>(sender());
+ Q_ASSERT(handshake);
+
+ QUdpSocket *clientSocket = nullptr;
+ for (ValidClient &client : dtlsClients) {
+ if (client.second.data() == handshake) {
+ clientSocket = client.first.data();
+ break;
+ }
+ }
+
+ Q_ASSERT(clientSocket);
+ handshake->handleTimeout(clientSocket);
+}
+
+QT_END_NAMESPACE
+
+QTEST_MAIN(tst_QDtlsCookie)
+
+#include "tst_qdtlscookie.moc"
diff --git a/tests/auto/network/ssl/qpassworddigestor/qpassworddigestor.pro b/tests/auto/network/ssl/qpassworddigestor/qpassworddigestor.pro
new file mode 100644
index 0000000000..3e2685f579
--- /dev/null
+++ b/tests/auto/network/ssl/qpassworddigestor/qpassworddigestor.pro
@@ -0,0 +1,4 @@
+CONFIG += testcase
+TARGET = tst_qpassworddigestor
+QT = core network testlib
+SOURCES = tst_qpassworddigestor.cpp
diff --git a/tests/auto/network/ssl/qpassworddigestor/tst_qpassworddigestor.cpp b/tests/auto/network/ssl/qpassworddigestor/tst_qpassworddigestor.cpp
new file mode 100644
index 0000000000..bbd6c72ca8
--- /dev/null
+++ b/tests/auto/network/ssl/qpassworddigestor/tst_qpassworddigestor.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtNetwork/qpassworddigestor.h>
+#include <QtCore/QByteArray>
+
+class tst_QPasswordDigestor : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void pbkdf1Vectors_data();
+ void pbkdf1Vectors();
+ void pbkdf2Vectors_data();
+ void pbkdf2Vectors();
+};
+
+void tst_QPasswordDigestor::pbkdf1Vectors_data()
+{
+ QTest::addColumn<QCryptographicHash::Algorithm>("algorithm");
+ QTest::addColumn<QByteArray>("password");
+ QTest::addColumn<QByteArray>("salt");
+ QTest::addColumn<int>("iterations");
+ QTest::addColumn<int>("dkLen");
+ QTest::addColumn<QByteArray>("result");
+
+ // data from
+ // https://web.archive.org/web/20160912052752/https://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
+ // (Note: this is not official, but at least it's something to compare with.)
+ QTest::newRow("di-mgt") << QCryptographicHash::Sha1 << QByteArray::fromHex("70617373776F7264")
+ << QByteArray::fromHex("78578E5A5D63CB06") << 1000 << 16
+ << QByteArray::fromHex("DC19847E05C64D2FAF10EBFB4A3D2A20");
+}
+
+void tst_QPasswordDigestor::pbkdf1Vectors()
+{
+ QFETCH(QCryptographicHash::Algorithm, algorithm);
+ QFETCH(QByteArray, password);
+ QFETCH(QByteArray, salt);
+ QFETCH(int, iterations);
+ QFETCH(int, dkLen);
+ QFETCH(QByteArray, result);
+
+ QCOMPARE(QPasswordDigestor::deriveKeyPbkdf1(algorithm, password, salt, iterations, dkLen), result);
+}
+
+void tst_QPasswordDigestor::pbkdf2Vectors_data()
+{
+ QTest::addColumn<QCryptographicHash::Algorithm>("algorithm");
+ QTest::addColumn<QByteArray>("password");
+ QTest::addColumn<QByteArray>("salt");
+ QTest::addColumn<int>("iterations");
+ QTest::addColumn<int>("dkLen");
+ QTest::addColumn<QByteArray>("result");
+
+ // data from https://tools.ietf.org/html/rfc6070
+ auto hash = QCryptographicHash::Sha1;
+ QTest::newRow("rfc6070-1") << hash << QByteArrayLiteral("password") << QByteArrayLiteral("salt")
+ << 1 << 20
+ << QByteArray::fromHex("0c60c80f961f0e71f3a9b524af6012062fe037a6");
+ QTest::newRow("rfc6070-2") << hash << QByteArrayLiteral("password") << QByteArrayLiteral("salt")
+ << 2 << 20
+ << QByteArray::fromHex("ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957");
+ QTest::newRow("rfc6070-3") << hash << QByteArrayLiteral("password") << QByteArrayLiteral("salt")
+ << 4096 << 20
+ << QByteArray::fromHex("4b007901b765489abead49d926f721d065a429c1");
+#if 0
+ // Excluding: takes about 3 minutes to run
+ QTest::newRow("rfc6070-4") << hash << QByteArrayLiteral("password") << QByteArrayLiteral("salt")
+ << 16777216 << 20
+ << QByteArray::fromHex("eefe3d61cd4da4e4e9945b3d6ba2158c2634e984");
+#endif
+ QTest::newRow("rfc6070-5") << hash << QByteArrayLiteral("passwordPASSWORDpassword")
+ << QByteArrayLiteral("saltSALTsaltSALTsaltSALTsaltSALTsalt") << 4096
+ << 25
+ << QByteArray::fromHex(
+ "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038");
+ QTest::newRow("rfc6070-6") << hash << QByteArrayLiteral("pass\0word")
+ << QByteArrayLiteral("sa\0lt") << 4096 << 16
+ << QByteArray::fromHex("56fa6aa75548099dcc37d7f03425e0c3");
+
+ // the next few bits of data are from https://tools.ietf.org/html/rfc3962#appendix-B
+ QByteArray password = QByteArrayLiteral("password");
+ QByteArray salt = QByteArrayLiteral("ATHENA.MIT.EDUraeburn");
+ QTest::newRow("rfc3962-1") << hash << password << salt << 1 << 16
+ << QByteArray::fromHex("cdedb5281bb2f801565a1122b2563515");
+ QTest::newRow("rfc3962-2")
+ << hash << password << salt << 1 << 32
+ << QByteArray::fromHex("cdedb5281bb2f801565a1122b25635150ad1f7a04bb9f3a333ecc0e2e1f70837");
+ QTest::newRow("rfc3962-3") << hash << password << salt << 2 << 16
+ << QByteArray::fromHex("01dbee7f4a9e243e988b62c73cda935d");
+ QTest::newRow("rfc3962-4")
+ << hash << QByteArrayLiteral("password") << salt << 2 << 32
+ << QByteArray::fromHex("01dbee7f4a9e243e988b62c73cda935da05378b93244ec8f48a99e61ad799d86");
+ QTest::newRow("rfc3962-5") << hash << password << salt << 1200 << 16
+ << QByteArray::fromHex("5c08eb61fdf71e4e4ec3cf6ba1f5512b");
+ QTest::newRow("rfc3962-6")
+ << hash << password << salt << 1200 << 32
+ << QByteArray::fromHex("5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13");
+
+ salt = QByteArray::fromHex("1234567878563412"); // 0x1234567878563412
+ QTest::newRow("rfc3962-7") << hash << password << salt << 5 << 16
+ << QByteArray::fromHex("d1daa78615f287e6a1c8b120d7062a49");
+ QTest::newRow("rfc3962-8")
+ << hash << password << salt << 5 << 32
+ << QByteArray::fromHex("d1daa78615f287e6a1c8b120d7062a493f98d203e6be49a6adf4fa574b6e64ee");
+
+ password = QByteArray(64, 'X');
+ salt = "pass phrase equals block size";
+ QTest::newRow("rfc3962-9") << hash << password << salt << 1200 << 16
+ << QByteArray::fromHex("139c30c0966bc32ba55fdbf212530ac9");
+ QTest::newRow("rfc3962-10")
+ << hash << password << salt << 1200 << 32
+ << QByteArray::fromHex("139c30c0966bc32ba55fdbf212530ac9c5ec59f1a452f5cc9ad940fea0598ed1");
+
+ password.append('X');
+ salt = "pass phrase exceeds block size";
+ QTest::newRow("rfc3962-11") << hash << password << salt << 1200 << 16
+ << QByteArray::fromHex("9ccad6d468770cd51b10e6a68721be61");
+ QTest::newRow("rfc3962-12")
+ << hash << password << salt << 1200 << 32
+ << QByteArray::fromHex("9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a");
+
+ password = QByteArray::fromHex("f09d849e"); // 0xf09d849e
+ salt = "EXAMPLE.COMpianist";
+ QTest::newRow("rfc3962-13") << hash << password << salt << 50 << 16
+ << QByteArray::fromHex("6b9cf26d45455a43a5b8bb276a403b39");
+ QTest::newRow("rfc3962-14")
+ << hash << password << salt << 50 << 32
+ << QByteArray::fromHex("6b9cf26d45455a43a5b8bb276a403b39e7fe37a0c41e02c281ff3069e1e94f52");
+}
+
+void tst_QPasswordDigestor::pbkdf2Vectors()
+{
+ QFETCH(QCryptographicHash::Algorithm, algorithm);
+ QFETCH(QByteArray, password);
+ QFETCH(QByteArray, salt);
+ QFETCH(int, iterations);
+ QFETCH(int, dkLen);
+ QFETCH(QByteArray, result);
+
+ QCOMPARE(QPasswordDigestor::deriveKeyPbkdf2(algorithm, password, salt, iterations, dkLen), result);
+}
+
+QTEST_MAIN(tst_QPasswordDigestor)
+#include "tst_qpassworddigestor.moc"
diff --git a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro
index 7c1cd5b66b..7e6870f74b 100644
--- a/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro
+++ b/tests/auto/network/ssl/qsslcertificate/qsslcertificate.pro
@@ -1,7 +1,6 @@
CONFIG += testcase
SOURCES += tst_qsslcertificate.cpp
-win32:LIBS += -lws2_32
QT = core network testlib
TARGET = tst_qsslcertificate
diff --git a/tests/auto/network/ssl/qsslcipher/qsslcipher.pro b/tests/auto/network/ssl/qsslcipher/qsslcipher.pro
index 81ef2d8d9a..392d22c054 100644
--- a/tests/auto/network/ssl/qsslcipher/qsslcipher.pro
+++ b/tests/auto/network/ssl/qsslcipher/qsslcipher.pro
@@ -1,7 +1,6 @@
CONFIG += testcase
SOURCES += tst_qsslcipher.cpp
-win32:LIBS += -lws2_32
QT = core network testlib
TARGET = tst_qsslcipher
diff --git a/tests/auto/network/ssl/qssldiffiehellmanparameters/qssldiffiehellmanparameters.pro b/tests/auto/network/ssl/qssldiffiehellmanparameters/qssldiffiehellmanparameters.pro
index dee95886e0..2d45f4476c 100644
--- a/tests/auto/network/ssl/qssldiffiehellmanparameters/qssldiffiehellmanparameters.pro
+++ b/tests/auto/network/ssl/qssldiffiehellmanparameters/qssldiffiehellmanparameters.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
CONFIG += parallel_test
SOURCES += tst_qssldiffiehellmanparameters.cpp
-win32: LIBS += -lws2_32
QT = core network testlib
TARGET = tst_qssldiffiehellmanparameters
diff --git a/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro b/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro
index a180086c5e..7eae6ae864 100644
--- a/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro
+++ b/tests/auto/network/ssl/qsslellipticcurve/qsslellipticcurve.pro
@@ -1,7 +1,6 @@
CONFIG += testcase
SOURCES += tst_qsslellipticcurve.cpp
-win32:LIBS += -lws2_32
QT = core network testlib
TARGET = tst_qsslellipticcurve
diff --git a/tests/auto/network/ssl/qsslerror/qsslerror.pro b/tests/auto/network/ssl/qsslerror/qsslerror.pro
index 117fd4ac27..83644d093c 100644
--- a/tests/auto/network/ssl/qsslerror/qsslerror.pro
+++ b/tests/auto/network/ssl/qsslerror/qsslerror.pro
@@ -1,7 +1,6 @@
CONFIG += testcase
SOURCES += tst_qsslerror.cpp
-win32:LIBS += -lws2_32
QT = core network testlib
TARGET = tst_qsslerror
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-DES.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-DES.der
new file mode 100644
index 0000000000..e70bde5820
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-DES.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-DES.pem
new file mode 100644
index 0000000000..fd62743d94
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-DES.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHwMBsGCSqGSIb3DQEFAzAOBAiBYHv8jvBwMQICCAAEgdCwfamafrN1nvpdnF5t
+KCPgBvRGfV9zStK+XItBAe72CZdAy1Jjr2UJHc8Rl3OEo2hmCr+892/lhK7GIugj
+oLOvON3VEqrUvrvmH0Qtm+/A/ypq14Lr4sBfq7bViM44bv/DUwHMD5/xmLtSzXlC
+AjjioBJ/k4K+6DzD3+eMDNr6Z9rCUcvJP6q8+PPhpIXEJquA3RYuyuDhdIbazO5A
+iMts7PbzBzW/4YhENPWaUdviuRZo/ap+WDJ/SdwiNxOxx7KrWgj3y2dAtNnVAv5T
+njE4
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-RC2-64.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-RC2-64.der
new file mode 100644
index 0000000000..40bbe6a441
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-RC2-64.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-RC2-64.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-RC2-64.pem
new file mode 100644
index 0000000000..6a8a8484e0
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-MD5-RC2-64.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHwMBsGCSqGSIb3DQEFBjAOBAga2K6FvYk1ygICCAAEgdCV9m57p+DrBrVafXUq
+8pgdr+1FEX9YaFXNRMKyPZ5Ca6t5RsPpWC3RdGlieH4iVp03/rlTttx0rLUWx3IG
+gsrd2adrP6Bl/lbEJnZ6lIeZz2KvPbbhfmRMCIhr/h24JSi5lmGl5KzxQXSm9ujb
+/5jtN/QtoQ3cLWpNn1SwMNdIAYgEpnCghwqITbBwMovD8yd2YNbNbejG/T+q6bwl
+GJE46OSX+IAWQ/wJejdq//ozD3m2PxjK6nktWeqAeoqcycYGYGKvta27lNqyuE3M
+BdGT
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-DES.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-DES.der
new file mode 100644
index 0000000000..6ebe9c4011
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-DES.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-DES.pem
new file mode 100644
index 0000000000..3422931606
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-DES.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHwMBsGCSqGSIb3DQEFCjAOBAjj2EIj8WAOWwICCAAEgdB4G1oLnLtLAGaZtpGb
+vU2g4g3pJtQLJX1H0a/cmXO1OrX7YRcESvw8nocZjNKKWCehfQqinRBpVUsoaGUw
+QssIDKlWkW3LbM11F6YMI5GCzN5bpWcJazQRyHEnIk/OTQN3aeKjnYQXep1nt7tN
+INKsCAVyx1cYfr3izxGRwN2hTraz5fBdeBpEye+Essn5KziwET32EbW+kt+wsule
+k4tvnKgCOvbvVzqIdafH/FfP04KRv39O+HR3evoBjhGudUxXJ0OLp8IZkG+34f3P
+ZQxC
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-RC2-64.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-RC2-64.der
new file mode 100644
index 0000000000..c8ae94c4f8
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-RC2-64.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-RC2-64.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-RC2-64.pem
new file mode 100644
index 0000000000..93857f010b
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-PBE-SHA1-RC2-64.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHwMBsGCSqGSIb3DQEFCzAOBAgrv/kKBXNFAwICCAAEgdAFpWxMmQygufWZpeAI
+heJ3uqyb5bnahW75t2HWQZTb1qEqp62/iLr1IlbHmZAQbJc0+VLhXz/2QtK3q/BB
+bHpa9cWGFi2HVgO4dFjSI7X68QrM93GPGHqwtnVZnlo2aPHgA6BzotEEwklXl4Db
+BbPKo0vBUVA9ZKaN0lH+Pzj/Rb37kC6xRWBjNd87jaszykcNFYkTNrrG8nESHJAw
+fTeHwrsGsmIz8FfOxRfqXrPwOiA5AZZ/S/8Jt2gtoOW5ydY6/Bfp0aEwAIhwxjFJ
+cy6N
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA1.der
new file mode 100644
index 0000000000..2c2caa0665
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA1.pem
new file mode 100644
index 0000000000..0797d9167f
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA1.pem
@@ -0,0 +1,9 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBHjBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQI8mhki8A7ijgCAggA
+MB0GCWCGSAFlAwQBAgQQbVjLreAybYGwsnk4ZMQUIgSB0Ozr2DfP+rkb58tT748m
++7xe+bhpT3xrrSpUsB2RXUH/6M7hVjb+XZ/JSAegqkuZq08df+ezpHjWX/W+IVL4
+Sx0wZWNW51TiwGymNFuBwSVliqCvndAaY+EIY3bsME5RFik86R4iAbtrxalWPFoR
+jscLkGtNstQR5JQCOccTN7h5jRBwEFrArqfPv+XZb5ysy9FjFnVDuspFg/CysIJD
+V7WEJcxOzEIk2bbxY4UEpLhfFv8RHrV8M7jmjVRC+mN094zMnzBVSv8KIjk0Ljff
+ysY=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA256.der
new file mode 100644
index 0000000000..3f3bd2e8ea
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA256.pem
new file mode 100644
index 0000000000..e78d69ae8a
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes128-hmacWithSHA256.pem
@@ -0,0 +1,9 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBLDBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQICIPD0G0X/sECAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBDSrIv/kITtQ/RL5j675WqsBIHQ
+oSiQJLyXPOmnNYmWLw4Biom8Utn/I8109mUujVPhUA63njp0I/jGwNn4FcdilZlO
+TTCKIxlzG3zhztS5xqxQFuzWNQdTgfqzO7DSi/ZtGErvZi+ShaiQU7ri7LYRIw8C
+7YtXiPrfPSKpfyU0adD2socAa1OlnvinoaHYd/QNs4EEv3hahIiq/nHpzRkb2qdX
+XIruJhlvF4B07aYfmRvMK4CVd6VGXfGfGXECFqMk5b7HwJzkMTbtB2bsMTNguGxK
+o1+Hf3PHRst6q1776z8ENw==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA1.der
new file mode 100644
index 0000000000..f078644544
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA1.pem
new file mode 100644
index 0000000000..9a6b147602
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA1.pem
@@ -0,0 +1,9 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBHjBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIdlQB+08q40gCAggA
+MB0GCWCGSAFlAwQBKgQQ3dY2cSZfdPyeYlHRO+M63wSB0DjoR/cQ2rLkW1Ur8V1q
+LG/0nv0O1mVK8Sj+BcOje/nqMU67lRdkXVI1yICmpwrwFEkwIV6zHIx+Dwriliel
+h0yXsTLaBmMQeJo17J6kOyuW+C0Mr8CqlnAVEoEQI7FPes7rtw6W0wkuuPPw3vEs
+RKB8xwdfS5t5ot5DtKZ5rN+6XbtRA/jdfi1O6ekKzeT0fpRGP+ppTEmCh77+8Ity
+/BwPKGXepZpHkOcDOvWGdDiuy7vhA5gaYyzpXPD2Fo3V5cobFzgLzT3in+b6YtV4
+s/4=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA256.der
new file mode 100644
index 0000000000..618be6ad9c
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA256.pem
new file mode 100644
index 0000000000..a82c2fbc94
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-aes256-hmacWithSHA256.pem
@@ -0,0 +1,9 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBLDBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIVsIsQ3kPm5gCAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBAOdrxyNKYeoKCTuDXeYiwpBIHQ
+DheVgnsmJ7bYb5Y02qOdCjfYEUje8bvendhIsG41recaNjdHcWQB1JOV8anmZPJ+
+4buMQhE9Lfw5Hvg2x0pqkvQCV0aUWUwwybnoQ9T8z0z67WJG6f03m9eE+Mzw9Q0D
+wavghqO/lnh9uGd4Tdfzuj0NWHbrey7ags81fZ9jWOdX/M5LywFr7oThokfq6LlH
+rpnK13j9MUVrmmSvsjVXGjWErEaTXbJOpCeyDn1510iI5pyGRZpicmfHzE6YNHvF
+dKSlxRWO+cOxE9Ax9dm5mg==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA1.der
new file mode 100644
index 0000000000..33ca45e2c9
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA1.pem
new file mode 100644
index 0000000000..ec276fd807
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA1.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBFTBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIwE9ZHpXAOK8CAggA
+MBQGCCqGSIb3DQMHBAgOtF6y98HdvQSB0KtvnVtpFqjG8OLzPyZrugisgiYBgvoU
+62D+rfO5Ji4cbWwuQEeS3ywI7rHH6BG8+mxcVeQHSmGZi336M/j0erO/yo6MnkrU
+a8pfrqfPvLJPa+2FPSWlM/+ppj+kcaZa0B8pF/mioBThID8KhDFm8CG4UwP4P2Kn
+GUUGmM9cyNdPFWuVg8PyY1zHcx2GNiL4XZcKp1qsGf75uso8DmgrvI+c9yDD+5ag
+rPmsgFSy3XtlNmYGyLq1pW4rQ6ivLknZc5oweqjISVT3jKjJqowgJYo=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA256.der
new file mode 100644
index 0000000000..6d23cd3604
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA256.pem
new file mode 100644
index 0000000000..f33f0dc4c4
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-des3-hmacWithSHA256.pem
@@ -0,0 +1,9 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBIzBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQI584onGZg/sMCAggA
+MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECMEvKBdjD2B+BIHQlCNsdhKhN8ce
+l73RzS4AUNbPamaLPV+l+vy8F4jjziCux0RwS/83ju/XlD/TntSYH4RYx/2vNHo5
+/YVGinOSTHZD7BqHHOxTjMqlVY4uFU2oJcGQ2VIsbVuPiL78Tq6XcuaIy5ElXjte
+g/qa8y9/cJM9wm6O1XMfIIL6AboBdbVloStvij3HOOOOlZp6161+QlmADdo2yJJ2
+byP7SoC4I6fLDrKZub8+AEcPFCjvLZ6a9HmCF8aw/rvVqOZ91YJOxgsPYYmOXJtG
+sYzN48y81w==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.der
new file mode 100644
index 0000000000..f195c03e3b
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.pem
new file mode 100644
index 0000000000..d317c53836
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHxMBwGCiqGSIb3DQEMAQQwDgQIcCYglgSeP+sCAggABIHQXnZlcc/CDvsT/3aQ
+o2E6AgnJgaq6P2l41yQ6BuomXRSI+KoP+nYWC2fAtb/URgdoNstrflNjTGysSdyl
+CU7A1FnrQkoSvvLElcy25/ttuH9LE4adbhCiKgv2NQXXY/2Lzeeq1e3iqLg7/5wx
+7B2XmgQvMV3EHN1uJWVDKuevOOJ5ULKYONELDaicrlm8IumdhWMvp3ypUrHe6hSD
+i2YYZf8eXfCY0NIRFeXluEgK4MFz/iEkl7aYpNDSA9F7Uk6TC3IRQu3yFs0GR37b
+4fDtpg==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.der
new file mode 100644
index 0000000000..96b54c3f5d
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.pem
new file mode 100644
index 0000000000..2fe8300613
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHxMBwGCiqGSIb3DQEMAQMwDgQIwZ3Xa+/tptsCAggABIHQmdPeV+Zd96TBIGM+
+kYRNqxckxWbVWE8EBWzJOwjlvrOxhVi3hbSl4QM3cMyNFv0ssyuJiXGQQ7+6/dkp
+UxPWigaSJkemDMtDTQNpHcK/4Ekao+PlAvzgi6wG0lUfL4ioSiEqrE5DlcdfctdR
+Nj9mF4u0rekPWthXhfHcmDxQKSORDi8gYfyQUaV59niKQGIYMsVz4Bu2fwrrTLFn
+NjzyHhYsva2GLAfEWNB13/VtIv4gJaB5mZpzLf81VWe52rR7rZWb3R/rWEz9FFQm
+vrgagw==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.der
new file mode 100644
index 0000000000..7fd85f55db
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem
new file mode 100644
index 0000000000..e9faf30e61
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHxMBwGCiqGSIb3DQEMAQUwDgQIMLBXkL2mR68CAggABIHQkquhoK6Ep0EtnjC7
+V2FbRzYrFSvOakBOGuU6U6p+JeStbTRp4gLQ9hY/8xG7l0GrzM8dlcrO5QnI9Ypk
+zw6a/9FTE+ROpQYGiRjnhdegRguIn6aaCdejfu5s4g09kz/Y6saM1LBkA/hby0m9
+YWB8IFg+/B8qLScjnhn7UOBm4HAW/UywXGH7IFH87ml1g87xlDu88GhcP8iqenco
+TrfPCQDoa+C0EBLV8yTR5aG66kK6BrWXNkyZgUiuhUF1TYmZhZDaiUJ4Er4gMlgA
+C8o6qw==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.der
new file mode 100644
index 0000000000..c0d8b9bb3f
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem
new file mode 100644
index 0000000000..a1d968b912
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem
@@ -0,0 +1,8 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHxMBwGCiqGSIb3DQEMAQYwDgQI3y3PINAU1csCAggABIHQEPD8M7YheSdikqwW
+tem/Oz+CZxAXWCBYokpxSeGexFR85Ni2bd/wr8tT4Mv5nNrPLlcNMrKLYCTWryEu
+PtW1XtMp881xmPM9QMgrFRfhiGeVfveEmKZzdGrXN5RRqa20Xa0ufEqaJpvfJHIz
+meWfNkAUtr0RhwK1tMfjxg3CvnSXG1l/cegvUgsc5Nq4VfCOwLYAPY24ltYIZrAp
+JKuc9XkbBx+Uow4kOVpOBTA28giB9gywSbpn1/bCgrm1iBltlrC1bOI2UEYLXAK8
+S8kOew==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.der
new file mode 100644
index 0000000000..59f01c9057
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem
new file mode 100644
index 0000000000..29da203ac1
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHqMBwGCiqGSIb3DQEMAQEwDgQIS1fq1s4wBy4CAggABIHJsEjsk3aow+m3DXPe
+1KCnwl0qXzzh96JCrtAa+2pWytp52+mZphUgnNXYkIoj0rdqJbr1y4/3t73ffVFG
+TU/4401k2QTSKo2mObTxY811fnWImBbNG3BJVmoq8zvJuHrctfVQuKBQb9UFA7RF
+E5WrYwkNXfRxgSsuUgtMvklHyxeAjxdZ0vWennUuPkJIa4XQhIY5gqMiume8dCGl
+mDujTHUPhBjRKifaGQv2hvc8l7FgjUlUY1DcZIl0AapzF3jEXS/Se90FOE2M
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.der
new file mode 100644
index 0000000000..f185d58b51
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem
new file mode 100644
index 0000000000..3dd08fd969
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHqMBwGCiqGSIb3DQEMAQIwDgQICCPn/nJOcwECAggABIHJY1EqBsfnKkOsytQR
+ujblH/MciuYQ5PIkhS+rfEyYvNaQAM4ELbZjBOhqhPxpWgV/nwzl5lbjGHGaBojp
+uH6Tm9L/J/DUVXt5U6i0bmuJ3vUQL9t8WlLwWKEUbszMOJfzgn+q7pr2AViOwcgA
+kL9JD3fTL7KspScIvYo8JD5YomwzDTMyhJFtkvKpjDtBsBkZxvmDRtBnjYYDAvie
+ICGKQ5ojeZD2p2v69ra9bhAOXi/wz+AMotLVWa8myrOb7B+X/b0xEnoOqxKL
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA1.der
new file mode 100644
index 0000000000..a3d1fa4c9b
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA1.pem
new file mode 100644
index 0000000000..9adf8802c3
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA1.pem
@@ -0,0 +1,9 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBHTBIBgkqhkiG9w0BBQ0wOzAeBgkqhkiG9w0BBQwwEQQI7hWoVS10HvICAggA
+AgEQMBkGCCqGSIb3DQMCMA0CAToECLPHM3qUvtYPBIHQl36zBfnW7J89+Kl+tLa4
+rm9Iu8KpMNJm2bnuLptltF/e5Vyp92xRvuCoaAVQka0dq4jKOVOkruMfHHHOf22g
+mxpwtJfYvKqqjW2KH2FE0Y3l1XPV6o4Of5FbhvcULDmNtCoFlme0hoAoHm1kUUzS
+Ed4CJqc6VpYpHGCv8X6k+0j274XnPqRJaY8KizrD0+/i6vS/nu/srxLqt9COT9nS
+tVTQL/CRmmXf8/jSdVLDMKjjboFU1FtVZnOq4yAAuJiBZFtfmIF5+EI1dbXMbMdF
+MA==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA256.der
new file mode 100644
index 0000000000..398d47b4c4
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA256.pem
new file mode 100644
index 0000000000..de0d9179a2
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8-rc2-hmacWithSHA256.pem
@@ -0,0 +1,9 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBKzBWBgkqhkiG9w0BBQ0wSTAsBgkqhkiG9w0BBQwwHwQIysmtT0sgtmsCAggA
+AgEQMAwGCCqGSIb3DQIJBQAwGQYIKoZIhvcNAwIwDQIBOgQI3Lf5sOaUEmsEgdDE
+0UkzkZdDMLBn9gGk9plFNb+2QKT2l0M1byplj92l8+eSv9stLTSf3v9STP7c/plJ
+PMj4RUym4W7URvFhIEicyLDYNL7nD9JELC2i7E6S3NaSAZVeOxSl4gxEVtOPC00i
+Dy/AISKSeNNBJkdUwT+m7as8Uc4+M1eitfMBQFUjRWQONpzw/2NtIeqI14VKPAM0
+1kVQTsO7TLEAwj7Jd1iscGakz+Ib7zMl1pCbVHrlh6nHrKvF+gvMDw5eC952CbpD
+XCcPq3tU2j6KGGzK3ksd
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8.der b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8.der
new file mode 100644
index 0000000000..ecd0670072
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8.pem b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8.pem
new file mode 100644
index 0000000000..a6f6f734eb
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/dsa-pri-512-pkcs8.pem
@@ -0,0 +1,7 @@
+-----BEGIN PRIVATE KEY-----
+MIHIAgEAMIGpBgcqhkjOOAQBMIGdAkEA+7WshnhYKUIf+71hYgDUGQcSk2JxzOw6
+rpKt3fkIafnkm6KnXeTIPrWlSLAhtHpsCX56HDzYu69BRyVjuYiFxwIVAJljwa1Y
+uxEZ/+w73/UFLgvb0juZAkEAhk+R4vDxKY6w78hLyCfhSwnT4L3BWn6pINaAM4NU
+lVzsYP6ye4R9vCvc2h+254GszhsjvKrCzl1RDI3UyJenAgQXAhUAl95kGzNYPVm5
+Y+2jpGA9N2PkcCU=
+-----END PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-DES.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-DES.der
new file mode 100644
index 0000000000..7af45943cb
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-DES.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-DES.pem
new file mode 100644
index 0000000000..91874a9b29
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-DES.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGgMBsGCSqGSIb3DQEFAzAOBAihGk2iurZE8wICCAAEgYCaneaK9dlMsDGD11jl
+F5etfmvAbUbpzVmooM4ORHweCnP/DiwJVyQ02dU3PlB0teLCG6DyJCl6CaOhZjRc
+cDE4fYIBBVtLlcqwr8oc73DWi3azJ+/KdkuUQyHZEkzNo9Thi1owDI6XMlWbFZwd
+wSlfuk9AghDAN8/n3iMu87veSQ==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-RC2-64.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-RC2-64.der
new file mode 100644
index 0000000000..14bb01d10d
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-RC2-64.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-RC2-64.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-RC2-64.pem
new file mode 100644
index 0000000000..30b186b796
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-MD5-RC2-64.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGgMBsGCSqGSIb3DQEFBjAOBAgQKZdqJ6i7cQICCAAEgYCfJQJakYch640S/EA0
+tLuO7xxLgeI9gxeooy0GM9FeHiDencz9BXJrFFpXLs8J5IgVuj2zjfMDOuf/3zCa
+gn1itwByKWPLXHx5vRUAT5zds2F3uBo7RCQj+FlR3xv4Xuqwx34qfYJpafORpi7/
+eO6M4V2BnAkws1b5UK0WDjFfSQ==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-DES.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-DES.der
new file mode 100644
index 0000000000..689780f8a1
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-DES.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-DES.pem
new file mode 100644
index 0000000000..1f737d9803
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-DES.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGgMBsGCSqGSIb3DQEFCjAOBAjruvWW+JZt7wICCAAEgYAgvrADpBoAMNrS8uYX
+9FTnHUsGr5Sg3e2ueEwMUGsnGliJJTa58r9634RffN6uyB8jBihCdQw5iBbzLkC2
+ltEVcOR8pNQvprGXX4X/jwOY4RhyKrb89YdZ2BZ4orzY5cL+6nGYQKEm3WlrXW+a
+Ncq6UvRpVmHqQ0OW+zuCbi5/nA==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-RC2-64.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-RC2-64.der
new file mode 100644
index 0000000000..a06790a254
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-RC2-64.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-RC2-64.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-RC2-64.pem
new file mode 100644
index 0000000000..814c341760
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-PBE-SHA1-RC2-64.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGgMBsGCSqGSIb3DQEFCzAOBAg95ivo7up6egICCAAEgYDAMawlX0a61+iLgab0
+Zi62Ef7g0Jdj0KG4NeKmWrmuCXI3HBiAVv878vWkL8cMx5DqhBDw8A14aOxCkIm9
+uZ5twNwunINclMQtYxL7mtQLjUr50sFFY/Dd2PH669Qb6dqZC6efO7y31n93+fUI
+gyntTIXfeuUSg8uw/qG9Vfa6oQ==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA1.der
new file mode 100644
index 0000000000..fe071489cb
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA1.pem
new file mode 100644
index 0000000000..d7c41b121d
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA1.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHOMEkGCSqGSIb3DQEFDTA8MBsGCSqGSIb3DQEFDDAOBAhC3xITYW8eRQICCAAw
+HQYJYIZIAWUDBAECBBDUQa3ddOnliyQ/qIYEFmK2BIGASDcmbEFHEwmV9uJzQEI4
+hfZTOVaR0lYHCTTnJjEsbM8oyvVvMxJkefNqPVkBF1Oc4nHaN6LEPIZRpHYJxjDH
+tk7RFlcvSlS2Dcv41y+2Bcj1dMtocXM1t6jxo5nioeBnHCUQr3VsDT9+eJvithY9
+UyUqUt+P5f1H1LCpqD3BYcc=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA256.der
new file mode 100644
index 0000000000..62113a1e6b
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA256.pem
new file mode 100644
index 0000000000..83e58214fb
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes128-hmacWithSHA256.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHcMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjv/NQpQZwZbgICCAAw
+DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEPMGCKos4+H6cwxOhDR8UbQEgYC6
+01v9qHJnnFkHBbQ7L4xpWY3RVHTalKfCfLQErqwPx1akV7BPdCZmjd4rAdIGLImy
+kaaAPVrJ3GVjF6fW+E9UIGoDEbFeZ1hlnTzhOTqUwGiBrCM0SY3XDyBxSdqv/Pk/
+M4Ibk/lDycV/kWm26j2I9OYPxedj4vdPgXPxEi7FeQ==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA1.der
new file mode 100644
index 0000000000..232a6cf2cd
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA1.pem
new file mode 100644
index 0000000000..294278ea44
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA1.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHOMEkGCSqGSIb3DQEFDTA8MBsGCSqGSIb3DQEFDDAOBAgYx6Cuor4IHQICCAAw
+HQYJYIZIAWUDBAEqBBDc1FODsp0BBJI/EOjU/nA1BIGAUIe6lzmR2cWVQUAW6gF8
+UdykIWS5E4AnbPtaiVdFNmhyjtUq10gf67jX3/hfA3QXwDCTT1aot+5Vjrb57M8S
+hjxrs871w0UvzBmrTLJA2/BWPz5gni72fj1N5JGYUKI4MFKHGhv53iUzW/E8KiRW
+ab4KY+hUF9zFcXOBwOGvG7E=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA256.der
new file mode 100644
index 0000000000..0f4075965a
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA256.pem
new file mode 100644
index 0000000000..90ab751415
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-aes256-hmacWithSHA256.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHcMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAg+0vyp4rA5hgICCAAw
+DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEDlKgIIcdKfiQcsZLfQt97cEgYAD
+TrjldhQKT8SjAnmChT/knsUeJzThLxKpdpRwbr8qYTZbCmngbb2oYBkrNzAwGoVM
++cj+6p3EgP7T/zjJYj7EArRvs7FM0spxqre2bQY3GG5E3PDGyR/h4nwdVTzorqNw
+/35Dtl8ifbnVI4SCwTtifnCDsz9TjIXszixrCm354g==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA1.der
new file mode 100644
index 0000000000..669cb1f9cc
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA1.pem
new file mode 100644
index 0000000000..233dd94a18
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA1.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHFMEAGCSqGSIb3DQEFDTAzMBsGCSqGSIb3DQEFDDAOBAjU9TMJNWzzUAICCAAw
+FAYIKoZIhvcNAwcECEd8I4R+1rlZBIGABNupNKmIR5j2lAyQAbDjXX2PtpOGH0+k
+KXnS7i6rmseQFjwDiF+xMefhj9ZamEgypDjyWaYz/EwV7dP0dUzZuQpzGsN/JLZS
+i1IhRV9sVABs4SbCn/KZsy8bLW/7/3e5qloRkXskB6dR4nVrq4kz1qMmQVO+9Ojo
+Td+SUeCdhd0=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA256.der
new file mode 100644
index 0000000000..9f444d6350
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA256.pem
new file mode 100644
index 0000000000..29f17933bd
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-des3-hmacWithSHA256.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHTME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAgf2AMm0URGvQICCAAw
+DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQI/4fa6rbvznsEgYBImRLhwGbEgcLm
++yHcsohX1uQyqPfP8PVHGtM6ITaAJ16djxQKfXRoffS4DSTnhFgHnXm42V7epgJO
+ZHRe0dVbKynbp1ZCnNIXsvsgyP4ghfw70j2u+45fiBK2ZqhVaQns/1t02eIa7Kud
+308ffy9xR8xbCV9H1hu978sWDPRgmA==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-2DES.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-2DES.der
new file mode 100644
index 0000000000..e7939899c8
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-2DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-2DES.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-2DES.pem
new file mode 100644
index 0000000000..eba00a5597
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-2DES.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGhMBwGCiqGSIb3DQEMAQQwDgQIASNN5nArudcCAggABIGAsi5Ta25v+vkS7qc0
+b10/Hv1H2SVhhOA4iYMdjB2XgpRFXBduYIFfROdAT8pJvspZ2EIJGu975H+SKeJ3
+ndULrOFmaDknlsAyVW8HslnOiuQVpNE0vTWWJYVg1xq9Hwg5YU7C1PsCMy8f5g4O
+gbsHxVy7AGF2FSrJqy2PVdoEADI=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-3DES.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-3DES.der
new file mode 100644
index 0000000000..9dd3f9d42c
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-3DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-3DES.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-3DES.pem
new file mode 100644
index 0000000000..01f62cf5f2
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-3DES.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGhMBwGCiqGSIb3DQEMAQMwDgQINArkfLom3CoCAggABIGAaqrWHE+VgTLr/TQk
+x86KYu88/eiO5jxGUxbFwUCOtTbw8g40MY4tuXNhhm9lQ5zVSrC7fdjagqr6Flz5
+YV8NWpURbA4CKXgX+JKUMzZclHUwfe/M/CI5tKIU8vu7O2jl8gL5mOAFagLmFUld
+iS5+KYtWvuOy1jQd9Cn4pOrF0yA=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-128.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-128.der
new file mode 100644
index 0000000000..2f1148d1ea
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-128.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem
new file mode 100644
index 0000000000..fdddcfb02c
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGhMBwGCiqGSIb3DQEMAQUwDgQIBOJoKaHoCH8CAggABIGA5ekhEhokinZUh8Su
+FU9XT9TmpJI6+uSUnV6dCI5F7jxUC4BKYUDLQ/wjassasP/z7NYgIUFXiSsx8+u9
+rIOd83qJly/QL3MI8HA/gwrUOK1mcQCdHM7WcDxgTDfA8iXvE7ipxkqWWh+vjWVg
+QIBy+Mik4f8m6qRJtHvkn1+QVUQ=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-40.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-40.der
new file mode 100644
index 0000000000..f8a47e1127
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-40.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem
new file mode 100644
index 0000000000..368b1d9fd7
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGhMBwGCiqGSIb3DQEMAQYwDgQIYoqh4a7jy44CAggABIGAhOjw9xEXhMSaBJM6
+Opu29QK4+h7/RJJ+NcrzFBPV5p6t0bjqONRxdq8LwXA5nimlUq3ZbRqjhu0BCKh5
++jvfjs0R9qD2cAv3QXjk6eh2YEx+wuDbc50SSL1Y826sLD06V4KThrQwfaLHE7r1
+mjx5N5Jg5rPFdTGe4umThyGlGPo=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-128.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-128.der
new file mode 100644
index 0000000000..a2e71ed488
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-128.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem
new file mode 100644
index 0000000000..91c71a3df0
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGaMBwGCiqGSIb3DQEMAQEwDgQIvutMegO9IYICAggABHoRfn/sZK/NRxF7jwF2
++/0zh3Y/8cCm4xeGaCP7NOcJoJXOisXXxT05tgQEa5mfymOFK1PYjnHHVVLGs6CQ
+TDPI2kb6XteXjkzR8Q0WQUtLSgAQ9/uEMmr43jAabaw+qnIcJrjaTt3rlbezZioR
+Q3xbb38W5QBFcUIpCg==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-40.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-40.der
new file mode 100644
index 0000000000..cf6373b642
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-40.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem
new file mode 100644
index 0000000000..cc5ec63996
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem
@@ -0,0 +1,6 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIGaMBwGCiqGSIb3DQEMAQIwDgQIGgo8eWJg23YCAggABHp/EXYSQmp35zzgLl8l
+paNqOjR3Ku19rhrN9QiW1dagTztFuqzezlZC7WjbycWz9qRZeQFLLAEi/DIipIAf
+sLsnbtfBypqcUCoO2AysmI31hPSaXSsHDH4cJ5LH+1DK6KVeQoVGJw/xTvrmaBD8
+lD9zOO313VgMIGe7wg==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA1.der
new file mode 100644
index 0000000000..be137430e6
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA1.pem
new file mode 100644
index 0000000000..b52d270e42
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA1.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHNMEgGCSqGSIb3DQEFDTA7MB4GCSqGSIb3DQEFDDARBAjwbKdmEddIYQICCAAC
+ARAwGQYIKoZIhvcNAwIwDQIBOgQIvopesgNCATUEgYDQ7uOTZ+cUnxDAVh3z845L
+QyZ2KkSbna0NmiKZGy9e1kh5iAQ1RhZ2iKaTTyGlpCi4i2mlZo3gvJbEHp+Do2vc
+nq9g57AP6dU9+1LsLsTeVFbdJ7OymlcwUoSfF723g9IGlQa0D5K4RTR3y34lHMNC
+NmrOwaAH4DPKDyC5EWYV0Q==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA256.der
new file mode 100644
index 0000000000..fecff8a2bd
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA256.pem
new file mode 100644
index 0000000000..67931bbbac
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8-rc2-hmacWithSHA256.pem
@@ -0,0 +1,7 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIHbMFYGCSqGSIb3DQEFDTBJMCwGCSqGSIb3DQEFDDAfBAhdjCzod22WFQICCAAC
+ARAwDAYIKoZIhvcNAgkFADAZBggqhkiG9w0DAjANAgE6BAj2j6TpIIho6QSBgK4/
+Kgspc57C+rWNbf3c0+o/bJ7ga3tTfq0iw8TYqZ8jV9+FZGjS4NVvh9EK8+L6f2w1
+NuyiGbKfsq7Lf1O1dlHNu2TagxYAWbJUwzoy0uUkfpRnfe5M/dl/l5Gx0cR4y9SH
+yKOhuX3YxUvOtkwxEb6iyNg8vaq0yRG/1F5O2jI3
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8.der b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8.der
new file mode 100644
index 0000000000..c8e51cc01b
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8.pem b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8.pem
new file mode 100644
index 0000000000..741f007304
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/ec-pri-224-secp224r1-pkcs8.pem
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MHgCAQAwEAYHKoZIzj0CAQYFK4EEACEEYTBfAgEBBBxr31AB6pNVnFUfX9rNKpZc
+Ps+RbUj5PYdpHLtIoTwDOgAEg7Qj4reRDs3ot/r/rp2orzU/g07BIYsZCsLLrf8j
+8wq50FHUIdwDRZEfpfGBPBXGgd/9DS9T7hU=
+-----END PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/genkeys.sh b/tests/auto/network/ssl/qsslkey/keys/genkeys.sh
index 7fb15e91ee..6210b42ab4 100755
--- a/tests/auto/network/ssl/qsslkey/keys/genkeys.sh
+++ b/tests/auto/network/ssl/qsslkey/keys/genkeys.sh
@@ -87,3 +87,58 @@ do
echo -e "\ngenerating EC public key to DER file ..."
openssl ec -in ec-pri-$size-$curve.pem -pubout -out ec-pub-$size-$curve.der -outform DER
done
+
+#--- PKCS#8 ------------------------------------------------------------------------
+# Note: We'll just grab some of the keys generated earlier and convert those
+# https://www.openssl.org/docs/manmaster/man1/pkcs8.html#PKCS-5-v1.5-and-PKCS-12-algorithms
+echo -e "\ngenerating unencrypted PKCS#8-format RSA PEM file ..."
+openssl pkcs8 -topk8 -nocrypt -in rsa-pri-512.pem -out rsa-pri-512-pkcs8.pem
+echo -e "\ngenerating unencrypted PKCS#8-format RSA DER file ..."
+openssl pkcs8 -topk8 -nocrypt -in rsa-pri-512.pem -outform DER -out rsa-pri-512-pkcs8.der
+
+echo -e "\ngenerating unencrypted PKCS#8-format DSA PEM file ..."
+openssl pkcs8 -topk8 -nocrypt -in dsa-pri-512.pem -out dsa-pri-512-pkcs8.pem
+echo -e "\ngenerating unencrypted PKCS#8-format DSA DER file ..."
+openssl pkcs8 -topk8 -nocrypt -in dsa-pri-512.pem -outform DER -out dsa-pri-512-pkcs8.der
+
+echo -e "\ngenerating unencrypted PKCS#8-format EC PEM file ..."
+openssl pkcs8 -topk8 -nocrypt -in ec-pri-224-secp224r1.pem -out ec-pri-224-secp224r1-pkcs8.pem
+echo -e "\ngenerating unencrypted PKCS#8-format EC DER file ..."
+openssl pkcs8 -topk8 -nocrypt -in ec-pri-224-secp224r1.pem -outform DER -out ec-pri-224-secp224r1-pkcs8.der
+
+for pkey in rsa-pri-512 dsa-pri-512 ec-pri-224-secp224r1
+do
+ pkeystem=`echo "$pkey" | cut -d- -f 1`
+ # List: https://www.openssl.org/docs/manmaster/man1/pkcs8.html#PKCS-5-v1.5-and-PKCS-12-algorithms
+ # These are technically supported, but fail to generate. Probably because MD2 is deprecated/removed
+ # PBE-MD2-DES PBE-MD2-RC2-64
+ for algorithm in PBE-MD5-DES PBE-SHA1-RC2-64 PBE-MD5-RC2-64 PBE-SHA1-DES
+ do
+ echo -e "\ngenerating encrypted PKCS#8-format (v1) PEM-encoded $pkeystem key using $algorithm ..."
+ openssl pkcs8 -topk8 -in $pkey.pem -v1 $algorithm -out $pkey-pkcs8-$algorithm.pem -passout pass:1234
+
+ echo -e "\ngenerating encrypted PKCS#8-format (v1) DER-encoded $pkeystem key using $algorithm ..."
+ openssl pkcs8 -topk8 -in $pkey.pem -v1 $algorithm -outform DER -out $pkey-pkcs8-$algorithm.der -passout pass:1234
+ done
+
+ for algorithm in PBE-SHA1-RC4-128 PBE-SHA1-RC4-40 PBE-SHA1-3DES PBE-SHA1-2DES PBE-SHA1-RC2-128 PBE-SHA1-RC2-40
+ do
+ echo -e "\ngenerating encrypted PKCS#8-format (v1 PKCS#12) PEM-encoded $pkeystem key using $algorithm ..."
+ openssl pkcs8 -topk8 -in $pkey.pem -v1 $algorithm -out $pkey-pkcs8-pkcs12-$algorithm.pem -passout pass:1234
+
+ echo -e "\ngenerating encrypted PKCS#8-format (v1 PKCS#12) DER-encoded $pkeystem key using $algorithm ..."
+ openssl pkcs8 -topk8 -in $pkey.pem -v1 $algorithm -outform DER -out $pkey-pkcs8-pkcs12-$algorithm.der -passout pass:1234
+ done
+
+ for algorithm in des3 aes128 aes256 rc2
+ do
+ for prf in hmacWithSHA1 hmacWithSHA256
+ do
+ echo -e "\ngenerating encrypted PKCS#8-format (v2) PEM-encoded $pkeystem key using $algorithm and $prf ..."
+ openssl pkcs8 -topk8 -in $pkey.pem -v2 $algorithm -v2prf $prf -out $pkey-pkcs8-$algorithm-$prf.pem -passout pass:1234
+
+ echo -e "\ngenerating encrypted PKCS#8-format (v2) DER-encoded $pkeystem key using $algorithm and $prf ..."
+ openssl pkcs8 -topk8 -in $pkey.pem -v2 $algorithm -v2prf $prf -outform DER -out $pkey-pkcs8-$algorithm-$prf.der -passout pass:1234
+ done
+ done
+done
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-DES.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-DES.der
new file mode 100644
index 0000000000..293001c629
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-DES.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-DES.pem
new file mode 100644
index 0000000000..e9aa918a11
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-DES.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBgTAbBgkqhkiG9w0BBQMwDgQIbdPEAuKuoSgCAggABIIBYAo3BSb8H60g9eyM
+2QajPdxRT5RJBQeSmlYCG4NEhiXYCXkGx2btS20w7yeX2ESqKPTSTMTB6XY1o44x
+DLnDF2FEjvrk89ADZraMaOKnUxcZiawXOi9chNf+S6PclRC+ZRMRfbCxTnqb6y8q
+42aD4oMmHv48f+/27/kFVwj4o/5ls6Hfwc6/YpXZXfT/8hIrkVaPd8QErhY+pAau
+H/ObrYXu7Hm1deBLdZD1+u19yFv/uGRg7E7S7/Ku2GSe0i9DpYlYpsz1lydubAp1
+RfxAARfMjEoo0gwUfGCvP6drh16fnLcu9GnxuPKacUTCRd3Pk6hm59TXdcLtXB+W
+tzQ/TpPY4u0oL2NU/aF9jqZuDWW89TAjvwekYpqrtq5cbU4VHpFLLc2yO1n4flRm
+pfHP4BXjW8D9frPMyLiOSJAdKoJnHfM4y9bG8SHbukmTaJCOUD2MJ5uXW8pVejxU
+gnYbceU=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-RC2-64.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-RC2-64.der
new file mode 100644
index 0000000000..3bb492bc5e
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-RC2-64.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-RC2-64.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-RC2-64.pem
new file mode 100644
index 0000000000..08115431df
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-MD5-RC2-64.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBgTAbBgkqhkiG9w0BBQYwDgQIHQKYle7B6TECAggABIIBYP7M3ZLd+cmLd7HG
+avwLJdK7dq1hUxdpDMYIIHXQMqR7yhrr271v6Sqlkq8i97CrdlmzWgWNiv8uok88
+z9CxT79Y6/sLcvKVfCkoI7Z/p86Pc2/P7otvhoc9GlRNIvU8r/nMtigf3FZDQWrp
+3XmBSabIERSQZxNwVjmSQzAVFd+SgfcqrNpKD0kErrphcySF7M4SfyTm3/dfFbrO
+gUdg0ULs0rbKbTpYyBgVhrdCXYFAQLajHlE6UVIAK21Ifq2EvJ3LQDUEXg6RADbf
+s2easyTlKfssoRzTDkBo60J2OsgmS5ls7fxOBndjxMZYPJI55k/ct4FPJraXPIsj
+j5iBIOJBdW7Fi42O/ezaLtSFC/TUwZf+rgsVQaqpz67ynp3V7K/wJqdR0P3WmO3T
+XkL3quUX+GFtm1htiqT9EGX6c1UZFfqmTJ3juLP4YpgOgUVLSIrOPauk2txH9E/R
+JATHbjg=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-DES.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-DES.der
new file mode 100644
index 0000000000..82e2f79cd8
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-DES.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-DES.pem
new file mode 100644
index 0000000000..82b997804a
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-DES.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBgTAbBgkqhkiG9w0BBQowDgQIQPSp44KDjkUCAggABIIBYLdDgiRyUnAkUhLW
+pqaNMqrK0iaSKpwHvsw1S4PhOQdFclVUEZKs+2oBedtrr3VysWRg/ZKNBdBAnzLi
+E3nw7RubL4WH2y3QNx6eLsMJsI1thF9pK0yWWfy+zQP3+oZVG+JTmctCLQDAToCa
+1OoRGnaHrZxcGzg/B1yI2hRSDdcuFCelMTIG4fGJ3dyrQHR/Gyxr4m27kV25H4t2
+Vxc6DSb1qWmSgauvUKLMlnvqtFVJ/OxjTz3BWPKUJqOyDd80PdfX8t5ttdK9Ebca
+DwIUHvAmblES9mknhUwJUym/JGQFd3GXPc7WNyTsqwV4x9xp/8WTmJvM8qPk8fNz
+x5kj3+VZgcAIh0ePKdF0TBAaAz5nKg611UwIOI/ShdMeyc1B3iWA71Y+uPElPEf+
+6+Zp8DwJNaOZ1SEqfNyB6aNMuYlTmbwctEKjokaIvyakSI6nFs63ycq5/s+HrMHT
+KHF9A4Q=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-RC2-64.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-RC2-64.der
new file mode 100644
index 0000000000..ea6b0d6134
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-RC2-64.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-RC2-64.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-RC2-64.pem
new file mode 100644
index 0000000000..14edbd1f09
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-PBE-SHA1-RC2-64.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBgTAbBgkqhkiG9w0BBQswDgQI+m9oVxROlkYCAggABIIBYBRYVJdSaW3fR2zh
+t/s5PFJ+9ebZUxhSRoc7lxk5LU76xJIH6EUa5k2sPH2WnWfu/V0Hi6t7FC0wkPLZ
+QUNcr8VPESfjDkzqmU9H+37mfrUG63P5hGgyoWzMEaok2uFfjt1e1XVfVLe8P1Z+
+zxy4+BNoLzWQ/Wb/gTwVVc0kkttmjUiRIqSQLCEh8ntWF2ws0JS+ihiR9NUdPdEe
+niQWskeAxWvO758m6kfTQeRY7WnVWPaqoosH1+uC8UZ2TmuWqTxJlHTvqEJzjPTK
+n7EzwIFHhZVJ+p+IT/6SvwL5i1h0dtlNwOfTlcU6W//U76cYmwwtrzjwVsKJNbBw
+vuPboJ2asZSzXa8887zI8O3+5ClkTCvJpk46QJHuNTQhJc1/R7aXgWbpiGu8CBCo
+PNB1OEbs+lTU8DYp8cIxdc/aTKnSxPm4d73jCaOEJ1Sj4tA97rPQVEFu0w/HLtP+
+6MxHjI0=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA1.der
new file mode 100644
index 0000000000..a42fb92161
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA1.pem
new file mode 100644
index 0000000000..11b1032852
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA1.pem
@@ -0,0 +1,12 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBrzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQINZqXAZw29eMCAggA
+MB0GCWCGSAFlAwQBAgQQMN7uviOQj5Hdt8Zb9sCtrQSCAWCsMtmLiGbnaleRuRh5
+mRWDqJ0PYXNaaTwQ24WKjl8dquPPJZz0QU2hDZGtuhBL90A2lqvG9oHJmFBpMg4E
+RPHS33R04BtCTdpfCUziKcBomHbrh8ttQ/Y1UA9OgSgob3GQIDxwNS+0p0wApyWC
+InPBE4DXByp9o1lQxNZj2wkmWLfkXCT75aMxevM30lf33SOCXDPTvtHlz/YcB6Yh
+i/b31YUAEOilXaqaCu427BMPKCanshJAjX3wwOROQ+yh8R8HiSPu+x55gJlU+yCn
+9S/oNwtTMimpI21cZTUIOkIRYyKJhgvUxjlQ0CjcMOjJvDms2rRgNhD6IFZrXoks
+FRF/Z9pUH0n/m3208uckyPkilwoFNoYLec0lq1SdtBq2LOBV0hgCmR0J0Fokpo/p
+8T/rzlb48JowOfZLnLqMtC6uqccQWmiEY3691exhFf5muUYsd8uOVkeWgMTfVnua
+jwVr
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA256.der
new file mode 100644
index 0000000000..74b870d490
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA256.pem
new file mode 100644
index 0000000000..371448ae69
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes128-hmacWithSHA256.pem
@@ -0,0 +1,12 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBvTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIadJLdxsx0GsCAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBDc7IW9CVmuaaYtM4KFXpsUBIIB
+YC1qJ4WQa6f2uxeaojvzpgYHmrh4gR9gXa2cNwCNQir557amVsPqiXEiSYmqrCy/
+Y9tN5ubLxu3z5TtscC1Y9bqP8oY3bQj+AleqzmywVI7dJhwGoTaM9lD574cknKVo
+Fn5oe6a4dTTg8wxcic+zWFc5EPi3g3swu3jqmjrLaOM8gd0RlWkAFmM60F8LX9G1
+mxnNZXHcRmkpugpICwaNYhROlzVfvLQvqtlJNccGc6QvYq/zY0nX6R3ISkbW/Bzn
+kadVaA4hNrao9RA9TT61v4H95+BGF6CLDTyU1z3jtaEvm4ihygeA5mS/pjBd7lAi
+V9YCNazgfMlgNv1ynwU67e8to89SFvzrv2sjUEDEAx1cN6zLGl42dz7ZDk1ytmsO
+grVc9vON+HhwrVIZiu8bMjj4lSD6E1XqsffpNzEhOAy2INp9ArvakCVP4mE06dv4
+4LHAAqaYj8jIHSBDPYw3F7w=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA1.der
new file mode 100644
index 0000000000..112aca5d9f
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA1.pem
new file mode 100644
index 0000000000..74aa2eb50a
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA1.pem
@@ -0,0 +1,12 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBrzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQILWdaWkH3cTMCAggA
+MB0GCWCGSAFlAwQBKgQQSj7y41B6JDjCn6mV9g3/EgSCAWBipZOOZk5C6IuwElK6
+1aGy8r4cmh6hbJ+IJIj5pNphE3IeLXfBQAUzJCD2wKKzgkL4bofdZYndIGqdBU/1
+0P27kCYKDIN0iixPr+gW6N0yEmD+R0v8fUFyQF+RiiZ0lCznAmKhc5d8C5r4zE5y
+QN4E6RTAoiaTGM85jEpb2qP0Ju/2lhFJ85z0Dn2xXtH/y4O2UYQklufYpPxDX9xQ
+DdgDPgdBXj7nH2a165CqFhA5b9PXCVjzSG8+u/PlWkO0UOCobL7YTlg0z88iAkWx
+VWX6DG7UJovp8boqJ6CL8AeroSKDsNRzO5inROWeanj8t00vsSadXUtKTlFRBSaM
+1Gzn81X5EZnhPzCkrmOmmK8+DZwgncRhLk6voFBfga9lSt9PZaDNEeNrVLixQvbc
+fc5nAIp4SwkFbo/n11YRjHyBZsYqm1ugQIaEW0jGsQxGxKAzeN342emBm0KHBqr6
+liGH
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA256.der
new file mode 100644
index 0000000000..45ebba1975
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA256.pem
new file mode 100644
index 0000000000..ecf4acf311
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-aes256-hmacWithSHA256.pem
@@ -0,0 +1,12 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBvTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQINZe2ZZmkA6ECAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBrqs2JUotuTr374kCzYAyoBIIB
+YDqyE1zTjItA+UhQ2jZ53NnaTCWTccqSVtb11jizZCOSvVEN0vayyr2OoQKsOw1y
+Uane3niV4MX8H98u5Vz+ijHuebBTiSbtSAlEqeeWTtzNfsQa4PN633n4ov1Ybn2+
+ZiW2n5d3cbC+bqPGs5cjTA6GPxLsojx6ZZEQBAyiUZ8Ikn2UsLxBV7RMiS1MK+wg
+1cvtOzDuA1SbAtLbv4GOFTYrZZrzrmtIJvxD9C0Nlsa4ci9PkVclE/tzTQxqHOq6
+DLC7LErqrWfZI3KNlw4c33CV3VaXiB1dFHcTohlYhYbrJZPz6wiKN5c1IxxD0fj8
+2BseKG3iV3jrp0yt9zSgquJL3OOAHk1rG4zvjQySJ29SVEH0TyvsLSPiV87U5u64
+rpHC8yRNz3ut//ZVPQKnz/dftFw5b80vXT2UT0BZQTzj4HHDkIBKDc8USteag91O
+SBmhwK5Vuuph6o8ILY3YoUA=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA1.der
new file mode 100644
index 0000000000..4f07e0cb50
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA1.pem
new file mode 100644
index 0000000000..8040f68152
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA1.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIjA3V6epUyL4CAggA
+MBQGCCqGSIb3DQMHBAin4GYIwaJohQSCAWC1BTA4MHvRL83mHd6lFsC/UgvGf5/4
+csPetxLj+foMBL9A6rspxB07WxB929Ayxy5rRWq4jeYhPCAg46PL+Ne5MYp9PnDm
+OjYIJjLNPk8wDuDYMDyMYH8+U4o+WaSz612YpcHIM5GEJ2TD0ngx6LctBNRtyWsR
+9Ehn2/NLxrBI0MS93gUxFA/8XkYsQp569kITAfomEjvlsJaNVI+h98cNYdD8Oi0d
+tveEPLh3xHYhNCRYpx34a/RaoAAP7KTGXXR6rjVjPWnNzG9sICBvLOve8Ro/c1cs
+EFynJ56Xd2UJCS/yMnIhlRehVl9IhN5XJ+7Dv0JKHx2BG6N+ME7YZMM9jDZb0WzH
+2+YJqPx99ERnDsRTIdQYgShWsTbMHTdz7MNzox/Zz6l4p7kipQOZLrknoNMb2hy8
+xh1f4SPT9kHwCV/obKSYzv7bGCYjBraetyBavIwl5LjlUySKQ+HC4zFS
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA256.der
new file mode 100644
index 0000000000..764d2f68ca
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA256.pem
new file mode 100644
index 0000000000..4327d31f43
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-des3-hmacWithSHA256.pem
@@ -0,0 +1,12 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBtDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIFcxat+WIQSYCAggA
+MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECHOnq5nGmYd0BIIBYNxOhizI4irA
+fq63+fV0k/C2HYCN7TEexoU+PiJlIm2/vlusPrTl6LnJqXTA6Y+iVelTWynnkKws
+c13oHCPMTx702JwzNntsLlQo+w8cShjc02SdbJrPUxE/RCtqWo85sEZTYteGk/Lr
+8GnPR3iDhB+m456PgdatqdpEsmy5EGcL3UT0kWmM5knVZfqHkx03kNxtMLV4rkcO
+SPsnezcI2MjyfC4DhXGBBaso48RYZ/905INvmLIRbBX1MHeYtRDpKQlyGQZiSyew
+TqyougDnYqSUs8yKhSsdHqUwltnZmIuJXEtcvtiA/Wmpt4fxxiPtJ8XYWyHreEMf
+w1CevyEbkUdOWsa7zsW10337Lr8DY4Ax/tOTqtARioOBSYdRwlhluBuh91bK5eBt
+ABidgQolNZ3SqIaBV+sEOX+gBDtpu/Lg4jAUO4eokKbhOlKL5YwueiSVrj/cWuKe
+6Js/MZGBcX0=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.der
new file mode 100644
index 0000000000..c89a60b8ef
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.pem
new file mode 100644
index 0000000000..46a31fa316
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-2DES.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBgjAcBgoqhkiG9w0BDAEEMA4ECEOdj9GT2jg/AgIIAASCAWARTCBBDzPLkY0e
+Y60arOJ+bkKuaJJ/OX0IGH3znnFQ5ZmtoToZtoNOaNXG0rAc3PVmkGOW6Uh5nIp8
+D5DrESPzbxltyONQb1TGW5InZKGpO/Vajqy6gDQ/QMR3eXDJsnvSvQ/eCEwqNHXA
+64V1A7Nw0Wfcv6M9qnFMB1LJmcC6Jpt3GTJeoqq+OlsUWqlUWfgIAdOng0ouvVJ0
+u04hGbOJyd5Ejov3PxWc7uXT1X4kcqUNiWFYwvjGocDByzFrW9tmoxyU3ESULdP2
+Fx910xvZnalZBFHQFIOufim/eHKdpND/c4YohgaTULsDwH4EAuZGyqB5kfP0lt8R
+gx3I3jpHiRZXTdzZW7LWIXqGYF+2AaQMTU7qNiNrgWCQ7k8h9YzM1Upzk6YLYsZ9
+UhlbbzkSbJOhlU/1Rce2q0Y7Fsi3bbJqZZ9o0xBK2aP3ApBau9/+ErNtAmuB6EXh
+aKIfeqqn
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.der
new file mode 100644
index 0000000000..cf1811f406
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.pem
new file mode 100644
index 0000000000..492b530b00
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-3DES.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBgjAcBgoqhkiG9w0BDAEDMA4ECEil5BSrj6LeAgIIAASCAWC/kwcthGmbTuVE
+ebfLDlGvn4tnSHzINEquDg3nz555OHreT0DDj0OWtsUY9IqVv/OrukJUXfQnj+jk
+j1TfMi0/MHRRbjmSHf3wGl8LUBtYzn0tmhfvoBtlCt7v3+VQo6QY/hXWbQmOopmx
+vNb8OfRWj0uLjGxeJpaOqsj0gZjbXUQcSXwaZyAG74qNCQMHs6Y/h93Xu9dVhe5h
+B+PtPgT4kFAHV72wiWkxZlyDkonAlhX4wpoEuzYFl+Mc+IZ0ss/bvhswVjjBYx5d
+v1fpOQcVPvjOFPdlm67WYfPyXWgIwP69JSwi7ywyg8GABPfgsNL4Kz9VhH/tanZL
+ZCFnZvHUAX12x39F6RAWxSw8r22jDtsDQQ9sO39PleIhtvfndquEQVx9rswrqKXD
+PxYTOiZ5fEoCxQb1/p9SBMC3rvVotMyuHueLyRYdxwYQOqagRwikJuYLYUK9ibMU
+bBDHp4Mc
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.der
new file mode 100644
index 0000000000..0cb3d5c28e
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem
new file mode 100644
index 0000000000..e74b99eb29
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-128.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBgjAcBgoqhkiG9w0BDAEFMA4ECC8vkmUmfY3WAgIIAASCAWDzODlrgQ+L8c/5
+YMHk8uVGYRK2cmFRVUIgHz8pnxx7BPnR3mb2igUVk55fi74bIgmk+KGnoRhG2jsq
+dXV2rfTHGZ/AdjwgwA1yLNinhy0BUObMQ4QOrtkNpq4K2MUK8fcvLNRvEhMni0dx
+r41Q4C+bnnx70td2iT7/0efgs4YfT2uxQq//MvI5vfyvCSx71GY6xJdc1wwGbqT7
+KoY5ARvL78Tb1wi6UmdsJza+DU1yO5z1TPAu+a0bawT4LWWAOj2+x/cglsq/La0g
+lJ797NBFWI0Uq5YCMBGzwv3RY2fHtVbt/TSav2Q4oIuaoxLkYRZ2HwUDseMJ4O5A
+46QZqHZyKSQX25pm/gq7kr6bbX/JrGVoWD5ynlaUiVBxyoKHaHRojlbyQTASxjMb
+XZG7jUDpcM4JQ1LKtrNmU72YYGyfrNZhr1TFmSw5ayVfw8vgO4U3Y+JeHXKZOqW/
+QTisuu3L
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.der
new file mode 100644
index 0000000000..404b593068
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem
new file mode 100644
index 0000000000..ddd0106a71
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC2-40.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBgjAcBgoqhkiG9w0BDAEGMA4ECAicFoXG2QPWAgIIAASCAWB0Uk5k6u0IoN6G
+CB6y4EpIc8lgEGIxO0iAMGYdQd/b/yYVSH5yWBJTM/WJCtIx0GPSYQUjnFh9IQOr
+AAimL90mlzCfdYHAJ7kS2rNCTWJeqXwPeOJmFpmI8oySUE6uflu16ZHXLuZoDIrZ
+O8JZnKF7KlQLIgFn5qiqRuuQrDKiildLChXtsU8nW1B+xBy89qkqWekw7nyN4J68
+3wsm7gzrT7PUNFl9XnWFw+FmSZag8sdqgvDZ0RiFdMAYeFWfTx70KY3PnSYOzoSw
+kYVgviMhcLFxulMsvIsVPaG4cr9JX/eNZfVFH8jnkm3Nqtdl647oO3LfwkXPKz/W
+1JNyd3/p2IOPnkMi8KMFvuhce3zoD77wZJ85PhbsW4YEsB+hxfk8N5ILJysrMf7J
+4BDxc4yYmV4mWna6aUiWnn4gD5ux1qxTUUGWf3tgnyHRGYS0d0xQUQzbCffeW7vj
+PDGpGqbl
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.der
new file mode 100644
index 0000000000..4d13899e1b
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem
new file mode 100644
index 0000000000..a9939f278c
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-128.pem
@@ -0,0 +1,10 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBfDAcBgoqhkiG9w0BDAEBMA4ECJJ4g6/+vh0mAgIIAASCAVo/PESsuYWux3ET
+RNX7Hk3fhm/ZFx5/lvpTFqRy1hMpA6i9liFeLpI13FHarasc92chFLhj+s5JZ+Qg
+WMlDz1nQf4c79dTxVpXGjf4pByXpqr+ksyb0Wo1/NayhjurqrVDpQf0kOdlCNKqn
+8IW2CB5zftsOn8PVkPF3/riUih4xYwvW2w+8rs8RRN0vX9PUsYjtqmq0KnpiWzut
+Tt/D0WJhJTlWVb5dp3nYXEZPM3IOHzvmqBDgbv66JgofpiKn7YXmDUx+edNuWwX2
++GTih5yaRp2IqGbVYT/3eeiyJCpeNLlHJdUDui7zWkiTKpL+RU5VsV4DSjVT7SGV
+tpMQM6HnaCDEr+y4GxUB3/2w8Ua9vZwJ/DRa0vS+N6N+gZfrD78j511h1JOl5EbD
+35P6xNWZBeQbO6pJMKGq5qj/IBgbOQp9xpRtmdTezcY/lys27qN+35vhJSTQy7XG
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.der
new file mode 100644
index 0000000000..cec667ea89
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem
new file mode 100644
index 0000000000..22667c1d9c
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-pkcs12-PBE-SHA1-RC4-40.pem
@@ -0,0 +1,10 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBfDAcBgoqhkiG9w0BDAECMA4ECE5xFtUDnxEJAgIIAASCAVri1/I0SyDAH3Zf
+N4WTxaXJj94JqNOrHC07kckm23evvqGtINC141iSUuPz+zInB0wd0IyDZj+v8ExB
+eFwKOblHhr7ZRCR0zN9IT0CHxjIVmU5W50lpJWTXcALgH+SW97K6jCjVdfAwSEkW
+8X5/iiuhbNXu/8BTy+CBfsiVl8R4CMGhAxD922JoiQqSFA1HzrcxZiIUJ+etN6BF
+YmiF5sCEhiMYMd7FbTDZ3u20dnNPu5Fn+L31aioZ+jtSyRNglVwWYZrdqGyZLlFO
+QAx3AlQdiiqOPJ5rwnezTWdjac9luxhhIFFFq14b02QPu7SeYG56MvruWkwM3raf
+73qbwtNE19yZ9DiWVXaeXpI84tL38E8sIQ1vthVuHtJ+6U1HUgPafVYZn+eKqiPz
+UrJYbJTPL27GS2zXJnr9OrwRlGpKHQGjHo6hyg0UmZ71xuurVuHPty00Oap1CV13
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA1.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA1.der
new file mode 100644
index 0000000000..3860600474
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA1.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA1.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA1.pem
new file mode 100644
index 0000000000..61de0e9893
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA1.pem
@@ -0,0 +1,11 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBpjBIBgkqhkiG9w0BBQ0wOzAeBgkqhkiG9w0BBQwwEQQIQYOeTgwR/LsCAggA
+AgEQMBkGCCqGSIb3DQMCMA0CAToECMd9tvoaH7I8BIIBWNGNJ3RipB+HrN0t6rsA
+C3iOTcc4LEo03gguQ4Uxf0KyDMt7fyLpo/77m0QXLVBMW7mDjDASsaFWDzqM1OxZ
+3kmV2+thdyLfnnA2l6tCDdImKWrNBYK2ogmpkJy15piwFZ/XUBrm63zP/NYCyRsF
+jXOzy0FGv/xxaw9RAiGJMsvdoopHr2Lo37DeeBoXCR6gzfvyyuqzr5fbrV7agk5i
+pGMAbJNKtbbCrzXOKCBDTGDUFiOtxNoDEsJy2Tx6YqotNJedyMzhZAatcL5h0a9w
+r4jRLSWmHqo9WTFgcibhcXuy6cko3/wGov0Z2Pq1bPga8tWeuta74IaGLCuVWwHE
+ze2nii7RWIU1oQ9ZgD6CuZnggyRT8b3/TYTQ6pra+yp99lvH48MySVJU5QEdpoOq
+tUU+7z0BdEl5SALfBlQhBCEP13KhPitKcppVphxMv1cAidIHBne1YGKo
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA256.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA256.der
new file mode 100644
index 0000000000..f4ca23ba74
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA256.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA256.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA256.pem
new file mode 100644
index 0000000000..c09da71121
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8-rc2-hmacWithSHA256.pem
@@ -0,0 +1,12 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBtDBWBgkqhkiG9w0BBQ0wSTAsBgkqhkiG9w0BBQwwHwQIi1jllb1PqZcCAggA
+AgEQMAwGCCqGSIb3DQIJBQAwGQYIKoZIhvcNAwIwDQIBOgQIQDijmMtzY+UEggFY
+gItLu4+5cGLUWeqbt9L7tKBoLpMSYGScvjcPwiKX1tygqg1lD9saeOqSZFx3AEyd
+3AlEpZSPaQpAqp61zrKV1cSYzafRyYV2R6NArgWpSZP3LggquoQHnZN/8hRtbidC
+7KgB/kXP7sCWKiUj4Smh/HhkS/w0K5doxt34VicijP4q29NZ0UDQDGABC1gA7L5l
+FvZrZJi6laawHJbZDb6zaHVbvL2OMclXrzLpHF269H/NYwE+3/xtUa8AhTYVRRq/
+oOByi++ap2QL32IyHbdgNEj7a9WGM58iWVW+jS9G45ChylIDG9oCg4KeHp+5sjPv
+rkDsXdzXeCwFQuJ1nj/pRVR6aI3qUMM1jjQFoOQ/XrPWIBvVzXC8eYRud/rHaOdV
+IH7B9kFFqwSAzzi9GtTNj1hfQ8adm54N+qq2c4JRKN/a6cSRAlwtoI344OO20ejv
+2RO9QGJkkSU=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8.der b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8.der
new file mode 100644
index 0000000000..b6ef9a15a2
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8.der
Binary files differ
diff --git a/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8.pem b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8.pem
new file mode 100644
index 0000000000..2a71a861bf
--- /dev/null
+++ b/tests/auto/network/ssl/qsslkey/keys/rsa-pri-512-pkcs8.pem
@@ -0,0 +1,10 @@
+-----BEGIN PRIVATE KEY-----
+MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAwDsb+Kv6gzwj4qqN
+kD5pZigHwVq+TgsAua++RsXnaWGiOWA2m2a5vM+TC9trcIAHHU2xaGjxt2UGi9b9
+mPNMoQIDAQABAkB64062Yfr7+m5WcQGevMdUbzLGAOS3r4D/M8JILCwLySrni0rV
+sti1UF1X2ypna24tsRKN0CD/a8111k+yZXeBAiEA4ats1RjWHIA9tIimdi3Qj9LO
+BtBs5wBaaryExZyQDFUCIQDaESne8AcqQ08gst1Ykyj0bKwl+ybSWxAzSb/52fFL
+HQIgKFX9s/EmhB2f6d7q8gCqYKqrTKiAbqGvh5h+mturG6kCIQDYAeRt92nBjYcW
+JtdnY+5PoE4uGUhtWtMDWuyVfDOuaQIgU9/flj81ZByBxXk5sULHUa3+eqfQKSgi
+xYZorAtL3xg=
+-----END PRIVATE KEY-----
diff --git a/tests/auto/network/ssl/qsslkey/qsslkey.pro b/tests/auto/network/ssl/qsslkey/qsslkey.pro
index 0074513878..8ed65e68ad 100644
--- a/tests/auto/network/ssl/qsslkey/qsslkey.pro
+++ b/tests/auto/network/ssl/qsslkey/qsslkey.pro
@@ -1,7 +1,6 @@
CONFIG += testcase
SOURCES += tst_qsslkey.cpp
-win32:LIBS += -lws2_32
QT = core network testlib
qtConfig(private_tests) {
QT += core-private network-private
diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
index 27d92db3bf..ddfe52c5e4 100644
--- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
+++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp
@@ -110,10 +110,10 @@ void tst_QSslKey::initTestCase()
testDataDir += QLatin1String("/");
QDir dir(testDataDir + "keys");
- QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable);
- QRegExp rx(QLatin1String("^(rsa|dsa|ec)-(pub|pri)-(\\d+)-?\\w*\\.(pem|der)$"));
- foreach (QFileInfo fileInfo, fileInfoList) {
- if (rx.indexIn(fileInfo.fileName()) >= 0)
+ const QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable);
+ QRegExp rx(QLatin1String("^(rsa|dsa|ec)-(pub|pri)-(\\d+)-?[\\w-]*\\.(pem|der)$"));
+ for (const QFileInfo &fileInfo : fileInfoList) {
+ if (rx.indexIn(fileInfo.fileName()) >= 0) {
keyInfoList << KeyInfo(
fileInfo,
rx.cap(1) == QLatin1String("rsa") ? QSsl::Rsa :
@@ -121,6 +121,7 @@ void tst_QSslKey::initTestCase()
rx.cap(2) == QLatin1String("pub") ? QSsl::PublicKey : QSsl::PrivateKey,
rx.cap(3).toInt(),
rx.cap(4) == QLatin1String("pem") ? QSsl::Pem : QSsl::Der);
+ }
}
}
@@ -163,6 +164,16 @@ void tst_QSslKey::createPlainTestRows(bool filter, QSsl::EncodingFormat format)
foreach (KeyInfo keyInfo, keyInfoList) {
if (filter && keyInfo.format != format)
continue;
+#ifdef Q_OS_WINRT
+ if (keyInfo.fileInfo.fileName().contains("RC2-64"))
+ continue; // WinRT treats RC2 as 128 bit
+#endif
+#if !defined(QT_NO_SSL) && defined(QT_NO_OPENSSL) // generic backend
+ if (keyInfo.fileInfo.fileName().contains(QRegularExpression("-aes\\d\\d\\d-")))
+ continue; // No AES support in the generic back-end
+ if (keyInfo.fileInfo.fileName().contains("pkcs8-pkcs12"))
+ continue; // The generic back-end doesn't support PKCS#12 algorithms
+#endif
QTest::newRow(keyInfo.fileInfo.fileName().toLatin1())
<< keyInfo.fileInfo.absoluteFilePath() << keyInfo.algorithm << keyInfo.type
@@ -186,7 +197,10 @@ void tst_QSslKey::constructor()
QFETCH(QSsl::EncodingFormat, format);
QByteArray encoded = readFile(absFilePath);
- QSslKey key(encoded, algorithm, format, type);
+ QByteArray passphrase;
+ if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-"))
+ passphrase = QByteArray("1234");
+ QSslKey key(encoded, algorithm, format, type, passphrase);
QVERIFY(!key.isNull());
}
@@ -215,9 +229,12 @@ void tst_QSslKey::constructorHandle()
? q_PEM_read_bio_PUBKEY
: q_PEM_read_bio_PrivateKey);
+ QByteArray passphrase;
+ if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-"))
+ passphrase = "1234";
BIO* bio = q_BIO_new(q_BIO_s_mem());
q_BIO_write(bio, pem.constData(), pem.length());
- QSslKey key(func(bio, nullptr, nullptr, nullptr), type);
+ QSslKey key(func(bio, nullptr, nullptr, static_cast<void *>(passphrase.data())), type);
q_BIO_free(bio);
QVERIFY(!key.isNull());
@@ -245,7 +262,10 @@ void tst_QSslKey::copyAndAssign()
QFETCH(QSsl::EncodingFormat, format);
QByteArray encoded = readFile(absFilePath);
- QSslKey key(encoded, algorithm, format, type);
+ QByteArray passphrase;
+ if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-"))
+ passphrase = QByteArray("1234");
+ QSslKey key(encoded, algorithm, format, type, passphrase);
QSslKey copied(key);
QCOMPARE(key, copied);
@@ -286,7 +306,10 @@ void tst_QSslKey::length()
QFETCH(QSsl::EncodingFormat, format);
QByteArray encoded = readFile(absFilePath);
- QSslKey key(encoded, algorithm, format, type);
+ QByteArray passphrase;
+ if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-"))
+ passphrase = QByteArray("1234");
+ QSslKey key(encoded, algorithm, format, type, passphrase);
QVERIFY(!key.isNull());
QCOMPARE(key.length(), length);
}
@@ -306,6 +329,17 @@ void tst_QSslKey::toPemOrDer()
QFETCH(QSsl::KeyType, type);
QFETCH(QSsl::EncodingFormat, format);
+ QByteArray dataTag = QByteArray(QTest::currentDataTag());
+ if (dataTag.contains("-pkcs8-")) // these are encrypted
+ QSKIP("Encrypted PKCS#8 keys gets decrypted when loaded. So we can't compare it to the encrypted version.");
+#ifndef QT_NO_OPENSSL
+ if (dataTag.contains("pkcs8"))
+ QSKIP("OpenSSL converts PKCS#8 keys to other formats, invalidating comparisons.");
+#else // !openssl
+ if (dataTag.contains("pkcs8") && dataTag.contains("rsa"))
+ QSKIP("PKCS#8 RSA keys are changed into a different format in the generic back-end, meaning the comparison fails.");
+#endif // openssl
+
QByteArray encoded = readFile(absFilePath);
QSslKey key(encoded, algorithm, format, type);
QVERIFY(!key.isNull());
@@ -326,6 +360,8 @@ void tst_QSslKey::toEncryptedPemOrDer_data()
passwords << " " << "foobar" << "foo bar"
<< "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?"; // ### add more (?)
foreach (KeyInfo keyInfo, keyInfoList) {
+ if (keyInfo.fileInfo.fileName().contains("pkcs8"))
+ continue; // pkcs8 keys are encrypted in a different way than the other keys
foreach (QString password, passwords) {
const QByteArray testName = keyInfo.fileInfo.fileName().toLatin1()
+ '-' + (keyInfo.algorithm == QSsl::Rsa ? "RSA" :
diff --git a/tests/auto/network/ssl/qsslsocket/qsslsocket.pro b/tests/auto/network/ssl/qsslsocket/qsslsocket.pro
index f45857b02d..1260dc9410 100644
--- a/tests/auto/network/ssl/qsslsocket/qsslsocket.pro
+++ b/tests/auto/network/ssl/qsslsocket/qsslsocket.pro
@@ -1,7 +1,6 @@
CONFIG += testcase
SOURCES += tst_qsslsocket.cpp
-win32:LIBS += -lws2_32
QT = core core-private network-private testlib
TARGET = tst_qsslsocket
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index e32fa7c724..b759aed074 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -202,6 +202,9 @@ private slots:
void verifyDepth();
void disconnectFromHostWhenConnecting();
void disconnectFromHostWhenConnected();
+#ifndef QT_NO_OPENSSL
+ void closeWhileEmittingSocketError();
+#endif
void resetProxy();
void ignoreSslErrorsList_data();
void ignoreSslErrorsList();
@@ -2336,6 +2339,66 @@ void tst_QSslSocket::disconnectFromHostWhenConnected()
QCOMPARE(socket->bytesToWrite(), qint64(0));
}
+#ifndef QT_NO_OPENSSL
+
+class BrokenPskHandshake : public QTcpServer
+{
+public:
+ void socketError(QAbstractSocket::SocketError error)
+ {
+ Q_UNUSED(error);
+ QSslSocket *clientSocket = qobject_cast<QSslSocket *>(sender());
+ Q_ASSERT(clientSocket);
+ clientSocket->close();
+ QTestEventLoop::instance().exitLoop();
+ }
+private:
+
+ void incomingConnection(qintptr handle) override
+ {
+ if (!socket.setSocketDescriptor(handle))
+ return;
+
+ QSslConfiguration serverConfig(QSslConfiguration::defaultConfiguration());
+ serverConfig.setPreSharedKeyIdentityHint("abcdefghijklmnop");
+ socket.setSslConfiguration(serverConfig);
+ socket.startServerEncryption();
+ }
+
+ QSslSocket socket;
+};
+
+void tst_QSslSocket::closeWhileEmittingSocketError()
+{
+ QFETCH_GLOBAL(bool, setProxy);
+ if (setProxy)
+ return;
+
+ BrokenPskHandshake handshake;
+ if (!handshake.listen())
+ QSKIP("failed to start TLS server");
+
+ QSslSocket clientSocket;
+ QSslConfiguration clientConfig(QSslConfiguration::defaultConfiguration());
+ clientConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
+ clientSocket.setSslConfiguration(clientConfig);
+
+ QSignalSpy socketErrorSpy(&clientSocket, SIGNAL(error(QAbstractSocket::SocketError)));
+ void (QSslSocket::*errorSignal)(QAbstractSocket::SocketError) = &QSslSocket::error;
+ connect(&clientSocket, errorSignal, &handshake, &BrokenPskHandshake::socketError);
+
+ clientSocket.connectToHostEncrypted(QStringLiteral("127.0.0.1"), handshake.serverPort());
+ // Make sure we have some data buffered so that close will try to flush:
+ clientSocket.write(QByteArray(1000000, Qt::Uninitialized));
+
+ QTestEventLoop::instance().enterLoopMSecs(1000);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(socketErrorSpy.count(), 1);
+}
+
+#endif // QT_NO_OPENSSL
+
void tst_QSslSocket::resetProxy()
{
#ifndef QT_NO_NETWORKPROXY
@@ -2809,13 +2872,13 @@ class SslServer4 : public QTcpServer
{
Q_OBJECT
public:
- SslServer4() : socket(0) {}
- WebSocket *socket;
+
+ QScopedPointer<WebSocket> socket;
protected:
- void incomingConnection(qintptr socketDescriptor)
+ void incomingConnection(qintptr socketDescriptor) override
{
- socket = new WebSocket(socketDescriptor);
+ socket.reset(new WebSocket(socketDescriptor));
}
};
@@ -2829,38 +2892,36 @@ void tst_QSslSocket::qtbug18498_peek()
return;
SslServer4 server;
- QSslSocket *client = new QSslSocket(this);
-
QVERIFY(server.listen(QHostAddress::LocalHost));
- client->connectToHost("127.0.0.1", server.serverPort());
- QVERIFY(client->waitForConnected(5000));
+
+ QSslSocket client;
+ client.connectToHost("127.0.0.1", server.serverPort());
+ QVERIFY(client.waitForConnected(5000));
QVERIFY(server.waitForNewConnection(1000));
- client->setObjectName("client");
- client->ignoreSslErrors();
+ client.ignoreSslErrors();
int encryptedCounter = 2;
- connect(client, &QSslSocket::encrypted, this, [&encryptedCounter, this](){
+ connect(&client, &QSslSocket::encrypted, this, [&encryptedCounter](){
if (!--encryptedCounter)
exitLoop();
});
- WebSocket *serversocket = server.socket;
- connect(serversocket, &QSslSocket::encrypted, this, [&encryptedCounter, this](){
+ WebSocket *serversocket = server.socket.data();
+ connect(serversocket, &QSslSocket::encrypted, this, [&encryptedCounter](){
if (!--encryptedCounter)
exitLoop();
});
- connect(client, SIGNAL(disconnected()), this, SLOT(exitLoop()));
+ connect(&client, SIGNAL(disconnected()), this, SLOT(exitLoop()));
- client->startClientEncryption();
+ client.startClientEncryption();
QVERIFY(serversocket);
- serversocket->setObjectName("server");
enterLoop(1);
QVERIFY(!timeout());
QVERIFY(serversocket->isEncrypted());
- QVERIFY(client->isEncrypted());
+ QVERIFY(client.isEncrypted());
QByteArray data("abc123");
- client->write(data.data());
+ client.write(data.data());
connect(serversocket, SIGNAL(readyRead()), this, SLOT(exitLoop()));
enterLoop(1);
diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro
index c862b3d3ae..05755ff606 100644
--- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro
+++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
testcase.timeout = 300 # this test is slow
SOURCES += tst_qsslsocket_onDemandCertificates_member.cpp
-win32:LIBS += -lws2_32
QT = core core-private network-private testlib
TARGET = tst_qsslsocket_onDemandCertificates_member
diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro
index c27a58fcd2..c345d7379f 100644
--- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro
+++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro
@@ -1,7 +1,6 @@
CONFIG += testcase
SOURCES += tst_qsslsocket_onDemandCertificates_static.cpp
-win32:LIBS += -lws2_32
QT = core core-private network-private testlib
TARGET = tst_qsslsocket_onDemandCertificates_static
diff --git a/tests/auto/network/ssl/ssl.pro b/tests/auto/network/ssl/ssl.pro
index 175f361071..a2d9159579 100644
--- a/tests/auto/network/ssl/ssl.pro
+++ b/tests/auto/network/ssl/ssl.pro
@@ -1,7 +1,8 @@
TEMPLATE=subdirs
-QT_FOR_CONFIG += network
+QT_FOR_CONFIG += network-private
SUBDIRS=\
+ qpassworddigestor \
qsslcertificate \
qsslcipher \
qsslellipticcurve \
@@ -13,7 +14,13 @@ qtConfig(ssl) {
SUBDIRS += \
qsslsocket \
qsslsocket_onDemandCertificates_member \
- qsslsocket_onDemandCertificates_static \
+ qsslsocket_onDemandCertificates_static
+
+ qtConfig(openssl) {
+ SUBDIRS += \
+ qdtlscookie \
+ qdtls
+ }
}
}
diff --git a/tests/auto/opengl/qgl/BLACKLIST b/tests/auto/opengl/qgl/BLACKLIST
index 71be4bf19d..1eb0197484 100644
--- a/tests/auto/opengl/qgl/BLACKLIST
+++ b/tests/auto/opengl/qgl/BLACKLIST
@@ -19,6 +19,7 @@ winrt
[graphicsViewClipping]
windows
winrt
+rhel-7.4 ci
[glFBOUseInGLWidget]
windows
winrt
diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp
index 76186f5575..09bea20d26 100644
--- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp
+++ b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp
@@ -131,6 +131,13 @@ public:
setAutoBufferSwap(false);
}
+ void resizeEvent(QResizeEvent *e)
+ {
+ m_thread->lock();
+ QGLWidget::resizeEvent(e);
+ m_thread->unlock();
+ }
+
void paintEvent(QPaintEvent *)
{
m_thread->lock();
diff --git a/tests/auto/other/gestures/BLACKLIST b/tests/auto/other/gestures/BLACKLIST
index 169117b36a..269bac5750 100644
--- a/tests/auto/other/gestures/BLACKLIST
+++ b/tests/auto/other/gestures/BLACKLIST
@@ -1,6 +1,18 @@
[]
rhel-7.4
+ubuntu-18.04
[customGesture]
# QTBUG-67254
ubuntu
opensuse
+opensuse-leap
+[graphicsItemGesture]
+ubuntu-18.04
+[graphicsItemTreeGesture]
+ubuntu-18.04
+[graphicsView]
+ubuntu-18.04
+[explicitGraphicsObjectTarget]
+ubuntu-18.04
+[autoCancelGestures2]
+ubuntu-18.04
diff --git a/tests/auto/other/lancelot/paintcommands.cpp b/tests/auto/other/lancelot/paintcommands.cpp
index 074644393d..65a688ec40 100644
--- a/tests/auto/other/lancelot/paintcommands.cpp
+++ b/tests/auto/other/lancelot/paintcommands.cpp
@@ -106,7 +106,8 @@ const char *PaintCommands::spreadMethodTable[] = {
const char *PaintCommands::coordinateMethodTable[] = {
"LogicalMode",
"StretchToDeviceMode",
- "ObjectBoundingMode"
+ "ObjectBoundingMode",
+ "ObjectMode"
};
const char *PaintCommands::sizeModeTable[] = {
@@ -176,6 +177,9 @@ const char *PaintCommands::imageFormatTable[] = {
"Format_A2RGB30_Premultiplied",
"Alpha8",
"Grayscale8",
+ "RGBx64",
+ "RGBA64",
+ "RGBA64_Premultiplied",
};
int PaintCommands::translateEnum(const char *table[], const QString &pattern, int limit)
@@ -561,6 +565,10 @@ void PaintCommands::staticInit()
"^bitmap_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$",
"bitmap_load <bitmap filename> <bitmapName>\n - note that the image is stored as a pixmap",
"bitmap_load :/images/bitmap.png myBitmap");
+ DECL_PAINTCOMMAND("pixmap_setDevicePixelRatio", command_pixmap_setDevicePixelRatio,
+ "^pixmap_setDevicePixelRatio\\s+([\\w.:\\/]*)\\s+([.0-9]*)$",
+ "pixmap_setDevicePixelRatio <pixmapName> <dpr>",
+ "pixmap_setDevicePixelRatio myPixmap 2.0");
DECL_PAINTCOMMAND("image_convertToFormat", command_image_convertToFormat,
"^image_convertToFormat\\s+([\\w.:\\/]*)\\s+([\\w.:\\/]+)\\s+([\\w0-9_]*)$",
"image_convertToFormat <sourceImageName> <destImageName> <image format enum>",
@@ -577,6 +585,10 @@ void PaintCommands::staticInit()
"^image_setColorCount\\s+([\\w.:\\/]*)\\s+([0-9]*)$",
"image_setColorCount <imageName> <nbColors>",
"image_setColorCount myImage 128");
+ DECL_PAINTCOMMAND("image_setDevicePixelRatio", command_image_setDevicePixelRatio,
+ "^image_setDevicePixelRatio\\s+([\\w.:\\/]*)\\s+([.0-9]*)$",
+ "image_setDevicePixelRatio <imageName> <dpr>",
+ "image_setDevicePixelRatio myImage 2.0");
DECL_PAINTCOMMANDSECTION("transformations");
DECL_PAINTCOMMAND("resetMatrix", command_resetMatrix,
@@ -1761,7 +1773,9 @@ void PaintCommands::command_setBrush(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
- QImage img = image_load<QImage>(caps.at(1));
+ QImage img = m_imageMap[caps.at(1)]; // try cache first
+ if (img.isNull())
+ img = image_load<QImage>(caps.at(1));
if (!img.isNull()) { // Assume image brush
if (m_verboseMode)
printf(" -(lance) setBrush(image=%s, width=%d, height=%d)\n",
@@ -2132,6 +2146,20 @@ void PaintCommands::command_bitmap_load(QRegularExpressionMatch re)
m_pixmapMap[name] = bm;
}
+void PaintCommands::command_pixmap_setDevicePixelRatio(QRegularExpressionMatch re)
+{
+ QStringList caps = re.capturedTexts();
+
+ QString name = caps.at(1);
+ double dpr = convertToDouble(caps.at(2));
+
+ if (m_verboseMode)
+ printf(" -(lance) pixmap_setDevicePixelRatio(%s), %.1f -> %.1f\n",
+ qPrintable(name), m_pixmapMap[name].devicePixelRatioF(), dpr);
+
+ m_pixmapMap[name].setDevicePixelRatio(dpr);
+}
+
/***************************************************************************************************/
void PaintCommands::command_pixmap_setMask(QRegularExpressionMatch re)
{
@@ -2197,6 +2225,21 @@ void PaintCommands::command_image_setColor(QRegularExpressionMatch re)
}
/***************************************************************************************************/
+void PaintCommands::command_image_setDevicePixelRatio(QRegularExpressionMatch re)
+{
+ QStringList caps = re.capturedTexts();
+
+ QString name = caps.at(1);
+ double dpr = convertToDouble(caps.at(2));
+
+ if (m_verboseMode)
+ printf(" -(lance) image_setDevicePixelRatio(%s), %.1f -> %.1f\n",
+ qPrintable(name), m_imageMap[name].devicePixelRatioF(), dpr);
+
+ m_imageMap[name].setDevicePixelRatio(dpr);
+}
+
+/***************************************************************************************************/
void PaintCommands::command_abort(QRegularExpressionMatch)
{
m_abort = true;
@@ -2355,7 +2398,7 @@ void PaintCommands::command_gradient_setSpread(QRegularExpressionMatch re)
void PaintCommands::command_gradient_setCoordinateMode(QRegularExpressionMatch re)
{
- int coord = translateEnum(coordinateMethodTable, re.captured(1), 3);
+ int coord = translateEnum(coordinateMethodTable, re.captured(1), 4);
if (m_verboseMode)
printf(" -(lance) gradient_setCoordinateMode %d=[%s]\n", coord,
diff --git a/tests/auto/other/lancelot/paintcommands.h b/tests/auto/other/lancelot/paintcommands.h
index e3fb96744c..83e3bbc11c 100644
--- a/tests/auto/other/lancelot/paintcommands.h
+++ b/tests/auto/other/lancelot/paintcommands.h
@@ -229,10 +229,12 @@ private:
void command_pixmap_load(QRegularExpressionMatch re);
void command_pixmap_setMask(QRegularExpressionMatch re);
void command_bitmap_load(QRegularExpressionMatch re);
+ void command_pixmap_setDevicePixelRatio(QRegularExpressionMatch re);
void command_image_convertToFormat(QRegularExpressionMatch re);
void command_image_load(QRegularExpressionMatch re);
void command_image_setColor(QRegularExpressionMatch re);
void command_image_setColorCount(QRegularExpressionMatch re);
+ void command_image_setDevicePixelRatio(QRegularExpressionMatch re);
// commands: transformation
void command_resetMatrix(QRegularExpressionMatch re);
diff --git a/tests/auto/other/lancelot/scripts/gradientxform_object.qps b/tests/auto/other/lancelot/scripts/gradientxform_object.qps
index d785a008c0..dcc718072f 100644
--- a/tests/auto/other/lancelot/scripts/gradientxform_object.qps
+++ b/tests/auto/other/lancelot/scripts/gradientxform_object.qps
@@ -62,7 +62,22 @@ repeat_block row
restore
end_block block
+save
translate 400 0
brushRotate 30.0
brushScale 1.5 .5
repeat_block block
+restore
+
+drawText 80 400 "BRUSH XFORM, OBJECT BOUNDING MODE"
+drawText 500 400 "BRUSH XFORM, OBJECT MODE"
+
+translate 0 400
+brushTranslate 0.5 0.5
+brushRotate 180.0
+brushTranslate -0.5 -0.5
+repeat_block block
+
+translate 400 0
+gradient_setCoordinateMode ObjectMode
+repeat_block block
diff --git a/tests/auto/other/lancelot/scripts/image_dpr.qps b/tests/auto/other/lancelot/scripts/image_dpr.qps
new file mode 100644
index 0000000000..7d3ca3099c
--- /dev/null
+++ b/tests/auto/other/lancelot/scripts/image_dpr.qps
@@ -0,0 +1,43 @@
+
+setRenderHint Antialiasing true
+setRenderHint SmoothPixmapTransform true
+
+image_load sign.png img1
+pixmap_load sign.png pix1
+
+begin_block drawIt
+save
+
+drawImage img1 20 20 -1 -1
+drawRect 17.5 17.5 85 85
+
+setBrush img1
+setPen NoPen
+drawRect 20 120 120 120
+
+brushRotate 45
+drawRect 20 260 120 120
+
+setBrush NoBrush
+drawTiledPixmap pix1 20 400 120 120
+
+restore
+end_block
+
+save
+translate 150 0
+rotate -5
+repeat_block drawIt
+restore
+
+image_setDevicePixelRatio img1 2.0
+pixmap_setDevicePixelRatio pix1 2.0
+translate 400 0
+repeat_block drawIt
+
+save
+translate 150 0
+rotate -5
+repeat_block drawIt
+restore
+
diff --git a/tests/auto/other/macnativeevents/macnativeevents.pro b/tests/auto/other/macnativeevents/macnativeevents.pro
index 0611377d0b..0fe5949a1d 100644
--- a/tests/auto/other/macnativeevents/macnativeevents.pro
+++ b/tests/auto/other/macnativeevents/macnativeevents.pro
@@ -8,3 +8,5 @@ SOURCES += tst_macnativeevents.cpp
requires(mac)
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
+
+LIBS += -framework AppKit
diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro
index ea2e1dabf2..61a464356c 100644
--- a/tests/auto/other/other.pro
+++ b/tests/auto/other/other.pro
@@ -7,7 +7,7 @@ SUBDIRS=\
lancelot \
languagechange \
macgui \
- macnativeevents \
+ #macnativeevents \
macplist \
networkselftest \
qaccessibility \
@@ -39,7 +39,7 @@ SUBDIRS=\
qaccessibilitylinux \
qaccessibilitymac \
-!qtHaveModule(network): SUBDIRS -= \
+winrt|!qtHaveModule(network): SUBDIRS -= \
lancelot \
networkselftest \
qnetworkaccessmanager_and_qprogressdialog \
@@ -48,7 +48,7 @@ cross_compile: SUBDIRS -= \
atwrapper \
compiler
-!qtConfig(accessibility): SUBDIRS -= qaccessibility
+winrt|!qtConfig(accessibility): SUBDIRS -= qaccessibility
!qtConfig(accessibility-atspi-bridge): SUBDIRS -= qaccessibilitylinux
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 8cf039c06a..8b24937079 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -876,6 +876,10 @@ void tst_QAccessibility::applicationTest()
QCOMPARE(interface->child(1), static_cast<QAccessibleInterface*>(0));
QCOMPARE(interface->childCount(), 0);
+ // Check that asking for the application interface twice returns the same object
+ QAccessibleInterface *app2 = QAccessible::queryAccessibleInterface(qApp);
+ QCOMPARE(interface, app2);
+
QWidget widget;
widget.show();
qApp->setActiveWindow(&widget);
diff --git a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
index e9407fd903..4ebf7a37f9 100644
--- a/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
+++ b/tests/auto/other/qaccessibilitymac/tst_qaccessibilitymac_helpers.mm
@@ -101,9 +101,9 @@ QDebug operator<<(QDebug dbg, AXErrorTag err)
@implementation TestAXObject
-- (id) initWithAXUIElementRef: (AXUIElementRef) ref {
+- (instancetype)initWithAXUIElementRef:(AXUIElementRef)ref {
- if ( self = [super init] ) {
+ if ((self = [super init])) {
reference = ref;
}
return self;
diff --git a/tests/auto/other/qfocusevent/BLACKLIST b/tests/auto/other/qfocusevent/BLACKLIST
index 502820fa12..0b03472587 100644
--- a/tests/auto/other/qfocusevent/BLACKLIST
+++ b/tests/auto/other/qfocusevent/BLACKLIST
@@ -2,4 +2,5 @@
osx-10.12 ci
[checkReason_ActiveWindow]
osx-10.12 ci
+winrt
diff --git a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
index ceac02279e..260ba12a97 100644
--- a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
+++ b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
@@ -351,9 +351,10 @@ void tst_QFocusEvent::checkReason_ActiveWindow()
d->hide();
if (!QGuiApplication::platformName().compare(QLatin1String("offscreen"), Qt::CaseInsensitive)
- || !QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive)) {
+ || !QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive)
+ || !QGuiApplication::platformName().compare(QLatin1String("winrt"), Qt::CaseInsensitive)) {
// Activate window of testFocusWidget, focus in that window goes to childFocusWidgetOne
- QWARN("Platforms offscreen and minimal require explicit activateWindow()");
+ QWARN("Platforms offscreen, minimal, and winrt require explicit activateWindow()");
testFocusWidget->activateWindow();
}
diff --git a/tests/auto/printsupport/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp b/tests/auto/printsupport/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
index bb3624a51d..7f874a843d 100644
--- a/tests/auto/printsupport/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
+++ b/tests/auto/printsupport/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
@@ -101,8 +101,7 @@ void tst_QAbstractPrintDialog::setMinMax()
QPrinter printer;
MyAbstractPrintDialog obj1(&printer);
obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::None));
- QEXPECT_FAIL("", "QTBUG-22637", Abort);
- QCOMPARE(obj1.minPage(), 1);
+ QCOMPARE(obj1.minPage(), 0);
QCOMPARE(obj1.maxPage(), INT_MAX);
QVERIFY(!obj1.isOptionEnabled(QAbstractPrintDialog::PrintPageRange));
obj1.setMinMax(2,5);
diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
index 4f86e74117..a65dd0bf8f 100644
--- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
+++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
@@ -1026,7 +1026,7 @@ void tst_QPrinter::duplex()
pdf.setOutputFormat(QPrinter::PdfFormat);
QCOMPARE(pdf.duplex(), QPrinter::DuplexNone);
pdf.setDuplex(QPrinter::DuplexAuto);
- QCOMPARE(pdf.duplex(), QPrinter::DuplexAuto);
+ QCOMPARE(pdf.duplex(), QPrinter::DuplexNone); // pdf doesn't have the concept of duplex
QPrinter native;
if (native.outputFormat() == QPrinter::NativeFormat) {
@@ -1071,7 +1071,7 @@ void tst_QPrinter::doubleSidedPrinting()
pdf.setOutputFormat(QPrinter::PdfFormat);
QCOMPARE(pdf.doubleSidedPrinting(), false);
pdf.setDoubleSidedPrinting(true);
- QCOMPARE(pdf.doubleSidedPrinting(), true);
+ QCOMPARE(pdf.doubleSidedPrinting(), false); // pdf doesn't have the concept of duplex
QPrinter native;
if (native.outputFormat() == QPrinter::NativeFormat) {
diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
index 7bfa29ec8e..15190b0f3e 100644
--- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
+++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
@@ -54,6 +54,18 @@ private slots:
void formatValue();
};
+static bool driverSupportsDefaultValues(QSqlDriver::DbmsType dbType)
+{
+ switch (dbType) {
+ case QSqlDriver::SQLite:
+ case QSqlDriver::PostgreSQL:
+ case QSqlDriver::Oracle:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
void tst_QSqlDriver::initTestCase_data()
{
@@ -81,8 +93,9 @@ void tst_QSqlDriver::recreateTestTables(QSqlDatabase db)
doubleField = "more_data double precision";
else
doubleField = "more_data double(8,7)";
+ const QString defValue(driverSupportsDefaultValues(dbType) ? QStringLiteral("DEFAULT 'defaultVal'") : QString());
QVERIFY_SQL( q, exec("create table " + relTEST1 +
- " (id int not null primary key, name varchar(20), title_key int, another_title_key int, " + doubleField + QLatin1Char(')')));
+ " (id int not null primary key, name varchar(20) " + defValue + ", title_key int, another_title_key int, " + doubleField + QLatin1Char(')')));
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(1, 'harry', 1, 2, 1.234567)"));
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(2, 'trond', 2, 1, 8.901234)"));
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(3, 'vohi', 1, 2, 5.678901)"));
@@ -127,7 +140,7 @@ void tst_QSqlDriver::record()
//check we can get records using an unquoted mixed case table name
QSqlRecord rec = db.driver()->record(tablename);
- QCOMPARE(rec.count(), 5);
+ QCOMPARE(rec.count(), fields.size());
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
// QTBUG-1363: QSqlField::length() always return -1 when using QODBC3 driver and QSqlDatabase::record()
@@ -141,6 +154,9 @@ void tst_QSqlDriver::record()
for (int i = 0; i < fields.count(); ++i)
QCOMPARE(rec.fieldName(i), fields[i]);
+ if (driverSupportsDefaultValues(dbType))
+ QCOMPARE(rec.field(QStringLiteral("name")).defaultValue().toString(), QStringLiteral("defaultVal"));
+
if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::Oracle || dbType == QSqlDriver::DB2)
tablename = tablename.toUpper();
else if (dbType == QSqlDriver::PostgreSQL)
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index c64310a715..4ce1009c90 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -180,6 +180,8 @@ private slots:
void timeStampParsing();
void sqliteVirtualTable_data() { generic_data("QSQLITE"); }
void sqliteVirtualTable();
+ void mysql_timeType_data() { generic_data("QMYSQL"); }
+ void mysql_timeType();
#ifdef NOT_READY_YET
void task_229811();
@@ -4722,5 +4724,58 @@ void tst_QSqlQuery::sqliteVirtualTable()
QCOMPARE(qry.value(1).toString(), "Peter");
}
+void tst_QSqlQuery::mysql_timeType()
+{
+ // The TIME data type is different to the standard with MySQL as it has a range of
+ // '-838:59:59' to '838:59:59'.
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ const auto tableName = qTableName("mysqlTimeType", __FILE__, db);
+ tst_Databases::safeDropTables(db, { tableName });
+ QSqlQuery qry(db);
+ QVERIFY_SQL(qry, exec("create table " + tableName + " (t time(6))"));
+
+ // MySQL will convert days into hours and add them together so 17 days 11 hours becomes 419 hours
+ const QStringList timeData = { "-838:59:59.000000", "-123:45:56.789", "000:00:00.0", "123:45:56.789",
+ "838:59:59.000000", "15:50", "12", "1213", "0 1:2:3", "17 11:22:33" };
+ const QStringList resultTimeData = { "-838:59:59.000000", "-123:45:56.789000", "00:00:00.000000",
+ "123:45:56.789000", "838:59:59.000000", "15:50:00.000000", "00:00:12.000000", "00:12:13.000000",
+ "01:02:03.000000", "419:22:33.000000" };
+ for (const QString &time : timeData)
+ QVERIFY_SQL(qry, exec("insert into " + tableName + " (t) VALUES ('" + time + "')"));
+
+ QVERIFY_SQL(qry, exec("select * from " + tableName));
+ for (const QString &time : qAsConst(resultTimeData)) {
+ QVERIFY(qry.next());
+ QCOMPARE(qry.value(0).toString(), time);
+ }
+
+ QVERIFY_SQL(qry, exec("delete from " + tableName));
+ for (const QString &time : timeData) {
+ QVERIFY_SQL(qry, prepare("insert into " + tableName + " (t) VALUES (:time)"));
+ qry.bindValue(0, time);
+ QVERIFY_SQL(qry, exec());
+ }
+ QVERIFY_SQL(qry, exec("select * from " + tableName));
+ for (const QString &time : resultTimeData) {
+ QVERIFY(qry.next());
+ QCOMPARE(qry.value(0).toString(), time);
+ }
+
+ QVERIFY_SQL(qry, exec("delete from " + tableName));
+ const QList<QTime> qTimeBasedData = { QTime(), QTime(1, 2, 3, 4), QTime(0, 0, 0, 0), QTime(23,59,59,999) };
+ for (const QTime &time : qTimeBasedData) {
+ QVERIFY_SQL(qry, prepare("insert into " + tableName + " (t) VALUES (:time)"));
+ qry.bindValue(0, time);
+ QVERIFY_SQL(qry, exec());
+ }
+ QVERIFY_SQL(qry, exec("select * from " + tableName));
+ for (const QTime &time : qTimeBasedData) {
+ QVERIFY(qry.next());
+ QCOMPARE(qry.value(0).toTime(), time);
+ }
+}
+
QTEST_MAIN( tst_QSqlQuery )
#include "tst_qsqlquery.moc"
diff --git a/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro b/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
index 2e4c3f998d..5c567ad771 100644
--- a/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
+++ b/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
@@ -6,5 +6,3 @@ QT = core core-private sql sql-private testlib
SOURCES += tst_qsqlresult.cpp
HEADERS += testsqldriver.h
-mingw: LIBS += -lws2_32
-
diff --git a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
index 5482dc393b..09a842eb83 100644
--- a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
+++ b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
@@ -401,8 +401,10 @@ void tst_QSqlThread::readWriteThreading()
QTRY_VERIFY_WITH_TIMEOUT(threadFinishedCount >= 2, 10000);
}
+#ifdef QOCI_THREADED
// run with n threads in parallel. Change this constant to hammer the poor DB server even more
static const int maxThreadCount = 4;
+#endif
void tst_QSqlThread::readFromSingleConnection()
{
diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/qsqlrelationaldelegate.pro b/tests/auto/sql/models/qsqlrelationaldelegate/qsqlrelationaldelegate.pro
new file mode 100644
index 0000000000..d911a46259
--- /dev/null
+++ b/tests/auto/sql/models/qsqlrelationaldelegate/qsqlrelationaldelegate.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+TARGET = tst_qsqlrelationaldelegate
+SOURCES += tst_qsqlrelationaldelegate.cpp
+
+QT = core sql testlib core-private sql-private widgets
diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
new file mode 100644
index 0000000000..36f592395e
--- /dev/null
+++ b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtSql/QtSql>
+#include <QTableView>
+#include <QComboBox>
+
+#include "../../kernel/qsqldatabase/tst_databases.h"
+
+const QString reltest1(qTableName("reltest1", __FILE__, QSqlDatabase())),
+ reltest2(qTableName("reltest2", __FILE__, QSqlDatabase()));
+
+class tst_QSqlRelationalDelegate : public QObject
+{
+ Q_OBJECT
+
+public:
+ void recreateTestTables(QSqlDatabase);
+
+ tst_Databases dbs;
+
+public slots:
+ void initTestCase_data();
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void comboBoxEditor();
+private:
+ void dropTestTables(QSqlDatabase db);
+};
+
+
+void tst_QSqlRelationalDelegate::initTestCase_data()
+{
+ QVERIFY(dbs.open());
+ if (dbs.fillTestTable() == 0)
+ QSKIP("No database drivers are available in this Qt configuration");
+}
+
+void tst_QSqlRelationalDelegate::recreateTestTables(QSqlDatabase db)
+{
+ dropTestTables(db);
+
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("create table " + reltest1 +
+ " (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
+ QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(1, 'harry', 1, 2)"));
+ QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(2, 'trond', 2, 1)"));
+ QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(3, 'vohi', 1, 2)"));
+ QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(4, 'boris', 2, 2)"));
+ QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(5, 'nat', NULL, NULL)"));
+ QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(6, 'ale', NULL, 2)"));
+
+ QVERIFY_SQL(q, exec("create table " + reltest2 + " (id int not null primary key, title varchar(20))"));
+ QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(1, 'herr')"));
+ QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(2, 'mister')"));
+}
+
+void tst_QSqlRelationalDelegate::initTestCase()
+{
+ foreach (const QString &dbname, dbs.dbNames) {
+ QSqlDatabase db=QSqlDatabase::database(dbname);
+ QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
+ if (dbType == QSqlDriver::Interbase) {
+ db.exec("SET DIALECT 3");
+ } else if (dbType == QSqlDriver::MSSqlServer) {
+ db.exec("SET ANSI_DEFAULTS ON");
+ db.exec("SET IMPLICIT_TRANSACTIONS OFF");
+ } else if (dbType == QSqlDriver::PostgreSQL) {
+ db.exec("set client_min_messages='warning'");
+ }
+ recreateTestTables(db);
+ }
+}
+
+void tst_QSqlRelationalDelegate::cleanupTestCase()
+{
+ foreach (const QString &dbName, dbs.dbNames) {
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+ dropTestTables(QSqlDatabase::database(dbName));
+ }
+ dbs.close();
+}
+
+void tst_QSqlRelationalDelegate::dropTestTables(QSqlDatabase db)
+{
+ QStringList tableNames = { reltest1, reltest2 };
+ tst_Databases::safeDropTables(db, tableNames);
+}
+
+void tst_QSqlRelationalDelegate::init()
+{
+}
+
+void tst_QSqlRelationalDelegate::cleanup()
+{
+}
+
+void tst_QSqlRelationalDelegate::comboBoxEditor()
+{
+ QFETCH_GLOBAL(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QTableView tv;
+ QSqlRelationalTableModel model(0, db);
+ model.setEditStrategy(QSqlTableModel::OnManualSubmit);
+ model.setTable(reltest1);
+ model.setRelation(2, QSqlRelation(reltest2, "id", "title"));
+ model.setRelation(3, QSqlRelation(reltest2, "id", "title"));
+ tv.setModel(&model);
+ QVERIFY_SQL(model, select());
+
+ QSqlRelationalDelegate delegate;
+ tv.setItemDelegate(&delegate);
+ tv.show();
+ QVERIFY(QTest::qWaitForWindowActive(&tv));
+
+ QModelIndex index = model.index(0, 2);
+ tv.setCurrentIndex(index);
+ tv.edit(index);
+ QList<QComboBox*> comboBoxes = tv.viewport()->findChildren<QComboBox *>();
+ QCOMPARE(comboBoxes.count(), 1);
+
+ QComboBox *editor = comboBoxes.at(0);
+ QCOMPARE(editor->currentText(), "herr");
+ QTest::keyClick(editor, Qt::Key_Down);
+ QTest::keyClick(editor, Qt::Key_Enter);
+ QCOMPARE(editor->currentText(), "mister");
+ QVERIFY_SQL(model, submitAll());
+
+ QSqlQuery qry(db);
+ QVERIFY_SQL(qry, exec("SELECT title_key FROM " + reltest1 + " WHERE id=1"));
+ QVERIFY(qry.next());
+ QCOMPARE(qry.value(0).toString(), "mister");
+}
+
+QTEST_MAIN(tst_QSqlRelationalDelegate)
+#include "tst_qsqlrelationaldelegate.moc"
diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
index 430fa981d5..da31f437d9 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -31,11 +31,29 @@
#include "../../kernel/qsqldatabase/tst_databases.h"
#include <QtSql>
#include <QtSql/private/qsqltablemodel_p.h>
+#include <QThread>
const QString test(qTableName("test", __FILE__, QSqlDatabase())),
test2(qTableName("test2", __FILE__, QSqlDatabase())),
test3(qTableName("test3", __FILE__, QSqlDatabase()));
+// In order to catch when the warning message occurs, indicating that the database belongs to another
+// thread, we have to install our own message handler. To ensure that the test reporting still happens
+// as before, we call the originating one.
+//
+// For now, this is only called inside the modelInAnotherThread() test
+QtMessageHandler oldHandler = nullptr;
+
+void sqlTableModelMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ if (type == QtWarningMsg &&
+ msg == "QSqlDatabasePrivate::database: requested database does not "
+ "belong to the calling thread.") {
+ QFAIL("Requested database does not belong to the calling thread.");
+ }
+ if (oldHandler)
+ oldHandler(type, context, msg);
+}
class tst_QSqlTableModel : public QObject
{
@@ -116,6 +134,7 @@ private slots:
void sqlite_bigTable_data() { generic_data("QSQLITE"); }
void sqlite_bigTable();
+ void modelInAnotherThread();
// bug specific tests
void insertRecordBeforeSelect_data() { generic_data(); }
@@ -276,6 +295,10 @@ void tst_QSqlTableModel::init()
void tst_QSqlTableModel::cleanup()
{
recreateTestTables();
+ if (oldHandler) {
+ qInstallMessageHandler(oldHandler);
+ oldHandler = nullptr;
+ }
}
void tst_QSqlTableModel::select()
@@ -2100,5 +2123,29 @@ void tst_QSqlTableModel::invalidFilterAndHeaderData()
QVERIFY(!v.isValid());
}
+class SqlThread : public QThread
+{
+public:
+ SqlThread() : QThread() {}
+ void run()
+ {
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "non-default-connection");
+ QSqlTableModel stm(nullptr, db);
+ isDone = true;
+ }
+ bool isDone = false;
+};
+
+void tst_QSqlTableModel::modelInAnotherThread()
+{
+ oldHandler = qInstallMessageHandler(sqlTableModelMessageHandler);
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+ CHECK_DATABASE(db);
+ SqlThread t;
+ t.start();
+ QTRY_VERIFY(t.isDone);
+ QVERIFY(t.isFinished());
+}
+
QTEST_MAIN(tst_QSqlTableModel)
#include "tst_qsqltablemodel.moc"
diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
index a662fea615..8e2c7694a5 100644
--- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
@@ -130,6 +130,10 @@ private slots:
void compare_unregistered_enums();
void compare_registered_enums();
void compare_class_enums();
+ void test_windowflags_data();
+ void test_windowflags();
+ void test_unregistered_flags_data();
+ void test_unregistered_flags();
void compare_boolfuncs();
void compare_to_nullptr();
void compare_pointerfuncs();
@@ -180,6 +184,64 @@ void tst_Cmptest::compare_class_enums()
QCOMPARE(MyClassEnum::MyClassEnumValue1, MyClassEnum::MyClassEnumValue2);
}
+void tst_Cmptest::test_windowflags_data()
+{
+ QTest::addColumn<Qt::WindowFlags>("actualWindowFlags");
+ QTest::addColumn<Qt::WindowFlags>("expectedWindowFlags");
+
+ const Qt::WindowFlags windowFlags = Qt::Window
+ | Qt::WindowSystemMenuHint | Qt::WindowStaysOnBottomHint;
+ QTest::newRow("pass")
+ << windowFlags
+ << windowFlags;
+ QTest::newRow("fail1")
+ << windowFlags
+ << (windowFlags | Qt::FramelessWindowHint);
+ QTest::newRow("fail2")
+ << Qt::WindowFlags(Qt::Window)
+ << Qt::WindowFlags(Qt::Window | Qt::FramelessWindowHint);
+}
+
+void tst_Cmptest::test_windowflags()
+{
+ QFETCH(Qt::WindowFlags, actualWindowFlags);
+ QFETCH(Qt::WindowFlags, expectedWindowFlags);
+ QCOMPARE(actualWindowFlags, expectedWindowFlags);
+}
+
+enum UnregisteredEnum {
+ UnregisteredEnumValue1 = 0x1,
+ UnregisteredEnumValue2 = 0x2,
+ UnregisteredEnumValue3 = 0x4
+};
+
+typedef QFlags<UnregisteredEnum> UnregisteredFlags;
+
+Q_DECLARE_METATYPE(UnregisteredFlags);
+
+void tst_Cmptest::test_unregistered_flags_data()
+{
+ QTest::addColumn<UnregisteredFlags>("actualFlags");
+ QTest::addColumn<UnregisteredFlags>("expectedFlags");
+
+ QTest::newRow("pass")
+ << UnregisteredFlags(UnregisteredEnumValue1)
+ << UnregisteredFlags(UnregisteredEnumValue1);
+ QTest::newRow("fail1")
+ << UnregisteredFlags(UnregisteredEnumValue1 | UnregisteredEnumValue2)
+ << UnregisteredFlags(UnregisteredEnumValue1 | UnregisteredEnumValue3);
+ QTest::newRow("fail2")
+ << UnregisteredFlags(UnregisteredEnumValue1)
+ << UnregisteredFlags(UnregisteredEnumValue1 | UnregisteredEnumValue3);
+}
+
+void tst_Cmptest::test_unregistered_flags()
+{
+ QFETCH(UnregisteredFlags, actualFlags);
+ QFETCH(UnregisteredFlags, expectedFlags);
+ QCOMPARE(actualFlags, expectedFlags);
+}
+
static bool boolfunc() { return true; }
static bool boolfunc2() { return true; }
diff --git a/tests/auto/testlib/selftests/expected_assert.tap b/tests/auto/testlib/selftests/expected_assert.tap
new file mode 100644
index 0000000000..4cd26848ac
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_assert.tap
@@ -0,0 +1,16 @@
+TAP version 13
+# tst_Assert
+ok 1 - initTestCase()
+ok 2 - testNumber1()
+# ASSERT: "false" in file qtbase/tests/auto/testlib/selftests/assert/tst_assert.cpp, line 0
+not ok 3 - testNumber2()
+ ---
+ # Received a fatal error.
+ at: tst_Assert::testNumber2() (Unknown file:0)
+ file: Unknown file
+ line: 0
+ ...
+1..3
+# tests 3
+# pass 2
+# fail 1
diff --git a/tests/auto/testlib/selftests/expected_badxml.tap b/tests/auto/testlib/selftests/expected_badxml.tap
new file mode 100644
index 0000000000..7aa4f11829
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_badxml.tap
@@ -0,0 +1,61 @@
+TAP version 13
+# tst_BadXml
+ok 1 - initTestCase()
+# a message
+not ok 2 - badDataTag(fail end cdata ]]> text ]]> more text)
+ ---
+ # a failure
+ at: tst_BadXml::badDataTag() (qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp:101)
+ file: qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp
+ line: 101
+ ...
+# a message
+ok 3 - badDataTag(pass end cdata ]]> text ]]> more text)
+# a message
+not ok 4 - badDataTag(fail quotes " text" more text)
+ ---
+ # a failure
+ at: tst_BadXml::badDataTag() (qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp:101)
+ file: qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp
+ line: 101
+ ...
+# a message
+ok 5 - badDataTag(pass quotes " text" more text)
+# a message
+not ok 6 - badDataTag(fail xml close > open < tags < text)
+ ---
+ # a failure
+ at: tst_BadXml::badDataTag() (qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp:101)
+ file: qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp
+ line: 101
+ ...
+# a message
+ok 7 - badDataTag(pass xml close > open < tags < text)
+# a message
+not ok 8 - badDataTag(fail all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs)
+ ---
+ # a failure
+ at: tst_BadXml::badDataTag() (qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp:101)
+ file: qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp
+ line: 101
+ ...
+# a message
+ok 9 - badDataTag(pass all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs)
+# end cdata ]]> text ]]> more text
+ok 10 - badMessage(string 0)
+# quotes " text" more text
+ok 11 - badMessage(string 1)
+# xml close > open < tags < text
+ok 12 - badMessage(string 2)
+# all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs
+ok 13 - badMessage(string 3)
+not ok 14 - failWithNoFile()
+ ---
+ # failure message
+ ...
+ok 15 - encoding() # SKIP Skipped for text due to unpredictable console encoding.
+ok 16 - cleanupTestCase()
+1..16
+# tests 16
+# pass 10
+# fail 5
diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.tap b/tests/auto/testlib/selftests/expected_benchlibcounting.tap
new file mode 100644
index 0000000000..e7a4280278
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibcounting.tap
@@ -0,0 +1,17 @@
+TAP version 13
+# tst_BenchlibCounting
+ok 1 - initTestCase()
+ok 2 - passingBenchmark()
+ok 3 - skippingBenchmark() # SKIP This is a skipping benchmark
+not ok 4 - failingBenchmark()
+ ---
+ # This is a failing benchmark
+ at: tst_BenchlibCounting::failingBenchmark() (qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp:58)
+ file: qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp
+ line: 58
+ ...
+ok 5 - cleanupTestCase()
+1..5
+# tests 5
+# pass 3
+# fail 1
diff --git a/tests/auto/testlib/selftests/expected_benchlibeventcounter.tap b/tests/auto/testlib/selftests/expected_benchlibeventcounter.tap
new file mode 100644
index 0000000000..02c65e59da
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibeventcounter.tap
@@ -0,0 +1,15 @@
+TAP version 13
+# tst_BenchlibEventCounter
+ok 1 - initTestCase()
+ok 2 - events(0)
+ok 3 - events(1)
+ok 4 - events(10)
+ok 5 - events(100)
+ok 6 - events(500)
+ok 7 - events(5000)
+ok 8 - events(100000)
+ok 9 - cleanupTestCase()
+1..9
+# tests 9
+# pass 9
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_benchlibtickcounter.tap b/tests/auto/testlib/selftests/expected_benchlibtickcounter.tap
new file mode 100644
index 0000000000..85d7f10ea0
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibtickcounter.tap
@@ -0,0 +1,9 @@
+TAP version 13
+# tst_BenchlibTickCounter
+ok 1 - initTestCase()
+ok 2 - threeBillionTicks()
+ok 3 - cleanupTestCase()
+1..3
+# tests 3
+# pass 3
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_benchlibwalltime.tap b/tests/auto/testlib/selftests/expected_benchlibwalltime.tap
new file mode 100644
index 0000000000..7653ccbeb3
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibwalltime.tap
@@ -0,0 +1,11 @@
+TAP version 13
+# tst_BenchlibWalltime
+ok 1 - initTestCase()
+ok 2 - waitForOneThousand()
+ok 3 - waitForFourThousand()
+ok 4 - qbenchmark_once()
+ok 5 - cleanupTestCase()
+1..5
+# tests 5
+# pass 5
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml
index d47967a445..58b5a5e530 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.lightxml
+++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml
@@ -29,6 +29,42 @@
</Incident>
<Duration msecs="0"/>
</TestFunction>
+<TestFunction name="test_windowflags">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[pass]]></DataTag>
+</Incident>
+<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[fail1]]></DataTag>
+ <Description><![CDATA[Compared values are not the same
+ Actual (actualWindowFlags) : Window|WindowSystemMenuHint|WindowStaysOnBottomHint
+ Expected (expectedWindowFlags): Window|FramelessWindowHint|WindowSystemMenuHint|WindowStaysOnBottomHint]]></Description>
+</Incident>
+<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[fail2]]></DataTag>
+ <Description><![CDATA[Compared values are not the same
+ Actual (actualWindowFlags) : Window
+ Expected (expectedWindowFlags): Window|FramelessWindowHint]]></Description>
+</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="test_unregistered_flags">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[pass]]></DataTag>
+</Incident>
+<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[fail1]]></DataTag>
+ <Description><![CDATA[Compared values are not the same
+ Actual (actualFlags) : 0x3
+ Expected (expectedFlags): 0x5]]></Description>
+</Incident>
+<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[fail2]]></DataTag>
+ <Description><![CDATA[Compared values are not the same
+ Actual (actualFlags) : 0x1
+ Expected (expectedFlags): 0x5]]></Description>
+</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
<TestFunction name="compare_boolfuncs">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.tap b/tests/auto/testlib/selftests/expected_cmptest.tap
new file mode 100644
index 0000000000..238db2fc2b
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_cmptest.tap
@@ -0,0 +1,456 @@
+TAP version 13
+# tst_Cmptest
+ok 1 - initTestCase()
+not ok 2 - compare_unregistered_enums()
+ ---
+ # Compared values are not the same
+ at: tst_Cmptest::compare_unregistered_enums() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:171)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 171
+ ...
+not ok 3 - compare_registered_enums()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: Sunday (Qt::Sunday)
+ found: Monday (Qt::Monday)
+ expected: Sunday (Qt::Sunday)
+ actual: Monday (Qt::Monday)
+ at: tst_Cmptest::compare_registered_enums() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:178)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 178
+ ...
+not ok 4 - compare_class_enums()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: MyClassEnumValue2 (MyClassEnum::MyClassEnumValue2)
+ found: MyClassEnumValue1 (MyClassEnum::MyClassEnumValue1)
+ expected: MyClassEnumValue2 (MyClassEnum::MyClassEnumValue2)
+ actual: MyClassEnumValue1 (MyClassEnum::MyClassEnumValue1)
+ at: tst_Cmptest::compare_class_enums() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:184)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 184
+ ...
+ok 5 - test_windowflags(pass)
+not ok 6 - test_windowflags(fail1)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: Window|FramelessWindowHint|WindowSystemMenuHint|WindowStaysOnBottomHint (expectedWindowFlags)
+ found: Window|WindowSystemMenuHint|WindowStaysOnBottomHint (actualWindowFlags)
+ expected: Window|FramelessWindowHint|WindowSystemMenuHint|WindowStaysOnBottomHint (expectedWindowFlags)
+ actual: Window|WindowSystemMenuHint|WindowStaysOnBottomHint (actualWindowFlags)
+ at: tst_Cmptest::test_windowflags() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:209)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 209
+ ...
+not ok 7 - test_windowflags(fail2)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: Window|FramelessWindowHint (expectedWindowFlags)
+ found: Window (actualWindowFlags)
+ expected: Window|FramelessWindowHint (expectedWindowFlags)
+ actual: Window (actualWindowFlags)
+ at: tst_Cmptest::test_windowflags() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:209)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 209
+ ...
+ok 8 - test_unregistered_flags(pass)
+not ok 9 - test_unregistered_flags(fail1)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: 0x5 (expectedFlags)
+ found: 0x3 (actualFlags)
+ expected: 0x5 (expectedFlags)
+ actual: 0x3 (actualFlags)
+ at: tst_Cmptest::test_unregistered_flags() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:242)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 242
+ ...
+not ok 10 - test_unregistered_flags(fail2)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: 0x5 (expectedFlags)
+ found: 0x1 (actualFlags)
+ expected: 0x5 (expectedFlags)
+ actual: 0x1 (actualFlags)
+ at: tst_Cmptest::test_unregistered_flags() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:242)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 242
+ ...
+ok 11 - compare_boolfuncs()
+ok 12 - compare_to_nullptr()
+ok 13 - compare_pointerfuncs()
+not ok 14 - compare_tostring(int, string)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QVariant(QString,hi) (expected)
+ found: QVariant(int,123) (actual)
+ expected: QVariant(QString,hi) (expected)
+ actual: QVariant(int,123) (actual)
+ at: tst_Cmptest::compare_tostring() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:331)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 331
+ ...
+ok 15 - compare_tostring(both invalid)
+not ok 16 - compare_tostring(null hash, invalid)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QVariant() (expected)
+ found: QVariant(QVariantHash) (actual)
+ expected: QVariant() (expected)
+ actual: QVariant(QVariantHash) (actual)
+ at: tst_Cmptest::compare_tostring() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:331)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 331
+ ...
+not ok 17 - compare_tostring(string, null user type)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QVariant(PhonyClass) (expected)
+ found: QVariant(QString,A simple string) (actual)
+ expected: QVariant(PhonyClass) (expected)
+ actual: QVariant(QString,A simple string) (actual)
+ at: tst_Cmptest::compare_tostring() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:331)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 331
+ ...
+not ok 18 - compare_tostring(both non-null user type)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QVariant(PhonyClass,<value not representable as string>) (expected)
+ found: QVariant(PhonyClass,<value not representable as string>) (actual)
+ expected: QVariant(PhonyClass,<value not representable as string>) (expected)
+ actual: QVariant(PhonyClass,<value not representable as string>) (actual)
+ at: tst_Cmptest::compare_tostring() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:331)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 331
+ ...
+ok 19 - compareQStringLists(empty lists)
+ok 20 - compareQStringLists(equal lists)
+not ok 21 - compareQStringLists(last item different)
+ ---
+ type: QCOMPARE
+ message: Compared lists differ at index 2.
+ wanted: "DIFFERS" (opB)
+ found: "string3" (opA)
+ expected: "DIFFERS" (opB)
+ actual: "string3" (opA)
+ at: tst_Cmptest::compareQStringLists() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:425)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 425
+ ...
+not ok 22 - compareQStringLists(second-last item different)
+ ---
+ type: QCOMPARE
+ message: Compared lists differ at index 2.
+ wanted: "DIFFERS" (opB)
+ found: "string3" (opA)
+ expected: "DIFFERS" (opB)
+ actual: "string3" (opA)
+ at: tst_Cmptest::compareQStringLists() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:425)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 425
+ ...
+not ok 23 - compareQStringLists(prefix)
+ ---
+ # Compared lists have different sizes.
+ Actual (opA) size: 2
+ Expected (opB) size: 1
+ at: tst_Cmptest::compareQStringLists() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:425)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 425
+ ...
+not ok 24 - compareQStringLists(short list second)
+ ---
+ # Compared lists have different sizes.
+ Actual (opA) size: 12
+ Expected (opB) size: 1
+ at: tst_Cmptest::compareQStringLists() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:425)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 425
+ ...
+not ok 25 - compareQStringLists(short list first)
+ ---
+ # Compared lists have different sizes.
+ Actual (opA) size: 1
+ Expected (opB) size: 12
+ at: tst_Cmptest::compareQStringLists() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:425)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 425
+ ...
+not ok 26 - compareQListInt()
+ ---
+ type: QCOMPARE
+ message: Compared lists differ at index 2.
+ wanted: 4 (int2)
+ found: 3 (int1)
+ expected: 4 (int2)
+ actual: 3 (int1)
+ at: tst_Cmptest::compareQListInt() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:432)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 432
+ ...
+not ok 27 - compareQListDouble()
+ ---
+ type: QCOMPARE
+ message: Compared lists differ at index 0.
+ wanted: 1 (double2)
+ found: 1.5 (double1)
+ expected: 1 (double2)
+ actual: 1.5 (double1)
+ at: tst_Cmptest::compareQListDouble() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:439)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 439
+ ...
+ok 28 - compareQColor(Qt::yellow vs "yellow")
+not ok 29 - compareQColor(Qt::yellow vs Qt::green)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: #ff00ff00 (colorB)
+ found: #ffffff00 (colorA)
+ expected: #ff00ff00 (colorB)
+ actual: #ffffff00 (colorA)
+ at: tst_Cmptest::compareQColor() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:458)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 458
+ ...
+not ok 30 - compareQColor(0x88ff0000 vs 0xffff0000)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: #ffff0000 (colorB)
+ found: #88ff0000 (colorA)
+ expected: #ffff0000 (colorB)
+ actual: #88ff0000 (colorA)
+ at: tst_Cmptest::compareQColor() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:458)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 458
+ ...
+ok 31 - compareQPixmaps(both null)
+not ok 32 - compareQPixmaps(one null)
+ ---
+ type: QCOMPARE
+ message: Compared QPixmaps differ.
+ wanted: 0 (opB).isNull()
+ found: 1 (opA).isNull()
+ expected: 0 (opB).isNull()
+ actual: 1 (opA).isNull()
+ at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:483)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 483
+ ...
+not ok 33 - compareQPixmaps(other null)
+ ---
+ type: QCOMPARE
+ message: Compared QPixmaps differ.
+ wanted: 1 (opB).isNull()
+ found: 0 (opA).isNull()
+ expected: 1 (opB).isNull()
+ actual: 0 (opA).isNull()
+ at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:483)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 483
+ ...
+ok 34 - compareQPixmaps(equal)
+not ok 35 - compareQPixmaps(different size)
+ ---
+ type: QCOMPARE
+ message: Compared QPixmaps differ in size.
+ wanted: 20x20 (opB)
+ found: 11x20 (opA)
+ expected: 20x20 (opB)
+ actual: 11x20 (opA)
+ at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:483)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 483
+ ...
+not ok 36 - compareQPixmaps(different pixels)
+ ---
+ # Compared values are not the same
+ at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:483)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 483
+ ...
+ok 37 - compareQImages(both null)
+not ok 38 - compareQImages(one null)
+ ---
+ type: QCOMPARE
+ message: Compared QImages differ.
+ wanted: 0 (opB).isNull()
+ found: 1 (opA).isNull()
+ expected: 0 (opB).isNull()
+ actual: 1 (opA).isNull()
+ at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 510
+ ...
+not ok 39 - compareQImages(other null)
+ ---
+ type: QCOMPARE
+ message: Compared QImages differ.
+ wanted: 1 (opB).isNull()
+ found: 0 (opA).isNull()
+ expected: 1 (opB).isNull()
+ actual: 0 (opA).isNull()
+ at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 510
+ ...
+ok 40 - compareQImages(equal)
+not ok 41 - compareQImages(different size)
+ ---
+ type: QCOMPARE
+ message: Compared QImages differ in size.
+ wanted: 20x20 (opB)
+ found: 11x20 (opA)
+ expected: 20x20 (opB)
+ actual: 11x20 (opA)
+ at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 510
+ ...
+not ok 42 - compareQImages(different format)
+ ---
+ type: QCOMPARE
+ message: Compared QImages differ in format.
+ wanted: 3 (opB)
+ found: 6 (opA)
+ expected: 3 (opB)
+ actual: 6 (opA)
+ at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 510
+ ...
+not ok 43 - compareQImages(different pixels)
+ ---
+ # Compared values are not the same
+ at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 510
+ ...
+ok 44 - compareQRegion(equal-empty)
+not ok 45 - compareQRegion(1-empty)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QRegion(null) (rB)
+ found: QRegion(200x50+10+10) (rA)
+ expected: QRegion(null) (rB)
+ actual: QRegion(200x50+10+10) (rA)
+ at: tst_Cmptest::compareQRegion() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:533)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 533
+ ...
+ok 46 - compareQRegion(equal)
+not ok 47 - compareQRegion(different lists)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QRegion(2 rectangles, 50x200+100+200, 200x50+10+10) (rB)
+ found: QRegion(200x50+10+10) (rA)
+ expected: QRegion(2 rectangles, 50x200+100+200, 200x50+10+10) (rB)
+ actual: QRegion(200x50+10+10) (rA)
+ at: tst_Cmptest::compareQRegion() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:533)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 533
+ ...
+not ok 48 - compareQVector2D()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QVector2D(1, 3) (v2b)
+ found: QVector2D(1, 2) (v2a)
+ expected: QVector2D(1, 3) (v2b)
+ actual: QVector2D(1, 2) (v2a)
+ at: tst_Cmptest::compareQVector2D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:542)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 542
+ ...
+not ok 49 - compareQVector3D()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QVector3D(1, 3, 3) (v3b)
+ found: QVector3D(1, 2, 3) (v3a)
+ expected: QVector3D(1, 3, 3) (v3b)
+ actual: QVector3D(1, 2, 3) (v3a)
+ at: tst_Cmptest::compareQVector3D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:551)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 551
+ ...
+not ok 50 - compareQVector4D()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: QVector4D(1, 3, 3, 4) (v4b)
+ found: QVector4D(1, 2, 3, 4) (v4a)
+ expected: QVector4D(1, 3, 3, 4) (v4b)
+ actual: QVector4D(1, 2, 3, 4) (v4a)
+ at: tst_Cmptest::compareQVector4D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:560)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 560
+ ...
+not ok 51 - verify()
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (opaqueFunc() < 2)
+ found: false (opaqueFunc() < 2)
+ expected: true (opaqueFunc() < 2)
+ actual: false (opaqueFunc() < 2)
+ at: tst_Cmptest::verify() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:572)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 572
+ ...
+not ok 52 - verify2()
+ ---
+ type: QVERIFY
+ message: 42
+ wanted: true (opaqueFunc() < 2)
+ found: false (opaqueFunc() < 2)
+ expected: true (opaqueFunc() < 2)
+ actual: false (opaqueFunc() < 2)
+ at: tst_Cmptest::verify2() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:578)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 578
+ ...
+not ok 53 - tryVerify()
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (opaqueFunc() < 2)
+ found: false (opaqueFunc() < 2)
+ expected: true (opaqueFunc() < 2)
+ actual: false (opaqueFunc() < 2)
+ at: tst_Cmptest::tryVerify() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:584)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 584
+ ...
+not ok 54 - tryVerify2()
+ ---
+ type: QVERIFY
+ message: 42
+ wanted: true (opaqueFunc() < 2)
+ found: false (opaqueFunc() < 2)
+ expected: true (opaqueFunc() < 2)
+ actual: false (opaqueFunc() < 2)
+ at: tst_Cmptest::tryVerify2() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:590)
+ file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+ line: 590
+ ...
+ok 55 - verifyExplicitOperatorBool()
+ok 56 - cleanupTestCase()
+1..56
+# tests 56
+# pass 18
+# fail 38
diff --git a/tests/auto/testlib/selftests/expected_cmptest.teamcity b/tests/auto/testlib/selftests/expected_cmptest.teamcity
index a0dc509279..422d0cbfdf 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.teamcity
+++ b/tests/auto/testlib/selftests/expected_cmptest.teamcity
@@ -10,6 +10,22 @@
##teamcity[testStarted name='compare_class_enums()' flowId='tst_Cmptest']
##teamcity[testFailed name='compare_class_enums()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1|n Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2' flowId='tst_Cmptest']
##teamcity[testFinished name='compare_class_enums()' flowId='tst_Cmptest']
+##teamcity[testStarted name='test_windowflags(pass)' flowId='tst_Cmptest']
+##teamcity[testFinished name='test_windowflags(pass)' flowId='tst_Cmptest']
+##teamcity[testStarted name='test_windowflags(fail1)' flowId='tst_Cmptest']
+##teamcity[testFailed name='test_windowflags(fail1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (actualWindowFlags) : Window||WindowSystemMenuHint||WindowStaysOnBottomHint|n Expected (expectedWindowFlags): Window||FramelessWindowHint||WindowSystemMenuHint||WindowStaysOnBottomHint' flowId='tst_Cmptest']
+##teamcity[testFinished name='test_windowflags(fail1)' flowId='tst_Cmptest']
+##teamcity[testStarted name='test_windowflags(fail2)' flowId='tst_Cmptest']
+##teamcity[testFailed name='test_windowflags(fail2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (actualWindowFlags) : Window|n Expected (expectedWindowFlags): Window||FramelessWindowHint' flowId='tst_Cmptest']
+##teamcity[testFinished name='test_windowflags(fail2)' flowId='tst_Cmptest']
+##teamcity[testStarted name='test_unregistered_flags(pass)' flowId='tst_Cmptest']
+##teamcity[testFinished name='test_unregistered_flags(pass)' flowId='tst_Cmptest']
+##teamcity[testStarted name='test_unregistered_flags(fail1)' flowId='tst_Cmptest']
+##teamcity[testFailed name='test_unregistered_flags(fail1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (actualFlags) : 0x3|n Expected (expectedFlags): 0x5' flowId='tst_Cmptest']
+##teamcity[testFinished name='test_unregistered_flags(fail1)' flowId='tst_Cmptest']
+##teamcity[testStarted name='test_unregistered_flags(fail2)' flowId='tst_Cmptest']
+##teamcity[testFailed name='test_unregistered_flags(fail2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same|n Actual (actualFlags) : 0x1|n Expected (expectedFlags): 0x5' flowId='tst_Cmptest']
+##teamcity[testFinished name='test_unregistered_flags(fail2)' flowId='tst_Cmptest']
##teamcity[testStarted name='compare_boolfuncs()' flowId='tst_Cmptest']
##teamcity[testFinished name='compare_boolfuncs()' flowId='tst_Cmptest']
##teamcity[testStarted name='compare_to_nullptr()' flowId='tst_Cmptest']
diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt
index 78df990dea..e1aa81c1a1 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.txt
+++ b/tests/auto/testlib/selftests/expected_cmptest.txt
@@ -11,6 +11,24 @@ FAIL! : tst_Cmptest::compare_class_enums() Compared values are not the same
Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1
Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2
Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
+PASS : tst_Cmptest::test_windowflags(pass)
+FAIL! : tst_Cmptest::test_windowflags(fail1) Compared values are not the same
+ Actual (actualWindowFlags) : Window|WindowSystemMenuHint|WindowStaysOnBottomHint
+ Expected (expectedWindowFlags): Window|FramelessWindowHint|WindowSystemMenuHint|WindowStaysOnBottomHint
+ Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
+FAIL! : tst_Cmptest::test_windowflags(fail2) Compared values are not the same
+ Actual (actualWindowFlags) : Window
+ Expected (expectedWindowFlags): Window|FramelessWindowHint
+ Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
+PASS : tst_Cmptest::test_unregistered_flags(pass)
+FAIL! : tst_Cmptest::test_unregistered_flags(fail1) Compared values are not the same
+ Actual (actualFlags) : 0x3
+ Expected (expectedFlags): 0x5
+ Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
+FAIL! : tst_Cmptest::test_unregistered_flags(fail2) Compared values are not the same
+ Actual (actualFlags) : 0x1
+ Expected (expectedFlags): 0x5
+ Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
PASS : tst_Cmptest::compare_boolfuncs()
PASS : tst_Cmptest::compare_to_nullptr()
PASS : tst_Cmptest::compare_pointerfuncs()
@@ -138,5 +156,5 @@ FAIL! : tst_Cmptest::tryVerify2() 'opaqueFunc() < 2' returned FALSE. (42)
Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)]
PASS : tst_Cmptest::verifyExplicitOperatorBool()
PASS : tst_Cmptest::cleanupTestCase()
-Totals: 16 passed, 34 failed, 0 skipped, 0 blacklisted, 0ms
+Totals: 18 passed, 38 failed, 0 skipped, 0 blacklisted, 0ms
********* Finished testing of tst_Cmptest *********
diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml
index 01b725f247..1c5a17631a 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.xml
+++ b/tests/auto/testlib/selftests/expected_cmptest.xml
@@ -31,6 +31,42 @@
</Incident>
<Duration msecs="0"/>
</TestFunction>
+<TestFunction name="test_windowflags">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[pass]]></DataTag>
+</Incident>
+<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[fail1]]></DataTag>
+ <Description><![CDATA[Compared values are not the same
+ Actual (actualWindowFlags) : Window|WindowSystemMenuHint|WindowStaysOnBottomHint
+ Expected (expectedWindowFlags): Window|FramelessWindowHint|WindowSystemMenuHint|WindowStaysOnBottomHint]]></Description>
+</Incident>
+<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[fail2]]></DataTag>
+ <Description><![CDATA[Compared values are not the same
+ Actual (actualWindowFlags) : Window
+ Expected (expectedWindowFlags): Window|FramelessWindowHint]]></Description>
+</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="test_unregistered_flags">
+<Incident type="pass" file="" line="0">
+ <DataTag><![CDATA[pass]]></DataTag>
+</Incident>
+<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[fail1]]></DataTag>
+ <Description><![CDATA[Compared values are not the same
+ Actual (actualFlags) : 0x3
+ Expected (expectedFlags): 0x5]]></Description>
+</Incident>
+<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="0">
+ <DataTag><![CDATA[fail2]]></DataTag>
+ <Description><![CDATA[Compared values are not the same
+ Actual (actualFlags) : 0x1
+ Expected (expectedFlags): 0x5]]></Description>
+</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
<TestFunction name="compare_boolfuncs">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml
index 812696ffcf..99823d1c1c 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml
+++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<testsuite errors="0" failures="34" tests="24" name="tst_Cmptest">
+<testsuite errors="0" failures="38" tests="26" name="tst_Cmptest">
<properties>
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
@@ -19,6 +19,22 @@
Actual (MyClassEnum::MyClassEnumValue1): MyClassEnumValue1
Expected (MyClassEnum::MyClassEnumValue2): MyClassEnumValue2" result="fail"/>
</testcase>
+ <testcase result="fail" name="test_windowflags">
+ <failure tag="fail1" message="Compared values are not the same
+ Actual (actualWindowFlags) : Window|WindowSystemMenuHint|WindowStaysOnBottomHint
+ Expected (expectedWindowFlags): Window|FramelessWindowHint|WindowSystemMenuHint|WindowStaysOnBottomHint" result="fail"/>
+ <failure tag="fail2" message="Compared values are not the same
+ Actual (actualWindowFlags) : Window
+ Expected (expectedWindowFlags): Window|FramelessWindowHint" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="test_unregistered_flags">
+ <failure tag="fail1" message="Compared values are not the same
+ Actual (actualFlags) : 0x3
+ Expected (expectedFlags): 0x5" result="fail"/>
+ <failure tag="fail2" message="Compared values are not the same
+ Actual (actualFlags) : 0x1
+ Expected (expectedFlags): 0x5" result="fail"/>
+ </testcase>
<testcase result="pass" name="compare_boolfuncs"/>
<testcase result="pass" name="compare_to_nullptr"/>
<testcase result="pass" name="compare_pointerfuncs"/>
diff --git a/tests/auto/testlib/selftests/expected_commandlinedata.tap b/tests/auto/testlib/selftests/expected_commandlinedata.tap
new file mode 100644
index 0000000000..1e1abfba50
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_commandlinedata.tap
@@ -0,0 +1,20 @@
+TAP version 13
+# tst_DataTable
+ok 1 - initTestCase()
+# QVERIFY(test)
+ok 2 - fiveTablePasses(fiveTablePasses_data1)
+# QVERIFY(test)
+ok 3 - fiveTablePasses(fiveTablePasses_data2)
+# QVERIFY(test)
+ok 4 - fiveTablePasses(fiveTablePasses_data3)
+# QVERIFY(test)
+ok 5 - fiveTablePasses(fiveTablePasses_data4)
+# QVERIFY(test)
+ok 6 - fiveTablePasses(fiveTablePasses_data5)
+# QVERIFY(test)
+ok 7 - fiveTablePasses(fiveTablePasses_data1)
+ok 8 - cleanupTestCase()
+1..8
+# tests 8
+# pass 8
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_counting.tap b/tests/auto/testlib/selftests/expected_counting.tap
new file mode 100644
index 0000000000..ad53e8f14e
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_counting.tap
@@ -0,0 +1,118 @@
+TAP version 13
+# tst_Counting
+ok 1 - initTestCase()
+ok 2 - testPassPass(row 1)
+ok 3 - testPassPass(row 2)
+ok 4 - testPassSkip(row 1)
+ok 5 - testPassSkip(row 2) # SKIP Skipping
+ok 6 - testPassFail(row 1)
+not ok 7 - testPassFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testPassFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 8 - testSkipPass(row 1) # SKIP Skipping
+ok 9 - testSkipPass(row 2)
+ok 10 - testSkipSkip(row 1) # SKIP Skipping
+ok 11 - testSkipSkip(row 2) # SKIP Skipping
+ok 12 - testSkipFail(row 1) # SKIP Skipping
+not ok 13 - testSkipFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testSkipFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+not ok 14 - testFailPass(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailPass() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 15 - testFailPass(row 2)
+not ok 16 - testFailSkip(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailSkip() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 17 - testFailSkip(row 2) # SKIP Skipping
+not ok 18 - testFailFail(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+not ok 19 - testFailFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 20 - testFailInInit(before)
+not ok 21 - testFailInInit(fail)
+ ---
+ # Fail in init()
+ at: tst_Counting::testFailInInit() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:221)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 221
+ ...
+ok 22 - testFailInInit(after)
+ok 23 - testFailInCleanup(before)
+# This test function should execute and then QFAIL in cleanup()
+not ok 24 - testFailInCleanup(fail)
+ ---
+ # Fail in cleanup()
+ at: tst_Counting::testFailInCleanup() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:229)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 229
+ ...
+ok 25 - testFailInCleanup(after)
+ok 26 - testSkipInInit(before)
+ok 27 - testSkipInInit(skip) # SKIP Skip in init()
+ok 28 - testSkipInInit(after)
+ok 29 - testSkipInCleanup(before)
+# This test function should execute and then QSKIP in cleanup()
+ok 30 - testSkipInCleanup(skip) # SKIP Skip in cleanup()
+ok 31 - testSkipInCleanup(after)
+ok 32 - cleanupTestCase()
+1..32
+# tests 32
+# pass 16
+# fail 8
diff --git a/tests/auto/testlib/selftests/expected_crashes_4.txt b/tests/auto/testlib/selftests/expected_crashes_4.txt
new file mode 100644
index 0000000000..e0e4d27b0a
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_crashes_4.txt
@@ -0,0 +1,7 @@
+********* Start testing of tst_Crashes *********
+Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
+PASS : tst_Crashes::initTestCase()
+QFATAL : tst_Crashes::crash() Received signal 11
+ Function time: ms Total time: ms
+FAIL! : tst_Crashes::crash() Received a fatal error.
+ Loc: [Unknown file(0)]
diff --git a/tests/auto/testlib/selftests/expected_datatable.tap b/tests/auto/testlib/selftests/expected_datatable.tap
new file mode 100644
index 0000000000..8a3d473b6c
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_datatable.tap
@@ -0,0 +1,183 @@
+TAP version 13
+# tst_DataTable
+ok 1 - initTestCase()
+ok 2 - singleTestFunction1()
+ok 3 - singleTestFunction2()
+ok 4 - fiveTablePasses(fiveTablePasses_data 1)
+ok 5 - fiveTablePasses(fiveTablePasses_data 2)
+ok 6 - fiveTablePasses(fiveTablePasses_data 3)
+ok 7 - fiveTablePasses(fiveTablePasses_data 4)
+ok 8 - fiveTablePasses(fiveTablePasses_data 5)
+not ok 9 - fiveTableFailures(fiveTableFailures_data 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (test)
+ found: false (test)
+ expected: true (test)
+ actual: false (test)
+ at: tst_DataTable::fiveTableFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:78)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 78
+ ...
+not ok 10 - fiveTableFailures(fiveTableFailures_data 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (test)
+ found: false (test)
+ expected: true (test)
+ actual: false (test)
+ at: tst_DataTable::fiveTableFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:78)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 78
+ ...
+not ok 11 - fiveTableFailures(fiveTableFailures_data 3)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (test)
+ found: false (test)
+ expected: true (test)
+ actual: false (test)
+ at: tst_DataTable::fiveTableFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:78)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 78
+ ...
+not ok 12 - fiveTableFailures(fiveTableFailures_data 4)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (test)
+ found: false (test)
+ expected: true (test)
+ actual: false (test)
+ at: tst_DataTable::fiveTableFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:78)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 78
+ ...
+not ok 13 - fiveTableFailures(fiveTableFailures_data 5)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (test)
+ found: false (test)
+ expected: true (test)
+ actual: false (test)
+ at: tst_DataTable::fiveTableFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:78)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 78
+ ...
+not ok 14 - startsWithFailure(startsWithFailure_data 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (test)
+ found: false (test)
+ expected: true (test)
+ actual: false (test)
+ at: tst_DataTable::startsWithFailure() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:78)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 78
+ ...
+ok 15 - startsWithFailure(startsWithFailure_data 2)
+ok 16 - startsWithFailure(startsWithFailure_data 3)
+ok 17 - startsWithFailure(startsWithFailure_data 4)
+ok 18 - startsWithFailure(startsWithFailure_data 5)
+ok 19 - endsWithFailure(endsWithFailure 1)
+ok 20 - endsWithFailure(endsWithFailure 2)
+ok 21 - endsWithFailure(endsWithFailure 3)
+ok 22 - endsWithFailure(endsWithFailure 4)
+not ok 23 - endsWithFailure(endsWithFailure 5)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (test)
+ found: false (test)
+ expected: true (test)
+ actual: false (test)
+ at: tst_DataTable::endsWithFailure() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:78)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 78
+ ...
+ok 24 - failureInMiddle(failureInMiddle_data 1)
+ok 25 - failureInMiddle(failureInMiddle_data 2)
+not ok 26 - failureInMiddle(failureInMiddle_data 3)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (test)
+ found: false (test)
+ expected: true (test)
+ actual: false (test)
+ at: tst_DataTable::failureInMiddle() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:78)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 78
+ ...
+ok 27 - failureInMiddle(failureInMiddle_data 4)
+ok 28 - failureInMiddle(failureInMiddle_data 5)
+not ok 29 - fiveIsolatedFailures(fiveIsolatedFailures_data 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (!test)
+ found: false (!test)
+ expected: true (!test)
+ actual: false (!test)
+ at: tst_DataTable::fiveIsolatedFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:160)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 160
+ ...
+not ok 30 - fiveIsolatedFailures(fiveIsolatedFailures_data 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (!test)
+ found: false (!test)
+ expected: true (!test)
+ actual: false (!test)
+ at: tst_DataTable::fiveIsolatedFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:160)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 160
+ ...
+not ok 31 - fiveIsolatedFailures(fiveIsolatedFailures_data 3)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (!test)
+ found: false (!test)
+ expected: true (!test)
+ actual: false (!test)
+ at: tst_DataTable::fiveIsolatedFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:160)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 160
+ ...
+not ok 32 - fiveIsolatedFailures(fiveIsolatedFailures_data 4)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (!test)
+ found: false (!test)
+ expected: true (!test)
+ actual: false (!test)
+ at: tst_DataTable::fiveIsolatedFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:160)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 160
+ ...
+not ok 33 - fiveIsolatedFailures(fiveIsolatedFailures_data 5)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (!test)
+ found: false (!test)
+ expected: true (!test)
+ actual: false (!test)
+ at: tst_DataTable::fiveIsolatedFailures() (qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp:160)
+ file: qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp
+ line: 160
+ ...
+ok 34 - cleanupTestCase()
+1..34
+# tests 34
+# pass 21
+# fail 13
diff --git a/tests/auto/testlib/selftests/expected_datetime.tap b/tests/auto/testlib/selftests/expected_datetime.tap
new file mode 100644
index 0000000000..896aeafa37
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_datetime.tap
@@ -0,0 +1,46 @@
+TAP version 13
+# tst_DateTime
+ok 1 - initTestCase()
+not ok 2 - dateTime()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: 2000/05/03 04:03:04.000[UTC] (utc)
+ found: 2000/05/03 04:03:04.000[UTC+00:02] (local)
+ expected: 2000/05/03 04:03:04.000[UTC] (utc)
+ actual: 2000/05/03 04:03:04.000[UTC+00:02] (local)
+ at: tst_DateTime::dateTime() (qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp:52)
+ file: qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp
+ line: 52
+ ...
+ok 3 - qurl(empty urls)
+not ok 4 - qurl(empty rhs)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: Invalid URL: (operandB)
+ found: http://example.com (operandA)
+ expected: Invalid URL: (operandB)
+ actual: http://example.com (operandA)
+ at: tst_DateTime::qurl() (qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp:60)
+ file: qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp
+ line: 60
+ ...
+not ok 5 - qurl(empty lhs)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: http://example.com (operandB)
+ found: Invalid URL: (operandA)
+ expected: http://example.com (operandB)
+ actual: Invalid URL: (operandA)
+ at: tst_DateTime::qurl() (qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp:60)
+ file: qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp
+ line: 60
+ ...
+ok 6 - qurl(same urls)
+ok 7 - cleanupTestCase()
+1..7
+# tests 7
+# pass 4
+# fail 3
diff --git a/tests/auto/testlib/selftests/expected_exceptionthrow.tap b/tests/auto/testlib/selftests/expected_exceptionthrow.tap
new file mode 100644
index 0000000000..d8dbf173d6
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_exceptionthrow.tap
@@ -0,0 +1,14 @@
+TAP version 13
+# tst_Exception
+ok 1 - initTestCase()
+not ok 2 - throwException()
+ ---
+ # Caught unhandled exception
+ at: tst_Exception::throwException() (qtbase/src/testlib/qtestcase.cpp:1846)
+ file: qtbase/src/testlib/qtestcase.cpp
+ line: 1846
+ ...
+1..2
+# tests 2
+# pass 1
+# fail 1
diff --git a/tests/auto/testlib/selftests/expected_expectfail.tap b/tests/auto/testlib/selftests/expected_expectfail.tap
new file mode 100644
index 0000000000..0e5dc4d982
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_expectfail.tap
@@ -0,0 +1,96 @@
+TAP version 13
+# tst_ExpectFail
+ok 1 - initTestCase()
+# begin
+not ok 2 - xfailAndContinue() # TODO This should xfail
+ ---
+ at: tst_ExpectFail::xfailAndContinue() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:65)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 65
+ ...
+# after
+# begin
+not ok 3 - xfailAndAbort() # TODO This should xfail
+ ---
+ at: tst_ExpectFail::xfailAndAbort() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:73)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 73
+ ...
+not ok 4 - xfailTwice()
+ ---
+ # Already expecting a fail
+ at: tst_ExpectFail::xfailTwice() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:83)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 83
+ ...
+not ok 5 - xfailWithQString() # TODO A string
+ ---
+ at: tst_ExpectFail::xfailWithQString() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:92)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 92
+ ...
+not ok 5 - xfailWithQString() # TODO Bug 5 (The message)
+ ---
+ at: tst_ExpectFail::xfailWithQString() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:97)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 97
+ ...
+ok 6 - xfailDataDrivenWithQVerify(Pass 1)
+ok 7 - xfailDataDrivenWithQVerify(Pass 2)
+not ok 8 - xfailDataDrivenWithQVerify(Abort) # TODO This test should xfail
+ ---
+ at: tst_ExpectFail::xfailDataDrivenWithQVerify() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:126)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 126
+ ...
+not ok 9 - xfailDataDrivenWithQVerify(Continue) # TODO This test should xfail
+ ---
+ at: tst_ExpectFail::xfailDataDrivenWithQVerify() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:126)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 126
+ ...
+ok 10 - xfailDataDrivenWithQCompare(Pass 1)
+ok 11 - xfailDataDrivenWithQCompare(Pass 2)
+not ok 12 - xfailDataDrivenWithQCompare(Abort) # TODO This test should xfail
+ ---
+ at: tst_ExpectFail::xfailDataDrivenWithQCompare() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:160)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 160
+ ...
+not ok 13 - xfailDataDrivenWithQCompare(Continue) # TODO This test should xfail
+ ---
+ at: tst_ExpectFail::xfailDataDrivenWithQCompare() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:160)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 160
+ ...
+ok 14 - xfailOnWrongRow(right row)
+not ok 15 - xfailOnAnyRow(first row) # TODO This test should xfail
+ ---
+ at: tst_ExpectFail::xfailOnAnyRow() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:195)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 195
+ ...
+not ok 16 - xfailOnAnyRow(second row) # TODO This test should xfail
+ ---
+ at: tst_ExpectFail::xfailOnAnyRow() (qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp:195)
+ file: qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp
+ line: 195
+ ...
+not ok 17 - xfailWithoutVerify(first row)
+ ---
+ # QEXPECT_FAIL was called without any subsequent verification statements
+ ...
+not ok 18 - xfailWithoutVerify(second row)
+ ---
+ # QEXPECT_FAIL was called without any subsequent verification statements
+ ...
+ok 19 - xpass() # TODO 'true' returned TRUE unexpectedly. ()
+ok 20 - xpassDataDrivenWithQVerify(XPass) # TODO 'true' returned TRUE unexpectedly. ()
+ok 21 - xpassDataDrivenWithQVerify(Pass)
+ok 22 - xpassDataDrivenWithQCompare(XPass) # TODO QCOMPARE(1, 1) returned TRUE unexpectedly.
+ok 23 - xpassDataDrivenWithQCompare(Pass)
+ok 24 - cleanupTestCase()
+1..24
+# tests 24
+# pass 18
+# fail 6
diff --git a/tests/auto/testlib/selftests/expected_failcleanup.tap b/tests/auto/testlib/selftests/expected_failcleanup.tap
new file mode 100644
index 0000000000..2098cc1e17
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_failcleanup.tap
@@ -0,0 +1,20 @@
+TAP version 13
+# tst_FailCleanup
+ok 1 - initTestCase()
+ok 2 - aTestFunction()
+not ok 3 - cleanupTestCase()
+ ---
+ type: QVERIFY
+ message: Fail inside cleanupTestCase
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_FailCleanup::cleanupTestCase() (qtbase/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp:46)
+ file: qtbase/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp
+ line: 46
+ ...
+1..3
+# tests 3
+# pass 2
+# fail 1
diff --git a/tests/auto/testlib/selftests/expected_failinit.tap b/tests/auto/testlib/selftests/expected_failinit.tap
new file mode 100644
index 0000000000..d99a71fd51
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_failinit.tap
@@ -0,0 +1,19 @@
+TAP version 13
+# tst_FailInit
+not ok 1 - initTestCase()
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_FailInit::initTestCase() (qtbase/tests/auto/testlib/selftests/failinit/tst_failinit.cpp:42)
+ file: qtbase/tests/auto/testlib/selftests/failinit/tst_failinit.cpp
+ line: 42
+ ...
+ok 2 - cleanupTestCase()
+1..2
+# tests 2
+# pass 1
+# fail 1
diff --git a/tests/auto/testlib/selftests/expected_failinitdata.tap b/tests/auto/testlib/selftests/expected_failinitdata.tap
new file mode 100644
index 0000000000..27bdda5a13
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_failinitdata.tap
@@ -0,0 +1,18 @@
+TAP version 13
+# tst_FailInitData
+not ok 1 - initTestCase()
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_FailInitData::initTestCase() (qtbase/tests/auto/testlib/selftests/failinitdata/tst_failinitdata.cpp:43)
+ file: qtbase/tests/auto/testlib/selftests/failinitdata/tst_failinitdata.cpp
+ line: 43
+ ...
+1..1
+# tests 1
+# pass 0
+# fail 1
diff --git a/tests/auto/testlib/selftests/expected_fetchbogus.tap b/tests/auto/testlib/selftests/expected_fetchbogus.tap
new file mode 100644
index 0000000000..c6761b2301
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_fetchbogus.tap
@@ -0,0 +1,15 @@
+TAP version 13
+# tst_FetchBogus
+ok 1 - initTestCase()
+# QFETCH: Requested testdata 'bubu' not available, check your _data function.
+not ok 2 - fetchBogus(foo)
+ ---
+ # Received a fatal error.
+ at: tst_FetchBogus::fetchBogus() (Unknown file:0)
+ file: Unknown file
+ line: 0
+ ...
+1..2
+# tests 2
+# pass 1
+# fail 1
diff --git a/tests/auto/testlib/selftests/expected_findtestdata.tap b/tests/auto/testlib/selftests/expected_findtestdata.tap
new file mode 100644
index 0000000000..0fb38d2822
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_findtestdata.tap
@@ -0,0 +1,10 @@
+TAP version 13
+# FindTestData
+ok 1 - initTestCase()
+# testdata testfile could not be located!
+ok 2 - paths()
+ok 3 - cleanupTestCase()
+1..3
+# tests 3
+# pass 3
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_float.tap b/tests/auto/testlib/selftests/expected_float.tap
new file mode 100644
index 0000000000..fae2dc9796
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_float.tap
@@ -0,0 +1,82 @@
+TAP version 13
+# tst_float
+ok 1 - initTestCase()
+ok 2 - floatComparisons(should SUCCEED 1)
+not ok 3 - floatComparisons(should FAIL 1)
+ ---
+ type: QCOMPARE
+ message: Compared floats are not the same (fuzzy compare)
+ wanted: 3 (operandRight)
+ found: 1 (operandLeft)
+ expected: 3 (operandRight)
+ actual: 1 (operandLeft)
+ at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48)
+ file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp
+ line: 48
+ ...
+not ok 4 - floatComparisons(should FAIL 2)
+ ---
+ type: QCOMPARE
+ message: Compared floats are not the same (fuzzy compare)
+ wanted: 3e-07 (operandRight)
+ found: 1e-07 (operandLeft)
+ expected: 3e-07 (operandRight)
+ actual: 1e-07 (operandLeft)
+ at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48)
+ file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp
+ line: 48
+ ...
+not ok 5 - floatComparisons(should FAIL 3)
+ ---
+ type: QCOMPARE
+ message: Compared floats are not the same (fuzzy compare)
+ wanted: 99999 (operandRight)
+ found: 99998 (operandLeft)
+ expected: 99999 (operandRight)
+ actual: 99998 (operandLeft)
+ at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48)
+ file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp
+ line: 48
+ ...
+ok 6 - floatComparisons(should SUCCEED 2)
+not ok 7 - compareFloatTests(1e0)
+ ---
+ type: QCOMPARE
+ message: Compared floats are not the same (fuzzy compare)
+ wanted: 3 (t3)
+ found: 1 (t1)
+ expected: 3 (t3)
+ actual: 1 (t1)
+ at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96)
+ file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp
+ line: 96
+ ...
+not ok 8 - compareFloatTests(1e-7)
+ ---
+ type: QCOMPARE
+ message: Compared floats are not the same (fuzzy compare)
+ wanted: 3e-07 (t3)
+ found: 1e-07 (t1)
+ expected: 3e-07 (t3)
+ actual: 1e-07 (t1)
+ at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96)
+ file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp
+ line: 96
+ ...
+not ok 9 - compareFloatTests(1e+7)
+ ---
+ type: QCOMPARE
+ message: Compared floats are not the same (fuzzy compare)
+ wanted: 3e+07 (t3)
+ found: 1e+07 (t1)
+ expected: 3e+07 (t3)
+ actual: 1e+07 (t1)
+ at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96)
+ file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp
+ line: 96
+ ...
+ok 10 - cleanupTestCase()
+1..10
+# tests 10
+# pass 4
+# fail 6
diff --git a/tests/auto/testlib/selftests/expected_globaldata.tap b/tests/auto/testlib/selftests/expected_globaldata.tap
new file mode 100644
index 0000000000..580cf3a7a8
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_globaldata.tap
@@ -0,0 +1,52 @@
+TAP version 13
+# tst_globaldata
+# initTestCase initTestCase (null)
+ok 1 - initTestCase()
+# init testGlobal local 1
+# global: false
+# local: false
+# cleanup testGlobal local 1
+ok 2 - testGlobal(1:local 1)
+# init testGlobal local 2
+# global: false
+# local: true
+# cleanup testGlobal local 2
+ok 3 - testGlobal(1:local 2)
+# init testGlobal local 1
+# global: true
+# local: false
+# cleanup testGlobal local 1
+ok 4 - testGlobal(2:local 1)
+# init testGlobal local 2
+# global: true
+# local: true
+# cleanup testGlobal local 2
+ok 5 - testGlobal(2:local 2)
+ok 6 - skip(1) # SKIP skipping
+# init skipLocal local 1
+ok 7 - skipLocal(1:local 1) # SKIP skipping
+# cleanup skipLocal local 1
+# init skipLocal local 2
+ok 8 - skipLocal(1:local 2) # SKIP skipping
+# cleanup skipLocal local 2
+# init skipSingle local 1
+# global: false local: false
+# cleanup skipSingle local 1
+ok 9 - skipSingle(1:local 1)
+# init skipSingle local 2
+# global: false local: true
+# cleanup skipSingle local 2
+ok 10 - skipSingle(1:local 2)
+# init skipSingle local 1
+ok 11 - skipSingle(2:local 1) # SKIP skipping
+# cleanup skipSingle local 1
+# init skipSingle local 2
+# global: true local: true
+# cleanup skipSingle local 2
+ok 12 - skipSingle(2:local 2)
+# cleanupTestCase cleanupTestCase (null)
+ok 13 - cleanupTestCase()
+1..13
+# tests 13
+# pass 9
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_keyboard.lightxml b/tests/auto/testlib/selftests/expected_keyboard.lightxml
new file mode 100644
index 0000000000..5699fba3bf
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_keyboard.lightxml
@@ -0,0 +1,18 @@
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QtBuild/>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="keyPressAndRelease">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_keyboard.tap b/tests/auto/testlib/selftests/expected_keyboard.tap
new file mode 100644
index 0000000000..0725434f8c
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_keyboard.tap
@@ -0,0 +1,9 @@
+TAP version 13
+# tst_Keyboard
+ok 1 - initTestCase()
+ok 2 - keyPressAndRelease()
+ok 3 - cleanupTestCase()
+1..3
+# tests 3
+# pass 3
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_keyboard.teamcity b/tests/auto/testlib/selftests/expected_keyboard.teamcity
new file mode 100644
index 0000000000..dc01f86ff0
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_keyboard.teamcity
@@ -0,0 +1,8 @@
+##teamcity[testSuiteStarted name='tst_Keyboard' flowId='tst_Keyboard']
+##teamcity[testStarted name='initTestCase()' flowId='tst_Keyboard']
+##teamcity[testFinished name='initTestCase()' flowId='tst_Keyboard']
+##teamcity[testStarted name='keyPressAndRelease()' flowId='tst_Keyboard']
+##teamcity[testFinished name='keyPressAndRelease()' flowId='tst_Keyboard']
+##teamcity[testStarted name='cleanupTestCase()' flowId='tst_Keyboard']
+##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Keyboard']
+##teamcity[testSuiteFinished name='tst_Keyboard' flowId='tst_Keyboard']
diff --git a/tests/auto/testlib/selftests/expected_keyboard.txt b/tests/auto/testlib/selftests/expected_keyboard.txt
new file mode 100644
index 0000000000..13b7c70672
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_keyboard.txt
@@ -0,0 +1,7 @@
+********* Start testing of tst_Keyboard *********
+Config: Using QtTest library
+PASS : tst_Keyboard::initTestCase()
+PASS : tst_Keyboard::keyPressAndRelease()
+PASS : tst_Keyboard::cleanupTestCase()
+Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
+********* Finished testing of tst_Keyboard *********
diff --git a/tests/auto/testlib/selftests/expected_keyboard.xml b/tests/auto/testlib/selftests/expected_keyboard.xml
new file mode 100644
index 0000000000..f5ad1b2287
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_keyboard.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TestCase name="tst_Keyboard">
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QtBuild/>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="keyPressAndRelease">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<Duration msecs="0"/>
+</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_keyboard.xunitxml b/tests/auto/testlib/selftests/expected_keyboard.xunitxml
new file mode 100644
index 0000000000..93b5f7bfff
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_keyboard.xunitxml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite errors="0" failures="0" tests="3" name="tst_Keyboard">
+ <properties>
+ <property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
+ <property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
+ <property value="" name="QtBuild"/>
+ </properties>
+ <testcase result="pass" name="initTestCase"/>
+ <testcase result="pass" name="keyPressAndRelease"/>
+ <testcase result="pass" name="cleanupTestCase"/>
+ <system-err/>
+</testsuite>
diff --git a/tests/auto/testlib/selftests/expected_longstring.tap b/tests/auto/testlib/selftests/expected_longstring.tap
new file mode 100644
index 0000000000..ac870f2d53
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_longstring.tap
@@ -0,0 +1,23 @@
+TAP version 13
+# tst_LongString
+ok 1 - initTestCase()
+not ok 2 - failWithLongString()
+ ---
+ # Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.
+
+Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia.
+
+Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum. Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi.
+
+Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis.
+
+Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
+ at: tst_LongString::failWithLongString() (qtbase/tests/auto/testlib/selftests/longstring/tst_longstring.cpp:54)
+ file: qtbase/tests/auto/testlib/selftests/longstring/tst_longstring.cpp
+ line: 54
+ ...
+ok 3 - cleanupTestCase()
+1..3
+# tests 3
+# pass 2
+# fail 1
diff --git a/tests/auto/testlib/selftests/expected_maxwarnings.tap b/tests/auto/testlib/selftests/expected_maxwarnings.tap
new file mode 100644
index 0000000000..57bfbd8f8d
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_maxwarnings.tap
@@ -0,0 +1,2011 @@
+TAP version 13
+# MaxWarnings
+ok 1 - initTestCase()
+# 0
+# 1
+# 2
+# 3
+# 4
+# 5
+# 6
+# 7
+# 8
+# 9
+# 10
+# 11
+# 12
+# 13
+# 14
+# 15
+# 16
+# 17
+# 18
+# 19
+# 20
+# 21
+# 22
+# 23
+# 24
+# 25
+# 26
+# 27
+# 28
+# 29
+# 30
+# 31
+# 32
+# 33
+# 34
+# 35
+# 36
+# 37
+# 38
+# 39
+# 40
+# 41
+# 42
+# 43
+# 44
+# 45
+# 46
+# 47
+# 48
+# 49
+# 50
+# 51
+# 52
+# 53
+# 54
+# 55
+# 56
+# 57
+# 58
+# 59
+# 60
+# 61
+# 62
+# 63
+# 64
+# 65
+# 66
+# 67
+# 68
+# 69
+# 70
+# 71
+# 72
+# 73
+# 74
+# 75
+# 76
+# 77
+# 78
+# 79
+# 80
+# 81
+# 82
+# 83
+# 84
+# 85
+# 86
+# 87
+# 88
+# 89
+# 90
+# 91
+# 92
+# 93
+# 94
+# 95
+# 96
+# 97
+# 98
+# 99
+# 100
+# 101
+# 102
+# 103
+# 104
+# 105
+# 106
+# 107
+# 108
+# 109
+# 110
+# 111
+# 112
+# 113
+# 114
+# 115
+# 116
+# 117
+# 118
+# 119
+# 120
+# 121
+# 122
+# 123
+# 124
+# 125
+# 126
+# 127
+# 128
+# 129
+# 130
+# 131
+# 132
+# 133
+# 134
+# 135
+# 136
+# 137
+# 138
+# 139
+# 140
+# 141
+# 142
+# 143
+# 144
+# 145
+# 146
+# 147
+# 148
+# 149
+# 150
+# 151
+# 152
+# 153
+# 154
+# 155
+# 156
+# 157
+# 158
+# 159
+# 160
+# 161
+# 162
+# 163
+# 164
+# 165
+# 166
+# 167
+# 168
+# 169
+# 170
+# 171
+# 172
+# 173
+# 174
+# 175
+# 176
+# 177
+# 178
+# 179
+# 180
+# 181
+# 182
+# 183
+# 184
+# 185
+# 186
+# 187
+# 188
+# 189
+# 190
+# 191
+# 192
+# 193
+# 194
+# 195
+# 196
+# 197
+# 198
+# 199
+# 200
+# 201
+# 202
+# 203
+# 204
+# 205
+# 206
+# 207
+# 208
+# 209
+# 210
+# 211
+# 212
+# 213
+# 214
+# 215
+# 216
+# 217
+# 218
+# 219
+# 220
+# 221
+# 222
+# 223
+# 224
+# 225
+# 226
+# 227
+# 228
+# 229
+# 230
+# 231
+# 232
+# 233
+# 234
+# 235
+# 236
+# 237
+# 238
+# 239
+# 240
+# 241
+# 242
+# 243
+# 244
+# 245
+# 246
+# 247
+# 248
+# 249
+# 250
+# 251
+# 252
+# 253
+# 254
+# 255
+# 256
+# 257
+# 258
+# 259
+# 260
+# 261
+# 262
+# 263
+# 264
+# 265
+# 266
+# 267
+# 268
+# 269
+# 270
+# 271
+# 272
+# 273
+# 274
+# 275
+# 276
+# 277
+# 278
+# 279
+# 280
+# 281
+# 282
+# 283
+# 284
+# 285
+# 286
+# 287
+# 288
+# 289
+# 290
+# 291
+# 292
+# 293
+# 294
+# 295
+# 296
+# 297
+# 298
+# 299
+# 300
+# 301
+# 302
+# 303
+# 304
+# 305
+# 306
+# 307
+# 308
+# 309
+# 310
+# 311
+# 312
+# 313
+# 314
+# 315
+# 316
+# 317
+# 318
+# 319
+# 320
+# 321
+# 322
+# 323
+# 324
+# 325
+# 326
+# 327
+# 328
+# 329
+# 330
+# 331
+# 332
+# 333
+# 334
+# 335
+# 336
+# 337
+# 338
+# 339
+# 340
+# 341
+# 342
+# 343
+# 344
+# 345
+# 346
+# 347
+# 348
+# 349
+# 350
+# 351
+# 352
+# 353
+# 354
+# 355
+# 356
+# 357
+# 358
+# 359
+# 360
+# 361
+# 362
+# 363
+# 364
+# 365
+# 366
+# 367
+# 368
+# 369
+# 370
+# 371
+# 372
+# 373
+# 374
+# 375
+# 376
+# 377
+# 378
+# 379
+# 380
+# 381
+# 382
+# 383
+# 384
+# 385
+# 386
+# 387
+# 388
+# 389
+# 390
+# 391
+# 392
+# 393
+# 394
+# 395
+# 396
+# 397
+# 398
+# 399
+# 400
+# 401
+# 402
+# 403
+# 404
+# 405
+# 406
+# 407
+# 408
+# 409
+# 410
+# 411
+# 412
+# 413
+# 414
+# 415
+# 416
+# 417
+# 418
+# 419
+# 420
+# 421
+# 422
+# 423
+# 424
+# 425
+# 426
+# 427
+# 428
+# 429
+# 430
+# 431
+# 432
+# 433
+# 434
+# 435
+# 436
+# 437
+# 438
+# 439
+# 440
+# 441
+# 442
+# 443
+# 444
+# 445
+# 446
+# 447
+# 448
+# 449
+# 450
+# 451
+# 452
+# 453
+# 454
+# 455
+# 456
+# 457
+# 458
+# 459
+# 460
+# 461
+# 462
+# 463
+# 464
+# 465
+# 466
+# 467
+# 468
+# 469
+# 470
+# 471
+# 472
+# 473
+# 474
+# 475
+# 476
+# 477
+# 478
+# 479
+# 480
+# 481
+# 482
+# 483
+# 484
+# 485
+# 486
+# 487
+# 488
+# 489
+# 490
+# 491
+# 492
+# 493
+# 494
+# 495
+# 496
+# 497
+# 498
+# 499
+# 500
+# 501
+# 502
+# 503
+# 504
+# 505
+# 506
+# 507
+# 508
+# 509
+# 510
+# 511
+# 512
+# 513
+# 514
+# 515
+# 516
+# 517
+# 518
+# 519
+# 520
+# 521
+# 522
+# 523
+# 524
+# 525
+# 526
+# 527
+# 528
+# 529
+# 530
+# 531
+# 532
+# 533
+# 534
+# 535
+# 536
+# 537
+# 538
+# 539
+# 540
+# 541
+# 542
+# 543
+# 544
+# 545
+# 546
+# 547
+# 548
+# 549
+# 550
+# 551
+# 552
+# 553
+# 554
+# 555
+# 556
+# 557
+# 558
+# 559
+# 560
+# 561
+# 562
+# 563
+# 564
+# 565
+# 566
+# 567
+# 568
+# 569
+# 570
+# 571
+# 572
+# 573
+# 574
+# 575
+# 576
+# 577
+# 578
+# 579
+# 580
+# 581
+# 582
+# 583
+# 584
+# 585
+# 586
+# 587
+# 588
+# 589
+# 590
+# 591
+# 592
+# 593
+# 594
+# 595
+# 596
+# 597
+# 598
+# 599
+# 600
+# 601
+# 602
+# 603
+# 604
+# 605
+# 606
+# 607
+# 608
+# 609
+# 610
+# 611
+# 612
+# 613
+# 614
+# 615
+# 616
+# 617
+# 618
+# 619
+# 620
+# 621
+# 622
+# 623
+# 624
+# 625
+# 626
+# 627
+# 628
+# 629
+# 630
+# 631
+# 632
+# 633
+# 634
+# 635
+# 636
+# 637
+# 638
+# 639
+# 640
+# 641
+# 642
+# 643
+# 644
+# 645
+# 646
+# 647
+# 648
+# 649
+# 650
+# 651
+# 652
+# 653
+# 654
+# 655
+# 656
+# 657
+# 658
+# 659
+# 660
+# 661
+# 662
+# 663
+# 664
+# 665
+# 666
+# 667
+# 668
+# 669
+# 670
+# 671
+# 672
+# 673
+# 674
+# 675
+# 676
+# 677
+# 678
+# 679
+# 680
+# 681
+# 682
+# 683
+# 684
+# 685
+# 686
+# 687
+# 688
+# 689
+# 690
+# 691
+# 692
+# 693
+# 694
+# 695
+# 696
+# 697
+# 698
+# 699
+# 700
+# 701
+# 702
+# 703
+# 704
+# 705
+# 706
+# 707
+# 708
+# 709
+# 710
+# 711
+# 712
+# 713
+# 714
+# 715
+# 716
+# 717
+# 718
+# 719
+# 720
+# 721
+# 722
+# 723
+# 724
+# 725
+# 726
+# 727
+# 728
+# 729
+# 730
+# 731
+# 732
+# 733
+# 734
+# 735
+# 736
+# 737
+# 738
+# 739
+# 740
+# 741
+# 742
+# 743
+# 744
+# 745
+# 746
+# 747
+# 748
+# 749
+# 750
+# 751
+# 752
+# 753
+# 754
+# 755
+# 756
+# 757
+# 758
+# 759
+# 760
+# 761
+# 762
+# 763
+# 764
+# 765
+# 766
+# 767
+# 768
+# 769
+# 770
+# 771
+# 772
+# 773
+# 774
+# 775
+# 776
+# 777
+# 778
+# 779
+# 780
+# 781
+# 782
+# 783
+# 784
+# 785
+# 786
+# 787
+# 788
+# 789
+# 790
+# 791
+# 792
+# 793
+# 794
+# 795
+# 796
+# 797
+# 798
+# 799
+# 800
+# 801
+# 802
+# 803
+# 804
+# 805
+# 806
+# 807
+# 808
+# 809
+# 810
+# 811
+# 812
+# 813
+# 814
+# 815
+# 816
+# 817
+# 818
+# 819
+# 820
+# 821
+# 822
+# 823
+# 824
+# 825
+# 826
+# 827
+# 828
+# 829
+# 830
+# 831
+# 832
+# 833
+# 834
+# 835
+# 836
+# 837
+# 838
+# 839
+# 840
+# 841
+# 842
+# 843
+# 844
+# 845
+# 846
+# 847
+# 848
+# 849
+# 850
+# 851
+# 852
+# 853
+# 854
+# 855
+# 856
+# 857
+# 858
+# 859
+# 860
+# 861
+# 862
+# 863
+# 864
+# 865
+# 866
+# 867
+# 868
+# 869
+# 870
+# 871
+# 872
+# 873
+# 874
+# 875
+# 876
+# 877
+# 878
+# 879
+# 880
+# 881
+# 882
+# 883
+# 884
+# 885
+# 886
+# 887
+# 888
+# 889
+# 890
+# 891
+# 892
+# 893
+# 894
+# 895
+# 896
+# 897
+# 898
+# 899
+# 900
+# 901
+# 902
+# 903
+# 904
+# 905
+# 906
+# 907
+# 908
+# 909
+# 910
+# 911
+# 912
+# 913
+# 914
+# 915
+# 916
+# 917
+# 918
+# 919
+# 920
+# 921
+# 922
+# 923
+# 924
+# 925
+# 926
+# 927
+# 928
+# 929
+# 930
+# 931
+# 932
+# 933
+# 934
+# 935
+# 936
+# 937
+# 938
+# 939
+# 940
+# 941
+# 942
+# 943
+# 944
+# 945
+# 946
+# 947
+# 948
+# 949
+# 950
+# 951
+# 952
+# 953
+# 954
+# 955
+# 956
+# 957
+# 958
+# 959
+# 960
+# 961
+# 962
+# 963
+# 964
+# 965
+# 966
+# 967
+# 968
+# 969
+# 970
+# 971
+# 972
+# 973
+# 974
+# 975
+# 976
+# 977
+# 978
+# 979
+# 980
+# 981
+# 982
+# 983
+# 984
+# 985
+# 986
+# 987
+# 988
+# 989
+# 990
+# 991
+# 992
+# 993
+# 994
+# 995
+# 996
+# 997
+# 998
+# 999
+# 1000
+# 1001
+# 1002
+# 1003
+# 1004
+# 1005
+# 1006
+# 1007
+# 1008
+# 1009
+# 1010
+# 1011
+# 1012
+# 1013
+# 1014
+# 1015
+# 1016
+# 1017
+# 1018
+# 1019
+# 1020
+# 1021
+# 1022
+# 1023
+# 1024
+# 1025
+# 1026
+# 1027
+# 1028
+# 1029
+# 1030
+# 1031
+# 1032
+# 1033
+# 1034
+# 1035
+# 1036
+# 1037
+# 1038
+# 1039
+# 1040
+# 1041
+# 1042
+# 1043
+# 1044
+# 1045
+# 1046
+# 1047
+# 1048
+# 1049
+# 1050
+# 1051
+# 1052
+# 1053
+# 1054
+# 1055
+# 1056
+# 1057
+# 1058
+# 1059
+# 1060
+# 1061
+# 1062
+# 1063
+# 1064
+# 1065
+# 1066
+# 1067
+# 1068
+# 1069
+# 1070
+# 1071
+# 1072
+# 1073
+# 1074
+# 1075
+# 1076
+# 1077
+# 1078
+# 1079
+# 1080
+# 1081
+# 1082
+# 1083
+# 1084
+# 1085
+# 1086
+# 1087
+# 1088
+# 1089
+# 1090
+# 1091
+# 1092
+# 1093
+# 1094
+# 1095
+# 1096
+# 1097
+# 1098
+# 1099
+# 1100
+# 1101
+# 1102
+# 1103
+# 1104
+# 1105
+# 1106
+# 1107
+# 1108
+# 1109
+# 1110
+# 1111
+# 1112
+# 1113
+# 1114
+# 1115
+# 1116
+# 1117
+# 1118
+# 1119
+# 1120
+# 1121
+# 1122
+# 1123
+# 1124
+# 1125
+# 1126
+# 1127
+# 1128
+# 1129
+# 1130
+# 1131
+# 1132
+# 1133
+# 1134
+# 1135
+# 1136
+# 1137
+# 1138
+# 1139
+# 1140
+# 1141
+# 1142
+# 1143
+# 1144
+# 1145
+# 1146
+# 1147
+# 1148
+# 1149
+# 1150
+# 1151
+# 1152
+# 1153
+# 1154
+# 1155
+# 1156
+# 1157
+# 1158
+# 1159
+# 1160
+# 1161
+# 1162
+# 1163
+# 1164
+# 1165
+# 1166
+# 1167
+# 1168
+# 1169
+# 1170
+# 1171
+# 1172
+# 1173
+# 1174
+# 1175
+# 1176
+# 1177
+# 1178
+# 1179
+# 1180
+# 1181
+# 1182
+# 1183
+# 1184
+# 1185
+# 1186
+# 1187
+# 1188
+# 1189
+# 1190
+# 1191
+# 1192
+# 1193
+# 1194
+# 1195
+# 1196
+# 1197
+# 1198
+# 1199
+# 1200
+# 1201
+# 1202
+# 1203
+# 1204
+# 1205
+# 1206
+# 1207
+# 1208
+# 1209
+# 1210
+# 1211
+# 1212
+# 1213
+# 1214
+# 1215
+# 1216
+# 1217
+# 1218
+# 1219
+# 1220
+# 1221
+# 1222
+# 1223
+# 1224
+# 1225
+# 1226
+# 1227
+# 1228
+# 1229
+# 1230
+# 1231
+# 1232
+# 1233
+# 1234
+# 1235
+# 1236
+# 1237
+# 1238
+# 1239
+# 1240
+# 1241
+# 1242
+# 1243
+# 1244
+# 1245
+# 1246
+# 1247
+# 1248
+# 1249
+# 1250
+# 1251
+# 1252
+# 1253
+# 1254
+# 1255
+# 1256
+# 1257
+# 1258
+# 1259
+# 1260
+# 1261
+# 1262
+# 1263
+# 1264
+# 1265
+# 1266
+# 1267
+# 1268
+# 1269
+# 1270
+# 1271
+# 1272
+# 1273
+# 1274
+# 1275
+# 1276
+# 1277
+# 1278
+# 1279
+# 1280
+# 1281
+# 1282
+# 1283
+# 1284
+# 1285
+# 1286
+# 1287
+# 1288
+# 1289
+# 1290
+# 1291
+# 1292
+# 1293
+# 1294
+# 1295
+# 1296
+# 1297
+# 1298
+# 1299
+# 1300
+# 1301
+# 1302
+# 1303
+# 1304
+# 1305
+# 1306
+# 1307
+# 1308
+# 1309
+# 1310
+# 1311
+# 1312
+# 1313
+# 1314
+# 1315
+# 1316
+# 1317
+# 1318
+# 1319
+# 1320
+# 1321
+# 1322
+# 1323
+# 1324
+# 1325
+# 1326
+# 1327
+# 1328
+# 1329
+# 1330
+# 1331
+# 1332
+# 1333
+# 1334
+# 1335
+# 1336
+# 1337
+# 1338
+# 1339
+# 1340
+# 1341
+# 1342
+# 1343
+# 1344
+# 1345
+# 1346
+# 1347
+# 1348
+# 1349
+# 1350
+# 1351
+# 1352
+# 1353
+# 1354
+# 1355
+# 1356
+# 1357
+# 1358
+# 1359
+# 1360
+# 1361
+# 1362
+# 1363
+# 1364
+# 1365
+# 1366
+# 1367
+# 1368
+# 1369
+# 1370
+# 1371
+# 1372
+# 1373
+# 1374
+# 1375
+# 1376
+# 1377
+# 1378
+# 1379
+# 1380
+# 1381
+# 1382
+# 1383
+# 1384
+# 1385
+# 1386
+# 1387
+# 1388
+# 1389
+# 1390
+# 1391
+# 1392
+# 1393
+# 1394
+# 1395
+# 1396
+# 1397
+# 1398
+# 1399
+# 1400
+# 1401
+# 1402
+# 1403
+# 1404
+# 1405
+# 1406
+# 1407
+# 1408
+# 1409
+# 1410
+# 1411
+# 1412
+# 1413
+# 1414
+# 1415
+# 1416
+# 1417
+# 1418
+# 1419
+# 1420
+# 1421
+# 1422
+# 1423
+# 1424
+# 1425
+# 1426
+# 1427
+# 1428
+# 1429
+# 1430
+# 1431
+# 1432
+# 1433
+# 1434
+# 1435
+# 1436
+# 1437
+# 1438
+# 1439
+# 1440
+# 1441
+# 1442
+# 1443
+# 1444
+# 1445
+# 1446
+# 1447
+# 1448
+# 1449
+# 1450
+# 1451
+# 1452
+# 1453
+# 1454
+# 1455
+# 1456
+# 1457
+# 1458
+# 1459
+# 1460
+# 1461
+# 1462
+# 1463
+# 1464
+# 1465
+# 1466
+# 1467
+# 1468
+# 1469
+# 1470
+# 1471
+# 1472
+# 1473
+# 1474
+# 1475
+# 1476
+# 1477
+# 1478
+# 1479
+# 1480
+# 1481
+# 1482
+# 1483
+# 1484
+# 1485
+# 1486
+# 1487
+# 1488
+# 1489
+# 1490
+# 1491
+# 1492
+# 1493
+# 1494
+# 1495
+# 1496
+# 1497
+# 1498
+# 1499
+# 1500
+# 1501
+# 1502
+# 1503
+# 1504
+# 1505
+# 1506
+# 1507
+# 1508
+# 1509
+# 1510
+# 1511
+# 1512
+# 1513
+# 1514
+# 1515
+# 1516
+# 1517
+# 1518
+# 1519
+# 1520
+# 1521
+# 1522
+# 1523
+# 1524
+# 1525
+# 1526
+# 1527
+# 1528
+# 1529
+# 1530
+# 1531
+# 1532
+# 1533
+# 1534
+# 1535
+# 1536
+# 1537
+# 1538
+# 1539
+# 1540
+# 1541
+# 1542
+# 1543
+# 1544
+# 1545
+# 1546
+# 1547
+# 1548
+# 1549
+# 1550
+# 1551
+# 1552
+# 1553
+# 1554
+# 1555
+# 1556
+# 1557
+# 1558
+# 1559
+# 1560
+# 1561
+# 1562
+# 1563
+# 1564
+# 1565
+# 1566
+# 1567
+# 1568
+# 1569
+# 1570
+# 1571
+# 1572
+# 1573
+# 1574
+# 1575
+# 1576
+# 1577
+# 1578
+# 1579
+# 1580
+# 1581
+# 1582
+# 1583
+# 1584
+# 1585
+# 1586
+# 1587
+# 1588
+# 1589
+# 1590
+# 1591
+# 1592
+# 1593
+# 1594
+# 1595
+# 1596
+# 1597
+# 1598
+# 1599
+# 1600
+# 1601
+# 1602
+# 1603
+# 1604
+# 1605
+# 1606
+# 1607
+# 1608
+# 1609
+# 1610
+# 1611
+# 1612
+# 1613
+# 1614
+# 1615
+# 1616
+# 1617
+# 1618
+# 1619
+# 1620
+# 1621
+# 1622
+# 1623
+# 1624
+# 1625
+# 1626
+# 1627
+# 1628
+# 1629
+# 1630
+# 1631
+# 1632
+# 1633
+# 1634
+# 1635
+# 1636
+# 1637
+# 1638
+# 1639
+# 1640
+# 1641
+# 1642
+# 1643
+# 1644
+# 1645
+# 1646
+# 1647
+# 1648
+# 1649
+# 1650
+# 1651
+# 1652
+# 1653
+# 1654
+# 1655
+# 1656
+# 1657
+# 1658
+# 1659
+# 1660
+# 1661
+# 1662
+# 1663
+# 1664
+# 1665
+# 1666
+# 1667
+# 1668
+# 1669
+# 1670
+# 1671
+# 1672
+# 1673
+# 1674
+# 1675
+# 1676
+# 1677
+# 1678
+# 1679
+# 1680
+# 1681
+# 1682
+# 1683
+# 1684
+# 1685
+# 1686
+# 1687
+# 1688
+# 1689
+# 1690
+# 1691
+# 1692
+# 1693
+# 1694
+# 1695
+# 1696
+# 1697
+# 1698
+# 1699
+# 1700
+# 1701
+# 1702
+# 1703
+# 1704
+# 1705
+# 1706
+# 1707
+# 1708
+# 1709
+# 1710
+# 1711
+# 1712
+# 1713
+# 1714
+# 1715
+# 1716
+# 1717
+# 1718
+# 1719
+# 1720
+# 1721
+# 1722
+# 1723
+# 1724
+# 1725
+# 1726
+# 1727
+# 1728
+# 1729
+# 1730
+# 1731
+# 1732
+# 1733
+# 1734
+# 1735
+# 1736
+# 1737
+# 1738
+# 1739
+# 1740
+# 1741
+# 1742
+# 1743
+# 1744
+# 1745
+# 1746
+# 1747
+# 1748
+# 1749
+# 1750
+# 1751
+# 1752
+# 1753
+# 1754
+# 1755
+# 1756
+# 1757
+# 1758
+# 1759
+# 1760
+# 1761
+# 1762
+# 1763
+# 1764
+# 1765
+# 1766
+# 1767
+# 1768
+# 1769
+# 1770
+# 1771
+# 1772
+# 1773
+# 1774
+# 1775
+# 1776
+# 1777
+# 1778
+# 1779
+# 1780
+# 1781
+# 1782
+# 1783
+# 1784
+# 1785
+# 1786
+# 1787
+# 1788
+# 1789
+# 1790
+# 1791
+# 1792
+# 1793
+# 1794
+# 1795
+# 1796
+# 1797
+# 1798
+# 1799
+# 1800
+# 1801
+# 1802
+# 1803
+# 1804
+# 1805
+# 1806
+# 1807
+# 1808
+# 1809
+# 1810
+# 1811
+# 1812
+# 1813
+# 1814
+# 1815
+# 1816
+# 1817
+# 1818
+# 1819
+# 1820
+# 1821
+# 1822
+# 1823
+# 1824
+# 1825
+# 1826
+# 1827
+# 1828
+# 1829
+# 1830
+# 1831
+# 1832
+# 1833
+# 1834
+# 1835
+# 1836
+# 1837
+# 1838
+# 1839
+# 1840
+# 1841
+# 1842
+# 1843
+# 1844
+# 1845
+# 1846
+# 1847
+# 1848
+# 1849
+# 1850
+# 1851
+# 1852
+# 1853
+# 1854
+# 1855
+# 1856
+# 1857
+# 1858
+# 1859
+# 1860
+# 1861
+# 1862
+# 1863
+# 1864
+# 1865
+# 1866
+# 1867
+# 1868
+# 1869
+# 1870
+# 1871
+# 1872
+# 1873
+# 1874
+# 1875
+# 1876
+# 1877
+# 1878
+# 1879
+# 1880
+# 1881
+# 1882
+# 1883
+# 1884
+# 1885
+# 1886
+# 1887
+# 1888
+# 1889
+# 1890
+# 1891
+# 1892
+# 1893
+# 1894
+# 1895
+# 1896
+# 1897
+# 1898
+# 1899
+# 1900
+# 1901
+# 1902
+# 1903
+# 1904
+# 1905
+# 1906
+# 1907
+# 1908
+# 1909
+# 1910
+# 1911
+# 1912
+# 1913
+# 1914
+# 1915
+# 1916
+# 1917
+# 1918
+# 1919
+# 1920
+# 1921
+# 1922
+# 1923
+# 1924
+# 1925
+# 1926
+# 1927
+# 1928
+# 1929
+# 1930
+# 1931
+# 1932
+# 1933
+# 1934
+# 1935
+# 1936
+# 1937
+# 1938
+# 1939
+# 1940
+# 1941
+# 1942
+# 1943
+# 1944
+# 1945
+# 1946
+# 1947
+# 1948
+# 1949
+# 1950
+# 1951
+# 1952
+# 1953
+# 1954
+# 1955
+# 1956
+# 1957
+# 1958
+# 1959
+# 1960
+# 1961
+# 1962
+# 1963
+# 1964
+# 1965
+# 1966
+# 1967
+# 1968
+# 1969
+# 1970
+# 1971
+# 1972
+# 1973
+# 1974
+# 1975
+# 1976
+# 1977
+# 1978
+# 1979
+# 1980
+# 1981
+# 1982
+# 1983
+# 1984
+# 1985
+# 1986
+# 1987
+# 1988
+# 1989
+# 1990
+# 1991
+# 1992
+# 1993
+# 1994
+# 1995
+# 1996
+# 1997
+# 1998
+# 1999
+# 2000
+# Maximum amount of warnings exceeded. Use -maxwarnings to override.
+ok 2 - warn()
+ok 3 - cleanupTestCase()
+1..3
+# tests 3
+# pass 3
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_pairdiagnostics.tap b/tests/auto/testlib/selftests/expected_pairdiagnostics.tap
new file mode 100644
index 0000000000..9c45880c2d
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_pairdiagnostics.tap
@@ -0,0 +1,32 @@
+TAP version 13
+# tst_PairDiagnostics
+ok 1 - initTestCase()
+not ok 2 - testQPair()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "QPair(1,2)" (pair2)
+ found: "QPair(1,1)" (pair1)
+ expected: "QPair(1,2)" (pair2)
+ actual: "QPair(1,1)" (pair1)
+ at: tst_PairDiagnostics::testQPair() (qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp:51)
+ file: qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp
+ line: 51
+ ...
+not ok 3 - testStdPair()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "std::pair(1,2)" (pair2)
+ found: "std::pair(1,1)" (pair1)
+ expected: "std::pair(1,2)" (pair2)
+ actual: "std::pair(1,1)" (pair1)
+ at: tst_PairDiagnostics::testStdPair() (qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp:58)
+ file: qtbase/tests/auto/testlib/selftests/pairdiagnostics/tst_pairdiagnostics.cpp
+ line: 58
+ ...
+ok 4 - cleanupTestCase()
+1..4
+# tests 4
+# pass 2
+# fail 2
diff --git a/tests/auto/testlib/selftests/expected_singleskip.tap b/tests/auto/testlib/selftests/expected_singleskip.tap
new file mode 100644
index 0000000000..2cc09e7d26
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_singleskip.tap
@@ -0,0 +1,9 @@
+TAP version 13
+# tst_SingleSkip
+ok 1 - initTestCase()
+ok 2 - myTest() # SKIP skipping test
+ok 3 - cleanupTestCase()
+1..3
+# tests 3
+# pass 2
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_skip.tap b/tests/auto/testlib/selftests/expected_skip.tap
new file mode 100644
index 0000000000..adf9f692a9
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_skip.tap
@@ -0,0 +1,13 @@
+TAP version 13
+# tst_Skip
+ok 1 - initTestCase()
+ok 2 - test() # SKIP skipping all
+ok 3 - emptytest() # SKIP skipping all
+ok 4 - singleSkip(local 1) # SKIP skipping one
+# this line should only be reached once (true)
+ok 5 - singleSkip(local 2)
+ok 6 - cleanupTestCase()
+1..6
+# tests 6
+# pass 3
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_skipcleanup.tap b/tests/auto/testlib/selftests/expected_skipcleanup.tap
new file mode 100644
index 0000000000..4a3f8f852c
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_skipcleanup.tap
@@ -0,0 +1,9 @@
+TAP version 13
+# tst_SkipCleanup
+ok 1 - initTestCase()
+ok 2 - aTestFunction()
+ok 3 - cleanupTestCase() # SKIP Skip inside cleanupTestCase.
+1..3
+# tests 3
+# pass 2
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_skipinit.tap b/tests/auto/testlib/selftests/expected_skipinit.tap
new file mode 100644
index 0000000000..1fc38e79aa
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_skipinit.tap
@@ -0,0 +1,8 @@
+TAP version 13
+# tst_SkipInit
+ok 1 - initTestCase() # SKIP Skip inside initTestCase. This should skip all tests in the class.
+ok 2 - cleanupTestCase()
+1..2
+# tests 2
+# pass 1
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_skipinitdata.tap b/tests/auto/testlib/selftests/expected_skipinitdata.tap
new file mode 100644
index 0000000000..1ea96ca74e
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_skipinitdata.tap
@@ -0,0 +1,7 @@
+TAP version 13
+# tst_SkipInitData
+ok 1 - initTestCase() # SKIP Skip inside initTestCase_data. This should skip all tests in the class.
+1..1
+# tests 1
+# pass 0
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_sleep.tap b/tests/auto/testlib/selftests/expected_sleep.tap
new file mode 100644
index 0000000000..7caef214d2
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_sleep.tap
@@ -0,0 +1,9 @@
+TAP version 13
+# tst_Sleep
+ok 1 - initTestCase()
+ok 2 - sleep()
+ok 3 - cleanupTestCase()
+1..3
+# tests 3
+# pass 3
+# fail 0
diff --git a/tests/auto/testlib/selftests/expected_strcmp.tap b/tests/auto/testlib/selftests/expected_strcmp.tap
new file mode 100644
index 0000000000..af368e4745
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_strcmp.tap
@@ -0,0 +1,87 @@
+TAP version 13
+# tst_StrCmp
+ok 1 - initTestCase()
+ok 2 - compareCharStars()
+not ok 3 - compareByteArray() # TODO Next test should fail
+ ---
+ at: tst_StrCmp::compareByteArray() (qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp:75)
+ file: qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp
+ line: 75
+ ...
+not ok 3 - compareByteArray() # TODO Next test should fail
+ ---
+ at: tst_StrCmp::compareByteArray() (qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp:82)
+ file: qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp
+ line: 82
+ ...
+not ok 3 - compareByteArray() # TODO Next test should fail
+ ---
+ at: tst_StrCmp::compareByteArray() (qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp:89)
+ file: qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp
+ line: 89
+ ...
+not ok 3 - compareByteArray()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"... (b)
+ found: "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"... (a)
+ expected: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"... (b)
+ actual: "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"... (a)
+ at: tst_StrCmp::compareByteArray() (qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp:96)
+ file: qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp
+ line: 96
+ ...
+not ok 4 - failByteArray()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "cba" (QByteArray("cba"))
+ found: "abc" (QByteArray("abc"))
+ expected: "cba" (QByteArray("cba"))
+ actual: "abc" (QByteArray("abc"))
+ at: tst_StrCmp::failByteArray() (qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp
+ line: 102
+ ...
+not ok 5 - failByteArrayNull()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "" (QByteArray())
+ found: "foo" (QByteArray("foo"))
+ expected: "" (QByteArray())
+ actual: "foo" (QByteArray("foo"))
+ at: tst_StrCmp::failByteArrayNull() (qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp:108)
+ file: qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp
+ line: 108
+ ...
+not ok 6 - failByteArrayEmpty()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "foo" (QByteArray("foo"))
+ found: "" (QByteArray(""))
+ expected: "foo" (QByteArray("foo"))
+ actual: "" (QByteArray(""))
+ at: tst_StrCmp::failByteArrayEmpty() (qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp:113)
+ file: qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp
+ line: 113
+ ...
+not ok 7 - failByteArraySingleChars()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "7" (QByteArray("7"))
+ found: "6" (QByteArray("6"))
+ expected: "7" (QByteArray("7"))
+ actual: "6" (QByteArray("6"))
+ at: tst_StrCmp::failByteArraySingleChars() (qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp:120)
+ file: qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp
+ line: 120
+ ...
+ok 8 - cleanupTestCase()
+1..8
+# tests 8
+# pass 3
+# fail 5
diff --git a/tests/auto/testlib/selftests/expected_subtest.tap b/tests/auto/testlib/selftests/expected_subtest.tap
new file mode 100644
index 0000000000..67fe7be570
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_subtest.tap
@@ -0,0 +1,68 @@
+TAP version 13
+# tst_Subtest
+# initTestCase initTestCase (null)
+ok 1 - initTestCase()
+# init test1 (null)
+# test1 test1 (null)
+# cleanup test1 (null)
+ok 2 - test1()
+# test2_data test2 (null)
+# test2_data end
+# init test2 data0
+# test2 test2 data0
+# test2 end
+# cleanup test2 data0
+ok 3 - test2(data0)
+# init test2 data1
+# test2 test2 data1
+# test2 end
+# cleanup test2 data1
+ok 4 - test2(data1)
+# init test2 data2
+# test2 test2 data2
+# test2 end
+# cleanup test2 data2
+ok 5 - test2(data2)
+# test3_data test3 (null)
+# test3_data end
+# init test3 data0
+# test2 test3 data0
+# test2 end
+# cleanup test3 data0
+ok 6 - test3(data0)
+# init test3 data1
+# test2 test3 data1
+not ok 7 - test3(data1)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "hello0" (QString("hello0"))
+ found: "hello1" (str)
+ expected: "hello0" (QString("hello0"))
+ actual: "hello1" (str)
+ at: tst_Subtest::test3() (qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp:141)
+ file: qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp
+ line: 141
+ ...
+# cleanup test3 data1
+# init test3 data2
+# test2 test3 data2
+not ok 8 - test3(data2)
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: "hello0" (QString("hello0"))
+ found: "hello2" (str)
+ expected: "hello0" (QString("hello0"))
+ actual: "hello2" (str)
+ at: tst_Subtest::test3() (qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp:141)
+ file: qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp
+ line: 141
+ ...
+# cleanup test3 data2
+# cleanupTestCase cleanupTestCase (null)
+ok 9 - cleanupTestCase()
+1..9
+# tests 9
+# pass 7
+# fail 2
diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.lightxml b/tests/auto/testlib/selftests/expected_tuplediagnostics.lightxml
new file mode 100644
index 0000000000..810941d894
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.lightxml
@@ -0,0 +1,34 @@
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QtBuild/>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testEmptyTuple">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testSimpleTuple">
+<Incident type="fail" file="/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp" line="0">
+ <Description><![CDATA[Compared values are not the same
+ Actual (std::tuple<int>{1}): std::tuple(1)
+ Expected (std::tuple<int>{2}): std::tuple(2)]]></Description>
+</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testTuple">
+<Incident type="fail" file="/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp" line="0">
+ <Description><![CDATA[Compared values are not the same
+ Actual (tuple1): std::tuple(42, 'Y', "tuple1")
+ Expected (tuple2): std::tuple(42, 'Y', "tuple2")]]></Description>
+</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.tap b/tests/auto/testlib/selftests/expected_tuplediagnostics.tap
new file mode 100644
index 0000000000..9e007c14e1
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.tap
@@ -0,0 +1,33 @@
+TAP version 13
+# tst_TupleDiagnostics
+ok 1 - initTestCase()
+ok 2 - testEmptyTuple()
+not ok 3 - testSimpleTuple()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: std::tuple(2) (std::tuple<int>{2})
+ found: std::tuple(1) (std::tuple<int>{1})
+ expected: std::tuple(2) (std::tuple<int>{2})
+ actual: std::tuple(1) (std::tuple<int>{1})
+ at: tst_TupleDiagnostics::testSimpleTuple() (/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp:53)
+ file: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp
+ line: 53
+ ...
+not ok 4 - testTuple()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: std::tuple(42, 'Y', "tuple2") (tuple2)
+ found: std::tuple(42, 'Y', "tuple1") (tuple1)
+ expected: std::tuple(42, 'Y', "tuple2") (tuple2)
+ actual: std::tuple(42, 'Y', "tuple1") (tuple1)
+ at: tst_TupleDiagnostics::testTuple() (/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp:60)
+ file: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp
+ line: 60
+ ...
+ok 5 - cleanupTestCase()
+1..5
+# tests 5
+# pass 3
+# fail 2
diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.teamcity b/tests/auto/testlib/selftests/expected_tuplediagnostics.teamcity
new file mode 100644
index 0000000000..a395857c60
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.teamcity
@@ -0,0 +1,14 @@
+##teamcity[testSuiteStarted name='tst_TupleDiagnostics' flowId='tst_TupleDiagnostics']
+##teamcity[testStarted name='initTestCase()' flowId='tst_TupleDiagnostics']
+##teamcity[testFinished name='initTestCase()' flowId='tst_TupleDiagnostics']
+##teamcity[testStarted name='testEmptyTuple()' flowId='tst_TupleDiagnostics']
+##teamcity[testFinished name='testEmptyTuple()' flowId='tst_TupleDiagnostics']
+##teamcity[testStarted name='testSimpleTuple()' flowId='tst_TupleDiagnostics']
+##teamcity[testFailed name='testSimpleTuple()' message='Failure! |[Loc: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (std::tuple<int>{1}): std::tuple(1)|n Expected (std::tuple<int>{2}): std::tuple(2)' flowId='tst_TupleDiagnostics']
+##teamcity[testFinished name='testSimpleTuple()' flowId='tst_TupleDiagnostics']
+##teamcity[testStarted name='testTuple()' flowId='tst_TupleDiagnostics']
+##teamcity[testFailed name='testTuple()' message='Failure! |[Loc: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (tuple1): std::tuple(42, |'Y|', "tuple1")|n Expected (tuple2): std::tuple(42, |'Y|', "tuple2")' flowId='tst_TupleDiagnostics']
+##teamcity[testFinished name='testTuple()' flowId='tst_TupleDiagnostics']
+##teamcity[testStarted name='cleanupTestCase()' flowId='tst_TupleDiagnostics']
+##teamcity[testFinished name='cleanupTestCase()' flowId='tst_TupleDiagnostics']
+##teamcity[testSuiteFinished name='tst_TupleDiagnostics' flowId='tst_TupleDiagnostics']
diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.txt b/tests/auto/testlib/selftests/expected_tuplediagnostics.txt
new file mode 100644
index 0000000000..ce568bf6c0
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.txt
@@ -0,0 +1,15 @@
+********* Start testing of tst_TupleDiagnostics *********
+Config: Using QtTest library
+PASS : tst_TupleDiagnostics::initTestCase()
+PASS : tst_TupleDiagnostics::testEmptyTuple()
+FAIL! : tst_TupleDiagnostics::testSimpleTuple() Compared values are not the same
+ Actual (std::tuple<int>{1}): std::tuple(1)
+ Expected (std::tuple<int>{2}): std::tuple(2)
+ Loc: [/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)]
+FAIL! : tst_TupleDiagnostics::testTuple() Compared values are not the same
+ Actual (tuple1): std::tuple(42, 'Y', "tuple1")
+ Expected (tuple2): std::tuple(42, 'Y', "tuple2")
+ Loc: [/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)]
+PASS : tst_TupleDiagnostics::cleanupTestCase()
+Totals: 3 passed, 2 failed, 0 skipped, 0 blacklisted, 0ms
+********* Finished testing of tst_TupleDiagnostics *********
diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.xml b/tests/auto/testlib/selftests/expected_tuplediagnostics.xml
new file mode 100644
index 0000000000..4c55a6d393
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TestCase name="tst_TupleDiagnostics">
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QtBuild/>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testEmptyTuple">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testSimpleTuple">
+<Incident type="fail" file="/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp" line="0">
+ <Description><![CDATA[Compared values are not the same
+ Actual (std::tuple<int>{1}): std::tuple(1)
+ Expected (std::tuple<int>{2}): std::tuple(2)]]></Description>
+</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testTuple">
+<Incident type="fail" file="/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp" line="0">
+ <Description><![CDATA[Compared values are not the same
+ Actual (tuple1): std::tuple(42, 'Y', "tuple1")
+ Expected (tuple2): std::tuple(42, 'Y', "tuple2")]]></Description>
+</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
+</TestFunction>
+<Duration msecs="0"/>
+</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.xunitxml b/tests/auto/testlib/selftests/expected_tuplediagnostics.xunitxml
new file mode 100644
index 0000000000..0a276a17f5
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.xunitxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite errors="0" failures="2" tests="5" name="tst_TupleDiagnostics">
+ <properties>
+ <property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
+ <property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
+ <property value="" name="QtBuild"/>
+ </properties>
+ <testcase result="pass" name="initTestCase"/>
+ <testcase result="pass" name="testEmptyTuple"/>
+ <testcase result="fail" name="testSimpleTuple">
+ <failure message="Compared values are not the same
+ Actual (std::tuple&lt;int&gt;{1}): std::tuple(1)
+ Expected (std::tuple&lt;int&gt;{2}): std::tuple(2)" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testTuple">
+ <failure message="Compared values are not the same
+ Actual (tuple1): std::tuple(42, &apos;Y&apos;, &quot;tuple1&quot;)
+ Expected (tuple2): std::tuple(42, &apos;Y&apos;, &quot;tuple2&quot;)" result="fail"/>
+ </testcase>
+ <testcase result="pass" name="cleanupTestCase"/>
+ <system-err/>
+</testsuite>
diff --git a/tests/auto/testlib/selftests/expected_verbose1.tap b/tests/auto/testlib/selftests/expected_verbose1.tap
new file mode 100644
index 0000000000..ad53e8f14e
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose1.tap
@@ -0,0 +1,118 @@
+TAP version 13
+# tst_Counting
+ok 1 - initTestCase()
+ok 2 - testPassPass(row 1)
+ok 3 - testPassPass(row 2)
+ok 4 - testPassSkip(row 1)
+ok 5 - testPassSkip(row 2) # SKIP Skipping
+ok 6 - testPassFail(row 1)
+not ok 7 - testPassFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testPassFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 8 - testSkipPass(row 1) # SKIP Skipping
+ok 9 - testSkipPass(row 2)
+ok 10 - testSkipSkip(row 1) # SKIP Skipping
+ok 11 - testSkipSkip(row 2) # SKIP Skipping
+ok 12 - testSkipFail(row 1) # SKIP Skipping
+not ok 13 - testSkipFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testSkipFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+not ok 14 - testFailPass(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailPass() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 15 - testFailPass(row 2)
+not ok 16 - testFailSkip(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailSkip() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 17 - testFailSkip(row 2) # SKIP Skipping
+not ok 18 - testFailFail(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+not ok 19 - testFailFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 20 - testFailInInit(before)
+not ok 21 - testFailInInit(fail)
+ ---
+ # Fail in init()
+ at: tst_Counting::testFailInInit() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:221)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 221
+ ...
+ok 22 - testFailInInit(after)
+ok 23 - testFailInCleanup(before)
+# This test function should execute and then QFAIL in cleanup()
+not ok 24 - testFailInCleanup(fail)
+ ---
+ # Fail in cleanup()
+ at: tst_Counting::testFailInCleanup() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:229)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 229
+ ...
+ok 25 - testFailInCleanup(after)
+ok 26 - testSkipInInit(before)
+ok 27 - testSkipInInit(skip) # SKIP Skip in init()
+ok 28 - testSkipInInit(after)
+ok 29 - testSkipInCleanup(before)
+# This test function should execute and then QSKIP in cleanup()
+ok 30 - testSkipInCleanup(skip) # SKIP Skip in cleanup()
+ok 31 - testSkipInCleanup(after)
+ok 32 - cleanupTestCase()
+1..32
+# tests 32
+# pass 16
+# fail 8
diff --git a/tests/auto/testlib/selftests/expected_verbose2.tap b/tests/auto/testlib/selftests/expected_verbose2.tap
new file mode 100644
index 0000000000..7e6a7280a4
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verbose2.tap
@@ -0,0 +1,136 @@
+TAP version 13
+# tst_Counting
+ok 1 - initTestCase()
+# QVERIFY(true)
+# QCOMPARE(2 + 1, 3)
+ok 2 - testPassPass(row 1)
+# QVERIFY(true)
+# QCOMPARE(2 + 1, 3)
+ok 3 - testPassPass(row 2)
+# QVERIFY(true)
+# QCOMPARE(2 + 1, 3)
+ok 4 - testPassSkip(row 1)
+ok 5 - testPassSkip(row 2) # SKIP Skipping
+# QVERIFY(true)
+# QCOMPARE(2 + 1, 3)
+ok 6 - testPassFail(row 1)
+# QVERIFY(false)
+not ok 7 - testPassFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testPassFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 8 - testSkipPass(row 1) # SKIP Skipping
+# QVERIFY(true)
+# QCOMPARE(2 + 1, 3)
+ok 9 - testSkipPass(row 2)
+ok 10 - testSkipSkip(row 1) # SKIP Skipping
+ok 11 - testSkipSkip(row 2) # SKIP Skipping
+ok 12 - testSkipFail(row 1) # SKIP Skipping
+# QVERIFY(false)
+not ok 13 - testSkipFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testSkipFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+# QVERIFY(false)
+not ok 14 - testFailPass(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailPass() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+# QVERIFY(true)
+# QCOMPARE(2 + 1, 3)
+ok 15 - testFailPass(row 2)
+# QVERIFY(false)
+not ok 16 - testFailSkip(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailSkip() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 17 - testFailSkip(row 2) # SKIP Skipping
+# QVERIFY(false)
+not ok 18 - testFailFail(row 1)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+# QVERIFY(false)
+not ok 19 - testFailFail(row 2)
+ ---
+ type: QVERIFY
+ message: Verification failed
+ wanted: true (false)
+ found: false (false)
+ expected: true (false)
+ actual: false (false)
+ at: tst_Counting::testFailFail() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:102)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 102
+ ...
+ok 20 - testFailInInit(before)
+not ok 21 - testFailInInit(fail)
+ ---
+ # Fail in init()
+ at: tst_Counting::testFailInInit() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:221)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 221
+ ...
+ok 22 - testFailInInit(after)
+ok 23 - testFailInCleanup(before)
+# This test function should execute and then QFAIL in cleanup()
+not ok 24 - testFailInCleanup(fail)
+ ---
+ # Fail in cleanup()
+ at: tst_Counting::testFailInCleanup() (qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp:229)
+ file: qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp
+ line: 229
+ ...
+ok 25 - testFailInCleanup(after)
+ok 26 - testSkipInInit(before)
+ok 27 - testSkipInInit(skip) # SKIP Skip in init()
+ok 28 - testSkipInInit(after)
+ok 29 - testSkipInCleanup(before)
+# This test function should execute and then QSKIP in cleanup()
+ok 30 - testSkipInCleanup(skip) # SKIP Skip in cleanup()
+ok 31 - testSkipInCleanup(after)
+ok 32 - cleanupTestCase()
+1..32
+# tests 32
+# pass 16
+# fail 8
diff --git a/tests/auto/testlib/selftests/expected_verifyexceptionthrown.tap b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.tap
new file mode 100644
index 0000000000..2b04c08cdb
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.tap
@@ -0,0 +1,53 @@
+TAP version 13
+# tst_VerifyExceptionThrown
+ok 1 - initTestCase()
+ok 2 - testCorrectStdTypes()
+ok 3 - testCorrectStdExceptions()
+ok 4 - testCorrectMyExceptions()
+not ok 5 - testFailInt()
+ ---
+ # Expected exception of type double to be thrown but unknown exception caught
+ at: tst_VerifyExceptionThrown::testFailInt() (qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp:115)
+ file: qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
+ line: 115
+ ...
+not ok 6 - testFailStdString()
+ ---
+ # Expected exception of type char* to be thrown but unknown exception caught
+ at: tst_VerifyExceptionThrown::testFailStdString() (qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp:120)
+ file: qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
+ line: 120
+ ...
+not ok 7 - testFailStdRuntimeError()
+ ---
+ # Expected exception of type std::runtime_error to be thrown but std::exception caught with message: logic error
+ at: tst_VerifyExceptionThrown::testFailStdRuntimeError() (qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp:125)
+ file: qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
+ line: 125
+ ...
+not ok 8 - testFailMyException()
+ ---
+ # Expected exception of type MyBaseException to be thrown but std::exception caught with message: logic error
+ at: tst_VerifyExceptionThrown::testFailMyException() (qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp:130)
+ file: qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
+ line: 130
+ ...
+not ok 9 - testFailMyDerivedException()
+ ---
+ # Expected exception of type std::runtime_error to be thrown but std::exception caught with message: MyDerivedException
+ at: tst_VerifyExceptionThrown::testFailMyDerivedException() (qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp:135)
+ file: qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
+ line: 135
+ ...
+not ok 10 - testFailNoException()
+ ---
+ # Expected exception of type std::exception to be thrown but no exception caught
+ at: tst_VerifyExceptionThrown::testFailNoException() (qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp:140)
+ file: qtbase/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
+ line: 140
+ ...
+ok 11 - cleanupTestCase()
+1..11
+# tests 11
+# pass 5
+# fail 6
diff --git a/tests/auto/testlib/selftests/expected_warnings.tap b/tests/auto/testlib/selftests/expected_warnings.tap
new file mode 100644
index 0000000000..0e357cb770
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_warnings.tap
@@ -0,0 +1,42 @@
+TAP version 13
+# tst_Warnings
+ok 1 - initTestCase()
+# Warning
+# Warning
+# Debug
+# Debug
+# Info
+# Info
+# Baba
+# Baba
+# Bubublabla
+# Babablabla
+ok 2 - testWarnings()
+# Did not receive message: "Warning0"
+# Did not receive message: "Warning1"
+not ok 3 - testMissingWarnings()
+ ---
+ # Not all expected messages were received
+ ...
+# Did not receive any message matching: "Warning\s\d"
+not ok 4 - testMissingWarningsRegularExpression()
+ ---
+ # Not all expected messages were received
+ ...
+# Did not receive message: "Warning0"
+# Did not receive message: "Warning1"
+not ok 5 - testMissingWarningsWithData(first row)
+ ---
+ # Not all expected messages were received
+ ...
+# Did not receive message: "Warning0"
+# Did not receive message: "Warning1"
+not ok 6 - testMissingWarningsWithData(second row)
+ ---
+ # Not all expected messages were received
+ ...
+ok 7 - cleanupTestCase()
+1..7
+# tests 7
+# pass 3
+# fail 4
diff --git a/tests/auto/testlib/selftests/expected_xunit.tap b/tests/auto/testlib/selftests/expected_xunit.tap
new file mode 100644
index 0000000000..13ff7e45a3
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_xunit.tap
@@ -0,0 +1,44 @@
+TAP version 13
+# tst_Xunit
+ok 1 - initTestCase()
+# just a QWARN() !
+ok 2 - testFunc1()
+# a qDebug() call with comment-ending stuff -->
+not ok 3 - testFunc2()
+ ---
+ type: QCOMPARE
+ message: Compared values are not the same
+ wanted: 3 (3)
+ found: 2 (2)
+ expected: 3 (3)
+ actual: 2 (2)
+ at: tst_Xunit::testFunc2() (qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp:61)
+ file: qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp
+ line: 61
+ ...
+ok 4 - testFunc3() # SKIP skipping this function!
+not ok 5 - testFunc4()
+ ---
+ # a forced failure!
+ at: tst_Xunit::testFunc4() (qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp:71)
+ file: qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp
+ line: 71
+ ...
+not ok 6 - testFunc5() # TODO this failure is expected
+ ---
+ at: tst_Xunit::testFunc5() (qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp:85)
+ file: qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp
+ line: 85
+ ...
+not ok 7 - testFunc6() # TODO this failure is also expected
+ ---
+ at: tst_Xunit::testFunc6() (qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp:91)
+ file: qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp
+ line: 91
+ ...
+ok 8 - testFunc7() # TODO 'true' returned TRUE unexpectedly. ()
+ok 9 - cleanupTestCase()
+1..9
+# tests 9
+# pass 5
+# fail 3
diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py
index aa11ca4fe7..1996416e8c 100755
--- a/tests/auto/testlib/selftests/generate_expected_output.py
+++ b/tests/auto/testlib/selftests/generate_expected_output.py
@@ -37,9 +37,7 @@
# it to the output of each test, ignoring various boring changes.
# This script canonicalises the parts that would exhibit those boring
# changes, so as to avoid noise in git (and conflicts in merges) for
-# the saved copies of the output. If you add or remove any files, be
-# sure to update selftests.qrc to match; the selftest only sees files
-# listed there.
+# the saved copies of the output.
import os
import subprocess
@@ -116,10 +114,13 @@ class Cleaner (object):
raise Fail('Unable to find', command, 'in $PATH')
# Are we being run from the right place ?
- myNames = scriptPath.split(os.path.sep)
- if not (here.split(os.path.sep)[-5:] == myNames[-6:-1]
+ scriptPath, myName = os.path.split(scriptPath)
+ hereNames, depth = scriptPath.split(os.path.sep), 5
+ hereNames = hereNames[-depth:] # path components from qtbase down
+ assert hereNames[0] == 'qtbase', ('Script moved: please correct depth', hereNames)
+ if not (here.split(os.path.sep)[-depth:] == hereNames
and os.path.isfile(qmake)):
- raise Fail('Run', myNames[-1], 'in its directory of a completed build')
+ raise Fail('Run', myName, 'in its directory of a completed build')
try:
qtver = subprocess.check_output([qmake, '-query', 'QT_VERSION'])
@@ -127,8 +128,17 @@ class Cleaner (object):
raise Fail(what.strerror)
qtver = qtver.strip().decode('utf-8')
- scriptPath = os.path.dirname(scriptPath) # ditch leaf file-name
- sentinel = os.path.sep + 'qtbase' + os.path.sep # '/qtbase/'
+ hereNames = tuple(hereNames)
+ # Add path to specific sources and to tst_*.cpp if missing (for in-source builds):
+ patterns += ((r'(^|[^/])\b(qtestcase.cpp)\b', r'\1qtbase/src/testlib/\2'),
+ # Add more special cases here, if they show up !
+ (r'([[" ])\.\./(counting/tst_counting.cpp)\b',
+ r'\1' + os.path.sep.join(hereNames + (r'\2',))),
+ # The common pattern:
+ (r'(^|[^/])\b(tst_)?([a-z]+\d*)\.cpp\b',
+ r'\1' + os.path.sep.join(hereNames + (r'\3', r'\2\3.cpp'))))
+
+ sentinel = os.path.sep + hereNames[0] + os.path.sep # '/qtbase/'
# Identify the path prefix of our qtbase ancestor directory
# (source, build and $PWD, when different); trim such prefixes
# off all paths we see.
@@ -212,7 +222,7 @@ class Scanner (object):
del re
def generateTestData(testname, clean,
- formats = ('xml', 'txt', 'xunitxml', 'lightxml', 'teamcity'),
+ formats = ('xml', 'txt', 'xunitxml', 'lightxml', 'teamcity', 'tap'),
extraArgs = {
"commandlinedata": "fiveTablePasses fiveTablePasses:fiveTablePasses_data1 -v2",
"benchlibcallgrind": "-callgrind",
diff --git a/tests/auto/testlib/selftests/keyboard/keyboard.pro b/tests/auto/testlib/selftests/keyboard/keyboard.pro
new file mode 100644
index 0000000000..0097318797
--- /dev/null
+++ b/tests/auto/testlib/selftests/keyboard/keyboard.pro
@@ -0,0 +1,7 @@
+SOURCES += tst_keyboard.cpp
+QT += testlib testlib-private gui gui-private
+
+macos:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+
+TARGET = keyboard
diff --git a/tests/auto/testlib/selftests/keyboard/tst_keyboard.cpp b/tests/auto/testlib/selftests/keyboard/tst_keyboard.cpp
new file mode 100644
index 0000000000..e185be8532
--- /dev/null
+++ b/tests/auto/testlib/selftests/keyboard/tst_keyboard.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/qtest.h>
+#include <QtGui/qwindow.h>
+
+class tst_Keyboard : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void keyPressAndRelease();
+};
+
+class KeyWindow : public QWindow
+{
+public:
+ void keyPressEvent(QKeyEvent *event) override
+ {
+ QSharedPointer<QKeyEvent> copiedEvent(new QKeyEvent(event->type(), event->key(),
+ event->modifiers(), event->text(), event->isAutoRepeat(), event->count()));
+ mEventOrder.append(copiedEvent);
+ }
+
+ void keyReleaseEvent(QKeyEvent *event) override
+ {
+ QSharedPointer<QKeyEvent> copiedEvent(new QKeyEvent(event->type(), event->key(),
+ event->modifiers(), event->text(), event->isAutoRepeat(), event->count()));
+ mEventOrder.append(copiedEvent);
+ }
+
+ QVector<QSharedPointer<QKeyEvent>> mEventOrder;
+};
+
+void tst_Keyboard::keyPressAndRelease()
+{
+ KeyWindow window;
+ window.show();
+ window.setGeometry(100, 100, 200, 200);
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+
+ QTest::keyPress(&window, Qt::Key_A);
+ QTest::keyRelease(&window, Qt::Key_A);
+ QCOMPARE(window.mEventOrder.size(), 2);
+
+ const auto pressEvent = window.mEventOrder.at(0);
+ QCOMPARE(pressEvent->type(), QEvent::KeyPress);
+ QCOMPARE(pressEvent->key(), Qt::Key_A);
+ QCOMPARE(pressEvent->modifiers(), Qt::NoModifier);
+ QCOMPARE(pressEvent->text(), "a");
+ QCOMPARE(pressEvent->isAutoRepeat(), false);
+
+ const auto releaseEvent = window.mEventOrder.at(1);
+ QCOMPARE(releaseEvent->type(), QEvent::KeyRelease);
+ QCOMPARE(releaseEvent->key(), Qt::Key_A);
+ QCOMPARE(releaseEvent->modifiers(), Qt::NoModifier);
+ QCOMPARE(releaseEvent->text(), "a");
+ QCOMPARE(releaseEvent->isAutoRepeat(), false);
+}
+
+QTEST_MAIN(tst_Keyboard)
+#include "tst_keyboard.moc"
diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri
index 079f3f7959..498d1653c0 100644
--- a/tests/auto/testlib/selftests/selftests.pri
+++ b/tests/auto/testlib/selftests/selftests.pri
@@ -27,8 +27,10 @@ SUBPROGRAMS = \
findtestdata \
float \
globaldata \
+ keyboard \
longstring \
maxwarnings \
+ mouse \
multiexec \
pairdiagnostics \
printdatatags \
@@ -43,12 +45,12 @@ SUBPROGRAMS = \
sleep \
strcmp \
subtest \
+ tuplediagnostics \
verbose1 \
verbose2 \
verifyexceptionthrown \
warnings \
- xunit \
- mouse
+ xunit
INCLUDEPATH += ../../../../shared/
HEADERS += ../../../../shared/emulationdetector.h
diff --git a/tests/auto/testlib/selftests/selftests.qrc b/tests/auto/testlib/selftests/selftests.qrc
deleted file mode 100644
index 75d3375394..0000000000
--- a/tests/auto/testlib/selftests/selftests.qrc
+++ /dev/null
@@ -1,219 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>expected_assert.lightxml</file>
- <file>expected_assert.teamcity</file>
- <file>expected_assert.txt</file>
- <file>expected_assert.xml</file>
- <file>expected_assert.xunitxml</file>
- <file>expected_badxml.lightxml</file>
- <file>expected_badxml.teamcity</file>
- <file>expected_badxml.txt</file>
- <file>expected_badxml.xml</file>
- <file>expected_badxml.xunitxml</file>
- <file>expected_benchlibcallgrind_0.txt</file>
- <file>expected_benchlibcallgrind_1.txt</file>
- <file>expected_benchlibcallgrind.csv</file>
- <file>expected_benchlibcallgrind.lightxml</file>
- <file>expected_benchlibcallgrind.xml</file>
- <file>expected_benchlibcallgrind.xunitxml</file>
- <file>expected_benchlibcounting.csv</file>
- <file>expected_benchlibcounting.lightxml</file>
- <file>expected_benchlibcounting.txt</file>
- <file>expected_benchlibcounting.xml</file>
- <file>expected_benchlibcounting.xunitxml</file>
- <file>expected_benchlibeventcounter.csv</file>
- <file>expected_benchlibeventcounter.lightxml</file>
- <file>expected_benchlibeventcounter.txt</file>
- <file>expected_benchlibeventcounter.xml</file>
- <file>expected_benchlibeventcounter.xunitxml</file>
- <file>expected_benchliboptions.lightxml</file>
- <file>expected_benchliboptions.txt</file>
- <file>expected_benchliboptions.xml</file>
- <file>expected_benchliboptions.xunitxml</file>
- <file>expected_benchlibtickcounter.csv</file>
- <file>expected_benchlibtickcounter.lightxml</file>
- <file>expected_benchlibtickcounter.txt</file>
- <file>expected_benchlibtickcounter.xml</file>
- <file>expected_benchlibtickcounter.xunitxml</file>
- <file>expected_benchlibwalltime.csv</file>
- <file>expected_benchlibwalltime.lightxml</file>
- <file>expected_benchlibwalltime.txt</file>
- <file>expected_benchlibwalltime.xml</file>
- <file>expected_benchlibwalltime.xunitxml</file>
- <file>expected_blacklisted.lightxml</file>
- <file>expected_blacklisted.txt</file>
- <file>expected_blacklisted.xml</file>
- <file>expected_blacklisted.xunitxml</file>
- <file>expected_cmptest.lightxml</file>
- <file>expected_cmptest.teamcity</file>
- <file>expected_cmptest.txt</file>
- <file>expected_cmptest.xml</file>
- <file>expected_cmptest.xunitxml</file>
- <file>expected_commandlinedata.lightxml</file>
- <file>expected_commandlinedata.teamcity</file>
- <file>expected_commandlinedata.txt</file>
- <file>expected_commandlinedata.xml</file>
- <file>expected_commandlinedata.xunitxml</file>
- <file>expected_counting.lightxml</file>
- <file>expected_counting.teamcity</file>
- <file>expected_counting.txt</file>
- <file>expected_counting.xml</file>
- <file>expected_counting.xunitxml</file>
- <file>expected_crashes_1.txt</file>
- <file>expected_crashes_2.txt</file>
- <file>expected_crashes_3.txt</file>
- <file>expected_datatable.lightxml</file>
- <file>expected_datatable.teamcity</file>
- <file>expected_datatable.txt</file>
- <file>expected_datatable.xml</file>
- <file>expected_datatable.xunitxml</file>
- <file>expected_datetime.lightxml</file>
- <file>expected_datetime.teamcity</file>
- <file>expected_datetime.txt</file>
- <file>expected_datetime.xml</file>
- <file>expected_datetime.xunitxml</file>
- <file>expected_differentexec.lightxml</file>
- <file>expected_differentexec.txt</file>
- <file>expected_differentexec.xml</file>
- <file>expected_differentexec.xunitxml</file>
- <file>expected_exceptionthrow.lightxml</file>
- <file>expected_exceptionthrow.teamcity</file>
- <file>expected_exceptionthrow.txt</file>
- <file>expected_exceptionthrow.xml</file>
- <file>expected_exceptionthrow.xunitxml</file>
- <file>expected_expectfail.lightxml</file>
- <file>expected_expectfail.teamcity</file>
- <file>expected_expectfail.txt</file>
- <file>expected_expectfail.xml</file>
- <file>expected_expectfail.xunitxml</file>
- <file>expected_failcleanup.lightxml</file>
- <file>expected_failcleanup.teamcity</file>
- <file>expected_failcleanup.txt</file>
- <file>expected_failcleanup.xml</file>
- <file>expected_failcleanup.xunitxml</file>
- <file>expected_failinit.lightxml</file>
- <file>expected_failinit.teamcity</file>
- <file>expected_failinit.txt</file>
- <file>expected_failinit.xml</file>
- <file>expected_failinit.xunitxml</file>
- <file>expected_failinitdata.lightxml</file>
- <file>expected_failinitdata.teamcity</file>
- <file>expected_failinitdata.txt</file>
- <file>expected_failinitdata.xml</file>
- <file>expected_failinitdata.xunitxml</file>
- <file>expected_fetchbogus.lightxml</file>
- <file>expected_fetchbogus.teamcity</file>
- <file>expected_fetchbogus.txt</file>
- <file>expected_fetchbogus.xml</file>
- <file>expected_fetchbogus.xunitxml</file>
- <file>expected_findtestdata.lightxml</file>
- <file>expected_findtestdata.teamcity</file>
- <file>expected_findtestdata.txt</file>
- <file>expected_findtestdata.xml</file>
- <file>expected_findtestdata.xunitxml</file>
- <file>expected_float.lightxml</file>
- <file>expected_float.txt</file>
- <file>expected_float.xml</file>
- <file>expected_float.xunitxml</file>
- <file>expected_globaldata.lightxml</file>
- <file>expected_globaldata.teamcity</file>
- <file>expected_globaldata.txt</file>
- <file>expected_globaldata.xml</file>
- <file>expected_globaldata.xunitxml</file>
- <file>expected_longstring.lightxml</file>
- <file>expected_longstring.teamcity</file>
- <file>expected_longstring.txt</file>
- <file>expected_longstring.xml</file>
- <file>expected_longstring.xunitxml</file>
- <file>expected_maxwarnings.lightxml</file>
- <file>expected_maxwarnings.teamcity</file>
- <file>expected_maxwarnings.txt</file>
- <file>expected_maxwarnings.xml</file>
- <file>expected_maxwarnings.xunitxml</file>
- <file>expected_multiexec.lightxml</file>
- <file>expected_multiexec.txt</file>
- <file>expected_multiexec.xml</file>
- <file>expected_multiexec.xunitxml</file>
- <file>expected_pairdiagnostics.lightxml</file>
- <file>expected_pairdiagnostics.teamcity</file>
- <file>expected_pairdiagnostics.txt</file>
- <file>expected_pairdiagnostics.xml</file>
- <file>expected_pairdiagnostics.xunitxml</file>
- <file>expected_printdatatags.txt</file>
- <file>expected_printdatatagswithglobaltags.txt</file>
- <file>expected_qexecstringlist.lightxml</file>
- <file>expected_qexecstringlist.txt</file>
- <file>expected_qexecstringlist.xml</file>
- <file>expected_qexecstringlist.xunitxml</file>
- <file>expected_silent.lightxml</file>
- <file>expected_silent.teamcity</file>
- <file>expected_silent.txt</file>
- <file>expected_silent.xml</file>
- <file>expected_silent.xunitxml</file>
- <file>expected_singleskip.lightxml</file>
- <file>expected_singleskip.teamcity</file>
- <file>expected_singleskip.txt</file>
- <file>expected_singleskip.xml</file>
- <file>expected_singleskip.xunitxml</file>
- <file>expected_skip.lightxml</file>
- <file>expected_skip.teamcity</file>
- <file>expected_skip.txt</file>
- <file>expected_skip.xml</file>
- <file>expected_skip.xunitxml</file>
- <file>expected_skipcleanup.lightxml</file>
- <file>expected_skipcleanup.teamcity</file>
- <file>expected_skipcleanup.txt</file>
- <file>expected_skipcleanup.xml</file>
- <file>expected_skipcleanup.xunitxml</file>
- <file>expected_skipinit.lightxml</file>
- <file>expected_skipinit.txt</file>
- <file>expected_skipinit.teamcity</file>
- <file>expected_skipinit.xml</file>
- <file>expected_skipinit.xunitxml</file>
- <file>expected_skipinitdata.lightxml</file>
- <file>expected_skipinitdata.teamcity</file>
- <file>expected_skipinitdata.txt</file>
- <file>expected_skipinitdata.xml</file>
- <file>expected_skipinitdata.xunitxml</file>
- <file>expected_sleep.lightxml</file>
- <file>expected_sleep.teamcity</file>
- <file>expected_sleep.txt</file>
- <file>expected_sleep.xml</file>
- <file>expected_sleep.xunitxml</file>
- <file>expected_strcmp.lightxml</file>
- <file>expected_strcmp.teamcity</file>
- <file>expected_strcmp.txt</file>
- <file>expected_strcmp.xml</file>
- <file>expected_strcmp.xunitxml</file>
- <file>expected_subtest.lightxml</file>
- <file>expected_subtest.txt</file>
- <file>expected_subtest.teamcity</file>
- <file>expected_subtest.xml</file>
- <file>expected_subtest.xunitxml</file>
- <file>expected_verbose1.lightxml</file>
- <file>expected_verbose1.teamcity</file>
- <file>expected_verbose1.txt</file>
- <file>expected_verbose1.xml</file>
- <file>expected_verbose1.xunitxml</file>
- <file>expected_verbose2.lightxml</file>
- <file>expected_verbose2.teamcity</file>
- <file>expected_verbose2.txt</file>
- <file>expected_verbose2.xml</file>
- <file>expected_verbose2.xunitxml</file>
- <file>expected_verifyexceptionthrown.lightxml</file>
- <file>expected_verifyexceptionthrown.teamcity</file>
- <file>expected_verifyexceptionthrown.txt</file>
- <file>expected_verifyexceptionthrown.xml</file>
- <file>expected_verifyexceptionthrown.xunitxml</file>
- <file>expected_warnings.lightxml</file>
- <file>expected_warnings.teamcity</file>
- <file>expected_warnings.txt</file>
- <file>expected_warnings.xml</file>
- <file>expected_warnings.xunitxml</file>
- <file>expected_xunit.lightxml</file>
- <file>expected_xunit.teamcity</file>
- <file>expected_xunit.txt</file>
- <file>expected_xunit.xml</file>
- <file>expected_xunit.xunitxml</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/testlib/selftests/test/test.pro b/tests/auto/testlib/selftests/test/test.pro
index bd2366f3e8..ec1633ebff 100644
--- a/tests/auto/testlib/selftests/test/test.pro
+++ b/tests/auto/testlib/selftests/test/test.pro
@@ -12,7 +12,9 @@ win32 {
}
}
-RESOURCES += ../selftests.qrc
+expected_files.files = $$files($$PWD/../expected_*)
+expected_files.base = $$PWD/..
+RESOURCES += expected_files
include(../selftests.pri)
!android:!winrt: for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../$${file}/$${file}"
diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp
index 63e5721e7e..c5f847562e 100644
--- a/tests/auto/testlib/selftests/tst_selftests.cpp
+++ b/tests/auto/testlib/selftests/tst_selftests.cpp
@@ -62,11 +62,22 @@ private slots:
private:
void doRunSubTest(QString const& subdir, QStringList const& loggers, QStringList const& arguments, bool crashes);
+ bool compareOutput(const QString &logger, const QString &subdir,
+ const QByteArray &rawOutput, const QByteArrayList &actual,
+ const QByteArrayList &expected,
+ QString *errorMessage) const;
+ bool compareLine(const QString &logger, const QString &subdir, bool benchmark,
+ const QString &actualLine, const QString &expLine,
+ QString *errorMessage) const;
+ bool checkXml(const QString &logger, QByteArray rawOutput,
+ QString *errorMessage) const;
+
QString logName(const QString &logger) const;
QList<LoggerSet> allLoggerSets() const;
QTemporaryDir tempDir;
QRegularExpression durationRegExp;
+ QRegularExpression teamcityLocRegExp;
};
struct BenchmarkResult
@@ -81,46 +92,50 @@ struct BenchmarkResult
static BenchmarkResult parse(QString const&, QString*);
};
-QT_BEGIN_NAMESPACE
-namespace QTest
+static QString msgMismatch(const QString &actual, const QString &expected)
{
-template <>
-inline bool qCompare
- (BenchmarkResult const &r1, BenchmarkResult const &r2,
- const char* actual, const char* expected, const char* file, int line)
+ return QLatin1String("Mismatch:\n'") + actual + QLatin1String("'\n !=\n'")
+ + expected + QLatin1Char('\'');
+}
+
+static bool compareBenchmarkResult(BenchmarkResult const &r1, BenchmarkResult const &r2,
+ QString *errorMessage)
{
// First make sure the iterations and unit match.
if (r1.iterations != r2.iterations || r1.unit != r2.unit) {
// Nope - compare whole string for best failure message
- return qCompare(r1.toString(), r2.toString(), actual, expected, file, line);
+ *errorMessage = msgMismatch(r1.toString(), r2.toString());
+ return false;
}
// Now check the value. Some variance is allowed, and how much depends on
// the measured unit.
qreal variance = 0.;
- if (r1.unit == "msecs" || r1.unit == "WalltimeMilliseconds") {
+ if (r1.unit == QLatin1String("msecs") || r1.unit == QLatin1String("WalltimeMilliseconds"))
variance = 0.1;
- }
- else if (r1.unit == "instruction reads") {
+ else if (r1.unit == QLatin1String("instruction reads"))
variance = 0.001;
- }
- else if (r1.unit == "CPU ticks" || r1.unit == "CPUTicks") {
+ else if (r1.unit == QLatin1String("CPU ticks") || r1.unit == QLatin1String("CPUTicks"))
variance = 0.001;
- }
+
if (variance == 0.) {
// No variance allowed - compare whole string
- return qCompare(r1.toString(), r2.toString(), actual, expected, file, line);
+ const QString r1S = r1.toString();
+ const QString r2S = r2.toString();
+ if (r1S != r2S) {
+ *errorMessage = msgMismatch(r1S, r2S);
+ return false;
+ }
+ return true;
}
- if (qAbs(qreal(r1.total) - qreal(r2.total)) <= qreal(r1.total)*variance) {
- return compare_helper(true, 0, 0, 0, actual, expected, file, line);
+ if (qAbs(qreal(r1.total) - qreal(r2.total)) > qreal(r1.total) * variance) {
+ // Whoops, didn't match. Compare the whole string for the most useful failure message.
+ *errorMessage = msgMismatch(r1.toString(), r2.toString());
+ return false;
}
-
- // Whoops, didn't match. Compare the whole string for the most useful failure message.
- return qCompare(r1.toString(), r2.toString(), actual, expected, file, line);
-}
+ return true;
}
-QT_END_NAMESPACE
// Split the passed block of text into an array of lines, replacing any
// filenames and line numbers with generic markers to avoid failing the test
@@ -227,26 +242,6 @@ static QByteArray runDiff(const QByteArrayList &expected, const QByteArrayList &
return result;
}
-// Print the difference preferably using 'diff', else just print lines
-static void printDifference(const QByteArrayList &expected, const QByteArrayList &actual)
-{
- QDebug info = qInfo();
- info.noquote();
- info.nospace();
- const QByteArray diff = runDiff(expected, actual);
- if (diff.isEmpty()) {
- info << "<<<<<<\n";
- for (const QByteArray &line : actual)
- info << line << '\n';
- info << "======\n";
- for (const QByteArray &line : expected)
- info << line << '\n';
- info << ">>>>>>\n";
- } else {
- info << diff;
- }
-}
-
// Each test is run with a set of one or more test output loggers.
// This struct holds information about one such test.
struct LoggerSet
@@ -315,6 +310,14 @@ QList<LoggerSet> tst_Selftests::allLoggerSets() const
QStringList() << "teamcity",
QStringList() << "-teamcity" << "-o" << logName("teamcity")
)
+ << LoggerSet("old stdout tap",
+ QStringList() << "stdout tap",
+ QStringList() << "-tap"
+ )
+ << LoggerSet("old tap",
+ QStringList() << "tap",
+ QStringList() << "-tap" << "-o" << logName("tap")
+ )
// Test with new-style options for a single logger
<< LoggerSet("new stdout txt",
QStringList() << "stdout txt",
@@ -362,6 +365,14 @@ QList<LoggerSet> tst_Selftests::allLoggerSets() const
QStringList() << "teamcity",
QStringList() << "-o" << logName("teamcity")+",teamcity"
)
+ << LoggerSet("new stdout tap",
+ QStringList() << "stdout tap",
+ QStringList() << "-o" << "-,tap"
+ )
+ << LoggerSet("new tap",
+ QStringList() << "tap",
+ QStringList() << "-o" << logName("tap")+",tap"
+ )
// Test with two loggers (don't test all 32 combinations, just a sample)
<< LoggerSet("stdout txt + txt",
QStringList() << "stdout txt" << "txt",
@@ -385,13 +396,14 @@ QList<LoggerSet> tst_Selftests::allLoggerSets() const
)
// All loggers at the same time (except csv)
<< LoggerSet("all loggers",
- QStringList() << "txt" << "xml" << "lightxml" << "stdout txt" << "xunitxml",
+ QStringList() << "txt" << "xml" << "lightxml" << "stdout txt" << "xunitxml" << "tap",
QStringList() << "-o" << logName("txt")+",txt"
<< "-o" << logName("xml")+",xml"
<< "-o" << logName("lightxml")+",lightxml"
<< "-o" << "-,txt"
<< "-o" << logName("xunitxml")+",xunitxml"
<< "-o" << logName("teamcity")+",teamcity"
+ << "-o" << logName("tap")+",tap"
)
;
}
@@ -399,6 +411,7 @@ QList<LoggerSet> tst_Selftests::allLoggerSets() const
tst_Selftests::tst_Selftests()
: tempDir(QDir::tempPath() + "/tst_selftests.XXXXXX")
, durationRegExp("<Duration msecs=\"[\\d\\.]+\"/>")
+ , teamcityLocRegExp("\\|\\[Loc: .*\\(\\d*\\)\\|\\]")
{}
void tst_Selftests::initTestCase()
@@ -464,6 +477,7 @@ void tst_Selftests::runSubTest_data()
<< "findtestdata"
<< "float"
<< "globaldata"
+ << "keyboard"
<< "longstring"
<< "maxwarnings"
<< "multiexec"
@@ -480,6 +494,7 @@ void tst_Selftests::runSubTest_data()
<< "sleep"
<< "strcmp"
<< "subtest"
+ << "tuplediagnostics"
<< "verbose1"
<< "verbose2"
#ifndef QT_NO_EXCEPTIONS
@@ -760,147 +775,203 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge
}
QList<QByteArray> res = splitLines(actualOutputs[n]);
- const QString expectedFileName = expectedFileNameFromTest(subdir, logger);
- QList<QByteArray> exp = expectedResult(expectedFileName);
+ QString errorMessage;
+ QString expectedFileName = expectedFileNameFromTest(subdir, logger);
+ QByteArrayList exp = expectedResult(expectedFileName);
+ if (!exp.isEmpty()) {
#ifdef Q_CC_MINGW
- // MinGW formats double numbers differently
- if (n == 0 && subdir == QStringLiteral("float")) {
- for (int i = 0; i < exp.size(); ++i) {
- exp[i].replace("e-07", "e-007");
- exp[i].replace("e+07", "e+007");
- }
- }
-#endif
-
- // For the "crashes" test, there are multiple versions of the
- // expected output. Load the one with the same line count as
- // the actual output.
- if (exp.count() == 0) {
- QList<QList<QByteArray> > expArr;
- QList<QByteArray> tmp;
- int i = 1;
- do {
- tmp = expectedResult(expectedFileNameFromTest(subdir + QLatin1Char('_') + QString::number(i++), logger));
- if (tmp.count())
- expArr += tmp;
- } while (tmp.count());
-
- for (int j = 0; j < expArr.count(); ++j) {
- if (res.count() == expArr.at(j).count()) {
- exp = expArr.at(j);
- break;
+ // MinGW formats double numbers differently (last verified with 7.1)
+ if (n == 0 && subdir == QStringLiteral("float")) {
+ for (int i = 0; i < exp.size(); ++i) {
+ exp[i].replace("e-07", "e-007");
+ exp[i].replace("e+07", "e+007");
}
}
-
- if (expArr.count()) {
- QVERIFY2(exp.count(),
- qPrintable(QString::fromLatin1("None of the expected output files for "
- "%1 format has matching line count.")
- .arg(loggers.at(n))));
+#endif
+ if (!compareOutput(logger, subdir, actualOutputs[n], res, exp, &errorMessage)) {
+ errorMessage.prepend(QLatin1Char('"') + logger + QLatin1String("\", ")
+ + expectedFileName + QLatin1Char(' '));
+ errorMessage += QLatin1String("\nActual:\n") + QLatin1String(actualOutputs[n]);
+ const QByteArray diff = runDiff(exp, res);
+ if (!diff.isEmpty())
+ errorMessage += QLatin1String("\nDiff:\n") + QLatin1String(diff);
+ QFAIL(qPrintable(errorMessage));
}
} else {
- if (res.count() != exp.count()) {
- printDifference(exp, res);
- QVERIFY2(res.count() == exp.count(),
- qPrintable(QString::fromLatin1("Mismatch in line count: %1 != %2 (%3, %4).")
- .arg(res.count()).arg(exp.count()).arg(loggers.at(n), expectedFileName)));
+ // For the "crashes" and other tests, there are multiple versions of the
+ // expected output. Loop until a matching one is found.
+ bool ok = false;
+ for (int i = 1; !ok; ++i) {
+ expectedFileName = expectedFileNameFromTest(subdir + QLatin1Char('_') + QString::number(i), logger);
+ const QByteArrayList exp = expectedResult(expectedFileName);
+ if (exp.isEmpty())
+ break;
+ QString errorMessage2;
+ ok = compareOutput(logger, subdir, actualOutputs[n], res, exp, &errorMessage2);
+ if (!ok)
+ errorMessage += QLatin1Char('\n') + expectedFileName + QLatin1String(": ") + errorMessage2;
+ }
+ if (!ok) { // Use QDebug's quote mechanism to report potentially garbled output.
+ errorMessage.prepend(QLatin1String("Cannot find a matching file for ") + subdir);
+ errorMessage += QLatin1String("\nActual:\n");
+ QDebug(&errorMessage) << actualOutputs[n];
+ QFAIL(qPrintable(errorMessage));
}
}
+ }
+}
- // By this point, we should have loaded a non-empty expected data file.
- QVERIFY2(exp.count(),
- qPrintable(QString::fromLatin1("Expected test data for %1 format is empty or not found.")
- .arg(loggers.at(n))));
-
- // For xml output formats, verify that the log is valid XML.
- if (logFormat(logger) == "xunitxml" || logFormat(logger) == "xml" || logFormat(logger) == "lightxml") {
- QByteArray xml(actualOutputs[n]);
- // lightxml intentionally skips the root element, which technically makes it
- // not valid XML.
- // We'll add that ourselves for the purpose of validation.
- if (logFormat(logger) == "lightxml") {
- xml.prepend("<root>");
- xml.append("</root>");
- }
+static QString teamCityLocation() { return QStringLiteral("|[Loc: _FILE_(_LINE_)|]"); }
+static QString qtVersionPlaceHolder() { return QStringLiteral("@INSERT_QT_VERSION_HERE@"); }
- QXmlStreamReader reader(xml);
+bool tst_Selftests::compareOutput(const QString &logger, const QString &subdir,
+ const QByteArray &rawOutput, const QByteArrayList &actual,
+ const QByteArrayList &expected,
+ QString *errorMessage) const
+{
- while (!reader.atEnd())
- reader.readNext();
+ if (actual.size() != expected.size()) {
+ *errorMessage = QString::fromLatin1("Mismatch in line count: %1 != %2.")
+ .arg(actual.size()).arg(expected.size());
+ return false;
+ }
- QVERIFY2(!reader.error(), qPrintable(QString("line %1, col %2: %3")
- .arg(reader.lineNumber())
- .arg(reader.columnNumber())
- .arg(reader.errorString())
- ));
+ // For xml output formats, verify that the log is valid XML.
+ if (logger.endsWith(QLatin1String("xml")) && !checkXml(logger, rawOutput, errorMessage))
+ return false;
+
+ // Verify that the actual output is an acceptable match for the
+ // expected output.
+
+ const QString qtVersion = QLatin1String(QT_VERSION_STR);
+ bool benchmark = false;
+ for (int i = 0, size = actual.size(); i < size; ++i) {
+ const QByteArray &actualLineBA = actual.at(i);
+ // the __FILE__ __LINE__ output is compiler dependent, skip it
+ if (actualLineBA.startsWith(" Loc: [") && actualLineBA.endsWith(")]"))
+ continue;
+ if (actualLineBA.endsWith(" : failure location"))
+ continue;
+
+ if (actualLineBA.startsWith("Config: Using QtTest library") // Text build string
+ || actualLineBA.startsWith(" <QtBuild") // XML, Light XML build string
+ || (actualLineBA.startsWith(" <property value=") && actualLineBA.endsWith("name=\"QtBuild\"/>"))) { // XUNIT-XML build string
+ continue;
}
- // Verify that the actual output is an acceptable match for the
- // expected output.
- bool benchmark = false;
- for (int i = 0; i < res.count(); ++i) {
- QByteArray line = res.at(i);
- // the __FILE__ __LINE__ output is compiler dependent, skip it
- if (line.startsWith(" Loc: [") && line.endsWith(")]"))
- continue;
- if (line.endsWith(" : failure location"))
- continue;
+ QString actualLine = QString::fromLatin1(actualLineBA);
+ QString expectedLine = QString::fromLatin1(expected.at(i));
+ expectedLine.replace(qtVersionPlaceHolder(), qtVersion);
- if (line.startsWith("Config: Using QtTest library") // Text build string
- || line.startsWith(" <QtBuild") // XML, Light XML build string
- || (line.startsWith(" <property value=") && line.endsWith("name=\"QtBuild\"/>"))) { // XUNIT-XML build string
- continue;
- }
+ // Special handling for ignoring _FILE_ and _LINE_ if logger is teamcity
+ if (logger.endsWith(QLatin1String("teamcity"))) {
+ actualLine.replace(teamcityLocRegExp, teamCityLocation());
+ expectedLine.replace(teamcityLocRegExp, teamCityLocation());
+ }
- QByteArray expLine = exp.at(i);
+ if (logger.endsWith(QLatin1String("tap"))) {
+ if (expectedLine.contains(QLatin1String("at:"))
+ || expectedLine.contains(QLatin1String("file:"))
+ || expectedLine.contains(QLatin1String("line:")))
+ actualLine = expectedLine;
+ }
- // Special handling for ignoring _FILE_ and _LINE_ if logger is teamcity
- if (logFormat(logger) == "teamcity") {
- QRegularExpression teamcityLocRegExp("\\|\\[Loc: .*\\(\\d*\\)\\|\\]");
- line = QString(line).replace(teamcityLocRegExp, "|[Loc: _FILE_(_LINE_)|]").toLatin1();
- expLine = QString(expLine).replace(teamcityLocRegExp, "|[Loc: _FILE_(_LINE_)|]").toLatin1();
- }
+ if (!compareLine(logger, subdir, benchmark, actualLine,
+ expectedLine, errorMessage)) {
+ errorMessage->prepend(QLatin1String("Line ") + QString::number(i + 1)
+ + QLatin1String(": "));
+ return false;
+ }
- const QString output(QString::fromLatin1(line));
- const QString expected(QString::fromLatin1(expLine).replace("@INSERT_QT_VERSION_HERE@", QT_VERSION_STR));
+ benchmark = actualLineBA.startsWith("RESULT : ");
+ }
+ return true;
+}
- if (subdir == "assert" && output.contains("ASSERT: ") && expected.contains("ASSERT: ") && output != expected)
- // Q_ASSERT uses __FILE__, the exact contents of which are
- // undefined. If we something that looks like a Q_ASSERT and we
- // were expecting to see a Q_ASSERT, we'll skip the line.
- continue;
- else if (expected.startsWith(QLatin1String("FAIL! : tst_Exception::throwException() Caught unhandled exce")) && expected != output)
- // On some platforms we compile without RTTI, and as a result we never throw an exception.
- QCOMPARE(output.simplified(), QString::fromLatin1("tst_Exception::throwException()").simplified());
- else if (benchmark || line.startsWith("<BenchmarkResult") || (logFormat(logger) == "csv" && line.startsWith('"'))) {
- // Don't do a literal comparison for benchmark results, since
- // results have some natural variance.
- QString error;
-
- BenchmarkResult actualResult = BenchmarkResult::parse(output, &error);
- QVERIFY2(error.isEmpty(), qPrintable(QString("Actual line didn't parse as benchmark result: %1\nLine: %2").arg(error).arg(output)));
-
- BenchmarkResult expectedResult = BenchmarkResult::parse(expected, &error);
- QVERIFY2(error.isEmpty(), qPrintable(QString("Expected line didn't parse as benchmark result: %1\nLine: %2").arg(error).arg(expected)));
-
- QCOMPARE(actualResult, expectedResult);
- } else if (line.startsWith(" <Duration msecs=") || line.startsWith("<Duration msecs=")) {
- QRegularExpressionMatch match = durationRegExp.match(line);
- QVERIFY2(match.hasMatch(), qPrintable(QString::fromLatin1("Invalid Duration tag at line %1 (%2): '%3'")
- .arg(i).arg(loggers.at(n), output)));
- } else if (line.startsWith("Totals:")) {
- const int lastCommaPos = line.lastIndexOf(',');
- if (lastCommaPos > 0)
- line.truncate(lastCommaPos); // Plain text logger: strip time (", 2323dms").
- } else {
- QVERIFY2(output == expected,
- qPrintable(QString::fromLatin1("Mismatch at line %1 (%2, %3):\n'%4'\n !=\n'%5'")
- .arg(i + 1).arg(loggers.at(n), expectedFileName, output, expected)));
- }
+bool tst_Selftests::compareLine(const QString &logger, const QString &subdir,
+ bool benchmark,
+ const QString &actualLine, const QString &expectedLine,
+ QString *errorMessage) const
+{
+ if (subdir == QLatin1String("assert") && actualLine.contains(QLatin1String("ASSERT: "))
+ && expectedLine.contains(QLatin1String("ASSERT: ")) && actualLine != expectedLine) {
+ // Q_ASSERT uses __FILE__, the exact contents of which are
+ // undefined. If have we something that looks like a Q_ASSERT and we
+ // were expecting to see a Q_ASSERT, we'll skip the line.
+ return true;
+ }
- benchmark = line.startsWith("RESULT : ");
+ if (expectedLine.startsWith(QLatin1String("FAIL! : tst_Exception::throwException() Caught unhandled exce"))
+ && actualLine != expectedLine) {
+ // On some platforms we compile without RTTI, and as a result we never throw an exception
+ if (actualLine.simplified() != QLatin1String("tst_Exception::throwException()")) {
+ *errorMessage = QString::fromLatin1("'%1' != 'tst_Exception::throwException()'").arg(actualLine);
+ return false;
}
+ return true;
+ }
+
+ if (benchmark || actualLine.startsWith(QLatin1String("<BenchmarkResult"))
+ || (logger == QLatin1String("csv") && actualLine.startsWith(QLatin1Char('"')))) {
+ // Don't do a literal comparison for benchmark results, since
+ // results have some natural variance.
+ QString error;
+ BenchmarkResult actualResult = BenchmarkResult::parse(actualLine, &error);
+ if (!error.isEmpty()) {
+ *errorMessage = QString::fromLatin1("Actual line didn't parse as benchmark result: %1\nLine: %2").arg(error, actualLine);
+ return false;
+ }
+ BenchmarkResult expectedResult = BenchmarkResult::parse(expectedLine, &error);
+ if (!error.isEmpty()) {
+ *errorMessage = QString::fromLatin1("Expected line didn't parse as benchmark result: %1\nLine: %2").arg(error, expectedLine);
+ return false;
+ }
+ return compareBenchmarkResult(actualResult, expectedResult, errorMessage);
+ }
+
+ if (actualLine.startsWith(QLatin1String(" <Duration msecs="))
+ || actualLine.startsWith(QLatin1String("<Duration msecs="))) {
+ QRegularExpressionMatch match = durationRegExp.match(actualLine);
+ if (match.hasMatch())
+ return true;
+ *errorMessage = QString::fromLatin1("Invalid Duration tag: '%1'").arg(actualLine);
+ return false;
+ }
+
+ if (actualLine.startsWith(QLatin1String("Totals:")) && expectedLine.startsWith(QLatin1String("Totals:")))
+ return true;
+
+ if (actualLine == expectedLine)
+ return true;
+
+ *errorMessage = msgMismatch(actualLine, expectedLine);
+ return false;
+}
+
+bool tst_Selftests::checkXml(const QString &logger, QByteArray xml,
+ QString *errorMessage) const
+{
+ // lightxml intentionally skips the root element, which technically makes it
+ // not valid XML.
+ // We'll add that ourselves for the purpose of validation.
+ if (logger.endsWith(QLatin1String("lightxml"))) {
+ xml.prepend("<root>");
+ xml.append("</root>");
+ }
+
+ QXmlStreamReader reader(xml);
+ while (!reader.atEnd())
+ reader.readNext();
+
+ if (reader.hasError()) {
+ const int lineNumber = int(reader.lineNumber());
+ const QByteArray line = xml.split('\n').value(lineNumber - 1);
+ *errorMessage = QString::fromLatin1("line %1, col %2 '%3': %4")
+ .arg(lineNumber).arg(reader.columnNumber())
+ .arg(QString::fromLatin1(line), reader.errorString());
+ return false;
}
+ return true;
}
#endif // QT_CONFIG(process)
diff --git a/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp b/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp
new file mode 100644
index 0000000000..17da52eaba
--- /dev/null
+++ b/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Make sure we get a real Q_ASSERT even in release builds
+#ifdef QT_NO_DEBUG
+# undef QT_NO_DEBUG
+#endif
+
+#include <QtTest/QtTest>
+
+class tst_TupleDiagnostics: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void testEmptyTuple() const;
+ void testSimpleTuple() const;
+ void testTuple() const;
+};
+
+void tst_TupleDiagnostics::testEmptyTuple() const
+{
+ QCOMPARE(std::tuple<>{}, std::tuple<>{});
+}
+
+void tst_TupleDiagnostics::testSimpleTuple() const
+{
+ QCOMPARE(std::tuple<int>{1}, std::tuple<int>{2});
+}
+
+void tst_TupleDiagnostics::testTuple() const
+{
+ std::tuple<int, char, QString> tuple1{42, 'Y', QStringLiteral("tuple1")};
+ std::tuple<int, char, QString> tuple2{42, 'Y', QStringLiteral("tuple2")};
+ QCOMPARE(tuple1, tuple2);
+}
+
+QTEST_MAIN(tst_TupleDiagnostics)
+
+#include "tst_tuplediagnostics.moc"
diff --git a/tests/auto/testlib/selftests/tuplediagnostics/tuplediagnostics.pro b/tests/auto/testlib/selftests/tuplediagnostics/tuplediagnostics.pro
new file mode 100644
index 0000000000..7a29e0e5e1
--- /dev/null
+++ b/tests/auto/testlib/selftests/tuplediagnostics/tuplediagnostics.pro
@@ -0,0 +1,6 @@
+SOURCES += tst_tuplediagnostics.cpp
+QT = core testlib
+
+CONFIG -= app_bundle debug_and_release_target
+
+TARGET = tuplediagnostics
diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri
new file mode 100644
index 0000000000..b2f593235f
--- /dev/null
+++ b/tests/auto/testserver.pri
@@ -0,0 +1,109 @@
+# Integrating docker-based test servers into Qt Test framework
+#
+# This file adds support for docker-based test servers built by testcase
+# projects that need them. To enable this feature, any automated test can
+# include testserver.pri in its project file. This instructs qmake to insert
+# additional targets into the generated Makefile. The 'check' target then brings
+# up test servers before running the testcase, and shuts them down afterwards.
+#
+# TESTSERVER_COMPOSE_FILE
+# - Contains the path of docker-compose file
+# This configuration file defines the services used for autotests. It tells the
+# docker engine how to build up the docker images and containers. In qtbase, a
+# shared docker-compose file is located in the tests folder.
+# Example: TESTSERVER_COMPOSE_FILE = \
+# $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml
+#
+# The user must run the provisioning scripts in advance before attempting to
+# build the test servers. The docker_testserver.sh script is used to build up
+# the docker images into the docker-cache. It handles the immutable parts of the
+# server installation that rarely need adjustment, such as downloading packages.
+# Example: qt5/coin/provisioning/.../testserver/docker_testserver.sh
+#
+# QT_TEST_SERVER_LIST
+# - A list of test servers to bring up for this testcase
+# These test servers should be defined in $$TESTSERVER_COMPOSE_FILE. Each
+# testcase can define the test servers it depends on.
+# Example: QT_TEST_SERVER_LIST = apache2 squid vsftpd ftp-proxy danted
+#
+# Pre-processor defines needed for the application:
+# QT_TEST_SERVER
+# - A preprocessor macro used for testcase to change testing parameters at
+# compile time
+# This macro is predefined for docker-based test servers and is passed as a
+# compiler option (-DQT_TEST_SERVER). The testcase can then check whether
+# docker-based servers are in use and change the testing parameters, such as
+# host name or port number, at compile time. An example can be found in
+# network-settings.h.
+#
+# Example:
+# #if defined(QT_TEST_SERVER)
+# Change the testing parameters at compile time
+# #endif
+#
+# QT_TEST_SERVER_DOMAIN
+# - A preprocessor macro that holds the server domain name
+# Provided for the helper functions in network-settings.h. Use function
+# serverDomainName() in your application instead.
+#
+# Additional make targets:
+# 1. check_network - A renamed target from the check target of testcase feature.
+# 2. testserver_clean - Clean up server containers/images and tidy away related
+# files.
+
+TESTSERVER_COMPOSE_FILE = $$dirname(_QMAKE_CONF_)/tests/testserver/docker-compose.yml
+TESTSERVER_VERSION = $$system(docker-compose --version)
+
+equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) {
+ # Make check with server "qt-test-server.qt-test-net" as a fallback
+ message("testserver: qt-test-server.qt-test-net")
+} else {
+ # Make check with test servers
+ message("testserver:" $$TESTSERVER_VERSION)
+
+ # Ensure that the docker-compose file is provided. It is a configuration
+ # file which is mandatory for all docker-compose commands. You can get more
+ # detail from the description of TESTSERVER_COMPOSE_FILE above. There is
+ # also an example showing how to configure it manually.
+ FILE_PRETEST_MSG = "Project variable 'TESTSERVER_COMPOSE_FILE' is not set"
+ testserver_pretest.commands = $(if $$TESTSERVER_COMPOSE_FILE,,$(error $$FILE_PRETEST_MSG))
+
+ # Before starting the test servers, it requires the user to run the setup
+ # script (coin/provisioning/.../testserver/docker_testserver.sh) in advance.
+ IMAGE_PRETEST_CMD = docker images -aq "qt-test-server-*"
+ IMAGE_PRETEST_MSG = "Docker image qt-test-server-* not found"
+ testserver_pretest.commands += $(if $(shell $$IMAGE_PRETEST_CMD),,$(error $$IMAGE_PRETEST_MSG))
+
+ # The domain name is relevant to https keycert (qnetworkreply/crts/qt-test-net-cacert.pem).
+ DNSDOMAIN = test-net.qt.local
+ TEST_ENV += TESTSERVER_DOMAIN=$$DNSDOMAIN
+ DEFINES += QT_TEST_SERVER QT_TEST_SERVER_DOMAIN=$$shell_quote(\"$${DNSDOMAIN}\")
+
+ # There is no docker bridge on macOS. It is impossible to ping a container.
+ # Docker docs recommends using port mapping to connect to a container.
+ equals(QMAKE_HOST.os, Darwin): TEST_ENV += TESTSERVER_BIND_LOCAL=1
+
+ # Rename the check target of testcase feature
+ check.target = check_network
+ testserver_test.target = check
+
+ # Pretesting test servers environment
+ testserver_test.depends = testserver_pretest
+
+ # Bring up test servers and make sure the services are ready.
+ testserver_test.commands = $$TEST_ENV docker-compose -f $$TESTSERVER_COMPOSE_FILE up -d \
+ --force-recreate --timeout 1 $${QT_TEST_SERVER_LIST} &&
+
+ # Check test cases with docker-based test servers.
+ testserver_test.commands += $(MAKE) check_network;
+
+ # Stop and remove test servers after testing.
+ testserver_test.commands += $$TEST_ENV docker-compose -f $$TESTSERVER_COMPOSE_FILE down \
+ --timeout 1
+
+ # Destroy test servers and tidy away related files.
+ testserver_clean.commands = $$TEST_ENV docker-compose -f $$TESTSERVER_COMPOSE_FILE down \
+ --rmi all
+
+ QMAKE_EXTRA_TARGETS += testserver_pretest testserver_test testserver_clean
+}
diff --git a/tests/auto/tools/moc/cxx11-enums.h b/tests/auto/tools/moc/cxx11-enums.h
index 47a4857cd0..93ab16c157 100644
--- a/tests/auto/tools/moc/cxx11-enums.h
+++ b/tests/auto/tools/moc/cxx11-enums.h
@@ -39,10 +39,14 @@ public:
enum TypedEnum : char { B0, B1 , B2, B3 };
enum class TypedEnumClass : char { C0, C1, C2, C3 };
enum NormalEnum { D2 = 2, D3, D0 =0 , D1 };
+ enum class ClassFlag { F0 = 1, F1 = 2, F2 = 4, F3 = 8};
+ Q_DECLARE_FLAGS(ClassFlags, ClassFlag)
+
Q_ENUM(EnumClass)
Q_ENUM(TypedEnum)
Q_ENUM(TypedEnumClass)
Q_ENUM(NormalEnum)
+ Q_FLAG(ClassFlags)
};
// Also test the Q_ENUMS macro
@@ -54,7 +58,10 @@ public:
enum TypedEnum : char { B0, B1 , B2, B3 };
enum class TypedEnumClass : char { C0, C1, C2, C3 };
enum NormalEnum { D2 = 2, D3, D0 =0 , D1 };
+ enum class ClassFlag { F0 = 1, F1 = 2, F2 = 4, F3 = 8 };
+ Q_DECLARE_FLAGS(ClassFlags, ClassFlag)
Q_ENUMS(EnumClass TypedEnum TypedEnumClass NormalEnum)
+ Q_FLAGS(ClassFlags)
};
#else
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index 753da401a2..92a94055a4 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -2248,6 +2248,7 @@ void tst_Moc::privateClass()
void tst_Moc::cxx11Enums_data()
{
QTest::addColumn<const QMetaObject *>("meta");
+ QTest::addColumn<QByteArray>("typeName");
QTest::addColumn<QByteArray>("enumName");
QTest::addColumn<char>("prefix");
QTest::addColumn<bool>("isScoped");
@@ -2255,14 +2256,16 @@ void tst_Moc::cxx11Enums_data()
const QMetaObject *meta1 = &CXX11Enums::staticMetaObject;
const QMetaObject *meta2 = &CXX11Enums2::staticMetaObject;
- QTest::newRow("EnumClass") << meta1 << QByteArray("EnumClass") << 'A' << true;
- QTest::newRow("EnumClass 2") << meta2 << QByteArray("EnumClass") << 'A' << true;
- QTest::newRow("TypedEnum") << meta1 << QByteArray("TypedEnum") << 'B' << false;
- QTest::newRow("TypedEnum 2") << meta2 << QByteArray("TypedEnum") << 'B' << false;
- QTest::newRow("TypedEnumClass") << meta1 << QByteArray("TypedEnumClass") << 'C' << true;
- QTest::newRow("TypedEnumClass 2") << meta2 << QByteArray("TypedEnumClass") << 'C' << true;
- QTest::newRow("NormalEnum") << meta1 << QByteArray("NormalEnum") << 'D' << false;
- QTest::newRow("NormalEnum 2") << meta2 << QByteArray("NormalEnum") << 'D' << false;
+ QTest::newRow("EnumClass") << meta1 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true;
+ QTest::newRow("EnumClass 2") << meta2 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true;
+ QTest::newRow("TypedEnum") << meta1 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false;
+ QTest::newRow("TypedEnum 2") << meta2 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false;
+ QTest::newRow("TypedEnumClass") << meta1 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true;
+ QTest::newRow("TypedEnumClass 2") << meta2 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true;
+ QTest::newRow("NormalEnum") << meta1 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false;
+ QTest::newRow("NormalEnum 2") << meta2 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false;
+ QTest::newRow("ClassFlags") << meta1 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true;
+ QTest::newRow("ClassFlags 2") << meta2 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true;
}
void tst_Moc::cxx11Enums()
@@ -2270,21 +2273,26 @@ void tst_Moc::cxx11Enums()
QFETCH(const QMetaObject *,meta);
QCOMPARE(meta->enumeratorOffset(), 0);
+ QFETCH(QByteArray, typeName);
QFETCH(QByteArray, enumName);
QFETCH(char, prefix);
QFETCH(bool, isScoped);
- int idx;
- idx = meta->indexOfEnumerator(enumName);
+ int idx = meta->indexOfEnumerator(typeName);
QVERIFY(idx != -1);
+ QCOMPARE(meta->indexOfEnumerator(enumName), idx);
+
QCOMPARE(meta->enumerator(idx).enclosingMetaObject(), meta);
QCOMPARE(meta->enumerator(idx).isValid(), true);
QCOMPARE(meta->enumerator(idx).keyCount(), 4);
- QCOMPARE(meta->enumerator(idx).name(), enumName.constData());
+ QCOMPARE(meta->enumerator(idx).name(), typeName.constData());
+ QCOMPARE(meta->enumerator(idx).enumName(), enumName.constData());
+ bool isFlag = meta->enumerator(idx).isFlag();
for (int i = 0; i < 4; i++) {
QByteArray v = prefix + QByteArray::number(i);
- QCOMPARE(meta->enumerator(idx).keyToValue(v), i);
- QCOMPARE(meta->enumerator(idx).valueToKey(i), v.constData());
+ const int value = isFlag ? (1 << i) : i;
+ QCOMPARE(meta->enumerator(idx).keyToValue(v), value);
+ QCOMPARE(meta->enumerator(idx).valueToKey(value), v.constData());
}
QCOMPARE(meta->enumerator(idx).isScoped(), isScoped);
}
diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp
index aeedf4ae32..948e2b3121 100644
--- a/tests/auto/tools/qmakelib/evaltest.cpp
+++ b/tests/auto/tools/qmakelib/evaltest.cpp
@@ -819,7 +819,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$member(): bad number of arguments")
<< "VAR = $$member(1, 2, 3, 4)"
<< "VAR ="
- << "##:1: member(var, start, end) requires one to three arguments."
+ << "##:1: member(var, [start, [end]]) requires one to three arguments."
<< true;
QTest::newRow("$$member(): bad args (1)")
@@ -1030,8 +1030,8 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$fromfile(): bad number of arguments")
<< "VAR = $$fromfile(1) \\\n$$fromfile(1, 2, 3)"
<< "VAR ="
- << "##:1: fromfile(file, variable) requires two arguments.\n"
- "##:2: fromfile(file, variable) requires two arguments."
+ << "##:1: fromfile(file, var) requires two arguments.\n"
+ "##:2: fromfile(file, var) requires two arguments."
<< true;
QTest::newRow("$$eval()")
@@ -1043,7 +1043,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$eval(): bad number of arguments")
<< "VAR = $$eval(1, 2)"
<< "VAR ="
- << "##:1: eval(variable) requires one argument."
+ << "##:1: eval(var) requires one argument."
<< true;
QTest::newRow("$$list()")
@@ -1128,7 +1128,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$format_number(): bad number of arguments")
<< "VAR = $$format_number(13, 1, 2)"
<< "VAR ="
- << "##:1: format_number(number[, options...]) requires one or two arguments."
+ << "##:1: format_number(number, [options...]) requires one or two arguments."
<< true;
QTest::newRow("$$format_number(): invalid option")
@@ -1200,7 +1200,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$join(): bad number of arguments")
<< "VAR = $$join(1, 2, 3, 4, 5)"
<< "VAR ="
- << "##:1: join(var, glue, before, after) requires one to four arguments."
+ << "##:1: join(var, [glue, [before, [after]]]) requires one to four arguments."
<< true;
QTest::newRow("$$split(): default sep")
@@ -1296,8 +1296,8 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$section(): bad number of arguments")
<< "VAR = $$section(1, 2) \\\n$$section(1, 2, 3, 4, 5)"
<< "VAR ="
- << "##:1: section(var, sep, begin, end) requires three or four arguments.\n"
- "##:2: section(var, sep, begin, end) requires three or four arguments."
+ << "##:1: section(var, sep, begin, [end]) requires three or four arguments.\n"
+ "##:2: section(var, sep, begin, [end]) requires three or four arguments."
<< true;
QTest::newRow("$$find()")
@@ -1333,7 +1333,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$cat(): bad number of arguments")
<< "VAR = $$cat(1, 2, 3)"
<< "VAR ="
- << "##:1: cat(file, singleline=true) requires one or two arguments."
+ << "##:1: cat(file, [mode=true|blob|lines]) requires one or two arguments."
<< true;
QTest::newRow("$$system(): default mode")
@@ -1473,7 +1473,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$files(): bad number of arguments")
<< "VAR = $$files(1, 2, 3)"
<< "VAR ="
- << "##:1: files(pattern, recursive=false) requires one or two arguments."
+ << "##:1: files(pattern, [recursive=false]) requires one or two arguments."
<< true;
#if 0
@@ -1639,7 +1639,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$absolute_path(): bad number of arguments")
<< "VAR = $$absolute_path(1, 2, 3)"
<< "VAR ="
- << "##:1: absolute_path(path[, base]) requires one or two arguments."
+ << "##:1: absolute_path(path, [base]) requires one or two arguments."
<< true;
QTest::newRow("$$relative_path(): relative file")
@@ -1683,7 +1683,7 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir)
QTest::newRow("$$relative_path(): bad number of arguments")
<< "VAR = $$relative_path(1, 2, 3)"
<< "VAR ="
- << "##:1: relative_path(path[, base]) requires one or two arguments."
+ << "##:1: relative_path(path, [base]) requires one or two arguments."
<< true;
QTest::newRow("$$clean_path()")
@@ -1847,7 +1847,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("defined(): bad number of arguments")
<< "defined(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: defined(function, [\"test\"|\"replace\"|\"var\"]) requires one or two arguments."
+ << "##:1: defined(object, [\"test\"|\"replace\"|\"var\"]) requires one or two arguments."
<< true;
QTest::newRow("export()")
@@ -1864,7 +1864,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("export(): bad number of arguments")
<< "export(1, 2): OK = 1"
<< "OK = UNDEF"
- << "##:1: export(variable) requires one argument."
+ << "##:1: export(var) requires one argument."
<< true;
QTest::newRow("infile(): found")
@@ -2006,7 +2006,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("CONFIG(): bad number of arguments")
<< "CONFIG(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: CONFIG(config) requires one or two arguments."
+ << "##:1: CONFIG(config, [mutuals]) requires one or two arguments."
<< true;
QTest::newRow("contains(simple plain): true")
@@ -2072,8 +2072,8 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("contains(): bad number of arguments")
<< "contains(1): OK = 1\ncontains(1, 2, 3, 4): OK = 1"
<< "OK = UNDEF"
- << "##:1: contains(var, val) requires two or three arguments.\n"
- "##:2: contains(var, val) requires two or three arguments."
+ << "##:1: contains(var, val, [mutuals]) requires two or three arguments.\n"
+ "##:2: contains(var, val, [mutuals]) requires two or three arguments."
<< true;
QTest::newRow("count(): true")
@@ -2133,8 +2133,8 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("count(): bad number of arguments")
<< "count(1): OK = 1\ncount(1, 2, 3, 4): OK = 1"
<< "OK = UNDEF"
- << "##:1: count(var, count, op=\"equals\") requires two or three arguments.\n"
- "##:2: count(var, count, op=\"equals\") requires two or three arguments."
+ << "##:1: count(var, count, [op=operator]) requires two or three arguments.\n"
+ "##:2: count(var, count, [op=operator]) requires two or three arguments."
<< true;
QTest::newRow("greaterThan(int): true")
@@ -2164,8 +2164,8 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("greaterThan(): bad number of arguments")
<< "greaterThan(1): OK = 1\ngreaterThan(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: greaterThan(variable, value) requires two arguments.\n"
- "##:2: greaterThan(variable, value) requires two arguments."
+ << "##:1: greaterThan(var, val) requires two arguments.\n"
+ "##:2: greaterThan(var, val) requires two arguments."
<< true;
QTest::newRow("lessThan(int): true")
@@ -2195,8 +2195,8 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("lessThan(): bad number of arguments")
<< "lessThan(1): OK = 1\nlessThan(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: lessThan(variable, value) requires two arguments.\n"
- "##:2: lessThan(variable, value) requires two arguments."
+ << "##:1: lessThan(var, val) requires two arguments.\n"
+ "##:2: lessThan(var, val) requires two arguments."
<< true;
QTest::newRow("equals(): true")
@@ -2214,8 +2214,8 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("equals(): bad number of arguments")
<< "equals(1): OK = 1\nequals(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: equals(variable, value) requires two arguments.\n"
- "##:2: equals(variable, value) requires two arguments."
+ << "##:1: equals(var, val) requires two arguments.\n"
+ "##:2: equals(var, val) requires two arguments."
<< true;
// That's just an alias, so don't test much.
@@ -2240,8 +2240,8 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("versionAtLeast(): bad number of arguments")
<< "versionAtLeast(1): OK = 1\nversionAtLeast(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: versionAtLeast(variable, versionNumber) requires two arguments.\n"
- "##:2: versionAtLeast(variable, versionNumber) requires two arguments."
+ << "##:1: versionAtLeast(var, version) requires two arguments.\n"
+ "##:2: versionAtLeast(var, version) requires two arguments."
<< true;
QTest::newRow("versionAtMost(): true")
@@ -2259,8 +2259,8 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("versionAtMost(): bad number of arguments")
<< "versionAtMost(1): OK = 1\nversionAtMost(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: versionAtMost(variable, versionNumber) requires two arguments.\n"
- "##:2: versionAtMost(variable, versionNumber) requires two arguments."
+ << "##:1: versionAtMost(var, version) requires two arguments.\n"
+ "##:2: versionAtMost(var, version) requires two arguments."
<< true;
QTest::newRow("clear(): top-level")
@@ -2288,7 +2288,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("clear(): bad number of arguments")
<< "clear(1, 2): OK = 1"
<< "OK = UNDEF"
- << "##:1: clear(variable) requires one argument."
+ << "##:1: clear(var) requires one argument."
<< true;
QTest::newRow("unset(): top-level")
@@ -2316,7 +2316,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("unset(): bad number of arguments")
<< "unset(1, 2): OK = 1"
<< "OK = UNDEF"
- << "##:1: unset(variable) requires one argument."
+ << "##:1: unset(var) requires one argument."
<< true;
// This function does not follow the established naming pattern.
@@ -2362,8 +2362,8 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("parseJson(): bad number of arguments")
<< "parseJson(1): OK = 1\nparseJson(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: parseJson(variable, into) requires two arguments.\n"
- "##:2: parseJson(variable, into) requires two arguments."
+ << "##:1: parseJson(var, into) requires two arguments.\n"
+ "##:2: parseJson(var, into) requires two arguments."
<< true;
QTest::newRow("include()")
@@ -2395,7 +2395,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("include(): bad number of arguments")
<< "include(1, 2, 3, 4): OK = 1"
<< "OK = UNDEF"
- << "##:1: include(file, [into, [silent]]) requires one, two or three arguments."
+ << "##:1: include(file, [into, [silent]]) requires one to three arguments."
<< true;
QTest::newRow("load()")
@@ -2419,7 +2419,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("load(): bad number of arguments")
<< "load(1, 2, 3): OK = 1"
<< "OK = UNDEF"
- << "##:1: load(feature) requires one or two arguments."
+ << "##:1: load(feature, [ignore_errors=false]) requires one or two arguments."
<< true;
QTest::newRow("discard_from()")
@@ -2668,7 +2668,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir)
QTest::newRow("mkpath(): bad number of arguments")
<< "mkpath(1, 2): OK = 1"
<< "OK = UNDEF"
- << "##:1: mkpath(file) requires one argument."
+ << "##:1: mkpath(path) requires one argument."
<< true;
#if 0
diff --git a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h
index d8db966b76..1f5004b2aa 100644
--- a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h
+++ b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h
@@ -24,10 +24,10 @@ public:
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
- Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(400, 300);
buttonBox = new QDialogButtonBox(Dialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setGeometry(QRect(30, 240, 341, 32));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h
index b167eaec8a..8dd8b11b62 100644
--- a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h
+++ b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h
@@ -24,10 +24,10 @@ public:
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
- Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(400, 300);
buttonBox = new QDialogButtonBox(Dialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setGeometry(QRect(290, 20, 81, 241));
buttonBox->setOrientation(Qt::Vertical);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h b/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h
index 52e9f3b931..95acabf3f8 100644
--- a/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h
+++ b/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h
@@ -22,7 +22,7 @@ public:
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
- Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(400, 300);
retranslateUi(Dialog);
diff --git a/tests/auto/tools/uic/baseline/Main_Window.ui.h b/tests/auto/tools/uic/baseline/Main_Window.ui.h
index eba78c1a2b..9e59e9f2e5 100644
--- a/tests/auto/tools/uic/baseline/Main_Window.ui.h
+++ b/tests/auto/tools/uic/baseline/Main_Window.ui.h
@@ -28,16 +28,16 @@ public:
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
- MainWindow->setObjectName(QStringLiteral("MainWindow"));
+ MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(800, 600);
menubar = new QMenuBar(MainWindow);
- menubar->setObjectName(QStringLiteral("menubar"));
+ menubar->setObjectName(QString::fromUtf8("menubar"));
MainWindow->setMenuBar(menubar);
centralwidget = new QWidget(MainWindow);
- centralwidget->setObjectName(QStringLiteral("centralwidget"));
+ centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
MainWindow->setCentralWidget(centralwidget);
statusbar = new QStatusBar(MainWindow);
- statusbar->setObjectName(QStringLiteral("statusbar"));
+ statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
retranslateUi(MainWindow);
diff --git a/tests/auto/tools/uic/baseline/Widget.ui.h b/tests/auto/tools/uic/baseline/Widget.ui.h
index 8cb31b4589..4318c2262f 100644
--- a/tests/auto/tools/uic/baseline/Widget.ui.h
+++ b/tests/auto/tools/uic/baseline/Widget.ui.h
@@ -30,22 +30,22 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(400, 300);
vboxLayout = new QVBoxLayout(Form);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
Alabel = new QLabel(Form);
- Alabel->setObjectName(QStringLiteral("Alabel"));
+ Alabel->setObjectName(QString::fromUtf8("Alabel"));
vboxLayout->addWidget(Alabel);
groupBox = new QGroupBox(Form);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
vboxLayout->addWidget(groupBox);
pushButton = new QPushButton(Form);
- pushButton->setObjectName(QStringLiteral("pushButton"));
+ pushButton->setObjectName(QString::fromUtf8("pushButton"));
vboxLayout->addWidget(pushButton);
diff --git a/tests/auto/tools/uic/baseline/addlinkdialog.ui.h b/tests/auto/tools/uic/baseline/addlinkdialog.ui.h
index 71d091380a..17f51a92f8 100644
--- a/tests/auto/tools/uic/baseline/addlinkdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/addlinkdialog.ui.h
@@ -38,31 +38,31 @@ public:
void setupUi(QDialog *AddLinkDialog)
{
if (AddLinkDialog->objectName().isEmpty())
- AddLinkDialog->setObjectName(QStringLiteral("AddLinkDialog"));
+ AddLinkDialog->setObjectName(QString::fromUtf8("AddLinkDialog"));
AddLinkDialog->setSizeGripEnabled(false);
AddLinkDialog->setModal(true);
verticalLayout = new QVBoxLayout(AddLinkDialog);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
formLayout = new QFormLayout();
- formLayout->setObjectName(QStringLiteral("formLayout"));
+ formLayout->setObjectName(QString::fromUtf8("formLayout"));
label = new QLabel(AddLinkDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
formLayout->setWidget(0, QFormLayout::LabelRole, label);
titleInput = new QLineEdit(AddLinkDialog);
- titleInput->setObjectName(QStringLiteral("titleInput"));
+ titleInput->setObjectName(QString::fromUtf8("titleInput"));
titleInput->setMinimumSize(QSize(337, 0));
formLayout->setWidget(0, QFormLayout::FieldRole, titleInput);
label_2 = new QLabel(AddLinkDialog);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
formLayout->setWidget(1, QFormLayout::LabelRole, label_2);
urlInput = new QLineEdit(AddLinkDialog);
- urlInput->setObjectName(QStringLiteral("urlInput"));
+ urlInput->setObjectName(QString::fromUtf8("urlInput"));
formLayout->setWidget(1, QFormLayout::FieldRole, urlInput);
@@ -74,14 +74,14 @@ public:
verticalLayout->addItem(verticalSpacer);
line = new QFrame(AddLinkDialog);
- line->setObjectName(QStringLiteral("line"));
+ line->setObjectName(QString::fromUtf8("line"));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
verticalLayout->addWidget(line);
buttonBox = new QDialogButtonBox(AddLinkDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/addtorrentform.ui.h b/tests/auto/tools/uic/baseline/addtorrentform.ui.h
index e76f05f1de..d259a011bf 100644
--- a/tests/auto/tools/uic/baseline/addtorrentform.ui.h
+++ b/tests/auto/tools/uic/baseline/addtorrentform.ui.h
@@ -56,7 +56,7 @@ public:
void setupUi(QDialog *AddTorrentFile)
{
if (AddTorrentFile->objectName().isEmpty())
- AddTorrentFile->setObjectName(QStringLiteral("AddTorrentFile"));
+ AddTorrentFile->setObjectName(QString::fromUtf8("AddTorrentFile"));
AddTorrentFile->resize(464, 385);
AddTorrentFile->setSizeGripEnabled(false);
AddTorrentFile->setModal(true);
@@ -65,56 +65,56 @@ public:
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(8, 8, 8, 8);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(AddTorrentFile);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
widget = new QWidget(groupBox);
- widget->setObjectName(QStringLiteral("widget"));
+ widget->setObjectName(QString::fromUtf8("widget"));
widget->setGeometry(QRect(10, 40, 364, 33));
gridLayout = new QGridLayout(groupBox);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
#endif
gridLayout->setContentsMargins(8, 8, 8, 8);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label_4 = new QLabel(groupBox);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
gridLayout->addWidget(label_4, 6, 0, 1, 1);
torrentFile = new QLineEdit(groupBox);
- torrentFile->setObjectName(QStringLiteral("torrentFile"));
+ torrentFile->setObjectName(QString::fromUtf8("torrentFile"));
gridLayout->addWidget(torrentFile, 0, 1, 1, 2);
label_2 = new QLabel(groupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout->addWidget(label_2, 1, 0, 1, 1);
browseTorrents = new QPushButton(groupBox);
- browseTorrents->setObjectName(QStringLiteral("browseTorrents"));
+ browseTorrents->setObjectName(QString::fromUtf8("browseTorrents"));
gridLayout->addWidget(browseTorrents, 0, 3, 1, 1);
label_5 = new QLabel(groupBox);
- label_5->setObjectName(QStringLiteral("label_5"));
+ label_5->setObjectName(QString::fromUtf8("label_5"));
label_5->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop);
gridLayout->addWidget(label_5, 5, 0, 1, 1);
label_3 = new QLabel(groupBox);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout->addWidget(label_3, 4, 0, 1, 1);
label_6 = new QLabel(groupBox);
- label_6->setObjectName(QStringLiteral("label_6"));
+ label_6->setObjectName(QString::fromUtf8("label_6"));
gridLayout->addWidget(label_6, 2, 0, 1, 1);
torrentContents = new QTextEdit(groupBox);
- torrentContents->setObjectName(QStringLiteral("torrentContents"));
+ torrentContents->setObjectName(QString::fromUtf8("torrentContents"));
torrentContents->setFocusPolicy(Qt::NoFocus);
torrentContents->setTabChangesFocus(true);
torrentContents->setLineWrapMode(QTextEdit::NoWrap);
@@ -123,43 +123,43 @@ public:
gridLayout->addWidget(torrentContents, 5, 1, 1, 3);
destinationFolder = new QLineEdit(groupBox);
- destinationFolder->setObjectName(QStringLiteral("destinationFolder"));
+ destinationFolder->setObjectName(QString::fromUtf8("destinationFolder"));
destinationFolder->setFocusPolicy(Qt::StrongFocus);
gridLayout->addWidget(destinationFolder, 6, 1, 1, 2);
announceUrl = new QLabel(groupBox);
- announceUrl->setObjectName(QStringLiteral("announceUrl"));
+ announceUrl->setObjectName(QString::fromUtf8("announceUrl"));
gridLayout->addWidget(announceUrl, 1, 1, 1, 3);
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
browseDestination = new QPushButton(groupBox);
- browseDestination->setObjectName(QStringLiteral("browseDestination"));
+ browseDestination->setObjectName(QString::fromUtf8("browseDestination"));
gridLayout->addWidget(browseDestination, 6, 3, 1, 1);
label_7 = new QLabel(groupBox);
- label_7->setObjectName(QStringLiteral("label_7"));
+ label_7->setObjectName(QString::fromUtf8("label_7"));
gridLayout->addWidget(label_7, 3, 0, 1, 1);
commentLabel = new QLabel(groupBox);
- commentLabel->setObjectName(QStringLiteral("commentLabel"));
+ commentLabel->setObjectName(QString::fromUtf8("commentLabel"));
gridLayout->addWidget(commentLabel, 3, 1, 1, 3);
creatorLabel = new QLabel(groupBox);
- creatorLabel->setObjectName(QStringLiteral("creatorLabel"));
+ creatorLabel->setObjectName(QString::fromUtf8("creatorLabel"));
gridLayout->addWidget(creatorLabel, 2, 1, 1, 3);
sizeLabel = new QLabel(groupBox);
- sizeLabel->setObjectName(QStringLiteral("sizeLabel"));
+ sizeLabel->setObjectName(QString::fromUtf8("sizeLabel"));
gridLayout->addWidget(sizeLabel, 4, 1, 1, 3);
@@ -171,19 +171,19 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
spacerItem = new QSpacerItem(131, 31, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(spacerItem);
okButton = new QPushButton(AddTorrentFile);
- okButton->setObjectName(QStringLiteral("okButton"));
+ okButton->setObjectName(QString::fromUtf8("okButton"));
okButton->setEnabled(false);
hboxLayout->addWidget(okButton);
cancelButton = new QPushButton(AddTorrentFile);
- cancelButton->setObjectName(QStringLiteral("cancelButton"));
+ cancelButton->setObjectName(QString::fromUtf8("cancelButton"));
hboxLayout->addWidget(cancelButton);
diff --git a/tests/auto/tools/uic/baseline/authenticationdialog.ui.h b/tests/auto/tools/uic/baseline/authenticationdialog.ui.h
index 331770b5e0..16c9ce16a8 100644
--- a/tests/auto/tools/uic/baseline/authenticationdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/authenticationdialog.ui.h
@@ -37,50 +37,50 @@ public:
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
- Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(389, 243);
gridLayout = new QGridLayout(Dialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(Dialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setWordWrap(false);
gridLayout->addWidget(label, 0, 0, 1, 2);
label_2 = new QLabel(Dialog);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout->addWidget(label_2, 2, 0, 1, 1);
userEdit = new QLineEdit(Dialog);
- userEdit->setObjectName(QStringLiteral("userEdit"));
+ userEdit->setObjectName(QString::fromUtf8("userEdit"));
gridLayout->addWidget(userEdit, 2, 1, 1, 1);
label_3 = new QLabel(Dialog);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout->addWidget(label_3, 3, 0, 1, 1);
passwordEdit = new QLineEdit(Dialog);
- passwordEdit->setObjectName(QStringLiteral("passwordEdit"));
+ passwordEdit->setObjectName(QString::fromUtf8("passwordEdit"));
gridLayout->addWidget(passwordEdit, 3, 1, 1, 1);
buttonBox = new QDialogButtonBox(Dialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
gridLayout->addWidget(buttonBox, 5, 0, 1, 2);
label_4 = new QLabel(Dialog);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
gridLayout->addWidget(label_4, 1, 0, 1, 1);
siteDescription = new QLabel(Dialog);
- siteDescription->setObjectName(QStringLiteral("siteDescription"));
+ siteDescription->setObjectName(QString::fromUtf8("siteDescription"));
QFont font;
font.setBold(true);
font.setWeight(75);
diff --git a/tests/auto/tools/uic/baseline/backside.ui.h b/tests/auto/tools/uic/baseline/backside.ui.h
index 963eb082ae..e7053c632f 100644
--- a/tests/auto/tools/uic/baseline/backside.ui.h
+++ b/tests/auto/tools/uic/baseline/backside.ui.h
@@ -47,47 +47,47 @@ public:
void setupUi(QWidget *BackSide)
{
if (BackSide->objectName().isEmpty())
- BackSide->setObjectName(QStringLiteral("BackSide"));
+ BackSide->setObjectName(QString::fromUtf8("BackSide"));
BackSide->resize(378, 385);
verticalLayout_2 = new QVBoxLayout(BackSide);
- verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
+ verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
groupBox = new QGroupBox(BackSide);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
groupBox->setFlat(true);
groupBox->setCheckable(true);
gridLayout = new QGridLayout(groupBox);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
hostName = new QLineEdit(groupBox);
- hostName->setObjectName(QStringLiteral("hostName"));
+ hostName->setObjectName(QString::fromUtf8("hostName"));
gridLayout->addWidget(hostName, 0, 1, 1, 1);
label_2 = new QLabel(groupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout->addWidget(label_2, 1, 0, 1, 1);
label_3 = new QLabel(groupBox);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout->addWidget(label_3, 2, 0, 1, 1);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
horizontalSlider = new QSlider(groupBox);
- horizontalSlider->setObjectName(QStringLiteral("horizontalSlider"));
+ horizontalSlider->setObjectName(QString::fromUtf8("horizontalSlider"));
horizontalSlider->setValue(42);
horizontalSlider->setOrientation(Qt::Horizontal);
horizontalLayout->addWidget(horizontalSlider);
spinBox = new QSpinBox(groupBox);
- spinBox->setObjectName(QStringLiteral("spinBox"));
+ spinBox->setObjectName(QString::fromUtf8("spinBox"));
spinBox->setValue(42);
horizontalLayout->addWidget(spinBox);
@@ -96,7 +96,7 @@ public:
gridLayout->addLayout(horizontalLayout, 2, 1, 1, 1);
dateTimeEdit = new QDateTimeEdit(groupBox);
- dateTimeEdit->setObjectName(QStringLiteral("dateTimeEdit"));
+ dateTimeEdit->setObjectName(QString::fromUtf8("dateTimeEdit"));
gridLayout->addWidget(dateTimeEdit, 1, 1, 1, 1);
@@ -104,11 +104,11 @@ public:
verticalLayout_2->addWidget(groupBox);
groupBox_2 = new QGroupBox(BackSide);
- groupBox_2->setObjectName(QStringLiteral("groupBox_2"));
+ groupBox_2->setObjectName(QString::fromUtf8("groupBox_2"));
groupBox_2->setFlat(true);
groupBox_2->setCheckable(true);
horizontalLayout_2 = new QHBoxLayout(groupBox_2);
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
treeWidget = new QTreeWidget(groupBox_2);
QTreeWidgetItem *__qtreewidgetitem = new QTreeWidgetItem(treeWidget);
QTreeWidgetItem *__qtreewidgetitem1 = new QTreeWidgetItem(__qtreewidgetitem);
@@ -121,7 +121,7 @@ public:
QTreeWidgetItem *__qtreewidgetitem4 = new QTreeWidgetItem(treeWidget);
QTreeWidgetItem *__qtreewidgetitem5 = new QTreeWidgetItem(__qtreewidgetitem4);
new QTreeWidgetItem(__qtreewidgetitem5);
- treeWidget->setObjectName(QStringLiteral("treeWidget"));
+ treeWidget->setObjectName(QString::fromUtf8("treeWidget"));
horizontalLayout_2->addWidget(treeWidget);
diff --git a/tests/auto/tools/uic/baseline/batchtranslation.ui.h b/tests/auto/tools/uic/baseline/batchtranslation.ui.h
index 1f55b6230e..8a4dc7a677 100644
--- a/tests/auto/tools/uic/baseline/batchtranslation.ui.h
+++ b/tests/auto/tools/uic/baseline/batchtranslation.ui.h
@@ -78,7 +78,7 @@ public:
void setupUi(QDialog *databaseTranslationDialog)
{
if (databaseTranslationDialog->objectName().isEmpty())
- databaseTranslationDialog->setObjectName(QStringLiteral("databaseTranslationDialog"));
+ databaseTranslationDialog->setObjectName(QString::fromUtf8("databaseTranslationDialog"));
databaseTranslationDialog->resize(425, 370);
vboxLayout = new QVBoxLayout(databaseTranslationDialog);
#ifndef Q_OS_MAC
@@ -87,9 +87,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(databaseTranslationDialog);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(4));
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -102,15 +102,15 @@ public:
#ifndef Q_OS_MAC
vboxLayout1->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
ckOnlyUntranslated = new QCheckBox(groupBox);
- ckOnlyUntranslated->setObjectName(QStringLiteral("ckOnlyUntranslated"));
+ ckOnlyUntranslated->setObjectName(QString::fromUtf8("ckOnlyUntranslated"));
ckOnlyUntranslated->setChecked(true);
vboxLayout1->addWidget(ckOnlyUntranslated);
ckMarkFinished = new QCheckBox(groupBox);
- ckMarkFinished->setObjectName(QStringLiteral("ckMarkFinished"));
+ ckMarkFinished->setObjectName(QString::fromUtf8("ckMarkFinished"));
ckMarkFinished->setChecked(true);
vboxLayout1->addWidget(ckMarkFinished);
@@ -119,7 +119,7 @@ public:
vboxLayout->addWidget(groupBox);
groupBox_2 = new QGroupBox(databaseTranslationDialog);
- groupBox_2->setObjectName(QStringLiteral("groupBox_2"));
+ groupBox_2->setObjectName(QString::fromUtf8("groupBox_2"));
QSizePolicy sizePolicy1(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(1));
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -132,7 +132,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout2->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
hboxLayout = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
@@ -140,9 +140,9 @@ public:
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(0, 0, 0, 0);
#endif
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
phrasebookList = new QListView(groupBox_2);
- phrasebookList->setObjectName(QStringLiteral("phrasebookList"));
+ phrasebookList->setObjectName(QString::fromUtf8("phrasebookList"));
phrasebookList->setUniformItemSizes(true);
hboxLayout->addWidget(phrasebookList);
@@ -152,14 +152,14 @@ public:
vboxLayout3->setSpacing(6);
#endif
vboxLayout3->setContentsMargins(0, 0, 0, 0);
- vboxLayout3->setObjectName(QStringLiteral("vboxLayout3"));
+ vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3"));
moveUpButton = new QPushButton(groupBox_2);
- moveUpButton->setObjectName(QStringLiteral("moveUpButton"));
+ moveUpButton->setObjectName(QString::fromUtf8("moveUpButton"));
vboxLayout3->addWidget(moveUpButton);
moveDownButton = new QPushButton(groupBox_2);
- moveDownButton->setObjectName(QStringLiteral("moveDownButton"));
+ moveDownButton->setObjectName(QString::fromUtf8("moveDownButton"));
vboxLayout3->addWidget(moveDownButton);
@@ -174,7 +174,7 @@ public:
vboxLayout2->addLayout(hboxLayout);
label = new QLabel(groupBox_2);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setWordWrap(true);
vboxLayout2->addWidget(label);
@@ -187,18 +187,18 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
spacerItem1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout1->addItem(spacerItem1);
runButton = new QPushButton(databaseTranslationDialog);
- runButton->setObjectName(QStringLiteral("runButton"));
+ runButton->setObjectName(QString::fromUtf8("runButton"));
hboxLayout1->addWidget(runButton);
cancelButton = new QPushButton(databaseTranslationDialog);
- cancelButton->setObjectName(QStringLiteral("cancelButton"));
+ cancelButton->setObjectName(QString::fromUtf8("cancelButton"));
hboxLayout1->addWidget(cancelButton);
diff --git a/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h b/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h
index c2bb062bb8..b5a44998be 100644
--- a/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h
@@ -48,7 +48,7 @@ public:
void setupUi(QDialog *BookmarkDialog)
{
if (BookmarkDialog->objectName().isEmpty())
- BookmarkDialog->setObjectName(QStringLiteral("BookmarkDialog"));
+ BookmarkDialog->setObjectName(QString::fromUtf8("BookmarkDialog"));
BookmarkDialog->resize(450, 135);
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
@@ -56,18 +56,18 @@ public:
sizePolicy.setHeightForWidth(BookmarkDialog->sizePolicy().hasHeightForWidth());
BookmarkDialog->setSizePolicy(sizePolicy);
verticalLayout_3 = new QVBoxLayout(BookmarkDialog);
- verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
+ verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3"));
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
verticalLayout_2 = new QVBoxLayout();
- verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
+ verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
label = new QLabel(BookmarkDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
verticalLayout_2->addWidget(label);
label_2 = new QLabel(BookmarkDialog);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
verticalLayout_2->addWidget(label_2);
@@ -75,14 +75,14 @@ public:
horizontalLayout->addLayout(verticalLayout_2);
verticalLayout = new QVBoxLayout();
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
bookmarkEdit = new QLineEdit(BookmarkDialog);
- bookmarkEdit->setObjectName(QStringLiteral("bookmarkEdit"));
+ bookmarkEdit->setObjectName(QString::fromUtf8("bookmarkEdit"));
verticalLayout->addWidget(bookmarkEdit);
bookmarkFolders = new QComboBox(BookmarkDialog);
- bookmarkFolders->setObjectName(QStringLiteral("bookmarkFolders"));
+ bookmarkFolders->setObjectName(QString::fromUtf8("bookmarkFolders"));
verticalLayout->addWidget(bookmarkFolders);
@@ -93,15 +93,15 @@ public:
verticalLayout_3->addLayout(horizontalLayout);
horizontalLayout_3 = new QHBoxLayout();
- horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3"));
+ horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
toolButton = new QToolButton(BookmarkDialog);
- toolButton->setObjectName(QStringLiteral("toolButton"));
+ toolButton->setObjectName(QString::fromUtf8("toolButton"));
toolButton->setMinimumSize(QSize(25, 20));
horizontalLayout_3->addWidget(toolButton);
line = new QFrame(BookmarkDialog);
- line->setObjectName(QStringLiteral("line"));
+ line->setObjectName(QString::fromUtf8("line"));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
@@ -111,7 +111,7 @@ public:
verticalLayout_3->addLayout(horizontalLayout_3);
bookmarkWidget = new BookmarkWidget(BookmarkDialog);
- bookmarkWidget->setObjectName(QStringLiteral("bookmarkWidget"));
+ bookmarkWidget->setObjectName(QString::fromUtf8("bookmarkWidget"));
bookmarkWidget->setEnabled(true);
QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Ignored);
sizePolicy1.setHorizontalStretch(0);
@@ -122,14 +122,14 @@ public:
verticalLayout_3->addWidget(bookmarkWidget);
horizontalLayout_4 = new QHBoxLayout();
- horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4"));
+ horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4"));
newFolderButton = new QPushButton(BookmarkDialog);
- newFolderButton->setObjectName(QStringLiteral("newFolderButton"));
+ newFolderButton->setObjectName(QString::fromUtf8("newFolderButton"));
horizontalLayout_4->addWidget(newFolderButton);
buttonBox = new QDialogButtonBox(BookmarkDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/bookwindow.ui.h b/tests/auto/tools/uic/baseline/bookwindow.ui.h
index 89b1e04c6c..8fe5f000e2 100644
--- a/tests/auto/tools/uic/baseline/bookwindow.ui.h
+++ b/tests/auto/tools/uic/baseline/bookwindow.ui.h
@@ -49,10 +49,10 @@ public:
void setupUi(QMainWindow *BookWindow)
{
if (BookWindow->objectName().isEmpty())
- BookWindow->setObjectName(QStringLiteral("BookWindow"));
+ BookWindow->setObjectName(QString::fromUtf8("BookWindow"));
BookWindow->resize(601, 420);
centralWidget = new QWidget(BookWindow);
- centralWidget->setObjectName(QStringLiteral("centralWidget"));
+ centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
vboxLayout = new QVBoxLayout(centralWidget);
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
@@ -60,9 +60,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(centralWidget);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
vboxLayout1 = new QVBoxLayout(groupBox);
#ifndef Q_OS_MAC
vboxLayout1->setSpacing(6);
@@ -70,57 +70,57 @@ public:
#ifndef Q_OS_MAC
vboxLayout1->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
bookTable = new QTableView(groupBox);
- bookTable->setObjectName(QStringLiteral("bookTable"));
+ bookTable->setObjectName(QString::fromUtf8("bookTable"));
bookTable->setSelectionBehavior(QAbstractItemView::SelectRows);
vboxLayout1->addWidget(bookTable);
groupBox_2 = new QGroupBox(groupBox);
- groupBox_2->setObjectName(QStringLiteral("groupBox_2"));
+ groupBox_2->setObjectName(QString::fromUtf8("groupBox_2"));
formLayout = new QFormLayout(groupBox_2);
- formLayout->setObjectName(QStringLiteral("formLayout"));
+ formLayout->setObjectName(QString::fromUtf8("formLayout"));
label_5 = new QLabel(groupBox_2);
- label_5->setObjectName(QStringLiteral("label_5"));
+ label_5->setObjectName(QString::fromUtf8("label_5"));
formLayout->setWidget(0, QFormLayout::LabelRole, label_5);
titleEdit = new QLineEdit(groupBox_2);
- titleEdit->setObjectName(QStringLiteral("titleEdit"));
+ titleEdit->setObjectName(QString::fromUtf8("titleEdit"));
titleEdit->setEnabled(true);
formLayout->setWidget(0, QFormLayout::FieldRole, titleEdit);
label_2_2_2_2 = new QLabel(groupBox_2);
- label_2_2_2_2->setObjectName(QStringLiteral("label_2_2_2_2"));
+ label_2_2_2_2->setObjectName(QString::fromUtf8("label_2_2_2_2"));
formLayout->setWidget(1, QFormLayout::LabelRole, label_2_2_2_2);
authorEdit = new QComboBox(groupBox_2);
- authorEdit->setObjectName(QStringLiteral("authorEdit"));
+ authorEdit->setObjectName(QString::fromUtf8("authorEdit"));
authorEdit->setEnabled(true);
formLayout->setWidget(1, QFormLayout::FieldRole, authorEdit);
label_3 = new QLabel(groupBox_2);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
formLayout->setWidget(2, QFormLayout::LabelRole, label_3);
genreEdit = new QComboBox(groupBox_2);
- genreEdit->setObjectName(QStringLiteral("genreEdit"));
+ genreEdit->setObjectName(QString::fromUtf8("genreEdit"));
genreEdit->setEnabled(true);
formLayout->setWidget(2, QFormLayout::FieldRole, genreEdit);
label_4 = new QLabel(groupBox_2);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
formLayout->setWidget(3, QFormLayout::LabelRole, label_4);
yearEdit = new QSpinBox(groupBox_2);
- yearEdit->setObjectName(QStringLiteral("yearEdit"));
+ yearEdit->setObjectName(QString::fromUtf8("yearEdit"));
yearEdit->setEnabled(true);
yearEdit->setMaximum(2100);
yearEdit->setMinimum(-1000);
@@ -128,12 +128,12 @@ public:
formLayout->setWidget(3, QFormLayout::FieldRole, yearEdit);
label = new QLabel(groupBox_2);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
formLayout->setWidget(4, QFormLayout::LabelRole, label);
ratingEdit = new QSpinBox(groupBox_2);
- ratingEdit->setObjectName(QStringLiteral("ratingEdit"));
+ ratingEdit->setObjectName(QString::fromUtf8("ratingEdit"));
ratingEdit->setMaximum(5);
formLayout->setWidget(4, QFormLayout::FieldRole, ratingEdit);
diff --git a/tests/auto/tools/uic/baseline/browserwidget.ui.h b/tests/auto/tools/uic/baseline/browserwidget.ui.h
index 491f51ce94..3db93c34cf 100644
--- a/tests/auto/tools/uic/baseline/browserwidget.ui.h
+++ b/tests/auto/tools/uic/baseline/browserwidget.ui.h
@@ -46,22 +46,22 @@ public:
void setupUi(QWidget *Browser)
{
if (Browser->objectName().isEmpty())
- Browser->setObjectName(QStringLiteral("Browser"));
+ Browser->setObjectName(QString::fromUtf8("Browser"));
Browser->resize(765, 515);
insertRowAction = new QAction(Browser);
- insertRowAction->setObjectName(QStringLiteral("insertRowAction"));
+ insertRowAction->setObjectName(QString::fromUtf8("insertRowAction"));
insertRowAction->setEnabled(false);
deleteRowAction = new QAction(Browser);
- deleteRowAction->setObjectName(QStringLiteral("deleteRowAction"));
+ deleteRowAction->setObjectName(QString::fromUtf8("deleteRowAction"));
deleteRowAction->setEnabled(false);
vboxLayout = new QVBoxLayout(Browser);
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(8, 8, 8, 8);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
splitter_2 = new QSplitter(Browser);
- splitter_2->setObjectName(QStringLiteral("splitter_2"));
+ splitter_2->setObjectName(QString::fromUtf8("splitter_2"));
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(7), static_cast<QSizePolicy::Policy>(7));
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -69,7 +69,7 @@ public:
splitter_2->setSizePolicy(sizePolicy);
splitter_2->setOrientation(Qt::Horizontal);
connectionWidget = new ConnectionWidget(splitter_2);
- connectionWidget->setObjectName(QStringLiteral("connectionWidget"));
+ connectionWidget->setObjectName(QString::fromUtf8("connectionWidget"));
QSizePolicy sizePolicy1(static_cast<QSizePolicy::Policy>(13), static_cast<QSizePolicy::Policy>(7));
sizePolicy1.setHorizontalStretch(1);
sizePolicy1.setVerticalStretch(0);
@@ -77,7 +77,7 @@ public:
connectionWidget->setSizePolicy(sizePolicy1);
splitter_2->addWidget(connectionWidget);
table = new QTableView(splitter_2);
- table->setObjectName(QStringLiteral("table"));
+ table->setObjectName(QString::fromUtf8("table"));
QSizePolicy sizePolicy2(static_cast<QSizePolicy::Policy>(7), static_cast<QSizePolicy::Policy>(7));
sizePolicy2.setHorizontalStretch(2);
sizePolicy2.setVerticalStretch(0);
@@ -90,7 +90,7 @@ public:
vboxLayout->addWidget(splitter_2);
groupBox = new QGroupBox(Browser);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
QSizePolicy sizePolicy3(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(3));
sizePolicy3.setHorizontalStretch(0);
sizePolicy3.setVerticalStretch(0);
@@ -104,9 +104,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout1->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
sqlEdit = new QTextEdit(groupBox);
- sqlEdit->setObjectName(QStringLiteral("sqlEdit"));
+ sqlEdit->setObjectName(QString::fromUtf8("sqlEdit"));
QSizePolicy sizePolicy4(static_cast<QSizePolicy::Policy>(7), static_cast<QSizePolicy::Policy>(3));
sizePolicy4.setHorizontalStretch(0);
sizePolicy4.setVerticalStretch(0);
@@ -122,18 +122,18 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(1, 1, 1, 1);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(spacerItem);
clearButton = new QPushButton(groupBox);
- clearButton->setObjectName(QStringLiteral("clearButton"));
+ clearButton->setObjectName(QString::fromUtf8("clearButton"));
hboxLayout->addWidget(clearButton);
submitButton = new QPushButton(groupBox);
- submitButton->setObjectName(QStringLiteral("submitButton"));
+ submitButton->setObjectName(QString::fromUtf8("submitButton"));
hboxLayout->addWidget(submitButton);
diff --git a/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h b/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h
index 5a545485e3..47f8f22132 100644
--- a/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h
+++ b/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h
@@ -29,19 +29,19 @@ public:
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
- Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(400, 300);
gridLayout = new QGridLayout(Dialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
treeWidget = new QTreeWidget(Dialog);
treeWidget->headerItem()->setText(0, QString());
treeWidget->headerItem()->setText(2, QString());
- treeWidget->setObjectName(QStringLiteral("treeWidget"));
+ treeWidget->setObjectName(QString::fromUtf8("treeWidget"));
gridLayout->addWidget(treeWidget, 0, 0, 1, 1);
buttonBox = new QDialogButtonBox(Dialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/buttongroup.ui.h b/tests/auto/tools/uic/baseline/buttongroup.ui.h
index 38029df7ec..ddc3995d4b 100644
--- a/tests/auto/tools/uic/baseline/buttongroup.ui.h
+++ b/tests/auto/tools/uic/baseline/buttongroup.ui.h
@@ -51,12 +51,12 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(545, 471);
gridLayout = new QGridLayout(Form);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
easingCurvePicker = new QListWidget(Form);
- easingCurvePicker->setObjectName(QStringLiteral("easingCurvePicker"));
+ easingCurvePicker->setObjectName(QString::fromUtf8("easingCurvePicker"));
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -72,17 +72,17 @@ public:
gridLayout->addWidget(easingCurvePicker, 0, 0, 1, 2);
verticalLayout = new QVBoxLayout();
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
groupBox_2 = new QGroupBox(Form);
- groupBox_2->setObjectName(QStringLiteral("groupBox_2"));
+ groupBox_2->setObjectName(QString::fromUtf8("groupBox_2"));
groupBox_2->setMaximumSize(QSize(16777215, 16777215));
gridLayout_2 = new QGridLayout(groupBox_2);
- gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
+ gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
lineRadio = new QRadioButton(groupBox_2);
buttonGroup = new QButtonGroup(Form);
- buttonGroup->setObjectName(QStringLiteral("buttonGroup"));
+ buttonGroup->setObjectName(QString::fromUtf8("buttonGroup"));
buttonGroup->addButton(lineRadio);
- lineRadio->setObjectName(QStringLiteral("lineRadio"));
+ lineRadio->setObjectName(QString::fromUtf8("lineRadio"));
lineRadio->setMaximumSize(QSize(16777215, 40));
lineRadio->setLayoutDirection(Qt::LeftToRight);
lineRadio->setChecked(true);
@@ -91,7 +91,7 @@ public:
circleRadio = new QRadioButton(groupBox_2);
buttonGroup->addButton(circleRadio);
- circleRadio->setObjectName(QStringLiteral("circleRadio"));
+ circleRadio->setObjectName(QString::fromUtf8("circleRadio"));
circleRadio->setMaximumSize(QSize(16777215, 40));
gridLayout_2->addWidget(circleRadio, 1, 0, 1, 1);
@@ -100,17 +100,17 @@ public:
verticalLayout->addWidget(groupBox_2);
groupBox = new QGroupBox(Form);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Preferred);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(groupBox->sizePolicy().hasHeightForWidth());
groupBox->setSizePolicy(sizePolicy1);
formLayout = new QFormLayout(groupBox);
- formLayout->setObjectName(QStringLiteral("formLayout"));
+ formLayout->setObjectName(QString::fromUtf8("formLayout"));
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy2.setHorizontalStretch(0);
sizePolicy2.setVerticalStretch(0);
@@ -121,7 +121,7 @@ public:
formLayout->setWidget(0, QFormLayout::LabelRole, label);
periodSpinBox = new QDoubleSpinBox(groupBox);
- periodSpinBox->setObjectName(QStringLiteral("periodSpinBox"));
+ periodSpinBox->setObjectName(QString::fromUtf8("periodSpinBox"));
periodSpinBox->setEnabled(false);
QSizePolicy sizePolicy3(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy3.setHorizontalStretch(0);
@@ -136,7 +136,7 @@ public:
formLayout->setWidget(0, QFormLayout::FieldRole, periodSpinBox);
amplitudeSpinBox = new QDoubleSpinBox(groupBox);
- amplitudeSpinBox->setObjectName(QStringLiteral("amplitudeSpinBox"));
+ amplitudeSpinBox->setObjectName(QString::fromUtf8("amplitudeSpinBox"));
amplitudeSpinBox->setEnabled(false);
amplitudeSpinBox->setMinimumSize(QSize(0, 30));
amplitudeSpinBox->setMinimum(-1);
@@ -146,13 +146,13 @@ public:
formLayout->setWidget(2, QFormLayout::FieldRole, amplitudeSpinBox);
label_3 = new QLabel(groupBox);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
label_3->setMinimumSize(QSize(0, 30));
formLayout->setWidget(4, QFormLayout::LabelRole, label_3);
overshootSpinBox = new QDoubleSpinBox(groupBox);
- overshootSpinBox->setObjectName(QStringLiteral("overshootSpinBox"));
+ overshootSpinBox->setObjectName(QString::fromUtf8("overshootSpinBox"));
overshootSpinBox->setEnabled(false);
overshootSpinBox->setMinimumSize(QSize(0, 30));
overshootSpinBox->setMinimum(-1);
@@ -162,7 +162,7 @@ public:
formLayout->setWidget(4, QFormLayout::FieldRole, overshootSpinBox);
label_2 = new QLabel(groupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
label_2->setMinimumSize(QSize(0, 30));
formLayout->setWidget(2, QFormLayout::LabelRole, label_2);
@@ -178,7 +178,7 @@ public:
gridLayout->addLayout(verticalLayout, 1, 0, 1, 1);
graphicsView = new QGraphicsView(Form);
- graphicsView->setObjectName(QStringLiteral("graphicsView"));
+ graphicsView->setObjectName(QString::fromUtf8("graphicsView"));
QSizePolicy sizePolicy4(QSizePolicy::Expanding, QSizePolicy::Expanding);
sizePolicy4.setHorizontalStretch(0);
sizePolicy4.setVerticalStretch(0);
diff --git a/tests/auto/tools/uic/baseline/calculator.ui.h b/tests/auto/tools/uic/baseline/calculator.ui.h
index ad738d7afc..0387ee472b 100644
--- a/tests/auto/tools/uic/baseline/calculator.ui.h
+++ b/tests/auto/tools/uic/baseline/calculator.ui.h
@@ -52,7 +52,7 @@ public:
void setupUi(QWidget *Calculator)
{
if (Calculator->objectName().isEmpty())
- Calculator->setObjectName(QStringLiteral("Calculator"));
+ Calculator->setObjectName(QString::fromUtf8("Calculator"));
Calculator->resize(314, 301);
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
@@ -62,88 +62,88 @@ public:
Calculator->setMinimumSize(QSize(314, 301));
Calculator->setMaximumSize(QSize(314, 301));
backspaceButton = new QToolButton(Calculator);
- backspaceButton->setObjectName(QStringLiteral("backspaceButton"));
+ backspaceButton->setObjectName(QString::fromUtf8("backspaceButton"));
backspaceButton->setGeometry(QRect(10, 50, 91, 41));
clearButton = new QToolButton(Calculator);
- clearButton->setObjectName(QStringLiteral("clearButton"));
+ clearButton->setObjectName(QString::fromUtf8("clearButton"));
clearButton->setGeometry(QRect(110, 50, 91, 41));
clearAllButton = new QToolButton(Calculator);
- clearAllButton->setObjectName(QStringLiteral("clearAllButton"));
+ clearAllButton->setObjectName(QString::fromUtf8("clearAllButton"));
clearAllButton->setGeometry(QRect(210, 50, 91, 41));
clearMemoryButton = new QToolButton(Calculator);
- clearMemoryButton->setObjectName(QStringLiteral("clearMemoryButton"));
+ clearMemoryButton->setObjectName(QString::fromUtf8("clearMemoryButton"));
clearMemoryButton->setGeometry(QRect(10, 100, 41, 41));
readMemoryButton = new QToolButton(Calculator);
- readMemoryButton->setObjectName(QStringLiteral("readMemoryButton"));
+ readMemoryButton->setObjectName(QString::fromUtf8("readMemoryButton"));
readMemoryButton->setGeometry(QRect(10, 150, 41, 41));
setMemoryButton = new QToolButton(Calculator);
- setMemoryButton->setObjectName(QStringLiteral("setMemoryButton"));
+ setMemoryButton->setObjectName(QString::fromUtf8("setMemoryButton"));
setMemoryButton->setGeometry(QRect(10, 200, 41, 41));
addToMemoryButton = new QToolButton(Calculator);
- addToMemoryButton->setObjectName(QStringLiteral("addToMemoryButton"));
+ addToMemoryButton->setObjectName(QString::fromUtf8("addToMemoryButton"));
addToMemoryButton->setGeometry(QRect(10, 250, 41, 41));
sevenButton = new QToolButton(Calculator);
- sevenButton->setObjectName(QStringLiteral("sevenButton"));
+ sevenButton->setObjectName(QString::fromUtf8("sevenButton"));
sevenButton->setGeometry(QRect(60, 100, 41, 41));
eightButton = new QToolButton(Calculator);
- eightButton->setObjectName(QStringLiteral("eightButton"));
+ eightButton->setObjectName(QString::fromUtf8("eightButton"));
eightButton->setGeometry(QRect(110, 100, 41, 41));
nineButton = new QToolButton(Calculator);
- nineButton->setObjectName(QStringLiteral("nineButton"));
+ nineButton->setObjectName(QString::fromUtf8("nineButton"));
nineButton->setGeometry(QRect(160, 100, 41, 41));
fourButton = new QToolButton(Calculator);
- fourButton->setObjectName(QStringLiteral("fourButton"));
+ fourButton->setObjectName(QString::fromUtf8("fourButton"));
fourButton->setGeometry(QRect(60, 150, 41, 41));
fiveButton = new QToolButton(Calculator);
- fiveButton->setObjectName(QStringLiteral("fiveButton"));
+ fiveButton->setObjectName(QString::fromUtf8("fiveButton"));
fiveButton->setGeometry(QRect(110, 150, 41, 41));
sixButton = new QToolButton(Calculator);
- sixButton->setObjectName(QStringLiteral("sixButton"));
+ sixButton->setObjectName(QString::fromUtf8("sixButton"));
sixButton->setGeometry(QRect(160, 150, 41, 41));
oneButton = new QToolButton(Calculator);
- oneButton->setObjectName(QStringLiteral("oneButton"));
+ oneButton->setObjectName(QString::fromUtf8("oneButton"));
oneButton->setGeometry(QRect(60, 200, 41, 41));
twoButton = new QToolButton(Calculator);
- twoButton->setObjectName(QStringLiteral("twoButton"));
+ twoButton->setObjectName(QString::fromUtf8("twoButton"));
twoButton->setGeometry(QRect(110, 200, 41, 41));
threeButton = new QToolButton(Calculator);
- threeButton->setObjectName(QStringLiteral("threeButton"));
+ threeButton->setObjectName(QString::fromUtf8("threeButton"));
threeButton->setGeometry(QRect(160, 200, 41, 41));
zeroButton = new QToolButton(Calculator);
- zeroButton->setObjectName(QStringLiteral("zeroButton"));
+ zeroButton->setObjectName(QString::fromUtf8("zeroButton"));
zeroButton->setGeometry(QRect(60, 250, 41, 41));
pointButton = new QToolButton(Calculator);
- pointButton->setObjectName(QStringLiteral("pointButton"));
+ pointButton->setObjectName(QString::fromUtf8("pointButton"));
pointButton->setGeometry(QRect(110, 250, 41, 41));
changeSignButton = new QToolButton(Calculator);
- changeSignButton->setObjectName(QStringLiteral("changeSignButton"));
+ changeSignButton->setObjectName(QString::fromUtf8("changeSignButton"));
changeSignButton->setGeometry(QRect(160, 250, 41, 41));
plusButton = new QToolButton(Calculator);
- plusButton->setObjectName(QStringLiteral("plusButton"));
+ plusButton->setObjectName(QString::fromUtf8("plusButton"));
plusButton->setGeometry(QRect(210, 250, 41, 41));
divisionButton = new QToolButton(Calculator);
- divisionButton->setObjectName(QStringLiteral("divisionButton"));
+ divisionButton->setObjectName(QString::fromUtf8("divisionButton"));
divisionButton->setGeometry(QRect(210, 100, 41, 41));
timesButton = new QToolButton(Calculator);
- timesButton->setObjectName(QStringLiteral("timesButton"));
+ timesButton->setObjectName(QString::fromUtf8("timesButton"));
timesButton->setGeometry(QRect(210, 150, 41, 41));
minusButton = new QToolButton(Calculator);
- minusButton->setObjectName(QStringLiteral("minusButton"));
+ minusButton->setObjectName(QString::fromUtf8("minusButton"));
minusButton->setGeometry(QRect(210, 200, 41, 41));
squareRootButton = new QToolButton(Calculator);
- squareRootButton->setObjectName(QStringLiteral("squareRootButton"));
+ squareRootButton->setObjectName(QString::fromUtf8("squareRootButton"));
squareRootButton->setGeometry(QRect(260, 100, 41, 41));
powerButton = new QToolButton(Calculator);
- powerButton->setObjectName(QStringLiteral("powerButton"));
+ powerButton->setObjectName(QString::fromUtf8("powerButton"));
powerButton->setGeometry(QRect(260, 150, 41, 41));
reciprocalButton = new QToolButton(Calculator);
- reciprocalButton->setObjectName(QStringLiteral("reciprocalButton"));
+ reciprocalButton->setObjectName(QString::fromUtf8("reciprocalButton"));
reciprocalButton->setGeometry(QRect(260, 200, 41, 41));
equalButton = new QToolButton(Calculator);
- equalButton->setObjectName(QStringLiteral("equalButton"));
+ equalButton->setObjectName(QString::fromUtf8("equalButton"));
equalButton->setGeometry(QRect(260, 250, 41, 41));
display = new QLineEdit(Calculator);
- display->setObjectName(QStringLiteral("display"));
+ display->setObjectName(QString::fromUtf8("display"));
display->setGeometry(QRect(10, 10, 291, 31));
display->setMaxLength(15);
display->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
diff --git a/tests/auto/tools/uic/baseline/calculatorform.ui.h b/tests/auto/tools/uic/baseline/calculatorform.ui.h
index ced29d5eab..f4661c6237 100644
--- a/tests/auto/tools/uic/baseline/calculatorform.ui.h
+++ b/tests/auto/tools/uic/baseline/calculatorform.ui.h
@@ -43,7 +43,7 @@ public:
void setupUi(QWidget *CalculatorForm)
{
if (CalculatorForm->objectName().isEmpty())
- CalculatorForm->setObjectName(QStringLiteral("CalculatorForm"));
+ CalculatorForm->setObjectName(QString::fromUtf8("CalculatorForm"));
CalculatorForm->resize(276, 98);
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(5));
sizePolicy.setHorizontalStretch(0);
@@ -57,30 +57,30 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
- gridLayout->setObjectName(QStringLiteral(""));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8(""));
hboxLayout = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(1, 1, 1, 1);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
- hboxLayout->setObjectName(QStringLiteral(""));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8(""));
vboxLayout = new QVBoxLayout();
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(1, 1, 1, 1);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
- vboxLayout->setObjectName(QStringLiteral(""));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8(""));
label = new QLabel(CalculatorForm);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setGeometry(QRect(1, 1, 45, 19));
vboxLayout->addWidget(label);
inputSpinBox1 = new QSpinBox(CalculatorForm);
- inputSpinBox1->setObjectName(QStringLiteral("inputSpinBox1"));
+ inputSpinBox1->setObjectName(QString::fromUtf8("inputSpinBox1"));
inputSpinBox1->setGeometry(QRect(1, 26, 45, 25));
inputSpinBox1->setMouseTracking(true);
@@ -90,7 +90,7 @@ public:
hboxLayout->addLayout(vboxLayout);
label_3 = new QLabel(CalculatorForm);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
label_3->setGeometry(QRect(54, 1, 7, 52));
label_3->setAlignment(Qt::AlignCenter);
@@ -101,16 +101,16 @@ public:
vboxLayout1->setSpacing(6);
#endif
vboxLayout1->setContentsMargins(1, 1, 1, 1);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
- vboxLayout1->setObjectName(QStringLiteral(""));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8(""));
label_2 = new QLabel(CalculatorForm);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
label_2->setGeometry(QRect(1, 1, 45, 19));
vboxLayout1->addWidget(label_2);
inputSpinBox2 = new QSpinBox(CalculatorForm);
- inputSpinBox2->setObjectName(QStringLiteral("inputSpinBox2"));
+ inputSpinBox2->setObjectName(QString::fromUtf8("inputSpinBox2"));
inputSpinBox2->setGeometry(QRect(1, 26, 45, 25));
inputSpinBox2->setMouseTracking(true);
@@ -120,7 +120,7 @@ public:
hboxLayout->addLayout(vboxLayout1);
label_3_2 = new QLabel(CalculatorForm);
- label_3_2->setObjectName(QStringLiteral("label_3_2"));
+ label_3_2->setObjectName(QString::fromUtf8("label_3_2"));
label_3_2->setGeometry(QRect(120, 1, 7, 52));
label_3_2->setAlignment(Qt::AlignCenter);
@@ -131,16 +131,16 @@ public:
vboxLayout2->setSpacing(6);
#endif
vboxLayout2->setContentsMargins(1, 1, 1, 1);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
- vboxLayout2->setObjectName(QStringLiteral(""));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8(""));
label_2_2_2 = new QLabel(CalculatorForm);
- label_2_2_2->setObjectName(QStringLiteral("label_2_2_2"));
+ label_2_2_2->setObjectName(QString::fromUtf8("label_2_2_2"));
label_2_2_2->setGeometry(QRect(1, 1, 37, 17));
vboxLayout2->addWidget(label_2_2_2);
outputWidget = new QLabel(CalculatorForm);
- outputWidget->setObjectName(QStringLiteral("outputWidget"));
+ outputWidget->setObjectName(QString::fromUtf8("outputWidget"));
outputWidget->setGeometry(QRect(1, 24, 37, 27));
outputWidget->setFrameShape(QFrame::Box);
outputWidget->setFrameShadow(QFrame::Sunken);
diff --git a/tests/auto/tools/uic/baseline/certificateinfo.ui.h b/tests/auto/tools/uic/baseline/certificateinfo.ui.h
index 07263bcdd7..2aa47d40ad 100644
--- a/tests/auto/tools/uic/baseline/certificateinfo.ui.h
+++ b/tests/auto/tools/uic/baseline/certificateinfo.ui.h
@@ -38,16 +38,16 @@ public:
void setupUi(QDialog *CertificateInfo)
{
if (CertificateInfo->objectName().isEmpty())
- CertificateInfo->setObjectName(QStringLiteral("CertificateInfo"));
+ CertificateInfo->setObjectName(QString::fromUtf8("CertificateInfo"));
CertificateInfo->resize(400, 397);
vboxLayout = new QVBoxLayout(CertificateInfo);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(CertificateInfo);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
hboxLayout = new QHBoxLayout(groupBox);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
certificationPathView = new QListWidget(groupBox);
- certificationPathView->setObjectName(QStringLiteral("certificationPathView"));
+ certificationPathView->setObjectName(QString::fromUtf8("certificationPathView"));
hboxLayout->addWidget(certificationPathView);
@@ -55,11 +55,11 @@ public:
vboxLayout->addWidget(groupBox);
groupBox_2 = new QGroupBox(CertificateInfo);
- groupBox_2->setObjectName(QStringLiteral("groupBox_2"));
+ groupBox_2->setObjectName(QString::fromUtf8("groupBox_2"));
hboxLayout1 = new QHBoxLayout(groupBox_2);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
certificateInfoView = new QListWidget(groupBox_2);
- certificateInfoView->setObjectName(QStringLiteral("certificateInfoView"));
+ certificateInfoView->setObjectName(QString::fromUtf8("certificateInfoView"));
hboxLayout1->addWidget(certificateInfoView);
@@ -67,13 +67,13 @@ public:
vboxLayout->addWidget(groupBox_2);
hboxLayout2 = new QHBoxLayout();
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout2->addItem(spacerItem);
buttonBox = new QDialogButtonBox(CertificateInfo);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setStandardButtons(QDialogButtonBox::Close);
hboxLayout2->addWidget(buttonBox);
diff --git a/tests/auto/tools/uic/baseline/chatdialog.ui.h b/tests/auto/tools/uic/baseline/chatdialog.ui.h
index 32b083fbc4..ace6951669 100644
--- a/tests/auto/tools/uic/baseline/chatdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/chatdialog.ui.h
@@ -35,7 +35,7 @@ public:
void setupUi(QDialog *ChatDialog)
{
if (ChatDialog->objectName().isEmpty())
- ChatDialog->setObjectName(QStringLiteral("ChatDialog"));
+ ChatDialog->setObjectName(QString::fromUtf8("ChatDialog"));
ChatDialog->resize(513, 349);
vboxLayout = new QVBoxLayout(ChatDialog);
#ifndef Q_OS_MAC
@@ -44,7 +44,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
hboxLayout = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
@@ -52,16 +52,16 @@ public:
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(0, 0, 0, 0);
#endif
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
textEdit = new QTextEdit(ChatDialog);
- textEdit->setObjectName(QStringLiteral("textEdit"));
+ textEdit->setObjectName(QString::fromUtf8("textEdit"));
textEdit->setFocusPolicy(Qt::NoFocus);
textEdit->setReadOnly(true);
hboxLayout->addWidget(textEdit);
listWidget = new QListWidget(ChatDialog);
- listWidget->setObjectName(QStringLiteral("listWidget"));
+ listWidget->setObjectName(QString::fromUtf8("listWidget"));
listWidget->setMaximumSize(QSize(180, 16777215));
listWidget->setFocusPolicy(Qt::NoFocus);
@@ -75,14 +75,14 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
label = new QLabel(ChatDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
hboxLayout1->addWidget(label);
lineEdit = new QLineEdit(ChatDialog);
- lineEdit->setObjectName(QStringLiteral("lineEdit"));
+ lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
hboxLayout1->addWidget(lineEdit);
diff --git a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h
index 921eb376de..8d4ccd53ae 100644
--- a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h
+++ b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h
@@ -48,16 +48,16 @@ public:
void setupUi(QMainWindow *ChatMainWindow)
{
if (ChatMainWindow->objectName().isEmpty())
- ChatMainWindow->setObjectName(QStringLiteral("ChatMainWindow"));
+ ChatMainWindow->setObjectName(QString::fromUtf8("ChatMainWindow"));
ChatMainWindow->resize(800, 600);
actionQuit = new QAction(ChatMainWindow);
- actionQuit->setObjectName(QStringLiteral("actionQuit"));
+ actionQuit->setObjectName(QString::fromUtf8("actionQuit"));
actionAboutQt = new QAction(ChatMainWindow);
- actionAboutQt->setObjectName(QStringLiteral("actionAboutQt"));
+ actionAboutQt->setObjectName(QString::fromUtf8("actionAboutQt"));
actionChangeNickname = new QAction(ChatMainWindow);
- actionChangeNickname->setObjectName(QStringLiteral("actionChangeNickname"));
+ actionChangeNickname->setObjectName(QString::fromUtf8("actionChangeNickname"));
centralwidget = new QWidget(ChatMainWindow);
- centralwidget->setObjectName(QStringLiteral("centralwidget"));
+ centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
hboxLayout = new QHBoxLayout(centralwidget);
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
@@ -65,7 +65,7 @@ public:
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
vboxLayout = new QVBoxLayout();
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
@@ -73,9 +73,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(0, 0, 0, 0);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
chatHistory = new QTextBrowser(centralwidget);
- chatHistory->setObjectName(QStringLiteral("chatHistory"));
+ chatHistory->setObjectName(QString::fromUtf8("chatHistory"));
chatHistory->setAcceptDrops(false);
chatHistory->setAcceptRichText(true);
@@ -86,19 +86,19 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
label = new QLabel(centralwidget);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
hboxLayout1->addWidget(label);
messageLineEdit = new QLineEdit(centralwidget);
- messageLineEdit->setObjectName(QStringLiteral("messageLineEdit"));
+ messageLineEdit->setObjectName(QString::fromUtf8("messageLineEdit"));
hboxLayout1->addWidget(messageLineEdit);
sendButton = new QPushButton(centralwidget);
- sendButton->setObjectName(QStringLiteral("sendButton"));
+ sendButton->setObjectName(QString::fromUtf8("sendButton"));
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(1), static_cast<QSizePolicy::Policy>(0));
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -115,15 +115,15 @@ public:
ChatMainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(ChatMainWindow);
- menubar->setObjectName(QStringLiteral("menubar"));
+ menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 800, 31));
menuQuit = new QMenu(menubar);
- menuQuit->setObjectName(QStringLiteral("menuQuit"));
+ menuQuit->setObjectName(QString::fromUtf8("menuQuit"));
menuFile = new QMenu(menubar);
- menuFile->setObjectName(QStringLiteral("menuFile"));
+ menuFile->setObjectName(QString::fromUtf8("menuFile"));
ChatMainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(ChatMainWindow);
- statusbar->setObjectName(QStringLiteral("statusbar"));
+ statusbar->setObjectName(QString::fromUtf8("statusbar"));
ChatMainWindow->setStatusBar(statusbar);
#ifndef QT_NO_SHORTCUT
label->setBuddy(messageLineEdit);
diff --git a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h
index 6aaa47f84e..c73dfb2c6e 100644
--- a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h
+++ b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h
@@ -37,7 +37,7 @@ public:
void setupUi(QDialog *NicknameDialog)
{
if (NicknameDialog->objectName().isEmpty())
- NicknameDialog->setObjectName(QStringLiteral("NicknameDialog"));
+ NicknameDialog->setObjectName(QString::fromUtf8("NicknameDialog"));
NicknameDialog->resize(396, 105);
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(1), static_cast<QSizePolicy::Policy>(1));
sizePolicy.setHorizontalStretch(0);
@@ -51,7 +51,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout1 = new QVBoxLayout();
#ifndef Q_OS_MAC
vboxLayout1->setSpacing(6);
@@ -59,16 +59,16 @@ public:
#ifndef Q_OS_MAC
vboxLayout1->setContentsMargins(0, 0, 0, 0);
#endif
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
label = new QLabel(NicknameDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
label->setSizePolicy(sizePolicy);
vboxLayout1->addWidget(label);
nickname = new QLineEdit(NicknameDialog);
- nickname->setObjectName(QStringLiteral("nickname"));
+ nickname->setObjectName(QString::fromUtf8("nickname"));
vboxLayout1->addWidget(nickname);
@@ -80,18 +80,18 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
spacerItem = new QSpacerItem(131, 31, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(spacerItem);
okButton = new QPushButton(NicknameDialog);
- okButton->setObjectName(QStringLiteral("okButton"));
+ okButton->setObjectName(QString::fromUtf8("okButton"));
hboxLayout->addWidget(okButton);
cancelButton = new QPushButton(NicknameDialog);
- cancelButton->setObjectName(QStringLiteral("cancelButton"));
+ cancelButton->setObjectName(QString::fromUtf8("cancelButton"));
hboxLayout->addWidget(cancelButton);
diff --git a/tests/auto/tools/uic/baseline/config.ui.h b/tests/auto/tools/uic/baseline/config.ui.h
index 7948f6b4ba..8287e0b1ac 100644
--- a/tests/auto/tools/uic/baseline/config.ui.h
+++ b/tests/auto/tools/uic/baseline/config.ui.h
@@ -118,20 +118,20 @@ public:
void setupUi(QDialog *Config)
{
if (Config->objectName().isEmpty())
- Config->setObjectName(QStringLiteral("Config"));
+ Config->setObjectName(QString::fromUtf8("Config"));
Config->resize(600, 650);
Config->setSizeGripEnabled(true);
vboxLayout = new QVBoxLayout(Config);
vboxLayout->setSpacing(6);
vboxLayout->setContentsMargins(11, 11, 11, 11);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout->setContentsMargins(8, 8, 8, 8);
hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(6);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
hboxLayout->setContentsMargins(0, 0, 0, 0);
ButtonGroup1 = new QGroupBox(Config);
- ButtonGroup1->setObjectName(QStringLiteral("ButtonGroup1"));
+ ButtonGroup1->setObjectName(QString::fromUtf8("ButtonGroup1"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -140,44 +140,44 @@ public:
vboxLayout1 = new QVBoxLayout(ButtonGroup1);
vboxLayout1->setSpacing(6);
vboxLayout1->setContentsMargins(11, 11, 11, 11);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
vboxLayout1->setContentsMargins(11, 11, 11, 11);
size_176_220 = new QRadioButton(ButtonGroup1);
- size_176_220->setObjectName(QStringLiteral("size_176_220"));
+ size_176_220->setObjectName(QString::fromUtf8("size_176_220"));
vboxLayout1->addWidget(size_176_220);
size_240_320 = new QRadioButton(ButtonGroup1);
- size_240_320->setObjectName(QStringLiteral("size_240_320"));
+ size_240_320->setObjectName(QString::fromUtf8("size_240_320"));
vboxLayout1->addWidget(size_240_320);
size_320_240 = new QRadioButton(ButtonGroup1);
- size_320_240->setObjectName(QStringLiteral("size_320_240"));
+ size_320_240->setObjectName(QString::fromUtf8("size_320_240"));
vboxLayout1->addWidget(size_320_240);
size_640_480 = new QRadioButton(ButtonGroup1);
- size_640_480->setObjectName(QStringLiteral("size_640_480"));
+ size_640_480->setObjectName(QString::fromUtf8("size_640_480"));
vboxLayout1->addWidget(size_640_480);
size_800_600 = new QRadioButton(ButtonGroup1);
- size_800_600->setObjectName(QStringLiteral("size_800_600"));
+ size_800_600->setObjectName(QString::fromUtf8("size_800_600"));
vboxLayout1->addWidget(size_800_600);
size_1024_768 = new QRadioButton(ButtonGroup1);
- size_1024_768->setObjectName(QStringLiteral("size_1024_768"));
+ size_1024_768->setObjectName(QString::fromUtf8("size_1024_768"));
vboxLayout1->addWidget(size_1024_768);
hboxLayout1 = new QHBoxLayout();
hboxLayout1->setSpacing(6);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
hboxLayout1->setContentsMargins(0, 0, 0, 0);
size_custom = new QRadioButton(ButtonGroup1);
- size_custom->setObjectName(QStringLiteral("size_custom"));
+ size_custom->setObjectName(QString::fromUtf8("size_custom"));
QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -187,7 +187,7 @@ public:
hboxLayout1->addWidget(size_custom);
size_width = new QSpinBox(ButtonGroup1);
- size_width->setObjectName(QStringLiteral("size_width"));
+ size_width->setObjectName(QString::fromUtf8("size_width"));
size_width->setMinimum(1);
size_width->setMaximum(1280);
size_width->setSingleStep(16);
@@ -196,7 +196,7 @@ public:
hboxLayout1->addWidget(size_width);
size_height = new QSpinBox(ButtonGroup1);
- size_height->setObjectName(QStringLiteral("size_height"));
+ size_height->setObjectName(QString::fromUtf8("size_height"));
size_height->setMinimum(1);
size_height->setMaximum(1024);
size_height->setSingleStep(16);
@@ -211,59 +211,59 @@ public:
hboxLayout->addWidget(ButtonGroup1);
ButtonGroup2 = new QGroupBox(Config);
- ButtonGroup2->setObjectName(QStringLiteral("ButtonGroup2"));
+ ButtonGroup2->setObjectName(QString::fromUtf8("ButtonGroup2"));
vboxLayout2 = new QVBoxLayout(ButtonGroup2);
vboxLayout2->setSpacing(6);
vboxLayout2->setContentsMargins(11, 11, 11, 11);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
vboxLayout2->setContentsMargins(11, 11, 11, 11);
depth_1 = new QRadioButton(ButtonGroup2);
- depth_1->setObjectName(QStringLiteral("depth_1"));
+ depth_1->setObjectName(QString::fromUtf8("depth_1"));
vboxLayout2->addWidget(depth_1);
depth_4gray = new QRadioButton(ButtonGroup2);
- depth_4gray->setObjectName(QStringLiteral("depth_4gray"));
+ depth_4gray->setObjectName(QString::fromUtf8("depth_4gray"));
vboxLayout2->addWidget(depth_4gray);
depth_8 = new QRadioButton(ButtonGroup2);
- depth_8->setObjectName(QStringLiteral("depth_8"));
+ depth_8->setObjectName(QString::fromUtf8("depth_8"));
vboxLayout2->addWidget(depth_8);
depth_12 = new QRadioButton(ButtonGroup2);
- depth_12->setObjectName(QStringLiteral("depth_12"));
+ depth_12->setObjectName(QString::fromUtf8("depth_12"));
vboxLayout2->addWidget(depth_12);
depth_15 = new QRadioButton(ButtonGroup2);
- depth_15->setObjectName(QStringLiteral("depth_15"));
+ depth_15->setObjectName(QString::fromUtf8("depth_15"));
vboxLayout2->addWidget(depth_15);
depth_16 = new QRadioButton(ButtonGroup2);
- depth_16->setObjectName(QStringLiteral("depth_16"));
+ depth_16->setObjectName(QString::fromUtf8("depth_16"));
vboxLayout2->addWidget(depth_16);
depth_18 = new QRadioButton(ButtonGroup2);
- depth_18->setObjectName(QStringLiteral("depth_18"));
+ depth_18->setObjectName(QString::fromUtf8("depth_18"));
vboxLayout2->addWidget(depth_18);
depth_24 = new QRadioButton(ButtonGroup2);
- depth_24->setObjectName(QStringLiteral("depth_24"));
+ depth_24->setObjectName(QString::fromUtf8("depth_24"));
vboxLayout2->addWidget(depth_24);
depth_32 = new QRadioButton(ButtonGroup2);
- depth_32->setObjectName(QStringLiteral("depth_32"));
+ depth_32->setObjectName(QString::fromUtf8("depth_32"));
vboxLayout2->addWidget(depth_32);
depth_32_argb = new QRadioButton(ButtonGroup2);
- depth_32_argb->setObjectName(QStringLiteral("depth_32_argb"));
+ depth_32_argb->setObjectName(QString::fromUtf8("depth_32_argb"));
vboxLayout2->addWidget(depth_32_argb);
@@ -275,16 +275,16 @@ public:
hboxLayout2 = new QHBoxLayout();
hboxLayout2->setSpacing(6);
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
hboxLayout2->setContentsMargins(0, 0, 0, 0);
TextLabel1_3 = new QLabel(Config);
- TextLabel1_3->setObjectName(QStringLiteral("TextLabel1_3"));
+ TextLabel1_3->setObjectName(QString::fromUtf8("TextLabel1_3"));
hboxLayout2->addWidget(TextLabel1_3);
skin = new QComboBox(Config);
skin->addItem(QString());
- skin->setObjectName(QStringLiteral("skin"));
+ skin->setObjectName(QString::fromUtf8("skin"));
QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Fixed);
sizePolicy2.setHorizontalStretch(0);
sizePolicy2.setVerticalStretch(0);
@@ -297,12 +297,12 @@ public:
vboxLayout->addLayout(hboxLayout2);
touchScreen = new QCheckBox(Config);
- touchScreen->setObjectName(QStringLiteral("touchScreen"));
+ touchScreen->setObjectName(QString::fromUtf8("touchScreen"));
vboxLayout->addWidget(touchScreen);
lcdScreen = new QCheckBox(Config);
- lcdScreen->setObjectName(QStringLiteral("lcdScreen"));
+ lcdScreen->setObjectName(QString::fromUtf8("lcdScreen"));
vboxLayout->addWidget(lcdScreen);
@@ -311,7 +311,7 @@ public:
vboxLayout->addItem(spacerItem);
TextLabel1 = new QLabel(Config);
- TextLabel1->setObjectName(QStringLiteral("TextLabel1"));
+ TextLabel1->setObjectName(QString::fromUtf8("TextLabel1"));
sizePolicy.setHeightForWidth(TextLabel1->sizePolicy().hasHeightForWidth());
TextLabel1->setSizePolicy(sizePolicy);
TextLabel1->setWordWrap(true);
@@ -319,21 +319,21 @@ public:
vboxLayout->addWidget(TextLabel1);
GroupBox1 = new QGroupBox(Config);
- GroupBox1->setObjectName(QStringLiteral("GroupBox1"));
+ GroupBox1->setObjectName(QString::fromUtf8("GroupBox1"));
gridLayout = new QGridLayout(GroupBox1);
gridLayout->setSpacing(6);
gridLayout->setContentsMargins(11, 11, 11, 11);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
gridLayout->setHorizontalSpacing(6);
gridLayout->setVerticalSpacing(6);
gridLayout->setContentsMargins(11, 11, 11, 11);
TextLabel3 = new QLabel(GroupBox1);
- TextLabel3->setObjectName(QStringLiteral("TextLabel3"));
+ TextLabel3->setObjectName(QString::fromUtf8("TextLabel3"));
gridLayout->addWidget(TextLabel3, 6, 0, 1, 1);
bslider = new QSlider(GroupBox1);
- bslider->setObjectName(QStringLiteral("bslider"));
+ bslider->setObjectName(QString::fromUtf8("bslider"));
QPalette palette;
QBrush brush(QColor(128, 128, 128, 255));
brush.setStyle(Qt::SolidPattern);
@@ -416,17 +416,17 @@ public:
gridLayout->addWidget(bslider, 6, 1, 1, 1);
blabel = new QLabel(GroupBox1);
- blabel->setObjectName(QStringLiteral("blabel"));
+ blabel->setObjectName(QString::fromUtf8("blabel"));
gridLayout->addWidget(blabel, 6, 2, 1, 1);
TextLabel2 = new QLabel(GroupBox1);
- TextLabel2->setObjectName(QStringLiteral("TextLabel2"));
+ TextLabel2->setObjectName(QString::fromUtf8("TextLabel2"));
gridLayout->addWidget(TextLabel2, 4, 0, 1, 1);
gslider = new QSlider(GroupBox1);
- gslider->setObjectName(QStringLiteral("gslider"));
+ gslider->setObjectName(QString::fromUtf8("gslider"));
QPalette palette1;
palette1.setBrush(QPalette::Active, QPalette::WindowText, brush);
QBrush brush11(QColor(0, 255, 0, 255));
@@ -497,22 +497,22 @@ public:
gridLayout->addWidget(gslider, 4, 1, 1, 1);
glabel = new QLabel(GroupBox1);
- glabel->setObjectName(QStringLiteral("glabel"));
+ glabel->setObjectName(QString::fromUtf8("glabel"));
gridLayout->addWidget(glabel, 4, 2, 1, 1);
TextLabel7 = new QLabel(GroupBox1);
- TextLabel7->setObjectName(QStringLiteral("TextLabel7"));
+ TextLabel7->setObjectName(QString::fromUtf8("TextLabel7"));
gridLayout->addWidget(TextLabel7, 0, 0, 1, 1);
TextLabel8 = new QLabel(GroupBox1);
- TextLabel8->setObjectName(QStringLiteral("TextLabel8"));
+ TextLabel8->setObjectName(QString::fromUtf8("TextLabel8"));
gridLayout->addWidget(TextLabel8, 0, 2, 1, 1);
gammaslider = new QSlider(GroupBox1);
- gammaslider->setObjectName(QStringLiteral("gammaslider"));
+ gammaslider->setObjectName(QString::fromUtf8("gammaslider"));
QPalette palette2;
palette2.setBrush(QPalette::Active, QPalette::WindowText, brush);
palette2.setBrush(QPalette::Active, QPalette::Button, brush7);
@@ -577,17 +577,17 @@ public:
gridLayout->addWidget(gammaslider, 0, 1, 1, 1);
TextLabel1_2 = new QLabel(GroupBox1);
- TextLabel1_2->setObjectName(QStringLiteral("TextLabel1_2"));
+ TextLabel1_2->setObjectName(QString::fromUtf8("TextLabel1_2"));
gridLayout->addWidget(TextLabel1_2, 2, 0, 1, 1);
rlabel = new QLabel(GroupBox1);
- rlabel->setObjectName(QStringLiteral("rlabel"));
+ rlabel->setObjectName(QString::fromUtf8("rlabel"));
gridLayout->addWidget(rlabel, 2, 2, 1, 1);
rslider = new QSlider(GroupBox1);
- rslider->setObjectName(QStringLiteral("rslider"));
+ rslider->setObjectName(QString::fromUtf8("rslider"));
QPalette palette3;
palette3.setBrush(QPalette::Active, QPalette::WindowText, brush);
QBrush brush18(QColor(255, 0, 0, 255));
@@ -658,12 +658,12 @@ public:
gridLayout->addWidget(rslider, 2, 1, 1, 1);
PushButton3 = new QPushButton(GroupBox1);
- PushButton3->setObjectName(QStringLiteral("PushButton3"));
+ PushButton3->setObjectName(QString::fromUtf8("PushButton3"));
gridLayout->addWidget(PushButton3, 8, 0, 1, 3);
MyCustomWidget1 = new GammaView(GroupBox1);
- MyCustomWidget1->setObjectName(QStringLiteral("MyCustomWidget1"));
+ MyCustomWidget1->setObjectName(QString::fromUtf8("MyCustomWidget1"));
gridLayout->addWidget(MyCustomWidget1, 0, 3, 9, 1);
@@ -672,20 +672,20 @@ public:
hboxLayout3 = new QHBoxLayout();
hboxLayout3->setSpacing(6);
- hboxLayout3->setObjectName(QStringLiteral("hboxLayout3"));
+ hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3"));
hboxLayout3->setContentsMargins(0, 0, 0, 0);
spacerItem1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout3->addItem(spacerItem1);
buttonOk = new QPushButton(Config);
- buttonOk->setObjectName(QStringLiteral("buttonOk"));
+ buttonOk->setObjectName(QString::fromUtf8("buttonOk"));
buttonOk->setAutoDefault(true);
hboxLayout3->addWidget(buttonOk);
buttonCancel = new QPushButton(Config);
- buttonCancel->setObjectName(QStringLiteral("buttonCancel"));
+ buttonCancel->setObjectName(QString::fromUtf8("buttonCancel"));
buttonCancel->setAutoDefault(true);
hboxLayout3->addWidget(buttonCancel);
diff --git a/tests/auto/tools/uic/baseline/connectdialog.ui.h b/tests/auto/tools/uic/baseline/connectdialog.ui.h
index 935f8a21a1..a470a6705d 100644
--- a/tests/auto/tools/uic/baseline/connectdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/connectdialog.ui.h
@@ -46,24 +46,24 @@ public:
void setupUi(QDialog *ConnectDialog)
{
if (ConnectDialog->objectName().isEmpty())
- ConnectDialog->setObjectName(QStringLiteral("ConnectDialog"));
+ ConnectDialog->setObjectName(QString::fromUtf8("ConnectDialog"));
ConnectDialog->resize(585, 361);
gridLayout = new QGridLayout(ConnectDialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
signalGroupBox = new QGroupBox(ConnectDialog);
- signalGroupBox->setObjectName(QStringLiteral("signalGroupBox"));
+ signalGroupBox->setObjectName(QString::fromUtf8("signalGroupBox"));
vboxLayout = new QVBoxLayout(signalGroupBox);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
signalList = new QListWidget(signalGroupBox);
- signalList->setObjectName(QStringLiteral("signalList"));
+ signalList->setObjectName(QString::fromUtf8("signalList"));
signalList->setTextElideMode(Qt::ElideMiddle);
vboxLayout->addWidget(signalList);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
editSignalsButton = new QToolButton(signalGroupBox);
- editSignalsButton->setObjectName(QStringLiteral("editSignalsButton"));
+ editSignalsButton->setObjectName(QString::fromUtf8("editSignalsButton"));
hboxLayout->addWidget(editSignalsButton);
@@ -78,19 +78,19 @@ public:
gridLayout->addWidget(signalGroupBox, 0, 0, 1, 2);
slotGroupBox = new QGroupBox(ConnectDialog);
- slotGroupBox->setObjectName(QStringLiteral("slotGroupBox"));
+ slotGroupBox->setObjectName(QString::fromUtf8("slotGroupBox"));
vboxLayout1 = new QVBoxLayout(slotGroupBox);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
slotList = new QListWidget(slotGroupBox);
- slotList->setObjectName(QStringLiteral("slotList"));
+ slotList->setObjectName(QString::fromUtf8("slotList"));
slotList->setTextElideMode(Qt::ElideMiddle);
vboxLayout1->addWidget(slotList);
hboxLayout1 = new QHBoxLayout();
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
editSlotsButton = new QToolButton(slotGroupBox);
- editSlotsButton->setObjectName(QStringLiteral("editSlotsButton"));
+ editSlotsButton->setObjectName(QString::fromUtf8("editSlotsButton"));
hboxLayout1->addWidget(editSlotsButton);
@@ -105,12 +105,12 @@ public:
gridLayout->addWidget(slotGroupBox, 0, 2, 1, 1);
showAllCheckBox = new QCheckBox(ConnectDialog);
- showAllCheckBox->setObjectName(QStringLiteral("showAllCheckBox"));
+ showAllCheckBox->setObjectName(QString::fromUtf8("showAllCheckBox"));
gridLayout->addWidget(showAllCheckBox, 1, 0, 1, 1);
buttonBox = new QDialogButtonBox(ConnectDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/controller.ui.h b/tests/auto/tools/uic/baseline/controller.ui.h
index e3382e2c17..72b0956472 100644
--- a/tests/auto/tools/uic/baseline/controller.ui.h
+++ b/tests/auto/tools/uic/baseline/controller.ui.h
@@ -31,7 +31,7 @@ public:
void setupUi(QWidget *Controller)
{
if (Controller->objectName().isEmpty())
- Controller->setObjectName(QStringLiteral("Controller"));
+ Controller->setObjectName(QString::fromUtf8("Controller"));
Controller->resize(255, 111);
gridLayout = new QGridLayout(Controller);
#ifndef Q_OS_MAC
@@ -40,30 +40,30 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(Controller);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setAlignment(Qt::AlignCenter);
gridLayout->addWidget(label, 1, 1, 1, 1);
decelerate = new QPushButton(Controller);
- decelerate->setObjectName(QStringLiteral("decelerate"));
+ decelerate->setObjectName(QString::fromUtf8("decelerate"));
gridLayout->addWidget(decelerate, 2, 1, 1, 1);
accelerate = new QPushButton(Controller);
- accelerate->setObjectName(QStringLiteral("accelerate"));
+ accelerate->setObjectName(QString::fromUtf8("accelerate"));
gridLayout->addWidget(accelerate, 0, 1, 1, 1);
right = new QPushButton(Controller);
- right->setObjectName(QStringLiteral("right"));
+ right->setObjectName(QString::fromUtf8("right"));
gridLayout->addWidget(right, 1, 2, 1, 1);
left = new QPushButton(Controller);
- left->setObjectName(QStringLiteral("left"));
+ left->setObjectName(QString::fromUtf8("left"));
gridLayout->addWidget(left, 1, 0, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/cookies.ui.h b/tests/auto/tools/uic/baseline/cookies.ui.h
index 2702fb489f..144c306874 100644
--- a/tests/auto/tools/uic/baseline/cookies.ui.h
+++ b/tests/auto/tools/uic/baseline/cookies.ui.h
@@ -39,33 +39,33 @@ public:
void setupUi(QDialog *CookiesDialog)
{
if (CookiesDialog->objectName().isEmpty())
- CookiesDialog->setObjectName(QStringLiteral("CookiesDialog"));
+ CookiesDialog->setObjectName(QString::fromUtf8("CookiesDialog"));
CookiesDialog->resize(550, 370);
gridLayout = new QGridLayout(CookiesDialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
spacerItem = new QSpacerItem(252, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout->addItem(spacerItem, 0, 0, 1, 1);
search = new SearchLineEdit(CookiesDialog);
- search->setObjectName(QStringLiteral("search"));
+ search->setObjectName(QString::fromUtf8("search"));
gridLayout->addWidget(search, 0, 1, 1, 1);
cookiesTable = new EditTableView(CookiesDialog);
- cookiesTable->setObjectName(QStringLiteral("cookiesTable"));
+ cookiesTable->setObjectName(QString::fromUtf8("cookiesTable"));
gridLayout->addWidget(cookiesTable, 1, 0, 1, 2);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
removeButton = new QPushButton(CookiesDialog);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
hboxLayout->addWidget(removeButton);
removeAllButton = new QPushButton(CookiesDialog);
- removeAllButton->setObjectName(QStringLiteral("removeAllButton"));
+ removeAllButton->setObjectName(QString::fromUtf8("removeAllButton"));
hboxLayout->addWidget(removeAllButton);
@@ -74,7 +74,7 @@ public:
hboxLayout->addItem(spacerItem1);
buttonBox = new QDialogButtonBox(CookiesDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setStandardButtons(QDialogButtonBox::Ok);
hboxLayout->addWidget(buttonBox);
diff --git a/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h b/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h
index eaa39e3e78..a3bf7a449e 100644
--- a/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h
+++ b/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h
@@ -54,23 +54,23 @@ public:
void setupUi(QDialog *CookiesExceptionsDialog)
{
if (CookiesExceptionsDialog->objectName().isEmpty())
- CookiesExceptionsDialog->setObjectName(QStringLiteral("CookiesExceptionsDialog"));
+ CookiesExceptionsDialog->setObjectName(QString::fromUtf8("CookiesExceptionsDialog"));
CookiesExceptionsDialog->resize(466, 446);
vboxLayout = new QVBoxLayout(CookiesExceptionsDialog);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
newExceptionGroupBox = new QGroupBox(CookiesExceptionsDialog);
- newExceptionGroupBox->setObjectName(QStringLiteral("newExceptionGroupBox"));
+ newExceptionGroupBox->setObjectName(QString::fromUtf8("newExceptionGroupBox"));
gridLayout = new QGridLayout(newExceptionGroupBox);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
label = new QLabel(newExceptionGroupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
hboxLayout->addWidget(label);
domainLineEdit = new QLineEdit(newExceptionGroupBox);
- domainLineEdit->setObjectName(QStringLiteral("domainLineEdit"));
+ domainLineEdit->setObjectName(QString::fromUtf8("domainLineEdit"));
hboxLayout->addWidget(domainLineEdit);
@@ -78,25 +78,25 @@ public:
gridLayout->addLayout(hboxLayout, 0, 0, 1, 1);
hboxLayout1 = new QHBoxLayout();
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
spacerItem = new QSpacerItem(81, 25, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout1->addItem(spacerItem);
blockButton = new QPushButton(newExceptionGroupBox);
- blockButton->setObjectName(QStringLiteral("blockButton"));
+ blockButton->setObjectName(QString::fromUtf8("blockButton"));
blockButton->setEnabled(false);
hboxLayout1->addWidget(blockButton);
allowForSessionButton = new QPushButton(newExceptionGroupBox);
- allowForSessionButton->setObjectName(QStringLiteral("allowForSessionButton"));
+ allowForSessionButton->setObjectName(QString::fromUtf8("allowForSessionButton"));
allowForSessionButton->setEnabled(false);
hboxLayout1->addWidget(allowForSessionButton);
allowButton = new QPushButton(newExceptionGroupBox);
- allowButton->setObjectName(QStringLiteral("allowButton"));
+ allowButton->setObjectName(QString::fromUtf8("allowButton"));
allowButton->setEnabled(false);
hboxLayout1->addWidget(allowButton);
@@ -108,30 +108,30 @@ public:
vboxLayout->addWidget(newExceptionGroupBox);
ExceptionsGroupBox = new QGroupBox(CookiesExceptionsDialog);
- ExceptionsGroupBox->setObjectName(QStringLiteral("ExceptionsGroupBox"));
+ ExceptionsGroupBox->setObjectName(QString::fromUtf8("ExceptionsGroupBox"));
gridLayout1 = new QGridLayout(ExceptionsGroupBox);
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
spacerItem1 = new QSpacerItem(252, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout1->addItem(spacerItem1, 0, 0, 1, 3);
search = new SearchLineEdit(ExceptionsGroupBox);
- search->setObjectName(QStringLiteral("search"));
+ search->setObjectName(QString::fromUtf8("search"));
gridLayout1->addWidget(search, 0, 3, 1, 1);
exceptionTable = new EditTableView(ExceptionsGroupBox);
- exceptionTable->setObjectName(QStringLiteral("exceptionTable"));
+ exceptionTable->setObjectName(QString::fromUtf8("exceptionTable"));
gridLayout1->addWidget(exceptionTable, 1, 0, 1, 4);
removeButton = new QPushButton(ExceptionsGroupBox);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
gridLayout1->addWidget(removeButton, 2, 0, 1, 1);
removeAllButton = new QPushButton(ExceptionsGroupBox);
- removeAllButton->setObjectName(QStringLiteral("removeAllButton"));
+ removeAllButton->setObjectName(QString::fromUtf8("removeAllButton"));
gridLayout1->addWidget(removeAllButton, 2, 1, 1, 1);
@@ -143,7 +143,7 @@ public:
vboxLayout->addWidget(ExceptionsGroupBox);
buttonBox = new QDialogButtonBox(CookiesExceptionsDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/default.ui.h b/tests/auto/tools/uic/baseline/default.ui.h
index 4fae8e7130..fafff9d728 100644
--- a/tests/auto/tools/uic/baseline/default.ui.h
+++ b/tests/auto/tools/uic/baseline/default.ui.h
@@ -63,18 +63,18 @@ public:
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
- MainWindow->setObjectName(QStringLiteral("MainWindow"));
+ MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(388, 413);
exitAction = new QAction(MainWindow);
- exitAction->setObjectName(QStringLiteral("exitAction"));
+ exitAction->setObjectName(QString::fromUtf8("exitAction"));
aboutQtAction = new QAction(MainWindow);
- aboutQtAction->setObjectName(QStringLiteral("aboutQtAction"));
+ aboutQtAction->setObjectName(QString::fromUtf8("aboutQtAction"));
editStyleAction = new QAction(MainWindow);
- editStyleAction->setObjectName(QStringLiteral("editStyleAction"));
+ editStyleAction->setObjectName(QString::fromUtf8("editStyleAction"));
aboutAction = new QAction(MainWindow);
- aboutAction->setObjectName(QStringLiteral("aboutAction"));
+ aboutAction->setObjectName(QString::fromUtf8("aboutAction"));
centralwidget = new QWidget(MainWindow);
- centralwidget->setObjectName(QStringLiteral("centralwidget"));
+ centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
gridLayout = new QGridLayout(centralwidget);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
@@ -82,9 +82,9 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
nameLabel = new QLabel(centralwidget);
- nameLabel->setObjectName(QStringLiteral("nameLabel"));
+ nameLabel->setObjectName(QString::fromUtf8("nameLabel"));
gridLayout->addWidget(nameLabel, 0, 0, 1, 1);
@@ -93,7 +93,7 @@ public:
nameCombo->addItem(QString());
nameCombo->addItem(QString());
nameCombo->addItem(QString());
- nameCombo->setObjectName(QStringLiteral("nameCombo"));
+ nameCombo->setObjectName(QString::fromUtf8("nameCombo"));
nameCombo->setEditable(true);
gridLayout->addWidget(nameCombo, 0, 1, 1, 3);
@@ -103,62 +103,62 @@ public:
gridLayout->addItem(spacerItem, 1, 3, 1, 1);
femaleRadioButton = new QRadioButton(centralwidget);
- femaleRadioButton->setObjectName(QStringLiteral("femaleRadioButton"));
+ femaleRadioButton->setObjectName(QString::fromUtf8("femaleRadioButton"));
gridLayout->addWidget(femaleRadioButton, 1, 2, 1, 1);
agreeCheckBox = new QCheckBox(centralwidget);
- agreeCheckBox->setObjectName(QStringLiteral("agreeCheckBox"));
+ agreeCheckBox->setObjectName(QString::fromUtf8("agreeCheckBox"));
gridLayout->addWidget(agreeCheckBox, 6, 0, 1, 4);
maleRadioButton = new QRadioButton(centralwidget);
- maleRadioButton->setObjectName(QStringLiteral("maleRadioButton"));
+ maleRadioButton->setObjectName(QString::fromUtf8("maleRadioButton"));
gridLayout->addWidget(maleRadioButton, 1, 1, 1, 1);
genderLabel = new QLabel(centralwidget);
- genderLabel->setObjectName(QStringLiteral("genderLabel"));
+ genderLabel->setObjectName(QString::fromUtf8("genderLabel"));
gridLayout->addWidget(genderLabel, 1, 0, 1, 1);
ageSpinBox = new QSpinBox(centralwidget);
- ageSpinBox->setObjectName(QStringLiteral("ageSpinBox"));
+ ageSpinBox->setObjectName(QString::fromUtf8("ageSpinBox"));
ageSpinBox->setMinimum(12);
ageSpinBox->setValue(22);
gridLayout->addWidget(ageSpinBox, 2, 1, 1, 3);
buttonBox = new QDialogButtonBox(centralwidget);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
gridLayout->addWidget(buttonBox, 7, 2, 1, 2);
ageLabel = new QLabel(centralwidget);
- ageLabel->setObjectName(QStringLiteral("ageLabel"));
+ ageLabel->setObjectName(QString::fromUtf8("ageLabel"));
gridLayout->addWidget(ageLabel, 2, 0, 1, 1);
passwordLabel = new QLabel(centralwidget);
- passwordLabel->setObjectName(QStringLiteral("passwordLabel"));
+ passwordLabel->setObjectName(QString::fromUtf8("passwordLabel"));
gridLayout->addWidget(passwordLabel, 3, 0, 1, 1);
passwordEdit = new QLineEdit(centralwidget);
- passwordEdit->setObjectName(QStringLiteral("passwordEdit"));
+ passwordEdit->setObjectName(QString::fromUtf8("passwordEdit"));
passwordEdit->setEchoMode(QLineEdit::Password);
gridLayout->addWidget(passwordEdit, 3, 1, 1, 3);
label = new QLabel(centralwidget);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 5, 0, 1, 1);
countryLabel = new QLabel(centralwidget);
- countryLabel->setObjectName(QStringLiteral("countryLabel"));
+ countryLabel->setObjectName(QString::fromUtf8("countryLabel"));
gridLayout->addWidget(countryLabel, 4, 0, 1, 1);
@@ -166,7 +166,7 @@ public:
new QListWidgetItem(professionList);
new QListWidgetItem(professionList);
new QListWidgetItem(professionList);
- professionList->setObjectName(QStringLiteral("professionList"));
+ professionList->setObjectName(QString::fromUtf8("professionList"));
gridLayout->addWidget(professionList, 5, 1, 1, 3);
@@ -176,21 +176,21 @@ public:
countryCombo->addItem(QString());
countryCombo->addItem(QString());
countryCombo->addItem(QString());
- countryCombo->setObjectName(QStringLiteral("countryCombo"));
+ countryCombo->setObjectName(QString::fromUtf8("countryCombo"));
gridLayout->addWidget(countryCombo, 4, 1, 1, 3);
MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
- menubar->setObjectName(QStringLiteral("menubar"));
+ menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 388, 21));
menu_File = new QMenu(menubar);
- menu_File->setObjectName(QStringLiteral("menu_File"));
+ menu_File->setObjectName(QString::fromUtf8("menu_File"));
menu_Help = new QMenu(menubar);
- menu_Help->setObjectName(QStringLiteral("menu_Help"));
+ menu_Help->setObjectName(QString::fromUtf8("menu_Help"));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
- statusbar->setObjectName(QStringLiteral("statusbar"));
+ statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
#ifndef QT_NO_SHORTCUT
nameLabel->setBuddy(nameCombo);
diff --git a/tests/auto/tools/uic/baseline/dialog.ui.h b/tests/auto/tools/uic/baseline/dialog.ui.h
index 1aa41c2ac8..2a159312b9 100644
--- a/tests/auto/tools/uic/baseline/dialog.ui.h
+++ b/tests/auto/tools/uic/baseline/dialog.ui.h
@@ -29,24 +29,24 @@ public:
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
- Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(451, 322);
gridLayout = new QGridLayout(Dialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
loadFromFileButton = new QPushButton(Dialog);
- loadFromFileButton->setObjectName(QStringLiteral("loadFromFileButton"));
+ loadFromFileButton->setObjectName(QString::fromUtf8("loadFromFileButton"));
gridLayout->addWidget(loadFromFileButton, 0, 0, 1, 1);
label = new QLabel(Dialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setAlignment(Qt::AlignCenter);
label->setWordWrap(true);
gridLayout->addWidget(label, 1, 0, 1, 1);
loadFromSharedMemoryButton = new QPushButton(Dialog);
- loadFromSharedMemoryButton->setObjectName(QStringLiteral("loadFromSharedMemoryButton"));
+ loadFromSharedMemoryButton->setObjectName(QString::fromUtf8("loadFromSharedMemoryButton"));
gridLayout->addWidget(loadFromSharedMemoryButton, 2, 0, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/downloaditem.ui.h b/tests/auto/tools/uic/baseline/downloaditem.ui.h
index 2e854aa9ed..f0e8e88307 100644
--- a/tests/auto/tools/uic/baseline/downloaditem.ui.h
+++ b/tests/auto/tools/uic/baseline/downloaditem.ui.h
@@ -41,13 +41,13 @@ public:
void setupUi(QWidget *DownloadItem)
{
if (DownloadItem->objectName().isEmpty())
- DownloadItem->setObjectName(QStringLiteral("DownloadItem"));
+ DownloadItem->setObjectName(QString::fromUtf8("DownloadItem"));
DownloadItem->resize(423, 110);
horizontalLayout = new QHBoxLayout(DownloadItem);
horizontalLayout->setContentsMargins(0, 0, 0, 0);
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
fileIcon = new QLabel(DownloadItem);
- fileIcon->setObjectName(QStringLiteral("fileIcon"));
+ fileIcon->setObjectName(QString::fromUtf8("fileIcon"));
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -57,9 +57,9 @@ public:
horizontalLayout->addWidget(fileIcon);
verticalLayout_2 = new QVBoxLayout();
- verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
+ verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
fileNameLabel = new SqueezeLabel(DownloadItem);
- fileNameLabel->setObjectName(QStringLiteral("fileNameLabel"));
+ fileNameLabel->setObjectName(QString::fromUtf8("fileNameLabel"));
QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Preferred);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -69,13 +69,13 @@ public:
verticalLayout_2->addWidget(fileNameLabel);
progressBar = new QProgressBar(DownloadItem);
- progressBar->setObjectName(QStringLiteral("progressBar"));
+ progressBar->setObjectName(QString::fromUtf8("progressBar"));
progressBar->setValue(0);
verticalLayout_2->addWidget(progressBar);
downloadInfoLabel = new SqueezeLabel(DownloadItem);
- downloadInfoLabel->setObjectName(QStringLiteral("downloadInfoLabel"));
+ downloadInfoLabel->setObjectName(QString::fromUtf8("downloadInfoLabel"));
QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Preferred);
sizePolicy2.setHorizontalStretch(0);
sizePolicy2.setVerticalStretch(0);
@@ -88,24 +88,24 @@ public:
horizontalLayout->addLayout(verticalLayout_2);
verticalLayout = new QVBoxLayout();
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
verticalSpacer = new QSpacerItem(17, 1, QSizePolicy::Minimum, QSizePolicy::Expanding);
verticalLayout->addItem(verticalSpacer);
tryAgainButton = new QPushButton(DownloadItem);
- tryAgainButton->setObjectName(QStringLiteral("tryAgainButton"));
+ tryAgainButton->setObjectName(QString::fromUtf8("tryAgainButton"));
tryAgainButton->setEnabled(false);
verticalLayout->addWidget(tryAgainButton);
stopButton = new QPushButton(DownloadItem);
- stopButton->setObjectName(QStringLiteral("stopButton"));
+ stopButton->setObjectName(QString::fromUtf8("stopButton"));
verticalLayout->addWidget(stopButton);
openButton = new QPushButton(DownloadItem);
- openButton->setObjectName(QStringLiteral("openButton"));
+ openButton->setObjectName(QString::fromUtf8("openButton"));
verticalLayout->addWidget(openButton);
diff --git a/tests/auto/tools/uic/baseline/downloads.ui.h b/tests/auto/tools/uic/baseline/downloads.ui.h
index 5ac40a9581..1df992d30f 100644
--- a/tests/auto/tools/uic/baseline/downloads.ui.h
+++ b/tests/auto/tools/uic/baseline/downloads.ui.h
@@ -36,21 +36,21 @@ public:
void setupUi(QDialog *DownloadDialog)
{
if (DownloadDialog->objectName().isEmpty())
- DownloadDialog->setObjectName(QStringLiteral("DownloadDialog"));
+ DownloadDialog->setObjectName(QString::fromUtf8("DownloadDialog"));
DownloadDialog->resize(332, 252);
gridLayout = new QGridLayout(DownloadDialog);
gridLayout->setSpacing(0);
gridLayout->setContentsMargins(0, 0, 0, 0);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
downloadsView = new EditTableView(DownloadDialog);
- downloadsView->setObjectName(QStringLiteral("downloadsView"));
+ downloadsView->setObjectName(QString::fromUtf8("downloadsView"));
gridLayout->addWidget(downloadsView, 0, 0, 1, 3);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
cleanupButton = new QPushButton(DownloadDialog);
- cleanupButton->setObjectName(QStringLiteral("cleanupButton"));
+ cleanupButton->setObjectName(QString::fromUtf8("cleanupButton"));
cleanupButton->setEnabled(false);
horizontalLayout->addWidget(cleanupButton);
@@ -63,7 +63,7 @@ public:
gridLayout->addLayout(horizontalLayout, 1, 0, 1, 1);
itemCount = new QLabel(DownloadDialog);
- itemCount->setObjectName(QStringLiteral("itemCount"));
+ itemCount->setObjectName(QString::fromUtf8("itemCount"));
gridLayout->addWidget(itemCount, 1, 1, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h
index 67ef6e1de1..194ff578e8 100644
--- a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h
+++ b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h
@@ -36,49 +36,49 @@ public:
void setupUi(QDialog *embeddedDialog)
{
if (embeddedDialog->objectName().isEmpty())
- embeddedDialog->setObjectName(QStringLiteral("embeddedDialog"));
+ embeddedDialog->setObjectName(QString::fromUtf8("embeddedDialog"));
embeddedDialog->resize(407, 134);
formLayout = new QFormLayout(embeddedDialog);
- formLayout->setObjectName(QStringLiteral("formLayout"));
+ formLayout->setObjectName(QString::fromUtf8("formLayout"));
label = new QLabel(embeddedDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
formLayout->setWidget(0, QFormLayout::LabelRole, label);
layoutDirection = new QComboBox(embeddedDialog);
layoutDirection->addItem(QString());
layoutDirection->addItem(QString());
- layoutDirection->setObjectName(QStringLiteral("layoutDirection"));
+ layoutDirection->setObjectName(QString::fromUtf8("layoutDirection"));
formLayout->setWidget(0, QFormLayout::FieldRole, layoutDirection);
label_2 = new QLabel(embeddedDialog);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
formLayout->setWidget(1, QFormLayout::LabelRole, label_2);
fontComboBox = new QFontComboBox(embeddedDialog);
- fontComboBox->setObjectName(QStringLiteral("fontComboBox"));
+ fontComboBox->setObjectName(QString::fromUtf8("fontComboBox"));
formLayout->setWidget(1, QFormLayout::FieldRole, fontComboBox);
label_3 = new QLabel(embeddedDialog);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
formLayout->setWidget(2, QFormLayout::LabelRole, label_3);
style = new QComboBox(embeddedDialog);
- style->setObjectName(QStringLiteral("style"));
+ style->setObjectName(QString::fromUtf8("style"));
formLayout->setWidget(2, QFormLayout::FieldRole, style);
label_4 = new QLabel(embeddedDialog);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
formLayout->setWidget(3, QFormLayout::LabelRole, label_4);
spacing = new QSlider(embeddedDialog);
- spacing->setObjectName(QStringLiteral("spacing"));
+ spacing->setObjectName(QString::fromUtf8("spacing"));
spacing->setOrientation(Qt::Horizontal);
formLayout->setWidget(3, QFormLayout::FieldRole, spacing);
diff --git a/tests/auto/tools/uic/baseline/enumnostdset.ui.h b/tests/auto/tools/uic/baseline/enumnostdset.ui.h
index 451cbd6a68..233fc616ac 100644
--- a/tests/auto/tools/uic/baseline/enumnostdset.ui.h
+++ b/tests/auto/tools/uic/baseline/enumnostdset.ui.h
@@ -24,10 +24,10 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(400, 300);
worldTimeClock = new WorldTimeClock(Form);
- worldTimeClock->setObjectName(QStringLiteral("worldTimeClock"));
+ worldTimeClock->setObjectName(QString::fromUtf8("worldTimeClock"));
worldTimeClock->setGeometry(QRect(100, 100, 100, 100));
worldTimeClock->setProperty("penStyle", QVariant::fromValue(Qt::DashDotLine));
diff --git a/tests/auto/tools/uic/baseline/filespage.ui.h b/tests/auto/tools/uic/baseline/filespage.ui.h
index 8ab8d09768..29ed981a8a 100644
--- a/tests/auto/tools/uic/baseline/filespage.ui.h
+++ b/tests/auto/tools/uic/baseline/filespage.ui.h
@@ -34,23 +34,23 @@ public:
void setupUi(QWidget *FilesPage)
{
if (FilesPage->objectName().isEmpty())
- FilesPage->setObjectName(QStringLiteral("FilesPage"));
+ FilesPage->setObjectName(QString::fromUtf8("FilesPage"));
FilesPage->resize(417, 242);
gridLayout = new QGridLayout(FilesPage);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
fileLabel = new QLabel(FilesPage);
- fileLabel->setObjectName(QStringLiteral("fileLabel"));
+ fileLabel->setObjectName(QString::fromUtf8("fileLabel"));
fileLabel->setWordWrap(true);
gridLayout->addWidget(fileLabel, 0, 0, 1, 2);
fileListWidget = new QListWidget(FilesPage);
- fileListWidget->setObjectName(QStringLiteral("fileListWidget"));
+ fileListWidget->setObjectName(QString::fromUtf8("fileListWidget"));
gridLayout->addWidget(fileListWidget, 1, 0, 3, 1);
removeButton = new QPushButton(FilesPage);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -60,7 +60,7 @@ public:
gridLayout->addWidget(removeButton, 1, 1, 1, 1);
removeAllButton = new QPushButton(FilesPage);
- removeAllButton->setObjectName(QStringLiteral("removeAllButton"));
+ removeAllButton->setObjectName(QString::fromUtf8("removeAllButton"));
gridLayout->addWidget(removeAllButton, 2, 1, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/filternamedialog.ui.h b/tests/auto/tools/uic/baseline/filternamedialog.ui.h
index 60642c29f6..716c291fdd 100644
--- a/tests/auto/tools/uic/baseline/filternamedialog.ui.h
+++ b/tests/auto/tools/uic/baseline/filternamedialog.ui.h
@@ -34,24 +34,24 @@ public:
void setupUi(QDialog *FilterNameDialogClass)
{
if (FilterNameDialogClass->objectName().isEmpty())
- FilterNameDialogClass->setObjectName(QStringLiteral("FilterNameDialogClass"));
+ FilterNameDialogClass->setObjectName(QString::fromUtf8("FilterNameDialogClass"));
FilterNameDialogClass->resize(312, 95);
gridLayout = new QGridLayout(FilterNameDialogClass);
gridLayout->setSpacing(6);
gridLayout->setContentsMargins(9, 9, 9, 9);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(FilterNameDialogClass);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
lineEdit = new QLineEdit(FilterNameDialogClass);
- lineEdit->setObjectName(QStringLiteral("lineEdit"));
+ lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
gridLayout->addWidget(lineEdit, 0, 1, 1, 2);
line = new QFrame(FilterNameDialogClass);
- line->setObjectName(QStringLiteral("line"));
+ line->setObjectName(QString::fromUtf8("line"));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
@@ -62,7 +62,7 @@ public:
gridLayout->addItem(spacerItem, 2, 0, 1, 2);
buttonBox = new QDialogButtonBox(FilterNameDialogClass);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/filterpage.ui.h b/tests/auto/tools/uic/baseline/filterpage.ui.h
index a20dffc09a..f6610fdc4d 100644
--- a/tests/auto/tools/uic/baseline/filterpage.ui.h
+++ b/tests/auto/tools/uic/baseline/filterpage.ui.h
@@ -42,37 +42,37 @@ public:
void setupUi(QWidget *FilterPage)
{
if (FilterPage->objectName().isEmpty())
- FilterPage->setObjectName(QStringLiteral("FilterPage"));
+ FilterPage->setObjectName(QString::fromUtf8("FilterPage"));
FilterPage->resize(419, 243);
gridLayout = new QGridLayout(FilterPage);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(FilterPage);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 1, 0, 1, 1);
filterLineEdit = new QLineEdit(FilterPage);
- filterLineEdit->setObjectName(QStringLiteral("filterLineEdit"));
+ filterLineEdit->setObjectName(QString::fromUtf8("filterLineEdit"));
gridLayout->addWidget(filterLineEdit, 2, 0, 1, 1);
groupBox = new QGroupBox(FilterPage);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
gridLayout1 = new QGridLayout(groupBox);
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
customFilterWidget = new QTreeWidget(groupBox);
- customFilterWidget->setObjectName(QStringLiteral("customFilterWidget"));
+ customFilterWidget->setObjectName(QString::fromUtf8("customFilterWidget"));
customFilterWidget->setColumnCount(2);
gridLayout1->addWidget(customFilterWidget, 0, 0, 3, 1);
addButton = new QPushButton(groupBox);
- addButton->setObjectName(QStringLiteral("addButton"));
+ addButton->setObjectName(QString::fromUtf8("addButton"));
gridLayout1->addWidget(addButton, 0, 1, 1, 1);
removeButton = new QPushButton(groupBox);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
gridLayout1->addWidget(removeButton, 1, 1, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/finddialog.ui.h b/tests/auto/tools/uic/baseline/finddialog.ui.h
index 0bb1ec4286..a427be3614 100644
--- a/tests/auto/tools/uic/baseline/finddialog.ui.h
+++ b/tests/auto/tools/uic/baseline/finddialog.ui.h
@@ -77,7 +77,7 @@ public:
void setupUi(QDialog *FindDialog)
{
if (FindDialog->objectName().isEmpty())
- FindDialog->setObjectName(QStringLiteral("FindDialog"));
+ FindDialog->setObjectName(QString::fromUtf8("FindDialog"));
FindDialog->resize(414, 170);
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
sizePolicy.setHorizontalStretch(0);
@@ -87,22 +87,22 @@ public:
hboxLayout = new QHBoxLayout(FindDialog);
hboxLayout->setSpacing(6);
hboxLayout->setContentsMargins(11, 11, 11, 11);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
vboxLayout = new QVBoxLayout();
vboxLayout->setSpacing(6);
vboxLayout->setContentsMargins(0, 0, 0, 0);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
hboxLayout1 = new QHBoxLayout();
hboxLayout1->setSpacing(6);
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
findWhat = new QLabel(FindDialog);
- findWhat->setObjectName(QStringLiteral("findWhat"));
+ findWhat->setObjectName(QString::fromUtf8("findWhat"));
hboxLayout1->addWidget(findWhat);
led = new QLineEdit(FindDialog);
- led->setObjectName(QStringLiteral("led"));
+ led->setObjectName(QString::fromUtf8("led"));
hboxLayout1->addWidget(led);
@@ -110,36 +110,36 @@ public:
vboxLayout->addLayout(hboxLayout1);
groupBox = new QGroupBox(FindDialog);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
gridLayout = new QGridLayout(groupBox);
gridLayout->setSpacing(6);
gridLayout->setContentsMargins(9, 9, 9, 9);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
sourceText = new QCheckBox(groupBox);
- sourceText->setObjectName(QStringLiteral("sourceText"));
+ sourceText->setObjectName(QString::fromUtf8("sourceText"));
sourceText->setChecked(true);
gridLayout->addWidget(sourceText, 1, 0, 1, 1);
translations = new QCheckBox(groupBox);
- translations->setObjectName(QStringLiteral("translations"));
+ translations->setObjectName(QString::fromUtf8("translations"));
translations->setChecked(true);
gridLayout->addWidget(translations, 2, 0, 1, 1);
matchCase = new QCheckBox(groupBox);
- matchCase->setObjectName(QStringLiteral("matchCase"));
+ matchCase->setObjectName(QString::fromUtf8("matchCase"));
gridLayout->addWidget(matchCase, 0, 1, 1, 1);
comments = new QCheckBox(groupBox);
- comments->setObjectName(QStringLiteral("comments"));
+ comments->setObjectName(QString::fromUtf8("comments"));
comments->setChecked(true);
gridLayout->addWidget(comments, 0, 0, 1, 1);
ignoreAccelerators = new QCheckBox(groupBox);
- ignoreAccelerators->setObjectName(QStringLiteral("ignoreAccelerators"));
+ ignoreAccelerators->setObjectName(QString::fromUtf8("ignoreAccelerators"));
ignoreAccelerators->setChecked(true);
gridLayout->addWidget(ignoreAccelerators, 1, 1, 1, 1);
@@ -153,15 +153,15 @@ public:
vboxLayout1 = new QVBoxLayout();
vboxLayout1->setSpacing(6);
vboxLayout1->setContentsMargins(0, 0, 0, 0);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
findNxt = new QPushButton(FindDialog);
- findNxt->setObjectName(QStringLiteral("findNxt"));
+ findNxt->setObjectName(QString::fromUtf8("findNxt"));
findNxt->setFlat(false);
vboxLayout1->addWidget(findNxt);
cancel = new QPushButton(FindDialog);
- cancel->setObjectName(QStringLiteral("cancel"));
+ cancel->setObjectName(QString::fromUtf8("cancel"));
vboxLayout1->addWidget(cancel);
diff --git a/tests/auto/tools/uic/baseline/form.ui.h b/tests/auto/tools/uic/baseline/form.ui.h
index fc4f3e079c..ecc63e339b 100644
--- a/tests/auto/tools/uic/baseline/form.ui.h
+++ b/tests/auto/tools/uic/baseline/form.ui.h
@@ -40,7 +40,7 @@ public:
void setupUi(QWidget *WorldTimeForm)
{
if (WorldTimeForm->objectName().isEmpty())
- WorldTimeForm->setObjectName(QStringLiteral("WorldTimeForm"));
+ WorldTimeForm->setObjectName(QString::fromUtf8("WorldTimeForm"));
WorldTimeForm->resize(400, 300);
hboxLayout = new QHBoxLayout(WorldTimeForm);
#ifndef Q_OS_MAC
@@ -49,9 +49,9 @@ public:
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
worldTimeClock = new WorldTimeClock(WorldTimeForm);
- worldTimeClock->setObjectName(QStringLiteral("worldTimeClock"));
+ worldTimeClock->setObjectName(QString::fromUtf8("worldTimeClock"));
hboxLayout->addWidget(worldTimeClock);
@@ -60,7 +60,7 @@ public:
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(1, 1, 1, 1);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
spacerItem = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
vboxLayout->addItem(spacerItem);
@@ -70,14 +70,14 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(1, 1, 1, 1);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
label = new QLabel(WorldTimeForm);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
hboxLayout1->addWidget(label);
timeEdit = new QTimeEdit(WorldTimeForm);
- timeEdit->setObjectName(QStringLiteral("timeEdit"));
+ timeEdit->setObjectName(QString::fromUtf8("timeEdit"));
timeEdit->setReadOnly(true);
hboxLayout1->addWidget(timeEdit);
@@ -90,14 +90,14 @@ public:
hboxLayout2->setSpacing(6);
#endif
hboxLayout2->setContentsMargins(1, 1, 1, 1);
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
label_2 = new QLabel(WorldTimeForm);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
hboxLayout2->addWidget(label_2);
spinBox = new QSpinBox(WorldTimeForm);
- spinBox->setObjectName(QStringLiteral("spinBox"));
+ spinBox->setObjectName(QString::fromUtf8("spinBox"));
spinBox->setMaximum(12);
spinBox->setMinimum(-12);
diff --git a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h
index 349ef9ac80..d2cfa03edb 100644
--- a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h
+++ b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h
@@ -92,19 +92,19 @@ public:
void setupUi(QDialog *FormWindowSettings)
{
if (FormWindowSettings->objectName().isEmpty())
- FormWindowSettings->setObjectName(QStringLiteral("FormWindowSettings"));
+ FormWindowSettings->setObjectName(QString::fromUtf8("FormWindowSettings"));
FormWindowSettings->resize(433, 465);
gridLayout = new QGridLayout(FormWindowSettings);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
buttonBox = new QDialogButtonBox(FormWindowSettings);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
gridLayout->addWidget(buttonBox, 6, 0, 1, 2);
line = new QFrame(FormWindowSettings);
- line->setObjectName(QStringLiteral("line"));
+ line->setObjectName(QString::fromUtf8("line"));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
@@ -115,33 +115,33 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
layoutDefaultGroupBox = new QGroupBox(FormWindowSettings);
- layoutDefaultGroupBox->setObjectName(QStringLiteral("layoutDefaultGroupBox"));
+ layoutDefaultGroupBox->setObjectName(QString::fromUtf8("layoutDefaultGroupBox"));
layoutDefaultGroupBox->setCheckable(true);
gridLayout1 = new QGridLayout(layoutDefaultGroupBox);
#ifndef Q_OS_MAC
gridLayout1->setSpacing(6);
#endif
gridLayout1->setContentsMargins(8, 8, 8, 8);
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
label_2 = new QLabel(layoutDefaultGroupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout1->addWidget(label_2, 1, 0, 1, 1);
label = new QLabel(layoutDefaultGroupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout1->addWidget(label, 0, 0, 1, 1);
defaultSpacingSpinBox = new QSpinBox(layoutDefaultGroupBox);
- defaultSpacingSpinBox->setObjectName(QStringLiteral("defaultSpacingSpinBox"));
+ defaultSpacingSpinBox->setObjectName(QString::fromUtf8("defaultSpacingSpinBox"));
gridLayout1->addWidget(defaultSpacingSpinBox, 1, 1, 1, 1);
defaultMarginSpinBox = new QSpinBox(layoutDefaultGroupBox);
- defaultMarginSpinBox->setObjectName(QStringLiteral("defaultMarginSpinBox"));
+ defaultMarginSpinBox->setObjectName(QString::fromUtf8("defaultMarginSpinBox"));
gridLayout1->addWidget(defaultMarginSpinBox, 0, 1, 1, 1);
@@ -149,31 +149,31 @@ public:
hboxLayout->addWidget(layoutDefaultGroupBox);
layoutFunctionGroupBox = new QGroupBox(FormWindowSettings);
- layoutFunctionGroupBox->setObjectName(QStringLiteral("layoutFunctionGroupBox"));
+ layoutFunctionGroupBox->setObjectName(QString::fromUtf8("layoutFunctionGroupBox"));
layoutFunctionGroupBox->setCheckable(true);
gridLayout2 = new QGridLayout(layoutFunctionGroupBox);
#ifndef Q_OS_MAC
gridLayout2->setSpacing(6);
#endif
gridLayout2->setContentsMargins(8, 8, 8, 8);
- gridLayout2->setObjectName(QStringLiteral("gridLayout2"));
+ gridLayout2->setObjectName(QString::fromUtf8("gridLayout2"));
spacingFunctionLineEdit = new QLineEdit(layoutFunctionGroupBox);
- spacingFunctionLineEdit->setObjectName(QStringLiteral("spacingFunctionLineEdit"));
+ spacingFunctionLineEdit->setObjectName(QString::fromUtf8("spacingFunctionLineEdit"));
gridLayout2->addWidget(spacingFunctionLineEdit, 1, 1, 1, 1);
marginFunctionLineEdit = new QLineEdit(layoutFunctionGroupBox);
- marginFunctionLineEdit->setObjectName(QStringLiteral("marginFunctionLineEdit"));
+ marginFunctionLineEdit->setObjectName(QString::fromUtf8("marginFunctionLineEdit"));
gridLayout2->addWidget(marginFunctionLineEdit, 0, 1, 1, 1);
label_3 = new QLabel(layoutFunctionGroupBox);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout2->addWidget(label_3, 0, 0, 1, 1);
label_3_2 = new QLabel(layoutFunctionGroupBox);
- label_3_2->setObjectName(QStringLiteral("label_3_2"));
+ label_3_2->setObjectName(QString::fromUtf8("label_3_2"));
gridLayout2->addWidget(label_3_2, 1, 0, 1, 1);
@@ -184,15 +184,15 @@ public:
gridLayout->addLayout(hboxLayout, 2, 0, 1, 2);
pixmapFunctionGroupBox_2 = new QGroupBox(FormWindowSettings);
- pixmapFunctionGroupBox_2->setObjectName(QStringLiteral("pixmapFunctionGroupBox_2"));
+ pixmapFunctionGroupBox_2->setObjectName(QString::fromUtf8("pixmapFunctionGroupBox_2"));
vboxLayout = new QVBoxLayout(pixmapFunctionGroupBox_2);
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(8, 8, 8, 8);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
authorLineEdit = new QLineEdit(pixmapFunctionGroupBox_2);
- authorLineEdit->setObjectName(QStringLiteral("authorLineEdit"));
+ authorLineEdit->setObjectName(QString::fromUtf8("authorLineEdit"));
vboxLayout->addWidget(authorLineEdit);
@@ -200,15 +200,15 @@ public:
gridLayout->addWidget(pixmapFunctionGroupBox_2, 0, 0, 1, 2);
includeHintsGroupBox = new QGroupBox(FormWindowSettings);
- includeHintsGroupBox->setObjectName(QStringLiteral("includeHintsGroupBox"));
+ includeHintsGroupBox->setObjectName(QString::fromUtf8("includeHintsGroupBox"));
vboxLayout1 = new QVBoxLayout(includeHintsGroupBox);
#ifndef Q_OS_MAC
vboxLayout1->setSpacing(6);
#endif
vboxLayout1->setContentsMargins(8, 8, 8, 8);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
includeHintsTextEdit = new QTextEdit(includeHintsGroupBox);
- includeHintsTextEdit->setObjectName(QStringLiteral("includeHintsTextEdit"));
+ includeHintsTextEdit->setObjectName(QString::fromUtf8("includeHintsTextEdit"));
vboxLayout1->addWidget(includeHintsTextEdit);
@@ -220,18 +220,18 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
pixmapFunctionGroupBox = new QGroupBox(FormWindowSettings);
- pixmapFunctionGroupBox->setObjectName(QStringLiteral("pixmapFunctionGroupBox"));
+ pixmapFunctionGroupBox->setObjectName(QString::fromUtf8("pixmapFunctionGroupBox"));
pixmapFunctionGroupBox->setCheckable(true);
vboxLayout2 = new QVBoxLayout(pixmapFunctionGroupBox);
#ifndef Q_OS_MAC
vboxLayout2->setSpacing(6);
#endif
vboxLayout2->setContentsMargins(8, 8, 8, 8);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
pixmapFunctionLineEdit = new QLineEdit(pixmapFunctionGroupBox);
- pixmapFunctionLineEdit->setObjectName(QStringLiteral("pixmapFunctionLineEdit"));
+ pixmapFunctionLineEdit->setObjectName(QString::fromUtf8("pixmapFunctionLineEdit"));
vboxLayout2->addWidget(pixmapFunctionLineEdit);
@@ -246,7 +246,7 @@ public:
gridLayout->addItem(spacerItem, 4, 1, 1, 1);
gridPanel = new qdesigner_internal::GridPanel(FormWindowSettings);
- gridPanel->setObjectName(QStringLiteral("gridPanel"));
+ gridPanel->setObjectName(QString::fromUtf8("gridPanel"));
gridLayout->addWidget(gridPanel, 1, 0, 1, 2);
diff --git a/tests/auto/tools/uic/baseline/generalpage.ui.h b/tests/auto/tools/uic/baseline/generalpage.ui.h
index cb0c4e92c4..bd04285d28 100644
--- a/tests/auto/tools/uic/baseline/generalpage.ui.h
+++ b/tests/auto/tools/uic/baseline/generalpage.ui.h
@@ -33,27 +33,27 @@ public:
void setupUi(QWidget *GeneralPage)
{
if (GeneralPage->objectName().isEmpty())
- GeneralPage->setObjectName(QStringLiteral("GeneralPage"));
+ GeneralPage->setObjectName(QString::fromUtf8("GeneralPage"));
GeneralPage->resize(417, 243);
gridLayout = new QGridLayout(GeneralPage);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(GeneralPage);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 1, 0, 1, 1);
namespaceLineEdit = new QLineEdit(GeneralPage);
- namespaceLineEdit->setObjectName(QStringLiteral("namespaceLineEdit"));
+ namespaceLineEdit->setObjectName(QString::fromUtf8("namespaceLineEdit"));
gridLayout->addWidget(namespaceLineEdit, 1, 1, 1, 1);
label_2 = new QLabel(GeneralPage);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout->addWidget(label_2, 2, 0, 1, 1);
folderLineEdit = new QLineEdit(GeneralPage);
- folderLineEdit->setObjectName(QStringLiteral("folderLineEdit"));
+ folderLineEdit->setObjectName(QString::fromUtf8("folderLineEdit"));
gridLayout->addWidget(folderLineEdit, 2, 1, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/gridalignment.ui.h b/tests/auto/tools/uic/baseline/gridalignment.ui.h
index 8e243ce800..421f257c9a 100644
--- a/tests/auto/tools/uic/baseline/gridalignment.ui.h
+++ b/tests/auto/tools/uic/baseline/gridalignment.ui.h
@@ -29,27 +29,27 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(279, 163);
gridLayout = new QGridLayout(Form);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
pushButton = new QPushButton(Form);
- pushButton->setObjectName(QStringLiteral("pushButton"));
+ pushButton->setObjectName(QString::fromUtf8("pushButton"));
gridLayout->addWidget(pushButton, 0, 0, 1, 1, Qt::AlignLeft);
pushButton_3 = new QPushButton(Form);
- pushButton_3->setObjectName(QStringLiteral("pushButton_3"));
+ pushButton_3->setObjectName(QString::fromUtf8("pushButton_3"));
gridLayout->addWidget(pushButton_3, 0, 1, 1, 1, Qt::AlignTop);
pushButton_2 = new QPushButton(Form);
- pushButton_2->setObjectName(QStringLiteral("pushButton_2"));
+ pushButton_2->setObjectName(QString::fromUtf8("pushButton_2"));
gridLayout->addWidget(pushButton_2, 1, 0, 1, 1, Qt::AlignRight);
pushButton_4 = new QPushButton(Form);
- pushButton_4->setObjectName(QStringLiteral("pushButton_4"));
+ pushButton_4->setObjectName(QString::fromUtf8("pushButton_4"));
gridLayout->addWidget(pushButton_4, 1, 1, 1, 1, Qt::AlignBottom);
diff --git a/tests/auto/tools/uic/baseline/gridpanel.ui.h b/tests/auto/tools/uic/baseline/gridpanel.ui.h
index feeff26013..858b71d0cc 100644
--- a/tests/auto/tools/uic/baseline/gridpanel.ui.h
+++ b/tests/auto/tools/uic/baseline/gridpanel.ui.h
@@ -46,17 +46,17 @@ public:
void setupUi(QWidget *qdesigner_internal__GridPanel)
{
if (qdesigner_internal__GridPanel->objectName().isEmpty())
- qdesigner_internal__GridPanel->setObjectName(QStringLiteral("qdesigner_internal__GridPanel"));
+ qdesigner_internal__GridPanel->setObjectName(QString::fromUtf8("qdesigner_internal__GridPanel"));
qdesigner_internal__GridPanel->resize(393, 110);
vboxLayout = new QVBoxLayout(qdesigner_internal__GridPanel);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout->setContentsMargins(0, 0, 0, 0);
m_gridGroupBox = new QGroupBox(qdesigner_internal__GridPanel);
- m_gridGroupBox->setObjectName(QStringLiteral("m_gridGroupBox"));
+ m_gridGroupBox->setObjectName(QString::fromUtf8("m_gridGroupBox"));
gridLayout = new QGridLayout(m_gridGroupBox);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
m_visibleCheckBox = new QCheckBox(m_gridGroupBox);
- m_visibleCheckBox->setObjectName(QStringLiteral("m_visibleCheckBox"));
+ m_visibleCheckBox->setObjectName(QString::fromUtf8("m_visibleCheckBox"));
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -66,28 +66,28 @@ public:
gridLayout->addWidget(m_visibleCheckBox, 0, 0, 1, 1);
label = new QLabel(m_gridGroupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 1, 1, 1);
m_deltaXSpinBox = new QSpinBox(m_gridGroupBox);
- m_deltaXSpinBox->setObjectName(QStringLiteral("m_deltaXSpinBox"));
+ m_deltaXSpinBox->setObjectName(QString::fromUtf8("m_deltaXSpinBox"));
m_deltaXSpinBox->setMinimum(2);
m_deltaXSpinBox->setMaximum(100);
gridLayout->addWidget(m_deltaXSpinBox, 0, 2, 1, 1);
m_snapXCheckBox = new QCheckBox(m_gridGroupBox);
- m_snapXCheckBox->setObjectName(QStringLiteral("m_snapXCheckBox"));
+ m_snapXCheckBox->setObjectName(QString::fromUtf8("m_snapXCheckBox"));
sizePolicy.setHeightForWidth(m_snapXCheckBox->sizePolicy().hasHeightForWidth());
m_snapXCheckBox->setSizePolicy(sizePolicy);
gridLayout->addWidget(m_snapXCheckBox, 0, 3, 1, 1);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
m_resetButton = new QPushButton(m_gridGroupBox);
- m_resetButton->setObjectName(QStringLiteral("m_resetButton"));
+ m_resetButton->setObjectName(QString::fromUtf8("m_resetButton"));
hboxLayout->addWidget(m_resetButton);
@@ -99,19 +99,19 @@ public:
gridLayout->addLayout(hboxLayout, 1, 0, 1, 1);
label_2 = new QLabel(m_gridGroupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout->addWidget(label_2, 1, 1, 1, 1);
m_deltaYSpinBox = new QSpinBox(m_gridGroupBox);
- m_deltaYSpinBox->setObjectName(QStringLiteral("m_deltaYSpinBox"));
+ m_deltaYSpinBox->setObjectName(QString::fromUtf8("m_deltaYSpinBox"));
m_deltaYSpinBox->setMinimum(2);
m_deltaYSpinBox->setMaximum(100);
gridLayout->addWidget(m_deltaYSpinBox, 1, 2, 1, 1);
m_snapYCheckBox = new QCheckBox(m_gridGroupBox);
- m_snapYCheckBox->setObjectName(QStringLiteral("m_snapYCheckBox"));
+ m_snapYCheckBox->setObjectName(QString::fromUtf8("m_snapYCheckBox"));
sizePolicy.setHeightForWidth(m_snapYCheckBox->sizePolicy().hasHeightForWidth());
m_snapYCheckBox->setSizePolicy(sizePolicy);
diff --git a/tests/auto/tools/uic/baseline/helpdialog.ui.h b/tests/auto/tools/uic/baseline/helpdialog.ui.h
index 7c584639c2..abcf280cf9 100644
--- a/tests/auto/tools/uic/baseline/helpdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/helpdialog.ui.h
@@ -98,26 +98,26 @@ public:
void setupUi(QWidget *HelpDialog)
{
if (HelpDialog->objectName().isEmpty())
- HelpDialog->setObjectName(QStringLiteral("HelpDialog"));
+ HelpDialog->setObjectName(QString::fromUtf8("HelpDialog"));
HelpDialog->resize(274, 417);
vboxLayout = new QVBoxLayout(HelpDialog);
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(0, 0, 0, 0);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
tabWidget = new QTabWidget(HelpDialog);
- tabWidget->setObjectName(QStringLiteral("tabWidget"));
+ tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
contentPage = new QWidget();
- contentPage->setObjectName(QStringLiteral("contentPage"));
+ contentPage->setObjectName(QString::fromUtf8("contentPage"));
vboxLayout1 = new QVBoxLayout(contentPage);
#ifndef Q_OS_MAC
vboxLayout1->setSpacing(6);
#endif
vboxLayout1->setContentsMargins(5, 5, 5, 5);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
listContents = new QTreeWidget(contentPage);
- listContents->setObjectName(QStringLiteral("listContents"));
+ listContents->setObjectName(QString::fromUtf8("listContents"));
listContents->setContextMenuPolicy(Qt::CustomContextMenu);
listContents->setRootIsDecorated(true);
listContents->setUniformRowHeights(true);
@@ -126,40 +126,40 @@ public:
tabWidget->addTab(contentPage, QString());
indexPage = new QWidget();
- indexPage->setObjectName(QStringLiteral("indexPage"));
+ indexPage->setObjectName(QString::fromUtf8("indexPage"));
vboxLayout2 = new QVBoxLayout(indexPage);
#ifndef Q_OS_MAC
vboxLayout2->setSpacing(6);
#endif
vboxLayout2->setContentsMargins(5, 5, 5, 5);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
TextLabel1 = new QLabel(indexPage);
- TextLabel1->setObjectName(QStringLiteral("TextLabel1"));
+ TextLabel1->setObjectName(QString::fromUtf8("TextLabel1"));
vboxLayout2->addWidget(TextLabel1);
editIndex = new QLineEdit(indexPage);
- editIndex->setObjectName(QStringLiteral("editIndex"));
+ editIndex->setObjectName(QString::fromUtf8("editIndex"));
vboxLayout2->addWidget(editIndex);
listIndex = new QListView(indexPage);
- listIndex->setObjectName(QStringLiteral("listIndex"));
+ listIndex->setObjectName(QString::fromUtf8("listIndex"));
listIndex->setContextMenuPolicy(Qt::CustomContextMenu);
vboxLayout2->addWidget(listIndex);
tabWidget->addTab(indexPage, QString());
bookmarkPage = new QWidget();
- bookmarkPage->setObjectName(QStringLiteral("bookmarkPage"));
+ bookmarkPage->setObjectName(QString::fromUtf8("bookmarkPage"));
vboxLayout3 = new QVBoxLayout(bookmarkPage);
#ifndef Q_OS_MAC
vboxLayout3->setSpacing(6);
#endif
vboxLayout3->setContentsMargins(5, 5, 5, 5);
- vboxLayout3->setObjectName(QStringLiteral("vboxLayout3"));
+ vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3"));
listBookmarks = new QTreeWidget(bookmarkPage);
- listBookmarks->setObjectName(QStringLiteral("listBookmarks"));
+ listBookmarks->setObjectName(QString::fromUtf8("listBookmarks"));
listBookmarks->setContextMenuPolicy(Qt::CustomContextMenu);
listBookmarks->setUniformRowHeights(true);
@@ -170,18 +170,18 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(spacerItem);
buttonAdd = new QPushButton(bookmarkPage);
- buttonAdd->setObjectName(QStringLiteral("buttonAdd"));
+ buttonAdd->setObjectName(QString::fromUtf8("buttonAdd"));
hboxLayout->addWidget(buttonAdd);
buttonRemove = new QPushButton(bookmarkPage);
- buttonRemove->setObjectName(QStringLiteral("buttonRemove"));
+ buttonRemove->setObjectName(QString::fromUtf8("buttonRemove"));
hboxLayout->addWidget(buttonRemove);
@@ -190,35 +190,35 @@ public:
tabWidget->addTab(bookmarkPage, QString());
searchPage = new QWidget();
- searchPage->setObjectName(QStringLiteral("searchPage"));
+ searchPage->setObjectName(QString::fromUtf8("searchPage"));
gridLayout = new QGridLayout(searchPage);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
#endif
gridLayout->setContentsMargins(5, 5, 5, 5);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
spacerItem1 = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed);
gridLayout->addItem(spacerItem1, 3, 0, 1, 1);
TextLabel1_2 = new QLabel(searchPage);
- TextLabel1_2->setObjectName(QStringLiteral("TextLabel1_2"));
+ TextLabel1_2->setObjectName(QString::fromUtf8("TextLabel1_2"));
gridLayout->addWidget(TextLabel1_2, 0, 0, 1, 1);
termsEdit = new QLineEdit(searchPage);
- termsEdit->setObjectName(QStringLiteral("termsEdit"));
+ termsEdit->setObjectName(QString::fromUtf8("termsEdit"));
gridLayout->addWidget(termsEdit, 1, 0, 1, 1);
resultBox = new QListWidget(searchPage);
- resultBox->setObjectName(QStringLiteral("resultBox"));
+ resultBox->setObjectName(QString::fromUtf8("resultBox"));
resultBox->setContextMenuPolicy(Qt::CustomContextMenu);
gridLayout->addWidget(resultBox, 5, 0, 1, 1);
TextLabel2 = new QLabel(searchPage);
- TextLabel2->setObjectName(QStringLiteral("TextLabel2"));
+ TextLabel2->setObjectName(QString::fromUtf8("TextLabel2"));
gridLayout->addWidget(TextLabel2, 4, 0, 1, 1);
@@ -227,9 +227,9 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(1, 1, 1, 1);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
helpButton = new QPushButton(searchPage);
- helpButton->setObjectName(QStringLiteral("helpButton"));
+ helpButton->setObjectName(QString::fromUtf8("helpButton"));
hboxLayout1->addWidget(helpButton);
@@ -238,7 +238,7 @@ public:
hboxLayout1->addItem(spacerItem2);
searchButton = new QPushButton(searchPage);
- searchButton->setObjectName(QStringLiteral("searchButton"));
+ searchButton->setObjectName(QString::fromUtf8("searchButton"));
searchButton->setEnabled(false);
hboxLayout1->addWidget(searchButton);
@@ -251,7 +251,7 @@ public:
vboxLayout->addWidget(tabWidget);
framePrepare = new QFrame(HelpDialog);
- framePrepare->setObjectName(QStringLiteral("framePrepare"));
+ framePrepare->setObjectName(QString::fromUtf8("framePrepare"));
framePrepare->setFrameShape(QFrame::StyledPanel);
framePrepare->setFrameShadow(QFrame::Raised);
hboxLayout2 = new QHBoxLayout(framePrepare);
@@ -259,14 +259,14 @@ public:
hboxLayout2->setSpacing(6);
#endif
hboxLayout2->setContentsMargins(3, 3, 3, 3);
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
labelPrepare = new QLabel(framePrepare);
- labelPrepare->setObjectName(QStringLiteral("labelPrepare"));
+ labelPrepare->setObjectName(QString::fromUtf8("labelPrepare"));
hboxLayout2->addWidget(labelPrepare);
progressPrepare = new QProgressBar(framePrepare);
- progressPrepare->setObjectName(QStringLiteral("progressPrepare"));
+ progressPrepare->setObjectName(QString::fromUtf8("progressPrepare"));
hboxLayout2->addWidget(progressPrepare);
diff --git a/tests/auto/tools/uic/baseline/history.ui.h b/tests/auto/tools/uic/baseline/history.ui.h
index f9050de854..715312d11a 100644
--- a/tests/auto/tools/uic/baseline/history.ui.h
+++ b/tests/auto/tools/uic/baseline/history.ui.h
@@ -39,33 +39,33 @@ public:
void setupUi(QDialog *HistoryDialog)
{
if (HistoryDialog->objectName().isEmpty())
- HistoryDialog->setObjectName(QStringLiteral("HistoryDialog"));
+ HistoryDialog->setObjectName(QString::fromUtf8("HistoryDialog"));
HistoryDialog->resize(758, 450);
gridLayout = new QGridLayout(HistoryDialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
spacerItem = new QSpacerItem(252, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout->addItem(spacerItem, 0, 0, 1, 1);
search = new SearchLineEdit(HistoryDialog);
- search->setObjectName(QStringLiteral("search"));
+ search->setObjectName(QString::fromUtf8("search"));
gridLayout->addWidget(search, 0, 1, 1, 1);
tree = new EditTreeView(HistoryDialog);
- tree->setObjectName(QStringLiteral("tree"));
+ tree->setObjectName(QString::fromUtf8("tree"));
gridLayout->addWidget(tree, 1, 0, 1, 2);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
removeButton = new QPushButton(HistoryDialog);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
hboxLayout->addWidget(removeButton);
removeAllButton = new QPushButton(HistoryDialog);
- removeAllButton->setObjectName(QStringLiteral("removeAllButton"));
+ removeAllButton->setObjectName(QString::fromUtf8("removeAllButton"));
hboxLayout->addWidget(removeAllButton);
@@ -74,7 +74,7 @@ public:
hboxLayout->addItem(spacerItem1);
buttonBox = new QDialogButtonBox(HistoryDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setStandardButtons(QDialogButtonBox::Ok);
hboxLayout->addWidget(buttonBox);
diff --git a/tests/auto/tools/uic/baseline/icontheme.ui.h b/tests/auto/tools/uic/baseline/icontheme.ui.h
index 75a1b648cd..936d6b5cf7 100644
--- a/tests/auto/tools/uic/baseline/icontheme.ui.h
+++ b/tests/auto/tools/uic/baseline/icontheme.ui.h
@@ -29,39 +29,39 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(122, 117);
verticalLayout = new QVBoxLayout(Form);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
fileicon = new QPushButton(Form);
- fileicon->setObjectName(QStringLiteral("fileicon"));
+ fileicon->setObjectName(QString::fromUtf8("fileicon"));
QIcon icon;
- icon.addFile(QStringLiteral("image1.png"), QSize(), QIcon::Normal, QIcon::Off);
+ icon.addFile(QString::fromUtf8("image1.png"), QSize(), QIcon::Normal, QIcon::Off);
fileicon->setIcon(icon);
verticalLayout->addWidget(fileicon);
fileandthemeicon = new QPushButton(Form);
- fileandthemeicon->setObjectName(QStringLiteral("fileandthemeicon"));
+ fileandthemeicon->setObjectName(QString::fromUtf8("fileandthemeicon"));
QIcon icon1;
- QString iconThemeName = QStringLiteral("edit-copy");
+ QString iconThemeName = QString::fromUtf8("edit-copy");
if (QIcon::hasThemeIcon(iconThemeName)) {
icon1 = QIcon::fromTheme(iconThemeName);
} else {
- icon1.addFile(QStringLiteral("image7.png"), QSize(), QIcon::Normal, QIcon::Off);
+ icon1.addFile(QString::fromUtf8("image7.png"), QSize(), QIcon::Normal, QIcon::Off);
}
fileandthemeicon->setIcon(icon1);
verticalLayout->addWidget(fileandthemeicon);
themeicon = new QPushButton(Form);
- themeicon->setObjectName(QStringLiteral("themeicon"));
+ themeicon->setObjectName(QString::fromUtf8("themeicon"));
QIcon icon2;
- iconThemeName = QStringLiteral("edit-copy");
+ iconThemeName = QString::fromUtf8("edit-copy");
if (QIcon::hasThemeIcon(iconThemeName)) {
icon2 = QIcon::fromTheme(iconThemeName);
} else {
- icon2.addFile(QStringLiteral(""), QSize(), QIcon::Normal, QIcon::Off);
+ icon2.addFile(QString::fromUtf8(""), QSize(), QIcon::Normal, QIcon::Off);
}
themeicon->setIcon(icon2);
diff --git a/tests/auto/tools/uic/baseline/idbased.ui.h b/tests/auto/tools/uic/baseline/idbased.ui.h
index dbcd92a839..e246313e11 100644
--- a/tests/auto/tools/uic/baseline/idbased.ui.h
+++ b/tests/auto/tools/uic/baseline/idbased.ui.h
@@ -26,12 +26,12 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(400, 300);
verticalLayout = new QVBoxLayout(Form);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
pushButton = new QPushButton(Form);
- pushButton->setObjectName(QStringLiteral("pushButton"));
+ pushButton->setObjectName(QString::fromUtf8("pushButton"));
verticalLayout->addWidget(pushButton);
diff --git a/tests/auto/tools/uic/baseline/identifierpage.ui.h b/tests/auto/tools/uic/baseline/identifierpage.ui.h
index d16333cc9c..322a9cf30a 100644
--- a/tests/auto/tools/uic/baseline/identifierpage.ui.h
+++ b/tests/auto/tools/uic/baseline/identifierpage.ui.h
@@ -36,16 +36,16 @@ public:
void setupUi(QWidget *IdentifierPage)
{
if (IdentifierPage->objectName().isEmpty())
- IdentifierPage->setObjectName(QStringLiteral("IdentifierPage"));
+ IdentifierPage->setObjectName(QString::fromUtf8("IdentifierPage"));
IdentifierPage->resize(417, 242);
gridLayout = new QGridLayout(IdentifierPage);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
spacerItem = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed);
gridLayout->addItem(spacerItem, 0, 1, 1, 1);
identifierCheckBox = new QCheckBox(IdentifierPage);
- identifierCheckBox->setObjectName(QStringLiteral("identifierCheckBox"));
+ identifierCheckBox->setObjectName(QString::fromUtf8("identifierCheckBox"));
gridLayout->addWidget(identifierCheckBox, 1, 0, 1, 3);
@@ -58,20 +58,20 @@ public:
gridLayout->addItem(spacerItem2, 2, 0, 1, 1);
globalButton = new QRadioButton(IdentifierPage);
- globalButton->setObjectName(QStringLiteral("globalButton"));
+ globalButton->setObjectName(QString::fromUtf8("globalButton"));
globalButton->setEnabled(false);
globalButton->setChecked(true);
gridLayout->addWidget(globalButton, 2, 1, 1, 1);
prefixLineEdit = new QLineEdit(IdentifierPage);
- prefixLineEdit->setObjectName(QStringLiteral("prefixLineEdit"));
+ prefixLineEdit->setObjectName(QString::fromUtf8("prefixLineEdit"));
prefixLineEdit->setEnabled(false);
gridLayout->addWidget(prefixLineEdit, 2, 2, 1, 1);
fileNameButton = new QRadioButton(IdentifierPage);
- fileNameButton->setObjectName(QStringLiteral("fileNameButton"));
+ fileNameButton->setObjectName(QString::fromUtf8("fileNameButton"));
fileNameButton->setEnabled(false);
gridLayout->addWidget(fileNameButton, 3, 1, 1, 2);
diff --git a/tests/auto/tools/uic/baseline/imagedialog.ui.h b/tests/auto/tools/uic/baseline/imagedialog.ui.h
index 29a30d1996..e32e7639fa 100644
--- a/tests/auto/tools/uic/baseline/imagedialog.ui.h
+++ b/tests/auto/tools/uic/baseline/imagedialog.ui.h
@@ -46,8 +46,8 @@ public:
void setupUi(QDialog *dialog)
{
if (dialog->objectName().isEmpty())
- dialog->setObjectName(QStringLiteral("dialog"));
- dialog->setObjectName(QStringLiteral("ImageDialog"));
+ dialog->setObjectName(QString::fromUtf8("dialog"));
+ dialog->setObjectName(QString::fromUtf8("ImageDialog"));
dialog->resize(320, 180);
vboxLayout = new QVBoxLayout(dialog);
#ifndef Q_OS_MAC
@@ -56,17 +56,17 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
- vboxLayout->setObjectName(QStringLiteral(""));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8(""));
gridLayout = new QGridLayout();
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
#endif
gridLayout->setContentsMargins(1, 1, 1, 1);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
- gridLayout->setObjectName(QStringLiteral(""));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8(""));
widthLabel = new QLabel(dialog);
- widthLabel->setObjectName(QStringLiteral("widthLabel"));
+ widthLabel->setObjectName(QString::fromUtf8("widthLabel"));
widthLabel->setGeometry(QRect(1, 27, 67, 22));
widthLabel->setFrameShape(QFrame::NoFrame);
widthLabel->setFrameShadow(QFrame::Plain);
@@ -75,7 +75,7 @@ public:
gridLayout->addWidget(widthLabel, 1, 0, 1, 1);
heightLabel = new QLabel(dialog);
- heightLabel->setObjectName(QStringLiteral("heightLabel"));
+ heightLabel->setObjectName(QString::fromUtf8("heightLabel"));
heightLabel->setGeometry(QRect(1, 55, 67, 22));
heightLabel->setFrameShape(QFrame::NoFrame);
heightLabel->setFrameShadow(QFrame::Plain);
@@ -84,7 +84,7 @@ public:
gridLayout->addWidget(heightLabel, 2, 0, 1, 1);
colorDepthCombo = new QComboBox(dialog);
- colorDepthCombo->setObjectName(QStringLiteral("colorDepthCombo"));
+ colorDepthCombo->setObjectName(QString::fromUtf8("colorDepthCombo"));
colorDepthCombo->setGeometry(QRect(74, 83, 227, 22));
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(0));
sizePolicy.setHorizontalStretch(0);
@@ -96,7 +96,7 @@ public:
gridLayout->addWidget(colorDepthCombo, 3, 1, 1, 1);
nameLineEdit = new QLineEdit(dialog);
- nameLineEdit->setObjectName(QStringLiteral("nameLineEdit"));
+ nameLineEdit->setObjectName(QString::fromUtf8("nameLineEdit"));
nameLineEdit->setGeometry(QRect(74, 83, 227, 22));
QSizePolicy sizePolicy1(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(0));
sizePolicy1.setHorizontalStretch(1);
@@ -108,7 +108,7 @@ public:
gridLayout->addWidget(nameLineEdit, 0, 1, 1, 1);
spinBox = new QSpinBox(dialog);
- spinBox->setObjectName(QStringLiteral("spinBox"));
+ spinBox->setObjectName(QString::fromUtf8("spinBox"));
spinBox->setGeometry(QRect(74, 1, 227, 20));
sizePolicy.setHeightForWidth(spinBox->sizePolicy().hasHeightForWidth());
spinBox->setSizePolicy(sizePolicy);
@@ -120,7 +120,7 @@ public:
gridLayout->addWidget(spinBox, 1, 1, 1, 1);
spinBox_2 = new QSpinBox(dialog);
- spinBox_2->setObjectName(QStringLiteral("spinBox_2"));
+ spinBox_2->setObjectName(QString::fromUtf8("spinBox_2"));
spinBox_2->setGeometry(QRect(74, 27, 227, 22));
sizePolicy.setHeightForWidth(spinBox_2->sizePolicy().hasHeightForWidth());
spinBox_2->setSizePolicy(sizePolicy);
@@ -132,7 +132,7 @@ public:
gridLayout->addWidget(spinBox_2, 2, 1, 1, 1);
nameLabel = new QLabel(dialog);
- nameLabel->setObjectName(QStringLiteral("nameLabel"));
+ nameLabel->setObjectName(QString::fromUtf8("nameLabel"));
nameLabel->setGeometry(QRect(1, 1, 67, 20));
nameLabel->setFrameShape(QFrame::NoFrame);
nameLabel->setFrameShadow(QFrame::Plain);
@@ -141,7 +141,7 @@ public:
gridLayout->addWidget(nameLabel, 0, 0, 1, 1);
colorDepthLabel = new QLabel(dialog);
- colorDepthLabel->setObjectName(QStringLiteral("colorDepthLabel"));
+ colorDepthLabel->setObjectName(QString::fromUtf8("colorDepthLabel"));
colorDepthLabel->setGeometry(QRect(1, 83, 67, 22));
colorDepthLabel->setFrameShape(QFrame::NoFrame);
colorDepthLabel->setFrameShadow(QFrame::Plain);
@@ -161,20 +161,20 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(1, 1, 1, 1);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
- hboxLayout->setObjectName(QStringLiteral(""));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8(""));
spacerItem1 = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(spacerItem1);
okButton = new QPushButton(dialog);
- okButton->setObjectName(QStringLiteral("okButton"));
+ okButton->setObjectName(QString::fromUtf8("okButton"));
okButton->setGeometry(QRect(135, 1, 80, 24));
hboxLayout->addWidget(okButton);
cancelButton = new QPushButton(dialog);
- cancelButton->setObjectName(QStringLiteral("cancelButton"));
+ cancelButton->setObjectName(QString::fromUtf8("cancelButton"));
cancelButton->setGeometry(QRect(221, 1, 80, 24));
hboxLayout->addWidget(cancelButton);
diff --git a/tests/auto/tools/uic/baseline/inputpage.ui.h b/tests/auto/tools/uic/baseline/inputpage.ui.h
index fb7ae1ea6f..9367dec6df 100644
--- a/tests/auto/tools/uic/baseline/inputpage.ui.h
+++ b/tests/auto/tools/uic/baseline/inputpage.ui.h
@@ -35,16 +35,16 @@ public:
void setupUi(QWidget *InputPage)
{
if (InputPage->objectName().isEmpty())
- InputPage->setObjectName(QStringLiteral("InputPage"));
+ InputPage->setObjectName(QString::fromUtf8("InputPage"));
InputPage->resize(417, 242);
gridLayout = new QGridLayout(InputPage);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
spacerItem = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed);
gridLayout->addItem(spacerItem, 0, 2, 1, 1);
label = new QLabel(InputPage);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -55,14 +55,14 @@ public:
hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
fileLineEdit = new QLineEdit(InputPage);
- fileLineEdit->setObjectName(QStringLiteral("fileLineEdit"));
+ fileLineEdit->setObjectName(QString::fromUtf8("fileLineEdit"));
hboxLayout->addWidget(fileLineEdit);
browseButton = new QToolButton(InputPage);
- browseButton->setObjectName(QStringLiteral("browseButton"));
+ browseButton->setObjectName(QString::fromUtf8("browseButton"));
hboxLayout->addWidget(browseButton);
diff --git a/tests/auto/tools/uic/baseline/installdialog.ui.h b/tests/auto/tools/uic/baseline/installdialog.ui.h
index 885488d2a7..3ec7f69b76 100644
--- a/tests/auto/tools/uic/baseline/installdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/installdialog.ui.h
@@ -44,32 +44,32 @@ public:
void setupUi(QDialog *InstallDialog)
{
if (InstallDialog->objectName().isEmpty())
- InstallDialog->setObjectName(QStringLiteral("InstallDialog"));
+ InstallDialog->setObjectName(QString::fromUtf8("InstallDialog"));
InstallDialog->resize(436, 245);
gridLayout = new QGridLayout(InstallDialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(InstallDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 4);
listWidget = new QListWidget(InstallDialog);
- listWidget->setObjectName(QStringLiteral("listWidget"));
+ listWidget->setObjectName(QString::fromUtf8("listWidget"));
gridLayout->addWidget(listWidget, 1, 0, 4, 4);
installButton = new QPushButton(InstallDialog);
- installButton->setObjectName(QStringLiteral("installButton"));
+ installButton->setObjectName(QString::fromUtf8("installButton"));
gridLayout->addWidget(installButton, 1, 4, 1, 1);
cancelButton = new QPushButton(InstallDialog);
- cancelButton->setObjectName(QStringLiteral("cancelButton"));
+ cancelButton->setObjectName(QString::fromUtf8("cancelButton"));
gridLayout->addWidget(cancelButton, 2, 4, 1, 1);
closeButton = new QPushButton(InstallDialog);
- closeButton->setObjectName(QStringLiteral("closeButton"));
+ closeButton->setObjectName(QString::fromUtf8("closeButton"));
gridLayout->addWidget(closeButton, 3, 4, 1, 1);
@@ -78,34 +78,34 @@ public:
gridLayout->addItem(spacerItem, 4, 4, 1, 1);
label_4 = new QLabel(InstallDialog);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
gridLayout->addWidget(label_4, 5, 0, 1, 1);
pathLineEdit = new QLineEdit(InstallDialog);
- pathLineEdit->setObjectName(QStringLiteral("pathLineEdit"));
+ pathLineEdit->setObjectName(QString::fromUtf8("pathLineEdit"));
gridLayout->addWidget(pathLineEdit, 5, 1, 1, 2);
browseButton = new QToolButton(InstallDialog);
- browseButton->setObjectName(QStringLiteral("browseButton"));
+ browseButton->setObjectName(QString::fromUtf8("browseButton"));
gridLayout->addWidget(browseButton, 5, 3, 1, 1);
line = new QFrame(InstallDialog);
- line->setObjectName(QStringLiteral("line"));
+ line->setObjectName(QString::fromUtf8("line"));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
gridLayout->addWidget(line, 6, 0, 1, 5);
statusLabel = new QLabel(InstallDialog);
- statusLabel->setObjectName(QStringLiteral("statusLabel"));
+ statusLabel->setObjectName(QString::fromUtf8("statusLabel"));
gridLayout->addWidget(statusLabel, 7, 0, 1, 2);
progressBar = new QProgressBar(InstallDialog);
- progressBar->setObjectName(QStringLiteral("progressBar"));
+ progressBar->setObjectName(QString::fromUtf8("progressBar"));
progressBar->setValue(0);
progressBar->setOrientation(Qt::Horizontal);
diff --git a/tests/auto/tools/uic/baseline/languagesdialog.ui.h b/tests/auto/tools/uic/baseline/languagesdialog.ui.h
index 6f722a4e74..cf2599fd07 100644
--- a/tests/auto/tools/uic/baseline/languagesdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/languagesdialog.ui.h
@@ -39,50 +39,50 @@ public:
void setupUi(QDialog *LanguagesDialog)
{
if (LanguagesDialog->objectName().isEmpty())
- LanguagesDialog->setObjectName(QStringLiteral("LanguagesDialog"));
+ LanguagesDialog->setObjectName(QString::fromUtf8("LanguagesDialog"));
LanguagesDialog->resize(400, 300);
verticalLayout = new QVBoxLayout(LanguagesDialog);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
languagesList = new QTreeWidget(LanguagesDialog);
- languagesList->setObjectName(QStringLiteral("languagesList"));
+ languagesList->setObjectName(QString::fromUtf8("languagesList"));
languagesList->setIndentation(0);
verticalLayout->addWidget(languagesList);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
upButton = new QToolButton(LanguagesDialog);
- upButton->setObjectName(QStringLiteral("upButton"));
+ upButton->setObjectName(QString::fromUtf8("upButton"));
upButton->setEnabled(false);
QIcon icon;
- icon.addFile(QStringLiteral(":/images/up.png"), QSize(), QIcon::Normal, QIcon::Off);
+ icon.addFile(QString::fromUtf8(":/images/up.png"), QSize(), QIcon::Normal, QIcon::Off);
upButton->setIcon(icon);
hboxLayout->addWidget(upButton);
downButton = new QToolButton(LanguagesDialog);
- downButton->setObjectName(QStringLiteral("downButton"));
+ downButton->setObjectName(QString::fromUtf8("downButton"));
downButton->setEnabled(false);
QIcon icon1;
- icon1.addFile(QStringLiteral(":/images/down.png"), QSize(), QIcon::Normal, QIcon::Off);
+ icon1.addFile(QString::fromUtf8(":/images/down.png"), QSize(), QIcon::Normal, QIcon::Off);
downButton->setIcon(icon1);
hboxLayout->addWidget(downButton);
removeButton = new QToolButton(LanguagesDialog);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
removeButton->setEnabled(false);
QIcon icon2;
- icon2.addFile(QStringLiteral(":/images/editdelete.png"), QSize(), QIcon::Normal, QIcon::Off);
+ icon2.addFile(QString::fromUtf8(":/images/editdelete.png"), QSize(), QIcon::Normal, QIcon::Off);
removeButton->setIcon(icon2);
hboxLayout->addWidget(removeButton);
openFileButton = new QToolButton(LanguagesDialog);
- openFileButton->setObjectName(QStringLiteral("openFileButton"));
+ openFileButton->setObjectName(QString::fromUtf8("openFileButton"));
openFileButton->setEnabled(true);
QIcon icon3;
- icon3.addFile(QStringLiteral(":/images/mac/fileopen.png"), QSize(), QIcon::Normal, QIcon::Off);
+ icon3.addFile(QString::fromUtf8(":/images/mac/fileopen.png"), QSize(), QIcon::Normal, QIcon::Off);
openFileButton->setIcon(icon3);
hboxLayout->addWidget(openFileButton);
@@ -92,7 +92,7 @@ public:
hboxLayout->addItem(spacerItem);
okButton = new QPushButton(LanguagesDialog);
- okButton->setObjectName(QStringLiteral("okButton"));
+ okButton->setObjectName(QString::fromUtf8("okButton"));
hboxLayout->addWidget(okButton);
diff --git a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h
index 06f55dba4c..14067ced18 100644
--- a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h
+++ b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h
@@ -79,7 +79,7 @@ public:
void setupUi(QDialog *qdesigner_internal__ListWidgetEditor)
{
if (qdesigner_internal__ListWidgetEditor->objectName().isEmpty())
- qdesigner_internal__ListWidgetEditor->setObjectName(QStringLiteral("qdesigner_internal__ListWidgetEditor"));
+ qdesigner_internal__ListWidgetEditor->setObjectName(QString::fromUtf8("qdesigner_internal__ListWidgetEditor"));
qdesigner_internal__ListWidgetEditor->resize(223, 245);
vboxLayout = new QVBoxLayout(qdesigner_internal__ListWidgetEditor);
#ifndef Q_OS_MAC
@@ -88,25 +88,25 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(qdesigner_internal__ListWidgetEditor);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
gridLayout = new QGridLayout(groupBox);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
listWidget = new QListWidget(groupBox);
- listWidget->setObjectName(QStringLiteral("listWidget"));
+ listWidget->setObjectName(QString::fromUtf8("listWidget"));
gridLayout->addWidget(listWidget, 0, 0, 1, 1);
horizontalLayout_2 = new QHBoxLayout();
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
newItemButton = new QToolButton(groupBox);
- newItemButton->setObjectName(QStringLiteral("newItemButton"));
+ newItemButton->setObjectName(QString::fromUtf8("newItemButton"));
horizontalLayout_2->addWidget(newItemButton);
deleteItemButton = new QToolButton(groupBox);
- deleteItemButton->setObjectName(QStringLiteral("deleteItemButton"));
+ deleteItemButton->setObjectName(QString::fromUtf8("deleteItemButton"));
horizontalLayout_2->addWidget(deleteItemButton);
@@ -115,12 +115,12 @@ public:
horizontalLayout_2->addItem(spacerItem);
moveItemUpButton = new QToolButton(groupBox);
- moveItemUpButton->setObjectName(QStringLiteral("moveItemUpButton"));
+ moveItemUpButton->setObjectName(QString::fromUtf8("moveItemUpButton"));
horizontalLayout_2->addWidget(moveItemUpButton);
moveItemDownButton = new QToolButton(groupBox);
- moveItemDownButton->setObjectName(QStringLiteral("moveItemDownButton"));
+ moveItemDownButton->setObjectName(QString::fromUtf8("moveItemDownButton"));
horizontalLayout_2->addWidget(moveItemDownButton);
@@ -128,14 +128,14 @@ public:
gridLayout->addLayout(horizontalLayout_2, 1, 0, 1, 1);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
horizontalLayout->addWidget(label);
itemIconSelector = new qdesigner_internal::IconSelector(groupBox);
- itemIconSelector->setObjectName(QStringLiteral("itemIconSelector"));
+ itemIconSelector->setObjectName(QString::fromUtf8("itemIconSelector"));
horizontalLayout->addWidget(itemIconSelector);
@@ -150,7 +150,7 @@ public:
vboxLayout->addWidget(groupBox);
buttonBox = new QDialogButtonBox(qdesigner_internal__ListWidgetEditor);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/mainwindow.ui.h b/tests/auto/tools/uic/baseline/mainwindow.ui.h
index 950040aeed..fe84d0baa3 100644
--- a/tests/auto/tools/uic/baseline/mainwindow.ui.h
+++ b/tests/auto/tools/uic/baseline/mainwindow.ui.h
@@ -86,14 +86,14 @@ public:
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
- MainWindow->setObjectName(QStringLiteral("MainWindow"));
+ MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(829, 813);
actionAdd_Custom_Font = new QAction(MainWindow);
- actionAdd_Custom_Font->setObjectName(QStringLiteral("actionAdd_Custom_Font"));
+ actionAdd_Custom_Font->setObjectName(QString::fromUtf8("actionAdd_Custom_Font"));
action_Exit = new QAction(MainWindow);
- action_Exit->setObjectName(QStringLiteral("action_Exit"));
+ action_Exit->setObjectName(QString::fromUtf8("action_Exit"));
centralwidget = new QWidget(MainWindow);
- centralwidget->setObjectName(QStringLiteral("centralwidget"));
+ centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
vboxLayout = new QVBoxLayout(centralwidget);
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
@@ -101,9 +101,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(centralwidget);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
hboxLayout = new QHBoxLayout(groupBox);
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
@@ -111,40 +111,40 @@ public:
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
hboxLayout->addWidget(label);
fontComboBox = new QFontComboBox(groupBox);
- fontComboBox->setObjectName(QStringLiteral("fontComboBox"));
+ fontComboBox->setObjectName(QString::fromUtf8("fontComboBox"));
hboxLayout->addWidget(fontComboBox);
label_2 = new QLabel(groupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
hboxLayout->addWidget(label_2);
pixelSize = new QSpinBox(groupBox);
- pixelSize->setObjectName(QStringLiteral("pixelSize"));
+ pixelSize->setObjectName(QString::fromUtf8("pixelSize"));
pixelSize->setMinimum(1);
hboxLayout->addWidget(pixelSize);
label_7 = new QLabel(groupBox);
- label_7->setObjectName(QStringLiteral("label_7"));
+ label_7->setObjectName(QString::fromUtf8("label_7"));
hboxLayout->addWidget(label_7);
weightCombo = new QComboBox(groupBox);
- weightCombo->setObjectName(QStringLiteral("weightCombo"));
+ weightCombo->setObjectName(QString::fromUtf8("weightCombo"));
hboxLayout->addWidget(weightCombo);
italic = new QCheckBox(groupBox);
- italic->setObjectName(QStringLiteral("italic"));
+ italic->setObjectName(QString::fromUtf8("italic"));
hboxLayout->addWidget(italic);
@@ -156,7 +156,7 @@ public:
vboxLayout->addWidget(groupBox);
groupBox_2 = new QGroupBox(centralwidget);
- groupBox_2->setObjectName(QStringLiteral("groupBox_2"));
+ groupBox_2->setObjectName(QString::fromUtf8("groupBox_2"));
vboxLayout1 = new QVBoxLayout(groupBox_2);
#ifndef Q_OS_MAC
vboxLayout1->setSpacing(6);
@@ -164,9 +164,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout1->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
chooseFromCodePoints = new QRadioButton(groupBox_2);
- chooseFromCodePoints->setObjectName(QStringLiteral("chooseFromCodePoints"));
+ chooseFromCodePoints->setObjectName(QString::fromUtf8("chooseFromCodePoints"));
chooseFromCodePoints->setChecked(true);
vboxLayout1->addWidget(chooseFromCodePoints);
@@ -176,9 +176,9 @@ public:
vboxLayout2->setSpacing(6);
#endif
vboxLayout2->setContentsMargins(0, 0, 0, 0);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
characterRangeView = new QListWidget(groupBox_2);
- characterRangeView->setObjectName(QStringLiteral("characterRangeView"));
+ characterRangeView->setObjectName(QString::fromUtf8("characterRangeView"));
vboxLayout2->addWidget(characterRangeView);
@@ -187,19 +187,19 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
selectAll = new QPushButton(groupBox_2);
- selectAll->setObjectName(QStringLiteral("selectAll"));
+ selectAll->setObjectName(QString::fromUtf8("selectAll"));
hboxLayout1->addWidget(selectAll);
deselectAll = new QPushButton(groupBox_2);
- deselectAll->setObjectName(QStringLiteral("deselectAll"));
+ deselectAll->setObjectName(QString::fromUtf8("deselectAll"));
hboxLayout1->addWidget(deselectAll);
invertSelection = new QPushButton(groupBox_2);
- invertSelection->setObjectName(QStringLiteral("invertSelection"));
+ invertSelection->setObjectName(QString::fromUtf8("invertSelection"));
hboxLayout1->addWidget(invertSelection);
@@ -214,7 +214,7 @@ public:
vboxLayout1->addLayout(vboxLayout2);
chooseFromSampleFile = new QRadioButton(groupBox_2);
- chooseFromSampleFile->setObjectName(QStringLiteral("chooseFromSampleFile"));
+ chooseFromSampleFile->setObjectName(QString::fromUtf8("chooseFromSampleFile"));
vboxLayout1->addWidget(chooseFromSampleFile);
@@ -223,27 +223,27 @@ public:
hboxLayout2->setSpacing(6);
#endif
hboxLayout2->setContentsMargins(0, 0, 0, 0);
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
label_5 = new QLabel(groupBox_2);
- label_5->setObjectName(QStringLiteral("label_5"));
+ label_5->setObjectName(QString::fromUtf8("label_5"));
label_5->setEnabled(false);
hboxLayout2->addWidget(label_5);
sampleFile = new QLineEdit(groupBox_2);
- sampleFile->setObjectName(QStringLiteral("sampleFile"));
+ sampleFile->setObjectName(QString::fromUtf8("sampleFile"));
sampleFile->setEnabled(false);
hboxLayout2->addWidget(sampleFile);
browseSampleFile = new QPushButton(groupBox_2);
- browseSampleFile->setObjectName(QStringLiteral("browseSampleFile"));
+ browseSampleFile->setObjectName(QString::fromUtf8("browseSampleFile"));
browseSampleFile->setEnabled(false);
hboxLayout2->addWidget(browseSampleFile);
charCount = new QLabel(groupBox_2);
- charCount->setObjectName(QStringLiteral("charCount"));
+ charCount->setObjectName(QString::fromUtf8("charCount"));
charCount->setEnabled(false);
hboxLayout2->addWidget(charCount);
@@ -255,7 +255,7 @@ public:
vboxLayout->addWidget(groupBox_2);
groupBox_3 = new QGroupBox(centralwidget);
- groupBox_3->setObjectName(QStringLiteral("groupBox_3"));
+ groupBox_3->setObjectName(QString::fromUtf8("groupBox_3"));
hboxLayout3 = new QHBoxLayout(groupBox_3);
#ifndef Q_OS_MAC
hboxLayout3->setSpacing(6);
@@ -263,9 +263,9 @@ public:
#ifndef Q_OS_MAC
hboxLayout3->setContentsMargins(9, 9, 9, 9);
#endif
- hboxLayout3->setObjectName(QStringLiteral("hboxLayout3"));
+ hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3"));
preview = new QLineEdit(groupBox_3);
- preview->setObjectName(QStringLiteral("preview"));
+ preview->setObjectName(QString::fromUtf8("preview"));
hboxLayout3->addWidget(preview);
@@ -273,7 +273,7 @@ public:
vboxLayout->addWidget(groupBox_3);
groupBox_4 = new QGroupBox(centralwidget);
- groupBox_4->setObjectName(QStringLiteral("groupBox_4"));
+ groupBox_4->setObjectName(QString::fromUtf8("groupBox_4"));
hboxLayout4 = new QHBoxLayout(groupBox_4);
#ifndef Q_OS_MAC
hboxLayout4->setSpacing(6);
@@ -281,29 +281,29 @@ public:
#ifndef Q_OS_MAC
hboxLayout4->setContentsMargins(9, 9, 9, 9);
#endif
- hboxLayout4->setObjectName(QStringLiteral("hboxLayout4"));
+ hboxLayout4->setObjectName(QString::fromUtf8("hboxLayout4"));
label_3 = new QLabel(groupBox_4);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
hboxLayout4->addWidget(label_3);
path = new QLineEdit(groupBox_4);
- path->setObjectName(QStringLiteral("path"));
+ path->setObjectName(QString::fromUtf8("path"));
hboxLayout4->addWidget(path);
browsePath = new QPushButton(groupBox_4);
- browsePath->setObjectName(QStringLiteral("browsePath"));
+ browsePath->setObjectName(QString::fromUtf8("browsePath"));
hboxLayout4->addWidget(browsePath);
label_4 = new QLabel(groupBox_4);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
hboxLayout4->addWidget(label_4);
fileName = new QLineEdit(groupBox_4);
- fileName->setObjectName(QStringLiteral("fileName"));
+ fileName->setObjectName(QString::fromUtf8("fileName"));
fileName->setEnabled(false);
hboxLayout4->addWidget(fileName);
@@ -316,9 +316,9 @@ public:
hboxLayout5->setSpacing(6);
#endif
hboxLayout5->setContentsMargins(0, 0, 0, 0);
- hboxLayout5->setObjectName(QStringLiteral("hboxLayout5"));
+ hboxLayout5->setObjectName(QString::fromUtf8("hboxLayout5"));
generate = new QPushButton(centralwidget);
- generate->setObjectName(QStringLiteral("generate"));
+ generate->setObjectName(QString::fromUtf8("generate"));
hboxLayout5->addWidget(generate);
@@ -331,13 +331,13 @@ public:
MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
- menubar->setObjectName(QStringLiteral("menubar"));
+ menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 829, 29));
menuFile = new QMenu(menubar);
- menuFile->setObjectName(QStringLiteral("menuFile"));
+ menuFile->setObjectName(QString::fromUtf8("menuFile"));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
- statusbar->setObjectName(QStringLiteral("statusbar"));
+ statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
menubar->addAction(menuFile->menuAction());
diff --git a/tests/auto/tools/uic/baseline/mydialog.ui.h b/tests/auto/tools/uic/baseline/mydialog.ui.h
index 95864d5195..1a784d1b0a 100644
--- a/tests/auto/tools/uic/baseline/mydialog.ui.h
+++ b/tests/auto/tools/uic/baseline/mydialog.ui.h
@@ -28,7 +28,7 @@ public:
void setupUi(QDialog *MyDialog)
{
if (MyDialog->objectName().isEmpty())
- MyDialog->setObjectName(QStringLiteral("MyDialog"));
+ MyDialog->setObjectName(QString::fromUtf8("MyDialog"));
MyDialog->resize(401, 70);
vboxLayout = new QVBoxLayout(MyDialog);
#ifndef Q_OS_MAC
@@ -37,14 +37,14 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
aLabel = new QLabel(MyDialog);
- aLabel->setObjectName(QStringLiteral("aLabel"));
+ aLabel->setObjectName(QString::fromUtf8("aLabel"));
vboxLayout->addWidget(aLabel);
aButton = new QPushButton(MyDialog);
- aButton->setObjectName(QStringLiteral("aButton"));
+ aButton->setObjectName(QString::fromUtf8("aButton"));
vboxLayout->addWidget(aButton);
diff --git a/tests/auto/tools/uic/baseline/myform.ui.h b/tests/auto/tools/uic/baseline/myform.ui.h
index d52c1ecf75..d3a08e04c9 100644
--- a/tests/auto/tools/uic/baseline/myform.ui.h
+++ b/tests/auto/tools/uic/baseline/myform.ui.h
@@ -41,35 +41,35 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(258, 224);
vboxLayout = new QVBoxLayout(Form);
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(8, 8, 8, 8);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(Form);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
gridLayout = new QGridLayout(groupBox);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
#endif
gridLayout->setContentsMargins(8, 8, 8, 8);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
radioButton_2 = new QRadioButton(groupBox);
- radioButton_2->setObjectName(QStringLiteral("radioButton_2"));
+ radioButton_2->setObjectName(QString::fromUtf8("radioButton_2"));
gridLayout->addWidget(radioButton_2, 1, 0, 1, 1);
radioButton = new QRadioButton(groupBox);
- radioButton->setObjectName(QStringLiteral("radioButton"));
+ radioButton->setObjectName(QString::fromUtf8("radioButton"));
radioButton->setChecked(true);
gridLayout->addWidget(radioButton, 0, 0, 1, 1);
checkBox_2 = new QCheckBox(groupBox);
- checkBox_2->setObjectName(QStringLiteral("checkBox_2"));
+ checkBox_2->setObjectName(QString::fromUtf8("checkBox_2"));
checkBox_2->setChecked(true);
gridLayout->addWidget(checkBox_2, 1, 1, 1, 1);
@@ -79,32 +79,32 @@ public:
gridLayout->addItem(spacerItem, 5, 0, 1, 1);
checkBox = new QCheckBox(groupBox);
- checkBox->setObjectName(QStringLiteral("checkBox"));
+ checkBox->setObjectName(QString::fromUtf8("checkBox"));
gridLayout->addWidget(checkBox, 0, 1, 1, 1);
radioButton_2_2 = new QRadioButton(groupBox);
- radioButton_2_2->setObjectName(QStringLiteral("radioButton_2_2"));
+ radioButton_2_2->setObjectName(QString::fromUtf8("radioButton_2_2"));
gridLayout->addWidget(radioButton_2_2, 2, 0, 1, 1);
radioButton_3 = new QRadioButton(groupBox);
- radioButton_3->setObjectName(QStringLiteral("radioButton_3"));
+ radioButton_3->setObjectName(QString::fromUtf8("radioButton_3"));
gridLayout->addWidget(radioButton_3, 3, 0, 1, 1);
radioButton_4 = new QRadioButton(groupBox);
- radioButton_4->setObjectName(QStringLiteral("radioButton_4"));
+ radioButton_4->setObjectName(QString::fromUtf8("radioButton_4"));
gridLayout->addWidget(radioButton_4, 4, 0, 1, 1);
checkBox_3 = new QCheckBox(groupBox);
- checkBox_3->setObjectName(QStringLiteral("checkBox_3"));
+ checkBox_3->setObjectName(QString::fromUtf8("checkBox_3"));
gridLayout->addWidget(checkBox_3, 2, 1, 1, 1);
checkBox_4 = new QCheckBox(groupBox);
- checkBox_4->setObjectName(QStringLiteral("checkBox_4"));
+ checkBox_4->setObjectName(QString::fromUtf8("checkBox_4"));
checkBox_4->setChecked(true);
gridLayout->addWidget(checkBox_4, 3, 1, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/newactiondialog.ui.h b/tests/auto/tools/uic/baseline/newactiondialog.ui.h
index 993ff456b8..ca99ab8356 100644
--- a/tests/auto/tools/uic/baseline/newactiondialog.ui.h
+++ b/tests/auto/tools/uic/baseline/newactiondialog.ui.h
@@ -76,42 +76,42 @@ public:
void setupUi(QDialog *qdesigner_internal__NewActionDialog)
{
if (qdesigner_internal__NewActionDialog->objectName().isEmpty())
- qdesigner_internal__NewActionDialog->setObjectName(QStringLiteral("qdesigner_internal__NewActionDialog"));
+ qdesigner_internal__NewActionDialog->setObjectName(QString::fromUtf8("qdesigner_internal__NewActionDialog"));
qdesigner_internal__NewActionDialog->resize(363, 156);
verticalLayout = new QVBoxLayout(qdesigner_internal__NewActionDialog);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
formLayout = new QFormLayout();
- formLayout->setObjectName(QStringLiteral("formLayout"));
+ formLayout->setObjectName(QString::fromUtf8("formLayout"));
label = new QLabel(qdesigner_internal__NewActionDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
formLayout->setWidget(0, QFormLayout::LabelRole, label);
editActionText = new QLineEdit(qdesigner_internal__NewActionDialog);
- editActionText->setObjectName(QStringLiteral("editActionText"));
+ editActionText->setObjectName(QString::fromUtf8("editActionText"));
editActionText->setMinimumSize(QSize(255, 0));
formLayout->setWidget(0, QFormLayout::FieldRole, editActionText);
label_3 = new QLabel(qdesigner_internal__NewActionDialog);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
formLayout->setWidget(1, QFormLayout::LabelRole, label_3);
editObjectName = new QLineEdit(qdesigner_internal__NewActionDialog);
- editObjectName->setObjectName(QStringLiteral("editObjectName"));
+ editObjectName->setObjectName(QString::fromUtf8("editObjectName"));
formLayout->setWidget(1, QFormLayout::FieldRole, editObjectName);
label_2 = new QLabel(qdesigner_internal__NewActionDialog);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
formLayout->setWidget(2, QFormLayout::LabelRole, label_2);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
iconSelector = new qdesigner_internal::IconSelector(qdesigner_internal__NewActionDialog);
- iconSelector->setObjectName(QStringLiteral("iconSelector"));
+ iconSelector->setObjectName(QString::fromUtf8("iconSelector"));
horizontalLayout->addWidget(iconSelector);
@@ -130,14 +130,14 @@ public:
verticalLayout->addItem(verticalSpacer);
line = new QFrame(qdesigner_internal__NewActionDialog);
- line->setObjectName(QStringLiteral("line"));
+ line->setObjectName(QString::fromUtf8("line"));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
verticalLayout->addWidget(line);
buttonBox = new QDialogButtonBox(qdesigner_internal__NewActionDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h b/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h
index d0279cf21f..f5fd6f1fa4 100644
--- a/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h
+++ b/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h
@@ -42,20 +42,20 @@ public:
void setupUi(QDialog *qdesigner_internal__NewDynamicPropertyDialog)
{
if (qdesigner_internal__NewDynamicPropertyDialog->objectName().isEmpty())
- qdesigner_internal__NewDynamicPropertyDialog->setObjectName(QStringLiteral("qdesigner_internal__NewDynamicPropertyDialog"));
+ qdesigner_internal__NewDynamicPropertyDialog->setObjectName(QString::fromUtf8("qdesigner_internal__NewDynamicPropertyDialog"));
qdesigner_internal__NewDynamicPropertyDialog->resize(340, 118);
verticalLayout = new QVBoxLayout(qdesigner_internal__NewDynamicPropertyDialog);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
formLayout = new QFormLayout();
- formLayout->setObjectName(QStringLiteral("formLayout"));
+ formLayout->setObjectName(QString::fromUtf8("formLayout"));
m_lineEdit = new QLineEdit(qdesigner_internal__NewDynamicPropertyDialog);
- m_lineEdit->setObjectName(QStringLiteral("m_lineEdit"));
+ m_lineEdit->setObjectName(QString::fromUtf8("m_lineEdit"));
m_lineEdit->setMinimumSize(QSize(220, 0));
formLayout->setWidget(0, QFormLayout::FieldRole, m_lineEdit);
label = new QLabel(qdesigner_internal__NewDynamicPropertyDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -65,9 +65,9 @@ public:
formLayout->setWidget(0, QFormLayout::LabelRole, label);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
m_comboBox = new QComboBox(qdesigner_internal__NewDynamicPropertyDialog);
- m_comboBox->setObjectName(QStringLiteral("m_comboBox"));
+ m_comboBox->setObjectName(QString::fromUtf8("m_comboBox"));
horizontalLayout->addWidget(m_comboBox);
@@ -79,7 +79,7 @@ public:
formLayout->setLayout(1, QFormLayout::FieldRole, horizontalLayout);
label_2 = new QLabel(qdesigner_internal__NewDynamicPropertyDialog);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
sizePolicy.setHeightForWidth(label_2->sizePolicy().hasHeightForWidth());
label_2->setSizePolicy(sizePolicy);
@@ -93,7 +93,7 @@ public:
verticalLayout->addItem(spacerItem);
m_buttonBox = new QDialogButtonBox(qdesigner_internal__NewDynamicPropertyDialog);
- m_buttonBox->setObjectName(QStringLiteral("m_buttonBox"));
+ m_buttonBox->setObjectName(QString::fromUtf8("m_buttonBox"));
m_buttonBox->setOrientation(Qt::Horizontal);
m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
m_buttonBox->setCenterButtons(false);
diff --git a/tests/auto/tools/uic/baseline/newform.ui.h b/tests/auto/tools/uic/baseline/newform.ui.h
index 26da1b6fc2..80e70dcf66 100644
--- a/tests/auto/tools/uic/baseline/newform.ui.h
+++ b/tests/auto/tools/uic/baseline/newform.ui.h
@@ -67,7 +67,7 @@ public:
void setupUi(QDialog *NewForm)
{
if (NewForm->objectName().isEmpty())
- NewForm->setObjectName(QStringLiteral("NewForm"));
+ NewForm->setObjectName(QString::fromUtf8("NewForm"));
NewForm->resize(495, 319);
vboxLayout = new QVBoxLayout(NewForm);
#ifndef Q_OS_MAC
@@ -76,15 +76,15 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
hboxLayout = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(1, 1, 1, 1);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
treeWidget = new QTreeWidget(NewForm);
- treeWidget->setObjectName(QStringLiteral("treeWidget"));
+ treeWidget->setObjectName(QString::fromUtf8("treeWidget"));
treeWidget->setIconSize(QSize(128, 128));
treeWidget->setRootIsDecorated(false);
treeWidget->setColumnCount(1);
@@ -92,7 +92,7 @@ public:
hboxLayout->addWidget(treeWidget);
lblPreview = new QLabel(NewForm);
- lblPreview->setObjectName(QStringLiteral("lblPreview"));
+ lblPreview->setObjectName(QString::fromUtf8("lblPreview"));
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(7), static_cast<QSizePolicy::Policy>(5));
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -108,19 +108,19 @@ public:
vboxLayout->addLayout(hboxLayout);
horizontalLine = new QFrame(NewForm);
- horizontalLine->setObjectName(QStringLiteral("horizontalLine"));
+ horizontalLine->setObjectName(QString::fromUtf8("horizontalLine"));
horizontalLine->setFrameShape(QFrame::HLine);
horizontalLine->setFrameShadow(QFrame::Sunken);
vboxLayout->addWidget(horizontalLine);
chkShowOnStartup = new QCheckBox(NewForm);
- chkShowOnStartup->setObjectName(QStringLiteral("chkShowOnStartup"));
+ chkShowOnStartup->setObjectName(QString::fromUtf8("chkShowOnStartup"));
vboxLayout->addWidget(chkShowOnStartup);
buttonBox = new QDialogButtonBox(NewForm);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
vboxLayout->addWidget(buttonBox);
diff --git a/tests/auto/tools/uic/baseline/orderdialog.ui.h b/tests/auto/tools/uic/baseline/orderdialog.ui.h
index e2b9762510..0ee08257f4 100644
--- a/tests/auto/tools/uic/baseline/orderdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/orderdialog.ui.h
@@ -70,18 +70,18 @@ public:
void setupUi(QDialog *qdesigner_internal__OrderDialog)
{
if (qdesigner_internal__OrderDialog->objectName().isEmpty())
- qdesigner_internal__OrderDialog->setObjectName(QStringLiteral("qdesigner_internal__OrderDialog"));
+ qdesigner_internal__OrderDialog->setObjectName(QString::fromUtf8("qdesigner_internal__OrderDialog"));
qdesigner_internal__OrderDialog->resize(467, 310);
vboxLayout = new QVBoxLayout(qdesigner_internal__OrderDialog);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(qdesigner_internal__OrderDialog);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
hboxLayout = new QHBoxLayout(groupBox);
hboxLayout->setSpacing(6);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
hboxLayout->setContentsMargins(9, 9, 9, 9);
pageList = new QListWidget(groupBox);
- pageList->setObjectName(QStringLiteral("pageList"));
+ pageList->setObjectName(QString::fromUtf8("pageList"));
pageList->setMinimumSize(QSize(344, 0));
pageList->setDragDropMode(QAbstractItemView::InternalMove);
pageList->setSelectionMode(QAbstractItemView::ContiguousSelection);
@@ -91,15 +91,15 @@ public:
vboxLayout1 = new QVBoxLayout();
vboxLayout1->setSpacing(6);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
vboxLayout1->setContentsMargins(0, 0, 0, 0);
upButton = new QToolButton(groupBox);
- upButton->setObjectName(QStringLiteral("upButton"));
+ upButton->setObjectName(QString::fromUtf8("upButton"));
vboxLayout1->addWidget(upButton);
downButton = new QToolButton(groupBox);
- downButton->setObjectName(QStringLiteral("downButton"));
+ downButton->setObjectName(QString::fromUtf8("downButton"));
vboxLayout1->addWidget(downButton);
@@ -114,7 +114,7 @@ public:
vboxLayout->addWidget(groupBox);
buttonBox = new QDialogButtonBox(qdesigner_internal__OrderDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset);
diff --git a/tests/auto/tools/uic/baseline/outputpage.ui.h b/tests/auto/tools/uic/baseline/outputpage.ui.h
index 1024ba1c19..00491bb3d8 100644
--- a/tests/auto/tools/uic/baseline/outputpage.ui.h
+++ b/tests/auto/tools/uic/baseline/outputpage.ui.h
@@ -33,16 +33,16 @@ public:
void setupUi(QWidget *OutputPage)
{
if (OutputPage->objectName().isEmpty())
- OutputPage->setObjectName(QStringLiteral("OutputPage"));
+ OutputPage->setObjectName(QString::fromUtf8("OutputPage"));
OutputPage->resize(417, 242);
gridLayout = new QGridLayout(OutputPage);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
spacerItem = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed);
gridLayout->addItem(spacerItem, 0, 1, 1, 1);
label = new QLabel(OutputPage);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -52,7 +52,7 @@ public:
gridLayout->addWidget(label, 1, 0, 1, 1);
projectLineEdit = new QLineEdit(OutputPage);
- projectLineEdit->setObjectName(QStringLiteral("projectLineEdit"));
+ projectLineEdit->setObjectName(QString::fromUtf8("projectLineEdit"));
QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -62,14 +62,14 @@ public:
gridLayout->addWidget(projectLineEdit, 1, 1, 1, 1);
label_2 = new QLabel(OutputPage);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
sizePolicy.setHeightForWidth(label_2->sizePolicy().hasHeightForWidth());
label_2->setSizePolicy(sizePolicy);
gridLayout->addWidget(label_2, 2, 0, 1, 1);
collectionLineEdit = new QLineEdit(OutputPage);
- collectionLineEdit->setObjectName(QStringLiteral("collectionLineEdit"));
+ collectionLineEdit->setObjectName(QString::fromUtf8("collectionLineEdit"));
sizePolicy1.setHeightForWidth(collectionLineEdit->sizePolicy().hasHeightForWidth());
collectionLineEdit->setSizePolicy(sizePolicy1);
diff --git a/tests/auto/tools/uic/baseline/pagefold.ui.h b/tests/auto/tools/uic/baseline/pagefold.ui.h
index c0ec214e85..c1ff03648d 100644
--- a/tests/auto/tools/uic/baseline/pagefold.ui.h
+++ b/tests/auto/tools/uic/baseline/pagefold.ui.h
@@ -67,18 +67,18 @@ public:
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
- MainWindow->setObjectName(QStringLiteral("MainWindow"));
+ MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(392, 412);
exitAction = new QAction(MainWindow);
- exitAction->setObjectName(QStringLiteral("exitAction"));
+ exitAction->setObjectName(QString::fromUtf8("exitAction"));
aboutQtAction = new QAction(MainWindow);
- aboutQtAction->setObjectName(QStringLiteral("aboutQtAction"));
+ aboutQtAction->setObjectName(QString::fromUtf8("aboutQtAction"));
editStyleAction = new QAction(MainWindow);
- editStyleAction->setObjectName(QStringLiteral("editStyleAction"));
+ editStyleAction->setObjectName(QString::fromUtf8("editStyleAction"));
aboutAction = new QAction(MainWindow);
- aboutAction->setObjectName(QStringLiteral("aboutAction"));
+ aboutAction->setObjectName(QString::fromUtf8("aboutAction"));
centralwidget = new QWidget(MainWindow);
- centralwidget->setObjectName(QStringLiteral("centralwidget"));
+ centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
vboxLayout = new QVBoxLayout(centralwidget);
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
@@ -86,9 +86,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
mainFrame = new QFrame(centralwidget);
- mainFrame->setObjectName(QStringLiteral("mainFrame"));
+ mainFrame->setObjectName(QString::fromUtf8("mainFrame"));
mainFrame->setFrameShape(QFrame::StyledPanel);
mainFrame->setFrameShadow(QFrame::Raised);
gridLayout = new QGridLayout(mainFrame);
@@ -98,13 +98,13 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
nameCombo = new QComboBox(mainFrame);
nameCombo->addItem(QString());
nameCombo->addItem(QString());
nameCombo->addItem(QString());
nameCombo->addItem(QString());
- nameCombo->setObjectName(QStringLiteral("nameCombo"));
+ nameCombo->setObjectName(QString::fromUtf8("nameCombo"));
nameCombo->setEditable(true);
gridLayout->addWidget(nameCombo, 0, 1, 1, 3);
@@ -114,56 +114,56 @@ public:
gridLayout->addItem(spacerItem, 1, 3, 1, 1);
femaleRadioButton = new QRadioButton(mainFrame);
- femaleRadioButton->setObjectName(QStringLiteral("femaleRadioButton"));
+ femaleRadioButton->setObjectName(QString::fromUtf8("femaleRadioButton"));
gridLayout->addWidget(femaleRadioButton, 1, 2, 1, 1);
genderLabel = new QLabel(mainFrame);
- genderLabel->setObjectName(QStringLiteral("genderLabel"));
+ genderLabel->setObjectName(QString::fromUtf8("genderLabel"));
gridLayout->addWidget(genderLabel, 1, 0, 1, 1);
ageLabel = new QLabel(mainFrame);
- ageLabel->setObjectName(QStringLiteral("ageLabel"));
+ ageLabel->setObjectName(QString::fromUtf8("ageLabel"));
gridLayout->addWidget(ageLabel, 2, 0, 1, 1);
maleRadioButton = new QRadioButton(mainFrame);
- maleRadioButton->setObjectName(QStringLiteral("maleRadioButton"));
+ maleRadioButton->setObjectName(QString::fromUtf8("maleRadioButton"));
gridLayout->addWidget(maleRadioButton, 1, 1, 1, 1);
nameLabel = new QLabel(mainFrame);
- nameLabel->setObjectName(QStringLiteral("nameLabel"));
+ nameLabel->setObjectName(QString::fromUtf8("nameLabel"));
gridLayout->addWidget(nameLabel, 0, 0, 1, 1);
passwordLabel = new QLabel(mainFrame);
- passwordLabel->setObjectName(QStringLiteral("passwordLabel"));
+ passwordLabel->setObjectName(QString::fromUtf8("passwordLabel"));
gridLayout->addWidget(passwordLabel, 3, 0, 1, 1);
ageSpinBox = new QSpinBox(mainFrame);
- ageSpinBox->setObjectName(QStringLiteral("ageSpinBox"));
+ ageSpinBox->setObjectName(QString::fromUtf8("ageSpinBox"));
ageSpinBox->setMinimum(12);
ageSpinBox->setValue(22);
gridLayout->addWidget(ageSpinBox, 2, 1, 1, 3);
buttonBox = new QDialogButtonBox(mainFrame);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
gridLayout->addWidget(buttonBox, 7, 2, 1, 2);
agreeCheckBox = new QCheckBox(mainFrame);
- agreeCheckBox->setObjectName(QStringLiteral("agreeCheckBox"));
+ agreeCheckBox->setObjectName(QString::fromUtf8("agreeCheckBox"));
gridLayout->addWidget(agreeCheckBox, 6, 0, 1, 4);
passwordEdit = new QLineEdit(mainFrame);
- passwordEdit->setObjectName(QStringLiteral("passwordEdit"));
+ passwordEdit->setObjectName(QString::fromUtf8("passwordEdit"));
passwordEdit->setEchoMode(QLineEdit::Password);
gridLayout->addWidget(passwordEdit, 3, 1, 1, 3);
@@ -172,12 +172,12 @@ public:
new QListWidgetItem(professionList);
new QListWidgetItem(professionList);
new QListWidgetItem(professionList);
- professionList->setObjectName(QStringLiteral("professionList"));
+ professionList->setObjectName(QString::fromUtf8("professionList"));
gridLayout->addWidget(professionList, 5, 1, 1, 3);
label = new QLabel(mainFrame);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 5, 0, 1, 1);
@@ -189,12 +189,12 @@ public:
countryCombo->addItem(QString());
countryCombo->addItem(QString());
countryCombo->addItem(QString());
- countryCombo->setObjectName(QStringLiteral("countryCombo"));
+ countryCombo->setObjectName(QString::fromUtf8("countryCombo"));
gridLayout->addWidget(countryCombo, 4, 1, 1, 3);
countryLabel = new QLabel(mainFrame);
- countryLabel->setObjectName(QStringLiteral("countryLabel"));
+ countryLabel->setObjectName(QString::fromUtf8("countryLabel"));
gridLayout->addWidget(countryLabel, 4, 0, 1, 1);
@@ -203,15 +203,15 @@ public:
MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
- menubar->setObjectName(QStringLiteral("menubar"));
+ menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 392, 25));
menu_File = new QMenu(menubar);
- menu_File->setObjectName(QStringLiteral("menu_File"));
+ menu_File->setObjectName(QString::fromUtf8("menu_File"));
menu_Help = new QMenu(menubar);
- menu_Help->setObjectName(QStringLiteral("menu_Help"));
+ menu_Help->setObjectName(QString::fromUtf8("menu_Help"));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
- statusbar->setObjectName(QStringLiteral("statusbar"));
+ statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
#ifndef QT_NO_SHORTCUT
ageLabel->setBuddy(ageSpinBox);
diff --git a/tests/auto/tools/uic/baseline/paletteeditor.ui.h b/tests/auto/tools/uic/baseline/paletteeditor.ui.h
index 3ccdf6082d..0061164960 100644
--- a/tests/auto/tools/uic/baseline/paletteeditor.ui.h
+++ b/tests/auto/tools/uic/baseline/paletteeditor.ui.h
@@ -79,7 +79,7 @@ public:
void setupUi(QDialog *qdesigner_internal__PaletteEditor)
{
if (qdesigner_internal__PaletteEditor->objectName().isEmpty())
- qdesigner_internal__PaletteEditor->setObjectName(QStringLiteral("qdesigner_internal__PaletteEditor"));
+ qdesigner_internal__PaletteEditor->setObjectName(QString::fromUtf8("qdesigner_internal__PaletteEditor"));
qdesigner_internal__PaletteEditor->resize(365, 409);
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(7), static_cast<QSizePolicy::Policy>(7));
sizePolicy.setHorizontalStretch(0);
@@ -93,9 +93,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
advancedBox = new QGroupBox(qdesigner_internal__PaletteEditor);
- advancedBox->setObjectName(QStringLiteral("advancedBox"));
+ advancedBox->setObjectName(QString::fromUtf8("advancedBox"));
advancedBox->setMinimumSize(QSize(0, 0));
advancedBox->setMaximumSize(QSize(16777215, 16777215));
gridLayout = new QGridLayout(advancedBox);
@@ -105,9 +105,9 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
buildButton = new QtColorButton(advancedBox);
- buildButton->setObjectName(QStringLiteral("buildButton"));
+ buildButton->setObjectName(QString::fromUtf8("buildButton"));
QSizePolicy sizePolicy1(static_cast<QSizePolicy::Policy>(7), static_cast<QSizePolicy::Policy>(13));
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -117,24 +117,24 @@ public:
gridLayout->addWidget(buildButton, 0, 1, 1, 1);
paletteView = new QTreeView(advancedBox);
- paletteView->setObjectName(QStringLiteral("paletteView"));
+ paletteView->setObjectName(QString::fromUtf8("paletteView"));
paletteView->setMinimumSize(QSize(0, 200));
gridLayout->addWidget(paletteView, 1, 0, 1, 4);
detailsRadio = new QRadioButton(advancedBox);
- detailsRadio->setObjectName(QStringLiteral("detailsRadio"));
+ detailsRadio->setObjectName(QString::fromUtf8("detailsRadio"));
gridLayout->addWidget(detailsRadio, 0, 3, 1, 1);
computeRadio = new QRadioButton(advancedBox);
- computeRadio->setObjectName(QStringLiteral("computeRadio"));
+ computeRadio->setObjectName(QString::fromUtf8("computeRadio"));
computeRadio->setChecked(true);
gridLayout->addWidget(computeRadio, 0, 2, 1, 1);
label = new QLabel(advancedBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
@@ -142,7 +142,7 @@ public:
vboxLayout->addWidget(advancedBox);
GroupBox126 = new QGroupBox(qdesigner_internal__PaletteEditor);
- GroupBox126->setObjectName(QStringLiteral("GroupBox126"));
+ GroupBox126->setObjectName(QString::fromUtf8("GroupBox126"));
QSizePolicy sizePolicy2(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(7));
sizePolicy2.setHorizontalStretch(0);
sizePolicy2.setVerticalStretch(0);
@@ -153,25 +153,25 @@ public:
gridLayout1->setSpacing(6);
#endif
gridLayout1->setContentsMargins(8, 8, 8, 8);
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
disabledRadio = new QRadioButton(GroupBox126);
- disabledRadio->setObjectName(QStringLiteral("disabledRadio"));
+ disabledRadio->setObjectName(QString::fromUtf8("disabledRadio"));
gridLayout1->addWidget(disabledRadio, 0, 2, 1, 1);
inactiveRadio = new QRadioButton(GroupBox126);
- inactiveRadio->setObjectName(QStringLiteral("inactiveRadio"));
+ inactiveRadio->setObjectName(QString::fromUtf8("inactiveRadio"));
gridLayout1->addWidget(inactiveRadio, 0, 1, 1, 1);
activeRadio = new QRadioButton(GroupBox126);
- activeRadio->setObjectName(QStringLiteral("activeRadio"));
+ activeRadio->setObjectName(QString::fromUtf8("activeRadio"));
activeRadio->setChecked(true);
gridLayout1->addWidget(activeRadio, 0, 0, 1, 1);
previewFrame = new qdesigner_internal::PreviewFrame(GroupBox126);
- previewFrame->setObjectName(QStringLiteral("previewFrame"));
+ previewFrame->setObjectName(QString::fromUtf8("previewFrame"));
sizePolicy.setHeightForWidth(previewFrame->sizePolicy().hasHeightForWidth());
previewFrame->setSizePolicy(sizePolicy);
@@ -181,7 +181,7 @@ public:
vboxLayout->addWidget(GroupBox126);
buttonBox = new QDialogButtonBox(qdesigner_internal__PaletteEditor);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/passworddialog.ui.h b/tests/auto/tools/uic/baseline/passworddialog.ui.h
index d47835b57b..9ab95c4de9 100644
--- a/tests/auto/tools/uic/baseline/passworddialog.ui.h
+++ b/tests/auto/tools/uic/baseline/passworddialog.ui.h
@@ -36,19 +36,19 @@ public:
void setupUi(QDialog *PasswordDialog)
{
if (PasswordDialog->objectName().isEmpty())
- PasswordDialog->setObjectName(QStringLiteral("PasswordDialog"));
+ PasswordDialog->setObjectName(QString::fromUtf8("PasswordDialog"));
PasswordDialog->resize(399, 148);
gridLayout = new QGridLayout(PasswordDialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
iconLabel = new QLabel(PasswordDialog);
- iconLabel->setObjectName(QStringLiteral("iconLabel"));
+ iconLabel->setObjectName(QString::fromUtf8("iconLabel"));
hboxLayout->addWidget(iconLabel);
introLabel = new QLabel(PasswordDialog);
- introLabel->setObjectName(QStringLiteral("introLabel"));
+ introLabel->setObjectName(QString::fromUtf8("introLabel"));
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -61,28 +61,28 @@ public:
gridLayout->addLayout(hboxLayout, 0, 0, 1, 2);
label = new QLabel(PasswordDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 1, 0, 1, 1);
userNameLineEdit = new QLineEdit(PasswordDialog);
- userNameLineEdit->setObjectName(QStringLiteral("userNameLineEdit"));
+ userNameLineEdit->setObjectName(QString::fromUtf8("userNameLineEdit"));
gridLayout->addWidget(userNameLineEdit, 1, 1, 1, 1);
lblPassword = new QLabel(PasswordDialog);
- lblPassword->setObjectName(QStringLiteral("lblPassword"));
+ lblPassword->setObjectName(QString::fromUtf8("lblPassword"));
gridLayout->addWidget(lblPassword, 2, 0, 1, 1);
passwordLineEdit = new QLineEdit(PasswordDialog);
- passwordLineEdit->setObjectName(QStringLiteral("passwordLineEdit"));
+ passwordLineEdit->setObjectName(QString::fromUtf8("passwordLineEdit"));
passwordLineEdit->setEchoMode(QLineEdit::Password);
gridLayout->addWidget(passwordLineEdit, 2, 1, 1, 1);
buttonBox = new QDialogButtonBox(PasswordDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/pathpage.ui.h b/tests/auto/tools/uic/baseline/pathpage.ui.h
index 361831721b..eb151f9550 100644
--- a/tests/auto/tools/uic/baseline/pathpage.ui.h
+++ b/tests/auto/tools/uic/baseline/pathpage.ui.h
@@ -38,12 +38,12 @@ public:
void setupUi(QWidget *PathPage)
{
if (PathPage->objectName().isEmpty())
- PathPage->setObjectName(QStringLiteral("PathPage"));
+ PathPage->setObjectName(QString::fromUtf8("PathPage"));
PathPage->resize(417, 243);
gridLayout = new QGridLayout(PathPage);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label_2 = new QLabel(PathPage);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -53,7 +53,7 @@ public:
gridLayout->addWidget(label_2, 0, 0, 1, 1);
filterLineEdit = new QLineEdit(PathPage);
- filterLineEdit->setObjectName(QStringLiteral("filterLineEdit"));
+ filterLineEdit->setObjectName(QString::fromUtf8("filterLineEdit"));
gridLayout->addWidget(filterLineEdit, 0, 1, 1, 2);
@@ -62,17 +62,17 @@ public:
gridLayout->addItem(spacerItem, 1, 1, 1, 1);
label = new QLabel(PathPage);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 2, 0, 1, 3);
pathListWidget = new QListWidget(PathPage);
- pathListWidget->setObjectName(QStringLiteral("pathListWidget"));
+ pathListWidget->setObjectName(QString::fromUtf8("pathListWidget"));
gridLayout->addWidget(pathListWidget, 3, 0, 3, 3);
addButton = new QPushButton(PathPage);
- addButton->setObjectName(QStringLiteral("addButton"));
+ addButton->setObjectName(QString::fromUtf8("addButton"));
QSizePolicy sizePolicy1(QSizePolicy::Maximum, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -82,7 +82,7 @@ public:
gridLayout->addWidget(addButton, 3, 3, 1, 1);
removeButton = new QPushButton(PathPage);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
sizePolicy1.setHeightForWidth(removeButton->sizePolicy().hasHeightForWidth());
removeButton->setSizePolicy(sizePolicy1);
diff --git a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h
index e41a7061b4..27a0fa79ed 100644
--- a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h
+++ b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h
@@ -77,45 +77,45 @@ public:
void setupUi(QDialog *PhraseBookBox)
{
if (PhraseBookBox->objectName().isEmpty())
- PhraseBookBox->setObjectName(QStringLiteral("PhraseBookBox"));
+ PhraseBookBox->setObjectName(QString::fromUtf8("PhraseBookBox"));
PhraseBookBox->resize(596, 454);
unnamed = new QHBoxLayout(PhraseBookBox);
unnamed->setSpacing(6);
unnamed->setContentsMargins(11, 11, 11, 11);
- unnamed->setObjectName(QStringLiteral("unnamed"));
+ unnamed->setObjectName(QString::fromUtf8("unnamed"));
inputsLayout = new QVBoxLayout();
inputsLayout->setSpacing(6);
- inputsLayout->setObjectName(QStringLiteral("inputsLayout"));
+ inputsLayout->setObjectName(QString::fromUtf8("inputsLayout"));
gridLayout = new QGridLayout();
gridLayout->setSpacing(6);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
target = new QLabel(PhraseBookBox);
- target->setObjectName(QStringLiteral("target"));
+ target->setObjectName(QString::fromUtf8("target"));
gridLayout->addWidget(target, 1, 0, 1, 1);
targetLed = new QLineEdit(PhraseBookBox);
- targetLed->setObjectName(QStringLiteral("targetLed"));
+ targetLed->setObjectName(QString::fromUtf8("targetLed"));
gridLayout->addWidget(targetLed, 1, 1, 1, 1);
source = new QLabel(PhraseBookBox);
- source->setObjectName(QStringLiteral("source"));
+ source->setObjectName(QString::fromUtf8("source"));
gridLayout->addWidget(source, 0, 0, 1, 1);
definitionLed = new QLineEdit(PhraseBookBox);
- definitionLed->setObjectName(QStringLiteral("definitionLed"));
+ definitionLed->setObjectName(QString::fromUtf8("definitionLed"));
gridLayout->addWidget(definitionLed, 2, 1, 1, 1);
sourceLed = new QLineEdit(PhraseBookBox);
- sourceLed->setObjectName(QStringLiteral("sourceLed"));
+ sourceLed->setObjectName(QString::fromUtf8("sourceLed"));
gridLayout->addWidget(sourceLed, 0, 1, 1, 1);
definition = new QLabel(PhraseBookBox);
- definition->setObjectName(QStringLiteral("definition"));
+ definition->setObjectName(QString::fromUtf8("definition"));
gridLayout->addWidget(definition, 2, 0, 1, 1);
@@ -123,7 +123,7 @@ public:
inputsLayout->addLayout(gridLayout);
phraseList = new QTreeView(PhraseBookBox);
- phraseList->setObjectName(QStringLiteral("phraseList"));
+ phraseList->setObjectName(QString::fromUtf8("phraseList"));
phraseList->setRootIsDecorated(false);
phraseList->setUniformRowHeights(true);
phraseList->setItemsExpandable(false);
@@ -137,24 +137,24 @@ public:
buttonLayout = new QVBoxLayout();
buttonLayout->setSpacing(6);
- buttonLayout->setObjectName(QStringLiteral("buttonLayout"));
+ buttonLayout->setObjectName(QString::fromUtf8("buttonLayout"));
newBut = new QPushButton(PhraseBookBox);
- newBut->setObjectName(QStringLiteral("newBut"));
+ newBut->setObjectName(QString::fromUtf8("newBut"));
buttonLayout->addWidget(newBut);
removeBut = new QPushButton(PhraseBookBox);
- removeBut->setObjectName(QStringLiteral("removeBut"));
+ removeBut->setObjectName(QString::fromUtf8("removeBut"));
buttonLayout->addWidget(removeBut);
saveBut = new QPushButton(PhraseBookBox);
- saveBut->setObjectName(QStringLiteral("saveBut"));
+ saveBut->setObjectName(QString::fromUtf8("saveBut"));
buttonLayout->addWidget(saveBut);
closeBut = new QPushButton(PhraseBookBox);
- closeBut->setObjectName(QStringLiteral("closeBut"));
+ closeBut->setObjectName(QString::fromUtf8("closeBut"));
buttonLayout->addWidget(closeBut);
diff --git a/tests/auto/tools/uic/baseline/pixmapfunction.ui b/tests/auto/tools/uic/baseline/pixmapfunction.ui
new file mode 100644
index 0000000000..8edafc7248
--- /dev/null
+++ b/tests/auto/tools/uic/baseline/pixmapfunction.ui
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>149</width>
+ <height>112</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap>labelPixmap</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>buttonIconNormalOff</normaloff>
+ <normalon>buttonIconNormalOn</normalon>
+ <disabledoff>buttonIconDisabledOff</disabledoff>
+ <disabledon>buttonIconDisabledOn</disabledon>
+ </iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <pixmapfunction>pixmapFunction</pixmapfunction>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/auto/tools/uic/baseline/pixmapfunction.ui.h b/tests/auto/tools/uic/baseline/pixmapfunction.ui.h
new file mode 100644
index 0000000000..1644380c15
--- /dev/null
+++ b/tests/auto/tools/uic/baseline/pixmapfunction.ui.h
@@ -0,0 +1,74 @@
+/********************************************************************************
+** Form generated from reading UI file 'pixmapfunction.ui'
+**
+** Created by: Qt User Interface Compiler version 5.12.0
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef PIXMAPFUNCTION_H
+#define PIXMAPFUNCTION_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QIcon>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class Ui_Form
+{
+public:
+ QVBoxLayout *verticalLayout;
+ QLabel *label;
+ QPushButton *pushButton;
+
+ void setupUi(QWidget *Form)
+ {
+ if (Form->objectName().isEmpty())
+ Form->setObjectName(QString::fromUtf8("Form"));
+ Form->resize(149, 112);
+ verticalLayout = new QVBoxLayout(Form);
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
+ label = new QLabel(Form);
+ label->setObjectName(QString::fromUtf8("label"));
+ label->setPixmap(QPixmap(pixmapFunction("labelPixmap")));
+
+ verticalLayout->addWidget(label);
+
+ pushButton = new QPushButton(Form);
+ pushButton->setObjectName(QString::fromUtf8("pushButton"));
+ QIcon icon;
+ icon.addPixmap(QPixmap(pixmapFunction("buttonIconNormalOff")), QIcon::Normal, QIcon::Off);
+ icon.addPixmap(QPixmap(pixmapFunction("buttonIconNormalOn")), QIcon::Normal, QIcon::On);
+ icon.addPixmap(QPixmap(pixmapFunction("buttonIconDisabledOff")), QIcon::Disabled, QIcon::Off);
+ icon.addPixmap(QPixmap(pixmapFunction("buttonIconDisabledOn")), QIcon::Disabled, QIcon::On);
+ pushButton->setIcon(icon);
+
+ verticalLayout->addWidget(pushButton);
+
+
+ retranslateUi(Form);
+
+ QMetaObject::connectSlotsByName(Form);
+ } // setupUi
+
+ void retranslateUi(QWidget *Form)
+ {
+ Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr));
+ label->setText(QString());
+ pushButton->setText(QApplication::translate("Form", "PushButton", nullptr));
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class Form: public Ui_Form {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // PIXMAPFUNCTION_H
diff --git a/tests/auto/tools/uic/baseline/plugindialog.ui.h b/tests/auto/tools/uic/baseline/plugindialog.ui.h
index 30256a35c2..3634b8436f 100644
--- a/tests/auto/tools/uic/baseline/plugindialog.ui.h
+++ b/tests/auto/tools/uic/baseline/plugindialog.ui.h
@@ -64,39 +64,39 @@ public:
void setupUi(QDialog *PluginDialog)
{
if (PluginDialog->objectName().isEmpty())
- PluginDialog->setObjectName(QStringLiteral("PluginDialog"));
+ PluginDialog->setObjectName(QString::fromUtf8("PluginDialog"));
PluginDialog->resize(401, 331);
vboxLayout = new QVBoxLayout(PluginDialog);
vboxLayout->setSpacing(6);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout->setContentsMargins(8, 8, 8, 8);
label = new QLabel(PluginDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setWordWrap(true);
vboxLayout->addWidget(label);
treeWidget = new QTreeWidget(PluginDialog);
- treeWidget->setObjectName(QStringLiteral("treeWidget"));
+ treeWidget->setObjectName(QString::fromUtf8("treeWidget"));
treeWidget->setTextElideMode(Qt::ElideNone);
vboxLayout->addWidget(treeWidget);
message = new QLabel(PluginDialog);
- message->setObjectName(QStringLiteral("message"));
+ message->setObjectName(QString::fromUtf8("message"));
message->setWordWrap(true);
vboxLayout->addWidget(message);
hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(6);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
hboxLayout->setContentsMargins(0, 0, 0, 0);
vboxLayout->addLayout(hboxLayout);
buttonBox = new QDialogButtonBox(PluginDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Close);
diff --git a/tests/auto/tools/uic/baseline/preferencesdialog.ui.h b/tests/auto/tools/uic/baseline/preferencesdialog.ui.h
index 15761b2cdc..289e6775b4 100644
--- a/tests/auto/tools/uic/baseline/preferencesdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/preferencesdialog.ui.h
@@ -53,21 +53,21 @@ public:
void setupUi(QDialog *PreferencesDialog)
{
if (PreferencesDialog->objectName().isEmpty())
- PreferencesDialog->setObjectName(QStringLiteral("PreferencesDialog"));
+ PreferencesDialog->setObjectName(QString::fromUtf8("PreferencesDialog"));
PreferencesDialog->resize(455, 359);
PreferencesDialog->setModal(true);
vboxLayout = new QVBoxLayout(PreferencesDialog);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
vboxLayout1 = new QVBoxLayout();
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
m_uiModeGroupBox = new QGroupBox(PreferencesDialog);
- m_uiModeGroupBox->setObjectName(QStringLiteral("m_uiModeGroupBox"));
+ m_uiModeGroupBox->setObjectName(QString::fromUtf8("m_uiModeGroupBox"));
vboxLayout2 = new QVBoxLayout(m_uiModeGroupBox);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
m_uiModeCombo = new QComboBox(m_uiModeGroupBox);
- m_uiModeCombo->setObjectName(QStringLiteral("m_uiModeCombo"));
+ m_uiModeCombo->setObjectName(QString::fromUtf8("m_uiModeCombo"));
vboxLayout2->addWidget(m_uiModeCombo);
@@ -75,12 +75,12 @@ public:
vboxLayout1->addWidget(m_uiModeGroupBox);
m_fontPanel = new FontPanel(PreferencesDialog);
- m_fontPanel->setObjectName(QStringLiteral("m_fontPanel"));
+ m_fontPanel->setObjectName(QString::fromUtf8("m_fontPanel"));
vboxLayout1->addWidget(m_fontPanel);
m_previewConfigurationWidget = new qdesigner_internal::PreviewConfigurationWidget(PreferencesDialog);
- m_previewConfigurationWidget->setObjectName(QStringLiteral("m_previewConfigurationWidget"));
+ m_previewConfigurationWidget->setObjectName(QString::fromUtf8("m_previewConfigurationWidget"));
vboxLayout1->addWidget(m_previewConfigurationWidget);
@@ -88,23 +88,23 @@ public:
hboxLayout->addLayout(vboxLayout1);
vboxLayout3 = new QVBoxLayout();
- vboxLayout3->setObjectName(QStringLiteral("vboxLayout3"));
+ vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3"));
m_templatePathGroupBox = new QGroupBox(PreferencesDialog);
- m_templatePathGroupBox->setObjectName(QStringLiteral("m_templatePathGroupBox"));
+ m_templatePathGroupBox->setObjectName(QString::fromUtf8("m_templatePathGroupBox"));
gridLayout = new QGridLayout(m_templatePathGroupBox);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
m_templatePathListWidget = new QListWidget(m_templatePathGroupBox);
- m_templatePathListWidget->setObjectName(QStringLiteral("m_templatePathListWidget"));
+ m_templatePathListWidget->setObjectName(QString::fromUtf8("m_templatePathListWidget"));
gridLayout->addWidget(m_templatePathListWidget, 0, 0, 1, 3);
m_addTemplatePathButton = new QToolButton(m_templatePathGroupBox);
- m_addTemplatePathButton->setObjectName(QStringLiteral("m_addTemplatePathButton"));
+ m_addTemplatePathButton->setObjectName(QString::fromUtf8("m_addTemplatePathButton"));
gridLayout->addWidget(m_addTemplatePathButton, 1, 0, 1, 1);
m_removeTemplatePathButton = new QToolButton(m_templatePathGroupBox);
- m_removeTemplatePathButton->setObjectName(QStringLiteral("m_removeTemplatePathButton"));
+ m_removeTemplatePathButton->setObjectName(QString::fromUtf8("m_removeTemplatePathButton"));
gridLayout->addWidget(m_removeTemplatePathButton, 1, 1, 1, 1);
@@ -116,7 +116,7 @@ public:
vboxLayout3->addWidget(m_templatePathGroupBox);
m_gridPanel = new qdesigner_internal::GridPanel(PreferencesDialog);
- m_gridPanel->setObjectName(QStringLiteral("m_gridPanel"));
+ m_gridPanel->setObjectName(QString::fromUtf8("m_gridPanel"));
vboxLayout3->addWidget(m_gridPanel);
@@ -127,14 +127,14 @@ public:
vboxLayout->addLayout(hboxLayout);
line = new QFrame(PreferencesDialog);
- line->setObjectName(QStringLiteral("line"));
+ line->setObjectName(QString::fromUtf8("line"));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
vboxLayout->addWidget(line);
m_dialogButtonBox = new QDialogButtonBox(PreferencesDialog);
- m_dialogButtonBox->setObjectName(QStringLiteral("m_dialogButtonBox"));
+ m_dialogButtonBox->setObjectName(QString::fromUtf8("m_dialogButtonBox"));
m_dialogButtonBox->setOrientation(Qt::Horizontal);
m_dialogButtonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h b/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h
index 60bf65af45..3c729b9c65 100644
--- a/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h
+++ b/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h
@@ -40,40 +40,40 @@ public:
void setupUi(QGroupBox *PreviewConfigurationWidget)
{
if (PreviewConfigurationWidget->objectName().isEmpty())
- PreviewConfigurationWidget->setObjectName(QStringLiteral("PreviewConfigurationWidget"));
+ PreviewConfigurationWidget->setObjectName(QString::fromUtf8("PreviewConfigurationWidget"));
PreviewConfigurationWidget->setCheckable(true);
formLayout = new QFormLayout(PreviewConfigurationWidget);
- formLayout->setObjectName(QStringLiteral("formLayout"));
+ formLayout->setObjectName(QString::fromUtf8("formLayout"));
m_styleLabel = new QLabel(PreviewConfigurationWidget);
- m_styleLabel->setObjectName(QStringLiteral("m_styleLabel"));
+ m_styleLabel->setObjectName(QString::fromUtf8("m_styleLabel"));
formLayout->setWidget(0, QFormLayout::LabelRole, m_styleLabel);
m_styleCombo = new QComboBox(PreviewConfigurationWidget);
- m_styleCombo->setObjectName(QStringLiteral("m_styleCombo"));
+ m_styleCombo->setObjectName(QString::fromUtf8("m_styleCombo"));
formLayout->setWidget(0, QFormLayout::FieldRole, m_styleCombo);
m_appStyleSheetLabel = new QLabel(PreviewConfigurationWidget);
- m_appStyleSheetLabel->setObjectName(QStringLiteral("m_appStyleSheetLabel"));
+ m_appStyleSheetLabel->setObjectName(QString::fromUtf8("m_appStyleSheetLabel"));
formLayout->setWidget(1, QFormLayout::LabelRole, m_appStyleSheetLabel);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
m_appStyleSheetLineEdit = new qdesigner_internal::TextPropertyEditor(PreviewConfigurationWidget);
- m_appStyleSheetLineEdit->setObjectName(QStringLiteral("m_appStyleSheetLineEdit"));
+ m_appStyleSheetLineEdit->setObjectName(QString::fromUtf8("m_appStyleSheetLineEdit"));
m_appStyleSheetLineEdit->setMinimumSize(QSize(149, 0));
hboxLayout->addWidget(m_appStyleSheetLineEdit);
m_appStyleSheetChangeButton = new QToolButton(PreviewConfigurationWidget);
- m_appStyleSheetChangeButton->setObjectName(QStringLiteral("m_appStyleSheetChangeButton"));
+ m_appStyleSheetChangeButton->setObjectName(QString::fromUtf8("m_appStyleSheetChangeButton"));
hboxLayout->addWidget(m_appStyleSheetChangeButton);
m_appStyleSheetClearButton = new QToolButton(PreviewConfigurationWidget);
- m_appStyleSheetClearButton->setObjectName(QStringLiteral("m_appStyleSheetClearButton"));
+ m_appStyleSheetClearButton->setObjectName(QString::fromUtf8("m_appStyleSheetClearButton"));
hboxLayout->addWidget(m_appStyleSheetClearButton);
@@ -81,19 +81,19 @@ public:
formLayout->setLayout(1, QFormLayout::FieldRole, hboxLayout);
m_skinLabel = new QLabel(PreviewConfigurationWidget);
- m_skinLabel->setObjectName(QStringLiteral("m_skinLabel"));
+ m_skinLabel->setObjectName(QString::fromUtf8("m_skinLabel"));
formLayout->setWidget(2, QFormLayout::LabelRole, m_skinLabel);
hboxLayout1 = new QHBoxLayout();
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
m_skinCombo = new QComboBox(PreviewConfigurationWidget);
- m_skinCombo->setObjectName(QStringLiteral("m_skinCombo"));
+ m_skinCombo->setObjectName(QString::fromUtf8("m_skinCombo"));
hboxLayout1->addWidget(m_skinCombo);
m_skinRemoveButton = new QToolButton(PreviewConfigurationWidget);
- m_skinRemoveButton->setObjectName(QStringLiteral("m_skinRemoveButton"));
+ m_skinRemoveButton->setObjectName(QString::fromUtf8("m_skinRemoveButton"));
hboxLayout1->addWidget(m_skinRemoveButton);
diff --git a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h
index 7ea1e72e04..8d4c0dae9f 100644
--- a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h
+++ b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h
@@ -45,7 +45,7 @@ public:
void setupUi(QDialog *PreviewDialogBase)
{
if (PreviewDialogBase->objectName().isEmpty())
- PreviewDialogBase->setObjectName(QStringLiteral("PreviewDialogBase"));
+ PreviewDialogBase->setObjectName(QString::fromUtf8("PreviewDialogBase"));
PreviewDialogBase->resize(733, 479);
vboxLayout = new QVBoxLayout(PreviewDialogBase);
#ifndef Q_OS_MAC
@@ -54,7 +54,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
hboxLayout = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
@@ -62,14 +62,14 @@ public:
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(0, 0, 0, 0);
#endif
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
label = new QLabel(PreviewDialogBase);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
hboxLayout->addWidget(label);
paperSizeCombo = new QComboBox(PreviewDialogBase);
- paperSizeCombo->setObjectName(QStringLiteral("paperSizeCombo"));
+ paperSizeCombo->setObjectName(QString::fromUtf8("paperSizeCombo"));
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(1), static_cast<QSizePolicy::Policy>(0));
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -79,12 +79,12 @@ public:
hboxLayout->addWidget(paperSizeCombo);
label_2 = new QLabel(PreviewDialogBase);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
hboxLayout->addWidget(label_2);
paperOrientationCombo = new QComboBox(PreviewDialogBase);
- paperOrientationCombo->setObjectName(QStringLiteral("paperOrientationCombo"));
+ paperOrientationCombo->setObjectName(QString::fromUtf8("paperOrientationCombo"));
sizePolicy.setHeightForWidth(paperOrientationCombo->sizePolicy().hasHeightForWidth());
paperOrientationCombo->setSizePolicy(sizePolicy);
@@ -102,9 +102,9 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
pageList = new QTreeWidget(PreviewDialogBase);
- pageList->setObjectName(QStringLiteral("pageList"));
+ pageList->setObjectName(QString::fromUtf8("pageList"));
pageList->setIndentation(0);
pageList->setRootIsDecorated(false);
pageList->setUniformRowHeights(true);
@@ -114,7 +114,7 @@ public:
hboxLayout1->addWidget(pageList);
previewArea = new QScrollArea(PreviewDialogBase);
- previewArea->setObjectName(QStringLiteral("previewArea"));
+ previewArea->setObjectName(QString::fromUtf8("previewArea"));
QSizePolicy sizePolicy1(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(5));
sizePolicy1.setHorizontalStretch(1);
sizePolicy1.setVerticalStretch(0);
@@ -131,9 +131,9 @@ public:
hboxLayout2->setSpacing(6);
#endif
hboxLayout2->setContentsMargins(0, 0, 0, 0);
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
progressBar = new QProgressBar(PreviewDialogBase);
- progressBar->setObjectName(QStringLiteral("progressBar"));
+ progressBar->setObjectName(QString::fromUtf8("progressBar"));
progressBar->setEnabled(false);
QSizePolicy sizePolicy2(static_cast<QSizePolicy::Policy>(7), static_cast<QSizePolicy::Policy>(0));
sizePolicy2.setHorizontalStretch(1);
@@ -147,7 +147,7 @@ public:
hboxLayout2->addWidget(progressBar);
buttonBox = new QDialogButtonBox(PreviewDialogBase);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/previewwidget.ui.h b/tests/auto/tools/uic/baseline/previewwidget.ui.h
index a86fec7c0d..6e359416c8 100644
--- a/tests/auto/tools/uic/baseline/previewwidget.ui.h
+++ b/tests/auto/tools/uic/baseline/previewwidget.ui.h
@@ -90,7 +90,7 @@ public:
void setupUi(QWidget *qdesigner_internal__PreviewWidget)
{
if (qdesigner_internal__PreviewWidget->objectName().isEmpty())
- qdesigner_internal__PreviewWidget->setObjectName(QStringLiteral("qdesigner_internal__PreviewWidget"));
+ qdesigner_internal__PreviewWidget->setObjectName(QString::fromUtf8("qdesigner_internal__PreviewWidget"));
qdesigner_internal__PreviewWidget->resize(471, 251);
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(1), static_cast<QSizePolicy::Policy>(1));
sizePolicy.setHorizontalStretch(0);
@@ -104,7 +104,7 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
vboxLayout = new QVBoxLayout();
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
@@ -112,15 +112,15 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(0, 0, 0, 0);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
LineEdit1 = new QLineEdit(qdesigner_internal__PreviewWidget);
- LineEdit1->setObjectName(QStringLiteral("LineEdit1"));
+ LineEdit1->setObjectName(QString::fromUtf8("LineEdit1"));
vboxLayout->addWidget(LineEdit1);
ComboBox1 = new QComboBox(qdesigner_internal__PreviewWidget);
ComboBox1->addItem(QString());
- ComboBox1->setObjectName(QStringLiteral("ComboBox1"));
+ ComboBox1->setObjectName(QString::fromUtf8("ComboBox1"));
vboxLayout->addWidget(ComboBox1);
@@ -129,14 +129,14 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
SpinBox1 = new QSpinBox(qdesigner_internal__PreviewWidget);
- SpinBox1->setObjectName(QStringLiteral("SpinBox1"));
+ SpinBox1->setObjectName(QString::fromUtf8("SpinBox1"));
hboxLayout->addWidget(SpinBox1);
PushButton1 = new QPushButton(qdesigner_internal__PreviewWidget);
- PushButton1->setObjectName(QStringLiteral("PushButton1"));
+ PushButton1->setObjectName(QString::fromUtf8("PushButton1"));
hboxLayout->addWidget(PushButton1);
@@ -144,19 +144,19 @@ public:
vboxLayout->addLayout(hboxLayout);
ScrollBar1 = new QScrollBar(qdesigner_internal__PreviewWidget);
- ScrollBar1->setObjectName(QStringLiteral("ScrollBar1"));
+ ScrollBar1->setObjectName(QString::fromUtf8("ScrollBar1"));
ScrollBar1->setOrientation(Qt::Horizontal);
vboxLayout->addWidget(ScrollBar1);
Slider1 = new QSlider(qdesigner_internal__PreviewWidget);
- Slider1->setObjectName(QStringLiteral("Slider1"));
+ Slider1->setObjectName(QString::fromUtf8("Slider1"));
Slider1->setOrientation(Qt::Horizontal);
vboxLayout->addWidget(Slider1);
listWidget = new QListWidget(qdesigner_internal__PreviewWidget);
- listWidget->setObjectName(QStringLiteral("listWidget"));
+ listWidget->setObjectName(QString::fromUtf8("listWidget"));
listWidget->setMaximumSize(QSize(32767, 50));
vboxLayout->addWidget(listWidget);
@@ -169,13 +169,13 @@ public:
gridLayout->addItem(spacerItem, 3, 0, 1, 2);
ProgressBar1 = new QProgressBar(qdesigner_internal__PreviewWidget);
- ProgressBar1->setObjectName(QStringLiteral("ProgressBar1"));
+ ProgressBar1->setObjectName(QString::fromUtf8("ProgressBar1"));
ProgressBar1->setOrientation(Qt::Horizontal);
gridLayout->addWidget(ProgressBar1, 2, 0, 1, 1);
ButtonGroup2 = new QGroupBox(qdesigner_internal__PreviewWidget);
- ButtonGroup2->setObjectName(QStringLiteral("ButtonGroup2"));
+ ButtonGroup2->setObjectName(QString::fromUtf8("ButtonGroup2"));
vboxLayout1 = new QVBoxLayout(ButtonGroup2);
#ifndef Q_OS_MAC
vboxLayout1->setSpacing(6);
@@ -183,15 +183,15 @@ public:
#ifndef Q_OS_MAC
vboxLayout1->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
CheckBox1 = new QCheckBox(ButtonGroup2);
- CheckBox1->setObjectName(QStringLiteral("CheckBox1"));
+ CheckBox1->setObjectName(QString::fromUtf8("CheckBox1"));
CheckBox1->setChecked(true);
vboxLayout1->addWidget(CheckBox1);
CheckBox2 = new QCheckBox(ButtonGroup2);
- CheckBox2->setObjectName(QStringLiteral("CheckBox2"));
+ CheckBox2->setObjectName(QString::fromUtf8("CheckBox2"));
vboxLayout1->addWidget(CheckBox2);
@@ -199,7 +199,7 @@ public:
gridLayout->addWidget(ButtonGroup2, 1, 0, 1, 1);
ButtonGroup1 = new QGroupBox(qdesigner_internal__PreviewWidget);
- ButtonGroup1->setObjectName(QStringLiteral("ButtonGroup1"));
+ ButtonGroup1->setObjectName(QString::fromUtf8("ButtonGroup1"));
vboxLayout2 = new QVBoxLayout(ButtonGroup1);
#ifndef Q_OS_MAC
vboxLayout2->setSpacing(6);
@@ -207,20 +207,20 @@ public:
#ifndef Q_OS_MAC
vboxLayout2->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
RadioButton1 = new QRadioButton(ButtonGroup1);
- RadioButton1->setObjectName(QStringLiteral("RadioButton1"));
+ RadioButton1->setObjectName(QString::fromUtf8("RadioButton1"));
RadioButton1->setChecked(true);
vboxLayout2->addWidget(RadioButton1);
RadioButton2 = new QRadioButton(ButtonGroup1);
- RadioButton2->setObjectName(QStringLiteral("RadioButton2"));
+ RadioButton2->setObjectName(QString::fromUtf8("RadioButton2"));
vboxLayout2->addWidget(RadioButton2);
RadioButton3 = new QRadioButton(ButtonGroup1);
- RadioButton3->setObjectName(QStringLiteral("RadioButton3"));
+ RadioButton3->setObjectName(QString::fromUtf8("RadioButton3"));
vboxLayout2->addWidget(RadioButton3);
diff --git a/tests/auto/tools/uic/baseline/proxy.ui.h b/tests/auto/tools/uic/baseline/proxy.ui.h
index 2112324eae..a1bc287190 100644
--- a/tests/auto/tools/uic/baseline/proxy.ui.h
+++ b/tests/auto/tools/uic/baseline/proxy.ui.h
@@ -34,44 +34,44 @@ public:
void setupUi(QDialog *ProxyDialog)
{
if (ProxyDialog->objectName().isEmpty())
- ProxyDialog->setObjectName(QStringLiteral("ProxyDialog"));
+ ProxyDialog->setObjectName(QString::fromUtf8("ProxyDialog"));
ProxyDialog->resize(369, 144);
gridLayout = new QGridLayout(ProxyDialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
iconLabel = new QLabel(ProxyDialog);
- iconLabel->setObjectName(QStringLiteral("iconLabel"));
+ iconLabel->setObjectName(QString::fromUtf8("iconLabel"));
gridLayout->addWidget(iconLabel, 0, 0, 1, 1);
introLabel = new QLabel(ProxyDialog);
- introLabel->setObjectName(QStringLiteral("introLabel"));
+ introLabel->setObjectName(QString::fromUtf8("introLabel"));
introLabel->setWordWrap(true);
gridLayout->addWidget(introLabel, 0, 1, 1, 2);
usernameLabel = new QLabel(ProxyDialog);
- usernameLabel->setObjectName(QStringLiteral("usernameLabel"));
+ usernameLabel->setObjectName(QString::fromUtf8("usernameLabel"));
gridLayout->addWidget(usernameLabel, 1, 0, 1, 2);
userNameLineEdit = new QLineEdit(ProxyDialog);
- userNameLineEdit->setObjectName(QStringLiteral("userNameLineEdit"));
+ userNameLineEdit->setObjectName(QString::fromUtf8("userNameLineEdit"));
gridLayout->addWidget(userNameLineEdit, 1, 2, 1, 1);
passwordLabel = new QLabel(ProxyDialog);
- passwordLabel->setObjectName(QStringLiteral("passwordLabel"));
+ passwordLabel->setObjectName(QString::fromUtf8("passwordLabel"));
gridLayout->addWidget(passwordLabel, 2, 0, 1, 2);
passwordLineEdit = new QLineEdit(ProxyDialog);
- passwordLineEdit->setObjectName(QStringLiteral("passwordLineEdit"));
+ passwordLineEdit->setObjectName(QString::fromUtf8("passwordLineEdit"));
passwordLineEdit->setEchoMode(QLineEdit::Password);
gridLayout->addWidget(passwordLineEdit, 2, 2, 1, 1);
buttonBox = new QDialogButtonBox(ProxyDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/qfiledialog.ui.h b/tests/auto/tools/uic/baseline/qfiledialog.ui.h
index cd1891c58c..53607db449 100644
--- a/tests/auto/tools/uic/baseline/qfiledialog.ui.h
+++ b/tests/auto/tools/uic/baseline/qfiledialog.ui.h
@@ -92,20 +92,20 @@ public:
void setupUi(QDialog *QFileDialog)
{
if (QFileDialog->objectName().isEmpty())
- QFileDialog->setObjectName(QStringLiteral("QFileDialog"));
+ QFileDialog->setObjectName(QString::fromUtf8("QFileDialog"));
QFileDialog->resize(521, 316);
QFileDialog->setSizeGripEnabled(true);
gridLayout = new QGridLayout(QFileDialog);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
lookInLabel = new QLabel(QFileDialog);
- lookInLabel->setObjectName(QStringLiteral("lookInLabel"));
+ lookInLabel->setObjectName(QString::fromUtf8("lookInLabel"));
gridLayout->addWidget(lookInLabel, 0, 0, 1, 1);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
lookInCombo = new QFileDialogComboBox(QFileDialog);
- lookInCombo->setObjectName(QStringLiteral("lookInCombo"));
+ lookInCombo->setObjectName(QString::fromUtf8("lookInCombo"));
QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(1);
sizePolicy.setVerticalStretch(0);
@@ -116,32 +116,32 @@ public:
hboxLayout->addWidget(lookInCombo);
backButton = new QToolButton(QFileDialog);
- backButton->setObjectName(QStringLiteral("backButton"));
+ backButton->setObjectName(QString::fromUtf8("backButton"));
hboxLayout->addWidget(backButton);
forwardButton = new QToolButton(QFileDialog);
- forwardButton->setObjectName(QStringLiteral("forwardButton"));
+ forwardButton->setObjectName(QString::fromUtf8("forwardButton"));
hboxLayout->addWidget(forwardButton);
toParentButton = new QToolButton(QFileDialog);
- toParentButton->setObjectName(QStringLiteral("toParentButton"));
+ toParentButton->setObjectName(QString::fromUtf8("toParentButton"));
hboxLayout->addWidget(toParentButton);
newFolderButton = new QToolButton(QFileDialog);
- newFolderButton->setObjectName(QStringLiteral("newFolderButton"));
+ newFolderButton->setObjectName(QString::fromUtf8("newFolderButton"));
hboxLayout->addWidget(newFolderButton);
listModeButton = new QToolButton(QFileDialog);
- listModeButton->setObjectName(QStringLiteral("listModeButton"));
+ listModeButton->setObjectName(QString::fromUtf8("listModeButton"));
hboxLayout->addWidget(listModeButton);
detailModeButton = new QToolButton(QFileDialog);
- detailModeButton->setObjectName(QStringLiteral("detailModeButton"));
+ detailModeButton->setObjectName(QString::fromUtf8("detailModeButton"));
hboxLayout->addWidget(detailModeButton);
@@ -149,7 +149,7 @@ public:
gridLayout->addLayout(hboxLayout, 0, 1, 1, 2);
splitter = new QSplitter(QFileDialog);
- splitter->setObjectName(QStringLiteral("splitter"));
+ splitter->setObjectName(QString::fromUtf8("splitter"));
QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -157,38 +157,38 @@ public:
splitter->setSizePolicy(sizePolicy1);
splitter->setOrientation(Qt::Horizontal);
sidebar = new QSidebar(splitter);
- sidebar->setObjectName(QStringLiteral("sidebar"));
+ sidebar->setObjectName(QString::fromUtf8("sidebar"));
splitter->addWidget(sidebar);
frame = new QFrame(splitter);
- frame->setObjectName(QStringLiteral("frame"));
+ frame->setObjectName(QString::fromUtf8("frame"));
frame->setFrameShape(QFrame::NoFrame);
frame->setFrameShadow(QFrame::Raised);
vboxLayout = new QVBoxLayout(frame);
vboxLayout->setSpacing(0);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout->setContentsMargins(0, 0, 0, 0);
stackedWidget = new QStackedWidget(frame);
- stackedWidget->setObjectName(QStringLiteral("stackedWidget"));
+ stackedWidget->setObjectName(QString::fromUtf8("stackedWidget"));
page = new QWidget();
- page->setObjectName(QStringLiteral("page"));
+ page->setObjectName(QString::fromUtf8("page"));
vboxLayout1 = new QVBoxLayout(page);
vboxLayout1->setSpacing(0);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
vboxLayout1->setContentsMargins(0, 0, 0, 0);
listView = new QFileDialogListView(page);
- listView->setObjectName(QStringLiteral("listView"));
+ listView->setObjectName(QString::fromUtf8("listView"));
vboxLayout1->addWidget(listView);
stackedWidget->addWidget(page);
page_2 = new QWidget();
- page_2->setObjectName(QStringLiteral("page_2"));
+ page_2->setObjectName(QString::fromUtf8("page_2"));
vboxLayout2 = new QVBoxLayout(page_2);
vboxLayout2->setSpacing(0);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
vboxLayout2->setContentsMargins(0, 0, 0, 0);
treeView = new QFileDialogTreeView(page_2);
- treeView->setObjectName(QStringLiteral("treeView"));
+ treeView->setObjectName(QString::fromUtf8("treeView"));
vboxLayout2->addWidget(treeView);
@@ -201,7 +201,7 @@ public:
gridLayout->addWidget(splitter, 1, 0, 1, 3);
fileNameLabel = new QLabel(QFileDialog);
- fileNameLabel->setObjectName(QStringLiteral("fileNameLabel"));
+ fileNameLabel->setObjectName(QString::fromUtf8("fileNameLabel"));
QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Preferred);
sizePolicy2.setHorizontalStretch(0);
sizePolicy2.setVerticalStretch(0);
@@ -212,7 +212,7 @@ public:
gridLayout->addWidget(fileNameLabel, 2, 0, 1, 1);
fileNameEdit = new QFileDialogLineEdit(QFileDialog);
- fileNameEdit->setObjectName(QStringLiteral("fileNameEdit"));
+ fileNameEdit->setObjectName(QString::fromUtf8("fileNameEdit"));
QSizePolicy sizePolicy3(QSizePolicy::Expanding, QSizePolicy::Fixed);
sizePolicy3.setHorizontalStretch(1);
sizePolicy3.setVerticalStretch(0);
@@ -222,14 +222,14 @@ public:
gridLayout->addWidget(fileNameEdit, 2, 1, 1, 1);
buttonBox = new QDialogButtonBox(QFileDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Vertical);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
gridLayout->addWidget(buttonBox, 2, 2, 2, 1);
fileTypeLabel = new QLabel(QFileDialog);
- fileTypeLabel->setObjectName(QStringLiteral("fileTypeLabel"));
+ fileTypeLabel->setObjectName(QString::fromUtf8("fileTypeLabel"));
QSizePolicy sizePolicy4(QSizePolicy::Preferred, QSizePolicy::Fixed);
sizePolicy4.setHorizontalStretch(0);
sizePolicy4.setVerticalStretch(0);
@@ -239,7 +239,7 @@ public:
gridLayout->addWidget(fileTypeLabel, 3, 0, 1, 1);
fileTypeCombo = new QComboBox(QFileDialog);
- fileTypeCombo->setObjectName(QStringLiteral("fileTypeCombo"));
+ fileTypeCombo->setObjectName(QString::fromUtf8("fileTypeCombo"));
QSizePolicy sizePolicy5(QSizePolicy::Expanding, QSizePolicy::Fixed);
sizePolicy5.setHorizontalStretch(0);
sizePolicy5.setVerticalStretch(0);
diff --git a/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h b/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h
index 5b0a5b9dc6..e914c664d3 100644
--- a/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h
+++ b/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h
@@ -76,45 +76,45 @@ public:
void setupUi(QWidget *QPageSetupWidget)
{
if (QPageSetupWidget->objectName().isEmpty())
- QPageSetupWidget->setObjectName(QStringLiteral("QPageSetupWidget"));
+ QPageSetupWidget->setObjectName(QString::fromUtf8("QPageSetupWidget"));
QPageSetupWidget->resize(416, 515);
gridLayout_3 = new QGridLayout(QPageSetupWidget);
gridLayout_3->setContentsMargins(0, 0, 0, 0);
- gridLayout_3->setObjectName(QStringLiteral("gridLayout_3"));
+ gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3"));
groupBox_2 = new QGroupBox(QPageSetupWidget);
- groupBox_2->setObjectName(QStringLiteral("groupBox_2"));
+ groupBox_2->setObjectName(QString::fromUtf8("groupBox_2"));
gridLayout_2 = new QGridLayout(groupBox_2);
- gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
+ gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
pageSizeLabel = new QLabel(groupBox_2);
- pageSizeLabel->setObjectName(QStringLiteral("pageSizeLabel"));
+ pageSizeLabel->setObjectName(QString::fromUtf8("pageSizeLabel"));
gridLayout_2->addWidget(pageSizeLabel, 0, 0, 1, 1);
pageSizeCombo = new QComboBox(groupBox_2);
- pageSizeCombo->setObjectName(QStringLiteral("pageSizeCombo"));
+ pageSizeCombo->setObjectName(QString::fromUtf8("pageSizeCombo"));
gridLayout_2->addWidget(pageSizeCombo, 0, 1, 1, 1);
widthLabel = new QLabel(groupBox_2);
- widthLabel->setObjectName(QStringLiteral("widthLabel"));
+ widthLabel->setObjectName(QString::fromUtf8("widthLabel"));
gridLayout_2->addWidget(widthLabel, 1, 0, 1, 1);
horizontalLayout_3 = new QHBoxLayout();
- horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3"));
+ horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
pageWidth = new QDoubleSpinBox(groupBox_2);
- pageWidth->setObjectName(QStringLiteral("pageWidth"));
+ pageWidth->setObjectName(QString::fromUtf8("pageWidth"));
pageWidth->setMaximum(9999.99);
horizontalLayout_3->addWidget(pageWidth);
heightLabel = new QLabel(groupBox_2);
- heightLabel->setObjectName(QStringLiteral("heightLabel"));
+ heightLabel->setObjectName(QString::fromUtf8("heightLabel"));
horizontalLayout_3->addWidget(heightLabel);
pageHeight = new QDoubleSpinBox(groupBox_2);
- pageHeight->setObjectName(QStringLiteral("pageHeight"));
+ pageHeight->setObjectName(QString::fromUtf8("pageHeight"));
pageHeight->setMaximum(9999.99);
horizontalLayout_3->addWidget(pageHeight);
@@ -123,12 +123,12 @@ public:
gridLayout_2->addLayout(horizontalLayout_3, 1, 1, 1, 1);
paperSourceLabel = new QLabel(groupBox_2);
- paperSourceLabel->setObjectName(QStringLiteral("paperSourceLabel"));
+ paperSourceLabel->setObjectName(QString::fromUtf8("paperSourceLabel"));
gridLayout_2->addWidget(paperSourceLabel, 2, 0, 1, 1);
paperSource = new QComboBox(groupBox_2);
- paperSource->setObjectName(QStringLiteral("paperSource"));
+ paperSource->setObjectName(QString::fromUtf8("paperSource"));
gridLayout_2->addWidget(paperSource, 2, 1, 1, 1);
@@ -140,9 +140,9 @@ public:
gridLayout_3->addWidget(groupBox_2, 1, 0, 1, 2);
horizontalLayout_4 = new QHBoxLayout();
- horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4"));
+ horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4"));
unitCombo = new QComboBox(QPageSetupWidget);
- unitCombo->setObjectName(QStringLiteral("unitCombo"));
+ unitCombo->setObjectName(QString::fromUtf8("unitCombo"));
horizontalLayout_4->addWidget(unitCombo);
@@ -154,32 +154,32 @@ public:
gridLayout_3->addLayout(horizontalLayout_4, 0, 0, 1, 2);
preview = new QWidget(QPageSetupWidget);
- preview->setObjectName(QStringLiteral("preview"));
+ preview->setObjectName(QString::fromUtf8("preview"));
gridLayout_3->addWidget(preview, 2, 1, 2, 1);
groupBox_3 = new QGroupBox(QPageSetupWidget);
- groupBox_3->setObjectName(QStringLiteral("groupBox_3"));
+ groupBox_3->setObjectName(QString::fromUtf8("groupBox_3"));
verticalLayout = new QVBoxLayout(groupBox_3);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
portrait = new QRadioButton(groupBox_3);
- portrait->setObjectName(QStringLiteral("portrait"));
+ portrait->setObjectName(QString::fromUtf8("portrait"));
portrait->setChecked(true);
verticalLayout->addWidget(portrait);
landscape = new QRadioButton(groupBox_3);
- landscape->setObjectName(QStringLiteral("landscape"));
+ landscape->setObjectName(QString::fromUtf8("landscape"));
verticalLayout->addWidget(landscape);
reverseLandscape = new QRadioButton(groupBox_3);
- reverseLandscape->setObjectName(QStringLiteral("reverseLandscape"));
+ reverseLandscape->setObjectName(QString::fromUtf8("reverseLandscape"));
verticalLayout->addWidget(reverseLandscape);
reversePortrait = new QRadioButton(groupBox_3);
- reversePortrait->setObjectName(QStringLiteral("reversePortrait"));
+ reversePortrait->setObjectName(QString::fromUtf8("reversePortrait"));
verticalLayout->addWidget(reversePortrait);
@@ -191,26 +191,26 @@ public:
gridLayout_3->addWidget(groupBox_3, 2, 0, 1, 1);
groupBox = new QGroupBox(QPageSetupWidget);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
horizontalLayout_2 = new QHBoxLayout(groupBox);
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
gridLayout = new QGridLayout();
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
topMargin = new QDoubleSpinBox(groupBox);
- topMargin->setObjectName(QStringLiteral("topMargin"));
+ topMargin->setObjectName(QString::fromUtf8("topMargin"));
topMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
topMargin->setMaximum(999.99);
gridLayout->addWidget(topMargin, 0, 1, 1, 1);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
horizontalSpacer_7 = new QSpacerItem(0, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout->addItem(horizontalSpacer_7);
leftMargin = new QDoubleSpinBox(groupBox);
- leftMargin->setObjectName(QStringLiteral("leftMargin"));
+ leftMargin->setObjectName(QString::fromUtf8("leftMargin"));
leftMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
leftMargin->setMaximum(999.99);
@@ -221,7 +221,7 @@ public:
horizontalLayout->addItem(horizontalSpacer);
rightMargin = new QDoubleSpinBox(groupBox);
- rightMargin->setObjectName(QStringLiteral("rightMargin"));
+ rightMargin->setObjectName(QString::fromUtf8("rightMargin"));
rightMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
rightMargin->setMaximum(999.99);
@@ -239,7 +239,7 @@ public:
gridLayout->addItem(horizontalSpacer_2, 0, 2, 1, 1);
bottomMargin = new QDoubleSpinBox(groupBox);
- bottomMargin->setObjectName(QStringLiteral("bottomMargin"));
+ bottomMargin->setObjectName(QString::fromUtf8("bottomMargin"));
bottomMargin->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
bottomMargin->setMaximum(999.99);
@@ -256,11 +256,11 @@ public:
gridLayout_3->addWidget(groupBox, 3, 0, 1, 1);
pagesPerSheetButtonGroup = new QGroupBox(QPageSetupWidget);
- pagesPerSheetButtonGroup->setObjectName(QStringLiteral("pagesPerSheetButtonGroup"));
+ pagesPerSheetButtonGroup->setObjectName(QString::fromUtf8("pagesPerSheetButtonGroup"));
gridLayout_4 = new QGridLayout(pagesPerSheetButtonGroup);
- gridLayout_4->setObjectName(QStringLiteral("gridLayout_4"));
+ gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));
pagesPerSheetCombo = new QComboBox(pagesPerSheetButtonGroup);
- pagesPerSheetCombo->setObjectName(QStringLiteral("pagesPerSheetCombo"));
+ pagesPerSheetCombo->setObjectName(QString::fromUtf8("pagesPerSheetCombo"));
gridLayout_4->addWidget(pagesPerSheetCombo, 0, 1, 1, 1);
@@ -269,17 +269,17 @@ public:
gridLayout_4->addItem(horizontalSpacer_6, 0, 2, 1, 1);
label = new QLabel(pagesPerSheetButtonGroup);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout_4->addWidget(label, 1, 0, 1, 1);
pagesPerSheetLayoutCombo = new QComboBox(pagesPerSheetButtonGroup);
- pagesPerSheetLayoutCombo->setObjectName(QStringLiteral("pagesPerSheetLayoutCombo"));
+ pagesPerSheetLayoutCombo->setObjectName(QString::fromUtf8("pagesPerSheetLayoutCombo"));
gridLayout_4->addWidget(pagesPerSheetLayoutCombo, 1, 1, 1, 1);
label_2 = new QLabel(pagesPerSheetButtonGroup);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout_4->addWidget(label_2, 0, 0, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h b/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h
index baa9bbec38..8626a9fc3c 100644
--- a/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h
+++ b/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h
@@ -36,30 +36,30 @@ public:
void setupUi(QWidget *QPrintPropertiesWidget)
{
if (QPrintPropertiesWidget->objectName().isEmpty())
- QPrintPropertiesWidget->setObjectName(QStringLiteral("QPrintPropertiesWidget"));
+ QPrintPropertiesWidget->setObjectName(QString::fromUtf8("QPrintPropertiesWidget"));
QPrintPropertiesWidget->resize(396, 288);
verticalLayout_4 = new QVBoxLayout(QPrintPropertiesWidget);
verticalLayout_4->setContentsMargins(0, 0, 0, 0);
- verticalLayout_4->setObjectName(QStringLiteral("verticalLayout_4"));
+ verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4"));
tabs = new QTabWidget(QPrintPropertiesWidget);
- tabs->setObjectName(QStringLiteral("tabs"));
+ tabs->setObjectName(QString::fromUtf8("tabs"));
tabPage = new QWidget();
- tabPage->setObjectName(QStringLiteral("tabPage"));
+ tabPage->setObjectName(QString::fromUtf8("tabPage"));
tabPage->setGeometry(QRect(0, 0, 392, 261));
horizontalLayout = new QHBoxLayout(tabPage);
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
pageSetup = new QPageSetupWidget(tabPage);
- pageSetup->setObjectName(QStringLiteral("pageSetup"));
+ pageSetup->setObjectName(QString::fromUtf8("pageSetup"));
horizontalLayout->addWidget(pageSetup);
tabs->addTab(tabPage, QString());
cupsPropertiesPage = new QWidget();
- cupsPropertiesPage->setObjectName(QStringLiteral("cupsPropertiesPage"));
+ cupsPropertiesPage->setObjectName(QString::fromUtf8("cupsPropertiesPage"));
horizontalLayout_2 = new QHBoxLayout(cupsPropertiesPage);
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
treeView = new QTreeView(cupsPropertiesPage);
- treeView->setObjectName(QStringLiteral("treeView"));
+ treeView->setObjectName(QString::fromUtf8("treeView"));
treeView->setAlternatingRowColors(true);
horizontalLayout_2->addWidget(treeView);
diff --git a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h
index a0f16c998b..656b5f9deb 100644
--- a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h
+++ b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h
@@ -70,20 +70,20 @@ public:
void setupUi(QWidget *QPrintSettingsOutput)
{
if (QPrintSettingsOutput->objectName().isEmpty())
- QPrintSettingsOutput->setObjectName(QStringLiteral("QPrintSettingsOutput"));
+ QPrintSettingsOutput->setObjectName(QString::fromUtf8("QPrintSettingsOutput"));
QPrintSettingsOutput->resize(416, 166);
horizontalLayout_2 = new QHBoxLayout(QPrintSettingsOutput);
horizontalLayout_2->setContentsMargins(0, 0, 0, 0);
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
tabs = new QTabWidget(QPrintSettingsOutput);
- tabs->setObjectName(QStringLiteral("tabs"));
+ tabs->setObjectName(QString::fromUtf8("tabs"));
copiesTab = new QWidget();
- copiesTab->setObjectName(QStringLiteral("copiesTab"));
+ copiesTab->setObjectName(QString::fromUtf8("copiesTab"));
copiesTab->setGeometry(QRect(0, 0, 412, 139));
horizontalLayout = new QHBoxLayout(copiesTab);
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
gbPrintRange = new QGroupBox(copiesTab);
- gbPrintRange->setObjectName(QStringLiteral("gbPrintRange"));
+ gbPrintRange->setObjectName(QString::fromUtf8("gbPrintRange"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -92,9 +92,9 @@ public:
_3 = new QVBoxLayout(gbPrintRange);
_3->setSpacing(4);
_3->setContentsMargins(6, 6, 6, 6);
- _3->setObjectName(QStringLiteral("_3"));
+ _3->setObjectName(QString::fromUtf8("_3"));
printAll = new QRadioButton(gbPrintRange);
- printAll->setObjectName(QStringLiteral("printAll"));
+ printAll->setObjectName(QString::fromUtf8("printAll"));
printAll->setChecked(true);
_3->addWidget(printAll);
@@ -104,14 +104,14 @@ public:
_4->setSpacing(6);
#endif
_4->setContentsMargins(0, 0, 0, 0);
- _4->setObjectName(QStringLiteral("_4"));
+ _4->setObjectName(QString::fromUtf8("_4"));
printRange = new QRadioButton(gbPrintRange);
- printRange->setObjectName(QStringLiteral("printRange"));
+ printRange->setObjectName(QString::fromUtf8("printRange"));
_4->addWidget(printRange);
from = new QSpinBox(gbPrintRange);
- from->setObjectName(QStringLiteral("from"));
+ from->setObjectName(QString::fromUtf8("from"));
from->setEnabled(false);
from->setMinimum(1);
from->setMaximum(999);
@@ -119,12 +119,12 @@ public:
_4->addWidget(from);
label_3 = new QLabel(gbPrintRange);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
_4->addWidget(label_3);
to = new QSpinBox(gbPrintRange);
- to->setObjectName(QStringLiteral("to"));
+ to->setObjectName(QString::fromUtf8("to"));
to->setEnabled(false);
to->setMinimum(1);
to->setMaximum(999);
@@ -139,7 +139,7 @@ public:
_3->addLayout(_4);
printSelection = new QRadioButton(gbPrintRange);
- printSelection->setObjectName(QStringLiteral("printSelection"));
+ printSelection->setObjectName(QString::fromUtf8("printSelection"));
_3->addWidget(printSelection);
@@ -151,16 +151,16 @@ public:
horizontalLayout->addWidget(gbPrintRange);
groupBox = new QGroupBox(copiesTab);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
gridLayout = new QGridLayout(groupBox);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
copies = new QSpinBox(groupBox);
- copies->setObjectName(QStringLiteral("copies"));
+ copies->setObjectName(QString::fromUtf8("copies"));
copies->setMinimum(1);
copies->setMaximum(999);
@@ -171,12 +171,12 @@ public:
gridLayout->addItem(horizontalSpacer, 0, 3, 1, 1);
collate = new QCheckBox(groupBox);
- collate->setObjectName(QStringLiteral("collate"));
+ collate->setObjectName(QString::fromUtf8("collate"));
gridLayout->addWidget(collate, 1, 0, 1, 2);
outputIcon = new QLabel(groupBox);
- outputIcon->setObjectName(QStringLiteral("outputIcon"));
+ outputIcon->setObjectName(QString::fromUtf8("outputIcon"));
QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Ignored);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -186,7 +186,7 @@ public:
gridLayout->addWidget(outputIcon, 1, 2, 2, 2);
reverse = new QCheckBox(groupBox);
- reverse->setObjectName(QStringLiteral("reverse"));
+ reverse->setObjectName(QString::fromUtf8("reverse"));
gridLayout->addWidget(reverse, 2, 0, 1, 2);
@@ -199,30 +199,30 @@ public:
tabs->addTab(copiesTab, QString());
optionsTab = new QWidget();
- optionsTab->setObjectName(QStringLiteral("optionsTab"));
+ optionsTab->setObjectName(QString::fromUtf8("optionsTab"));
optionsTab->setGeometry(QRect(0, 0, 412, 139));
gridLayout_2 = new QGridLayout(optionsTab);
- gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
+ gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
colorMode = new QGroupBox(optionsTab);
- colorMode->setObjectName(QStringLiteral("colorMode"));
+ colorMode->setObjectName(QString::fromUtf8("colorMode"));
gridLayout_4 = new QGridLayout(colorMode);
- gridLayout_4->setObjectName(QStringLiteral("gridLayout_4"));
+ gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));
verticalSpacer_6 = new QSpacerItem(1, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
gridLayout_4->addItem(verticalSpacer_6, 2, 0, 1, 1);
color = new QRadioButton(colorMode);
- color->setObjectName(QStringLiteral("color"));
+ color->setObjectName(QString::fromUtf8("color"));
gridLayout_4->addWidget(color, 0, 0, 1, 1);
colorIcon = new QLabel(colorMode);
- colorIcon->setObjectName(QStringLiteral("colorIcon"));
+ colorIcon->setObjectName(QString::fromUtf8("colorIcon"));
gridLayout_4->addWidget(colorIcon, 0, 1, 3, 1);
grayscale = new QRadioButton(colorMode);
- grayscale->setObjectName(QStringLiteral("grayscale"));
+ grayscale->setObjectName(QString::fromUtf8("grayscale"));
gridLayout_4->addWidget(grayscale, 1, 0, 1, 1);
@@ -230,22 +230,22 @@ public:
gridLayout_2->addWidget(colorMode, 0, 1, 1, 1);
duplex = new QGroupBox(optionsTab);
- duplex->setObjectName(QStringLiteral("duplex"));
+ duplex->setObjectName(QString::fromUtf8("duplex"));
verticalLayout = new QVBoxLayout(duplex);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
noDuplex = new QRadioButton(duplex);
- noDuplex->setObjectName(QStringLiteral("noDuplex"));
+ noDuplex->setObjectName(QString::fromUtf8("noDuplex"));
noDuplex->setChecked(true);
verticalLayout->addWidget(noDuplex);
duplexLong = new QRadioButton(duplex);
- duplexLong->setObjectName(QStringLiteral("duplexLong"));
+ duplexLong->setObjectName(QString::fromUtf8("duplexLong"));
verticalLayout->addWidget(duplexLong);
duplexShort = new QRadioButton(duplex);
- duplexShort->setObjectName(QStringLiteral("duplexShort"));
+ duplexShort->setObjectName(QString::fromUtf8("duplexShort"));
verticalLayout->addWidget(duplexShort);
diff --git a/tests/auto/tools/uic/baseline/qprintwidget.ui.h b/tests/auto/tools/uic/baseline/qprintwidget.ui.h
index 73fa2cfcfa..04b05143c6 100644
--- a/tests/auto/tools/uic/baseline/qprintwidget.ui.h
+++ b/tests/auto/tools/uic/baseline/qprintwidget.ui.h
@@ -46,22 +46,22 @@ public:
void setupUi(QWidget *QPrintWidget)
{
if (QPrintWidget->objectName().isEmpty())
- QPrintWidget->setObjectName(QStringLiteral("QPrintWidget"));
+ QPrintWidget->setObjectName(QString::fromUtf8("QPrintWidget"));
QPrintWidget->resize(443, 175);
horizontalLayout_2 = new QHBoxLayout(QPrintWidget);
horizontalLayout_2->setContentsMargins(0, 0, 0, 0);
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
printerGroup = new QGroupBox(QPrintWidget);
- printerGroup->setObjectName(QStringLiteral("printerGroup"));
+ printerGroup->setObjectName(QString::fromUtf8("printerGroup"));
gridLayout = new QGridLayout(printerGroup);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(printerGroup);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
printers = new QComboBox(printerGroup);
- printers->setObjectName(QStringLiteral("printers"));
+ printers->setObjectName(QString::fromUtf8("printers"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(3);
sizePolicy.setVerticalStretch(0);
@@ -71,7 +71,7 @@ public:
gridLayout->addWidget(printers, 0, 1, 1, 1);
properties = new QPushButton(printerGroup);
- properties->setObjectName(QStringLiteral("properties"));
+ properties->setObjectName(QString::fromUtf8("properties"));
QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(1);
sizePolicy1.setVerticalStretch(0);
@@ -81,44 +81,44 @@ public:
gridLayout->addWidget(properties, 0, 2, 1, 1);
label_2 = new QLabel(printerGroup);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout->addWidget(label_2, 1, 0, 1, 1);
location = new QLabel(printerGroup);
- location->setObjectName(QStringLiteral("location"));
+ location->setObjectName(QString::fromUtf8("location"));
gridLayout->addWidget(location, 1, 1, 1, 1);
preview = new QCheckBox(printerGroup);
- preview->setObjectName(QStringLiteral("preview"));
+ preview->setObjectName(QString::fromUtf8("preview"));
gridLayout->addWidget(preview, 1, 2, 1, 1);
label_3 = new QLabel(printerGroup);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout->addWidget(label_3, 2, 0, 1, 1);
type = new QLabel(printerGroup);
- type->setObjectName(QStringLiteral("type"));
+ type->setObjectName(QString::fromUtf8("type"));
gridLayout->addWidget(type, 2, 1, 1, 1);
lOutput = new QLabel(printerGroup);
- lOutput->setObjectName(QStringLiteral("lOutput"));
+ lOutput->setObjectName(QString::fromUtf8("lOutput"));
gridLayout->addWidget(lOutput, 3, 0, 1, 1);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
filename = new QLineEdit(printerGroup);
- filename->setObjectName(QStringLiteral("filename"));
+ filename->setObjectName(QString::fromUtf8("filename"));
horizontalLayout->addWidget(filename);
fileBrowser = new QToolButton(printerGroup);
- fileBrowser->setObjectName(QStringLiteral("fileBrowser"));
+ fileBrowser->setObjectName(QString::fromUtf8("fileBrowser"));
horizontalLayout->addWidget(fileBrowser);
diff --git a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h
index 5ed3ff1acd..2131bc6d9b 100644
--- a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h
+++ b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h
@@ -55,44 +55,44 @@ public:
void setupUi(QDialog *QSqlConnectionDialogUi)
{
if (QSqlConnectionDialogUi->objectName().isEmpty())
- QSqlConnectionDialogUi->setObjectName(QStringLiteral("QSqlConnectionDialogUi"));
+ QSqlConnectionDialogUi->setObjectName(QString::fromUtf8("QSqlConnectionDialogUi"));
QSqlConnectionDialogUi->resize(315, 302);
vboxLayout = new QVBoxLayout(QSqlConnectionDialogUi);
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(8, 8, 8, 8);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
connGroupBox = new QGroupBox(QSqlConnectionDialogUi);
- connGroupBox->setObjectName(QStringLiteral("connGroupBox"));
+ connGroupBox->setObjectName(QString::fromUtf8("connGroupBox"));
gridLayout = new QGridLayout(connGroupBox);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
#endif
gridLayout->setContentsMargins(8, 8, 8, 8);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
comboDriver = new QComboBox(connGroupBox);
- comboDriver->setObjectName(QStringLiteral("comboDriver"));
+ comboDriver->setObjectName(QString::fromUtf8("comboDriver"));
gridLayout->addWidget(comboDriver, 0, 1, 1, 1);
textLabel4 = new QLabel(connGroupBox);
- textLabel4->setObjectName(QStringLiteral("textLabel4"));
+ textLabel4->setObjectName(QString::fromUtf8("textLabel4"));
gridLayout->addWidget(textLabel4, 2, 0, 1, 1);
textLabel2 = new QLabel(connGroupBox);
- textLabel2->setObjectName(QStringLiteral("textLabel2"));
+ textLabel2->setObjectName(QString::fromUtf8("textLabel2"));
gridLayout->addWidget(textLabel2, 0, 0, 1, 1);
editDatabase = new QLineEdit(connGroupBox);
- editDatabase->setObjectName(QStringLiteral("editDatabase"));
+ editDatabase->setObjectName(QString::fromUtf8("editDatabase"));
gridLayout->addWidget(editDatabase, 1, 1, 1, 1);
portSpinBox = new QSpinBox(connGroupBox);
- portSpinBox->setObjectName(QStringLiteral("portSpinBox"));
+ portSpinBox->setObjectName(QString::fromUtf8("portSpinBox"));
portSpinBox->setMaximum(65535);
portSpinBox->setMinimum(-1);
portSpinBox->setValue(-1);
@@ -100,38 +100,38 @@ public:
gridLayout->addWidget(portSpinBox, 5, 1, 1, 1);
textLabel3 = new QLabel(connGroupBox);
- textLabel3->setObjectName(QStringLiteral("textLabel3"));
+ textLabel3->setObjectName(QString::fromUtf8("textLabel3"));
gridLayout->addWidget(textLabel3, 1, 0, 1, 1);
editPassword = new QLineEdit(connGroupBox);
- editPassword->setObjectName(QStringLiteral("editPassword"));
+ editPassword->setObjectName(QString::fromUtf8("editPassword"));
editPassword->setEchoMode(QLineEdit::Password);
gridLayout->addWidget(editPassword, 3, 1, 1, 1);
editUsername = new QLineEdit(connGroupBox);
- editUsername->setObjectName(QStringLiteral("editUsername"));
+ editUsername->setObjectName(QString::fromUtf8("editUsername"));
gridLayout->addWidget(editUsername, 2, 1, 1, 1);
editHostname = new QLineEdit(connGroupBox);
- editHostname->setObjectName(QStringLiteral("editHostname"));
+ editHostname->setObjectName(QString::fromUtf8("editHostname"));
gridLayout->addWidget(editHostname, 4, 1, 1, 1);
textLabel5 = new QLabel(connGroupBox);
- textLabel5->setObjectName(QStringLiteral("textLabel5"));
+ textLabel5->setObjectName(QString::fromUtf8("textLabel5"));
gridLayout->addWidget(textLabel5, 4, 0, 1, 1);
textLabel5_2 = new QLabel(connGroupBox);
- textLabel5_2->setObjectName(QStringLiteral("textLabel5_2"));
+ textLabel5_2->setObjectName(QString::fromUtf8("textLabel5_2"));
gridLayout->addWidget(textLabel5_2, 5, 0, 1, 1);
textLabel4_2 = new QLabel(connGroupBox);
- textLabel4_2->setObjectName(QStringLiteral("textLabel4_2"));
+ textLabel4_2->setObjectName(QString::fromUtf8("textLabel4_2"));
gridLayout->addWidget(textLabel4_2, 3, 0, 1, 1);
@@ -143,13 +143,13 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(spacerItem);
dbCheckBox = new QCheckBox(QSqlConnectionDialogUi);
- dbCheckBox->setObjectName(QStringLiteral("dbCheckBox"));
+ dbCheckBox->setObjectName(QString::fromUtf8("dbCheckBox"));
hboxLayout->addWidget(dbCheckBox);
@@ -161,18 +161,18 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
spacerItem1 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout1->addItem(spacerItem1);
okButton = new QPushButton(QSqlConnectionDialogUi);
- okButton->setObjectName(QStringLiteral("okButton"));
+ okButton->setObjectName(QString::fromUtf8("okButton"));
hboxLayout1->addWidget(okButton);
cancelButton = new QPushButton(QSqlConnectionDialogUi);
- cancelButton->setObjectName(QStringLiteral("cancelButton"));
+ cancelButton->setObjectName(QString::fromUtf8("cancelButton"));
hboxLayout1->addWidget(cancelButton);
diff --git a/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h b/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h
index 53fd59295b..805f70e60d 100644
--- a/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h
@@ -58,12 +58,12 @@ public:
void setupUi(QDialog *QtGradientDialog)
{
if (QtGradientDialog->objectName().isEmpty())
- QtGradientDialog->setObjectName(QStringLiteral("QtGradientDialog"));
+ QtGradientDialog->setObjectName(QString::fromUtf8("QtGradientDialog"));
QtGradientDialog->resize(178, 81);
vboxLayout = new QVBoxLayout(QtGradientDialog);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
gradientEditor = new QtGradientEditor(QtGradientDialog);
- gradientEditor->setObjectName(QStringLiteral("gradientEditor"));
+ gradientEditor->setObjectName(QString::fromUtf8("gradientEditor"));
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -73,7 +73,7 @@ public:
vboxLayout->addWidget(gradientEditor);
buttonBox = new QDialogButtonBox(QtGradientDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h b/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h
index 6e63c4863d..21dc9551d0 100644
--- a/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h
+++ b/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h
@@ -145,10 +145,10 @@ public:
void setupUi(QWidget *QtGradientEditor)
{
if (QtGradientEditor->objectName().isEmpty())
- QtGradientEditor->setObjectName(QStringLiteral("QtGradientEditor"));
+ QtGradientEditor->setObjectName(QString::fromUtf8("QtGradientEditor"));
QtGradientEditor->resize(364, 518);
frame = new QFrame(QtGradientEditor);
- frame->setObjectName(QStringLiteral("frame"));
+ frame->setObjectName(QString::fromUtf8("frame"));
frame->setGeometry(QRect(10, 69, 193, 150));
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
sizePolicy.setHorizontalStretch(0);
@@ -159,73 +159,73 @@ public:
frame->setFrameShadow(QFrame::Raised);
vboxLayout = new QVBoxLayout(frame);
vboxLayout->setSpacing(6);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout->setContentsMargins(0, 0, 0, 0);
gradientWidget = new QtGradientWidget(frame);
- gradientWidget->setObjectName(QStringLiteral("gradientWidget"));
+ gradientWidget->setObjectName(QString::fromUtf8("gradientWidget"));
sizePolicy.setHeightForWidth(gradientWidget->sizePolicy().hasHeightForWidth());
gradientWidget->setSizePolicy(sizePolicy);
vboxLayout->addWidget(gradientWidget);
label1 = new QLabel(QtGradientEditor);
- label1->setObjectName(QStringLiteral("label1"));
+ label1->setObjectName(QString::fromUtf8("label1"));
label1->setGeometry(QRect(209, 69, 64, 23));
spinBox1 = new QDoubleSpinBox(QtGradientEditor);
- spinBox1->setObjectName(QStringLiteral("spinBox1"));
+ spinBox1->setObjectName(QString::fromUtf8("spinBox1"));
spinBox1->setGeometry(QRect(279, 69, 73, 23));
spinBox1->setKeyboardTracking(false);
spinBox1->setDecimals(3);
spinBox1->setMaximum(1);
spinBox1->setSingleStep(0.01);
label2 = new QLabel(QtGradientEditor);
- label2->setObjectName(QStringLiteral("label2"));
+ label2->setObjectName(QString::fromUtf8("label2"));
label2->setGeometry(QRect(209, 99, 64, 23));
spinBox2 = new QDoubleSpinBox(QtGradientEditor);
- spinBox2->setObjectName(QStringLiteral("spinBox2"));
+ spinBox2->setObjectName(QString::fromUtf8("spinBox2"));
spinBox2->setGeometry(QRect(279, 99, 73, 23));
spinBox2->setKeyboardTracking(false);
spinBox2->setDecimals(3);
spinBox2->setMaximum(1);
spinBox2->setSingleStep(0.01);
label3 = new QLabel(QtGradientEditor);
- label3->setObjectName(QStringLiteral("label3"));
+ label3->setObjectName(QString::fromUtf8("label3"));
label3->setGeometry(QRect(209, 129, 64, 23));
spinBox3 = new QDoubleSpinBox(QtGradientEditor);
- spinBox3->setObjectName(QStringLiteral("spinBox3"));
+ spinBox3->setObjectName(QString::fromUtf8("spinBox3"));
spinBox3->setGeometry(QRect(279, 129, 73, 23));
spinBox3->setKeyboardTracking(false);
spinBox3->setDecimals(3);
spinBox3->setMaximum(1);
spinBox3->setSingleStep(0.01);
label4 = new QLabel(QtGradientEditor);
- label4->setObjectName(QStringLiteral("label4"));
+ label4->setObjectName(QString::fromUtf8("label4"));
label4->setGeometry(QRect(209, 159, 64, 23));
spinBox4 = new QDoubleSpinBox(QtGradientEditor);
- spinBox4->setObjectName(QStringLiteral("spinBox4"));
+ spinBox4->setObjectName(QString::fromUtf8("spinBox4"));
spinBox4->setGeometry(QRect(279, 159, 73, 23));
spinBox4->setKeyboardTracking(false);
spinBox4->setDecimals(3);
spinBox4->setMaximum(1);
spinBox4->setSingleStep(0.01);
label5 = new QLabel(QtGradientEditor);
- label5->setObjectName(QStringLiteral("label5"));
+ label5->setObjectName(QString::fromUtf8("label5"));
label5->setGeometry(QRect(209, 189, 64, 23));
spinBox5 = new QDoubleSpinBox(QtGradientEditor);
- spinBox5->setObjectName(QStringLiteral("spinBox5"));
+ spinBox5->setObjectName(QString::fromUtf8("spinBox5"));
spinBox5->setGeometry(QRect(279, 189, 73, 23));
spinBox5->setKeyboardTracking(false);
spinBox5->setDecimals(3);
spinBox5->setMaximum(1);
spinBox5->setSingleStep(0.01);
gradientStopsWidget = new QtGradientStopsWidget(QtGradientEditor);
- gradientStopsWidget->setObjectName(QStringLiteral("gradientStopsWidget"));
+ gradientStopsWidget->setObjectName(QString::fromUtf8("gradientStopsWidget"));
gradientStopsWidget->setGeometry(QRect(10, 225, 193, 67));
zoomLabel = new QLabel(QtGradientEditor);
- zoomLabel->setObjectName(QStringLiteral("zoomLabel"));
+ zoomLabel->setObjectName(QString::fromUtf8("zoomLabel"));
zoomLabel->setGeometry(QRect(209, 231, 64, 23));
zoomAllButton = new QToolButton(QtGradientEditor);
- zoomAllButton->setObjectName(QStringLiteral("zoomAllButton"));
+ zoomAllButton->setObjectName(QString::fromUtf8("zoomAllButton"));
zoomAllButton->setGeometry(QRect(279, 260, 72, 26));
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(0);
@@ -233,15 +233,15 @@ public:
sizePolicy1.setHeightForWidth(zoomAllButton->sizePolicy().hasHeightForWidth());
zoomAllButton->setSizePolicy(sizePolicy1);
positionLabel = new QLabel(QtGradientEditor);
- positionLabel->setObjectName(QStringLiteral("positionLabel"));
+ positionLabel->setObjectName(QString::fromUtf8("positionLabel"));
positionLabel->setGeometry(QRect(209, 304, 64, 23));
hLabel = new QLabel(QtGradientEditor);
- hLabel->setObjectName(QStringLiteral("hLabel"));
+ hLabel->setObjectName(QString::fromUtf8("hLabel"));
hLabel->setGeometry(QRect(10, 335, 32, 18));
sizePolicy1.setHeightForWidth(hLabel->sizePolicy().hasHeightForWidth());
hLabel->setSizePolicy(sizePolicy1);
frame_2 = new QFrame(QtGradientEditor);
- frame_2->setObjectName(QStringLiteral("frame_2"));
+ frame_2->setObjectName(QString::fromUtf8("frame_2"));
frame_2->setGeometry(QRect(48, 333, 155, 23));
QSizePolicy sizePolicy2(QSizePolicy::Ignored, QSizePolicy::Preferred);
sizePolicy2.setHorizontalStretch(0);
@@ -251,10 +251,10 @@ public:
frame_2->setFrameShape(QFrame::StyledPanel);
frame_2->setFrameShadow(QFrame::Raised);
hboxLayout = new QHBoxLayout(frame_2);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
hboxLayout->setContentsMargins(0, 0, 0, 0);
hueColorLine = new QtColorLine(frame_2);
- hueColorLine->setObjectName(QStringLiteral("hueColorLine"));
+ hueColorLine->setObjectName(QString::fromUtf8("hueColorLine"));
QSizePolicy sizePolicy3(QSizePolicy::Expanding, QSizePolicy::Preferred);
sizePolicy3.setHorizontalStretch(0);
sizePolicy3.setVerticalStretch(0);
@@ -264,99 +264,99 @@ public:
hboxLayout->addWidget(hueColorLine);
hueLabel = new QLabel(QtGradientEditor);
- hueLabel->setObjectName(QStringLiteral("hueLabel"));
+ hueLabel->setObjectName(QString::fromUtf8("hueLabel"));
hueLabel->setGeometry(QRect(209, 335, 64, 18));
sizePolicy1.setHeightForWidth(hueLabel->sizePolicy().hasHeightForWidth());
hueLabel->setSizePolicy(sizePolicy1);
sLabel = new QLabel(QtGradientEditor);
- sLabel->setObjectName(QStringLiteral("sLabel"));
+ sLabel->setObjectName(QString::fromUtf8("sLabel"));
sLabel->setGeometry(QRect(10, 364, 32, 18));
sizePolicy1.setHeightForWidth(sLabel->sizePolicy().hasHeightForWidth());
sLabel->setSizePolicy(sizePolicy1);
frame_5 = new QFrame(QtGradientEditor);
- frame_5->setObjectName(QStringLiteral("frame_5"));
+ frame_5->setObjectName(QString::fromUtf8("frame_5"));
frame_5->setGeometry(QRect(48, 362, 155, 23));
sizePolicy2.setHeightForWidth(frame_5->sizePolicy().hasHeightForWidth());
frame_5->setSizePolicy(sizePolicy2);
frame_5->setFrameShape(QFrame::StyledPanel);
frame_5->setFrameShadow(QFrame::Raised);
hboxLayout1 = new QHBoxLayout(frame_5);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
hboxLayout1->setContentsMargins(0, 0, 0, 0);
saturationColorLine = new QtColorLine(frame_5);
- saturationColorLine->setObjectName(QStringLiteral("saturationColorLine"));
+ saturationColorLine->setObjectName(QString::fromUtf8("saturationColorLine"));
sizePolicy3.setHeightForWidth(saturationColorLine->sizePolicy().hasHeightForWidth());
saturationColorLine->setSizePolicy(sizePolicy3);
hboxLayout1->addWidget(saturationColorLine);
saturationLabel = new QLabel(QtGradientEditor);
- saturationLabel->setObjectName(QStringLiteral("saturationLabel"));
+ saturationLabel->setObjectName(QString::fromUtf8("saturationLabel"));
saturationLabel->setGeometry(QRect(209, 364, 64, 18));
sizePolicy1.setHeightForWidth(saturationLabel->sizePolicy().hasHeightForWidth());
saturationLabel->setSizePolicy(sizePolicy1);
vLabel = new QLabel(QtGradientEditor);
- vLabel->setObjectName(QStringLiteral("vLabel"));
+ vLabel->setObjectName(QString::fromUtf8("vLabel"));
vLabel->setGeometry(QRect(10, 393, 32, 18));
sizePolicy1.setHeightForWidth(vLabel->sizePolicy().hasHeightForWidth());
vLabel->setSizePolicy(sizePolicy1);
frame_3 = new QFrame(QtGradientEditor);
- frame_3->setObjectName(QStringLiteral("frame_3"));
+ frame_3->setObjectName(QString::fromUtf8("frame_3"));
frame_3->setGeometry(QRect(48, 391, 155, 23));
sizePolicy2.setHeightForWidth(frame_3->sizePolicy().hasHeightForWidth());
frame_3->setSizePolicy(sizePolicy2);
frame_3->setFrameShape(QFrame::StyledPanel);
frame_3->setFrameShadow(QFrame::Raised);
hboxLayout2 = new QHBoxLayout(frame_3);
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
hboxLayout2->setContentsMargins(0, 0, 0, 0);
valueColorLine = new QtColorLine(frame_3);
- valueColorLine->setObjectName(QStringLiteral("valueColorLine"));
+ valueColorLine->setObjectName(QString::fromUtf8("valueColorLine"));
sizePolicy3.setHeightForWidth(valueColorLine->sizePolicy().hasHeightForWidth());
valueColorLine->setSizePolicy(sizePolicy3);
hboxLayout2->addWidget(valueColorLine);
valueLabel = new QLabel(QtGradientEditor);
- valueLabel->setObjectName(QStringLiteral("valueLabel"));
+ valueLabel->setObjectName(QString::fromUtf8("valueLabel"));
valueLabel->setGeometry(QRect(209, 393, 64, 18));
sizePolicy1.setHeightForWidth(valueLabel->sizePolicy().hasHeightForWidth());
valueLabel->setSizePolicy(sizePolicy1);
aLabel = new QLabel(QtGradientEditor);
- aLabel->setObjectName(QStringLiteral("aLabel"));
+ aLabel->setObjectName(QString::fromUtf8("aLabel"));
aLabel->setGeometry(QRect(10, 422, 32, 18));
sizePolicy1.setHeightForWidth(aLabel->sizePolicy().hasHeightForWidth());
aLabel->setSizePolicy(sizePolicy1);
frame_4 = new QFrame(QtGradientEditor);
- frame_4->setObjectName(QStringLiteral("frame_4"));
+ frame_4->setObjectName(QString::fromUtf8("frame_4"));
frame_4->setGeometry(QRect(48, 420, 155, 23));
sizePolicy2.setHeightForWidth(frame_4->sizePolicy().hasHeightForWidth());
frame_4->setSizePolicy(sizePolicy2);
frame_4->setFrameShape(QFrame::StyledPanel);
frame_4->setFrameShadow(QFrame::Raised);
hboxLayout3 = new QHBoxLayout(frame_4);
- hboxLayout3->setObjectName(QStringLiteral("hboxLayout3"));
+ hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3"));
hboxLayout3->setContentsMargins(0, 0, 0, 0);
alphaColorLine = new QtColorLine(frame_4);
- alphaColorLine->setObjectName(QStringLiteral("alphaColorLine"));
+ alphaColorLine->setObjectName(QString::fromUtf8("alphaColorLine"));
sizePolicy3.setHeightForWidth(alphaColorLine->sizePolicy().hasHeightForWidth());
alphaColorLine->setSizePolicy(sizePolicy3);
hboxLayout3->addWidget(alphaColorLine);
alphaLabel = new QLabel(QtGradientEditor);
- alphaLabel->setObjectName(QStringLiteral("alphaLabel"));
+ alphaLabel->setObjectName(QString::fromUtf8("alphaLabel"));
alphaLabel->setGeometry(QRect(209, 422, 64, 18));
sizePolicy1.setHeightForWidth(alphaLabel->sizePolicy().hasHeightForWidth());
alphaLabel->setSizePolicy(sizePolicy1);
typeComboBox = new QComboBox(QtGradientEditor);
- typeComboBox->setObjectName(QStringLiteral("typeComboBox"));
+ typeComboBox->setObjectName(QString::fromUtf8("typeComboBox"));
typeComboBox->setGeometry(QRect(10, 40, 79, 22));
spreadComboBox = new QComboBox(QtGradientEditor);
- spreadComboBox->setObjectName(QStringLiteral("spreadComboBox"));
+ spreadComboBox->setObjectName(QString::fromUtf8("spreadComboBox"));
spreadComboBox->setGeometry(QRect(96, 40, 72, 22));
colorLabel = new QLabel(QtGradientEditor);
- colorLabel->setObjectName(QStringLiteral("colorLabel"));
+ colorLabel->setObjectName(QString::fromUtf8("colorLabel"));
colorLabel->setGeometry(QRect(10, 298, 32, 29));
QSizePolicy sizePolicy4(QSizePolicy::Fixed, QSizePolicy::Preferred);
sizePolicy4.setHorizontalStretch(0);
@@ -364,10 +364,10 @@ public:
sizePolicy4.setHeightForWidth(colorLabel->sizePolicy().hasHeightForWidth());
colorLabel->setSizePolicy(sizePolicy4);
colorButton = new QtColorButton(QtGradientEditor);
- colorButton->setObjectName(QStringLiteral("colorButton"));
+ colorButton->setObjectName(QString::fromUtf8("colorButton"));
colorButton->setGeometry(QRect(48, 300, 26, 25));
hsvRadioButton = new QRadioButton(QtGradientEditor);
- hsvRadioButton->setObjectName(QStringLiteral("hsvRadioButton"));
+ hsvRadioButton->setObjectName(QString::fromUtf8("hsvRadioButton"));
hsvRadioButton->setGeometry(QRect(80, 301, 49, 23));
QSizePolicy sizePolicy5(QSizePolicy::Fixed, QSizePolicy::Fixed);
sizePolicy5.setHorizontalStretch(0);
@@ -376,18 +376,18 @@ public:
hsvRadioButton->setSizePolicy(sizePolicy5);
hsvRadioButton->setChecked(true);
rgbRadioButton = new QRadioButton(QtGradientEditor);
- rgbRadioButton->setObjectName(QStringLiteral("rgbRadioButton"));
+ rgbRadioButton->setObjectName(QString::fromUtf8("rgbRadioButton"));
rgbRadioButton->setGeometry(QRect(135, 301, 49, 23));
sizePolicy5.setHeightForWidth(rgbRadioButton->sizePolicy().hasHeightForWidth());
rgbRadioButton->setSizePolicy(sizePolicy5);
positionWidget = new QWidget(QtGradientEditor);
- positionWidget->setObjectName(QStringLiteral("positionWidget"));
+ positionWidget->setObjectName(QString::fromUtf8("positionWidget"));
positionWidget->setGeometry(QRect(279, 304, 73, 23));
vboxLayout1 = new QVBoxLayout(positionWidget);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
vboxLayout1->setContentsMargins(0, 0, 0, 0);
positionSpinBox = new QDoubleSpinBox(positionWidget);
- positionSpinBox->setObjectName(QStringLiteral("positionSpinBox"));
+ positionSpinBox->setObjectName(QString::fromUtf8("positionSpinBox"));
positionSpinBox->setKeyboardTracking(false);
positionSpinBox->setDecimals(3);
positionSpinBox->setMinimum(0);
@@ -398,65 +398,65 @@ public:
vboxLayout1->addWidget(positionSpinBox);
hueWidget = new QWidget(QtGradientEditor);
- hueWidget->setObjectName(QStringLiteral("hueWidget"));
+ hueWidget->setObjectName(QString::fromUtf8("hueWidget"));
hueWidget->setGeometry(QRect(279, 333, 73, 23));
vboxLayout2 = new QVBoxLayout(hueWidget);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
vboxLayout2->setContentsMargins(0, 0, 0, 0);
hueSpinBox = new QSpinBox(hueWidget);
- hueSpinBox->setObjectName(QStringLiteral("hueSpinBox"));
+ hueSpinBox->setObjectName(QString::fromUtf8("hueSpinBox"));
hueSpinBox->setKeyboardTracking(false);
hueSpinBox->setMaximum(359);
vboxLayout2->addWidget(hueSpinBox);
saturationWidget = new QWidget(QtGradientEditor);
- saturationWidget->setObjectName(QStringLiteral("saturationWidget"));
+ saturationWidget->setObjectName(QString::fromUtf8("saturationWidget"));
saturationWidget->setGeometry(QRect(279, 362, 73, 23));
vboxLayout3 = new QVBoxLayout(saturationWidget);
- vboxLayout3->setObjectName(QStringLiteral("vboxLayout3"));
+ vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3"));
vboxLayout3->setContentsMargins(0, 0, 0, 0);
saturationSpinBox = new QSpinBox(saturationWidget);
- saturationSpinBox->setObjectName(QStringLiteral("saturationSpinBox"));
+ saturationSpinBox->setObjectName(QString::fromUtf8("saturationSpinBox"));
saturationSpinBox->setKeyboardTracking(false);
saturationSpinBox->setMaximum(255);
vboxLayout3->addWidget(saturationSpinBox);
valueWidget = new QWidget(QtGradientEditor);
- valueWidget->setObjectName(QStringLiteral("valueWidget"));
+ valueWidget->setObjectName(QString::fromUtf8("valueWidget"));
valueWidget->setGeometry(QRect(279, 391, 73, 23));
vboxLayout4 = new QVBoxLayout(valueWidget);
- vboxLayout4->setObjectName(QStringLiteral("vboxLayout4"));
+ vboxLayout4->setObjectName(QString::fromUtf8("vboxLayout4"));
vboxLayout4->setContentsMargins(0, 0, 0, 0);
valueSpinBox = new QSpinBox(valueWidget);
- valueSpinBox->setObjectName(QStringLiteral("valueSpinBox"));
+ valueSpinBox->setObjectName(QString::fromUtf8("valueSpinBox"));
valueSpinBox->setKeyboardTracking(false);
valueSpinBox->setMaximum(255);
vboxLayout4->addWidget(valueSpinBox);
alphaWidget = new QWidget(QtGradientEditor);
- alphaWidget->setObjectName(QStringLiteral("alphaWidget"));
+ alphaWidget->setObjectName(QString::fromUtf8("alphaWidget"));
alphaWidget->setGeometry(QRect(279, 420, 73, 23));
vboxLayout5 = new QVBoxLayout(alphaWidget);
- vboxLayout5->setObjectName(QStringLiteral("vboxLayout5"));
+ vboxLayout5->setObjectName(QString::fromUtf8("vboxLayout5"));
vboxLayout5->setContentsMargins(0, 0, 0, 0);
alphaSpinBox = new QSpinBox(alphaWidget);
- alphaSpinBox->setObjectName(QStringLiteral("alphaSpinBox"));
+ alphaSpinBox->setObjectName(QString::fromUtf8("alphaSpinBox"));
alphaSpinBox->setKeyboardTracking(false);
alphaSpinBox->setMaximum(255);
vboxLayout5->addWidget(alphaSpinBox);
zoomWidget = new QWidget(QtGradientEditor);
- zoomWidget->setObjectName(QStringLiteral("zoomWidget"));
+ zoomWidget->setObjectName(QString::fromUtf8("zoomWidget"));
zoomWidget->setGeometry(QRect(279, 231, 73, 23));
vboxLayout6 = new QVBoxLayout(zoomWidget);
- vboxLayout6->setObjectName(QStringLiteral("vboxLayout6"));
+ vboxLayout6->setObjectName(QString::fromUtf8("vboxLayout6"));
vboxLayout6->setContentsMargins(0, 0, 0, 0);
zoomSpinBox = new QSpinBox(zoomWidget);
- zoomSpinBox->setObjectName(QStringLiteral("zoomSpinBox"));
+ zoomSpinBox->setObjectName(QString::fromUtf8("zoomSpinBox"));
zoomSpinBox->setKeyboardTracking(false);
zoomSpinBox->setMinimum(100);
zoomSpinBox->setMaximum(10000);
@@ -466,33 +466,33 @@ public:
vboxLayout6->addWidget(zoomSpinBox);
line1Widget = new QWidget(QtGradientEditor);
- line1Widget->setObjectName(QStringLiteral("line1Widget"));
+ line1Widget->setObjectName(QString::fromUtf8("line1Widget"));
line1Widget->setGeometry(QRect(209, 219, 143, 16));
vboxLayout7 = new QVBoxLayout(line1Widget);
- vboxLayout7->setObjectName(QStringLiteral("vboxLayout7"));
+ vboxLayout7->setObjectName(QString::fromUtf8("vboxLayout7"));
vboxLayout7->setContentsMargins(0, 0, 0, 0);
line1 = new QFrame(line1Widget);
- line1->setObjectName(QStringLiteral("line1"));
+ line1->setObjectName(QString::fromUtf8("line1"));
line1->setFrameShape(QFrame::HLine);
line1->setFrameShadow(QFrame::Sunken);
vboxLayout7->addWidget(line1);
line2Widget = new QWidget(QtGradientEditor);
- line2Widget->setObjectName(QStringLiteral("line2Widget"));
+ line2Widget->setObjectName(QString::fromUtf8("line2Widget"));
line2Widget->setGeometry(QRect(209, 292, 143, 16));
vboxLayout8 = new QVBoxLayout(line2Widget);
- vboxLayout8->setObjectName(QStringLiteral("vboxLayout8"));
+ vboxLayout8->setObjectName(QString::fromUtf8("vboxLayout8"));
vboxLayout8->setContentsMargins(0, 0, 0, 0);
line2 = new QFrame(line2Widget);
- line2->setObjectName(QStringLiteral("line2"));
+ line2->setObjectName(QString::fromUtf8("line2"));
line2->setFrameShape(QFrame::HLine);
line2->setFrameShadow(QFrame::Sunken);
vboxLayout8->addWidget(line2);
zoomButtonsWidget = new QWidget(QtGradientEditor);
- zoomButtonsWidget->setObjectName(QStringLiteral("zoomButtonsWidget"));
+ zoomButtonsWidget->setObjectName(QString::fromUtf8("zoomButtonsWidget"));
zoomButtonsWidget->setGeometry(QRect(209, 260, 64, 26));
QSizePolicy sizePolicy6(QSizePolicy::Maximum, QSizePolicy::Preferred);
sizePolicy6.setHorizontalStretch(0);
@@ -500,15 +500,15 @@ public:
sizePolicy6.setHeightForWidth(zoomButtonsWidget->sizePolicy().hasHeightForWidth());
zoomButtonsWidget->setSizePolicy(sizePolicy6);
hboxLayout4 = new QHBoxLayout(zoomButtonsWidget);
- hboxLayout4->setObjectName(QStringLiteral("hboxLayout4"));
+ hboxLayout4->setObjectName(QString::fromUtf8("hboxLayout4"));
hboxLayout4->setContentsMargins(0, 0, 0, 0);
zoomInButton = new QToolButton(zoomButtonsWidget);
- zoomInButton->setObjectName(QStringLiteral("zoomInButton"));
+ zoomInButton->setObjectName(QString::fromUtf8("zoomInButton"));
hboxLayout4->addWidget(zoomInButton);
zoomOutButton = new QToolButton(zoomButtonsWidget);
- zoomOutButton->setObjectName(QStringLiteral("zoomOutButton"));
+ zoomOutButton->setObjectName(QString::fromUtf8("zoomOutButton"));
hboxLayout4->addWidget(zoomOutButton);
@@ -517,7 +517,7 @@ public:
hboxLayout4->addItem(spacerItem);
detailsButton = new QToolButton(QtGradientEditor);
- detailsButton->setObjectName(QStringLiteral("detailsButton"));
+ detailsButton->setObjectName(QString::fromUtf8("detailsButton"));
detailsButton->setGeometry(QRect(176, 40, 25, 22));
QSizePolicy sizePolicy7(QSizePolicy::Fixed, QSizePolicy::Ignored);
sizePolicy7.setHorizontalStretch(0);
@@ -527,32 +527,32 @@ public:
detailsButton->setCheckable(true);
detailsButton->setAutoRaise(true);
linearButton = new QToolButton(QtGradientEditor);
- linearButton->setObjectName(QStringLiteral("linearButton"));
+ linearButton->setObjectName(QString::fromUtf8("linearButton"));
linearButton->setGeometry(QRect(10, 10, 30, 26));
linearButton->setCheckable(true);
linearButton->setAutoRaise(true);
radialButton = new QToolButton(QtGradientEditor);
- radialButton->setObjectName(QStringLiteral("radialButton"));
+ radialButton->setObjectName(QString::fromUtf8("radialButton"));
radialButton->setGeometry(QRect(40, 10, 30, 26));
radialButton->setCheckable(true);
radialButton->setAutoRaise(true);
conicalButton = new QToolButton(QtGradientEditor);
- conicalButton->setObjectName(QStringLiteral("conicalButton"));
+ conicalButton->setObjectName(QString::fromUtf8("conicalButton"));
conicalButton->setGeometry(QRect(70, 10, 30, 26));
conicalButton->setCheckable(true);
conicalButton->setAutoRaise(true);
padButton = new QToolButton(QtGradientEditor);
- padButton->setObjectName(QStringLiteral("padButton"));
+ padButton->setObjectName(QString::fromUtf8("padButton"));
padButton->setGeometry(QRect(110, 10, 30, 26));
padButton->setCheckable(true);
padButton->setAutoRaise(true);
repeatButton = new QToolButton(QtGradientEditor);
- repeatButton->setObjectName(QStringLiteral("repeatButton"));
+ repeatButton->setObjectName(QString::fromUtf8("repeatButton"));
repeatButton->setGeometry(QRect(140, 10, 30, 26));
repeatButton->setCheckable(true);
repeatButton->setAutoRaise(true);
reflectButton = new QToolButton(QtGradientEditor);
- reflectButton->setObjectName(QStringLiteral("reflectButton"));
+ reflectButton->setObjectName(QString::fromUtf8("reflectButton"));
reflectButton->setGeometry(QRect(170, 10, 30, 26));
reflectButton->setCheckable(true);
reflectButton->setAutoRaise(true);
diff --git a/tests/auto/tools/uic/baseline/qtgradientview.ui.h b/tests/auto/tools/uic/baseline/qtgradientview.ui.h
index 4d51c2400e..aa3c03b02f 100644
--- a/tests/auto/tools/uic/baseline/qtgradientview.ui.h
+++ b/tests/auto/tools/uic/baseline/qtgradientview.ui.h
@@ -35,15 +35,15 @@ public:
void setupUi(QWidget *QtGradientView)
{
if (QtGradientView->objectName().isEmpty())
- QtGradientView->setObjectName(QStringLiteral("QtGradientView"));
+ QtGradientView->setObjectName(QString::fromUtf8("QtGradientView"));
QtGradientView->resize(484, 228);
vboxLayout = new QVBoxLayout(QtGradientView);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout->setContentsMargins(0, 0, 0, 0);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
newButton = new QToolButton(QtGradientView);
- newButton->setObjectName(QStringLiteral("newButton"));
+ newButton->setObjectName(QString::fromUtf8("newButton"));
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -55,7 +55,7 @@ public:
hboxLayout->addWidget(newButton);
editButton = new QToolButton(QtGradientView);
- editButton->setObjectName(QStringLiteral("editButton"));
+ editButton->setObjectName(QString::fromUtf8("editButton"));
sizePolicy.setHeightForWidth(editButton->sizePolicy().hasHeightForWidth());
editButton->setSizePolicy(sizePolicy);
editButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -64,7 +64,7 @@ public:
hboxLayout->addWidget(editButton);
renameButton = new QToolButton(QtGradientView);
- renameButton->setObjectName(QStringLiteral("renameButton"));
+ renameButton->setObjectName(QString::fromUtf8("renameButton"));
sizePolicy.setHeightForWidth(renameButton->sizePolicy().hasHeightForWidth());
renameButton->setSizePolicy(sizePolicy);
renameButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -73,7 +73,7 @@ public:
hboxLayout->addWidget(renameButton);
removeButton = new QToolButton(QtGradientView);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
sizePolicy.setHeightForWidth(removeButton->sizePolicy().hasHeightForWidth());
removeButton->setSizePolicy(sizePolicy);
removeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -89,7 +89,7 @@ public:
vboxLayout->addLayout(hboxLayout);
listWidget = new QListWidget(QtGradientView);
- listWidget->setObjectName(QStringLiteral("listWidget"));
+ listWidget->setObjectName(QString::fromUtf8("listWidget"));
vboxLayout->addWidget(listWidget);
diff --git a/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h b/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h
index 74fe3745c9..e6d98ed4f0 100644
--- a/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h
@@ -58,12 +58,12 @@ public:
void setupUi(QDialog *QtGradientViewDialog)
{
if (QtGradientViewDialog->objectName().isEmpty())
- QtGradientViewDialog->setObjectName(QStringLiteral("QtGradientViewDialog"));
+ QtGradientViewDialog->setObjectName(QString::fromUtf8("QtGradientViewDialog"));
QtGradientViewDialog->resize(178, 72);
vboxLayout = new QVBoxLayout(QtGradientViewDialog);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
gradientView = new QtGradientView(QtGradientViewDialog);
- gradientView->setObjectName(QStringLiteral("gradientView"));
+ gradientView->setObjectName(QString::fromUtf8("gradientView"));
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -73,7 +73,7 @@ public:
vboxLayout->addWidget(gradientView);
buttonBox = new QDialogButtonBox(QtGradientViewDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h
index 62d99b3235..6a8c9c7172 100644
--- a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h
+++ b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h
@@ -49,20 +49,20 @@ public:
void setupUi(QDialog *QtResourceEditorDialog)
{
if (QtResourceEditorDialog->objectName().isEmpty())
- QtResourceEditorDialog->setObjectName(QStringLiteral("QtResourceEditorDialog"));
+ QtResourceEditorDialog->setObjectName(QString::fromUtf8("QtResourceEditorDialog"));
QtResourceEditorDialog->resize(469, 317);
verticalLayout = new QVBoxLayout(QtResourceEditorDialog);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
splitter = new QSplitter(QtResourceEditorDialog);
- splitter->setObjectName(QStringLiteral("splitter"));
+ splitter->setObjectName(QString::fromUtf8("splitter"));
splitter->setOrientation(Qt::Horizontal);
layoutWidget = new QWidget(splitter);
- layoutWidget->setObjectName(QStringLiteral("layoutWidget"));
+ layoutWidget->setObjectName(QString::fromUtf8("layoutWidget"));
gridLayout = new QGridLayout(layoutWidget);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
gridLayout->setContentsMargins(0, 0, 0, 0);
qrcFileList = new QListWidget(layoutWidget);
- qrcFileList->setObjectName(QStringLiteral("qrcFileList"));
+ qrcFileList->setObjectName(QString::fromUtf8("qrcFileList"));
QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -72,12 +72,12 @@ public:
gridLayout->addWidget(qrcFileList, 0, 0, 1, 4);
newQrcButton = new QToolButton(layoutWidget);
- newQrcButton->setObjectName(QStringLiteral("newQrcButton"));
+ newQrcButton->setObjectName(QString::fromUtf8("newQrcButton"));
gridLayout->addWidget(newQrcButton, 1, 0, 1, 1);
removeQrcButton = new QToolButton(layoutWidget);
- removeQrcButton->setObjectName(QStringLiteral("removeQrcButton"));
+ removeQrcButton->setObjectName(QString::fromUtf8("removeQrcButton"));
gridLayout->addWidget(removeQrcButton, 1, 2, 1, 1);
@@ -86,33 +86,33 @@ public:
gridLayout->addItem(spacerItem, 1, 3, 1, 1);
importQrcButton = new QToolButton(layoutWidget);
- importQrcButton->setObjectName(QStringLiteral("importQrcButton"));
+ importQrcButton->setObjectName(QString::fromUtf8("importQrcButton"));
gridLayout->addWidget(importQrcButton, 1, 1, 1, 1);
splitter->addWidget(layoutWidget);
widget = new QWidget(splitter);
- widget->setObjectName(QStringLiteral("widget"));
+ widget->setObjectName(QString::fromUtf8("widget"));
gridLayout1 = new QGridLayout(widget);
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
gridLayout1->setContentsMargins(0, 0, 0, 0);
resourceTreeView = new QTreeView(widget);
- resourceTreeView->setObjectName(QStringLiteral("resourceTreeView"));
+ resourceTreeView->setObjectName(QString::fromUtf8("resourceTreeView"));
gridLayout1->addWidget(resourceTreeView, 0, 0, 1, 4);
newResourceButton = new QToolButton(widget);
- newResourceButton->setObjectName(QStringLiteral("newResourceButton"));
+ newResourceButton->setObjectName(QString::fromUtf8("newResourceButton"));
gridLayout1->addWidget(newResourceButton, 1, 0, 1, 1);
addResourceButton = new QToolButton(widget);
- addResourceButton->setObjectName(QStringLiteral("addResourceButton"));
+ addResourceButton->setObjectName(QString::fromUtf8("addResourceButton"));
gridLayout1->addWidget(addResourceButton, 1, 1, 1, 1);
removeResourceButton = new QToolButton(widget);
- removeResourceButton->setObjectName(QStringLiteral("removeResourceButton"));
+ removeResourceButton->setObjectName(QString::fromUtf8("removeResourceButton"));
gridLayout1->addWidget(removeResourceButton, 1, 2, 1, 1);
@@ -125,7 +125,7 @@ public:
verticalLayout->addWidget(splitter);
buttonBox = new QDialogButtonBox(QtResourceEditorDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h
index 1c546aa196..e893386d9b 100644
--- a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h
+++ b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h
@@ -50,21 +50,21 @@ public:
void setupUi(QDialog *QtToolBarDialog)
{
if (QtToolBarDialog->objectName().isEmpty())
- QtToolBarDialog->setObjectName(QStringLiteral("QtToolBarDialog"));
+ QtToolBarDialog->setObjectName(QString::fromUtf8("QtToolBarDialog"));
QtToolBarDialog->resize(583, 508);
gridLayout = new QGridLayout(QtToolBarDialog);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
#endif
gridLayout->setContentsMargins(8, 8, 8, 8);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
actionTree = new QTreeWidget(QtToolBarDialog);
- actionTree->setObjectName(QStringLiteral("actionTree"));
+ actionTree->setObjectName(QString::fromUtf8("actionTree"));
gridLayout->addWidget(actionTree, 1, 0, 3, 1);
label = new QLabel(QtToolBarDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
@@ -73,24 +73,24 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
label_2 = new QLabel(QtToolBarDialog);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
hboxLayout->addWidget(label_2);
newButton = new QToolButton(QtToolBarDialog);
- newButton->setObjectName(QStringLiteral("newButton"));
+ newButton->setObjectName(QString::fromUtf8("newButton"));
hboxLayout->addWidget(newButton);
removeButton = new QToolButton(QtToolBarDialog);
- removeButton->setObjectName(QStringLiteral("removeButton"));
+ removeButton->setObjectName(QString::fromUtf8("removeButton"));
hboxLayout->addWidget(removeButton);
renameButton = new QToolButton(QtToolBarDialog);
- renameButton->setObjectName(QStringLiteral("renameButton"));
+ renameButton->setObjectName(QString::fromUtf8("renameButton"));
hboxLayout->addWidget(renameButton);
@@ -102,9 +102,9 @@ public:
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(0, 0, 0, 0);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
upButton = new QToolButton(QtToolBarDialog);
- upButton->setObjectName(QStringLiteral("upButton"));
+ upButton->setObjectName(QString::fromUtf8("upButton"));
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -114,21 +114,21 @@ public:
vboxLayout->addWidget(upButton);
leftButton = new QToolButton(QtToolBarDialog);
- leftButton->setObjectName(QStringLiteral("leftButton"));
+ leftButton->setObjectName(QString::fromUtf8("leftButton"));
sizePolicy.setHeightForWidth(leftButton->sizePolicy().hasHeightForWidth());
leftButton->setSizePolicy(sizePolicy);
vboxLayout->addWidget(leftButton);
rightButton = new QToolButton(QtToolBarDialog);
- rightButton->setObjectName(QStringLiteral("rightButton"));
+ rightButton->setObjectName(QString::fromUtf8("rightButton"));
sizePolicy.setHeightForWidth(rightButton->sizePolicy().hasHeightForWidth());
rightButton->setSizePolicy(sizePolicy);
vboxLayout->addWidget(rightButton);
downButton = new QToolButton(QtToolBarDialog);
- downButton->setObjectName(QStringLiteral("downButton"));
+ downButton->setObjectName(QString::fromUtf8("downButton"));
sizePolicy.setHeightForWidth(downButton->sizePolicy().hasHeightForWidth());
downButton->setSizePolicy(sizePolicy);
@@ -142,22 +142,22 @@ public:
gridLayout->addLayout(vboxLayout, 3, 1, 1, 1);
currentToolBarList = new QListWidget(QtToolBarDialog);
- currentToolBarList->setObjectName(QStringLiteral("currentToolBarList"));
+ currentToolBarList->setObjectName(QString::fromUtf8("currentToolBarList"));
gridLayout->addWidget(currentToolBarList, 3, 2, 1, 1);
label_3 = new QLabel(QtToolBarDialog);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout->addWidget(label_3, 2, 1, 1, 2);
toolBarList = new QListWidget(QtToolBarDialog);
- toolBarList->setObjectName(QStringLiteral("toolBarList"));
+ toolBarList->setObjectName(QString::fromUtf8("toolBarList"));
gridLayout->addWidget(toolBarList, 1, 1, 1, 2);
buttonBox = new QDialogButtonBox(QtToolBarDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setStandardButtons(QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults);
gridLayout->addWidget(buttonBox, 5, 0, 1, 3);
diff --git a/tests/auto/tools/uic/baseline/qttrid.ui.h b/tests/auto/tools/uic/baseline/qttrid.ui.h
index b7ec1062de..890ffc7789 100644
--- a/tests/auto/tools/uic/baseline/qttrid.ui.h
+++ b/tests/auto/tools/uic/baseline/qttrid.ui.h
@@ -67,28 +67,28 @@ public:
void setupUi(QMainWindow *RemoteControlClass)
{
if (RemoteControlClass->objectName().isEmpty())
- RemoteControlClass->setObjectName(QStringLiteral("RemoteControlClass"));
+ RemoteControlClass->setObjectName(QString::fromUtf8("RemoteControlClass"));
RemoteControlClass->resize(344, 364);
actionQuit = new QAction(RemoteControlClass);
- actionQuit->setObjectName(QStringLiteral("actionQuit"));
+ actionQuit->setObjectName(QString::fromUtf8("actionQuit"));
centralWidget = new QWidget(RemoteControlClass);
- centralWidget->setObjectName(QStringLiteral("centralWidget"));
+ centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
gridLayout = new QGridLayout(centralWidget);
gridLayout->setSpacing(6);
gridLayout->setContentsMargins(11, 11, 11, 11);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(centralWidget);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
startUrlLineEdit = new QLineEdit(centralWidget);
- startUrlLineEdit->setObjectName(QStringLiteral("startUrlLineEdit"));
+ startUrlLineEdit->setObjectName(QString::fromUtf8("startUrlLineEdit"));
gridLayout->addWidget(startUrlLineEdit, 0, 1, 1, 2);
launchButton = new QPushButton(centralWidget);
- launchButton->setObjectName(QStringLiteral("launchButton"));
+ launchButton->setObjectName(QString::fromUtf8("launchButton"));
gridLayout->addWidget(launchButton, 1, 1, 1, 1);
@@ -101,27 +101,27 @@ public:
gridLayout->addItem(spacerItem1, 2, 1, 1, 1);
actionGroupBox = new QGroupBox(centralWidget);
- actionGroupBox->setObjectName(QStringLiteral("actionGroupBox"));
+ actionGroupBox->setObjectName(QString::fromUtf8("actionGroupBox"));
actionGroupBox->setEnabled(false);
gridLayout1 = new QGridLayout(actionGroupBox);
gridLayout1->setSpacing(6);
gridLayout1->setContentsMargins(11, 11, 11, 11);
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
label_2 = new QLabel(actionGroupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout1->addWidget(label_2, 0, 0, 1, 1);
hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
indexLineEdit = new QLineEdit(actionGroupBox);
- indexLineEdit->setObjectName(QStringLiteral("indexLineEdit"));
+ indexLineEdit->setObjectName(QString::fromUtf8("indexLineEdit"));
hboxLayout->addWidget(indexLineEdit);
indexButton = new QToolButton(actionGroupBox);
- indexButton->setObjectName(QStringLiteral("indexButton"));
+ indexButton->setObjectName(QString::fromUtf8("indexButton"));
const QIcon icon = QIcon(QString::fromUtf8(":/remotecontrol/enter.png"));
indexButton->setIcon(icon);
@@ -131,20 +131,20 @@ public:
gridLayout1->addLayout(hboxLayout, 0, 1, 1, 2);
label_4 = new QLabel(actionGroupBox);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
gridLayout1->addWidget(label_4, 1, 0, 1, 1);
hboxLayout1 = new QHBoxLayout();
hboxLayout1->setSpacing(0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
identifierLineEdit = new QLineEdit(actionGroupBox);
- identifierLineEdit->setObjectName(QStringLiteral("identifierLineEdit"));
+ identifierLineEdit->setObjectName(QString::fromUtf8("identifierLineEdit"));
hboxLayout1->addWidget(identifierLineEdit);
identifierButton = new QToolButton(actionGroupBox);
- identifierButton->setObjectName(QStringLiteral("identifierButton"));
+ identifierButton->setObjectName(QString::fromUtf8("identifierButton"));
identifierButton->setIcon(icon);
hboxLayout1->addWidget(identifierButton);
@@ -153,20 +153,20 @@ public:
gridLayout1->addLayout(hboxLayout1, 1, 1, 1, 2);
label_3 = new QLabel(actionGroupBox);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout1->addWidget(label_3, 2, 0, 1, 1);
hboxLayout2 = new QHBoxLayout();
hboxLayout2->setSpacing(0);
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
urlLineEdit = new QLineEdit(actionGroupBox);
- urlLineEdit->setObjectName(QStringLiteral("urlLineEdit"));
+ urlLineEdit->setObjectName(QString::fromUtf8("urlLineEdit"));
hboxLayout2->addWidget(urlLineEdit);
urlButton = new QToolButton(actionGroupBox);
- urlButton->setObjectName(QStringLiteral("urlButton"));
+ urlButton->setObjectName(QString::fromUtf8("urlButton"));
urlButton->setIcon(icon);
hboxLayout2->addWidget(urlButton);
@@ -175,7 +175,7 @@ public:
gridLayout1->addLayout(hboxLayout2, 2, 1, 1, 2);
syncContentsButton = new QPushButton(actionGroupBox);
- syncContentsButton->setObjectName(QStringLiteral("syncContentsButton"));
+ syncContentsButton->setObjectName(QString::fromUtf8("syncContentsButton"));
gridLayout1->addWidget(syncContentsButton, 3, 1, 1, 1);
@@ -184,17 +184,17 @@ public:
gridLayout1->addItem(spacerItem2, 3, 2, 1, 1);
contentsCheckBox = new QCheckBox(actionGroupBox);
- contentsCheckBox->setObjectName(QStringLiteral("contentsCheckBox"));
+ contentsCheckBox->setObjectName(QString::fromUtf8("contentsCheckBox"));
gridLayout1->addWidget(contentsCheckBox, 4, 0, 1, 3);
indexCheckBox = new QCheckBox(actionGroupBox);
- indexCheckBox->setObjectName(QStringLiteral("indexCheckBox"));
+ indexCheckBox->setObjectName(QString::fromUtf8("indexCheckBox"));
gridLayout1->addWidget(indexCheckBox, 5, 0, 1, 1);
bookmarksCheckBox = new QCheckBox(actionGroupBox);
- bookmarksCheckBox->setObjectName(QStringLiteral("bookmarksCheckBox"));
+ bookmarksCheckBox->setObjectName(QString::fromUtf8("bookmarksCheckBox"));
gridLayout1->addWidget(bookmarksCheckBox, 6, 0, 1, 3);
@@ -203,13 +203,13 @@ public:
RemoteControlClass->setCentralWidget(centralWidget);
menuBar = new QMenuBar(RemoteControlClass);
- menuBar->setObjectName(QStringLiteral("menuBar"));
+ menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 344, 21));
menuFile = new QMenu(menuBar);
- menuFile->setObjectName(QStringLiteral("menuFile"));
+ menuFile->setObjectName(QString::fromUtf8("menuFile"));
RemoteControlClass->setMenuBar(menuBar);
statusBar = new QStatusBar(RemoteControlClass);
- statusBar->setObjectName(QStringLiteral("statusBar"));
+ statusBar->setObjectName(QString::fromUtf8("statusBar"));
RemoteControlClass->setStatusBar(statusBar);
menuBar->addAction(menuFile->menuAction());
diff --git a/tests/auto/tools/uic/baseline/querywidget.ui.h b/tests/auto/tools/uic/baseline/querywidget.ui.h
index 0e941a0e5e..81516722d5 100644
--- a/tests/auto/tools/uic/baseline/querywidget.ui.h
+++ b/tests/auto/tools/uic/baseline/querywidget.ui.h
@@ -46,13 +46,13 @@ public:
void setupUi(QMainWindow *QueryWidget)
{
if (QueryWidget->objectName().isEmpty())
- QueryWidget->setObjectName(QStringLiteral("QueryWidget"));
+ QueryWidget->setObjectName(QString::fromUtf8("QueryWidget"));
QueryWidget->resize(545, 531);
centralwidget = new QWidget(QueryWidget);
- centralwidget->setObjectName(QStringLiteral("centralwidget"));
+ centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
centralwidget->setGeometry(QRect(0, 29, 545, 480));
verticalLayout = new QVBoxLayout(centralwidget);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
vboxLayout = new QVBoxLayout();
#ifndef Q_OS_MAC
vboxLayout->setSpacing(6);
@@ -60,12 +60,12 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(0, 0, 0, 0);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
inputGroupBox = new QGroupBox(centralwidget);
- inputGroupBox->setObjectName(QStringLiteral("inputGroupBox"));
+ inputGroupBox->setObjectName(QString::fromUtf8("inputGroupBox"));
inputGroupBox->setMinimumSize(QSize(550, 120));
verticalLayout_4 = new QVBoxLayout(inputGroupBox);
- verticalLayout_4->setObjectName(QStringLiteral("verticalLayout_4"));
+ verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4"));
_2 = new QVBoxLayout();
#ifndef Q_OS_MAC
_2->setSpacing(6);
@@ -73,9 +73,9 @@ public:
#ifndef Q_OS_MAC
_2->setContentsMargins(0, 0, 0, 0);
#endif
- _2->setObjectName(QStringLiteral("_2"));
+ _2->setObjectName(QString::fromUtf8("_2"));
inputTextEdit = new QTextEdit(inputGroupBox);
- inputTextEdit->setObjectName(QStringLiteral("inputTextEdit"));
+ inputTextEdit->setObjectName(QString::fromUtf8("inputTextEdit"));
_2->addWidget(inputTextEdit);
@@ -86,17 +86,17 @@ public:
vboxLayout->addWidget(inputGroupBox);
queryGroupBox = new QGroupBox(centralwidget);
- queryGroupBox->setObjectName(QStringLiteral("queryGroupBox"));
+ queryGroupBox->setObjectName(QString::fromUtf8("queryGroupBox"));
queryGroupBox->setMinimumSize(QSize(550, 120));
verticalLayout_5 = new QVBoxLayout(queryGroupBox);
- verticalLayout_5->setObjectName(QStringLiteral("verticalLayout_5"));
+ verticalLayout_5->setObjectName(QString::fromUtf8("verticalLayout_5"));
defaultQueries = new QComboBox(queryGroupBox);
- defaultQueries->setObjectName(QStringLiteral("defaultQueries"));
+ defaultQueries->setObjectName(QString::fromUtf8("defaultQueries"));
verticalLayout_5->addWidget(defaultQueries);
queryTextEdit = new QTextEdit(queryGroupBox);
- queryTextEdit->setObjectName(QStringLiteral("queryTextEdit"));
+ queryTextEdit->setObjectName(QString::fromUtf8("queryTextEdit"));
queryTextEdit->setMinimumSize(QSize(400, 60));
queryTextEdit->setReadOnly(true);
queryTextEdit->setAcceptRichText(false);
@@ -107,10 +107,10 @@ public:
vboxLayout->addWidget(queryGroupBox);
outputGroupBox = new QGroupBox(centralwidget);
- outputGroupBox->setObjectName(QStringLiteral("outputGroupBox"));
+ outputGroupBox->setObjectName(QString::fromUtf8("outputGroupBox"));
outputGroupBox->setMinimumSize(QSize(550, 120));
verticalLayout_6 = new QVBoxLayout(outputGroupBox);
- verticalLayout_6->setObjectName(QStringLiteral("verticalLayout_6"));
+ verticalLayout_6->setObjectName(QString::fromUtf8("verticalLayout_6"));
_3 = new QVBoxLayout();
#ifndef Q_OS_MAC
_3->setSpacing(6);
@@ -118,9 +118,9 @@ public:
#ifndef Q_OS_MAC
_3->setContentsMargins(0, 0, 0, 0);
#endif
- _3->setObjectName(QStringLiteral("_3"));
+ _3->setObjectName(QString::fromUtf8("_3"));
outputTextEdit = new QTextEdit(outputGroupBox);
- outputTextEdit->setObjectName(QStringLiteral("outputTextEdit"));
+ outputTextEdit->setObjectName(QString::fromUtf8("outputTextEdit"));
outputTextEdit->setMinimumSize(QSize(500, 80));
outputTextEdit->setReadOnly(true);
outputTextEdit->setAcceptRichText(false);
@@ -138,11 +138,11 @@ public:
QueryWidget->setCentralWidget(centralwidget);
menubar = new QMenuBar(QueryWidget);
- menubar->setObjectName(QStringLiteral("menubar"));
+ menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 545, 29));
QueryWidget->setMenuBar(menubar);
statusbar = new QStatusBar(QueryWidget);
- statusbar->setObjectName(QStringLiteral("statusbar"));
+ statusbar->setObjectName(QString::fromUtf8("statusbar"));
statusbar->setGeometry(QRect(0, 509, 545, 22));
QueryWidget->setStatusBar(statusbar);
diff --git a/tests/auto/tools/uic/baseline/remotecontrol.ui.h b/tests/auto/tools/uic/baseline/remotecontrol.ui.h
index c883637dc4..5893ff42af 100644
--- a/tests/auto/tools/uic/baseline/remotecontrol.ui.h
+++ b/tests/auto/tools/uic/baseline/remotecontrol.ui.h
@@ -67,28 +67,28 @@ public:
void setupUi(QMainWindow *RemoteControlClass)
{
if (RemoteControlClass->objectName().isEmpty())
- RemoteControlClass->setObjectName(QStringLiteral("RemoteControlClass"));
+ RemoteControlClass->setObjectName(QString::fromUtf8("RemoteControlClass"));
RemoteControlClass->resize(344, 364);
actionQuit = new QAction(RemoteControlClass);
- actionQuit->setObjectName(QStringLiteral("actionQuit"));
+ actionQuit->setObjectName(QString::fromUtf8("actionQuit"));
centralWidget = new QWidget(RemoteControlClass);
- centralWidget->setObjectName(QStringLiteral("centralWidget"));
+ centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
gridLayout = new QGridLayout(centralWidget);
gridLayout->setSpacing(6);
gridLayout->setContentsMargins(11, 11, 11, 11);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(centralWidget);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
startUrlLineEdit = new QLineEdit(centralWidget);
- startUrlLineEdit->setObjectName(QStringLiteral("startUrlLineEdit"));
+ startUrlLineEdit->setObjectName(QString::fromUtf8("startUrlLineEdit"));
gridLayout->addWidget(startUrlLineEdit, 0, 1, 1, 2);
launchButton = new QPushButton(centralWidget);
- launchButton->setObjectName(QStringLiteral("launchButton"));
+ launchButton->setObjectName(QString::fromUtf8("launchButton"));
gridLayout->addWidget(launchButton, 1, 1, 1, 1);
@@ -101,27 +101,27 @@ public:
gridLayout->addItem(spacerItem1, 2, 1, 1, 1);
actionGroupBox = new QGroupBox(centralWidget);
- actionGroupBox->setObjectName(QStringLiteral("actionGroupBox"));
+ actionGroupBox->setObjectName(QString::fromUtf8("actionGroupBox"));
actionGroupBox->setEnabled(false);
gridLayout1 = new QGridLayout(actionGroupBox);
gridLayout1->setSpacing(6);
gridLayout1->setContentsMargins(11, 11, 11, 11);
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
label_2 = new QLabel(actionGroupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout1->addWidget(label_2, 0, 0, 1, 1);
hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
indexLineEdit = new QLineEdit(actionGroupBox);
- indexLineEdit->setObjectName(QStringLiteral("indexLineEdit"));
+ indexLineEdit->setObjectName(QString::fromUtf8("indexLineEdit"));
hboxLayout->addWidget(indexLineEdit);
indexButton = new QToolButton(actionGroupBox);
- indexButton->setObjectName(QStringLiteral("indexButton"));
+ indexButton->setObjectName(QString::fromUtf8("indexButton"));
const QIcon icon = QIcon(QString::fromUtf8(":/remotecontrol/enter.png"));
indexButton->setIcon(icon);
@@ -131,20 +131,20 @@ public:
gridLayout1->addLayout(hboxLayout, 0, 1, 1, 2);
label_4 = new QLabel(actionGroupBox);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
gridLayout1->addWidget(label_4, 1, 0, 1, 1);
hboxLayout1 = new QHBoxLayout();
hboxLayout1->setSpacing(0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
identifierLineEdit = new QLineEdit(actionGroupBox);
- identifierLineEdit->setObjectName(QStringLiteral("identifierLineEdit"));
+ identifierLineEdit->setObjectName(QString::fromUtf8("identifierLineEdit"));
hboxLayout1->addWidget(identifierLineEdit);
identifierButton = new QToolButton(actionGroupBox);
- identifierButton->setObjectName(QStringLiteral("identifierButton"));
+ identifierButton->setObjectName(QString::fromUtf8("identifierButton"));
identifierButton->setIcon(icon);
hboxLayout1->addWidget(identifierButton);
@@ -153,20 +153,20 @@ public:
gridLayout1->addLayout(hboxLayout1, 1, 1, 1, 2);
label_3 = new QLabel(actionGroupBox);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout1->addWidget(label_3, 2, 0, 1, 1);
hboxLayout2 = new QHBoxLayout();
hboxLayout2->setSpacing(0);
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
urlLineEdit = new QLineEdit(actionGroupBox);
- urlLineEdit->setObjectName(QStringLiteral("urlLineEdit"));
+ urlLineEdit->setObjectName(QString::fromUtf8("urlLineEdit"));
hboxLayout2->addWidget(urlLineEdit);
urlButton = new QToolButton(actionGroupBox);
- urlButton->setObjectName(QStringLiteral("urlButton"));
+ urlButton->setObjectName(QString::fromUtf8("urlButton"));
urlButton->setIcon(icon);
hboxLayout2->addWidget(urlButton);
@@ -175,7 +175,7 @@ public:
gridLayout1->addLayout(hboxLayout2, 2, 1, 1, 2);
syncContentsButton = new QPushButton(actionGroupBox);
- syncContentsButton->setObjectName(QStringLiteral("syncContentsButton"));
+ syncContentsButton->setObjectName(QString::fromUtf8("syncContentsButton"));
gridLayout1->addWidget(syncContentsButton, 3, 1, 1, 1);
@@ -184,17 +184,17 @@ public:
gridLayout1->addItem(spacerItem2, 3, 2, 1, 1);
contentsCheckBox = new QCheckBox(actionGroupBox);
- contentsCheckBox->setObjectName(QStringLiteral("contentsCheckBox"));
+ contentsCheckBox->setObjectName(QString::fromUtf8("contentsCheckBox"));
gridLayout1->addWidget(contentsCheckBox, 4, 0, 1, 3);
indexCheckBox = new QCheckBox(actionGroupBox);
- indexCheckBox->setObjectName(QStringLiteral("indexCheckBox"));
+ indexCheckBox->setObjectName(QString::fromUtf8("indexCheckBox"));
gridLayout1->addWidget(indexCheckBox, 5, 0, 1, 1);
bookmarksCheckBox = new QCheckBox(actionGroupBox);
- bookmarksCheckBox->setObjectName(QStringLiteral("bookmarksCheckBox"));
+ bookmarksCheckBox->setObjectName(QString::fromUtf8("bookmarksCheckBox"));
gridLayout1->addWidget(bookmarksCheckBox, 6, 0, 1, 3);
@@ -203,13 +203,13 @@ public:
RemoteControlClass->setCentralWidget(centralWidget);
menuBar = new QMenuBar(RemoteControlClass);
- menuBar->setObjectName(QStringLiteral("menuBar"));
+ menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 344, 21));
menuFile = new QMenu(menuBar);
- menuFile->setObjectName(QStringLiteral("menuFile"));
+ menuFile->setObjectName(QString::fromUtf8("menuFile"));
RemoteControlClass->setMenuBar(menuBar);
statusBar = new QStatusBar(RemoteControlClass);
- statusBar->setObjectName(QStringLiteral("statusBar"));
+ statusBar->setObjectName(QString::fromUtf8("statusBar"));
RemoteControlClass->setStatusBar(statusBar);
menuBar->addAction(menuFile->menuAction());
diff --git a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h
index 6cd8726d07..9ef6eedb4c 100644
--- a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h
+++ b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h
@@ -67,13 +67,13 @@ public:
void setupUi(QDialog *SaveFormAsTemplate)
{
if (SaveFormAsTemplate->objectName().isEmpty())
- SaveFormAsTemplate->setObjectName(QStringLiteral("SaveFormAsTemplate"));
+ SaveFormAsTemplate->setObjectName(QString::fromUtf8("SaveFormAsTemplate"));
vboxLayout = new QVBoxLayout(SaveFormAsTemplate);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
formLayout = new QFormLayout();
- formLayout->setObjectName(QStringLiteral("formLayout"));
+ formLayout->setObjectName(QString::fromUtf8("formLayout"));
label = new QLabel(SaveFormAsTemplate);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setFrameShape(QFrame::NoFrame);
label->setFrameShadow(QFrame::Plain);
label->setTextFormat(Qt::AutoText);
@@ -81,14 +81,14 @@ public:
formLayout->setWidget(0, QFormLayout::LabelRole, label);
templateNameEdit = new QLineEdit(SaveFormAsTemplate);
- templateNameEdit->setObjectName(QStringLiteral("templateNameEdit"));
+ templateNameEdit->setObjectName(QString::fromUtf8("templateNameEdit"));
templateNameEdit->setMinimumSize(QSize(222, 0));
templateNameEdit->setEchoMode(QLineEdit::Normal);
formLayout->setWidget(0, QFormLayout::FieldRole, templateNameEdit);
label_2 = new QLabel(SaveFormAsTemplate);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
label_2->setFrameShape(QFrame::NoFrame);
label_2->setFrameShadow(QFrame::Plain);
label_2->setTextFormat(Qt::AutoText);
@@ -96,7 +96,7 @@ public:
formLayout->setWidget(1, QFormLayout::LabelRole, label_2);
categoryCombo = new QComboBox(SaveFormAsTemplate);
- categoryCombo->setObjectName(QStringLiteral("categoryCombo"));
+ categoryCombo->setObjectName(QString::fromUtf8("categoryCombo"));
formLayout->setWidget(1, QFormLayout::FieldRole, categoryCombo);
@@ -104,14 +104,14 @@ public:
vboxLayout->addLayout(formLayout);
horizontalLine = new QFrame(SaveFormAsTemplate);
- horizontalLine->setObjectName(QStringLiteral("horizontalLine"));
+ horizontalLine->setObjectName(QString::fromUtf8("horizontalLine"));
horizontalLine->setFrameShape(QFrame::HLine);
horizontalLine->setFrameShadow(QFrame::Sunken);
vboxLayout->addWidget(horizontalLine);
buttonBox = new QDialogButtonBox(SaveFormAsTemplate);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/settings.ui.h b/tests/auto/tools/uic/baseline/settings.ui.h
index 6a1f11fa85..cc680c8033 100644
--- a/tests/auto/tools/uic/baseline/settings.ui.h
+++ b/tests/auto/tools/uic/baseline/settings.ui.h
@@ -47,14 +47,14 @@ public:
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
- Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(392, 176);
verticalLayout = new QVBoxLayout(Dialog);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
label = new QLabel(Dialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -66,7 +66,7 @@ public:
hboxLayout->addWidget(label);
deviceCombo = new QComboBox(Dialog);
- deviceCombo->setObjectName(QStringLiteral("deviceCombo"));
+ deviceCombo->setObjectName(QString::fromUtf8("deviceCombo"));
QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -79,9 +79,9 @@ public:
verticalLayout->addLayout(hboxLayout);
hboxLayout1 = new QHBoxLayout();
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
label_6 = new QLabel(Dialog);
- label_6->setObjectName(QStringLiteral("label_6"));
+ label_6->setObjectName(QString::fromUtf8("label_6"));
sizePolicy.setHeightForWidth(label_6->sizePolicy().hasHeightForWidth());
label_6->setSizePolicy(sizePolicy);
label_6->setMinimumSize(QSize(90, 0));
@@ -90,7 +90,7 @@ public:
hboxLayout1->addWidget(label_6);
audioEffectsCombo = new QComboBox(Dialog);
- audioEffectsCombo->setObjectName(QStringLiteral("audioEffectsCombo"));
+ audioEffectsCombo->setObjectName(QString::fromUtf8("audioEffectsCombo"));
sizePolicy1.setHeightForWidth(audioEffectsCombo->sizePolicy().hasHeightForWidth());
audioEffectsCombo->setSizePolicy(sizePolicy1);
@@ -100,9 +100,9 @@ public:
verticalLayout->addLayout(hboxLayout1);
hboxLayout2 = new QHBoxLayout();
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
crossFadeLabel = new QLabel(Dialog);
- crossFadeLabel->setObjectName(QStringLiteral("crossFadeLabel"));
+ crossFadeLabel->setObjectName(QString::fromUtf8("crossFadeLabel"));
sizePolicy.setHeightForWidth(crossFadeLabel->sizePolicy().hasHeightForWidth());
crossFadeLabel->setSizePolicy(sizePolicy);
crossFadeLabel->setMinimumSize(QSize(90, 0));
@@ -111,9 +111,9 @@ public:
hboxLayout2->addWidget(crossFadeLabel);
vboxLayout = new QVBoxLayout();
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
crossFadeSlider = new QSlider(Dialog);
- crossFadeSlider->setObjectName(QStringLiteral("crossFadeSlider"));
+ crossFadeSlider->setObjectName(QString::fromUtf8("crossFadeSlider"));
sizePolicy1.setHeightForWidth(crossFadeSlider->sizePolicy().hasHeightForWidth());
crossFadeSlider->setSizePolicy(sizePolicy1);
crossFadeSlider->setMinimum(-20);
@@ -127,9 +127,9 @@ public:
vboxLayout->addWidget(crossFadeSlider);
hboxLayout3 = new QHBoxLayout();
- hboxLayout3->setObjectName(QStringLiteral("hboxLayout3"));
+ hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3"));
label_3 = new QLabel(Dialog);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
QFont font;
font.setPointSize(9);
label_3->setFont(font);
@@ -141,7 +141,7 @@ public:
hboxLayout3->addItem(spacerItem);
label_5 = new QLabel(Dialog);
- label_5->setObjectName(QStringLiteral("label_5"));
+ label_5->setObjectName(QString::fromUtf8("label_5"));
label_5->setFont(font);
hboxLayout3->addWidget(label_5);
@@ -151,7 +151,7 @@ public:
hboxLayout3->addItem(spacerItem1);
label_4 = new QLabel(Dialog);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
label_4->setFont(font);
hboxLayout3->addWidget(label_4);
@@ -166,7 +166,7 @@ public:
verticalLayout->addLayout(hboxLayout2);
buttonBox = new QDialogButtonBox(Dialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h
index ad6c5776e1..5833a25a8b 100644
--- a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h
@@ -45,33 +45,33 @@ public:
void setupUi(QDialog *SignalSlotDialogClass)
{
if (SignalSlotDialogClass->objectName().isEmpty())
- SignalSlotDialogClass->setObjectName(QStringLiteral("SignalSlotDialogClass"));
+ SignalSlotDialogClass->setObjectName(QString::fromUtf8("SignalSlotDialogClass"));
SignalSlotDialogClass->resize(617, 535);
vboxLayout = new QVBoxLayout(SignalSlotDialogClass);
vboxLayout->setSpacing(6);
vboxLayout->setContentsMargins(11, 11, 11, 11);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
slotGroupBox = new QGroupBox(SignalSlotDialogClass);
- slotGroupBox->setObjectName(QStringLiteral("slotGroupBox"));
+ slotGroupBox->setObjectName(QString::fromUtf8("slotGroupBox"));
vboxLayout1 = new QVBoxLayout(slotGroupBox);
vboxLayout1->setSpacing(6);
vboxLayout1->setContentsMargins(11, 11, 11, 11);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
slotListView = new QListView(slotGroupBox);
- slotListView->setObjectName(QStringLiteral("slotListView"));
+ slotListView->setObjectName(QString::fromUtf8("slotListView"));
vboxLayout1->addWidget(slotListView);
hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(6);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
addSlotButton = new QToolButton(slotGroupBox);
- addSlotButton->setObjectName(QStringLiteral("addSlotButton"));
+ addSlotButton->setObjectName(QString::fromUtf8("addSlotButton"));
hboxLayout->addWidget(addSlotButton);
removeSlotButton = new QToolButton(slotGroupBox);
- removeSlotButton->setObjectName(QStringLiteral("removeSlotButton"));
+ removeSlotButton->setObjectName(QString::fromUtf8("removeSlotButton"));
hboxLayout->addWidget(removeSlotButton);
@@ -86,26 +86,26 @@ public:
vboxLayout->addWidget(slotGroupBox);
signalGroupBox = new QGroupBox(SignalSlotDialogClass);
- signalGroupBox->setObjectName(QStringLiteral("signalGroupBox"));
+ signalGroupBox->setObjectName(QString::fromUtf8("signalGroupBox"));
vboxLayout2 = new QVBoxLayout(signalGroupBox);
vboxLayout2->setSpacing(6);
vboxLayout2->setContentsMargins(11, 11, 11, 11);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
signalListView = new QListView(signalGroupBox);
- signalListView->setObjectName(QStringLiteral("signalListView"));
+ signalListView->setObjectName(QString::fromUtf8("signalListView"));
vboxLayout2->addWidget(signalListView);
hboxLayout1 = new QHBoxLayout();
hboxLayout1->setSpacing(6);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
addSignalButton = new QToolButton(signalGroupBox);
- addSignalButton->setObjectName(QStringLiteral("addSignalButton"));
+ addSignalButton->setObjectName(QString::fromUtf8("addSignalButton"));
hboxLayout1->addWidget(addSignalButton);
removeSignalButton = new QToolButton(signalGroupBox);
- removeSignalButton->setObjectName(QStringLiteral("removeSignalButton"));
+ removeSignalButton->setObjectName(QString::fromUtf8("removeSignalButton"));
hboxLayout1->addWidget(removeSignalButton);
@@ -120,7 +120,7 @@ public:
vboxLayout->addWidget(signalGroupBox);
buttonBox = new QDialogButtonBox(SignalSlotDialogClass);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
vboxLayout->addWidget(buttonBox);
diff --git a/tests/auto/tools/uic/baseline/sslclient.ui.h b/tests/auto/tools/uic/baseline/sslclient.ui.h
index 3e7feab75a..382889648e 100644
--- a/tests/auto/tools/uic/baseline/sslclient.ui.h
+++ b/tests/auto/tools/uic/baseline/sslclient.ui.h
@@ -48,29 +48,29 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(343, 320);
vboxLayout = new QVBoxLayout(Form);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
gridLayout = new QGridLayout();
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
hostNameLabel = new QLabel(Form);
- hostNameLabel->setObjectName(QStringLiteral("hostNameLabel"));
+ hostNameLabel->setObjectName(QString::fromUtf8("hostNameLabel"));
gridLayout->addWidget(hostNameLabel, 0, 0, 1, 1);
hostNameEdit = new QLineEdit(Form);
- hostNameEdit->setObjectName(QStringLiteral("hostNameEdit"));
+ hostNameEdit->setObjectName(QString::fromUtf8("hostNameEdit"));
gridLayout->addWidget(hostNameEdit, 0, 1, 1, 1);
portLabel = new QLabel(Form);
- portLabel->setObjectName(QStringLiteral("portLabel"));
+ portLabel->setObjectName(QString::fromUtf8("portLabel"));
gridLayout->addWidget(portLabel, 1, 0, 1, 1);
portBox = new QSpinBox(Form);
- portBox->setObjectName(QStringLiteral("portBox"));
+ portBox->setObjectName(QString::fromUtf8("portBox"));
portBox->setMinimum(1);
portBox->setMaximum(65535);
portBox->setValue(993);
@@ -81,25 +81,25 @@ public:
vboxLayout->addLayout(gridLayout);
connectButton = new QPushButton(Form);
- connectButton->setObjectName(QStringLiteral("connectButton"));
+ connectButton->setObjectName(QString::fromUtf8("connectButton"));
connectButton->setEnabled(true);
vboxLayout->addWidget(connectButton);
sessionBox = new QGroupBox(Form);
- sessionBox->setObjectName(QStringLiteral("sessionBox"));
+ sessionBox->setObjectName(QString::fromUtf8("sessionBox"));
sessionBox->setEnabled(false);
vboxLayout1 = new QVBoxLayout(sessionBox);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
cipherText = new QLabel(sessionBox);
- cipherText->setObjectName(QStringLiteral("cipherText"));
+ cipherText->setObjectName(QString::fromUtf8("cipherText"));
hboxLayout->addWidget(cipherText);
cipherLabel = new QLabel(sessionBox);
- cipherLabel->setObjectName(QStringLiteral("cipherLabel"));
+ cipherLabel->setObjectName(QString::fromUtf8("cipherLabel"));
cipherLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
hboxLayout->addWidget(cipherLabel);
@@ -108,7 +108,7 @@ public:
vboxLayout1->addLayout(hboxLayout);
sessionOutput = new QTextEdit(sessionBox);
- sessionOutput->setObjectName(QStringLiteral("sessionOutput"));
+ sessionOutput->setObjectName(QString::fromUtf8("sessionOutput"));
sessionOutput->setEnabled(false);
sessionOutput->setFocusPolicy(Qt::NoFocus);
sessionOutput->setReadOnly(true);
@@ -116,20 +116,20 @@ public:
vboxLayout1->addWidget(sessionOutput);
hboxLayout1 = new QHBoxLayout();
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
sessionInputLabel = new QLabel(sessionBox);
- sessionInputLabel->setObjectName(QStringLiteral("sessionInputLabel"));
+ sessionInputLabel->setObjectName(QString::fromUtf8("sessionInputLabel"));
hboxLayout1->addWidget(sessionInputLabel);
sessionInput = new QLineEdit(sessionBox);
- sessionInput->setObjectName(QStringLiteral("sessionInput"));
+ sessionInput->setObjectName(QString::fromUtf8("sessionInput"));
sessionInput->setEnabled(false);
hboxLayout1->addWidget(sessionInput);
sendButton = new QPushButton(sessionBox);
- sendButton->setObjectName(QStringLiteral("sendButton"));
+ sendButton->setObjectName(QString::fromUtf8("sendButton"));
sendButton->setEnabled(false);
sendButton->setFocusPolicy(Qt::TabFocus);
diff --git a/tests/auto/tools/uic/baseline/sslerrors.ui.h b/tests/auto/tools/uic/baseline/sslerrors.ui.h
index d920908de6..04f21ded43 100644
--- a/tests/auto/tools/uic/baseline/sslerrors.ui.h
+++ b/tests/auto/tools/uic/baseline/sslerrors.ui.h
@@ -36,25 +36,25 @@ public:
void setupUi(QDialog *SslErrors)
{
if (SslErrors->objectName().isEmpty())
- SslErrors->setObjectName(QStringLiteral("SslErrors"));
+ SslErrors->setObjectName(QString::fromUtf8("SslErrors"));
SslErrors->resize(371, 216);
vboxLayout = new QVBoxLayout(SslErrors);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
label = new QLabel(SslErrors);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setWordWrap(true);
vboxLayout->addWidget(label);
sslErrorList = new QListWidget(SslErrors);
- sslErrorList->setObjectName(QStringLiteral("sslErrorList"));
+ sslErrorList->setObjectName(QString::fromUtf8("sslErrorList"));
vboxLayout->addWidget(sslErrorList);
hboxLayout = new QHBoxLayout();
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
certificateChainButton = new QPushButton(SslErrors);
- certificateChainButton->setObjectName(QStringLiteral("certificateChainButton"));
+ certificateChainButton->setObjectName(QString::fromUtf8("certificateChainButton"));
certificateChainButton->setAutoDefault(false);
hboxLayout->addWidget(certificateChainButton);
@@ -64,12 +64,12 @@ public:
hboxLayout->addItem(spacerItem);
pushButton = new QPushButton(SslErrors);
- pushButton->setObjectName(QStringLiteral("pushButton"));
+ pushButton->setObjectName(QString::fromUtf8("pushButton"));
hboxLayout->addWidget(pushButton);
pushButton_2 = new QPushButton(SslErrors);
- pushButton_2->setObjectName(QStringLiteral("pushButton_2"));
+ pushButton_2->setObjectName(QString::fromUtf8("pushButton_2"));
hboxLayout->addWidget(pushButton_2);
diff --git a/tests/auto/tools/uic/baseline/statistics.ui.h b/tests/auto/tools/uic/baseline/statistics.ui.h
index ab0f4f9b8d..0b508836f2 100644
--- a/tests/auto/tools/uic/baseline/statistics.ui.h
+++ b/tests/auto/tools/uic/baseline/statistics.ui.h
@@ -76,24 +76,24 @@ public:
void setupUi(QDialog *Statistics)
{
if (Statistics->objectName().isEmpty())
- Statistics->setObjectName(QStringLiteral("Statistics"));
- Statistics->setObjectName(QStringLiteral("linguist_stats"));
+ Statistics->setObjectName(QString::fromUtf8("Statistics"));
+ Statistics->setObjectName(QString::fromUtf8("linguist_stats"));
Statistics->resize(336, 164);
gridLayout = new QGridLayout(Statistics);
gridLayout->setSpacing(6);
gridLayout->setContentsMargins(11, 11, 11, 11);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
- gridLayout->setObjectName(QStringLiteral("unnamed"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("unnamed"));
hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(6);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
- hboxLayout->setObjectName(QStringLiteral("unnamed"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("unnamed"));
spacer4_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(spacer4_2);
closeBtn = new QPushButton(Statistics);
- closeBtn->setObjectName(QStringLiteral("closeBtn"));
+ closeBtn->setObjectName(QString::fromUtf8("closeBtn"));
hboxLayout->addWidget(closeBtn);
@@ -105,66 +105,66 @@ public:
gridLayout->addLayout(hboxLayout, 1, 0, 1, 1);
frame4 = new QFrame(Statistics);
- frame4->setObjectName(QStringLiteral("frame4"));
+ frame4->setObjectName(QString::fromUtf8("frame4"));
frame4->setFrameShape(QFrame::StyledPanel);
frame4->setFrameShadow(QFrame::Raised);
gridLayout1 = new QGridLayout(frame4);
gridLayout1->setSpacing(6);
gridLayout1->setContentsMargins(11, 11, 11, 11);
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
- gridLayout1->setObjectName(QStringLiteral("unnamed"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("unnamed"));
textLabel4 = new QLabel(frame4);
- textLabel4->setObjectName(QStringLiteral("textLabel4"));
+ textLabel4->setObjectName(QString::fromUtf8("textLabel4"));
gridLayout1->addWidget(textLabel4, 0, 2, 1, 1);
textLabel5 = new QLabel(frame4);
- textLabel5->setObjectName(QStringLiteral("textLabel5"));
+ textLabel5->setObjectName(QString::fromUtf8("textLabel5"));
gridLayout1->addWidget(textLabel5, 0, 1, 1, 1);
untrWords = new QLabel(frame4);
- untrWords->setObjectName(QStringLiteral("untrWords"));
+ untrWords->setObjectName(QString::fromUtf8("untrWords"));
gridLayout1->addWidget(untrWords, 1, 1, 1, 1);
trWords = new QLabel(frame4);
- trWords->setObjectName(QStringLiteral("trWords"));
+ trWords->setObjectName(QString::fromUtf8("trWords"));
gridLayout1->addWidget(trWords, 1, 2, 1, 1);
textLabel1 = new QLabel(frame4);
- textLabel1->setObjectName(QStringLiteral("textLabel1"));
+ textLabel1->setObjectName(QString::fromUtf8("textLabel1"));
gridLayout1->addWidget(textLabel1, 1, 0, 1, 1);
trChars = new QLabel(frame4);
- trChars->setObjectName(QStringLiteral("trChars"));
+ trChars->setObjectName(QString::fromUtf8("trChars"));
gridLayout1->addWidget(trChars, 2, 2, 1, 1);
untrChars = new QLabel(frame4);
- untrChars->setObjectName(QStringLiteral("untrChars"));
+ untrChars->setObjectName(QString::fromUtf8("untrChars"));
gridLayout1->addWidget(untrChars, 2, 1, 1, 1);
textLabel3 = new QLabel(frame4);
- textLabel3->setObjectName(QStringLiteral("textLabel3"));
+ textLabel3->setObjectName(QString::fromUtf8("textLabel3"));
gridLayout1->addWidget(textLabel3, 2, 0, 1, 1);
textLabel6 = new QLabel(frame4);
- textLabel6->setObjectName(QStringLiteral("textLabel6"));
+ textLabel6->setObjectName(QString::fromUtf8("textLabel6"));
gridLayout1->addWidget(textLabel6, 3, 0, 1, 1);
trCharsSpc = new QLabel(frame4);
- trCharsSpc->setObjectName(QStringLiteral("trCharsSpc"));
+ trCharsSpc->setObjectName(QString::fromUtf8("trCharsSpc"));
gridLayout1->addWidget(trCharsSpc, 3, 2, 1, 1);
untrCharsSpc = new QLabel(frame4);
- untrCharsSpc->setObjectName(QStringLiteral("untrCharsSpc"));
+ untrCharsSpc->setObjectName(QString::fromUtf8("untrCharsSpc"));
gridLayout1->addWidget(untrCharsSpc, 3, 1, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h
index 44603f1e8a..fd78ce91c1 100644
--- a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h
+++ b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h
@@ -82,7 +82,7 @@ public:
void setupUi(QDialog *qdesigner_internal__Dialog)
{
if (qdesigner_internal__Dialog->objectName().isEmpty())
- qdesigner_internal__Dialog->setObjectName(QStringLiteral("qdesigner_internal__Dialog"));
+ qdesigner_internal__Dialog->setObjectName(QString::fromUtf8("qdesigner_internal__Dialog"));
qdesigner_internal__Dialog->resize(400, 300);
vboxLayout = new QVBoxLayout(qdesigner_internal__Dialog);
#ifndef Q_OS_MAC
@@ -91,9 +91,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(qdesigner_internal__Dialog);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
gridLayout = new QGridLayout(groupBox);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
@@ -101,7 +101,7 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
vboxLayout1 = new QVBoxLayout();
#ifndef Q_OS_MAC
vboxLayout1->setSpacing(6);
@@ -109,7 +109,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout1->setContentsMargins(0, 0, 0, 0);
#endif
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
hboxLayout = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
@@ -117,15 +117,15 @@ public:
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(0, 0, 0, 0);
#endif
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
newButton = new QToolButton(groupBox);
- newButton->setObjectName(QStringLiteral("newButton"));
+ newButton->setObjectName(QString::fromUtf8("newButton"));
newButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
hboxLayout->addWidget(newButton);
deleteButton = new QToolButton(groupBox);
- deleteButton->setObjectName(QStringLiteral("deleteButton"));
+ deleteButton->setObjectName(QString::fromUtf8("deleteButton"));
deleteButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
hboxLayout->addWidget(deleteButton);
@@ -142,14 +142,14 @@ public:
hboxLayout1->setSpacing(6);
#endif
hboxLayout1->setContentsMargins(0, 0, 0, 0);
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
hboxLayout1->addWidget(label);
valueEdit = new QLineEdit(groupBox);
- valueEdit->setObjectName(QStringLiteral("valueEdit"));
+ valueEdit->setObjectName(QString::fromUtf8("valueEdit"));
hboxLayout1->addWidget(valueEdit);
@@ -164,18 +164,18 @@ public:
vboxLayout2->setSpacing(6);
#endif
vboxLayout2->setContentsMargins(0, 0, 0, 0);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
spacerItem1 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
vboxLayout2->addItem(spacerItem1);
upButton = new QToolButton(groupBox);
- upButton->setObjectName(QStringLiteral("upButton"));
+ upButton->setObjectName(QString::fromUtf8("upButton"));
vboxLayout2->addWidget(upButton);
downButton = new QToolButton(groupBox);
- downButton->setObjectName(QStringLiteral("downButton"));
+ downButton->setObjectName(QString::fromUtf8("downButton"));
vboxLayout2->addWidget(downButton);
@@ -187,7 +187,7 @@ public:
gridLayout->addLayout(vboxLayout2, 0, 1, 1, 1);
listView = new QListView(groupBox);
- listView->setObjectName(QStringLiteral("listView"));
+ listView->setObjectName(QString::fromUtf8("listView"));
gridLayout->addWidget(listView, 0, 0, 1, 1);
@@ -195,7 +195,7 @@ public:
vboxLayout->addWidget(groupBox);
buttonBox = new QDialogButtonBox(qdesigner_internal__Dialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h
index a867317820..5ae254ebab 100644
--- a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h
+++ b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h
@@ -41,7 +41,7 @@ public:
void setupUi(QWidget *StyleSheetEditor)
{
if (StyleSheetEditor->objectName().isEmpty())
- StyleSheetEditor->setObjectName(QStringLiteral("StyleSheetEditor"));
+ StyleSheetEditor->setObjectName(QString::fromUtf8("StyleSheetEditor"));
StyleSheetEditor->resize(445, 289);
gridLayout = new QGridLayout(StyleSheetEditor);
#ifndef Q_OS_MAC
@@ -50,7 +50,7 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
spacerItem = new QSpacerItem(32, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
gridLayout->addItem(spacerItem, 0, 6, 1, 1);
@@ -63,7 +63,7 @@ public:
styleSheetCombo->addItem(QString());
styleSheetCombo->addItem(QString());
styleSheetCombo->addItem(QString());
- styleSheetCombo->setObjectName(QStringLiteral("styleSheetCombo"));
+ styleSheetCombo->setObjectName(QString::fromUtf8("styleSheetCombo"));
gridLayout->addWidget(styleSheetCombo, 0, 5, 1, 1);
@@ -72,7 +72,7 @@ public:
gridLayout->addItem(spacerItem2, 0, 3, 1, 1);
styleCombo = new QComboBox(StyleSheetEditor);
- styleCombo->setObjectName(QStringLiteral("styleCombo"));
+ styleCombo->setObjectName(QString::fromUtf8("styleCombo"));
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(5), static_cast<QSizePolicy::Policy>(0));
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -82,7 +82,7 @@ public:
gridLayout->addWidget(styleCombo, 0, 2, 1, 1);
label_7 = new QLabel(StyleSheetEditor);
- label_7->setObjectName(QStringLiteral("label_7"));
+ label_7->setObjectName(QString::fromUtf8("label_7"));
QSizePolicy sizePolicy1(static_cast<QSizePolicy::Policy>(0), static_cast<QSizePolicy::Policy>(5));
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -96,13 +96,13 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
spacerItem3 = new QSpacerItem(321, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(spacerItem3);
applyButton = new QPushButton(StyleSheetEditor);
- applyButton->setObjectName(QStringLiteral("applyButton"));
+ applyButton->setObjectName(QString::fromUtf8("applyButton"));
applyButton->setEnabled(false);
hboxLayout->addWidget(applyButton);
@@ -111,12 +111,12 @@ public:
gridLayout->addLayout(hboxLayout, 2, 0, 1, 7);
styleTextEdit = new QTextEdit(StyleSheetEditor);
- styleTextEdit->setObjectName(QStringLiteral("styleTextEdit"));
+ styleTextEdit->setObjectName(QString::fromUtf8("styleTextEdit"));
gridLayout->addWidget(styleTextEdit, 1, 0, 1, 7);
label_8 = new QLabel(StyleSheetEditor);
- label_8->setObjectName(QStringLiteral("label_8"));
+ label_8->setObjectName(QString::fromUtf8("label_8"));
sizePolicy1.setHeightForWidth(label_8->sizePolicy().hasHeightForWidth());
label_8->setSizePolicy(sizePolicy1);
diff --git a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h
index 5d670b46af..09b230f5df 100644
--- a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h
+++ b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h
@@ -77,28 +77,28 @@ public:
void setupUi(QWidget *TabbedBrowser)
{
if (TabbedBrowser->objectName().isEmpty())
- TabbedBrowser->setObjectName(QStringLiteral("TabbedBrowser"));
+ TabbedBrowser->setObjectName(QString::fromUtf8("TabbedBrowser"));
TabbedBrowser->resize(710, 664);
vboxLayout = new QVBoxLayout(TabbedBrowser);
vboxLayout->setSpacing(0);
vboxLayout->setContentsMargins(0, 0, 0, 0);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
tab = new QTabWidget(TabbedBrowser);
- tab->setObjectName(QStringLiteral("tab"));
+ tab->setObjectName(QString::fromUtf8("tab"));
frontpage = new QWidget();
- frontpage->setObjectName(QStringLiteral("frontpage"));
+ frontpage->setObjectName(QString::fromUtf8("frontpage"));
gridLayout = new QGridLayout(frontpage);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
#endif
gridLayout->setContentsMargins(8, 8, 8, 8);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
tab->addTab(frontpage, QString());
vboxLayout->addWidget(tab);
frameFind = new QFrame(TabbedBrowser);
- frameFind->setObjectName(QStringLiteral("frameFind"));
+ frameFind->setObjectName(QString::fromUtf8("frameFind"));
frameFind->setFrameShape(QFrame::StyledPanel);
frameFind->setFrameShadow(QFrame::Raised);
hboxLayout = new QHBoxLayout(frameFind);
@@ -106,9 +106,9 @@ public:
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
toolClose = new QToolButton(frameFind);
- toolClose->setObjectName(QStringLiteral("toolClose"));
+ toolClose->setObjectName(QString::fromUtf8("toolClose"));
const QIcon icon = QIcon(QString::fromUtf8(":/qt-project.org/assistant/images/close.png"));
toolClose->setIcon(icon);
toolClose->setAutoRaise(true);
@@ -116,7 +116,7 @@ public:
hboxLayout->addWidget(toolClose);
editFind = new QLineEdit(frameFind);
- editFind->setObjectName(QStringLiteral("editFind"));
+ editFind->setObjectName(QString::fromUtf8("editFind"));
QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(0), static_cast<QSizePolicy::Policy>(0));
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -127,7 +127,7 @@ public:
hboxLayout->addWidget(editFind);
toolPrevious = new QToolButton(frameFind);
- toolPrevious->setObjectName(QStringLiteral("toolPrevious"));
+ toolPrevious->setObjectName(QString::fromUtf8("toolPrevious"));
const QIcon icon1 = QIcon(QString::fromUtf8(":/qt-project.org/assistant/images/win/previous.png"));
toolPrevious->setIcon(icon1);
toolPrevious->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -136,7 +136,7 @@ public:
hboxLayout->addWidget(toolPrevious);
toolNext = new QToolButton(frameFind);
- toolNext->setObjectName(QStringLiteral("toolNext"));
+ toolNext->setObjectName(QString::fromUtf8("toolNext"));
toolNext->setMinimumSize(QSize(0, 0));
const QIcon icon2 = QIcon(QString::fromUtf8(":/qt-project.org/assistant/images/win/next.png"));
toolNext->setIcon(icon2);
@@ -147,17 +147,17 @@ public:
hboxLayout->addWidget(toolNext);
checkCase = new QCheckBox(frameFind);
- checkCase->setObjectName(QStringLiteral("checkCase"));
+ checkCase->setObjectName(QString::fromUtf8("checkCase"));
hboxLayout->addWidget(checkCase);
checkWholeWords = new QCheckBox(frameFind);
- checkWholeWords->setObjectName(QStringLiteral("checkWholeWords"));
+ checkWholeWords->setObjectName(QString::fromUtf8("checkWholeWords"));
hboxLayout->addWidget(checkWholeWords);
labelWrapped = new QLabel(frameFind);
- labelWrapped->setObjectName(QStringLiteral("labelWrapped"));
+ labelWrapped->setObjectName(QString::fromUtf8("labelWrapped"));
labelWrapped->setMinimumSize(QSize(0, 20));
labelWrapped->setMaximumSize(QSize(105, 20));
labelWrapped->setTextFormat(Qt::RichText);
diff --git a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h
index ff000305cc..e3ba00095e 100644
--- a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h
+++ b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h
@@ -104,28 +104,28 @@ public:
void setupUi(QDialog *qdesigner_internal__TableWidgetEditor)
{
if (qdesigner_internal__TableWidgetEditor->objectName().isEmpty())
- qdesigner_internal__TableWidgetEditor->setObjectName(QStringLiteral("qdesigner_internal__TableWidgetEditor"));
+ qdesigner_internal__TableWidgetEditor->setObjectName(QString::fromUtf8("qdesigner_internal__TableWidgetEditor"));
qdesigner_internal__TableWidgetEditor->resize(591, 455);
gridLayout_4 = new QGridLayout(qdesigner_internal__TableWidgetEditor);
- gridLayout_4->setObjectName(QStringLiteral("gridLayout_4"));
+ gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));
itemsBox = new QGroupBox(qdesigner_internal__TableWidgetEditor);
- itemsBox->setObjectName(QStringLiteral("itemsBox"));
+ itemsBox->setObjectName(QString::fromUtf8("itemsBox"));
gridLayout = new QGridLayout(itemsBox);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
tableWidget = new QTableWidget(itemsBox);
- tableWidget->setObjectName(QStringLiteral("tableWidget"));
+ tableWidget->setObjectName(QString::fromUtf8("tableWidget"));
gridLayout->addWidget(tableWidget, 0, 0, 1, 1);
horizontalLayout_5 = new QHBoxLayout();
- horizontalLayout_5->setObjectName(QStringLiteral("horizontalLayout_5"));
+ horizontalLayout_5->setObjectName(QString::fromUtf8("horizontalLayout_5"));
label_3 = new QLabel(itemsBox);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
horizontalLayout_5->addWidget(label_3);
itemIconSelector = new qdesigner_internal::IconSelector(itemsBox);
- itemIconSelector->setObjectName(QStringLiteral("itemIconSelector"));
+ itemIconSelector->setObjectName(QString::fromUtf8("itemIconSelector"));
horizontalLayout_5->addWidget(itemIconSelector);
@@ -140,14 +140,14 @@ public:
gridLayout_4->addWidget(itemsBox, 0, 0, 1, 1);
buttonBox = new QDialogButtonBox(qdesigner_internal__TableWidgetEditor);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
gridLayout_4->addWidget(buttonBox, 1, 0, 1, 2);
widget = new QWidget(qdesigner_internal__TableWidgetEditor);
- widget->setObjectName(QStringLiteral("widget"));
+ widget->setObjectName(QString::fromUtf8("widget"));
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -155,13 +155,13 @@ public:
widget->setSizePolicy(sizePolicy);
verticalLayout = new QVBoxLayout(widget);
verticalLayout->setContentsMargins(0, 0, 0, 0);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
columnsBox = new QGroupBox(widget);
- columnsBox->setObjectName(QStringLiteral("columnsBox"));
+ columnsBox->setObjectName(QString::fromUtf8("columnsBox"));
gridLayout_2 = new QGridLayout(columnsBox);
- gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
+ gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
columnsListWidget = new QListWidget(columnsBox);
- columnsListWidget->setObjectName(QStringLiteral("columnsListWidget"));
+ columnsListWidget->setObjectName(QString::fromUtf8("columnsListWidget"));
QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Expanding);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -172,14 +172,14 @@ public:
gridLayout_2->addWidget(columnsListWidget, 0, 0, 1, 1);
horizontalLayout_3 = new QHBoxLayout();
- horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3"));
+ horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
newColumnButton = new QToolButton(columnsBox);
- newColumnButton->setObjectName(QStringLiteral("newColumnButton"));
+ newColumnButton->setObjectName(QString::fromUtf8("newColumnButton"));
horizontalLayout_3->addWidget(newColumnButton);
deleteColumnButton = new QToolButton(columnsBox);
- deleteColumnButton->setObjectName(QStringLiteral("deleteColumnButton"));
+ deleteColumnButton->setObjectName(QString::fromUtf8("deleteColumnButton"));
horizontalLayout_3->addWidget(deleteColumnButton);
@@ -188,12 +188,12 @@ public:
horizontalLayout_3->addItem(spacerItem);
moveColumnUpButton = new QToolButton(columnsBox);
- moveColumnUpButton->setObjectName(QStringLiteral("moveColumnUpButton"));
+ moveColumnUpButton->setObjectName(QString::fromUtf8("moveColumnUpButton"));
horizontalLayout_3->addWidget(moveColumnUpButton);
moveColumnDownButton = new QToolButton(columnsBox);
- moveColumnDownButton->setObjectName(QStringLiteral("moveColumnDownButton"));
+ moveColumnDownButton->setObjectName(QString::fromUtf8("moveColumnDownButton"));
horizontalLayout_3->addWidget(moveColumnDownButton);
@@ -201,14 +201,14 @@ public:
gridLayout_2->addLayout(horizontalLayout_3, 1, 0, 1, 1);
horizontalLayout_2 = new QHBoxLayout();
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
label = new QLabel(columnsBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
horizontalLayout_2->addWidget(label);
columnIconSelector = new qdesigner_internal::IconSelector(columnsBox);
- columnIconSelector->setObjectName(QStringLiteral("columnIconSelector"));
+ columnIconSelector->setObjectName(QString::fromUtf8("columnIconSelector"));
horizontalLayout_2->addWidget(columnIconSelector);
@@ -223,11 +223,11 @@ public:
verticalLayout->addWidget(columnsBox);
rowsBox = new QGroupBox(widget);
- rowsBox->setObjectName(QStringLiteral("rowsBox"));
+ rowsBox->setObjectName(QString::fromUtf8("rowsBox"));
gridLayout_3 = new QGridLayout(rowsBox);
- gridLayout_3->setObjectName(QStringLiteral("gridLayout_3"));
+ gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3"));
rowsListWidget = new QListWidget(rowsBox);
- rowsListWidget->setObjectName(QStringLiteral("rowsListWidget"));
+ rowsListWidget->setObjectName(QString::fromUtf8("rowsListWidget"));
sizePolicy1.setHeightForWidth(rowsListWidget->sizePolicy().hasHeightForWidth());
rowsListWidget->setSizePolicy(sizePolicy1);
rowsListWidget->setFocusPolicy(Qt::TabFocus);
@@ -235,14 +235,14 @@ public:
gridLayout_3->addWidget(rowsListWidget, 0, 0, 1, 1);
horizontalLayout_4 = new QHBoxLayout();
- horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4"));
+ horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4"));
newRowButton = new QToolButton(rowsBox);
- newRowButton->setObjectName(QStringLiteral("newRowButton"));
+ newRowButton->setObjectName(QString::fromUtf8("newRowButton"));
horizontalLayout_4->addWidget(newRowButton);
deleteRowButton = new QToolButton(rowsBox);
- deleteRowButton->setObjectName(QStringLiteral("deleteRowButton"));
+ deleteRowButton->setObjectName(QString::fromUtf8("deleteRowButton"));
horizontalLayout_4->addWidget(deleteRowButton);
@@ -251,12 +251,12 @@ public:
horizontalLayout_4->addItem(spacerItem2);
moveRowUpButton = new QToolButton(rowsBox);
- moveRowUpButton->setObjectName(QStringLiteral("moveRowUpButton"));
+ moveRowUpButton->setObjectName(QString::fromUtf8("moveRowUpButton"));
horizontalLayout_4->addWidget(moveRowUpButton);
moveRowDownButton = new QToolButton(rowsBox);
- moveRowDownButton->setObjectName(QStringLiteral("moveRowDownButton"));
+ moveRowDownButton->setObjectName(QString::fromUtf8("moveRowDownButton"));
horizontalLayout_4->addWidget(moveRowDownButton);
@@ -264,14 +264,14 @@ public:
gridLayout_3->addLayout(horizontalLayout_4, 1, 0, 1, 1);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
label_2 = new QLabel(rowsBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
horizontalLayout->addWidget(label_2);
rowIconSelector = new qdesigner_internal::IconSelector(rowsBox);
- rowIconSelector->setObjectName(QStringLiteral("rowIconSelector"));
+ rowIconSelector->setObjectName(QString::fromUtf8("rowIconSelector"));
horizontalLayout->addWidget(rowIconSelector);
diff --git a/tests/auto/tools/uic/baseline/tetrixwindow.ui.h b/tests/auto/tools/uic/baseline/tetrixwindow.ui.h
index 32c6464209..dc1033ce3a 100644
--- a/tests/auto/tools/uic/baseline/tetrixwindow.ui.h
+++ b/tests/auto/tools/uic/baseline/tetrixwindow.ui.h
@@ -42,7 +42,7 @@ public:
void setupUi(QWidget *TetrixWindow)
{
if (TetrixWindow->objectName().isEmpty())
- TetrixWindow->setObjectName(QStringLiteral("TetrixWindow"));
+ TetrixWindow->setObjectName(QString::fromUtf8("TetrixWindow"));
TetrixWindow->resize(537, 475);
vboxLayout = new QVBoxLayout(TetrixWindow);
#ifndef Q_OS_MAC
@@ -51,7 +51,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
gridLayout = new QGridLayout();
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
@@ -59,39 +59,39 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(0, 0, 0, 0);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
startButton = new QPushButton(TetrixWindow);
- startButton->setObjectName(QStringLiteral("startButton"));
+ startButton->setObjectName(QString::fromUtf8("startButton"));
startButton->setFocusPolicy(Qt::NoFocus);
gridLayout->addWidget(startButton, 4, 0, 1, 1);
linesLcd = new QLCDNumber(TetrixWindow);
- linesLcd->setObjectName(QStringLiteral("linesLcd"));
+ linesLcd->setObjectName(QString::fromUtf8("linesLcd"));
linesLcd->setSegmentStyle(QLCDNumber::Filled);
gridLayout->addWidget(linesLcd, 3, 2, 1, 1);
linesRemovedLabel = new QLabel(TetrixWindow);
- linesRemovedLabel->setObjectName(QStringLiteral("linesRemovedLabel"));
+ linesRemovedLabel->setObjectName(QString::fromUtf8("linesRemovedLabel"));
linesRemovedLabel->setAlignment(Qt::AlignBottom|Qt::AlignHCenter);
gridLayout->addWidget(linesRemovedLabel, 2, 2, 1, 1);
pauseButton = new QPushButton(TetrixWindow);
- pauseButton->setObjectName(QStringLiteral("pauseButton"));
+ pauseButton->setObjectName(QString::fromUtf8("pauseButton"));
pauseButton->setFocusPolicy(Qt::NoFocus);
gridLayout->addWidget(pauseButton, 5, 2, 1, 1);
scoreLcd = new QLCDNumber(TetrixWindow);
- scoreLcd->setObjectName(QStringLiteral("scoreLcd"));
+ scoreLcd->setObjectName(QString::fromUtf8("scoreLcd"));
scoreLcd->setSegmentStyle(QLCDNumber::Filled);
gridLayout->addWidget(scoreLcd, 1, 2, 1, 1);
board = new TetrixBoard(TetrixWindow);
- board->setObjectName(QStringLiteral("board"));
+ board->setObjectName(QString::fromUtf8("board"));
board->setFocusPolicy(Qt::StrongFocus);
board->setFrameShape(QFrame::Panel);
board->setFrameShadow(QFrame::Sunken);
@@ -99,31 +99,31 @@ public:
gridLayout->addWidget(board, 0, 1, 6, 1);
levelLabel = new QLabel(TetrixWindow);
- levelLabel->setObjectName(QStringLiteral("levelLabel"));
+ levelLabel->setObjectName(QString::fromUtf8("levelLabel"));
levelLabel->setAlignment(Qt::AlignBottom|Qt::AlignHCenter);
gridLayout->addWidget(levelLabel, 2, 0, 1, 1);
nextLabel = new QLabel(TetrixWindow);
- nextLabel->setObjectName(QStringLiteral("nextLabel"));
+ nextLabel->setObjectName(QString::fromUtf8("nextLabel"));
nextLabel->setAlignment(Qt::AlignBottom|Qt::AlignHCenter);
gridLayout->addWidget(nextLabel, 0, 0, 1, 1);
levelLcd = new QLCDNumber(TetrixWindow);
- levelLcd->setObjectName(QStringLiteral("levelLcd"));
+ levelLcd->setObjectName(QString::fromUtf8("levelLcd"));
levelLcd->setSegmentStyle(QLCDNumber::Filled);
gridLayout->addWidget(levelLcd, 3, 0, 1, 1);
scoreLabel = new QLabel(TetrixWindow);
- scoreLabel->setObjectName(QStringLiteral("scoreLabel"));
+ scoreLabel->setObjectName(QString::fromUtf8("scoreLabel"));
scoreLabel->setAlignment(Qt::AlignBottom|Qt::AlignHCenter);
gridLayout->addWidget(scoreLabel, 0, 2, 1, 1);
nextPieceLabel = new QLabel(TetrixWindow);
- nextPieceLabel->setObjectName(QStringLiteral("nextPieceLabel"));
+ nextPieceLabel->setObjectName(QString::fromUtf8("nextPieceLabel"));
nextPieceLabel->setFrameShape(QFrame::Box);
nextPieceLabel->setFrameShadow(QFrame::Raised);
nextPieceLabel->setAlignment(Qt::AlignCenter);
@@ -131,7 +131,7 @@ public:
gridLayout->addWidget(nextPieceLabel, 1, 0, 1, 1);
quitButton = new QPushButton(TetrixWindow);
- quitButton->setObjectName(QStringLiteral("quitButton"));
+ quitButton->setObjectName(QString::fromUtf8("quitButton"));
quitButton->setFocusPolicy(Qt::NoFocus);
gridLayout->addWidget(quitButton, 4, 2, 1, 1);
diff --git a/tests/auto/tools/uic/baseline/textfinder.ui.h b/tests/auto/tools/uic/baseline/textfinder.ui.h
index beae214e19..2f6bfebf98 100644
--- a/tests/auto/tools/uic/baseline/textfinder.ui.h
+++ b/tests/auto/tools/uic/baseline/textfinder.ui.h
@@ -36,7 +36,7 @@ public:
void setupUi(QWidget *Form)
{
if (Form->objectName().isEmpty())
- Form->setObjectName(QStringLiteral("Form"));
+ Form->setObjectName(QString::fromUtf8("Form"));
Form->resize(378, 158);
vboxLayout = new QVBoxLayout(Form);
#ifndef Q_OS_MAC
@@ -45,7 +45,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
gridLayout = new QGridLayout();
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
@@ -53,19 +53,19 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(0, 0, 0, 0);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
lineEdit = new QLineEdit(Form);
- lineEdit->setObjectName(QStringLiteral("lineEdit"));
+ lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
gridLayout->addWidget(lineEdit, 0, 1, 1, 1);
searchLabel = new QLabel(Form);
- searchLabel->setObjectName(QStringLiteral("searchLabel"));
+ searchLabel->setObjectName(QString::fromUtf8("searchLabel"));
gridLayout->addWidget(searchLabel, 0, 0, 1, 1);
findButton = new QPushButton(Form);
- findButton->setObjectName(QStringLiteral("findButton"));
+ findButton->setObjectName(QString::fromUtf8("findButton"));
gridLayout->addWidget(findButton, 0, 2, 1, 1);
@@ -73,7 +73,7 @@ public:
vboxLayout->addLayout(gridLayout);
textEdit = new QTextEdit(Form);
- textEdit->setObjectName(QStringLiteral("textEdit"));
+ textEdit->setObjectName(QString::fromUtf8("textEdit"));
vboxLayout->addWidget(textEdit);
diff --git a/tests/auto/tools/uic/baseline/topicchooser.ui.h b/tests/auto/tools/uic/baseline/topicchooser.ui.h
index 2770553775..90ec485e39 100644
--- a/tests/auto/tools/uic/baseline/topicchooser.ui.h
+++ b/tests/auto/tools/uic/baseline/topicchooser.ui.h
@@ -37,7 +37,7 @@ public:
void setupUi(QDialog *TopicChooser)
{
if (TopicChooser->objectName().isEmpty())
- TopicChooser->setObjectName(QStringLiteral("TopicChooser"));
+ TopicChooser->setObjectName(QString::fromUtf8("TopicChooser"));
TopicChooser->resize(391, 223);
TopicChooser->setSizeGripEnabled(true);
vboxLayout = new QVBoxLayout(TopicChooser);
@@ -45,40 +45,40 @@ public:
vboxLayout->setSpacing(6);
#endif
vboxLayout->setContentsMargins(11, 11, 11, 11);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
- vboxLayout->setObjectName(QStringLiteral("unnamed"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("unnamed"));
label = new QLabel(TopicChooser);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
vboxLayout->addWidget(label);
listWidget = new QListWidget(TopicChooser);
- listWidget->setObjectName(QStringLiteral("listWidget"));
+ listWidget->setObjectName(QString::fromUtf8("listWidget"));
vboxLayout->addWidget(listWidget);
Layout16 = new QWidget(TopicChooser);
- Layout16->setObjectName(QStringLiteral("Layout16"));
+ Layout16->setObjectName(QString::fromUtf8("Layout16"));
hboxLayout = new QHBoxLayout(Layout16);
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
#endif
hboxLayout->setContentsMargins(0, 0, 0, 0);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
- hboxLayout->setObjectName(QStringLiteral("unnamed"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("unnamed"));
hboxLayout->setContentsMargins(0, 0, 0, 0);
Horizontal_Spacing2 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout->addItem(Horizontal_Spacing2);
buttonDisplay = new QPushButton(Layout16);
- buttonDisplay->setObjectName(QStringLiteral("buttonDisplay"));
+ buttonDisplay->setObjectName(QString::fromUtf8("buttonDisplay"));
buttonDisplay->setAutoDefault(true);
hboxLayout->addWidget(buttonDisplay);
buttonCancel = new QPushButton(Layout16);
- buttonCancel->setObjectName(QStringLiteral("buttonCancel"));
+ buttonCancel->setObjectName(QString::fromUtf8("buttonCancel"));
buttonCancel->setAutoDefault(true);
hboxLayout->addWidget(buttonCancel);
diff --git a/tests/auto/tools/uic/baseline/translatedialog.ui.h b/tests/auto/tools/uic/baseline/translatedialog.ui.h
index 32b73be37a..5bea11f9f2 100644
--- a/tests/auto/tools/uic/baseline/translatedialog.ui.h
+++ b/tests/auto/tools/uic/baseline/translatedialog.ui.h
@@ -79,7 +79,7 @@ public:
void setupUi(QDialog *TranslateDialog)
{
if (TranslateDialog->objectName().isEmpty())
- TranslateDialog->setObjectName(QStringLiteral("TranslateDialog"));
+ TranslateDialog->setObjectName(QString::fromUtf8("TranslateDialog"));
TranslateDialog->resize(407, 145);
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
sizePolicy.setHorizontalStretch(0);
@@ -89,35 +89,35 @@ public:
hboxLayout = new QHBoxLayout(TranslateDialog);
hboxLayout->setSpacing(6);
hboxLayout->setContentsMargins(11, 11, 11, 11);
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
hboxLayout->setContentsMargins(9, 9, 9, 9);
vboxLayout = new QVBoxLayout();
vboxLayout->setSpacing(6);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout->setContentsMargins(0, 0, 0, 0);
gridLayout = new QGridLayout();
gridLayout->setSpacing(6);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
gridLayout->setHorizontalSpacing(6);
gridLayout->setVerticalSpacing(6);
gridLayout->setContentsMargins(0, 0, 0, 0);
ledTranslateTo = new QLineEdit(TranslateDialog);
- ledTranslateTo->setObjectName(QStringLiteral("ledTranslateTo"));
+ ledTranslateTo->setObjectName(QString::fromUtf8("ledTranslateTo"));
gridLayout->addWidget(ledTranslateTo, 1, 1, 1, 1);
findWhat = new QLabel(TranslateDialog);
- findWhat->setObjectName(QStringLiteral("findWhat"));
+ findWhat->setObjectName(QString::fromUtf8("findWhat"));
gridLayout->addWidget(findWhat, 0, 0, 1, 1);
translateTo = new QLabel(TranslateDialog);
- translateTo->setObjectName(QStringLiteral("translateTo"));
+ translateTo->setObjectName(QString::fromUtf8("translateTo"));
gridLayout->addWidget(translateTo, 1, 0, 1, 1);
ledFindWhat = new QLineEdit(TranslateDialog);
- ledFindWhat->setObjectName(QStringLiteral("ledFindWhat"));
+ ledFindWhat->setObjectName(QString::fromUtf8("ledFindWhat"));
gridLayout->addWidget(ledFindWhat, 0, 1, 1, 1);
@@ -125,18 +125,18 @@ public:
vboxLayout->addLayout(gridLayout);
groupBox = new QGroupBox(TranslateDialog);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
vboxLayout1 = new QVBoxLayout(groupBox);
vboxLayout1->setSpacing(6);
vboxLayout1->setContentsMargins(11, 11, 11, 11);
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
ckMatchCase = new QCheckBox(groupBox);
- ckMatchCase->setObjectName(QStringLiteral("ckMatchCase"));
+ ckMatchCase->setObjectName(QString::fromUtf8("ckMatchCase"));
vboxLayout1->addWidget(ckMatchCase);
ckMarkFinished = new QCheckBox(groupBox);
- ckMarkFinished->setObjectName(QStringLiteral("ckMarkFinished"));
+ ckMarkFinished->setObjectName(QString::fromUtf8("ckMarkFinished"));
vboxLayout1->addWidget(ckMarkFinished);
@@ -152,26 +152,26 @@ public:
vboxLayout2 = new QVBoxLayout();
vboxLayout2->setSpacing(6);
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
vboxLayout2->setContentsMargins(0, 0, 0, 0);
findNxt = new QPushButton(TranslateDialog);
- findNxt->setObjectName(QStringLiteral("findNxt"));
+ findNxt->setObjectName(QString::fromUtf8("findNxt"));
findNxt->setFlat(false);
vboxLayout2->addWidget(findNxt);
translate = new QPushButton(TranslateDialog);
- translate->setObjectName(QStringLiteral("translate"));
+ translate->setObjectName(QString::fromUtf8("translate"));
vboxLayout2->addWidget(translate);
translateAll = new QPushButton(TranslateDialog);
- translateAll->setObjectName(QStringLiteral("translateAll"));
+ translateAll->setObjectName(QString::fromUtf8("translateAll"));
vboxLayout2->addWidget(translateAll);
cancel = new QPushButton(TranslateDialog);
- cancel->setObjectName(QStringLiteral("cancel"));
+ cancel->setObjectName(QString::fromUtf8("cancel"));
vboxLayout2->addWidget(cancel);
diff --git a/tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h b/tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h
index 1da7140f97..eea7b7335d 100644
--- a/tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h
+++ b/tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h
@@ -23,7 +23,7 @@ public:
void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
- Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(400, 300);
retranslateUi(Dialog);
diff --git a/tests/auto/tools/uic/baseline/translationsettings.ui.h b/tests/auto/tools/uic/baseline/translationsettings.ui.h
index 522c9bd4e0..764e3a85b6 100644
--- a/tests/auto/tools/uic/baseline/translationsettings.ui.h
+++ b/tests/auto/tools/uic/baseline/translationsettings.ui.h
@@ -36,7 +36,7 @@ public:
void setupUi(QDialog *TranslationSettings)
{
if (TranslationSettings->objectName().isEmpty())
- TranslationSettings->setObjectName(QStringLiteral("TranslationSettings"));
+ TranslationSettings->setObjectName(QString::fromUtf8("TranslationSettings"));
TranslationSettings->resize(346, 125);
vboxLayout = new QVBoxLayout(TranslationSettings);
#ifndef Q_OS_MAC
@@ -45,9 +45,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
groupBox = new QGroupBox(TranslationSettings);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
gridLayout = new QGridLayout(groupBox);
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
@@ -55,24 +55,24 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(9, 9, 9, 9);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
cbLanguageList = new QComboBox(groupBox);
- cbLanguageList->setObjectName(QStringLiteral("cbLanguageList"));
+ cbLanguageList->setObjectName(QString::fromUtf8("cbLanguageList"));
gridLayout->addWidget(cbLanguageList, 0, 1, 1, 1);
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 0, 0, 1, 1);
cbCountryList = new QComboBox(groupBox);
- cbCountryList->setObjectName(QStringLiteral("cbCountryList"));
+ cbCountryList->setObjectName(QString::fromUtf8("cbCountryList"));
gridLayout->addWidget(cbCountryList, 1, 1, 1, 1);
lblCountry = new QLabel(groupBox);
- lblCountry->setObjectName(QStringLiteral("lblCountry"));
+ lblCountry->setObjectName(QString::fromUtf8("lblCountry"));
gridLayout->addWidget(lblCountry, 1, 0, 1, 1);
@@ -80,7 +80,7 @@ public:
vboxLayout->addWidget(groupBox);
buttonBox = new QDialogButtonBox(TranslationSettings);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h
index 13957e843c..d432195648 100644
--- a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h
+++ b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h
@@ -96,34 +96,34 @@ public:
void setupUi(QDialog *qdesigner_internal__TreeWidgetEditor)
{
if (qdesigner_internal__TreeWidgetEditor->objectName().isEmpty())
- qdesigner_internal__TreeWidgetEditor->setObjectName(QStringLiteral("qdesigner_internal__TreeWidgetEditor"));
+ qdesigner_internal__TreeWidgetEditor->setObjectName(QString::fromUtf8("qdesigner_internal__TreeWidgetEditor"));
qdesigner_internal__TreeWidgetEditor->resize(619, 321);
gridLayout_3 = new QGridLayout(qdesigner_internal__TreeWidgetEditor);
- gridLayout_3->setObjectName(QStringLiteral("gridLayout_3"));
+ gridLayout_3->setObjectName(QString::fromUtf8("gridLayout_3"));
itemsBox = new QGroupBox(qdesigner_internal__TreeWidgetEditor);
- itemsBox->setObjectName(QStringLiteral("itemsBox"));
+ itemsBox->setObjectName(QString::fromUtf8("itemsBox"));
gridLayout = new QGridLayout(itemsBox);
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
treeWidget = new QTreeWidget(itemsBox);
- treeWidget->setObjectName(QStringLiteral("treeWidget"));
+ treeWidget->setObjectName(QString::fromUtf8("treeWidget"));
treeWidget->setFocusPolicy(Qt::TabFocus);
gridLayout->addWidget(treeWidget, 0, 0, 1, 1);
horizontalLayout_4 = new QHBoxLayout();
- horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4"));
+ horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4"));
newItemButton = new QToolButton(itemsBox);
- newItemButton->setObjectName(QStringLiteral("newItemButton"));
+ newItemButton->setObjectName(QString::fromUtf8("newItemButton"));
horizontalLayout_4->addWidget(newItemButton);
newSubItemButton = new QToolButton(itemsBox);
- newSubItemButton->setObjectName(QStringLiteral("newSubItemButton"));
+ newSubItemButton->setObjectName(QString::fromUtf8("newSubItemButton"));
horizontalLayout_4->addWidget(newSubItemButton);
deleteItemButton = new QToolButton(itemsBox);
- deleteItemButton->setObjectName(QStringLiteral("deleteItemButton"));
+ deleteItemButton->setObjectName(QString::fromUtf8("deleteItemButton"));
horizontalLayout_4->addWidget(deleteItemButton);
@@ -132,22 +132,22 @@ public:
horizontalLayout_4->addItem(spacerItem);
moveItemLeftButton = new QToolButton(itemsBox);
- moveItemLeftButton->setObjectName(QStringLiteral("moveItemLeftButton"));
+ moveItemLeftButton->setObjectName(QString::fromUtf8("moveItemLeftButton"));
horizontalLayout_4->addWidget(moveItemLeftButton);
moveItemRightButton = new QToolButton(itemsBox);
- moveItemRightButton->setObjectName(QStringLiteral("moveItemRightButton"));
+ moveItemRightButton->setObjectName(QString::fromUtf8("moveItemRightButton"));
horizontalLayout_4->addWidget(moveItemRightButton);
moveItemUpButton = new QToolButton(itemsBox);
- moveItemUpButton->setObjectName(QStringLiteral("moveItemUpButton"));
+ moveItemUpButton->setObjectName(QString::fromUtf8("moveItemUpButton"));
horizontalLayout_4->addWidget(moveItemUpButton);
moveItemDownButton = new QToolButton(itemsBox);
- moveItemDownButton->setObjectName(QStringLiteral("moveItemDownButton"));
+ moveItemDownButton->setObjectName(QString::fromUtf8("moveItemDownButton"));
horizontalLayout_4->addWidget(moveItemDownButton);
@@ -155,14 +155,14 @@ public:
gridLayout->addLayout(horizontalLayout_4, 1, 0, 1, 1);
horizontalLayout_2 = new QHBoxLayout();
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
label_2 = new QLabel(itemsBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
horizontalLayout_2->addWidget(label_2);
itemIconSelector = new qdesigner_internal::IconSelector(itemsBox);
- itemIconSelector->setObjectName(QStringLiteral("itemIconSelector"));
+ itemIconSelector->setObjectName(QString::fromUtf8("itemIconSelector"));
horizontalLayout_2->addWidget(itemIconSelector);
@@ -177,16 +177,16 @@ public:
gridLayout_3->addWidget(itemsBox, 0, 0, 1, 1);
columnsBox = new QGroupBox(qdesigner_internal__TreeWidgetEditor);
- columnsBox->setObjectName(QStringLiteral("columnsBox"));
+ columnsBox->setObjectName(QString::fromUtf8("columnsBox"));
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(columnsBox->sizePolicy().hasHeightForWidth());
columnsBox->setSizePolicy(sizePolicy);
gridLayout_2 = new QGridLayout(columnsBox);
- gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
+ gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
listWidget = new QListWidget(columnsBox);
- listWidget->setObjectName(QStringLiteral("listWidget"));
+ listWidget->setObjectName(QString::fromUtf8("listWidget"));
QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Expanding);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -197,14 +197,14 @@ public:
gridLayout_2->addWidget(listWidget, 0, 0, 1, 1);
horizontalLayout_3 = new QHBoxLayout();
- horizontalLayout_3->setObjectName(QStringLiteral("horizontalLayout_3"));
+ horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
newColumnButton = new QToolButton(columnsBox);
- newColumnButton->setObjectName(QStringLiteral("newColumnButton"));
+ newColumnButton->setObjectName(QString::fromUtf8("newColumnButton"));
horizontalLayout_3->addWidget(newColumnButton);
deleteColumnButton = new QToolButton(columnsBox);
- deleteColumnButton->setObjectName(QStringLiteral("deleteColumnButton"));
+ deleteColumnButton->setObjectName(QString::fromUtf8("deleteColumnButton"));
horizontalLayout_3->addWidget(deleteColumnButton);
@@ -213,12 +213,12 @@ public:
horizontalLayout_3->addItem(spacerItem1);
moveColumnUpButton = new QToolButton(columnsBox);
- moveColumnUpButton->setObjectName(QStringLiteral("moveColumnUpButton"));
+ moveColumnUpButton->setObjectName(QString::fromUtf8("moveColumnUpButton"));
horizontalLayout_3->addWidget(moveColumnUpButton);
moveColumnDownButton = new QToolButton(columnsBox);
- moveColumnDownButton->setObjectName(QStringLiteral("moveColumnDownButton"));
+ moveColumnDownButton->setObjectName(QString::fromUtf8("moveColumnDownButton"));
horizontalLayout_3->addWidget(moveColumnDownButton);
@@ -226,14 +226,14 @@ public:
gridLayout_2->addLayout(horizontalLayout_3, 1, 0, 1, 1);
horizontalLayout = new QHBoxLayout();
- horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
label = new QLabel(columnsBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
horizontalLayout->addWidget(label);
columnIconSelector = new qdesigner_internal::IconSelector(columnsBox);
- columnIconSelector->setObjectName(QStringLiteral("columnIconSelector"));
+ columnIconSelector->setObjectName(QString::fromUtf8("columnIconSelector"));
horizontalLayout->addWidget(columnIconSelector);
@@ -248,7 +248,7 @@ public:
gridLayout_3->addWidget(columnsBox, 0, 1, 1, 1);
buttonBox = new QDialogButtonBox(qdesigner_internal__TreeWidgetEditor);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
diff --git a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h
index da6e86a8ce..3fbf125a1f 100644
--- a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h
+++ b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h
@@ -79,58 +79,58 @@ public:
void setupUi(QMainWindow *TrPreviewToolClass)
{
if (TrPreviewToolClass->objectName().isEmpty())
- TrPreviewToolClass->setObjectName(QStringLiteral("TrPreviewToolClass"));
+ TrPreviewToolClass->setObjectName(QString::fromUtf8("TrPreviewToolClass"));
TrPreviewToolClass->resize(593, 466);
actionOpenForm = new QAction(TrPreviewToolClass);
- actionOpenForm->setObjectName(QStringLiteral("actionOpenForm"));
+ actionOpenForm->setObjectName(QString::fromUtf8("actionOpenForm"));
const QIcon icon = QIcon(QString::fromUtf8(":/images/open_form.png"));
actionOpenForm->setIcon(icon);
actionLoadTranslation = new QAction(TrPreviewToolClass);
- actionLoadTranslation->setObjectName(QStringLiteral("actionLoadTranslation"));
+ actionLoadTranslation->setObjectName(QString::fromUtf8("actionLoadTranslation"));
const QIcon icon1 = QIcon(QString::fromUtf8(":/images/load_translation.png"));
actionLoadTranslation->setIcon(icon1);
actionReloadTranslations = new QAction(TrPreviewToolClass);
- actionReloadTranslations->setObjectName(QStringLiteral("actionReloadTranslations"));
+ actionReloadTranslations->setObjectName(QString::fromUtf8("actionReloadTranslations"));
const QIcon icon2 = QIcon(QString::fromUtf8(":/images/reload_translations.png"));
actionReloadTranslations->setIcon(icon2);
actionClose = new QAction(TrPreviewToolClass);
- actionClose->setObjectName(QStringLiteral("actionClose"));
+ actionClose->setObjectName(QString::fromUtf8("actionClose"));
actionAbout = new QAction(TrPreviewToolClass);
- actionAbout->setObjectName(QStringLiteral("actionAbout"));
+ actionAbout->setObjectName(QString::fromUtf8("actionAbout"));
actionAbout_Qt = new QAction(TrPreviewToolClass);
- actionAbout_Qt->setObjectName(QStringLiteral("actionAbout_Qt"));
+ actionAbout_Qt->setObjectName(QString::fromUtf8("actionAbout_Qt"));
centralWidget = new QWidget(TrPreviewToolClass);
- centralWidget->setObjectName(QStringLiteral("centralWidget"));
+ centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
TrPreviewToolClass->setCentralWidget(centralWidget);
menuBar = new QMenuBar(TrPreviewToolClass);
- menuBar->setObjectName(QStringLiteral("menuBar"));
+ menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 593, 21));
menuView = new QMenu(menuBar);
- menuView->setObjectName(QStringLiteral("menuView"));
+ menuView->setObjectName(QString::fromUtf8("menuView"));
menuViewViews = new QMenu(menuView);
- menuViewViews->setObjectName(QStringLiteral("menuViewViews"));
+ menuViewViews->setObjectName(QString::fromUtf8("menuViewViews"));
menuHelp = new QMenu(menuBar);
- menuHelp->setObjectName(QStringLiteral("menuHelp"));
+ menuHelp->setObjectName(QString::fromUtf8("menuHelp"));
menuFile = new QMenu(menuBar);
- menuFile->setObjectName(QStringLiteral("menuFile"));
+ menuFile->setObjectName(QString::fromUtf8("menuFile"));
TrPreviewToolClass->setMenuBar(menuBar);
mainToolBar = new QToolBar(TrPreviewToolClass);
- mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
+ mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
mainToolBar->setOrientation(Qt::Horizontal);
TrPreviewToolClass->addToolBar(static_cast<Qt::ToolBarArea>(4), mainToolBar);
statusBar = new QStatusBar(TrPreviewToolClass);
- statusBar->setObjectName(QStringLiteral("statusBar"));
+ statusBar->setObjectName(QString::fromUtf8("statusBar"));
TrPreviewToolClass->setStatusBar(statusBar);
dwForms = new QDockWidget(TrPreviewToolClass);
- dwForms->setObjectName(QStringLiteral("dwForms"));
+ dwForms->setObjectName(QString::fromUtf8("dwForms"));
dockWidgetContents = new QWidget();
- dockWidgetContents->setObjectName(QStringLiteral("dockWidgetContents"));
+ dockWidgetContents->setObjectName(QString::fromUtf8("dockWidgetContents"));
vboxLayout = new QVBoxLayout(dockWidgetContents);
vboxLayout->setSpacing(0);
vboxLayout->setContentsMargins(0, 0, 0, 0);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
viewForms = new QListView(dockWidgetContents);
- viewForms->setObjectName(QStringLiteral("viewForms"));
+ viewForms->setObjectName(QString::fromUtf8("viewForms"));
viewForms->setEditTriggers(QAbstractItemView::NoEditTriggers);
viewForms->setAlternatingRowColors(true);
viewForms->setUniformItemSizes(true);
diff --git a/tests/auto/tools/uic/baseline/validators.ui.h b/tests/auto/tools/uic/baseline/validators.ui.h
index a28f9e8390..0595cf2037 100644
--- a/tests/auto/tools/uic/baseline/validators.ui.h
+++ b/tests/auto/tools/uic/baseline/validators.ui.h
@@ -76,7 +76,7 @@ public:
void setupUi(QWidget *ValidatorsForm)
{
if (ValidatorsForm->objectName().isEmpty())
- ValidatorsForm->setObjectName(QStringLiteral("ValidatorsForm"));
+ ValidatorsForm->setObjectName(QString::fromUtf8("ValidatorsForm"));
ValidatorsForm->resize(526, 668);
vboxLayout = new QVBoxLayout(ValidatorsForm);
#ifndef Q_OS_MAC
@@ -85,7 +85,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
hboxLayout = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout->setSpacing(6);
@@ -93,9 +93,9 @@ public:
#ifndef Q_OS_MAC
hboxLayout->setContentsMargins(0, 0, 0, 0);
#endif
- hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
localeSelector = new LocaleSelector(ValidatorsForm);
- localeSelector->setObjectName(QStringLiteral("localeSelector"));
+ localeSelector->setObjectName(QString::fromUtf8("localeSelector"));
hboxLayout->addWidget(localeSelector);
@@ -107,7 +107,7 @@ public:
vboxLayout->addLayout(hboxLayout);
groupBox = new QGroupBox(ValidatorsForm);
- groupBox->setObjectName(QStringLiteral("groupBox"));
+ groupBox->setObjectName(QString::fromUtf8("groupBox"));
vboxLayout1 = new QVBoxLayout(groupBox);
#ifndef Q_OS_MAC
vboxLayout1->setSpacing(6);
@@ -115,7 +115,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout1->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout1->setObjectName(QStringLiteral("vboxLayout1"));
+ vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1"));
hboxLayout1 = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout1->setSpacing(6);
@@ -123,7 +123,7 @@ public:
#ifndef Q_OS_MAC
hboxLayout1->setContentsMargins(0, 0, 0, 0);
#endif
- hboxLayout1->setObjectName(QStringLiteral("hboxLayout1"));
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
gridLayout = new QGridLayout();
#ifndef Q_OS_MAC
gridLayout->setSpacing(6);
@@ -131,15 +131,15 @@ public:
#ifndef Q_OS_MAC
gridLayout->setContentsMargins(0, 0, 0, 0);
#endif
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label = new QLabel(groupBox);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout->addWidget(label, 0, 0, 1, 1);
minVal = new QSpinBox(groupBox);
- minVal->setObjectName(QStringLiteral("minVal"));
+ minVal->setObjectName(QString::fromUtf8("minVal"));
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(1);
sizePolicy.setVerticalStretch(0);
@@ -151,13 +151,13 @@ public:
gridLayout->addWidget(minVal, 0, 1, 1, 1);
label_2 = new QLabel(groupBox);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
label_2->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout->addWidget(label_2, 1, 0, 1, 1);
maxVal = new QSpinBox(groupBox);
- maxVal->setObjectName(QStringLiteral("maxVal"));
+ maxVal->setObjectName(QString::fromUtf8("maxVal"));
sizePolicy.setHeightForWidth(maxVal->sizePolicy().hasHeightForWidth());
maxVal->setSizePolicy(sizePolicy);
maxVal->setMinimum(-1000000);
@@ -170,7 +170,7 @@ public:
hboxLayout1->addLayout(gridLayout);
frame = new QFrame(groupBox);
- frame->setObjectName(QStringLiteral("frame"));
+ frame->setObjectName(QString::fromUtf8("frame"));
frame->setFrameShape(QFrame::StyledPanel);
frame->setFrameShadow(QFrame::Sunken);
vboxLayout2 = new QVBoxLayout(frame);
@@ -180,9 +180,9 @@ public:
#ifndef Q_OS_MAC
vboxLayout2->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout2->setObjectName(QStringLiteral("vboxLayout2"));
+ vboxLayout2->setObjectName(QString::fromUtf8("vboxLayout2"));
ledWidget = new LEDWidget(frame);
- ledWidget->setObjectName(QStringLiteral("ledWidget"));
+ ledWidget->setObjectName(QString::fromUtf8("ledWidget"));
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Fixed);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
@@ -194,7 +194,7 @@ public:
vboxLayout2->addWidget(ledWidget);
label_7 = new QLabel(frame);
- label_7->setObjectName(QStringLiteral("label_7"));
+ label_7->setObjectName(QString::fromUtf8("label_7"));
vboxLayout2->addWidget(label_7);
@@ -209,7 +209,7 @@ public:
vboxLayout1->addItem(spacerItem1);
editor = new QLineEdit(groupBox);
- editor->setObjectName(QStringLiteral("editor"));
+ editor->setObjectName(QString::fromUtf8("editor"));
vboxLayout1->addWidget(editor);
@@ -217,7 +217,7 @@ public:
vboxLayout->addWidget(groupBox);
groupBox_2 = new QGroupBox(ValidatorsForm);
- groupBox_2->setObjectName(QStringLiteral("groupBox_2"));
+ groupBox_2->setObjectName(QString::fromUtf8("groupBox_2"));
vboxLayout3 = new QVBoxLayout(groupBox_2);
#ifndef Q_OS_MAC
vboxLayout3->setSpacing(6);
@@ -225,7 +225,7 @@ public:
#ifndef Q_OS_MAC
vboxLayout3->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout3->setObjectName(QStringLiteral("vboxLayout3"));
+ vboxLayout3->setObjectName(QString::fromUtf8("vboxLayout3"));
hboxLayout2 = new QHBoxLayout();
#ifndef Q_OS_MAC
hboxLayout2->setSpacing(6);
@@ -233,7 +233,7 @@ public:
#ifndef Q_OS_MAC
hboxLayout2->setContentsMargins(0, 0, 0, 0);
#endif
- hboxLayout2->setObjectName(QStringLiteral("hboxLayout2"));
+ hboxLayout2->setObjectName(QString::fromUtf8("hboxLayout2"));
gridLayout1 = new QGridLayout();
#ifndef Q_OS_MAC
gridLayout1->setSpacing(6);
@@ -241,15 +241,15 @@ public:
#ifndef Q_OS_MAC
gridLayout1->setContentsMargins(0, 0, 0, 0);
#endif
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
label_3 = new QLabel(groupBox_2);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
label_3->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout1->addWidget(label_3, 0, 0, 1, 1);
doubleMinVal = new QDoubleSpinBox(groupBox_2);
- doubleMinVal->setObjectName(QStringLiteral("doubleMinVal"));
+ doubleMinVal->setObjectName(QString::fromUtf8("doubleMinVal"));
sizePolicy.setHeightForWidth(doubleMinVal->sizePolicy().hasHeightForWidth());
doubleMinVal->setSizePolicy(sizePolicy);
doubleMinVal->setMinimum(-100000);
@@ -259,7 +259,7 @@ public:
gridLayout1->addWidget(doubleMinVal, 0, 1, 1, 1);
label_5 = new QLabel(groupBox_2);
- label_5->setObjectName(QStringLiteral("label_5"));
+ label_5->setObjectName(QString::fromUtf8("label_5"));
label_5->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout1->addWidget(label_5, 0, 2, 1, 1);
@@ -267,18 +267,18 @@ public:
doubleFormat = new QComboBox(groupBox_2);
doubleFormat->addItem(QString());
doubleFormat->addItem(QString());
- doubleFormat->setObjectName(QStringLiteral("doubleFormat"));
+ doubleFormat->setObjectName(QString::fromUtf8("doubleFormat"));
gridLayout1->addWidget(doubleFormat, 0, 3, 1, 1);
label_4 = new QLabel(groupBox_2);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
label_4->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout1->addWidget(label_4, 1, 0, 1, 1);
doubleMaxVal = new QDoubleSpinBox(groupBox_2);
- doubleMaxVal->setObjectName(QStringLiteral("doubleMaxVal"));
+ doubleMaxVal->setObjectName(QString::fromUtf8("doubleMaxVal"));
sizePolicy.setHeightForWidth(doubleMaxVal->sizePolicy().hasHeightForWidth());
doubleMaxVal->setSizePolicy(sizePolicy);
doubleMaxVal->setMinimum(-100000);
@@ -288,13 +288,13 @@ public:
gridLayout1->addWidget(doubleMaxVal, 1, 1, 1, 1);
label_6 = new QLabel(groupBox_2);
- label_6->setObjectName(QStringLiteral("label_6"));
+ label_6->setObjectName(QString::fromUtf8("label_6"));
label_6->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
gridLayout1->addWidget(label_6, 1, 2, 1, 1);
doubleDecimals = new QSpinBox(groupBox_2);
- doubleDecimals->setObjectName(QStringLiteral("doubleDecimals"));
+ doubleDecimals->setObjectName(QString::fromUtf8("doubleDecimals"));
doubleDecimals->setValue(2);
gridLayout1->addWidget(doubleDecimals, 1, 3, 1, 1);
@@ -303,7 +303,7 @@ public:
hboxLayout2->addLayout(gridLayout1);
frame_2 = new QFrame(groupBox_2);
- frame_2->setObjectName(QStringLiteral("frame_2"));
+ frame_2->setObjectName(QString::fromUtf8("frame_2"));
frame_2->setFrameShape(QFrame::StyledPanel);
frame_2->setFrameShadow(QFrame::Sunken);
vboxLayout4 = new QVBoxLayout(frame_2);
@@ -313,16 +313,16 @@ public:
#ifndef Q_OS_MAC
vboxLayout4->setContentsMargins(9, 9, 9, 9);
#endif
- vboxLayout4->setObjectName(QStringLiteral("vboxLayout4"));
+ vboxLayout4->setObjectName(QString::fromUtf8("vboxLayout4"));
doubleLedWidget = new LEDWidget(frame_2);
- doubleLedWidget->setObjectName(QStringLiteral("doubleLedWidget"));
+ doubleLedWidget->setObjectName(QString::fromUtf8("doubleLedWidget"));
doubleLedWidget->setPixmap(QPixmap(QString::fromUtf8(":/ledoff.png")));
doubleLedWidget->setAlignment(Qt::AlignCenter);
vboxLayout4->addWidget(doubleLedWidget);
label_8 = new QLabel(frame_2);
- label_8->setObjectName(QStringLiteral("label_8"));
+ label_8->setObjectName(QString::fromUtf8("label_8"));
vboxLayout4->addWidget(label_8);
@@ -337,7 +337,7 @@ public:
vboxLayout3->addItem(spacerItem2);
doubleEditor = new QLineEdit(groupBox_2);
- doubleEditor->setObjectName(QStringLiteral("doubleEditor"));
+ doubleEditor->setObjectName(QString::fromUtf8("doubleEditor"));
vboxLayout3->addWidget(doubleEditor);
@@ -353,13 +353,13 @@ public:
hboxLayout3->setSpacing(6);
#endif
hboxLayout3->setContentsMargins(0, 0, 0, 0);
- hboxLayout3->setObjectName(QStringLiteral("hboxLayout3"));
+ hboxLayout3->setObjectName(QString::fromUtf8("hboxLayout3"));
spacerItem4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hboxLayout3->addItem(spacerItem4);
pushButton = new QPushButton(ValidatorsForm);
- pushButton->setObjectName(QStringLiteral("pushButton"));
+ pushButton->setObjectName(QString::fromUtf8("pushButton"));
hboxLayout3->addWidget(pushButton);
diff --git a/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h b/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h
index 1254eee3f7..d6f7ff5526 100644
--- a/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h
+++ b/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h
@@ -64,14 +64,14 @@ public:
void setupUi(QDialog *WateringConfigDialog)
{
if (WateringConfigDialog->objectName().isEmpty())
- WateringConfigDialog->setObjectName(QStringLiteral("WateringConfigDialog"));
+ WateringConfigDialog->setObjectName(QString::fromUtf8("WateringConfigDialog"));
WateringConfigDialog->resize(334, 550);
vboxLayout = new QVBoxLayout(WateringConfigDialog);
- vboxLayout->setObjectName(QStringLiteral("vboxLayout"));
+ vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
gridLayout = new QGridLayout();
- gridLayout->setObjectName(QStringLiteral("gridLayout"));
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
label_3 = new QLabel(WateringConfigDialog);
- label_3->setObjectName(QStringLiteral("label_3"));
+ label_3->setObjectName(QString::fromUtf8("label_3"));
gridLayout->addWidget(label_3, 0, 0, 1, 1);
@@ -82,7 +82,7 @@ public:
plantComboBox->addItem(QString());
plantComboBox->addItem(QString());
plantComboBox->addItem(QString());
- plantComboBox->setObjectName(QStringLiteral("plantComboBox"));
+ plantComboBox->setObjectName(QString::fromUtf8("plantComboBox"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
@@ -96,12 +96,12 @@ public:
gridLayout->addItem(spacerItem, 1, 0, 1, 1);
label_2 = new QLabel(WateringConfigDialog);
- label_2->setObjectName(QStringLiteral("label_2"));
+ label_2->setObjectName(QString::fromUtf8("label_2"));
gridLayout->addWidget(label_2, 2, 0, 1, 1);
temperatureCheckBox = new QCheckBox(WateringConfigDialog);
- temperatureCheckBox->setObjectName(QStringLiteral("temperatureCheckBox"));
+ temperatureCheckBox->setObjectName(QString::fromUtf8("temperatureCheckBox"));
gridLayout->addWidget(temperatureCheckBox, 3, 1, 1, 3);
@@ -110,7 +110,7 @@ public:
gridLayout->addItem(spacerItem1, 4, 1, 1, 1);
temperatureSpinBox = new QSpinBox(WateringConfigDialog);
- temperatureSpinBox->setObjectName(QStringLiteral("temperatureSpinBox"));
+ temperatureSpinBox->setObjectName(QString::fromUtf8("temperatureSpinBox"));
temperatureSpinBox->setEnabled(false);
temperatureSpinBox->setMinimum(10);
temperatureSpinBox->setMaximum(60);
@@ -123,7 +123,7 @@ public:
gridLayout->addItem(spacerItem2, 4, 3, 1, 1);
rainCheckBox = new QCheckBox(WateringConfigDialog);
- rainCheckBox->setObjectName(QStringLiteral("rainCheckBox"));
+ rainCheckBox->setObjectName(QString::fromUtf8("rainCheckBox"));
gridLayout->addWidget(rainCheckBox, 5, 1, 1, 3);
@@ -132,7 +132,7 @@ public:
gridLayout->addItem(spacerItem3, 6, 1, 1, 1);
rainSpinBox = new QSpinBox(WateringConfigDialog);
- rainSpinBox->setObjectName(QStringLiteral("rainSpinBox"));
+ rainSpinBox->setObjectName(QString::fromUtf8("rainSpinBox"));
rainSpinBox->setEnabled(false);
rainSpinBox->setMinimum(1);
@@ -147,22 +147,22 @@ public:
gridLayout->addItem(spacerItem5, 7, 2, 1, 1);
label = new QLabel(WateringConfigDialog);
- label->setObjectName(QStringLiteral("label"));
+ label->setObjectName(QString::fromUtf8("label"));
gridLayout->addWidget(label, 8, 0, 1, 1);
startTimeEdit = new QTimeEdit(WateringConfigDialog);
- startTimeEdit->setObjectName(QStringLiteral("startTimeEdit"));
+ startTimeEdit->setObjectName(QString::fromUtf8("startTimeEdit"));
gridLayout->addWidget(startTimeEdit, 8, 1, 1, 3);
label_4 = new QLabel(WateringConfigDialog);
- label_4->setObjectName(QStringLiteral("label_4"));
+ label_4->setObjectName(QString::fromUtf8("label_4"));
gridLayout->addWidget(label_4, 9, 0, 1, 1);
amountSpinBox = new QSpinBox(WateringConfigDialog);
- amountSpinBox->setObjectName(QStringLiteral("amountSpinBox"));
+ amountSpinBox->setObjectName(QString::fromUtf8("amountSpinBox"));
amountSpinBox->setMinimum(100);
amountSpinBox->setMaximum(10000);
amountSpinBox->setSingleStep(100);
@@ -171,7 +171,7 @@ public:
gridLayout->addWidget(amountSpinBox, 9, 1, 1, 3);
label_5 = new QLabel(WateringConfigDialog);
- label_5->setObjectName(QStringLiteral("label_5"));
+ label_5->setObjectName(QString::fromUtf8("label_5"));
gridLayout->addWidget(label_5, 10, 0, 1, 1);
@@ -180,17 +180,17 @@ public:
sourceComboBox->addItem(QString());
sourceComboBox->addItem(QString());
sourceComboBox->addItem(QString());
- sourceComboBox->setObjectName(QStringLiteral("sourceComboBox"));
+ sourceComboBox->setObjectName(QString::fromUtf8("sourceComboBox"));
gridLayout->addWidget(sourceComboBox, 10, 1, 1, 3);
label_6 = new QLabel(WateringConfigDialog);
- label_6->setObjectName(QStringLiteral("label_6"));
+ label_6->setObjectName(QString::fromUtf8("label_6"));
gridLayout->addWidget(label_6, 11, 0, 1, 1);
filterCheckBox = new QCheckBox(WateringConfigDialog);
- filterCheckBox->setObjectName(QStringLiteral("filterCheckBox"));
+ filterCheckBox->setObjectName(QString::fromUtf8("filterCheckBox"));
gridLayout->addWidget(filterCheckBox, 11, 1, 1, 2);
@@ -206,18 +206,18 @@ public:
vboxLayout->addLayout(gridLayout);
gridLayout1 = new QGridLayout();
- gridLayout1->setObjectName(QStringLiteral("gridLayout1"));
+ gridLayout1->setObjectName(QString::fromUtf8("gridLayout1"));
spacerItem8 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
gridLayout1->addItem(spacerItem8, 0, 1, 1, 1);
helpBrowser = new HelpBrowser(WateringConfigDialog);
- helpBrowser->setObjectName(QStringLiteral("helpBrowser"));
+ helpBrowser->setObjectName(QString::fromUtf8("helpBrowser"));
gridLayout1->addWidget(helpBrowser, 1, 0, 1, 2);
helpLabel = new QLabel(WateringConfigDialog);
- helpLabel->setObjectName(QStringLiteral("helpLabel"));
+ helpLabel->setObjectName(QString::fromUtf8("helpLabel"));
gridLayout1->addWidget(helpLabel, 0, 0, 1, 1);
@@ -225,14 +225,14 @@ public:
vboxLayout->addLayout(gridLayout1);
line = new QFrame(WateringConfigDialog);
- line->setObjectName(QStringLiteral("line"));
+ line->setObjectName(QString::fromUtf8("line"));
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
vboxLayout->addWidget(line);
buttonBox = new QDialogButtonBox(WateringConfigDialog);
- buttonBox->setObjectName(QStringLiteral("buttonBox"));
+ buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok);
diff --git a/tests/auto/widgets/dialogs/dialogs.pro b/tests/auto/widgets/dialogs/dialogs.pro
index cf548f2dea..e0ebe78f33 100644
--- a/tests/auto/widgets/dialogs/dialogs.pro
+++ b/tests/auto/widgets/dialogs/dialogs.pro
@@ -18,3 +18,4 @@ SUBDIRS=\
mac:qinputdialog.CONFIG += no_check_target # QTBUG-25496
mingw: SUBDIRS -= qfilesystemmodel # QTBUG-29403
+winrt: SUBDIRS -= qfiledialog qfiledialog2 qmessagebox # QTBUG-68297
diff --git a/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro
index c8ddedb401..563db6e887 100644
--- a/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro
+++ b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro
@@ -2,5 +2,3 @@ CONFIG += testcase
TARGET = tst_qcolordialog
QT += widgets testlib
SOURCES += tst_qcolordialog.cpp
-
-linux*: CONFIG += insignificant_test # Crashes on different Linux distros
diff --git a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
index 0df0544a06..6a0ad4b3a4 100644
--- a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
+++ b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
@@ -84,6 +84,9 @@ void tst_QColorDialog::testNativeActiveModalWidget()
// Check that QApplication::activeModalWidget retruns the
// color dialog when it is executing, even when using a native
// dialog:
+#if defined(Q_OS_LINUX)
+ QSKIP("This test crashes sometimes. Although rarely, but it happens. See QTBUG-50842.");
+#endif
TestNativeDialog d;
QTimer::singleShot(1000, &d, SLOT(hide()));
d.exec();
@@ -121,6 +124,9 @@ void tst_QColorDialog::testGetRgba()
void tst_QColorDialog::defaultOkButton()
{
+#if defined(Q_OS_LINUX)
+ QSKIP("This test crashes sometimes. Although rarely, but it happens. See QTBUG-50842.");
+#endif
QTimer::singleShot(4000, qApp, SLOT(quit()));
QTimer::singleShot(0, this, SLOT(testGetRgba()));
qApp->exec();
diff --git a/tests/auto/widgets/dialogs/qdialog/BLACKLIST b/tests/auto/widgets/dialogs/qdialog/BLACKLIST
index 3da7337784..dd6a8bfff9 100644
--- a/tests/auto/widgets/dialogs/qdialog/BLACKLIST
+++ b/tests/auto/widgets/dialogs/qdialog/BLACKLIST
@@ -1,2 +1,4 @@
[snapToDefaultButton]
osx
+[showFullScreen]
+osx-10.13 ci
diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
index 7e246b5366..afe49368ae 100644
--- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
+++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
@@ -369,6 +369,10 @@ void tst_QDialog::showAsTool()
testWidget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&testWidget));
dialog.exec();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "As winrt does not support child widgets, the dialog is being activated"
+ "together with the main widget.", Continue);
+#endif
if (testWidget.style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, &testWidget)) {
QCOMPARE(dialog.wasActive(), true);
} else {
@@ -551,10 +555,11 @@ void tst_QDialog::snapToDefaultButton()
#ifdef QT_NO_CURSOR
QSKIP("Test relies on there being a cursor");
#else
- if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
- QSKIP("Wayland: Wayland does not support setting the cursor position.");
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)
+ || !QGuiApplication::platformName().compare(QLatin1String("winrt"), Qt::CaseInsensitive))
+ QSKIP("This platform does not support setting the cursor position.");
- const QRect dialogGeometry(QApplication::desktop()->availableGeometry().topLeft()
+ const QRect dialogGeometry(QGuiApplication::primaryScreen()->availableGeometry().topLeft()
+ QPoint(100, 100), QSize(200, 200));
const QPoint startingPos = dialogGeometry.bottomRight() + QPoint(100, 100);
QCursor::setPos(startingPos);
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
index 47d63b7d53..ae8e4f7e04 100644
--- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
@@ -49,6 +49,7 @@
#include <qsortfilterproxymodel.h>
#include <qlineedit.h>
#include <qlayout.h>
+#include <qtemporarydir.h>
#include <private/qfiledialog_p.h>
#if defined QT_BUILD_INTERNAL
#include <private/qsidebar_p.h>
@@ -933,7 +934,6 @@ void tst_QFiledialog::selectFiles()
QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(QString)));
QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(QStringList)));
QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(QString)));
- fd.show();
fd.setFileMode(QFileDialog::ExistingFiles);
QString filesPath = fd.directory().absolutePath();
@@ -1311,57 +1311,116 @@ void tst_QFiledialog::saveButtonText()
QCOMPARE(button->text(), caption);
}
+// Predicate for use with QTRY_VERIFY() that checks whether the file dialog list
+// has been populated (contains an entry).
+class DirPopulatedPredicate
+{
+public:
+ explicit DirPopulatedPredicate(QListView *list, const QString &needle) :
+ m_list(list), m_needle(needle) {}
+
+ operator bool() const
+ {
+ const auto model = m_list->model();
+ const auto root = m_list->rootIndex();
+ for (int r = 0, count = model->rowCount(root); r < count; ++r) {
+ if (m_needle == model->index(r, 0, root).data(Qt::DisplayRole).toString())
+ return true;
+ }
+ return false;
+ }
+
+private:
+ QListView *m_list;
+ QString m_needle;
+};
+
+// A predicate for use with QTRY_VERIFY() that ensures an entry of the file dialog
+// list is selected by pressing cursor down.
+class SelectDirTestPredicate
+{
+public:
+ explicit SelectDirTestPredicate(QListView *list, const QString &needle) :
+ m_list(list), m_needle(needle) {}
+
+ operator bool() const
+ {
+ if (m_needle == m_list->currentIndex().data(Qt::DisplayRole).toString())
+ return true;
+ QCoreApplication::processEvents();
+ QTest::keyClick(m_list, Qt::Key_Down);
+ return false;
+ }
+
+private:
+ QListView *m_list;
+ QString m_needle;
+};
+
void tst_QFiledialog::clearLineEdit()
{
- QFileDialog fd(0, "caption", "foo");
+ // Play it really safe by creating a directory which should show first in
+ // a temporary dir
+ QTemporaryDir workDir(QDir::tempPath() + QLatin1String("/tst_qfd_clearXXXXXX"));
+ QVERIFY2(workDir.isValid(), qPrintable(workDir.errorString()));
+ const QString workDirPath = workDir.path();
+ const QString dirName = QLatin1String("aaaaa");
+ QVERIFY(QDir(workDirPath).mkdir(dirName));
+
+ QFileDialog fd(nullptr,
+ QLatin1String(QTest::currentTestFunction()) + QLatin1String(" AnyFile"),
+ "foo");
fd.setViewMode(QFileDialog::List);
fd.setFileMode(QFileDialog::AnyFile);
fd.show();
- //play it really safe by creating a directory
- QDir::home().mkdir("_____aaaaaaaaaaaaaaaaaaaaaa");
-
QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit");
QVERIFY(lineEdit);
QCOMPARE(lineEdit->text(), QLatin1String("foo"));
- fd.setDirectory(QDir::home());
QListView* list = fd.findChild<QListView*>("listView");
QVERIFY(list);
- // saving a file the text shouldn't be cleared
- fd.setDirectory(QDir::home());
+ // When in AnyFile mode, lineEdit's text shouldn't be cleared when entering
+ // a directory by activating one in the list
+ fd.setDirectory(workDirPath);
+ DirPopulatedPredicate dirPopulated(list, dirName);
+ QTRY_VERIFY(dirPopulated);
#ifdef QT_KEYPAD_NAVIGATION
list->setEditFocus(true);
#endif
- QTest::keyClick(list, Qt::Key_Down);
+
+ SelectDirTestPredicate selectTestDir(list, dirName);
+ QTRY_VERIFY(selectTestDir);
+
#ifndef Q_OS_MAC
QTest::keyClick(list, Qt::Key_Return);
#else
QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
#endif
- QTRY_VERIFY(fd.directory().absolutePath() != QDir::home().absolutePath());
+ QTRY_VERIFY(fd.directory().absolutePath() != workDirPath);
QVERIFY(!lineEdit->text().isEmpty());
- // selecting a dir the text should be cleared so one can just hit ok
+ // When in Directory mode, lineEdit's text should be cleared when entering
+ // a directory by activating one in the list so one can just hit ok
// and it selects that directory
fd.setFileMode(QFileDialog::Directory);
- fd.setDirectory(QDir::home());
+ fd.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1String(" Directory"));
+ fd.setDirectory(workDirPath);
+ QTRY_VERIFY(dirPopulated);
+
+ QTRY_VERIFY(selectTestDir);
- QTest::keyClick(list, Qt::Key_Down);
#ifndef Q_OS_MAC
QTest::keyClick(list, Qt::Key_Return);
#else
QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
#endif
- QTRY_VERIFY(fd.directory().absolutePath() != QDir::home().absolutePath());
+ QTRY_VERIFY(fd.directory().absolutePath() != workDirPath);
QVERIFY(lineEdit->text().isEmpty());
-
- //remove the dir
- QDir::home().rmdir("_____aaaaaaaaaaaaaaaaaaaaaa");
}
void tst_QFiledialog::enableChooseButton()
@@ -1521,7 +1580,8 @@ public:
const QWindow *window = QGuiApplication::topLevelWindows().constFirst();
const QFileDialog *fileDialog = qobject_cast<QFileDialog*>(QApplication::activeModalWidget());
- QVERIFY(fileDialog);
+ if (!fileDialog)
+ return;
// The problem in QTBUG-57193 was from a platform input context plugin that was
// connected to QWindow::focusObjectChanged(), and consequently accessed the focus
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST b/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST
new file mode 100644
index 0000000000..e0887d8ad1
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST
@@ -0,0 +1,2 @@
+[QTBUG4419_lineEditSelectAll]
+osx
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
index fca1f17a4d..8f9a8c11a7 100644
--- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
@@ -1176,7 +1176,7 @@ void tst_QFileDialog2::QTBUG4419_lineEditSelectAll()
fd.setFileMode(QFileDialog::AnyFile);
fd.show();
- QApplication::setActiveWindow(&fd);
+ fd.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&fd));
QCOMPARE(fd.isVisible(), true);
QCOMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
index 70f5c40bcc..049468fd7c 100644
--- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
+++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
@@ -190,6 +190,8 @@ void tst_QMessageBox::sanityTest()
QSKIP("Test hangs on macOS 10.12 -- QTQAINFRA-1362");
return;
}
+#elif defined(Q_OS_WINRT)
+ QSKIP("Test hangs on winrt -- QTBUG-68297");
#endif
QMessageBox msgBox;
msgBox.setText("This is insane");
diff --git a/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp b/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
index 3c189f92cc..9c5e226731 100644
--- a/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
+++ b/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
@@ -55,6 +55,9 @@ void tst_QSidebar::setUrls()
QCOMPARE(model->rowCount(), 0);
qsidebar.setUrls(urls);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "One of the URLs is not seen as valid on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(qsidebar.urls(), urls);
QCOMPARE(model->rowCount(), urls.count());
qsidebar.setUrls(urls);
@@ -99,6 +102,9 @@ void tst_QSidebar::addUrls()
// test < 0
qsidebar.addUrls(urls, -1);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "One of the URLs is not seen as valid on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(model->rowCount(), 2);
// test = 0
@@ -185,6 +191,9 @@ void tst_QSidebar::goToUrl()
QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(QUrl)));
QTest::mousePress(qsidebar.viewport(), Qt::LeftButton, 0, qsidebar.visualRect(qsidebar.model()->index(0, 0)).center());
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(spy.count(), 1);
QCOMPARE((spy.value(0)).at(0).toUrl(), urls.first());
}
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
index 6ad93b2666..a5b8646d40 100644
--- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -2596,6 +2596,9 @@ void tst_QWizard::task161658_alignments()
void tst_QWizard::task177022_setFixedSize()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Widgets cannot have a fixed size on WinRT.");
+#endif
int width = 300;
int height = 200;
QWizard wiz;
diff --git a/tests/auto/widgets/effects/qgraphicseffect/BLACKLIST b/tests/auto/widgets/effects/qgraphicseffect/BLACKLIST
new file mode 100644
index 0000000000..4833af527f
--- /dev/null
+++ b/tests/auto/widgets/effects/qgraphicseffect/BLACKLIST
@@ -0,0 +1,3 @@
+[prepareGeometryChangeInvalidateCache]
+opensuse
+opensuse-leap
diff --git a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp
index 5b142048b5..95662a49a0 100644
--- a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp
+++ b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp
@@ -731,12 +731,12 @@ void tst_QGraphicsEffect::itemHasNoContents()
CustomEffect *effect = new CustomEffect;
parent->setGraphicsEffect(effect);
- QTRY_COMPARE(effect->numRepaints, 1);
+ QTRY_VERIFY(effect->numRepaints >= 1);
for (int i = 0; i < 3; ++i) {
effect->reset();
effect->update();
- QTRY_COMPARE(effect->numRepaints, 1);
+ QTRY_VERIFY(effect->numRepaints >= 1);
}
}
diff --git a/tests/auto/widgets/graphicsview/graphicsview.pro b/tests/auto/widgets/graphicsview/graphicsview.pro
index e99897a4f6..0f4c1721e3 100644
--- a/tests/auto/widgets/graphicsview/graphicsview.pro
+++ b/tests/auto/widgets/graphicsview/graphicsview.pro
@@ -30,3 +30,5 @@ SUBDIRS=\
!contains(styles, fusion):SUBDIRS -= \
qgraphicsproxywidget \
qgraphicswidget \
+
+winrt: SUBDIRS -= qgraphicsview # QTBUG-68297
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
index 6c1abaedb3..1130a47260 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -477,7 +477,7 @@ private:
void tst_QGraphicsItem::construction()
{
for (int i = 0; i < 7; ++i) {
- QGraphicsItem *item;
+ QGraphicsItem *item = nullptr;
switch (i) {
case 0:
item = new QGraphicsEllipseItem;
@@ -986,6 +986,7 @@ void tst_QGraphicsItem::inputMethodHints()
QGraphicsView view(&scene);
QApplication::setActiveWindow(&view);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
item->setFocus();
QTRY_VERIFY(item->hasFocus());
@@ -1036,6 +1037,7 @@ void tst_QGraphicsItem::toolTip()
view.setFixedSize(200, 200);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
{
QHelpEvent helpEvent(QEvent::ToolTip, view.viewport()->rect().topLeft(),
@@ -3226,6 +3228,7 @@ void tst_QGraphicsItem::hoverEventsGenerateRepaints()
QGraphicsScene scene;
QGraphicsView view(&scene);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
EventTester *tester = new EventTester;
@@ -4143,10 +4146,13 @@ void tst_QGraphicsItem::ensureVisible()
void tst_QGraphicsItem::cursor()
{
QGraphicsScene scene;
- QGraphicsRectItem *item1 = scene.addRect(QRectF(0, 0, 50, 50));
- QGraphicsRectItem *item2 = scene.addRect(QRectF(0, 0, 50, 50));
- item1->setPos(-100, 0);
- item2->setPos(50, 0);
+ QWidget topLevel;
+ QGraphicsView view(&scene,&topLevel);
+ topLevel.showMaximized();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ view.setFixedSize(topLevel.size());
+ QGraphicsRectItem *item1 = scene.addRect(QRectF(-100, 0, 50, 50));
+ QGraphicsRectItem *item2 = scene.addRect(QRectF(50, 0, 50, 50));
QVERIFY(!item1->hasCursor());
QVERIFY(!item2->hasCursor());
@@ -4172,14 +4178,6 @@ void tst_QGraphicsItem::cursor()
item1->setCursor(Qt::IBeamCursor);
item2->setCursor(Qt::PointingHandCursor);
- QWidget topLevel;
- topLevel.resize(250, 150);
- QTestPrivate::centerOnScreen(&topLevel);
- QGraphicsView view(&scene,&topLevel);
- view.setFixedSize(200, 100);
- topLevel.show();
- QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
-
QTest::mouseMove(&view, view.rect().center());
const Qt::CursorShape viewportShape = view.viewport()->cursor().shape();
@@ -4938,6 +4936,7 @@ void tst_QGraphicsItem::sceneEventFilter()
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QGraphicsTextItem *text1 = scene.addText(QLatin1String("Text1"));
@@ -5078,6 +5077,9 @@ void tst_QGraphicsItem::paint()
PaintTester tester2;
scene2.addItem(&tester2);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort);
+#endif
//First show one paint
QTRY_COMPARE(tester2.painted, 1);
@@ -6533,6 +6535,9 @@ void tst_QGraphicsItem::ensureUpdateOnTextItem()
QVERIFY(QTest::qWaitForWindowExposed(&view));
TextItem *text1 = new TextItem(QLatin1String("123"));
scene.addItem(text1);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(text1->updates,1);
//same bouding rect but we have to update
@@ -6802,6 +6807,7 @@ void tst_QGraphicsItem::opacity2()
MyGraphicsView view(&scene);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(view.repaints >= 1);
@@ -6874,6 +6880,7 @@ void tst_QGraphicsItem::opacityZeroUpdates()
MyGraphicsView view(&scene);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(view.repaints > 0);
@@ -6891,6 +6898,9 @@ void tst_QGraphicsItem::opacityZeroUpdates()
QRegion expectedRegion = parentDeviceBoundingRect.adjusted(-2, -2, 2, 2);
expectedRegion += childDeviceBoundingRect.adjusted(-2, -2, 2, 2);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort);
+#endif
COMPARE_REGIONS(view.paintedRegion, expectedRegion);
}
@@ -7262,6 +7272,7 @@ void tst_QGraphicsItem::cacheMode()
view.resize(150, 150);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
EventTester *tester = new EventTester;
@@ -7440,6 +7451,7 @@ void tst_QGraphicsItem::cacheMode2()
view.resize(150, 150);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
EventTester *tester = new EventTester;
@@ -8093,6 +8105,7 @@ void tst_QGraphicsItem::moveLineItem()
MyGraphicsView view(&scene);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
view.reset();
@@ -8108,6 +8121,9 @@ void tst_QGraphicsItem::moveLineItem()
// Make sure the calculated region is correct.
item->update();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(view.paintedRegion, expectedRegion);
view.reset();
@@ -8161,6 +8177,7 @@ void tst_QGraphicsItem::sorting()
view.setFrameStyle(0);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(_paintedItems.count() > 0);
@@ -8197,6 +8214,7 @@ void tst_QGraphicsItem::itemHasNoContents()
QGraphicsView view(&scene);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(!_paintedItems.isEmpty());
@@ -9204,6 +9222,7 @@ void tst_QGraphicsItem::ensureDirtySceneTransform()
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
@@ -9590,6 +9609,7 @@ void tst_QGraphicsItem::QTBUG_4233_updateCachedWithSceneRect()
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), (QWidget *)&view);
@@ -10720,6 +10740,7 @@ void tst_QGraphicsItem::scroll()
MyGraphicsView view(&scene);
view.setFrameStyle(0);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(view.repaints > 0);
@@ -11242,6 +11263,7 @@ void tst_QGraphicsItem::QTBUG_6738_missingUpdateWithSetParent()
MyGraphicsView view(&scene);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(view.repaints > 0);
@@ -11290,6 +11312,7 @@ void tst_QGraphicsItem::QT_2653_fullUpdateDiscardingOpacityUpdate()
parentGreen->setFlag(QGraphicsItem::ItemIgnoresTransformations);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
view.reset();
@@ -11332,10 +11355,14 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2()
origView.reset();
childYellow->setOpacity(0.0);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(origView.repaints, 1);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
view.reset();
origView.reset();
@@ -11475,6 +11502,7 @@ void tst_QGraphicsItem::doNotMarkFullUpdateIfNotInScene()
item2->setParentItem(item);
scene.addItem(item);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(view.windowHandle()));
QVERIFY(QTest::qWaitForWindowActive(view.windowHandle()));
view.activateWindow();
QTRY_VERIFY(view.isActiveWindow());
@@ -11506,6 +11534,7 @@ void tst_QGraphicsItem::itemDiesDuringDraggingOperation()
scene.addItem(item);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), (QWidget *)&view);
QGraphicsSceneDragDropEvent dragEnter(QEvent::GraphicsSceneDragEnter);
@@ -11533,6 +11562,7 @@ void tst_QGraphicsItem::QTBUG_12112_focusItem()
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), (QWidget *)&view);
diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro
index e7bcccb495..c10cbe1b1a 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro
@@ -4,5 +4,6 @@ TARGET = tst_qgraphicsproxywidget
QT += widgets widgets-private testlib
QT += core-private gui-private
+DEFINES += QTEST_QPA_MOUSE_HANDLING
SOURCES += tst_qgraphicsproxywidget.cpp
diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index 4cd2fef2dc..49afc5f369 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -33,12 +33,6 @@
#include <private/qgraphicsproxywidget_p.h>
#include <private/qlayoutengine_p.h> // qSmartMin functions...
-static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::NoButton)
-{
- QMouseEvent event(QEvent::MouseMove, point, widget->mapToGlobal(point), button, button, 0);
- QApplication::sendEvent(widget, &event);
-}
-
/*
Notes:
@@ -95,10 +89,8 @@ private slots:
void focusNextPrevChild();
void focusOutEvent_data();
void focusOutEvent();
-#ifndef QT_NO_CURSOR
void hoverEnterLeaveEvent_data();
void hoverEnterLeaveEvent();
-#endif
void hoverMoveEvent_data();
void hoverMoveEvent();
void keyPressEvent_data();
@@ -138,9 +130,7 @@ private slots:
void setFocus_complexTwoWidgets();
void popup_basic();
void popup_subwidget();
-#ifndef QT_NO_CURSOR
void changingCursor_basic();
-#endif
void tooltip_basic();
void childPos_data();
void childPos();
@@ -685,7 +675,6 @@ void tst_QGraphicsProxyWidget::focusInEvent()
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
proxy->setEnabled(true);
scene.addItem(proxy);
- proxy->setVisible(true);
QWidget *widget = new QWidget;
widget->resize(100, 100);
@@ -716,7 +705,6 @@ void tst_QGraphicsProxyWidget::focusInEventNoWidget()
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
proxy->setEnabled(true);
scene.addItem(proxy);
- proxy->setVisible(true);
view.show();
proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // <- shouldn't need to do this
@@ -931,7 +919,6 @@ protected:
}
};
-#ifndef QT_NO_CURSOR
void tst_QGraphicsProxyWidget::hoverEnterLeaveEvent_data()
{
QTest::addColumn<bool>("hasWidget");
@@ -952,8 +939,6 @@ void tst_QGraphicsProxyWidget::hoverEnterLeaveEvent()
QGraphicsScene scene;
QGraphicsView view(&scene);
- //do not let the window manager move the window while we are moving the mouse on it
- view.setWindowFlags(Qt::X11BypassWindowManagerHint);
view.show();
QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
@@ -968,31 +953,30 @@ void tst_QGraphicsProxyWidget::hoverEnterLeaveEvent()
if (hasWidget)
proxy->setWidget(widgetGuard.take());
proxy->setPos(50, 0);
+ QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
scene.addItem(proxy);
- QTest::qWait(30);
+ QTRY_VERIFY(sceneChangedSpy.count() > 0);
+
+ // outside graphics item
QTest::mouseMove(&view, QPoint(10, 10));
- QTest::qWait(30);
- // in
+ QCOMPARE(widget->testAttribute(Qt::WA_UnderMouse), false);
+ QCOMPARE(widget->enterCount, 0);
+ QCOMPARE(widget->hoverEnter, 0);
+ // over graphics item
QTest::mouseMove(&view, QPoint(50, 50));
- QSKIP("QTBUG-25294");
QTRY_COMPARE(widget->testAttribute(Qt::WA_UnderMouse), hasWidget);
- // ### this attribute isn't supported
QCOMPARE(widget->enterCount, hasWidget ? 1 : 0);
QCOMPARE(widget->hoverEnter, (hasWidget && hoverEnabled) ? 1 : 0);
- // does not work on all platforms
- //QCOMPARE(widget->moveCount, 0);
- // out
+ QTRY_COMPARE(widget->leaveCount, 0);
+ QTRY_COMPARE(widget->hoverLeave, 0);
+ // outside graphics item
QTest::mouseMove(&view, QPoint(10, 10));
- // QTRY_COMPARE(widget->testAttribute(Qt::WA_UnderMouse), false);
- // ### this attribute isn't supported
+ QTRY_COMPARE(widget->testAttribute(Qt::WA_UnderMouse), false);
QTRY_COMPARE(widget->leaveCount, hasWidget ? 1 : 0);
QTRY_COMPARE(widget->hoverLeave, (hasWidget && hoverEnabled) ? 1 : 0);
- // does not work on all platforms
- //QCOMPARE(widget->moveCount, 0);
}
-#endif
void tst_QGraphicsProxyWidget::hoverMoveEvent_data()
{
@@ -1174,19 +1158,20 @@ void tst_QGraphicsProxyWidget::mouseDoubleClickEvent()
widget->setText("foo");
widget->resize(50, 50);
view.resize(100, 100);
- if (hasWidget) {
+ if (hasWidget)
proxy->setWidget(widget);
- proxy->show();
- }
proxy->setPos(50, 0);
+ QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
scene.addItem(proxy);
proxy->setFocus();
- QTest::mouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y())));
- QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y())));
- QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y())));
- QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y())));
- QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y())));
+ // wait for scene to be updated before doing any coordinate mappings on it
+ QTRY_VERIFY(sceneChangedSpy.count() > 0);
+
+ QPoint pointInLineEdit = view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y()));
+ QTest::mousePress(view.viewport(), Qt::LeftButton, 0, pointInLineEdit);
+ QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, pointInLineEdit);
+ QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, pointInLineEdit);
QTRY_COMPARE(widget->selectedText(), hasWidget ? QString("foo") : QString());
@@ -1217,19 +1202,20 @@ void tst_QGraphicsProxyWidget::mousePressReleaseEvent()
QPushButton *widget = new QPushButton;
QSignalSpy spy(widget, SIGNAL(clicked()));
widget->resize(50, 50);
- if (hasWidget) {
+ if (hasWidget)
proxy->setWidget(widget);
- proxy->show();
- }
proxy->setPos(50, 0);
+ QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
scene.addItem(proxy);
proxy->setFocus();
- QTest::mousePress(view.viewport(), Qt::LeftButton, 0,
- view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
+ // wait for scene to be updated before doing any coordinate mappings on it
+ QTRY_VERIFY(sceneChangedSpy.count() > 0);
+
+ QPoint buttonCenter = view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()));
+ QTest::mousePress(view.viewport(), Qt::LeftButton, 0, buttonCenter);
QTRY_COMPARE(spy.count(), 0);
- QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0,
- view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
+ QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, buttonCenter);
QTRY_COMPARE(spy.count(), (hasWidget) ? 1 : 0);
if (!hasWidget)
@@ -1282,16 +1268,13 @@ void tst_QGraphicsProxyWidget::paintEvent()
w->show();
QVERIFY(QTest::qWaitForWindowExposed(w));
- QApplication::processEvents();
- QTest::qWait(30);
proxy.setWidget(w);
+ QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
scene.addItem(&proxy);
- //make sure we flush all the paint events
- QTRY_VERIFY(proxy.paintCount > 1);
- QTest::qWait(30);
- proxy.paintCount = 0;
+ QTRY_VERIFY(sceneChangedSpy.count() > 0); // make sure the scene is ready
+ proxy.paintCount = 0;
w->update();
QTRY_VERIFY(proxy.paintCount >= 1); //the widget should have been painted now
}
@@ -2545,35 +2528,34 @@ void tst_QGraphicsProxyWidget::popup_subwidget()
QCOMPARE(popup->size(), child->size().toSize());
}
-#ifndef QT_NO_CURSOR
void tst_QGraphicsProxyWidget::changingCursor_basic()
{
+#if !QT_CONFIG(cursor)
+ QSKIP("This test requires the QCursor API");
+#else
// Confirm that mouse events are working properly by checking that
// when moving the mouse over a line edit it will change the cursor into the I
QGraphicsScene scene;
QGraphicsView view(&scene);
view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
QLineEdit *widget = new QLineEdit;
proxy->setWidget(widget);
- proxy->show();
+ QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
scene.addItem(proxy);
- QApplication::setActiveWindow(&view);
- QVERIFY(QTest::qWaitForWindowActive(&view));
- QVERIFY(view.isActiveWindow());
+ QTRY_VERIFY(sceneChangedSpy.count() > 0); // make sure the scene is ready
// in
QTest::mouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
- sendMouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
QTRY_COMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
// out
QTest::mouseMove(view.viewport(), QPoint(1, 1));
- sendMouseMove(view.viewport(), QPoint(1, 1));
QTRY_COMPARE(view.viewport()->cursor().shape(), Qt::ArrowCursor);
+#endif // !QT_CONFIG(cursor)
}
-#endif
static bool findViewAndTipLabel(const QWidget *view)
{
@@ -2972,7 +2954,7 @@ void tst_QGraphicsProxyWidget::dontCrashWhenDie()
MainWidget *w = new MainWidget();
w->show();
QVERIFY(QTest::qWaitForWindowExposed(w));
- QTest::qWait(100);
+
QTest::mouseMove(w->view->viewport(), w->view->mapFromScene(w->widget->mapToScene(w->widget->boundingRect().center())));
delete w->item;
@@ -3219,9 +3201,6 @@ void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget_data()
void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget()
{
-#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
- QSKIP("Test case unstable on this platform, QTBUG-33067");
-#endif
QFETCH(bool, bypass);
QWidget *widget = new QWidget;
@@ -3230,6 +3209,7 @@ void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget()
QGraphicsScene scene;
QGraphicsView view(&scene);
view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
QGraphicsProxyWidget *proxy = scene.addWidget(widget);
@@ -3243,6 +3223,7 @@ void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget()
QFileDialog *dialog = new QFileDialog(widget, flags);
dialog->setOption(QFileDialog::DontUseNativeDialog, true);
dialog->show();
+ QVERIFY(QTest::qWaitForWindowActive(dialog));
QCOMPARE(proxy->childItems().size(), bypass ? 0 : 1);
if (!bypass)
@@ -3637,25 +3618,21 @@ public:
QPushButton *hideButton = new QPushButton("I'm a button with a very very long text");
hideButton->setGeometry(10, 10, 400, 50);
topButton = addWidget(hideButton);
- connect(hideButton, SIGNAL(clicked()), this, SLOT(hideButton()));
+ connect(hideButton, &QPushButton::clicked, this, [&]() { topButton->hide(); });
topButton->setFocus();
}
QGraphicsProxyWidget *topButton;
HoverButton *hoverButton;
-
-public slots:
- void hideButton() {
- QCursor::setPos(600,600);
- topButton->hide();
- }
};
void tst_QGraphicsProxyWidget::QTBUG_6986_sendMouseEventToAlienWidget()
{
-#if defined(Q_OS_DARWIN) || defined(Q_OS_WIN) || defined(QT_NO_CURSOR)
- QSKIP("Test case unstable on this platform");
-#endif
+ if (QGuiApplication::platformName() == QLatin1String("cocoa")) {
+ // The "Second button" does not receive QEvent::HoverLeave
+ QSKIP("This test fails only on Cocoa. Investigate why. See QTBUG-69219");
+ }
+
QGraphicsView view;
Scene scene;
view.setScene(&scene);
@@ -3663,9 +3640,12 @@ void tst_QGraphicsProxyWidget::QTBUG_6986_sendMouseEventToAlienWidget()
QApplication::setActiveWindow(&view);
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QCOMPARE(QApplication::activeWindow(), &view);
- QCursor::setPos(view.mapToGlobal(view.mapFromScene(scene.topButton->boundingRect().center())));
- QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(scene.topButton->scenePos()));
+
+ QPoint topButtonTopLeftCorner = view.mapFromScene(scene.topButton->scenePos());
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, topButtonTopLeftCorner);
+ // move to the bottom right corner (buttons are placed in the top left corner)
+ QCOMPARE(scene.hoverButton->hoverLeaveReceived, false);
+ QTest::mouseMove(view.viewport(), view.viewport()->rect().bottomRight());
QTRY_COMPARE(scene.hoverButton->hoverLeaveReceived, true);
}
diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST
index 70170d2822..0e7a1b451f 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST
+++ b/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST
@@ -3,3 +3,15 @@
osx-10.11 ci
[isActive]
opensuse-42.3 ci
+[removeFullyTransparentItem]
+osx-10.11
+osx-10.12
+[tabFocus_sceneWithNestedFocusWidgets]
+opensuse
+opensuse-leap
+[inputMethod]
+opensuse
+opensuse-leap
+[hoverEvents_parentChild]
+ubuntu
+
diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
index b256aab3e7..c8ee2d65a3 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -1275,10 +1275,10 @@ void tst_QGraphicsScene::removeItem()
view.show();
QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
- QTest::mouseMove(view.viewport(), view.mapFromScene(hoverItem->scenePos() + QPointF(20, 20)), Qt::NoButton);
+ QTest::mouseMove(view.windowHandle(), view.mapFromScene(hoverItem->scenePos() + QPointF(20, 20)));
QTRY_VERIFY(!hoverItem->isHovered);
- QTest::mouseMove(view.viewport(), view.mapFromScene(hoverItem->scenePos()), Qt::NoButton);
+ QTest::mouseMove(view.windowHandle(), view.mapFromScene(hoverItem->scenePos()));
QTRY_VERIFY(hoverItem->isHovered);
scene.removeItem(hoverItem);
@@ -2657,7 +2657,7 @@ void tst_QGraphicsScene::render()
void tst_QGraphicsScene::renderItemsWithNegativeWidthOrHeight()
{
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) || defined(Q_OS_WINRT)
QSKIP("Test only works on platforms with resizable windows");
#endif
diff --git a/tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp
index f3ac70ddb5..baccf7bff8 100644
--- a/tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicssceneindex/tst_qgraphicssceneindex.cpp
@@ -355,6 +355,9 @@ void tst_QGraphicsSceneIndex::clear()
MyItem *item = new MyItem;
scene.addItem(item);
qApp->processEvents();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "There is one additional paint event on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(item->numPaints, 1);
}
diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
index fe5b320492..3dc110298a 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
@@ -48,7 +48,6 @@
#include <QtWidgets/QBoxLayout>
#include <QtWidgets/QStyle>
#include <QtWidgets/QPushButton>
-#include <QtWidgets/QDesktopWidget>
#ifndef QT_NO_OPENGL
#include <QtWidgets/QOpenGLWidget>
#endif
@@ -262,11 +261,11 @@ private slots:
void QTBUG_4151_clipAndIgnore_data();
void QTBUG_4151_clipAndIgnore();
void QTBUG_5859_exposedRect();
+ void hoverLeave();
+ void QTBUG_16063_microFocusRect();
#ifndef QT_NO_CURSOR
void QTBUG_7438_cursor();
#endif
- void hoverLeave();
- void QTBUG_16063_microFocusRect();
public slots:
void dummySlot() {}
@@ -431,6 +430,7 @@ void tst_QGraphicsView::interactive()
QCOMPARE(item->events.size(), 0);
view.show();
view.activateWindow();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_COMPARE(item->events.size(), 1); // activate
@@ -1646,6 +1646,7 @@ void tst_QGraphicsView::itemsInRect_cosmeticAdjust()
view.setFrameStyle(0);
view.resize(300, 300);
view.showNormal();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(rect->numPaints > 0);
@@ -2140,6 +2141,7 @@ void tst_QGraphicsView::sendEvent()
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
@@ -2207,6 +2209,7 @@ void tst_QGraphicsView::wheelEvent()
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
@@ -2435,14 +2438,15 @@ void tst_QGraphicsView::viewportUpdateMode()
scene.setBackgroundBrush(Qt::red);
CustomView view;
- QDesktopWidget desktop;
- view.setFixedSize(QSize(500, 500).boundedTo(desktop.availableGeometry().size())); // 500 is too big for all common smartphones
+ QScreen *screen = QGuiApplication::primaryScreen();
+ view.setFixedSize(QSize(500, 500).boundedTo(screen->availableGeometry().size())); // 500 is too big for all common smartphones
view.setScene(&scene);
QCOMPARE(view.viewportUpdateMode(), QGraphicsView::MinimalViewportUpdate);
// Show the view, and initialize our test.
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(!view.lastUpdateRegions.isEmpty());
view.lastUpdateRegions.clear();
@@ -2526,6 +2530,7 @@ void tst_QGraphicsView::viewportUpdateMode2()
view.resize(200 + left + right, 200 + top + bottom);
toplevel.show();
qApp->setActiveWindow(&toplevel);
+ QVERIFY(QTest::qWaitForWindowExposed(&toplevel));
QVERIFY(QTest::qWaitForWindowActive(&toplevel));
QTRY_VERIFY(view.painted);
const QRect viewportRect = view.viewport()->rect();
@@ -3170,6 +3175,7 @@ void tst_QGraphicsView::task172231_untransformableItems()
view.scale(2, 1);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
@@ -3969,6 +3975,7 @@ void tst_QGraphicsView::exposeRegion()
view.setScene(&scene);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(item->paints > 0);
@@ -4123,6 +4130,7 @@ void tst_QGraphicsView::update2()
view.resize(200, 200);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(rect->numPaints > 0);
@@ -4192,6 +4200,7 @@ void tst_QGraphicsView::update_ancestorClipsChildrenToShape()
CustomView view(&scene);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(view.painted);
@@ -4245,6 +4254,7 @@ void tst_QGraphicsView::update_ancestorClipsChildrenToShape2()
CustomView view(&scene);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(view.painted);
@@ -4305,6 +4315,7 @@ void tst_QGraphicsView::inputMethodSensitivity()
QGraphicsView view(&scene);
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
@@ -4399,6 +4410,7 @@ void tst_QGraphicsView::inputContextReset()
view.show();
QApplication::setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
@@ -4546,6 +4558,7 @@ void tst_QGraphicsView::task255529_transformationAnchorMouseAndViewportMargins()
view.setWindowFlags(Qt::X11BypassWindowManagerHint);
view.show();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
// This is highly unstable (observed to pass on Windows and some Linux configurations).
#ifndef Q_OS_MAC
@@ -4673,6 +4686,7 @@ void tst_QGraphicsView::QTBUG_4151_clipAndIgnore()
view.resize(75, 75);
view.show();
view.activateWindow();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(QApplication::activeWindow(), (QWidget *)&view);
@@ -4710,6 +4724,7 @@ void tst_QGraphicsView::QTBUG_5859_exposedRect()
view.scale(4.15, 4.15);
view.showNormal();
qApp->setActiveWindow(&view);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
view.viewport()->repaint(10,10,20,20);
@@ -4834,6 +4849,7 @@ void tst_QGraphicsView::QTBUG_16063_microFocusRect()
view.setFixedSize(40, 40);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
scene.setFocusItem(item);
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index 58a66f99b4..45c86800d6 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -1217,6 +1217,9 @@ void tst_QAbstractItemView::task250754_fontChange()
font.setPixelSize(60);
tree.setFont(font);
+#ifdef Q_OS_WINRT
+ QSKIP("Resizing the widget does not work as expected for WinRT, so the scroll bar might not be visible");
+#endif
//now with the huge items, the scrollbar must be visible
QTRY_VERIFY(tree.verticalScrollBar()->isVisible());
@@ -1534,6 +1537,9 @@ void tst_QAbstractItemView::testClickedSignal()
QSignalSpy clickedSpy(&view, SIGNAL(clicked(QModelIndex)));
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(clickedSpy.count(), 1);
QTest::mouseClick(view.viewport(), Qt::RightButton, 0, p);
@@ -2257,6 +2263,9 @@ void tst_QAbstractItemView::QTBUG46785_mouseout_hover_state()
QTest::mouseMove(table.viewport(), QPoint(-50, 0));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "QTest::mouseMove does not work on WinRT", Abort);
+#endif
QTRY_VERIFY(delegate.m_paintedWithoutHover);
}
diff --git a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
index 58b34e8aea..c58dbf599c 100644
--- a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
+++ b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
@@ -948,8 +948,10 @@ void tst_QColumnView::parentCurrentIndex()
QTRY_COMPARE(view.createdColumns[0]->currentIndex(), first);
QTRY_COMPARE(view.createdColumns[1]->currentIndex(), second);
+#ifndef Q_OS_WINRT
// The next two lines should be removed when QTBUG-22707 is resolved.
QEXPECT_FAIL("", "QTBUG-22707", Abort);
+#endif
QVERIFY(view.createdColumns[2]);
QTRY_COMPARE(view.createdColumns[2]->currentIndex(), third);
diff --git a/tests/auto/widgets/itemviews/qdirmodel/tst_qdirmodel.cpp b/tests/auto/widgets/itemviews/qdirmodel/tst_qdirmodel.cpp
index 48d39bbb11..d401154228 100644
--- a/tests/auto/widgets/itemviews/qdirmodel/tst_qdirmodel.cpp
+++ b/tests/auto/widgets/itemviews/qdirmodel/tst_qdirmodel.cpp
@@ -314,6 +314,9 @@ void tst_QDirModel::mkdir()
model.setReadOnly(false);
QModelIndex parent = model.index(SRCDIR "dirtest");
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Sandboxed applications cannot access SRCDIR - QTBUG-68297", Abort);
+#endif
QVERIFY(parent.isValid());
QCOMPARE(model.rowCount(parent), 1); // start out with only 'test1' - in's in the depot
@@ -351,6 +354,9 @@ void tst_QDirModel::rmdir()
model.setReadOnly(false);
QModelIndex parent = model.index(SRCDIR "/dirtest");
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Sandboxed applications cannot access SRCDIR - QTBUG-68297", Abort);
+#endif
QVERIFY(parent.isValid());
QCOMPARE(model.rowCount(parent), 1); // start out with only 'test1' - in's in the depot
@@ -460,6 +466,9 @@ bool tst_QDirModel::rowsAboutToBeRemoved_cleanup(const QString &test_path)
void tst_QDirModel::rowsAboutToBeRemoved()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Test fails on WinRT - QTBUG-68297");
+#endif
QFETCH(QString, test_path);
QFETCH(QStringList, initial_files);
QFETCH(int, remove_row);
@@ -571,6 +580,9 @@ void tst_QDirModel::unreadable()
void tst_QDirModel::filePath()
{
QFile::remove(SRCDIR "test.lnk");
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Sandboxed applications cannot access SRCDIR - QTBUG-68297", Abort);
+#endif
QVERIFY(QFile(SRCDIR "tst_qdirmodel.cpp").link(SRCDIR "test.lnk"));
QDirModel model;
model.setResolveSymlinks(false);
@@ -629,6 +641,9 @@ void tst_QDirModel::filter()
QDirModel model;
model.setNameFilters(QStringList() << "*.nada");
QModelIndex index = model.index(SRCDIR "test");
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Sandboxed applications cannot access SRCDIR - QTBUG-68297", Abort);
+#endif
QCOMPARE(model.rowCount(index), 0);
QModelIndex index2 = model.index(SRCDIR "test/file01.tst");
QVERIFY(!index2.isValid());
@@ -638,6 +653,9 @@ void tst_QDirModel::filter()
void tst_QDirModel::task244669_remove()
{
QFile f1(SRCDIR "dirtest/f1.txt");
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Sandboxed applications cannot access SRCDIR - QTBUG-68297", Abort);
+#endif
QVERIFY(f1.open(QIODevice::WriteOnly));
f1.close();
QFile f2(SRCDIR "dirtest/f2.txt");
diff --git a/tests/auto/widgets/itemviews/qheaderview/BLACKLIST b/tests/auto/widgets/itemviews/qheaderview/BLACKLIST
new file mode 100644
index 0000000000..efb813f7d2
--- /dev/null
+++ b/tests/auto/widgets/itemviews/qheaderview/BLACKLIST
@@ -0,0 +1,3 @@
+[stretchAndRestoreLastSection]
+opensuse
+opensuse-leap
diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
index 0dd98cf61c..b6932d4892 100644
--- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
@@ -244,7 +244,9 @@ private slots:
void testMinMaxSectionSize_data();
void testMinMaxSectionSize();
void sizeHintCrash();
+ void testResetCachedSizeHint();
void statusTips();
+
protected:
void setupTestData(bool use_reset_model = false);
void additionalInit();
@@ -266,9 +268,9 @@ Q_OBJECT
public:
QtTestModel(QObject *parent = 0): QAbstractTableModel(parent),
- cols(0), rows(0), wrongIndex(false) {}
- int rowCount(const QModelIndex&) const { return rows; }
- int columnCount(const QModelIndex&) const { return cols; }
+ cols(0), rows(0), wrongIndex(false), m_bMultiLine(false) {}
+ int rowCount(const QModelIndex&) const override { return rows; }
+ int columnCount(const QModelIndex&) const override { return cols; }
bool isEditable(const QModelIndex &) const { return true; }
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
{
@@ -280,11 +282,15 @@ public:
return QVariant();
if (orientation == Qt::Horizontal && col >= cols)
return QVariant();
+ if (m_bMultiLine)
+ return QString("%1\n%1").arg(section);
return QLatin1Char('[') + QString::number(row) + QLatin1Char(',')
+ QString::number(col) + QLatin1String(",0] -- Header");
}
- QVariant data(const QModelIndex &idx, int) const
+ QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override
{
+ if (role != Qt::DisplayRole)
+ return QVariant();
if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) {
wrongIndex = true;
qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(), idx.internalPointer());
@@ -367,8 +373,16 @@ public:
emit layoutChanged();
}
+ void setMultiLineHeader(bool bEnable)
+ {
+ beginResetModel();
+ m_bMultiLine = bEnable;
+ endResetModel();
+ }
+
int cols, rows;
mutable bool wrongIndex;
+ bool m_bMultiLine;
};
// Testing get/set functions
@@ -391,6 +405,7 @@ void tst_QHeaderView::getSetCheck()
// int QHeaderView::defaultSectionSize()
// void QHeaderView::setDefaultSectionSize(int)
+ obj1.setMinimumSectionSize(0);
obj1.setDefaultSectionSize(-1);
QVERIFY(obj1.defaultSectionSize() >= 0);
obj1.setDefaultSectionSize(0);
@@ -657,6 +672,8 @@ void tst_QHeaderView::sectionSize()
{
#if defined Q_OS_QNX
QSKIP("The section size is dpi dependent on QNX");
+#elif defined Q_OS_WINRT
+ QSKIP("Fails on WinRT - QTBUG-68297");
#endif
QFETCH(QList<int>, boundsCheck);
QFETCH(QList<int>, defaultSizes);
@@ -761,6 +778,8 @@ void tst_QHeaderView::visualIndexAt()
{
#if defined Q_OS_QNX
QSKIP("The section size is dpi dependent on QNX");
+#elif defined Q_OS_WINRT
+ QSKIP("Fails on WinRT - QTBUG-68297");
#endif
QFETCH(QList<int>, hidden);
QFETCH(QList<int>, from);
@@ -830,11 +849,9 @@ void tst_QHeaderView::offset()
void tst_QHeaderView::sectionSizeHint()
{
- // Test bad arguments
- view->sectionSizeHint(-1);
- view->sectionSizeHint(99999);
-
- // TODO how to test the return value?
+ QCOMPARE(view->sectionSizeHint(-1), -1);
+ QCOMPARE(view->sectionSizeHint(99999), -1);
+ QVERIFY(view->sectionSizeHint(0) >= 0);
}
void tst_QHeaderView::logicalIndex()
@@ -2044,6 +2061,7 @@ void tst_QHeaderView::defaultSectionSize()
QHeaderView h((Qt::Orientation)direction);
h.setModel(&m);
+ h.setMinimumSectionSize(0);
QCOMPARE(h.defaultSectionSize(), oldDefaultSize);
h.setDefaultSectionSize(newDefaultSize);
@@ -2144,6 +2162,9 @@ void tst_QHeaderView::preserveHiddenSectionWidth()
void tst_QHeaderView::invisibleStretchLastSection()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Fails on WinRT - QTBUG-68297");
+#endif
int count = 6;
QStandardItemModel model(1, count);
QHeaderView view(Qt::Horizontal);
@@ -2281,6 +2302,7 @@ void tst_QHeaderView::QTBUG6058_reset()
QHeaderView view(Qt::Vertical);
view.setModel(&proxy);
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view));
proxy.setSourceModel(&model1);
@@ -3306,8 +3328,16 @@ void tst_QHeaderView::testMinMaxSectionSize()
QHeaderView &header = *tv.horizontalHeader();
header.setMinimumSectionSize(sectionSizeMin);
header.setMaximumSectionSize(sectionSizeMax);
+ // check bounds for default section size
+ header.setDefaultSectionSize(sectionSizeMin - 1);
+ QCOMPARE(header.defaultSectionSize(), sectionSizeMin);
+ header.setDefaultSectionSize(sectionSizeMax + 1);
+ QCOMPARE(header.defaultSectionSize(), sectionSizeMax);
+
header.setDefaultSectionSize(defaultSectionSize);
+ QCOMPARE(header.defaultSectionSize(), defaultSectionSize);
header.setStretchLastSection(stretchLastSection);
+ QCOMPARE(header.stretchLastSection(), stretchLastSection);
// check defaults
QCOMPARE(header.sectionSize(0), defaultSectionSize);
@@ -3338,6 +3368,26 @@ void tst_QHeaderView::testMinMaxSectionSize()
QTRY_COMPARE(header.sectionSize(0), defaultSectionSize);
}
+void tst_QHeaderView::testResetCachedSizeHint()
+{
+ QtTestModel model;
+ model.rows = model.cols = 10;
+
+ QTableView tv;
+ tv.setModel(&model);
+ tv.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tv));
+
+ QSize s1 = tv.horizontalHeader()->sizeHint();
+ model.setMultiLineHeader(true);
+ QSize s2 = tv.horizontalHeader()->sizeHint();
+ model.setMultiLineHeader(false);
+ QSize s3 = tv.horizontalHeader()->sizeHint();
+ QCOMPARE(s1, s3);
+ QVERIFY(s1 != s2);
+}
+
+
class StatusTipHeaderView : public QHeaderView
{
public:
@@ -3372,7 +3422,7 @@ void tst_QHeaderView::statusTips()
// Ensure it is moved away first and then moved to the relevant section
QTest::mouseMove(QApplication::desktop(),
headerView.rect().bottomLeft() + QPoint(20, 20));
- QPoint centerPoint = QRect(headerView.sectionPosition(0), headerView.y(),
+ QPoint centerPoint = QRect(headerView.sectionPosition(0), 0,
headerView.sectionSize(0), headerView.height()).center();
QTest::mouseMove(headerView.windowHandle(), centerPoint);
QTRY_VERIFY(headerView.gotStatusTipEvent);
@@ -3380,7 +3430,7 @@ void tst_QHeaderView::statusTips()
headerView.gotStatusTipEvent = false;
headerView.statusTipText.clear();
- centerPoint = QRect(headerView.sectionPosition(1), headerView.y(),
+ centerPoint = QRect(headerView.sectionPosition(1), 0,
headerView.sectionSize(1), headerView.height()).center();
QTest::mouseMove(headerView.windowHandle(), centerPoint);
QTRY_VERIFY(headerView.gotStatusTipEvent);
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST b/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
index 0f7c377194..c6aeebc8f8 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
+++ b/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
@@ -5,3 +5,4 @@ opensuse-42.3 ci
[comboBox]
# QTBUG-67282
opensuse
+opensuse-leap
diff --git a/tests/auto/widgets/itemviews/qitemview/BLACKLIST b/tests/auto/widgets/itemviews/qitemview/BLACKLIST
new file mode 100644
index 0000000000..d5fc89f204
--- /dev/null
+++ b/tests/auto/widgets/itemviews/qitemview/BLACKLIST
@@ -0,0 +1,2 @@
+[scrollTo]
+winrt
diff --git a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp
index afd6d84486..bbdaac5c6f 100644
--- a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp
+++ b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp
@@ -546,23 +546,26 @@ void tst_QItemView::walkScreen(QAbstractItemView *view)
}
}
-void walkIndex(QModelIndex index, QAbstractItemView *view)
+void walkIndex(const QModelIndex &index, const QAbstractItemView *view)
{
- QRect visualRect = view->visualRect(index);
- //if (index.column() == 0)
- //qDebug() << index << visualRect;
- int width = visualRect.width();
- int height = visualRect.height();
+ const QRect visualRect = view->visualRect(index);
+ const int width = visualRect.width();
+ const int height = visualRect.height();
- for (int w = 0; w < width; ++w)
+ if (width == 0 || height == 0)
+ return;
+
+ const auto widths = (width < 2) ? QVector<int>({ 0, 1 }) : QVector<int>({ 0, 1, width / 2, width - 2, width - 1 });
+ const auto heights = (height < 2) ? QVector<int>({ 0, 1 }) : QVector<int>({ 0, 1, height / 2, height - 2, height - 1 });
+ for (int w : widths)
{
- for (int h = 0; h < height; ++h)
+ for (int h : heights)
{
- QPoint point(visualRect.x()+w, visualRect.y()+h);
- if (view->indexAt(point) != index) {
+ const QPoint point(visualRect.x() + w, visualRect.y() + h);
+ const auto idxAt = view->indexAt(point);
+ if (idxAt != index)
qDebug() << "index" << index << "visualRect" << visualRect << point << view->indexAt(point);
- }
- QCOMPARE(view->indexAt(point), index);
+ QCOMPARE(idxAt, index);
}
}
@@ -579,7 +582,7 @@ void walkIndex(QModelIndex index, QAbstractItemView *view)
a bug it will point it out, but the above tests should have already found the basic bugs
because it is easier to figure out the problem in those tests then this one.
*/
-void checkChildren(QAbstractItemView *currentView, const QModelIndex &parent = QModelIndex(), int currentDepth=0)
+void checkChildren(const QAbstractItemView *currentView, const QModelIndex &parent = QModelIndex(), int currentDepth = 0)
{
QAbstractItemModel *currentModel = currentView->model();
@@ -623,7 +626,6 @@ void tst_QItemView::indexAt()
view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll);
view->show();
view->setModel(treeModel);
-#if 0
checkChildren(view);
QModelIndex index = view->model()->index(0, 0);
@@ -636,7 +638,6 @@ void tst_QItemView::indexAt()
QPoint p(1, view->height()/2);
QModelIndex idx = view->indexAt(p);
QCOMPARE(idx, QModelIndex());
-#endif
}
void tst_QItemView::scrollTo_data()
diff --git a/tests/auto/widgets/itemviews/qlistview/qlistview.pro b/tests/auto/widgets/itemviews/qlistview/qlistview.pro
index e49a0c5fbf..75f45ab432 100644
--- a/tests/auto/widgets/itemviews/qlistview/qlistview.pro
+++ b/tests/auto/widgets/itemviews/qlistview/qlistview.pro
@@ -3,4 +3,3 @@ TARGET = tst_qlistview
QT += widgets gui-private widgets-private core-private testlib testlib-private
SOURCES += tst_qlistview.cpp
win32:!winrt: LIBS += -luser32
-linux*: CONFIG += insignificant_test # Crashes
diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
index d0c9dae313..5227db64ec 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -149,6 +149,8 @@ private slots:
void taskQTBUG_7232_AllowUserToControlSingleStep();
void taskQTBUG_51086_skippingIndexesInSelectedIndexes();
void taskQTBUG_47694_indexOutOfBoundBatchLayout();
+ void itemAlignment();
+ void internalDragDropMove();
};
// Testing get/set functions
@@ -1462,6 +1464,9 @@ void tst_QListView::wordWrap()
QApplication::processEvents();
QTRY_COMPARE(lv.horizontalScrollBar()->isVisible(), false);
+#ifdef Q_OS_WINRT
+QSKIP("setFixedSize does not work on WinRT. Vertical scroll bar will not be visible.");
+#endif
QTRY_COMPARE(lv.verticalScrollBar()->isVisible(), true);
}
@@ -2083,6 +2088,9 @@ void tst_QListView::taskQTBUG_21115_scrollToAndHiddenItems_data()
void tst_QListView::taskQTBUG_21115_scrollToAndHiddenItems()
{
QFETCH(int, flow);
+#ifdef Q_OS_WINRT
+ QSKIP("Fails on WinRT - QTBUG-68297");
+#endif
ScrollPerItemListView lv;
lv.setUniformItemSizes(true);
@@ -2293,6 +2301,9 @@ void tst_QListView::testScrollToWithHidden()
lv.scrollTo(model.index(26, 0));
int expectedScrollBarValue = lv.verticalScrollBar()->value();
+#ifdef Q_OS_WINRT
+ QSKIP("Might fail on WinRT - QTBUG-68297");
+#endif
QVERIFY(expectedScrollBarValue != 0);
lv.scrollTo(model.index(25, 0));
@@ -2419,6 +2430,7 @@ void tst_QListView::taskQTBUG_39902_mutualScrollBars()
void tst_QListView::horizontalScrollingByVerticalWheelEvents()
{
+#if QT_CONFIG(wheelevent)
QListView lv;
lv.setWrapping(true);
@@ -2460,6 +2472,9 @@ void tst_QListView::horizontalScrollingByVerticalWheelEvents()
int vValue = lv.verticalScrollBar()->value();
QApplication::sendEvent(lv.viewport(), &wheelDownEvent);
QVERIFY(lv.verticalScrollBar()->value() > vValue);
+#else
+ QSKIP("Built with --no-feature-wheelevent");
+#endif
}
void tst_QListView::taskQTBUG_7232_AllowUserToControlSingleStep()
@@ -2540,5 +2555,76 @@ void tst_QListView::taskQTBUG_47694_indexOutOfBoundBatchLayout()
view.scrollTo(model.index(batchSize - 1, 0));
}
+void tst_QListView::itemAlignment()
+{
+ auto item1 = new QStandardItem("111");
+ auto item2 = new QStandardItem("111111");
+ QStandardItemModel model;
+ model.appendRow(item1);
+ model.appendRow(item2);
+
+ QListView w;
+ w.setModel(&model);
+ w.setWrapping(true);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+
+ QVERIFY(w.visualRect(item1->index()).width() > 0);
+ QVERIFY(w.visualRect(item1->index()).width() == w.visualRect(item2->index()).width());
+
+ w.setItemAlignment(Qt::AlignLeft);
+ QApplication::processEvents();
+
+ QVERIFY(w.visualRect(item1->index()).width() < w.visualRect(item2->index()).width());
+}
+
+void tst_QListView::internalDragDropMove()
+{
+ const QString platform(QGuiApplication::platformName().toLower());
+ if (platform != QLatin1String("xcb"))
+ QSKIP("Need a window system with proper DnD support via injected mouse events");
+
+ // on an internal move, the item was deleted which should not happen
+ // see QTBUG-67440
+ class QListViewWithPublicStartDrag : public QListView
+ {
+ public:
+ using QListView::startDrag;
+ };
+
+ QStandardItemModel data(0, 1);
+ QPixmap pixmap(32, 32);
+ for (int i = 0; i < 10; ++i) {
+ pixmap.fill(Qt::GlobalColor(i + 1));
+ data.appendRow(new QStandardItem(QIcon(pixmap), QString::number(i)));
+ }
+ QItemSelectionModel selections(&data);
+ QListViewWithPublicStartDrag list;
+ list.setWindowTitle(QTest::currentTestFunction());
+ list.setViewMode(QListView::IconMode);
+ list.setDefaultDropAction(Qt::MoveAction);
+ list.setModel(&data);
+ list.setSelectionModel(&selections);
+ list.resize(300, 300);
+ list.show();
+ selections.select(data.index(1, 0), QItemSelectionModel::Select);
+ QVERIFY(QTest::qWaitForWindowExposed(&list));
+
+ // execute as soon as the eventloop is running again
+ // which is the case inside list.startDrag()
+ QTimer::singleShot(0, [&list]()
+ {
+ const QPoint pos = list.rect().center();
+ QMouseEvent mouseMove(QEvent::MouseMove, pos, list.mapToGlobal(pos), Qt::NoButton, 0, 0);
+ QApplication::sendEvent(&list, &mouseMove);
+ QMouseEvent mouseRelease(QEvent::MouseButtonRelease, pos, list.mapToGlobal(pos), Qt::LeftButton, 0, 0);
+ QApplication::sendEvent(&list, &mouseRelease);
+ });
+ const int expectedCount = data.rowCount();
+ list.startDrag(Qt::MoveAction|Qt::CopyAction);
+ QCOMPARE(expectedCount, data.rowCount());
+}
+
+
QTEST_MAIN(tst_QListView)
#include "tst_qlistview.moc"
diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
index 8427b04be7..228d03350a 100644
--- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
@@ -1353,6 +1353,11 @@ void tst_QTableView::moveCursorBiggerJump()
QCOMPARE(view.indexAt(QPoint(0,0)), model.index(7,0));
QTest::keyClick(&view, Qt::Key_PageUp);
QCOMPARE(view.indexAt(QPoint(0,0)), model.index(0,0));
+
+ QTest::keyClick(&view, Qt::Key_PageDown);
+ view.verticalHeader()->hideSection(0);
+ QTest::keyClick(&view, Qt::Key_PageUp);
+ QTRY_COMPARE(view.currentIndex().row(), view.rowAt(0));
}
void tst_QTableView::hideRows_data()
@@ -2329,6 +2334,14 @@ void tst_QTableView::rowViewportPosition()
view.setVerticalScrollMode((QAbstractItemView::ScrollMode)verticalScrollMode);
view.verticalScrollBar()->setValue(verticalScrollValue);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("row 1, scroll per item, 1", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("row 5, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("row 9, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("row 1, scroll per pixel, 1", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("row 5, scroll per pixel, 5", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("row 9, scroll per pixel, 5", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(view.rowViewportPosition(row), rowViewportPosition);
}
@@ -2492,6 +2505,13 @@ void tst_QTableView::columnViewportPosition()
view.setHorizontalScrollMode((QAbstractItemView::ScrollMode)horizontalScrollMode);
view.horizontalScrollBar()->setValue(horizontalScrollValue);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("column 5, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("column 9, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("column 1, scroll per pixel 1", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("column 5, scroll per pixel 5", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("column 9, scroll per pixel 5", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(view.columnViewportPosition(column), columnViewportPosition);
}
diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
index 4d4a95b3f5..208ce27c8f 100644
--- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
@@ -32,6 +32,7 @@
#include <qlist.h>
#include <qpair.h>
#include <qheaderview.h>
+#include <qlineedit.h>
#include <qtablewidget.h>
@@ -81,6 +82,7 @@ private slots:
void itemData();
void setItemData();
void cellWidget();
+ void cellWidgetGeometry();
void task231094();
void task219380_removeLastRow();
void task262056_sortDuplicate();
@@ -1343,27 +1345,45 @@ void tst_QTableWidget::setItemWithSorting()
}
}
+class QTableWidgetDataChanged : public QTableWidget
+{
+ Q_OBJECT
+public:
+ using QTableWidget::QTableWidget;
+
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) override
+ {
+ QTableWidget::dataChanged(topLeft, bottomRight, roles);
+ currentRoles = roles;
+ }
+ QVector<int> currentRoles;
+};
+
void tst_QTableWidget::itemData()
{
- QTableWidget widget(2, 2);
+ QTableWidgetDataChanged widget(2, 2);
widget.setItem(0, 0, new QTableWidgetItem());
QTableWidgetItem *item = widget.item(0, 0);
QVERIFY(item);
item->setFlags(item->flags() | Qt::ItemIsEditable);
item->setData(Qt::DisplayRole, QString("0"));
+ QCOMPARE(widget.currentRoles, QVector<int>({Qt::DisplayRole, Qt::EditRole}));
item->setData(Qt::CheckStateRole, Qt::PartiallyChecked);
- item->setData(Qt::UserRole + 0, QString("1"));
- item->setData(Qt::UserRole + 1, QString("2"));
- item->setData(Qt::UserRole + 2, QString("3"));
- item->setData(Qt::UserRole + 3, QString("4"));
+ QCOMPARE(widget.currentRoles, {Qt::CheckStateRole});
+ for (int i = 0; i < 4; ++i)
+ {
+ item->setData(Qt::UserRole + i, QString::number(i + 1));
+ QCOMPARE(widget.currentRoles, {Qt::UserRole + i});
+ }
QMap<int, QVariant> flags = widget.model()->itemData(widget.model()->index(0, 0));
QCOMPARE(flags.count(), 6);
- QCOMPARE(flags[(Qt::UserRole + 0)].toString(), QString("1"));
+ for (int i = 0; i < 4; ++i)
+ QCOMPARE(flags[Qt::UserRole + i].toString(), QString::number(i + 1));
}
void tst_QTableWidget::setItemData()
{
- QTableWidget table(10, 10);
+ QTableWidgetDataChanged table(10, 10);
table.setSortingEnabled(false);
QSignalSpy dataChangedSpy(table.model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)));
@@ -1376,6 +1396,7 @@ void tst_QTableWidget::setItemData()
data.insert(Qt::DisplayRole, QLatin1String("Display"));
data.insert(Qt::ToolTipRole, QLatin1String("ToolTip"));
table.model()->setItemData(idx, data);
+ QCOMPARE(table.currentRoles, QVector<int>({Qt::DisplayRole, Qt::EditRole, Qt::ToolTipRole}));
QCOMPARE(table.model()->data(idx, Qt::DisplayRole).toString(), QLatin1String("Display"));
QCOMPARE(table.model()->data(idx, Qt::ToolTipRole).toString(), QLatin1String("ToolTip"));
@@ -1404,6 +1425,28 @@ void tst_QTableWidget::cellWidget()
QCOMPARE(table.cellWidget(5, 5), static_cast<QWidget*>(0));
}
+void tst_QTableWidget::cellWidgetGeometry()
+{
+ QTableWidget tw(3,2);
+ tw.show();
+ // make sure the next row added is not completely visibile
+ tw.resize(300, tw.rowHeight(0) * 3 + tw.rowHeight(0) / 2);
+ QVERIFY(QTest::qWaitForWindowExposed(&tw));
+
+ tw.scrollToBottom();
+ tw.setRowCount(tw.rowCount() + 1);
+ auto item = new QTableWidgetItem("Hello");
+ tw.setItem(0,0,item);
+ auto le = new QLineEdit("world");
+ tw.setCellWidget(0,1,le);
+ // process delayedPendingLayout triggered by setting the row count
+ tw.doItemsLayout();
+ // so y pos is 0 for the first row
+ tw.scrollToTop();
+ // check if updateEditorGeometries has set the correct y pos for the editors
+ QCOMPARE(tw.visualItemRect(item).top(), le->geometry().top());
+}
+
void tst_QTableWidget::task231094()
{
QTableWidget tw(5, 3);
diff --git a/tests/auto/widgets/itemviews/qtreeview/BLACKLIST b/tests/auto/widgets/itemviews/qtreeview/BLACKLIST
deleted file mode 100644
index 5eb80007c4..0000000000
--- a/tests/auto/widgets/itemviews/qtreeview/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[setSortingEnabledChild]
-windows
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 1ea1843abe..a79341b66f 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -839,6 +839,9 @@ void tst_QTreeView::horizontalScrollMode()
QCOMPARE(view.horizontalScrollMode(), QAbstractItemView::ScrollPerPixel);
QCOMPARE(view.horizontalScrollBar()->minimum(), 0);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "setFixedSize does not work on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(view.horizontalScrollBar()->maximum() > 2);
view.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
@@ -1975,6 +1978,10 @@ void tst_QTreeView::setSelection()
QVERIFY(selectionModel);
QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("(0,-20,20,50),rows", "Fails on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("(0,-50,20,90),rows", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(selectedIndexes.count(), expectedItems.count());
for (int i = 0; i < selectedIndexes.count(); ++i) {
QModelIndex idx = selectedIndexes.at(i);
@@ -2600,8 +2607,10 @@ void tst_QTreeView::setSortingEnabledChild()
{
QMainWindow win;
QTreeView view;
- QStandardItemModel model(1,1);
+ // two columns to not get in trouble with stretchLastSection
+ QStandardItemModel model(1,2);
view.setModel(&model);
+ view.header()->setDefaultSectionSize(92);
win.setCentralWidget(&view);
const int size = view.header()->sectionSize(0);
view.setSortingEnabled(true);
diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
index 321e4bcd0e..8c93df9073 100644
--- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
@@ -160,6 +160,7 @@ private slots:
void task20345_sortChildren();
void getMimeDataWithInvalidItem();
void testVisualItemRect();
+ void reparentHiddenItem();
public slots:
void itemSelectionChanged();
@@ -1938,23 +1939,38 @@ void tst_QTreeWidget::setData()
}
}
+class QTreeWidgetDataChanged : public QTreeWidget
+{
+ Q_OBJECT
+public:
+ using QTreeWidget::QTreeWidget;
+
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) override
+ {
+ QTreeWidget::dataChanged(topLeft, bottomRight, roles);
+ currentRoles = roles;
+ }
+ QVector<int> currentRoles;
+};
+
void tst_QTreeWidget::itemData()
{
- QTreeWidget widget;
+ QTreeWidgetDataChanged widget;
QTreeWidgetItem item(&widget);
widget.setColumnCount(2);
item.setFlags(item.flags() | Qt::ItemIsEditable);
item.setData(0, Qt::DisplayRole, QString("0"));
+ QCOMPARE(widget.currentRoles, QVector<int>({Qt::DisplayRole, Qt::EditRole}));
item.setData(0, Qt::CheckStateRole, Qt::PartiallyChecked);
- item.setData(0, Qt::UserRole + 0, QString("1"));
- item.setData(0, Qt::UserRole + 1, QString("2"));
- item.setData(0, Qt::UserRole + 2, QString("3"));
- item.setData(0, Qt::UserRole + 3, QString("4"));
-
+ QCOMPARE(widget.currentRoles, {Qt::CheckStateRole});
+ for (int i = 0; i < 4; ++i) {
+ item.setData(0, Qt::UserRole + i, QString::number(i + 1));
+ QCOMPARE(widget.currentRoles, {Qt::UserRole + i});
+ }
QMap<int, QVariant> flags = widget.model()->itemData(widget.model()->index(0, 0));
QCOMPARE(flags.count(), 6);
- QCOMPARE(flags[Qt::UserRole + 0].toString(), QString("1"));
-
+ for (int i = 0; i < 4; ++i)
+ QCOMPARE(flags[Qt::UserRole + i].toString(), QString::number(i + 1));
flags = widget.model()->itemData(widget.model()->index(0, 1));
QCOMPARE(flags.count(), 0);
}
@@ -3412,8 +3428,9 @@ void tst_QTreeWidget::taskQTBUG_34717_collapseAtBottom()
void tst_QTreeWidget::task20345_sortChildren()
{
- if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
- QSKIP("Wayland: This causes a crash triggered by setVisible(false)");
+ if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)
+ || !QGuiApplication::platformName().compare(QLatin1String("winrt"), Qt::CaseInsensitive))
+ QSKIP("Wayland/WinRT: This causes a crash triggered by setVisible(false)");
// This test case is considered successful if it is executed (no crash in sorting)
QTreeWidget tw;
@@ -3483,5 +3500,34 @@ void tst_QTreeWidget::testVisualItemRect()
QCOMPARE(r.width(), sectionSize);
}
+void tst_QTreeWidget::reparentHiddenItem()
+{
+ QTreeWidgetItem *parent = new QTreeWidgetItem(testWidget);
+ parent->setText(0, "parent");
+ QTreeWidgetItem *otherParent = new QTreeWidgetItem(testWidget);
+ otherParent->setText(0, "other parent");
+ QTreeWidgetItem *child = new QTreeWidgetItem(parent);
+ child->setText(0, "child");
+ QTreeWidgetItem *grandChild = new QTreeWidgetItem(child);
+ grandChild->setText(0, "grandchild");
+ QVERIFY(child->parent());
+ QVERIFY(grandChild->parent());
+
+ testWidget->expandItem(parent);
+ testWidget->expandItem(otherParent);
+ testWidget->expandItem(child);
+
+ QVERIFY(!parent->isHidden());
+ QVERIFY(!child->isHidden());
+ QVERIFY(!grandChild->isHidden());
+
+ grandChild->setHidden(true);
+
+ QVERIFY(grandChild->isHidden());
+ parent->removeChild(child);
+ otherParent->addChild(child);
+ QVERIFY(grandChild->isHidden());
+}
+
QTEST_MAIN(tst_QTreeWidget)
#include "tst_qtreewidget.moc"
diff --git a/tests/auto/widgets/kernel/qapplication/BLACKLIST b/tests/auto/widgets/kernel/qapplication/BLACKLIST
index ca0efdff8a..d7de7bf16e 100644
--- a/tests/auto/widgets/kernel/qapplication/BLACKLIST
+++ b/tests/auto/widgets/kernel/qapplication/BLACKLIST
@@ -1,3 +1,4 @@
[touchEventPropagation]
# QTBUG-66745
opensuse
+opensuse-leap
diff --git a/tests/auto/widgets/kernel/qapplication/desktopsettingsaware/desktopsettingsaware.pro b/tests/auto/widgets/kernel/qapplication/desktopsettingsaware/desktopsettingsaware.pro
index a10ff71b05..442bf33b61 100644
--- a/tests/auto/widgets/kernel/qapplication/desktopsettingsaware/desktopsettingsaware.pro
+++ b/tests/auto/widgets/kernel/qapplication/desktopsettingsaware/desktopsettingsaware.pro
@@ -1,6 +1,14 @@
QT += widgets
-CONFIG -= app_bundle debug_and_release_target
+CONFIG -= app_bundle
-DESTDIR = ./
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/desktopsettingsaware_helper
+ } else {
+ TARGET = ../../release/desktopsettingsaware_helper
+ }
+} else {
+ TARGET = ../desktopsettingsaware_helper
+}
SOURCES += main.cpp
diff --git a/tests/auto/widgets/kernel/qapplication/modal/modal.pro b/tests/auto/widgets/kernel/qapplication/modal/modal.pro
index a34871d2aa..e832d90821 100644
--- a/tests/auto/widgets/kernel/qapplication/modal/modal.pro
+++ b/tests/auto/widgets/kernel/qapplication/modal/modal.pro
@@ -1,7 +1,15 @@
QT += widgets
SOURCES += main.cpp \
base.cpp
-DESTDIR = ./
-CONFIG -= app_bundle debug_and_release_target
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/modal_helper
+ } else {
+ TARGET = ../../release/modal_helper
+ }
+} else {
+ TARGET = ../modal_helper
+}
+CONFIG -= app_bundle
HEADERS += base.h
diff --git a/tests/auto/widgets/kernel/qapplication/test/test.pro b/tests/auto/widgets/kernel/qapplication/test/test.pro
index 41aad02a1b..8ade4d8364 100644
--- a/tests/auto/widgets/kernel/qapplication/test/test.pro
+++ b/tests/auto/widgets/kernel/qapplication/test/test.pro
@@ -1,18 +1,28 @@
CONFIG += testcase
-CONFIG -= debug_and_release_target
QT += widgets widgets-private testlib
QT += core-private gui-private
SOURCES += ../tst_qapplication.cpp
-TARGET = ../tst_qapplication
-TESTDATA = ../test/test.pro ../tmp/README
+builtin_testdata: DEFINES += BUILTIN_TESTDATA
-!android:!winrt {
- SUBPROGRAMS = desktopsettingsaware modal
- win32:SUBPROGRAMS += wincmdline
+TESTDATA = ../test/test.pro ../tmp/README ../modal
- for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../$${file}/$${file}"
-}
+!android:!winrt: SUBPROGRAMS = desktopsettingsaware modal
+debug_and_release {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/tst_qapplication
+ !android:!winrt: TEST_HELPER_INSTALLS = ../debug/helper
+ for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../debug/$${file}"
+ } else {
+ TARGET = ../../release/tst_qapplication
+ !android:!winrt: TEST_HELPER_INSTALLS = ../release/helper
+ for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../release/$${file}"
+ }
+} else {
+ TARGET = ../tst_qapplication
+ !android:!winrt: TEST_HELPER_INSTALLS = ../helper
+ for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../$${file}"
+}
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index 5301dababc..67e46ad1b3 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -96,7 +96,6 @@ public:
tst_QApplication();
private slots:
- void initTestCase();
void cleanup();
void sendEventsOnProcessEvents(); // this must be the first test
void staticSetup();
@@ -187,13 +186,6 @@ public:
}
};
-void tst_QApplication::initTestCase()
-{
- // chdir to our testdata path and execute helper apps relative to that.
- const QString testdataDir = QFileInfo(QFINDTESTDATA("desktopsettingsaware")).absolutePath();
- QVERIFY2(QDir::setCurrent(testdataDir), qPrintable("Could not chdir to " + testdataDir));
-}
-
void tst_QApplication::sendEventsOnProcessEvents()
{
int argc = 0;
@@ -277,6 +269,9 @@ public:
void tst_QApplication::alert()
{
+#ifdef Q_OS_WINRT
+ QSKIP("WinRT does not support more than 1 native widget at the same time");
+#endif
int argc = 0;
QApplication app(argc, 0);
app.alert(0, 0);
@@ -820,6 +815,9 @@ public:
void tst_QApplication::closeAllWindows()
{
+#ifdef Q_OS_WINRT
+ QSKIP("PromptOnCloseWidget does not work on WinRT - QTBUG-68297");
+#endif
int argc = 0;
QApplication app(argc, 0);
@@ -888,7 +886,11 @@ bool isPathListIncluded(const QStringList &l, const QStringList &r)
#define QT_TST_QAPP_DEBUG
void tst_QApplication::libraryPaths()
{
+#ifndef BUILTIN_TESTDATA
const QString testDir = QFileInfo(QFINDTESTDATA("test/test.pro")).absolutePath();
+#else
+ const QString testDir = QFileInfo(QFINDTESTDATA("test.pro")).absolutePath();
+#endif
QVERIFY(!testDir.isEmpty());
{
QApplication::setLibraryPaths(QStringList() << testDir);
@@ -921,6 +923,9 @@ void tst_QApplication::libraryPaths()
QStringList expected = QSet<QString>::fromList((QStringList() << installPathPlugins << appDirPath)).toList();
expected.sort();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "On WinRT PluginsPath is outside of sandbox. QTBUG-68297", Abort);
+#endif
QVERIFY2(isPathListIncluded(actual, expected),
qPrintable("actual:\n - " + actual.join("\n - ") +
"\nexpected:\n - " + expected.join("\n - ")));
@@ -1040,6 +1045,9 @@ void tst_QApplication::libraryPaths_qt_plugin_path_2()
<< QDir(app.applicationDirPath()).canonicalPath()
<< QDir(QDir::fromNativeSeparators(QString::fromLatin1(validPath))).canonicalPath();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "On WinRT PluginsPath is outside of sandbox. QTBUG-68297", Abort);
+#endif
QVERIFY2(isPathListIncluded(app.libraryPaths(), expected),
qPrintable("actual:\n - " + app.libraryPaths().join("\n - ") +
"\nexpected:\n - " + expected.join("\n - ")));
@@ -1434,20 +1442,10 @@ void tst_QApplication::testDeleteLaterProcessEvents()
void tst_QApplication::desktopSettingsAware()
{
#if QT_CONFIG(process)
- QString path;
- {
- // We need an application object for QFINDTESTDATA to work
- // properly in all cases.
- int argc = 0;
- QCoreApplication app(argc, 0);
- path = QFINDTESTDATA("desktopsettingsaware/");
- }
- QVERIFY2(!path.isEmpty(), "Cannot locate desktopsettingsaware helper application");
- path += "desktopsettingsaware";
QProcess testProcess;
- testProcess.start(path);
+ testProcess.start("desktopsettingsaware_helper");
QVERIFY2(testProcess.waitForStarted(),
- qPrintable(QString::fromLatin1("Cannot start '%1': %2").arg(path, testProcess.errorString())));
+ qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(10000));
QCOMPARE(int(testProcess.state()), int(QProcess::NotRunning));
QVERIFY(int(testProcess.error()) != int(QProcess::Crashed));
@@ -1744,6 +1742,9 @@ void tst_QApplication::focusMouseClick()
QSpontaneKeyEvent::setSpontaneous(&ev);
QVERIFY(ev.spontaneous());
qApp->notify(&w2, &ev);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(QApplication::focusWidget(), &w2);
// now back to tab focus and click again (it already had focus) -> focus should stay
@@ -2112,23 +2113,12 @@ void tst_QApplication::touchEventPropagation()
void tst_QApplication::qtbug_12673()
{
- QString path;
- {
- // We need an application object for QFINDTESTDATA to work
- // properly in all cases.
- int argc = 0;
- QCoreApplication app(argc, 0);
- path = QFINDTESTDATA("modal/");
- }
- QVERIFY2(!path.isEmpty(), "Cannot locate modal helper application");
- path += "modal";
-
#if QT_CONFIG(process)
QProcess testProcess;
QStringList arguments;
- testProcess.start(path, arguments);
+ testProcess.start("modal_helper", arguments);
QVERIFY2(testProcess.waitForStarted(),
- qPrintable(QString::fromLatin1("Cannot start '%1': %2").arg(path, testProcess.errorString())));
+ qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(20000));
QCOMPARE(testProcess.exitStatus(), QProcess::NormalExit);
#else
diff --git a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp
index 8314dbedf5..b2650d1f32 100644
--- a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp
+++ b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp
@@ -56,6 +56,7 @@ private slots:
void taskQTBUG_40609_addingWidgetToItsOwnLayout();
void taskQTBUG_40609_addingLayoutToItself();
void replaceWidget();
+ void indexOf();
};
class CustomLayoutStyle : public QProxyStyle
@@ -512,5 +513,24 @@ void tst_QBoxLayout::replaceWidget()
QCOMPARE(boxLayout->indexOf(replaceTo), 1);
}
+void tst_QBoxLayout::indexOf()
+{
+ QWidget w;
+ auto outer = new QVBoxLayout(&w);
+ auto inner = new QHBoxLayout();
+ outer->addLayout(inner);
+ auto widget1 = new QWidget();
+ QWidget widget2;
+ inner->addWidget(widget1);
+
+ QCOMPARE(inner->indexOf(widget1), 0);
+ QCOMPARE(inner->indexOf(&widget2), -1);
+ QCOMPARE(outer->indexOf(widget1), -1);
+ QCOMPARE(outer->indexOf(&widget2), -1);
+ QCOMPARE(outer->indexOf(outer), -1);
+ QCOMPARE(outer->indexOf(inner), 0);
+ QCOMPARE(inner->indexOf(inner->itemAt(0)), 0);
+}
+
QTEST_MAIN(tst_QBoxLayout)
#include "tst_qboxlayout.moc"
diff --git a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp
index 162da61584..cff3dad35e 100644
--- a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp
+++ b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp
@@ -273,6 +273,9 @@ void tst_QFormLayout::wrapping()
w.setWindowTitle(QTest::currentTestFunction());
w.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "setFixedWidth does not work on WinRT", Abort);
+#endif
QCOMPARE(le->geometry().y() > lbl->geometry().y(), true);
//TODO: additional tests covering different wrapping cases
diff --git a/tests/auto/widgets/kernel/qgesturerecognizer/BLACKLIST b/tests/auto/widgets/kernel/qgesturerecognizer/BLACKLIST
deleted file mode 100644
index 7f55c2dae0..0000000000
--- a/tests/auto/widgets/kernel/qgesturerecognizer/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[panGesture:Two finger]
-xcb
diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp
index 300a8878ba..936f581d89 100644
--- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp
+++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp
@@ -337,7 +337,7 @@ void tst_QLayout::adjustSizeShouldMakeSureLayoutIsActivated()
void tst_QLayout::testRetainSizeWhenHidden()
{
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
+#if (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)) || defined(Q_OS_WINRT)
QSKIP("Test does not work on platforms which default to showMaximized()");
#endif
diff --git a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp
index eb3264be53..89bb946be9 100644
--- a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp
+++ b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp
@@ -116,8 +116,16 @@ void tst_QSizePolicy::constExpr()
{ Q_CONSTEXPR QSizePolicy sp = QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); Q_UNUSED(sp); }
{ Q_CONSTEXPR QSizePolicy sp = QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding, QSizePolicy::DefaultType);
Q_CONSTEXPR QSizePolicy tp = sp.transposed(); Q_UNUSED(tp); }
- { Q_RELAXED_CONSTEXPR auto sp = QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::CheckBox);
- Q_RELAXED_CONSTEXPR auto tp = sp.transposed(); Q_UNUSED(tp); }
+ {
+ // QTBUG-69983: For ControlType != QSizePolicy::DefaultType, qCountTrailingZeroBits()
+ // is used, which MSVC 15.8.1 does not consider constexpr due to built-ins
+# if defined(QT_HAS_CONSTEXPR_BUILTINS) && (!defined(Q_CC_MSVC) || _MSC_VER < 1915)
+ Q_RELAXED_CONSTEXPR auto sp = QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::CheckBox);
+# else
+ Q_CONSTEXPR auto sp = QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding, QSizePolicy::DefaultType);
+# endif
+ Q_RELAXED_CONSTEXPR auto tp = sp.transposed(); Q_UNUSED(tp);
+ }
#else
QSKIP("QSizePolicy cannot be constexpr with this version of the compiler.");
#endif
diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST
index 6cebce26e8..d8654e5768 100644
--- a/tests/auto/widgets/kernel/qwidget/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST
@@ -2,35 +2,27 @@
[normalGeometry]
ubuntu-16.04
[saveRestoreGeometry]
-ubuntu-16.04
+xcb
b2qt
-# QTBUG-66708
-opensuse
[restoreVersion1Geometry]
-xcb
osx
[updateWhileMinimized]
ubuntu-16.04
+ubuntu-18.04
rhel-7.4
osx
[focusProxyAndInputMethods]
linux
-[showMaximized]
-osx
-[setGeometry]
-osx
[raise]
# QTBUG-68175
opensuse
-osx
-[resizeEvent]
-osx
+opensuse-leap
[setWindowGeometry]
osx
[windowMoveResize]
osx
[childEvents]
-osx
+osx ci
[renderInvisible]
osx
[optimizedResizeMove]
@@ -42,27 +34,10 @@ osx
[showMinimizedKeepsFocus]
osx-10.11 ci
osx-10.12 ci
-[moveWindowInShowEvent:1]
-osx
-[moveWindowInShowEvent:2]
-osx
-[taskQTBUG_4055_sendSyntheticEnterLeave]
-osx
-[syntheticEnterLeave]
-osx
+osx-10.13 ci
[maskedUpdate]
-osx
-opensuse-42.3
-[hideOpaqueChildWhileHidden]
-osx
-[resizeStaticContentsChildWidget_QTBUG35282]
-osx
-[lower]
-osx
-[setClearAndResizeMask]
-osx
-[setToolTip]
-osx
+opensuse
+opensuse-leap
[moveInResizeEvent]
ubuntu-16.04
[moveChild:right]
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 6a049aedf1..360e6986f6 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -188,7 +188,8 @@ private slots:
void reverseTabOrder();
void tabOrderWithProxy();
void tabOrderWithCompoundWidgets();
-#ifdef Q_OS_WIN
+ void tabOrderNoChange();
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void activation();
#endif
void reparent();
@@ -416,8 +417,7 @@ private:
bool tst_QWidget::ensureScreenSize(int width, int height)
{
- QSize available;
- available = QDesktopWidget().availableGeometry().size();
+ const QSize available = QGuiApplication::primaryScreen()->availableGeometry().size();
return (available.width() >= width && available.height() >= height);
}
@@ -1426,7 +1426,7 @@ void tst_QWidget::mapFromAndTo()
subWindow2->setGeometry(75, 75, 100, 100);
subSubWindow->setGeometry(10, 10, 10, 10);
-#if !defined(Q_OS_QNX)
+#if !defined(Q_OS_QNX) && !defined(Q_OS_WINRT)
//update visibility
if (windowMinimized) {
if (!windowHidden) {
@@ -1931,7 +1931,35 @@ void tst_QWidget::tabOrderWithCompoundWidgets()
QVERIFY(lastEdit->hasFocus());
}
-#ifdef Q_OS_WIN
+static QVector<QWidget*> getFocusChain(QWidget *start, bool bForward)
+{
+ QVector<QWidget*> ret;
+ QWidget *cur = start;
+ do {
+ ret += cur;
+ auto widgetPrivate = static_cast<QWidgetPrivate *>(qt_widget_private(cur));
+ cur = bForward ? widgetPrivate->focus_next : widgetPrivate->focus_prev;
+ } while (cur != start);
+ return ret;
+}
+
+void tst_QWidget::tabOrderNoChange()
+{
+ QWidget w;
+ auto *verticalLayout = new QVBoxLayout(&w);
+ auto *tabWidget = new QTabWidget(&w);
+ auto *tv = new QTreeView(tabWidget);
+ tabWidget->addTab(tv, QStringLiteral("Tab 1"));
+ verticalLayout->addWidget(tabWidget);
+
+ const auto focusChainForward = getFocusChain(&w, true);
+ const auto focusChainBackward = getFocusChain(&w, false);
+ QWidget::setTabOrder(tabWidget, tv);
+ QCOMPARE(focusChainForward, getFocusChain(&w, true));
+ QCOMPARE(focusChainBackward, getFocusChain(&w, false));
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void tst_QWidget::activation()
{
Q_CHECK_PAINTEVENTS
@@ -1976,7 +2004,8 @@ void tst_QWidget::windowState()
QPoint pos;
QSize size = m_testWidgetSize;
if (QGuiApplicationPrivate::platformIntegration()->defaultWindowState(Qt::Widget)
- == Qt::WindowFullScreen) {
+ == Qt::WindowFullScreen
+ || m_platform == QStringLiteral("winrt")) {
size = QGuiApplication::primaryScreen()->size();
} else {
pos = QPoint(10, 10);
@@ -2181,8 +2210,8 @@ void tst_QWidget::showFullScreen()
QSKIP("QTBUG-52974");
#endif
- if (m_platform == QStringLiteral("wayland"))
- QSKIP("Wayland: This fails. Figure out why.");
+ if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT: This fails. QTBUG-68297");
QWidget plain;
QHBoxLayout *layout;
QWidget layouted;
@@ -2304,6 +2333,8 @@ void tst_QWidget::resizeEvent()
wTopLevel.resize(200, 200);
wTopLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&wTopLevel));
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support resize", Abort);
QCOMPARE (wTopLevel.m_resizeEventCount, 1); // initial resize event before paint for toplevels
wTopLevel.hide();
QSize safeSize(640,480);
@@ -2319,6 +2350,12 @@ void tst_QWidget::resizeEvent()
void tst_QWidget::showMinimized()
{
+ if (m_platform == QStringLiteral("wayland")) {
+ QSKIP("Wayland: Neither xdg_shell, wl_shell or ivi_application support "
+ "letting a client know whether it's minimized. So on these shells "
+ "Qt Wayland will always report that it's unmimized.");
+ }
+
QWidget plain;
plain.move(100, 100);
plain.resize(200, 200);
@@ -2327,6 +2364,9 @@ void tst_QWidget::showMinimized()
plain.showMinimized();
QVERIFY(plain.isMinimized());
QVERIFY(plain.isVisible());
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Winrt does not support move and resize", Abort);
+#endif
QCOMPARE(plain.pos(), pos);
plain.showNormal();
@@ -2478,11 +2518,15 @@ void tst_QWidget::showMinimizedKeepsFocus()
#ifdef Q_OS_OSX
if (!macHasAccessToWindowsServer())
QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
+#elif defined(Q_OS_WINRT)
+ QEXPECT_FAIL("", "Winrt fails here - QTBUG-68297", Continue);
#endif
QTRY_COMPARE(window.focusWidget(), firstchild);
#ifdef Q_OS_OSX
if (!macHasAccessToWindowsServer())
QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
+#elif defined(Q_OS_WINRT)
+ QEXPECT_FAIL("", "Winrt fails here - QTBUG-68297", Continue);
#endif
QTRY_COMPARE(qApp->focusWidget(), firstchild);
}
@@ -2513,6 +2557,9 @@ void tst_QWidget::reparent()
parent.show();
childTLW.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT does not support more than 1 top level widget", Abort);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(&parent));
parent.move(parentPosition);
@@ -2610,6 +2657,8 @@ void tst_QWidget::normalGeometry()
if (m_platform == QStringLiteral("wayland"))
QSKIP("Wayland: This fails. Figure out why.");
+ else if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT: This fails. Figure out why - QTBUG-68297.");
QWidget parent;
parent.setWindowTitle("NormalGeometry parent");
QWidget *child = new QWidget(&parent);
@@ -2719,12 +2768,14 @@ void tst_QWidget::setGeometry()
tlw.setGeometry(tr);
child.setGeometry(cr);
tlw.showNormal();
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support setGeometry", Abort);
QTRY_COMPARE(tlw.geometry().size(), tr.size());
QCOMPARE(child.geometry(), cr);
tlw.setParent(0, Qt::Window|Qt::FramelessWindowHint);
tr = QRect(0,0,100,100);
- tr.moveTopLeft(QApplication::desktop()->availableGeometry().topLeft());
+ tr.moveTopLeft(QGuiApplication::primaryScreen()->availableGeometry().topLeft());
tlw.setGeometry(tr);
QCOMPARE(tlw.geometry(), tr);
tlw.showNormal();
@@ -3198,6 +3249,8 @@ void tst_QWidget::saveRestoreGeometry()
QVERIFY(QTest::qWaitForWindowExposed(&widget));
QApplication::processEvents();
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support move/resize", Abort);
QTRY_COMPARE(widget.pos(), position);
QCOMPARE(widget.size(), size);
savedGeometry = widget.saveGeometry();
@@ -3338,6 +3391,7 @@ void tst_QWidget::restoreVersion1Geometry()
QFETCH(QString, fileName);
QFETCH(uint, expectedWindowState);
QFETCH(QPoint, expectedPosition);
+ Q_UNUSED(expectedPosition);
QFETCH(QSize, expectedSize);
QFETCH(QRect, expectedNormalGeometry);
@@ -3357,28 +3411,28 @@ void tst_QWidget::restoreVersion1Geometry()
QCOMPARE(uint(widget.windowState() & WindowStateMask), expectedWindowState);
if (expectedWindowState == Qt::WindowNoState) {
- QCOMPARE(widget.pos(), expectedPosition);
+ QTRY_COMPARE(widget.geometry(), expectedNormalGeometry);
QCOMPARE(widget.size(), expectedSize);
}
+
widget.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
QTest::qWait(100);
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support restoreGeometry", Abort);
+
if (expectedWindowState == Qt::WindowNoState) {
- QTRY_COMPARE(widget.pos(), expectedPosition);
QTRY_COMPARE(widget.size(), expectedSize);
+ QCOMPARE(widget.geometry(), expectedNormalGeometry);
}
widget.showNormal();
QTest::qWait(10);
- if (expectedWindowState != Qt::WindowNoState) {
- // restoring from maximized or fullscreen, we can only restore to the normal geometry
- QTRY_COMPARE(widget.geometry(), expectedNormalGeometry);
- } else {
- QTRY_COMPARE(widget.pos(), expectedPosition);
- QTRY_COMPARE(widget.size(), expectedSize);
- }
+ QTRY_COMPARE(widget.geometry(), expectedNormalGeometry);
+ if (expectedWindowState == Qt::WindowNoState)
+ QCOMPARE(widget.size(), expectedSize);
#if 0
// Code for saving a new geometry*.dat files
@@ -3413,6 +3467,8 @@ void tst_QWidget::widgetAt()
QSKIP("Wayland: This fails. Figure out why.");
if (m_platform == QStringLiteral("offscreen"))
QSKIP("Platform offscreen does not support lower()/raise() or WindowMasks");
+ if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT does not support more than 1 top level widget");
Q_CHECK_PAINTEVENTS
@@ -3714,6 +3770,8 @@ void tst_QWidget::optimizedResizeMove()
staticWidget.gotPaintEvent = false;
staticWidget.move(staticWidget.pos() + QPoint(10, 10));
QTest::qWait(20);
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support move/resize", Abort);
QCOMPARE(staticWidget.gotPaintEvent, false);
staticWidget.gotPaintEvent = false;
@@ -3798,9 +3856,10 @@ void tst_QWidget::optimizedResize_topLevel()
// a native function call works (it basically has to go through
// WM_RESIZE in QApplication). This is a corner case, though.
// See task 243708
- const QRect frame = topLevel.frameGeometry();
- MoveWindow(winHandleOf(&topLevel), frame.x(), frame.y(),
- frame.width() + 10, frame.height() + 10,
+ RECT rect;
+ GetWindowRect(winHandleOf(&topLevel), &rect);
+ MoveWindow(winHandleOf(&topLevel), rect.left, rect.top,
+ rect.right - rect.left + 10, rect.bottom - rect.top + 10,
true);
QTest::qWait(100);
#endif
@@ -3812,6 +3871,8 @@ void tst_QWidget::optimizedResize_topLevel()
QTRY_VERIFY(topLevel.gotPaintEvent);
if (m_platform == QStringLiteral("xcb") || m_platform == QStringLiteral("offscreen"))
QSKIP("QTBUG-26424");
+ else if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support move/resize", Abort);
QCOMPARE(topLevel.partial, true);
QCOMPARE(topLevel.paintedRegion, expectedUpdateRegion);
}
@@ -3860,7 +3921,7 @@ void tst_QWidget::setMinimumSize()
QSize nonDefaultSize = defaultSize + QSize(5,5);
w.setMinimumSize(nonDefaultSize);
w.showNormal();
- QVERIFY(QTest::qWaitForWindowActive(&w));
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
QVERIFY2(w.height() >= nonDefaultSize.height(),
msgComparisonFailed(w.height(), ">=", nonDefaultSize.height()));
QVERIFY2(w.width() >= nonDefaultSize.width(),
@@ -3915,6 +3976,8 @@ void tst_QWidget::setFixedSize()
QVERIFY(QTest::qWaitForWindowActive(&w));
if (m_platform == QStringLiteral("xcb"))
QSKIP("QTBUG-26424");
+ else if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support move/resize", Abort);
QCOMPARE(w.size(), defaultSize + QSize(150,150));
}
@@ -4115,6 +4178,8 @@ void tst_QWidget::transientParent()
void tst_QWidget::showNativeChild()
{
+ if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT does not support setGeometry");
QWidget topLevel;
topLevel.setGeometry(QRect(m_availableTopLeft + QPoint(100, 100), m_testWidgetSize));
topLevel.setWindowTitle(__FUNCTION__);
@@ -4297,6 +4362,8 @@ void tst_QWidget::update()
// widgets are transparent by default, so both should get repaints
{
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support setGeometry", Abort);
QApplication::processEvents();
QApplication::processEvents();
QCOMPARE(child.numPaintEvents, 1);
@@ -4518,8 +4585,9 @@ void tst_QWidget::scroll()
{
if (m_platform == QStringLiteral("wayland"))
QSKIP("Wayland: This fails. Figure out why.");
- const int w = qMin(500, qApp->desktop()->availableGeometry().width() / 2);
- const int h = qMin(500, qApp->desktop()->availableGeometry().height() / 2);
+ QScreen *screen = QGuiApplication::primaryScreen();
+ const int w = qMin(500, screen->availableGeometry().width() / 2);
+ const int h = qMin(500, screen->availableGeometry().height() / 2);
UpdateWidget updateWidget;
updateWidget.resize(w, h);
@@ -4536,6 +4604,8 @@ void tst_QWidget::scroll()
qApp->processEvents();
QRegion dirty(QRect(0, 0, w, 10));
dirty += QRegion(QRect(0, 10, 10, h - 10));
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT does not support move/resize", Abort);
QTRY_COMPARE(updateWidget.paintedRegion, dirty);
}
@@ -4647,7 +4717,7 @@ void tst_QWidget::setWindowGeometry_data()
QList<QList<QRect> > rects;
const int width = m_testWidgetSize.width();
const int height = m_testWidgetSize.height();
- const QRect availableAdjusted = QApplication::desktop()->availableGeometry().adjusted(100, 100, -100, -100);
+ const QRect availableAdjusted = QGuiApplication::primaryScreen()->availableGeometry().adjusted(100, 100, -100, -100);
rects << (QList<QRect>()
<< QRect(m_availableTopLeft + QPoint(100, 100), m_testWidgetSize)
<< availableAdjusted
@@ -4711,6 +4781,8 @@ void tst_QWidget::setWindowGeometry()
{
if (m_platform == QStringLiteral("xcb"))
QSKIP("X11: Skip this test due to Window manager positioning issues.");
+ else if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT does not support setWindowGeometry");
QFETCH(QList<QRect>, rects);
QFETCH(int, windowFlags);
@@ -4877,6 +4949,8 @@ void tst_QWidget::windowMoveResize()
QSKIP("X11: Skip this test due to Window manager positioning issues.");
if (m_platform == QStringLiteral("wayland"))
QSKIP("Wayland: This fails. Figure out why.");
+ if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT does not support move/resize");
QFETCH(QList<QRect>, rects);
QFETCH(int, windowFlags);
@@ -5197,6 +5271,9 @@ void tst_QWidget::moveChild()
QTRY_COMPARE(parent.r, QRegion(parent.rect()) - child.geometry());
QTRY_COMPARE(child.r, QRegion(child.rect()));
+
+ if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT does not support setGeometry (and we cannot use QEXPECT_FAIL because of VERIFY_COLOR)");
VERIFY_COLOR(child, child.rect(),
child.color);
VERIFY_COLOR(parent, QRegion(parent.rect()) - child.geometry(), parent.color);
@@ -5253,6 +5330,8 @@ void tst_QWidget::showAndMoveChild()
child.move(desktopDimensions.width()/2, desktopDimensions.height()/2);
qApp->processEvents();
+ if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT does not support setGeometry (and we cannot use QEXPECT_FAIL because of VERIFY_COLOR)");
VERIFY_COLOR(child, child.rect(), Qt::blue);
VERIFY_COLOR(parent, QRegion(parent.rect()) - child.geometry(), Qt::red);
}
@@ -5341,6 +5420,8 @@ void tst_QWidget::multipleToplevelFocusCheck()
if (m_platform == QStringLiteral("wayland"))
QSKIP("Wayland: This fails. Figure out why.");
+ else if (m_platform == QStringLiteral("winrt"))
+ QSKIP("Winrt: Sometimes crashes in QTextLayout. - QTBUG-68297");
TopLevelFocusCheck w1;
TopLevelFocusCheck w2;
@@ -5499,6 +5580,8 @@ void tst_QWidget::setFocus()
testWidget->clearFocus();
child1.setFocus();
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT fails here - QTBUG-68297", Abort);
QVERIFY(!child1.hasFocus());
QCOMPARE(window.focusWidget(), &child1);
QCOMPARE(QApplication::focusWidget(), nullptr);
@@ -6185,8 +6268,8 @@ QByteArray EventRecorder::msgEventListMismatch(const EventList &expected, const
void tst_QWidget::childEvents()
{
- if (m_platform == QStringLiteral("wayland"))
- QSKIP("Wayland: This fails. Figure out why.");
+ if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT: This fails. QTBUG-68297.");
EventRecorder::EventList expected;
// Move away the cursor; otherwise it might result in an enter event if it's
@@ -6582,6 +6665,8 @@ void tst_QWidget::renderInvisible()
{
if (m_platform == QStringLiteral("xcb"))
QSKIP("QTBUG-26424");
+ if (m_platform == QStringLiteral("winrt"))
+ QSKIP("WinRT: This fails. QTBUG-68297.");
QScopedPointer<QCalendarWidget> calendar(new QCalendarWidget);
calendar->move(m_availableTopLeft + QPoint(100, 100));
@@ -7430,7 +7515,7 @@ void tst_QWidget::moveWindowInShowEvent_data()
QTest::addColumn<QPoint>("initial");
QTest::addColumn<QPoint>("position");
- QPoint p = QApplication::desktop()->availableGeometry().topLeft();
+ QPoint p = QGuiApplication::primaryScreen()->availableGeometry().topLeft();
QTest::newRow("1") << p << (p + QPoint(10, 10));
QTest::newRow("2") << (p + QPoint(10,10)) << p;
@@ -7455,7 +7540,8 @@ void tst_QWidget::moveWindowInShowEvent()
};
MoveWindowInShowEventWidget widget;
- widget.resize(QSize(qApp->desktop()->availableGeometry().size() / 3).expandedTo(QSize(1, 1)));
+ QScreen *screen = QGuiApplication::primaryScreen();
+ widget.resize(QSize(screen->availableGeometry().size() / 3).expandedTo(QSize(1, 1)));
// move to this position in showEvent()
widget.position = position;
@@ -7524,6 +7610,8 @@ void tst_QWidget::hideOpaqueChildWhileHidden()
child.hide();
child2.hide();
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT: This fails. QTBUG-68297.", Abort);
QTRY_COMPARE(w.r, QRegion(child.geometry()));
child.show();
@@ -7561,6 +7649,8 @@ void tst_QWidget::updateWhileMinimized()
// Make sure update requests are discarded until the widget is shown again.
widget.update(0, 0, 50, 50);
QTest::qWait(10);
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT: This fails. QTBUG-68297.", Abort);
QCOMPARE(widget.numPaintEvents, 0);
// Restore window.
@@ -8088,6 +8178,8 @@ void tst_QWidget::doubleRepaint()
#if defined(Q_OS_QNX)
QEXPECT_FAIL("", "Platform does not support showMinimized()", Continue);
#endif
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT: This fails. QTBUG-68297.", Abort);
QCOMPARE(widget.numPaintEvents, 0);
widget.numPaintEvents = 0;
@@ -8105,7 +8197,7 @@ void tst_QWidget::resizeInPaintEvent()
window.resize(200, 200);
window.show();
qApp->setActiveWindow(&window);
- QVERIFY(QTest::qWaitForWindowActive(&window));
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
QTRY_VERIFY(widget.numPaintEvents > 0);
widget.reset();
@@ -8217,6 +8309,8 @@ void tst_QWidget::setMaskInResizeEvent()
QRegion expectedParentUpdate(0, 0, 100, 10); // Old testWidget area.
expectedParentUpdate += testWidget.geometry(); // New testWidget area.
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT: This fails. QTBUG-68297.", Abort);
QTRY_COMPARE(w.paintedRegion, expectedParentUpdate);
QTRY_COMPARE(testWidget.paintedRegion, testWidget.mask());
@@ -8645,7 +8739,7 @@ void tst_QWidget::translucentWidget()
ColorRedWidget label;
label.setFixedSize(16,16);
label.setAttribute(Qt::WA_TranslucentBackground);
- const QPoint labelPos = qApp->desktop()->availableGeometry().topLeft();
+ const QPoint labelPos = QGuiApplication::primaryScreen()->availableGeometry().topLeft();
label.move(labelPos);
label.show();
QVERIFY(QTest::qWaitForWindowExposed(&label));
@@ -8661,6 +8755,8 @@ void tst_QWidget::translucentWidget()
widgetSnapshot = label.grab(QRect(QPoint(0, 0), label.size()));
const QImage actual = widgetSnapshot.toImage().convertToFormat(QImage::Format_RGB32);
const QImage expected = pm.toImage().scaled(label.devicePixelRatioF() * pm.size());
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT: This fails. QTBUG-68297.", Abort);
QCOMPARE(actual.size(),expected.size());
QCOMPARE(actual,expected);
}
@@ -8704,7 +8800,7 @@ void tst_QWidget::setClearAndResizeMask()
centerOnScreen(&topLevel);
topLevel.show();
qApp->setActiveWindow(&topLevel);
- QVERIFY(QTest::qWaitForWindowActive(&topLevel));
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
QTRY_VERIFY(topLevel.numPaintEvents > 0);
topLevel.reset();
@@ -9104,7 +9200,7 @@ void tst_QWidget::syntheticEnterLeave()
void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
{
if (m_platform == QStringLiteral("wayland"))
- QSKIP("Wayland: This fails. Figure out why.");
+ QSKIP("Wayland: Clients can't set cursor position on wayland.");
class SELParent : public QWidget
{
public:
@@ -9122,7 +9218,8 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
void mouseMoveEvent(QMouseEvent *event)
{
QCOMPARE(event->button(), Qt::NoButton);
- QCOMPARE(event->buttons(), Qt::MouseButtons(Qt::NoButton));
+ QCOMPARE(event->buttons(), QApplication::mouseButtons());
+ QCOMPARE(event->modifiers(), QApplication::keyboardModifiers());
++numMouseMoveEvents;
}
void reset() { numEnterEvents = numMouseMoveEvents = 0; }
@@ -9156,11 +9253,11 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
child.setMouseTracking(true);
child.show();
- // Make sure the child gets enter event and mouse move event.
+ // Make sure the child gets enter event.
// Note that we verify event->button() and event->buttons()
// in SELChild::mouseMoveEvent().
QTRY_COMPARE(child.numEnterEvents, 1);
- QCOMPARE(child.numMouseMoveEvents, 1);
+ QCOMPARE(child.numMouseMoveEvents, 0);
// Sending synthetic enter/leave trough the parent's mousePressEvent handler.
parent.child = &child;
@@ -9169,12 +9266,21 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
child.reset();
QTest::mouseClick(&parent, Qt::LeftButton);
- // Make sure the child gets enter event and one mouse move event.
+ // Make sure the child gets enter event.
QTRY_COMPARE(child.numEnterEvents, 1);
- QCOMPARE(child.numMouseMoveEvents, 1);
+ QCOMPARE(child.numMouseMoveEvents, 0);
child.hide();
child.reset();
+ QTest::keyPress(&parent, Qt::Key_Shift);
+ QTest::mouseClick(&parent, Qt::LeftButton);
+
+ // Make sure the child gets enter event
+ QTRY_COMPARE(child.numEnterEvents, 1);
+ QCOMPARE(child.numMouseMoveEvents, 0);
+ QTest::keyRelease(&child, Qt::Key_Shift);
+ child.hide();
+ child.reset();
child.setMouseTracking(false);
QTest::mouseClick(&parent, Qt::LeftButton);
@@ -9351,6 +9457,8 @@ void tst_QWidget::rectOutsideCoordinatesLimit_task144779()
correct.fill(Qt::green);
const QPixmap mainPixmap = grabFromWidget(&main, QRect(QPoint(0, 0), QSize(-1, -1)));
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT: This fails. QTBUG-68297.", Abort);
QTRY_COMPARE(mainPixmap.toImage().convertToFormat(QImage::Format_RGB32),
correct.toImage().convertToFormat(QImage::Format_RGB32));
#ifndef QT_NO_CURSOR
@@ -9442,6 +9550,8 @@ void tst_QWidget::activateWindow()
qApp->processEvents();
QTRY_VERIFY(mainwindow->isActiveWindow());
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT: This fails. QTBUG-68297.", Abort);
QTRY_VERIFY(!mainwindow2->isActiveWindow());
}
@@ -9960,9 +10070,6 @@ public:
void tst_QWidget::touchEventSynthesizedMouseEvent()
{
- if (m_platform == QStringLiteral("wayland"))
- QSKIP("Wayland: This fails. Figure out why.");
-
{
// Simple case, we ignore the touch events, we get mouse events instead
TouchMouseWidget widget;
@@ -10544,7 +10651,7 @@ void tst_QWidget::keyboardModifiers()
KeyboardWidget w;
w.resize(300, 300);
w.show();
- QVERIFY(QTest::qWaitForWindowActive(&w));
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
QTest::mouseClick(&w, Qt::LeftButton, Qt::ControlModifier);
QCOMPARE(w.m_eventCounter, 1);
QCOMPARE(int(w.m_modifiers), int(Qt::ControlModifier));
@@ -10605,6 +10712,8 @@ void tst_QWidget::resizeStaticContentsChildWidget_QTBUG35282()
widget.showNormal();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
+ if (m_platform == QStringLiteral("winrt"))
+ QEXPECT_FAIL("", "WinRT: This fails. QTBUG-68297.", Abort);
QCOMPARE(childWidget.numPaintEvents, 0);
childWidget.reset();
diff --git a/tests/auto/widgets/kernel/qwidget_window/BLACKLIST b/tests/auto/widgets/kernel/qwidget_window/BLACKLIST
index d3bfaba433..c980325d9a 100644
--- a/tests/auto/widgets/kernel/qwidget_window/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget_window/BLACKLIST
@@ -2,3 +2,6 @@
# QTBUG-66345
opensuse-42.3
ubuntu-16.04
+ubuntu-18.04
+[setWindowState]
+ubuntu-18.04
diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
index b143555b0d..f4da4c3e5f 100644
--- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
+++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
@@ -44,6 +44,8 @@
#include <qmainwindow.h>
#include <qtoolbar.h>
#include <private/qwindow_p.h>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
#include <QtTest/private/qtesthelpers_p.h>
@@ -79,10 +81,12 @@ private slots:
void tst_showWithoutActivating();
void tst_paintEventOnSecondShow();
+ void tst_exposeObscuredMapped_QTBUG39220();
void tst_paintEventOnResize_QTBUG50796();
#if QT_CONFIG(draganddrop)
void tst_dnd();
+ void tst_dnd_events();
#endif
void tst_qtbug35600();
@@ -156,6 +160,9 @@ void tst_QWidget_window::tst_move_show()
QWidget w;
w.move(100, 100);
w.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Winrt does not support move", Abort);
+#endif
QCOMPARE(w.pos(), QPoint(100, 100));
// QCoreApplication::processEvents(QEventLoop::AllEvents, 3000);
}
@@ -185,6 +192,9 @@ void tst_QWidget_window::tst_resize_show()
QWidget w;
w.resize(200, 200);
w.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Winrt does not support resize", Abort);
+#endif
QCOMPARE(w.size(), QSize(200, 200));
// QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
}
@@ -370,6 +380,33 @@ void tst_QWidget_window::tst_paintEventOnSecondShow()
QTRY_VERIFY(w.paintEventCount > 0);
}
+void tst_QWidget_window::tst_exposeObscuredMapped_QTBUG39220()
+{
+ const auto integration = QGuiApplicationPrivate::platformIntegration();
+ if (!integration->hasCapability(QPlatformIntegration::MultipleWindows)
+ || !integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)
+ || QGuiApplication::platformName() == QLatin1String("winrt")) {
+ QSKIP("The platform does not have the required capabilities");
+ }
+ // QTBUG-39220: Fully obscured parent widgets may not receive expose
+ // events (as is the case for frameless, obscured parents on Windows).
+ // Ensure Qt::WA_Mapped is set so updating works.
+ const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
+ const QSize size = availableGeometry.size() / 6;
+ QWidget topLevel;
+ setFrameless(&topLevel);
+ topLevel.resize(size);
+ const QPoint sizeP(size.width(), size.height());
+ topLevel.move(availableGeometry.center() - sizeP / 2);
+ QWidget *child = new QWidget(&topLevel);
+ child->resize(size);
+ child->move(0, 0);
+ QVERIFY(child->winId());
+ topLevel.show();
+ QTRY_VERIFY(child->testAttribute(Qt::WA_Mapped));
+ QVERIFY(topLevel.testAttribute(Qt::WA_Mapped));
+}
+
void tst_QWidget_window::tst_paintEventOnResize_QTBUG50796()
{
const QRect availableGeo = QGuiApplication::primaryScreen()->availableGeometry();
@@ -416,6 +453,7 @@ static const char *expectedLogC[] = {
"Event at 11,81 ignored",
"Event at 11,101 ignored",
"acceptingDropsWidget1::dragEnterEvent at 1,11 action=1 MIME_DATA_ADDRESS 'testmimetext'",
+ "acceptingDropsWidget1::dragMoveEvent at 1,11 action=1 MIME_DATA_ADDRESS 'testmimetext'",
"Event at 11,121 accepted",
"acceptingDropsWidget1::dragMoveEvent at 1,31 action=1 MIME_DATA_ADDRESS 'testmimetext'",
"Event at 11,141 accepted",
@@ -426,6 +464,7 @@ static const char *expectedLogC[] = {
"acceptingDropsWidget1::dragLeaveEvent QDragLeaveEvent",
"Event at 11,201 ignored",
"acceptingDropsWidget2::dragEnterEvent at 1,11 action=1 MIME_DATA_ADDRESS 'testmimetext'",
+ "acceptingDropsWidget2::dragMoveEvent at 1,11 action=1 MIME_DATA_ADDRESS 'testmimetext'",
"Event at 11,221 accepted",
"acceptingDropsWidget2::dragMoveEvent at 1,31 action=1 MIME_DATA_ADDRESS 'testmimetext'",
"Event at 11,241 accepted",
@@ -591,6 +630,92 @@ void tst_QWidget_window::tst_dnd()
QCOMPARE(log, expectedLog);
}
+
+class DnDEventRecorder : public QWidget
+{
+ Q_OBJECT
+public:
+ QString _dndEvents;
+ DnDEventRecorder() { setAcceptDrops(true); }
+
+protected:
+ void mousePressEvent(QMouseEvent *)
+ {
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setData("application/x-dnditemdata", "some data");
+ QDrag *drag = new QDrag(this);
+ drag->setMimeData(mimeData);
+ drag->exec();
+ }
+
+ void dragEnterEvent(QDragEnterEvent *e)
+ {
+ e->accept();
+ _dndEvents.append(QStringLiteral("DragEnter "));
+ }
+ void dragMoveEvent(QDragMoveEvent *e)
+ {
+ e->accept();
+ _dndEvents.append(QStringLiteral("DragMove "));
+ emit releaseMouseButton();
+ }
+ void dragLeaveEvent(QDragLeaveEvent *e)
+ {
+ e->accept();
+ _dndEvents.append(QStringLiteral("DragLeave "));
+ }
+ void dropEvent(QDropEvent *e)
+ {
+ e->accept();
+ _dndEvents.append(QStringLiteral("DropEvent "));
+ }
+
+signals:
+ void releaseMouseButton();
+};
+
+void tst_QWidget_window::tst_dnd_events()
+{
+ // Note: This test is somewhat a hack as testing DnD with qtestlib is not
+ // supported at the moment. The test verifies that we get an expected event
+ // sequence on dnd operation that does not move a mouse. This logic is implemented
+ // in QGuiApplication, so we have to go via QWindowSystemInterface API (QTest::mouse*).
+ const auto platformName = QGuiApplication::platformName().toLower();
+ // The test is known to work with XCB and platforms that use the default dnd
+ // implementation QSimpleDrag (e.g. qnx). Running on XCB should be sufficient to
+ // catch regressions at cross platform code: QGuiApplication::processDrag/Leave().
+ if (platformName != "xcb")
+ return;
+
+ const QString expectedDndEvents = "DragEnter DragMove DropEvent DragEnter DragMove "
+ "DropEvent DragEnter DragMove DropEvent ";
+ DnDEventRecorder dndWidget;
+ dndWidget.setGeometry(100, 100, 200, 200);
+ dndWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&dndWidget));
+ QVERIFY(QTest::qWaitForWindowActive(&dndWidget));
+
+ // ### FIXME - QTBUG-35117 ???
+ auto targetCenter = QPoint(dndWidget.width(), dndWidget.height()) / 2;
+ auto targetCenterGlobal = dndWidget.mapToGlobal(targetCenter);
+ QCursor::setPos(targetCenterGlobal);
+ QVERIFY(QTest::qWaitFor([&]() { return QCursor::pos() == targetCenterGlobal; }));
+ QCoreApplication::processEvents(); // clear mouse events generated from cursor
+
+ auto window = dndWidget.window()->windowHandle();
+
+ // Some dnd implementation rely on running internal event loops, so we have to use
+ // the following queued signal hack to simulate mouse clicks in the widget.
+ QObject::connect(&dndWidget, &DnDEventRecorder::releaseMouseButton, this, [=]() {
+ QTest::mouseRelease(window, Qt::LeftButton);
+ }, Qt::QueuedConnection);
+
+ QTest::mousePress(window, Qt::LeftButton);
+ QTest::mousePress(window, Qt::LeftButton);
+ QTest::mousePress(window, Qt::LeftButton);
+
+ QCOMPARE(dndWidget._dndEvents, expectedDndEvents);
+}
#endif
void tst_QWidget_window::tst_qtbug35600()
@@ -704,6 +829,9 @@ void tst_QWidget_window::tst_resize_count()
ResizeWidget resize;
resize.show();
QVERIFY(QTest::qWaitForWindowExposed(&resize));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Winrt does not support resize", Abort);
+#endif
QCOMPARE(resize.resizeCount, 1);
resize.resizeCount = 0;
QSize size = resize.size();
@@ -901,6 +1029,11 @@ void tst_QWidget_window::setWindowState()
w.setWindowState(state);
QCOMPARE(w.windowState(), state);
w.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("0", "Winrt windows are maximized by default", Abort);
+ QEXPECT_FAIL("Qt::WindowMinimized", "Winrt windows are maximized by default", Abort);
+ QEXPECT_FAIL("Qt::WindowFullScreen", "Winrt windows are maximized by default", Abort);
+#endif
QCOMPARE(w.windowState(), state);
QCOMPARE(w.windowHandle()->windowStates(), state);
if (!(state & Qt::WindowMinimized))
diff --git a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
index c9c8e193b3..693a792f0a 100644
--- a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
+++ b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
@@ -104,6 +104,9 @@ void tst_QWindowContainer::testShow()
root.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(window));
}
@@ -140,6 +143,9 @@ void tst_QWindowContainer::testExposeObscure()
container->show();
QVERIFY(QTest::qWaitForWindowExposed(container.data()));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(window));
QVERIFY(window->numberOfExposes > 0);
@@ -255,6 +261,9 @@ void tst_QWindowContainer::testUnparentReparent()
QTRY_VERIFY(!window->isVisible());
container->show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(window));
QTRY_VERIFY(window->isVisible());
@@ -359,6 +368,9 @@ void tst_QWindowContainer::testNativeContainerParent()
root.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(window));
QTRY_COMPARE(window->parent(), container->windowHandle());
}
diff --git a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
index e49fd701d6..587e8a080d 100644
--- a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
+++ b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
@@ -82,7 +82,7 @@ private slots:
void testFusionStyle();
#endif
void testWindowsStyle();
-#if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA)
+#if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA) && !defined(Q_OS_WINRT)
void testWindowsVistaStyle();
#endif
#ifdef Q_OS_MAC
@@ -198,6 +198,9 @@ void tst_QStyle::drawItemPixmap()
QVERIFY(image.reinterpretAsFormat(QImage::Format_RGB32));
const QRgb *bits = reinterpret_cast<const QRgb *>(image.constBits());
const QRgb *end = bits + image.byteCount() / sizeof(QRgb);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "QWidget::resize does not work on WinRT", Continue);
+#endif
QVERIFY(std::all_of(bits, end, [green] (QRgb r) { return r == green; }));
testWidget->hide();
}
@@ -344,7 +347,7 @@ QImage readImage(const QString &fileName)
}
-#if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA)
+#if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA) && !defined(Q_OS_WINRT)
void tst_QStyle::testWindowsVistaStyle()
{
QStyle *vistastyle = QStyleFactory::create("WindowsVista");
@@ -716,6 +719,9 @@ void tst_QStyle::testFrameOnlyAroundContents()
area.verticalScrollBar()->setStyle(&frameStyle);
area.setStyle(&frameStyle);
// Test that we reserve space for scrollbar spacing
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "QWidget::setGeometry does not work on WinRT", Continue);
+#endif
QVERIFY(viewPortWidth == area.viewport()->width() + SCROLLBAR_SPACING);
delete winStyle;
}
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
index 6d47d5cfb6..43aec651fe 100644
--- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
+++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
@@ -98,7 +98,9 @@ private slots:
void widgetStyle();
void appStyle();
void QTBUG11658_cachecrash();
+ void styleSheetTargetAttribute();
void unpolish();
+
private:
QColor COLOR(const QWidget& w) {
w.ensurePolished();
@@ -2000,6 +2002,59 @@ void tst_QStyleSheetStyle::widgetStylePropagation()
QCOMPARE(COLOR(childLabel), childExpectedColor);
}
+void tst_QStyleSheetStyle::styleSheetTargetAttribute()
+{
+ QGroupBox gb;
+ QLabel lb(&gb);
+ QPushButton pb(&lb);
+
+ gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
+ QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
+
+ qApp->setStyleSheet("QPushButton { background-color: blue; }");
+
+ gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
+ QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), true);
+
+ qApp->setStyleSheet("QGroupBox { background-color: blue; }");
+
+ gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
+ QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), true);
+ QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
+
+ qApp->setStyleSheet("QGroupBox * { background-color: blue; }");
+
+ gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
+ QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), true);
+ QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), true);
+
+ qApp->setStyleSheet("* { background-color: blue; }");
+ gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
+ QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), true);
+ QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), true);
+ QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), true);
+
+ qApp->setStyleSheet("QLabel { font-size: 32pt; }");
+
+ gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
+ QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), true);
+ QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
+
+ qApp->setStyleSheet("");
+
+ gb.ensurePolished(); lb.ensurePolished(); pb.ensurePolished();
+ QCOMPARE(gb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(lb.testAttribute(Qt::WA_StyleSheetTarget), false);
+ QCOMPARE(pb.testAttribute(Qt::WA_StyleSheetTarget), false);
+}
+
void tst_QStyleSheetStyle::unpolish()
{
QWidget w;
diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
index 0511c278d5..ad64f1aef7 100644
--- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
+++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
@@ -621,6 +621,9 @@ void tst_QCompleter::directoryModel_data()
void tst_QCompleter::directoryModel()
{
+#ifdef Q_OS_WINRT
+ QSKIP("WinRT cannot access directories outside of the application's sandbox");
+#endif
filter();
}
@@ -667,6 +670,9 @@ void tst_QCompleter::fileSystemModel_data()
void tst_QCompleter::fileSystemModel()
{
+#ifdef Q_OS_WINRT
+ QSKIP("WinRT cannot access directories outside of the application's sandbox");
+#endif
//QFileSystemModel is assync.
filter(true);
}
@@ -1696,6 +1702,9 @@ void tst_QCompleter::QTBUG_14292_filesystem()
// Wait for all file system model slots/timers to trigger
// until the model sees the subdirectories.
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_VERIFY(testFileSystemReady(model));
// But this should not cause the combo to pop up.
QVERIFY(!comp.popup()->isVisible());
diff --git a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp
index 372a467ada..007825d39c 100644
--- a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp
+++ b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp
@@ -334,6 +334,10 @@ void tst_QAbstractScrollArea::task214488_layoutDirection()
int refValue = hbar->value();
qApp->sendEvent(&scrollArea, new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT: Scrollbar is not guaranteed to be visible, as QWidget::resize does not"
+ "work", Abort);
+#endif
QVERIFY(lessThan ? (hbar->value() < refValue) : (hbar->value() > refValue));
}
diff --git a/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp b/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp
index 5c0f4b1536..312ec0b1ec 100644
--- a/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp
+++ b/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp
@@ -153,6 +153,9 @@ void tst_QCalendarWidget::getSetCheck()
void tst_QCalendarWidget::buttonClickCheck()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Fails on WinRT - QTBUG-68297");
+#endif
QCalendarWidget object;
QSize size = object.sizeHint();
object.setGeometry(0,0,size.width(), size.height());
@@ -283,6 +286,10 @@ void tst_QCalendarWidget::showPrevNext()
QFETCH(QDate, dateOrigin);
QFETCH(QDate, expectedDate);
+#ifdef Q_OS_WINRT
+ QSKIP("Fails on WinRT - QTBUG-68297");
+#endif
+
QCalendarWidget calWidget;
calWidget.show();
QVERIFY(QTest::qWaitForWindowExposed(&calWidget));
diff --git a/tests/auto/widgets/widgets/qcombobox/qcombobox.pro b/tests/auto/widgets/widgets/qcombobox/qcombobox.pro
index 939153dc88..ba25a85634 100644
--- a/tests/auto/widgets/widgets/qcombobox/qcombobox.pro
+++ b/tests/auto/widgets/widgets/qcombobox/qcombobox.pro
@@ -1,4 +1,7 @@
CONFIG += testcase
TARGET = tst_qcombobox
QT += widgets widgets-private gui-private core-private testlib testlib-private
+DEFINES += QTEST_QPA_MOUSE_HANDLING
SOURCES += tst_qcombobox.cpp
+
+TESTDATA += qtlogo.png qtlogoinverted.png
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index 7c1deb8fff..943fb997cd 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -1672,6 +1672,9 @@ void tst_QComboBox::setCustomModelAndView()
const QRect subItemRect = view->visualRect(model->indexFromItem(subItem));
QWidget *window = view->window();
QTest::mouseClick(window->windowHandle(), Qt::LeftButton, 0, view->mapTo(window, subItemRect.center()));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(combo.currentText(), subItem21Text);
}
@@ -2188,8 +2191,8 @@ void tst_QComboBox::itemListPosition()
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
useFullScreenForPopupMenu = theme->themeHint(QPlatformTheme::UseFullScreenForPopupMenu).toBool();
const QRect screen = useFullScreenForPopupMenu ?
- QApplication::desktop()->screenGeometry(scrNumber) :
- QApplication::desktop()->availableGeometry(scrNumber);
+ QApplication::screens().at(scrNumber)->geometry() :
+ QApplication::screens().at(scrNumber)->availableGeometry();
topLevel.move(screen.width() - topLevel.sizeHint().width() - 10, 0); //puts the combo to the top-right corner
@@ -2311,7 +2314,7 @@ void tst_QComboBox::task191329_size()
setFrameless(&tableCombo);
tableCombo.move(200, 200);
int rows;
- if (QApplication::desktop()->screenGeometry().height() < 480)
+ if (QApplication::primaryScreen()->geometry().height() < 480)
rows = 8;
else
rows = 15;
@@ -2376,6 +2379,9 @@ void tst_QComboBox::task190205_setModelAdjustToContents()
correctBox.addItems(finalContent);
correctBox.showNormal();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT does not support more than 1 native top level widget", Abort);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(&box));
QVERIFY(QTest::qWaitForWindowExposed(&correctBox));
@@ -2390,8 +2396,7 @@ void tst_QComboBox::task248169_popupWithMinimalSize()
QComboBox comboBox;
comboBox.addItems(initialContent);
- QDesktopWidget desktop;
- QRect desktopSize = desktop.availableGeometry();
+ QRect desktopSize = QGuiApplication::primaryScreen()->availableGeometry();
comboBox.view()->setMinimumWidth(desktopSize.width() / 2);
comboBox.setGeometry(desktopSize.width() - (desktopSize.width() / 4), (desktopSize.width() / 4), (desktopSize.width() / 2), (desktopSize.width() / 4));
@@ -2407,6 +2412,7 @@ void tst_QComboBox::task248169_popupWithMinimalSize()
#if defined QT_BUILD_INTERNAL
QFrame *container = comboBox.findChild<QComboBoxPrivateContainer *>();
QVERIFY(container);
+ QDesktopWidget desktop;
QTRY_VERIFY(desktop.screenGeometry(container).contains(container->geometry()));
#endif
}
@@ -2719,32 +2725,18 @@ void tst_QComboBox::resetModel()
}
-static inline void centerCursor(const QWidget *w)
-{
-#ifndef QT_NO_CURSOR
- // Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA:
- const QPoint target(w->mapToGlobal(w->rect().center()));
- QCursor::setPos(QPoint(target.x() + 1, target.y()));
- QCursor::setPos(target);
-#else // !QT_NO_CURSOR
- Q_UNUSED(w)
-#endif
-}
-
void tst_QComboBox::keyBoardNavigationWithMouse()
{
QComboBox combo;
combo.setEditable(false);
setFrameless(&combo);
- combo.move(200, 200);
- for (int i = 0; i < 80; i++)
- combo.addItem( QString::number(i));
+ for (int i = 0; i < 200; i++)
+ combo.addItem(QString::number(i));
+ combo.move(200, 200);
combo.showNormal();
- centerCursor(&combo); // QTBUG-33973, cursor needs to be within view from start on Mac.
QApplication::setActiveWindow(&combo);
QVERIFY(QTest::qWaitForWindowActive(&combo));
- QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&combo));
QCOMPARE(combo.currentText(), QLatin1String("0"));
@@ -2752,18 +2744,12 @@ void tst_QComboBox::keyBoardNavigationWithMouse()
QTRY_VERIFY(combo.hasFocus());
QTest::keyClick(combo.lineEdit(), Qt::Key_Space);
- QTest::qWait(30);
QTRY_VERIFY(combo.view());
QTRY_VERIFY(combo.view()->isVisible());
- QTest::qWait(130);
QCOMPARE(combo.currentText(), QLatin1String("0"));
- // When calling cursor function, Windows CE responds with: This function is not supported on this system.
-#if !defined Q_OS_QNX
- // Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA:
- centerCursor(combo.view());
- QTest::qWait(200);
+ QTest::mouseMove(&combo, combo.rect().center());
#define GET_SELECTION(SEL) \
QCOMPARE(combo.view()->selectionModel()->selection().count(), 1); \
@@ -2771,23 +2757,19 @@ void tst_QComboBox::keyBoardNavigationWithMouse()
SEL = combo.view()->selectionModel()->selection().indexes().first().row()
int selection;
- GET_SELECTION(selection);
+ GET_SELECTION(selection); // get initial selection
- //since we moved the mouse is in the middle it should even be around 5;
- QVERIFY2(selection > 3, (QByteArrayLiteral("selection=") + QByteArray::number(selection)).constData());
-
- static const int final = 40;
+ const int final = 40;
for (int i = selection + 1; i <= final; i++)
{
QTest::keyClick(combo.view(), Qt::Key_Down);
- QTest::qWait(20);
GET_SELECTION(selection);
QCOMPARE(selection, i);
}
QTest::keyClick(combo.view(), Qt::Key_Enter);
QTRY_COMPARE(combo.currentText(), QString::number(final));
-#endif
+#undef GET_SELECTION
}
void tst_QComboBox::task_QTBUG_1071_changingFocusEmitsActivated()
@@ -3334,6 +3316,9 @@ void tst_QComboBox::task_QTBUG_56693_itemFontFromModel()
QVERIFY(container);
QVERIFY(QTest::qWaitForWindowExposed(container));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(proxyStyle->italicItemsNo, 5);
box.hidePopup();
diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
index fa28ec2575..e2f1307eb1 100644
--- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
+++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
@@ -70,6 +70,7 @@
#include <QSignalSpy>
#include <QTestEventList>
#include <QDateEdit>
+#include <QProxyStyle>
#include <private/qdatetimeedit_p.h>
@@ -93,6 +94,46 @@ public:
friend class tst_QDateTimeEdit;
};
+class PressAndHoldStyle : public QProxyStyle
+{
+ Q_OBJECT
+public:
+ using QProxyStyle::QProxyStyle;
+
+ int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
+ {
+ switch (hint) {
+ case QStyle::SH_SpinBox_ClickAutoRepeatRate:
+ return 5;
+ case QStyle::SH_SpinBox_ClickAutoRepeatThreshold:
+ return 10;
+ default:
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+ }
+};
+
+class StepModifierStyle : public QProxyStyle
+{
+ Q_OBJECT
+public:
+ using QProxyStyle::QProxyStyle;
+
+ int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
+ {
+ switch (hint) {
+ case QStyle::SH_SpinBox_StepModifier:
+ return stepModifier;
+ default:
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+ }
+
+ Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
+};
+
class tst_QDateTimeEdit : public QObject
{
Q_OBJECT
@@ -205,9 +246,8 @@ private slots:
void reverseTest();
void ddMMMMyyyy();
-#if QT_CONFIG(wheelevent)
+ void wheelEvent_data();
void wheelEvent();
-#endif
void specialValueCornerCase();
void cursorPositionOnInit();
@@ -245,14 +285,105 @@ private slots:
void dateEditCorrectSectionSize_data();
void dateEditCorrectSectionSize();
#endif
+
+ void stepModifierKeys_data();
+ void stepModifierKeys();
+
+ void stepModifierButtons_data();
+ void stepModifierButtons();
+
+ void stepModifierPressAndHold_data();
+ void stepModifierPressAndHold();
private:
EditorDateEdit* testWidget;
QWidget *testFocusWidget;
};
+typedef QList<QDate> DateList;
typedef QList<QTime> TimeList;
typedef QList<Qt::Key> KeyList;
+static QLatin1String modifierToName(Qt::KeyboardModifier modifier)
+{
+ switch (modifier) {
+ case Qt::NoModifier:
+ return QLatin1Literal("No");
+ break;
+ case Qt::ControlModifier:
+ return QLatin1Literal("Ctrl");
+ break;
+ case Qt::ShiftModifier:
+ return QLatin1Literal("Shift");
+ break;
+ case Qt::AltModifier:
+ return QLatin1Literal("Alt");
+ break;
+ case Qt::MetaModifier:
+ return QLatin1Literal("Meta");
+ break;
+ default:
+ qFatal("Unexpected keyboard modifier");
+ return QLatin1String();
+ }
+}
+
+static QLatin1String sectionToName(const QDateTimeEdit::Section section)
+{
+ switch (section) {
+ case QDateTimeEdit::SecondSection:
+ return QLatin1Literal("Second");
+ case QDateTimeEdit::MinuteSection:
+ return QLatin1Literal("Minute");
+ case QDateTimeEdit::HourSection:
+ return QLatin1Literal("Hours");
+ case QDateTimeEdit::DaySection:
+ return QLatin1Literal("Day");
+ case QDateTimeEdit::MonthSection:
+ return QLatin1Literal("Month");
+ case QDateTimeEdit::YearSection:
+ return QLatin1Literal("Year");
+ default:
+ qFatal("Unexpected section");
+ return QLatin1String();
+ }
+}
+
+static QDate stepDate(const QDate& startDate, const QDateTimeEdit::Section section,
+ const int steps)
+{
+ switch (section) {
+ case QDateTimeEdit::DaySection:
+ return startDate.addDays(steps);
+ case QDateTimeEdit::MonthSection:
+ return startDate.addMonths(steps);
+ case QDateTimeEdit::YearSection:
+ return startDate.addYears(steps);
+ default:
+ qFatal("Unexpected section");
+ return QDate();
+ }
+}
+
+static QTime stepTime(const QTime& startTime, const QDateTimeEdit::Section section,
+ const int steps)
+{
+ switch (section) {
+ case QDateTimeEdit::SecondSection:
+ return startTime.addSecs(steps);
+ case QDateTimeEdit::MinuteSection:
+ return QTime(startTime.hour(),
+ startTime.minute() + steps,
+ startTime.second());
+ case QDateTimeEdit::HourSection:
+ return QTime(startTime.hour() + steps,
+ startTime.minute(),
+ startTime.second());
+ default:
+ qFatal("Unexpected section");
+ return QTime();
+ }
+}
+
// Testing get/set functions
void tst_QDateTimeEdit::getSetCheck()
{
@@ -326,6 +457,8 @@ void tst_QDateTimeEdit::cleanup()
testWidget->setTimeSpec(Qt::LocalTime);
testWidget->setSpecialValueText(QString());
testWidget->setWrapping(false);
+ // Restore the default.
+ testWidget->setCalendarPopup(false);
}
void tst_QDateTimeEdit::constructor_qwidget()
@@ -3000,20 +3133,176 @@ void tst_QDateTimeEdit::ddMMMMyyyy()
QCOMPARE(testWidget->lineEdit()->text(), "01." + QDate::longMonthName(1) + ".200");
}
+void tst_QDateTimeEdit::wheelEvent_data()
+{
#if QT_CONFIG(wheelevent)
+ QTest::addColumn<QPoint>("angleDelta");
+ QTest::addColumn<int>("qt4Delta");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
+ QTest::addColumn<Qt::MouseEventSource>("source");
+ QTest::addColumn<QDateTimeEdit::Section>("section");
+ QTest::addColumn<QDate>("startDate");
+ QTest::addColumn<DateList>("expectedDates");
+
+ const auto fractions = {false, true};
+
+ const auto directions = {true, false};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ const auto sources = {Qt::MouseEventNotSynthesized,
+ Qt::MouseEventSynthesizedBySystem,
+ Qt::MouseEventSynthesizedByQt,
+ Qt::MouseEventSynthesizedByApplication};
+
+ const auto sections = {QDateTimeEdit::DaySection,
+ QDateTimeEdit::MonthSection,
+ QDateTimeEdit::YearSection};
+
+ for (auto fraction : fractions) {
+ for (auto up : directions) {
+
+ const QDate startDate(2000, up ? 2 : 12, 17);
+
+ const int units = (fraction ? 60 : 120) * (up ? 1 : -1);
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ for (auto source : sources) {
+
+#ifdef Q_OS_MACOS
+ QPoint angleDelta;
+ if ((modifier & Qt::ShiftModifier) &&
+ source == Qt::MouseEventNotSynthesized) {
+ // On macOS the Shift modifier converts vertical
+ // mouse wheel events to horizontal.
+ angleDelta = { units, 0 };
+ } else {
+ // However, this is not the case for trackpad scroll
+ // events.
+ angleDelta = { 0, units };
+ }
+#else
+ const QPoint angleDelta(0, units);
+#endif
+
+ QLatin1String sourceName;
+ switch (source) {
+ case Qt::MouseEventNotSynthesized:
+ sourceName = QLatin1Literal("NotSynthesized");
+ break;
+ case Qt::MouseEventSynthesizedBySystem:
+ sourceName = QLatin1Literal("SynthesizedBySystem");
+ break;
+ case Qt::MouseEventSynthesizedByQt:
+ sourceName = QLatin1Literal("SynthesizedByQt");
+ break;
+ case Qt::MouseEventSynthesizedByApplication:
+ sourceName = QLatin1Literal("SynthesizedByApplication");
+ break;
+ default:
+ qFatal("Unexpected wheel event source");
+ continue;
+ }
+
+ for (const auto section : sections) {
+
+ DateList expectedDates;
+ if (fraction)
+ expectedDates << startDate;
+
+ const auto expectedDate = stepDate(startDate, section, steps);
+ if (!expectedDate.isValid())
+ continue;
+
+ expectedDates << expectedDate;
+
+ const QLatin1String sectionName = sectionToName(section);
+
+ QTest::addRow("%s%s%s%sWith%sKeyboardModifier%s",
+ fraction ? "half" : "full",
+ up ? "Up" : "Down",
+ stepModifierName.latin1(),
+ sectionName.latin1(),
+ modifierName.latin1(),
+ sourceName.latin1())
+ << angleDelta
+ << units
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << source
+ << section
+ << startDate
+ << expectedDates;
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+ QSKIP("Built with --no-feature-wheelevent");
+#endif
+}
+
void tst_QDateTimeEdit::wheelEvent()
{
- testWidget->setDisplayFormat("dddd/MM");
- testWidget->setDate(QDate(2000, 2, 21));
- testWidget->setCurrentSection(QDateTimeEdit::DaySection);
- QWheelEvent w(testWidget->lineEdit()->geometry().center(), 120, 0, 0);
- qApp->sendEvent(testWidget, &w);
- QCOMPARE(testWidget->date(), QDate(2000, 2, 22));
- testWidget->setCurrentSection(QDateTimeEdit::MonthSection);
- qApp->sendEvent(testWidget, &w);
- QCOMPARE(testWidget->date(), QDate(2000, 3, 22));
-}
+#if QT_CONFIG(wheelevent)
+ QFETCH(QPoint, angleDelta);
+ QFETCH(int, qt4Delta);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifiers);
+ QFETCH(Qt::MouseEventSource, source);
+ QFETCH(QDateTimeEdit::Section, section);
+ QFETCH(QDate, startDate);
+ QFETCH(DateList, expectedDates);
+
+ EditorDateEdit edit(0);
+ edit.setDate(startDate);
+ edit.setCurrentSection(section);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ edit.setStyle(style.data());
+
+ QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta,
+ Qt::Vertical, Qt::NoButton, modifiers, Qt::NoScrollPhase,
+ source);
+
+ QCOMPARE(edit.date(), startDate);
+ for (QDate expected : expectedDates) {
+ qApp->sendEvent(&edit, &event);
+ QCOMPARE(edit.date(), expected);
+ }
+#else
+ QSKIP("Built with --no-feature-wheelevent");
#endif // QT_CONFIG(wheelevent)
+}
void tst_QDateTimeEdit::specialValueCornerCase()
{
@@ -3735,5 +4024,308 @@ void tst_QDateTimeEdit::dateEditCorrectSectionSize()
}
#endif
+void tst_QDateTimeEdit::stepModifierKeys_data()
+{
+ QTest::addColumn<QDate>("startDate");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<QDateTimeEdit::Section>("section");
+ QTest::addColumn<QTestEventList>("keys");
+ QTest::addColumn<QDate>("expectedDate");
+
+ const auto keyList = {Qt::Key_Up, Qt::Key_Down};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ const auto sections = {QDateTimeEdit::DaySection,
+ QDateTimeEdit::MonthSection,
+ QDateTimeEdit::YearSection};
+
+ for (auto key : keyList) {
+
+ const bool up = key == Qt::Key_Up;
+ Q_ASSERT(up || key == Qt::Key_Down);
+
+ const QDate startDate(2000, up ? 2 : 12, 17);
+
+ for (auto modifier : modifierList) {
+
+ QTestEventList keys;
+ keys.addKeyClick(key, modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ for (const auto section : sections) {
+
+ const auto expectedDate = stepDate(startDate, section, steps);
+ if (!expectedDate.isValid())
+ continue;
+
+ const auto sectionName = sectionToName(section);
+
+ QTest::addRow("%s%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ sectionName.latin1(),
+ modifierName.latin1())
+ << startDate
+ << static_cast<int>(stepModifier)
+ << section
+ << keys
+ << expectedDate;
+ }
+ }
+ }
+ }
+}
+
+void tst_QDateTimeEdit::stepModifierKeys()
+{
+ QFETCH(QDate, startDate);
+ QFETCH(int, stepModifier);
+ QFETCH(QDateTimeEdit::Section, section);
+ QFETCH(QTestEventList, keys);
+ QFETCH(QDate, expectedDate);
+
+ // This can interfere with our stuff.
+ testWidget->hide();
+
+ QDateTimeEdit edit(0);
+ edit.setDate(startDate);
+ edit.show();
+ QVERIFY(QTest::qWaitForWindowActive(&edit));
+ edit.setCurrentSection(section);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ edit.setStyle(style.data());
+
+ QCOMPARE(edit.date(), startDate);
+ keys.simulate(&edit);
+ QCOMPARE(edit.date(), expectedDate);
+}
+
+void tst_QDateTimeEdit::stepModifierButtons_data()
+{
+ QTest::addColumn<QStyle::SubControl>("subControl");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
+ QTest::addColumn<QDateTimeEdit::Section>("section");
+ QTest::addColumn<QTime>("startTime");
+ QTest::addColumn<QTime>("expectedTime");
+
+ const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ const auto sections = {QDateTimeEdit::SecondSection,
+ QDateTimeEdit::MinuteSection,
+ QDateTimeEdit::HourSection};
+
+ const QTime startTime(12, 36, 24);
+
+ for (auto subControl : subControls) {
+
+ const bool up = subControl == QStyle::SC_SpinBoxUp;
+ Q_ASSERT(up || subControl == QStyle::SC_SpinBoxDown);
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ for (const auto section : sections) {
+
+ const auto expectedTime = stepTime(startTime, section, steps);
+ if (!expectedTime.isValid())
+ continue;
+
+ const auto sectionName = sectionToName(section);
+
+ QTest::addRow("%s%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ sectionName.latin1(),
+ modifierName.latin1())
+ << subControl
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << section
+ << startTime
+ << expectedTime;
+ }
+ }
+ }
+ }
+}
+
+void tst_QDateTimeEdit::stepModifierButtons()
+{
+ QFETCH(QStyle::SubControl, subControl);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifiers);
+ QFETCH(QDateTimeEdit::Section, section);
+ QFETCH(QTime, startTime);
+ QFETCH(QTime, expectedTime);
+
+ testWidget->hide();
+
+ EditorDateEdit edit(0);
+ edit.setTime(startTime);
+ edit.show();
+ QVERIFY(QTest::qWaitForWindowActive(&edit));
+ edit.setCurrentSection(section);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ edit.setStyle(style.data());
+
+ QStyleOptionSpinBox spinBoxStyleOption;
+ edit.initStyleOption(&spinBoxStyleOption);
+
+ const QRect buttonRect = edit.style()->subControlRect(
+ QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &edit);
+
+ QCOMPARE(edit.time(), startTime);
+ QTest::mouseClick(&edit, Qt::LeftButton, modifiers, buttonRect.center());
+ QCOMPARE(edit.time(), expectedTime);
+}
+
+void tst_QDateTimeEdit::stepModifierPressAndHold_data()
+{
+ QTest::addColumn<QStyle::SubControl>("subControl");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
+ QTest::addColumn<int>("expectedStepModifier");
+
+ const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ for (auto subControl : subControls) {
+
+ const bool up = subControl == QStyle::SC_SpinBoxUp;
+ Q_ASSERT(up || subControl == QStyle::SC_SpinBoxDown);
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ QTest::addRow("%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ modifierName.latin1())
+ << subControl
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << steps;
+ }
+ }
+ }
+}
+
+void tst_QDateTimeEdit::stepModifierPressAndHold()
+{
+ QFETCH(QStyle::SubControl, subControl);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifiers);
+ QFETCH(int, expectedStepModifier);
+
+ const QDate startDate(2000, 1, 1);
+
+ testWidget->hide();
+
+ EditorDateEdit edit(0);
+ edit.setDate(startDate);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> stepModifierStyle(
+ new StepModifierStyle(new PressAndHoldStyle));
+ stepModifierStyle->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ edit.setStyle(stepModifierStyle.data());
+
+ QSignalSpy spy(&edit, &EditorDateEdit::dateChanged);
+
+ edit.show();
+ QVERIFY(QTest::qWaitForWindowActive(&edit));
+ edit.setCurrentSection(QDateTimeEdit::YearSection);
+
+ QStyleOptionSpinBox spinBoxStyleOption;
+ edit.initStyleOption(&spinBoxStyleOption);
+
+ const QRect buttonRect = edit.style()->subControlRect(
+ QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &edit);
+
+ QTest::mousePress(&edit, Qt::LeftButton, modifiers, buttonRect.center());
+ QTRY_VERIFY(spy.length() >= 3);
+ QTest::mouseRelease(&edit, Qt::LeftButton, modifiers, buttonRect.center());
+
+ const auto value = spy.last().at(0);
+ QVERIFY(value.type() == QVariant::Date);
+ const QDate expectedDate = startDate.addYears(spy.length() *
+ expectedStepModifier);
+ QCOMPARE(value.toDate(), expectedDate);
+}
+
QTEST_MAIN(tst_QDateTimeEdit)
#include "tst_qdatetimeedit.moc"
diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
index 7d1e736f42..078a3215fd 100644
--- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
+++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
@@ -36,7 +36,7 @@
#include <qmainwindow.h>
#include <qlineedit.h>
#include <qtabbar.h>
-#include <QDesktopWidget>
+#include <QScreen>
#include <QtGui/QPainter>
#include "private/qdockwidget_p.h"
@@ -338,7 +338,7 @@ void tst_QDockWidget::features()
void tst_QDockWidget::setFloating()
{
- const QRect deskRect = QApplication::desktop()->availableGeometry();
+ const QRect deskRect = QGuiApplication::primaryScreen()->availableGeometry();
QMainWindow mw;
mw.move(deskRect.left() + deskRect.width() * 2 / 3, deskRect.top() + deskRect.height() / 3);
QDockWidget dw;
@@ -756,7 +756,7 @@ void tst_QDockWidget::restoreStateWhileStillFloating()
// When the dock widget is already floating then it takes a different code path
// so this test covers the case where the restoreState() is effectively just
// moving it back and resizing it
- const QRect availGeom = QApplication::desktop()->availableGeometry();
+ const QRect availGeom = QGuiApplication::primaryScreen()->availableGeometry();
const QPoint startingDockPos = availGeom.center();
QMainWindow mw;
QDockWidget *dock = createTestDock(mw);
@@ -781,10 +781,8 @@ void tst_QDockWidget::restoreDockWidget()
QByteArray geometry;
QByteArray state;
- const bool isXcb = !QGuiApplication::platformName().compare("xcb", Qt::CaseInsensitive);
-
const QString name = QStringLiteral("main");
- const QRect availableGeometry = QApplication::desktop()->availableGeometry();
+ const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
const QSize size = availableGeometry.size() / 5;
const QPoint mainWindowPos = availableGeometry.bottomRight() - QPoint(size.width(), size.height()) - QPoint(100, 100);
const QPoint dockPos = availableGeometry.center();
@@ -815,8 +813,7 @@ void tst_QDockWidget::restoreDockWidget()
dock->show();
QVERIFY(QTest::qWaitForWindowExposed(dock));
QTRY_VERIFY(dock->isFloating());
- if (!isXcb) // Avoid Window manager positioning issues
- QTRY_COMPARE(dock->pos(), dockPos);
+ QTRY_COMPARE(dock->pos(), dockPos);
}
QVERIFY(!geometry.isEmpty());
@@ -837,8 +834,6 @@ void tst_QDockWidget::restoreDockWidget()
restoreWindow.show();
QVERIFY(QTest::qWaitForWindowExposed(&restoreWindow));
QTRY_VERIFY(dock->isFloating());
- if (isXcb)
- QSKIP("Skip due to Window manager positioning issues", Abort);
QTRY_COMPARE(dock->pos(), dockPos);
}
}
@@ -868,7 +863,7 @@ void tst_QDockWidget::task169808_setFloating()
public:
QSize sizeHint() const
{
- const QRect& deskRect = qApp->desktop()->availableGeometry();
+ const QRect& deskRect = QGuiApplication::primaryScreen()->availableGeometry();
return QSize(qMin(300, deskRect.width() / 2), qMin(300, deskRect.height() / 2));
}
@@ -892,6 +887,9 @@ void tst_QDockWidget::task169808_setFloating()
mw.show();
QVERIFY(QTest::qWaitForWindowExposed(&mw));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Widgets are maximized on WinRT by default", Abort);
+#endif
QCOMPARE(dw->widget()->size(), dw->widget()->sizeHint());
//and now we try to test if the contents margin is taken into account
@@ -934,6 +932,9 @@ void tst_QDockWidget::task248604_infiniteResize()
d.setContentsMargins(2, 2, 2, 2);
d.setMinimumSize(320, 240);
d.showNormal();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Widgets are maximized on WinRT by default", Abort);
+#endif
QTRY_COMPARE(d.size(), QSize(320, 240));
}
diff --git a/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST b/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST
new file mode 100644
index 0000000000..c1b6c9693e
--- /dev/null
+++ b/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST
@@ -0,0 +1,2 @@
+[editingFinished]
+*
diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
index d44cc40527..b1610c297d 100644
--- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
+++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
@@ -31,6 +31,7 @@
#include <qapplication.h>
#include <limits.h>
+#include <cmath>
#include <float.h>
#include <qspinbox.h>
@@ -40,6 +41,10 @@
#include <qlineedit.h>
#include <qdebug.h>
+#include <QStyleOptionSpinBox>
+#include <QStyle>
+#include <QProxyStyle>
+
class DoubleSpinBox : public QDoubleSpinBox
{
Q_OBJECT
@@ -59,6 +64,16 @@ public:
{
return QDoubleSpinBox::valueFromText(text);
}
+#if QT_CONFIG(wheelevent)
+ void wheelEvent(QWheelEvent *event)
+ {
+ QDoubleSpinBox::wheelEvent(event);
+ }
+#endif
+ void initStyleOption(QStyleOptionSpinBox *option) const
+ {
+ QDoubleSpinBox::initStyleOption(option);
+ }
QLineEdit* lineEdit() const { return QDoubleSpinBox::lineEdit(); }
public slots:
@@ -68,6 +83,46 @@ public slots:
}
};
+class PressAndHoldStyle : public QProxyStyle
+{
+ Q_OBJECT
+public:
+ using QProxyStyle::QProxyStyle;
+
+ int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
+ {
+ switch (hint) {
+ case QStyle::SH_SpinBox_ClickAutoRepeatRate:
+ return 5;
+ case QStyle::SH_SpinBox_ClickAutoRepeatThreshold:
+ return 10;
+ default:
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+ }
+};
+
+class StepModifierStyle : public QProxyStyle
+{
+ Q_OBJECT
+public:
+ using QProxyStyle::QProxyStyle;
+
+ int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
+ {
+ switch (hint) {
+ case QStyle::SH_SpinBox_StepModifier:
+ return stepModifier;
+ default:
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+ }
+
+ Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
+};
+
class tst_QDoubleSpinBox : public QObject
{
@@ -135,6 +190,19 @@ private slots:
void setGroupSeparatorShown_data();
void setGroupSeparatorShown();
+ void adaptiveDecimalStep();
+
+ void wheelEvents_data();
+ void wheelEvents();
+
+ void stepModifierKeys_data();
+ void stepModifierKeys();
+
+ void stepModifierButtons_data();
+ void stepModifierButtons();
+
+ void stepModifierPressAndHold_data();
+ void stepModifierPressAndHold();
public slots:
void valueChangedHelper(const QString &);
void valueChangedHelper(double);
@@ -149,6 +217,30 @@ typedef QList<double> DoubleList;
Q_DECLARE_METATYPE(QLocale::Language)
Q_DECLARE_METATYPE(QLocale::Country)
+static QLatin1String modifierToName(Qt::KeyboardModifier modifier)
+{
+ switch (modifier) {
+ case Qt::NoModifier:
+ return QLatin1Literal("No");
+ break;
+ case Qt::ControlModifier:
+ return QLatin1Literal("Ctrl");
+ break;
+ case Qt::ShiftModifier:
+ return QLatin1Literal("Shift");
+ break;
+ case Qt::AltModifier:
+ return QLatin1Literal("Alt");
+ break;
+ case Qt::MetaModifier:
+ return QLatin1Literal("Meta");
+ break;
+ default:
+ qFatal("Unexpected keyboard modifier");
+ return QLatin1String();
+ }
+}
+
tst_QDoubleSpinBox::tst_QDoubleSpinBox()
{
@@ -1139,5 +1231,548 @@ void tst_QDoubleSpinBox::setGroupSeparatorShown()
QCOMPARE(spinBox.value()+1000, 33000.44);
}
+void tst_QDoubleSpinBox::adaptiveDecimalStep()
+{
+ DoubleSpinBox spinBox;
+ spinBox.setRange(-100000, 100000);
+ spinBox.setDecimals(4);
+ spinBox.setStepType(DoubleSpinBox::StepType::AdaptiveDecimalStepType);
+
+ // Positive values
+
+ spinBox.setValue(0);
+
+ // Go from 0 to 0.01
+ for (double i = 0; i < 0.00999; i += 0.0001) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+
+ // Go from 0.01 to 0.1
+ for (double i = 0.01; i < 0.0999; i += 0.001) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+
+ // Go from 0.1 to 1
+ for (double i = 0.1; i < 0.999; i += 0.01) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+
+ // Go from 1 to 10
+ for (double i = 1; i < 9.99; i += 0.1) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+
+ // Go from 10 to 100
+ for (int i = 10; i < 100; i++) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+
+ // Go from 100 to 1000
+ for (int i = 100; i < 1000; i += 10) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+
+ // Go from 1000 to 10000
+ for (int i = 1000; i < 10000; i += 100) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+
+ // Test decreasing the values now
+
+ // Go from 10000 down to 1000
+ for (int i = 10000; i > 1000; i -= 100) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Go from 1000 down to 100
+ for (int i = 1000; i > 100; i -= 10) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Negative values
+
+ spinBox.setValue(0);
+
+ // Go from 0 to -0.01
+ for (double i = 0; i > -0.00999; i -= 0.0001) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Go from -0.01 to -0.1
+ for (double i = -0.01; i > -0.0999; i -= 0.001) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Go from -0.1 to -1
+ for (double i = -0.1; i > -0.999; i -= 0.01) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Go from -1 to -10
+ for (double i = -1; i > -9.99; i -= 0.1) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Go from -10 to -100
+ for (int i = -10; i > -100; i--) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Go from -100 to -1000
+ for (int i = -100; i > -1000; i -= 10) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Go from 1000 to 10000
+ for (int i = -1000; i > -10000; i -= 100) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(-1);
+ }
+
+ // Test increasing the values now
+
+ // Go from -10000 up to -1000
+ for (int i = -10000; i < -1000; i += 100) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+
+ // Go from -1000 up to -100
+ for (int i = -1000; i < -100; i += 10) {
+ QVERIFY(qFuzzyCompare(spinBox.value(), i));
+ spinBox.stepBy(1);
+ }
+}
+
+void tst_QDoubleSpinBox::wheelEvents_data()
+{
+#if QT_CONFIG(wheelevent)
+ QTest::addColumn<QPoint>("angleDelta");
+ QTest::addColumn<int>("qt4Delta");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifier");
+ QTest::addColumn<Qt::MouseEventSource>("source");
+ QTest::addColumn<double>("start");
+ QTest::addColumn<DoubleList>("expectedValues");
+
+ const auto fractions = {false, true};
+
+ const auto directions = {true, false};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ const auto sources = {Qt::MouseEventNotSynthesized,
+ Qt::MouseEventSynthesizedBySystem,
+ Qt::MouseEventSynthesizedByQt,
+ Qt::MouseEventSynthesizedByApplication};
+
+ const double startValue = 0.0;
+
+ for (auto fraction : fractions) {
+ for (auto up : directions) {
+
+ const int units = (fraction ? 60 : 120) * (up ? 1 : -1);
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ for (auto source : sources) {
+
+#ifdef Q_OS_MACOS
+ QPoint angleDelta;
+ if ((modifier & Qt::ShiftModifier) &&
+ source == Qt::MouseEventNotSynthesized) {
+ // On macOS the Shift modifier converts vertical
+ // mouse wheel events to horizontal.
+ angleDelta = { units, 0 };
+ } else {
+ // However, this is not the case for trackpad scroll
+ // events.
+ angleDelta = { 0, units };
+ }
+#else
+ const QPoint angleDelta(0, units);
+#endif
+
+ QLatin1String sourceName;
+ switch (source) {
+ case Qt::MouseEventNotSynthesized:
+ sourceName = QLatin1Literal("NotSynthesized");
+ break;
+ case Qt::MouseEventSynthesizedBySystem:
+ sourceName = QLatin1Literal("SynthesizedBySystem");
+ break;
+ case Qt::MouseEventSynthesizedByQt:
+ sourceName = QLatin1Literal("SynthesizedByQt");
+ break;
+ case Qt::MouseEventSynthesizedByApplication:
+ sourceName = QLatin1Literal("SynthesizedByApplication");
+ break;
+ default:
+ qFatal("Unexpected wheel event source");
+ continue;
+ }
+
+ DoubleList expectedValues;
+ if (fraction)
+ expectedValues << startValue;
+ expectedValues << startValue + steps;
+
+ QTest::addRow("%s%s%sWith%sKeyboardModifier%s",
+ fraction ? "half" : "full",
+ up ? "Up" : "Down",
+ stepModifierName.latin1(),
+ modifierName.latin1(),
+ sourceName.latin1())
+ << angleDelta
+ << units
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << source
+ << startValue
+ << expectedValues;
+ }
+ }
+ }
+ }
+ }
+#else
+ QSKIP("Built with --no-feature-wheelevent");
+#endif
+}
+
+void tst_QDoubleSpinBox::wheelEvents()
+{
+#if QT_CONFIG(wheelevent)
+ QFETCH(QPoint, angleDelta);
+ QFETCH(int, qt4Delta);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifier);
+ QFETCH(Qt::MouseEventSource, source);
+ QFETCH(double, start);
+ QFETCH(DoubleList, expectedValues);
+
+ DoubleSpinBox spinBox;
+ spinBox.setRange(-20, 20);
+ spinBox.setValue(start);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ spinBox.setStyle(style.data());
+
+ QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta,
+ Qt::Vertical, Qt::NoButton, modifier, Qt::NoScrollPhase,
+ source);
+ for (int expected : expectedValues) {
+ qApp->sendEvent(&spinBox, &event);
+ QCOMPARE(spinBox.value(), expected);
+ }
+#else
+ QSKIP("Built with --no-feature-wheelevent");
+#endif
+}
+
+void tst_QDoubleSpinBox::stepModifierKeys_data()
+{
+ QTest::addColumn<double>("startValue");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<QTestEventList>("keys");
+ QTest::addColumn<double>("expectedValue");
+
+ const auto keyList = {Qt::Key_Up, Qt::Key_Down};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+
+ for (auto key : keyList) {
+
+ const bool up = key == Qt::Key_Up;
+ Q_ASSERT(up || key == Qt::Key_Down);
+
+ const double startValue = up ? 0.0 : 10.0;
+
+ for (auto modifier : modifierList) {
+
+ QTestEventList keys;
+ keys.addKeyClick(key, modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ const double expectedValue = startValue + steps;
+
+ QTest::addRow("%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ modifierName.latin1())
+ << startValue
+ << static_cast<int>(stepModifier)
+ << keys
+ << expectedValue;
+ }
+ }
+ }
+}
+
+void tst_QDoubleSpinBox::stepModifierKeys()
+{
+ QFETCH(double, startValue);
+ QFETCH(int, stepModifier);
+ QFETCH(QTestEventList, keys);
+ QFETCH(double, expectedValue);
+
+ QDoubleSpinBox spin(0);
+ spin.setValue(startValue);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ spin.setStyle(style.data());
+
+ spin.show();
+ QVERIFY(QTest::qWaitForWindowActive(&spin));
+
+ QCOMPARE(spin.value(), startValue);
+ keys.simulate(&spin);
+ QCOMPARE(spin.value(), expectedValue);
+}
+
+void tst_QDoubleSpinBox::stepModifierButtons_data()
+{
+ QTest::addColumn<QStyle::SubControl>("subControl");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
+ QTest::addColumn<double>("startValue");
+ QTest::addColumn<double>("expectedValue");
+
+ const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ for (auto subControl : subControls) {
+
+ const bool up = subControl == QStyle::SC_SpinBoxUp;
+ Q_ASSERT(up || subControl == QStyle::SC_SpinBoxDown);
+
+ const double startValue = up ? 0 : 10;
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ const double expectedValue = startValue + steps;
+
+ QTest::addRow("%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ modifierName.latin1())
+ << subControl
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << startValue
+ << expectedValue;
+ }
+ }
+ }
+}
+
+void tst_QDoubleSpinBox::stepModifierButtons()
+{
+ QFETCH(QStyle::SubControl, subControl);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifiers);
+ QFETCH(double, startValue);
+ QFETCH(double, expectedValue);
+
+ DoubleSpinBox spin(0);
+ spin.setRange(-20, 20);
+ spin.setValue(startValue);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ spin.setStyle(style.data());
+
+ spin.show();
+ QVERIFY(QTest::qWaitForWindowActive(&spin));
+
+ QStyleOptionSpinBox spinBoxStyleOption;
+ spin.initStyleOption(&spinBoxStyleOption);
+
+ const QRect buttonRect = spin.style()->subControlRect(
+ QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &spin);
+
+ QCOMPARE(spin.value(), startValue);
+ QTest::mouseClick(&spin, Qt::LeftButton, modifiers, buttonRect.center());
+ QCOMPARE(spin.value(), expectedValue);
+}
+
+void tst_QDoubleSpinBox::stepModifierPressAndHold_data()
+{
+ QTest::addColumn<QStyle::SubControl>("subControl");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
+ QTest::addColumn<int>("expectedStepModifier");
+
+ const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ for (auto subControl : subControls) {
+
+ const bool up = subControl == QStyle::SC_SpinBoxUp;
+ Q_ASSERT(up || subControl == QStyle::SC_SpinBoxDown);
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ QTest::addRow("%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ modifierName.latin1())
+ << subControl
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << steps;
+ }
+ }
+ }
+}
+
+void tst_QDoubleSpinBox::stepModifierPressAndHold()
+{
+ QFETCH(QStyle::SubControl, subControl);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifiers);
+ QFETCH(int, expectedStepModifier);
+
+ DoubleSpinBox spin(0);
+ spin.setRange(-100.0, 100.0);
+ spin.setValue(0.0);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> stepModifierStyle(
+ new StepModifierStyle(new PressAndHoldStyle));
+ stepModifierStyle->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ spin.setStyle(stepModifierStyle.data());
+
+ QSignalSpy spy(&spin, QOverload<double>::of(&DoubleSpinBox::valueChanged));
+
+ spin.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&spin));
+
+ QStyleOptionSpinBox spinBoxStyleOption;
+ spin.initStyleOption(&spinBoxStyleOption);
+
+ const QRect buttonRect = spin.style()->subControlRect(
+ QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &spin);
+
+ QTest::mousePress(&spin, Qt::LeftButton, modifiers, buttonRect.center());
+ QTRY_VERIFY(spy.length() >= 3);
+ QTest::mouseRelease(&spin, Qt::LeftButton, modifiers, buttonRect.center());
+
+ const auto value = spy.last().at(0);
+ QVERIFY(value.type() == QVariant::Double);
+ QCOMPARE(value.toDouble(), spy.length() * expectedStepModifier);
+}
+
QTEST_MAIN(tst_QDoubleSpinBox)
#include "tst_qdoublespinbox.moc"
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index 17462a5f86..448e2030bc 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -304,7 +304,7 @@ private slots:
void QTBUG59957_clearButtonLeftmostAction();
void QTBUG_60319_setInputMaskCheckImSurroundingText();
void testQuickSelectionWithMouse();
-
+ void inputRejected();
protected slots:
void editingFinished();
@@ -2279,6 +2279,16 @@ void tst_QLineEdit::deleteSelectedText()
}
+class ToUpperValidator : public QValidator
+{
+public:
+ ToUpperValidator() {}
+ State validate(QString &input, int &) const override
+ {
+ input = input.toUpper();
+ return QValidator::Acceptable;
+ }
+};
void tst_QLineEdit::textChangedAndTextEdited()
{
@@ -2320,6 +2330,23 @@ void tst_QLineEdit::textChangedAndTextEdited()
QCOMPARE(edited_count, 0);
QVERIFY(changed_string.isEmpty());
QVERIFY(!changed_string.isNull());
+
+ changed_count = 0;
+ edited_count = 0;
+ changed_string.clear();
+
+ QScopedPointer<ToUpperValidator> validator(new ToUpperValidator());
+ testWidget->setValidator(validator.data());
+ testWidget->setText("foo");
+ QCOMPARE(changed_count, 1);
+ QCOMPARE(edited_count, 0);
+ QCOMPARE(changed_string, QLatin1String("FOO"));
+ testWidget->setCursorPosition(sizeof("foo"));
+ QTest::keyClick(testWidget, 'b');
+ QCOMPARE(changed_count, 2);
+ QCOMPARE(edited_count, 1);
+ QCOMPARE(changed_string, QLatin1String("FOOB"));
+ testWidget->setValidator(nullptr);
}
void tst_QLineEdit::onTextChanged(const QString &text)
@@ -2637,9 +2664,9 @@ void tst_QLineEdit::setValidator_QIntValidator_data()
<< 0
<< 100
<< QString("153")
- << QString(useKeys ? "15" : "")
+ << QString("153")
<< bool(useKeys)
- << bool(useKeys ? true : false)
+ << bool(false)
<< uint(QLineEdit::Normal);
QTest::newRow(QString(inputMode + "range [-100,100] int '-153'").toLatin1())
<< -100
@@ -2660,7 +2687,7 @@ void tst_QLineEdit::setValidator_QIntValidator_data()
QTest::newRow(QString(inputMode + "range [3,7] int '8'").toLatin1())
<< 3
<< 7
- << QString("8")
+ << QString("")
<< QString("")
<< bool(useKeys)
<< bool(false)
@@ -3265,7 +3292,7 @@ void tst_QLineEdit::editInvalidText()
{
QLineEdit *testWidget = ensureTestWidget();
testWidget->clear();
- testWidget->setValidator(new QIntValidator(0, 120, 0));
+ testWidget->setValidator(new QIntValidator(0, 12, 0));
testWidget->setText("1234");
QVERIFY(!testWidget->hasAcceptableInput());
@@ -4726,6 +4753,9 @@ void tst_QLineEdit::testQuickSelectionWithMouse()
QTest::mousePress(lineEdit.windowHandle(), Qt::LeftButton, Qt::NoModifier, center);
QTest::mouseMove(lineEdit.windowHandle(), center + QPoint(20, 0));
qCDebug(lcTests) << "Selected text:" << lineEdit.selectedText();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT does not support QTest::mousePress/-Move", Abort);
+#endif
QVERIFY(!lineEdit.selectedText().isEmpty());
QVERIFY(!lineEdit.selectedText().endsWith(suffix));
@@ -4793,5 +4823,56 @@ void tst_QLineEdit::testQuickSelectionWithMouse()
QVERIFY(lineEdit.selectedText().endsWith(suffix));
}
+void tst_QLineEdit::inputRejected()
+{
+ QLineEdit *testWidget = ensureTestWidget();
+ QSignalSpy spyInputRejected(testWidget, SIGNAL(inputRejected()));
+
+ QTest::keyClicks(testWidget, "abcde");
+ QCOMPARE(spyInputRejected.count(), 0);
+ testWidget->setText("fghij");
+ QCOMPARE(spyInputRejected.count(), 0);
+ testWidget->insert("k");
+ QCOMPARE(spyInputRejected.count(), 0);
+
+ testWidget->clear();
+ testWidget->setMaxLength(5);
+ QTest::keyClicks(testWidget, "abcde");
+ QCOMPARE(spyInputRejected.count(), 0);
+ QTest::keyClicks(testWidget, "fgh");
+ QCOMPARE(spyInputRejected.count(), 3);
+ testWidget->clear();
+ spyInputRejected.clear();
+ QApplication::clipboard()->setText("ijklmno");
+ testWidget->paste();
+ // The first 5 characters are accepted, but
+ // the last 2 are not.
+ QCOMPARE(spyInputRejected.count(), 1);
+
+ testWidget->setMaxLength(INT_MAX);
+ testWidget->clear();
+ spyInputRejected.clear();
+ QIntValidator intValidator(1, 100);
+ testWidget->setValidator(&intValidator);
+ QTest::keyClicks(testWidget, "11");
+ QCOMPARE(spyInputRejected.count(), 0);
+ QTest::keyClicks(testWidget, "a#");
+ QCOMPARE(spyInputRejected.count(), 2);
+ testWidget->clear();
+ spyInputRejected.clear();
+ QApplication::clipboard()->setText("a#");
+ testWidget->paste();
+ QCOMPARE(spyInputRejected.count(), 1);
+
+ testWidget->clear();
+ testWidget->setValidator(0);
+ spyInputRejected.clear();
+ testWidget->setInputMask("999.999.999.999;_");
+ QTest::keyClicks(testWidget, "11");
+ QCOMPARE(spyInputRejected.count(), 0);
+ QTest::keyClicks(testWidget, "a#");
+ QCOMPARE(spyInputRejected.count(), 2);
+}
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/widgets/widgets/qmainwindow/BLACKLIST b/tests/auto/widgets/widgets/qmainwindow/BLACKLIST
new file mode 100644
index 0000000000..a03ea11f40
--- /dev/null
+++ b/tests/auto/widgets/widgets/qmainwindow/BLACKLIST
@@ -0,0 +1,2 @@
+[resizeDocks]
+winrt
diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
index ae71663036..1acf07301c 100644
--- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
@@ -43,7 +43,7 @@
#include <qlabel.h>
#include <qtextedit.h>
#include <qstylehints.h>
-#include <qdesktopwidget.h>
+#include <qscreen.h>
#include <private/qmainwindowlayout_p.h>
#include <private/qdockarealayout_p.h>
@@ -768,7 +768,7 @@ void tst_QMainWindow::contentsMargins()
QFETCH(int, contentsMargin);
QMainWindow mw;
- const QRect availGeometry = QApplication::desktop()->availableGeometry();
+ const QRect availGeometry = QGuiApplication::primaryScreen()->availableGeometry();
mw.menuBar()->addMenu("File");
mw.setWindowTitle(QLatin1String(QTest::currentTestFunction())
+ QLatin1Char(' ') + QLatin1String(QTest::currentDataTag()));
@@ -1782,6 +1782,9 @@ void tst_QMainWindow::centralWidgetSize()
mainWindow.setCentralWidget(&widget);
mainWindow.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Widgets are maximized by default on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(widget.size(), widget.sizeHint());
}
@@ -1826,6 +1829,9 @@ void tst_QMainWindow::fixedSizeCentralWidget()
// finally verify that we get the space back when we resize to the old size
mainWindow.resize(mwSize);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "QMainWindow::resize does not work on WinRT", Continue);
+#endif
QTRY_COMPARE(child->height(), childHeight);
}
diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
index ecad7267dd..6cc19051d2 100644
--- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
+++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
@@ -357,6 +357,9 @@ void tst_QMdiArea::subWindowActivated()
QMdiSubWindow *window = windows.at(i);
window->showNormal();
qApp->processEvents();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("data2", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY( window == activeWindow );
QVERIFY( activeWindow == workspace->activeSubWindow() );
}
@@ -517,6 +520,9 @@ void tst_QMdiArea::subWindowActivated2()
mdiArea.showNormal();
mdiArea.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(spy.count(), 1);
QCOMPARE(mdiArea.activeSubWindow(), activeSubWindow);
spy.clear();
@@ -1191,6 +1197,9 @@ void tst_QMdiArea::addAndRemoveWindows()
// Don't occupy space.
QMdiSubWindow *window3 = workspace.addSubWindow(new QWidget);
window3->show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Windows are maximized by default on WinRT", Abort);
+#endif
QCOMPARE(window3->geometry().topLeft(), QPoint(window2RestoreGeometry.right() + 1, 0));
}
@@ -1451,6 +1460,9 @@ void tst_QMdiArea::subWindowList()
QList<QMdiSubWindow *> widgets = workspace.subWindowList(windowOrder);
QCOMPARE(widgets.count(), windowCount);
if (windowOrder == QMdiArea::StackingOrder) {
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(widgets.at(widgets.count() - 1), windows[staysOnTop2]);
QCOMPARE(widgets.at(widgets.count() - 2), windows[staysOnTop1]);
QCOMPARE(widgets.at(widgets.count() - 3), windows[activeSubWindow]);
@@ -1666,6 +1678,9 @@ void tst_QMdiArea::tileSubWindows()
// Re-tile.
workspace.tileSubWindows();
workspace.setActiveSubWindow(0);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(workspace.viewport()->childrenRect(), workspace.viewport()->rect());
// Cascade and verify that the views are not tiled anymore.
@@ -1965,6 +1980,9 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation()
// Verify that new windows are not maximized.
mdiArea.addSubWindow(new QWidget)->show();
QVERIFY(mdiArea.activeSubWindow());
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(!mdiArea.activeSubWindow()->isMaximized());
}
@@ -1986,6 +2004,9 @@ void tst_QMdiArea::delayedPlacement()
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
QCOMPARE(window1->geometry().topLeft(), QPoint(0, 0));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(window2->geometry().topLeft(), window1->geometry().topRight() + QPoint(1, 0));
QCOMPARE(window3->geometry().topLeft(), window2->geometry().topRight() + QPoint(1, 0));
}
@@ -2117,6 +2138,10 @@ void tst_QMdiArea::updateScrollBars()
subWindow1->showNormal();
qApp->processEvents();
QVERIFY(!subWindow1->isMaximized());
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Widgets are maximized by default on WinRT, so scroll bars might not be"
+ "visible", Abort);
+#endif
QVERIFY(hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient) || hbar->isVisible());
QVERIFY(vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient) || vbar->isVisible());
if (i == 0) {
@@ -2318,6 +2343,10 @@ void tst_QMdiArea::setViewMode()
QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
// Default.
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Widgets are maximized by default on WinRT, so scroll bars might not be"
+ "visible", Abort);
+#endif
QVERIFY(!activeSubWindow->isMaximized());
QTabBar *tabBar = mdiArea.findChild<QTabBar *>();
QVERIFY(!tabBar);
diff --git a/tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro b/tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro
index 4299f7711e..e33271428f 100644
--- a/tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro
+++ b/tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
TARGET = tst_qmdisubwindow
-QT += widgets testlib
+QT += widgets widgets-private testlib
INCLUDEPATH += .
SOURCES += tst_qmdisubwindow.cpp
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
index 360e0c93c4..8b2f032172 100644
--- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
+++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
@@ -30,6 +30,7 @@
#include <QtTest/QtTest>
#include "qmdisubwindow.h"
+#include "private/qmdisubwindow_p.h"
#include "qmdiarea.h"
#include <QLayout>
@@ -517,6 +518,9 @@ void tst_QMdiSubWindow::emittingOfSignals()
}
}
}
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("windowMaximized", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(count, 1);
window->setParent(0);
@@ -542,6 +546,9 @@ void tst_QMdiSubWindow::showShaded()
QVERIFY(QTest::qWaitForWindowExposed(&workspace));
QVERIFY(!window->isShaded());
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Windows are maximized per default on WinRt ", Abort);
+#endif
QVERIFY(!window->isMaximized());
QCOMPARE(window->size(), QSize(300, 300));
@@ -634,6 +641,10 @@ void tst_QMdiSubWindow::showNormal()
qApp->processEvents();
window->showNormal();
qApp->processEvents();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("showMinimized", "Windows are maximized per default on WinRt ", Abort);
+ QEXPECT_FAIL("showMaximized", "Windows are maximized per default on WinRt ", Abort);
+#endif
QCOMPARE(window->geometry(), originalGeometry);
}
@@ -713,7 +724,9 @@ void tst_QMdiSubWindow::setOpaqueResizeAndMove()
resizeSpy.clear();
QCOMPARE(resizeSpy.count(), 0);
- QTest::qWait(250); // delayed update of dirty regions
+ // we need to wait for the resizeTimer to make sure updateDirtyRegions is called
+ auto priv = static_cast<QMdiSubWindowPrivate*>(qt_widget_private(window));
+ QTRY_COMPARE(priv->resizeTimerId, -1);
// Enter resize mode.
int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2;
@@ -740,6 +753,9 @@ void tst_QMdiSubWindow::setOpaqueResizeAndMove()
// Leave resize mode
sendMouseRelease(mouseReceiver, mousePosition);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(resizeSpy.count(), expectedGeometryCount);
QCOMPARE(window->size(), windowSize + QSize(geometryCount, geometryCount));
}
@@ -903,6 +919,9 @@ void tst_QMdiSubWindow::mouseDoubleClick()
workspace.show();
window->show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Windows are maximized per default on WinRt ", Abort);
+#endif
QVERIFY(!window->isMaximized());
QVERIFY(!window->isShaded());
@@ -971,6 +990,9 @@ void tst_QMdiSubWindow::setSystemMenu()
QVERIFY(!qApp->activePopupWidget());
subWindow->showSystemMenu();
QTRY_COMPARE(qApp->activePopupWidget(), qobject_cast<QWidget *>(systemMenu));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(systemMenu->mapToGlobal(QPoint(0, 0)),
(globalPopupPos = subWindow->mapToGlobal(subWindow->contentsRect().topLeft())) );
@@ -1196,6 +1218,9 @@ void tst_QMdiSubWindow::restoreFocusOverCreation()
QTRY_COMPARE(QApplication::focusWidget(), subWidget2->m_lineEdit1);
mdiArea.setActiveSubWindow(subWindow1);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRt - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(QApplication::focusWidget(), subWidget1->m_lineEdit2);
}
@@ -1404,6 +1429,9 @@ void tst_QMdiSubWindow::resizeEvents()
QCOMPARE(window->widget()->windowState(), windowState);
// Make sure we got as many resize events as expected.
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("maximized", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(windowResizeEventSpy.count(), expectedWindowResizeEvents);
QCOMPARE(widgetResizeEventSpy.count(), expectedWidgetResizeEvents);
windowResizeEventSpy.clear();
@@ -1413,6 +1441,10 @@ void tst_QMdiSubWindow::resizeEvents()
window->showNormal();
// Check that the window state is correct.
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("minimized", "Broken on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("shaded", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(window->windowState(), Qt::WindowNoState | Qt::WindowActive);
QCOMPARE(window->widget()->windowState(), Qt::WindowNoState);
@@ -1673,6 +1705,9 @@ void tst_QMdiSubWindow::fixedMinMaxSize()
QCOMPARE(subWindow->maximumSize(), maximumSize);
mdiArea.addSubWindow(subWindow);
subWindow->show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Windows are maximized per default on WinRt ", Abort);
+#endif
QCOMPARE(subWindow->size(), minimumSize);
// Calculate the size of a minimized sub window.
@@ -2057,6 +2092,9 @@ void tst_QMdiSubWindow::testFullScreenState()
subWindow->showFullScreen(); // QMdiSubWindow does not support the fullscreen state. This call
// should be equivalent to setVisible(true) (and not showNormal())
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Windows are maximized per default on WinRt ", Abort);
+#endif
QCOMPARE(subWindow->size(), QSize(300, 300));
}
diff --git a/tests/auto/widgets/widgets/qmenu/BLACKLIST b/tests/auto/widgets/widgets/qmenu/BLACKLIST
index 1c970c43b3..89d12a259f 100644
--- a/tests/auto/widgets/widgets/qmenu/BLACKLIST
+++ b/tests/auto/widgets/widgets/qmenu/BLACKLIST
@@ -10,3 +10,5 @@ osx ci
osx
[tearOff]
osx
+[activeSubMenuPosition]
+winrt
diff --git a/tests/auto/widgets/widgets/qmenu/qmenu.pro b/tests/auto/widgets/widgets/qmenu/qmenu.pro
index 84b6530184..4a492ee941 100644
--- a/tests/auto/widgets/widgets/qmenu/qmenu.pro
+++ b/tests/auto/widgets/widgets/qmenu/qmenu.pro
@@ -5,4 +5,6 @@ SOURCES += tst_qmenu.cpp
macx:{
OBJECTIVE_SOURCES += tst_qmenu_mac.mm
LIBS += -lobjc
+} else {
+ DEFINES += QTEST_QPA_MOUSE_HANDLING
}
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index 0dde385bdb..a88fd8d19c 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -29,6 +29,7 @@
#include <QtTest/QtTest>
#include <QtTest/private/qtesthelpers_p.h>
#include <qapplication.h>
+#include <private/qguiapplication_p.h>
#include <QPushButton>
#include <QMainWindow>
#include <QMenuBar>
@@ -48,6 +49,7 @@
#include <qdebug.h>
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformintegration.h>
using namespace QTestPrivate;
@@ -459,6 +461,9 @@ void tst_QMenu::focus()
void tst_QMenu::overrideMenuAction()
{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("Window activation is not supported");
+
//test the override menu action by first creating an action to which we set its menu
QMainWindow w;
w.resize(300, 200);
@@ -614,6 +619,9 @@ static QMenu *getTornOffMenu()
void tst_QMenu::tearOff()
{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("Window activation is not supported");
+
QWidget widget;
QScopedPointer<QMenu> menu(new QMenu(&widget));
QVERIFY(!menu->isTearOffEnabled()); //default value
@@ -686,6 +694,9 @@ void tst_QMenu::tearOff()
void tst_QMenu::submenuTearOffDontClose()
{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("Window activation is not supported");
+
QWidget widget;
QMenu *menu = new QMenu(&widget);
QVERIFY(!menu->isTearOffEnabled()); //default value
@@ -713,7 +724,8 @@ void tst_QMenu::submenuTearOffDontClose()
// Move then click to avoid the submenu moves from causing it to close
QTest::mouseMove(menu, submenuPos, 100);
QTest::mouseClick(menu, Qt::LeftButton, 0, submenuPos, 100);
- QTRY_VERIFY(QTest::qWaitForWindowActive(submenu));
+ QVERIFY(QTest::qWaitFor([&]() { return submenu->window()->windowHandle(); }));
+ QVERIFY(QTest::qWaitForWindowActive(submenu));
// Make sure we enter the submenu frame directly on the tear-off area
QTest::mouseMove(submenu, QPoint(10, 3), 100);
if (submenu->style()->styleHint(QStyle::SH_Menu_SubMenuDontStartSloppyOnLeave)) {
@@ -843,6 +855,10 @@ private:
void tst_QMenu::activeSubMenuPositionExec()
{
+
+#ifdef Q_OS_WINRT
+ QSKIP("Broken on WinRT - QTBUG-68297");
+#endif
SubMenuPositionExecMenu menu;
menu.exec(QGuiApplication::primaryScreen()->availableGeometry().center());
}
@@ -986,9 +1002,6 @@ void tst_QMenu::task258920_mouseBorder()
QAction *action = menu.addAction("test");
const QPoint center = QApplication::desktop()->availableGeometry().center();
-#ifndef QT_NO_CURSOR
- QCursor::setPos(center - QPoint(100, 100)); // Mac: Ensure cursor is outside
-#endif
menu.popup(center);
QVERIFY(QTest::qWaitForWindowExposed(&menu));
QRect actionRect = menu.actionGeometry(action);
@@ -1082,6 +1095,9 @@ void tst_QMenu::pushButtonPopulateOnAboutToShow()
QTimer::singleShot(300, buttonMenu, SLOT(hide()));
QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center());
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT does not support QTest::mouseClick", Abort);
+#endif
QVERIFY2(!buttonMenu->geometry().intersects(b.geometry()), msgGeometryIntersects(buttonMenu->geometry(), b.geometry()));
// note: we're assuming that, if we previously got the desired geometry, we'll get it here too
@@ -1180,6 +1196,9 @@ void tst_QMenu::click_while_dismissing_submenu()
//this opens the submenu, move two times to emulate user interaction (d->motions > 0 in QMenu)
QTest::mouseMove(menuWindow, menu.rect().center() + QPoint(0,2));
QTest::mouseMove(menuWindow, menu.rect().center() + QPoint(1,3), 60);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT does not support QTest::mouseMove", Abort);
+#endif
QVERIFY(menuShownSpy.wait());
QVERIFY(sub.isVisible());
QVERIFY(QTest::qWaitForWindowExposed(&sub));
@@ -1229,96 +1248,95 @@ public:
void tst_QMenu::QTBUG47515_widgetActionEnterLeave()
{
-#if !QT_CONFIG(cursor)
- QSKIP("This test requires QCursor API");
-#else
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("Window activation is not supported");
if (QGuiApplication::platformName() == QLatin1String("cocoa"))
QSKIP("See QTBUG-63031");
- QPoint screenCenter = QGuiApplication::primaryScreen()->availableGeometry().center();
- QPoint pointOutsideMenu = screenCenter - QPoint(100, 100);
+ const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
+ QRect geometry(QPoint(), availableGeometry.size() / 3);
+ geometry.moveCenter(availableGeometry.center());
+ QPoint pointOutsideMenu = geometry.bottomRight() - QPoint(5, 5);
- QMenu menu("Menu1");
- QMenu submenu("Menu2");
+ QMainWindow topLevel;
+ topLevel.setGeometry(geometry);
- QWidgetAction menuAction(&menu);
- MyWidget w1(&menu);
- menuAction.setDefaultWidget(&w1);
+ QMenuBar *menuBar = topLevel.menuBar();
+ menuBar->setNativeMenuBar(false);
+ QMenu *menu = menuBar->addMenu("Menu1");
+ QMenu *submenu = menu->addMenu("Menu2");
- QWidgetAction submenuAction(&submenu);
- MyWidget w2(&submenu);
- submenuAction.setDefaultWidget(&w2);
+ QWidgetAction *menuAction = new QWidgetAction(menu);
+ MyWidget *w1 = new MyWidget(menu);
+ menuAction->setDefaultWidget(w1);
- QAction *nextMenuAct = menu.addMenu(&submenu);
+ QWidgetAction *submenuAction = new QWidgetAction(submenu);
+ MyWidget *w2 = new MyWidget(submenu);
+ submenuAction->setDefaultWidget(w2);
- menu.addAction(&menuAction);
- submenu.addAction(&submenuAction);
+ QAction *nextMenuAct = menu->addMenu(submenu);
- // Root menu
- {
- QCursor::setPos(pointOutsideMenu);
- QTRY_COMPARE(QCursor::pos(), pointOutsideMenu);
- menu.popup(screenCenter);
- QVERIFY(QTest::qWaitForWindowExposed(&menu));
+ menu->addAction(menuAction);
+ submenu->addAction(submenuAction);
+
+ topLevel.show();
+ topLevel.setWindowTitle(QTest::currentTestFunction());
+ QVERIFY(QTest::qWaitForWindowActive(&topLevel));
+ QWindow *topLevelWindow = topLevel.windowHandle();
+ QVERIFY(topLevelWindow);
- w1.enter = 0;
- w1.leave = 0;
- QPoint w1Center = w1.rect().center();
- const QPoint w1CenterGlobal = w1.mapToGlobal(w1Center);
- QCursor::setPos(w1CenterGlobal);
- QTRY_COMPARE(QCursor::pos(), w1CenterGlobal);
- QVERIFY(w1.isVisible());
- QTRY_COMPARE(w1.leave, 0);
- QTRY_COMPARE(w1.enter, 1);
+ // Root menu: Click on menu bar to open menu1
+ {
+ const QPoint menuActionPos = menuBar->mapTo(&topLevel, menuBar->actionGeometry(menu->menuAction()).center());
+ QTest::mouseClick(topLevelWindow, Qt::LeftButton, Qt::KeyboardModifiers(), menuActionPos);
+ QVERIFY(QTest::qWaitForWindowExposed(menu));
+
+ w1->enter = 0;
+ w1->leave = 0;
+ QPoint w1Center = topLevel.mapFromGlobal(w1->mapToGlobal(w1->rect().center()));
+ QTest::mouseMove(topLevelWindow, w1Center);
+ QVERIFY(w1->isVisible());
+ QTRY_COMPARE(w1->leave, 0);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT does not support QTest::mouseMove", Abort);
+#endif
+ QTRY_COMPARE(w1->enter, 1);
// Check whether leave event is not delivered on mouse move
- w1.move = 0;
- QWidget *nativeParent = w1.nativeParentWidget();
- QVERIFY(nativeParent);
- QWindow *window = nativeParent->windowHandle();
- QVERIFY(window);
- QTest::mouseMove(window, w1.mapTo(nativeParent, w1Center + QPoint(1, 1)));
- QTRY_COMPARE(w1.move, 1);
- QTRY_COMPARE(w1.leave, 0);
- QTRY_COMPARE(w1.enter, 1);
-
- QCursor::setPos(pointOutsideMenu);
- QTRY_COMPARE(QCursor::pos(), pointOutsideMenu);
- QTRY_COMPARE(w1.leave, 1);
- QTRY_COMPARE(w1.enter, 1);
+ w1->move = 0;
+ QTest::mouseMove(topLevelWindow, w1Center + QPoint(1, 1));
+ QTRY_COMPARE(w1->move, 1);
+ QTRY_COMPARE(w1->leave, 0);
+ QTRY_COMPARE(w1->enter, 1);
+
+ QTest::mouseMove(topLevelWindow, topLevel.mapFromGlobal(pointOutsideMenu));
+ QTRY_COMPARE(w1->leave, 1);
+ QTRY_COMPARE(w1->enter, 1);
}
// Submenu
{
- menu.setActiveAction(nextMenuAct);
- QVERIFY(QTest::qWaitForWindowExposed(&submenu));
+ menu->setActiveAction(nextMenuAct);
+ QVERIFY(QTest::qWaitForWindowExposed(submenu));
- QPoint w2Center = w2.rect().center();
- const QPoint w2CenterGlobal = w2.mapToGlobal(w2Center);
- QCursor::setPos(w2CenterGlobal);
- QTRY_COMPARE(QCursor::pos(), w2CenterGlobal);
+ QPoint w2Center = topLevel.mapFromGlobal(w2->mapToGlobal(w2->rect().center()));
+ QTest::mouseMove(topLevelWindow, w2Center);
- QVERIFY(w2.isVisible());
- QTRY_COMPARE(w2.leave, 0);
- QTRY_COMPARE(w2.enter, 1);
+ QVERIFY(w2->isVisible());
+ QTRY_COMPARE(w2->leave, 0);
+ QTRY_COMPARE(w2->enter, 1);
// Check whether leave event is not delivered on mouse move
- w2.move = 0;
- QWidget *nativeParent = w2.nativeParentWidget();
- QVERIFY(nativeParent);
- QWindow *window = nativeParent->windowHandle();
- QVERIFY(window);
- QTest::mouseMove(window, w2.mapTo(nativeParent, w2Center + QPoint(1, 1)));
- QTRY_COMPARE(w2.move, 1);
- QTRY_COMPARE(w2.leave, 0);
- QTRY_COMPARE(w2.enter, 1);
-
- QCursor::setPos(pointOutsideMenu);
- QTRY_COMPARE(QCursor::pos(), pointOutsideMenu);
- QTRY_COMPARE(w2.leave, 1);
- QTRY_COMPARE(w2.enter, 1);
+ w2->move = 0;
+ QTest::mouseMove(topLevelWindow, w2Center + QPoint(1, 1));
+ QTRY_COMPARE(w2->move, 1);
+ QTRY_COMPARE(w2->leave, 0);
+ QTRY_COMPARE(w2->enter, 1);
+
+ QTest::mouseMove(topLevelWindow, topLevel.mapFromGlobal(pointOutsideMenu));
+ QTRY_COMPARE(w2->leave, 1);
+ QTRY_COMPARE(w2->enter, 1);
}
-#endif // QT_NO_CURSOR
}
class MyMenu : public QMenu
@@ -1407,6 +1425,9 @@ void tst_QMenu::QTBUG_56917_wideMenuSize()
menu.popup(QPoint());
QVERIFY(QTest::qWaitForWindowExposed(&menu));
QVERIFY(menu.isVisible());
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(menu.height() <= menuSizeHint.height());
}
@@ -1542,6 +1563,9 @@ void tst_QMenu::menuSize_Scrolling()
getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
QRect lastItem = actionGeometry(actions().at(actions().length() - 1));
QSize s = size();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE( s.width(), lastItem.right() + fw + hmargin + rightMargin + 1);
QMenu::showEvent(e);
}
@@ -1610,6 +1634,12 @@ void tst_QMenu::menuSize_Scrolling()
return;
QTest::keyClick(&menu, Qt::Key_End);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("data8", "Broken on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("data9", "Broken on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("data10", "Broken on WinRT - QTBUG-68297", Abort);
+ QEXPECT_FAIL("data11", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_COMPARE(menu.actionGeometry(actions.last()).right(),
menu.width() - mm.fw - mm.hmargin - leftMargin - 1);
QCOMPARE(menu.actionGeometry(actions.last()).bottom(),
@@ -1618,6 +1648,8 @@ void tst_QMenu::menuSize_Scrolling()
void tst_QMenu::tearOffMenuNotDisplayed()
{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("Window activation is not supported");
QWidget widget;
QScopedPointer<QMenu> menu(new QMenu(&widget));
menu->setTearOffEnabled(true);
@@ -1653,6 +1685,9 @@ void tst_QMenu::tearOffMenuNotDisplayed()
void tst_QMenu::QTBUG_61039_menu_shortcuts()
{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("Window activation is not supported");
+
QAction *actionKamen = new QAction("Action Kamen");
actionKamen->setShortcut(QKeySequence(QLatin1String("K")));
diff --git a/tests/auto/widgets/widgets/qmenubar/BLACKLIST b/tests/auto/widgets/widgets/qmenubar/BLACKLIST
index 9b8e07312d..f897797f00 100644
--- a/tests/auto/widgets/widgets/qmenubar/BLACKLIST
+++ b/tests/auto/widgets/widgets/qmenubar/BLACKLIST
@@ -1,5 +1,8 @@
[check_menuPosition]
ubuntu-16.04
#QTBUG-66255
+ubuntu-18.04
[activatedCount]
*
+[QTBUG_65488_hiddenActionTriggered]
+winrt
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
index ab82268578..3063d43aa6 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -1184,6 +1184,9 @@ void tst_QMenuBar::check_menuPosition()
mbItemRect.moveTo(w.menuBar()->mapToGlobal(mbItemRect.topLeft()));
QTest::keyClick(&w, Qt::Key_M, Qt::AltModifier );
QVERIFY(menu.isActiveWindow());
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "QTest::keyClick does not work on WinRT.", Abort);
+#endif
QCOMPARE(menu.pos(), QPoint(mbItemRect.x(), mbItemRect.top() - menu.height()));
menu.close();
}
@@ -1512,6 +1515,9 @@ void tst_QMenuBar::cornerWidgets()
case Qt::TopLeftCorner:
QVERIFY2(fileMenuGeometry.left() >= cornerWidgetWidth,
msgComparison(fileMenuGeometry.left(), ">=", cornerWidgetWidth));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY2(menuBarWidth - editMenuGeometry.right() < cornerWidgetWidth,
msgComparison(menuBarWidth - editMenuGeometry.right(), "<", cornerWidgetWidth));
break;
@@ -1754,7 +1760,6 @@ void tst_QMenuBar::QTBUG_57404_existingMenuItemException()
mb->addMenu(editMenu);
QAction *copyAction = editMenu->addAction("&Copy");
copyAction->setShortcut(QKeySequence("Ctrl+C"));
- QTest::ignoreMessage(QtWarningMsg, "Menu item \"&Copy\" has unsupported role QPlatformMenuItem::MenuRole(NoRole)");
copyAction->setMenuRole(QAction::NoRole);
QVERIFY(QTest::qWaitForWindowExposed(&mw2));
diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
index a08a8862b8..cfa2ddc4cc 100644
--- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
+++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
@@ -1352,6 +1352,9 @@ void tst_QPlainTextEdit::adjustScrollbars()
QLatin1String txt("\nabc def ghi jkl mno pqr stu vwx");
ed->setPlainText(txt + txt + txt + txt);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "WinRT does not support setMinimum/MaximumSize", Abort);
+#endif
QVERIFY(ed->verticalScrollBar()->maximum() > 0);
ed->moveCursor(QTextCursor::End);
diff --git a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp
index 39989c6dbb..df5ff9d448 100644
--- a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp
+++ b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp
@@ -255,6 +255,9 @@ void tst_QProgressBar::setMinMaxRepaint()
pbar.repainted = false;
pbar.setMinimum(0);
QTest::qWait(50);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QTRY_VERIFY(!pbar.repainted);
// No repaint when setting maximum to the current maximum
diff --git a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
index 625f38d8ae..66f4df4498 100644
--- a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+++ b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
@@ -507,7 +507,7 @@ void tst_QPushButton::sizeHint_data()
#if !defined(QT_NO_STYLE_FUSION)
QTest::newRow("fusion") << QString::fromLatin1("fusion");
#endif
-#if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA)
+#if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA) && !defined(Q_OS_WINRT)
QTest::newRow("windowsvista") << QString::fromLatin1("windowsvista");
#endif
}
diff --git a/tests/auto/widgets/widgets/qsizegrip/BLACKLIST b/tests/auto/widgets/widgets/qsizegrip/BLACKLIST
deleted file mode 100644
index 2c874bcb57..0000000000
--- a/tests/auto/widgets/widgets/qsizegrip/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[hideAndShowOnWindowStateChange:Qt::Window]
-xcb
diff --git a/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp b/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp
index 7610adc155..4cc1810cd4 100644
--- a/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp
+++ b/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp
@@ -107,6 +107,9 @@ void tst_QSizeGrip::hideAndShowOnWindowStateChange_data()
void tst_QSizeGrip::hideAndShowOnWindowStateChange()
{
QFETCH(Qt::WindowType, windowType);
+#ifdef Q_OS_WINRT
+ QSKIP("Broken on WinRT - QTBUG-68297");
+#endif
QWidget *parentWidget = windowType == Qt::Window ? 0 : new QWidget;
TestWidget *widget = new TestWidget(parentWidget, Qt::WindowFlags(windowType));
@@ -152,6 +155,10 @@ void tst_QSizeGrip::hideAndShowOnWindowStateChange()
void tst_QSizeGrip::orientation()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Broken on WinRT - QTBUG-68297");
+#endif
+
TestWidget widget;
widget.setLayout(new QVBoxLayout);
QSizeGrip *sizeGrip = new QSizeGrip(&widget);
@@ -198,7 +205,9 @@ void tst_QSizeGrip::dontCrashOnTLWChange()
// the above setup causes a change of TLW for the size grip,
// and it must not crash.
-
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
QVERIFY(QTest::qWaitForWindowExposed(mw));
}
diff --git a/tests/auto/widgets/widgets/qspinbox/BLACKLIST b/tests/auto/widgets/widgets/qspinbox/BLACKLIST
new file mode 100644
index 0000000000..a38511bfb4
--- /dev/null
+++ b/tests/auto/widgets/widgets/qspinbox/BLACKLIST
@@ -0,0 +1,3 @@
+[stepModifierPressAndHold]
+opensuse ci # QTBUG-69492
+opensuse-leap ci
diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
index 57816f9f70..37bb28dec9 100644
--- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
+++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
@@ -50,6 +50,9 @@
#include <QKeySequence>
#include <QStackedWidget>
#include <QDebug>
+#include <QStyleOptionSpinBox>
+#include <QStyle>
+#include <QProxyStyle>
class SpinBox : public QSpinBox
{
@@ -75,10 +78,54 @@ public:
QSpinBox::wheelEvent(event);
}
#endif
+ void initStyleOption(QStyleOptionSpinBox *option) const
+ {
+ QSpinBox::initStyleOption(option);
+ }
QLineEdit *lineEdit() const { return QSpinBox::lineEdit(); }
};
+class PressAndHoldStyle : public QProxyStyle
+{
+ Q_OBJECT
+public:
+ using QProxyStyle::QProxyStyle;
+
+ int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
+ {
+ switch (hint) {
+ case QStyle::SH_SpinBox_ClickAutoRepeatRate:
+ return 5;
+ case QStyle::SH_SpinBox_ClickAutoRepeatThreshold:
+ return 10;
+ default:
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+ }
+};
+
+class StepModifierStyle : public QProxyStyle
+{
+ Q_OBJECT
+public:
+ using QProxyStyle::QProxyStyle;
+
+ int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
+ {
+ switch (hint) {
+ case QStyle::SH_SpinBox_StepModifier:
+ return stepModifier;
+ default:
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+ }
+
+ Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
+};
+
class tst_QSpinBox : public QObject
{
Q_OBJECT
@@ -143,8 +190,19 @@ private slots:
void setGroupSeparatorShown_data();
void setGroupSeparatorShown();
+ void wheelEvents_data();
void wheelEvents();
+ void adaptiveDecimalStep();
+
+ void stepModifierKeys_data();
+ void stepModifierKeys();
+
+ void stepModifierButtons_data();
+ void stepModifierButtons();
+
+ void stepModifierPressAndHold_data();
+ void stepModifierPressAndHold();
public slots:
void valueChangedHelper(const QString &);
void valueChangedHelper(int);
@@ -158,6 +216,30 @@ typedef QList<int> IntList;
Q_DECLARE_METATYPE(QLocale::Language)
Q_DECLARE_METATYPE(QLocale::Country)
+static QLatin1String modifierToName(Qt::KeyboardModifier modifier)
+{
+ switch (modifier) {
+ case Qt::NoModifier:
+ return QLatin1Literal("No");
+ break;
+ case Qt::ControlModifier:
+ return QLatin1Literal("Ctrl");
+ break;
+ case Qt::ShiftModifier:
+ return QLatin1Literal("Shift");
+ break;
+ case Qt::AltModifier:
+ return QLatin1Literal("Alt");
+ break;
+ case Qt::MetaModifier:
+ return QLatin1Literal("Meta");
+ break;
+ default:
+ qFatal("Unexpected keyboard modifier");
+ return QLatin1String();
+ }
+}
+
// Testing get/set functions
void tst_QSpinBox::getSetCheck()
{
@@ -410,13 +492,17 @@ void tst_QSpinBox::setReadOnly()
QTest::keyClick(&spin, Qt::Key_Up);
QCOMPARE(spin.value(), 1);
spin.setReadOnly(true);
+#ifndef Q_OS_WINRT // QTBUG-68297
QCOMPARE(spin.eventsReceived, QList<QEvent::Type>() << QEvent::ReadOnlyChange);
+#endif
QTest::keyClick(&spin, Qt::Key_Up);
QCOMPARE(spin.value(), 1);
spin.stepBy(1);
QCOMPARE(spin.value(), 2);
spin.setReadOnly(false);
+#ifndef Q_OS_WINRT // QTBUG-68297
QCOMPARE(spin.eventsReceived, QList<QEvent::Type>() << QEvent::ReadOnlyChange << QEvent::ReadOnlyChange);
+#endif
QTest::keyClick(&spin, Qt::Key_Up);
QCOMPARE(spin.value(), 3);
}
@@ -1215,28 +1301,505 @@ void tst_QSpinBox::setGroupSeparatorShown()
QCOMPARE(spinBox.value()+1000, 33000);
}
+void tst_QSpinBox::wheelEvents_data()
+{
+#if QT_CONFIG(wheelevent)
+ QTest::addColumn<QPoint>("angleDelta");
+ QTest::addColumn<int>("qt4Delta");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifier");
+ QTest::addColumn<Qt::MouseEventSource>("source");
+ QTest::addColumn<int>("start");
+ QTest::addColumn<IntList>("expectedValues");
+
+ const auto fractions = {false, true};
+
+ const auto directions = {true, false};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ const auto sources = {Qt::MouseEventNotSynthesized,
+ Qt::MouseEventSynthesizedBySystem,
+ Qt::MouseEventSynthesizedByQt,
+ Qt::MouseEventSynthesizedByApplication};
+
+ const int startValue = 0;
+
+ for (auto fraction : fractions) {
+ for (auto up : directions) {
+
+ const int units = (fraction ? 60 : 120) * (up ? 1 : -1);
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ for (auto source : sources) {
+
+#ifdef Q_OS_MACOS
+ QPoint angleDelta;
+ if ((modifier & Qt::ShiftModifier) &&
+ source == Qt::MouseEventNotSynthesized) {
+ // On macOS the Shift modifier converts vertical
+ // mouse wheel events to horizontal.
+ angleDelta = { units, 0 };
+ } else {
+ // However, this is not the case for trackpad scroll
+ // events.
+ angleDelta = { 0, units };
+ }
+#else
+ const QPoint angleDelta(0, units);
+#endif
+
+ QLatin1String sourceName;
+ switch (source) {
+ case Qt::MouseEventNotSynthesized:
+ sourceName = QLatin1Literal("NotSynthesized");
+ break;
+ case Qt::MouseEventSynthesizedBySystem:
+ sourceName = QLatin1Literal("SynthesizedBySystem");
+ break;
+ case Qt::MouseEventSynthesizedByQt:
+ sourceName = QLatin1Literal("SynthesizedByQt");
+ break;
+ case Qt::MouseEventSynthesizedByApplication:
+ sourceName = QLatin1Literal("SynthesizedByApplication");
+ break;
+ default:
+ qFatal("Unexpected wheel event source");
+ continue;
+ }
+
+ IntList expectedValues;
+ if (fraction)
+ expectedValues << startValue;
+ expectedValues << startValue + steps;
+
+ QTest::addRow("%s%s%sWith%sKeyboardModifier%s",
+ fraction ? "half" : "full",
+ up ? "Up" : "Down",
+ stepModifierName.latin1(),
+ modifierName.latin1(),
+ sourceName.latin1())
+ << angleDelta
+ << units
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << source
+ << startValue
+ << expectedValues;
+ }
+ }
+ }
+ }
+ }
+#else
+ QSKIP("Built with --no-feature-wheelevent");
+#endif
+}
+
void tst_QSpinBox::wheelEvents()
{
#if QT_CONFIG(wheelevent)
+ QFETCH(QPoint, angleDelta);
+ QFETCH(int, qt4Delta);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifier);
+ QFETCH(Qt::MouseEventSource, source);
+ QFETCH(int, start);
+ QFETCH(IntList, expectedValues);
+
SpinBox spinBox;
spinBox.setRange(-20, 20);
+ spinBox.setValue(start);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ spinBox.setStyle(style.data());
+
+ QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta,
+ Qt::Vertical, Qt::NoButton, modifier, Qt::NoScrollPhase,
+ source);
+ for (int expected : expectedValues) {
+ qApp->sendEvent(&spinBox, &event);
+ QCOMPARE(spinBox.value(), expected);
+ }
+#else
+ QSKIP("Built with --no-feature-wheelevent");
+#endif
+}
+
+void tst_QSpinBox::adaptiveDecimalStep()
+{
+ SpinBox spinBox;
+ spinBox.setRange(-100000, 100000);
+ spinBox.setStepType(SpinBox::StepType::AdaptiveDecimalStepType);
+
+ // Positive values
+
spinBox.setValue(0);
- QWheelEvent wheelUp(QPointF(), QPointF(), QPoint(), QPoint(0, 120), 120, Qt::Vertical, Qt::NoButton, Qt::NoModifier);
- spinBox.wheelEvent(&wheelUp);
- QCOMPARE(spinBox.value(), 1);
+ // Go from 0 to 100
+ for (int i = 0; i < 100; i++) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(1);
+ }
- QWheelEvent wheelDown(QPointF(), QPointF(), QPoint(), QPoint(0, -120), -120, Qt::Vertical, Qt::NoButton, Qt::NoModifier);
- spinBox.wheelEvent(&wheelDown);
- spinBox.wheelEvent(&wheelDown);
- QCOMPARE(spinBox.value(), -1);
+ // Go from 100 to 1000
+ for (int i = 100; i < 1000; i += 10) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(1);
+ }
- QWheelEvent wheelHalfUp(QPointF(), QPointF(), QPoint(), QPoint(0, 60), 60, Qt::Vertical, Qt::NoButton, Qt::NoModifier);
- spinBox.wheelEvent(&wheelHalfUp);
- QCOMPARE(spinBox.value(), -1);
- spinBox.wheelEvent(&wheelHalfUp);
- QCOMPARE(spinBox.value(), 0);
-#endif
+ // Go from 1000 to 10000
+ for (int i = 1000; i < 10000; i += 100) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(1);
+ }
+
+ // Test decreasing the values now
+
+ // Go from 10000 down to 1000
+ for (int i = 10000; i > 1000; i -= 100) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(-1);
+ }
+
+ // Go from 1000 down to 100
+ for (int i = 1000; i > 100; i -= 10) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(-1);
+ }
+
+ // Negative values
+
+ spinBox.setValue(0);
+
+ // Go from 0 to -100
+ for (int i = 0; i > -100; i--) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(-1);
+ }
+
+ // Go from -100 to -1000
+ for (int i = -100; i > -1000; i -= 10) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(-1);
+ }
+
+ // Go from 1000 to 10000
+ for (int i = -1000; i > -10000; i -= 100) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(-1);
+ }
+
+ // Test increasing the values now
+
+ // Go from -10000 up to -1000
+ for (int i = -10000; i < -1000; i += 100) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(1);
+ }
+
+ // Go from -1000 up to -100
+ for (int i = -1000; i < -100; i += 10) {
+ QCOMPARE(spinBox.value(), i);
+ spinBox.stepBy(1);
+ }
+}
+
+void tst_QSpinBox::stepModifierKeys_data()
+{
+ QTest::addColumn<int>("startValue");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<QTestEventList>("keys");
+ QTest::addColumn<int>("expectedValue");
+
+ const auto keyList = {Qt::Key_Up, Qt::Key_Down};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ for (auto key : keyList) {
+
+ const bool up = key == Qt::Key_Up;
+ Q_ASSERT(up || key == Qt::Key_Down);
+
+ const int startValue = up ? 0.0 : 10.0;
+
+ for (auto modifier : modifierList) {
+
+ QTestEventList keys;
+ keys.addKeyClick(key, modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ const int expectedValue = startValue + steps;
+
+ QTest::addRow("%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ modifierName.latin1())
+ << startValue
+ << static_cast<int>(stepModifier)
+ << keys
+ << expectedValue;
+ }
+ }
+ }
+}
+
+void tst_QSpinBox::stepModifierKeys()
+{
+ QFETCH(int, startValue);
+ QFETCH(int, stepModifier);
+ QFETCH(QTestEventList, keys);
+ QFETCH(int, expectedValue);
+
+ QSpinBox spin(0);
+ spin.setValue(startValue);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ spin.setStyle(style.data());
+
+ spin.show();
+ QVERIFY(QTest::qWaitForWindowActive(&spin));
+
+ QCOMPARE(spin.value(), startValue);
+ keys.simulate(&spin);
+ QCOMPARE(spin.value(), expectedValue);
+}
+
+void tst_QSpinBox::stepModifierButtons_data()
+{
+ QTest::addColumn<QStyle::SubControl>("subControl");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
+ QTest::addColumn<int>("startValue");
+ QTest::addColumn<int>("expectedValue");
+
+ const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ for (auto subControl : subControls) {
+
+ const bool up = subControl == QStyle::SC_SpinBoxUp;
+ Q_ASSERT(up || subControl == QStyle::SC_SpinBoxDown);
+
+ const int startValue = up ? 0 : 10;
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ const int expectedValue = startValue + steps;
+
+ QTest::addRow("%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ modifierName.latin1())
+ << subControl
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << startValue
+ << expectedValue;
+ }
+ }
+ }
+}
+
+void tst_QSpinBox::stepModifierButtons()
+{
+ QFETCH(QStyle::SubControl, subControl);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifiers);
+ QFETCH(int, startValue);
+ QFETCH(int, expectedValue);
+
+ SpinBox spin(0);
+ spin.setRange(-20, 20);
+ spin.setValue(startValue);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
+ new StepModifierStyle);
+ style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ spin.setStyle(style.data());
+
+ spin.show();
+ QVERIFY(QTest::qWaitForWindowActive(&spin));
+
+ QStyleOptionSpinBox spinBoxStyleOption;
+ spin.initStyleOption(&spinBoxStyleOption);
+
+ const QRect buttonRect = spin.style()->subControlRect(
+ QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &spin);
+
+ QCOMPARE(spin.value(), startValue);
+ QTest::mouseClick(&spin, Qt::LeftButton, modifiers, buttonRect.center());
+ QCOMPARE(spin.value(), expectedValue);
+}
+
+void tst_QSpinBox::stepModifierPressAndHold_data()
+{
+ QTest::addColumn<QStyle::SubControl>("subControl");
+ QTest::addColumn<int>("stepModifier");
+ QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
+ QTest::addColumn<int>("expectedStepModifier");
+
+ const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
+
+ const auto modifierList = {Qt::NoModifier,
+ Qt::ShiftModifier,
+ Qt::ControlModifier,
+ Qt::AltModifier,
+ Qt::MetaModifier};
+
+ const auto validStepModifierList = {Qt::NoModifier,
+ Qt::ControlModifier,
+ Qt::ShiftModifier};
+
+ for (auto subControl : subControls) {
+
+ const bool up = subControl == QStyle::SC_SpinBoxUp;
+ Q_ASSERT(up || subControl == QStyle::SC_SpinBoxDown);
+
+ for (auto modifier : modifierList) {
+
+ const Qt::KeyboardModifiers modifiers(modifier);
+
+ const auto modifierName = modifierToName(modifier);
+ if (modifierName.isEmpty())
+ continue;
+
+ for (auto stepModifier : validStepModifierList) {
+
+ const auto stepModifierName = modifierToName(stepModifier);
+ if (stepModifierName.isEmpty())
+ continue;
+
+ const int steps = (modifier & stepModifier ? 10 : 1)
+ * (up ? 1 : -1);
+
+ QTest::addRow("%s%sWith%sKeyboardModifier",
+ up ? "up" : "down",
+ stepModifierName.latin1(),
+ modifierName.latin1())
+ << subControl
+ << static_cast<int>(stepModifier)
+ << modifiers
+ << steps;
+ }
+ }
+ }
+}
+
+void tst_QSpinBox::stepModifierPressAndHold()
+{
+ QFETCH(QStyle::SubControl, subControl);
+ QFETCH(int, stepModifier);
+ QFETCH(Qt::KeyboardModifiers, modifiers);
+ QFETCH(int, expectedStepModifier);
+
+ SpinBox spin(0);
+ spin.setRange(-100, 100);
+ spin.setValue(0);
+
+ QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> stepModifierStyle(
+ new StepModifierStyle(new PressAndHoldStyle));
+ stepModifierStyle->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
+ spin.setStyle(stepModifierStyle.data());
+
+ QSignalSpy spy(&spin, QOverload<int>::of(&SpinBox::valueChanged));
+ // TODO: remove debug output when QTBUG-69492 is fixed
+ connect(&spin, QOverload<int>::of(&SpinBox::valueChanged), [=]() {
+ qDebug() << QTime::currentTime() << "valueChanged emitted";
+ });
+
+ spin.show();
+ QVERIFY(QTest::qWaitForWindowActive(&spin));
+
+ QStyleOptionSpinBox spinBoxStyleOption;
+ spin.initStyleOption(&spinBoxStyleOption);
+
+ const QRect buttonRect = spin.style()->subControlRect(
+ QStyle::CC_SpinBox, &spinBoxStyleOption, subControl, &spin);
+
+ // TODO: remove debug output when QTBUG-69492 is fixed
+ qDebug() << "QGuiApplication::focusWindow():" << QGuiApplication::focusWindow();
+ qDebug() << "QGuiApplication::topLevelWindows():" << QGuiApplication::topLevelWindows();
+ QTest::mousePress(&spin, Qt::LeftButton, modifiers, buttonRect.center());
+ QTRY_VERIFY2(spy.length() >= 3, qPrintable(QString::fromLatin1(
+ "Expected valueChanged() to be emitted 3 or more times, but it was only emitted %1 times").arg(spy.length())));
+ QTest::mouseRelease(&spin, Qt::LeftButton, modifiers, buttonRect.center());
+
+ const auto value = spy.last().at(0);
+ QVERIFY(value.type() == QVariant::Int);
+ QCOMPARE(value.toInt(), spy.length() * expectedStepModifier);
}
QTEST_MAIN(tst_QSpinBox)
diff --git a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
index 77abf5e5a7..d744cece9c 100644
--- a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
+++ b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
@@ -773,12 +773,16 @@ void tst_QSplitter::replaceWidget()
const int expectedResizeCount = visible ? 1 : 0; // new widget only
const int expectedPaintCount = visible && !collapsed ? 2 : 0; // splitter and new widget
QTRY_COMPARE(ef.resizeCount, expectedResizeCount);
+#ifndef Q_OS_WINRT // QTBUG-68297
QTRY_COMPARE(ef.paintCount, expectedPaintCount);
+#endif
QCOMPARE(newWidget->parentWidget(), &sp);
QCOMPARE(newWidget->isVisible(), visible);
if (visible && !collapsed)
QCOMPARE(newWidget->geometry(), oldGeom);
+#ifndef Q_OS_WINRT // QTBUG-68297
QCOMPARE(newWidget->size().isEmpty(), !visible || collapsed);
+#endif
delete res;
}
QCOMPARE(sp.count(), count);
@@ -830,7 +834,9 @@ void tst_QSplitter::replaceWidgetWithSplitterChild()
QTRY_VERIFY(ef.resizeCount > 0);
QTRY_VERIFY(ef.paintCount > 0);
QCOMPARE(sp.count(), count + 1);
+#ifndef Q_OS_WINRT // QTBUG-68297
QCOMPARE(sp.sizes().mid(0, count), sizes);
+#endif
QCOMPARE(sp.sizes().last(), sibling->width());
} else {
// No-op for the rest
diff --git a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp
index 14ee6cb9bd..928910344c 100644
--- a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp
+++ b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp
@@ -141,6 +141,9 @@ void tst_QStatusBar::setSizeGripEnabled()
QTRY_VERIFY(statusBar->isVisible());
QPointer<QSizeGrip> sizeGrip = statusBar->findChild<QSizeGrip *>();
QVERIFY(sizeGrip);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(sizeGrip->isVisible());
statusBar->setSizeGripEnabled(true);
diff --git a/tests/auto/widgets/widgets/qtextbrowser/qtextbrowser.pro b/tests/auto/widgets/widgets/qtextbrowser/qtextbrowser.pro
index 5416c1c71f..9680ffd871 100644
--- a/tests/auto/widgets/widgets/qtextbrowser/qtextbrowser.pro
+++ b/tests/auto/widgets/widgets/qtextbrowser/qtextbrowser.pro
@@ -5,3 +5,5 @@ SOURCES += tst_qtextbrowser.cpp
QT += widgets testlib
TESTDATA += *.html subdir/*
+
+builtin_testdata: DEFINES += BUILTIN_TESTDATA
diff --git a/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp b/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp
index 700fa505c1..8a1b228c71 100644
--- a/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp
+++ b/tests/auto/widgets/widgets/qtextbrowser/tst_qtextbrowser.cpp
@@ -29,7 +29,6 @@
#include <QtTest/QtTest>
#include <qtextbrowser.h>
-#include <qdatetime.h>
#include <qapplication.h>
#include <qscrollbar.h>
@@ -114,7 +113,7 @@ void tst_QTextBrowser::cleanup()
void tst_QTextBrowser::noReloadOnAnchorJump()
{
- QUrl url = QUrl::fromLocalFile("anchor.html");
+ QUrl url = QUrl::fromLocalFile(QFINDTESTDATA("anchor.html"));
browser->htmlLoadAttempts = 0;
browser->setSource(url);
@@ -130,11 +129,11 @@ void tst_QTextBrowser::noReloadOnAnchorJump()
void tst_QTextBrowser::bgColorOnSourceChange()
{
- browser->setSource(QUrl::fromLocalFile("pagewithbg.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("pagewithbg.html")));
QVERIFY(browser->document()->rootFrame()->frameFormat().hasProperty(QTextFormat::BackgroundBrush));
QCOMPARE(browser->document()->rootFrame()->frameFormat().background().color(), QColor(Qt::blue));
- browser->setSource(QUrl::fromLocalFile("pagewithoutbg.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("pagewithoutbg.html")));
QVERIFY(!browser->document()->rootFrame()->frameFormat().hasProperty(QTextFormat::BackgroundBrush));
}
@@ -147,7 +146,7 @@ void tst_QTextBrowser::forwardButton()
QVERIFY(browser->historyTitle(0).isEmpty());
QVERIFY(browser->historyTitle(1).isEmpty());
- browser->setSource(QUrl::fromLocalFile("pagewithbg.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("pagewithbg.html")));
QVERIFY(!forwardEmissions.isEmpty());
QVariant val = forwardEmissions.takeLast()[0];
@@ -160,12 +159,12 @@ void tst_QTextBrowser::forwardButton()
QVERIFY(!val.toBool());
QVERIFY(browser->historyTitle(-1).isEmpty());
- QCOMPARE(browser->historyUrl(0), QUrl::fromLocalFile("pagewithbg.html"));
+ QCOMPARE(browser->historyUrl(0), QUrl::fromLocalFile(QFINDTESTDATA("pagewithbg.html")));
QCOMPARE(browser->documentTitle(), QString("Page With BG"));
QCOMPARE(browser->historyTitle(0), QString("Page With BG"));
QVERIFY(browser->historyTitle(1).isEmpty());
- browser->setSource(QUrl::fromLocalFile("anchor.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("anchor.html")));
QVERIFY(!forwardEmissions.isEmpty());
val = forwardEmissions.takeLast()[0];
@@ -197,8 +196,11 @@ void tst_QTextBrowser::forwardButton()
QCOMPARE(browser->historyTitle(0), QString("Page With BG"));
QCOMPARE(browser->historyTitle(1), QString("Sample Anchor"));
- browser->setSource(QUrl("pagewithoutbg.html"));
+ browser->setSource(QUrl(QFINDTESTDATA("pagewithoutbg.html")));
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QVERIFY(!forwardEmissions.isEmpty());
val = forwardEmissions.takeLast()[0];
QCOMPARE(val.type(), QVariant::Bool);
@@ -212,11 +214,11 @@ void tst_QTextBrowser::forwardButton()
void tst_QTextBrowser::viewportPositionInHistory()
{
- browser->setSource(QUrl::fromLocalFile("bigpage.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("bigpage.html")));
browser->scrollToAnchor("bottom");
QVERIFY(browser->verticalScrollBar()->value() > 0);
- browser->setSource(QUrl::fromLocalFile("pagewithbg.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("pagewithbg.html")));
QCOMPARE(browser->verticalScrollBar()->value(), 0);
browser->backward();
@@ -225,6 +227,9 @@ void tst_QTextBrowser::viewportPositionInHistory()
void tst_QTextBrowser::relativeLinks()
{
+#ifdef BUILTIN_TESTDATA
+ QSKIP("Relative links cannot be checked when resources are used to package tests.");
+#endif
QSignalSpy sourceChangedSpy(browser, SIGNAL(sourceChanged(QUrl)));
browser->setSource(QUrl("subdir/../qtextbrowser.html"));
QVERIFY(!browser->document()->isEmpty());
@@ -256,11 +261,11 @@ void tst_QTextBrowser::relativeLinks()
void tst_QTextBrowser::anchors()
{
- browser->setSource(QUrl::fromLocalFile("bigpage.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("bigpage.html")));
browser->setSource(QUrl("#bottom"));
QVERIFY(browser->verticalScrollBar()->value() > 0);
- browser->setSource(QUrl::fromLocalFile("bigpage.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("bigpage.html")));
browser->setSource(QUrl("#id-anchor"));
QVERIFY(browser->verticalScrollBar()->value() > 0);
}
@@ -420,6 +425,9 @@ void tst_QTextBrowser::clearHistory()
void tst_QTextBrowser::sourceInsideLoadResource()
{
+#ifdef Q_OS_WINRT
+ QSKIP("Paths cannot be compared if applications are sandboxed.");
+#endif
QUrl url = QUrl::fromLocalFile("pagewithimage.html");
browser->setSource(url);
QCOMPARE(browser->lastResource, QUrl::fromLocalFile(QDir::current().filePath("foobar.png")));
@@ -515,7 +523,11 @@ void tst_QTextBrowser::adjacentAnchors()
void tst_QTextBrowser::loadResourceOnRelativeLocalFiles()
{
+#ifndef BUILTIN_TESTDATA
browser->setSource(QUrl::fromLocalFile("subdir/index.html"));
+#else
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("subdir/index.html")));
+#endif
QVERIFY(!browser->toPlainText().isEmpty());
QVariant v = browser->loadResource(QTextDocument::HtmlResource, QUrl("../anchor.html"));
QVERIFY(v.isValid());
@@ -526,7 +538,7 @@ void tst_QTextBrowser::loadResourceOnRelativeLocalFiles()
void tst_QTextBrowser::focusIndicator()
{
HackBrowser *browser = new HackBrowser;
- browser->setSource(QUrl::fromLocalFile("firstpage.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("firstpage.html")));
QVERIFY(!browser->textCursor().hasSelection());
browser->focusTheNextChild();
@@ -578,7 +590,7 @@ void tst_QTextBrowser::focusIndicator()
void tst_QTextBrowser::focusHistory()
{
HackBrowser *browser = new HackBrowser;
- browser->setSource(QUrl::fromLocalFile("firstpage.html"));
+ browser->setSource(QUrl::fromLocalFile(QFINDTESTDATA("firstpage.html")));
QVERIFY(!browser->textCursor().hasSelection());
browser->focusTheNextChild();
diff --git a/tests/auto/widgets/widgets/qtextedit/qtextedit.pro b/tests/auto/widgets/widgets/qtextedit/qtextedit.pro
index 8b39ab59b7..de8531daec 100644
--- a/tests/auto/widgets/widgets/qtextedit/qtextedit.pro
+++ b/tests/auto/widgets/widgets/qtextedit/qtextedit.pro
@@ -6,3 +6,5 @@ QT += widgets widgets-private gui-private core-private testlib
SOURCES += tst_qtextedit.cpp
osx: LIBS += -framework AppKit
+
+TESTDATA += fullWidthSelection
diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
index f383d430d6..6a2ae4951b 100644
--- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
@@ -1702,6 +1702,9 @@ void tst_QTextEdit::adjustScrollbars()
QLatin1String txt("\nabc def ghi jkl mno pqr stu vwx");
ed->setText(txt + txt + txt + txt);
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "setMinimum/MaximumSize does not work on WinRT", Abort);
+#endif
QVERIFY(ed->verticalScrollBar()->maximum() > 0);
ed->moveCursor(QTextCursor::End);
@@ -1882,6 +1885,9 @@ void tst_QTextEdit::copyPasteBackgroundImage()
QBrush ba = a->cellAt(0, 0).format().background();
QBrush bb = b->cellAt(0, 0).format().background();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Fails on WinRT - QTBUG-68297", Abort);
+#endif
QCOMPARE(ba.style(), Qt::TexturePattern);
QCOMPARE(ba.style(), bb.style());
diff --git a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp
index a7a62496e6..44b30fa794 100644
--- a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp
+++ b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp
@@ -272,6 +272,9 @@ void tst_QToolButton::qtbug_34759_sizeHintResetWhenSettingMenu()
button1.show();
button2.show();
+#ifdef Q_OS_WINRT
+ QEXPECT_FAIL("", "Winrt does not support more than 1 native top level widget.", Abort);
+#endif
QVERIFY(QTest::qWaitForWindowExposed(&button1));
QVERIFY(QTest::qWaitForWindowExposed(&button2));
diff --git a/tests/auto/widgets/widgets/widgets.pro b/tests/auto/widgets/widgets/widgets.pro
index c098108edc..c6325aac15 100644
--- a/tests/auto/widgets/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets/widgets.pro
@@ -55,4 +55,4 @@ SUBDIRS=\
qtextedit \
qtoolbar \
-qtConfig(opengl): SUBDIRS += qopenglwidget
+!winrt:qtConfig(opengl): SUBDIRS += qopenglwidget
diff --git a/tests/baselineserver/shared/qbaselinetest.cpp b/tests/baselineserver/shared/qbaselinetest.cpp
index ef38e21edb..11fb208f20 100644
--- a/tests/baselineserver/shared/qbaselinetest.cpp
+++ b/tests/baselineserver/shared/qbaselinetest.cpp
@@ -46,6 +46,7 @@ static BaselineProtocol proto;
static bool connected = false;
static bool triedConnecting = false;
static bool dryRunMode = false;
+static enum { UploadMissing, UploadAll, UploadNone } baselinePolicy = UploadMissing;
static QByteArray curFunction;
static ImageItemList itemList;
@@ -71,12 +72,26 @@ void handleCmdLineArgs(int *argcp, char ***argvp)
if (arg == "-simfail") {
simfail = true;
+ } else if (arg == "-fuzzlevel") {
+ i++;
+ bool ok = false;
+ (void)nextArg.toInt(&ok);
+ if (!ok) {
+ qWarning() << "-fuzzlevel requires integer parameter";
+ showHelp = true;
+ break;
+ }
+ customInfo.insert("FuzzLevel", QString::fromLatin1(nextArg));
} else if (arg == "-auto") {
customAutoModeSet = true;
customInfo.setAdHocRun(false);
} else if (arg == "-adhoc") {
customAutoModeSet = true;
customInfo.setAdHocRun(true);
+ } else if (arg == "-setbaselines") {
+ baselinePolicy = UploadAll;
+ } else if (arg == "-nosetbaselines") {
+ baselinePolicy = UploadNone;
} else if (arg == "-compareto") {
i++;
int split = qMax(0, nextArg.indexOf('='));
@@ -106,8 +121,11 @@ void handleCmdLineArgs(int *argcp, char ***argvp)
QTextStream out(stdout);
out << "\n Baseline testing (lancelot) options:\n";
out << " -simfail : Force an image comparison mismatch. For testing purposes.\n";
+ out << " -fuzzlevel <int> : Specify the percentage of fuzziness in comparison. Overrides server default. 0 means exact match.\n";
out << " -auto : Inform server that this run is done by a daemon, CI system or similar.\n";
out << " -adhoc (default) : The inverse of -auto; this run is done by human, e.g. for testing.\n";
+ out << " -setbaselines : Store ALL rendered images as new baselines. Forces replacement of previous baselines.\n";
+ out << " -nosetbaselines : Do not store rendered images as new baselines when previous baselines are missing.\n";
out << " -compareto KEY=VAL : Force comparison to baselines from a different client,\n";
out << " for example: -compareto QtVersion=4.8.0\n";
out << " Multiple -compareto client specifications may be given.\n";
@@ -276,8 +294,8 @@ bool compareItem(const ImageItem &baseline, const QImage &img, QByteArray *msg,
return true;
break;
case ImageItem::BaselineNotFound:
- if (!customInfo.overrides().isEmpty()) {
- qWarning() << "Cannot compare to other system's baseline: No such baseline found on server.";
+ if (!customInfo.overrides().isEmpty() || baselinePolicy == UploadNone) {
+ qWarning() << "Cannot compare to baseline: No such baseline found on server.";
return true;
}
if (proto.submitNewBaseline(item, &srvMsg))
@@ -298,6 +316,14 @@ bool compareItem(const ImageItem &baseline, const QImage &img, QByteArray *msg,
qWarning() << "Failed to report image match to server:" << srvMsg;
return true;
}
+ // At this point, we have established a legitimate mismatch
+ if (baselinePolicy == UploadAll) {
+ if (proto.submitNewBaseline(item, &srvMsg))
+ qDebug() << msg->constData() << "Forcing new baseline; uploaded ok.";
+ else
+ qDebug() << msg->constData() << "Forcing new baseline; uploading failed:" << srvMsg;
+ return true;
+ }
bool fuzzyMatch = false;
bool res = proto.submitMismatch(item, &srvMsg, &fuzzyMatch);
if (res && fuzzyMatch) {
diff --git a/tests/benchmarks/corelib/tools/qtimezone/main.cpp b/tests/benchmarks/corelib/tools/qtimezone/main.cpp
new file mode 100644
index 0000000000..65455a7261
--- /dev/null
+++ b/tests/benchmarks/corelib/tools/qtimezone/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure <david.faure@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QTimeZone>
+#include <QTest>
+#include <qdebug.h>
+
+class tst_QTimeZone : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void isTimeZoneIdAvailable();
+};
+
+void tst_QTimeZone::isTimeZoneIdAvailable()
+{
+ const QList<QByteArray> available = QTimeZone::availableTimeZoneIds();
+ QBENCHMARK {
+ for (const QByteArray &id : available)
+ QVERIFY(QTimeZone::isTimeZoneIdAvailable(id));
+ }
+}
+
+QTEST_MAIN(tst_QTimeZone)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/tools/qtimezone/qtimezone.pro b/tests/benchmarks/corelib/tools/qtimezone/qtimezone.pro
new file mode 100644
index 0000000000..d0531b568b
--- /dev/null
+++ b/tests/benchmarks/corelib/tools/qtimezone/qtimezone.pro
@@ -0,0 +1,4 @@
+TARGET = tst_bench_qtimezone
+QT = core testlib
+
+SOURCES += main.cpp
diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro
index af9b7d241d..ca9c0a6f89 100644
--- a/tests/benchmarks/corelib/tools/tools.pro
+++ b/tests/benchmarks/corelib/tools/tools.pro
@@ -15,6 +15,7 @@ SUBDIRS = \
qstring \
qstringbuilder \
qstringlist \
+ qtimezone \
qvector \
qalgorithms
diff --git a/tests/benchmarks/gui/graphicsview/graphicsview.pro b/tests/benchmarks/gui/graphicsview/graphicsview.pro
deleted file mode 100644
index d89a00c4b9..0000000000
--- a/tests/benchmarks/gui/graphicsview/graphicsview.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = \
- functional \
- qgraphicsanchorlayout \
- qgraphicsitem \
- #qgraphicslayout \ # FIXME: broken
- qgraphicsscene \
- qgraphicsview \
- qgraphicswidget
-
-!qtHaveModule(widgets): SUBDIRS -= \
- qgraphicsanchorlayout \
- qgraphicsitem \
- qgraphicsscene \
- qgraphicsview \
- qgraphicswidget
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
deleted file mode 100644
index 313cc56b0b..0000000000
--- a/tests/benchmarks/gui/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qtest.h>
-#include <QGraphicsItem>
-#include <QGraphicsScene>
-#include <QGraphicsView>
-
-class tst_QGraphicsItem : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QGraphicsItem();
- virtual ~tst_QGraphicsItem();
-
-public slots:
- void initTestCase();
- void init();
- void cleanup();
-
-private slots:
- void setParentItem();
- void setParentItem_deep();
- void setParentItem_deep_reversed();
- void deleteItemWithManyChildren();
- void setPos_data();
- void setPos();
- void setTransform_data();
- void setTransform();
- void rotate();
- void scale();
- void shear();
- void translate();
-};
-
-tst_QGraphicsItem::tst_QGraphicsItem()
-{
-}
-
-tst_QGraphicsItem::~tst_QGraphicsItem()
-{
-}
-
-static inline void processEvents()
-{
- QApplication::processEvents();
- QApplication::processEvents();
-}
-
-void tst_QGraphicsItem::initTestCase()
-{
- processEvents();
- QTest::qWait(1500);
- processEvents();
-}
-
-void tst_QGraphicsItem::init()
-{
- processEvents();
-}
-
-void tst_QGraphicsItem::cleanup()
-{
-}
-
-void tst_QGraphicsItem::setParentItem()
-{
- QBENCHMARK {
- QGraphicsRectItem rect;
- QGraphicsRectItem *childRect = new QGraphicsRectItem;
- childRect->setParentItem(&rect);
- }
-}
-
-void tst_QGraphicsItem::setParentItem_deep()
-{
- QBENCHMARK {
- QGraphicsRectItem rect;
- QGraphicsRectItem *lastRect = &rect;
- for (int i = 0; i < 10; ++i) {
- QGraphicsRectItem *childRect = new QGraphicsRectItem;
- childRect->setParentItem(lastRect);
- lastRect = childRect;
- }
- QGraphicsItem *first = rect.childItems().first();
- first->setParentItem(0);
- }
-}
-
-void tst_QGraphicsItem::setParentItem_deep_reversed()
-{
- QBENCHMARK {
- QGraphicsRectItem *lastRect = new QGraphicsRectItem;
- for (int i = 0; i < 100; ++i) {
- QGraphicsRectItem *parentRect = new QGraphicsRectItem;
- lastRect->setParentItem(parentRect);
- lastRect = parentRect;
- }
- delete lastRect;
- }
-}
-
-void tst_QGraphicsItem::deleteItemWithManyChildren()
-{
- QBENCHMARK {
- QGraphicsRectItem *rect = new QGraphicsRectItem;
- for (int i = 0; i < 1000; ++i)
- new QGraphicsRectItem(rect);
- delete rect;
- }
-}
-
-void tst_QGraphicsItem::setPos_data()
-{
- QTest::addColumn<QPointF>("pos");
-
- QTest::newRow("0, 0") << QPointF(0, 0);
- QTest::newRow("10, 10") << QPointF(10, 10);
- QTest::newRow("-10, -10") << QPointF(-10, -10);
-}
-
-void tst_QGraphicsItem::setPos()
-{
- QFETCH(QPointF, pos);
-
- QGraphicsScene scene;
- QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));
- processEvents();
-
- QBENCHMARK {
- rect->setPos(10, 10);
- }
-}
-
-void tst_QGraphicsItem::setTransform_data()
-{
- QTest::addColumn<QTransform>("transform");
-
- QTest::newRow("rotate 45z") << QTransform().rotate(45);
- QTest::newRow("scale 2x2") << QTransform().scale(2, 2);
- QTest::newRow("translate 100, 100") << QTransform().translate(100, 100);
- QTest::newRow("rotate 45x 45y 45z") << QTransform().rotate(45, Qt::XAxis)
- .rotate(45, Qt::YAxis).rotate(45, Qt::ZAxis);
-}
-
-void tst_QGraphicsItem::setTransform()
-{
- QFETCH(QTransform, transform);
-
- QGraphicsScene scene;
- QGraphicsRectItem *item = scene.addRect(QRectF(0, 0, 100, 100));
- processEvents();
-
- QBENCHMARK {
- item->setTransform(transform);
- }
-}
-
-void tst_QGraphicsItem::rotate()
-{
- QGraphicsScene scene;
- QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
- processEvents();
-
- const QTransform rotate(QTransform().rotate(45));
- QBENCHMARK {
- item->setTransform(rotate, true);
- }
-}
-
-void tst_QGraphicsItem::scale()
-{
- QGraphicsScene scene;
- QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
- processEvents();
-
- const QTransform scale(QTransform::fromScale(2, 2));
- QBENCHMARK {
- item->setTransform(scale, true);
- }
-}
-
-void tst_QGraphicsItem::shear()
-{
- QGraphicsScene scene;
- QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
- processEvents();
-
- const QTransform shear = QTransform().shear(1.5, 1.5);
- QBENCHMARK {
- item->setTransform(shear, true);
- }
-}
-
-void tst_QGraphicsItem::translate()
-{
- QGraphicsScene scene;
- QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
- processEvents();
-
- const QTransform translate = QTransform::fromTranslate(100, 100);
- QBENCHMARK {
- item->setTransform(translate, true);
- }
-}
-
-QTEST_MAIN(tst_QGraphicsItem)
-#include "tst_qgraphicsitem.moc"
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro b/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro
deleted file mode 100644
index 9026fb37d8..0000000000
--- a/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE = app
-TARGET = tst_bench_qgraphicslayout
-QT += testlib
-SOURCES += tst_qgraphicslayout.cpp
-
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp
deleted file mode 100644
index 1db130203a..0000000000
--- a/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtGui/qgraphicslayout.h>
-#include <QtGui/qgraphicslinearlayout.h>
-#include <QtGui/qgraphicswidget.h>
-#include <QtGui/qgraphicsview.h>
-
-class tst_QGraphicsLayout : public QObject
-{
- Q_OBJECT
-public:
- tst_QGraphicsLayout() {}
- ~tst_QGraphicsLayout() {}
-
-private slots:
- void invalidate();
-};
-
-
-class RectWidget : public QGraphicsWidget
-{
-public:
- RectWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0) : QGraphicsWidget(parent, wFlags), setGeometryCalls(0) {}
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
- {
- Q_UNUSED(option);
- Q_UNUSED(widget);
- painter->drawRoundRect(rect());
- painter->drawLine(rect().topLeft(), rect().bottomRight());
- painter->drawLine(rect().bottomLeft(), rect().topRight());
- }
-
- void setGeometry(const QRectF &rect)
- {
- //qDebug() << "setGeometry():" << this->data(0).toString();
- setGeometryCalls->insert(this, rect);
- QGraphicsWidget::setGeometry(rect);
- }
-
- void callUpdateGeometry() {
- QGraphicsWidget::updateGeometry();
- }
-
- QMap<RectWidget*, QRectF> *setGeometryCalls;
-};
-
-/**
- * Test to see how much time is needed to resize all widgets in a
- * layout-widget-layout-widget-.... hierarchy from the point where a
- * leaf widget changes its size hint. (updateGeometry() is called).
- *
- * If you run the test for 4.7 you'll get some really high numbers, but
- * that's because they also include painting (and possible processing of
- * some other events).
- */
-void tst_QGraphicsLayout::invalidate()
-{
- QGraphicsLayout::setInstantInvalidatePropagation(true);
- QGraphicsScene scene;
- QGraphicsView *view = new QGraphicsView(&scene);
- QMap<RectWidget*, QRectF> setGeometryCalls;
-
- RectWidget *window = new RectWidget(0, Qt::Window);
- window->setGeometryCalls = &setGeometryCalls;
- window->setData(0, QString(QChar('a')));
-
- scene.addItem(window);
- RectWidget *leaf = 0;
- const int depth = 100;
- RectWidget *parent = window;
- for (int i = 1; i < depth; ++i) {
- QGraphicsLinearLayout *l = new QGraphicsLinearLayout(parent);
- l->setContentsMargins(0,0,0,0);
- RectWidget *child = new RectWidget;
- child->setData(0, QString(QChar('a' + i)));
- child->setGeometryCalls = &setGeometryCalls;
- l->addItem(child);
- parent = child;
- }
- leaf = parent;
- leaf->setMinimumSize(QSizeF(1,1));
-
- view->show();
-
- QVERIFY(QTest::qWaitForWindowShown(view));
-
- // ...then measure...
-
- int pass = 1;
-
- // should be as small as possible, to reduce overhead of painting
- QSizeF size(1, 1);
- setGeometryCalls.clear();
- QBENCHMARK {
- leaf->setMinimumSize(size);
- leaf->setMaximumSize(size);
- while (setGeometryCalls.count() < depth) {
- QApplication::sendPostedEvents();
- }
- // force a resize on each widget, this will ensure
- // that each iteration will resize all 50 widgets
- int w = int(size.width());
- w^=2;
- size.setWidth(w);
- }
- delete view;
- QGraphicsLayout::setInstantInvalidatePropagation(false);
-}
-
-QTEST_MAIN(tst_QGraphicsLayout)
-
-#include "tst_qgraphicslayout.moc"
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro b/tests/benchmarks/gui/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro
deleted file mode 100644
index 7126c8ecd6..0000000000
--- a/tests/benchmarks/gui/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE = app
-TARGET = tst_bench_qgraphicslinearlayout
-QT += testlib
-SOURCES += tst_qgraphicslinearlayout.cpp
-
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/benchmarks/gui/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
deleted file mode 100644
index 325fcfbb09..0000000000
--- a/tests/benchmarks/gui/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtGui/qgraphicslinearlayout.h>
-#include <QtGui/qgraphicswidget.h>
-#include <QtGui/qgraphicsview.h>
-
-class tst_QGraphicsLinearLayout : public QObject
-{
- Q_OBJECT
-public:
- tst_QGraphicsLinearLayout() {}
- ~tst_QGraphicsLinearLayout() {}
-
-private slots:
- void heightForWidth_data();
- void heightForWidth();
-};
-
-
-struct MySquareWidget : public QGraphicsWidget
-{
- MySquareWidget() {}
- virtual QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const
- {
- if (which != Qt::PreferredSize)
- return QGraphicsWidget::sizeHint(which, constraint);
- if (constraint.width() < 0)
- return QGraphicsWidget::sizeHint(which, constraint);
- return QSizeF(constraint.width(), constraint.width());
- }
-};
-
-void tst_QGraphicsLinearLayout::heightForWidth_data()
-{
- QTest::addColumn<bool>("hfw");
- QTest::addColumn<bool>("nested");
-
- QTest::newRow("hfw") << true << false;
- QTest::newRow("hfw, nested") << true << true;
- QTest::newRow("not hfw") << false << false;
- QTest::newRow("not hfw, nested") << false << true;
-}
-
-void tst_QGraphicsLinearLayout::heightForWidth()
-{
- QFETCH(bool, hfw);
- QFETCH(bool, nested);
-
- QGraphicsScene scene;
- QGraphicsWidget *form = new QGraphicsWidget;
- scene.addItem(form);
-
- QGraphicsLinearLayout *outerlayout = 0;
- if (nested) {
- outerlayout = new QGraphicsLinearLayout(form);
- for (int i = 0; i < 8; i++) {
- QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical);
- outerlayout->addItem(layout);
- outerlayout = layout;
- }
- }
-
- QGraphicsLinearLayout *qlayout = 0;
- qlayout = new QGraphicsLinearLayout(Qt::Vertical);
- if (nested)
- outerlayout->addItem(qlayout);
- else
- form->setLayout(qlayout);
-
- MySquareWidget *widget = new MySquareWidget;
- for (int i = 0; i < 1; i++) {
- widget = new MySquareWidget;
- QSizePolicy sizepolicy = widget->sizePolicy();
- sizepolicy.setHeightForWidth(hfw);
- widget->setSizePolicy(sizepolicy);
- qlayout->addItem(widget);
- }
- // make sure only one iteration is done.
- // run with tst_QGraphicsLinearLayout.exe "heightForWidth" -tickcounter -iterations 6
- // this will iterate 6 times the whole test, (not only the benchmark)
- // which should reduce warmup time and give a realistic picture of the performance of
- // effectiveSizeHint()
- QSizeF constraint(hfw ? 100 : -1, -1);
- QBENCHMARK {
- (void)form->effectiveSizeHint(Qt::PreferredSize, constraint);
- }
-
-}
-
-
-QTEST_MAIN(tst_QGraphicsLinearLayout)
-
-#include "tst_qgraphicslinearlayout.moc"
diff --git a/tests/benchmarks/gui/gui.pro b/tests/benchmarks/gui/gui.pro
index e943347938..b5853c9e81 100644
--- a/tests/benchmarks/gui/gui.pro
+++ b/tests/benchmarks/gui/gui.pro
@@ -1,21 +1,13 @@
TEMPLATE = subdirs
SUBDIRS = \
animation \
- graphicsview \
image \
- itemviews \
kernel \
math3d \
painting \
- styles \
text
TRUSTED_BENCHMARKS += \
- graphicsview/functional/GraphicsViewBenchmark \
- graphicsview/qgraphicsview \
painting/qtracebench
include(../trusted-benchmarks.pri)
-
-!qtHaveModule(widgets): SUBDIRS -= \
- itemviews
diff --git a/tests/benchmarks/gui/image/image.pro b/tests/benchmarks/gui/image/image.pro
index 89008290fc..8dfb4d0ae9 100644
--- a/tests/benchmarks/gui/image/image.pro
+++ b/tests/benchmarks/gui/image/image.pro
@@ -6,6 +6,3 @@ SUBDIRS = \
qimagescale \
qpixmap \
qpixmapcache
-
-!qtHaveModule(widgets)|!qtHaveModule(network): SUBDIRS -= \
- qimagereader
diff --git a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro
index 33e0c50bba..29f7f6b16e 100644
--- a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro
+++ b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro
@@ -8,4 +8,3 @@ SOURCES += tst_qimagereader.cpp
qtConfig(gif): DEFINES += QTEST_HAVE_GIF
qtConfig(jpeg): DEFINES += QTEST_HAVE_JPEG
-QT += network
diff --git a/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp b/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp
index 76d46f9484..d81d5bb01a 100644
--- a/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp
@@ -35,8 +35,6 @@
#include <QImageWriter>
#include <QPixmap>
#include <QSet>
-#include <QTcpSocket>
-#include <QTcpServer>
#include <QTimer>
typedef QMap<QString, QString> QStringMap;
diff --git a/tests/benchmarks/gui/kernel/kernel.pro b/tests/benchmarks/gui/kernel/kernel.pro
index 607e58b6c0..acc6dc402d 100644
--- a/tests/benchmarks/gui/kernel/kernel.pro
+++ b/tests/benchmarks/gui/kernel/kernel.pro
@@ -1,6 +1,4 @@
TEMPLATE = subdirs
-qtHaveModule(widgets): SUBDIRS = \
- qapplication \
- qwidget \
+SUBDIRS = \
qguimetatype \
qguivariant
diff --git a/tests/benchmarks/gui/painting/painting.pro b/tests/benchmarks/gui/painting/painting.pro
index d08dfa707b..400c2994a6 100644
--- a/tests/benchmarks/gui/painting/painting.pro
+++ b/tests/benchmarks/gui/painting/painting.pro
@@ -10,5 +10,4 @@ SUBDIRS = \
!qtHaveModule(widgets): SUBDIRS -= \
qpainter \
- qtracebench \
qtbench
diff --git a/tests/benchmarks/gui/painting/qpainter/tst_qpainter.cpp b/tests/benchmarks/gui/painting/qpainter/tst_qpainter.cpp
index 0248d6f855..485306a8ac 100644
--- a/tests/benchmarks/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/benchmarks/gui/painting/qpainter/tst_qpainter.cpp
@@ -29,7 +29,6 @@
#include <qtest.h>
#include <QPainter>
#include <QPixmap>
-#include <QDialog>
#include <QImage>
#include <QPaintEngine>
#include <QTileRules>
@@ -650,6 +649,9 @@ void tst_QPainter::drawPixmapImage_data_helper(bool pixmaps)
"A2RGB30_pm",
"Alpha8",
"Grayscale8",
+ "RGBx64",
+ "RGBA64",
+ "RGBA64_pm",
};
const QImage::Format pixmapFormats[] = {
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro
index ded6a06795..ded6a06795 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.pro
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc
index 18ae04dd69..18ae04dd69 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/GraphicsViewBenchmark.qrc
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/main.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/main.cpp
index 87ab80d74f..87ab80d74f 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/main.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/main.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png
index 525b5559a0..525b5559a0 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_001_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png
index 3d932985a6..3d932985a6 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_002_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png
index 556cfcba6a..556cfcba6a 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_003_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png
index 94acf9e669..94acf9e669 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_004_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png
index ed0c7c42f0..ed0c7c42f0 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_005_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png
index d4b4dc3a8e..d4b4dc3a8e 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_006_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png
index 0e45d18e4d..0e45d18e4d 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_007_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png
index 0c25540ac9..0c25540ac9 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_008_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png
index ce435ea537..ce435ea537 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_009_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png
index 021db25882..021db25882 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_man_010_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png
index 0051da326f..0051da326f 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_001_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png
index e8a946a8ba..e8a946a8ba 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_002_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png
index b2bb851f69..b2bb851f69 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_003_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png
index 871c075d05..871c075d05 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_004_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png
index d4c18b8bb0..d4c18b8bb0 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_picture_005_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png
index 10a5947234..10a5947234 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_001_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png
index 65b4e03c5b..65b4e03c5b 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_002_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png
index 935ec07171..935ec07171 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_003_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png
index fbc1a937fd..fbc1a937fd 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_004_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png
index af96d3e149..af96d3e149 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_005_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png
index fb4192d35f..fb4192d35f 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_006_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png
index f5d6dea0b0..f5d6dea0b0 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_007_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png
index d08b8dc364..d08b8dc364 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_008_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png
index 768b97de6e..768b97de6e 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_009_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png
index d1fe28e61e..d1fe28e61e 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/avatars/avatar_woman_010_58x58.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg
index 1552bafa17..1552bafa17 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_360x640px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg
index 5589110950..5589110950 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_background_horisontal_640x360px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg
index 665675b1e8..665675b1e8 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_default_icon_52x52px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg
index db9fc7af33..db9fc7af33 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_divider_360x76px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg
index dae2bd4842..dae2bd4842 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_list_highlighter_360x76px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg
index fe12e782a6..fe12e782a6 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_idle_33x33px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg
index 0c973f1bc9..0c973f1bc9 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_offline_33x33px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg
index fcb434afda..fcb434afda 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_contact_status_online_33x33px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg
index 897be81dc5..897be81dc5 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scroll_16x80px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg
index 3baec2f4b6..3baec2f4b6 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_scrollbar_7x14px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg
index dd6fb70a8d..dd6fb70a8d 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_left_14x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg
index cabf9285a7..cabf9285a7 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_middle_14x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg
index f3a795b88d..f3a795b88d 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_status_field_right_14x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg
index a0efd347fb..a0efd347fb 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_356x96px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg
index 0a3efd8111..0a3efd8111 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_topbar_horisontal_636x96px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg
index 1ffeedde1b..1ffeedde1b 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_default_icon_68x68px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg
index 71f49aa719..71f49aa719 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_idle_38x38px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg
index 84c2514adc..84c2514adc 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_offline_38x38px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg
index 76daf31809..76daf31809 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/blue_SVG/blue_user_status_online_38x38px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt
index dc7e7d81b6..dc7e7d81b6 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/areacodes.txt
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt
index 4bf14924a7..4bf14924a7 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesF.txt
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt
index 189d8d015f..189d8d015f 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/firstnamesM.txt
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt
index 35b3f9f9c2..35b3f9f9c2 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/contacts/lastnames.txt
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg
index 8daf275b19..8daf275b19 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_360x640px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg
index c2b070a3b1..c2b070a3b1 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_background_horisontal_640x360px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg
index 6e34f255b2..6e34f255b2 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_53x53px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg
index 29c284de08..29c284de08 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_default_icon_highlight_53x53px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg
index db9fc7af33..db9fc7af33 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_divider_360x76px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg
index 0ee3ea23e6..0ee3ea23e6 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_list_highlighter_357x80px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg
index 925d3eb36e..925d3eb36e 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_idle_27x47.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg
index 6f74723f09..6f74723f09 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_offline_27x47.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg
index 56951605de..56951605de 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_contact_status_online_27x47.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg
index 4f6482afa5..4f6482afa5 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scroll_5x80px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg
index 54a40c3cc8..54a40c3cc8 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_scrollbar_5x14px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg
index a21c91df48..a21c91df48 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_left_14x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg
index b84200d9b1..b84200d9b1 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_middle_10x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg
index 231560dd9e..231560dd9e 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_status_field_right_14x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg
index 679d9a5305..679d9a5305 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_356x96px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg
index 1ef4fb9224..1ef4fb9224 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_topbar_horisontal_636x96px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg
index 4df0214e56..4df0214e56 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_default_icon_84x68px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg
index 2d6da38ad0..2d6da38ad0 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_idle_24x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg
index d5920268b1..d5920268b1 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_offline_24x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg
index 46ad07dbbd..46ad07dbbd 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/resources/lime_SVG/lime_user_status_online_24x24px.svg
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp
index 00481a638d..00481a638d 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h
index 7373f66deb..7373f66deb 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemcontainer.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp
index 961cf4e03c..961cf4e03c 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h
index 8cd295ba89..8cd295ba89 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractitemview.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp
index 39847b8edb..39847b8edb 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h
index f681ca9fce..f681ca9fce 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractscrollarea.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp
index 6a6df15e23..6a6df15e23 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h
index 4f9fbf4623..4f9fbf4623 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/abstractviewitem.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp
index 9f5f16d373..9f5f16d373 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h
index 0cb0ee778c..0cb0ee778c 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/backgrounditem.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp
index b8bd55789d..b8bd55789d 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h
index 8e76b88463..8e76b88463 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/button.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp
index 226c60cec8..226c60cec8 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h
index eaddeac59d..eaddeac59d 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/commandline.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp
index 7809b38050..7809b38050 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h
index bcb9681d5d..bcb9681d5d 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/dummydatagen.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp
index 3682ae55e1..3682ae55e1 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h
index 7e247b63a4..7e247b63a4 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/gvbwidget.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp
index a081e1b064..a081e1b064 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h
index 48d1bafe9f..48d1bafe9f 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/iconitem.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp
index eabe3671e5..eabe3671e5 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h
index a69b60c9e2..a69b60c9e2 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri
index 55b551ef8f..55b551ef8f 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglist.pri
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp
index 5aa93256ff..5aa93256ff 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h
index 467f193604..467f193604 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/itemrecyclinglistview.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp
index 5fb2ee1a51..5fb2ee1a51 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h
index 2c1f14b20e..2c1f14b20e 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/label.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp
index 1872bcc9d3..1872bcc9d3 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h
index 4f033803ac..4f033803ac 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitem.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp
index 0e4520d0a8..0e4520d0a8 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h
index ba35023bbc..ba35023bbc 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcache.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp
index 496919214d..496919214d 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h
index 62c9450c38..62c9450c38 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listitemcontainer.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp
index fe87a2abc4..fe87a2abc4 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h
index 623c90dedc..623c90dedc 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listmodel.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp
index 6e09a09d81..6e09a09d81 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h
index 0dfd41a1c3..0dfd41a1c3 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/listwidget.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp
index c8ccb60dbb..c8ccb60dbb 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h
index d7fe404023..d7fe404023 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/mainview.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp
index 1cc75d569b..1cc75d569b 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h
index 074d5b9d95..074d5b9d95 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/menu.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp
index c0aed25abb..c0aed25abb 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h
index 021a8b8902..021a8b8902 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/recycledlistitem.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h
index b03f09048a..b03f09048a 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/resourcemoninterface.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp
index 81f123e2b7..81f123e2b7 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h
index 966052676c..966052676c 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scrollbar.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp
index 203ea7e046..203ea7e046 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h
index 8f40dcfd16..8f40dcfd16 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h
index cf11c7fa02..cf11c7fa02 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/scroller_p.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp
index 9cb44882a6..9cb44882a6 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h
index dc228162c4..dc228162c4 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/settings.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp
index 941cab8c21..941cab8c21 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h
index 3c1ec4f82a..3c1ec4f82a 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelist.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp
index 67f34859c1..67f34859c1 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h
index ad606cda8f..ad606cda8f 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/simplelistview.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp
index 06851b0fd8..06851b0fd8 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h
index 4aafd0c288..4aafd0c288 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/theme.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp
index 1209b4a0f7..1209b4a0f7 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h
index 4ae63d8755..4ae63d8755 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/themeevent.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp
index 7c3d97b859..7c3d97b859 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h
index 53750ca706..53750ca706 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/topbar.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp
index 59ed50157b..59ed50157b 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.cpp
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h
index a18df35957..a18df35957 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h
index bd4047c134..bd4047c134 100644
--- a/tests/benchmarks/gui/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h
+++ b/tests/benchmarks/widgets/graphicsview/functional/GraphicsViewBenchmark/widgets/webview_p.h
diff --git a/tests/benchmarks/gui/graphicsview/functional/functional.pro b/tests/benchmarks/widgets/graphicsview/functional/functional.pro
index 3c2979448b..3c2979448b 100644
--- a/tests/benchmarks/gui/graphicsview/functional/functional.pro
+++ b/tests/benchmarks/widgets/graphicsview/functional/functional.pro
diff --git a/tests/benchmarks/widgets/graphicsview/graphicsview.pro b/tests/benchmarks/widgets/graphicsview/graphicsview.pro
new file mode 100644
index 0000000000..8344cd4edf
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/graphicsview.pro
@@ -0,0 +1,10 @@
+TEMPLATE = subdirs
+SUBDIRS = \
+ functional \
+ qgraphicsanchorlayout \
+ qgraphicsitem \
+ qgraphicslayout \
+ qgraphicslinearlayout \
+ qgraphicsscene \
+ qgraphicsview \
+ qgraphicswidget
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro b/tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro
index 01c0dbd653..01c0dbd653 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp
index b15aad04cd..b15aad04cd 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsitem/qgraphicsitem.pro b/tests/benchmarks/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro
index 461ec13263..461ec13263 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsitem/qgraphicsitem.pro
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro
diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
new file mode 100644
index 0000000000..56b34fff2a
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QGraphicsItem>
+#include <QGraphicsScene>
+#include <QGraphicsView>
+
+class tst_QGraphicsItem : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QGraphicsItem();
+ virtual ~tst_QGraphicsItem();
+
+public slots:
+ void initTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void setParentItem();
+ void setParentItem_deep();
+ void setParentItem_deep_reversed();
+ void deleteItemWithManyChildren();
+ void setPos_data();
+ void setPos();
+ void setTransform_data();
+ void setTransform();
+ void rotate();
+ void scale();
+ void shear();
+ void translate();
+};
+
+tst_QGraphicsItem::tst_QGraphicsItem()
+{
+}
+
+tst_QGraphicsItem::~tst_QGraphicsItem()
+{
+}
+
+static inline void processEvents()
+{
+ QApplication::processEvents();
+ QApplication::processEvents();
+}
+
+void tst_QGraphicsItem::initTestCase()
+{
+ processEvents();
+ QTest::qWait(1500);
+ processEvents();
+}
+
+void tst_QGraphicsItem::init()
+{
+ processEvents();
+}
+
+void tst_QGraphicsItem::cleanup()
+{
+}
+
+void tst_QGraphicsItem::setParentItem()
+{
+ QBENCHMARK {
+ QGraphicsRectItem rect;
+ QGraphicsRectItem *childRect = new QGraphicsRectItem;
+ childRect->setParentItem(&rect);
+ }
+}
+
+void tst_QGraphicsItem::setParentItem_deep()
+{
+ QBENCHMARK {
+ QGraphicsRectItem rect;
+ QGraphicsRectItem *lastRect = &rect;
+ for (int i = 0; i < 10; ++i) {
+ QGraphicsRectItem *childRect = new QGraphicsRectItem;
+ childRect->setParentItem(lastRect);
+ lastRect = childRect;
+ }
+ QGraphicsItem *first = rect.childItems().first();
+ first->setParentItem(0);
+ }
+}
+
+void tst_QGraphicsItem::setParentItem_deep_reversed()
+{
+ QBENCHMARK {
+ QGraphicsRectItem *lastRect = new QGraphicsRectItem;
+ for (int i = 0; i < 100; ++i) {
+ QGraphicsRectItem *parentRect = new QGraphicsRectItem;
+ lastRect->setParentItem(parentRect);
+ lastRect = parentRect;
+ }
+ delete lastRect;
+ }
+}
+
+void tst_QGraphicsItem::deleteItemWithManyChildren()
+{
+ QBENCHMARK {
+ QGraphicsRectItem *rect = new QGraphicsRectItem;
+ for (int i = 0; i < 1000; ++i)
+ new QGraphicsRectItem(rect);
+ delete rect;
+ }
+}
+
+void tst_QGraphicsItem::setPos_data()
+{
+ QTest::addColumn<QPointF>("pos");
+
+ QTest::newRow("0, 0") << QPointF(0, 0);
+ QTest::newRow("10, 10") << QPointF(10, 10);
+ QTest::newRow("-10, -10") << QPointF(-10, -10);
+}
+
+void tst_QGraphicsItem::setPos()
+{
+ QFETCH(QPointF, pos);
+
+ QGraphicsScene scene;
+ QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));
+ processEvents();
+
+ QBENCHMARK {
+ rect->setPos(pos);
+ }
+}
+
+void tst_QGraphicsItem::setTransform_data()
+{
+ QTest::addColumn<QTransform>("transform");
+
+ QTest::newRow("rotate 45z") << QTransform().rotate(45);
+ QTest::newRow("scale 2x2") << QTransform().scale(2, 2);
+ QTest::newRow("translate 100, 100") << QTransform().translate(100, 100);
+ QTest::newRow("rotate 45x 45y 45z") << QTransform().rotate(45, Qt::XAxis)
+ .rotate(45, Qt::YAxis).rotate(45, Qt::ZAxis);
+}
+
+void tst_QGraphicsItem::setTransform()
+{
+ QFETCH(QTransform, transform);
+
+ QGraphicsScene scene;
+ QGraphicsRectItem *item = scene.addRect(QRectF(0, 0, 100, 100));
+ processEvents();
+
+ QBENCHMARK {
+ item->setTransform(transform);
+ }
+}
+
+void tst_QGraphicsItem::rotate()
+{
+ QGraphicsScene scene;
+ QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
+ processEvents();
+
+ const QTransform rotate(QTransform().rotate(45));
+ QBENCHMARK {
+ item->setTransform(rotate, true);
+ }
+}
+
+void tst_QGraphicsItem::scale()
+{
+ QGraphicsScene scene;
+ QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
+ processEvents();
+
+ const QTransform scale(QTransform::fromScale(2, 2));
+ QBENCHMARK {
+ item->setTransform(scale, true);
+ }
+}
+
+void tst_QGraphicsItem::shear()
+{
+ QGraphicsScene scene;
+ QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
+ processEvents();
+
+ const QTransform shear = QTransform().shear(1.5, 1.5);
+ QBENCHMARK {
+ item->setTransform(shear, true);
+ }
+}
+
+void tst_QGraphicsItem::translate()
+{
+ QGraphicsScene scene;
+ QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
+ processEvents();
+
+ const QTransform translate = QTransform::fromTranslate(100, 100);
+ QBENCHMARK {
+ item->setTransform(translate, true);
+ }
+}
+
+QTEST_MAIN(tst_QGraphicsItem)
+#include "tst_qgraphicsitem.moc"
diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicslayout/qgraphicslayout.pro b/tests/benchmarks/widgets/graphicsview/qgraphicslayout/qgraphicslayout.pro
new file mode 100644
index 0000000000..a20d9e0921
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicslayout/qgraphicslayout.pro
@@ -0,0 +1,5 @@
+TEMPLATE = app
+TARGET = tst_bench_qgraphicslayout
+QT += testlib widgets
+SOURCES += tst_qgraphicslayout.cpp
+
diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp
new file mode 100644
index 0000000000..5c97d7f738
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <QGraphicsLayout>
+#include <QGraphicsLinearLayout>
+#include <QGraphicsWidget>
+#include <QGraphicsView>
+
+class tst_QGraphicsLayout : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QGraphicsLayout() {}
+ ~tst_QGraphicsLayout() {}
+
+private slots:
+ void invalidate();
+};
+
+
+class RectWidget : public QGraphicsWidget
+{
+public:
+ RectWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0) : QGraphicsWidget(parent, wFlags), setGeometryCalls(0) {}
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+ painter->drawRoundRect(rect());
+ painter->drawLine(rect().topLeft(), rect().bottomRight());
+ painter->drawLine(rect().bottomLeft(), rect().topRight());
+ }
+
+ void setGeometry(const QRectF &rect)
+ {
+ //qDebug() << "setGeometry():" << this->data(0).toString();
+ setGeometryCalls->insert(this, rect);
+ QGraphicsWidget::setGeometry(rect);
+ }
+
+ void callUpdateGeometry() {
+ QGraphicsWidget::updateGeometry();
+ }
+
+ QMap<RectWidget*, QRectF> *setGeometryCalls;
+};
+
+/**
+ * Test to see how much time is needed to resize all widgets in a
+ * layout-widget-layout-widget-.... hierarchy from the point where a
+ * leaf widget changes its size hint. (updateGeometry() is called).
+ *
+ * If you run the test for 4.7 you'll get some really high numbers, but
+ * that's because they also include painting (and possible processing of
+ * some other events).
+ */
+void tst_QGraphicsLayout::invalidate()
+{
+ QGraphicsLayout::setInstantInvalidatePropagation(true);
+ QGraphicsScene *scene = new QGraphicsScene;
+ QGraphicsView *view = new QGraphicsView(scene);
+ QMap<RectWidget*, QRectF> *setGeometryCalls = new QMap<RectWidget*, QRectF>;
+
+ RectWidget *window = new RectWidget(0, Qt::Window);
+ window->setGeometryCalls = setGeometryCalls;
+ window->setData(0, QString(QChar('a')));
+
+ scene->addItem(window);
+ RectWidget *leaf = 0;
+ const int depth = 100;
+ RectWidget *parent = window;
+ for (int i = 1; i < depth; ++i) {
+ QGraphicsLinearLayout *l = new QGraphicsLinearLayout(parent);
+ l->setContentsMargins(0,0,0,0);
+ RectWidget *child = new RectWidget;
+ child->setData(0, QString(QChar('a' + i)));
+ child->setGeometryCalls = setGeometryCalls;
+ l->addItem(child);
+ parent = child;
+ }
+ leaf = parent;
+ leaf->setMinimumSize(QSizeF(1,1));
+
+ view->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(view));
+
+ // ...then measure...
+
+ int pass = 1;
+
+ // should be as small as possible, to reduce overhead of painting
+ QSizeF size(1, 1);
+ setGeometryCalls->clear();
+ QBENCHMARK {
+ leaf->setMinimumSize(size);
+ leaf->setMaximumSize(size);
+ while (setGeometryCalls->count() < depth) {
+ QApplication::sendPostedEvents();
+ }
+ // force a resize on each widget, this will ensure
+ // that each iteration will resize all 50 widgets
+ int w = int(size.width());
+ w^=2;
+ size.setWidth(w);
+ }
+ window->setGeometryCalls = nullptr;
+ delete view;
+ delete scene;
+ QGraphicsLayout::setInstantInvalidatePropagation(false);
+ delete setGeometryCalls;
+}
+
+QTEST_MAIN(tst_QGraphicsLayout)
+
+#include "tst_qgraphicslayout.moc"
diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro b/tests/benchmarks/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro
new file mode 100644
index 0000000000..e9a9e9353e
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro
@@ -0,0 +1,5 @@
+TEMPLATE = app
+TARGET = tst_bench_qgraphicslinearlayout
+QT += testlib widgets
+SOURCES += tst_qgraphicslinearlayout.cpp
+
diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
new file mode 100644
index 0000000000..254d147e52
--- /dev/null
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <QGraphicsLinearLayout>
+#include <QGraphicsWidget>
+#include <QGraphicsView>
+
+class tst_QGraphicsLinearLayout : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QGraphicsLinearLayout() {}
+ ~tst_QGraphicsLinearLayout() {}
+
+private slots:
+ void heightForWidth_data();
+ void heightForWidth();
+};
+
+
+struct MySquareWidget : public QGraphicsWidget
+{
+ MySquareWidget() {}
+ virtual QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const
+ {
+ if (which != Qt::PreferredSize)
+ return QGraphicsWidget::sizeHint(which, constraint);
+ if (constraint.width() < 0)
+ return QGraphicsWidget::sizeHint(which, constraint);
+ return QSizeF(constraint.width(), constraint.width());
+ }
+};
+
+void tst_QGraphicsLinearLayout::heightForWidth_data()
+{
+ QTest::addColumn<bool>("hfw");
+ QTest::addColumn<bool>("nested");
+
+ QTest::newRow("hfw") << true << false;
+ QTest::newRow("hfw, nested") << true << true;
+ QTest::newRow("not hfw") << false << false;
+ QTest::newRow("not hfw, nested") << false << true;
+}
+
+void tst_QGraphicsLinearLayout::heightForWidth()
+{
+ QFETCH(bool, hfw);
+ QFETCH(bool, nested);
+
+ QGraphicsScene scene;
+ QGraphicsWidget *form = new QGraphicsWidget;
+ scene.addItem(form);
+
+ QGraphicsLinearLayout *outerlayout = 0;
+ if (nested) {
+ outerlayout = new QGraphicsLinearLayout(form);
+ for (int i = 0; i < 8; i++) {
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical);
+ outerlayout->addItem(layout);
+ outerlayout = layout;
+ }
+ }
+
+ QGraphicsLinearLayout *qlayout = 0;
+ qlayout = new QGraphicsLinearLayout(Qt::Vertical);
+ if (nested)
+ outerlayout->addItem(qlayout);
+ else
+ form->setLayout(qlayout);
+
+ MySquareWidget *widget = new MySquareWidget;
+ for (int i = 0; i < 1; i++) {
+ widget = new MySquareWidget;
+ QSizePolicy sizepolicy = widget->sizePolicy();
+ sizepolicy.setHeightForWidth(hfw);
+ widget->setSizePolicy(sizepolicy);
+ qlayout->addItem(widget);
+ }
+ // make sure only one iteration is done.
+ // run with tst_QGraphicsLinearLayout.exe "heightForWidth" -tickcounter -iterations 6
+ // this will iterate 6 times the whole test, (not only the benchmark)
+ // which should reduce warmup time and give a realistic picture of the performance of
+ // effectiveSizeHint()
+ QSizeF constraint(hfw ? 100 : -1, -1);
+ QBENCHMARK {
+ (void)form->effectiveSizeHint(Qt::PreferredSize, constraint);
+ }
+
+}
+
+
+QTEST_MAIN(tst_QGraphicsLinearLayout)
+
+#include "tst_qgraphicslinearlayout.moc"
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsscene/qgraphicsscene.pro b/tests/benchmarks/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro
index 769f84423e..769f84423e 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsscene/qgraphicsscene.pro
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
index 6145fabbf8..6145fabbf8 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp
index 57ab62b1c3..57ab62b1c3 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.debug b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.debug
index 8fe1e5b0f1..8fe1e5b0f1 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.debug
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.debug
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.h b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.h
index c14f8c41de..c14f8c41de 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.h
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.h
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.pro b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.pro
index 8ef79cef23..8ef79cef23 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/chip.pro
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.pro
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/fileprint.png b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/fileprint.png
index ba7c02dc18..ba7c02dc18 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/fileprint.png
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/fileprint.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/images.qrc b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/images.qrc
index c7cdf0c4c0..c7cdf0c4c0 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/images.qrc
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/images.qrc
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/main.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/main.cpp
index 53fcfa7192..53fcfa7192 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/main.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/main.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.cpp
index b162461403..b162461403 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.h b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.h
index b0e12b448a..b0e12b448a 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.h
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/mainwindow.h
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/qt4logo.png b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/qt4logo.png
index 157e86ed64..157e86ed64 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/qt4logo.png
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/qt4logo.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateleft.png b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/rotateleft.png
index 8cfa931986..8cfa931986 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateleft.png
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/rotateleft.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateright.png b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/rotateright.png
index ec5e8664a1..ec5e8664a1 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/rotateright.png
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/rotateright.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp
index de4e9e5ad7..de4e9e5ad7 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/view.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.h b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/view.h
index e20543858b..e20543858b 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/view.h
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/view.h
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomin.png b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/zoomin.png
index 8b0daeea48..8b0daeea48 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomin.png
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/zoomin.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomout.png b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/zoomout.png
index 1575dd24f6..1575dd24f6 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/chipTest/zoomout.png
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/zoomout.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp
index e0cc0f8eb4..e0cc0f8eb4 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/moveItems/main.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/moveItems.pro b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/moveItems/moveItems.pro
index 28dcadcbfa..28dcadcbfa 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/moveItems/moveItems.pro
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/moveItems/moveItems.pro
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp
index 1fbb229cd8..1fbb229cd8 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/scrolltest/main.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/scrolltest.pro b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/scrolltest/scrolltest.pro
index 28dcadcbfa..28dcadcbfa 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/benchapps/scrolltest/scrolltest.pro
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/scrolltest/scrolltest.pro
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.cpp
index cf82282bfe..cf82282bfe 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.h b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.h
index d991f771e2..d991f771e2 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chip.h
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.h
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.cpp
index dfa08b6869..dfa08b6869 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.h
index d85686c94e..d85686c94e 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.h
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.pri b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.pri
index 105117de30..105117de30 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.pri
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.pri
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/images.qrc b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/images.qrc
index 73e8620b25..73e8620b25 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/images.qrc
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/images.qrc
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/qt4logo.png b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/qt4logo.png
index 157e86ed64..157e86ed64 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/qt4logo.png
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/qt4logo.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/images/designer.png b/tests/benchmarks/widgets/graphicsview/qgraphicsview/images/designer.png
index 0988fcee3f..0988fcee3f 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/images/designer.png
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/images/designer.png
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine-big.jpeg b/tests/benchmarks/widgets/graphicsview/qgraphicsview/images/wine-big.jpeg
index 9900a50f94..9900a50f94 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine-big.jpeg
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/images/wine-big.jpeg
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine.jpeg b/tests/benchmarks/widgets/graphicsview/qgraphicsview/images/wine.jpeg
index 8fe1d3a67d..8fe1d3a67d 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/images/wine.jpeg
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/images/wine.jpeg
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.pro b/tests/benchmarks/widgets/graphicsview/qgraphicsview/qgraphicsview.pro
index 3d48959f3c..3d48959f3c 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.pro
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/qgraphicsview.pro
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.qrc b/tests/benchmarks/widgets/graphicsview/qgraphicsview/qgraphicsview.qrc
index 3681648f56..3681648f56 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/qgraphicsview.qrc
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/qgraphicsview.qrc
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/random.data b/tests/benchmarks/widgets/graphicsview/qgraphicsview/random.data
index 190a36c707..190a36c707 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/random.data
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/random.data
Binary files differ
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
index 9bb5231528..9bb5231528 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicswidget/qgraphicswidget.pro b/tests/benchmarks/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro
index 00becec216..00becec216 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicswidget/qgraphicswidget.pro
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
index d9bc7f21b6..d9bc7f21b6 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
+++ b/tests/benchmarks/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp
diff --git a/tests/benchmarks/gui/itemviews/itemviews.pro b/tests/benchmarks/widgets/itemviews/itemviews.pro
index a23cdf7b97..a23cdf7b97 100644
--- a/tests/benchmarks/gui/itemviews/itemviews.pro
+++ b/tests/benchmarks/widgets/itemviews/itemviews.pro
diff --git a/tests/benchmarks/gui/itemviews/qheaderview/qheaderview.pro b/tests/benchmarks/widgets/itemviews/qheaderview/qheaderview.pro
index 7e8415e495..7e8415e495 100644
--- a/tests/benchmarks/gui/itemviews/qheaderview/qheaderview.pro
+++ b/tests/benchmarks/widgets/itemviews/qheaderview/qheaderview.pro
diff --git a/tests/benchmarks/gui/itemviews/qheaderview/qheaderviewbench.cpp b/tests/benchmarks/widgets/itemviews/qheaderview/qheaderviewbench.cpp
index 49ce060580..49ce060580 100644
--- a/tests/benchmarks/gui/itemviews/qheaderview/qheaderviewbench.cpp
+++ b/tests/benchmarks/widgets/itemviews/qheaderview/qheaderviewbench.cpp
diff --git a/tests/benchmarks/gui/itemviews/qtableview/qtableview.pro b/tests/benchmarks/widgets/itemviews/qtableview/qtableview.pro
index bd2306d646..bd2306d646 100644
--- a/tests/benchmarks/gui/itemviews/qtableview/qtableview.pro
+++ b/tests/benchmarks/widgets/itemviews/qtableview/qtableview.pro
diff --git a/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp b/tests/benchmarks/widgets/itemviews/qtableview/tst_qtableview.cpp
index 9ce214e5ff..9ce214e5ff 100644
--- a/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/benchmarks/widgets/itemviews/qtableview/tst_qtableview.cpp
diff --git a/tests/benchmarks/widgets/kernel/kernel.pro b/tests/benchmarks/widgets/kernel/kernel.pro
new file mode 100644
index 0000000000..a50aad2014
--- /dev/null
+++ b/tests/benchmarks/widgets/kernel/kernel.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = \
+ qapplication \
+ qwidget
diff --git a/tests/benchmarks/gui/kernel/qapplication/main.cpp b/tests/benchmarks/widgets/kernel/qapplication/main.cpp
index 49de765ef0..49de765ef0 100644
--- a/tests/benchmarks/gui/kernel/qapplication/main.cpp
+++ b/tests/benchmarks/widgets/kernel/qapplication/main.cpp
diff --git a/tests/benchmarks/gui/kernel/qapplication/qapplication.pro b/tests/benchmarks/widgets/kernel/qapplication/qapplication.pro
index 86a016d42e..86a016d42e 100644
--- a/tests/benchmarks/gui/kernel/qapplication/qapplication.pro
+++ b/tests/benchmarks/widgets/kernel/qapplication/qapplication.pro
diff --git a/tests/benchmarks/gui/kernel/qwidget/qwidget.pro b/tests/benchmarks/widgets/kernel/qwidget/qwidget.pro
index 758c9c5b98..758c9c5b98 100644
--- a/tests/benchmarks/gui/kernel/qwidget/qwidget.pro
+++ b/tests/benchmarks/widgets/kernel/qwidget/qwidget.pro
diff --git a/tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp b/tests/benchmarks/widgets/kernel/qwidget/tst_qwidget.cpp
index b9af7a55cd..b9af7a55cd 100644
--- a/tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/benchmarks/widgets/kernel/qwidget/tst_qwidget.cpp
diff --git a/tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp b/tests/benchmarks/widgets/styles/qstylesheetstyle/main.cpp
index 9dbf618dd9..9dbf618dd9 100644
--- a/tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp
+++ b/tests/benchmarks/widgets/styles/qstylesheetstyle/main.cpp
diff --git a/tests/benchmarks/gui/styles/qstylesheetstyle/qstylesheetstyle.pro b/tests/benchmarks/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro
index 5aef3520c0..5aef3520c0 100644
--- a/tests/benchmarks/gui/styles/qstylesheetstyle/qstylesheetstyle.pro
+++ b/tests/benchmarks/widgets/styles/qstylesheetstyle/qstylesheetstyle.pro
diff --git a/tests/benchmarks/gui/styles/styles.pro b/tests/benchmarks/widgets/styles/styles.pro
index 2c1d10b48c..2c1d10b48c 100644
--- a/tests/benchmarks/gui/styles/styles.pro
+++ b/tests/benchmarks/widgets/styles/styles.pro
diff --git a/tests/benchmarks/widgets/widgets.pro b/tests/benchmarks/widgets/widgets.pro
index 8fe49ff2c6..d241e31d0b 100644
--- a/tests/benchmarks/widgets/widgets.pro
+++ b/tests/benchmarks/widgets/widgets.pro
@@ -1,3 +1,13 @@
TEMPLATE = subdirs
SUBDIRS = \
+ graphicsview \
+ itemviews \
+ kernel \
+ styles \
widgets \
+
+TRUSTED_BENCHMARKS += \
+ graphicsview/functional/GraphicsViewBenchmark \
+ graphicsview/qgraphicsview
+
+include(../trusted-benchmarks.pri)
diff --git a/tests/manual/cocoa/menurama/main.cpp b/tests/manual/cocoa/menurama/main.cpp
index 00594b6d1f..e39c01ea4d 100644
--- a/tests/manual/cocoa/menurama/main.cpp
+++ b/tests/manual/cocoa/menurama/main.cpp
@@ -29,9 +29,46 @@
#include "mainwindow.h"
#include "menuramaapplication.h"
+#include <QtWidgets/QAction>
+#include <QtWidgets/QMenu>
+
int main(int argc, char *argv[])
{
MenuramaApplication a(argc, argv);
+ a.setQuitOnLastWindowClosed(false);
+
+ auto *dockMenu = new QMenu();
+ dockMenu->setAsDockMenu();
+ dockMenu->addAction(QLatin1String("New Window"), [=] {
+ auto *w = new MainWindow;
+ w->setAttribute(Qt::WA_DeleteOnClose, true);
+ w->show();
+ });
+ auto *disabledAction = dockMenu->addAction(QLatin1String("Disabled Item"), [=] {
+ qDebug() << "Should not happen!";
+ Q_UNREACHABLE();
+ });
+ disabledAction->setEnabled(false);
+ dockMenu->addAction(QLatin1String("Last Item Before Separator"), [=] {
+ qDebug() << "Last Item triggered";
+ });
+ auto *hiddenAction = dockMenu->addAction(QLatin1String("Invisible Item (FIXME rdar:39615815)"), [=] {
+ qDebug() << "Should not happen!";
+ Q_UNREACHABLE();
+ });
+ hiddenAction->setVisible(false);
+ dockMenu->addSeparator();
+ auto *toolsMenu = dockMenu->addMenu(QLatin1String("Menurama Tools"));
+ toolsMenu->addAction(QLatin1String("Hammer"), [=] {
+ qDebug() << "Bang! Bang!";
+ });
+ toolsMenu->addAction(QLatin1String("Wrench"), [=] {
+ qDebug() << "Clang! Clang!";
+ });
+ toolsMenu->addAction(QLatin1String("Screwdriver"), [=] {
+ qDebug() << "Squeak! Squeak!";
+ });
+
MainWindow w;
w.show();
diff --git a/tests/manual/cocoa/menurama/mainwindow.ui b/tests/manual/cocoa/menurama/mainwindow.ui
index 4fb3e3420e..2c6ac52f58 100644
--- a/tests/manual/cocoa/menurama/mainwindow.ui
+++ b/tests/manual/cocoa/menurama/mainwindow.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>486</width>
- <height>288</height>
+ <height>376</height>
</rect>
</property>
<property name="windowTitle">
@@ -58,7 +58,7 @@ Click on &quot;Dynamic Stuff&quot; then move left and right to other menus. Disa
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
- <item>
+ <item alignment="Qt::AlignTop">
<widget class="QPushButton" name="addManyButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -71,7 +71,7 @@ Click on &quot;Dynamic Stuff&quot; then move left and right to other menus. Disa
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignTop">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Adding hundreds of items should not block the UI for noticeable periods of time. Odd numbered items should be disabled, those with 2nd LSB on should be hidden.</string>
@@ -83,6 +83,16 @@ Click on &quot;Dynamic Stuff&quot; then move left and right to other menus. Disa
</item>
</layout>
</item>
+ <item alignment="Qt::AlignTop">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Check out the dock menu. You can close this window to verify that its actions will trigger in the absence of any window. And you can add more windows from there too.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
diff --git a/tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.h b/tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.h
index be716aa582..4a145a729f 100644
--- a/tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.h
+++ b/tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.h
@@ -28,10 +28,5 @@
#import <AppKit/AppKit.h>
-@interface TestMouseMovedNSView : NSView {
- NSPoint mouseMovedPoint_;
- BOOL wasAcceptingMouseEvents_;
- NSTrackingRectTag trackingRect_;
- NSTrackingArea* trackingArea_;
-}
+@interface TestMouseMovedNSView : NSView
@end
diff --git a/tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.m b/tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.m
index 65b42dbb2f..20a3fcc513 100644
--- a/tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.m
+++ b/tests/manual/cocoa/qmaccocoaviewcontainer/TestMouseMovedNSView.m
@@ -28,9 +28,14 @@
#import "TestMouseMovedNSView.h"
-@implementation TestMouseMovedNSView
+@implementation TestMouseMovedNSView {
+ NSPoint mouseMovedPoint_;
+ BOOL wasAcceptingMouseEvents_;
+ NSTrackingRectTag trackingRect_;
+ NSTrackingArea* trackingArea_;
+}
-- (id)initWithFrame:(NSRect)frame
+- (instancetype)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self)
@@ -40,13 +45,13 @@
- (void)viewDidMoveToWindow
{
- trackingArea_ = [[NSTrackingArea alloc] initWithRect:[self bounds] options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
+ trackingArea_ = [[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
[self addTrackingArea:trackingArea_];
}
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
{
- if ([self window] && trackingArea_)
+ if (self.window && trackingArea_)
[self removeTrackingArea:trackingArea_];
}
@@ -54,7 +59,7 @@
{
[super updateTrackingAreas];
[self removeTrackingArea: trackingArea_];
- trackingArea_ = [[NSTrackingArea alloc] initWithRect:[self bounds] options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
+ trackingArea_ = [[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
[self addTrackingArea:trackingArea_];
}
@@ -64,20 +69,20 @@
- (void)mouseEntered:(NSEvent *)theEvent
{
wasAcceptingMouseEvents_ = [[self window] acceptsMouseMovedEvents];
- [[self window] setAcceptsMouseMovedEvents:YES];
- [[self window] makeFirstResponder:self];
+ [self.window setAcceptsMouseMovedEvents:YES];
+ [self.window makeFirstResponder:self];
}
- (void)mouseExited:(NSEvent *)theEvent
{
- [[self window] setAcceptsMouseMovedEvents:wasAcceptingMouseEvents_];
+ [self.window setAcceptsMouseMovedEvents:wasAcceptingMouseEvents_];
[self setNeedsDisplay:YES];
[self displayIfNeeded];
}
-(void)mouseMoved:(NSEvent *)pTheEvent
{
- mouseMovedPoint_ = [self convertPoint:[pTheEvent locationInWindow] fromView:nil];
+ mouseMovedPoint_ = [self convertPoint:pTheEvent.locationInWindow fromView:nil];
[self setNeedsDisplay:YES];
[self displayIfNeeded];
}
@@ -88,7 +93,7 @@
NSRectFill(dirtyRect);
NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext];
- CGContextRef cgContextRef = (CGContextRef) [nsGraphicsContext graphicsPort];
+ CGContextRef cgContextRef = nsGraphicsContext.CGContext;
CGContextSetRGBStrokeColor(cgContextRef, 0, 0, 0, .5);
CGContextSetLineWidth(cgContextRef, 1.0);
diff --git a/tests/manual/cocoa/qmaccocoaviewcontainer/main.mm b/tests/manual/cocoa/qmaccocoaviewcontainer/main.mm
index 9cf06391ca..8b05b64a1e 100644
--- a/tests/manual/cocoa/qmaccocoaviewcontainer/main.mm
+++ b/tests/manual/cocoa/qmaccocoaviewcontainer/main.mm
@@ -83,7 +83,7 @@ int main(int argc, char **argv)
w.resize(300, 300);
w.setWindowTitle("QMacCocoaViewContainer");
NSRect r = NSMakeRect(0, 0, 100, 100);
- NSView *view = [[TestMouseMovedNSView alloc] initWithFrame: r];
+ NSView *view = [[TestMouseMovedNSView alloc] initWithFrame:r];
QMacCocoaViewContainer *nativeChild = new QMacCocoaViewContainer(view, &w);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(nativeChild);
diff --git a/tests/manual/cocoa/qt_on_cocoa/main.mm b/tests/manual/cocoa/qt_on_cocoa/main.mm
index 805ef0d7c2..e6218e48ac 100644
--- a/tests/manual/cocoa/qt_on_cocoa/main.mm
+++ b/tests/manual/cocoa/qt_on_cocoa/main.mm
@@ -50,31 +50,30 @@
}
@end
-@interface AppDelegate : NSObject <NSApplicationDelegate> {
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+@end
+
+@implementation AppDelegate {
QGuiApplication *m_app;
QWindow *m_window;
}
-- (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv;
-- (void) applicationWillFinishLaunching: (NSNotification *)notification;
-- (void)applicationWillTerminate:(NSNotification *)notification;
-@end
-
-@implementation AppDelegate
-- (AppDelegate *) initWithArgc:(int)argc argv:(const char **)argv
+- (instancetype)initWithArgc:(int)argc argv:(const char **)argv
{
- m_app = new QGuiApplication(argc, const_cast<char **>(argv));
+ if ((self = [self init])) {
+ m_app = new QGuiApplication(argc, const_cast<char **>(argv));
+ }
return self;
}
-- (void) applicationWillFinishLaunching: (NSNotification *)notification
+- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
Q_UNUSED(notification);
// Create the NSWindow
NSRect frame = NSMakeRect(500, 500, 500, 500);
- NSWindow* window = [[NSWindow alloc] initWithContentRect:frame
- styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
+ NSWindow *window = [[NSWindow alloc] initWithContentRect:frame
+ styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
backing:NSBackingStoreBuffered
defer:NO];
@@ -100,7 +99,7 @@
childWindow->setGeometry(50, 50, 100, 100);
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, 80, 25)];
- [(NSView*)childWindow->winId() addSubview:textField];
+ [reinterpret_cast<NSView *>(childWindow->winId()) addSubview:textField];
[contentView addSubview:reinterpret_cast<NSView *>(m_window->winId())];
@@ -125,10 +124,7 @@
int main(int argc, const char *argv[])
{
// Create NSApplicaiton with delgate
- NSApplication *app =[NSApplication sharedApplication];
+ NSApplication *app = [NSApplication sharedApplication];
app.delegate = [[AppDelegate alloc] initWithArgc:argc argv:argv];
- return NSApplicationMain (argc, argv);
+ return NSApplicationMain(argc, argv);
}
-
-
-
diff --git a/tests/manual/highdpi/dragwidget.cpp b/tests/manual/highdpi/dragwidget.cpp
index fc1ea72963..46a8ea8090 100644
--- a/tests/manual/highdpi/dragwidget.cpp
+++ b/tests/manual/highdpi/dragwidget.cpp
@@ -42,7 +42,7 @@ public:
};
DragWidget::DragWidget(QString text, QWidget *parent)
- : QWidget(parent), otherWindow(0)
+ : QWidget(parent), otherWindow(nullptr)
{
int x = 5;
int y = 5;
diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp
index bd6af75b16..7225587ac0 100644
--- a/tests/manual/highdpi/main.cpp
+++ b/tests/manual/highdpi/main.cpp
@@ -45,6 +45,8 @@
#include <QPainter>
#include <QWindow>
#include <QScreen>
+#include <QGraphicsView>
+#include <QGraphicsTextItem>
#include <QFile>
#include <QMouseEvent>
#include <QTemporaryDir>
@@ -59,7 +61,7 @@
class DemoContainerBase
{
public:
- DemoContainerBase() : m_widget(0) {}
+ DemoContainerBase() : m_widget(nullptr) {}
virtual ~DemoContainerBase() {}
QString name() { return option().names().first(); }
virtual QCommandLineOption &option() = 0;
@@ -155,7 +157,7 @@ static qreal getScreenFactorWithoutPixelDensity(const QScreen *screen)
static inline qreal getGlobalScaleFactor()
{
- QScreen *noScreen = 0;
+ QScreen *noScreen = nullptr;
return QHighDpiScaling::factor(noScreen);
}
@@ -334,6 +336,60 @@ void PixmapPainter::paintEvent(QPaintEvent *)
x+=dx * 2; p.drawImage(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), imageLarge);
}
+class TiledPixmapPainter : public QWidget
+{
+public:
+ QPixmap pixmap1X;
+ QPixmap pixmap2X;
+ QPixmap pixmapLarge;
+
+ TiledPixmapPainter();
+ void paintEvent(QPaintEvent *event);
+};
+
+TiledPixmapPainter::TiledPixmapPainter()
+{
+ pixmap1X = QPixmap(":/qticon32.png");
+ pixmap2X = QPixmap(":/qticon32@2x.png");
+ pixmapLarge = QPixmap(":/qticon64.png");
+}
+
+void TiledPixmapPainter::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+ QPainter p(this);
+
+ int xoff = 10;
+ int yoff = 10;
+ int tiles = 4;
+ int pixmapEdge = 32;
+ int tileAreaEdge = pixmapEdge * tiles;
+
+ // Expected behavior for both 1x and 2x dislays:
+ // 1x pixmap : 4 x 4 tiles
+ // large pixmap: 2 x 2 tiles
+ // 2x pixmap : 4 x 4 tiles
+ //
+ // On a 2x display the 2x pimxap tiles
+ // will be drawn in high resolution.
+ p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap1X);
+ yoff += tiles * pixmapEdge + 10;
+ p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmapLarge);
+ yoff += tiles * pixmapEdge + 10;
+ p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap2X);
+
+ // Again, with an offset. The offset is in
+ // device-independent pixels.
+ QPoint offset(40, 40); // larger than the pixmap edge size to exercise that code path
+ yoff = 10;
+ xoff = 20 + tiles * pixmapEdge ;
+ p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap1X, offset);
+ yoff += tiles * pixmapEdge + 10;
+ p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmapLarge, offset);
+ yoff += tiles * pixmapEdge + 10;
+ p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap2X, offset);
+}
+
class Labels : public QWidget
{
public:
@@ -579,7 +635,7 @@ template <typename T>
void apiTestdevicePixelRatioGetter()
{
if (0) {
- T *t = 0;
+ T *t = nullptr;
t->devicePixelRatio();
}
}
@@ -588,7 +644,7 @@ template <typename T>
void apiTestdevicePixelRatioSetter()
{
if (0) {
- T *t = 0;
+ T *t = nullptr;
t->setDevicePixelRatio(2.0);
}
}
@@ -791,7 +847,7 @@ class CursorTester : public QWidget
{
public:
CursorTester()
- :moveLabel(0), moving(false)
+ :moveLabel(nullptr), moving(false)
{
}
@@ -889,7 +945,7 @@ class ScreenDisplayer : public QWidget
{
public:
ScreenDisplayer()
- : QWidget(), moveLabel(0), scaleFactor(1.0)
+ : QWidget(), moveLabel(nullptr), scaleFactor(1.0)
{
}
@@ -1098,6 +1154,28 @@ void PhysicalSizeTest::paintEvent(QPaintEvent *)
}
+class GraphicsViewCaching : public QGraphicsView
+{
+public:
+ GraphicsViewCaching() {
+ QGraphicsScene *scene = new QGraphicsScene(0, 0, 400, 400);
+
+ QGraphicsTextItem *item = scene->addText("NoCache");
+ item->setCacheMode(QGraphicsItem::NoCache);
+ item->setPos(10, 10);
+
+ item = scene->addText("ItemCoordinateCache");
+ item->setCacheMode(QGraphicsItem::ItemCoordinateCache);
+ item->setPos(10, 30);
+
+ item = scene->addText("DeviceCoordinateCache");
+ item->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+ item->setPos(10, 50);
+
+ setScene(scene);
+ }
+};
+
int main(int argc, char **argv)
{
QApplication app(argc, argv);
@@ -1119,6 +1197,7 @@ int main(int argc, char **argv)
DemoContainerList demoList;
demoList << new DemoContainer<PixmapPainter>("pixmap", "Test pixmap painter");
+ demoList << new DemoContainer<TiledPixmapPainter>("tiledpixmap", "Test tiled pixmap painter");
demoList << new DemoContainer<Labels>("label", "Test Labels");
demoList << new DemoContainer<MainWindow>("mainwindow", "Test QMainWindow");
demoList << new DemoContainer<StandardIcons>("standard-icons", "Test standard icons");
@@ -1132,7 +1211,7 @@ int main(int argc, char **argv)
demoList << new DemoContainer<CursorTester>("cursorpos", "Test cursor and window positioning");
demoList << new DemoContainer<ScreenDisplayer>("screens", "Test screen and window positioning");
demoList << new DemoContainer<PhysicalSizeTest>("physicalsize", "Test manual highdpi support using physicalDotsPerInch");
-
+ demoList << new DemoContainer<GraphicsViewCaching>("graphicsview", "Test QGraphicsView caching");
foreach (DemoContainerBase *demo, demoList)
parser.addOption(demo->option());
diff --git a/tests/manual/windowchildgeometry/controllerwidget.cpp b/tests/manual/windowchildgeometry/controllerwidget.cpp
index 871313d983..396fad53dc 100644
--- a/tests/manual/windowchildgeometry/controllerwidget.cpp
+++ b/tests/manual/windowchildgeometry/controllerwidget.cpp
@@ -236,7 +236,7 @@ private:
WidgetWindowControl::WidgetWindowControl(QWidget *w )
: BaseWindowControl(w)
- , m_statesControl(new WindowStatesControl(WindowStatesControl::WantVisibleCheckBox | WindowStatesControl::WantActiveCheckBox))
+ , m_statesControl(new WindowStatesControl)
{
setTitle(w->windowTitle());
m_layout->addWidget(m_statesControl, 2, 0);
@@ -364,14 +364,14 @@ private:
virtual void setObjectWindowFlags(QObject *o, Qt::WindowFlags f)
{ static_cast<QWindow *>(o)->setFlags(f); }
- WindowStateControl *m_stateControl;
+ WindowStatesControl *m_statesControl;
QWindow *m_window;
QWindow *m_detachedParent; // set when this window is detached. This is the window we should re-attach to.
};
WindowControl::WindowControl(QWindow *w )
: BaseWindowControl(w)
- , m_stateControl(new WindowStateControl(WindowStateControl::WantVisibleCheckBox | WindowStateControl::WantMinimizeRadioButton))
+ , m_statesControl(new WindowStatesControl)
, m_window(w)
, m_detachedParent(0)
{
diff --git a/tests/manual/windowgeometry/controllerwidget.cpp b/tests/manual/windowgeometry/controllerwidget.cpp
index 7620d2df56..b05ea2907e 100644
--- a/tests/manual/windowgeometry/controllerwidget.cpp
+++ b/tests/manual/windowgeometry/controllerwidget.cpp
@@ -256,7 +256,7 @@ private:
WidgetWindowControl::WidgetWindowControl(QWidget *w )
: BaseWindowControl(w)
- , m_statesControl(new WindowStatesControl(WindowStatesControl::WantVisibleCheckBox | WindowStatesControl::WantActiveCheckBox))
+ , m_statesControl(new WindowStatesControl)
{
setTitle(w->windowTitle());
m_layout->addWidget(m_statesControl, 2, 0);
@@ -354,34 +354,34 @@ private:
virtual void setObjectWindowFlags(QObject *o, Qt::WindowFlags f)
{ static_cast<QWindow *>(o)->setFlags(f); }
- WindowStateControl *m_stateControl;
+ WindowStatesControl *m_statesControl;
};
WindowControl::WindowControl(QWindow *w )
: BaseWindowControl(w)
- , m_stateControl(new WindowStateControl(WindowStateControl::WantVisibleCheckBox | WindowStateControl::WantMinimizeRadioButton))
+ , m_statesControl(new WindowStatesControl)
{
setTitle(w->title());
QGroupBox *stateGroupBox = new QGroupBox(tr("State"));
QVBoxLayout *l = new QVBoxLayout(stateGroupBox);
- l->addWidget(m_stateControl);
+ l->addWidget(m_statesControl);
m_layout->addWidget(stateGroupBox, 2, 0);
- connect(m_stateControl, SIGNAL(changed()), this, SLOT(stateChanged()));
+ connect(m_statesControl, SIGNAL(changed()), this, SLOT(stateChanged()));
}
void WindowControl::refresh()
{
const QWindow *w = static_cast<const QWindow *>(m_object);
BaseWindowControl::refresh();
- m_stateControl->setVisibleValue(w->isVisible());
- m_stateControl->setState(w->windowState());
+ m_statesControl->setVisibleValue(w->isVisible());
+ m_statesControl->setStates(w->windowStates());
}
void WindowControl::stateChanged()
{
QWindow *w = static_cast<QWindow *>(m_object);
- w->setVisible(m_stateControl->visibleValue());
- w->setWindowState(m_stateControl->state());
+ w->setVisible(m_statesControl->visibleValue());
+ w->setWindowStates(m_statesControl->states());
}
#endif
diff --git a/tests/testserver/apache2/apache2.sh b/tests/testserver/apache2/apache2.sh
new file mode 100755
index 0000000000..4b0c74e2c4
--- /dev/null
+++ b/tests/testserver/apache2/apache2.sh
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+set -ex
+
+# package apache2
+
+# add users
+useradd httptest; echo "httptest:httptest" | chpasswd
+
+# enable apache2 module
+/usr/sbin/a2enmod ssl dav_fs headers deflate auth_digest cgi
+
+# enable apache2 config
+cp $TESTDATA/{main,security,ssl,dav}.conf /etc/apache2/conf-available/
+/usr/sbin/a2enconf main security ssl dav
+
+# install configurations and test data
+cp $TESTDATA/deflate.conf /etc/apache2/mods-available/
+mkdir -p -m 1777 /home/writeables/dav # dav.conf
+a2dissite '*' # disable all of the default apache2 sites
+
+# Populate the web-site:
+su $USER -c "cp -r $TESTDATA/www ~/www"
+
+# tst_QNetworkReply::getFromHttp(success-internal)
+su $USER -c "cp rfc3252.txt ~/www/htdocs/"; rm rfc3252.txt
+
+# tst_QNetworkReply::synchronousRequest_data()
+su $USER -c "mkdir -p ~/www/htdocs/deflate/"
+su $USER -c "ln -s ~/www/htdocs/rfc3252.txt ~/www/htdocs/deflate/"
+
+# tst_QNetworkReply::headFromHttp(with-authentication)
+su $USER -c "ln -s ~/www/htdocs/rfc3252.txt ~/www/htdocs/rfcs-auth/"
+
+# Duplicate rfc3252.txt 20 times for bigfile tests:
+su $USER -c "seq 20 | xargs -i cat ~/www/htdocs/rfc3252.txt >> ~/www/htdocs/bigfile"
+
+# tst_QNetworkReply::postToHttp(empty)
+su $USER -c "ln -s ~/www/htdocs/protected/cgi-bin/md5sum.cgi ~/www/cgi-bin/"
+
+# tst_QNetworkReply::lastModifiedHeaderForHttp() expects this time-stamp:
+touch -d "2007-05-22 12:04:57 GMT" /home/$USER/www/htdocs/fluke.gif
+
+# Create 10MB file for use by tst_Q*::downloadBigFile and interruption tests:
+su $USER -c "/bin/dd if=/dev/zero of=~/www/htdocs/mediumfile bs=1 count=0 seek=10000000"
+
+# enable service with installed configurations
+service apache2 restart
diff --git a/tests/testserver/apache2/testdata/dav.conf b/tests/testserver/apache2/testdata/dav.conf
new file mode 100644
index 0000000000..c207c2734b
--- /dev/null
+++ b/tests/testserver/apache2/testdata/dav.conf
@@ -0,0 +1,7 @@
+Alias /dav /home/writeables/dav
+<Location /dav>
+ DAV On
+ order allow,deny
+ allow from all
+ Require all granted
+</Location>
diff --git a/tests/testserver/apache2/testdata/deflate.conf b/tests/testserver/apache2/testdata/deflate.conf
new file mode 100644
index 0000000000..6a15701d49
--- /dev/null
+++ b/tests/testserver/apache2/testdata/deflate.conf
@@ -0,0 +1,5 @@
+# The default configuration will turn on DEFLATE for files served up
+# from everywhere.
+#
+# For testing purposes, we want DEFLATE off by default, and on only for
+# specific paths (which is set elsewhere).
diff --git a/tests/testserver/apache2/testdata/main.conf b/tests/testserver/apache2/testdata/main.conf
new file mode 100644
index 0000000000..f3b13bb571
--- /dev/null
+++ b/tests/testserver/apache2/testdata/main.conf
@@ -0,0 +1,56 @@
+ServerName apache2.test-net.qt.local:80
+
+NameVirtualHost *:443
+
+<VirtualHost *:80>
+</VirtualHost>
+
+<VirtualHost *:443>
+SSLEngine On
+CustomLog /var/log/apache2/ssl_access.log combined
+ErrorLog /var/log/apache2/ssl_error.log
+</VirtualHost>
+
+# default ubuntu config turns off SSLv2 because it is deprecated.
+# Turn it back on so we can test it.
+SSLProtocol all
+
+DocumentRoot /home/qt-test-server/www/htdocs
+ScriptAlias /qtest/cgi-bin/ "/home/qt-test-server/www/cgi-bin/"
+ScriptAlias /qtest/protected/cgi-bin/ "/home/qt-test-server/www/htdocs/protected/cgi-bin/"
+Alias /qtest "/home/qt-test-server/www/htdocs/"
+
+<Directory "/home/qt-test-server/www/htdocs">
+ Require all granted
+</Directory>
+
+<Directory "/home/qt-test-server/www/htdocs/rfcs-auth">
+ AuthType Basic
+ AuthName "Restricted Files"
+ AuthUserFile /home/qt-test-server/passwords
+ Require user httptest
+</Directory>
+
+<Directory "/home/qt-test-server/www/htdocs/auth-digest">
+ AuthType Digest
+ AuthName "Digest testing"
+ AuthDigestProvider file
+ AuthUserFile /home/qt-test-server/www/htdocs/digest-authfile
+ Require user httptest
+</Directory>
+
+<Directory "/home/qt-test-server/www/htdocs/deflate">
+ AddOutputFilterByType DEFLATE text/html text/plain text/xml
+ Header append Vary User-Agent env=!dont-vary
+</Directory>
+
+<Directory "/home/qt-test-server/www/cgi-bin">
+ Options +ExecCGI -Includes
+ AddHandler cgi-script .cgi .pl
+ Require all granted
+</Directory>
+
+
+<Directory "/home/qt-test-server/www/htdocs/protected/">
+ AllowOverride AuthConfig Options
+</Directory>
diff --git a/tests/testserver/apache2/testdata/security.conf b/tests/testserver/apache2/testdata/security.conf
new file mode 100644
index 0000000000..30a8ee3765
--- /dev/null
+++ b/tests/testserver/apache2/testdata/security.conf
@@ -0,0 +1,51 @@
+#
+# Disable access to the entire file system except for the directories that
+# are explicitly allowed later.
+#
+# This currently breaks the configurations that come with some web application
+# Debian packages. It will be made the default for the release after lenny.
+#
+#<Directory />
+# AllowOverride None
+# Order Deny,Allow
+# Deny from all
+#</Directory>
+
+
+# Changing the following options will not really affect the security of the
+# server, but might make attacks slightly more difficult in some cases.
+
+#
+# ServerTokens
+# This directive configures what you return as the Server HTTP response
+# Header. The default is 'Full' which sends information about the OS-Type
+# and compiled in modules.
+# Set to one of: Full | OS | Minimal | Minor | Major | Prod
+# where Full conveys the most information, and Prod the least.
+#
+#ServerTokens Minimal
+ServerTokens OS
+#ServerTokens Full
+
+#
+# Optionally add a line containing the server version and virtual host
+# name to server-generated pages (internal error documents, FTP directory
+# listings, mod_status and mod_info output etc., but not CGI generated
+# documents or custom error documents).
+# Set to "EMail" to also include a mailto: link to the ServerAdmin.
+# Set to one of: On | Off | EMail
+#
+#ServerSignature Off
+ServerSignature On
+
+#
+# Allow TRACE method
+#
+# Set to "extended" to also reflect the request body (only for testing and
+# diagnostic purposes).
+#
+# Set to one of: On | Off | extended
+#
+#TraceEnable Off
+TraceEnable On
+
diff --git a/tests/testserver/apache2/testdata/ssl.conf b/tests/testserver/apache2/testdata/ssl.conf
new file mode 100644
index 0000000000..d6bbaf0da0
--- /dev/null
+++ b/tests/testserver/apache2/testdata/ssl.conf
@@ -0,0 +1,2 @@
+SSLCertificateFile /home/qt-test-server/ssl-certs/qt-test-server-cert.pem
+SSLCertificateKeyFile /home/qt-test-server/ssl-certs/private/qt-test-server-key.pem
diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/echo.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/echo.cgi
new file mode 100755
index 0000000000..16315a3db6
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/cgi-bin/echo.cgi
@@ -0,0 +1,11 @@
+#!/usr/bin/perl
+
+if ($ENV{'REQUEST_METHOD'} eq "GET") {
+ $request = $ENV{'QUERY_STRING'};
+} elsif ($ENV{'REQUEST_METHOD'} eq "POST") {
+ read(STDIN, $request, $ENV{'CONTENT_LENGTH'}) || die "Could not get query\n";
+}
+
+print "Content-type: text/plain\n\n";
+print $request;
+
diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/get-cookie.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/get-cookie.cgi
new file mode 100755
index 0000000000..59f40ac78b
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/cgi-bin/get-cookie.cgi
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+echo "Content-Type: text/plain"
+echo
+echo "$HTTP_COOKIE"
diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/http-delete.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/http-delete.cgi
new file mode 100755
index 0000000000..18000c9f4c
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/cgi-bin/http-delete.cgi
@@ -0,0 +1,22 @@
+#!/usr/bin/perl
+
+use CGI;
+
+if ($ENV{'REQUEST_METHOD'} eq "DELETE") {
+ $queryString = $ENV{'QUERY_STRING'};
+ if ($queryString eq "200-ok") {
+ $returnCode = 200;
+ } elsif ($queryString eq "202-accepted") {
+ $returnCode = 202;
+ } elsif ($queryString eq "204-no-content") {
+ $returnCode = 204;
+ } else {
+ $returnCode = 404;
+ }
+} else {
+ # 405 = Method Not Allowed
+ $returnCode = 405;
+}
+
+$q = new CGI;
+print $q->header(-status=>$returnCode);
diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/http-unknown-authentication-method.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/http-unknown-authentication-method.cgi
new file mode 100755
index 0000000000..ce47e8384c
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/cgi-bin/http-unknown-authentication-method.cgi
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+use CGI;
+
+$queryString = $ENV{'QUERY_STRING'};
+my $message;
+if ($queryString eq "407-proxy-authorization-required") {
+ $status = 407;
+} else {
+ $status = 401;
+}
+
+$q = new CGI;
+print $q->header(-status=>$status,
+ -type=>"text/plain",
+ -WWW_Authenticate=>'WSSE realm="Test", profile="TestProfile"'),
+ "authorization required";
diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires500.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires500.cgi
new file mode 100755
index 0000000000..66a3741641
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires500.cgi
@@ -0,0 +1,12 @@
+#!/bin/bash
+if [ "${HTTP_IF_MODIFIED_SINCE}" ]
+then
+ echo "Status: 500"
+ echo ""
+ exit;
+fi
+
+echo "Expires: Mon, 30 Oct 2028 14:19:41 GMT"
+echo "Content-type: text/html";
+echo ""
+echo "Hello World!"
diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/multipart.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/multipart.cgi
new file mode 100755
index 0000000000..6973875cc9
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/cgi-bin/multipart.cgi
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+use CGI;
+use Digest::MD5 qw(md5_hex);
+
+$q = new CGI;
+print $q->header();
+
+$contentType = $ENV{"CONTENT_TYPE"};
+print "content type: $contentType\n";
+
+if ($contentType =~ /^multipart\/form-data/) {
+ foreach my $key ($q->param) {
+ foreach my $value ($q->param($key)) {
+ if ($key =~ /text/) {
+ $retValue = $value;
+ } else {
+ $retValue = md5_hex($value);
+ }
+ print "key: $key, value: $retValue\n";
+ }
+ }
+} else {
+ #$contentLength = $ENV{"CONTENT_LENGTH"};
+ #print "content length: $contentLength\r\n";
+
+ $data = $q->param('POSTDATA');
+ $data =~ s/--\S*--$//; # remove ending boundary
+ @parts = split(/--\S*\r\n/, $data);
+ shift(@parts);
+ foreach (@parts) {
+ #print "raw: $_";
+ ($header, $content) = split("\r\n\r\n");
+ @headerFields = split("\r\n", $header);
+ foreach (@headerFields) {
+ ($fieldName, $value) = split(": ");
+ print "header: $fieldName, value: '$value'\n";
+ }
+ $content =~ s/\r\n//;
+ print "content: $content\n\n";
+ }
+}
diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/set-cookie.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/set-cookie.cgi
new file mode 100755
index 0000000000..dc463f00f3
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/cgi-bin/set-cookie.cgi
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+echo "Content-type: text/plain"
+while read line; do
+ echo "Set-Cookie: $line"
+done
+
+echo
+echo "Success"
diff --git a/tests/testserver/apache2/testdata/www/htdocs/auth-digest/index.html b/tests/testserver/apache2/testdata/www/htdocs/auth-digest/index.html
new file mode 100644
index 0000000000..fa96496aa0
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/htdocs/auth-digest/index.html
@@ -0,0 +1 @@
+digest authentication successful
diff --git a/tests/testserver/apache2/testdata/www/htdocs/digest-authfile b/tests/testserver/apache2/testdata/www/htdocs/digest-authfile
new file mode 100644
index 0000000000..99963901ce
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/htdocs/digest-authfile
@@ -0,0 +1 @@
+httptest:Digest testing:5f68f4bc3cd2873a3d547558fe7d9782
diff --git a/tests/testserver/apache2/testdata/www/htdocs/fluke.gif b/tests/testserver/apache2/testdata/www/htdocs/fluke.gif
new file mode 100644
index 0000000000..6060cbd4d7
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/htdocs/fluke.gif
Binary files differ
diff --git a/tests/testserver/apache2/testdata/www/htdocs/index.html b/tests/testserver/apache2/testdata/www/htdocs/index.html
new file mode 100644
index 0000000000..abc1df188d
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/htdocs/index.html
@@ -0,0 +1,3 @@
+<h1>Welcome to qt-test-server</h1>
+<img src="fluke.gif" alt="fluke">
+<p>This is a network test server. It serves as a caching ftp and http proxy, transparent http/socks5 proxy, imap, ftp and http server, and more.</p>
diff --git a/tests/testserver/apache2/testdata/www/htdocs/protected/.htaccess b/tests/testserver/apache2/testdata/www/htdocs/protected/.htaccess
new file mode 100644
index 0000000000..c465494167
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/htdocs/protected/.htaccess
@@ -0,0 +1,5 @@
+Require valid-user
+AuthUserFile /home/qt-test-server/passwords
+AuthType basic
+AuthName "password-protected area"
+Options Indexes
diff --git a/tests/testserver/apache2/testdata/www/htdocs/protected/cgi-bin/md5sum.cgi b/tests/testserver/apache2/testdata/www/htdocs/protected/cgi-bin/md5sum.cgi
new file mode 100755
index 0000000000..e580462b85
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/htdocs/protected/cgi-bin/md5sum.cgi
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+echo "Content-type: text/plain";
+echo "Content-length: 33"
+echo
+md5sum | cut -f 1 -d " "
diff --git a/tests/testserver/apache2/testdata/www/htdocs/rfcs-auth/index.html b/tests/testserver/apache2/testdata/www/htdocs/rfcs-auth/index.html
new file mode 100644
index 0000000000..472e6ce55d
--- /dev/null
+++ b/tests/testserver/apache2/testdata/www/htdocs/rfcs-auth/index.html
@@ -0,0 +1 @@
+you found the secret
diff --git a/tests/testserver/common/ssl.sh b/tests/testserver/common/ssl.sh
new file mode 100755
index 0000000000..8a4728ad4d
--- /dev/null
+++ b/tests/testserver/common/ssl.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+set -ex
+
+# package ssl
+
+# install ssl_certs and test data
+su $USER -c "mkdir -p -m 700 ~/ssl-certs/private"
+su $USER -c "cp $CONFIG/ssl/qt-test-server-cert.pem ~/ssl-certs/"
+su $USER -c "cp $CONFIG/ssl/private/qt-test-server-key.pem ~/ssl-certs/private/"
diff --git a/tests/testserver/common/startup.sh b/tests/testserver/common/startup.sh
new file mode 100755
index 0000000000..84d4003f86
--- /dev/null
+++ b/tests/testserver/common/startup.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+set -ex
+
+# export variables
+export USER=qt-test-server
+export PASS=password
+export CONFIG=common/testdata
+export TESTDATA=service/testdata
+
+# add users
+useradd -m -s /bin/bash $USER; echo "$USER:$PASS" | chpasswd
+
+# install configurations and test data
+su $USER -c "cp $CONFIG/system/passwords ~/"
+
+# modules initialization (apache2.sh, ftp-proxy.sh ...)
+for RUN_CMD
+do $RUN_CMD
+done
+
+# start multicast DNS service discovery (mDNS)
+sed -i "s,#domain-name=local,domain-name=test-net.qt.local," /etc/avahi/avahi-daemon.conf
+service dbus restart
+service avahi-daemon restart
+
+# keep-alive in docker detach mode
+sleep infinity
diff --git a/tests/testserver/common/testdata/ssl/private/qt-test-server-key.pem b/tests/testserver/common/testdata/ssl/private/qt-test-server-key.pem
new file mode 100644
index 0000000000..8b7ce5811a
--- /dev/null
+++ b/tests/testserver/common/testdata/ssl/private/qt-test-server-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDNqttv1jTJp/HAvuRBGBniAski5qfVugMunih69F8ad193qRE7
+j37wLsae6zrZEtfBDFHoJFI/I8NCDBHG8hyhQv60wmmDrfdwsRgVzCAoYjDwLBXm
+Mxmvw+scwJH3EWiUUPhJNwgy1z5136O8aQAV3s2HD1wCa4LIAX1q8B3ccwIDAQAB
+AoGAGiDou+6UykHB3uDhkruDHkmIUBzJmceF+/gv4F8Hbg9YW5VpEQ4L7Guk5C+y
+TD2ul2H/TeS/ZjIe7lcmMwYzSLcyeKfaiaV1EhPGjIdvB4ysTN79pfWXQtlpt/Z9
+I/EOoW9XosJ/EOFdpgV0MC9QMTQKMyS0qQLwhBsoAW4DcEECQQDmrWEPNprbEDIH
+Sm+KlMH6rdybIvzR3IPlYE6kMjQIWbUmGNxSUT7B/UDh2QeaTT54Rb1Ygnq7gVjC
+RHU3wnGxAkEA5D6jI/E/xtQSq0KKVpbOxN1dIo0MVPbO/hI7/pO2DdZIM0O4GL55
+ks83O5ZDTfrVy2Ys/9lqbbq+5FSs+NZ1YwJBANzAXRsO+YDcbdP2Uun+0+fOjEhW
+YjV/XyWaVYfil1LKboXn0qhgIbvJXVcEt7bdZwP4UWwracKY1NUMaFSVGvECQQC/
+L3iX8szpT1sT+XjHbytj28jX2C4sPVDFoaB/bltg280+o8rhbyuGvewWDZfzCdlr
+tvqalROBNpwPxp3dEkbhAkEAl7N7/7hWbw7Xv69ww7i0jcPduukbtbEY1DTmARhR
+rOF5AiztOAe+R94iLzkj63ZU0LcoSAixehp2tdkdtTI4CQ==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/testserver/common/testdata/ssl/qt-test-server-cert.pem b/tests/testserver/common/testdata/ssl/qt-test-server-cert.pem
new file mode 100644
index 0000000000..43c8794ce2
--- /dev/null
+++ b/tests/testserver/common/testdata/ssl/qt-test-server-cert.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIIClTCCAf4CCQC2xMhNhwvATDANBgkqhkiG9w0BAQQFADCBjjELMAkGA1UEChMC
+UXQxGTAXBgNVBAsTEENvcmUgQW5kIE5ldHdvcmsxGzAZBgkqhkiG9w0BCQEWDG5v
+Ym9keS5xdC5pbzENMAsGA1UEBxMET3NsbzENMAsGA1UECBMET3NsbzELMAkGA1UE
+BhMCTk8xHDAaBgNVBAMUEyoudGVzdC1uZXQucXQubG9jYWwwHhcNMTgwNzAxMTgz
+NjI3WhcNNDgwNjIzMTgzNjI3WjCBjjELMAkGA1UEChMCUXQxGTAXBgNVBAsTEENv
+cmUgQW5kIE5ldHdvcmsxGzAZBgkqhkiG9w0BCQEWDG5vYm9keS5xdC5pbzENMAsG
+A1UEBxMET3NsbzENMAsGA1UECBMET3NsbzELMAkGA1UEBhMCTk8xHDAaBgNVBAMU
+EyoudGVzdC1uZXQucXQubG9jYWwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
+AM2q22/WNMmn8cC+5EEYGeICySLmp9W6Ay6eKHr0Xxp3X3epETuPfvAuxp7rOtkS
+18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt93CxGBXMIChiMPAsFeYzGa/D6xzAkfcR
+aJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJrgsgBfWrwHdxzAgMBAAEwDQYJKoZIhvcN
+AQEEBQADgYEAZu/lQPy8PXeyyYGamOVms/FZKJ48BH1y8KC3BeBU5FYnhvgG7pz8
+Wz9JKvt2t/r45wQeAkNL6HnGUBhPJsHMjPHl5KktqN+db3D+FQygBeS2V1+zmC0X
+UZNRE4aWiHvt1Lq+pTx89SOMOpfqWfh4qTQKiE5jC2V4DeCNQ3u7uI8=
+-----END CERTIFICATE-----
diff --git a/tests/testserver/common/testdata/system/passwords b/tests/testserver/common/testdata/system/passwords
new file mode 100644
index 0000000000..4e911b3f0e
--- /dev/null
+++ b/tests/testserver/common/testdata/system/passwords
@@ -0,0 +1,12 @@
+# user: foo; passwd: bar
+foo:bab.5ZXQdbvEo
+
+# user: qsockstest; passwd: qsockstest
+#qsockstest:S7oOqMpoG6aTk
+
+# user: qsockstest; passwd: password
+qsockstest:Cd3Lv2aD0aiBs
+
+#user httptest password httptest
+httptest:v2fwkDMgrRjRA
+# added by mgoetz for tst_qnetworkreply ioPostToHttpFromSocket
diff --git a/tests/testserver/danted/danted.sh b/tests/testserver/danted/danted.sh
new file mode 100755
index 0000000000..bf3d154f33
--- /dev/null
+++ b/tests/testserver/danted/danted.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+set -ex
+
+# package dante-server
+
+# add users
+useradd -d /dev/null -s /bin/false qsockstest; echo "qsockstest:$PASS" | chpasswd
+
+# install configurations and test data
+cp $TESTDATA/danted{,-authenticating}.conf /etc/
+
+# enable service with installed configurations
+service danted start
+service danted-authenticating start
diff --git a/tests/testserver/danted/testdata/danted-authenticating.conf b/tests/testserver/danted/testdata/danted-authenticating.conf
new file mode 100644
index 0000000000..ccb4acc801
--- /dev/null
+++ b/tests/testserver/danted/testdata/danted-authenticating.conf
@@ -0,0 +1,19 @@
+# A sample danted-authenticating.conf
+# See: https://www.inet.no/dante/doc/1.4.x/config/
+logoutput: /var/log/sockd-authenticating.log
+internal: eth0 port = 1081
+external: eth0
+method: username
+user.privileged: root
+user.notprivileged: nobody
+user.libwrap: nobody
+
+client pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ log: error connect disconnect
+}
+
+pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ log: error connect disconnect
+}
diff --git a/tests/testserver/danted/testdata/danted.conf b/tests/testserver/danted/testdata/danted.conf
new file mode 100644
index 0000000000..bd0e6a8343
--- /dev/null
+++ b/tests/testserver/danted/testdata/danted.conf
@@ -0,0 +1,19 @@
+# A sample danted.conf
+# See: https://www.inet.no/dante/doc/1.4.x/config/
+logoutput: /var/log/sockd.log
+internal: eth0 port = 1080
+external: eth0
+method: username none
+user.privileged: proxy
+user.notprivileged: nobody
+user.libwrap: nobody
+
+client pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ log: error connect disconnect
+}
+
+pass {
+ from: 0.0.0.0/0 to: 0.0.0.0/0
+ log: error connect disconnect
+}
diff --git a/tests/testserver/docker-compose.yml b/tests/testserver/docker-compose.yml
new file mode 100644
index 0000000000..a151d6bfb0
--- /dev/null
+++ b/tests/testserver/docker-compose.yml
@@ -0,0 +1,83 @@
+version: '3.4'
+
+# The tag of images is used by docker compose file to launch the corresponding
+# docker containers. The value of tag comes from the provisioning script
+# (coin/provisioning/.../testserver/docker_testserver.sh). The script gets SHA-1
+# of each server context as the tag of docker images. If one of the server
+# contexts gets changes, please make sure to update this compose file as well.
+# You can run command 'docker images' to list all the tag of test server images.
+# For example:
+# REPOSITORY TAG IMAGE ID
+# qt-test-server-apache2 e2a70c8b169c204e762b375885bd3a26cc40ba48 2ad5c8720317
+
+services:
+ apache2:
+ image: qt-test-server-apache2:cc9ea678b92bdda33acb9fa0159bb4ad0f3cd947
+ container_name: qt-test-server-apache2
+ domainname: test-net.qt.local
+ hostname: apache2
+ volumes:
+ - ./common:/common:ro
+ - ./apache2:/service:ro
+ entrypoint: common/startup.sh
+ command: [common/ssl.sh, service/apache2.sh]
+
+ squid:
+ image: qt-test-server-squid:577d99307eea9a8cccfec944d25be2bce2fe99cc
+ container_name: qt-test-server-squid
+ domainname: test-net.qt.local
+ hostname: squid
+ depends_on:
+ - apache2
+ external_links:
+ - apache2:apache2.test-net.qt.local
+ volumes:
+ - ./common:/common:ro
+ - ./squid:/service:ro
+ entrypoint: common/startup.sh
+ command: service/squid.sh
+
+ vsftpd:
+ image: qt-test-server-vsftpd:18896604c7e90b543e56d80c8a8aabdb65a590d0
+ container_name: qt-test-server-vsftpd
+ domainname: test-net.qt.local
+ hostname: vsftpd
+ volumes:
+ - ./common:/common:ro
+ - ./vsftpd:/service:ro
+ entrypoint: common/startup.sh
+ command: service/vsftpd.sh
+
+ ftp-proxy:
+ image: qt-test-server-ftp-proxy:2c6c8f1ab6a364b540c43d705fb6f15a585cb2af
+ container_name: qt-test-server-ftp-proxy
+ domainname: test-net.qt.local
+ hostname: ftp-proxy
+ depends_on:
+ - vsftpd
+ external_links:
+ - vsftpd:vsftpd.test-net.qt.local
+ volumes:
+ - ./common:/common:ro
+ - ./ftp-proxy:/service:ro
+ entrypoint: common/startup.sh
+ command: service/ftp-proxy.sh
+
+ danted:
+ image: qt-test-server-danted:327dd56c3c35db85b26fac93213a5a1918475bc7
+ container_name: qt-test-server-danted
+ domainname: test-net.qt.local
+ hostname: danted
+ depends_on:
+ - apache2
+ - vsftpd
+ - ftp-proxy
+ external_links:
+ - apache2:apache2.test-net.qt.local
+ - vsftpd:vsftpd.test-net.qt.local
+ - ftp-proxy:ftp-proxy.test-net.qt.local
+ volumes:
+ - ./common:/common:ro
+ - ./danted:/service:ro
+ entrypoint: common/startup.sh
+ command: service/danted.sh
diff --git a/tests/testserver/ftp-proxy/ftp-proxy.sh b/tests/testserver/ftp-proxy/ftp-proxy.sh
new file mode 100755
index 0000000000..087a7b7bcc
--- /dev/null
+++ b/tests/testserver/ftp-proxy/ftp-proxy.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+set -ex
+
+# package ftp-proxy
+
+# install configurations and test data
+sed -i 's/# AllowMagicUser\tno/AllowMagicUser\tyes/' /etc/proxy-suite/ftp-proxy.conf
+
+# enable service with installed configurations
+ftp-proxy -d
diff --git a/tests/testserver/squid/squid.sh b/tests/testserver/squid/squid.sh
new file mode 100755
index 0000000000..8e413f2f14
--- /dev/null
+++ b/tests/testserver/squid/squid.sh
@@ -0,0 +1,46 @@
+#!/usr/bin/env bash
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+set -ex
+
+# package squid
+
+# install configurations and test data
+cp $TESTDATA/squid{,-authenticating-ntlm}.conf /etc/squid/
+sed -e 's,NAME=squid,NAME=squid-authenticating-ntlm,' \
+ -e 's,CONFIG=/etc/squid/squid.conf,CONFIG=/etc/squid/squid-authenticating-ntlm.conf,' \
+ -e 's,SQUID_ARGS="-YC -f $CONFIG",SQUID_ARGS="-D -YC -f $CONFIG",' \
+ /etc/init.d/squid >/etc/init.d/squid-authenticating-ntlm
+chmod +x /etc/init.d/squid-authenticating-ntlm
+
+# enable service with installed configurations
+service squid start
+service squid-authenticating-ntlm start
diff --git a/tests/testserver/squid/testdata/squid-authenticating-ntlm.conf b/tests/testserver/squid/testdata/squid-authenticating-ntlm.conf
new file mode 100644
index 0000000000..55a74498e9
--- /dev/null
+++ b/tests/testserver/squid/testdata/squid-authenticating-ntlm.conf
@@ -0,0 +1,41 @@
+pid_filename /var/run/squid-authenticating-ntlm.pid
+access_log /var/log/squid/access-authenticating-ntlm.log
+cache_log /var/log/squid/cache-authenticating-ntlm.log
+cache_store_log /var/log/squid/store-authenticating-ntlm.log
+http_port 3130
+hierarchy_stoplist cgi-bin ?
+acl QUERY urlpath_regex cgi-bin \?
+no_cache deny QUERY
+refresh_pattern ^ftp: 1440 20% 10080
+refresh_pattern ^gopher: 1440 0% 1440
+refresh_pattern . 0 20% 4320
+acl port3130 myport 3130
+acl manager proto cache_object
+acl localhost src 127.0.0.1/255.255.255.255
+acl to_localhost dst 127.0.0.0/8
+acl SSL_ports port 443 563
+acl Safe_ports port 80 # http
+acl Safe_ports port 21 # ftp
+acl Safe_ports port 443 563 # https, snews
+acl Safe_ports port 70 # gopher
+acl Safe_ports port 210 # wais
+acl Safe_ports port 1025-65535 # unregistered ports
+acl Safe_ports port 280 # http-mgmt
+acl Safe_ports port 488 # gss-http
+acl Safe_ports port 591 # filemaker
+acl Safe_ports port 777 # multiling http
+acl CONNECT method CONNECT
+http_access allow manager localhost
+http_access deny manager
+http_access allow localhost
+
+
+# port 3130: ntlm auth
+auth_param ntlm program /usr/lib/squid/ntlm_smb_lm_auth --debuglevel=5 --logfile=/var/log/ntlm --log-basename=/var/log/ntlm --helper-protocol=squid-2.5-ntlmssp
+auth_param ntlm children 2
+acl ntlm_users proxy_auth REQUIRED
+http_access allow port3130 ntlm_users
+http_reply_access allow port3130 ntlm_users
+
+icp_access allow all
+coredump_dir /var/cache/squid
diff --git a/tests/testserver/squid/testdata/squid.conf b/tests/testserver/squid/testdata/squid.conf
new file mode 100644
index 0000000000..da1b13af8c
--- /dev/null
+++ b/tests/testserver/squid/testdata/squid.conf
@@ -0,0 +1,46 @@
+http_port 3128
+http_port 3129
+hierarchy_stoplist cgi-bin ?
+acl QUERY urlpath_regex cgi-bin \?
+no_cache deny QUERY
+refresh_pattern ^ftp: 1440 20% 10080
+refresh_pattern ^gopher: 1440 0% 1440
+refresh_pattern . 0 20% 4320
+acl port3128 myport 3128
+acl port3129 myport 3129
+acl manager proto cache_object
+acl localhost src 127.0.0.1/255.255.255.255
+acl to_localhost dst 127.0.0.0/8
+acl SSL_ports port 443 563
+acl Safe_ports port 80 # http
+acl Safe_ports port 21 # ftp
+acl Safe_ports port 443 563 # https, snews
+acl Safe_ports port 70 # gopher
+acl Safe_ports port 210 # wais
+acl Safe_ports port 1025-65535 # unregistered ports
+acl Safe_ports port 280 # http-mgmt
+acl Safe_ports port 488 # gss-http
+acl Safe_ports port 591 # filemaker
+acl Safe_ports port 777 # multiling http
+acl CONNECT method CONNECT
+http_access allow manager localhost
+http_access deny manager
+http_access allow localhost
+
+
+# port 3128: no auth required
+http_access allow port3128
+http_reply_access allow port3128
+
+# port 3129: basic auth
+auth_param basic program /usr/lib/squid/basic_ncsa_auth /home/qt-test-server/passwords
+auth_param basic children 5
+auth_param basic realm Squid proxy-caching web server
+auth_param basic credentialsttl 2 hours
+auth_param basic casesensitive off
+acl ncsa_users proxy_auth REQUIRED
+http_access allow port3129 ncsa_users
+http_reply_access allow port3129 ncsa_users
+
+icp_access allow all
+coredump_dir /var/cache/squid
diff --git a/tests/testserver/vsftpd/testdata/ftp/pub/file-not-readable.txt b/tests/testserver/vsftpd/testdata/ftp/pub/file-not-readable.txt
new file mode 100644
index 0000000000..235fa4d28b
--- /dev/null
+++ b/tests/testserver/vsftpd/testdata/ftp/pub/file-not-readable.txt
@@ -0,0 +1 @@
+If you can read this, you are too close.
diff --git a/tests/testserver/vsftpd/testdata/vsftpd.conf b/tests/testserver/vsftpd/testdata/vsftpd.conf
new file mode 100644
index 0000000000..6bdb186c9f
--- /dev/null
+++ b/tests/testserver/vsftpd/testdata/vsftpd.conf
@@ -0,0 +1,112 @@
+# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
+anonymous_enable=YES
+#
+# Uncomment this to allow local users to log in.
+local_enable=YES
+#
+# Uncomment this to enable any form of FTP write command.
+write_enable=YES
+#
+# Default umask for local users is 077. You may wish to change this to 022,
+# if your users expect that (022 is used by most other ftpd's)
+local_umask=022
+#
+# Uncomment this to allow the anonymous FTP user to upload files. This only
+# has an effect if the above global write enable is activated. Also, you will
+# obviously need to create a directory writable by the FTP user.
+anon_upload_enable=YES
+anon_umask=022
+#
+# Uncomment this if you want the anonymous FTP user to be able to create
+# new directories.
+anon_mkdir_write_enable=YES
+anon_other_write_enable=YES
+anon_world_readable_only=YES
+#
+# Activate directory messages - messages given to remote users when they
+# go into a certain directory.
+dirmessage_enable=YES
+#
+# Activate logging of uploads/downloads.
+xferlog_enable=YES
+#
+# Make sure PORT transfer connections originate from port 20 (ftp-data).
+connect_from_port_20=YES
+#
+# If you want, you can arrange for uploaded anonymous files to be owned by
+# a different user. Note! Using "root" for uploaded files is not
+# recommended!
+#chown_uploads=YES
+#chown_username=ftp
+#chown_groupname=ftp
+#
+# You may override where the log file goes if you like. The default is shown
+# below.
+#xferlog_file=/var/log/vsftpd.log
+#
+# If you want, you can have your log file in standard ftpd xferlog format
+xferlog_std_format=YES
+#
+# You may change the default value for timing out an idle session.
+#idle_session_timeout=600
+#
+# You may change the default value for timing out a data connection.
+#data_connection_timeout=120
+#
+# It is recommended that you define on your system a unique user which the
+# ftp server can use as a totally isolated and unprivileged user.
+#nopriv_user=ftpsecure
+#
+# Enable this and the server will recognize asynchronous ABOR requests. Not
+# recommended for security (the code is non-trivial). Not enabling it,
+# however, may confuse older FTP clients.
+#async_abor_enable=YES
+#
+# By default the server will pretend to allow ASCII mode but in fact ignore
+# the request. Turn on the below options to have the server actually do ASCII
+# mangling on files when in ASCII mode.
+# Beware that on some FTP servers, ASCII support allows a denial of service
+# attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
+# predicted this attack and has always been safe, reporting the size of the
+# raw file.
+# ASCII mangling is a horrible feature of the protocol.
+ascii_upload_enable=YES
+ascii_download_enable=YES
+#
+# You may fully customize the login banner string:
+#ftpd_banner=Welcome to blah FTP service.
+#
+# You may specify a file of disallowed anonymous e-mail addresses. Apparently
+# useful for combatting certain DoS attacks.
+#deny_email_enable=YES
+# (default follows)
+#banned_email_file=/etc/vsftpd/banned_emails
+#
+# You may specify an explicit list of local users to chroot() to their home
+# directory. If chroot_local_user is YES, then this list becomes a list of
+# users to NOT chroot().
+#chroot_list_enable=YES
+# (default follows)
+#chroot_list_file=/etc/vsftpd/chroot_list
+#
+# You may activate the "-R" option to the builtin ls. This is disabled by
+# default to avoid remote users being able to cause excessive I/O on large
+# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
+# the presence of the "-R" option, so there is a strong case for enabling it.
+ls_recurse_enable=YES
+
+pam_service_name=vsftpd
+userlist_enable=YES
+#enable for standalone mode
+listen=YES
+tcp_wrappers=YES
+
+# Enabling SFTP
+#ssl_enable=YES
+#allow_anon_ssl=YES
+#force_local_data_ssl=NO
+#force_local_logins_ssl=NO
+#ssl_tlsv1=YES
+#ssl_sslv2=NO
+#ssl_sslv3=NO
+#rsa_cert_file=/etc/vsftpd/vsftpd.pem
diff --git a/tests/testserver/vsftpd/testdata/vsftpd.user_list b/tests/testserver/vsftpd/testdata/vsftpd.user_list
new file mode 100644
index 0000000000..d283e3d260
--- /dev/null
+++ b/tests/testserver/vsftpd/testdata/vsftpd.user_list
@@ -0,0 +1,20 @@
+# vsftpd userlist
+# If userlist_deny=NO, only allow users in this file
+# If userlist_deny=YES (default), never allow users in this file, and
+# do not even prompt for a password.
+# Note that the default vsftpd pam config also checks /etc/vsftpd.ftpusers
+# for users that are denied.
+root
+bin
+daemon
+adm
+lp
+sync
+shutdown
+halt
+mail
+news
+uucp
+operator
+games
+nobody
diff --git a/tests/testserver/vsftpd/vsftpd.sh b/tests/testserver/vsftpd/vsftpd.sh
new file mode 100755
index 0000000000..1ba1a8c347
--- /dev/null
+++ b/tests/testserver/vsftpd/vsftpd.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:GPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 or (at your option) any later version
+## approved by the KDE Free Qt Foundation. The licenses are as published by
+## the Free Software Foundation and appearing in the file LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+set -ex
+
+# package vsftpd
+
+# add users
+usermod -d "/home/$USER/ftp/" ftp #existing user
+useradd -d "/home/$USER/ftp" -s /bin/bash ftptest; echo "ftptest:$PASS" | chpasswd
+
+# install configurations and test data
+cp $TESTDATA/vsftpd.{conf,user_list} /etc/
+
+# Resolve error message "vsftpd failed - probably invalid config" during boot
+command='start-stop-daemon --start --background -m --oknodo --pidfile /var/run/vsftpd/vsftpd.pid'
+command+=' --exec ${DAEMON}'
+sed -i "s,$command.*$,$command; sleep 1," /etc/init.d/vsftpd
+
+# Populate the FTP sites:
+su $USER -c "cp -r $TESTDATA/ftp ~/ftp"
+ln -s /home/$USER/ftp /var/ftp
+
+# tst_QNetworkReply::getFromFtp_data()
+su $USER -c "mkdir -p ~/ftp/qtest/"
+su $USER -c "cp rfc3252.txt ~/ftp/qtest/"; rm rfc3252.txt
+
+# Duplicate rfc3252.txt 20 times for bigfile tests:
+su $USER -c "seq 20 | xargs -i cat ~/ftp/qtest/rfc3252.txt >> ~/ftp/qtest/bigfile"
+
+# tst_QNetworkReply::getErrors_data(), testdata with special permissions
+su $USER -c "chmod 0600 ~/ftp/pub/file-not-readable.txt"
+
+# Shared FTP folder (sticky bit)
+su $USER -c "mkdir -p -m 1777 ~/ftp/qtest/upload" # FTP incoming dir
+
+# enable service with installed configurations
+service vsftpd restart
diff --git a/util/edid/qedidvendortable.py b/util/edid/qedidvendortable.py
index bac8417326..6fc45dbc17 100755
--- a/util/edid/qedidvendortable.py
+++ b/util/edid/qedidvendortable.py
@@ -29,7 +29,10 @@
import urllib.request
-url = 'https://git.fedorahosted.org/cgit/hwdata.git/plain/pnp.ids'
+# The original source for this data used to be
+# 'https://git.fedorahosted.org/cgit/hwdata.git/plain/pnp.ids'
+# which is discontinued. For now there seems to be a fork at:
+url = 'https://github.com/vcrhonek/hwdata/raw/master/pnp.ids'
copyright = """/****************************************************************************
**
@@ -74,7 +77,7 @@ copyright = """/****************************************************************
notice = """/*
* This lookup table was generated from {}
*
- * Do not change directly this file, instead edit the
+ * Do not change this file directly, instead edit the
* qtbase/util/edid/qedidvendortable.py script and regenerate this file.
*/""".format(url)
@@ -129,6 +132,6 @@ for line in data.split('\n'):
print(copyright)
print(notice)
print(header % (max_vendor_length + 1))
-for pnp_id in vendors.keys():
+for pnp_id in sorted(vendors.keys()):
print(' { "%s", "%s" },' % (pnp_id, vendors[pnp_id]))
print(footer)
diff --git a/util/gradientgen/.gitignore b/util/gradientgen/.gitignore
new file mode 100644
index 0000000000..1a8e824bee
--- /dev/null
+++ b/util/gradientgen/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+tobinaryjson
diff --git a/util/gradientgen/gradientgen.js b/util/gradientgen/gradientgen.js
new file mode 100755
index 0000000000..434f05b2bb
--- /dev/null
+++ b/util/gradientgen/gradientgen.js
@@ -0,0 +1,133 @@
+#! /usr/bin/env node
+
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+const _ = require('lodash');
+const fs = require('fs');
+
+const postcss = require('postcss');
+const minifyGradients = require('postcss-minify-gradients');
+const valueParser = require('postcss-value-parser');
+const parseColor = require('parse-color');
+const math = require('mathjs');
+
+const argc = process.argv.length;
+if (argc < 3) {
+ console.log("usage: gradientgen [mode] <filename>");
+ process.exit(1);
+}
+
+const filename = process.argv[argc - 1];
+const mode = argc > 3 ? process.argv[argc - 2] : 'json';
+
+fs.readFile(filename, (err, css) => {
+ postcss([minifyGradients]).process(css)
+ .then(result => {
+ let enums = [];
+ let gradients = [];
+
+ result.root.walkRules(rule => {
+ gradients.push(null); // Placeholder
+
+ const name = _.startCase(rule.selector).replace(/\s/g, '');
+ if (enums.indexOf(name) >= 0)
+ return; // Duplicate entry
+
+ // We can only support single gradient declarations
+ if (rule.nodes.length > 1)
+ return;
+
+ valueParser(rule.nodes[0].value).walk(node => {
+ if (node.type !== 'function')
+ return;
+
+ if (node.value !== 'linear-gradient')
+ return;
+
+ const args = node.nodes.reduce((args, arg) => {
+ if (arg.type === 'div')
+ args.push([]);
+ else if (arg.type !== 'space')
+ args[args.length - 1].push(arg.value);
+ return args;
+ }, [[]]);
+
+ let angle = valueParser.unit(args[0][0]);
+ if (angle.unit !== 'deg')
+ return;
+
+ angle = parseInt(angle.number);
+ if (angle < 0)
+ angle += 360;
+
+ // Angle is in degrees, but we need radians
+ const radians = angle * math.pi / 180;
+
+ const gradientLine = (math.abs(math.sin(radians)) + math.abs(math.cos(radians)));
+ const cathetus = fn => math.round(fn(radians - math.pi / 2) * gradientLine / 2, 10);
+
+ const x = cathetus(math.cos);
+ const y = cathetus(math.sin);
+
+ const start = { x: 0.5 - x, y: 0.5 - y };
+ const end = { x: 0.5 + x, y: 0.5 + y };
+
+ let stops = []
+
+ let lastPosition = 0;
+ args.slice(1).forEach((arg, index) => {
+ let [color, position = !index ? '0%' : '100%'] = arg;
+ position = parseInt(position) / 100;
+ if (position < lastPosition)
+ position = lastPosition;
+ lastPosition = position;
+ color = parseColor(color).hex;
+ color = parseInt(color.slice(1), 16)
+ stops.push({ color, position })
+ });
+
+ gradients[gradients.length - 1] = { start, end, stops };
+ });
+
+ if (!gradients[gradients.length - 1])
+ return; // Not supported
+
+ enums.push(name);
+
+ if (mode == 'debug')
+ console.log(name, args, gradients[gradients.length - 1])
+ else if (mode == 'enums')
+ console.log(`${name} = ${gradients.length},`)
+ });
+
+ // Done walking declarations
+ if (mode == 'json')
+ console.log(JSON.stringify(gradients, undefined, 4));
+ });
+});
diff --git a/util/gradientgen/package-lock.json b/util/gradientgen/package-lock.json
new file mode 100644
index 0000000000..77939b7fe3
--- /dev/null
+++ b/util/gradientgen/package-lock.json
@@ -0,0 +1,183 @@
+{
+ "name": "gradientgen",
+ "version": "0.0.1",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+ }
+ }
+ },
+ "complex.js": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.4.tgz",
+ "integrity": "sha512-Syl95HpxUTS0QjwNxencZsKukgh1zdS9uXeXX2Us0pHaqBR6kiZZi0AkZ9VpZFwHJyVIUVzI4EumjWdXP3fy6w=="
+ },
+ "decimal.js": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-9.0.1.tgz",
+ "integrity": "sha512-2h0iKbJwnImBk4TGk7CG1xadoA0g3LDPlQhQzbZ221zvG0p2YVUedbKIPsOZXKZGx6YmZMJKYOalpCMxSdDqTQ=="
+ },
+ "escape-latex": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.0.3.tgz",
+ "integrity": "sha512-GfKaG/7FOKdIdciylIzgaShBTPjdGQ5LJ2EcKLKXPLpcMO1MvCEVotkhydEShwCINRacZr2r3fk5A1PwZ4e5sA=="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "fraction.js": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.4.tgz",
+ "integrity": "sha512-aK/oGatyYLTtXRHjfEsytX5fieeR5H4s8sLorzcT12taFS+dbMZejnvm9gRa8mZAPwci24ucjq9epDyaq5u8Iw=="
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo="
+ },
+ "javascript-natural-sort": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
+ "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k="
+ },
+ "js-base64": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz",
+ "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw=="
+ },
+ "lodash": {
+ "version": "4.17.10",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
+ "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
+ },
+ "mathjs": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-4.2.2.tgz",
+ "integrity": "sha512-AKrRfTeGrCBqYN1TYEpLIwrfZh9rKu9lH4n7K0MwTiYqN5crJ7BKh/TnErFvbUmyRVQDv87UjSfNTqeO0JA0JQ==",
+ "requires": {
+ "complex.js": "2.0.4",
+ "decimal.js": "9.0.1",
+ "escape-latex": "1.0.3",
+ "fraction.js": "4.0.4",
+ "javascript-natural-sort": "0.7.1",
+ "seed-random": "2.2.0",
+ "tiny-emitter": "2.0.2",
+ "typed-function": "1.0.3"
+ }
+ },
+ "parse-color": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz",
+ "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=",
+ "requires": {
+ "color-convert": "0.5.3"
+ },
+ "dependencies": {
+ "color-convert": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
+ "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0="
+ }
+ }
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.4.3",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
+ "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
+ "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU="
+ },
+ "seed-random": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz",
+ "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ="
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ },
+ "tiny-emitter": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz",
+ "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow=="
+ },
+ "typed-function": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-1.0.3.tgz",
+ "integrity": "sha512-sVC/1pm70oELDFMdYtFXMFqyawenLoaDiAXA3QvOAwKF/WvFNTSJN23cY2lFNL8iP0kh3T0PPKewrboO8XUVGQ=="
+ }
+ }
+}
diff --git a/util/gradientgen/package.json b/util/gradientgen/package.json
new file mode 100644
index 0000000000..35c324b8cc
--- /dev/null
+++ b/util/gradientgen/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "gradientgen",
+ "version": "0.0.1",
+ "description": "Generates gradient presets for QGradient",
+ "main": "gradientgen.js",
+ "dependencies": {
+ "lodash": "^4.17.10",
+ "mathjs": "^4.2.2",
+ "parse-color": "^1.0.0",
+ "postcss-minify-gradients": "^1.0.5",
+ "postcss-value-parser": "^3.3.0"
+ }
+}
diff --git a/util/gradientgen/tobinaryjson.cpp b/util/gradientgen/tobinaryjson.cpp
new file mode 100644
index 0000000000..65fe07f4b8
--- /dev/null
+++ b/util/gradientgen/tobinaryjson.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <iostream>
+
+#include <qdebug.h>
+#include <qjsondocument.h>
+
+using namespace std;
+
+int main()
+{
+ QByteArray json;
+ while (!cin.eof()) {
+ char arr[1024];
+ cin.read(arr, sizeof(arr));
+ json.append(arr, cin.gcount());
+ }
+
+ QJsonParseError error;
+ QJsonDocument document = QJsonDocument::fromJson(json, &error);
+ if (document.isNull()) {
+ qDebug() << "error:" << qPrintable(error.errorString()) << "at offset" << error.offset;
+ return 1;
+ }
+
+ QByteArray binaryJson = document.toBinaryData();
+ cout.write(binaryJson.constData(), binaryJson.size());
+}
diff --git a/util/gradientgen/tobinaryjson.pro b/util/gradientgen/tobinaryjson.pro
new file mode 100644
index 0000000000..8ed3509278
--- /dev/null
+++ b/util/gradientgen/tobinaryjson.pro
@@ -0,0 +1,4 @@
+SOURCES += tobinaryjson.cpp
+QT = core
+CONFIG += console
+CONFIG -= app_bundle
diff --git a/util/local_database/cldr2qlocalexml.py b/util/local_database/cldr2qlocalexml.py
index 58ea21edab..ce45f631a6 100755
--- a/util/local_database/cldr2qlocalexml.py
+++ b/util/local_database/cldr2qlocalexml.py
@@ -37,6 +37,14 @@ pass the path of that sub-directory to this script as its single
command-line argument. Save its standard output (but not error) to a
file for later processing by ``./qlocalexml2cpp.py``
+When you update the CLDR data, be sure to also update
+src/corelib/tools/qt_attribution.json's entry for unicode-cldr. Check
+this script's output for unknown language, country or script messages;
+if any can be resolved, use their entry in common/main/en.xml to
+append new entries to enumdata.py's lists and update documentation in
+src/corelib/tools/qlocale.qdoc, adding the new entries in alphabetic
+order.
+
.. _CLDR: ftp://unicode.org/Public/cldr/
"""
@@ -142,6 +150,28 @@ def generateLocaleInfo(path):
return _generateLocaleInfo(path, code('language'), code('script'),
code('territory'), code('variant'))
+def getNumberSystems(cache={}):
+ """Cached look-up of number system information.
+
+ Pass no arguments. Returns a mapping from number system names to,
+ for each system, a mapping with keys u'digits', u'type' and
+ u'id'\n"""
+ if not cache:
+ for ns in findTagsInFile(os.path.join(cldr_dir, '..', 'supplemental',
+ 'numberingSystems.xml'),
+ 'numberingSystems'):
+ # ns has form: [u'numberingSystem', [(u'digits', u'0123456789'), (u'type', u'numeric'), (u'id', u'latn')]]
+ entry = dict(ns[1])
+ name = entry[u'id']
+ if u'digits' in entry and ord(entry[u'digits'][0]) > 0xffff:
+ # FIXME: make this redundant:
+ # omit number system if zero doesn't fit in single-char16 UTF-16 :-(
+ sys.stderr.write('skipping number system "%s" [can\'t represent its zero, U+%X, QTBUG-69324]\n'
+ % (name, ord(entry[u'digits'][0])))
+ else:
+ cache[name] = entry
+ return cache
+
def _generateLocaleInfo(path, language_code, script_code, country_code, variant_code=""):
if not path.endswith(".xml"):
return {}
@@ -239,20 +269,9 @@ def _generateLocaleInfo(path, language_code, script_code, country_code, variant_
result['list'] = get_number_in_system(path, "numbers/symbols/list", numbering_system)
result['percent'] = get_number_in_system(path, "numbers/symbols/percentSign", numbering_system)
try:
- numbering_systems = {}
- for ns in findTagsInFile(os.path.join(cldr_dir, '..', 'supplemental',
- 'numberingSystems.xml'),
- 'numberingSystems'):
- tmp = {}
- id = ""
- for data in ns[1:][0]: # ns looks like this: [u'numberingSystem', [(u'digits', u'0123456789'), (u'type', u'numeric'), (u'id', u'latn')]]
- tmp[data[0]] = data[1]
- if data[0] == u"id":
- id = data[1]
- numbering_systems[id] = tmp
- result['zero'] = numbering_systems[numbering_system][u"digits"][0]
- except e:
- sys.stderr.write("Native zero detection problem:\n" + str(e) + "\n")
+ result['zero'] = getNumberSystems()[numbering_system][u"digits"][0]
+ except Exception as e:
+ sys.stderr.write("Native zero detection problem: %s\n" % repr(e))
result['zero'] = get_number_in_system(path, "numbers/symbols/nativeZeroDigit", numbering_system)
result['minus'] = get_number_in_system(path, "numbers/symbols/minusSign", numbering_system)
result['plus'] = get_number_in_system(path, "numbers/symbols/plusSign", numbering_system)
diff --git a/util/local_database/enumdata.py b/util/local_database/enumdata.py
index 2d16e5851d..e24ac02b07 100644
--- a/util/local_database/enumdata.py
+++ b/util/local_database/enumdata.py
@@ -27,779 +27,825 @@
##
#############################################################################
-# language_list and country_list reflect the current values of enums in qlocale.h
-# If new xml language files are available in CLDR, these languages and countries
-# need to be *appended* to this list.
+# Each *_list reflects the current values of its enums in qlocale.h;
+# if new xml language files are available in CLDR, these languages and
+# countries need to be *appended* to this list (for compatibility
+# between versions). Include any spaces present in names (scripts
+# shall squish them out for the enum entries) in *_list, but use the
+# squished forms of names in the *_aliases mappings.
+
+### Qt 6: restore alphabetic order in each list.
language_list = {
- 0 : [ "AnyLanguage", " " ],
- 1 : [ "C", " " ],
- 2 : [ "Abkhazian", "ab" ],
- 3 : [ "Oromo", "om" ], # macrolanguage
- 4 : [ "Afar", "aa" ],
- 5 : [ "Afrikaans", "af" ],
- 6 : [ "Albanian", "sq" ], # macrolanguage
- 7 : [ "Amharic", "am" ],
- 8 : [ "Arabic", "ar" ], # macrolanguage
- 9 : [ "Armenian", "hy" ],
- 10 : [ "Assamese", "as" ],
- 11 : [ "Aymara", "ay" ], # macrolanguage
- 12 : [ "Azerbaijani", "az" ], # macrolanguage
- 13 : [ "Bashkir", "ba" ],
- 14 : [ "Basque", "eu" ],
- 15 : [ "Bengali", "bn" ],
- 16 : [ "Dzongkha", "dz" ],
- 17 : [ "Bihari", "bh" ],
- 18 : [ "Bislama", "bi" ],
- 19 : [ "Breton", "br" ],
- 20 : [ "Bulgarian", "bg" ],
- 21 : [ "Burmese", "my" ],
- 22 : [ "Belarusian", "be" ],
- 23 : [ "Khmer", "km" ],
- 24 : [ "Catalan", "ca" ],
- 25 : [ "Chinese", "zh" ], # macrolanguage
- 26 : [ "Corsican", "co" ],
- 27 : [ "Croatian", "hr" ],
- 28 : [ "Czech", "cs" ],
- 29 : [ "Danish", "da" ],
- 30 : [ "Dutch", "nl" ],
- 31 : [ "English", "en" ],
- 32 : [ "Esperanto", "eo" ],
- 33 : [ "Estonian", "et" ], # macrolanguage
- 34 : [ "Faroese", "fo" ],
- 35 : [ "Fijian", "fj" ],
- 36 : [ "Finnish", "fi" ],
- 37 : [ "French", "fr" ],
- 38 : [ "Western Frisian", "fy" ],
- 39 : [ "Gaelic", "gd" ],
- 40 : [ "Galician", "gl" ],
- 41 : [ "Georgian", "ka" ],
- 42 : [ "German", "de" ],
- 43 : [ "Greek", "el" ],
- 44 : [ "Greenlandic", "kl" ],
- 45 : [ "Guarani", "gn" ], # macrolanguage
- 46 : [ "Gujarati", "gu" ],
- 47 : [ "Hausa", "ha" ],
- 48 : [ "Hebrew", "he" ],
- 49 : [ "Hindi", "hi" ],
- 50 : [ "Hungarian", "hu" ],
- 51 : [ "Icelandic", "is" ],
- 52 : [ "Indonesian", "id" ],
- 53 : [ "Interlingua", "ia" ],
- 54 : [ "Interlingue", "ie" ],
- 55 : [ "Inuktitut", "iu" ], # macrolanguage
- 56 : [ "Inupiak", "ik" ], # macrolanguage
- 57 : [ "Irish", "ga" ],
- 58 : [ "Italian", "it" ],
- 59 : [ "Japanese", "ja" ],
- 60 : [ "Javanese", "jv" ],
- 61 : [ "Kannada", "kn" ],
- 62 : [ "Kashmiri", "ks" ],
- 63 : [ "Kazakh", "kk" ],
- 64 : [ "Kinyarwanda", "rw" ],
- 65 : [ "Kirghiz", "ky" ],
- 66 : [ "Korean", "ko" ],
- 67 : [ "Kurdish", "ku" ], # macrolanguage
- 68 : [ "Rundi", "rn" ],
- 69 : [ "Lao", "lo" ],
- 70 : [ "Latin", "la" ],
- 71 : [ "Latvian", "lv" ], # macrolanguage
- 72 : [ "Lingala", "ln" ],
- 73 : [ "Lithuanian", "lt" ],
- 74 : [ "Macedonian", "mk" ],
- 75 : [ "Malagasy", "mg" ], # macrolanguage
- 76 : [ "Malay", "ms" ], # macrolanguage
- 77 : [ "Malayalam", "ml" ],
- 78 : [ "Maltese", "mt" ],
- 79 : [ "Maori", "mi" ],
- 80 : [ "Marathi", "mr" ],
- 81 : [ "Marshallese", "mh" ],
- 82 : [ "Mongolian", "mn" ], # macrolanguage
- 83 : [ "Nauru", "na" ],
- 84 : [ "Nepali", "ne" ], # macrolanguage
- 85 : [ "NorwegianBokmal", "nb" ],
- 86 : [ "Occitan", "oc" ],
- 87 : [ "Oriya", "or" ], # macrolanguage
- 88 : [ "Pashto", "ps" ], # macrolanguage
- 89 : [ "Persian", "fa" ], # macrolanguage
- 90 : [ "Polish", "pl" ],
- 91 : [ "Portuguese", "pt" ],
- 92 : [ "Punjabi", "pa" ],
- 93 : [ "Quechua", "qu" ], # macrolanguage
- 94 : [ "Romansh", "rm" ],
- 95 : [ "Romanian", "ro" ],
- 96 : [ "Russian", "ru" ],
- 97 : [ "Samoan", "sm" ],
- 98 : [ "Sango", "sg" ],
- 99 : [ "Sanskrit", "sa" ],
- 100 : [ "Serbian", "sr" ],
- 101 : [ "Ossetic", "os" ],
- 102 : [ "Southern Sotho", "st" ],
- 103 : [ "Tswana", "tn" ],
- 104 : [ "Shona", "sn" ],
- 105 : [ "Sindhi", "sd" ],
- 106 : [ "Sinhala", "si" ],
- 107 : [ "Swati", "ss" ],
- 108 : [ "Slovak", "sk" ],
- 109 : [ "Slovenian", "sl" ],
- 110 : [ "Somali", "so" ],
- 111 : [ "Spanish", "es" ],
- 112 : [ "Sundanese", "su" ],
- 113 : [ "Swahili", "sw" ], # macrolanguage
- 114 : [ "Swedish", "sv" ],
- 115 : [ "Sardinian", "sc" ], # macrolanguage
- 116 : [ "Tajik", "tg" ],
- 117 : [ "Tamil", "ta" ],
- 118 : [ "Tatar", "tt" ],
- 119 : [ "Telugu", "te" ],
- 120 : [ "Thai", "th" ],
- 121 : [ "Tibetan", "bo" ],
- 122 : [ "Tigrinya", "ti" ],
- 123 : [ "Tongan", "to" ],
- 124 : [ "Tsonga", "ts" ],
- 125 : [ "Turkish", "tr" ],
- 126 : [ "Turkmen", "tk" ],
- 127 : [ "Tahitian", "ty" ],
- 128 : [ "Uighur", "ug" ],
- 129 : [ "Ukrainian", "uk" ],
- 130 : [ "Urdu", "ur" ],
- 131 : [ "Uzbek", "uz" ], # macrolanguage
- 132 : [ "Vietnamese", "vi" ],
- 133 : [ "Volapuk", "vo" ],
- 134 : [ "Welsh", "cy" ],
- 135 : [ "Wolof", "wo" ],
- 136 : [ "Xhosa", "xh" ],
- 137 : [ "Yiddish", "yi" ], # macrolanguage
- 138 : [ "Yoruba", "yo" ],
- 139 : [ "Zhuang", "za" ], # macrolanguage
- 140 : [ "Zulu", "zu" ],
- 141 : [ "NorwegianNynorsk", "nn" ],
- 142 : [ "Bosnian", "bs" ],
- 143 : [ "Divehi", "dv" ],
- 144 : [ "Manx", "gv" ],
- 145 : [ "Cornish", "kw" ],
- 146 : [ "Akan", "ak" ], # macrolanguage
- 147 : [ "Konkani", "kok" ],
- 148 : [ "Ga", "gaa" ],
- 149 : [ "Igbo", "ig" ],
- 150 : [ "Kamba", "kam" ],
- 151 : [ "Syriac", "syr" ],
- 152 : [ "Blin", "byn" ],
- 153 : [ "Geez", "gez" ],
- 154 : [ "Koro", "kfo" ],
- 155 : [ "Sidamo", "sid" ],
- 156 : [ "Atsam", "cch" ],
- 157 : [ "Tigre", "tig" ],
- 158 : [ "Jju", "kaj" ],
- 159 : [ "Friulian", "fur" ],
- 160 : [ "Venda", "ve" ],
- 161 : [ "Ewe", "ee" ],
- 162 : [ "Walamo", "wal" ],
- 163 : [ "Hawaiian", "haw" ],
- 164 : [ "Tyap", "kcg" ],
- 165 : [ "Nyanja", "ny" ],
- 166 : [ "Filipino", "fil" ],
- 167 : [ "Swiss German", "gsw" ],
- 168 : [ "Sichuan Yi", "ii" ],
- 169 : [ "Kpelle", "kpe" ],
- 170 : [ "Low German", "nds" ],
- 171 : [ "South Ndebele", "nr" ],
- 172 : [ "Northern Sotho", "nso" ],
- 173 : [ "Northern Sami", "se" ],
- 174 : [ "Taroko", "trv" ],
- 175 : [ "Gusii", "guz" ],
- 176 : [ "Taita", "dav" ],
- 177 : [ "Fulah", "ff" ], # macrolanguage
- 178 : [ "Kikuyu", "ki" ],
- 179 : [ "Samburu", "saq" ],
- 180 : [ "Sena", "seh" ],
- 181 : [ "North Ndebele", "nd" ],
- 182 : [ "Rombo", "rof" ],
- 183 : [ "Tachelhit", "shi" ],
- 184 : [ "Kabyle", "kab" ],
- 185 : [ "Nyankole", "nyn" ],
- 186 : [ "Bena", "bez" ],
- 187 : [ "Vunjo", "vun" ],
- 188 : [ "Bambara", "bm" ],
- 189 : [ "Embu", "ebu" ],
- 190 : [ "Cherokee", "chr" ],
- 191 : [ "Morisyen", "mfe" ],
- 192 : [ "Makonde", "kde" ],
- 193 : [ "Langi", "lag" ],
- 194 : [ "Ganda", "lg" ],
- 195 : [ "Bemba", "bem" ],
- 196 : [ "Kabuverdianu", "kea" ],
- 197 : [ "Meru", "mer" ],
- 198 : [ "Kalenjin", "kln" ],
- 199 : [ "Nama", "naq" ],
- 200 : [ "Machame", "jmc" ],
- 201 : [ "Colognian", "ksh" ],
- 202 : [ "Masai", "mas" ],
- 203 : [ "Soga", "xog" ],
- 204 : [ "Luyia", "luy" ],
- 205 : [ "Asu", "asa" ],
- 206 : [ "Teso", "teo" ],
- 207 : [ "Saho", "ssy" ],
- 208 : [ "Koyra Chiini", "khq" ],
- 209 : [ "Rwa", "rwk" ],
- 210 : [ "Luo", "luo" ],
- 211 : [ "Chiga", "cgg" ],
- 212 : [ "Central Morocco Tamazight", "tzm" ],
- 213 : [ "Koyraboro Senni", "ses" ],
- 214 : [ "Shambala", "ksb" ],
- 215 : [ "Bodo", "brx" ],
- 216 : [ "Avaric", "av" ],
- 217 : [ "Chamorro", "ch" ],
- 218 : [ "Chechen", "ce" ],
- 219 : [ "Church", "cu" ], # macrolanguage
- 220 : [ "Chuvash", "cv" ],
- 221 : [ "Cree", "cr" ], # macrolanguage
- 222 : [ "Haitian", "ht" ],
- 223 : [ "Herero", "hz" ],
- 224 : [ "Hiri Motu", "ho" ],
- 225 : [ "Kanuri", "kr" ], # macrolanguage
- 226 : [ "Komi", "kv" ], # macrolanguage
- 227 : [ "Kongo", "kg" ], # macrolanguage
- 228 : [ "Kwanyama", "kj" ],
- 229 : [ "Limburgish", "li" ],
- 230 : [ "LubaKatanga", "lu" ],
- 231 : [ "Luxembourgish", "lb" ],
- 232 : [ "Navaho", "nv" ],
- 233 : [ "Ndonga", "ng" ],
- 234 : [ "Ojibwa", "oj" ], # macrolanguage
- 235 : [ "Pali", "pi" ], # macrolanguage
- 236 : [ "Walloon", "wa" ],
- 237 : [ "Aghem", "agq" ],
- 238 : [ "Basaa", "bas" ],
- 239 : [ "Zarma", "dje" ],
- 240 : [ "Duala", "dua" ],
- 241 : [ "JolaFonyi", "dyo" ],
- 242 : [ "Ewondo", "ewo" ],
- 243 : [ "Bafia", "ksf" ],
- 244 : [ "MakhuwaMeetto", "mgh" ],
- 245 : [ "Mundang", "mua" ],
- 246 : [ "Kwasio", "nmg" ],
- 247 : [ "Nuer", "nus" ],
- 248 : [ "Sakha", "sah" ],
- 249 : [ "Sangu", "sbp" ],
- 250 : [ "Congo Swahili", "swc" ],
- 251 : [ "Tasawaq", "twq" ],
- 252 : [ "Vai", "vai" ],
- 253 : [ "Walser", "wae" ],
- 254 : [ "Yangben", "yav" ],
- 255 : [ "Avestan", "ae" ],
- 256 : [ "Asturian", "ast" ],
- 257 : [ "Ngomba", "jgo" ],
- 258 : [ "Kako", "kkj" ],
- 259 : [ "Meta", "mgo" ],
- 260 : [ "Ngiemboon", "nnh" ],
- 261 : [ "Aragonese", "an" ],
- 262 : [ "Akkadian", "akk" ],
- 263 : [ "AncientEgyptian", "egy" ],
- 264 : [ "AncientGreek", "grc" ],
- 265 : [ "Aramaic", "arc" ],
- 266 : [ "Balinese", "ban" ],
- 267 : [ "Bamun", "bax" ],
- 268 : [ "BatakToba", "bbc" ],
- 269 : [ "Buginese", "bug" ],
- 270 : [ "Buhid", "bku" ],
- 271 : [ "Carian", "xcr" ],
- 272 : [ "Chakma", "ccp" ],
- 273 : [ "ClassicalMandaic", "myz" ],
- 274 : [ "Coptic", "cop" ],
- 275 : [ "Dogri", "doi" ], # macrolanguage
- 276 : [ "EasternCham", "cjm" ],
- 277 : [ "EasternKayah", "eky" ],
- 278 : [ "Etruscan", "ett" ],
- 279 : [ "Gothic", "got" ],
- 280 : [ "Hanunoo", "hnn" ],
- 281 : [ "Ingush", "inh" ],
- 282 : [ "LargeFloweryMiao", "hmd" ],
- 283 : [ "Lepcha", "lep" ],
- 284 : [ "Limbu", "lif" ],
- 285 : [ "Lisu", "lis" ],
- 286 : [ "Lu", "khb" ],
- 287 : [ "Lycian", "xlc" ],
- 288 : [ "Lydian", "xld" ],
- 289 : [ "Mandingo", "man" ], # macrolanguage
- 290 : [ "Manipuri", "mni" ],
- 291 : [ "Meroitic", "xmr" ],
- 292 : [ "NorthernThai", "nod" ],
- 293 : [ "OldIrish", "sga" ],
- 294 : [ "OldNorse", "non" ],
- 295 : [ "OldPersian", "peo" ],
- 296 : [ "OldTurkish", "otk" ],
- 297 : [ "Pahlavi", "pal" ],
- 298 : [ "Parthian", "xpr" ],
- 299 : [ "Phoenician", "phn" ],
- 300 : [ "PrakritLanguage", "pra" ],
- 301 : [ "Rejang", "rej" ],
- 302 : [ "Sabaean", "xsa" ],
- 303 : [ "Samaritan", "smp" ],
- 304 : [ "Santali", "sat" ],
- 305 : [ "Saurashtra", "saz" ],
- 306 : [ "Sora", "srb" ],
- 307 : [ "Sylheti", "syl" ],
- 308 : [ "Tagbanwa", "tbw" ],
- 309 : [ "TaiDam", "blt" ],
- 310 : [ "TaiNua", "tdd" ],
- 311 : [ "Ugaritic", "uga" ],
- 312 : [ "Akoose", "bss" ],
- 313 : [ "Lakota", "lkt" ],
- 314 : [ "Standard Moroccan Tamazight", "zgh" ],
- 315 : [ "Mapuche", "arn" ],
- 316 : [ "Central Kurdish", "ckb" ],
- 317 : [ "LowerSorbian", "dsb" ],
- 318 : [ "UpperSorbian", "hsb" ],
- 319 : [ "Kenyang", "ken" ],
- 320 : [ "Mohawk", "moh" ],
- 321 : [ "Nko", "nqo" ],
- 322 : [ "Prussian", "prg" ],
- 323 : [ "Kiche", "quc" ],
- 324 : [ "Southern Sami", "sma" ],
- 325 : [ "Lule Sami", "smj" ],
- 326 : [ "Inari Sami", "smn" ],
- 327 : [ "Skolt Sami", "sms" ],
- 328 : [ "Warlpiri", "wbp" ],
- 329 : [ "Manichaean Middle Persian", "xmn" ],
- 330 : [ "Mende", "men" ],
- 331 : [ "Ancient North Arabian", "xna" ],
- 332 : [ "Linear A", "lab" ],
- 333 : [ "Hmong Njua", "hnj" ],
- 334 : [ "Ho", "hoc" ],
- 335 : [ "Lezghian", "lez" ],
- 336 : [ "Bassa", "bsq" ],
- 337 : [ "Mono", "mru" ],
- 338 : [ "Tedim Chin", "ctd" ],
- 339 : [ "Maithili", "mai" ],
- 340 : [ "Ahom", "aho" ],
- 341 : [ "American Sign Language", "ase" ],
- 342 : [ "Ardhamagadhi Prakrit", "pka" ],
- 343 : [ "Bhojpuri", "bho" ],
- 344 : [ "Hieroglyphic Luwian", "hlu" ],
- 345 : [ "Literary Chinese", "lzh" ],
- 346 : [ "Mazanderani", "mzn" ],
- 347 : [ "Mru", "mro" ],
- 348 : [ "Newari", "new" ],
- 349 : [ "Northern Luri", "lrc" ],
- 350 : [ "Palauan", "pau" ],
- 351 : [ "Papiamento", "pap" ],
- 352 : [ "Saraiki", "skr" ],
- 353 : [ "Tokelau", "tkl" ],
- 354 : [ "Tok Pisin", "tpi" ],
- 355 : [ "Tuvalu", "tvl" ],
- 356 : [ "UncodedLanguages", "mis" ],
- 357 : [ "Cantonese", "yue" ],
- 358 : [ "Osage", "osa" ],
- 359 : [ "Tangut", "txg" ]
+ 0 : ["AnyLanguage", " "],
+ 1 : ["C", " "],
+ 2 : ["Abkhazian", "ab"],
+ 3 : ["Oromo", "om"], # macrolanguage
+ 4 : ["Afar", "aa"],
+ 5 : ["Afrikaans", "af"],
+ 6 : ["Albanian", "sq"], # macrolanguage
+ 7 : ["Amharic", "am"],
+ 8 : ["Arabic", "ar"], # macrolanguage
+ 9 : ["Armenian", "hy"],
+ 10 : ["Assamese", "as"],
+ 11 : ["Aymara", "ay"], # macrolanguage
+ 12 : ["Azerbaijani", "az"], # macrolanguage
+ 13 : ["Bashkir", "ba"],
+ 14 : ["Basque", "eu"],
+ 15 : ["Bengali", "bn"],
+ 16 : ["Dzongkha", "dz"],
+ 17 : ["Bihari", "bh"],
+ 18 : ["Bislama", "bi"],
+ 19 : ["Breton", "br"],
+ 20 : ["Bulgarian", "bg"],
+ 21 : ["Burmese", "my"],
+ 22 : ["Belarusian", "be"],
+ 23 : ["Khmer", "km"],
+ 24 : ["Catalan", "ca"],
+ 25 : ["Chinese", "zh"], # macrolanguage
+ 26 : ["Corsican", "co"],
+ 27 : ["Croatian", "hr"],
+ 28 : ["Czech", "cs"],
+ 29 : ["Danish", "da"],
+ 30 : ["Dutch", "nl"],
+ 31 : ["English", "en"],
+ 32 : ["Esperanto", "eo"],
+ 33 : ["Estonian", "et"], # macrolanguage
+ 34 : ["Faroese", "fo"],
+ 35 : ["Fijian", "fj"],
+ 36 : ["Finnish", "fi"],
+ 37 : ["French", "fr"],
+ 38 : ["Western Frisian", "fy"],
+ 39 : ["Gaelic", "gd"],
+ 40 : ["Galician", "gl"],
+ 41 : ["Georgian", "ka"],
+ 42 : ["German", "de"],
+ 43 : ["Greek", "el"],
+ 44 : ["Greenlandic", "kl"],
+ 45 : ["Guarani", "gn"], # macrolanguage
+ 46 : ["Gujarati", "gu"],
+ 47 : ["Hausa", "ha"],
+ 48 : ["Hebrew", "he"],
+ 49 : ["Hindi", "hi"],
+ 50 : ["Hungarian", "hu"],
+ 51 : ["Icelandic", "is"],
+ 52 : ["Indonesian", "id"],
+ 53 : ["Interlingua", "ia"],
+ 54 : ["Interlingue", "ie"],
+ 55 : ["Inuktitut", "iu"], # macrolanguage
+ 56 : ["Inupiak", "ik"], # macrolanguage
+ 57 : ["Irish", "ga"],
+ 58 : ["Italian", "it"],
+ 59 : ["Japanese", "ja"],
+ 60 : ["Javanese", "jv"],
+ 61 : ["Kannada", "kn"],
+ 62 : ["Kashmiri", "ks"],
+ 63 : ["Kazakh", "kk"],
+ 64 : ["Kinyarwanda", "rw"],
+ 65 : ["Kirghiz", "ky"],
+ 66 : ["Korean", "ko"],
+ 67 : ["Kurdish", "ku"], # macrolanguage
+ 68 : ["Rundi", "rn"],
+ 69 : ["Lao", "lo"],
+ 70 : ["Latin", "la"],
+ 71 : ["Latvian", "lv"], # macrolanguage
+ 72 : ["Lingala", "ln"],
+ 73 : ["Lithuanian", "lt"],
+ 74 : ["Macedonian", "mk"],
+ 75 : ["Malagasy", "mg"], # macrolanguage
+ 76 : ["Malay", "ms"], # macrolanguage
+ 77 : ["Malayalam", "ml"],
+ 78 : ["Maltese", "mt"],
+ 79 : ["Maori", "mi"],
+ 80 : ["Marathi", "mr"],
+ 81 : ["Marshallese", "mh"],
+ 82 : ["Mongolian", "mn"], # macrolanguage
+ 83 : ["Nauru", "na"],
+ 84 : ["Nepali", "ne"], # macrolanguage
+ 85 : ["Norwegian Bokmal", "nb"],
+ 86 : ["Occitan", "oc"],
+ 87 : ["Oriya", "or"], # macrolanguage
+ 88 : ["Pashto", "ps"], # macrolanguage
+ 89 : ["Persian", "fa"], # macrolanguage
+ 90 : ["Polish", "pl"],
+ 91 : ["Portuguese", "pt"],
+ 92 : ["Punjabi", "pa"],
+ 93 : ["Quechua", "qu"], # macrolanguage
+ 94 : ["Romansh", "rm"],
+ 95 : ["Romanian", "ro"],
+ 96 : ["Russian", "ru"],
+ 97 : ["Samoan", "sm"],
+ 98 : ["Sango", "sg"],
+ 99 : ["Sanskrit", "sa"],
+ 100 : ["Serbian", "sr"],
+ 101 : ["Ossetic", "os"],
+ 102 : ["Southern Sotho", "st"],
+ 103 : ["Tswana", "tn"],
+ 104 : ["Shona", "sn"],
+ 105 : ["Sindhi", "sd"],
+ 106 : ["Sinhala", "si"],
+ 107 : ["Swati", "ss"],
+ 108 : ["Slovak", "sk"],
+ 109 : ["Slovenian", "sl"],
+ 110 : ["Somali", "so"],
+ 111 : ["Spanish", "es"],
+ 112 : ["Sundanese", "su"],
+ 113 : ["Swahili", "sw"], # macrolanguage
+ 114 : ["Swedish", "sv"],
+ 115 : ["Sardinian", "sc"], # macrolanguage
+ 116 : ["Tajik", "tg"],
+ 117 : ["Tamil", "ta"],
+ 118 : ["Tatar", "tt"],
+ 119 : ["Telugu", "te"],
+ 120 : ["Thai", "th"],
+ 121 : ["Tibetan", "bo"],
+ 122 : ["Tigrinya", "ti"],
+ 123 : ["Tongan", "to"],
+ 124 : ["Tsonga", "ts"],
+ 125 : ["Turkish", "tr"],
+ 126 : ["Turkmen", "tk"],
+ 127 : ["Tahitian", "ty"],
+ 128 : ["Uighur", "ug"],
+ 129 : ["Ukrainian", "uk"],
+ 130 : ["Urdu", "ur"],
+ 131 : ["Uzbek", "uz"], # macrolanguage
+ 132 : ["Vietnamese", "vi"],
+ 133 : ["Volapuk", "vo"],
+ 134 : ["Welsh", "cy"],
+ 135 : ["Wolof", "wo"],
+ 136 : ["Xhosa", "xh"],
+ 137 : ["Yiddish", "yi"], # macrolanguage
+ 138 : ["Yoruba", "yo"],
+ 139 : ["Zhuang", "za"], # macrolanguage
+ 140 : ["Zulu", "zu"],
+ 141 : ["Norwegian Nynorsk", "nn"],
+ 142 : ["Bosnian", "bs"],
+ 143 : ["Divehi", "dv"],
+ 144 : ["Manx", "gv"],
+ 145 : ["Cornish", "kw"],
+ 146 : ["Akan", "ak"], # macrolanguage
+ 147 : ["Konkani", "kok"],
+ 148 : ["Ga", "gaa"],
+ 149 : ["Igbo", "ig" ],
+ 150 : ["Kamba", "kam"],
+ 151 : ["Syriac", "syr"],
+ 152 : ["Blin", "byn"],
+ 153 : ["Geez", "gez"],
+ 154 : ["Koro", "kfo"],
+ 155 : ["Sidamo", "sid"],
+ 156 : ["Atsam", "cch"],
+ 157 : ["Tigre", "tig"],
+ 158 : ["Jju", "kaj"],
+ 159 : ["Friulian", "fur"],
+ 160 : ["Venda", "ve" ],
+ 161 : ["Ewe", "ee" ],
+ 162 : ["Walamo", "wal"],
+ 163 : ["Hawaiian", "haw"],
+ 164 : ["Tyap", "kcg"],
+ 165 : ["Nyanja", "ny" ],
+ 166 : ["Filipino", "fil"],
+ 167 : ["Swiss German", "gsw"],
+ 168 : ["Sichuan Yi", "ii" ],
+ 169 : ["Kpelle", "kpe"],
+ 170 : ["Low German", "nds"],
+ 171 : ["South Ndebele", "nr" ],
+ 172 : ["Northern Sotho", "nso"],
+ 173 : ["Northern Sami", "se" ],
+ 174 : ["Taroko", "trv"],
+ 175 : ["Gusii", "guz"],
+ 176 : ["Taita", "dav"],
+ 177 : ["Fulah", "ff"], # macrolanguage
+ 178 : ["Kikuyu", "ki"],
+ 179 : ["Samburu", "saq"],
+ 180 : ["Sena", "seh"],
+ 181 : ["North Ndebele", "nd"],
+ 182 : ["Rombo", "rof"],
+ 183 : ["Tachelhit", "shi"],
+ 184 : ["Kabyle", "kab"],
+ 185 : ["Nyankole", "nyn"],
+ 186 : ["Bena", "bez"],
+ 187 : ["Vunjo", "vun"],
+ 188 : ["Bambara", "bm"],
+ 189 : ["Embu", "ebu"],
+ 190 : ["Cherokee", "chr"],
+ 191 : ["Morisyen", "mfe"],
+ 192 : ["Makonde", "kde"],
+ 193 : ["Langi", "lag"],
+ 194 : ["Ganda", "lg"],
+ 195 : ["Bemba", "bem"],
+ 196 : ["Kabuverdianu", "kea"],
+ 197 : ["Meru", "mer"],
+ 198 : ["Kalenjin", "kln"],
+ 199 : ["Nama", "naq"],
+ 200 : ["Machame", "jmc"],
+ 201 : ["Colognian", "ksh"],
+ 202 : ["Masai", "mas"],
+ 203 : ["Soga", "xog"],
+ 204 : ["Luyia", "luy"],
+ 205 : ["Asu", "asa"],
+ 206 : ["Teso", "teo"],
+ 207 : ["Saho", "ssy"],
+ 208 : ["Koyra Chiini", "khq"],
+ 209 : ["Rwa", "rwk"],
+ 210 : ["Luo", "luo"],
+ 211 : ["Chiga", "cgg"],
+ 212 : ["Central Morocco Tamazight", "tzm"],
+ 213 : ["Koyraboro Senni", "ses"],
+ 214 : ["Shambala", "ksb"],
+ 215 : ["Bodo", "brx"],
+ 216 : ["Avaric", "av"],
+ 217 : ["Chamorro", "ch"],
+ 218 : ["Chechen", "ce"],
+ 219 : ["Church", "cu"], # macrolanguage
+ 220 : ["Chuvash", "cv"],
+ 221 : ["Cree", "cr"], # macrolanguage
+ 222 : ["Haitian", "ht"],
+ 223 : ["Herero", "hz"],
+ 224 : ["Hiri Motu", "ho"],
+ 225 : ["Kanuri", "kr"], # macrolanguage
+ 226 : ["Komi", "kv"], # macrolanguage
+ 227 : ["Kongo", "kg"], # macrolanguage
+ 228 : ["Kwanyama", "kj"],
+ 229 : ["Limburgish", "li"],
+ 230 : ["Luba Katanga", "lu"],
+ 231 : ["Luxembourgish", "lb"],
+ 232 : ["Navaho", "nv"],
+ 233 : ["Ndonga", "ng"],
+ 234 : ["Ojibwa", "oj"], # macrolanguage
+ 235 : ["Pali", "pi"], # macrolanguage
+ 236 : ["Walloon", "wa"],
+ 237 : ["Aghem", "agq"],
+ 238 : ["Basaa", "bas"],
+ 239 : ["Zarma", "dje"],
+ 240 : ["Duala", "dua"],
+ 241 : ["Jola Fonyi", "dyo"],
+ 242 : ["Ewondo", "ewo"],
+ 243 : ["Bafia", "ksf"],
+ 244 : ["Makhuwa Meetto", "mgh"],
+ 245 : ["Mundang", "mua"],
+ 246 : ["Kwasio", "nmg"],
+ 247 : ["Nuer", "nus"],
+ 248 : ["Sakha", "sah"],
+ 249 : ["Sangu", "sbp"],
+ 250 : ["Congo Swahili", "swc"],
+ 251 : ["Tasawaq", "twq"],
+ 252 : ["Vai", "vai"],
+ 253 : ["Walser", "wae"],
+ 254 : ["Yangben", "yav"],
+ 255 : ["Avestan", "ae"],
+ 256 : ["Asturian", "ast"],
+ 257 : ["Ngomba", "jgo"],
+ 258 : ["Kako", "kkj"],
+ 259 : ["Meta", "mgo"],
+ 260 : ["Ngiemboon", "nnh"],
+ 261 : ["Aragonese", "an"],
+ 262 : ["Akkadian", "akk"],
+ 263 : ["Ancient Egyptian", "egy"],
+ 264 : ["Ancient Greek", "grc"],
+ 265 : ["Aramaic", "arc"],
+ 266 : ["Balinese", "ban"],
+ 267 : ["Bamun", "bax"],
+ 268 : ["Batak Toba", "bbc"],
+ 269 : ["Buginese", "bug"],
+ 270 : ["Buhid", "bku"],
+ 271 : ["Carian", "xcr"],
+ 272 : ["Chakma", "ccp"],
+ 273 : ["Classical Mandaic", "myz"],
+ 274 : ["Coptic", "cop"],
+ 275 : ["Dogri", "doi"], # macrolanguage
+ 276 : ["Eastern Cham", "cjm"],
+ 277 : ["Eastern Kayah", "eky"],
+ 278 : ["Etruscan", "ett"],
+ 279 : ["Gothic", "got"],
+ 280 : ["Hanunoo", "hnn"],
+ 281 : ["Ingush", "inh"],
+ 282 : ["Large Flowery Miao", "hmd"],
+ 283 : ["Lepcha", "lep"],
+ 284 : ["Limbu", "lif"],
+ 285 : ["Lisu", "lis"],
+ 286 : ["Lu", "khb"],
+ 287 : ["Lycian", "xlc"],
+ 288 : ["Lydian", "xld"],
+ 289 : ["Mandingo", "man"], # macrolanguage
+ 290 : ["Manipuri", "mni"],
+ 291 : ["Meroitic", "xmr"],
+ 292 : ["Northern Thai", "nod"],
+ 293 : ["Old Irish", "sga"],
+ 294 : ["Old Norse", "non"],
+ 295 : ["Old Persian", "peo"],
+ 296 : ["Old Turkish", "otk"],
+ 297 : ["Pahlavi", "pal"],
+ 298 : ["Parthian", "xpr"],
+ 299 : ["Phoenician", "phn"],
+ 300 : ["Prakrit Language", "pra"],
+ 301 : ["Rejang", "rej"],
+ 302 : ["Sabaean", "xsa"],
+ 303 : ["Samaritan", "smp"],
+ 304 : ["Santali", "sat"],
+ 305 : ["Saurashtra", "saz"],
+ 306 : ["Sora", "srb"],
+ 307 : ["Sylheti", "syl"],
+ 308 : ["Tagbanwa", "tbw"],
+ 309 : ["Tai Dam", "blt"],
+ 310 : ["Tai Nua", "tdd"],
+ 311 : ["Ugaritic", "uga"],
+ 312 : ["Akoose", "bss"],
+ 313 : ["Lakota", "lkt"],
+ 314 : ["Standard Moroccan Tamazight", "zgh"],
+ 315 : ["Mapuche", "arn"],
+ 316 : ["Central Kurdish", "ckb"],
+ 317 : ["Lower Sorbian", "dsb"],
+ 318 : ["Upper Sorbian", "hsb"],
+ 319 : ["Kenyang", "ken"],
+ 320 : ["Mohawk", "moh"],
+ 321 : ["Nko", "nqo"],
+ 322 : ["Prussian", "prg"],
+ 323 : ["Kiche", "quc"],
+ 324 : ["Southern Sami", "sma"],
+ 325 : ["Lule Sami", "smj"],
+ 326 : ["Inari Sami", "smn"],
+ 327 : ["Skolt Sami", "sms"],
+ 328 : ["Warlpiri", "wbp"],
+ 329 : ["Manichaean Middle Persian", "xmn"],
+ 330 : ["Mende", "men"],
+ 331 : ["Ancient North Arabian", "xna"],
+ 332 : ["Linear A", "lab"],
+ 333 : ["Hmong Njua", "hnj"],
+ 334 : ["Ho", "hoc"],
+ 335 : ["Lezghian", "lez"],
+ 336 : ["Bassa", "bsq"],
+ 337 : ["Mono", "mru"],
+ 338 : ["Tedim Chin", "ctd"],
+ 339 : ["Maithili", "mai"],
+ 340 : ["Ahom", "aho"],
+ 341 : ["American Sign Language", "ase"],
+ 342 : ["Ardhamagadhi Prakrit", "pka"],
+ 343 : ["Bhojpuri", "bho"],
+ 344 : ["Hieroglyphic Luwian", "hlu"],
+ 345 : ["Literary Chinese", "lzh"],
+ 346 : ["Mazanderani", "mzn"],
+ 347 : ["Mru", "mro"],
+ 348 : ["Newari", "new"],
+ 349 : ["Northern Luri", "lrc"],
+ 350 : ["Palauan", "pau"],
+ 351 : ["Papiamento", "pap"],
+ 352 : ["Saraiki", "skr"],
+ 353 : ["Tokelau", "tkl"],
+ 354 : ["Tok Pisin", "tpi"],
+ 355 : ["Tuvalu", "tvl"],
+ 356 : ["Uncoded Languages", "mis"],
+ 357 : ["Cantonese", "yue"],
+ 358 : ["Osage", "osa"],
+ 359 : ["Tangut", "txg"]
+}
+
+language_aliases = {
+ # Legacy - should disappear at some point:
+ 'Norwegian': 'NorwegianBokmal',
+ 'Moldavian': 'Romanian',
+ 'SerboCroatian': 'Serbian',
+ 'Tagalog': 'Filipino',
+ 'Twi': 'Akan',
+ # Renamings:
+ 'Afan': 'Oromo',
+ 'Byelorussian': 'Belarusian',
+ 'Bhutani': 'Dzongkha',
+ 'Cambodian': 'Khmer',
+ 'Kurundi': 'Rundi',
+ 'RhaetoRomance': 'Romansh',
+ 'Chewa': 'Nyanja',
+ 'Frisian': 'WesternFrisian',
+ 'Uigur': 'Uighur',
}
country_list = {
- 0 : [ "AnyCountry", "ZZ" ],
- 1 : [ "Afghanistan", "AF" ],
- 2 : [ "Albania", "AL" ],
- 3 : [ "Algeria", "DZ" ],
- 4 : [ "AmericanSamoa", "AS" ],
- 5 : [ "Andorra", "AD" ],
- 6 : [ "Angola", "AO" ],
- 7 : [ "Anguilla", "AI" ],
- 8 : [ "Antarctica", "AQ" ],
- 9 : [ "AntiguaAndBarbuda", "AG" ],
- 10 : [ "Argentina", "AR" ],
- 11 : [ "Armenia", "AM" ],
- 12 : [ "Aruba", "AW" ],
- 13 : [ "Australia", "AU" ],
- 14 : [ "Austria", "AT" ],
- 15 : [ "Azerbaijan", "AZ" ],
- 16 : [ "Bahamas", "BS" ],
- 17 : [ "Bahrain", "BH" ],
- 18 : [ "Bangladesh", "BD" ],
- 19 : [ "Barbados", "BB" ],
- 20 : [ "Belarus", "BY" ],
- 21 : [ "Belgium", "BE" ],
- 22 : [ "Belize", "BZ" ],
- 23 : [ "Benin", "BJ" ],
- 24 : [ "Bermuda", "BM" ],
- 25 : [ "Bhutan", "BT" ],
- 26 : [ "Bolivia", "BO" ],
- 27 : [ "BosniaAndHerzegowina", "BA" ],
- 28 : [ "Botswana", "BW" ],
- 29 : [ "BouvetIsland", "BV" ],
- 30 : [ "Brazil", "BR" ],
- 31 : [ "BritishIndianOceanTerritory", "IO" ],
- 32 : [ "Brunei", "BN" ],
- 33 : [ "Bulgaria", "BG" ],
- 34 : [ "BurkinaFaso", "BF" ],
- 35 : [ "Burundi", "BI" ],
- 36 : [ "Cambodia", "KH" ],
- 37 : [ "Cameroon", "CM" ],
- 38 : [ "Canada", "CA" ],
- 39 : [ "CapeVerde", "CV" ],
- 40 : [ "CaymanIslands", "KY" ],
- 41 : [ "CentralAfricanRepublic", "CF" ],
- 42 : [ "Chad", "TD" ],
- 43 : [ "Chile", "CL" ],
- 44 : [ "China", "CN" ],
- 45 : [ "ChristmasIsland", "CX" ],
- 46 : [ "CocosIslands", "CC" ],
- 47 : [ "Colombia", "CO" ],
- 48 : [ "Comoros", "KM" ],
- 49 : [ "CongoKinshasa", "CD" ],
- 50 : [ "CongoBrazzaville", "CG" ],
- 51 : [ "CookIslands", "CK" ],
- 52 : [ "CostaRica", "CR" ],
- 53 : [ "IvoryCoast", "CI" ],
- 54 : [ "Croatia", "HR" ],
- 55 : [ "Cuba", "CU" ],
- 56 : [ "Cyprus", "CY" ],
- 57 : [ "CzechRepublic", "CZ" ],
- 58 : [ "Denmark", "DK" ],
- 59 : [ "Djibouti", "DJ" ],
- 60 : [ "Dominica", "DM" ],
- 61 : [ "DominicanRepublic", "DO" ],
- 62 : [ "EastTimor", "TL" ],
- 63 : [ "Ecuador", "EC" ],
- 64 : [ "Egypt", "EG" ],
- 65 : [ "ElSalvador", "SV" ],
- 66 : [ "EquatorialGuinea", "GQ" ],
- 67 : [ "Eritrea", "ER" ],
- 68 : [ "Estonia", "EE" ],
- 69 : [ "Ethiopia", "ET" ],
- 70 : [ "FalklandIslands", "FK" ],
- 71 : [ "FaroeIslands", "FO" ],
- 72 : [ "Fiji", "FJ" ],
- 73 : [ "Finland", "FI" ],
- 74 : [ "France", "FR" ],
- 75 : [ "Guernsey", "GG" ],
- 76 : [ "FrenchGuiana", "GF" ],
- 77 : [ "FrenchPolynesia", "PF" ],
- 78 : [ "FrenchSouthernTerritories", "TF" ],
- 79 : [ "Gabon", "GA" ],
- 80 : [ "Gambia", "GM" ],
- 81 : [ "Georgia", "GE" ],
- 82 : [ "Germany", "DE" ],
- 83 : [ "Ghana", "GH" ],
- 84 : [ "Gibraltar", "GI" ],
- 85 : [ "Greece", "GR" ],
- 86 : [ "Greenland", "GL" ],
- 87 : [ "Grenada", "GD" ],
- 88 : [ "Guadeloupe", "GP" ],
- 89 : [ "Guam", "GU" ],
- 90 : [ "Guatemala", "GT" ],
- 91 : [ "Guinea", "GN" ],
- 92 : [ "GuineaBissau", "GW" ],
- 93 : [ "Guyana", "GY" ],
- 94 : [ "Haiti", "HT" ],
- 95 : [ "HeardAndMcDonaldIslands", "HM" ],
- 96 : [ "Honduras", "HN" ],
- 97 : [ "HongKong", "HK" ],
- 98 : [ "Hungary", "HU" ],
- 99 : [ "Iceland", "IS" ],
- 100 : [ "India", "IN" ],
- 101 : [ "Indonesia", "ID" ],
- 102 : [ "Iran", "IR" ],
- 103 : [ "Iraq", "IQ" ],
- 104 : [ "Ireland", "IE" ],
- 105 : [ "Israel", "IL" ],
- 106 : [ "Italy", "IT" ],
- 107 : [ "Jamaica", "JM" ],
- 108 : [ "Japan", "JP" ],
- 109 : [ "Jordan", "JO" ],
- 110 : [ "Kazakhstan", "KZ" ],
- 111 : [ "Kenya", "KE" ],
- 112 : [ "Kiribati", "KI" ],
- 113 : [ "NorthKorea", "KP" ],
- 114 : [ "SouthKorea", "KR" ],
- 115 : [ "Kuwait", "KW" ],
- 116 : [ "Kyrgyzstan", "KG" ],
- 117 : [ "Laos", "LA" ],
- 118 : [ "Latvia", "LV" ],
- 119 : [ "Lebanon", "LB" ],
- 120 : [ "Lesotho", "LS" ],
- 121 : [ "Liberia", "LR" ],
- 122 : [ "Libya", "LY" ],
- 123 : [ "Liechtenstein", "LI" ],
- 124 : [ "Lithuania", "LT" ],
- 125 : [ "Luxembourg", "LU" ],
- 126 : [ "Macau", "MO" ],
- 127 : [ "Macedonia", "MK" ],
- 128 : [ "Madagascar", "MG" ],
- 129 : [ "Malawi", "MW" ],
- 130 : [ "Malaysia", "MY" ],
- 131 : [ "Maldives", "MV" ],
- 132 : [ "Mali", "ML" ],
- 133 : [ "Malta", "MT" ],
- 134 : [ "MarshallIslands", "MH" ],
- 135 : [ "Martinique", "MQ" ],
- 136 : [ "Mauritania", "MR" ],
- 137 : [ "Mauritius", "MU" ],
- 138 : [ "Mayotte", "YT" ],
- 139 : [ "Mexico", "MX" ],
- 140 : [ "Micronesia", "FM" ],
- 141 : [ "Moldova", "MD" ],
- 142 : [ "Monaco", "MC" ],
- 143 : [ "Mongolia", "MN" ],
- 144 : [ "Montserrat", "MS" ],
- 145 : [ "Morocco", "MA" ],
- 146 : [ "Mozambique", "MZ" ],
- 147 : [ "Myanmar", "MM" ],
- 148 : [ "Namibia", "NA" ],
- 149 : [ "Nauru", "NR" ],
- 150 : [ "Nepal", "NP" ],
- 151 : [ "Netherlands", "NL" ],
- 152 : [ "CuraSao", "CW" ],
- 153 : [ "NewCaledonia", "NC" ],
- 154 : [ "NewZealand", "NZ" ],
- 155 : [ "Nicaragua", "NI" ],
- 156 : [ "Niger", "NE" ],
- 157 : [ "Nigeria", "NG" ],
- 158 : [ "Niue", "NU" ],
- 159 : [ "NorfolkIsland", "NF" ],
- 160 : [ "NorthernMarianaIslands", "MP" ],
- 161 : [ "Norway", "NO" ],
- 162 : [ "Oman", "OM" ],
- 163 : [ "Pakistan", "PK" ],
- 164 : [ "Palau", "PW" ],
- 165 : [ "PalestinianTerritories", "PS" ],
- 166 : [ "Panama", "PA" ],
- 167 : [ "PapuaNewGuinea", "PG" ],
- 168 : [ "Paraguay", "PY" ],
- 169 : [ "Peru", "PE" ],
- 170 : [ "Philippines", "PH" ],
- 171 : [ "Pitcairn", "PN" ],
- 172 : [ "Poland", "PL" ],
- 173 : [ "Portugal", "PT" ],
- 174 : [ "PuertoRico", "PR" ],
- 175 : [ "Qatar", "QA" ],
- 176 : [ "Reunion", "RE" ],
- 177 : [ "Romania", "RO" ],
- 178 : [ "Russia", "RU" ],
- 179 : [ "Rwanda", "RW" ],
- 180 : [ "SaintKittsAndNevis", "KN" ],
- 181 : [ "SaintLucia", "LC" ],
- 182 : [ "SaintVincentAndTheGrenadines", "VC" ],
- 183 : [ "Samoa", "WS" ],
- 184 : [ "SanMarino", "SM" ],
- 185 : [ "SaoTomeAndPrincipe", "ST" ],
- 186 : [ "SaudiArabia", "SA" ],
- 187 : [ "Senegal", "SN" ],
- 188 : [ "Seychelles", "SC" ],
- 189 : [ "SierraLeone", "SL" ],
- 190 : [ "Singapore", "SG" ],
- 191 : [ "Slovakia", "SK" ],
- 192 : [ "Slovenia", "SI" ],
- 193 : [ "SolomonIslands", "SB" ],
- 194 : [ "Somalia", "SO" ],
- 195 : [ "SouthAfrica", "ZA" ],
- 196 : [ "SouthGeorgiaAndTheSouthSandwichIslands", "GS" ],
- 197 : [ "Spain", "ES" ],
- 198 : [ "SriLanka", "LK" ],
- 199 : [ "SaintHelena", "SH" ],
- 200 : [ "SaintPierreAndMiquelon", "PM" ],
- 201 : [ "Sudan", "SD" ],
- 202 : [ "Suriname", "SR" ],
- 203 : [ "SvalbardAndJanMayenIslands", "SJ" ],
- 204 : [ "Swaziland", "SZ" ],
- 205 : [ "Sweden", "SE" ],
- 206 : [ "Switzerland", "CH" ],
- 207 : [ "Syria", "SY" ],
- 208 : [ "Taiwan", "TW" ],
- 209 : [ "Tajikistan", "TJ" ],
- 210 : [ "Tanzania", "TZ" ],
- 211 : [ "Thailand", "TH" ],
- 212 : [ "Togo", "TG" ],
- 213 : [ "Tokelau", "TK" ],
- 214 : [ "Tonga", "TO" ],
- 215 : [ "TrinidadAndTobago", "TT" ],
- 216 : [ "Tunisia", "TN" ],
- 217 : [ "Turkey", "TR" ],
- 218 : [ "Turkmenistan", "TM" ],
- 219 : [ "TurksAndCaicosIslands", "TC" ],
- 220 : [ "Tuvalu", "TV" ],
- 221 : [ "Uganda", "UG" ],
- 222 : [ "Ukraine", "UA" ],
- 223 : [ "UnitedArabEmirates", "AE" ],
- 224 : [ "UnitedKingdom", "GB" ],
- 225 : [ "UnitedStates", "US" ],
- 226 : [ "UnitedStatesMinorOutlyingIslands", "UM" ],
- 227 : [ "Uruguay", "UY" ],
- 228 : [ "Uzbekistan", "UZ" ],
- 229 : [ "Vanuatu", "VU" ],
- 230 : [ "VaticanCityState", "VA" ],
- 231 : [ "Venezuela", "VE" ],
- 232 : [ "Vietnam", "VN" ],
- 233 : [ "BritishVirginIslands", "VG" ],
- 234 : [ "UnitedStatesVirginIslands", "VI" ],
- 235 : [ "WallisAndFutunaIslands", "WF" ],
- 236 : [ "WesternSahara", "EH" ],
- 237 : [ "Yemen", "YE" ],
- 238 : [ "CanaryIslands", "IC" ],
- 239 : [ "Zambia", "ZM" ],
- 240 : [ "Zimbabwe", "ZW" ],
- 241 : [ "ClippertonIsland", "CP" ],
- 242 : [ "Montenegro", "ME" ],
- 243 : [ "Serbia", "RS" ],
- 244 : [ "Saint Barthelemy", "BL" ],
- 245 : [ "Saint Martin", "MF" ],
- 246 : [ "LatinAmericaAndTheCaribbean", "419" ],
- 247 : [ "AscensionIsland", "AC" ],
- 248 : [ "AlandIslands", "AX" ],
- 249 : [ "DiegoGarcia", "DG" ],
- 250 : [ "CeutaAndMelilla", "EA" ],
- 251 : [ "IsleOfMan", "IM" ],
- 252 : [ "Jersey", "JE" ],
- 253 : [ "TristanDaCunha", "TA" ],
- 254 : [ "SouthSudan", "SS" ],
- 255 : [ "Bonaire", "BQ" ],
- 256 : [ "SintMaarten", "SX" ],
- 257 : [ "Kosovo", "XK" ],
- 258 : [ "European Union", "EU" ],
- 259 : [ "Outlying Oceania", "QO" ]
+ 0 : ["AnyCountry", "ZZ"],
+ 1 : ["Afghanistan", "AF"],
+ 2 : ["Albania", "AL"],
+ 3 : ["Algeria", "DZ"],
+ 4 : ["American Samoa", "AS"],
+ 5 : ["Andorra", "AD"],
+ 6 : ["Angola", "AO"],
+ 7 : ["Anguilla", "AI"],
+ 8 : ["Antarctica", "AQ"],
+ 9 : ["Antigua And Barbuda", "AG"],
+ 10 : ["Argentina", "AR"],
+ 11 : ["Armenia", "AM"],
+ 12 : ["Aruba", "AW"],
+ 13 : ["Australia", "AU"],
+ 14 : ["Austria", "AT"],
+ 15 : ["Azerbaijan", "AZ"],
+ 16 : ["Bahamas", "BS"],
+ 17 : ["Bahrain", "BH"],
+ 18 : ["Bangladesh", "BD"],
+ 19 : ["Barbados", "BB"],
+ 20 : ["Belarus", "BY"],
+ 21 : ["Belgium", "BE"],
+ 22 : ["Belize", "BZ"],
+ 23 : ["Benin", "BJ"],
+ 24 : ["Bermuda", "BM"],
+ 25 : ["Bhutan", "BT"],
+ 26 : ["Bolivia", "BO"],
+ 27 : ["Bosnia And Herzegowina", "BA"],
+ 28 : ["Botswana", "BW"],
+ 29 : ["Bouvet Island", "BV"],
+ 30 : ["Brazil", "BR"],
+ 31 : ["British Indian Ocean Territory", "IO"],
+ 32 : ["Brunei", "BN"],
+ 33 : ["Bulgaria", "BG"],
+ 34 : ["Burkina Faso", "BF"],
+ 35 : ["Burundi", "BI"],
+ 36 : ["Cambodia", "KH"],
+ 37 : ["Cameroon", "CM"],
+ 38 : ["Canada", "CA"],
+ 39 : ["Cape Verde", "CV"],
+ 40 : ["Cayman Islands", "KY"],
+ 41 : ["Central African Republic", "CF"],
+ 42 : ["Chad", "TD"],
+ 43 : ["Chile", "CL"],
+ 44 : ["China", "CN"],
+ 45 : ["Christmas Island", "CX"],
+ 46 : ["Cocos Islands", "CC"],
+ 47 : ["Colombia", "CO"],
+ 48 : ["Comoros", "KM"],
+ 49 : ["Congo Kinshasa", "CD"],
+ 50 : ["Congo Brazzaville", "CG"],
+ 51 : ["Cook Islands", "CK"],
+ 52 : ["Costa Rica", "CR"],
+ 53 : ["Ivory Coast", "CI"],
+ 54 : ["Croatia", "HR"],
+ 55 : ["Cuba", "CU"],
+ 56 : ["Cyprus", "CY"],
+ 57 : ["Czech Republic", "CZ"],
+ 58 : ["Denmark", "DK"],
+ 59 : ["Djibouti", "DJ"],
+ 60 : ["Dominica", "DM"],
+ 61 : ["Dominican Republic", "DO"],
+ 62 : ["East Timor", "TL"],
+ 63 : ["Ecuador", "EC"],
+ 64 : ["Egypt", "EG"],
+ 65 : ["El Salvador", "SV"],
+ 66 : ["Equatorial Guinea", "GQ"],
+ 67 : ["Eritrea", "ER"],
+ 68 : ["Estonia", "EE"],
+ 69 : ["Ethiopia", "ET"],
+ 70 : ["Falkland Islands", "FK"],
+ 71 : ["Faroe Islands", "FO"],
+ 72 : ["Fiji", "FJ"],
+ 73 : ["Finland", "FI"],
+ 74 : ["France", "FR"],
+ 75 : ["Guernsey", "GG"],
+ 76 : ["French Guiana", "GF"],
+ 77 : ["French Polynesia", "PF"],
+ 78 : ["French Southern Territories", "TF"],
+ 79 : ["Gabon", "GA"],
+ 80 : ["Gambia", "GM"],
+ 81 : ["Georgia", "GE"],
+ 82 : ["Germany", "DE"],
+ 83 : ["Ghana", "GH"],
+ 84 : ["Gibraltar", "GI"],
+ 85 : ["Greece", "GR"],
+ 86 : ["Greenland", "GL"],
+ 87 : ["Grenada", "GD"],
+ 88 : ["Guadeloupe", "GP"],
+ 89 : ["Guam", "GU"],
+ 90 : ["Guatemala", "GT"],
+ 91 : ["Guinea", "GN"],
+ 92 : ["Guinea Bissau", "GW"],
+ 93 : ["Guyana", "GY"],
+ 94 : ["Haiti", "HT"],
+ 95 : ["Heard And McDonald Islands", "HM"],
+ 96 : ["Honduras", "HN"],
+ 97 : ["Hong Kong", "HK"],
+ 98 : ["Hungary", "HU"],
+ 99 : ["Iceland", "IS"],
+ 100 : ["India", "IN"],
+ 101 : ["Indonesia", "ID"],
+ 102 : ["Iran", "IR"],
+ 103 : ["Iraq", "IQ"],
+ 104 : ["Ireland", "IE"],
+ 105 : ["Israel", "IL"],
+ 106 : ["Italy", "IT"],
+ 107 : ["Jamaica", "JM"],
+ 108 : ["Japan", "JP"],
+ 109 : ["Jordan", "JO"],
+ 110 : ["Kazakhstan", "KZ"],
+ 111 : ["Kenya", "KE"],
+ 112 : ["Kiribati", "KI"],
+ 113 : ["North Korea", "KP"],
+ 114 : ["South Korea", "KR"],
+ 115 : ["Kuwait", "KW"],
+ 116 : ["Kyrgyzstan", "KG"],
+ 117 : ["Laos", "LA"],
+ 118 : ["Latvia", "LV"],
+ 119 : ["Lebanon", "LB"],
+ 120 : ["Lesotho", "LS"],
+ 121 : ["Liberia", "LR"],
+ 122 : ["Libya", "LY"],
+ 123 : ["Liechtenstein", "LI"],
+ 124 : ["Lithuania", "LT"],
+ 125 : ["Luxembourg", "LU"],
+ 126 : ["Macau", "MO"],
+ 127 : ["Macedonia", "MK"],
+ 128 : ["Madagascar", "MG"],
+ 129 : ["Malawi", "MW"],
+ 130 : ["Malaysia", "MY"],
+ 131 : ["Maldives", "MV"],
+ 132 : ["Mali", "ML"],
+ 133 : ["Malta", "MT"],
+ 134 : ["Marshall Islands", "MH"],
+ 135 : ["Martinique", "MQ"],
+ 136 : ["Mauritania", "MR"],
+ 137 : ["Mauritius", "MU"],
+ 138 : ["Mayotte", "YT"],
+ 139 : ["Mexico", "MX"],
+ 140 : ["Micronesia", "FM"],
+ 141 : ["Moldova", "MD"],
+ 142 : ["Monaco", "MC"],
+ 143 : ["Mongolia", "MN"],
+ 144 : ["Montserrat", "MS"],
+ 145 : ["Morocco", "MA"],
+ 146 : ["Mozambique", "MZ"],
+ 147 : ["Myanmar", "MM"],
+ 148 : ["Namibia", "NA"],
+ 149 : ["Nauru", "NR"],
+ 150 : ["Nepal", "NP"],
+ 151 : ["Netherlands", "NL"],
+ 152 : ["Cura Sao", "CW"],
+ 153 : ["New Caledonia", "NC"],
+ 154 : ["New Zealand", "NZ"],
+ 155 : ["Nicaragua", "NI"],
+ 156 : ["Niger", "NE"],
+ 157 : ["Nigeria", "NG"],
+ 158 : ["Niue", "NU"],
+ 159 : ["Norfolk Island", "NF"],
+ 160 : ["Northern Mariana Islands", "MP"],
+ 161 : ["Norway", "NO"],
+ 162 : ["Oman", "OM"],
+ 163 : ["Pakistan", "PK"],
+ 164 : ["Palau", "PW"],
+ 165 : ["Palestinian Territories", "PS"],
+ 166 : ["Panama", "PA"],
+ 167 : ["Papua New Guinea", "PG"],
+ 168 : ["Paraguay", "PY"],
+ 169 : ["Peru", "PE"],
+ 170 : ["Philippines", "PH"],
+ 171 : ["Pitcairn", "PN"],
+ 172 : ["Poland", "PL"],
+ 173 : ["Portugal", "PT"],
+ 174 : ["Puerto Rico", "PR"],
+ 175 : ["Qatar", "QA"],
+ 176 : ["Reunion", "RE"],
+ 177 : ["Romania", "RO"],
+ 178 : ["Russia", "RU"],
+ 179 : ["Rwanda", "RW"],
+ 180 : ["Saint Kitts And Nevis", "KN"],
+ 181 : ["Saint Lucia", "LC"],
+ 182 : ["Saint Vincent And The Grenadines", "VC"],
+ 183 : ["Samoa", "WS"],
+ 184 : ["San Marino", "SM"],
+ 185 : ["Sao Tome And Principe", "ST"],
+ 186 : ["Saudi Arabia", "SA"],
+ 187 : ["Senegal", "SN"],
+ 188 : ["Seychelles", "SC"],
+ 189 : ["Sierra Leone", "SL"],
+ 190 : ["Singapore", "SG"],
+ 191 : ["Slovakia", "SK"],
+ 192 : ["Slovenia", "SI"],
+ 193 : ["Solomon Islands", "SB"],
+ 194 : ["Somalia", "SO"],
+ 195 : ["South Africa", "ZA"],
+ 196 : ["South Georgia And The South Sandwich Islands", "GS"],
+ 197 : ["Spain", "ES"],
+ 198 : ["Sri Lanka", "LK"],
+ 199 : ["Saint Helena", "SH"],
+ 200 : ["Saint Pierre And Miquelon", "PM"],
+ 201 : ["Sudan", "SD"],
+ 202 : ["Suriname", "SR"],
+ 203 : ["Svalbard And Jan Mayen Islands", "SJ"],
+ 204 : ["Swaziland", "SZ"],
+ 205 : ["Sweden", "SE"],
+ 206 : ["Switzerland", "CH"],
+ 207 : ["Syria", "SY"],
+ 208 : ["Taiwan", "TW"],
+ 209 : ["Tajikistan", "TJ"],
+ 210 : ["Tanzania", "TZ"],
+ 211 : ["Thailand", "TH"],
+ 212 : ["Togo", "TG"],
+ 213 : ["Tokelau", "TK"],
+ 214 : ["Tonga", "TO"],
+ 215 : ["Trinidad And Tobago", "TT"],
+ 216 : ["Tunisia", "TN"],
+ 217 : ["Turkey", "TR"],
+ 218 : ["Turkmenistan", "TM"],
+ 219 : ["Turks And Caicos Islands", "TC"],
+ 220 : ["Tuvalu", "TV"],
+ 221 : ["Uganda", "UG"],
+ 222 : ["Ukraine", "UA"],
+ 223 : ["United Arab Emirates", "AE"],
+ 224 : ["United Kingdom", "GB"],
+ 225 : ["United States", "US"],
+ 226 : ["United States Minor Outlying Islands", "UM"],
+ 227 : ["Uruguay", "UY"],
+ 228 : ["Uzbekistan", "UZ"],
+ 229 : ["Vanuatu", "VU"],
+ 230 : ["Vatican City State", "VA"],
+ 231 : ["Venezuela", "VE"],
+ 232 : ["Vietnam", "VN"],
+ 233 : ["British Virgin Islands", "VG"],
+ 234 : ["United States Virgin Islands", "VI"],
+ 235 : ["Wallis And Futuna Islands", "WF"],
+ 236 : ["Western Sahara", "EH"],
+ 237 : ["Yemen", "YE"],
+ 238 : ["Canary Islands", "IC"],
+ 239 : ["Zambia", "ZM"],
+ 240 : ["Zimbabwe", "ZW"],
+ 241 : ["Clipperton Island", "CP"],
+ 242 : ["Montenegro", "ME"],
+ 243 : ["Serbia", "RS"],
+ 244 : ["Saint Barthelemy", "BL"],
+ 245 : ["Saint Martin", "MF"],
+ 246 : ["Latin America", "419"],
+ 247 : ["Ascension Island", "AC"],
+ 248 : ["Aland Islands", "AX"],
+ 249 : ["Diego Garcia", "DG"],
+ 250 : ["Ceuta And Melilla", "EA"],
+ 251 : ["Isle Of Man", "IM"],
+ 252 : ["Jersey", "JE"],
+ 253 : ["Tristan Da Cunha", "TA"],
+ 254 : ["South Sudan", "SS"],
+ 255 : ["Bonaire", "BQ"],
+ 256 : ["Sint Maarten", "SX"],
+ 257 : ["Kosovo", "XK"],
+ 258 : ["European Union", "EU"],
+ 259 : ["Outlying Oceania", "QO"],
+ 260 : ["World", "001"],
+ 261 : ["Europe", "150"]
+}
+
+country_aliases = {
+ # Deprecated:
+ 'Tokelau': 'TokelauCountry',
+ 'Tuvalu': 'TuvaluCountry',
+ # Renamings:
+ 'DemocraticRepublicOfCongo': 'CongoKinshasa',
+ 'PeoplesRepublicOfCongo': 'CongoBrazzaville',
+ 'DemocraticRepublicOfKorea': 'NorthKorea',
+ 'RepublicOfKorea': 'SouthKorea',
+ 'RussianFederation': 'Russia',
+ 'SyrianArabRepublic': 'Syria',
+ 'LatinAmericaAndTheCaribbean': 'LatinAmerica',
}
script_list = {
- 0 : [ "AnyScript", "Zzzz" ],
- 1 : [ "Arabic", "Arab" ],
- 2 : [ "Cyrillic", "Cyrl" ],
- 3 : [ "Deseret", "Dsrt" ],
- 4 : [ "Gurmukhi", "Guru" ],
- 5 : [ "Simplified Han", "Hans" ],
- 6 : [ "Traditional Han", "Hant" ],
- 7 : [ "Latin", "Latn" ],
- 8 : [ "Mongolian", "Mong" ],
- 9 : [ "Tifinagh", "Tfng" ],
- 10 : [ "Armenian", "Armn" ],
- 11 : [ "Bengali", "Beng" ],
- 12 : [ "Cherokee", "Cher" ],
- 13 : [ "Devanagari", "Deva" ],
- 14 : [ "Ethiopic", "Ethi" ],
- 15 : [ "Georgian", "Geor" ],
- 16 : [ "Greek", "Grek" ],
- 17 : [ "Gujarati", "Gujr" ],
- 18 : [ "Hebrew", "Hebr" ],
- 19 : [ "Japanese", "Jpan" ],
- 20 : [ "Khmer", "Khmr" ],
- 21 : [ "Kannada", "Knda" ],
- 22 : [ "Korean", "Kore" ],
- 23 : [ "Lao", "Laoo" ],
- 24 : [ "Malayalam", "Mlym" ],
- 25 : [ "Myanmar", "Mymr" ],
- 26 : [ "Oriya", "Orya" ],
- 27 : [ "Tamil", "Taml" ],
- 28 : [ "Telugu", "Telu" ],
- 29 : [ "Thaana", "Thaa" ],
- 30 : [ "Thai", "Thai" ],
- 31 : [ "Tibetan", "Tibt" ],
- 32 : [ "Sinhala", "Sinh" ],
- 33 : [ "Syriac", "Syrc" ],
- 34 : [ "Yi", "Yiii" ],
- 35 : [ "Vai", "Vaii" ],
- 36 : [ "Avestan", "Avst" ],
- 37 : [ "Balinese", "Bali" ],
- 38 : [ "Bamum", "Bamu" ],
- 39 : [ "Batak", "Batk" ],
- 40 : [ "Bopomofo", "Bopo" ],
- 41 : [ "Brahmi", "Brah" ],
- 42 : [ "Buginese", "Bugi" ],
- 43 : [ "Buhid", "Buhd" ],
- 44 : [ "CanadianAboriginal", "Cans" ],
- 45 : [ "Carian", "Cari" ],
- 46 : [ "Chakma", "Cakm" ],
- 47 : [ "Cham", "Cham" ],
- 48 : [ "Coptic", "Copt" ],
- 49 : [ "Cypriot", "Cprt" ],
- 50 : [ "Egyptian Hieroglyphs", "Egyp" ],
- 51 : [ "Fraser", "Lisu" ],
- 52 : [ "Glagolitic", "Glag" ],
- 53 : [ "Gothic", "Goth" ],
- 54 : [ "Han", "Hani" ],
- 55 : [ "Hangul", "Hang" ],
- 56 : [ "Hanunoo", "Hano" ],
- 57 : [ "Imperial Aramaic", "Armi" ],
- 58 : [ "Inscriptional Pahlavi", "Phli" ],
- 59 : [ "Inscriptional Parthian", "Prti" ],
- 60 : [ "Javanese", "Java" ],
- 61 : [ "Kaithi", "Kthi" ],
- 62 : [ "Katakana", "Kana" ],
- 63 : [ "Kayah Li", "Kali" ],
- 64 : [ "Kharoshthi", "Khar" ],
- 65 : [ "Lanna", "Lana" ],
- 66 : [ "Lepcha", "Lepc" ],
- 67 : [ "Limbu", "Limb" ],
- 68 : [ "Linear B", "Linb" ],
- 69 : [ "Lycian", "Lyci" ],
- 70 : [ "Lydian", "Lydi" ],
- 71 : [ "Mandaean", "Mand" ],
- 72 : [ "Meitei Mayek", "Mtei" ],
- 73 : [ "Meroitic", "Mero" ],
- 74 : [ "Meroitic Cursive", "Merc" ],
- 75 : [ "Nko", "Nkoo" ],
- 76 : [ "New Tai Lue", "Talu" ],
- 77 : [ "Ogham", "Ogam" ],
- 78 : [ "Ol Chiki", "Olck" ],
- 79 : [ "Old Italic", "Ital" ],
- 80 : [ "Old Persian", "Xpeo" ],
- 81 : [ "Old South Arabian", "Sarb" ],
- 82 : [ "Orkhon", "Orkh" ],
- 83 : [ "Osmanya", "Osma" ],
- 84 : [ "Phags Pa", "Phag" ],
- 85 : [ "Phoenician", "Phnx" ],
- 86 : [ "Pollard Phonetic", "Plrd" ],
- 87 : [ "Rejang", "Rjng" ],
- 88 : [ "Runic", "Runr" ],
- 89 : [ "Samaritan", "Samr" ],
- 90 : [ "Saurashtra", "Saur" ],
- 91 : [ "Sharada", "Shrd" ],
- 92 : [ "Shavian", "Shaw" ],
- 93 : [ "Sora Sompeng", "Sora" ],
- 94 : [ "Cuneiform", "Xsux" ],
- 95 : [ "Sundanese", "Sund" ],
- 96 : [ "Syloti Nagri", "Sylo" ],
- 97 : [ "Tagalog", "Tglg" ],
- 98 : [ "Tagbanwa", "Tagb" ],
- 99 : [ "Tai Le", "Tale" ],
- 100 : [ "Tai Viet", "Tavt" ],
- 101 : [ "Takri", "Takr" ],
- 102 : [ "Ugaritic", "Ugar" ],
- 103 : [ "Braille", "Brai" ],
- 104 : [ "Hiragana", "Hira" ],
- 105 : [ "Caucasian Albanian", "Aghb" ],
- 106 : [ "Bassa Vah", "Bass" ],
- 107 : [ "Duployan", "Dupl" ],
- 108 : [ "Elbasan", "Elba" ],
- 109 : [ "Grantha", "Gran" ],
- 110 : [ "Pahawh Hmong", "Hmng" ],
- 111 : [ "Khojki", "Khoj" ],
- 112 : [ "Linear A", "Lina" ],
- 113 : [ "Mahajani", "Mahj" ],
- 114 : [ "Manichaean", "Mani" ],
- 115 : [ "Mende Kikakui", "Mend" ],
- 116 : [ "Modi", "Modi" ],
- 117 : [ "Mro", "Mroo" ],
- 118 : [ "Old North Arabian", "Narb" ],
- 119 : [ "Nabataean", "Nbat" ],
- 120 : [ "Palmyrene", "Palm" ],
- 121 : [ "Pau Cin Hau", "Pauc" ],
- 122 : [ "Old Permic", "Perm" ],
- 123 : [ "Psalter Pahlavi", "Phlp" ],
- 124 : [ "Siddham", "Sidd" ],
- 125 : [ "Khudawadi", "Sind" ],
- 126 : [ "Tirhuta", "Tirh" ],
- 127 : [ "Varang Kshiti", "Wara" ],
- 128 : [ "Ahom", "Ahom" ],
- 129 : [ "Anatolian Hieroglyphs", "Hluw" ],
- 130 : [ "Hatran", "Hatr" ],
- 131 : [ "Multani", "Mult" ],
- 132 : [ "Old Hungarian", "Hung" ],
- 133 : [ "SignWriting", "Sgnw" ],
- 134 : [ "Adlam", "Adlm" ],
- 135 : [ "Bhaiksuki", "Bhks" ],
- 136 : [ "Marchen", "Marc" ],
- 137 : [ "Newa", "Newa" ],
- 138 : [ "Osage", "Osge" ],
- 139 : [ "Tangut", "Tang" ],
- 140 : [ "Han with Bopomofo", "Hanb" ],
- 141 : [ "Jamo", "Jamo" ]
+ 0 : ["AnyScript", "Zzzz"],
+ 1 : ["Arabic", "Arab"],
+ 2 : ["Cyrillic", "Cyrl"],
+ 3 : ["Deseret", "Dsrt"],
+ 4 : ["Gurmukhi", "Guru"],
+ 5 : ["Simplified Han", "Hans"],
+ 6 : ["Traditional Han", "Hant"],
+ 7 : ["Latin", "Latn"],
+ 8 : ["Mongolian", "Mong"],
+ 9 : ["Tifinagh", "Tfng"],
+ 10 : ["Armenian", "Armn"],
+ 11 : ["Bengali", "Beng"],
+ 12 : ["Cherokee", "Cher"],
+ 13 : ["Devanagari", "Deva"],
+ 14 : ["Ethiopic", "Ethi"],
+ 15 : ["Georgian", "Geor"],
+ 16 : ["Greek", "Grek"],
+ 17 : ["Gujarati", "Gujr"],
+ 18 : ["Hebrew", "Hebr"],
+ 19 : ["Japanese", "Jpan"],
+ 20 : ["Khmer", "Khmr"],
+ 21 : ["Kannada", "Knda"],
+ 22 : ["Korean", "Kore"],
+ 23 : ["Lao", "Laoo"],
+ 24 : ["Malayalam", "Mlym"],
+ 25 : ["Myanmar", "Mymr"],
+ 26 : ["Oriya", "Orya"],
+ 27 : ["Tamil", "Taml"],
+ 28 : ["Telugu", "Telu"],
+ 29 : ["Thaana", "Thaa"],
+ 30 : ["Thai", "Thai"],
+ 31 : ["Tibetan", "Tibt"],
+ 32 : ["Sinhala", "Sinh"],
+ 33 : ["Syriac", "Syrc"],
+ 34 : ["Yi", "Yiii"],
+ 35 : ["Vai", "Vaii"],
+ 36 : ["Avestan", "Avst"],
+ 37 : ["Balinese", "Bali"],
+ 38 : ["Bamum", "Bamu"],
+ 39 : ["Batak", "Batk"],
+ 40 : ["Bopomofo", "Bopo"],
+ 41 : ["Brahmi", "Brah"],
+ 42 : ["Buginese", "Bugi"],
+ 43 : ["Buhid", "Buhd"],
+ 44 : ["Canadian Aboriginal", "Cans"],
+ 45 : ["Carian", "Cari"],
+ 46 : ["Chakma", "Cakm"],
+ 47 : ["Cham", "Cham"],
+ 48 : ["Coptic", "Copt"],
+ 49 : ["Cypriot", "Cprt"],
+ 50 : ["Egyptian Hieroglyphs", "Egyp"],
+ 51 : ["Fraser", "Lisu"],
+ 52 : ["Glagolitic", "Glag"],
+ 53 : ["Gothic", "Goth"],
+ 54 : ["Han", "Hani"],
+ 55 : ["Hangul", "Hang"],
+ 56 : ["Hanunoo", "Hano"],
+ 57 : ["Imperial Aramaic", "Armi"],
+ 58 : ["Inscriptional Pahlavi", "Phli"],
+ 59 : ["Inscriptional Parthian", "Prti"],
+ 60 : ["Javanese", "Java"],
+ 61 : ["Kaithi", "Kthi"],
+ 62 : ["Katakana", "Kana"],
+ 63 : ["Kayah Li", "Kali"],
+ 64 : ["Kharoshthi", "Khar"],
+ 65 : ["Lanna", "Lana"],
+ 66 : ["Lepcha", "Lepc"],
+ 67 : ["Limbu", "Limb"],
+ 68 : ["Linear B", "Linb"],
+ 69 : ["Lycian", "Lyci"],
+ 70 : ["Lydian", "Lydi"],
+ 71 : ["Mandaean", "Mand"],
+ 72 : ["Meitei Mayek", "Mtei"],
+ 73 : ["Meroitic", "Mero"],
+ 74 : ["Meroitic Cursive", "Merc"],
+ 75 : ["Nko", "Nkoo"],
+ 76 : ["New Tai Lue", "Talu"],
+ 77 : ["Ogham", "Ogam"],
+ 78 : ["Ol Chiki", "Olck"],
+ 79 : ["Old Italic", "Ital"],
+ 80 : ["Old Persian", "Xpeo"],
+ 81 : ["Old South Arabian", "Sarb"],
+ 82 : ["Orkhon", "Orkh"],
+ 83 : ["Osmanya", "Osma"],
+ 84 : ["Phags Pa", "Phag"],
+ 85 : ["Phoenician", "Phnx"],
+ 86 : ["Pollard Phonetic", "Plrd"],
+ 87 : ["Rejang", "Rjng"],
+ 88 : ["Runic", "Runr"],
+ 89 : ["Samaritan", "Samr"],
+ 90 : ["Saurashtra", "Saur"],
+ 91 : ["Sharada", "Shrd"],
+ 92 : ["Shavian", "Shaw"],
+ 93 : ["Sora Sompeng", "Sora"],
+ 94 : ["Cuneiform", "Xsux"],
+ 95 : ["Sundanese", "Sund"],
+ 96 : ["Syloti Nagri", "Sylo"],
+ 97 : ["Tagalog", "Tglg"],
+ 98 : ["Tagbanwa", "Tagb"],
+ 99 : ["Tai Le", "Tale"],
+ 100 : ["Tai Viet", "Tavt"],
+ 101 : ["Takri", "Takr"],
+ 102 : ["Ugaritic", "Ugar"],
+ 103 : ["Braille", "Brai"],
+ 104 : ["Hiragana", "Hira"],
+ 105 : ["Caucasian Albanian", "Aghb"],
+ 106 : ["Bassa Vah", "Bass"],
+ 107 : ["Duployan", "Dupl"],
+ 108 : ["Elbasan", "Elba"],
+ 109 : ["Grantha", "Gran"],
+ 110 : ["Pahawh Hmong", "Hmng"],
+ 111 : ["Khojki", "Khoj"],
+ 112 : ["Linear A", "Lina"],
+ 113 : ["Mahajani", "Mahj"],
+ 114 : ["Manichaean", "Mani"],
+ 115 : ["Mende Kikakui", "Mend"],
+ 116 : ["Modi", "Modi"],
+ 117 : ["Mro", "Mroo"],
+ 118 : ["Old North Arabian", "Narb"],
+ 119 : ["Nabataean", "Nbat"],
+ 120 : ["Palmyrene", "Palm"],
+ 121 : ["Pau Cin Hau", "Pauc"],
+ 122 : ["Old Permic", "Perm"],
+ 123 : ["Psalter Pahlavi", "Phlp"],
+ 124 : ["Siddham", "Sidd"],
+ 125 : ["Khudawadi", "Sind"],
+ 126 : ["Tirhuta", "Tirh"],
+ 127 : ["Varang Kshiti", "Wara"],
+ 128 : ["Ahom", "Ahom"],
+ 129 : ["Anatolian Hieroglyphs", "Hluw"],
+ 130 : ["Hatran", "Hatr"],
+ 131 : ["Multani", "Mult"],
+ 132 : ["Old Hungarian", "Hung"],
+ 133 : ["Sign Writing", "Sgnw"],
+ 134 : ["Adlam", "Adlm"],
+ 135 : ["Bhaiksuki", "Bhks"],
+ 136 : ["Marchen", "Marc"],
+ 137 : ["Newa", "Newa"],
+ 138 : ["Osage", "Osge"],
+ 139 : ["Tangut", "Tang"],
+ 140 : ["Han with Bopomofo", "Hanb"],
+ 141 : ["Jamo", "Jamo"]
+}
+
+script_aliases = {
+ # Renamings:
+ 'SimplifiedChineseScript': 'SimplifiedHanScript',
+ 'TraditionalChineseScript': 'TraditionalHanScript',
}
def countryCodeToId(code):
diff --git a/util/local_database/qlocalexml2cpp.py b/util/local_database/qlocalexml2cpp.py
index 0f10f8ce2d..fb5ae5ba54 100755
--- a/util/local_database/qlocalexml2cpp.py
+++ b/util/local_database/qlocalexml2cpp.py
@@ -38,6 +38,7 @@ import sys
import tempfile
import datetime
import xml.dom.minidom
+from enumdata import language_aliases, country_aliases, script_aliases
from localexml import Locale
@@ -751,27 +752,15 @@ def main():
# Language enum
qlocaleh_temp_file.write(" enum Language {\n")
- language = ""
- for key in language_map.keys():
- language = fixedLanguageName(language_map[key][0], dupes)
+ language = None
+ for key, value in language_map.items():
+ language = fixedLanguageName(value[0], dupes)
qlocaleh_temp_file.write(" " + language + " = " + str(key) + ",\n")
- # legacy. should disappear at some point
- qlocaleh_temp_file.write("\n")
- qlocaleh_temp_file.write(" Norwegian = NorwegianBokmal,\n")
- qlocaleh_temp_file.write(" Moldavian = Romanian,\n")
- qlocaleh_temp_file.write(" SerboCroatian = Serbian,\n")
- qlocaleh_temp_file.write(" Tagalog = Filipino,\n")
- qlocaleh_temp_file.write(" Twi = Akan,\n")
- # renamings
- qlocaleh_temp_file.write(" Afan = Oromo,\n")
- qlocaleh_temp_file.write(" Byelorussian = Belarusian,\n")
- qlocaleh_temp_file.write(" Bhutani = Dzongkha,\n")
- qlocaleh_temp_file.write(" Cambodian = Khmer,\n")
- qlocaleh_temp_file.write(" Kurundi = Rundi,\n")
- qlocaleh_temp_file.write(" RhaetoRomance = Romansh,\n")
- qlocaleh_temp_file.write(" Chewa = Nyanja,\n")
- qlocaleh_temp_file.write(" Frisian = WesternFrisian,\n")
- qlocaleh_temp_file.write(" Uigur = Uighur,\n")
+
+ qlocaleh_temp_file.write("\n " +
+ ",\n ".join('%s = %s' % pair
+ for pair in sorted(language_aliases.items())) +
+ ",\n")
qlocaleh_temp_file.write("\n")
qlocaleh_temp_file.write(" LastLanguage = " + language + "\n")
qlocaleh_temp_file.write(" };\n")
@@ -780,35 +769,28 @@ def main():
# Script enum
qlocaleh_temp_file.write(" enum Script {\n")
- script = ""
- for key in script_map.keys():
- script = fixedScriptName(script_map[key][0], dupes)
+ script = None
+ for key, value in script_map.items():
+ script = fixedScriptName(value[0], dupes)
qlocaleh_temp_file.write(" " + script + " = " + str(key) + ",\n")
- # renamings
- qlocaleh_temp_file.write("\n")
- qlocaleh_temp_file.write(" SimplifiedChineseScript = SimplifiedHanScript,\n")
- qlocaleh_temp_file.write(" TraditionalChineseScript = TraditionalHanScript,\n")
+ qlocaleh_temp_file.write("\n " +
+ ",\n ".join('%s = %s' % pair
+ for pair in sorted(script_aliases.items())) +
+ ",\n")
qlocaleh_temp_file.write("\n")
qlocaleh_temp_file.write(" LastScript = " + script + "\n")
qlocaleh_temp_file.write(" };\n")
# Country enum
qlocaleh_temp_file.write(" enum Country {\n")
- country = ""
- for key in country_map.keys():
- country = fixedCountryName(country_map[key][0], dupes)
+ country = None
+ for key, value in country_map.items():
+ country = fixedCountryName(value[0], dupes)
qlocaleh_temp_file.write(" " + country + " = " + str(key) + ",\n")
- # deprecated
- qlocaleh_temp_file.write("\n")
- qlocaleh_temp_file.write(" Tokelau = TokelauCountry,\n")
- qlocaleh_temp_file.write(" Tuvalu = TuvaluCountry,\n")
- # renamings
- qlocaleh_temp_file.write(" DemocraticRepublicOfCongo = CongoKinshasa,\n")
- qlocaleh_temp_file.write(" PeoplesRepublicOfCongo = CongoBrazzaville,\n")
- qlocaleh_temp_file.write(" DemocraticRepublicOfKorea = NorthKorea,\n")
- qlocaleh_temp_file.write(" RepublicOfKorea = SouthKorea,\n")
- qlocaleh_temp_file.write(" RussianFederation = Russia,\n")
- qlocaleh_temp_file.write(" SyrianArabRepublic = Syria,\n")
+ qlocaleh_temp_file.write("\n " +
+ ",\n ".join('%s = %s' % pair
+ for pair in sorted(country_aliases.items())) +
+ ",\n")
qlocaleh_temp_file.write("\n")
qlocaleh_temp_file.write(" LastCountry = " + country + "\n")
qlocaleh_temp_file.write(" };\n")
@@ -835,7 +817,7 @@ def main():
qlocaleqdoc_temp_file = os.fdopen(qlocaleqdoc_temp_file, "w")
qlocaleqdoc_file = open(qtsrcdir + "/src/corelib/tools/qlocale.qdoc", "r")
s = qlocaleqdoc_file.readline()
- DOCSTRING=" QLocale's data is based on Common Locale Data Repository "
+ DOCSTRING = " QLocale's data is based on Common Locale Data Repository "
while s:
if DOCSTRING in s:
qlocaleqdoc_temp_file.write(DOCSTRING + "v" + cldr_version + ".\n")
diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp
index 0f3c28137d..0c3c0b2ee1 100644
--- a/util/unicode/main.cpp
+++ b/util/unicode/main.cpp
@@ -2473,6 +2473,10 @@ static QByteArray createPropertyInfo()
out += ", ";
out += QByteArray::number( p.lowerCaseDiff );
out += ", ";
+ out += "#ifdef Q_OS_WASM \n"
+// " unsigned char : 0; //wasm 64 packing trick QTBUG-65259\n"
+ out += "#endif \n"
+ out += ", ";
// " ushort upperCaseSpecial : 1;\n"
// " signed short upperCaseDiff : 15;\n"
out += QByteArray::number( p.upperCaseSpecial );
@@ -2497,6 +2501,10 @@ static QByteArray createPropertyInfo()
// " ushort nfQuickCheck : 8;\n"
out += QByteArray::number( p.nfQuickCheck );
out += ", ";
+ out += "#ifdef Q_OS_WASM \n"
+// " unsigned char : 0; //wasm 64 packing trick QTBUG-65259\n"
+ out += "#endif \n"
+ out += ", ";
// " ushort graphemeBreakClass : 5; /* 5 used */\n"
// " ushort wordBreakClass : 5; /* 5 used */\n"
// " ushort sentenceBreakClass : 8; /* 4 used */\n"
diff --git a/util/x86simdgen/generate.pl b/util/x86simdgen/generate.pl
new file mode 100755
index 0000000000..5df2f4d526
--- /dev/null
+++ b/util/x86simdgen/generate.pl
@@ -0,0 +1,199 @@
+#!/usr/bin/env perl
+#############################################################################
+##
+## Copyright (C) 2018 Intel Corporation.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the build configuration tools of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:MIT$
+## Permission is hereby granted, free of charge, to any person obtaining a copy
+## of this software and associated documentation files (the "Software"), to deal
+## in the Software without restriction, including without limitation the rights
+## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+## copies of the Software, and to permit persons to whom the Software is
+## furnished to do so, subject to the following conditions:
+##
+## The above copyright notice and this permission notice shall be included in
+## all copies or substantial portions of the Software.
+##
+## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+## THE SOFTWARE.
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+use strict;
+$\ = "\n";
+$/ = "\n";
+my %leaves = (
+ Leaf1EDX => "CPUID Leaf 1, EDX",
+ Leaf1ECX => "CPUID Leaf 1, ECX",
+ Leaf7_0EBX => "CPUID Leaf 7, Sub-leaf 0, EBX",
+ Leaf7_0ECX => "CPUID Leaf 7, Sub-leaf 0, ECX",
+ Leaf7_0EDX => "CPUID Leaf 7, Sub-leaf 0, EDX",
+);
+my @leafNames = sort keys %leaves;
+
+# Read data from stdin
+my $i = 1;
+my @features;
+while (<STDIN>) {
+ s/#.*$//;
+ chomp;
+ next if $_ eq "";
+
+ my ($name, $function, $bit, $depends) = split /\s+/;
+ die("Unknown CPUID function \"$function\"")
+ unless grep $function, @leafNames;
+
+ my $id = uc($name);
+ $id =~ s/[^A-Z0-9_]/_/g;
+ push @features,
+ { name => $name, depends => $depends, id => $id, bit => $bit, leaf => $function };
+ ++$i;
+}
+
+if (my $h = shift @ARGV) {
+ open HEADER, ">", $h;
+ select HEADER;
+}
+
+# Print the qsimd_x86_p.h output
+print q{// This is a generated file. DO NOT EDIT.
+// Please see util/x86simdgen/generate.pl";
+#ifndef QSIMD_P_H
+# error "Please include <private/qsimd_p.h> instead"
+#endif
+#ifndef QSIMD_X86_P_H
+#define QSIMD_X86_P_H
+
+#include "qsimd_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.
+//
+
+QT_BEGIN_NAMESPACE
+
+// used only to indicate that the CPU detection was initialized
+#define QSimdInitialized (Q_UINT64_C(1) << 0)};
+
+# Print the enum
+my $lastleaf;
+for (my $i = 0; $i < scalar @features; ++$i) {
+ my $feature = $features[$i];
+ # Leaf header:
+ printf "\n// in %s:\n", $leaves{$feature->{leaf}}
+ if $feature->{leaf} ne $lastleaf;
+ $lastleaf = $feature->{leaf};
+
+ # Feature
+ printf "#define CpuFeature%-33s (Q_UINT64_C(1) << %d)\n", $feature->{id}, $i + 1;
+
+ # Feature string names for Clang and GCC
+ my $str = $feature->{name};
+ $str .= ",$feature->{depends}" if defined($feature->{depends});
+ printf "#define QT_FUNCTION_TARGET_STRING_%-17s \"%s\"\n",
+ $feature->{id}, $str;
+}
+
+print q{
+static const quint64 qCompilerCpuFeatures = 0};
+
+# And print the compiler-enabled features part:
+for (my $i = 0; $i < scalar @features; ++$i) {
+ my $feature = $features[$i];
+ printf
+ "#ifdef __%s__\n" .
+ " | CpuFeature%s\n" .
+ "#endif\n",
+ $feature->{id}, $feature->{id};
+}
+
+print q{ ;
+
+QT_END_NAMESPACE
+
+#endif // QSIMD_X86_P_H
+};
+
+if (my $cpp = shift @ARGV) {
+ open CPP, ">", $cpp;
+ select CPP;
+} else {
+ print q{
+
+---- cut here, paste the rest into qsimd_x86.cpp ---
+
+
+};
+};
+
+print "// This is a generated file. DO NOT EDIT.";
+print "// Please see util/x86simdgen/generate.pl";
+print '#include "qsimd_p.h"';
+print "";
+
+# Now generate the string table and bit-location array
+my $offset = 0;
+my @offsets;
+print "static const char features_string[] =";
+for my $feature (@features) {
+ print " \" $feature->{name}\\0\"";
+ push @offsets, $offset;
+ $offset += 2 + length($feature->{name});
+}
+print " \"\\0\";";
+
+# Print the string offset table
+printf "\nstatic const %s features_indices[] = {\n %3d",
+ $offset > 255 ? "quint16" : "quint8", $offset;
+for (my $j = 0; $j < scalar @offsets; ++$j) {
+ printf ",%s%3d",
+ ($j + 1) % 8 ? " " : "\n ", $offsets[$j];
+}
+print "\n};";
+
+# Print the locator enum and table
+print "\nenum X86CpuidLeaves {";
+map { print " $_," } @leafNames;
+print " X86CpuidMaxLeaf\n};";
+
+my $type = scalar %leaves > 8 ? "quint16" : "quint8";
+printf "\nstatic const %s x86_locators[] = {",
+ $type, $type;
+my $lastname;
+for (my $j = 0; $j < scalar @features; ++$j) {
+ my $feature = $features[$j];
+ printf ", // %s", $lastname
+ if defined($lastname);
+ printf "\n %s*32 + %2d",
+ $feature->{leaf}, $feature->{bit};
+ $lastname = $feature->{name};
+}
+printf qq{ // $lastname
+\};
+
+// List of AVX512 features (see detectProcessorFeatures())
+static const quint64 AllAVX512 = 0};
+
+# Print AVX512 features
+for (my $j = 0; $j < scalar @features; ++$j) {
+ my $feature = $features[$j];
+ $_ = $feature->{id};
+ printf "\n | CpuFeature%s", $_ if /AVX512/;
+}
+print ";";
diff --git a/util/x86simdgen/simd.txt b/util/x86simdgen/simd.txt
new file mode 100644
index 0000000000..1fce7b9497
--- /dev/null
+++ b/util/x86simdgen/simd.txt
@@ -0,0 +1,37 @@
+# Feature CPUID function Bit Required feature
+sse2 Leaf1EDX 26
+sse3 Leaf1ECX 0
+ssse3 Leaf1ECX 9
+fma Leaf1ECX 12
+sse4.1 Leaf1ECX 19
+sse4.2 Leaf1ECX 20
+movbe Leaf1ECX 22
+popcnt Leaf1ECX 23
+aes Leaf1ECX 25 sse4.2
+avx Leaf1ECX 28
+f16c Leaf1ECX 29
+rdrnd Leaf1ECX 30
+bmi Leaf7_0EBX 3
+hle Leaf7_0EBX 4
+avx2 Leaf7_0EBX 5
+bmi2 Leaf7_0EBX 8
+rtm Leaf7_0EBX 11
+avx512f Leaf7_0EBX 16
+avx512dq Leaf7_0EBX 17
+rdseed Leaf7_0EBX 18
+avx512ifma Leaf7_0EBX 21
+avx512pf Leaf7_0EBX 26
+avx512er Leaf7_0EBX 27
+avx512cd Leaf7_0EBX 28
+sha Leaf7_0EBX 29
+avx512bw Leaf7_0EBX 30
+avx512vl Leaf7_0EBX 31
+avx512vbmi Leaf7_0ECX 1
+avx512vbmi2 Leaf7_0ECX 6
+gfni Leaf7_0ECX 8
+vaes Leaf7_0ECX 9
+avx512vnni Leaf7_0ECX 11
+avx512bitalg Leaf7_0ECX 12
+avx512vpopcntdq Leaf7_0ECX 14
+avx5124nniw Leaf7_0EDX 2
+avx5124fmaps Leaf7_0EDX 3